summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--CREDITS7
-rw-r--r--Documentation/CodingStyle18
-rw-r--r--Documentation/DocBook/Makefile4
-rw-r--r--Documentation/DocBook/genericirq.tmpl4
-rw-r--r--Documentation/arm/Samsung-S3C24XX/Overview.txt30
-rw-r--r--Documentation/block/biodoc.txt7
-rw-r--r--Documentation/cachetlb.txt23
-rw-r--r--Documentation/feature-removal-schedule.txt25
-rw-r--r--Documentation/filesystems/bfs.txt2
-rw-r--r--Documentation/filesystems/fuse.txt4
-rw-r--r--Documentation/hwmon/f71805f56
-rw-r--r--Documentation/hwmon/it8715
-rw-r--r--Documentation/hwmon/k8temp2
-rw-r--r--Documentation/hwmon/pc8742738
-rw-r--r--Documentation/hwmon/sysfs-interface4
-rw-r--r--Documentation/hwmon/w83627ehf2
-rw-r--r--Documentation/hwmon/w83791d2
-rw-r--r--Documentation/hwmon/w83793110
-rw-r--r--Documentation/ibm-acpi.txt151
-rw-r--r--Documentation/kernel-parameters.txt14
-rw-r--r--Documentation/powerpc/booting-without-of.txt19
-rw-r--r--Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl8
-rw-r--r--Documentation/tty.txt111
-rw-r--r--MAINTAINERS191
-rw-r--r--Makefile56
-rw-r--r--arch/arm/Kconfig13
-rw-r--r--arch/arm/configs/ep93xx_defconfig123
-rw-r--r--arch/arm/configs/iop13xx_defconfig99
-rw-r--r--arch/arm/configs/iop32x_defconfig213
-rw-r--r--arch/arm/configs/iop33x_defconfig110
-rw-r--r--arch/arm/configs/ixp2000_defconfig114
-rw-r--r--arch/arm/configs/ixp23xx_defconfig136
-rw-r--r--arch/arm/configs/lpd270_defconfig103
-rw-r--r--arch/arm/configs/onearm_defconfig126
-rw-r--r--arch/arm/kernel/apm.c2
-rw-r--r--arch/arm/kernel/calls.S37
-rw-r--r--arch/arm/kernel/ecard.c2
-rw-r--r--arch/arm/kernel/head.S19
-rw-r--r--arch/arm/kernel/setup.c4
-rw-r--r--arch/arm/kernel/sys_arm.c13
-rw-r--r--arch/arm/mach-at91rm9200/at91sam9260_devices.c1
-rw-r--r--arch/arm/mach-at91rm9200/board-sam9260ek.c1
-rw-r--r--arch/arm/mach-ep93xx/core.c4
-rw-r--r--arch/arm/mach-imx/Makefile2
-rw-r--r--arch/arm/mach-imx/cpufreq.c287
-rw-r--r--arch/arm/mach-iop13xx/io.c19
-rw-r--r--arch/arm/mach-iop13xx/iq81340mc.c6
-rw-r--r--arch/arm/mach-iop13xx/iq81340sc.c6
-rw-r--r--arch/arm/mach-iop13xx/irq.c22
-rw-r--r--arch/arm/mach-iop13xx/setup.c2
-rw-r--r--arch/arm/mach-netx/time.c42
-rw-r--r--arch/arm/mach-omap1/Kconfig1
-rw-r--r--arch/arm/mach-omap1/board-osk.c1
-rw-r--r--arch/arm/mach-omap2/board-apollon.c1
-rw-r--r--arch/arm/mach-omap2/gpmc.c21
-rw-r--r--arch/arm/mach-pxa/generic.c4
-rw-r--r--arch/arm/mach-pxa/time.c45
-rw-r--r--arch/arm/mach-pxa/trizeps4.c5
-rw-r--r--arch/arm/mach-s3c2410/Kconfig25
-rw-r--r--arch/arm/mach-s3c2410/cpu.c1
-rw-r--r--arch/arm/mach-s3c2410/devs.c1
-rw-r--r--arch/arm/mach-s3c2410/dma.c6
-rw-r--r--arch/arm/mach-s3c2410/irq.h2
-rw-r--r--arch/arm/mach-s3c2410/mach-anubis.c1
-rw-r--r--arch/arm/mach-s3c2410/mach-bast.c1
-rw-r--r--arch/arm/mach-s3c2410/mach-h1940.c3
-rw-r--r--arch/arm/mach-s3c2410/mach-n30.c3
-rw-r--r--arch/arm/mach-s3c2410/mach-nexcoder.c1
-rw-r--r--arch/arm/mach-s3c2410/mach-osiris.c1
-rw-r--r--arch/arm/mach-s3c2410/mach-otom.c1
-rw-r--r--arch/arm/mach-s3c2410/mach-smdk2410.c1
-rw-r--r--arch/arm/mach-s3c2410/mach-smdk2413.c1
-rw-r--r--arch/arm/mach-s3c2410/mach-smdk2440.c1
-rw-r--r--arch/arm/mach-s3c2410/mach-vr1000.c2
-rw-r--r--arch/arm/mach-s3c2410/mach-vstms.c1
-rw-r--r--arch/arm/mach-s3c2410/pm-simtec.c1
-rw-r--r--arch/arm/mach-s3c2410/pm.c1
-rw-r--r--arch/arm/mach-s3c2410/s3c2410-clock.c5
-rw-r--r--arch/arm/mach-s3c2410/s3c2410-dma.c9
-rw-r--r--arch/arm/mach-s3c2410/s3c2410-pm.c8
-rw-r--r--arch/arm/mach-s3c2410/s3c2410.c3
-rw-r--r--arch/arm/mach-s3c2410/s3c2412-clock.c11
-rw-r--r--arch/arm/mach-s3c2410/s3c2412-dma.c3
-rw-r--r--arch/arm/mach-s3c2410/s3c2412.c2
-rw-r--r--arch/arm/mach-s3c2410/s3c2440-clock.c24
-rw-r--r--arch/arm/mach-s3c2410/s3c2440-dma.c3
-rw-r--r--arch/arm/mach-s3c2410/s3c2440.c9
-rw-r--r--arch/arm/mach-s3c2410/s3c2440.h18
-rw-r--r--arch/arm/mach-s3c2410/s3c2442-clock.c22
-rw-r--r--arch/arm/mach-s3c2410/s3c2442.c20
-rw-r--r--arch/arm/mach-s3c2410/s3c244x.c3
-rw-r--r--arch/arm/mach-s3c2410/usb-simtec.h3
-rw-r--r--arch/arm/mach-sa1100/jornada720.c229
-rw-r--r--arch/arm/mm/consistent.c2
-rw-r--r--arch/arm/mm/copypage-v4mc.c8
-rw-r--r--arch/arm/mm/copypage-v6.c10
-rw-r--r--arch/arm/mm/copypage-xscale.c8
-rw-r--r--arch/arm/mm/fault-armv.c2
-rw-r--r--arch/arm/mm/flush.c2
-rw-r--r--arch/arm/mm/ioremap.c102
-rw-r--r--arch/arm/mm/mmu.c28
-rw-r--r--arch/arm/mm/pgd.c2
-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.S6
-rw-r--r--arch/arm/mm/proc-arm1026.S6
-rw-r--r--arch/arm/mm/proc-arm6_7.S10
-rw-r--r--arch/arm/mm/proc-arm720.S6
-rw-r--r--arch/arm/mm/proc-arm920.S6
-rw-r--r--arch/arm/mm/proc-arm922.S6
-rw-r--r--arch/arm/mm/proc-arm925.S6
-rw-r--r--arch/arm/mm/proc-arm926.S8
-rw-r--r--arch/arm/mm/proc-sa110.S6
-rw-r--r--arch/arm/mm/proc-sa1100.S6
-rw-r--r--arch/arm/mm/proc-syms.c2
-rw-r--r--arch/arm/mm/proc-v6.S39
-rw-r--r--arch/arm/mm/proc-xsc3.S8
-rw-r--r--arch/arm/mm/proc-xscale.S6
-rw-r--r--arch/arm/vfp/vfpmodule.c41
-rw-r--r--arch/arm26/kernel/ecard.c2
-rw-r--r--arch/arm26/kernel/irq.c2
-rw-r--r--arch/cris/arch-v10/drivers/axisflashmap.c2
-rw-r--r--arch/cris/arch-v10/drivers/gpio.c2
-rw-r--r--arch/cris/arch-v32/drivers/axisflashmap.c2
-rw-r--r--arch/cris/arch-v32/drivers/gpio.c2
-rw-r--r--arch/cris/arch-v32/kernel/signal.c2
-rw-r--r--arch/cris/kernel/profile.c2
-rw-r--r--arch/h8300/kernel/ints.c2
-rw-r--r--arch/h8300/platform/h8s/ints.c2
-rw-r--r--arch/i386/boot/compressed/.gitignore1
-rw-r--r--arch/i386/boot/compressed/head.S2
-rw-r--r--arch/i386/defconfig4
-rw-r--r--arch/i386/kernel/acpi/boot.c22
-rw-r--r--arch/i386/kernel/apm.c8
-rw-r--r--arch/i386/kernel/e820.c2
-rw-r--r--arch/i386/kernel/entry.S32
-rw-r--r--arch/i386/kernel/microcode.c8
-rw-r--r--arch/i386/kernel/process.c7
-rw-r--r--arch/i386/kernel/ptrace.c21
-rw-r--r--arch/i386/kernel/setup.c2
-rw-r--r--arch/i386/kernel/smpboot.c2
-rw-r--r--arch/i386/kernel/traps.c83
-rw-r--r--arch/i386/mm/discontig.c28
-rw-r--r--arch/i386/mm/init.c10
-rw-r--r--arch/i386/pci/fixup.c13
-rw-r--r--arch/i386/pci/mmconfig.c6
-rw-r--r--arch/ia64/kernel/cpufreq/acpi-cpufreq.c4
-rw-r--r--arch/ia64/kernel/process.c10
-rw-r--r--arch/ia64/sn/kernel/sn2/sn_hwperf.c2
-rw-r--r--arch/m68k/mm/kmap.c2
-rw-r--r--arch/mips/kernel/apm.c2
-rw-r--r--arch/mips/mm/init.c25
-rw-r--r--arch/parisc/hpux/sys_hpux.c2
-rw-r--r--arch/parisc/kernel/unwind.c2
-rw-r--r--arch/powerpc/boot/Makefile3
-rw-r--r--arch/powerpc/configs/cell_defconfig358
-rw-r--r--arch/powerpc/kernel/nvram_64.c4
-rw-r--r--arch/powerpc/kernel/of_platform.c1
-rw-r--r--arch/powerpc/kernel/pci_32.c2
-rw-r--r--arch/powerpc/kernel/pci_64.c1
-rw-r--r--arch/powerpc/kernel/prom_parse.c15
-rw-r--r--arch/powerpc/kernel/signal_32.c16
-rw-r--r--arch/powerpc/mm/imalloc.c6
-rw-r--r--arch/powerpc/platforms/Makefile2
-rw-r--r--arch/powerpc/platforms/cell/io-workarounds.c2
-rw-r--r--arch/powerpc/platforms/cell/spu_priv1_mmio.c95
-rw-r--r--arch/powerpc/platforms/iseries/Kconfig2
-rw-r--r--arch/powerpc/platforms/pseries/eeh_cache.c2
-rw-r--r--arch/powerpc/sysdev/mpic.c2
-rw-r--r--arch/ppc/8260_io/fcc_enet.c4
-rw-r--r--arch/ppc/8xx_io/cs4218_tdm.c2
-rw-r--r--arch/s390/Kconfig2
-rw-r--r--arch/s390/defconfig47
-rw-r--r--arch/s390/hypfs/hypfs_diag.c4
-rw-r--r--arch/s390/kernel/debug.c8
-rw-r--r--arch/s390/kernel/ipl.c59
-rw-r--r--arch/s390/kernel/reipl.S6
-rw-r--r--arch/s390/kernel/reipl64.S5
-rw-r--r--arch/s390/kernel/reset.S42
-rw-r--r--arch/s390/kernel/s390_ext.c2
-rw-r--r--arch/sparc/defconfig711
-rw-r--r--arch/sparc/kernel/ioport.c5
-rw-r--r--arch/sparc/kernel/irq.c4
-rw-r--r--arch/sparc/kernel/sparc_ksyms.c8
-rw-r--r--arch/sparc/kernel/sun4d_irq.c2
-rw-r--r--arch/sparc/kernel/time.c5
-rw-r--r--arch/sparc/lib/Makefile4
-rw-r--r--arch/sparc/lib/atomic32.c39
-rw-r--r--arch/sparc/lib/bitops.S109
-rw-r--r--arch/sparc64/defconfig36
-rw-r--r--arch/sparc64/kernel/head.S7
-rw-r--r--arch/sparc64/kernel/irq.c24
-rw-r--r--arch/sparc64/kernel/isa.c20
-rw-r--r--arch/sparc64/kernel/of_device.c7
-rw-r--r--arch/sparc64/kernel/smp.c7
-rw-r--r--arch/sparc64/kernel/sys_sunos32.c4
-rw-r--r--arch/sparc64/mm/init.c147
-rw-r--r--arch/um/drivers/net_kern.c15
-rw-r--r--arch/um/include/net_kern.h2
-rw-r--r--arch/um/sys-i386/ldt.c4
-rw-r--r--arch/x86_64/Makefile2
-rw-r--r--arch/x86_64/defconfig4
-rw-r--r--arch/x86_64/kernel/entry.S33
-rw-r--r--arch/x86_64/kernel/pci-calgary.c11
-rw-r--r--arch/x86_64/kernel/process.c6
-rw-r--r--arch/x86_64/kernel/traps.c86
-rw-r--r--arch/x86_64/kernel/vmlinux.lds.S2
-rw-r--r--arch/xtensa/kernel/Makefile2
-rw-r--r--arch/xtensa/kernel/syscall.c2
-rw-r--r--block/as-iosched.c15
-rw-r--r--block/cfq-iosched.c46
-rw-r--r--block/elevator.c26
-rw-r--r--block/ll_rw_blk.c96
-rw-r--r--block/scsi_ioctl.c3
-rw-r--r--crypto/blkcipher.c1
-rw-r--r--drivers/acorn/block/fd1772.c4
-rw-r--r--drivers/acpi/Kconfig17
-rw-r--r--drivers/acpi/ac.c9
-rw-r--r--drivers/acpi/acpi_memhotplug.c5
-rw-r--r--drivers/acpi/asus_acpi.c70
-rw-r--r--drivers/acpi/battery.c31
-rw-r--r--drivers/acpi/button.c223
-rw-r--r--drivers/acpi/container.c5
-rw-r--r--drivers/acpi/dock.c153
-rw-r--r--drivers/acpi/ec.c356
-rw-r--r--drivers/acpi/events/evmisc.c1
-rw-r--r--drivers/acpi/executer/exmutex.c6
-rw-r--r--drivers/acpi/fan.c9
-rw-r--r--drivers/acpi/glue.c10
-rw-r--r--drivers/acpi/hotkey.c5
-rw-r--r--drivers/acpi/i2c_ec.c8
-rw-r--r--drivers/acpi/ibm_acpi.c1053
-rw-r--r--drivers/acpi/namespace/nsxfobj.c44
-rw-r--r--drivers/acpi/numa.c2
-rw-r--r--drivers/acpi/osl.c5
-rw-r--r--drivers/acpi/pci_bind.c16
-rw-r--r--drivers/acpi/pci_irq.c9
-rw-r--r--drivers/acpi/pci_link.c14
-rw-r--r--drivers/acpi/pci_root.c16
-rw-r--r--drivers/acpi/power.c9
-rw-r--r--drivers/acpi/processor_core.c17
-rw-r--r--drivers/acpi/processor_idle.c26
-rw-r--r--drivers/acpi/processor_perflib.c10
-rw-r--r--drivers/acpi/processor_thermal.c6
-rw-r--r--drivers/acpi/processor_throttling.c6
-rw-r--r--drivers/acpi/sbs.c27
-rw-r--r--drivers/acpi/scan.c3
-rw-r--r--drivers/acpi/sleep/wakeup.c6
-rw-r--r--drivers/acpi/tables.c2
-rw-r--r--drivers/acpi/tables/tbxface.c54
-rw-r--r--drivers/acpi/thermal.c37
-rw-r--r--drivers/acpi/toshiba_acpi.c89
-rw-r--r--drivers/acpi/utilities/utdebug.c5
-rw-r--r--drivers/acpi/utilities/utmutex.c16
-rw-r--r--drivers/acpi/utils.c10
-rw-r--r--drivers/acpi/video.c110
-rw-r--r--drivers/ata/Kconfig6
-rw-r--r--drivers/ata/ahci.c10
-rw-r--r--drivers/ata/ata_piix.c22
-rw-r--r--drivers/ata/libata-core.c14
-rw-r--r--drivers/ata/libata-scsi.c242
-rw-r--r--drivers/ata/libata-sff.c42
-rw-r--r--drivers/ata/pata_cs5530.c3
-rw-r--r--drivers/ata/pata_legacy.c4
-rw-r--r--drivers/ata/pata_qdi.c4
-rw-r--r--drivers/ata/pata_rz1000.c2
-rw-r--r--drivers/ata/pata_via.c11
-rw-r--r--drivers/ata/pata_winbond.c4
-rw-r--r--drivers/ata/pdc_adma.c4
-rw-r--r--drivers/ata/sata_nv.c8
-rw-r--r--drivers/ata/sata_svw.c82
-rw-r--r--drivers/ata/sata_vsc.c43
-rw-r--r--drivers/atm/Kconfig4
-rw-r--r--drivers/atm/eni.c4
-rw-r--r--drivers/atm/fore200e.c166
-rw-r--r--drivers/atm/he.c2
-rw-r--r--drivers/atm/lanai.c2
-rw-r--r--drivers/atm/nicstar.c4
-rw-r--r--drivers/atm/zatm.c4
-rw-r--r--drivers/base/class.c2
-rw-r--r--drivers/base/dmapool.c2
-rw-r--r--drivers/base/firmware_class.c1
-rw-r--r--drivers/base/platform.c4
-rw-r--r--drivers/block/Kconfig7
-rw-r--r--drivers/block/Makefile1
-rw-r--r--drivers/block/aoe/aoecmd.c13
-rw-r--r--drivers/block/cciss.c31
-rw-r--r--drivers/block/cpqarray.c10
-rw-r--r--drivers/block/swim_iop.c578
-rw-r--r--drivers/block/viodasd.c6
-rw-r--r--drivers/bluetooth/hci_usb.c1
-rw-r--r--drivers/cdrom/cdrom.c19
-rw-r--r--drivers/cdrom/cm206.c2
-rw-r--r--drivers/cdrom/viocd.c4
-rw-r--r--drivers/char/Kconfig8
-rw-r--r--drivers/char/consolemap.c2
-rw-r--r--drivers/char/drm/drmP.h7
-rw-r--r--drivers/char/drm/drm_lock.c2
-rw-r--r--drivers/char/drm/drm_stub.c12
-rw-r--r--drivers/char/drm/drm_sysfs.c8
-rw-r--r--drivers/char/drm/i915_irq.c199
-rw-r--r--drivers/char/drm/r128_drm.h3
-rw-r--r--drivers/char/drm/r128_drv.h3
-rw-r--r--drivers/char/drm/r128_state.c3
-rw-r--r--drivers/char/drm/r300_cmdbuf.c32
-rw-r--r--drivers/char/drm/radeon_drv.h15
-rw-r--r--drivers/char/drm/radeon_irq.c4
-rw-r--r--drivers/char/drm/radeon_mem.c4
-rw-r--r--drivers/char/drm/radeon_state.c13
-rw-r--r--drivers/char/drm/savage_bci.c4
-rw-r--r--drivers/char/ipmi/ipmi_watchdog.c11
-rw-r--r--drivers/char/isicom.c103
-rw-r--r--drivers/char/lcd.c2
-rw-r--r--drivers/char/lp.c2
-rw-r--r--drivers/char/mxser.c1
-rw-r--r--drivers/char/mxser_new.c9
-rw-r--r--drivers/char/n_r3964.c37
-rw-r--r--drivers/char/n_tty.c1
-rw-r--r--drivers/char/pcmcia/synclink_cs.c2
-rw-r--r--drivers/char/rio/riocmd.c2
-rw-r--r--drivers/char/rtc.c43
-rw-r--r--drivers/char/sx.c8
-rw-r--r--drivers/char/synclink.c2
-rw-r--r--drivers/char/synclinkmp.c4
-rw-r--r--drivers/char/sysrq.c37
-rw-r--r--drivers/char/tlclk.c2
-rw-r--r--drivers/char/tty_io.c8
-rw-r--r--drivers/char/viocons.c17
-rw-r--r--drivers/char/viotape.c5
-rw-r--r--drivers/char/vt.c2
-rw-r--r--drivers/char/vt_ioctl.c10
-rw-r--r--drivers/connector/cn_queue.c5
-rw-r--r--drivers/connector/connector.c17
-rw-r--r--drivers/fc4/fc.c10
-rw-r--r--drivers/hid/hid-input.c44
-rw-r--r--drivers/hwmon/Kconfig56
-rw-r--r--drivers/hwmon/Makefile3
-rw-r--r--drivers/hwmon/ams/Makefile8
-rw-r--r--drivers/hwmon/ams/ams-core.c265
-rw-r--r--drivers/hwmon/ams/ams-i2c.c299
-rw-r--r--drivers/hwmon/ams/ams-input.c160
-rw-r--r--drivers/hwmon/ams/ams-pmu.c207
-rw-r--r--drivers/hwmon/ams/ams.h72
-rw-r--r--drivers/hwmon/f71805f.c569
-rw-r--r--drivers/hwmon/hdaps.c68
-rw-r--r--drivers/hwmon/hwmon-vid.c4
-rw-r--r--drivers/hwmon/it87.c202
-rw-r--r--drivers/hwmon/k8temp.c4
-rw-r--r--drivers/hwmon/pc87360.c2
-rw-r--r--drivers/hwmon/pc87427.c627
-rw-r--r--drivers/hwmon/w83627ehf.c2
-rw-r--r--drivers/hwmon/w83792d.c2
-rw-r--r--drivers/hwmon/w83793.c1609
-rw-r--r--drivers/i2c/busses/i2c-ali1563.c2
-rw-r--r--drivers/i2c/chips/tps65010.c21
-rw-r--r--drivers/ide/ide-floppy.c2
-rw-r--r--drivers/ide/ide-tape.c8
-rw-r--r--drivers/ide/pci/atiixp.c1
-rw-r--r--drivers/ide/pci/hpt366.c886
-rw-r--r--drivers/ide/pci/piix.c66
-rw-r--r--drivers/ide/pci/slc90e66.c20
-rw-r--r--drivers/ieee1394/sbp2.c83
-rw-r--r--drivers/infiniband/hw/mthca/mthca_main.c113
-rw-r--r--drivers/infiniband/hw/mthca/mthca_provider.c3
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.c2
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.h2
-rw-r--r--drivers/input/keyboard/amikbd.c2
-rw-r--r--drivers/input/keyboard/hilkbd.c5
-rw-r--r--drivers/input/keyboard/sunkbd.c2
-rw-r--r--drivers/input/serio/i8042-sparcio.h6
-rw-r--r--drivers/isdn/act2000/act2000_isa.c2
-rw-r--r--drivers/isdn/capi/capidrv.c2
-rw-r--r--drivers/isdn/divert/divert_procfs.c2
-rw-r--r--drivers/isdn/divert/isdn_divert.c6
-rw-r--r--drivers/isdn/gigaset/bas-gigaset.c118
-rw-r--r--drivers/isdn/hysdn/hysdn_procconf.c2
-rw-r--r--drivers/isdn/hysdn/hysdn_proclog.c2
-rw-r--r--drivers/isdn/i4l/isdn_audio.c6
-rw-r--r--drivers/isdn/i4l/isdn_net.c2
-rw-r--r--drivers/isdn/i4l/isdn_ppp.c3
-rw-r--r--drivers/isdn/pcbit/layer2.c2
-rw-r--r--drivers/kvm/Kconfig4
-rw-r--r--drivers/kvm/kvm.h24
-rw-r--r--drivers/kvm/kvm_main.c189
-rw-r--r--drivers/kvm/kvm_svm.h2
-rw-r--r--drivers/kvm/kvm_vmx.h2
-rw-r--r--drivers/kvm/mmu.c39
-rw-r--r--drivers/kvm/paging_tmpl.h24
-rw-r--r--drivers/kvm/svm.c141
-rw-r--r--drivers/kvm/vmx.c136
-rw-r--r--drivers/kvm/vmx.h10
-rw-r--r--drivers/kvm/x86_emulate.c8
-rw-r--r--drivers/kvm/x86_emulate.h2
-rw-r--r--drivers/macintosh/adb.c2
-rw-r--r--drivers/macintosh/apm_emu.c2
-rw-r--r--drivers/macintosh/smu.c2
-rw-r--r--drivers/macintosh/via-pmu-backlight.c2
-rw-r--r--drivers/macintosh/via-pmu68k.c2
-rw-r--r--drivers/md/faulty.c2
-rw-r--r--drivers/md/md.c13
-rw-r--r--drivers/md/raid1.c2
-rw-r--r--drivers/md/raid10.c6
-rw-r--r--drivers/md/raid5.c20
-rw-r--r--drivers/media/common/ir-functions.c1
-rw-r--r--drivers/media/dvb/bt8xx/dst_ca.c2
-rw-r--r--drivers/media/dvb/bt8xx/dvb-bt8xx.c2
-rw-r--r--drivers/media/dvb/dvb-core/dvb_net.c4
-rw-r--r--drivers/media/dvb/dvb-usb/nova-t-usb2.c4
-rw-r--r--drivers/media/dvb/frontends/dib3000mc.c2
-rw-r--r--drivers/media/dvb/ttusb-dec/ttusbdecfe.c4
-rw-r--r--drivers/media/video/Kconfig2
-rw-r--r--drivers/media/video/bt8xx/bttv-driver.c4
-rw-r--r--drivers/media/video/cafe_ccic.c2
-rw-r--r--drivers/media/video/cpia2/cpia2_usb.c4
-rw-r--r--drivers/media/video/cx2341x.c21
-rw-r--r--drivers/media/video/cx25840/cx25840-vbi.c9
-rw-r--r--drivers/media/video/cx88/cx88-cards.c2
-rw-r--r--drivers/media/video/cx88/cx88-core.c35
-rw-r--r--drivers/media/video/cx88/cx88.h2
-rw-r--r--drivers/media/video/dabusb.c4
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c4
-rw-r--r--drivers/media/video/meye.c4
-rw-r--r--drivers/media/video/msp3400-driver.c8
-rw-r--r--drivers/media/video/msp3400-kthreads.c11
-rw-r--r--drivers/media/video/planb.c2
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c8
-rw-r--r--drivers/media/video/tuner-core.c4
-rw-r--r--drivers/media/video/usbvideo/usbvideo.c2
-rw-r--r--drivers/media/video/usbvision/usbvision-cards.c11
-rw-r--r--drivers/media/video/usbvision/usbvision-core.c83
-rw-r--r--drivers/media/video/usbvision/usbvision-i2c.c35
-rw-r--r--drivers/media/video/usbvision/usbvision-video.c150
-rw-r--r--drivers/media/video/usbvision/usbvision.h27
-rw-r--r--drivers/media/video/videocodec.c2
-rw-r--r--drivers/media/video/vivi.c8
-rw-r--r--drivers/media/video/w9966.c2
-rw-r--r--drivers/media/video/w9968cf.c24
-rw-r--r--drivers/media/video/zoran_device.c3
-rw-r--r--drivers/message/i2o/core.h4
-rw-r--r--drivers/message/i2o/driver.c2
-rw-r--r--drivers/message/i2o/exec-osm.c4
-rw-r--r--drivers/message/i2o/i2o_config.c4
-rw-r--r--drivers/misc/msi-laptop.c3
-rw-r--r--drivers/mtd/devices/m25p80.c4
-rw-r--r--drivers/mtd/devices/mtd_dataflash.c4
-rw-r--r--drivers/mtd/rfd_ftl.c2
-rw-r--r--drivers/net/8139cp.c6
-rw-r--r--drivers/net/appletalk/ipddp.c2
-rw-r--r--drivers/net/arm/ep93xx_eth.c4
-rw-r--r--drivers/net/b44.c6
-rw-r--r--drivers/net/bnx2.c23
-rw-r--r--drivers/net/bsd_comp.c2
-rw-r--r--drivers/net/e1000/e1000_ethtool.c3
-rw-r--r--drivers/net/e1000/e1000_hw.c296
-rw-r--r--drivers/net/e1000/e1000_hw.h310
-rw-r--r--drivers/net/e1000/e1000_main.c345
-rw-r--r--drivers/net/e1000/e1000_param.c4
-rw-r--r--drivers/net/forcedeth.c16
-rw-r--r--drivers/net/ibm_emac/ibm_emac_phy.c4
-rw-r--r--drivers/net/irda/donauboe.c2
-rw-r--r--drivers/net/irda/irda-usb.c2
-rw-r--r--drivers/net/irda/irport.c2
-rw-r--r--drivers/net/iseries_veth.c9
-rw-r--r--drivers/net/lp486e.c4
-rw-r--r--drivers/net/myri10ge/myri10ge.c163
-rw-r--r--drivers/net/netxen/netxen_nic.h25
-rw-r--r--drivers/net/netxen/netxen_nic_ethtool.c5
-rw-r--r--drivers/net/netxen/netxen_nic_hw.c296
-rw-r--r--drivers/net/netxen/netxen_nic_init.c251
-rw-r--r--drivers/net/netxen/netxen_nic_ioctl.h77
-rw-r--r--drivers/net/netxen/netxen_nic_isr.c3
-rw-r--r--drivers/net/netxen/netxen_nic_main.c85
-rw-r--r--drivers/net/phy/phy_device.c2
-rw-r--r--drivers/net/ppp_deflate.c4
-rw-r--r--drivers/net/ppp_mppe.c2
-rw-r--r--drivers/net/r8169.c6
-rw-r--r--drivers/net/skge.c7
-rw-r--r--drivers/net/sky2.c35
-rw-r--r--drivers/net/slip.c6
-rw-r--r--drivers/net/smc911x.c23
-rw-r--r--drivers/net/tg3.c42
-rw-r--r--drivers/net/tg3.h1
-rw-r--r--drivers/net/via-velocity.c18
-rw-r--r--drivers/net/wan/hostess_sv11.c2
-rw-r--r--drivers/net/wan/pc300_drv.c2
-rw-r--r--drivers/net/wan/pc300_tty.c2
-rw-r--r--drivers/net/wan/x25_asy.c8
-rw-r--r--drivers/net/wireless/hostap/hostap_ap.c2
-rw-r--r--drivers/net/wireless/hostap/hostap_download.c2
-rw-r--r--drivers/net/wireless/hostap/hostap_hw.c2
-rw-r--r--drivers/net/wireless/hostap/hostap_ioctl.c2
-rw-r--r--drivers/net/wireless/hostap/hostap_main.c2
-rw-r--r--drivers/net/wireless/ipw2100.c2
-rw-r--r--drivers/net/wireless/prism54/isl_ioctl.c2
-rw-r--r--drivers/net/wireless/wavelan_cs.c2
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.c2
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c96
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.h5
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.c4
-rw-r--r--drivers/parisc/iosapic.c2
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c2
-rw-r--r--drivers/pci/hotplug/acpiphp_ibm.c3
-rw-r--r--drivers/pci/hotplug/cpqphp_nvram.c8
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c2
-rw-r--r--drivers/pci/hotplug/rpaphp_slot.c47
-rw-r--r--drivers/pci/hotplug/shpchp.h238
-rw-r--r--drivers/pci/hotplug/shpchp_core.c116
-rw-r--r--drivers/pci/hotplug/shpchp_ctrl.c21
-rw-r--r--drivers/pci/hotplug/shpchp_hpc.c223
-rw-r--r--drivers/pci/htirq.c9
-rw-r--r--drivers/pci/pci-driver.c12
-rw-r--r--drivers/pci/pci.c112
-rw-r--r--drivers/pci/pcie/aer/aerdrv.c2
-rw-r--r--drivers/pci/pcie/portdrv_pci.c2
-rw-r--r--drivers/pci/probe.c10
-rw-r--r--drivers/pci/quirks.c217
-rw-r--r--drivers/pci/search.c38
-rw-r--r--drivers/pci/setup-bus.c2
-rw-r--r--drivers/pci/setup-res.c19
-rw-r--r--drivers/pcmcia/at91_cf.c2
-rw-r--r--drivers/pcmcia/omap_cf.c2
-rw-r--r--drivers/pnp/isapnp/core.c22
-rw-r--r--drivers/pnp/pnpacpi/core.c6
-rw-r--r--drivers/pnp/pnpacpi/rsparser.c22
-rw-r--r--drivers/pnp/pnpbios/core.c16
-rw-r--r--drivers/pnp/pnpbios/proc.c8
-rw-r--r--drivers/pnp/pnpbios/rsparser.c16
-rw-r--r--drivers/rtc/rtc-at91rm9200.c5
-rw-r--r--drivers/rtc/rtc-dev.c2
-rw-r--r--drivers/rtc/rtc-omap.c3
-rw-r--r--drivers/rtc/rtc-proc.c4
-rw-r--r--drivers/rtc/rtc-s3c.c6
-rw-r--r--drivers/rtc/rtc-sa1100.c4
-rw-r--r--drivers/rtc/rtc-sysfs.c2
-rw-r--r--drivers/s390/char/con3215.c2
-rw-r--r--drivers/s390/char/keyboard.c2
-rw-r--r--drivers/s390/char/monwriter.c2
-rw-r--r--drivers/s390/char/sclp_cpi.c4
-rw-r--r--drivers/s390/cio/cio.c36
-rw-r--r--drivers/s390/cio/css.c3
-rw-r--r--drivers/s390/cio/qdio.c13
-rw-r--r--drivers/s390/crypto/ap_bus.c14
-rw-r--r--drivers/s390/crypto/zcrypt_cex2a.c4
-rw-r--r--drivers/s390/crypto/zcrypt_pcica.c4
-rw-r--r--drivers/s390/crypto/zcrypt_pcixcc.c2
-rw-r--r--drivers/s390/net/ctcmain.c6
-rw-r--r--drivers/s390/net/iucv.c2
-rw-r--r--drivers/s390/scsi/zfcp_aux.c2
-rw-r--r--drivers/sbus/char/vfc_dev.c2
-rw-r--r--drivers/scsi/aacraid/aachba.c2
-rw-r--r--drivers/scsi/aacraid/comminit.c2
-rw-r--r--drivers/scsi/aha1542.c2
-rw-r--r--drivers/scsi/aic7xxx_old.c2
-rw-r--r--drivers/scsi/dc395x.c2
-rw-r--r--drivers/scsi/dpt_i2o.c10
-rw-r--r--drivers/scsi/ibmvscsi/Makefile2
-rw-r--r--drivers/scsi/initio.c2
-rw-r--r--drivers/scsi/osst.c2
-rw-r--r--drivers/scsi/pluto.c2
-rw-r--r--drivers/scsi/scsi_lib.c4
-rw-r--r--drivers/scsi/sr_ioctl.c2
-rw-r--r--drivers/scsi/sr_vendor.c4
-rw-r--r--drivers/scsi/sun3_NCR5380.c6
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_hipd.c2
-rw-r--r--drivers/serial/8250_pci.c24
-rw-r--r--drivers/serial/sunsab.c11
-rw-r--r--drivers/serial/sunsu.c10
-rw-r--r--drivers/serial/sunzilog.c14
-rw-r--r--drivers/serial/uartlite.c4
-rw-r--r--drivers/spi/spi_mpc83xx.c2
-rw-r--r--drivers/spi/spi_s3c24xx.c2
-rw-r--r--drivers/spi/spi_s3c24xx_gpio.c3
-rw-r--r--drivers/usb/class/usblp.c54
-rw-r--r--drivers/usb/core/devio.c6
-rw-r--r--drivers/usb/gadget/at91_udc.c238
-rw-r--r--drivers/usb/gadget/at91_udc.h7
-rw-r--r--drivers/usb/gadget/dummy_hcd.c7
-rw-r--r--drivers/usb/gadget/file_storage.c2
-rw-r--r--drivers/usb/gadget/gmidi.c12
-rw-r--r--drivers/usb/gadget/goku_udc.c12
-rw-r--r--drivers/usb/gadget/lh7a40x_udc.c13
-rw-r--r--drivers/usb/gadget/net2280.c11
-rw-r--r--drivers/usb/gadget/omap_udc.c13
-rw-r--r--drivers/usb/gadget/pxa2xx_udc.c7
-rw-r--r--drivers/usb/gadget/serial.c4
-rw-r--r--drivers/usb/host/hc_crisv10.c2
-rw-r--r--drivers/usb/host/ohci-at91.c3
-rw-r--r--drivers/usb/host/ohci-au1xxx.c4
-rw-r--r--drivers/usb/host/ohci-dbg.c8
-rw-r--r--drivers/usb/host/ohci-ep93xx.c2
-rw-r--r--drivers/usb/host/ohci-hcd.c110
-rw-r--r--drivers/usb/host/ohci-hub.c21
-rw-r--r--drivers/usb/host/ohci-lh7a404.c8
-rw-r--r--drivers/usb/host/ohci-mem.c10
-rw-r--r--drivers/usb/host/ohci-omap.c4
-rw-r--r--drivers/usb/host/ohci-pci.c16
-rw-r--r--drivers/usb/host/ohci-pnx4008.c4
-rw-r--r--drivers/usb/host/ohci-pnx8550.c258
-rw-r--r--drivers/usb/host/ohci-ppc-soc.c8
-rw-r--r--drivers/usb/host/ohci-pxa27x.c10
-rw-r--r--drivers/usb/host/ohci-q.c103
-rw-r--r--drivers/usb/host/ohci-s3c2410.c4
-rw-r--r--drivers/usb/host/ohci-sa1111.c8
-rw-r--r--drivers/usb/host/ohci.h92
-rw-r--r--drivers/usb/host/u132-hcd.c92
-rw-r--r--drivers/usb/host/uhci-hcd.c13
-rw-r--r--drivers/usb/host/uhci-hub.c14
-rw-r--r--drivers/usb/input/Kconfig5
-rw-r--r--drivers/usb/input/wacom_sys.c4
-rw-r--r--drivers/usb/input/wacom_wac.c26
-rw-r--r--drivers/usb/misc/appledisplay.c2
-rw-r--r--drivers/usb/misc/auerswald.c10
-rw-r--r--drivers/usb/misc/ftdi-elan.c592
-rw-r--r--drivers/usb/misc/phidgetservo.c1
-rw-r--r--drivers/usb/misc/trancevibrator.c2
-rw-r--r--drivers/usb/misc/uss720.c2
-rw-r--r--drivers/usb/net/gl620a.c154
-rw-r--r--drivers/usb/net/rndis_host.c2
-rw-r--r--drivers/usb/net/rtl8150.c6
-rw-r--r--drivers/usb/serial/airprime.c3
-rw-r--r--drivers/usb/serial/cp2101.c1
-rw-r--r--drivers/usb/serial/cypress_m8.c17
-rw-r--r--drivers/usb/serial/digi_acceleport.c4
-rw-r--r--drivers/usb/serial/ftdi_sio.c1
-rw-r--r--drivers/usb/serial/ftdi_sio.h5
-rw-r--r--drivers/usb/serial/funsoft.c27
-rw-r--r--drivers/usb/serial/io_ti.c2
-rw-r--r--drivers/usb/serial/ipaq.c2
-rw-r--r--drivers/usb/serial/kl5kusb105.c68
-rw-r--r--drivers/usb/serial/kobil_sct.c4
-rw-r--r--drivers/usb/serial/mos7840.c6
-rw-r--r--drivers/usb/serial/option.c3
-rw-r--r--drivers/usb/serial/pl2303.c2
-rw-r--r--drivers/usb/serial/ti_usb_3410_5052.c2
-rw-r--r--drivers/usb/serial/whiteheat.c4
-rw-r--r--drivers/usb/storage/sddr09.c2
-rw-r--r--drivers/usb/storage/unusual_devs.h16
-rw-r--r--drivers/video/amba-clcd.c2
-rw-r--r--drivers/video/amifb.c8
-rw-r--r--drivers/video/aty/aty128fb.c2
-rw-r--r--drivers/video/aty/atyfb_base.c6
-rw-r--r--drivers/video/aty/radeon_backlight.c2
-rw-r--r--drivers/video/backlight/backlight.c7
-rw-r--r--drivers/video/bw2.c18
-rw-r--r--drivers/video/cg14.c28
-rw-r--r--drivers/video/cg3.c22
-rw-r--r--drivers/video/cg6.c33
-rw-r--r--drivers/video/ffb.c25
-rw-r--r--drivers/video/gxt4500.c95
-rw-r--r--drivers/video/leo.c29
-rw-r--r--drivers/video/matrox/i2c-matroxfb.c2
-rw-r--r--drivers/video/matrox/matroxfb_base.c2
-rw-r--r--drivers/video/matrox/matroxfb_crtc2.c2
-rw-r--r--drivers/video/nvidia/nv_backlight.c2
-rw-r--r--drivers/video/p9100.c25
-rw-r--r--drivers/video/pxafb.c40
-rw-r--r--drivers/video/riva/fbdev.c2
-rw-r--r--drivers/video/sa1100fb.c6
-rw-r--r--drivers/video/sstfb.c335
-rw-r--r--drivers/video/tcx.c33
-rw-r--r--drivers/w1/slaves/Kconfig4
-rw-r--r--fs/Kconfig5
-rw-r--r--fs/aio.c9
-rw-r--r--fs/autofs4/inode.c2
-rw-r--r--fs/befs/btree.c2
-rw-r--r--fs/befs/debug.c6
-rw-r--r--fs/bfs/inode.c4
-rw-r--r--fs/binfmt_misc.c2
-rw-r--r--fs/bio.c2
-rw-r--r--fs/block_dev.c202
-rw-r--r--fs/buffer.c18
-rw-r--r--fs/cifs/cifssmb.c2
-rw-r--r--fs/cifs/file.c26
-rw-r--r--fs/debugfs/inode.c39
-rw-r--r--fs/dlm/lowcomms-tcp.c2
-rw-r--r--fs/file.c2
-rw-r--r--fs/fuse/file.c4
-rw-r--r--fs/gfs2/Kconfig4
-rw-r--r--fs/hugetlbfs/inode.c2
-rw-r--r--fs/inode.c43
-rw-r--r--fs/jbd/commit.c8
-rw-r--r--fs/jffs/inode-v23.c4
-rw-r--r--fs/jffs/intrep.c14
-rw-r--r--fs/jfs/jfs_dtree.c4
-rw-r--r--fs/jfs/jfs_imap.c2
-rw-r--r--fs/jfs/jfs_metapage.c15
-rw-r--r--fs/lockd/clntlock.c10
-rw-r--r--fs/lockd/clntproc.c39
-rw-r--r--fs/lockd/svclock.c4
-rw-r--r--fs/lockd/svcshare.c2
-rw-r--r--fs/lockd/xdr.c8
-rw-r--r--fs/lockd/xdr4.c8
-rw-r--r--fs/namespace.c5
-rw-r--r--fs/ncpfs/inode.c34
-rw-r--r--fs/nfs/nfs4proc.c2
-rw-r--r--fs/nfsd/export.c33
-rw-r--r--fs/nfsd/lockd.c2
-rw-r--r--fs/nfsd/nfs4proc.c625
-rw-r--r--fs/nfsd/nfs4state.c91
-rw-r--r--fs/nfsd/nfs4xdr.c14
-rw-r--r--fs/nfsd/nfsfh.c6
-rw-r--r--fs/nfsd/vfs.c2
-rw-r--r--fs/ocfs2/alloc.c2
-rw-r--r--fs/ocfs2/aops.c24
-rw-r--r--fs/ocfs2/cluster/heartbeat.c21
-rw-r--r--fs/ocfs2/cluster/nodemanager.c6
-rw-r--r--fs/ocfs2/cluster/tcp.c10
-rw-r--r--fs/ocfs2/dlm/dlmdomain.c4
-rw-r--r--fs/ocfs2/dlm/dlmlock.c4
-rw-r--r--fs/ocfs2/dlm/dlmmaster.c2
-rw-r--r--fs/ocfs2/dlm/dlmrecovery.c6
-rw-r--r--fs/ocfs2/dlmglue.c10
-rw-r--r--fs/ocfs2/file.c21
-rw-r--r--fs/ocfs2/localalloc.c2
-rw-r--r--fs/ocfs2/slot_map.c2
-rw-r--r--fs/ocfs2/suballoc.c6
-rw-r--r--fs/ocfs2/super.c6
-rw-r--r--fs/ocfs2/vote.c4
-rw-r--r--fs/pipe.c17
-rw-r--r--fs/ramfs/file-mmu.c4
-rw-r--r--fs/ramfs/file-nommu.c4
-rw-r--r--fs/read_write.c2
-rw-r--r--fs/reiserfs/stree.c2
-rw-r--r--fs/reiserfs/xattr_acl.c2
-rw-r--r--fs/smbfs/inode.c5
-rw-r--r--fs/smbfs/proc.c6
-rw-r--r--fs/smbfs/smbiod.c5
-rw-r--r--fs/splice.c8
-rw-r--r--fs/stack.c2
-rw-r--r--fs/sysv/super.c3
-rw-r--r--fs/sysv/sysv.h3
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.c4
-rw-r--r--include/acpi/acpixf.h7
-rw-r--r--include/asm-alpha/cacheflush.h1
-rw-r--r--include/asm-arm/arch-ep93xx/irqs.h6
-rw-r--r--include/asm-arm/arch-imx/imx-regs.h10
-rw-r--r--include/asm-arm/arch-iop13xx/io.h3
-rw-r--r--include/asm-arm/arch-iop13xx/iq81340.h5
-rw-r--r--include/asm-arm/arch-ixp23xx/memory.h16
-rw-r--r--include/asm-arm/arch-pxa/pxa-regs.h3
-rw-r--r--include/asm-arm/arch-s3c2410/anubis-cpld.h2
-rw-r--r--include/asm-arm/arch-s3c2410/anubis-irq.h2
-rw-r--r--include/asm-arm/arch-s3c2410/anubis-map.h2
-rw-r--r--include/asm-arm/arch-s3c2410/audio.h2
-rw-r--r--include/asm-arm/arch-s3c2410/bast-cpld.h4
-rw-r--r--include/asm-arm/arch-s3c2410/bast-irq.h4
-rw-r--r--include/asm-arm/arch-s3c2410/bast-map.h4
-rw-r--r--include/asm-arm/arch-s3c2410/bast-pmu.h2
-rw-r--r--include/asm-arm/arch-s3c2410/dma.h2
-rw-r--r--include/asm-arm/arch-s3c2410/entry-macro.S2
-rw-r--r--include/asm-arm/arch-s3c2410/h1940-latch.h4
-rw-r--r--include/asm-arm/arch-s3c2410/hardware.h8
-rw-r--r--include/asm-arm/arch-s3c2410/iic.h2
-rw-r--r--include/asm-arm/arch-s3c2410/irqs.h3
-rw-r--r--include/asm-arm/arch-s3c2410/leds-gpio.h2
-rw-r--r--include/asm-arm/arch-s3c2410/map.h30
-rw-r--r--include/asm-arm/arch-s3c2410/nand.h4
-rw-r--r--include/asm-arm/arch-s3c2410/osiris-cpld.h2
-rw-r--r--include/asm-arm/arch-s3c2410/regs-serial.h2
-rw-r--r--include/asm-arm/arch-s3c2410/regs-udc.h7
-rw-r--r--include/asm-arm/arch-s3c2410/system.h4
-rw-r--r--include/asm-arm/arch-s3c2410/timex.h4
-rw-r--r--include/asm-arm/arch-s3c2410/uncompress.h5
-rw-r--r--include/asm-arm/arch-s3c2410/usb-control.h4
-rw-r--r--include/asm-arm/arch-s3c2410/vr1000-cpld.h4
-rw-r--r--include/asm-arm/arch-s3c2410/vr1000-irq.h4
-rw-r--r--include/asm-arm/arch-s3c2410/vr1000-map.h4
-rw-r--r--include/asm-arm/cacheflush.h4
-rw-r--r--include/asm-arm/cpu-multi32.h7
-rw-r--r--include/asm-arm/cpu-single.h4
-rw-r--r--include/asm-arm/elf.h1
-rw-r--r--include/asm-arm/flat.h4
-rw-r--r--include/asm-arm/irq.h5
-rw-r--r--include/asm-arm/pgtable.h11
-rw-r--r--include/asm-arm/processor.h16
-rw-r--r--include/asm-arm/system.h52
-rw-r--r--include/asm-arm/thread_info.h2
-rw-r--r--include/asm-arm/unistd.h25
-rw-r--r--include/asm-arm26/cacheflush.h1
-rw-r--r--include/asm-avr32/cacheflush.h1
-rw-r--r--include/asm-avr32/pgalloc.h2
-rw-r--r--include/asm-cris/cacheflush.h1
-rw-r--r--include/asm-frv/cacheflush.h1
-rw-r--r--include/asm-frv/thread_info.h2
-rw-r--r--include/asm-generic/bug.h2
-rw-r--r--include/asm-generic/vmlinux.lds.h25
-rw-r--r--include/asm-h8300/cacheflush.h1
-rw-r--r--include/asm-i386/acpi.h26
-rw-r--r--include/asm-i386/cacheflush.h1
-rw-r--r--include/asm-i386/e820.h2
-rw-r--r--include/asm-i386/thread_info.h2
-rw-r--r--include/asm-i386/unwind.h91
-rw-r--r--include/asm-ia64/cacheflush.h1
-rw-r--r--include/asm-ia64/pci.h3
-rw-r--r--include/asm-ia64/scatterlist.h3
-rw-r--r--include/asm-ia64/thread_info.h2
-rw-r--r--include/asm-m32r/cacheflush.h3
-rw-r--r--include/asm-m68k/cacheflush.h2
-rw-r--r--include/asm-m68k/swim_iop.h221
-rw-r--r--include/asm-m68knommu/cacheflush.h1
-rw-r--r--include/asm-mips/cacheflush.h2
-rw-r--r--include/asm-mips/page.h16
-rw-r--r--include/asm-parisc/cacheflush.h2
-rw-r--r--include/asm-powerpc/cacheflush.h1
-rw-r--r--include/asm-powerpc/spu.h2
-rw-r--r--include/asm-powerpc/thread_info.h2
-rw-r--r--include/asm-s390/cacheflush.h1
-rw-r--r--include/asm-s390/qdio.h1
-rw-r--r--include/asm-s390/reset.h1
-rw-r--r--include/asm-sh/cpu-sh2/cacheflush.h2
-rw-r--r--include/asm-sh/cpu-sh3/cacheflush.h3
-rw-r--r--include/asm-sh/cpu-sh4/cacheflush.h1
-rw-r--r--include/asm-sh/thread_info.h2
-rw-r--r--include/asm-sh64/cacheflush.h2
-rw-r--r--include/asm-sh64/pgalloc.h2
-rw-r--r--include/asm-sparc/bitops.h100
-rw-r--r--include/asm-sparc/cacheflush.h1
-rw-r--r--include/asm-sparc/of_device.h2
-rw-r--r--include/asm-sparc64/cacheflush.h1
-rw-r--r--include/asm-sparc64/hw_irq.h2
-rw-r--r--include/asm-sparc64/of_device.h2
-rw-r--r--include/asm-sparc64/percpu.h10
-rw-r--r--include/asm-v850/cacheflush.h1
-rw-r--r--include/asm-x86_64/acpi.h26
-rw-r--r--include/asm-x86_64/cacheflush.h1
-rw-r--r--include/asm-x86_64/thread_info.h2
-rw-r--r--include/asm-x86_64/unwind.h96
-rw-r--r--include/asm-xtensa/cacheflush.h2
-rw-r--r--include/asm-xtensa/termbits.h11
-rw-r--r--include/asm-xtensa/uaccess.h1
-rw-r--r--include/linux/Kbuild3
-rw-r--r--include/linux/aio.h1
-rw-r--r--include/linux/backlight.h2
-rw-r--r--include/linux/bio.h1
-rw-r--r--include/linux/blkdev.h14
-rw-r--r--include/linux/coda_linux.h2
-rw-r--r--include/linux/connector.h2
-rw-r--r--include/linux/cpuset.h24
-rw-r--r--include/linux/debug_locks.h2
-rw-r--r--include/linux/device.h2
-rw-r--r--include/linux/elevator.h3
-rw-r--r--include/linux/fb.h2
-rw-r--r--include/linux/file.h5
-rw-r--r--include/linux/freezer.h11
-rw-r--r--include/linux/fs.h1
-rw-r--r--include/linux/gameport.h2
-rw-r--r--include/linux/highmem.h7
-rw-r--r--include/linux/i2c-id.h1
-rw-r--r--include/linux/if_fddi.h2
-rw-r--r--include/linux/init_task.h1
-rw-r--r--include/linux/input.h15
-rw-r--r--include/linux/ioport.h3
-rw-r--r--include/linux/kobject.h11
-rw-r--r--include/linux/kvm.h3
-rw-r--r--include/linux/lockd/bind.h2
-rw-r--r--include/linux/lockd/lockd.h2
-rw-r--r--include/linux/lockd/sm_inter.h2
-rw-r--r--include/linux/lockd/xdr.h8
-rw-r--r--include/linux/lockdep.h16
-rw-r--r--include/linux/mount.h1
-rw-r--r--include/linux/n_r3964.h2
-rw-r--r--include/linux/ncp_mount.h2
-rw-r--r--include/linux/net.h2
-rw-r--r--include/linux/netdevice.h1
-rw-r--r--include/linux/netfilter_bridge.h1
-rw-r--r--include/linux/netfilter_ipv4.h2
-rw-r--r--include/linux/netfilter_ipv6.h2
-rw-r--r--include/linux/nfsd/nfsd.h4
-rw-r--r--include/linux/nfsd/state.h1
-rw-r--r--include/linux/nfsd/xdr4.h40
-rw-r--r--include/linux/nsproxy.h1
-rw-r--r--include/linux/page-flags.h8
-rw-r--r--include/linux/pci.h29
-rw-r--r--include/linux/pci_ids.h8
-rw-r--r--include/linux/pci_regs.h19
-rw-r--r--include/linux/pipe_fs_i.h5
-rw-r--r--include/linux/platform_device.h2
-rw-r--r--include/linux/reciprocal_div.h32
-rw-r--r--include/linux/rmap.h2
-rw-r--r--include/linux/sched.h1
-rw-r--r--include/linux/sctp.h10
-rw-r--r--include/linux/slab.h306
-rw-r--r--include/linux/slab_def.h100
-rw-r--r--include/linux/smb_fs_sb.h2
-rw-r--r--include/linux/spi/spi.h2
-rw-r--r--include/linux/sysrq.h22
-rw-r--r--include/linux/unwind.h63
-rw-r--r--include/linux/vmstat.h11
-rw-r--r--include/linux/workqueue.h36
-rw-r--r--include/media/cx2341x.h2
-rw-r--r--include/media/ir-common.h1
-rw-r--r--include/net/ax25.h26
-rw-r--r--include/net/bluetooth/hci.h4
-rw-r--r--include/net/ip6_checksum.h2
-rw-r--r--include/net/ip6_fib.h4
-rw-r--r--include/net/netfilter/nf_conntrack_compat.h10
-rw-r--r--include/net/rose.h6
-rw-r--r--include/net/sctp/sctp.h2
-rw-r--r--include/net/sctp/structs.h18
-rw-r--r--include/net/sctp/ulpevent.h2
-rw-r--r--include/net/sctp/user.h30
-rw-r--r--include/net/tcp.h9
-rw-r--r--include/rdma/ib_verbs.h77
-rw-r--r--include/sound/pcm_oss.h1
-rw-r--r--include/sound/version.h4
-rw-r--r--include/sound/ymfpci.h5
-rw-r--r--include/video/sstfb.h13
-rw-r--r--init/Kconfig10
-rw-r--r--init/Makefile9
-rw-r--r--init/main.c2
-rw-r--r--ipc/msgutil.c4
-rw-r--r--kernel/Makefile1
-rw-r--r--kernel/auditfilter.c4
-rw-r--r--kernel/cpu.c4
-rw-r--r--kernel/cpuset.c84
-rw-r--r--kernel/exit.c31
-rw-r--r--kernel/fork.c2
-rw-r--r--kernel/irq/chip.c5
-rw-r--r--kernel/lockdep.c207
-rw-r--r--kernel/module.c29
-rw-r--r--kernel/nsproxy.c4
-rw-r--r--kernel/power/Kconfig9
-rw-r--r--kernel/power/disk.c8
-rw-r--r--kernel/power/main.c2
-rw-r--r--kernel/power/process.c21
-rw-r--r--kernel/printk.c2
-rw-r--r--kernel/rcutorture.c3
-rw-r--r--kernel/relay.c21
-rw-r--r--kernel/sched.c25
-rw-r--r--kernel/signal.c4
-rw-r--r--kernel/sysctl.c3
-rw-r--r--kernel/timer.c21
-rw-r--r--kernel/unwind.c1305
-rw-r--r--kernel/workqueue.c28
-rw-r--r--lib/Kconfig5
-rw-r--r--lib/Kconfig.debug18
-rw-r--r--lib/Makefile5
-rw-r--r--lib/fault-inject.c32
-rw-r--r--lib/ioremap.c1
-rw-r--r--lib/kobject_uevent.c44
-rw-r--r--lib/kref.c7
-rw-r--r--lib/reciprocal_div.c9
-rw-r--r--mm/filemap_xip.c2
-rw-r--r--mm/fremap.c2
-rw-r--r--mm/hugetlb.c8
-rw-r--r--mm/memory.c14
-rw-r--r--mm/mincore.c183
-rw-r--r--mm/oom_kill.c9
-rw-r--r--mm/page-writeback.c77
-rw-r--r--mm/page_alloc.c2
-rw-r--r--mm/rmap.c36
-rw-r--r--mm/shmem.c7
-rw-r--r--mm/slab.c29
-rw-r--r--mm/slob.c27
-rw-r--r--mm/truncate.c31
-rw-r--r--mm/vmscan.c14
-rw-r--r--net/ax25/af_ax25.c4
-rw-r--r--net/ax25/ax25_iface.c103
-rw-r--r--net/ax25/ax25_route.c2
-rw-r--r--net/bluetooth/hci_sock.c4
-rw-r--r--net/bridge/br_netfilter.c188
-rw-r--r--net/dccp/ccids/ccid3.c6
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_assoc.c4
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_wx.c2
-rw-r--r--net/ipv4/netfilter/Kconfig2
-rw-r--r--net/ipv4/netfilter/arp_tables.c5
-rw-r--r--net/ipv4/netfilter/ip_tables.c181
-rw-r--r--net/ipv4/netfilter/ipt_CLUSTERIP.c8
-rw-r--r--net/ipv4/route.c3
-rw-r--r--net/ipv4/tcp.c5
-rw-r--r--net/ipv4/tcp_ipv4.c3
-rw-r--r--net/ipv4/udp.c13
-rw-r--r--net/ipv6/ipv6_sockglue.c23
-rw-r--r--net/ipv6/netfilter/Kconfig5
-rw-r--r--net/ipv6/netfilter/ip6_tables.c5
-rw-r--r--net/ipv6/route.c2
-rw-r--r--net/netfilter/Kconfig2
-rw-r--r--net/netfilter/xt_CONNMARK.c14
-rw-r--r--net/netfilter/xt_CONNSECMARK.c14
-rw-r--r--net/netfilter/xt_connbytes.c14
-rw-r--r--net/netfilter/xt_connmark.c7
-rw-r--r--net/netfilter/xt_conntrack.c8
-rw-r--r--net/netfilter/xt_helper.c8
-rw-r--r--net/netfilter/xt_physdev.c12
-rw-r--r--net/netfilter/xt_state.c7
-rw-r--r--net/netlabel/netlabel_cipso_v4.c37
-rw-r--r--net/netrom/af_netrom.c15
-rw-r--r--net/netrom/nr_dev.c24
-rw-r--r--net/netrom/nr_route.c19
-rw-r--r--net/rose/af_rose.c18
-rw-r--r--net/rose/rose_dev.c22
-rw-r--r--net/rose/rose_loopback.c5
-rw-r--r--net/rose/rose_route.c47
-rw-r--r--net/sctp/associola.c1
-rw-r--r--net/sctp/ipv6.c38
-rw-r--r--net/sctp/protocol.c74
-rw-r--r--net/sctp/sm_make_chunk.c24
-rw-r--r--net/sctp/sm_statefuns.c32
-rw-r--r--net/sctp/socket.c152
-rw-r--r--net/sctp/ulpevent.c24
-rw-r--r--net/sunrpc/auth_gss/gss_spkm3_mech.c2
-rw-r--r--net/sunrpc/auth_gss/svcauth_gss.c11
-rw-r--r--net/sunrpc/cache.c31
-rw-r--r--net/sunrpc/svc.c2
-rw-r--r--net/sunrpc/svcauth_unix.c5
-rw-r--r--net/tipc/config.c2
-rw-r--r--net/xfrm/xfrm_algo.c3
-rw-r--r--scripts/kconfig/conf.c2
-rw-r--r--scripts/kconfig/confdata.c37
-rw-r--r--scripts/kconfig/gconf.c35
-rw-r--r--scripts/kconfig/gconf.glade4
-rw-r--r--scripts/kconfig/lkc.h2
-rw-r--r--scripts/kconfig/lkc_proto.h3
-rw-r--r--scripts/kconfig/mconf.c21
-rw-r--r--scripts/kconfig/qconf.cc15
-rw-r--r--scripts/kconfig/qconf.h3
-rw-r--r--scripts/kconfig/symbol.c3
-rw-r--r--scripts/kconfig/zconf.tab.c_shipped2
-rw-r--r--scripts/kconfig/zconf.y2
-rwxr-xr-xscripts/kernel-doc17
-rw-r--r--scripts/mod/modpost.c1
-rw-r--r--security/selinux/ss/services.c6
-rw-r--r--sound/aoa/codecs/snd-aoa-codec-onyx.h1
-rw-r--r--sound/aoa/codecs/snd-aoa-codec-tas.c1
-rw-r--r--sound/core/control.c2
-rw-r--r--sound/core/oss/mixer_oss.c2
-rw-r--r--sound/core/oss/pcm_oss.c52
-rw-r--r--sound/core/pcm.c4
-rw-r--r--sound/core/pcm_lib.c8
-rw-r--r--sound/core/rawmidi.c4
-rw-r--r--sound/core/seq/seq_memory.c2
-rw-r--r--sound/core/sgbuf.c2
-rw-r--r--sound/isa/gus/gus_mem.c7
-rw-r--r--sound/isa/sb/sb_common.c2
-rw-r--r--sound/isa/wavefront/wavefront_synth.c2
-rw-r--r--sound/oss/ad1848.c2
-rw-r--r--sound/oss/cs4232.c2
-rw-r--r--sound/oss/dmasound/tas3001c.c14
-rw-r--r--sound/oss/dmasound/tas3004.c15
-rw-r--r--sound/oss/emu10k1/audio.c6
-rw-r--r--sound/oss/emu10k1/cardmi.c2
-rw-r--r--sound/oss/emu10k1/cardmo.c2
-rw-r--r--sound/oss/emu10k1/midi.c10
-rw-r--r--sound/oss/emu10k1/mixer.c2
-rw-r--r--sound/oss/hal2.c2
-rw-r--r--sound/oss/mpu401.c2
-rw-r--r--sound/oss/opl3.c2
-rw-r--r--sound/oss/sb_common.c2
-rw-r--r--sound/oss/sb_midi.c4
-rw-r--r--sound/oss/sb_mixer.c2
-rw-r--r--sound/oss/v_midi.c2
-rw-r--r--sound/oss/waveartist.c2
-rw-r--r--sound/pci/ac97/ac97_codec.c10
-rw-r--r--sound/pci/ac97/ac97_patch.c7
-rw-r--r--sound/pci/ad1889.c4
-rw-r--r--sound/pci/ali5451/ali5451.c5
-rw-r--r--sound/pci/als300.c6
-rw-r--r--sound/pci/atiixp.c2
-rw-r--r--sound/pci/atiixp_modem.c2
-rw-r--r--sound/pci/au88x0/au88x0.c2
-rw-r--r--sound/pci/azt3328.c5
-rw-r--r--sound/pci/bt87x.c4
-rw-r--r--sound/pci/ca0106/ca0106.h2
-rw-r--r--sound/pci/ca0106/ca0106_main.c37
-rw-r--r--sound/pci/cmipci.c2
-rw-r--r--sound/pci/cs4281.c2
-rw-r--r--sound/pci/cs46xx/cs46xx_lib.c2
-rw-r--r--sound/pci/cs5535audio/cs5535audio.c2
-rw-r--r--sound/pci/echoaudio/echoaudio.c6
-rw-r--r--sound/pci/emu10k1/emu10k1_main.c5
-rw-r--r--sound/pci/emu10k1/emu10k1x.c9
-rw-r--r--sound/pci/ens1370.c2
-rw-r--r--sound/pci/es1938.c4
-rw-r--r--sound/pci/es1968.c8
-rw-r--r--sound/pci/fm801.c2
-rw-r--r--sound/pci/hda/hda_codec.c3
-rw-r--r--sound/pci/hda/hda_intel.c3
-rw-r--r--sound/pci/hda/hda_proc.c53
-rw-r--r--sound/pci/hda/patch_analog.c8
-rw-r--r--sound/pci/hda/patch_realtek.c6
-rw-r--r--sound/pci/hda/patch_si3054.c3
-rw-r--r--sound/pci/ice1712/ice1712.c2
-rw-r--r--sound/pci/ice1712/ice1724.c2
-rw-r--r--sound/pci/intel8x0.c4
-rw-r--r--sound/pci/intel8x0m.c4
-rw-r--r--sound/pci/korg1212/korg1212.c2
-rw-r--r--sound/pci/maestro3.c4
-rw-r--r--sound/pci/mixart/mixart.c5
-rw-r--r--sound/pci/nm256/nm256.c2
-rw-r--r--sound/pci/pcxhr/pcxhr.c2
-rw-r--r--sound/pci/riptide/riptide.c5
-rw-r--r--sound/pci/rme32.c3
-rw-r--r--sound/pci/rme96.c3
-rw-r--r--sound/pci/rme9652/hdsp.c9
-rw-r--r--sound/pci/rme9652/hdspm.c3
-rw-r--r--sound/pci/rme9652/rme9652.c7
-rw-r--r--sound/pci/sonicvibes.c5
-rw-r--r--sound/pci/trident/trident_main.c6
-rw-r--r--sound/pci/via82xx.c6
-rw-r--r--sound/pci/via82xx_modem.c2
-rw-r--r--sound/pci/vx222/vx222.c4
-rw-r--r--sound/pci/ymfpci/ymfpci.c5
-rw-r--r--sound/pci/ymfpci/ymfpci_main.c39
-rw-r--r--sound/usb/usbaudio.c3
1105 files changed, 18458 insertions, 12970 deletions
diff --git a/.gitignore b/.gitignore
index 9eb4b7711499..060a71d41ad7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -42,3 +42,6 @@ patches-*
# quilt's files
patches
series
+
+# cscope files
+cscope.*
diff --git a/CREDITS b/CREDITS
index 8218e790f43d..75c5ce82720c 100644
--- a/CREDITS
+++ b/CREDITS
@@ -516,9 +516,10 @@ S: Orlando, Florida
S: USA
N: Lennert Buytenhek
-E: buytenh@gnu.org
-D: Rewrite of the ethernet bridging code
-S: Ravenhorst 58B
+E: kernel@wantstofly.org
+D: Original (2.4) rewrite of the ethernet bridging code
+D: Various ARM bits and pieces
+S: Ravenhorst 58
S: 2317 AK Leiden
S: The Netherlands
diff --git a/Documentation/CodingStyle b/Documentation/CodingStyle
index 0ad6dcb5d45f..9069189e78ef 100644
--- a/Documentation/CodingStyle
+++ b/Documentation/CodingStyle
@@ -682,6 +682,24 @@ result. Typical examples would be functions that return pointers; they use
NULL or the ERR_PTR mechanism to report failure.
+ Chapter 17: Don't re-invent the kernel macros
+
+The header file include/linux/kernel.h contains a number of macros that
+you should use, rather than explicitly coding some variant of them yourself.
+For example, if you need to calculate the length of an array, take advantage
+of the macro
+
+ #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+Similarly, if you need to calculate the size of some structure member, use
+
+ #define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))
+
+There are also min() and max() macros that do strict type checking if you
+need them. Feel free to peruse that header file to see what else is already
+defined that you shouldn't reproduce in your code.
+
+
Appendix I: References
diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile
index 36526a1e76d7..867608ab3ca0 100644
--- a/Documentation/DocBook/Makefile
+++ b/Documentation/DocBook/Makefile
@@ -53,8 +53,8 @@ installmandocs: mandocs
###
#External programs used
-KERNELDOC = scripts/kernel-doc
-DOCPROC = scripts/basic/docproc
+KERNELDOC = $(srctree)/scripts/kernel-doc
+DOCPROC = $(objtree)/scripts/basic/docproc
XMLTOFLAGS = -m $(srctree)/Documentation/DocBook/stylesheet.xsl
#XMLTOFLAGS += --skip-validation
diff --git a/Documentation/DocBook/genericirq.tmpl b/Documentation/DocBook/genericirq.tmpl
index 0f4a4b6321e4..4215f69ce7e6 100644
--- a/Documentation/DocBook/genericirq.tmpl
+++ b/Documentation/DocBook/genericirq.tmpl
@@ -303,10 +303,10 @@ desc->status |= running;
do {
if (desc->status & masked)
desc->chip->enable();
- desc-status &= ~pending;
+ desc->status &= ~pending;
handle_IRQ_event(desc->action);
} while (status & pending);
-desc-status &= ~running;
+desc->status &= ~running;
desc->chip->end();
</programlisting>
</para>
diff --git a/Documentation/arm/Samsung-S3C24XX/Overview.txt b/Documentation/arm/Samsung-S3C24XX/Overview.txt
index dda7ecdde87b..28d014714ab8 100644
--- a/Documentation/arm/Samsung-S3C24XX/Overview.txt
+++ b/Documentation/arm/Samsung-S3C24XX/Overview.txt
@@ -76,6 +76,15 @@ Machines
A S3C2410 based PDA from Acer. There is a Wiki page at
http://handhelds.org/moin/moin.cgi/AcerN30Documentation .
+ AML M5900
+
+ American Microsystems' M5900
+
+ Nex Vision Nexcoder
+ Nex Vision Otom
+
+ Two machines by Nex Vision
+
Adding New Machines
-------------------
@@ -115,6 +124,10 @@ RTC
Support for the onboard RTC unit, including alarm function.
+ This has recently been upgraded to use the new RTC core,
+ and the module has been renamed to rtc-s3c to fit in with
+ the new rtc naming scheme.
+
Watchdog
--------
@@ -128,7 +141,7 @@ NAND
The current kernels now have support for the s3c2410 NAND
controller. If there are any problems the latest linux-mtd
- CVS can be found from http://www.linux-mtd.infradead.org/
+ code can be found from http://www.linux-mtd.infradead.org/
Serial
@@ -168,6 +181,21 @@ Suspend to RAM
See Suspend.txt for more information.
+SPI
+---
+
+ SPI drivers are available for both the in-built hardware
+ (although there is no DMA support yet) and a generic
+ GPIO based solution.
+
+
+LEDs
+----
+
+ There is support for GPIO based LEDs via a platform driver
+ in the LED subsystem.
+
+
Platform Data
-------------
diff --git a/Documentation/block/biodoc.txt b/Documentation/block/biodoc.txt
index c6c9a9c10d7f..3adaace328a6 100644
--- a/Documentation/block/biodoc.txt
+++ b/Documentation/block/biodoc.txt
@@ -946,6 +946,13 @@ elevator_merged_fn called when a request in the scheduler has been
scheduler for example, to reposition the request
if its sorting order has changed.
+elevator_allow_merge_fn called whenever the block layer determines
+ that a bio can be merged into an existing
+ request safely. The io scheduler may still
+ want to stop a merge at this point if it
+ results in some sort of conflict internally,
+ this hook allows it to do that.
+
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
diff --git a/Documentation/cachetlb.txt b/Documentation/cachetlb.txt
index 53245c429f7d..73e794f0ff09 100644
--- a/Documentation/cachetlb.txt
+++ b/Documentation/cachetlb.txt
@@ -179,10 +179,21 @@ Here are the routines, one by one:
lines associated with 'mm'.
This interface is used to handle whole address space
- page table operations such as what happens during
- fork, exit, and exec.
+ page table operations such as what happens during exit and exec.
+
+2) void flush_cache_dup_mm(struct mm_struct *mm)
+
+ This interface flushes an entire user address space from
+ the caches. That is, after running, there will be no cache
+ lines associated with 'mm'.
+
+ This interface is used to handle whole address space
+ page table operations such as what happens during fork.
+
+ This option is separate from flush_cache_mm to allow some
+ optimizations for VIPT caches.
-2) void flush_cache_range(struct vm_area_struct *vma,
+3) void flush_cache_range(struct vm_area_struct *vma,
unsigned long start, unsigned long end)
Here we are flushing a specific range of (user) virtual
@@ -199,7 +210,7 @@ Here are the routines, one by one:
call flush_cache_page (see below) for each entry which may be
modified.
-3) void flush_cache_page(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn)
+4) void flush_cache_page(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn)
This time we need to remove a PAGE_SIZE sized range
from the cache. The 'vma' is the backing structure used by
@@ -220,7 +231,7 @@ Here are the routines, one by one:
This is used primarily during fault processing.
-4) void flush_cache_kmaps(void)
+5) void flush_cache_kmaps(void)
This routine need only be implemented if the platform utilizes
highmem. It will be called right before all of the kmaps
@@ -232,7 +243,7 @@ Here are the routines, one by one:
This routing should be implemented in asm/highmem.h
-5) void flush_cache_vmap(unsigned long start, unsigned long end)
+6) void flush_cache_vmap(unsigned long start, unsigned long end)
void flush_cache_vunmap(unsigned long start, unsigned long end)
Here in these two interfaces we are flushing a specific range
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 64ce44da5936..30f3c8c9c12a 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -151,15 +151,6 @@ Who: Thomas Gleixner <tglx@linutronix.de>
---------------------------
-What: I2C interface of the it87 driver
-When: January 2007
-Why: The ISA interface is faster and should be always available. The I2C
- probing is also known to cause trouble in at least one case (see
- bug #5889.)
-Who: Jean Delvare <khali@linux-fr.org>
-
----------------------------
-
What: Unused EXPORT_SYMBOL/EXPORT_SYMBOL_GPL exports
(temporary transition config option provided until then)
The transition config option will also be removed at the same time.
@@ -216,22 +207,6 @@ Who: Thomas Gleixner <tglx@linutronix.de>
---------------------------
-What: Bridge netfilter deferred IPv4/IPv6 output hook calling
-When: January 2007
-Why: The deferred output hooks are a layering violation causing unusual
- and broken behaviour on bridge devices. Examples of things they
- break include QoS classifation using the MARK or CLASSIFY targets,
- the IPsec policy match and connection tracking with VLANs on a
- bridge. Their only use is to enable bridge output port filtering
- within iptables with the physdev match, which can also be done by
- combining iptables and ebtables using netfilter marks. Until it
- will get removed the hook deferral is disabled by default and is
- only enabled when needed.
-
-Who: Patrick McHardy <kaber@trash.net>
-
----------------------------
-
What: PHYSDEVPATH, PHYSDEVBUS, PHYSDEVDRIVER in the uevent environment
When: October 2008
Why: The stacking of class devices makes these values misleading and
diff --git a/Documentation/filesystems/bfs.txt b/Documentation/filesystems/bfs.txt
index d2841e0bcf02..ea825e178e79 100644
--- a/Documentation/filesystems/bfs.txt
+++ b/Documentation/filesystems/bfs.txt
@@ -54,4 +54,4 @@ The first 4 bytes should be 0x1badface.
If you have any patches, questions or suggestions regarding this BFS
implementation please contact the author:
-Tigran A. Aivazian <tigran@veritas.com>
+Tigran Aivazian <tigran@aivazian.fsnet.co.uk>
diff --git a/Documentation/filesystems/fuse.txt b/Documentation/filesystems/fuse.txt
index 345392c4caeb..397a41adb4c3 100644
--- a/Documentation/filesystems/fuse.txt
+++ b/Documentation/filesystems/fuse.txt
@@ -94,8 +94,8 @@ Mount options
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.
+ access based on file mode. It is usually useful together with the
+ 'allow_other' mount option.
'allow_other'
diff --git a/Documentation/hwmon/f71805f b/Documentation/hwmon/f71805f
index 2ca69df669c3..bfd0f154959c 100644
--- a/Documentation/hwmon/f71805f
+++ b/Documentation/hwmon/f71805f
@@ -6,6 +6,10 @@ Supported chips:
Prefix: 'f71805f'
Addresses scanned: none, address read from Super I/O config space
Datasheet: Provided by Fintek on request
+ * Fintek F71872F/FG
+ Prefix: 'f71872f'
+ Addresses scanned: none, address read from Super I/O config space
+ Datasheet: Provided by Fintek on request
Author: Jean Delvare <khali@linux-fr.org>
@@ -13,8 +17,8 @@ Thanks to Denis Kieft from Barracuda Networks for the donation of a
test system (custom Jetway K8M8MS motherboard, with CPU and RAM) and
for providing initial documentation.
-Thanks to Kris Chen from Fintek for answering technical questions and
-providing additional documentation.
+Thanks to Kris Chen and Aaron Huang from Fintek for answering technical
+questions and providing additional documentation.
Thanks to Chris Lin from Jetway for providing wiring schematics and
answering technical questions.
@@ -28,8 +32,11 @@ capabilities. It can monitor up to 9 voltages (counting its own power
source), 3 fans and 3 temperature sensors.
This chip also has fan controlling features, using either DC or PWM, in
-three different modes (one manual, two automatic). The driver doesn't
-support these features yet.
+three different modes (one manual, two automatic).
+
+The Fintek F71872F/FG Super I/O chip is almost the same, with two
+additional internal voltages monitored (VSB and battery). It also features
+6 VID inputs. The VID inputs are not yet supported by this driver.
The driver assumes that no more than one chip is present, which seems
reasonable.
@@ -42,7 +49,8 @@ Voltages are sampled by an 8-bit ADC with a LSB of 8 mV. The supported
range is thus from 0 to 2.040 V. Voltage values outside of this range
need external resistors. An exception is in0, which is used to monitor
the chip's own power source (+3.3V), and is divided internally by a
-factor 2.
+factor 2. For the F71872F/FG, in9 (VSB) and in10 (battery) are also
+divided internally by a factor 2.
The two LSB of the voltage limit registers are not used (always 0), so
you can only set the limits in steps of 32 mV (before scaling).
@@ -61,9 +69,12 @@ in5 VIN5 +12V 200K 20K 11.00 1.05 V
in6 VIN6 VCC1.5V 10K - 1.00 1.50 V
in7 VIN7 VCORE 10K - 1.00 ~1.40 V (1)
in8 VIN8 VSB5V 200K 47K 1.00 0.95 V
+in10 VSB VSB3.3V int. int. 2.00 1.65 V (3)
+in9 VBAT VBATTERY int. int. 2.00 1.50 V (3)
(1) Depends on your hardware setup.
(2) Obviously not correct, swapping R1 and R2 would make more sense.
+(3) F71872F/FG only.
These values can be used as hints at best, as motherboard manufacturers
are free to use a completely different setup. As a matter of fact, the
@@ -103,3 +114,38 @@ sensor. Each channel can be used for connecting either a thermal diode
or a thermistor. The driver reports the currently selected mode, but
doesn't allow changing it. In theory, the BIOS should have configured
everything properly.
+
+
+Fan Control
+-----------
+
+Both PWM (pulse-width modulation) and DC fan speed control methods are
+supported. The right one to use depends on external circuitry on the
+motherboard, so the driver assumes that the BIOS set the method
+properly. The driver will report the method, but won't let you change
+it.
+
+When the PWM method is used, you can select the operating frequency,
+from 187.5 kHz (default) to 31 Hz. The best frequency depends on the
+fan model. As a rule of thumb, lower frequencies seem to give better
+control, but may generate annoying high-pitch noise. Fintek recommends
+not going below 1 kHz, as the fan tachometers get confused by lower
+frequencies as well.
+
+When the DC method is used, Fintek recommends not going below 5 V, which
+corresponds to a pwm value of 106 for the driver. The driver doesn't
+enforce this limit though.
+
+Three different fan control modes are supported:
+
+* Manual mode
+ You ask for a specific PWM duty cycle or DC voltage.
+
+* Fan speed mode
+ You ask for a specific fan speed. This mode assumes that pwm1
+ corresponds to fan1, pwm2 to fan2 and pwm3 to fan3.
+
+* Temperature mode
+ You define 3 temperature/fan speed trip points, and the fan speed is
+ adjusted depending on the measured temperature, using interpolation.
+ This mode is not yet supported by the driver.
diff --git a/Documentation/hwmon/it87 b/Documentation/hwmon/it87
index e783fd62e308..74a80992d237 100644
--- a/Documentation/hwmon/it87
+++ b/Documentation/hwmon/it87
@@ -9,8 +9,7 @@ Supported chips:
http://www.ite.com.tw/
* IT8712F
Prefix: 'it8712'
- Addresses scanned: I2C 0x2d
- from Super I/O config space (8 I/O ports)
+ Addresses scanned: from Super I/O config space (8 I/O ports)
Datasheet: Publicly available at the ITE website
http://www.ite.com.tw/
* IT8716F
@@ -53,6 +52,18 @@ Module Parameters
misconfigured by BIOS - PWM values would be inverted. This option tries
to fix this. Please contact your BIOS manufacturer and ask him for fix.
+
+Hardware Interfaces
+-------------------
+
+All the chips suported by this driver are LPC Super-I/O chips, accessed
+through the LPC bus (ISA-like I/O ports). The IT8712F additionally has an
+SMBus interface to the hardware monitoring functions. This driver no
+longer supports this interface though, as it is slower and less reliable
+than the ISA access, and was only available on a small number of
+motherboard models.
+
+
Description
-----------
diff --git a/Documentation/hwmon/k8temp b/Documentation/hwmon/k8temp
index 30d123b8d920..0005c7166146 100644
--- a/Documentation/hwmon/k8temp
+++ b/Documentation/hwmon/k8temp
@@ -8,7 +8,7 @@ Supported chips:
Datasheet: http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/32559.pdf
Author: Rudolf Marek
-Contact: Rudolf Marek <r.marek@sh.cvut.cz>
+Contact: Rudolf Marek <r.marek@assembler.cz>
Description
-----------
diff --git a/Documentation/hwmon/pc87427 b/Documentation/hwmon/pc87427
new file mode 100644
index 000000000000..9a0708f9f49e
--- /dev/null
+++ b/Documentation/hwmon/pc87427
@@ -0,0 +1,38 @@
+Kernel driver pc87427
+=====================
+
+Supported chips:
+ * National Semiconductor PC87427
+ Prefix: 'pc87427'
+ Addresses scanned: none, address read from Super I/O config space
+ Datasheet: http://www.winbond.com.tw/E-WINBONDHTM/partner/apc_007.html
+
+Author: Jean Delvare <khali@linux-fr.org>
+
+Thanks to Amir Habibi at Candelis for setting up a test system, and to
+Michael Kress for testing several iterations of this driver.
+
+
+Description
+-----------
+
+The National Semiconductor Super I/O chip includes complete hardware
+monitoring capabilities. It can monitor up to 18 voltages, 8 fans and
+6 temperature sensors. Only the fans are supported at the moment.
+
+This chip also has fan controlling features, which are not yet supported
+by this driver either.
+
+The driver assumes that no more than one chip is present, which seems
+reasonable.
+
+
+Fan Monitoring
+--------------
+
+Fan rotation speeds are reported as 14-bit values from a gated clock
+signal. Speeds down to 83 RPM can be measured.
+
+An alarm is triggered if the rotation speed drops below a programmable
+limit. Another alarm is triggered if the speed is too low to to be measured
+(including stalled or missing fan).
diff --git a/Documentation/hwmon/sysfs-interface b/Documentation/hwmon/sysfs-interface
index d1d390aaf620..efef3b962cd3 100644
--- a/Documentation/hwmon/sysfs-interface
+++ b/Documentation/hwmon/sysfs-interface
@@ -208,12 +208,14 @@ temp[1-*]_auto_point[1-*]_temp_hyst
****************
temp[1-*]_type Sensor type selection.
- Integers 1 to 4 or thermistor Beta value (typically 3435)
+ Integers 1 to 6 or thermistor Beta value (typically 3435)
RW
1: PII/Celeron Diode
2: 3904 transistor
3: thermal diode
4: thermistor (default/unknown Beta)
+ 5: AMD AMDSI
+ 6: Intel PECI
Not all types are supported by all chips
temp[1-*]_max Temperature max value.
diff --git a/Documentation/hwmon/w83627ehf b/Documentation/hwmon/w83627ehf
index caa610a297e8..8a15a7408753 100644
--- a/Documentation/hwmon/w83627ehf
+++ b/Documentation/hwmon/w83627ehf
@@ -10,7 +10,7 @@ Supported chips:
Authors:
Jean Delvare <khali@linux-fr.org>
Yuan Mu (Winbond)
- Rudolf Marek <r.marek@sh.cvut.cz>
+ Rudolf Marek <r.marek@assembler.cz>
Description
-----------
diff --git a/Documentation/hwmon/w83791d b/Documentation/hwmon/w83791d
index 19b2ed739fa1..db9881df88a5 100644
--- a/Documentation/hwmon/w83791d
+++ b/Documentation/hwmon/w83791d
@@ -18,7 +18,7 @@ Credits:
and Mark Studebaker <mdsxyz123@yahoo.com>
w83792d.c:
Chunhao Huang <DZShen@Winbond.com.tw>,
- Rudolf Marek <r.marek@sh.cvut.cz>
+ Rudolf Marek <r.marek@assembler.cz>
Additional contributors:
Sven Anders <anders@anduras.de>
diff --git a/Documentation/hwmon/w83793 b/Documentation/hwmon/w83793
new file mode 100644
index 000000000000..45e5408340e0
--- /dev/null
+++ b/Documentation/hwmon/w83793
@@ -0,0 +1,110 @@
+Kernel driver w83793
+====================
+
+Supported chips:
+ * Winbond W83793G/W83793R
+ Prefix: 'w83793'
+ Addresses scanned: I2C 0x2c - 0x2f
+ Datasheet: Still not published
+
+Authors:
+ Yuan Mu (Winbond Electronics)
+ Rudolf Marek <r.marek@assembler.cz>
+
+
+Module parameters
+-----------------
+
+* reset int
+ (default 0)
+ This parameter is not recommended, it will lose motherboard specific
+ settings. Use 'reset=1' to reset the chip when loading this module.
+
+* force_subclients=bus,caddr,saddr1,saddr2
+ This is used to force the i2c addresses for subclients of
+ a certain chip. Typical usage is `force_subclients=0,0x2f,0x4a,0x4b'
+ to force the subclients of chip 0x2f on bus 0 to i2c addresses
+ 0x4a and 0x4b.
+
+
+Description
+-----------
+
+This driver implements support for Winbond W83793G/W83793R chips.
+
+* Exported features
+ This driver exports 10 voltage sensors, up to 12 fan tachometer inputs,
+ 6 remote temperatures, up to 8 sets of PWM fan controls, SmartFan
+ (automatic fan speed control) on all temperature/PWM combinations, 2
+ sets of 6-pin CPU VID input.
+
+* Sensor resolutions
+ If your motherboard maker used the reference design, the resolution of
+ voltage0-2 is 2mV, resolution of voltage3/4/5 is 16mV, 8mV for voltage6,
+ 24mV for voltage7/8. Temp1-4 have a 0.25 degree Celsius resolution,
+ temp5-6 have a 1 degree Celsiis resolution.
+
+* Temperature sensor types
+ Temp1-4 have 3 possible types. It can be read from (and written to)
+ temp[1-4]_type.
+ - If the value of 0, the related temperature channel stops
+ monitoring.
+ - If the value is 3, it starts monitoring using a remote termal diode
+ (default).
+ - If the value is 5, it starts monitoring using the temperature sensor
+ in AMD CPU and get result by AMDSI.
+ - If the value is 6, it starts monitoring using the temperature sensor
+ in Intel CPU and get result by PECI.
+ Temp5-6 can be connected to external thermistors (value of
+ temp[5-6]_type is 4). They can also be disabled (value is 0).
+
+* Alarm mechanism
+ For voltage sensors, an alarm triggers if the measured value is below
+ the low voltage limit or over the high voltage limit.
+ For temperature sensors, an alarm triggers if the measured value goes
+ above the high temperature limit, and wears off only after the measured
+ value drops below the hysteresis value.
+ For fan sensors, an alarm triggers if the measured value is below the
+ low speed limit.
+
+* SmartFan/PWM control
+ If you want to set a pwm fan to manual mode, you just need to make sure it
+ is not controlled by any temp channel, for example, you want to set fan1
+ to manual mode, you need to check the value of temp[1-6]_fan_map, make
+ sure bit 0 is cleared in the 6 values. And then set the pwm1 value to
+ control the fan.
+
+ Each temperature channel can control all the 8 PWM outputs (by setting the
+ corresponding bit in tempX_fan_map), you can set the temperature channel
+ mode using temp[1-6]_pwm_enable, 2 is Thermal Cruise mode and 3
+ is the SmartFanII mode. Temperature channels will try to speed up or
+ slow down all controlled fans, this means one fan can receive different
+ PWM value requests from different temperature channels, but the chip
+ will always pick the safest (max) PWM value for each fan.
+
+ In Thermal Cruise mode, the chip attempts to keep the temperature at a
+ predefined value, within a tolerance margin. So if tempX_input >
+ thermal_cruiseX + toleranceX, the chip will increase the PWM value,
+ if tempX_input < thermal_cruiseX - toleranceX, the chip will decrease
+ the PWM value. If the temperature is within the tolerance range, the PWM
+ value is left unchanged.
+
+ SmartFanII works differently, you have to define up to 7 PWM, temperature
+ trip points, defining a PWM/temperature curve which the chip will follow.
+ While not fundamentally different from the Thermal Cruise mode, the
+ implementation is quite different, giving you a finer-grained control.
+
+* Chassis
+ If the case open alarm triggers, it will stay in this state unless cleared
+ by any write to the sysfs file "chassis".
+
+* VID and VRM
+ The VRM version is detected automatically, don't modify the it unless you
+ *do* know the cpu VRM version and it's not properly detected.
+
+
+Notes
+-----
+
+ Only Fan1-5 and PWM1-3 are guaranteed to always exist, other fan inputs and
+ PWM outputs may or may not exist depending on the chip pin configuration.
diff --git a/Documentation/ibm-acpi.txt b/Documentation/ibm-acpi.txt
index e50595bfd8ea..0132d363feb5 100644
--- a/Documentation/ibm-acpi.txt
+++ b/Documentation/ibm-acpi.txt
@@ -398,25 +398,67 @@ 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:
+This feature shows readings from up to eight different sensors on older
+ThinkPads, and it has experimental support for up to sixteen different
+sensors on newer ThinkPads. Readings from sensors that are not available
+return -128.
+No commands can be written to this file.
+
+EXPERIMENTAL: The 16-sensors 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. When EXPERIMENTAL
+mode is enabled, reading the first 8 sensors on newer ThinkPads will
+also use an new experimental thermal sensor access mode.
+
+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):
+EXPERIMENTAL: On the T43/p, a typical output may be:
+temperatures: 48 48 36 52 38 -128 31 -128 48 52 48 -128 -128 -128 -128 -128
+
+The mapping of thermal sensors to physical locations varies depending on
+system-board model (and thus, on ThinkPad model).
+
+http://thinkwiki.org/wiki/Thermal_Sensors is a public wiki page that
+tries to track down these locations for various models.
+
+Most (newer?) models seem to follow this pattern:
1: CPU
-2: Mini PCI Module
-3: HDD
+2: (depends on model)
+3: (depends on model)
4: GPU
-5: Battery
-6: N/A
-7: Battery
-8: N/A
+5: Main battery: main sensor
+6: Bay battery: main sensor
+7: Main battery: secondary sensor
+8: Bay battery: secondary sensor
+9-15: (depends on model)
+
+For the R51 (source: Thomas Gruber):
+2: Mini-PCI
+3: Internal HDD
+
+For the T43, T43/p (source: Shmidoax/Thinkwiki.org)
+http://thinkwiki.org/wiki/Thermal_Sensors#ThinkPad_T43.2C_T43p
+2: System board, left side (near PCMCIA slot), reported as HDAPS temp
+3: PCMCIA slot
+9: MCH (northbridge) to DRAM Bus
+10: ICH (southbridge), under Mini-PCI card, under touchpad
+11: Power regulator, underside of system board, below F2 key
+
+The A31 has a very atypical layout for the thermal sensors
+(source: Milos Popovic, http://thinkwiki.org/wiki/Thermal_Sensors#ThinkPad_A31)
+1: CPU
+2: Main Battery: main sensor
+3: Power Converter
+4: Bay Battery: main sensor
+5: MCH (northbridge)
+6: PCMCIA/ambient
+7: Main Battery: secondary sensor
+8: Bay Battery: secondary sensor
-No commands can be written to this file.
EXPERIMENTAL: Embedded controller register dump -- /proc/acpi/ibm/ecdump
------------------------------------------------------------------------
@@ -529,27 +571,57 @@ 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.
+This feature attempts to show the current fan speed, control mode and
+other fan data that might be available. 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.
+
+Most ThinkPad fans work in "levels". Level 0 stops the fan. The higher
+the level, the higher the fan speed, although adjacent levels often map
+to the same fan speed. 7 is the highest level, where the fan reaches
+the maximum recommended speed. Level "auto" means the EC changes the
+fan level according to some internal algorithm, usually based on
+readings from the thermal sensors. Level "disengaged" means the EC
+disables the speed-locked closed-loop fan control, and drives the fan as
+fast as it can go, which might exceed hardware limits, so use this level
+with caution.
+
+The fan usually ramps up or down slowly from one speed to another,
+and it is normal for the EC to take several seconds to react to fan
+commands.
The fan may be enabled or disabled with the following commands:
echo enable >/proc/acpi/ibm/fan
echo disable >/proc/acpi/ibm/fan
+Placing a fan on level 0 is the same as disabling it. Enabling a fan
+will try to place it in a safe level if it is too slow or disabled.
+
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.
+monitoring all of 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.
+An enabled fan in level "auto" may stop spinning if the EC decides the
+ThinkPad is cool enough and doesn't need the extra airflow. This is
+normal, and the EC will spin the fan up if the varios thermal readings
+rise too much.
+
+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.
+
+The fan level can be controlled with the command:
+
+ echo 'level <level>' > /proc/acpi/ibm/thermal
+
+Where <level> is an integer from 0 to 7, or one of the words "auto"
+or "disengaged" (without the quotes). Not all ThinkPads support the
+"auto" and "disengaged" levels.
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
@@ -562,12 +634,9 @@ 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:
-
- echo 'level <level>' > /proc/acpi/ibm/thermal
+The ThinkPad's ACPI DSDT code will reprogram the fan on its own when
+certain conditions are met. It will override any fan programming done
+through ibm-acpi.
EXPERIMENTAL: WAN -- /proc/acpi/ibm/wan
---------------------------------------
@@ -601,6 +670,26 @@ example:
modprobe ibm_acpi hotkey=enable,0xffff video=auto_disable
+The ibm-acpi kernel driver can be programmed to revert the fan level
+to a safe setting if userspace does not issue one of the fan commands:
+"enable", "disable", "level" or "watchdog" within a configurable
+ammount of time. To do this, use the "watchdog" command.
+
+ echo 'watchdog <interval>' > /proc/acpi/ibm/fan
+
+Interval is the ammount of time in seconds to wait for one of the
+above mentioned fan commands before reseting the fan level to a safe
+one. If set to zero, the watchdog is disabled (default). When the
+watchdog timer runs out, it does the exact equivalent of the "enable"
+fan command.
+
+Note that the watchdog timer stops after it enables the fan. It will
+be rearmed again automatically (using the same interval) when one of
+the above mentioned fan commands is received. The fan watchdog is,
+therefore, not suitable to protect against fan mode changes made
+through means other than the "enable", "disable", and "level" fan
+commands.
+
Example Configuration
---------------------
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index d8323b8893c3..25d298517104 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1656,6 +1656,12 @@ and is between 256 and 4096 characters. It is defined in the file
sym53c416= [HW,SCSI]
See header of drivers/scsi/sym53c416.c.
+ sysrq_always_enabled
+ [KNL]
+ Ignore sysrq setting - this boot parameter will
+ neutralize any effect of /proc/sys/kernel/sysrq.
+ Useful for debugging.
+
t128= [HW,SCSI]
See header of drivers/scsi/t128.c.
@@ -1708,6 +1714,14 @@ and is between 256 and 4096 characters. It is defined in the file
uart6850= [HW,OSS]
Format: <io>,<irq>
+ uhci-hcd.ignore_oc=
+ [USB] Ignore overcurrent events (default N).
+ Some badly-designed motherboards generate lots of
+ bogus events, for ports that aren't wired to
+ anything. Set this parameter to avoid log spamming.
+ Note that genuine overcurrent events won't be
+ reported either.
+
usbhid.mousepoll=
[USBHID] The interval which mice are to be polled at.
diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt
index b3bd36668db3..33994271cb3b 100644
--- a/Documentation/powerpc/booting-without-of.txt
+++ b/Documentation/powerpc/booting-without-of.txt
@@ -1703,29 +1703,32 @@ platforms are moved over to use the flattened-device-tree model.
Required properties:
- device_type : has to be "rom"
- - compatible : Should specify what this ROM device is compatible with
- (i.e. "onenand"). Currently, this is most likely to be "direct-mapped"
- (which corresponds to the MTD physmap mapping driver).
- - regs : Offset and length of the register set (or memory mapping) for
+ - compatible : Should specify what this flash device is compatible with.
+ Currently, this is most likely to be "direct-mapped" (which
+ corresponds to the MTD physmap mapping driver).
+ - reg : Offset and length of the register set (or memory mapping) for
the device.
+ - bank-width : Width of the flash data bus in bytes. Required
+ for the NOR flashes (compatible == "direct-mapped" and others) ONLY.
Recommended properties :
- - bank-width : Width of the flash data bus in bytes. Required
- for the NOR flashes (compatible == "direct-mapped" and others) ONLY.
- partitions : Several pairs of 32-bit values where the first value is
partition's offset from the start of the device and the second one is
partition size in bytes with LSB used to signify a read only
- partititon (so, the parition size should always be an even number).
+ partition (so, the parition size should always be an even number).
- partition-names : The list of concatenated zero terminated strings
representing the partition names.
+ - probe-type : The type of probe which should be done for the chip
+ (JEDEC vs CFI actually). Valid ONLY for NOR flashes.
Example:
flash@ff000000 {
device_type = "rom";
compatible = "direct-mapped";
- regs = <ff000000 01000000>;
+ probe-type = "CFI";
+ reg = <ff000000 01000000>;
bank-width = <4>;
partitions = <00000000 00f80000
00f80000 00080001>;
diff --git a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
index 077fbe25ebf4..ccd0a953953d 100644
--- a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
+++ b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
@@ -927,7 +927,7 @@
<informalexample>
<programlisting>
<![CDATA[
- struct mychip *chip = (struct mychip *)card->private_data;
+ struct mychip *chip = card->private_data;
]]>
</programlisting>
</informalexample>
@@ -1095,7 +1095,7 @@
/* release the irq */
if (chip->irq >= 0)
- free_irq(chip->irq, (void *)chip);
+ free_irq(chip->irq, chip);
/* release the i/o ports & memory */
pci_release_regions(chip->pci);
/* disable the PCI entry */
@@ -1148,7 +1148,7 @@
}
chip->port = pci_resource_start(pci, 0);
if (request_irq(pci->irq, snd_mychip_interrupt,
- IRQF_DISABLED|IRQF_SHARED, "My Chip", chip)) {
+ IRQF_SHARED, "My Chip", chip)) {
printk(KERN_ERR "cannot grab irq %d\n", pci->irq);
snd_mychip_free(chip);
return -EBUSY;
@@ -1387,7 +1387,7 @@
<programlisting>
<![CDATA[
if (chip->irq >= 0)
- free_irq(chip->irq, (void *)chip);
+ free_irq(chip->irq, chip);
]]>
</programlisting>
</informalexample>
diff --git a/Documentation/tty.txt b/Documentation/tty.txt
index dab56604745d..5f799e612e03 100644
--- a/Documentation/tty.txt
+++ b/Documentation/tty.txt
@@ -39,28 +39,37 @@ Line Discipline Methods
TTY side interfaces:
+open() - Called when the line discipline is attached to
+ the terminal. No other call into the line
+ discipline for this tty will occur until it
+ completes successfully. Can sleep.
+
close() - This is called on a terminal when the line
discipline is being unplugged. At the point of
execution no further users will enter the
ldisc code for this tty. Can sleep.
-open() - Called when the line discipline is attached to
- the terminal. No other call into the line
- discipline for this tty will occur until it
- completes successfully. Can sleep.
+hangup() - Called when the tty line is hung up.
+ The line discipline should cease I/O to the tty.
+ No further calls into the ldisc code will occur.
+ Can sleep.
write() - A process is writing data through the line
discipline. Multiple write calls are serialized
by the tty layer for the ldisc. May sleep.
-flush_buffer() - May be called at any point between open and close.
+flush_buffer() - (optional) May be called at any point between
+ open and close, and instructs the line discipline
+ to empty its input buffer.
-chars_in_buffer() - Report the number of bytes in the buffer.
+chars_in_buffer() - (optional) Report the number of bytes in the input
+ buffer.
-set_termios() - Called on termios structure changes. The caller
- passes the old termios data and the current data
- is in the tty. Called under the termios semaphore so
- allowed to sleep. Serialized against itself only.
+set_termios() - (optional) Called on termios structure changes.
+ The caller passes the old termios data and the
+ current data is in the tty. Called under the
+ termios semaphore so allowed to sleep. Serialized
+ against itself only.
read() - Move data from the line discipline to the user.
Multiple read calls may occur in parallel and the
@@ -92,6 +101,88 @@ write_wakeup() - May be called at any point between open and close.
this function. In such a situation defer it.
+Driver Access
+
+Line discipline methods can call the following methods of the underlying
+hardware driver through the function pointers within the tty->driver
+structure:
+
+write() Write a block of characters to the tty device.
+ Returns the number of characters accepted.
+
+put_char() Queues a character for writing to the tty device.
+ If there is no room in the queue, the character is
+ ignored.
+
+flush_chars() (Optional) If defined, must be called after
+ queueing characters with put_char() in order to
+ start transmission.
+
+write_room() Returns the numbers of characters the tty driver
+ will accept for queueing to be written.
+
+ioctl() Invoke device specific ioctl.
+ Expects data pointers to refer to userspace.
+ Returns ENOIOCTLCMD for unrecognized ioctl numbers.
+
+set_termios() Notify the tty driver that the device's termios
+ settings have changed. New settings are in
+ tty->termios. Previous settings should be passed in
+ the "old" argument.
+
+throttle() Notify the tty driver that input buffers for the
+ line discipline are close to full, and it should
+ somehow signal that no more characters should be
+ sent to the tty.
+
+unthrottle() Notify the tty driver that characters can now be
+ sent to the tty without fear of overrunning the
+ input buffers of the line disciplines.
+
+stop() Ask the tty driver to stop outputting characters
+ to the tty device.
+
+start() Ask the tty driver to resume sending characters
+ to the tty device.
+
+hangup() Ask the tty driver to hang up the tty device.
+
+break_ctl() (Optional) Ask the tty driver to turn on or off
+ BREAK status on the RS-232 port. If state is -1,
+ then the BREAK status should be turned on; if
+ state is 0, then BREAK should be turned off.
+ If this routine is not implemented, use ioctls
+ TIOCSBRK / TIOCCBRK instead.
+
+wait_until_sent() Waits until the device has written out all of the
+ characters in its transmitter FIFO.
+
+send_xchar() Send a high-priority XON/XOFF character to the device.
+
+
+Flags
+
+Line discipline methods have access to tty->flags field containing the
+following interesting flags:
+
+TTY_THROTTLED Driver input is throttled. The ldisc should call
+ tty->driver->unthrottle() in order to resume
+ reception when it is ready to process more data.
+
+TTY_DO_WRITE_WAKEUP If set, causes the driver to call the ldisc's
+ write_wakeup() method in order to resume
+ transmission when it can accept more data
+ to transmit.
+
+TTY_IO_ERROR If set, causes all subsequent userspace read/write
+ calls on the tty to fail, returning -EIO.
+
+TTY_OTHER_CLOSED Device is a pty and the other side has closed.
+
+TTY_NO_WRITE_SPLIT Prevent driver from splitting up writes into
+ smaller chunks.
+
+
Locking
Callers to the line discipline functions from the tty layer are required to
diff --git a/MAINTAINERS b/MAINTAINERS
index 8a0bfeca55c9..7f6c051cac65 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -277,7 +277,7 @@ S: Maintained
ALI1563 I2C DRIVER
P: Rudolf Marek
-M: r.marek@sh.cvut.cz
+M: r.marek@assembler.cz
L: i2c@lm-sensors.org
S: Maintained
@@ -296,6 +296,13 @@ L: info-linux@geode.amd.com
W: http://www.amd.com/us-en/ConnectivitySolutions/TechnicalResources/0,,50_2334_2452_11363,00.html
S: Supported
+AMS (Apple Motion Sensor) DRIVER
+P: Stelian Pop
+M: stelian@popies.net
+P: Michael Hanselmann
+M: linux-kernel@hansmi.ch
+S: Supported
+
AMSO1100 RNIC DRIVER
P: Tom Tucker
M: tom@opengridcomputing.com
@@ -348,6 +355,24 @@ P: Ian Molton
M: spyro@f2s.com
S: Maintained
+ARM/ADI ROADRUNNER MACHINE SUPPORT
+P: Lennert Buytenhek
+M: kernel@wantstofly.org
+L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
+S: Maintained
+
+ARM/ADS SPHERE MACHINE SUPPORT
+P: Lennert Buytenhek
+M: kernel@wantstofly.org
+L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
+S: Maintained
+
+ARM/AJECO 1ARM MACHINE SUPPORT
+P: Lennert Buytenhek
+M: kernel@wantstofly.org
+L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
+S: Maintained
+
ARM/ATMEL AT91RM9200 ARM ARCHITECTURE
P: Andrew Victor
M: andrew@sanpeople.com
@@ -355,17 +380,89 @@ L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
W: http://maxim.org.za/at91_26.html
S: Maintained
+ARM/CIRRUS LOGIC EP93XX ARM ARCHITECTURE
+P: Lennert Buytenhek
+M: kernel@wantstofly.org
+L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
+S: Maintained
+
+ARM/CIRRUS LOGIC EDB9315A MACHINE SUPPORT
+P: Lennert Buytenhek
+M: kernel@wantstofly.org
+L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
+S: Maintained
+
ARM/CORGI MACHINE SUPPORT
P: Richard Purdie
M: rpurdie@rpsys.net
S: Maintained
+ARM/GLOMATION GESBC9312SX MACHINE SUPPORT
+P: Lennert Buytenhek
+M: kernel@wantstofly.org
+L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
+S: Maintained
+
ARM/HP JORNADA 7XX MACHINE SUPPORT
P: Kristoffer Ericson
M: kristoffer_e1@hotmail.com
W: www.jlime.com
S: Maintained
+ARM/INTEL IOP32X ARM ARCHITECTURE
+P: Lennert Buytenhek
+M: kernel@wantstofly.org
+L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
+S: Maintained
+
+ARM/INTEL IOP13XX ARM ARCHITECTURE
+P: Lennert Buytenhek
+M: kernel@wantstofly.org
+L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
+S: Maintained
+
+ARM/INTEL IQ81342EX MACHINE SUPPORT
+P: Lennert Buytenhek
+M: kernel@wantstofly.org
+L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
+S: Maintained
+
+ARM/INTEL IXP2000 ARM ARCHITECTURE
+P: Lennert Buytenhek
+M: kernel@wantstofly.org
+L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
+S: Maintained
+
+ARM/INTEL IXDP2850 MACHINE SUPPORT
+P: Lennert Buytenhek
+M: kernel@wantstofly.org
+L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
+S: Maintained
+
+ARM/INTEL IXP23XX ARM ARCHITECTURE
+P: Lennert Buytenhek
+M: kernel@wantstofly.org
+L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
+S: Maintained
+
+ARM/INTEL XSC3 (MANZANO) ARM CORE
+P: Lennert Buytenhek
+M: kernel@wantstofly.org
+L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
+S: Maintained
+
+ARM/IP FABRICS DOUBLE ESPRESSO MACHINE SUPPORT
+P: Lennert Buytenhek
+M: kernel@wantstofly.org
+L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
+S: Maintained
+
+ARM/LOGICPD PXA270 MACHINE SUPPORT
+P: Lennert Buytenhek
+M: kernel@wantstofly.org
+L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
+S: Maintained
+
ARM/TOSA MACHINE SUPPORT
P: Dirk Opfer
M: dirk@opfer-online.de
@@ -384,6 +481,12 @@ L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
W: http://www.arm.linux.org.uk/
S: Maintained
+ARM/RADISYS ENP2611 MACHINE SUPPORT
+P: Lennert Buytenhek
+M: kernel@wantstofly.org
+L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
+S: Maintained
+
ARM/SHARK MACHINE SUPPORT
P: Alexander Schulz
M: alex@shark-linux.de
@@ -399,18 +502,30 @@ S: Maintained
ARM/S3C2410 ARM ARCHITECTURE
P: Ben Dooks
-M: ben-s3c2410@fluff.org
+M: ben-linux@fluff.org
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
W: http://www.fluff.org/ben/linux/
S: Maintained
ARM/S3C2440 ARM ARCHITECTURE
P: Ben Dooks
-M: ben-s3c2440@fluff.org
+M: ben-linux@fluff.org
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
W: http://www.fluff.org/ben/linux/
S: Maintained
+ARM/TECHNOLOGIC SYSTEMS TS7250 MACHINE SUPPORT
+P: Lennert Buytenhek
+M: kernel@wantstofly.org
+L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
+S: Maintained
+
+ARM/THECUS N2100 MACHINE SUPPORT
+P: Lennert Buytenhek
+M: kernel@wantstofly.org
+L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
+S: Maintained
+
ARPD SUPPORT
P: Jonathan Layes
L: netdev@vger.kernel.org
@@ -681,12 +796,24 @@ M: joel.becker@oracle.com
L: linux-kernel@vger.kernel.org
S: Supported
+CIRRUS LOGIC EP93XX ETHERNET DRIVER
+P: Lennert Buytenhek
+M: kernel@wantstofly.org
+L: netdev@vger.kernel.org
+S: Maintained
+
CIRRUS LOGIC GENERIC FBDEV DRIVER
P: Jeff Garzik
M: jgarzik@pobox.com
L: linux-fbdev-devel@lists.sourceforge.net (subscribers-only)
S: Odd Fixes
+CIRRUS LOGIC EP93XX OHCI USB HOST DRIVER
+P: Lennert Buytenhek
+M: kernel@wantstofly.org
+L: linux-usb-devel@lists.sourceforge.net
+S: Maintained
+
CIRRUS LOGIC CS4280/CS461x SOUNDDRIVER
P: Cirrus Logic Corporation (kernel 2.2 driver)
M: Cirrus Logic Corporation, Thomas Woller <twoller@crystal.cirrus.com>
@@ -936,11 +1063,8 @@ L: linux-kernel@vger.kernel.org
S: Maintained
DOCBOOK FOR DOCUMENTATION
-P: Martin Waitz
-M: tali@admingilde.org
P: Randy Dunlap
M: rdunlap@xenotime.net
-T: git http://tali.admingilde.org/git/linux-docbook.git
S: Maintained
DOCKING STATION DRIVER
@@ -1270,6 +1394,12 @@ L: linux-nvidia@lists.surfsouth.com
W: http://drama.obuda.kando.hu/~fero/cgi-bin/hgafb.shtml
S: Maintained
+HID CORE LAYER
+P: Jiri Kosina
+M: jkosina@suse.cz
+L: linux-input@atrey.karlin.mff.cuni.cz
+S: Maintained
+
HIGH-SPEED SCC DRIVER FOR AX.25
P: Klaus Kudielka
M: klaus.kudielka@ieee.org
@@ -1390,6 +1520,15 @@ W: http://www.ia64-linux.org/
T: git kernel.org:/pub/scm/linux/kernel/git/aegl/linux-2.6.git
S: Maintained
+IBM ACPI EXTRAS DRIVER
+P: Henrique de Moraes Holschuh
+M: ibm-acpi@hmh.eng.br
+L: ibm-acpi-devel@lists.sourceforge.net
+W: http://ibm-acpi.sourceforge.net
+W: http://thinkwiki.org/wiki/Ibm-acpi
+T: git repo.or.cz/linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git
+S: Maintained
+
SN-IA64 (Itanium) SUB-PLATFORM
P: Jes Sorensen
M: jes@sgi.com
@@ -1425,10 +1564,9 @@ T: git kernel.org:/pub/scm/linux/kernel/git/bart/ide-2.6.git
S: Maintained
IDE/ATAPI CDROM DRIVER
-P: Jens Axboe
-M: axboe@kernel.dk
-L: linux-kernel@vger.kernel.org
-W: http://www.kernel.dk
+P: Alan Cox
+M: alan@lxorguk.ukuu.org.uk
+L: linux-ide@vger.kernel.org
S: Maintained
IDE/ATAPI FLOPPY DRIVERS
@@ -1544,6 +1682,12 @@ P: Deepak Saxena
M: dsaxena@plexity.net
S: Maintained
+INTEL IXP2000 ETHERNET DRIVER
+P: Lennert Buytenhek
+M: kernel@wantstofly.org
+L: netdev@vger.kernel.org
+S: Maintained
+
INTEL PRO/100 ETHERNET SUPPORT
P: John Ronciak
M: john.ronciak@intel.com
@@ -1747,6 +1891,13 @@ W: http://nfs.sourceforge.net/
W: http://www.cse.unsw.edu.au/~neilb/patches/linux-devel/
S: Maintained
+KERNEL VIRTUAL MACHINE (KVM)
+P: Avi Kivity
+M: avi@qumranet.com
+L: kvm-devel@lists.sourceforge.net
+W: kvm.sourceforge.net
+S: Supported
+
KEXEC
P: Eric Biederman
M: ebiederm@xmission.com
@@ -1905,9 +2056,9 @@ S: Maintained
LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI)
P: Eric Moore
-M: Eric.Moore@lsil.com
-M: support@lsil.com
-L: mpt_linux_developer@lsil.com
+M: Eric.Moore@lsi.com
+M: support@lsi.com
+L: mpt_linux_developer@lsi.com
L: linux-scsi@vger.kernel.org
W: http://www.lsilogic.com/support
S: Supported
@@ -3110,7 +3261,7 @@ USB EHCI DRIVER
P: David Brownell
M: dbrownell@users.sourceforge.net
L: linux-usb-devel@lists.sourceforge.net
-S: Maintained
+S: Odd Fixes
USB ET61X[12]51 DRIVER
P: Luca Risolia
@@ -3163,11 +3314,11 @@ S: Maintained
W: http://www.one-eyed-alien.net/~mdharm/linux-usb/
USB OHCI DRIVER
-P: Roman Weissgaerber
-M: weissg@vienna.at
+P: David Brownell
+M: dbrownell@users.sourceforge.net
L: linux-usb-users@lists.sourceforge.net
L: linux-usb-devel@lists.sourceforge.net
-S: Maintained
+S: Odd Fixes
USB OPTION-CARD DRIVER
P: Matthias Urlichs
@@ -3429,6 +3580,12 @@ M: bezaur@gmail.com
L: lm-sensors@lm-sensors.org
S: Maintained
+W83793 HARDWARE MONITORING DRIVER
+P: Rudolf Marek
+M: r.marek@assembler.cz
+L: lm-sensors@lm-sensors.org
+S: Maintained
+
W83L51xD SD/MMC CARD INTERFACE DRIVER
P: Pierre Ossman
M: drzeus-wbsd@drzeus.cx
diff --git a/Makefile b/Makefile
index 4eabaa8afbff..0e9eee768288 100644
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
VERSION = 2
PATCHLEVEL = 6
-SUBLEVEL = 19
-EXTRAVERSION =
-NAME=Avast! A bilge rat!
+SUBLEVEL = 20
+EXTRAVERSION =-rc3
+NAME = Homicidal Dwarf Hamster
# *DOCUMENTATION*
# To see a list of typical targets execute "make help"
@@ -368,10 +368,14 @@ endif
# Detect when mixed targets is specified, and make a second invocation
# of make so .config is not included in this case either (for *config).
-no-dot-config-targets := clean mrproper distclean \
+PHONY += generated_headers
+
+generated_headers: include/linux/version.h include/linux/compile.h \
+ include/linux/utsrelease.h
+
+no-dot-config-targets := generated_headers clean mrproper distclean \
cscope TAGS tags help %docs check% \
- include/linux/version.h headers_% \
- kernelrelease kernelversion
+ headers_% kernelrelease kernelversion
config-targets := 0
mixed-targets := 0
@@ -496,11 +500,6 @@ else
CFLAGS += -fomit-frame-pointer
endif
-ifdef CONFIG_UNWIND_INFO
-CFLAGS += -fasynchronous-unwind-tables
-LDFLAGS_vmlinux += --eh-frame-hdr
-endif
-
ifdef CONFIG_DEBUG_INFO
CFLAGS += -g
endif
@@ -739,6 +738,16 @@ debug_kallsyms: .tmp_map$(last_kallsyms)
endif # ifdef CONFIG_KALLSYMS
+# compile.h changes depending on hostname, generation number, etc,
+# so we regenerate it always.
+# mkcompile_h will make sure to only update the
+# actual file if its content has changed.
+
+include/linux/compile.h: FORCE
+ @echo ' CHK $@'
+ $(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkcompile_h $@ \
+ "$(UTS_MACHINE)" "$(CONFIG_SMP)" "$(CONFIG_PREEMPT)" "$(CC) $(CFLAGS)"
+
# vmlinux image - including updated kernel symbols
vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) FORCE
ifdef CONFIG_HEADERS_CHECK
@@ -857,8 +866,8 @@ endif
# prepare2 creates a makefile if using a separate output directory
prepare2: prepare3 outputmakefile
-prepare1: prepare2 include/linux/version.h include/linux/utsrelease.h \
- include/asm include/config/auto.conf
+prepare1: prepare2 generated_headers include/asm include/config/auto.conf
+
ifneq ($(KBUILD_MODULES),)
$(Q)mkdir -p $(MODVERDIR)
$(Q)rm -f $(MODVERDIR)/*
@@ -927,14 +936,14 @@ export INSTALL_HDR_PATH
HDRARCHES=$(filter-out generic,$(patsubst $(srctree)/include/asm-%/Kbuild,%,$(wildcard $(srctree)/include/asm-*/Kbuild)))
PHONY += headers_install_all
-headers_install_all: include/linux/version.h scripts_basic FORCE
+headers_install_all: generated_headers scripts_basic FORCE
$(Q)$(MAKE) $(build)=scripts scripts/unifdef
$(Q)for arch in $(HDRARCHES); do \
$(MAKE) ARCH=$$arch -f $(srctree)/scripts/Makefile.headersinst obj=include BIASMDIR=-bi-$$arch ;\
done
PHONY += headers_install
-headers_install: include/linux/version.h scripts_basic FORCE
+headers_install: generated_headers scripts_basic FORCE
@if [ ! -r $(srctree)/include/asm-$(ARCH)/Kbuild ]; then \
echo '*** Error: Headers not exportable for this architecture ($(ARCH))'; \
exit 1 ; fi
@@ -1031,8 +1040,7 @@ CLEAN_FILES += vmlinux System.map \
# Directories & files removed with 'make mrproper'
MRPROPER_DIRS += include/config include2 usr/include
MRPROPER_FILES += .config .config.old include/asm .version .old_version \
- include/linux/autoconf.h include/linux/version.h \
- include/linux/utsrelease.h \
+ include/linux/autoconf.h include/linux/utsrelease.h include/linux/version.h \
Module.symvers tags TAGS cscope*
# clean - Delete most, but leave enough to build external modules
@@ -1390,12 +1398,18 @@ endif #ifeq ($(mixed-targets),1)
PHONY += checkstack kernelrelease kernelversion
-# Use $(SUBARCH) here instead of $(ARCH) so that this works for UML.
-# In the UML case, $(SUBARCH) is the name of the underlying
-# architecture, while for all other arches, it is the same as $(ARCH).
+# UML needs a little special treatment here. It wants to use the host
+# toolchain, so needs $(SUBARCH) passed to checkstack.pl. Everyone
+# else wants $(ARCH), including people doing cross-builds, which means
+# that $(SUBARCH) doesn't work here.
+ifeq ($(ARCH), um)
+CHECKSTACK_ARCH := $(SUBARCH)
+else
+CHECKSTACK_ARCH := $(ARCH)
+endif
checkstack:
$(OBJDUMP) -d vmlinux $$(find . -name '*.ko') | \
- $(PERL) $(src)/scripts/checkstack.pl $(SUBARCH)
+ $(PERL) $(src)/scripts/checkstack.pl $(CHECKSTACK_ARCH)
kernelrelease:
$(if $(wildcard include/config/kernel.release), $(Q)echo $(KERNELRELEASE), \
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index aa1d400d721a..6783c2e5512d 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -740,7 +740,7 @@ config XIP_PHYS_ADDR
endmenu
-if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP)
+if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX )
menu "CPU Frequency scaling"
@@ -767,6 +767,15 @@ config CPU_FREQ_INTEGRATOR
If in doubt, say Y.
+config CPU_FREQ_IMX
+ tristate "CPUfreq driver for i.MX CPUs"
+ depends on ARCH_IMX && CPU_FREQ
+ default n
+ help
+ This enables the CPUfreq driver for i.MX CPUs.
+
+ If in doubt, say N.
+
endmenu
endif
@@ -945,6 +954,8 @@ source "drivers/video/Kconfig"
source "sound/Kconfig"
+source "drivers/hid/Kconfig"
+
source "drivers/usb/Kconfig"
source "drivers/mmc/Kconfig"
diff --git a/arch/arm/configs/ep93xx_defconfig b/arch/arm/configs/ep93xx_defconfig
index f8a66b72ad5d..24a701ab33e5 100644
--- a/arch/arm/configs/ep93xx_defconfig
+++ b/arch/arm/configs/ep93xx_defconfig
@@ -1,14 +1,18 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1-git9
-# Sat Jul 15 15:08:10 2006
+# Linux kernel version: 2.6.20-rc1
+# Sat Dec 16 06:05:24 2006
#
CONFIG_ARM=y
+# CONFIG_GENERIC_TIME is not set
CONFIG_MMU=y
CONFIG_GENERIC_HARDIRQS=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_VECTORS_BASE=0xffff0000
@@ -28,18 +32,22 @@ CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
-CONFIG_SYSCTL=y
+# CONFIG_UTS_NS is not set
# CONFIG_AUDIT is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
+CONFIG_SYSFS_DEPRECATED=y
# CONFIG_RELAY is not set
CONFIG_INITRAMFS_SOURCE=""
-CONFIG_UID16=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -48,12 +56,12 @@ CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_SHMEM=y
CONFIG_SLAB=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
# CONFIG_SLOB is not set
@@ -71,7 +79,10 @@ CONFIG_KMOD=y
#
# Block layer
#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
#
# IO Schedulers
@@ -103,7 +114,9 @@ CONFIG_ARCH_EP93XX=y
# CONFIG_ARCH_NETX is not set
# CONFIG_ARCH_H720X is not set
# CONFIG_ARCH_IMX is not set
-# CONFIG_ARCH_IOP3XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IOP13XX is not set
# CONFIG_ARCH_IXP4XX is not set
# CONFIG_ARCH_IXP2000 is not set
# CONFIG_ARCH_IXP23XX is not set
@@ -127,6 +140,7 @@ CONFIG_CRUNCH=y
#
CONFIG_MACH_ADSSPHERE=y
CONFIG_MACH_EDB9302=y
+CONFIG_MACH_EDB9302A=y
CONFIG_MACH_EDB9312=y
CONFIG_MACH_EDB9315=y
CONFIG_MACH_EDB9315A=y
@@ -138,12 +152,14 @@ CONFIG_MACH_TS72XX=y
#
CONFIG_CPU_32=y
CONFIG_CPU_ARM920T=y
-CONFIG_CPU_32v4=y
+CONFIG_CPU_32v4T=y
CONFIG_CPU_ABRT_EV4T=y
CONFIG_CPU_CACHE_V4WT=y
CONFIG_CPU_CACHE_VIVT=y
CONFIG_CPU_COPY_V4WB=y
CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
#
# Processor Features
@@ -230,6 +246,7 @@ CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
CONFIG_XFRM=y
# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
CONFIG_NET_KEY=y
CONFIG_INET=y
# CONFIG_IP_MULTICAST is not set
@@ -250,13 +267,29 @@ CONFIG_SYN_COOKIES=y
# CONFIG_INET_TUNNEL is not set
CONFIG_INET_XFRM_MODE_TRANSPORT=y
CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
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_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
# CONFIG_INET6_XFRM_TUNNEL is not set
# CONFIG_INET6_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_BEET is not set
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+# CONFIG_IPV6_SIT is not set
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
# CONFIG_NETWORK_SECMARK is not set
# CONFIG_NETFILTER is not set
@@ -283,7 +316,6 @@ CONFIG_TCP_CONG_BIC=y
# 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
@@ -330,7 +362,7 @@ CONFIG_MTD_REDBOOT_PARTS=y
CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
-# CONFIG_MTD_CMDLINE_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
# CONFIG_MTD_AFS_PARTS is not set
#
@@ -342,6 +374,7 @@ CONFIG_MTD_BLOCK=y
# CONFIG_NFTL is not set
# CONFIG_INFTL is not set
# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
#
# RAM/ROM/Flash chip drivers
@@ -430,7 +463,7 @@ CONFIG_MTD_NAND_IDS=y
#
# CONFIG_BLK_DEV_COW_COMMON is not set
# CONFIG_BLK_DEV_LOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_NBD=y
# CONFIG_BLK_DEV_UB is not set
# CONFIG_BLK_DEV_RAM is not set
# CONFIG_BLK_DEV_INITRD is not set
@@ -442,6 +475,8 @@ CONFIG_MTD_NAND_IDS=y
#
# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
# CONFIG_SCSI_PROC_FS is not set
#
@@ -460,23 +495,29 @@ CONFIG_BLK_DEV_SD=y
# CONFIG_SCSI_MULTI_LUN is not set
# CONFIG_SCSI_CONSTANTS is not set
# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
#
-# SCSI Transport Attributes
+# SCSI Transports
#
# 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
+# CONFIG_SCSI_SAS_LIBSAS is not set
#
# SCSI low-level drivers
#
# CONFIG_ISCSI_TCP is not set
-# CONFIG_SCSI_SATA is not set
# CONFIG_SCSI_DEBUG is not set
#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
+
+#
# Multi-device support (RAID and LVM)
#
# CONFIG_MD is not set
@@ -513,6 +554,7 @@ CONFIG_NETDEVICES=y
#
CONFIG_NET_ETHERNET=y
CONFIG_MII=y
+CONFIG_EP93XX_ETH=y
# CONFIG_SMC91X is not set
# CONFIG_DM9000 is not set
@@ -607,17 +649,12 @@ CONFIG_EP93XX_WATCHDOG=y
# CONFIG_NVRAM 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
#
# CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
#
# I2C support
@@ -645,7 +682,7 @@ CONFIG_I2C_ALGOBIT=y
#
# CONFIG_SENSORS_DS1337 is not set
# CONFIG_SENSORS_DS1374 is not set
-# CONFIG_SENSORS_EEPROM 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
@@ -664,6 +701,7 @@ CONFIG_I2C_DEBUG_CHIP=y
#
# Dallas's 1-wire bus
#
+# CONFIG_W1 is not set
#
# Hardware Monitoring support
@@ -697,12 +735,15 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_LM92 is not set
# CONFIG_SENSORS_MAX1619 is not set
# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
# CONFIG_SENSORS_SMSC47M1 is not set
# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_W83781D is not set
# CONFIG_SENSORS_W83791D is not set
# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
# CONFIG_SENSORS_W83L785TS is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
@@ -711,6 +752,7 @@ CONFIG_HWMON=y
#
# Misc devices
#
+# CONFIG_TIFM_CORE is not set
#
# LED devices
@@ -729,7 +771,6 @@ CONFIG_HWMON=y
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
#
# Digital Video Broadcasting Devices
@@ -742,6 +783,7 @@ CONFIG_VIDEO_V4L2=y
#
# CONFIG_FIRMWARE_EDID is not set
# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -763,6 +805,7 @@ CONFIG_USB_DEBUG=y
CONFIG_USB_DEVICEFS=y
# CONFIG_USB_BANDWIDTH is not set
CONFIG_USB_DYNAMIC_MINORS=y
+# CONFIG_USB_MULTITHREAD_PROBE is not set
# CONFIG_USB_OTG is not set
#
@@ -797,12 +840,12 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_SDDR55 is not set
# CONFIG_USB_STORAGE_JUMPSHOT is not set
# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
# CONFIG_USB_LIBUSUAL is not set
#
# USB Input Devices
#
-# CONFIG_USB_HID is not set
#
# USB HID Boot Protocol drivers
@@ -821,6 +864,7 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_KAWETH is not set
# CONFIG_USB_PEGASUS is not set
CONFIG_USB_RTL8150=y
+# CONFIG_USB_USBNET_MII is not set
# CONFIG_USB_USBNET is not set
# CONFIG_USB_MON is not set
@@ -834,8 +878,8 @@ CONFIG_USB_RTL8150=y
CONFIG_USB_SERIAL=y
CONFIG_USB_SERIAL_CONSOLE=y
# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_AIRCABLE is not set
# CONFIG_USB_SERIAL_AIRPRIME is not set
-# CONFIG_USB_SERIAL_ANYDATA is not set
# CONFIG_USB_SERIAL_ARK3116 is not set
# CONFIG_USB_SERIAL_BELKIN is not set
# CONFIG_USB_SERIAL_WHITEHEAT is not set
@@ -857,6 +901,8 @@ CONFIG_USB_SERIAL_CONSOLE=y
# CONFIG_USB_SERIAL_KLSI is not set
# CONFIG_USB_SERIAL_KOBIL_SCT is not set
# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_MOS7720 is not set
+# CONFIG_USB_SERIAL_MOS7840 is not set
# CONFIG_USB_SERIAL_NAVMAN is not set
CONFIG_USB_SERIAL_PL2303=y
# CONFIG_USB_SERIAL_HP4X is not set
@@ -867,12 +913,14 @@ CONFIG_USB_SERIAL_PL2303=y
# CONFIG_USB_SERIAL_XIRCOM is not set
# CONFIG_USB_SERIAL_OPTION is not set
# CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_SERIAL_DEBUG is not set
#
# USB Miscellaneous drivers
#
# CONFIG_USB_EMI62 is not set
# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
# CONFIG_USB_AUERSWALD is not set
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
@@ -880,11 +928,12 @@ CONFIG_USB_SERIAL_PL2303=y
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGETKIT is not set
-# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_PHIDGET is not set
# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
# CONFIG_USB_APPLEDISPLAY is not set
# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
# CONFIG_USB_TEST is not set
#
@@ -908,6 +957,7 @@ CONFIG_RTC_LIB=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_HCTOSYS=y
CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
#
# RTC interfaces
@@ -921,7 +971,7 @@ CONFIG_RTC_INTF_DEV=y
# RTC drivers
#
# CONFIG_RTC_DRV_X1205 is not set
-# CONFIG_RTC_DRV_DS1307 is not set
+CONFIG_RTC_DRV_DS1307=y
# CONFIG_RTC_DRV_DS1553 is not set
# CONFIG_RTC_DRV_ISL1208 is not set
# CONFIG_RTC_DRV_DS1672 is not set
@@ -943,12 +993,14 @@ CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4DEV_FS is not set
CONFIG_JBD=y
# CONFIG_JBD_DEBUG 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_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
@@ -980,8 +1032,10 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
# Pseudo filesystems
#
CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
# CONFIG_CONFIGFS_FS is not set
@@ -1102,6 +1156,11 @@ CONFIG_NLS_ISO8859_1=y
# CONFIG_NLS_UTF8 is not set
#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
# Profiling support
#
# CONFIG_PROFILING is not set
@@ -1110,8 +1169,11 @@ CONFIG_NLS_ISO8859_1=y
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_DETECT_SOFTLOCKUP=y
@@ -1128,10 +1190,9 @@ CONFIG_DEBUG_MUTEXES=y
# CONFIG_DEBUG_KOBJECT is not set
CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_FS is not set
# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
CONFIG_FRAME_POINTER=y
-# CONFIG_UNWIND_INFO is not set
CONFIG_FORCED_INLINING=y
# CONFIG_RCU_TORTURE_TEST is not set
CONFIG_DEBUG_USER=y
@@ -1151,12 +1212,9 @@ CONFIG_DEBUG_LL=y
# CONFIG_CRYPTO is not set
#
-# Hardware crypto devices
-#
-
-#
# Library routines
#
+CONFIG_BITREVERSE=y
# CONFIG_CRC_CCITT is not set
# CONFIG_CRC16 is not set
CONFIG_CRC32=y
@@ -1164,3 +1222,4 @@ CONFIG_LIBCRC32C=y
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
CONFIG_PLIST=y
+CONFIG_IOMAP_COPY=y
diff --git a/arch/arm/configs/iop13xx_defconfig b/arch/arm/configs/iop13xx_defconfig
index f6e46193fd26..43c4a37e9247 100644
--- a/arch/arm/configs/iop13xx_defconfig
+++ b/arch/arm/configs/iop13xx_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.19
-# Fri Dec 1 10:51:01 2006
+# Linux kernel version: 2.6.20-rc1-git5
+# Tue Dec 19 21:38:01 2006
#
CONFIG_ARM=y
# CONFIG_GENERIC_TIME is not set
@@ -11,6 +11,8 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_VECTORS_BASE=0xffff0000
@@ -39,6 +41,7 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_AUDIT is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
+CONFIG_SYSFS_DEPRECATED=y
# CONFIG_RELAY is not set
CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -77,7 +80,9 @@ CONFIG_KMOD=y
# Block layer
#
CONFIG_BLOCK=y
+# CONFIG_LBD is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
#
# IO Schedulers
@@ -154,11 +159,13 @@ CONFIG_IO_36=y
CONFIG_ARM_THUMB=y
# CONFIG_CPU_DCACHE_DISABLE is not set
# CONFIG_CPU_BPREDICT_DISABLE is not set
+# CONFIG_IWMMXT is not set
#
# Bus support
#
CONFIG_PCI=y
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
#
# PCCARD (PCMCIA/CardBus) support
@@ -259,9 +266,23 @@ CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_CUBIC=y
CONFIG_DEFAULT_TCP_CONG="cubic"
-# CONFIG_IPV6 is not set
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
# CONFIG_INET6_XFRM_TUNNEL is not set
# CONFIG_INET6_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_BEET is not set
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+# CONFIG_IPV6_SIT is not set
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
# CONFIG_NETWORK_SECMARK is not set
# CONFIG_NETFILTER is not set
@@ -433,7 +454,7 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2
# CONFIG_BLK_DEV_UMEM is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
# CONFIG_BLK_DEV_LOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_NBD=y
# CONFIG_BLK_DEV_SX8 is not set
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=2
@@ -448,6 +469,7 @@ CONFIG_BLK_DEV_INITRD=y
#
# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
+# CONFIG_SCSI_TGT is not set
# CONFIG_SCSI_NETLINK is not set
CONFIG_SCSI_PROC_FS=y
@@ -467,6 +489,7 @@ CONFIG_CHR_DEV_SG=y
# CONFIG_SCSI_MULTI_LUN is not set
CONFIG_SCSI_CONSTANTS=y
# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
#
# SCSI Transports
@@ -510,6 +533,7 @@ CONFIG_SCSI_SAS_ATTRS=y
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_SRP is not set
#
# Serial ATA (prod) and Parallel ATA (experimental) drivers
@@ -605,6 +629,7 @@ CONFIG_E1000_NAPI=y
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
# CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
#
# Token Ring devices
@@ -711,10 +736,6 @@ CONFIG_HW_RANDOM=y
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
# CONFIG_DRM is not set
# CONFIG_RAW_DRIVER is not set
@@ -820,6 +841,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_LM92 is not set
# CONFIG_SENSORS_MAX1619 is not set
# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
# CONFIG_SENSORS_SIS5595 is not set
# CONFIG_SENSORS_SMSC47M1 is not set
# CONFIG_SENSORS_SMSC47M192 is not set
@@ -830,6 +852,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_W83781D is not set
# CONFIG_SENSORS_W83791D is not set
# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
# CONFIG_SENSORS_W83L785TS is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
@@ -883,6 +906,11 @@ CONFIG_DUMMY_CONSOLE=y
# CONFIG_SOUND is not set
#
+# HID Devices
+#
+CONFIG_HID=y
+
+#
# USB support
#
CONFIG_USB_ARCH_HAS_HCD=y
@@ -970,6 +998,7 @@ CONFIG_RAMFS=y
#
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
+CONFIG_ECRYPT_FS=y
# CONFIG_HFS_FS is not set
# CONFIG_HFSPLUS_FS is not set
# CONFIG_BEFS_FS is not set
@@ -1092,6 +1121,11 @@ CONFIG_NLS_DEFAULT="iso8859-1"
# CONFIG_NLS_UTF8 is not set
#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
# Profiling support
#
# CONFIG_PROFILING is not set
@@ -1103,28 +1137,68 @@ CONFIG_NLS_DEFAULT="iso8859-1"
CONFIG_ENABLE_MUST_CHECK=y
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
# CONFIG_DEBUG_KERNEL is not set
CONFIG_LOG_BUF_SHIFT=14
CONFIG_DEBUG_BUGVERBOSE=y
-# CONFIG_DEBUG_FS is not set
CONFIG_FRAME_POINTER=y
-# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_USER=y
#
# Security options
#
-# CONFIG_KEYS is not set
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
# CONFIG_SECURITY is not set
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_WP512=y
+CONFIG_CRYPTO_TGR192=y
+CONFIG_CRYPTO_GF128MUL=y
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_LRW=y
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_BLOWFISH=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_TWOFISH_COMMON=y
+CONFIG_CRYPTO_SERPENT=y
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_CAST5=y
+CONFIG_CRYPTO_CAST6=y
+CONFIG_CRYPTO_TEA=y
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_KHAZAD=y
+CONFIG_CRYPTO_ANUBIS=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
#
# Library routines
#
+CONFIG_BITREVERSE=y
CONFIG_CRC_CCITT=y
# CONFIG_CRC16 is not set
CONFIG_CRC32=y
@@ -1132,3 +1206,4 @@ CONFIG_LIBCRC32C=y
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
CONFIG_PLIST=y
+CONFIG_IOMAP_COPY=y
diff --git a/arch/arm/configs/iop32x_defconfig b/arch/arm/configs/iop32x_defconfig
index b275c53728ec..7909a555706d 100644
--- a/arch/arm/configs/iop32x_defconfig
+++ b/arch/arm/configs/iop32x_defconfig
@@ -1,15 +1,18 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc7
-# Tue Sep 19 00:30:18 2006
+# Linux kernel version: 2.6.20-rc1-git5
+# Tue Dec 19 21:37:52 2006
#
CONFIG_ARM=y
+# CONFIG_GENERIC_TIME is not set
CONFIG_MMU=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_VECTORS_BASE=0xffff0000
@@ -29,18 +32,22 @@ CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
# CONFIG_POSIX_MQUEUE is not set
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
-CONFIG_SYSCTL=y
+# CONFIG_UTS_NS is not set
# CONFIG_AUDIT is not set
# CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
# CONFIG_RELAY is not set
CONFIG_INITRAMFS_SOURCE=""
-CONFIG_UID16=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -49,12 +56,12 @@ CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_SHMEM=y
CONFIG_SLAB=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
# CONFIG_SLOB is not set
@@ -72,7 +79,10 @@ CONFIG_KMOD=y
#
# Block layer
#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
#
# IO Schedulers
@@ -106,6 +116,7 @@ CONFIG_DEFAULT_IOSCHED="cfq"
# CONFIG_ARCH_IMX is not set
CONFIG_ARCH_IOP32X=y
# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IOP13XX is not set
# CONFIG_ARCH_IXP4XX is not set
# CONFIG_ARCH_IXP2000 is not set
# CONFIG_ARCH_IXP23XX is not set
@@ -141,17 +152,22 @@ CONFIG_CPU_32v5=y
CONFIG_CPU_ABRT_EV5T=y
CONFIG_CPU_CACHE_VIVT=y
CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
#
# Processor Features
#
# CONFIG_ARM_THUMB is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_IWMMXT is not set
CONFIG_XSCALE_PMU=y
#
# Bus support
#
CONFIG_PCI=y
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
# CONFIG_PCI_DEBUG is not set
#
@@ -225,6 +241,7 @@ CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
CONFIG_XFRM=y
# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
# CONFIG_NET_KEY is not set
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
@@ -246,13 +263,29 @@ CONFIG_IP_PNP_BOOTP=y
# CONFIG_INET_TUNNEL is not set
CONFIG_INET_XFRM_MODE_TRANSPORT=y
CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
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_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
# CONFIG_INET6_XFRM_TUNNEL is not set
# CONFIG_INET6_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_BEET is not set
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+# CONFIG_IPV6_SIT is not set
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
# CONFIG_NETWORK_SECMARK is not set
# CONFIG_NETFILTER is not set
@@ -279,7 +312,6 @@ CONFIG_TCP_CONG_BIC=y
# 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
@@ -338,6 +370,7 @@ CONFIG_MTD_BLOCK=y
# CONFIG_NFTL is not set
# CONFIG_INFTL is not set
# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
#
# RAM/ROM/Flash chip drivers
@@ -419,9 +452,11 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=1
# 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 is not set
-# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_NBD=y
# 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=8192
@@ -440,6 +475,8 @@ CONFIG_BLK_DEV_INITRD=y
#
# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
CONFIG_SCSI_PROC_FS=y
#
@@ -458,14 +495,16 @@ CONFIG_CHR_DEV_SG=y
# CONFIG_SCSI_MULTI_LUN is not set
# CONFIG_SCSI_CONSTANTS is not set
# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
#
-# SCSI Transport Attributes
+# SCSI Transports
#
# 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
+# CONFIG_SCSI_SAS_LIBSAS is not set
#
# SCSI low-level drivers
@@ -478,26 +517,84 @@ CONFIG_CHR_DEV_SG=y
# CONFIG_SCSI_AIC7XXX is not set
# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ARCMSR 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_HPTIOP is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
# CONFIG_SCSI_IPS is not set
# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
# CONFIG_SCSI_SYM53C8XX_2 is not set
# CONFIG_SCSI_IPR is not set
# CONFIG_SCSI_QLOGIC_1280 is not set
# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI 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
+# CONFIG_SCSI_SRP is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+CONFIG_ATA=y
+# CONFIG_SATA_AHCI is not set
+# CONFIG_SATA_SVW is not set
+# CONFIG_ATA_PIIX is not set
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
+# CONFIG_PDC_ADMA is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+CONFIG_SATA_SIL=y
+# CONFIG_SATA_SIL24 is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
+# CONFIG_PATA_ALI is not set
+# CONFIG_PATA_AMD is not set
+# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATIIXP is not set
+# CONFIG_PATA_CMD64X is not set
+# CONFIG_PATA_CS5520 is not set
+# CONFIG_PATA_CS5530 is not set
+# CONFIG_PATA_CYPRESS is not set
+# CONFIG_PATA_EFAR is not set
+# CONFIG_ATA_GENERIC is not set
+# CONFIG_PATA_HPT366 is not set
+# CONFIG_PATA_HPT37X is not set
+# CONFIG_PATA_HPT3X2N is not set
+# CONFIG_PATA_HPT3X3 is not set
+# CONFIG_PATA_IT821X is not set
+# CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_TRIFLEX is not set
+# CONFIG_PATA_MARVELL is not set
+# CONFIG_PATA_MPIIX is not set
+# CONFIG_PATA_OLDPIIX is not set
+# CONFIG_PATA_NETCELL is not set
+# CONFIG_PATA_NS87410 is not set
+# CONFIG_PATA_OPTI is not set
+# CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC_OLD is not set
+# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RZ1000 is not set
+# CONFIG_PATA_SC1200 is not set
+# CONFIG_PATA_SERVERWORKS is not set
+# CONFIG_PATA_PDC2027X is not set
+# CONFIG_PATA_SIL680 is not set
+# CONFIG_PATA_SIS is not set
+# CONFIG_PATA_VIA is not set
+# CONFIG_PATA_WINBOND is not set
#
# Multi-device support (RAID and LVM)
@@ -512,6 +609,7 @@ CONFIG_MD_RAID1=y
# CONFIG_MD_MULTIPATH is not set
# CONFIG_MD_FAULTY is not set
CONFIG_BLK_DEV_DM=y
+# CONFIG_DM_DEBUG is not set
# CONFIG_DM_CRYPT is not set
# CONFIG_DM_SNAPSHOT is not set
# CONFIG_DM_MIRROR is not set
@@ -612,6 +710,7 @@ CONFIG_R8169=y
# CONFIG_VIA_VELOCITY is not set
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
#
# Ethernet (10000 Mbit)
@@ -620,6 +719,7 @@ CONFIG_R8169=y
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
# CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
#
# Token Ring devices
@@ -654,6 +754,7 @@ CONFIG_R8169=y
# Input device support
#
CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
#
# Userland interfaces
@@ -725,10 +826,6 @@ CONFIG_HW_RANDOM=y
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
# CONFIG_DRM is not set
# CONFIG_RAW_DRIVER is not set
@@ -736,7 +833,6 @@ CONFIG_HW_RANDOM=y
# TPM devices
#
# CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
#
# I2C support
@@ -801,6 +897,7 @@ CONFIG_I2C_IOP3XX=y
#
# Dallas's 1-wire bus
#
+# CONFIG_W1 is not set
#
# Hardware Monitoring support
@@ -834,15 +931,18 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_LM92 is not set
# CONFIG_SENSORS_MAX1619 is not set
# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
# CONFIG_SENSORS_SIS5595 is not set
# CONFIG_SENSORS_SMSC47M1 is not set
# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_VT8231 is not set
# CONFIG_SENSORS_W83781D is not set
# CONFIG_SENSORS_W83791D is not set
# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
# CONFIG_SENSORS_W83L785TS is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
@@ -851,6 +951,8 @@ CONFIG_HWMON=y
#
# Misc devices
#
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
#
# LED devices
@@ -869,12 +971,12 @@ CONFIG_HWMON=y
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
#
# Digital Video Broadcasting Devices
#
# CONFIG_DVB is not set
+# CONFIG_USB_DABUSB is not set
#
# Graphics support
@@ -895,6 +997,11 @@ CONFIG_DUMMY_CONSOLE=y
# CONFIG_SOUND is not set
#
+# HID Devices
+#
+CONFIG_HID=y
+
+#
# USB support
#
CONFIG_USB_ARCH_HAS_HCD=y
@@ -909,6 +1016,7 @@ CONFIG_USB=y
# CONFIG_USB_DEVICEFS is not set
# CONFIG_USB_BANDWIDTH is not set
# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_MULTITHREAD_PROBE is not set
# CONFIG_USB_OTG is not set
#
@@ -946,6 +1054,7 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_SDDR55 is not set
# CONFIG_USB_STORAGE_JUMPSHOT is not set
# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
# CONFIG_USB_LIBUSUAL is not set
#
@@ -984,6 +1093,7 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_KAWETH is not set
# CONFIG_USB_PEGASUS is not set
# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET_MII is not set
# CONFIG_USB_USBNET is not set
CONFIG_USB_MON=y
@@ -1001,6 +1111,7 @@ CONFIG_USB_MON=y
#
# CONFIG_USB_EMI62 is not set
# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
# CONFIG_USB_AUERSWALD is not set
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
@@ -1008,12 +1119,13 @@ CONFIG_USB_MON=y
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGETKIT is not set
-# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_PHIDGET is not set
# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
# CONFIG_USB_APPLEDISPLAY is not set
# CONFIG_USB_SISUSBVGA is not set
# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
#
# USB DSL modem support
@@ -1045,6 +1157,7 @@ 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_EXT4DEV_FS is not set
CONFIG_JBD=y
# CONFIG_JBD_DEBUG is not set
CONFIG_FS_MBCACHE=y
@@ -1056,6 +1169,7 @@ CONFIG_XFS_FS=y
CONFIG_XFS_SECURITY=y
CONFIG_XFS_POSIX_ACL=y
# CONFIG_XFS_RT is not set
+# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
@@ -1084,8 +1198,10 @@ CONFIG_DNOTIFY=y
# Pseudo filesystems
#
CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
# CONFIG_CONFIGFS_FS is not set
@@ -1095,6 +1211,7 @@ CONFIG_RAMFS=y
#
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
+CONFIG_ECRYPT_FS=y
# CONFIG_HFS_FS is not set
# CONFIG_HFSPLUS_FS is not set
# CONFIG_BEFS_FS is not set
@@ -1129,7 +1246,7 @@ CONFIG_NFSD=y
CONFIG_NFSD_V3=y
# CONFIG_NFSD_V3_ACL is not set
# CONFIG_NFSD_V4 is not set
-# CONFIG_NFSD_TCP is not set
+CONFIG_NFSD_TCP=y
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
@@ -1172,6 +1289,11 @@ CONFIG_MSDOS_PARTITION=y
# CONFIG_NLS is not set
#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
# Profiling support
#
# CONFIG_PROFILING is not set
@@ -1180,8 +1302,11 @@ CONFIG_MSDOS_PARTITION=y
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_DETECT_SOFTLOCKUP=y
@@ -1197,10 +1322,9 @@ CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_DEBUG_KOBJECT is not set
CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_FS is not set
# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
CONFIG_FRAME_POINTER=y
-# CONFIG_UNWIND_INFO is not set
# CONFIG_FORCED_INLINING is not set
# CONFIG_RCU_TORTURE_TEST is not set
CONFIG_DEBUG_USER=y
@@ -1211,13 +1335,48 @@ CONFIG_DEBUG_LL=y
#
# Security options
#
-# CONFIG_KEYS is not set
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
# CONFIG_SECURITY is not set
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_WP512=y
+CONFIG_CRYPTO_TGR192=y
+CONFIG_CRYPTO_GF128MUL=y
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_LRW=y
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_BLOWFISH=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_TWOFISH_COMMON=y
+CONFIG_CRYPTO_SERPENT=y
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_CAST5=y
+CONFIG_CRYPTO_CAST6=y
+CONFIG_CRYPTO_TEA=y
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_KHAZAD=y
+CONFIG_CRYPTO_ANUBIS=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -1226,10 +1385,12 @@ CONFIG_DEBUG_LL=y
#
# Library routines
#
+CONFIG_BITREVERSE=y
# CONFIG_CRC_CCITT is not set
# CONFIG_CRC16 is not set
CONFIG_CRC32=y
-# CONFIG_LIBCRC32C is not set
+CONFIG_LIBCRC32C=y
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
CONFIG_PLIST=y
+CONFIG_IOMAP_COPY=y
diff --git a/arch/arm/configs/iop33x_defconfig b/arch/arm/configs/iop33x_defconfig
index 848e3ace9069..fa271bce8ff7 100644
--- a/arch/arm/configs/iop33x_defconfig
+++ b/arch/arm/configs/iop33x_defconfig
@@ -1,15 +1,18 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc7
-# Tue Sep 19 00:30:42 2006
+# Linux kernel version: 2.6.20-rc1
+# Sat Dec 16 06:05:34 2006
#
CONFIG_ARM=y
+# CONFIG_GENERIC_TIME is not set
CONFIG_MMU=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_VECTORS_BASE=0xffff0000
@@ -29,18 +32,22 @@ CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
# CONFIG_POSIX_MQUEUE is not set
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
-CONFIG_SYSCTL=y
+# CONFIG_UTS_NS is not set
# CONFIG_AUDIT is not set
# CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
# CONFIG_RELAY is not set
CONFIG_INITRAMFS_SOURCE=""
-CONFIG_UID16=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -49,12 +56,12 @@ CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_SHMEM=y
CONFIG_SLAB=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
# CONFIG_SLOB is not set
@@ -72,7 +79,10 @@ CONFIG_KMOD=y
#
# Block layer
#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
#
# IO Schedulers
@@ -106,6 +116,7 @@ CONFIG_DEFAULT_IOSCHED="cfq"
# CONFIG_ARCH_IMX is not set
# CONFIG_ARCH_IOP32X is not set
CONFIG_ARCH_IOP33X=y
+# CONFIG_ARCH_IOP13XX is not set
# CONFIG_ARCH_IXP4XX is not set
# CONFIG_ARCH_IXP2000 is not set
# CONFIG_ARCH_IXP23XX is not set
@@ -139,17 +150,22 @@ CONFIG_CPU_32v5=y
CONFIG_CPU_ABRT_EV5T=y
CONFIG_CPU_CACHE_VIVT=y
CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
#
# Processor Features
#
# CONFIG_ARM_THUMB is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_IWMMXT is not set
CONFIG_XSCALE_PMU=y
#
# Bus support
#
CONFIG_PCI=y
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
# CONFIG_PCI_DEBUG is not set
#
@@ -223,6 +239,7 @@ CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
CONFIG_XFRM=y
# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
# CONFIG_NET_KEY is not set
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
@@ -244,13 +261,29 @@ CONFIG_IP_PNP_BOOTP=y
# CONFIG_INET_TUNNEL is not set
CONFIG_INET_XFRM_MODE_TRANSPORT=y
CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
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_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
# CONFIG_INET6_XFRM_TUNNEL is not set
# CONFIG_INET6_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_BEET is not set
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+# CONFIG_IPV6_SIT is not set
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
# CONFIG_NETWORK_SECMARK is not set
# CONFIG_NETFILTER is not set
@@ -277,7 +310,6 @@ CONFIG_TCP_CONG_BIC=y
# 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
@@ -336,6 +368,7 @@ CONFIG_MTD_BLOCK=y
# CONFIG_NFTL is not set
# CONFIG_INFTL is not set
# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
#
# RAM/ROM/Flash chip drivers
@@ -423,7 +456,7 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=1
# CONFIG_BLK_DEV_UMEM is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
# CONFIG_BLK_DEV_LOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_NBD=y
# CONFIG_BLK_DEV_SX8 is not set
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
@@ -443,6 +476,8 @@ CONFIG_BLK_DEV_INITRD=y
#
# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
CONFIG_SCSI_PROC_FS=y
#
@@ -461,14 +496,16 @@ CONFIG_CHR_DEV_SG=y
# CONFIG_SCSI_MULTI_LUN is not set
# CONFIG_SCSI_CONSTANTS is not set
# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
#
-# SCSI Transport Attributes
+# SCSI Transports
#
# 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
+# CONFIG_SCSI_SAS_LIBSAS is not set
#
# SCSI low-level drivers
@@ -481,26 +518,34 @@ CONFIG_CHR_DEV_SG=y
# CONFIG_SCSI_AIC7XXX is not set
# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ARCMSR 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_HPTIOP is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
# CONFIG_SCSI_IPS is not set
# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
# CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_IPR is not set
# CONFIG_SCSI_QLOGIC_1280 is not set
# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI 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
+# CONFIG_SCSI_SRP is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
#
# Multi-device support (RAID and LVM)
@@ -515,6 +560,7 @@ CONFIG_MD_RAID1=y
# CONFIG_MD_MULTIPATH is not set
# CONFIG_MD_FAULTY is not set
CONFIG_BLK_DEV_DM=y
+# CONFIG_DM_DEBUG is not set
# CONFIG_DM_CRYPT is not set
# CONFIG_DM_SNAPSHOT is not set
# CONFIG_DM_MIRROR is not set
@@ -580,6 +626,7 @@ CONFIG_E1000_NAPI=y
# CONFIG_SK98LIN is not set
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
#
# Ethernet (10000 Mbit)
@@ -588,6 +635,7 @@ CONFIG_E1000_NAPI=y
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
# CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
#
# Token Ring devices
@@ -622,6 +670,7 @@ CONFIG_E1000_NAPI=y
# Input device support
#
CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
#
# Userland interfaces
@@ -693,10 +742,6 @@ CONFIG_HW_RANDOM=y
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
# CONFIG_DRM is not set
# CONFIG_RAW_DRIVER is not set
@@ -704,7 +749,6 @@ CONFIG_HW_RANDOM=y
# TPM devices
#
# CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
#
# I2C support
@@ -769,6 +813,7 @@ CONFIG_I2C_IOP3XX=y
#
# Dallas's 1-wire bus
#
+# CONFIG_W1 is not set
#
# Hardware Monitoring support
@@ -802,15 +847,18 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_LM92 is not set
# CONFIG_SENSORS_MAX1619 is not set
# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
# CONFIG_SENSORS_SIS5595 is not set
# CONFIG_SENSORS_SMSC47M1 is not set
# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_VT8231 is not set
# CONFIG_SENSORS_W83781D is not set
# CONFIG_SENSORS_W83791D is not set
# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
# CONFIG_SENSORS_W83L785TS is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
@@ -819,6 +867,8 @@ CONFIG_HWMON=y
#
# Misc devices
#
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
#
# LED devices
@@ -837,7 +887,6 @@ CONFIG_HWMON=y
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
#
# Digital Video Broadcasting Devices
@@ -863,6 +912,11 @@ CONFIG_DUMMY_CONSOLE=y
# CONFIG_SOUND is not set
#
+# HID Devices
+#
+CONFIG_HID=y
+
+#
# USB support
#
CONFIG_USB_ARCH_HAS_HCD=y
@@ -900,6 +954,7 @@ 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_EXT4DEV_FS is not set
CONFIG_JBD=y
# CONFIG_JBD_DEBUG is not set
CONFIG_FS_MBCACHE=y
@@ -911,6 +966,7 @@ CONFIG_XFS_FS=y
CONFIG_XFS_SECURITY=y
CONFIG_XFS_POSIX_ACL=y
# CONFIG_XFS_RT is not set
+# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
@@ -939,8 +995,10 @@ CONFIG_DNOTIFY=y
# Pseudo filesystems
#
CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
# CONFIG_CONFIGFS_FS is not set
@@ -1019,6 +1077,11 @@ CONFIG_MSDOS_PARTITION=y
# CONFIG_NLS is not set
#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
# Profiling support
#
# CONFIG_PROFILING is not set
@@ -1027,8 +1090,11 @@ CONFIG_MSDOS_PARTITION=y
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_DETECT_SOFTLOCKUP=y
@@ -1044,10 +1110,9 @@ CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_DEBUG_KOBJECT is not set
CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_FS is not set
# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
CONFIG_FRAME_POINTER=y
-# CONFIG_UNWIND_INFO is not set
# CONFIG_FORCED_INLINING is not set
# CONFIG_RCU_TORTURE_TEST is not set
CONFIG_DEBUG_USER=y
@@ -1067,10 +1132,6 @@ CONFIG_DEBUG_LL=y
# CONFIG_CRYPTO is not set
#
-# Hardware crypto devices
-#
-
-#
# Library routines
#
# CONFIG_CRC_CCITT is not set
@@ -1078,3 +1139,4 @@ CONFIG_DEBUG_LL=y
# CONFIG_CRC32 is not set
# CONFIG_LIBCRC32C is not set
CONFIG_PLIST=y
+CONFIG_IOMAP_COPY=y
diff --git a/arch/arm/configs/ixp2000_defconfig b/arch/arm/configs/ixp2000_defconfig
index bbd2dcf91e52..f8f9793b526f 100644
--- a/arch/arm/configs/ixp2000_defconfig
+++ b/arch/arm/configs/ixp2000_defconfig
@@ -1,14 +1,18 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Sun Jul 9 15:28:50 2006
+# Linux kernel version: 2.6.20-rc1
+# Sat Dec 16 06:05:39 2006
#
CONFIG_ARM=y
+# CONFIG_GENERIC_TIME is not set
CONFIG_MMU=y
CONFIG_GENERIC_HARDIRQS=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_VECTORS_BASE=0xffff0000
@@ -28,17 +32,22 @@ CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
# CONFIG_POSIX_MQUEUE is not set
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
# CONFIG_AUDIT is not set
# CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
# CONFIG_RELAY is not set
CONFIG_INITRAMFS_SOURCE=""
-CONFIG_UID16=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -47,12 +56,12 @@ CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_SHMEM=y
CONFIG_SLAB=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
# CONFIG_SLOB is not set
@@ -70,7 +79,10 @@ CONFIG_KMOD=y
#
# Block layer
#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
#
# IO Schedulers
@@ -102,7 +114,9 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
# CONFIG_ARCH_NETX is not set
# CONFIG_ARCH_H720X is not set
# CONFIG_ARCH_IMX is not set
-# CONFIG_ARCH_IOP3XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IOP13XX is not set
# CONFIG_ARCH_IXP4XX is not set
CONFIG_ARCH_IXP2000=y
# CONFIG_ARCH_IXP23XX is not set
@@ -143,24 +157,28 @@ CONFIG_CPU_32v5=y
CONFIG_CPU_ABRT_EV5T=y
CONFIG_CPU_CACHE_VIVT=y
CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
#
# Processor Features
#
# CONFIG_ARM_THUMB is not set
CONFIG_CPU_BIG_ENDIAN=y
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_IWMMXT is not set
CONFIG_XSCALE_PMU=y
#
# Bus support
#
CONFIG_PCI=y
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
# CONFIG_PCI_DEBUG is not set
#
# PCCARD (PCMCIA/CardBus) support
#
-# CONFIG_PCCARD is not set
#
# Kernel Features
@@ -228,6 +246,7 @@ CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
CONFIG_XFRM=y
# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
# CONFIG_NET_KEY is not set
CONFIG_INET=y
# CONFIG_IP_MULTICAST is not set
@@ -248,13 +267,29 @@ CONFIG_SYN_COOKIES=y
# CONFIG_INET_TUNNEL is not set
CONFIG_INET_XFRM_MODE_TRANSPORT=y
CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
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_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
# CONFIG_INET6_XFRM_TUNNEL is not set
# CONFIG_INET6_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_BEET is not set
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+# CONFIG_IPV6_SIT is not set
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
# CONFIG_NETWORK_SECMARK is not set
# CONFIG_NETFILTER is not set
@@ -281,7 +316,6 @@ CONFIG_TCP_CONG_BIC=y
# 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
@@ -308,7 +342,6 @@ CONFIG_TCP_CONG_BIC=y
#
CONFIG_STANDALONE=y
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
-# CONFIG_FW_LOADER is not set
# CONFIG_DEBUG_DRIVER is not set
# CONFIG_SYS_HYPERVISOR is not set
@@ -340,6 +373,7 @@ CONFIG_MTD_BLOCK=y
# CONFIG_NFTL is not set
# CONFIG_INFTL is not set
# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
#
# RAM/ROM/Flash chip drivers
@@ -422,11 +456,12 @@ CONFIG_MTD_IXP2000=y
# 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_NBD=y
# CONFIG_BLK_DEV_SX8 is not set
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
CONFIG_BLK_DEV_INITRD=y
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
@@ -436,6 +471,12 @@ CONFIG_BLK_DEV_INITRD=y
#
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
#
# Multi-device support (RAID and LVM)
@@ -501,8 +542,8 @@ CONFIG_NET_PCI=y
# CONFIG_FORCEDETH is not set
CONFIG_CS89x0=y
# CONFIG_DGRS is not set
-CONFIG_EEPRO100=y
-# CONFIG_E100 is not set
+# CONFIG_EEPRO100 is not set
+CONFIG_E100=y
# CONFIG_FEALNX is not set
# CONFIG_NATSEMI is not set
# CONFIG_NE2K_PCI is not set
@@ -532,6 +573,7 @@ CONFIG_ENP2611_MSF_NET=y
# CONFIG_VIA_VELOCITY is not set
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
#
# Ethernet (10000 Mbit)
@@ -540,6 +582,7 @@ CONFIG_ENP2611_MSF_NET=y
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
# CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
#
# Token Ring devices
@@ -555,7 +598,6 @@ CONFIG_ENP2611_MSF_NET=y
# Wan interfaces
#
CONFIG_WAN=y
-# CONFIG_DSCC4 is not set
# CONFIG_LANMEDIA is not set
CONFIG_HDLC=y
CONFIG_HDLC_RAW=y
@@ -571,6 +613,7 @@ CONFIG_HDLC_PPP=y
# CONFIG_WANXL is not set
# CONFIG_PC300 is not set
# CONFIG_FARSYNC is not set
+# CONFIG_DSCC4 is not set
CONFIG_DLCI=y
CONFIG_DLCI_COUNT=24
CONFIG_DLCI_MAX=8
@@ -592,6 +635,7 @@ CONFIG_DLCI_MAX=8
# Input device support
#
CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
#
# Userland interfaces
@@ -673,10 +717,6 @@ CONFIG_IXP2000_WATCHDOG=y
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
# CONFIG_DRM is not set
# CONFIG_RAW_DRIVER is not set
@@ -684,7 +724,6 @@ CONFIG_IXP2000_WATCHDOG=y
# TPM devices
#
# CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
#
# I2C support
@@ -749,6 +788,7 @@ CONFIG_SENSORS_EEPROM=y
#
# Dallas's 1-wire bus
#
+# CONFIG_W1 is not set
#
# Hardware Monitoring support
@@ -782,15 +822,18 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_LM92 is not set
# CONFIG_SENSORS_MAX1619 is not set
# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
# CONFIG_SENSORS_SIS5595 is not set
# CONFIG_SENSORS_SMSC47M1 is not set
# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_VT8231 is not set
# CONFIG_SENSORS_W83781D is not set
# CONFIG_SENSORS_W83791D is not set
# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
# CONFIG_SENSORS_W83L785TS is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
@@ -799,6 +842,8 @@ CONFIG_HWMON=y
#
# Misc devices
#
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
#
# LED devices
@@ -817,7 +862,6 @@ CONFIG_HWMON=y
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
#
# Digital Video Broadcasting Devices
@@ -829,6 +873,7 @@ CONFIG_VIDEO_V4L2=y
#
# CONFIG_FIRMWARE_EDID is not set
# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -836,6 +881,11 @@ CONFIG_VIDEO_V4L2=y
# CONFIG_SOUND is not set
#
+# HID Devices
+#
+CONFIG_HID=y
+
+#
# USB support
#
CONFIG_USB_ARCH_HAS_HCD=y
@@ -875,6 +925,7 @@ CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
CONFIG_EXT3_FS_POSIX_ACL=y
# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
CONFIG_JBD=y
# CONFIG_JBD_DEBUG is not set
CONFIG_FS_MBCACHE=y
@@ -882,6 +933,7 @@ CONFIG_FS_MBCACHE=y
# CONFIG_JFS_FS is not set
CONFIG_FS_POSIX_ACL=y
# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
@@ -910,8 +962,10 @@ CONFIG_DNOTIFY=y
# Pseudo filesystems
#
CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
# CONFIG_CONFIGFS_FS is not set
@@ -961,7 +1015,6 @@ CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
# CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
@@ -994,6 +1047,11 @@ CONFIG_MSDOS_PARTITION=y
# CONFIG_NLS is not set
#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
# Profiling support
#
# CONFIG_PROFILING is not set
@@ -1002,8 +1060,11 @@ CONFIG_MSDOS_PARTITION=y
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_DETECT_SOFTLOCKUP=y
@@ -1019,10 +1080,9 @@ CONFIG_DEBUG_MUTEXES=y
# CONFIG_DEBUG_KOBJECT is not set
CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_FS is not set
# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
CONFIG_FRAME_POINTER=y
-# CONFIG_UNWIND_INFO is not set
CONFIG_FORCED_INLINING=y
# CONFIG_RCU_TORTURE_TEST is not set
CONFIG_DEBUG_USER=y
@@ -1042,12 +1102,9 @@ CONFIG_DEBUG_LL=y
# CONFIG_CRYPTO is not set
#
-# Hardware crypto devices
-#
-
-#
# Library routines
#
+CONFIG_BITREVERSE=y
# CONFIG_CRC_CCITT is not set
# CONFIG_CRC16 is not set
CONFIG_CRC32=y
@@ -1055,3 +1112,4 @@ CONFIG_CRC32=y
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
CONFIG_PLIST=y
+CONFIG_IOMAP_COPY=y
diff --git a/arch/arm/configs/ixp23xx_defconfig b/arch/arm/configs/ixp23xx_defconfig
index 06deefaec1d2..27cf022dd807 100644
--- a/arch/arm/configs/ixp23xx_defconfig
+++ b/arch/arm/configs/ixp23xx_defconfig
@@ -1,14 +1,18 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Sun Jul 9 14:13:35 2006
+# Linux kernel version: 2.6.20-rc1
+# Sat Dec 16 06:05:45 2006
#
CONFIG_ARM=y
+# CONFIG_GENERIC_TIME is not set
CONFIG_MMU=y
CONFIG_GENERIC_HARDIRQS=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_VECTORS_BASE=0xffff0000
@@ -28,17 +32,22 @@ CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
# CONFIG_POSIX_MQUEUE is not set
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
# CONFIG_AUDIT is not set
# CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
# CONFIG_RELAY is not set
CONFIG_INITRAMFS_SOURCE=""
-CONFIG_UID16=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -47,12 +56,12 @@ CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_SHMEM=y
CONFIG_SLAB=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
# CONFIG_SLOB is not set
@@ -70,7 +79,10 @@ CONFIG_KMOD=y
#
# Block layer
#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
#
# IO Schedulers
@@ -102,7 +114,9 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
# CONFIG_ARCH_NETX is not set
# CONFIG_ARCH_H720X is not set
# CONFIG_ARCH_IMX is not set
-# CONFIG_ARCH_IOP3XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IOP13XX is not set
# CONFIG_ARCH_IXP4XX is not set
# CONFIG_ARCH_IXP2000 is not set
CONFIG_ARCH_IXP23XX=y
@@ -137,6 +151,8 @@ CONFIG_CPU_32v5=y
CONFIG_CPU_ABRT_EV5T=y
CONFIG_CPU_CACHE_VIVT=y
CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
CONFIG_IO_36=y
#
@@ -144,11 +160,15 @@ CONFIG_IO_36=y
#
# CONFIG_ARM_THUMB is not set
CONFIG_CPU_BIG_ENDIAN=y
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+# CONFIG_IWMMXT is not set
#
# Bus support
#
CONFIG_PCI=y
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
# CONFIG_PCI_DEBUG is not set
#
@@ -222,6 +242,7 @@ CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
CONFIG_XFRM=y
# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
# CONFIG_NET_KEY is not set
CONFIG_INET=y
# CONFIG_IP_MULTICAST is not set
@@ -242,13 +263,29 @@ CONFIG_SYN_COOKIES=y
# CONFIG_INET_TUNNEL is not set
CONFIG_INET_XFRM_MODE_TRANSPORT=y
CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
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_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
# CONFIG_INET6_XFRM_TUNNEL is not set
# CONFIG_INET6_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_BEET is not set
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+# CONFIG_IPV6_SIT is not set
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
# CONFIG_NETWORK_SECMARK is not set
# CONFIG_NETFILTER is not set
@@ -275,7 +312,6 @@ CONFIG_TCP_CONG_BIC=y
# 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
@@ -334,6 +370,7 @@ CONFIG_MTD_BLOCK=y
# CONFIG_NFTL is not set
# CONFIG_INFTL is not set
# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
#
# RAM/ROM/Flash chip drivers
@@ -418,12 +455,13 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=1
# 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_NBD=y
# 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=8192
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
CONFIG_BLK_DEV_INITRD=y
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
@@ -432,6 +470,7 @@ CONFIG_BLK_DEV_INITRD=y
# ATA/ATAPI/MFM/RLL support
#
CONFIG_IDE=y
+CONFIG_IDE_MAX_HWIFS=4
CONFIG_BLK_DEV_IDE=y
#
@@ -455,7 +494,6 @@ CONFIG_BLK_DEV_IDEPCI=y
# CONFIG_BLK_DEV_OFFBOARD is not set
# CONFIG_BLK_DEV_GENERIC is not set
# CONFIG_BLK_DEV_OPTI621 is not set
-# CONFIG_BLK_DEV_SL82C105 is not set
CONFIG_BLK_DEV_IDEDMA_PCI=y
# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
# CONFIG_IDEDMA_PCI_AUTO is not set
@@ -469,6 +507,7 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y
# CONFIG_BLK_DEV_CS5530 is not set
# CONFIG_BLK_DEV_HPT34X is not set
# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_JMICRON is not set
# CONFIG_BLK_DEV_SC1200 is not set
# CONFIG_BLK_DEV_PIIX is not set
# CONFIG_BLK_DEV_IT821X is not set
@@ -477,6 +516,7 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y
# CONFIG_BLK_DEV_PDC202XX_NEW is not set
# CONFIG_BLK_DEV_SVWKS is not set
CONFIG_BLK_DEV_SIIMAGE=y
+# CONFIG_BLK_DEV_SL82C105 is not set
# CONFIG_BLK_DEV_SLC90E66 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
@@ -491,6 +531,8 @@ CONFIG_BLK_DEV_IDEDMA=y
#
# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
CONFIG_SCSI_PROC_FS=y
#
@@ -509,14 +551,16 @@ CONFIG_BLK_DEV_SD=y
# CONFIG_SCSI_MULTI_LUN is not set
# CONFIG_SCSI_CONSTANTS is not set
# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
#
-# SCSI Transport Attributes
+# SCSI Transports
#
# 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
+# CONFIG_SCSI_SAS_LIBSAS is not set
#
# SCSI low-level drivers
@@ -529,26 +573,34 @@ CONFIG_BLK_DEV_SD=y
# CONFIG_SCSI_AIC7XXX is not set
# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ARCMSR 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_HPTIOP is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
# CONFIG_SCSI_IPS is not set
# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
# CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_IPR is not set
# CONFIG_SCSI_QLOGIC_1280 is not set
# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI 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
+# CONFIG_SCSI_SRP is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
#
# Multi-device support (RAID and LVM)
@@ -649,6 +701,7 @@ CONFIG_E1000_NAPI=y
# CONFIG_VIA_VELOCITY is not set
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
#
# Ethernet (10000 Mbit)
@@ -657,6 +710,7 @@ CONFIG_E1000_NAPI=y
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
# CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
#
# Token Ring devices
@@ -672,7 +726,6 @@ CONFIG_E1000_NAPI=y
# Wan interfaces
#
CONFIG_WAN=y
-# CONFIG_DSCC4 is not set
# CONFIG_LANMEDIA is not set
CONFIG_HDLC=y
CONFIG_HDLC_RAW=y
@@ -688,6 +741,7 @@ CONFIG_HDLC_PPP=y
# CONFIG_WANXL is not set
# CONFIG_PC300 is not set
# CONFIG_FARSYNC is not set
+# CONFIG_DSCC4 is not set
CONFIG_DLCI=y
CONFIG_DLCI_COUNT=24
CONFIG_DLCI_MAX=8
@@ -710,6 +764,7 @@ CONFIG_DLCI_MAX=8
# Input device support
#
CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
#
# Userland interfaces
@@ -795,10 +850,6 @@ CONFIG_WATCHDOG=y
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
# CONFIG_DRM is not set
# CONFIG_RAW_DRIVER is not set
@@ -806,7 +857,6 @@ CONFIG_WATCHDOG=y
# TPM devices
#
# CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
#
# I2C support
@@ -870,6 +920,7 @@ CONFIG_SENSORS_EEPROM=y
#
# Dallas's 1-wire bus
#
+# CONFIG_W1 is not set
#
# Hardware Monitoring support
@@ -903,15 +954,18 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_LM92 is not set
# CONFIG_SENSORS_MAX1619 is not set
# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
# CONFIG_SENSORS_SIS5595 is not set
# CONFIG_SENSORS_SMSC47M1 is not set
# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_VT8231 is not set
# CONFIG_SENSORS_W83781D is not set
# CONFIG_SENSORS_W83791D is not set
# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
# CONFIG_SENSORS_W83L785TS is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
@@ -920,6 +974,8 @@ CONFIG_HWMON=y
#
# Misc devices
#
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
#
# LED devices
@@ -938,7 +994,6 @@ CONFIG_HWMON=y
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
#
# Digital Video Broadcasting Devices
@@ -951,6 +1006,7 @@ CONFIG_VIDEO_V4L2=y
#
# CONFIG_FIRMWARE_EDID is not set
# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -958,6 +1014,11 @@ CONFIG_VIDEO_V4L2=y
# CONFIG_SOUND is not set
#
+# HID Devices
+#
+CONFIG_HID=y
+
+#
# USB support
#
CONFIG_USB_ARCH_HAS_HCD=y
@@ -972,6 +1033,7 @@ CONFIG_USB=y
# CONFIG_USB_DEVICEFS is not set
# CONFIG_USB_BANDWIDTH is not set
# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_MULTITHREAD_PROBE is not set
# CONFIG_USB_OTG is not set
#
@@ -1012,6 +1074,7 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_SDDR55 is not set
# CONFIG_USB_STORAGE_JUMPSHOT is not set
# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
# CONFIG_USB_LIBUSUAL is not set
#
@@ -1050,6 +1113,7 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_KAWETH is not set
# CONFIG_USB_PEGASUS is not set
# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET_MII is not set
# CONFIG_USB_USBNET is not set
CONFIG_USB_MON=y
@@ -1067,19 +1131,21 @@ CONFIG_USB_MON=y
#
# CONFIG_USB_EMI62 is not set
# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX 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_CY7C63 is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGETKIT is not set
-# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_PHIDGET is not set
# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
# CONFIG_USB_APPLEDISPLAY is not set
# CONFIG_USB_SISUSBVGA is not set
# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
#
# USB DSL modem support
@@ -1113,6 +1179,7 @@ CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
CONFIG_EXT3_FS_POSIX_ACL=y
# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
CONFIG_JBD=y
# CONFIG_JBD_DEBUG is not set
CONFIG_FS_MBCACHE=y
@@ -1120,6 +1187,7 @@ CONFIG_FS_MBCACHE=y
# CONFIG_JFS_FS is not set
CONFIG_FS_POSIX_ACL=y
# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
@@ -1150,8 +1218,10 @@ CONFIG_FAT_DEFAULT_CODEPAGE=437
# Pseudo filesystems
#
CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
# CONFIG_CONFIGFS_FS is not set
@@ -1201,7 +1271,6 @@ CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
# CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
@@ -1273,6 +1342,11 @@ CONFIG_NLS_CODEPAGE_437=y
# CONFIG_NLS_UTF8 is not set
#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
# Profiling support
#
# CONFIG_PROFILING is not set
@@ -1281,8 +1355,11 @@ CONFIG_NLS_CODEPAGE_437=y
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_DETECT_SOFTLOCKUP=y
@@ -1298,10 +1375,9 @@ CONFIG_DEBUG_MUTEXES=y
# CONFIG_DEBUG_KOBJECT is not set
CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_FS is not set
# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
CONFIG_FRAME_POINTER=y
-# CONFIG_UNWIND_INFO is not set
CONFIG_FORCED_INLINING=y
# CONFIG_RCU_TORTURE_TEST is not set
CONFIG_DEBUG_USER=y
@@ -1321,12 +1397,9 @@ CONFIG_DEBUG_LL=y
# CONFIG_CRYPTO is not set
#
-# Hardware crypto devices
-#
-
-#
# Library routines
#
+CONFIG_BITREVERSE=y
# CONFIG_CRC_CCITT is not set
# CONFIG_CRC16 is not set
CONFIG_CRC32=y
@@ -1334,3 +1407,4 @@ CONFIG_CRC32=y
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
CONFIG_PLIST=y
+CONFIG_IOMAP_COPY=y
diff --git a/arch/arm/configs/lpd270_defconfig b/arch/arm/configs/lpd270_defconfig
index e146189ab54f..a3bf5833b87a 100644
--- a/arch/arm/configs/lpd270_defconfig
+++ b/arch/arm/configs/lpd270_defconfig
@@ -1,14 +1,18 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Sun Jul 9 14:15:23 2006
+# Linux kernel version: 2.6.20-rc1
+# Sat Dec 16 06:05:51 2006
#
CONFIG_ARM=y
+# CONFIG_GENERIC_TIME is not set
CONFIG_MMU=y
CONFIG_GENERIC_HARDIRQS=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_ARCH_MTD_XIP=y
@@ -29,16 +33,21 @@ CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
# CONFIG_AUDIT is not set
# CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
# CONFIG_RELAY is not set
CONFIG_INITRAMFS_SOURCE=""
-CONFIG_UID16=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -47,12 +56,12 @@ CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_SHMEM=y
CONFIG_SLAB=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
# CONFIG_SLOB is not set
@@ -69,7 +78,10 @@ CONFIG_MODULES=y
#
# Block layer
#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
#
# IO Schedulers
@@ -101,7 +113,9 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
# CONFIG_ARCH_NETX is not set
# CONFIG_ARCH_H720X is not set
# CONFIG_ARCH_IMX is not set
-# CONFIG_ARCH_IOP3XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IOP13XX is not set
# CONFIG_ARCH_IXP4XX is not set
# CONFIG_ARCH_IXP2000 is not set
# CONFIG_ARCH_IXP23XX is not set
@@ -125,7 +139,6 @@ CONFIG_MACH_LOGICPD_PXA270=y
# CONFIG_PXA_SHARPSL is not set
# CONFIG_MACH_TRIZEPS4 is not set
CONFIG_PXA27x=y
-CONFIG_IWMMXT=y
#
# Processor Type
@@ -136,11 +149,15 @@ CONFIG_CPU_32v5=y
CONFIG_CPU_ABRT_EV5T=y
CONFIG_CPU_CACHE_VIVT=y
CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
#
# Processor Features
#
# CONFIG_ARM_THUMB is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+CONFIG_IWMMXT=y
CONFIG_XSCALE_PMU=y
#
@@ -217,6 +234,7 @@ CONFIG_NET=y
CONFIG_UNIX=y
CONFIG_XFRM=y
# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
# CONFIG_NET_KEY is not set
CONFIG_INET=y
# CONFIG_IP_MULTICAST is not set
@@ -237,13 +255,29 @@ CONFIG_IP_PNP_BOOTP=y
# CONFIG_INET_TUNNEL is not set
CONFIG_INET_XFRM_MODE_TRANSPORT=y
CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
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_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
# CONFIG_INET6_XFRM_TUNNEL is not set
# CONFIG_INET6_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_BEET is not set
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+# CONFIG_IPV6_SIT is not set
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
# CONFIG_NETWORK_SECMARK is not set
# CONFIG_NETFILTER is not set
@@ -270,7 +304,6 @@ CONFIG_TCP_CONG_BIC=y
# 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
@@ -329,6 +362,7 @@ CONFIG_MTD_BLOCK=y
# CONFIG_NFTL is not set
# CONFIG_INFTL is not set
# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
#
# RAM/ROM/Flash chip drivers
@@ -410,7 +444,7 @@ CONFIG_MTD_CFI_UTIL=y
#
# CONFIG_BLK_DEV_COW_COMMON is not set
# CONFIG_BLK_DEV_LOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_NBD=y
# CONFIG_BLK_DEV_RAM is not set
# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CDROM_PKTCDVD is not set
@@ -447,6 +481,12 @@ CONFIG_BLK_DEV_IDEDISK=y
#
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
#
# Multi-device support (RAID and LVM)
@@ -526,6 +566,7 @@ CONFIG_SMC91X=y
# Input device support
#
CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
#
# Userland interfaces
@@ -548,6 +589,7 @@ CONFIG_KEYBOARD_ATKBD=y
# CONFIG_KEYBOARD_LKKBD is not set
# CONFIG_KEYBOARD_XTKBD is not set
# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
@@ -600,17 +642,12 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_NVRAM 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
#
# CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
#
# I2C support
@@ -626,6 +663,7 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# Dallas's 1-wire bus
#
+# CONFIG_W1 is not set
#
# Hardware Monitoring support
@@ -634,11 +672,14 @@ CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
# CONFIG_SENSORS_ABITUGURU is not set
# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_VT1211 is not set
# CONFIG_HWMON_DEBUG_CHIP is not set
#
# Misc devices
#
+# CONFIG_TIFM_CORE is not set
#
# LED devices
@@ -657,7 +698,6 @@ CONFIG_HWMON=y
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
#
# Digital Video Broadcasting Devices
@@ -679,6 +719,7 @@ CONFIG_FB_CFB_IMAGEBLIT=y
# CONFIG_FB_S1D13XXX is not set
CONFIG_FB_PXA=y
# CONFIG_FB_PXA_PARAMETERS is not set
+# CONFIG_FB_MBX is not set
# CONFIG_FB_VIRTUAL is not set
#
@@ -725,7 +766,6 @@ CONFIG_SND_VERBOSE_PROCFS=y
# Generic devices
#
CONFIG_SND_AC97_CODEC=y
-CONFIG_SND_AC97_BUS=y
# CONFIG_SND_DUMMY is not set
# CONFIG_SND_MTPAV is not set
# CONFIG_SND_SERIAL_U16550 is not set
@@ -741,6 +781,12 @@ CONFIG_SND_PXA2XX_AC97=y
# Open Sound System
#
# CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=y
+
+#
+# HID Devices
+#
+CONFIG_HID=y
#
# USB support
@@ -777,10 +823,12 @@ 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_EXT4DEV_FS 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_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
@@ -811,6 +859,7 @@ CONFIG_FAT_DEFAULT_CODEPAGE=437
# Pseudo filesystems
#
CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
@@ -860,7 +909,6 @@ CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
# CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
@@ -917,6 +965,11 @@ CONFIG_NLS_ISO8859_1=y
# CONFIG_NLS_UTF8 is not set
#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
# Profiling support
#
# CONFIG_PROFILING is not set
@@ -925,8 +978,11 @@ CONFIG_NLS_ISO8859_1=y
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_DETECT_SOFTLOCKUP=y
@@ -942,10 +998,9 @@ CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_DEBUG_KOBJECT is not set
CONFIG_DEBUG_BUGVERBOSE=y
CONFIG_DEBUG_INFO=y
-# CONFIG_DEBUG_FS is not set
# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
CONFIG_FRAME_POINTER=y
-# CONFIG_UNWIND_INFO is not set
CONFIG_FORCED_INLINING=y
# CONFIG_RCU_TORTURE_TEST is not set
CONFIG_DEBUG_USER=y
@@ -965,12 +1020,9 @@ CONFIG_DEBUG_LL=y
# CONFIG_CRYPTO is not set
#
-# Hardware crypto devices
-#
-
-#
# Library routines
#
+CONFIG_BITREVERSE=y
# CONFIG_CRC_CCITT is not set
# CONFIG_CRC16 is not set
CONFIG_CRC32=y
@@ -978,3 +1030,4 @@ CONFIG_CRC32=y
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
CONFIG_PLIST=y
+CONFIG_IOMAP_COPY=y
diff --git a/arch/arm/configs/onearm_defconfig b/arch/arm/configs/onearm_defconfig
index 0498ebd7d5de..650a248613e5 100644
--- a/arch/arm/configs/onearm_defconfig
+++ b/arch/arm/configs/onearm_defconfig
@@ -1,14 +1,18 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Sun Jul 9 14:16:20 2006
+# Linux kernel version: 2.6.20-rc1
+# Sat Dec 16 06:05:18 2006
#
CONFIG_ARM=y
+# CONFIG_GENERIC_TIME is not set
CONFIG_MMU=y
CONFIG_GENERIC_HARDIRQS=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_VECTORS_BASE=0xffff0000
@@ -28,16 +32,21 @@ CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
# CONFIG_SWAP is not set
CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
# CONFIG_AUDIT is not set
# CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
# CONFIG_RELAY is not set
CONFIG_INITRAMFS_SOURCE=""
-CONFIG_UID16=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -46,12 +55,12 @@ CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_SHMEM=y
CONFIG_SLAB=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
# CONFIG_SLOB is not set
@@ -69,7 +78,10 @@ CONFIG_KMOD=y
#
# Block layer
#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
#
# IO Schedulers
@@ -101,7 +113,9 @@ CONFIG_ARCH_AT91=y
# CONFIG_ARCH_NETX is not set
# CONFIG_ARCH_H720X is not set
# CONFIG_ARCH_IMX is not set
-# CONFIG_ARCH_IOP3XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IOP13XX is not set
# CONFIG_ARCH_IXP4XX is not set
# CONFIG_ARCH_IXP2000 is not set
# CONFIG_ARCH_IXP23XX is not set
@@ -118,10 +132,6 @@ CONFIG_ARCH_AT91=y
#
# Atmel AT91 System-on-Chip
#
-
-#
-# Atmel AT91 Processors
-#
CONFIG_ARCH_AT91RM9200=y
# CONFIG_ARCH_AT91SAM9260 is not set
# CONFIG_ARCH_AT91SAM9261 is not set
@@ -140,6 +150,10 @@ CONFIG_MACH_ONEARM=y
# CONFIG_MACH_KAFA is not set
#
+# AT91 Board Options
+#
+
+#
# AT91 Feature Selections
#
CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
@@ -149,12 +163,14 @@ CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
#
CONFIG_CPU_32=y
CONFIG_CPU_ARM920T=y
-CONFIG_CPU_32v4=y
+CONFIG_CPU_32v4T=y
CONFIG_CPU_ABRT_EV4T=y
CONFIG_CPU_CACHE_V4WT=y
CONFIG_CPU_CACHE_VIVT=y
CONFIG_CPU_COPY_V4WB=y
CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
#
# Processor Features
@@ -251,6 +267,7 @@ CONFIG_PACKET=y
CONFIG_UNIX=y
CONFIG_XFRM=y
# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
# CONFIG_NET_KEY is not set
CONFIG_INET=y
# CONFIG_IP_MULTICAST is not set
@@ -271,13 +288,29 @@ CONFIG_IP_PNP_BOOTP=y
# CONFIG_INET_TUNNEL is not set
CONFIG_INET_XFRM_MODE_TRANSPORT=y
CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
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_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
# CONFIG_INET6_XFRM_TUNNEL is not set
# CONFIG_INET6_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_BEET is not set
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+# CONFIG_IPV6_SIT is not set
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
# CONFIG_NETWORK_SECMARK is not set
# CONFIG_NETFILTER is not set
@@ -304,7 +337,6 @@ CONFIG_TCP_CONG_BIC=y
# 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
@@ -360,6 +392,7 @@ CONFIG_MTD_BLOCK=y
# CONFIG_NFTL is not set
# CONFIG_INFTL is not set
# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
#
# RAM/ROM/Flash chip drivers
@@ -438,11 +471,12 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=0
#
# CONFIG_BLK_DEV_COW_COMMON is not set
# CONFIG_BLK_DEV_LOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_NBD=y
# CONFIG_BLK_DEV_UB is not set
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
CONFIG_BLK_DEV_INITRD=y
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
@@ -457,6 +491,12 @@ CONFIG_BLK_DEV_INITRD=y
#
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
#
# Multi-device support (RAID and LVM)
@@ -541,6 +581,7 @@ CONFIG_ARM_AT91_ETHER=y
# Input device support
#
CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
#
# Userland interfaces
@@ -619,10 +660,6 @@ CONFIG_AT91RM9200_WATCHDOG=y
# CONFIG_R3964 is not set
#
-# Ftape, the floppy tape device driver
-#
-
-#
# PCMCIA character devices
#
# CONFIG_SYNCLINK_CS is not set
@@ -634,7 +671,6 @@ CONFIG_AT91RM9200_WATCHDOG=y
# TPM devices
#
# CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
#
# I2C support
@@ -652,6 +688,7 @@ CONFIG_I2C_CHARDEV=y
#
# I2C Hardware Bus support
#
+# CONFIG_I2C_AT91 is not set
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_PARPORT_LIGHT is not set
# CONFIG_I2C_STUB is not set
@@ -681,6 +718,7 @@ CONFIG_I2C_CHARDEV=y
#
# Dallas's 1-wire bus
#
+# CONFIG_W1 is not set
#
# Hardware Monitoring support
@@ -714,12 +752,15 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_LM92 is not set
# CONFIG_SENSORS_MAX1619 is not set
# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
# CONFIG_SENSORS_SMSC47M1 is not set
# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_W83781D is not set
# CONFIG_SENSORS_W83791D is not set
# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
# CONFIG_SENSORS_W83L785TS is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
@@ -728,6 +769,7 @@ CONFIG_HWMON=y
#
# Misc devices
#
+# CONFIG_TIFM_CORE is not set
#
# LED devices
@@ -746,7 +788,6 @@ CONFIG_HWMON=y
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
#
# Digital Video Broadcasting Devices
@@ -759,6 +800,7 @@ CONFIG_VIDEO_V4L2=y
#
# CONFIG_FIRMWARE_EDID is not set
# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -766,6 +808,11 @@ CONFIG_VIDEO_V4L2=y
# CONFIG_SOUND is not set
#
+# HID Devices
+#
+CONFIG_HID=y
+
+#
# USB support
#
CONFIG_USB_ARCH_HAS_HCD=y
@@ -780,6 +827,7 @@ CONFIG_USB_DEBUG=y
CONFIG_USB_DEVICEFS=y
# CONFIG_USB_BANDWIDTH is not set
# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_MULTITHREAD_PROBE is not set
# CONFIG_USB_OTG is not set
#
@@ -804,7 +852,6 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
#
# may also be needed; see USB_STORAGE Help for more information
#
-# CONFIG_USB_STORAGE is not set
# CONFIG_USB_LIBUSUAL is not set
#
@@ -842,6 +889,7 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_USB_KAWETH is not set
# CONFIG_USB_PEGASUS is not set
# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET_MII is not set
# CONFIG_USB_USBNET is not set
CONFIG_USB_MON=y
@@ -859,18 +907,20 @@ CONFIG_USB_MON=y
#
# CONFIG_USB_EMI62 is not set
# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX 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_CY7C63 is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGETKIT is not set
-# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_PHIDGET is not set
# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
# CONFIG_USB_APPLEDISPLAY is not set
# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
# CONFIG_USB_TEST is not set
#
@@ -897,6 +947,7 @@ CONFIG_USB_AT91=y
# CONFIG_USB_GADGETFS is not set
# CONFIG_USB_FILE_STORAGE is not set
# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
#
# MMC/SD Card support
@@ -904,7 +955,8 @@ CONFIG_USB_AT91=y
CONFIG_MMC=y
# CONFIG_MMC_DEBUG is not set
CONFIG_MMC_BLOCK=y
-CONFIG_MMC_AT91RM9200=y
+# CONFIG_MMC_AT91 is not set
+# CONFIG_MMC_TIFM_SD is not set
#
# Real Time Clock
@@ -919,10 +971,12 @@ 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_EXT4DEV_FS is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
CONFIG_FS_POSIX_ACL=y
# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
@@ -951,8 +1005,10 @@ CONFIG_DNOTIFY=y
# Pseudo filesystems
#
CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
# CONFIG_CONFIGFS_FS is not set
@@ -995,7 +1051,6 @@ CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
# CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
@@ -1013,6 +1068,11 @@ CONFIG_MSDOS_PARTITION=y
# CONFIG_NLS is not set
#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
# Profiling support
#
# CONFIG_PROFILING is not set
@@ -1021,8 +1081,11 @@ CONFIG_MSDOS_PARTITION=y
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_DETECT_SOFTLOCKUP=y
@@ -1038,10 +1101,9 @@ CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_DEBUG_KOBJECT is not set
CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_FS is not set
# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
CONFIG_FRAME_POINTER=y
-# CONFIG_UNWIND_INFO is not set
CONFIG_FORCED_INLINING=y
# CONFIG_RCU_TORTURE_TEST is not set
CONFIG_DEBUG_USER=y
@@ -1061,15 +1123,13 @@ CONFIG_DEBUG_LL=y
# CONFIG_CRYPTO is not set
#
-# Hardware crypto devices
-#
-
-#
# Library routines
#
+CONFIG_BITREVERSE=y
# CONFIG_CRC_CCITT is not set
# CONFIG_CRC16 is not set
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
CONFIG_PLIST=y
+CONFIG_IOMAP_COPY=y
diff --git a/arch/arm/kernel/apm.c b/arch/arm/kernel/apm.c
index a11fb9a40c04..2c37b70b17ab 100644
--- a/arch/arm/kernel/apm.c
+++ b/arch/arm/kernel/apm.c
@@ -423,7 +423,7 @@ static int apm_open(struct inode * inode, struct file * filp)
{
struct apm_user *as;
- as = (struct apm_user *)kzalloc(sizeof(*as), GFP_KERNEL);
+ as = kzalloc(sizeof(*as), GFP_KERNEL);
if (as) {
/*
* XXX - this is a tiny bit broken, when we consider BSD
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
index 3173924a9b60..f7598cbc7ec5 100644
--- a/arch/arm/kernel/calls.S
+++ b/arch/arm/kernel/calls.S
@@ -110,7 +110,7 @@
CALL(sys_ni_syscall) /* was sys_profil */
CALL(sys_statfs)
/* 100 */ CALL(sys_fstatfs)
- CALL(sys_ni_syscall)
+ CALL(sys_ni_syscall) /* sys_ioperm */
CALL(OBSOLETE(ABI(sys_socketcall, sys_oabi_socketcall)))
CALL(sys_syslog)
CALL(sys_setitimer)
@@ -132,7 +132,7 @@
/* 120 */ CALL(sys_clone_wrapper)
CALL(sys_setdomainname)
CALL(sys_newuname)
- CALL(sys_ni_syscall)
+ CALL(sys_ni_syscall) /* modify_ldt */
CALL(sys_adjtimex)
/* 125 */ CALL(sys_mprotect)
CALL(sys_sigprocmask)
@@ -146,7 +146,7 @@
CALL(sys_bdflush)
/* 135 */ CALL(sys_sysfs)
CALL(sys_personality)
- CALL(sys_ni_syscall) /* CALL(_sys_afs_syscall) */
+ CALL(sys_ni_syscall) /* reserved for afs_syscall */
CALL(sys_setfsuid16)
CALL(sys_setfsgid16)
/* 140 */ CALL(sys_llseek)
@@ -175,7 +175,7 @@
CALL(sys_arm_mremap)
CALL(sys_setresuid16)
/* 165 */ CALL(sys_getresuid16)
- CALL(sys_ni_syscall)
+ CALL(sys_ni_syscall) /* vm86 */
CALL(sys_ni_syscall) /* was sys_query_module */
CALL(sys_poll)
CALL(sys_nfsservctl)
@@ -197,8 +197,8 @@
/* 185 */ CALL(sys_capset)
CALL(sys_sigaltstack_wrapper)
CALL(sys_sendfile)
- CALL(sys_ni_syscall)
- CALL(sys_ni_syscall)
+ CALL(sys_ni_syscall) /* getpmsg */
+ CALL(sys_ni_syscall) /* putpmsg */
/* 190 */ CALL(sys_vfork_wrapper)
CALL(sys_getrlimit)
CALL(sys_mmap2)
@@ -331,6 +331,31 @@
CALL(sys_mbind)
/* 320 */ CALL(sys_get_mempolicy)
CALL(sys_set_mempolicy)
+ CALL(sys_openat)
+ CALL(sys_mkdirat)
+ CALL(sys_mknodat)
+/* 325 */ CALL(sys_fchownat)
+ CALL(sys_futimesat)
+ CALL(sys_fstatat64)
+ CALL(sys_unlinkat)
+ CALL(sys_renameat)
+/* 330 */ CALL(sys_linkat)
+ CALL(sys_symlinkat)
+ CALL(sys_readlinkat)
+ CALL(sys_fchmodat)
+ CALL(sys_faccessat)
+/* 335 */ CALL(sys_ni_syscall) /* eventually pselect6 */
+ CALL(sys_ni_syscall) /* eventually ppoll */
+ CALL(sys_unshare)
+ CALL(sys_set_robust_list)
+ CALL(sys_get_robust_list)
+/* 340 */ CALL(sys_splice)
+ CALL(sys_arm_sync_file_range)
+ CALL(sys_tee)
+ CALL(sys_vmsplice)
+ CALL(sys_move_pages)
+/* 345 */ CALL(sys_getcpu)
+ CALL(sys_ni_syscall) /* eventually epoll_pwait */
#ifndef syscalls_counted
.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
#define syscalls_counted
diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c
index a786f769035d..71257e3d513f 100644
--- a/arch/arm/kernel/ecard.c
+++ b/arch/arm/kernel/ecard.c
@@ -353,7 +353,7 @@ int ecard_readchunk(struct in_chunk_dir *cd, ecard_t *ec, int id, int num)
}
if (c_id(&excd) == 0x80) { /* loader */
if (!ec->loader) {
- ec->loader = (loader_t)kmalloc(c_len(&excd),
+ ec->loader = kmalloc(c_len(&excd),
GFP_KERNEL);
if (ec->loader)
ecard_readbytes(ec->loader, ec,
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index bda0748ffb00..d994561816a1 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -22,30 +22,31 @@
#include <asm/thread_info.h>
#include <asm/system.h>
-#define KERNEL_RAM_ADDR (PAGE_OFFSET + TEXT_OFFSET)
+#define KERNEL_RAM_VADDR (PAGE_OFFSET + TEXT_OFFSET)
+#define KERNEL_RAM_PADDR (PHYS_OFFSET + TEXT_OFFSET)
/*
* swapper_pg_dir is the virtual address of the initial page table.
- * We place the page tables 16K below KERNEL_RAM_ADDR. Therefore, we must
- * make sure that KERNEL_RAM_ADDR is correctly set. Currently, we expect
+ * We place the page tables 16K below KERNEL_RAM_VADDR. Therefore, we must
+ * make sure that KERNEL_RAM_VADDR is correctly set. Currently, we expect
* the least significant 16 bits to be 0x8000, but we could probably
- * relax this restriction to KERNEL_RAM_ADDR >= PAGE_OFFSET + 0x4000.
+ * relax this restriction to KERNEL_RAM_VADDR >= PAGE_OFFSET + 0x4000.
*/
-#if (KERNEL_RAM_ADDR & 0xffff) != 0x8000
-#error KERNEL_RAM_ADDR must start at 0xXXXX8000
+#if (KERNEL_RAM_VADDR & 0xffff) != 0x8000
+#error KERNEL_RAM_VADDR must start at 0xXXXX8000
#endif
.globl swapper_pg_dir
- .equ swapper_pg_dir, KERNEL_RAM_ADDR - 0x4000
+ .equ swapper_pg_dir, KERNEL_RAM_VADDR - 0x4000
.macro pgtbl, rd
- ldr \rd, =(__virt_to_phys(KERNEL_RAM_ADDR - 0x4000))
+ ldr \rd, =(KERNEL_RAM_PADDR - 0x4000)
.endm
#ifdef CONFIG_XIP_KERNEL
#define TEXTADDR XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR)
#else
-#define TEXTADDR KERNEL_RAM_ADDR
+#define TEXTADDR KERNEL_RAM_VADDR
#endif
/*
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 238dd9b6db84..bbab134cd82d 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -354,9 +354,6 @@ static void __init setup_processor(void)
#ifndef CONFIG_ARM_THUMB
elf_hwcap &= ~HWCAP_THUMB;
#endif
-#ifndef CONFIG_VFP
- elf_hwcap &= ~HWCAP_VFP;
-#endif
cpu_proc_init();
}
@@ -858,6 +855,7 @@ static const char *hwcap_str[] = {
"edsp",
"java",
"iwmmxt",
+ "crunch",
NULL
};
diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c
index 00c18d35913c..3d4fcbc16276 100644
--- a/arch/arm/kernel/sys_arm.c
+++ b/arch/arm/kernel/sys_arm.c
@@ -328,3 +328,16 @@ asmlinkage long sys_arm_fadvise64_64(int fd, int advice,
{
return sys_fadvise64_64(fd, offset, len, advice);
}
+
+/*
+ * Yet more syscall fsckage - we can't fit sys_sync_file_range's
+ * arguments into the available registers with EABI. So, let's
+ * create an ARM specific syscall for this which has _sane_
+ * arguments. (This incidentally also has an ABI-independent
+ * argument layout.)
+ */
+asmlinkage long sys_arm_sync_file_range(int fd, unsigned int flags,
+ loff_t offset, loff_t nbytes)
+{
+ return sys_sync_file_range(fd, offset, nbytes, flags);
+}
diff --git a/arch/arm/mach-at91rm9200/at91sam9260_devices.c b/arch/arm/mach-at91rm9200/at91sam9260_devices.c
index a6c596dc4516..f42d3a40ec3c 100644
--- a/arch/arm/mach-at91rm9200/at91sam9260_devices.c
+++ b/arch/arm/mach-at91rm9200/at91sam9260_devices.c
@@ -18,6 +18,7 @@
#include <asm/arch/gpio.h>
#include <asm/arch/at91sam9260.h>
#include <asm/arch/at91sam926x_mc.h>
+#include <asm/arch/at91sam9260_matrix.h>
#include "generic.h"
diff --git a/arch/arm/mach-at91rm9200/board-sam9260ek.c b/arch/arm/mach-at91rm9200/board-sam9260ek.c
index ffca9bdec37b..da5d58ac870b 100644
--- a/arch/arm/mach-at91rm9200/board-sam9260ek.c
+++ b/arch/arm/mach-at91rm9200/board-sam9260ek.c
@@ -119,6 +119,7 @@ static struct spi_board_info ek_spi_devices[] = {
* MACB Ethernet device
*/
static struct __initdata eth_platform_data ek_macb_data = {
+ .phy_irq_pin = AT91_PIN_PA7,
.is_rmii = 1,
};
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index d649b39711d4..6b26346191c0 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -477,4 +477,8 @@ void __init ep93xx_init_devices(void)
platform_device_register(&ep93xx_rtc_device);
platform_device_register(&ep93xx_ohci_device);
+
+#ifdef CONFIG_CRUNCH
+ elf_hwcap |= HWCAP_CRUNCH;
+#endif
}
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 0b27d79f2efd..02272aa36e90 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -9,6 +9,8 @@
obj-y += irq.o time.o dma.o generic.o
+obj-$(CONFIG_CPU_FREQ_IMX) += cpufreq.o
+
# Specific board support
obj-$(CONFIG_ARCH_MX1ADS) += mx1ads.o
diff --git a/arch/arm/mach-imx/cpufreq.c b/arch/arm/mach-imx/cpufreq.c
new file mode 100644
index 000000000000..ac5f99895660
--- /dev/null
+++ b/arch/arm/mach-imx/cpufreq.c
@@ -0,0 +1,287 @@
+/*
+ * cpu.c: clock scaling for the iMX
+ *
+ * Copyright (C) 2000 2001, The Delft University of Technology
+ * Copyright (c) 2004 Sascha Hauer <sascha@saschahauer.de>
+ * Copyright (C) 2006 Inky Lung <ilung@cwlinux.com>
+ * Copyright (C) 2006 Pavel Pisa, PiKRON <ppisa@pikron.com>
+ *
+ * Based on SA1100 version written by:
+ * - Johan Pouwelse (J.A.Pouwelse@its.tudelft.nl): initial version
+ * - Erik Mouw (J.A.K.Mouw@its.tudelft.nl):
+ *
+ * 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*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <asm/system.h>
+
+#include <asm/hardware.h>
+
+#include "generic.h"
+
+#ifndef __val2mfld
+#define __val2mfld(mask,val) (((mask)&~((mask)<<1))*(val)&(mask))
+#endif
+#ifndef __mfld2val
+#define __mfld2val(mask,val) (((val)&(mask))/((mask)&~((mask)<<1)))
+#endif
+
+#define CR_920T_CLOCK_MODE 0xC0000000
+#define CR_920T_FASTBUS_MODE 0x00000000
+#define CR_920T_ASYNC_MODE 0xC0000000
+
+static u32 mpctl0_at_boot;
+
+static void imx_set_async_mode(void)
+{
+ adjust_cr(CR_920T_CLOCK_MODE, CR_920T_ASYNC_MODE);
+}
+
+static void imx_set_fastbus_mode(void)
+{
+ adjust_cr(CR_920T_CLOCK_MODE, CR_920T_FASTBUS_MODE);
+}
+
+static void imx_set_mpctl0(u32 mpctl0)
+{
+ unsigned long flags;
+
+ if (mpctl0 == 0) {
+ local_irq_save(flags);
+ CSCR &= ~CSCR_MPEN;
+ local_irq_restore(flags);
+ return;
+ }
+
+ local_irq_save(flags);
+ MPCTL0 = mpctl0;
+ CSCR |= CSCR_MPEN;
+ local_irq_restore(flags);
+}
+
+/**
+ * imx_compute_mpctl - compute new PLL parameters
+ * @new_mpctl: pointer to location assigned by new PLL control register value
+ * @cur_mpctl: current PLL control register parameters
+ * @freq: required frequency in Hz
+ * @relation: is one of %CPUFREQ_RELATION_L (supremum)
+ * and %CPUFREQ_RELATION_H (infimum)
+ */
+long imx_compute_mpctl(u32 *new_mpctl, u32 cur_mpctl, unsigned long freq, int relation)
+{
+ u32 f_ref = (CSCR & CSCR_SYSTEM_SEL) ? 16000000 : (CLK32 * 512);
+ u32 mfi;
+ u32 mfn;
+ u32 mfd;
+ u32 pd;
+ unsigned long long ll;
+ long l;
+ long quot;
+
+ /* Fdppl=2*Fref*(MFI+MFN/(MFD+1))/(PD+1) */
+ /* PD=<0,15>, MFD=<1,1023>, MFI=<5,15> MFN=<0,1022> */
+
+ if (cur_mpctl) {
+ mfd = ((cur_mpctl >> 16) & 0x3ff) + 1;
+ pd = ((cur_mpctl >> 26) & 0xf) + 1;
+ } else {
+ pd=2; mfd=313;
+ }
+
+ /* pd=2; mfd=313; mfi=8; mfn=183; */
+ /* (MFI+MFN/(MFD)) = Fdppl / (2*Fref) * (PD); */
+
+ quot = (f_ref + (1 << 9)) >> 10;
+ l = (freq * pd + quot) / (2 * quot);
+ mfi = l >> 10;
+ mfn = ((l & ((1 << 10) - 1)) * mfd + (1 << 9)) >> 10;
+
+ mfd -= 1;
+ pd -= 1;
+
+ *new_mpctl = ((mfi & 0xf) << 10) | (mfn & 0x3ff) | ((mfd & 0x3ff) << 16)
+ | ((pd & 0xf) << 26);
+
+ ll = 2 * (unsigned long long)f_ref * ( (mfi<<16) + (mfn<<16) / (mfd+1) );
+ quot = (pd+1) * (1<<16);
+ ll += quot / 2;
+ do_div(ll, quot);
+ freq = ll;
+
+ pr_debug(KERN_DEBUG "imx: new PLL parameters pd=%d mfd=%d mfi=%d mfn=%d, freq=%ld\n",
+ pd, mfd, mfi, mfn, freq);
+
+ return freq;
+}
+
+
+static int imx_verify_speed(struct cpufreq_policy *policy)
+{
+ if (policy->cpu != 0)
+ return -EINVAL;
+
+ cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, policy->cpuinfo.max_freq);
+
+ return 0;
+}
+
+static unsigned int imx_get_speed(unsigned int cpu)
+{
+ unsigned int freq;
+ unsigned int cr;
+ unsigned int cscr;
+ unsigned int bclk_div;
+
+ if (cpu)
+ return 0;
+
+ cscr = CSCR;
+ bclk_div = __mfld2val(CSCR_BCLK_DIV, cscr) + 1;
+ cr = get_cr();
+
+ if((cr & CR_920T_CLOCK_MODE) == CR_920T_FASTBUS_MODE) {
+ freq = imx_get_system_clk();
+ freq = (freq + bclk_div/2) / bclk_div;
+ } else {
+ freq = imx_get_mcu_clk();
+ if (cscr & CSCR_MPU_PRESC)
+ freq /= 2;
+ }
+
+ freq = (freq + 500) / 1000;
+
+ return freq;
+}
+
+static int imx_set_target(struct cpufreq_policy *policy,
+ unsigned int target_freq,
+ unsigned int relation)
+{
+ struct cpufreq_freqs freqs;
+ u32 mpctl0 = 0;
+ u32 cscr;
+ unsigned long flags;
+ long freq;
+ long sysclk;
+ unsigned int bclk_div = 1;
+
+ freq = target_freq * 1000;
+
+ pr_debug(KERN_DEBUG "imx: requested frequency %ld Hz, mpctl0 at boot 0x%08x\n",
+ freq, mpctl0_at_boot);
+
+ sysclk = imx_get_system_clk();
+
+ if (freq > sysclk + 1000000) {
+ freq = imx_compute_mpctl(&mpctl0, mpctl0_at_boot, freq, relation);
+ if (freq < 0) {
+ printk(KERN_WARNING "imx: target frequency %ld Hz cannot be set\n", freq);
+ return -EINVAL;
+ }
+ } else {
+ if(freq + 1000 < sysclk) {
+ if (relation == CPUFREQ_RELATION_L)
+ bclk_div = (sysclk - 1000) / freq;
+ else
+ bclk_div = (sysclk + freq + 1000) / freq;
+
+ if(bclk_div > 16)
+ bclk_div = 16;
+ }
+ freq = (sysclk + bclk_div / 2) / bclk_div;
+ }
+
+ freqs.old = imx_get_speed(0);
+ freqs.new = (freq + 500) / 1000;
+ freqs.cpu = 0;
+ freqs.flags = 0;
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+ local_irq_save(flags);
+
+ imx_set_fastbus_mode();
+
+ imx_set_mpctl0(mpctl0);
+
+ cscr = CSCR;
+ cscr &= ~CSCR_BCLK_DIV;
+ cscr |= __val2mfld(CSCR_BCLK_DIV, bclk_div - 1);
+ CSCR = cscr;
+
+ if(mpctl0) {
+ CSCR |= CSCR_MPLL_RESTART;
+
+ /* Wait until MPLL is stablized */
+ while( CSCR & CSCR_MPLL_RESTART );
+
+ imx_set_async_mode();
+ }
+
+ local_irq_restore(flags);
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+ pr_debug(KERN_INFO "imx: set frequency %ld Hz, running from %s\n",
+ freq, mpctl0? "MPLL": "SPLL");
+
+ return 0;
+}
+
+static int __init imx_cpufreq_driver_init(struct cpufreq_policy *policy)
+{
+ printk(KERN_INFO "i.MX cpu freq change driver v1.0\n");
+
+ if (policy->cpu != 0)
+ return -EINVAL;
+
+ policy->cur = policy->min = policy->max = imx_get_speed(0);
+ policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
+ policy->cpuinfo.min_freq = 8000;
+ policy->cpuinfo.max_freq = 200000;
+ policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+ return 0;
+}
+
+static struct cpufreq_driver imx_driver = {
+ .flags = CPUFREQ_STICKY,
+ .verify = imx_verify_speed,
+ .target = imx_set_target,
+ .get = imx_get_speed,
+ .init = imx_cpufreq_driver_init,
+ .name = "imx",
+};
+
+static int __init imx_cpufreq_init(void)
+{
+
+ mpctl0_at_boot = 0;
+
+ if((CSCR & CSCR_MPEN) &&
+ ((get_cr() & CR_920T_CLOCK_MODE) != CR_920T_FASTBUS_MODE))
+ mpctl0_at_boot = MPCTL0;
+
+ return cpufreq_register_driver(&imx_driver);
+}
+
+arch_initcall(imx_cpufreq_init);
+
diff --git a/arch/arm/mach-iop13xx/io.c b/arch/arm/mach-iop13xx/io.c
index fbf9f88e46ea..e79a1b62600f 100644
--- a/arch/arm/mach-iop13xx/io.c
+++ b/arch/arm/mach-iop13xx/io.c
@@ -21,6 +21,25 @@
#include <asm/hardware.h>
#include <asm/io.h>
+void * __iomem __iop13xx_io(unsigned long io_addr)
+{
+ void __iomem * io_virt;
+
+ switch (io_addr) {
+ case IOP13XX_PCIE_LOWER_IO_PA ... IOP13XX_PCIE_UPPER_IO_PA:
+ io_virt = (void *) IOP13XX_PCIE_IO_PHYS_TO_VIRT(io_addr);
+ break;
+ case IOP13XX_PCIX_LOWER_IO_PA ... IOP13XX_PCIX_UPPER_IO_PA:
+ io_virt = (void *) IOP13XX_PCIX_IO_PHYS_TO_VIRT(io_addr);
+ break;
+ default:
+ BUG();
+ }
+
+ return io_virt;
+}
+EXPORT_SYMBOL(__iop13xx_io);
+
void * __iomem __iop13xx_ioremap(unsigned long cookie, size_t size,
unsigned long flags)
{
diff --git a/arch/arm/mach-iop13xx/iq81340mc.c b/arch/arm/mach-iop13xx/iq81340mc.c
index ee595786cd22..2a1bbfe9896f 100644
--- a/arch/arm/mach-iop13xx/iq81340mc.c
+++ b/arch/arm/mach-iop13xx/iq81340mc.c
@@ -88,11 +88,11 @@ static struct sys_timer iq81340mc_timer = {
MACHINE_START(IQ81340MC, "Intel IQ81340MC")
/* Maintainer: Dan Williams <dan.j.williams@intel.com> */
- .phys_io = PHYS_IO,
- .io_pg_offst = IO_PG_OFFSET,
+ .phys_io = IOP13XX_PMMR_PHYS_MEM_BASE,
+ .io_pg_offst = (IOP13XX_PMMR_VIRT_MEM_BASE >> 18) & 0xfffc,
+ .boot_params = 0x00000100,
.map_io = iop13xx_map_io,
.init_irq = iop13xx_init_irq,
.timer = &iq81340mc_timer,
- .boot_params = BOOT_PARAM_OFFSET,
.init_machine = iq81340mc_init,
MACHINE_END
diff --git a/arch/arm/mach-iop13xx/iq81340sc.c b/arch/arm/mach-iop13xx/iq81340sc.c
index 6677e14b61bf..5ad2b62c9bfd 100644
--- a/arch/arm/mach-iop13xx/iq81340sc.c
+++ b/arch/arm/mach-iop13xx/iq81340sc.c
@@ -90,11 +90,11 @@ static struct sys_timer iq81340sc_timer = {
MACHINE_START(IQ81340SC, "Intel IQ81340SC")
/* Maintainer: Dan Williams <dan.j.williams@intel.com> */
- .phys_io = PHYS_IO,
- .io_pg_offst = IO_PG_OFFSET,
+ .phys_io = IOP13XX_PMMR_PHYS_MEM_BASE,
+ .io_pg_offst = (IOP13XX_PMMR_VIRT_MEM_BASE >> 18) & 0xfffc,
+ .boot_params = 0x00000100,
.map_io = iop13xx_map_io,
.init_irq = iop13xx_init_irq,
.timer = &iq81340sc_timer,
- .boot_params = BOOT_PARAM_OFFSET,
.init_machine = iq81340sc_init,
MACHINE_END
diff --git a/arch/arm/mach-iop13xx/irq.c b/arch/arm/mach-iop13xx/irq.c
index c4d9c8c5579c..dbbc07c38b14 100644
--- a/arch/arm/mach-iop13xx/irq.c
+++ b/arch/arm/mach-iop13xx/irq.c
@@ -222,25 +222,29 @@ iop13xx_irq_unmask3(unsigned int irq)
iop13xx_cp6_restore(cp_flags);
}
-static struct irqchip iop13xx_irqchip0 = {
+static struct irq_chip iop13xx_irqchip1 = {
+ .name = "IOP13xx-1",
.ack = iop13xx_irq_mask0,
.mask = iop13xx_irq_mask0,
.unmask = iop13xx_irq_unmask0,
};
-static struct irqchip iop13xx_irqchip1 = {
+static struct irq_chip iop13xx_irqchip2 = {
+ .name = "IOP13xx-2",
.ack = iop13xx_irq_mask1,
.mask = iop13xx_irq_mask1,
.unmask = iop13xx_irq_unmask1,
};
-static struct irqchip iop13xx_irqchip2 = {
+static struct irq_chip iop13xx_irqchip3 = {
+ .name = "IOP13xx-3",
.ack = iop13xx_irq_mask2,
.mask = iop13xx_irq_mask2,
.unmask = iop13xx_irq_unmask2,
};
-static struct irqchip iop13xx_irqchip3 = {
+static struct irq_chip iop13xx_irqchip4 = {
+ .name = "IOP13xx-4",
.ack = iop13xx_irq_mask3,
.mask = iop13xx_irq_mask3,
.unmask = iop13xx_irq_unmask3,
@@ -270,15 +274,15 @@ void __init iop13xx_init_irq(void)
for(i = 0; i < NR_IOP13XX_IRQS; i++) {
if (i < 32)
- set_irq_chip(i, &iop13xx_irqchip0);
- else if (i < 64)
set_irq_chip(i, &iop13xx_irqchip1);
- else if (i < 96)
+ else if (i < 64)
set_irq_chip(i, &iop13xx_irqchip2);
- else
+ else if (i < 96)
set_irq_chip(i, &iop13xx_irqchip3);
+ else
+ set_irq_chip(i, &iop13xx_irqchip4);
- set_irq_handler(i, do_level_IRQ);
+ set_irq_handler(i, handle_level_irq);
set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
}
diff --git a/arch/arm/mach-iop13xx/setup.c b/arch/arm/mach-iop13xx/setup.c
index 3756d2ccb1a7..5fbeb28d04bb 100644
--- a/arch/arm/mach-iop13xx/setup.c
+++ b/arch/arm/mach-iop13xx/setup.c
@@ -337,7 +337,7 @@ void __init iop13xx_platform_init(void)
#ifdef CONFIG_MTD_PHYSMAP
iq8134x_flash_resource.end = iq8134x_flash_resource.start +
- iq8134x_probe_flash_size();
+ iq8134x_probe_flash_size() - 1;
if (iq8134x_flash_resource.end > iq8134x_flash_resource.start)
iop13xx_devices[plat_idx++] = &iq8134x_flash;
else
diff --git a/arch/arm/mach-netx/time.c b/arch/arm/mach-netx/time.c
index 0993336c0b55..5773b55ef4a6 100644
--- a/arch/arm/mach-netx/time.c
+++ b/arch/arm/mach-netx/time.c
@@ -19,6 +19,8 @@
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/clocksource.h>
#include <asm/hardware.h>
#include <asm/io.h>
@@ -26,15 +28,6 @@
#include <asm/arch/netx-regs.h>
/*
- * Returns number of us since last clock interrupt. Note that interrupts
- * will have been disabled by do_gettimeoffset()
- */
-static unsigned long netx_gettimeoffset(void)
-{
- return readl(NETX_GPIO_COUNTER_CURRENT(0)) / 100;
-}
-
-/*
* IRQ handler for the timer
*/
static irqreturn_t
@@ -43,6 +36,7 @@ netx_timer_interrupt(int irq, void *dev_id)
write_seqlock(&xtime_lock);
timer_tick();
+
write_sequnlock(&xtime_lock);
/* acknowledge interrupt */
@@ -51,13 +45,26 @@ netx_timer_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
-
static struct irqaction netx_timer_irq = {
.name = "NetX Timer Tick",
.flags = IRQF_DISABLED | IRQF_TIMER,
.handler = netx_timer_interrupt,
};
+cycle_t netx_get_cycles(void)
+{
+ return readl(NETX_GPIO_COUNTER_CURRENT(1));
+}
+
+static struct clocksource clocksource_netx = {
+ .name = "netx_timer",
+ .rating = 200,
+ .read = netx_get_cycles,
+ .mask = CLOCKSOURCE_MASK(32),
+ .shift = 20,
+ .is_continuous = 1,
+};
+
/*
* Set up timer interrupt
*/
@@ -80,9 +87,20 @@ static void __init netx_timer_init(void)
NETX_GPIO_COUNTER_CTRL(0));
setup_irq(NETX_IRQ_TIMER0, &netx_timer_irq);
+
+ /* Setup timer one for clocksource */
+ writel(0, NETX_GPIO_COUNTER_CTRL(1));
+ writel(0, NETX_GPIO_COUNTER_CURRENT(1));
+ writel(0xFFFFFFFF, NETX_GPIO_COUNTER_MAX(1));
+
+ writel(NETX_GPIO_COUNTER_CTRL_RUN,
+ NETX_GPIO_COUNTER_CTRL(1));
+
+ clocksource_netx.mult =
+ clocksource_hz2mult(CLOCK_TICK_RATE, clocksource_netx.shift);
+ clocksource_register(&clocksource_netx);
}
struct sys_timer netx_timer = {
- .init = netx_timer_init,
- .offset = netx_gettimeoffset,
+ .init = netx_timer_init,
};
diff --git a/arch/arm/mach-omap1/Kconfig b/arch/arm/mach-omap1/Kconfig
index d135568dc9e7..8781aaeb576b 100644
--- a/arch/arm/mach-omap1/Kconfig
+++ b/arch/arm/mach-omap1/Kconfig
@@ -43,6 +43,7 @@ config MACH_OMAP_H3
config MACH_OMAP_OSK
bool "TI OSK Support"
depends on ARCH_OMAP1 && ARCH_OMAP16XX
+ select TPS65010
help
TI OMAP 5912 OSK (OMAP Starter Kit) board support. Say Y here
if you have such a board.
diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c
index 3a622801d7b0..7d0cf7af88ce 100644
--- a/arch/arm/mach-omap1/board-osk.c
+++ b/arch/arm/mach-omap1/board-osk.c
@@ -30,6 +30,7 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/irq.h>
+#include <linux/interrupt.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c
index 03d6905ba490..878ff9181d0e 100644
--- a/arch/arm/mach-omap2/board-apollon.c
+++ b/arch/arm/mach-omap2/board-apollon.c
@@ -22,6 +22,7 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/onenand.h>
+#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index f4f04d87df32..d8f57824423f 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -17,6 +17,7 @@
#include <linux/spinlock.h>
#include <asm/io.h>
+#include <asm/mach-types.h>
#include <asm/arch/gpmc.h>
#undef DEBUG
@@ -338,19 +339,13 @@ void __init gpmc_mem_init(void)
int cs;
unsigned long boot_rom_space = 0;
- if (cpu_is_omap242x()) {
- u32 l;
- l = omap_readl(OMAP242X_CONTROL_STATUS);
- /* In case of internal boot the 1st MB is redirected to the
- * boot ROM memory space.
- */
- if (l & (1 << 3))
- boot_rom_space = BOOT_ROM_SPACE;
- } else
- /* We assume internal boot if the mode can't be
- * determined.
- */
- boot_rom_space = BOOT_ROM_SPACE;
+ /* never allocate the first page, to facilitate bug detection;
+ * even if we didn't boot from ROM.
+ */
+ boot_rom_space = BOOT_ROM_SPACE;
+ /* In apollon the CS0 is mapped as 0x0000 0000 */
+ if (machine_is_omap_apollon())
+ boot_rom_space = 0;
gpmc_mem_root.start = GPMC_MEM_START + boot_rom_space;
gpmc_mem_root.end = GPMC_MEM_END;
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
index 6ae605857ca9..9de1278d234f 100644
--- a/arch/arm/mach-pxa/generic.c
+++ b/arch/arm/mach-pxa/generic.c
@@ -76,7 +76,9 @@ unsigned long long sched_clock(void)
/*
* 96-bit math to perform tick * NSEC_PER_SEC / CLOCK_TICK_RATE for
* any value of CLOCK_TICK_RATE. Max value is in the 80 thousand
- * years range which is nice, but with higher computation cost.
+ * years range and truncation to unsigned long long limits it to
+ * sched_clock's max range of ~584 years. This is nice but with
+ * higher computation cost.
*/
{
union {
diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c
index b91466861029..ee2beb400414 100644
--- a/arch/arm/mach-pxa/time.c
+++ b/arch/arm/mach-pxa/time.c
@@ -18,6 +18,7 @@
#include <linux/signal.h>
#include <linux/errno.h>
#include <linux/sched.h>
+#include <linux/clocksource.h>
#include <asm/system.h>
#include <asm/hardware.h>
@@ -48,27 +49,6 @@ static int pxa_set_rtc(void)
return 0;
}
-/* IRQs are disabled before entering here from do_gettimeofday() */
-static unsigned long pxa_gettimeoffset (void)
-{
- long ticks_to_match, elapsed, usec;
-
- /* Get ticks before next timer match */
- ticks_to_match = OSMR0 - OSCR;
-
- /* We need elapsed ticks since last match */
- elapsed = LATCH - ticks_to_match;
-
- /* don't get fooled by the workaround in pxa_timer_interrupt() */
- if (elapsed <= 0)
- return 0;
-
- /* Now convert them to usec */
- usec = (unsigned long)(elapsed * (tick_nsec / 1000))/LATCH;
-
- return usec;
-}
-
#ifdef CONFIG_NO_IDLE_HZ
static unsigned long initial_match;
static int match_posponed;
@@ -121,6 +101,20 @@ static struct irqaction pxa_timer_irq = {
.handler = pxa_timer_interrupt,
};
+static cycle_t pxa_get_cycles(void)
+{
+ return OSCR;
+}
+
+static struct clocksource clocksource_pxa = {
+ .name = "pxa_timer",
+ .rating = 200,
+ .read = pxa_get_cycles,
+ .mask = CLOCKSOURCE_MASK(32),
+ .shift = 20,
+ .is_continuous = 1,
+};
+
static void __init pxa_timer_init(void)
{
struct timespec tv;
@@ -139,6 +133,14 @@ static void __init pxa_timer_init(void)
OIER = OIER_E0; /* enable match on timer 0 to cause interrupts */
OSMR0 = OSCR + LATCH; /* set initial match */
local_irq_restore(flags);
+
+ /*
+ * OSCR runs continuously on PXA and is not written to,
+ * so we can use it as clock source directly.
+ */
+ clocksource_pxa.mult =
+ clocksource_hz2mult(CLOCK_TICK_RATE, clocksource_pxa.shift);
+ clocksource_register(&clocksource_pxa);
}
#ifdef CONFIG_NO_IDLE_HZ
@@ -211,7 +213,6 @@ struct sys_timer pxa_timer = {
.init = pxa_timer_init,
.suspend = pxa_timer_suspend,
.resume = pxa_timer_resume,
- .offset = pxa_gettimeoffset,
#ifdef CONFIG_NO_IDLE_HZ
.dyn_tick = &pxa_dyn_tick,
#endif
diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c
index c1827d021ba8..119c64b7223f 100644
--- a/arch/arm/mach-pxa/trizeps4.c
+++ b/arch/arm/mach-pxa/trizeps4.c
@@ -393,10 +393,6 @@ static struct pxafb_mach_info sharp_lcd = {
.pxafb_backlight_power = board_backlight_power,
};
-static void __init trizeps4_fixup(struct machine_desc *desc, struct tag *tags, char **cmdline, struct meminfo *mi)
-{
-}
-
static void __init trizeps4_init(void)
{
platform_add_devices(trizeps4_devices, ARRAY_SIZE(trizeps4_devices));
@@ -469,7 +465,6 @@ MACHINE_START(TRIZEPS4, "Keith und Koep Trizeps IV module")
.phys_io = 0x40000000,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = TRIZEPS4_SDRAM_BASE + 0x100,
- .fixup = trizeps4_fixup,
.init_machine = trizeps4_init,
.map_io = trizeps4_map_io,
.init_irq = pxa_init_irq,
diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig
index 9f46bf330bc8..eb4ec411312b 100644
--- a/arch/arm/mach-s3c2410/Kconfig
+++ b/arch/arm/mach-s3c2410/Kconfig
@@ -5,6 +5,7 @@ menu "S3C24XX Implementations"
config MACH_AML_M5900
bool "AML M5900 Series"
select CPU_S3C2410
+ select PM_SIMTEC if PM
help
Say Y here if you are using the American Microsystems M5900 Series
<http://www.amltd.com>
@@ -12,6 +13,7 @@ config MACH_AML_M5900
config MACH_ANUBIS
bool "Simtec Electronics ANUBIS"
select CPU_S3C2440
+ select PM_SIMTEC if PM
help
Say Y here if you are using the Simtec Electronics ANUBIS
development system
@@ -19,6 +21,7 @@ config MACH_ANUBIS
config MACH_OSIRIS
bool "Simtec IM2440D20 (OSIRIS) module"
select CPU_S3C2440
+ select PM_SIMTEC if PM
help
Say Y here if you are using the Simtec IM2440D20 module, also
known as the Osiris.
@@ -26,6 +29,7 @@ config MACH_OSIRIS
config ARCH_BAST
bool "Simtec Electronics BAST (EB2410ITX)"
select CPU_S3C2410
+ select PM_SIMTEC if PM
select ISA
help
Say Y here if you are using the Simtec Electronics EB2410ITX
@@ -43,14 +47,13 @@ config BAST_PC104_IRQ
config PM_H1940
bool
- depends on PM
help
Internal node for H1940 and related PM
config ARCH_H1940
bool "IPAQ H1940"
select CPU_S3C2410
- select PM_H1940
+ select PM_H1940 if PM
help
Say Y here if you are using the HP IPAQ H1940
@@ -112,6 +115,7 @@ config MACH_SMDK2413
config MACH_VR1000
bool "Thorcom VR1000"
+ select PM_SIMTEC if PM
select CPU_S3C2410
help
Say Y here if you are using the Thorcom VR1000 board.
@@ -122,7 +126,7 @@ config MACH_VR1000
config MACH_RX3715
bool "HP iPAQ rx3715"
select CPU_S3C2440
- select PM_H1940
+ select PM_H1940 if PM
help
Say Y here if you are using the HP iPAQ rx3715.
@@ -156,7 +160,6 @@ config S3C2410_CLOCK
config S3C2410_PM
bool
- depends on CONFIG_PM
help
Power Management code common to S3C2410 and better
@@ -171,7 +174,7 @@ config CPU_S3C2410
bool
depends on ARCH_S3C2410
select S3C2410_CLOCK
- select S3C2410_PM
+ select S3C2410_PM if PM
help
Support for S3C2410 and S3C2410A family from the S3C24XX line
of Samsung Mobile CPUs.
@@ -186,14 +189,13 @@ config CPU_S3C2412_ONLY
config S3C2412_PM
bool
- default y if PM
- depends on CPU_S3C2412
help
Internal config node to apply S3C2412 power management
config CPU_S3C2412
bool
depends on ARCH_S3C2410
+ select S3C2412_PM if PM
help
Support for the S3C2412 and S3C2413 SoCs from the S3C24XX line
@@ -207,7 +209,7 @@ config CPU_S3C2440
bool
depends on ARCH_S3C2410
select S3C2410_CLOCK
- select S3C2410_PM
+ select S3C2410_PM if PM
select CPU_S3C244X
help
Support for S3C2440 Samsung Mobile CPU based systems.
@@ -216,7 +218,7 @@ config CPU_S3C2442
bool
depends on ARCH_S3C2420
select S3C2410_CLOCK
- select S3C2410_PM
+ select S3C2410_PM if PM
select CPU_S3C244X
help
Support for S3C2442 Samsung Mobile CPU based systems.
@@ -300,8 +302,9 @@ config S3C2410_PM_CHECK_CHUNKSIZE
config PM_SIMTEC
bool
- depends on PM && (ARCH_BAST || MACH_VR1000 || MACH_AML_M5900)
- default y
+ help
+ Common power management code for systems that are
+ compatible with the Simtec style of power management
config S3C2410_LOWLEVEL_UART_PORT
int "S3C2410 UART to use for low-level messages"
diff --git a/arch/arm/mach-s3c2410/cpu.c b/arch/arm/mach-s3c2410/cpu.c
index 9d4899eddf1f..ae1f5bb63f7a 100644
--- a/arch/arm/mach-s3c2410/cpu.c
+++ b/arch/arm/mach-s3c2410/cpu.c
@@ -26,6 +26,7 @@
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
+#include <linux/serial_core.h>
#include <linux/platform_device.h>
#include <asm/hardware.h>
diff --git a/arch/arm/mach-s3c2410/devs.c b/arch/arm/mach-s3c2410/devs.c
index cae35ff76f33..faccde2092d2 100644
--- a/arch/arm/mach-s3c2410/devs.c
+++ b/arch/arm/mach-s3c2410/devs.c
@@ -17,6 +17,7 @@
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/init.h>
+#include <linux/serial_core.h>
#include <linux/platform_device.h>
#include <asm/mach/arch.h>
diff --git a/arch/arm/mach-s3c2410/dma.c b/arch/arm/mach-s3c2410/dma.c
index 01abb0ace234..fa860e716b4f 100644
--- a/arch/arm/mach-s3c2410/dma.c
+++ b/arch/arm/mach-s3c2410/dma.c
@@ -1,6 +1,6 @@
/* linux/arch/arm/mach-s3c2410/dma.c
*
- * (c) 2003-2005,2006 Simtec Electronics
+ * Copyright (c) 2003-2005,2006 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* S3C2410 DMA core
@@ -1053,11 +1053,11 @@ int s3c2410_dma_config(dmach_t channel,
if (chan == NULL)
return -EINVAL;
- printk("Initial dcon is %08x\n", dcon);
+ pr_debug("%s: Initial dcon is %08x\n", __FUNCTION__, dcon);
dcon |= chan->dcon & dma_sel.dcon_mask;
- printk("New dcon is %08x\n", dcon);
+ pr_debug("%s: New dcon is %08x\n", __FUNCTION__, dcon);
switch (xferunit) {
case 1:
diff --git a/arch/arm/mach-s3c2410/irq.h b/arch/arm/mach-s3c2410/irq.h
index 3686a0082245..e5913da3b919 100644
--- a/arch/arm/mach-s3c2410/irq.h
+++ b/arch/arm/mach-s3c2410/irq.h
@@ -8,8 +8,6 @@
* 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.
- *
- * Modifications:
*/
#define irqdbf(x...)
diff --git a/arch/arm/mach-s3c2410/mach-anubis.c b/arch/arm/mach-s3c2410/mach-anubis.c
index e94cdcd96591..0fad0c2fe07b 100644
--- a/arch/arm/mach-s3c2410/mach-anubis.c
+++ b/arch/arm/mach-s3c2410/mach-anubis.c
@@ -15,6 +15,7 @@
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/init.h>
+#include <linux/serial_core.h>
#include <linux/platform_device.h>
#include <asm/mach/arch.h>
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
index 2968fb235f95..b8b76757ec54 100644
--- a/arch/arm/mach-s3c2410/mach-bast.c
+++ b/arch/arm/mach-s3c2410/mach-bast.c
@@ -16,6 +16,7 @@
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/init.h>
+#include <linux/serial_core.h>
#include <linux/platform_device.h>
#include <linux/dm9000.h>
diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c
index f5b98099a5d9..15b625eae499 100644
--- a/arch/arm/mach-s3c2410/mach-h1940.c
+++ b/arch/arm/mach-s3c2410/mach-h1940.c
@@ -17,6 +17,7 @@
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/init.h>
+#include <linux/serial_core.h>
#include <linux/platform_device.h>
#include <asm/mach/arch.h>
@@ -37,8 +38,6 @@
#include <asm/arch/h1940-latch.h>
#include <asm/arch/fb.h>
-#include <linux/serial_core.h>
-
#include "clock.h"
#include "devs.h"
#include "cpu.h"
diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c
index 116ac3169966..0411e9adb54d 100644
--- a/arch/arm/mach-s3c2410/mach-n30.c
+++ b/arch/arm/mach-s3c2410/mach-n30.c
@@ -20,6 +20,7 @@
#include <linux/timer.h>
#include <linux/init.h>
#include <linux/delay.h>
+#include <linux/serial_core.h>
#include <linux/platform_device.h>
#include <linux/kthread.h>
@@ -37,8 +38,6 @@
#include <asm/arch/regs-gpio.h>
#include <asm/arch/iic.h>
-#include <linux/serial_core.h>
-
#include "s3c2410.h"
#include "clock.h"
#include "devs.h"
diff --git a/arch/arm/mach-s3c2410/mach-nexcoder.c b/arch/arm/mach-s3c2410/mach-nexcoder.c
index 065a1d4e860b..d6dfdad8c90b 100644
--- a/arch/arm/mach-s3c2410/mach-nexcoder.c
+++ b/arch/arm/mach-s3c2410/mach-nexcoder.c
@@ -19,6 +19,7 @@
#include <linux/timer.h>
#include <linux/init.h>
#include <linux/string.h>
+#include <linux/serial_core.h>
#include <linux/platform_device.h>
#include <linux/mtd/map.h>
diff --git a/arch/arm/mach-s3c2410/mach-osiris.c b/arch/arm/mach-s3c2410/mach-osiris.c
index a4ab144e7292..37b40850c9b9 100644
--- a/arch/arm/mach-s3c2410/mach-osiris.c
+++ b/arch/arm/mach-s3c2410/mach-osiris.c
@@ -16,6 +16,7 @@
#include <linux/timer.h>
#include <linux/init.h>
#include <linux/device.h>
+#include <linux/serial_core.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
diff --git a/arch/arm/mach-s3c2410/mach-otom.c b/arch/arm/mach-s3c2410/mach-otom.c
index c71673fd9955..2c738b375e4d 100644
--- a/arch/arm/mach-s3c2410/mach-otom.c
+++ b/arch/arm/mach-s3c2410/mach-otom.c
@@ -15,6 +15,7 @@
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/init.h>
+#include <linux/serial_core.h>
#include <linux/platform_device.h>
#include <asm/mach/arch.h>
diff --git a/arch/arm/mach-s3c2410/mach-smdk2410.c b/arch/arm/mach-s3c2410/mach-smdk2410.c
index b3b0171d5052..01c0c986d827 100644
--- a/arch/arm/mach-s3c2410/mach-smdk2410.c
+++ b/arch/arm/mach-s3c2410/mach-smdk2410.c
@@ -35,6 +35,7 @@
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/init.h>
+#include <linux/serial_core.h>
#include <linux/platform_device.h>
#include <asm/mach/arch.h>
diff --git a/arch/arm/mach-s3c2410/mach-smdk2413.c b/arch/arm/mach-s3c2410/mach-smdk2413.c
index 3a4ca7f6f7b9..4f89abd7a6df 100644
--- a/arch/arm/mach-s3c2410/mach-smdk2413.c
+++ b/arch/arm/mach-s3c2410/mach-smdk2413.c
@@ -17,6 +17,7 @@
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/init.h>
+#include <linux/serial_core.h>
#include <linux/platform_device.h>
#include <asm/mach/arch.h>
diff --git a/arch/arm/mach-s3c2410/mach-smdk2440.c b/arch/arm/mach-s3c2410/mach-smdk2440.c
index e2205ff1b0ee..2b61f4ed1da4 100644
--- a/arch/arm/mach-s3c2410/mach-smdk2440.c
+++ b/arch/arm/mach-s3c2410/mach-smdk2440.c
@@ -19,6 +19,7 @@
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/init.h>
+#include <linux/serial_core.h>
#include <linux/platform_device.h>
#include <asm/mach/arch.h>
diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c
index e2eda3937ab0..a382fc095110 100644
--- a/arch/arm/mach-s3c2410/mach-vr1000.c
+++ b/arch/arm/mach-s3c2410/mach-vr1000.c
@@ -352,7 +352,7 @@ static struct platform_device vr1000_led2 = {
static struct platform_device vr1000_led3 = {
.name = "s3c24xx_led",
- .id = 1,
+ .id = 3,
.dev = {
.platform_data = &vr1000_led3_pdata,
},
diff --git a/arch/arm/mach-s3c2410/mach-vstms.c b/arch/arm/mach-s3c2410/mach-vstms.c
index ea554e7c006e..0360e1055bcd 100644
--- a/arch/arm/mach-s3c2410/mach-vstms.c
+++ b/arch/arm/mach-s3c2410/mach-vstms.c
@@ -15,6 +15,7 @@
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/init.h>
+#include <linux/serial_core.h>
#include <linux/platform_device.h>
#include <linux/mtd/mtd.h>
diff --git a/arch/arm/mach-s3c2410/pm-simtec.c b/arch/arm/mach-s3c2410/pm-simtec.c
index 42cd05e298f8..619133eb7168 100644
--- a/arch/arm/mach-s3c2410/pm-simtec.c
+++ b/arch/arm/mach-s3c2410/pm-simtec.c
@@ -27,7 +27,6 @@
#include <asm/io.h>
#include <asm/arch/map.h>
-#include <asm/arch/regs-serial.h>
#include <asm/arch/regs-gpio.h>
#include <asm/arch/regs-mem.h>
diff --git a/arch/arm/mach-s3c2410/pm.c b/arch/arm/mach-s3c2410/pm.c
index b49a0b3b72b3..00834097eb82 100644
--- a/arch/arm/mach-s3c2410/pm.c
+++ b/arch/arm/mach-s3c2410/pm.c
@@ -34,6 +34,7 @@
#include <linux/crc32.h>
#include <linux/ioport.h>
#include <linux/delay.h>
+#include <linux/serial_core.h>
#include <asm/cacheflush.h>
#include <asm/hardware.h>
diff --git a/arch/arm/mach-s3c2410/s3c2410-clock.c b/arch/arm/mach-s3c2410/s3c2410-clock.c
index 00abe199a08e..992cc6af230e 100644
--- a/arch/arm/mach-s3c2410/s3c2410-clock.c
+++ b/arch/arm/mach-s3c2410/s3c2410-clock.c
@@ -30,13 +30,18 @@
#include <linux/clk.h>
#include <linux/mutex.h>
#include <linux/delay.h>
+#include <linux/serial_core.h>
+
+#include <asm/mach/map.h>
#include <asm/hardware.h>
#include <asm/io.h>
+#include <asm/arch/regs-serial.h>
#include <asm/arch/regs-clock.h>
#include <asm/arch/regs-gpio.h>
+#include "s3c2410.h"
#include "clock.h"
#include "cpu.h"
diff --git a/arch/arm/mach-s3c2410/s3c2410-dma.c b/arch/arm/mach-s3c2410/s3c2410-dma.c
index 51e5098b32e8..e67ba3911f11 100644
--- a/arch/arm/mach-s3c2410/s3c2410-dma.c
+++ b/arch/arm/mach-s3c2410/s3c2410-dma.c
@@ -1,6 +1,6 @@
/* linux/arch/arm/mach-s3c2410/s3c2410-dma.c
*
- * (c) 2006 Simtec Electronics
+ * Copyright (c) 2006 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* S3C2410 DMA selection
@@ -15,6 +15,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/sysdev.h>
+#include <linux/serial_core.h>
#include <asm/dma.h>
#include <asm/arch/dma.h>
@@ -131,6 +132,7 @@ static int s3c2410_dma_add(struct sys_device *sysdev)
return s3c24xx_dma_init_map(&s3c2410_dma_sel);
}
+#if defined(CONFIG_CPU_S3C2410)
static struct sysdev_driver s3c2410_dma_driver = {
.add = s3c2410_dma_add,
};
@@ -141,9 +143,10 @@ static int __init s3c2410_dma_init(void)
}
arch_initcall(s3c2410_dma_init);
+#endif
+#if defined(CONFIG_CPU_S3C2442)
/* S3C2442 DMA contains the same selection table as the S3C2410 */
-
static struct sysdev_driver s3c2442_dma_driver = {
.add = s3c2410_dma_add,
};
@@ -154,5 +157,5 @@ static int __init s3c2442_dma_init(void)
}
arch_initcall(s3c2442_dma_init);
-
+#endif
diff --git a/arch/arm/mach-s3c2410/s3c2410-pm.c b/arch/arm/mach-s3c2410/s3c2410-pm.c
index 77c6814c0f05..8bb6e5e21f59 100644
--- a/arch/arm/mach-s3c2410/s3c2410-pm.c
+++ b/arch/arm/mach-s3c2410/s3c2410-pm.c
@@ -87,7 +87,7 @@ static void s3c2410_pm_prepare(void)
}
-int s3c2410_pm_resume(struct sys_device *dev)
+static int s3c2410_pm_resume(struct sys_device *dev)
{
unsigned long tmp;
@@ -111,6 +111,7 @@ static int s3c2410_pm_add(struct sys_device *dev)
return 0;
}
+#if defined(CONFIG_CPU_S3C2410)
static struct sysdev_driver s3c2410_pm_driver = {
.add = s3c2410_pm_add,
.resume = s3c2410_pm_resume,
@@ -124,7 +125,9 @@ static int __init s3c2410_pm_drvinit(void)
}
arch_initcall(s3c2410_pm_drvinit);
+#endif
+#if defined(CONFIG_CPU_S3C2440)
static struct sysdev_driver s3c2440_pm_driver = {
.add = s3c2410_pm_add,
.resume = s3c2410_pm_resume,
@@ -136,7 +139,9 @@ static int __init s3c2440_pm_drvinit(void)
}
arch_initcall(s3c2440_pm_drvinit);
+#endif
+#if defined(CONFIG_CPU_S3C2442)
static struct sysdev_driver s3c2442_pm_driver = {
.add = s3c2410_pm_add,
.resume = s3c2410_pm_resume,
@@ -148,3 +153,4 @@ static int __init s3c2442_pm_drvinit(void)
}
arch_initcall(s3c2442_pm_drvinit);
+#endif
diff --git a/arch/arm/mach-s3c2410/s3c2410.c b/arch/arm/mach-s3c2410/s3c2410.c
index 183e4033ce61..4cdc0d70c19f 100644
--- a/arch/arm/mach-s3c2410/s3c2410.c
+++ b/arch/arm/mach-s3c2410/s3c2410.c
@@ -17,6 +17,7 @@
#include <linux/timer.h>
#include <linux/init.h>
#include <linux/sysdev.h>
+#include <linux/serial_core.h>
#include <linux/platform_device.h>
#include <asm/mach/arch.h>
@@ -38,11 +39,9 @@
/* Initial IO mappings */
static struct map_desc s3c2410_iodesc[] __initdata = {
- IODESC_ENT(USBHOST),
IODESC_ENT(CLKPWR),
IODESC_ENT(LCD),
IODESC_ENT(TIMER),
- IODESC_ENT(ADC),
IODESC_ENT(WATCHDOG),
};
diff --git a/arch/arm/mach-s3c2410/s3c2412-clock.c b/arch/arm/mach-s3c2410/s3c2412-clock.c
index c95ed3e18580..8f94ad83901d 100644
--- a/arch/arm/mach-s3c2410/s3c2412-clock.c
+++ b/arch/arm/mach-s3c2410/s3c2412-clock.c
@@ -30,13 +30,18 @@
#include <linux/clk.h>
#include <linux/mutex.h>
#include <linux/delay.h>
+#include <linux/serial_core.h>
+
+#include <asm/mach/map.h>
#include <asm/hardware.h>
#include <asm/io.h>
+#include <asm/arch/regs-serial.h>
#include <asm/arch/regs-clock.h>
#include <asm/arch/regs-gpio.h>
+#include "s3c2412.h"
#include "clock.h"
#include "cpu.h"
@@ -49,7 +54,7 @@
* set the correct muxing at initialisation
*/
-int s3c2412_clkcon_enable(struct clk *clk, int enable)
+static int s3c2412_clkcon_enable(struct clk *clk, int enable)
{
unsigned int clocks = clk->ctrlbit;
unsigned long clkcon;
@@ -556,7 +561,7 @@ struct clk_init {
struct clk *src_1;
};
-struct clk_init clks_src[] __initdata = {
+static struct clk_init clks_src[] __initdata = {
{
.clk = &clk_usysclk,
.bit = S3C2412_CLKSRC_USBCLK_HCLK,
@@ -619,7 +624,7 @@ static void __init s3c2412_clk_initparents(void)
/* clocks to add straight away */
-struct clk *clks[] __initdata = {
+static struct clk *clks[] __initdata = {
&clk_ext,
&clk_usb_bus,
&clk_erefclk,
diff --git a/arch/arm/mach-s3c2410/s3c2412-dma.c b/arch/arm/mach-s3c2410/s3c2412-dma.c
index 171f3706d36d..fe71a8fdb87c 100644
--- a/arch/arm/mach-s3c2410/s3c2412-dma.c
+++ b/arch/arm/mach-s3c2410/s3c2412-dma.c
@@ -1,6 +1,6 @@
/* linux/arch/arm/mach-s3c2410/s3c2412-dma.c
*
- * (c) 2006 Simtec Electronics
+ * Copyright (c) 2006 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* S3C2412 DMA selection
@@ -15,6 +15,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/sysdev.h>
+#include <linux/serial_core.h>
#include <asm/dma.h>
#include <asm/arch/dma.h>
diff --git a/arch/arm/mach-s3c2410/s3c2412.c b/arch/arm/mach-s3c2410/s3c2412.c
index e76431c41461..2f651a811ecd 100644
--- a/arch/arm/mach-s3c2410/s3c2412.c
+++ b/arch/arm/mach-s3c2410/s3c2412.c
@@ -17,6 +17,7 @@
#include <linux/timer.h>
#include <linux/init.h>
#include <linux/sysdev.h>
+#include <linux/serial_core.h>
#include <linux/platform_device.h>
#include <asm/mach/arch.h>
@@ -60,7 +61,6 @@ static struct map_desc s3c2412_iodesc[] __initdata = {
IODESC_ENT(CLKPWR),
IODESC_ENT(LCD),
IODESC_ENT(TIMER),
- IODESC_ENT(ADC),
IODESC_ENT(WATCHDOG),
};
diff --git a/arch/arm/mach-s3c2410/s3c2440-clock.c b/arch/arm/mach-s3c2410/s3c2440-clock.c
index 15796864d010..ba13c1d079d1 100644
--- a/arch/arm/mach-s3c2410/s3c2440-clock.c
+++ b/arch/arm/mach-s3c2410/s3c2440-clock.c
@@ -113,18 +113,18 @@ static int s3c2440_clk_add(struct sys_device *sysdev)
{
unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN);
unsigned long clkdivn;
- struct clk *clk_h;
- struct clk *clk_p;
- struct clk *clk_upll;
+ struct clk *clock_h;
+ struct clk *clock_p;
+ struct clk *clock_upll;
printk("S3C2440: Clock Support, DVS %s\n",
(camdivn & S3C2440_CAMDIVN_DVSEN) ? "on" : "off");
- clk_p = clk_get(NULL, "pclk");
- clk_h = clk_get(NULL, "hclk");
- clk_upll = clk_get(NULL, "upll");
+ clock_p = clk_get(NULL, "pclk");
+ clock_h = clk_get(NULL, "hclk");
+ clock_upll = clk_get(NULL, "upll");
- if (IS_ERR(clk_p) || IS_ERR(clk_h) || IS_ERR(clk_upll)) {
+ if (IS_ERR(clock_p) || IS_ERR(clock_h) || IS_ERR(clock_upll)) {
printk(KERN_ERR "S3C2440: Failed to get parent clocks\n");
return -EINVAL;
}
@@ -132,8 +132,8 @@ static int s3c2440_clk_add(struct sys_device *sysdev)
/* check rate of UPLL, and if it is near 96MHz, then change
* to using half the UPLL rate for the system */
- if (clk_get_rate(clk_upll) > (94 * MHZ)) {
- clk_usb_bus.rate = clk_get_rate(clk_upll) / 2;
+ if (clk_get_rate(clock_upll) > (94 * MHZ)) {
+ clk_usb_bus.rate = clk_get_rate(clock_upll) / 2;
mutex_lock(&clocks_mutex);
@@ -144,9 +144,9 @@ static int s3c2440_clk_add(struct sys_device *sysdev)
mutex_unlock(&clocks_mutex);
}
- s3c2440_clk_cam.parent = clk_h;
- s3c2440_clk_ac97.parent = clk_p;
- s3c2440_clk_cam_upll.parent = clk_upll;
+ s3c2440_clk_cam.parent = clock_h;
+ s3c2440_clk_ac97.parent = clock_p;
+ s3c2440_clk_cam_upll.parent = clock_upll;
s3c24xx_register_clock(&s3c2440_clk_ac97);
s3c24xx_register_clock(&s3c2440_clk_cam);
diff --git a/arch/arm/mach-s3c2410/s3c2440-dma.c b/arch/arm/mach-s3c2410/s3c2440-dma.c
index 11e109c84a15..47b861b9443d 100644
--- a/arch/arm/mach-s3c2410/s3c2440-dma.c
+++ b/arch/arm/mach-s3c2410/s3c2440-dma.c
@@ -1,6 +1,6 @@
/* linux/arch/arm/mach-s3c2410/s3c2440-dma.c
*
- * (c) 2006 Simtec Electronics
+ * Copyright (c) 2006 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* S3C2440 DMA selection
@@ -15,6 +15,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/sysdev.h>
+#include <linux/serial_core.h>
#include <asm/dma.h>
#include <asm/arch/dma.h>
diff --git a/arch/arm/mach-s3c2410/s3c2440.c b/arch/arm/mach-s3c2410/s3c2440.c
index 0ab50f44f318..344eb27cca48 100644
--- a/arch/arm/mach-s3c2410/s3c2440.c
+++ b/arch/arm/mach-s3c2410/s3c2440.c
@@ -17,6 +17,7 @@
#include <linux/timer.h>
#include <linux/init.h>
#include <linux/platform_device.h>
+#include <linux/serial_core.h>
#include <linux/sysdev.h>
#include <linux/clk.h>
@@ -28,17 +29,9 @@
#include <asm/io.h>
#include <asm/irq.h>
-#include <asm/arch/regs-clock.h>
-#include <asm/arch/regs-serial.h>
-#include <asm/arch/regs-gpio.h>
-#include <asm/arch/regs-gpioj.h>
-#include <asm/arch/regs-dsc.h>
-
#include "s3c2440.h"
-#include "clock.h"
#include "devs.h"
#include "cpu.h"
-#include "pm.h"
static struct sys_device s3c2440_sysdev = {
.cls = &s3c2440_sysclass,
diff --git a/arch/arm/mach-s3c2410/s3c2440.h b/arch/arm/mach-s3c2410/s3c2440.h
index 29cb6df65a48..dcd316076c59 100644
--- a/arch/arm/mach-s3c2410/s3c2440.h
+++ b/arch/arm/mach-s3c2410/s3c2440.h
@@ -8,28 +8,10 @@
* 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.
- *
- * Modifications:
- * 24-Aug-2004 BJD Start of S3C2440 CPU support
- * 04-Nov-2004 BJD Added s3c2440_init_uarts()
- * 04-Jan-2005 BJD Moved uart init to cpu code
- * 10-Jan-2005 BJD Moved 2440 specific init here
- * 14-Jan-2005 BJD Split the clock initialisation code
*/
#ifdef CONFIG_CPU_S3C2440
-
extern int s3c2440_init(void);
-
-extern void s3c2440_map_io(struct map_desc *mach_desc, int size);
-
-extern void s3c2440_init_uarts(struct s3c2410_uartcfg *cfg, int no);
-
-extern void s3c2440_init_clocks(int xtal);
-
#else
-#define s3c2440_init_clocks NULL
-#define s3c2440_init_uarts NULL
-#define s3c2440_map_io NULL
#define s3c2440_init NULL
#endif
diff --git a/arch/arm/mach-s3c2410/s3c2442-clock.c b/arch/arm/mach-s3c2410/s3c2442-clock.c
index d9f54b5cab7f..4e292ca7c9be 100644
--- a/arch/arm/mach-s3c2410/s3c2442-clock.c
+++ b/arch/arm/mach-s3c2410/s3c2442-clock.c
@@ -117,18 +117,18 @@ static int s3c2442_clk_add(struct sys_device *sysdev)
{
unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN);
unsigned long clkdivn;
- struct clk *clk_h;
- struct clk *clk_p;
- struct clk *clk_upll;
+ struct clk *clock_h;
+ struct clk *clock_p;
+ struct clk *clock_upll;
printk("S3C2442: Clock Support, DVS %s\n",
(camdivn & S3C2440_CAMDIVN_DVSEN) ? "on" : "off");
- clk_p = clk_get(NULL, "pclk");
- clk_h = clk_get(NULL, "hclk");
- clk_upll = clk_get(NULL, "upll");
+ clock_p = clk_get(NULL, "pclk");
+ clock_h = clk_get(NULL, "hclk");
+ clock_upll = clk_get(NULL, "upll");
- if (IS_ERR(clk_p) || IS_ERR(clk_h) || IS_ERR(clk_upll)) {
+ if (IS_ERR(clock_p) || IS_ERR(clock_h) || IS_ERR(clock_upll)) {
printk(KERN_ERR "S3C2442: Failed to get parent clocks\n");
return -EINVAL;
}
@@ -136,8 +136,8 @@ static int s3c2442_clk_add(struct sys_device *sysdev)
/* check rate of UPLL, and if it is near 96MHz, then change
* to using half the UPLL rate for the system */
- if (clk_get_rate(clk_upll) > (94 * MHZ)) {
- clk_usb_bus.rate = clk_get_rate(clk_upll) / 2;
+ if (clk_get_rate(clock_upll) > (94 * MHZ)) {
+ clk_usb_bus.rate = clk_get_rate(clock_upll) / 2;
mutex_lock(&clocks_mutex);
@@ -148,8 +148,8 @@ static int s3c2442_clk_add(struct sys_device *sysdev)
mutex_unlock(&clocks_mutex);
}
- s3c2442_clk_cam.parent = clk_h;
- s3c2442_clk_cam_upll.parent = clk_upll;
+ s3c2442_clk_cam.parent = clock_h;
+ s3c2442_clk_cam_upll.parent = clock_upll;
s3c24xx_register_clock(&s3c2442_clk_cam);
s3c24xx_register_clock(&s3c2442_clk_cam_upll);
diff --git a/arch/arm/mach-s3c2410/s3c2442.c b/arch/arm/mach-s3c2410/s3c2442.c
index 581667efd13c..428732ee68c4 100644
--- a/arch/arm/mach-s3c2410/s3c2442.c
+++ b/arch/arm/mach-s3c2410/s3c2442.c
@@ -16,29 +16,11 @@
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/init.h>
-#include <linux/platform_device.h>
+#include <linux/serial_core.h>
#include <linux/sysdev.h>
-#include <linux/clk.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <asm/hardware.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-
-#include <asm/arch/regs-clock.h>
-#include <asm/arch/regs-serial.h>
-#include <asm/arch/regs-gpio.h>
-#include <asm/arch/regs-gpioj.h>
-#include <asm/arch/regs-dsc.h>
#include "s3c2442.h"
-#include "clock.h"
-#include "devs.h"
#include "cpu.h"
-#include "pm.h"
static struct sys_device s3c2442_sysdev = {
.cls = &s3c2442_sysclass,
diff --git a/arch/arm/mach-s3c2410/s3c244x.c b/arch/arm/mach-s3c2410/s3c244x.c
index 9a2258270de9..23c7494ad10d 100644
--- a/arch/arm/mach-s3c2410/s3c244x.c
+++ b/arch/arm/mach-s3c2410/s3c244x.c
@@ -16,6 +16,7 @@
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/init.h>
+#include <linux/serial_core.h>
#include <linux/platform_device.h>
#include <linux/sysdev.h>
#include <linux/clk.h>
@@ -47,8 +48,6 @@ static struct map_desc s3c244x_iodesc[] __initdata = {
IODESC_ENT(TIMER),
IODESC_ENT(WATCHDOG),
IODESC_ENT(LCD),
- IODESC_ENT(ADC),
- IODESC_ENT(USBHOST),
};
/* uart initialisation */
diff --git a/arch/arm/mach-s3c2410/usb-simtec.h b/arch/arm/mach-s3c2410/usb-simtec.h
index d8aa6127dedb..03842ede9e71 100644
--- a/arch/arm/mach-s3c2410/usb-simtec.h
+++ b/arch/arm/mach-s3c2410/usb-simtec.h
@@ -10,9 +10,6 @@
* 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.
- *
- * Modifications:
- * 20-Aug-2004 BJD Created
*/
extern int usb_simtec_init(void);
diff --git a/arch/arm/mach-sa1100/jornada720.c b/arch/arm/mach-sa1100/jornada720.c
index 17f5a43acdb7..54ecdaa373d6 100644
--- a/arch/arm/mach-sa1100/jornada720.c
+++ b/arch/arm/mach-sa1100/jornada720.c
@@ -1,5 +1,15 @@
/*
* linux/arch/arm/mach-sa1100/jornada720.c
+ *
+ * HP Jornada720 init code
+ *
+ * Copyright (C) 2006 Filip Zyzniewski <filip.zyzniewski@tefnet.pl>
+ * Copyright (C) 2005 Michael Gernoth <michael@gernoth.net>
+ *
+ * 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/init.h>
@@ -10,13 +20,13 @@
#include <linux/ioport.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
+#include <video/s1d13xxxfb.h>
#include <asm/hardware.h>
#include <asm/hardware/sa1111.h>
#include <asm/irq.h>
#include <asm/mach-types.h>
#include <asm/setup.h>
-
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
#include <asm/mach/map.h>
@@ -24,13 +34,170 @@
#include "generic.h"
+/*
+ * HP Documentation referred in this file:
+ * http://www.jlime.com/downloads/development/docs/jornada7xx/jornada720.txt
+ */
+
+/* line 110 of HP's doc */
+#define TUCR_VAL 0x20000400
+
+/* memory space (line 52 of HP's doc) */
+#define SA1111REGSTART 0x40000000
+#define SA1111REGLEN 0x00001fff
+#define EPSONREGSTART 0x48000000
+#define EPSONREGLEN 0x00100000
+#define EPSONFBSTART 0x48200000
+/* 512kB framebuffer */
+#define EPSONFBLEN 512*1024
+
+static struct s1d13xxxfb_regval s1d13xxxfb_initregs[] = {
+ /* line 344 of HP's doc */
+ {0x0001,0x00}, // Miscellaneous Register
+ {0x01FC,0x00}, // Display Mode Register
+ {0x0004,0x00}, // General IO Pins Configuration Register 0
+ {0x0005,0x00}, // General IO Pins Configuration Register 1
+ {0x0008,0x00}, // General IO Pins Control Register 0
+ {0x0009,0x00}, // General IO Pins Control Register 1
+ {0x0010,0x01}, // Memory Clock Configuration Register
+ {0x0014,0x11}, // LCD Pixel Clock Configuration Register
+ {0x0018,0x01}, // CRT/TV Pixel Clock Configuration Register
+ {0x001C,0x01}, // MediaPlug Clock Configuration Register
+ {0x001E,0x01}, // CPU To Memory Wait State Select Register
+ {0x0020,0x00}, // Memory Configuration Register
+ {0x0021,0x45}, // DRAM Refresh Rate Register
+ {0x002A,0x01}, // DRAM Timings Control Register 0
+ {0x002B,0x03}, // DRAM Timings Control Register 1
+ {0x0030,0x1c}, // Panel Type Register
+ {0x0031,0x00}, // MOD Rate Register
+ {0x0032,0x4F}, // LCD Horizontal Display Width Register
+ {0x0034,0x07}, // LCD Horizontal Non-Display Period Register
+ {0x0035,0x01}, // TFT FPLINE Start Position Register
+ {0x0036,0x0B}, // TFT FPLINE Pulse Width Register
+ {0x0038,0xEF}, // LCD Vertical Display Height Register 0
+ {0x0039,0x00}, // LCD Vertical Display Height Register 1
+ {0x003A,0x13}, // LCD Vertical Non-Display Period Register
+ {0x003B,0x0B}, // TFT FPFRAME Start Position Register
+ {0x003C,0x01}, // TFT FPFRAME Pulse Width Register
+ {0x0040,0x05}, // LCD Display Mode Register (2:4bpp,3:8bpp,5:16bpp)
+ {0x0041,0x00}, // LCD Miscellaneous Register
+ {0x0042,0x00}, // LCD Display Start Address Register 0
+ {0x0043,0x00}, // LCD Display Start Address Register 1
+ {0x0044,0x00}, // LCD Display Start Address Register 2
+ {0x0046,0x80}, // LCD Memory Address Offset Register 0
+ {0x0047,0x02}, // LCD Memory Address Offset Register 1
+ {0x0048,0x00}, // LCD Pixel Panning Register
+ {0x004A,0x00}, // LCD Display FIFO High Threshold Control Register
+ {0x004B,0x00}, // LCD Display FIFO Low Threshold Control Register
+ {0x0050,0x4F}, // CRT/TV Horizontal Display Width Register
+ {0x0052,0x13}, // CRT/TV Horizontal Non-Display Period Register
+ {0x0053,0x01}, // CRT/TV HRTC Start Position Register
+ {0x0054,0x0B}, // CRT/TV HRTC Pulse Width Register
+ {0x0056,0xDF}, // CRT/TV Vertical Display Height Register 0
+ {0x0057,0x01}, // CRT/TV Vertical Display Height Register 1
+ {0x0058,0x2B}, // CRT/TV Vertical Non-Display Period Register
+ {0x0059,0x09}, // CRT/TV VRTC Start Position Register
+ {0x005A,0x01}, // CRT/TV VRTC Pulse Width Register
+ {0x005B,0x10}, // TV Output Control Register
+ {0x0060,0x03}, // CRT/TV Display Mode Register (2:4bpp,3:8bpp,5:16bpp)
+ {0x0062,0x00}, // CRT/TV Display Start Address Register 0
+ {0x0063,0x00}, // CRT/TV Display Start Address Register 1
+ {0x0064,0x00}, // CRT/TV Display Start Address Register 2
+ {0x0066,0x40}, // CRT/TV Memory Address Offset Register 0
+ {0x0067,0x01}, // CRT/TV Memory Address Offset Register 1
+ {0x0068,0x00}, // CRT/TV Pixel Panning Register
+ {0x006A,0x00}, // CRT/TV Display FIFO High Threshold Control Register
+ {0x006B,0x00}, // CRT/TV Display FIFO Low Threshold Control Register
+ {0x0070,0x00}, // LCD Ink/Cursor Control Register
+ {0x0071,0x01}, // LCD Ink/Cursor Start Address Register
+ {0x0072,0x00}, // LCD Cursor X Position Register 0
+ {0x0073,0x00}, // LCD Cursor X Position Register 1
+ {0x0074,0x00}, // LCD Cursor Y Position Register 0
+ {0x0075,0x00}, // LCD Cursor Y Position Register 1
+ {0x0076,0x00}, // LCD Ink/Cursor Blue Color 0 Register
+ {0x0077,0x00}, // LCD Ink/Cursor Green Color 0 Register
+ {0x0078,0x00}, // LCD Ink/Cursor Red Color 0 Register
+ {0x007A,0x1F}, // LCD Ink/Cursor Blue Color 1 Register
+ {0x007B,0x3F}, // LCD Ink/Cursor Green Color 1 Register
+ {0x007C,0x1F}, // LCD Ink/Cursor Red Color 1 Register
+ {0x007E,0x00}, // LCD Ink/Cursor FIFO Threshold Register
+ {0x0080,0x00}, // CRT/TV Ink/Cursor Control Register
+ {0x0081,0x01}, // CRT/TV Ink/Cursor Start Address Register
+ {0x0082,0x00}, // CRT/TV Cursor X Position Register 0
+ {0x0083,0x00}, // CRT/TV Cursor X Position Register 1
+ {0x0084,0x00}, // CRT/TV Cursor Y Position Register 0
+ {0x0085,0x00}, // CRT/TV Cursor Y Position Register 1
+ {0x0086,0x00}, // CRT/TV Ink/Cursor Blue Color 0 Register
+ {0x0087,0x00}, // CRT/TV Ink/Cursor Green Color 0 Register
+ {0x0088,0x00}, // CRT/TV Ink/Cursor Red Color 0 Register
+ {0x008A,0x1F}, // CRT/TV Ink/Cursor Blue Color 1 Register
+ {0x008B,0x3F}, // CRT/TV Ink/Cursor Green Color 1 Register
+ {0x008C,0x1F}, // CRT/TV Ink/Cursor Red Color 1 Register
+ {0x008E,0x00}, // CRT/TV Ink/Cursor FIFO Threshold Register
+ {0x0100,0x00}, // BitBlt Control Register 0
+ {0x0101,0x00}, // BitBlt Control Register 1
+ {0x0102,0x00}, // BitBlt ROP Code/Color Expansion Register
+ {0x0103,0x00}, // BitBlt Operation Register
+ {0x0104,0x00}, // BitBlt Source Start Address Register 0
+ {0x0105,0x00}, // BitBlt Source Start Address Register 1
+ {0x0106,0x00}, // BitBlt Source Start Address Register 2
+ {0x0108,0x00}, // BitBlt Destination Start Address Register 0
+ {0x0109,0x00}, // BitBlt Destination Start Address Register 1
+ {0x010A,0x00}, // BitBlt Destination Start Address Register 2
+ {0x010C,0x00}, // BitBlt Memory Address Offset Register 0
+ {0x010D,0x00}, // BitBlt Memory Address Offset Register 1
+ {0x0110,0x00}, // BitBlt Width Register 0
+ {0x0111,0x00}, // BitBlt Width Register 1
+ {0x0112,0x00}, // BitBlt Height Register 0
+ {0x0113,0x00}, // BitBlt Height Register 1
+ {0x0114,0x00}, // BitBlt Background Color Register 0
+ {0x0115,0x00}, // BitBlt Background Color Register 1
+ {0x0118,0x00}, // BitBlt Foreground Color Register 0
+ {0x0119,0x00}, // BitBlt Foreground Color Register 1
+ {0x01E0,0x00}, // Look-Up Table Mode Register
+ {0x01E2,0x00}, // Look-Up Table Address Register
+ /* not sure, wouldn't like to mess with the driver */
+ {0x01E4,0x00}, // Look-Up Table Data Register
+ /* jornada doc says 0x00, but I trust the driver */
+ {0x01F0,0x10}, // Power Save Configuration Register
+ {0x01F1,0x00}, // Power Save Status Register
+ {0x01F4,0x00}, // CPU-to-Memory Access Watchdog Timer Register
+ {0x01FC,0x01}, // Display Mode Register(0x01:LCD, 0x02:CRT, 0x03:LCD&CRT)
+};
+
+static struct s1d13xxxfb_pdata s1d13xxxfb_data = {
+ .initregs = s1d13xxxfb_initregs,
+ .initregssize = ARRAY_SIZE(s1d13xxxfb_initregs),
+ .platform_init_video = NULL
+};
-#define JORTUCR_VAL 0x20000400
+static struct resource s1d13xxxfb_resources[] = {
+ [0] = {
+ .start = EPSONFBSTART,
+ .end = EPSONFBSTART + EPSONFBLEN,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = EPSONREGSTART,
+ .end = EPSONREGSTART + EPSONREGLEN,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device s1d13xxxfb_device = {
+ .name = S1D_DEVICENAME,
+ .id = 0,
+ .dev = {
+ .platform_data = &s1d13xxxfb_data,
+ },
+ .num_resources = ARRAY_SIZE(s1d13xxxfb_resources),
+ .resource = s1d13xxxfb_resources,
+};
static struct resource sa1111_resources[] = {
[0] = {
- .start = 0x40000000,
- .end = 0x40001fff,
+ .start = SA1111REGSTART,
+ .end = SA1111REGSTART + SA1111REGLEN,
.flags = IORESOURCE_MEM,
},
[1] = {
@@ -53,18 +220,32 @@ static struct platform_device sa1111_device = {
.resource = sa1111_resources,
};
+static struct platform_device jornada720_mcu_device = {
+ .name = "jornada720_mcu",
+ .id = -1,
+};
+
static struct platform_device *devices[] __initdata = {
&sa1111_device,
+ &jornada720_mcu_device,
+ &s1d13xxxfb_device,
};
+/* a stub for now, we theoretically cannot suspend without a flashboard */
+int pm_suspend(suspend_state_t state)
+{
+ return -1;
+}
+
static int __init jornada720_init(void)
{
int ret = -ENODEV;
if (machine_is_jornada720()) {
GPDR |= GPIO_GPIO20;
- TUCR = JORTUCR_VAL; /* set the oscillator out to the SA-1101 */
-
+ /* oscillator setup (line 116 of HP's doc) */
+ TUCR = TUCR_VAL;
+ /* resetting SA1111 (line 118 of HP's doc) */
GPSR = GPIO_GPIO20;
udelay(1);
GPCR = GPIO_GPIO20;
@@ -72,10 +253,6 @@ static int __init jornada720_init(void)
GPSR = GPIO_GPIO20;
udelay(20);
- /* LDD4 is speaker, LDD3 is microphone */
- PPSR &= ~(PPC_LDD3 | PPC_LDD4);
- PPDR |= PPC_LDD3 | PPC_LDD4;
-
ret = platform_add_devices(devices, ARRAY_SIZE(devices));
}
return ret;
@@ -85,19 +262,19 @@ arch_initcall(jornada720_init);
static struct map_desc jornada720_io_desc[] __initdata = {
{ /* Epson registers */
- .virtual = 0xf0000000,
- .pfn = __phys_to_pfn(0x48000000),
- .length = 0x00100000,
+ .virtual = 0xf0000000,
+ .pfn = __phys_to_pfn(EPSONREGSTART),
+ .length = EPSONREGLEN,
.type = MT_DEVICE
}, { /* Epson frame buffer */
- .virtual = 0xf1000000,
- .pfn = __phys_to_pfn(0x48200000),
- .length = 0x00100000,
+ .virtual = 0xf1000000,
+ .pfn = __phys_to_pfn(EPSONFBSTART),
+ .length = EPSONFBLEN,
.type = MT_DEVICE
}, { /* SA-1111 */
- .virtual = 0xf4000000,
- .pfn = __phys_to_pfn(0x40000000),
- .length = 0x00100000,
+ .virtual = 0xf4000000,
+ .pfn = __phys_to_pfn(SA1111REGSTART),
+ .length = SA1111REGLEN,
.type = MT_DEVICE
}
};
@@ -106,7 +283,7 @@ static void __init jornada720_map_io(void)
{
sa1100_map_io();
iotable_init(jornada720_io_desc, ARRAY_SIZE(jornada720_io_desc));
-
+
sa1100_register_uart(0, 3);
sa1100_register_uart(1, 1);
}
@@ -116,7 +293,7 @@ static struct mtd_partition jornada720_partitions[] = {
.name = "JORNADA720 boot firmware",
.size = 0x00040000,
.offset = 0,
- .mask_flags = MTD_WRITEABLE, /* force read-only */
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
}, {
.name = "JORNADA720 kernel",
.size = 0x000c0000,
@@ -139,7 +316,7 @@ static struct mtd_partition jornada720_partitions[] = {
.offset = 0x00540000,
}, {
.name = "JORNADA720 usr local",
- .size = 0, /* will expand to the end of the flash */
+ .size = 0, /* will expand to the end of the flash */
.offset = 0x00d00000,
}
};
@@ -147,10 +324,12 @@ static struct mtd_partition jornada720_partitions[] = {
static void jornada720_set_vpp(int vpp)
{
if (vpp)
- PPSR |= 0x80;
+ /* enabling flash write (line 470 of HP's doc) */
+ PPSR |= PPC_LDD7;
else
- PPSR &= ~0x80;
- PPDR |= 0x80;
+ /* disabling flash write (line 470 of HP's doc) */
+ PPSR &= ~PPC_LDD7;
+ PPDR |= PPC_LDD7;
}
static struct flash_platform_data jornada720_flash_data = {
diff --git a/arch/arm/mm/consistent.c b/arch/arm/mm/consistent.c
index b797217e82be..6a9c362fef5e 100644
--- a/arch/arm/mm/consistent.c
+++ b/arch/arm/mm/consistent.c
@@ -238,7 +238,7 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
* x86 does not mark the pages reserved...
*/
SetPageReserved(page);
- set_pte(pte, mk_pte(page, prot));
+ set_pte_ext(pte, mk_pte(page, prot), 0);
page++;
pte++;
off++;
diff --git a/arch/arm/mm/copypage-v4mc.c b/arch/arm/mm/copypage-v4mc.c
index df1645e14b4c..ded0e96d069d 100644
--- a/arch/arm/mm/copypage-v4mc.c
+++ b/arch/arm/mm/copypage-v4mc.c
@@ -19,6 +19,7 @@
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/tlbflush.h>
+#include <asm/cacheflush.h>
#include "mm.h"
@@ -69,9 +70,14 @@ mc_copy_user_page(void *from, void *to)
void v4_mc_copy_user_page(void *kto, const void *kfrom, unsigned long vaddr)
{
+ struct page *page = virt_to_page(kfrom);
+
+ if (test_and_clear_bit(PG_dcache_dirty, &page->flags))
+ __flush_dcache_page(page_mapping(page), page);
+
spin_lock(&minicache_lock);
- set_pte(TOP_PTE(0xffff8000), pfn_pte(__pa(kfrom) >> PAGE_SHIFT, minicache_pgprot));
+ set_pte_ext(TOP_PTE(0xffff8000), pfn_pte(__pa(kfrom) >> PAGE_SHIFT, minicache_pgprot), 0);
flush_tlb_kernel_page(0xffff8000);
mc_copy_user_page((void *)0xffff8000, kto);
diff --git a/arch/arm/mm/copypage-v6.c b/arch/arm/mm/copypage-v6.c
index 3d0d3a963d20..3adb79257f43 100644
--- a/arch/arm/mm/copypage-v6.c
+++ b/arch/arm/mm/copypage-v6.c
@@ -53,6 +53,10 @@ static void v6_copy_user_page_aliasing(void *kto, const void *kfrom, unsigned lo
{
unsigned int offset = CACHE_COLOUR(vaddr);
unsigned long from, to;
+ struct page *page = virt_to_page(kfrom);
+
+ if (test_and_clear_bit(PG_dcache_dirty, &page->flags))
+ __flush_dcache_page(page_mapping(page), page);
/*
* Discard data in the kernel mapping for the new page.
@@ -70,8 +74,8 @@ static void v6_copy_user_page_aliasing(void *kto, const void *kfrom, unsigned lo
*/
spin_lock(&v6_lock);
- set_pte(TOP_PTE(from_address) + offset, pfn_pte(__pa(kfrom) >> PAGE_SHIFT, PAGE_KERNEL));
- set_pte(TOP_PTE(to_address) + offset, pfn_pte(__pa(kto) >> PAGE_SHIFT, PAGE_KERNEL));
+ set_pte_ext(TOP_PTE(from_address) + offset, pfn_pte(__pa(kfrom) >> PAGE_SHIFT, PAGE_KERNEL), 0);
+ set_pte_ext(TOP_PTE(to_address) + offset, pfn_pte(__pa(kto) >> PAGE_SHIFT, PAGE_KERNEL), 0);
from = from_address + (offset << PAGE_SHIFT);
to = to_address + (offset << PAGE_SHIFT);
@@ -110,7 +114,7 @@ static void v6_clear_user_page_aliasing(void *kaddr, unsigned long vaddr)
*/
spin_lock(&v6_lock);
- set_pte(TOP_PTE(to_address) + offset, pfn_pte(__pa(kaddr) >> PAGE_SHIFT, PAGE_KERNEL));
+ set_pte_ext(TOP_PTE(to_address) + offset, pfn_pte(__pa(kaddr) >> PAGE_SHIFT, PAGE_KERNEL), 0);
flush_tlb_kernel_page(to);
clear_page((void *)to);
diff --git a/arch/arm/mm/copypage-xscale.c b/arch/arm/mm/copypage-xscale.c
index 84ebe0aa379e..2e455f82a4d5 100644
--- a/arch/arm/mm/copypage-xscale.c
+++ b/arch/arm/mm/copypage-xscale.c
@@ -19,6 +19,7 @@
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/tlbflush.h>
+#include <asm/cacheflush.h>
#include "mm.h"
@@ -91,9 +92,14 @@ mc_copy_user_page(void *from, void *to)
void xscale_mc_copy_user_page(void *kto, const void *kfrom, unsigned long vaddr)
{
+ struct page *page = virt_to_page(kfrom);
+
+ if (test_and_clear_bit(PG_dcache_dirty, &page->flags))
+ __flush_dcache_page(page_mapping(page), page);
+
spin_lock(&minicache_lock);
- set_pte(TOP_PTE(COPYPAGE_MINICACHE), pfn_pte(__pa(kfrom) >> PAGE_SHIFT, minicache_pgprot));
+ set_pte_ext(TOP_PTE(COPYPAGE_MINICACHE), pfn_pte(__pa(kfrom) >> PAGE_SHIFT, minicache_pgprot), 0);
flush_tlb_kernel_page(COPYPAGE_MINICACHE);
mc_copy_user_page((void *)COPYPAGE_MINICACHE, kto);
diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c
index 7fc1b35a6746..cf95c5d0ce4c 100644
--- a/arch/arm/mm/fault-armv.c
+++ b/arch/arm/mm/fault-armv.c
@@ -61,7 +61,7 @@ static int adjust_pte(struct vm_area_struct *vma, unsigned long address)
if (pte_present(entry) && pte_val(entry) & shared_pte_mask) {
flush_cache_page(vma, address, pte_pfn(entry));
pte_val(entry) &= ~shared_pte_mask;
- set_pte(pte, entry);
+ set_pte_at(vma->vm_mm, address, pte, entry);
flush_tlb_page(vma, address);
ret = 1;
}
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
index 454205b789d5..628348c9f6c5 100644
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -26,7 +26,7 @@ static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr)
unsigned long to = ALIAS_FLUSH_START + (CACHE_COLOUR(vaddr) << PAGE_SHIFT);
const int zero = 0;
- set_pte(TOP_PTE(to), pfn_pte(pfn, PAGE_KERNEL));
+ set_pte_ext(TOP_PTE(to), pfn_pte(pfn, PAGE_KERNEL), 0);
flush_tlb_kernel_page(to);
asm( "mcrr p15, 0, %1, %0, c14\n"
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index 465440592791..251685fe73a8 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -38,89 +38,71 @@
*/
#define VM_ARM_SECTION_MAPPING 0x80000000
-static inline void
-remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
- unsigned long phys_addr, pgprot_t pgprot)
+static int remap_area_pte(pmd_t *pmd, unsigned long addr, unsigned long end,
+ unsigned long phys_addr, pgprot_t prot)
{
- unsigned long end;
+ pte_t *pte;
+
+ pte = pte_alloc_kernel(pmd, addr);
+ if (!pte)
+ return -ENOMEM;
- address &= ~PMD_MASK;
- end = address + size;
- if (end > PMD_SIZE)
- end = PMD_SIZE;
- BUG_ON(address >= end);
do {
if (!pte_none(*pte))
goto bad;
- set_pte(pte, pfn_pte(phys_addr >> PAGE_SHIFT, pgprot));
- address += PAGE_SIZE;
+ set_pte_ext(pte, pfn_pte(phys_addr >> PAGE_SHIFT, prot), 0);
phys_addr += PAGE_SIZE;
- pte++;
- } while (address && (address < end));
- return;
+ } while (pte++, addr += PAGE_SIZE, addr != end);
+ return 0;
bad:
- printk("remap_area_pte: page already exists\n");
+ printk(KERN_CRIT "remap_area_pte: page already exists\n");
BUG();
}
-static inline int
-remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
- unsigned long phys_addr, unsigned long flags)
+static inline int remap_area_pmd(pgd_t *pgd, unsigned long addr,
+ unsigned long end, unsigned long phys_addr,
+ pgprot_t prot)
{
- unsigned long end;
- pgprot_t pgprot;
-
- address &= ~PGDIR_MASK;
- end = address + size;
-
- if (end > PGDIR_SIZE)
- end = PGDIR_SIZE;
+ unsigned long next;
+ pmd_t *pmd;
+ int ret = 0;
- phys_addr -= address;
- BUG_ON(address >= end);
+ pmd = pmd_alloc(&init_mm, pgd, addr);
+ if (!pmd)
+ return -ENOMEM;
- pgprot = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | L_PTE_WRITE | flags);
do {
- pte_t * pte = pte_alloc_kernel(pmd, address);
- if (!pte)
- return -ENOMEM;
- remap_area_pte(pte, address, end - address, address + phys_addr, pgprot);
- address = (address + PMD_SIZE) & PMD_MASK;
- pmd++;
- } while (address && (address < end));
- return 0;
+ next = pmd_addr_end(addr, end);
+ ret = remap_area_pte(pmd, addr, next, phys_addr, prot);
+ if (ret)
+ return ret;
+ phys_addr += next - addr;
+ } while (pmd++, addr = next, addr != end);
+ return ret;
}
-static int
-remap_area_pages(unsigned long start, unsigned long pfn,
- unsigned long size, unsigned long flags)
+static int remap_area_pages(unsigned long start, unsigned long pfn,
+ unsigned long size, unsigned long flags)
{
- unsigned long address = start;
- unsigned long end = start + size;
+ unsigned long addr = start;
+ unsigned long next, end = start + size;
unsigned long phys_addr = __pfn_to_phys(pfn);
+ pgprot_t prot = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG |
+ L_PTE_DIRTY | L_PTE_WRITE | flags);
+ pgd_t *pgd;
int err = 0;
- pgd_t * dir;
- phys_addr -= address;
- dir = pgd_offset(&init_mm, address);
- BUG_ON(address >= end);
+ BUG_ON(addr >= end);
+ pgd = pgd_offset_k(addr);
do {
- pmd_t *pmd = pmd_alloc(&init_mm, dir, address);
- if (!pmd) {
- err = -ENOMEM;
- break;
- }
- if (remap_area_pmd(pmd, address, end - address,
- phys_addr + address, flags)) {
- err = -ENOMEM;
+ next = pgd_addr_end(addr, end);
+ err = remap_area_pmd(pgd, addr, next, phys_addr, prot);
+ if (err)
break;
- }
-
- address = (address + PGDIR_SIZE) & PGDIR_MASK;
- dir++;
- } while (address && (address < end));
+ phys_addr += next - addr;
+ } while (pgd++, addr = next, addr != end);
return err;
}
@@ -310,6 +292,8 @@ __ioremap_pfn(unsigned long pfn, unsigned long offset, size_t size,
if (pfn >= 0x100000 && (__pfn_to_phys(pfn) & ~SUPERSECTION_MASK))
return NULL;
+ size = PAGE_ALIGN(size);
+
area = get_vm_area(size, VM_IOREMAP);
if (!area)
return NULL;
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index b7f194af20b4..655c8376f0b5 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -154,6 +154,26 @@ static int __init noalign_setup(char *__unused)
}
__setup("noalign", noalign_setup);
+#ifndef CONFIG_SMP
+void adjust_cr(unsigned long mask, unsigned long set)
+{
+ unsigned long flags;
+
+ mask &= ~CR_A;
+
+ set &= mask;
+
+ local_irq_save(flags);
+
+ cr_no_alignment = (cr_no_alignment & ~mask) | set;
+ cr_alignment = (cr_alignment & ~mask) | set;
+
+ set_cr((get_cr() & ~mask) | set);
+
+ local_irq_restore(flags);
+}
+#endif
+
struct mem_types {
unsigned int prot_pte;
unsigned int prot_l1;
@@ -294,12 +314,6 @@ static void __init build_mem_type_table(void)
mem_types[MT_DEVICE].prot_pte |= L_PTE_BUFFERABLE;
mem_types[MT_DEVICE].prot_sect |= PMD_SECT_BUFFERED;
- /*
- * User pages need to be mapped with the ASID
- * (iow, non-global)
- */
- user_pgprot |= L_PTE_ASID;
-
#ifdef CONFIG_SMP
/*
* Mark memory with the "shared" attribute for SMP systems
@@ -408,7 +422,7 @@ alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pg
}
ptep = pte_offset_kernel(pmdp, virt);
- set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, prot));
+ set_pte_ext(ptep, pfn_pte(phys >> PAGE_SHIFT, prot), 0);
}
/*
diff --git a/arch/arm/mm/pgd.c b/arch/arm/mm/pgd.c
index 20c1b0df75f2..50b9aed6000d 100644
--- a/arch/arm/mm/pgd.c
+++ b/arch/arm/mm/pgd.c
@@ -57,7 +57,7 @@ pgd_t *get_pgd_slow(struct mm_struct *mm)
init_pmd = pmd_offset(init_pgd, 0);
init_pte = pte_offset_map_nested(init_pmd, 0);
- set_pte(new_pte, *init_pte);
+ set_pte_ext(new_pte, *init_pte, 0);
pte_unmap_nested(init_pte);
pte_unmap(new_pte);
}
diff --git a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S
index 289b8e6f504d..700c04d6996e 100644
--- a/arch/arm/mm/proc-arm1020.S
+++ b/arch/arm/mm/proc-arm1020.S
@@ -397,7 +397,7 @@ ENTRY(cpu_arm1020_switch_mm)
* Set a PTE and flush it out
*/
.align 5
-ENTRY(cpu_arm1020_set_pte)
+ENTRY(cpu_arm1020_set_pte_ext)
#ifdef CONFIG_MMU
str r1, [r0], #-2048 @ linux version
@@ -477,7 +477,7 @@ arm1020_processor_functions:
.word cpu_arm1020_do_idle
.word cpu_arm1020_dcache_clean_area
.word cpu_arm1020_switch_mm
- .word cpu_arm1020_set_pte
+ .word cpu_arm1020_set_pte_ext
.size arm1020_processor_functions, . - arm1020_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm1020e.S b/arch/arm/mm/proc-arm1020e.S
index bed9db6ba582..1cc206ab5eae 100644
--- a/arch/arm/mm/proc-arm1020e.S
+++ b/arch/arm/mm/proc-arm1020e.S
@@ -381,7 +381,7 @@ ENTRY(cpu_arm1020e_switch_mm)
* Set a PTE and flush it out
*/
.align 5
-ENTRY(cpu_arm1020e_set_pte)
+ENTRY(cpu_arm1020e_set_pte_ext)
#ifdef CONFIG_MMU
str r1, [r0], #-2048 @ linux version
@@ -458,7 +458,7 @@ arm1020e_processor_functions:
.word cpu_arm1020e_do_idle
.word cpu_arm1020e_dcache_clean_area
.word cpu_arm1020e_switch_mm
- .word cpu_arm1020e_set_pte
+ .word cpu_arm1020e_set_pte_ext
.size arm1020e_processor_functions, . - arm1020e_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm1022.S b/arch/arm/mm/proc-arm1022.S
index d2a7c1b9cab9..aff0ea08e2f8 100644
--- a/arch/arm/mm/proc-arm1022.S
+++ b/arch/arm/mm/proc-arm1022.S
@@ -358,12 +358,12 @@ ENTRY(cpu_arm1022_switch_mm)
mov pc, lr
/*
- * cpu_arm1022_set_pte(ptep, pte)
+ * cpu_arm1022_set_pte_ext(ptep, pte, ext)
*
* Set a PTE and flush it out
*/
.align 5
-ENTRY(cpu_arm1022_set_pte)
+ENTRY(cpu_arm1022_set_pte_ext)
#ifdef CONFIG_MMU
str r1, [r0], #-2048 @ linux version
@@ -441,7 +441,7 @@ arm1022_processor_functions:
.word cpu_arm1022_do_idle
.word cpu_arm1022_dcache_clean_area
.word cpu_arm1022_switch_mm
- .word cpu_arm1022_set_pte
+ .word cpu_arm1022_set_pte_ext
.size arm1022_processor_functions, . - arm1022_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm1026.S b/arch/arm/mm/proc-arm1026.S
index 3247ce5c0177..65e43a109085 100644
--- a/arch/arm/mm/proc-arm1026.S
+++ b/arch/arm/mm/proc-arm1026.S
@@ -347,12 +347,12 @@ ENTRY(cpu_arm1026_switch_mm)
mov pc, lr
/*
- * cpu_arm1026_set_pte(ptep, pte)
+ * cpu_arm1026_set_pte_ext(ptep, pte, ext)
*
* Set a PTE and flush it out
*/
.align 5
-ENTRY(cpu_arm1026_set_pte)
+ENTRY(cpu_arm1026_set_pte_ext)
#ifdef CONFIG_MMU
str r1, [r0], #-2048 @ linux version
@@ -436,7 +436,7 @@ arm1026_processor_functions:
.word cpu_arm1026_do_idle
.word cpu_arm1026_dcache_clean_area
.word cpu_arm1026_switch_mm
- .word cpu_arm1026_set_pte
+ .word cpu_arm1026_set_pte_ext
.size arm1026_processor_functions, . - arm1026_processor_functions
.section .rodata
diff --git a/arch/arm/mm/proc-arm6_7.S b/arch/arm/mm/proc-arm6_7.S
index ce4f9eef763c..123a7dc7a433 100644
--- a/arch/arm/mm/proc-arm6_7.S
+++ b/arch/arm/mm/proc-arm6_7.S
@@ -209,14 +209,14 @@ ENTRY(cpu_arm7_switch_mm)
mov pc, lr
/*
- * Function: arm6_7_set_pte(pte_t *ptep, pte_t pte)
+ * Function: arm6_7_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext)
* Params : r0 = Address to set
* : r1 = value to set
* Purpose : Set a PTE and flush it out of any WB cache
*/
.align 5
-ENTRY(cpu_arm6_set_pte)
-ENTRY(cpu_arm7_set_pte)
+ENTRY(cpu_arm6_set_pte_ext)
+ENTRY(cpu_arm7_set_pte_ext)
#ifdef CONFIG_MMU
str r1, [r0], #-2048 @ linux version
@@ -299,7 +299,7 @@ ENTRY(arm6_processor_functions)
.word cpu_arm6_do_idle
.word cpu_arm6_dcache_clean_area
.word cpu_arm6_switch_mm
- .word cpu_arm6_set_pte
+ .word cpu_arm6_set_pte_ext
.size arm6_processor_functions, . - arm6_processor_functions
/*
@@ -315,7 +315,7 @@ ENTRY(arm7_processor_functions)
.word cpu_arm7_do_idle
.word cpu_arm7_dcache_clean_area
.word cpu_arm7_switch_mm
- .word cpu_arm7_set_pte
+ .word cpu_arm7_set_pte_ext
.size arm7_processor_functions, . - arm7_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm720.S b/arch/arm/mm/proc-arm720.S
index c04c194da785..dc763be43362 100644
--- a/arch/arm/mm/proc-arm720.S
+++ b/arch/arm/mm/proc-arm720.S
@@ -88,13 +88,13 @@ ENTRY(cpu_arm720_switch_mm)
mov pc, lr
/*
- * Function: arm720_set_pte(pte_t *ptep, pte_t pte)
+ * Function: arm720_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext)
* Params : r0 = Address to set
* : r1 = value to set
* Purpose : Set a PTE and flush it out of any WB cache
*/
.align 5
-ENTRY(cpu_arm720_set_pte)
+ENTRY(cpu_arm720_set_pte_ext)
#ifdef CONFIG_MMU
str r1, [r0], #-2048 @ linux version
@@ -204,7 +204,7 @@ ENTRY(arm720_processor_functions)
.word cpu_arm720_do_idle
.word cpu_arm720_dcache_clean_area
.word cpu_arm720_switch_mm
- .word cpu_arm720_set_pte
+ .word cpu_arm720_set_pte_ext
.size arm720_processor_functions, . - arm720_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S
index 65cbb2851bff..75c945ed6c4d 100644
--- a/arch/arm/mm/proc-arm920.S
+++ b/arch/arm/mm/proc-arm920.S
@@ -344,12 +344,12 @@ ENTRY(cpu_arm920_switch_mm)
mov pc, lr
/*
- * cpu_arm920_set_pte(ptep, pte)
+ * cpu_arm920_set_pte(ptep, pte, ext)
*
* Set a PTE and flush it out
*/
.align 5
-ENTRY(cpu_arm920_set_pte)
+ENTRY(cpu_arm920_set_pte_ext)
#ifdef CONFIG_MMU
str r1, [r0], #-2048 @ linux version
@@ -423,7 +423,7 @@ arm920_processor_functions:
.word cpu_arm920_do_idle
.word cpu_arm920_dcache_clean_area
.word cpu_arm920_switch_mm
- .word cpu_arm920_set_pte
+ .word cpu_arm920_set_pte_ext
.size arm920_processor_functions, . - arm920_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm922.S b/arch/arm/mm/proc-arm922.S
index 52761b70d735..ffb751b877ff 100644
--- a/arch/arm/mm/proc-arm922.S
+++ b/arch/arm/mm/proc-arm922.S
@@ -348,12 +348,12 @@ ENTRY(cpu_arm922_switch_mm)
mov pc, lr
/*
- * cpu_arm922_set_pte(ptep, pte)
+ * cpu_arm922_set_pte_ext(ptep, pte, ext)
*
* Set a PTE and flush it out
*/
.align 5
-ENTRY(cpu_arm922_set_pte)
+ENTRY(cpu_arm922_set_pte_ext)
#ifdef CONFIG_MMU
str r1, [r0], #-2048 @ linux version
@@ -427,7 +427,7 @@ arm922_processor_functions:
.word cpu_arm922_do_idle
.word cpu_arm922_dcache_clean_area
.word cpu_arm922_switch_mm
- .word cpu_arm922_set_pte
+ .word cpu_arm922_set_pte_ext
.size arm922_processor_functions, . - arm922_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm925.S b/arch/arm/mm/proc-arm925.S
index 5b74339d1588..44c2c997819f 100644
--- a/arch/arm/mm/proc-arm925.S
+++ b/arch/arm/mm/proc-arm925.S
@@ -391,12 +391,12 @@ ENTRY(cpu_arm925_switch_mm)
mov pc, lr
/*
- * cpu_arm925_set_pte(ptep, pte)
+ * cpu_arm925_set_pte_ext(ptep, pte, ext)
*
* Set a PTE and flush it out
*/
.align 5
-ENTRY(cpu_arm925_set_pte)
+ENTRY(cpu_arm925_set_pte_ext)
#ifdef CONFIG_MMU
str r1, [r0], #-2048 @ linux version
@@ -490,7 +490,7 @@ arm925_processor_functions:
.word cpu_arm925_do_idle
.word cpu_arm925_dcache_clean_area
.word cpu_arm925_switch_mm
- .word cpu_arm925_set_pte
+ .word cpu_arm925_set_pte_ext
.size arm925_processor_functions, . - arm925_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S
index 8628ed29a955..5b80b6bdd0cb 100644
--- a/arch/arm/mm/proc-arm926.S
+++ b/arch/arm/mm/proc-arm926.S
@@ -348,12 +348,12 @@ ENTRY(cpu_arm926_switch_mm)
mov pc, lr
/*
- * cpu_arm926_set_pte(ptep, pte)
+ * cpu_arm926_set_pte_ext(ptep, pte, ext)
*
* Set a PTE and flush it out
*/
.align 5
-ENTRY(cpu_arm926_set_pte)
+ENTRY(cpu_arm926_set_pte_ext)
#ifdef CONFIG_MMU
str r1, [r0], #-2048 @ linux version
@@ -439,7 +439,7 @@ arm926_processor_functions:
.word cpu_arm926_do_idle
.word cpu_arm926_dcache_clean_area
.word cpu_arm926_switch_mm
- .word cpu_arm926_set_pte
+ .word cpu_arm926_set_pte_ext
.size arm926_processor_functions, . - arm926_processor_functions
.section ".rodata"
@@ -480,7 +480,7 @@ __arm926_proc_info:
b __arm926_setup
.long cpu_arch_name
.long cpu_elf_name
- .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_VFP|HWCAP_EDSP|HWCAP_JAVA
+ .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_JAVA
.long cpu_arm926_name
.long arm926_processor_functions
.long v4wbi_tlb_fns
diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S
index cd7d865c9d19..6e226e12989f 100644
--- a/arch/arm/mm/proc-sa110.S
+++ b/arch/arm/mm/proc-sa110.S
@@ -146,12 +146,12 @@ ENTRY(cpu_sa110_switch_mm)
#endif
/*
- * cpu_sa110_set_pte(ptep, pte)
+ * cpu_sa110_set_pte_ext(ptep, pte, ext)
*
* Set a PTE and flush it out
*/
.align 5
-ENTRY(cpu_sa110_set_pte)
+ENTRY(cpu_sa110_set_pte_ext)
#ifdef CONFIG_MMU
str r1, [r0], #-2048 @ linux version
@@ -222,7 +222,7 @@ ENTRY(sa110_processor_functions)
.word cpu_sa110_do_idle
.word cpu_sa110_dcache_clean_area
.word cpu_sa110_switch_mm
- .word cpu_sa110_set_pte
+ .word cpu_sa110_set_pte_ext
.size sa110_processor_functions, . - sa110_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S
index b776653cc31c..9afb11d089fe 100644
--- a/arch/arm/mm/proc-sa1100.S
+++ b/arch/arm/mm/proc-sa1100.S
@@ -159,12 +159,12 @@ ENTRY(cpu_sa1100_switch_mm)
#endif
/*
- * cpu_sa1100_set_pte(ptep, pte)
+ * cpu_sa1100_set_pte_ext(ptep, pte, ext)
*
* Set a PTE and flush it out
*/
.align 5
-ENTRY(cpu_sa1100_set_pte)
+ENTRY(cpu_sa1100_set_pte_ext)
#ifdef CONFIG_MMU
str r1, [r0], #-2048 @ linux version
@@ -237,7 +237,7 @@ ENTRY(sa1100_processor_functions)
.word cpu_sa1100_do_idle
.word cpu_sa1100_dcache_clean_area
.word cpu_sa1100_switch_mm
- .word cpu_sa1100_set_pte
+ .word cpu_sa1100_set_pte_ext
.size sa1100_processor_functions, . - sa1100_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-syms.c b/arch/arm/mm/proc-syms.c
index ab143557e688..9f396b4fa0b7 100644
--- a/arch/arm/mm/proc-syms.c
+++ b/arch/arm/mm/proc-syms.c
@@ -17,7 +17,7 @@
#ifndef MULTI_CPU
EXPORT_SYMBOL(cpu_dcache_clean_area);
-EXPORT_SYMBOL(cpu_set_pte);
+EXPORT_SYMBOL(cpu_set_pte_ext);
#else
EXPORT_SYMBOL(processor);
#endif
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index b440c8a1d345..7b1843befb9c 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -103,13 +103,14 @@ ENTRY(cpu_v6_switch_mm)
mov pc, lr
/*
- * cpu_v6_set_pte(ptep, pte)
+ * cpu_v6_set_pte_ext(ptep, pte, ext)
*
* Set a level 2 translation table entry.
*
* - ptep - pointer to level 2 translation table entry
* (hardware version is stored at -1024 bytes)
* - pte - PTE value to store
+ * - ext - value for extended PTE bits
*
* Permissions:
* YUWD APX AP1 AP0 SVC User
@@ -121,33 +122,34 @@ ENTRY(cpu_v6_switch_mm)
* 11x0 0 1 0 r/w r/o
* 1111 0 1 1 r/w r/w
*/
-ENTRY(cpu_v6_set_pte)
+ENTRY(cpu_v6_set_pte_ext)
#ifdef CONFIG_MMU
str r1, [r0], #-2048 @ linux version
- bic r2, r1, #0x000003f0
- bic r2, r2, #0x00000003
- orr r2, r2, #PTE_EXT_AP0 | 2
+ bic r3, r1, #0x000003f0
+ bic r3, r3, #0x00000003
+ orr r3, r3, r2
+ orr r3, r3, #PTE_EXT_AP0 | 2
tst r1, #L_PTE_WRITE
tstne r1, #L_PTE_DIRTY
- orreq r2, r2, #PTE_EXT_APX
+ orreq r3, r3, #PTE_EXT_APX
tst r1, #L_PTE_USER
- orrne r2, r2, #PTE_EXT_AP1
- tstne r2, #PTE_EXT_APX
- bicne r2, r2, #PTE_EXT_APX | PTE_EXT_AP0
+ orrne r3, r3, #PTE_EXT_AP1
+ tstne r3, #PTE_EXT_APX
+ bicne r3, r3, #PTE_EXT_APX | PTE_EXT_AP0
tst r1, #L_PTE_YOUNG
- biceq r2, r2, #PTE_EXT_APX | PTE_EXT_AP_MASK
+ biceq r3, r3, #PTE_EXT_APX | PTE_EXT_AP_MASK
tst r1, #L_PTE_EXEC
- orreq r2, r2, #PTE_EXT_XN
+ orreq r3, r3, #PTE_EXT_XN
tst r1, #L_PTE_PRESENT
- moveq r2, #0
+ moveq r3, #0
- str r2, [r0]
+ str r3, [r0]
mcr p15, 0, r0, c7, c10, 1 @ flush_pte
#endif
mov pc, lr
@@ -156,7 +158,7 @@ ENTRY(cpu_v6_set_pte)
cpu_v6_name:
- .asciz "Some Random V6 Processor"
+ .asciz "ARMv6-compatible processor"
.align
.section ".text.init", #alloc, #execinstr
@@ -207,11 +209,6 @@ __v6_setup:
#endif
mcr p15, 0, r4, c2, c0, 1 @ load TTB1
#endif /* CONFIG_MMU */
-#ifdef CONFIG_VFP
- mrc p15, 0, r0, c1, c0, 2
- orr r0, r0, #(0xf << 20)
- mcr p15, 0, r0, c1, c0, 2 @ Enable full access to VFP
-#endif
adr r5, v6_crval
ldmia r5, {r5, r6}
mrc p15, 0, r0, c1, c0, 0 @ read control register
@@ -238,7 +235,7 @@ ENTRY(v6_processor_functions)
.word cpu_v6_do_idle
.word cpu_v6_dcache_clean_area
.word cpu_v6_switch_mm
- .word cpu_v6_set_pte
+ .word cpu_v6_set_pte_ext
.size v6_processor_functions, . - v6_processor_functions
.type cpu_arch_name, #object
@@ -273,7 +270,7 @@ __v6_proc_info:
b __v6_setup
.long cpu_arch_name
.long cpu_elf_name
- .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_VFP|HWCAP_EDSP|HWCAP_JAVA
+ .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_JAVA
.long cpu_v6_name
.long v6_processor_functions
.long v6wbi_tlb_fns
diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S
index 1ef564d0957f..94a58455f346 100644
--- a/arch/arm/mm/proc-xsc3.S
+++ b/arch/arm/mm/proc-xsc3.S
@@ -2,7 +2,7 @@
* linux/arch/arm/mm/proc-xsc3.S
*
* Original Author: Matthew Gilbert
- * Current Maintainer: Deepak Saxena <dsaxena@plexity.net>
+ * Current Maintainer: Lennert Buytenhek <buytenh@wantstofly.org>
*
* Copyright 2004 (C) Intel Corp.
* Copyright 2005 (c) MontaVista Software, Inc.
@@ -357,13 +357,13 @@ ENTRY(cpu_xsc3_switch_mm)
cpwait_ret lr, ip
/*
- * cpu_xsc3_set_pte(ptep, pte)
+ * cpu_xsc3_set_pte_ext(ptep, pte, ext)
*
* Set a PTE and flush it out
*
*/
.align 5
-ENTRY(cpu_xsc3_set_pte)
+ENTRY(cpu_xsc3_set_pte_ext)
str r1, [r0], #-2048 @ linux version
bic r2, r1, #0xff0 @ Keep C, B bits
@@ -457,7 +457,7 @@ ENTRY(xsc3_processor_functions)
.word cpu_xsc3_do_idle
.word cpu_xsc3_dcache_clean_area
.word cpu_xsc3_switch_mm
- .word cpu_xsc3_set_pte
+ .word cpu_xsc3_set_pte_ext
.size xsc3_processor_functions, . - xsc3_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S
index cc1004b3e511..490e11b34231 100644
--- a/arch/arm/mm/proc-xscale.S
+++ b/arch/arm/mm/proc-xscale.S
@@ -421,14 +421,14 @@ ENTRY(cpu_xscale_switch_mm)
cpwait_ret lr, ip
/*
- * cpu_xscale_set_pte(ptep, pte)
+ * cpu_xscale_set_pte_ext(ptep, pte, ext)
*
* Set a PTE and flush it out
*
* Errata 40: must set memory to write-through for user read-only pages.
*/
.align 5
-ENTRY(cpu_xscale_set_pte)
+ENTRY(cpu_xscale_set_pte_ext)
str r1, [r0], #-2048 @ linux version
bic r2, r1, #0xff0
@@ -529,7 +529,7 @@ ENTRY(xscale_processor_functions)
.word cpu_xscale_do_idle
.word cpu_xscale_dcache_clean_area
.word cpu_xscale_switch_mm
- .word cpu_xscale_set_pte
+ .word cpu_xscale_set_pte_ext
.size xscale_processor_functions, . - xscale_processor_functions
.section ".rodata"
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index f08eafbddcc1..490d9d18a7d1 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -263,13 +263,36 @@ void VFP9_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs)
if (exceptions)
vfp_raise_exceptions(exceptions, trigger, orig_fpscr, regs);
}
-
+
+static void vfp_enable(void *unused)
+{
+ u32 access = get_copro_access();
+
+ /*
+ * Enable full access to VFP (cp10 and cp11)
+ */
+ set_copro_access(access | CPACC_FULL(10) | CPACC_FULL(11));
+}
+
+#include <linux/smp.h>
+
/*
* VFP support code initialisation.
*/
static int __init vfp_init(void)
{
unsigned int vfpsid;
+ unsigned int cpu_arch = cpu_architecture();
+ u32 access = 0;
+
+ if (cpu_arch >= CPU_ARCH_ARMv6) {
+ access = get_copro_access();
+
+ /*
+ * Enable full access to VFP (cp10 and cp11)
+ */
+ set_copro_access(access | CPACC_FULL(10) | CPACC_FULL(11));
+ }
/*
* First check that there is a VFP that we can use.
@@ -277,13 +300,22 @@ static int __init vfp_init(void)
* we just need to read the VFPSID register.
*/
vfpsid = fmrx(FPSID);
+ barrier();
printk(KERN_INFO "VFP support v0.3: ");
if (VFP_arch) {
printk("not present\n");
+
+ /*
+ * Restore the copro access register.
+ */
+ if (cpu_arch >= CPU_ARCH_ARMv6)
+ set_copro_access(access);
} else if (vfpsid & FPSID_NODOUBLE) {
printk("no double precision support\n");
} else {
+ smp_call_function(vfp_enable, NULL, 1, 1);
+
VFP_arch = (vfpsid & FPSID_ARCH_MASK) >> FPSID_ARCH_BIT; /* Extract the architecture version */
printk("implementor %02x architecture %d part %02x variant %x rev %x\n",
(vfpsid & FPSID_IMPLEMENTER_MASK) >> FPSID_IMPLEMENTER_BIT,
@@ -291,9 +323,16 @@ static int __init vfp_init(void)
(vfpsid & FPSID_PART_MASK) >> FPSID_PART_BIT,
(vfpsid & FPSID_VARIANT_MASK) >> FPSID_VARIANT_BIT,
(vfpsid & FPSID_REV_MASK) >> FPSID_REV_BIT);
+
vfp_vector = vfp_support_entry;
thread_register_notifier(&vfp_notifier_block);
+
+ /*
+ * We detected VFP, and the support code is
+ * in place; report VFP support to userspace.
+ */
+ elf_hwcap |= HWCAP_VFP;
}
return 0;
}
diff --git a/arch/arm26/kernel/ecard.c b/arch/arm26/kernel/ecard.c
index 43dd41be71fb..9dbc17247c6f 100644
--- a/arch/arm26/kernel/ecard.c
+++ b/arch/arm26/kernel/ecard.c
@@ -215,7 +215,7 @@ int ecard_readchunk(struct in_chunk_dir *cd, ecard_t *ec, int id, int num)
}
if (c_id(&excd) == 0x80) { /* loader */
if (!ec->loader) {
- ec->loader = (loader_t)kmalloc(c_len(&excd),
+ ec->loader = kmalloc(c_len(&excd),
GFP_KERNEL);
if (ec->loader)
ecard_readbytes(ec->loader, ec,
diff --git a/arch/arm26/kernel/irq.c b/arch/arm26/kernel/irq.c
index d87d68b77d66..d53382c83bf9 100644
--- a/arch/arm26/kernel/irq.c
+++ b/arch/arm26/kernel/irq.c
@@ -545,7 +545,7 @@ int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_
(irq_flags & IRQF_SHARED && !dev_id))
return -EINVAL;
- action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL);
+ action = kmalloc(sizeof(struct irqaction), GFP_KERNEL);
if (!action)
return -ENOMEM;
diff --git a/arch/cris/arch-v10/drivers/axisflashmap.c b/arch/cris/arch-v10/drivers/axisflashmap.c
index 4fa81abab0c7..ffade19a14e6 100644
--- a/arch/cris/arch-v10/drivers/axisflashmap.c
+++ b/arch/cris/arch-v10/drivers/axisflashmap.c
@@ -516,7 +516,7 @@ static int __init init_axis_flash(void)
#else
struct mtd_info *mtd_ram;
- mtd_ram = (struct mtd_info *)kmalloc(sizeof(struct mtd_info),
+ mtd_ram = kmalloc(sizeof(struct mtd_info),
GFP_KERNEL);
if (!mtd_ram) {
panic("axisflashmap couldn't allocate memory for "
diff --git a/arch/cris/arch-v10/drivers/gpio.c b/arch/cris/arch-v10/drivers/gpio.c
index fcba6632ed7b..9aba18b931dd 100644
--- a/arch/cris/arch-v10/drivers/gpio.c
+++ b/arch/cris/arch-v10/drivers/gpio.c
@@ -440,7 +440,7 @@ gpio_open(struct inode *inode, struct file *filp)
if (p > GPIO_MINOR_LAST)
return -EINVAL;
- priv = (struct gpio_private *)kmalloc(sizeof(struct gpio_private),
+ priv = kmalloc(sizeof(struct gpio_private),
GFP_KERNEL);
if (!priv)
diff --git a/arch/cris/arch-v32/drivers/axisflashmap.c b/arch/cris/arch-v32/drivers/axisflashmap.c
index 41952320e00a..5180d45412fc 100644
--- a/arch/cris/arch-v32/drivers/axisflashmap.c
+++ b/arch/cris/arch-v32/drivers/axisflashmap.c
@@ -427,7 +427,7 @@ static int __init init_axis_flash(void)
#else
struct mtd_info *mtd_ram;
- mtd_ram = (struct mtd_info *)kmalloc(sizeof(struct mtd_info),
+ mtd_ram = kmalloc(sizeof(struct mtd_info),
GFP_KERNEL);
if (!mtd_ram) {
panic("axisflashmap couldn't allocate memory for "
diff --git a/arch/cris/arch-v32/drivers/gpio.c b/arch/cris/arch-v32/drivers/gpio.c
index c3f876b4da6b..08d36f0955c6 100644
--- a/arch/cris/arch-v32/drivers/gpio.c
+++ b/arch/cris/arch-v32/drivers/gpio.c
@@ -423,7 +423,7 @@ gpio_open(struct inode *inode, struct file *filp)
if (p > GPIO_MINOR_LAST)
return -EINVAL;
- priv = (struct gpio_private *)kmalloc(sizeof(struct gpio_private),
+ priv = kmalloc(sizeof(struct gpio_private),
GFP_KERNEL);
if (!priv)
diff --git a/arch/cris/arch-v32/kernel/signal.c b/arch/cris/arch-v32/kernel/signal.c
index 99e59b3eacf8..7cd6ac803409 100644
--- a/arch/cris/arch-v32/kernel/signal.c
+++ b/arch/cris/arch-v32/kernel/signal.c
@@ -686,7 +686,7 @@ keep_debug_flags(unsigned long oldccs, unsigned long oldspc,
int __init
cris_init_signal(void)
{
- u16* data = (u16*)kmalloc(PAGE_SIZE, GFP_KERNEL);
+ u16* data = kmalloc(PAGE_SIZE, GFP_KERNEL);
/* This is movu.w __NR_sigreturn, r9; break 13; */
data[0] = 0x9c5f;
diff --git a/arch/cris/kernel/profile.c b/arch/cris/kernel/profile.c
index 69c52189f044..f60ab785f235 100644
--- a/arch/cris/kernel/profile.c
+++ b/arch/cris/kernel/profile.c
@@ -59,7 +59,7 @@ static int
__init init_cris_profile(void)
{
struct proc_dir_entry *entry;
- sample_buffer = (char*)kmalloc(SAMPLE_BUFFER_SIZE, GFP_KERNEL);
+ sample_buffer = kmalloc(SAMPLE_BUFFER_SIZE, GFP_KERNEL);
sample_buffer_pos = sample_buffer;
entry = create_proc_entry("system_profile", S_IWUSR | S_IRUGO, NULL);
if (entry) {
diff --git a/arch/h8300/kernel/ints.c b/arch/h8300/kernel/ints.c
index 1bfc77e391d5..587ef7f4fcc7 100644
--- a/arch/h8300/kernel/ints.c
+++ b/arch/h8300/kernel/ints.c
@@ -141,7 +141,7 @@ int request_irq(unsigned int irq,
return -EBUSY;
if (use_kmalloc)
- irq_handle = (irq_handler_t *)kmalloc(sizeof(irq_handler_t), GFP_ATOMIC);
+ irq_handle = kmalloc(sizeof(irq_handler_t), GFP_ATOMIC);
else {
/* use bootmem allocater */
irq_handle = (irq_handler_t *)alloc_bootmem(sizeof(irq_handler_t));
diff --git a/arch/h8300/platform/h8s/ints.c b/arch/h8300/platform/h8s/ints.c
index 270440de4610..567f681ddfec 100644
--- a/arch/h8300/platform/h8s/ints.c
+++ b/arch/h8300/platform/h8s/ints.c
@@ -176,7 +176,7 @@ int request_irq(unsigned int irq,
}
if (use_kmalloc)
- irq_handle = (irq_handler_t *)kmalloc(sizeof(irq_handler_t), GFP_ATOMIC);
+ irq_handle = kmalloc(sizeof(irq_handler_t), GFP_ATOMIC);
else {
/* use bootmem allocater */
irq_handle = (irq_handler_t *)alloc_bootmem(sizeof(irq_handler_t));
diff --git a/arch/i386/boot/compressed/.gitignore b/arch/i386/boot/compressed/.gitignore
new file mode 100644
index 000000000000..be0ed065249b
--- /dev/null
+++ b/arch/i386/boot/compressed/.gitignore
@@ -0,0 +1 @@
+relocs
diff --git a/arch/i386/boot/compressed/head.S b/arch/i386/boot/compressed/head.S
index f395a4bb38bb..3517a32aaf41 100644
--- a/arch/i386/boot/compressed/head.S
+++ b/arch/i386/boot/compressed/head.S
@@ -28,7 +28,7 @@
#include <asm/page.h>
#include <asm/boot.h>
-.section ".text.head"
+.section ".text.head","ax",@progbits
.globl startup_32
startup_32:
diff --git a/arch/i386/defconfig b/arch/i386/defconfig
index 3265208e5899..88b7c1cf65a2 100644
--- a/arch/i386/defconfig
+++ b/arch/i386/defconfig
@@ -1167,7 +1167,7 @@ CONFIG_USB_STORAGE=y
# USB Input Devices
#
CONFIG_USB_HID=y
-# CONFIG_USB_HID_POWERBOOK is not set
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
# CONFIG_HID_FF is not set
# CONFIG_USB_HIDDEV is not set
# CONFIG_USB_AIPTEK is not set
@@ -1493,8 +1493,6 @@ CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_VM is not set
# CONFIG_DEBUG_LIST is not set
# CONFIG_FRAME_POINTER is not set
-CONFIG_UNWIND_INFO=y
-CONFIG_STACK_UNWIND=y
# CONFIG_FORCED_INLINING is not set
# CONFIG_HEADERS_CHECK is not set
# CONFIG_RCU_TORTURE_TEST is not set
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c
index c8f96cff07c6..094300b3a81f 100644
--- a/arch/i386/kernel/acpi/boot.c
+++ b/arch/i386/kernel/acpi/boot.c
@@ -1327,3 +1327,25 @@ static int __init setup_acpi_sci(char *s)
return 0;
}
early_param("acpi_sci", setup_acpi_sci);
+
+int __acpi_acquire_global_lock(unsigned int *lock)
+{
+ unsigned int old, new, val;
+ do {
+ old = *lock;
+ new = (((old & ~0x3) + 2) + ((old >> 1) & 0x1));
+ val = cmpxchg(lock, old, new);
+ } while (unlikely (val != old));
+ return (new < 3) ? -1 : 0;
+}
+
+int __acpi_release_global_lock(unsigned int *lock)
+{
+ unsigned int old, new, val;
+ do {
+ old = *lock;
+ new = old & ~0x3;
+ val = cmpxchg(lock, old, new);
+ } while (unlikely (val != old));
+ return old & 0x1;
+}
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
index a97847da9ed5..199016927541 100644
--- a/arch/i386/kernel/apm.c
+++ b/arch/i386/kernel/apm.c
@@ -785,7 +785,11 @@ static int apm_do_idle(void)
polling = !!(current_thread_info()->status & TS_POLLING);
if (polling) {
current_thread_info()->status &= ~TS_POLLING;
- smp_mb__after_clear_bit();
+ /*
+ * TS_POLLING-cleared state must be visible before we
+ * test NEED_RESCHED:
+ */
+ smp_mb();
}
if (!need_resched()) {
idled = 1;
@@ -1604,7 +1608,7 @@ static int do_open(struct inode * inode, struct file * filp)
{
struct apm_user * as;
- as = (struct apm_user *)kmalloc(sizeof(*as), GFP_KERNEL);
+ as = kmalloc(sizeof(*as), GFP_KERNEL);
if (as == NULL) {
printk(KERN_ERR "apm: cannot allocate struct of size %d bytes\n",
sizeof(*as));
diff --git a/arch/i386/kernel/e820.c b/arch/i386/kernel/e820.c
index 2f7d0a92fd7c..f391abcf7da9 100644
--- a/arch/i386/kernel/e820.c
+++ b/arch/i386/kernel/e820.c
@@ -668,7 +668,7 @@ void __init register_bootmem_low_pages(unsigned long max_low_pfn)
}
}
-void __init register_memory(void)
+void __init e820_register_memory(void)
{
unsigned long gapstart, gapsize, round;
unsigned long long last;
diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
index de34b7fed3c1..06461b8b715d 100644
--- a/arch/i386/kernel/entry.S
+++ b/arch/i386/kernel/entry.S
@@ -979,38 +979,6 @@ ENTRY(spurious_interrupt_bug)
jmp error_code
CFI_ENDPROC
-#ifdef CONFIG_STACK_UNWIND
-ENTRY(arch_unwind_init_running)
- CFI_STARTPROC
- movl 4(%esp), %edx
- movl (%esp), %ecx
- leal 4(%esp), %eax
- movl %ebx, PT_EBX(%edx)
- xorl %ebx, %ebx
- movl %ebx, PT_ECX(%edx)
- movl %ebx, PT_EDX(%edx)
- movl %esi, PT_ESI(%edx)
- movl %edi, PT_EDI(%edx)
- movl %ebp, PT_EBP(%edx)
- movl %ebx, PT_EAX(%edx)
- movl $__USER_DS, PT_DS(%edx)
- movl $__USER_DS, PT_ES(%edx)
- movl $0, PT_GS(%edx)
- movl %ebx, PT_ORIG_EAX(%edx)
- movl %ecx, PT_EIP(%edx)
- movl 12(%esp), %ecx
- movl $__KERNEL_CS, PT_CS(%edx)
- movl %ebx, PT_EFLAGS(%edx)
- movl %eax, PT_OLDESP(%edx)
- movl 8(%esp), %eax
- movl %ecx, 8(%esp)
- movl PT_EBX(%edx), %ebx
- movl $__KERNEL_DS, PT_OLDSS(%edx)
- jmpl *%eax
- CFI_ENDPROC
-ENDPROC(arch_unwind_init_running)
-#endif
-
ENTRY(kernel_thread_helper)
pushl $0 # fake return address for unwinder
CFI_STARTPROC
diff --git a/arch/i386/kernel/microcode.c b/arch/i386/kernel/microcode.c
index 972346604f9d..c8fa13721bcb 100644
--- a/arch/i386/kernel/microcode.c
+++ b/arch/i386/kernel/microcode.c
@@ -1,7 +1,7 @@
/*
* Intel CPU Microcode Update Driver for Linux
*
- * Copyright (C) 2000-2004 Tigran Aivazian
+ * Copyright (C) 2000-2006 Tigran Aivazian <tigran@aivazian.fsnet.co.uk>
* 2006 Shaohua Li <shaohua.li@intel.com>
*
* This driver allows to upgrade microcode on Intel processors
@@ -92,7 +92,7 @@
#include <asm/processor.h>
MODULE_DESCRIPTION("Intel CPU (IA-32) Microcode Update Driver");
-MODULE_AUTHOR("Tigran Aivazian <tigran@veritas.com>");
+MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>");
MODULE_LICENSE("GPL");
#define MICROCODE_VERSION "1.14a"
@@ -722,7 +722,7 @@ mc_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu)
return NOTIFY_OK;
}
-static struct notifier_block mc_cpu_notifier = {
+static struct notifier_block __cpuinitdata mc_cpu_notifier = {
.notifier_call = mc_cpu_callback,
};
@@ -752,7 +752,7 @@ static int __init microcode_init (void)
register_hotcpu_notifier(&mc_cpu_notifier);
printk(KERN_INFO
- "IA-32 Microcode Update Driver: v" MICROCODE_VERSION " <tigran@veritas.com>\n");
+ "IA-32 Microcode Update Driver: v" MICROCODE_VERSION " <tigran@aivazian.fsnet.co.uk>\n");
return 0;
}
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index 99308510a17c..c641056233a6 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -102,7 +102,12 @@ void default_idle(void)
{
if (!hlt_counter && boot_cpu_data.hlt_works_ok) {
current_thread_info()->status &= ~TS_POLLING;
- smp_mb__after_clear_bit();
+ /*
+ * TS_POLLING-cleared state must be visible before we
+ * test NEED_RESCHED:
+ */
+ smp_mb();
+
local_irq_disable();
if (!need_resched())
safe_halt(); /* enables interrupts racelessly */
diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c
index f3f94ac5736a..af8aabe85800 100644
--- a/arch/i386/kernel/ptrace.c
+++ b/arch/i386/kernel/ptrace.c
@@ -45,7 +45,7 @@
/*
* Offset of eflags on child stack..
*/
-#define EFL_OFFSET ((EFL-2)*4-sizeof(struct pt_regs))
+#define EFL_OFFSET offsetof(struct pt_regs, eflags)
static inline struct pt_regs *get_child_regs(struct task_struct *task)
{
@@ -54,24 +54,24 @@ static inline struct pt_regs *get_child_regs(struct task_struct *task)
}
/*
- * this routine will get a word off of the processes privileged stack.
- * the offset is how far from the base addr as stored in the TSS.
- * this routine assumes that all the privileged stacks are in our
+ * This routine will get a word off of the processes privileged stack.
+ * the offset is bytes into the pt_regs structure on the stack.
+ * This routine assumes that all the privileged stacks are in our
* data space.
*/
static inline int get_stack_long(struct task_struct *task, int offset)
{
unsigned char *stack;
- stack = (unsigned char *)task->thread.esp0;
+ stack = (unsigned char *)task->thread.esp0 - sizeof(struct pt_regs);
stack += offset;
return (*((int *)stack));
}
/*
- * this routine will put a word on the processes privileged stack.
- * the offset is how far from the base addr as stored in the TSS.
- * this routine assumes that all the privileged stacks are in our
+ * This routine will put a word on the processes privileged stack.
+ * the offset is bytes into the pt_regs structure on the stack.
+ * This routine assumes that all the privileged stacks are in our
* data space.
*/
static inline int put_stack_long(struct task_struct *task, int offset,
@@ -79,7 +79,7 @@ static inline int put_stack_long(struct task_struct *task, int offset,
{
unsigned char * stack;
- stack = (unsigned char *) task->thread.esp0;
+ stack = (unsigned char *)task->thread.esp0 - sizeof(struct pt_regs);
stack += offset;
*(unsigned long *) stack = data;
return 0;
@@ -114,7 +114,7 @@ static int putreg(struct task_struct *child,
}
if (regno > ES*4)
regno -= 1*4;
- put_stack_long(child, regno - sizeof(struct pt_regs), value);
+ put_stack_long(child, regno, value);
return 0;
}
@@ -137,7 +137,6 @@ static unsigned long getreg(struct task_struct *child,
default:
if (regno > ES*4)
regno -= 1*4;
- regno = regno - sizeof(struct pt_regs);
retval &= get_stack_long(child, regno);
}
return retval;
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index 79df6e612dbd..6f6cb7b31d18 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -639,7 +639,7 @@ void __init setup_arch(char **cmdline_p)
get_smp_config();
#endif
- register_memory();
+ e820_register_memory();
#ifdef CONFIG_VT
#if defined(CONFIG_VGA_CONSOLE)
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index b0f84e5778ad..aef39be81361 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -69,9 +69,7 @@ static int __devinitdata smp_b_stepping;
/* Number of siblings per CPU package */
int smp_num_siblings = 1;
-#ifdef CONFIG_SMP
EXPORT_SYMBOL(smp_num_siblings);
-#endif
/* Last level cache ID of each logical CPU */
int cpu_llc_id[NR_CPUS] __cpuinitdata = {[0 ... NR_CPUS-1] = BAD_APICID};
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index 2b30dbf8d117..0efad8aeb41a 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -94,11 +94,6 @@ asmlinkage void spurious_interrupt_bug(void);
asmlinkage void machine_check(void);
int kstack_depth_to_print = 24;
-#ifdef CONFIG_STACK_UNWIND
-static int call_trace = 1;
-#else
-#define call_trace (-1)
-#endif
ATOMIC_NOTIFIER_HEAD(i386die_chain);
int register_die_notifier(struct notifier_block *nb)
@@ -152,33 +147,6 @@ static inline unsigned long print_context_stack(struct thread_info *tinfo,
return ebp;
}
-struct ops_and_data {
- struct stacktrace_ops *ops;
- void *data;
-};
-
-static asmlinkage int
-dump_trace_unwind(struct unwind_frame_info *info, void *data)
-{
- struct ops_and_data *oad = (struct ops_and_data *)data;
- int n = 0;
- unsigned long sp = UNW_SP(info);
-
- if (arch_unw_user_mode(info))
- return -1;
- while (unwind(info) == 0 && UNW_PC(info)) {
- n++;
- oad->ops->address(oad->data, UNW_PC(info));
- if (arch_unw_user_mode(info))
- break;
- if ((sp & ~(PAGE_SIZE - 1)) == (UNW_SP(info) & ~(PAGE_SIZE - 1))
- && sp > UNW_SP(info))
- break;
- sp = UNW_SP(info);
- }
- return n;
-}
-
#define MSG(msg) ops->warning(data, msg)
void dump_trace(struct task_struct *task, struct pt_regs *regs,
@@ -190,41 +158,6 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
if (!task)
task = current;
- if (call_trace >= 0) {
- int unw_ret = 0;
- struct unwind_frame_info info;
- struct ops_and_data oad = { .ops = ops, .data = data };
-
- if (regs) {
- if (unwind_init_frame_info(&info, task, regs) == 0)
- unw_ret = dump_trace_unwind(&info, &oad);
- } else if (task == current)
- unw_ret = unwind_init_running(&info, dump_trace_unwind,
- &oad);
- else {
- if (unwind_init_blocked(&info, task) == 0)
- unw_ret = dump_trace_unwind(&info, &oad);
- }
- if (unw_ret > 0) {
- if (call_trace == 1 && !arch_unw_user_mode(&info)) {
- ops->warning_symbol(data,
- "DWARF2 unwinder stuck at %s",
- UNW_PC(&info));
- if (UNW_SP(&info) >= PAGE_OFFSET) {
- MSG("Leftover inexact backtrace:");
- stack = (void *)UNW_SP(&info);
- if (!stack)
- return;
- ebp = UNW_FP(&info);
- } else
- MSG("Full inexact backtrace again:");
- } else if (call_trace >= 1)
- return;
- else
- MSG("Full inexact backtrace again:");
- } else
- MSG("Inexact backtrace:");
- }
if (!stack) {
unsigned long dummy;
stack = &dummy;
@@ -1258,19 +1191,3 @@ static int __init kstack_setup(char *s)
return 1;
}
__setup("kstack=", kstack_setup);
-
-#ifdef CONFIG_STACK_UNWIND
-static int __init call_trace_setup(char *s)
-{
- if (strcmp(s, "old") == 0)
- call_trace = -1;
- else if (strcmp(s, "both") == 0)
- call_trace = 0;
- else if (strcmp(s, "newfallback") == 0)
- call_trace = 1;
- else if (strcmp(s, "new") == 2)
- call_trace = 2;
- return 1;
-}
-__setup("call_trace=", call_trace_setup);
-#endif
diff --git a/arch/i386/mm/discontig.c b/arch/i386/mm/discontig.c
index 103b76e56a94..e0c390d6ceb5 100644
--- a/arch/i386/mm/discontig.c
+++ b/arch/i386/mm/discontig.c
@@ -405,3 +405,31 @@ void __init set_highmem_pages_init(int bad_ppro)
totalram_pages += totalhigh_pages;
#endif
}
+
+#ifdef CONFIG_MEMORY_HOTPLUG
+int paddr_to_nid(u64 addr)
+{
+ int nid;
+ unsigned long pfn = PFN_DOWN(addr);
+
+ for_each_node(nid)
+ if (node_start_pfn[nid] <= pfn &&
+ pfn < node_end_pfn[nid])
+ return nid;
+
+ return -1;
+}
+
+/*
+ * This function is used to ask node id BEFORE memmap and mem_section's
+ * initialization (pfn_to_nid() can't be used yet).
+ * If _PXM is not defined on ACPI's DSDT, node id must be found by this.
+ */
+int memory_add_physaddr_to_nid(u64 addr)
+{
+ int nid = paddr_to_nid(addr);
+ return (nid >= 0) ? nid : 0;
+}
+
+EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid);
+#endif
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c
index 84697dfc7348..60a7e57af197 100644
--- a/arch/i386/mm/init.c
+++ b/arch/i386/mm/init.c
@@ -673,16 +673,10 @@ void __init mem_init(void)
#endif
}
-/*
- * this is for the non-NUMA, single node SMP system case.
- * Specifically, in the case of x86, we will always add
- * memory to the highmem for now.
- */
#ifdef CONFIG_MEMORY_HOTPLUG
-#ifndef CONFIG_NEED_MULTIPLE_NODES
int arch_add_memory(int nid, u64 start, u64 size)
{
- struct pglist_data *pgdata = &contig_page_data;
+ struct pglist_data *pgdata = NODE_DATA(nid);
struct zone *zone = pgdata->node_zones + ZONE_HIGHMEM;
unsigned long start_pfn = start >> PAGE_SHIFT;
unsigned long nr_pages = size >> PAGE_SHIFT;
@@ -694,7 +688,7 @@ int remove_memory(u64 start, u64 size)
{
return -EINVAL;
}
-#endif
+EXPORT_SYMBOL_GPL(remove_memory);
#endif
struct kmem_cache *pgd_cache;
diff --git a/arch/i386/pci/fixup.c b/arch/i386/pci/fixup.c
index cde1170b01a1..8053b17ab647 100644
--- a/arch/i386/pci/fixup.c
+++ b/arch/i386/pci/fixup.c
@@ -115,7 +115,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, pci
#define VIA_8363_KL133_REVISION_ID 0x81
#define VIA_8363_KM133_REVISION_ID 0x84
-static void __devinit pci_fixup_via_northbridge_bug(struct pci_dev *d)
+static void pci_fixup_via_northbridge_bug(struct pci_dev *d)
{
u8 v;
u8 revision;
@@ -151,6 +151,10 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8363_0, pci_fixup_
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8622, pci_fixup_via_northbridge_bug);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8361, pci_fixup_via_northbridge_bug);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8367_0, pci_fixup_via_northbridge_bug);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8363_0, pci_fixup_via_northbridge_bug);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8622, pci_fixup_via_northbridge_bug);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8361, pci_fixup_via_northbridge_bug);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8367_0, pci_fixup_via_northbridge_bug);
/*
* For some reasons Intel decided that certain parts of their
@@ -181,7 +185,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_fixup_transparent_
* issue another HALT within 80 ns of the initial HALT, the failure condition
* is avoided.
*/
-static void __init pci_fixup_nforce2(struct pci_dev *dev)
+static void pci_fixup_nforce2(struct pci_dev *dev)
{
u32 val;
@@ -204,6 +208,7 @@ static void __init pci_fixup_nforce2(struct pci_dev *dev)
}
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2, pci_fixup_nforce2);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2, pci_fixup_nforce2);
/* Max PCI Express root ports */
#define MAX_PCIEROOT 6
@@ -419,7 +424,7 @@ DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_TI, 0x8032,
* Prevent the BIOS trapping accesses to the Cyrix CS5530A video device
* configuration space.
*/
-static void __devinit pci_early_fixup_cyrix_5530(struct pci_dev *dev)
+static void pci_early_fixup_cyrix_5530(struct pci_dev *dev)
{
u8 r;
/* clear 'F4 Video Configuration Trap' bit */
@@ -429,3 +434,5 @@ static void __devinit pci_early_fixup_cyrix_5530(struct pci_dev *dev)
}
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY,
pci_early_fixup_cyrix_5530);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY,
+ pci_early_fixup_cyrix_5530);
diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c
index c6b6d9bbc453..e2616a266e13 100644
--- a/arch/i386/pci/mmconfig.c
+++ b/arch/i386/pci/mmconfig.c
@@ -26,6 +26,7 @@
/* The base address of the last MMCONFIG device accessed */
static u32 mmcfg_last_accessed_device;
+static int mmcfg_last_accessed_cpu;
static DECLARE_BITMAP(fallback_slots, MAX_CHECK_BUS*32);
@@ -73,8 +74,11 @@ static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn)
static void pci_exp_set_dev_base(unsigned int base, int bus, int devfn)
{
u32 dev_base = base | (bus << 20) | (devfn << 12);
- if (dev_base != mmcfg_last_accessed_device) {
+ int cpu = smp_processor_id();
+ if (dev_base != mmcfg_last_accessed_device ||
+ cpu != mmcfg_last_accessed_cpu) {
mmcfg_last_accessed_device = dev_base;
+ mmcfg_last_accessed_cpu = cpu;
set_fixmap_nocache(FIX_PCIE_MCFG, dev_base);
}
}
diff --git a/arch/ia64/kernel/cpufreq/acpi-cpufreq.c b/arch/ia64/kernel/cpufreq/acpi-cpufreq.c
index 088f130197ae..15c08d52f09f 100644
--- a/arch/ia64/kernel/cpufreq/acpi-cpufreq.c
+++ b/arch/ia64/kernel/cpufreq/acpi-cpufreq.c
@@ -276,12 +276,10 @@ acpi_cpufreq_cpu_init (
dprintk("acpi_cpufreq_cpu_init\n");
- data = kmalloc(sizeof(struct cpufreq_acpi_io), GFP_KERNEL);
+ data = kzalloc(sizeof(struct cpufreq_acpi_io), GFP_KERNEL);
if (!data)
return (-ENOMEM);
- memset(data, 0, sizeof(struct cpufreq_acpi_io));
-
acpi_io_data[cpu] = data;
result = acpi_processor_register_performance(&data->acpi_data, cpu);
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
index 51922b98086a..17685abaf496 100644
--- a/arch/ia64/kernel/process.c
+++ b/arch/ia64/kernel/process.c
@@ -268,10 +268,16 @@ cpu_idle (void)
/* endless idle loop with no priority at all */
while (1) {
- if (can_do_pal_halt)
+ if (can_do_pal_halt) {
current_thread_info()->status &= ~TS_POLLING;
- else
+ /*
+ * TS_POLLING-cleared state must be visible before we
+ * test NEED_RESCHED:
+ */
+ smp_mb();
+ } else {
current_thread_info()->status |= TS_POLLING;
+ }
if (!need_resched()) {
void (*idle)(void);
diff --git a/arch/ia64/sn/kernel/sn2/sn_hwperf.c b/arch/ia64/sn/kernel/sn2/sn_hwperf.c
index 462ea178f49a..33367996d72d 100644
--- a/arch/ia64/sn/kernel/sn2/sn_hwperf.c
+++ b/arch/ia64/sn/kernel/sn2/sn_hwperf.c
@@ -189,7 +189,7 @@ static void print_pci_topology(struct seq_file *s)
int e;
for (sz = PAGE_SIZE; sz < 16 * PAGE_SIZE; sz += PAGE_SIZE) {
- if (!(p = (char *)kmalloc(sz, GFP_KERNEL)))
+ if (!(p = kmalloc(sz, GFP_KERNEL)))
break;
e = ia64_sn_ioif_get_pci_topology(__pa(p), sz);
if (e == SALRET_OK)
diff --git a/arch/m68k/mm/kmap.c b/arch/m68k/mm/kmap.c
index b54ef1726c55..46b7d6035aab 100644
--- a/arch/m68k/mm/kmap.c
+++ b/arch/m68k/mm/kmap.c
@@ -59,7 +59,7 @@ static struct vm_struct *get_io_area(unsigned long size)
unsigned long addr;
struct vm_struct **p, *tmp, *area;
- area = (struct vm_struct *)kmalloc(sizeof(*area), GFP_KERNEL);
+ area = kmalloc(sizeof(*area), GFP_KERNEL);
if (!area)
return NULL;
addr = KMAP_START;
diff --git a/arch/mips/kernel/apm.c b/arch/mips/kernel/apm.c
index 528e731049c1..ba16d07588cb 100644
--- a/arch/mips/kernel/apm.c
+++ b/arch/mips/kernel/apm.c
@@ -356,7 +356,7 @@ static int apm_open(struct inode * inode, struct file * filp)
{
struct apm_user *as;
- as = (struct apm_user *)kzalloc(sizeof(*as), GFP_KERNEL);
+ as = kzalloc(sizeof(*as), GFP_KERNEL);
if (as) {
/*
* XXX - this is a tiny bit broken, when we consider BSD
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index ea2d15370bb7..30245c09d025 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -203,6 +203,31 @@ static inline void kunmap_coherent(struct page *page)
preempt_check_resched();
}
+void copy_user_highpage(struct page *to, struct page *from,
+ unsigned long vaddr, struct vm_area_struct *vma)
+{
+ void *vfrom, *vto;
+
+ vto = kmap_atomic(to, KM_USER1);
+ if (cpu_has_dc_aliases) {
+ vfrom = kmap_coherent(from, vaddr);
+ copy_page(vto, vfrom);
+ kunmap_coherent(from);
+ } else {
+ vfrom = kmap_atomic(from, KM_USER0);
+ copy_page(vto, vfrom);
+ kunmap_atomic(vfrom, KM_USER0);
+ }
+ if (((vma->vm_flags & VM_EXEC) && !cpu_has_ic_fills_f_dc) ||
+ pages_do_alias((unsigned long)vto, vaddr & PAGE_MASK))
+ flush_data_cache_page((unsigned long)vto);
+ kunmap_atomic(vto, KM_USER1);
+ /* Make sure this page is cleared on other CPU's too before using it */
+ smp_wmb();
+}
+
+EXPORT_SYMBOL(copy_user_highpage);
+
void copy_to_user_page(struct vm_area_struct *vma,
struct page *page, unsigned long vaddr, void *dst, const void *src,
unsigned long len)
diff --git a/arch/parisc/hpux/sys_hpux.c b/arch/parisc/hpux/sys_hpux.c
index d88309209f56..04c2ff444396 100644
--- a/arch/parisc/hpux/sys_hpux.c
+++ b/arch/parisc/hpux/sys_hpux.c
@@ -475,7 +475,7 @@ int hpux_sysfs(int opcode, unsigned long arg1, unsigned long arg2)
printk(KERN_DEBUG "len of arg1 = %d\n", len);
if (len == 0)
return 0;
- fsname = (char *) kmalloc(len, GFP_KERNEL);
+ fsname = kmalloc(len, GFP_KERNEL);
if ( !fsname ) {
printk(KERN_DEBUG "failed to kmalloc fsname\n");
return 0;
diff --git a/arch/parisc/kernel/unwind.c b/arch/parisc/kernel/unwind.c
index 920bdbf8404f..c10ab47d81fa 100644
--- a/arch/parisc/kernel/unwind.c
+++ b/arch/parisc/kernel/unwind.c
@@ -343,7 +343,7 @@ void unwind_frame_init_from_blocked_task(struct unwind_frame_info *info, struct
struct pt_regs *r = &t->thread.regs;
struct pt_regs *r2;
- r2 = (struct pt_regs *)kmalloc(sizeof(struct pt_regs), GFP_KERNEL);
+ r2 = kmalloc(sizeof(struct pt_regs), GFP_KERNEL);
if (!r2)
return;
*r2 = *r;
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 343dbcfdf08a..98392fb5f581 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -152,6 +152,9 @@ $(obj)/zImage.initrd.miboot: vmlinux $(wrapperbits)
$(obj)/zImage.ps3: vmlinux
$(STRIP) -s -R .comment $< -o $@
+$(obj)/zImage.initrd.ps3: vmlinux
+ @echo " WARNING zImage.initrd.ps3 not supported (yet)"
+
$(obj)/uImage: vmlinux $(wrapperbits)
$(call cmd,wrap,uboot)
diff --git a/arch/powerpc/configs/cell_defconfig b/arch/powerpc/configs/cell_defconfig
index a98c982c73ad..d1d25152f74f 100644
--- a/arch/powerpc/configs/cell_defconfig
+++ b/arch/powerpc/configs/cell_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.19-rc6
-# Wed Nov 22 15:33:04 2006
+# Linux kernel version: 2.6.20-rc1
+# Tue Dec 19 14:59:53 2006
#
CONFIG_PPC64=y
CONFIG_64BIT=y
@@ -10,6 +10,8 @@ CONFIG_MMU=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_IRQ_PER_CPU=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_ARCH_HAS_ILOG2_U32=y
+CONFIG_ARCH_HAS_ILOG2_U64=y
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_GENERIC_FIND_NEXT_BIT=y
@@ -23,6 +25,7 @@ CONFIG_PPC_OF=y
CONFIG_PPC_UDBG_16550=y
# CONFIG_GENERIC_TBSYNC is not set
CONFIG_AUDIT_ARCH=y
+CONFIG_GENERIC_BUG=y
# CONFIG_DEFAULT_UIMAGE is not set
#
@@ -66,6 +69,7 @@ CONFIG_SYSVIPC=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_CPUSETS=y
+CONFIG_SYSFS_DEPRECATED=y
# CONFIG_RELAY is not set
CONFIG_INITRAMFS_SOURCE=""
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
@@ -128,14 +132,16 @@ CONFIG_PPC_MULTIPLATFORM=y
# CONFIG_APUS is not set
# CONFIG_PPC_PSERIES is not set
# CONFIG_PPC_ISERIES is not set
+# CONFIG_PPC_MPC52xx is not set
# CONFIG_PPC_PMAC is not set
# CONFIG_PPC_MAPLE is not set
# CONFIG_PPC_PASEMI is not set
CONFIG_PPC_CELL=y
CONFIG_PPC_CELL_NATIVE=y
CONFIG_PPC_IBM_CELL_BLADE=y
-CONFIG_UDBG_RTAS_CONSOLE=y
CONFIG_PPC_PS3=y
+CONFIG_PPC_NATIVE=y
+CONFIG_UDBG_RTAS_CONSOLE=y
# CONFIG_U3_DART is not set
CONFIG_PPC_RTAS=y
# CONFIG_RTAS_ERROR_LOGGING is not set
@@ -177,12 +183,14 @@ CONFIG_CBE_CPUFREQ=m
CONFIG_PS3_HTAB_SIZE=20
# CONFIG_PS3_DYNAMIC_DMA is not set
CONFIG_PS3_USE_LPAR_ADDR=y
+CONFIG_PS3_VUART=y
#
# Kernel options
#
# CONFIG_HZ_100 is not set
CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
# CONFIG_HZ_1000 is not set
CONFIG_HZ=250
CONFIG_PREEMPT_NONE=y
@@ -237,6 +245,7 @@ CONFIG_GENERIC_ISA_DMA=y
CONFIG_PCI=y
CONFIG_PCI_DOMAINS=y
CONFIG_PCIEPORTBUS=y
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
# CONFIG_PCI_DEBUG is not set
#
@@ -270,7 +279,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=y
+CONFIG_IP_PNP_RARP=y
CONFIG_NET_IPIP=y
# CONFIG_NET_IPGRE is not set
# CONFIG_IP_MROUTE is not set
@@ -289,6 +301,7 @@ CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_CUBIC=y
CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
#
# IP: Virtual Server Configuration
@@ -317,31 +330,67 @@ CONFIG_NETFILTER=y
#
# Core Netfilter Configuration
#
-# CONFIG_NETFILTER_NETLINK is not set
-# CONFIG_NETFILTER_XTABLES is not set
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+# CONFIG_NF_CONNTRACK_ENABLED is not set
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
+CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_QUOTA=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
#
# IP: Netfilter Configuration
#
-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_H323 is not set
-# CONFIG_IP_NF_SIP is not set
CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_IPRANGE=m
+CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_RECENT=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_MATCH_OWNER=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=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_MANGLE=m
+CONFIG_IP_NF_TARGET_TOS=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
#
# IPv6: Netfilter Configuration (EXPERIMENTAL)
#
# CONFIG_IP6_NF_QUEUE is not set
+# CONFIG_IP6_NF_IPTABLES is not set
#
# DCCP Configuration (EXPERIMENTAL)
@@ -373,6 +422,7 @@ CONFIG_IP_NF_QUEUE=m
# QoS and/or fair queueing
#
# CONFIG_NET_SCHED is not set
+CONFIG_NET_CLS_ROUTE=y
#
# Network testing
@@ -428,6 +478,7 @@ CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
# CONFIG_BLK_DEV_NBD is not set
# 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=131072
@@ -457,6 +508,7 @@ CONFIG_IDEDISK_MULTI_MODE=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
#
@@ -468,7 +520,6 @@ CONFIG_IDEPCI_SHARE_IRQ=y
# CONFIG_BLK_DEV_OFFBOARD is not set
CONFIG_BLK_DEV_GENERIC=y
# CONFIG_BLK_DEV_OPTI621 is not set
-# CONFIG_BLK_DEV_SL82C105 is not set
CONFIG_BLK_DEV_IDEDMA_PCI=y
# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
CONFIG_IDEDMA_PCI_AUTO=y
@@ -492,6 +543,7 @@ CONFIG_BLK_DEV_AEC62XX=y
# CONFIG_BLK_DEV_PDC202XX_NEW is not set
# CONFIG_BLK_DEV_SVWKS is not set
CONFIG_BLK_DEV_SIIMAGE=y
+# CONFIG_BLK_DEV_SL82C105 is not set
# CONFIG_BLK_DEV_SLC90E66 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
@@ -505,8 +557,74 @@ CONFIG_IDEDMA_AUTO=y
# SCSI device support
#
# CONFIG_RAID_ATTRS is not set
-# CONFIG_SCSI is not set
+CONFIG_SCSI=m
+# CONFIG_SCSI_TGT is not set
# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+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 is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+
+#
+# SCSI Transports
+#
+# 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
+# CONFIG_SCSI_SAS_LIBSAS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX 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_AIC94XX is not set
+# CONFIG_SCSI_ARCMSR is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_HPTIOP 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_STEX is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_SRP is not set
#
# Serial ATA (prod) and Parallel ATA (experimental) drivers
@@ -538,6 +656,9 @@ CONFIG_DM_MULTIPATH=m
# Fusion MPT device support
#
# 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
@@ -552,6 +673,7 @@ CONFIG_DM_MULTIPATH=m
#
# Macintosh device drivers
#
+# CONFIG_MAC_EMUMOUSEBTN is not set
# CONFIG_WINDFARM is not set
#
@@ -559,7 +681,7 @@ CONFIG_DM_MULTIPATH=m
#
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
-CONFIG_BONDING=y
+CONFIG_BONDING=m
# CONFIG_EQUALIZER is not set
CONFIG_TUN=y
@@ -604,11 +726,11 @@ CONFIG_E1000_NAPI=y
# CONFIG_R8169 is not set
# CONFIG_SIS190 is not set
CONFIG_SKGE=m
-# CONFIG_SKY2 is not set
+CONFIG_SKY2=m
# CONFIG_SK98LIN is not set
-# CONFIG_TIGON3 is not set
+CONFIG_TIGON3=y
# CONFIG_BNX2 is not set
-CONFIG_SPIDER_NET=m
+CONFIG_SPIDER_NET=y
# CONFIG_QLA3XXX is not set
#
@@ -618,6 +740,7 @@ CONFIG_SPIDER_NET=m
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
# CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
#
# Token Ring devices
@@ -637,6 +760,7 @@ CONFIG_SPIDER_NET=m
# 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_NETPOLL is not set
@@ -703,6 +827,7 @@ CONFIG_SERIAL_NONSTANDARD=y
# CONFIG_DIGIEPCA is not set
# CONFIG_MOXA_INTELLIO is not set
# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_MOXA_SMARTIO_NEW is not set
# CONFIG_ISI is not set
# CONFIG_SYNCLINK is not set
# CONFIG_SYNCLINKMP is not set
@@ -729,6 +854,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
+CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_UNIX98_PTYS=y
# CONFIG_LEGACY_PTYS is not set
CONFIG_HVC_DRIVER=y
@@ -756,16 +882,17 @@ CONFIG_WATCHDOG_RTAS=y
#
# CONFIG_PCIPCWATCHDOG is not set
# CONFIG_WDTPCI is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
# CONFIG_HW_RANDOM is not set
CONFIG_GEN_RTC=y
# CONFIG_GEN_RTC_X is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
# CONFIG_AGP is not set
# CONFIG_DRM is not set
# CONFIG_RAW_DRIVER is not set
@@ -855,12 +982,14 @@ CONFIG_I2C_ALGOBIT=y
# Digital Video Broadcasting Devices
#
# CONFIG_DVB is not set
+# CONFIG_USB_DABUSB is not set
#
# Graphics support
#
CONFIG_FIRMWARE_EDID=y
# CONFIG_FB is not set
+# CONFIG_FB_IBM_GXT4500 is not set
#
# Console display driver support
@@ -875,18 +1004,145 @@ CONFIG_DUMMY_CONSOLE=y
# CONFIG_SOUND is not set
#
+# HID Devices
+#
+CONFIG_HID=m
+
+#
# USB support
#
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
CONFIG_USB_ARCH_HAS_EHCI=y
-# CONFIG_USB 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_MULTITHREAD_PROBE 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_EHCI_TT_NEWSCHED 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_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
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Input Devices
+#
+# CONFIG_USB_HID 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_TOUCHSCREEN is not set
+# CONFIG_USB_YEALINK is not set
+# CONFIG_USB_XPAD is not set
+# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_ATI_REMOTE2 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 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_MII 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_ADUTUX 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_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
+
+#
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
@@ -912,7 +1168,7 @@ CONFIG_USB_ARCH_HAS_EHCI=y
#
# InfiniBand support
#
-CONFIG_INFINIBAND=y
+CONFIG_INFINIBAND=m
CONFIG_INFINIBAND_USER_MAD=m
CONFIG_INFINIBAND_USER_ACCESS=m
CONFIG_INFINIBAND_ADDR_TRANS=y
@@ -922,6 +1178,8 @@ CONFIG_INFINIBAND_MTHCA_DEBUG=y
CONFIG_INFINIBAND_IPOIB=m
CONFIG_INFINIBAND_IPOIB_DEBUG=y
CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y
+# CONFIG_INFINIBAND_SRP is not set
+# CONFIG_INFINIBAND_ISER is not set
#
# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
@@ -946,6 +1204,10 @@ CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y
#
#
+# Virtualization
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
@@ -1028,23 +1290,18 @@ CONFIG_RAMFS=y
#
# Network File Systems
#
-CONFIG_NFS_FS=m
+CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
CONFIG_NFS_V3_ACL=y
# CONFIG_NFS_V4 is not set
# CONFIG_NFS_DIRECTIO is not set
-CONFIG_NFSD=m
-CONFIG_NFSD_V2_ACL=y
-CONFIG_NFSD_V3=y
-CONFIG_NFSD_V3_ACL=y
-# CONFIG_NFSD_V4 is not set
-CONFIG_NFSD_TCP=y
-CONFIG_LOCKD=m
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=m
-CONFIG_NFS_ACL_SUPPORT=m
+CONFIG_NFS_ACL_SUPPORT=y
CONFIG_NFS_COMMON=y
-CONFIG_SUNRPC=m
+CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -1120,8 +1377,14 @@ CONFIG_NLS_ISO8859_15=m
# CONFIG_NLS_UTF8 is not set
#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
# Library routines
#
+CONFIG_BITREVERSE=y
# CONFIG_CRC_CCITT is not set
# CONFIG_CRC16 is not set
CONFIG_CRC32=y
@@ -1130,7 +1393,10 @@ CONFIG_ZLIB_INFLATE=m
CONFIG_ZLIB_DEFLATE=m
CONFIG_TEXTSEARCH=y
CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
CONFIG_PLIST=y
+CONFIG_IOMAP_COPY=y
#
# Instrumentation Support
@@ -1146,6 +1412,8 @@ CONFIG_OPROFILE=y
# CONFIG_ENABLE_MUST_CHECK is not set
CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
CONFIG_LOG_BUF_SHIFT=15
CONFIG_DETECT_SOFTLOCKUP=y
@@ -1159,12 +1427,11 @@ CONFIG_DEBUG_MUTEXES=y
CONFIG_DEBUG_SPINLOCK_SLEEP=y
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_INFO is not set
-CONFIG_DEBUG_FS=y
# CONFIG_DEBUG_VM is not set
# CONFIG_DEBUG_LIST is not set
# CONFIG_FORCED_INLINING is not set
-# CONFIG_HEADERS_CHECK is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_DEBUG_STACKOVERFLOW is not set
# CONFIG_DEBUG_STACK_USAGE is not set
@@ -1191,6 +1458,7 @@ CONFIG_CRYPTO_BLKCIPHER=m
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
# CONFIG_CRYPTO_NULL is not set
# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=m
@@ -1199,8 +1467,10 @@ CONFIG_CRYPTO_SHA1=m
# CONFIG_CRYPTO_SHA512 is not set
# CONFIG_CRYPTO_WP512 is not set
# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
CONFIG_CRYPTO_ECB=m
CONFIG_CRYPTO_CBC=m
+# CONFIG_CRYPTO_LRW is not set
CONFIG_CRYPTO_DES=m
# CONFIG_CRYPTO_BLOWFISH is not set
# CONFIG_CRYPTO_TWOFISH is not set
diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c
index 6960f090991e..869cebbba967 100644
--- a/arch/powerpc/kernel/nvram_64.c
+++ b/arch/powerpc/kernel/nvram_64.c
@@ -505,7 +505,7 @@ static int nvram_scan_partitions(void)
return -ENODEV;
total_size = ppc_md.nvram_size();
- header = (char *) kmalloc(NVRAM_HEADER_LEN, GFP_KERNEL);
+ header = kmalloc(NVRAM_HEADER_LEN, GFP_KERNEL);
if (!header) {
printk(KERN_ERR "nvram_scan_partitions: Failed kmalloc\n");
return -ENOMEM;
@@ -574,7 +574,7 @@ static int __init nvram_init(void)
}
/* initialize our anchor for the nvram partition list */
- nvram_part = (struct nvram_partition *) kmalloc(sizeof(struct nvram_partition), GFP_KERNEL);
+ nvram_part = kmalloc(sizeof(struct nvram_partition), GFP_KERNEL);
if (!nvram_part) {
printk(KERN_ERR "nvram_init: Failed kmalloc\n");
return -ENOMEM;
diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c
index 3002ea3a61a2..b7345176b399 100644
--- a/arch/powerpc/kernel/of_platform.c
+++ b/arch/powerpc/kernel/of_platform.c
@@ -50,6 +50,7 @@ static struct of_device_id of_default_bus_ids[] = {
{ .type = "plb5", },
{ .type = "plb4", },
{ .type = "opb", },
+ { .type = "ebc", },
{},
};
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c
index 8336deafc624..2847cd51a2d7 100644
--- a/arch/powerpc/kernel/pci_32.c
+++ b/arch/powerpc/kernel/pci_32.c
@@ -670,7 +670,7 @@ pcibios_make_OF_bus_map(void)
struct pci_controller* hose;
struct property *map_prop;
- pci_to_OF_bus_map = (u8*)kmalloc(pci_bus_count, GFP_KERNEL);
+ pci_to_OF_bus_map = kmalloc(pci_bus_count, GFP_KERNEL);
if (!pci_to_OF_bus_map) {
printk(KERN_ERR "Can't allocate OF bus map !\n");
return;
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index a6b7692c7269..73c59ec49120 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -360,6 +360,7 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
DBG(" class: 0x%x\n", dev->class);
dev->current_state = 4; /* unknown power state */
+ dev->error_state = pci_channel_io_normal;
if (!strcmp(type, "pci") || !strcmp(type, "pciex")) {
/* a PCI-PCI bridge */
diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c
index 0dfbe1cd28eb..12c51e4ad2b4 100644
--- a/arch/powerpc/kernel/prom_parse.c
+++ b/arch/powerpc/kernel/prom_parse.c
@@ -920,9 +920,20 @@ static int of_irq_map_oldworld(struct device_node *device, int index,
/*
* Old machines just have a list of interrupt numbers
- * and no interrupt-controller nodes.
+ * and no interrupt-controller nodes. We also have dodgy
+ * cases where the APPL,interrupts property is completely
+ * missing behind pci-pci bridges and we have to get it
+ * from the parent (the bridge itself, as apple just wired
+ * everything together on these)
*/
- ints = get_property(device, "AAPL,interrupts", &intlen);
+ while (device) {
+ ints = get_property(device, "AAPL,interrupts", &intlen);
+ if (ints != NULL)
+ break;
+ device = device->parent;
+ if (device && strcmp(device->type, "pci") != 0)
+ break;
+ }
if (ints == NULL)
return -EINVAL;
intlen /= sizeof(u32);
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index e4ebe1a6228e..6b405a3f43f9 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -835,11 +835,21 @@ long sys_swapcontext(struct ucontext __user *old_ctx,
return -EINVAL;
if (old_ctx != NULL) {
+ struct mcontext __user *mctx;
+
+ /*
+ * old_ctx might not be 16-byte aligned, in which
+ * case old_ctx->uc_mcontext won't be either.
+ * Because we have the old_ctx->uc_pad2 field
+ * before old_ctx->uc_mcontext, we need to round down
+ * from &old_ctx->uc_mcontext to a 16-byte boundary.
+ */
+ mctx = (struct mcontext __user *)
+ ((unsigned long) &old_ctx->uc_mcontext & ~0xfUL);
if (!access_ok(VERIFY_WRITE, old_ctx, sizeof(*old_ctx))
- || save_user_regs(regs, &old_ctx->uc_mcontext, 0)
+ || save_user_regs(regs, mctx, 0)
|| put_sigset_t(&old_ctx->uc_sigmask, &current->blocked)
- || __put_user(to_user_ptr(&old_ctx->uc_mcontext),
- &old_ctx->uc_regs))
+ || __put_user(to_user_ptr(mctx), &old_ctx->uc_regs))
return -EFAULT;
}
if (new_ctx == NULL)
diff --git a/arch/powerpc/mm/imalloc.c b/arch/powerpc/mm/imalloc.c
index add8c1a9af68..c831815c31f0 100644
--- a/arch/powerpc/mm/imalloc.c
+++ b/arch/powerpc/mm/imalloc.c
@@ -138,7 +138,7 @@ static struct vm_struct * split_im_region(unsigned long v_addr,
struct vm_struct *vm2 = NULL;
struct vm_struct *new_vm = NULL;
- vm1 = (struct vm_struct *) kmalloc(sizeof(*vm1), GFP_KERNEL);
+ vm1 = kmalloc(sizeof(*vm1), GFP_KERNEL);
if (vm1 == NULL) {
printk(KERN_ERR "%s() out of memory\n", __FUNCTION__);
return NULL;
@@ -172,7 +172,7 @@ static struct vm_struct * split_im_region(unsigned long v_addr,
* uppermost remainder, and use existing parent one for the
* lower remainder of parent range
*/
- vm2 = (struct vm_struct *) kmalloc(sizeof(*vm2), GFP_KERNEL);
+ vm2 = kmalloc(sizeof(*vm2), GFP_KERNEL);
if (vm2 == NULL) {
printk(KERN_ERR "%s() out of memory\n", __FUNCTION__);
kfree(vm1);
@@ -206,7 +206,7 @@ static struct vm_struct * __add_new_im_area(unsigned long req_addr,
break;
}
- area = (struct vm_struct *) kmalloc(sizeof(*area), GFP_KERNEL);
+ area = kmalloc(sizeof(*area), GFP_KERNEL);
if (!area)
return NULL;
area->flags = 0;
diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile
index 44d95eaf22e6..507d1b98f270 100644
--- a/arch/powerpc/platforms/Makefile
+++ b/arch/powerpc/platforms/Makefile
@@ -5,9 +5,9 @@ ifeq ($(CONFIG_PPC64),y)
obj-$(CONFIG_PPC_PMAC) += powermac/
endif
endif
+obj-$(CONFIG_PPC_MPC52xx) += 52xx/
obj-$(CONFIG_PPC_CHRP) += chrp/
obj-$(CONFIG_4xx) += 4xx/
-obj-$(CONFIG_PPC_MPC52xx) += 52xx/
obj-$(CONFIG_PPC_83xx) += 83xx/
obj-$(CONFIG_PPC_85xx) += 85xx/
obj-$(CONFIG_PPC_86xx) += 86xx/
diff --git a/arch/powerpc/platforms/cell/io-workarounds.c b/arch/powerpc/platforms/cell/io-workarounds.c
index 580d42595912..7c73128305ec 100644
--- a/arch/powerpc/platforms/cell/io-workarounds.c
+++ b/arch/powerpc/platforms/cell/io-workarounds.c
@@ -37,7 +37,7 @@
*/
#define SPIDER_DISABLE_PREFETCH
-#define MAX_SPIDERS 2
+#define MAX_SPIDERS 3
static struct spider_pci_bus {
void __iomem *regs;
diff --git a/arch/powerpc/platforms/cell/spu_priv1_mmio.c b/arch/powerpc/platforms/cell/spu_priv1_mmio.c
index a5de0430c56d..910a926b61a2 100644
--- a/arch/powerpc/platforms/cell/spu_priv1_mmio.c
+++ b/arch/powerpc/platforms/cell/spu_priv1_mmio.c
@@ -37,8 +37,9 @@
#include "interrupt.h"
#include "spu_priv1_mmio.h"
+static DEFINE_MUTEX(add_spumem_mutex);
+
struct spu_pdata {
- int nid;
struct device_node *devnode;
struct spu_priv1 __iomem *priv1;
};
@@ -56,20 +57,9 @@ struct device_node *spu_devnode(struct spu *spu)
EXPORT_SYMBOL_GPL(spu_devnode);
-static int __init find_spu_node_id(struct device_node *spe)
-{
- const unsigned int *id;
- struct device_node *cpu;
- cpu = spe->parent->parent;
- id = get_property(cpu, "node-id", NULL);
- return id ? *id : 0;
-}
-
static int __init cell_spuprop_present(struct spu *spu, struct device_node *spe,
const char *prop)
{
- static DEFINE_MUTEX(add_spumem_mutex);
-
const struct address_prop {
unsigned long address;
unsigned int len;
@@ -87,7 +77,7 @@ static int __init cell_spuprop_present(struct spu *spu, struct device_node *spe,
start_pfn = p->address >> PAGE_SHIFT;
nr_pages = ((unsigned long)p->len + PAGE_SIZE - 1) >> PAGE_SHIFT;
- pgdata = NODE_DATA(spu_get_pdata(spu)->nid);
+ pgdata = NODE_DATA(spu->node);
zone = pgdata->node_zones;
/* XXX rethink locking here */
@@ -140,6 +130,7 @@ static int __init spu_map_interrupts_old(struct spu *spu,
{
unsigned int isrc;
const u32 *tmp;
+ int nid;
/* Get the interrupt source unit from the device-tree */
tmp = get_property(np, "isrc", NULL);
@@ -147,8 +138,15 @@ static int __init spu_map_interrupts_old(struct spu *spu,
return -ENODEV;
isrc = tmp[0];
+ tmp = get_property(np->parent->parent, "node-id", NULL);
+ if (!tmp) {
+ printk(KERN_WARNING "%s: can't find node-id\n", __FUNCTION__);
+ nid = spu->node;
+ } else
+ nid = tmp[0];
+
/* Add the node number */
- isrc |= spu->node << IIC_IRQ_NODE_SHIFT;
+ isrc |= nid << IIC_IRQ_NODE_SHIFT;
/* Now map interrupts of all 3 classes */
spu->irqs[0] = irq_create_mapping(NULL, IIC_IRQ_CLASS_0 | isrc);
@@ -237,70 +235,88 @@ err:
return ret;
}
-static int spu_map_resource(struct device_node *node, int nr,
- void __iomem** virt, unsigned long *phys)
+static int spu_map_resource(struct spu *spu, int nr,
+ void __iomem** virt, unsigned long *phys)
{
+ struct device_node *np = spu_get_pdata(spu)->devnode;
+ unsigned long start_pfn, nr_pages;
+ struct pglist_data *pgdata;
+ struct zone *zone;
struct resource resource = { };
+ unsigned long len;
int ret;
- ret = of_address_to_resource(node, nr, &resource);
+ ret = of_address_to_resource(np, nr, &resource);
if (ret)
goto out;
if (phys)
*phys = resource.start;
- *virt = ioremap(resource.start, resource.end - resource.start);
+ len = resource.end - resource.start + 1;
+ *virt = ioremap(resource.start, len);
if (!*virt)
ret = -EINVAL;
+ start_pfn = resource.start >> PAGE_SHIFT;
+ nr_pages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT;
+
+ pgdata = NODE_DATA(spu->node);
+ zone = pgdata->node_zones;
+
+ /* XXX rethink locking here */
+ mutex_lock(&add_spumem_mutex);
+ ret = __add_pages(zone, start_pfn, nr_pages);
+ mutex_unlock(&add_spumem_mutex);
+
out:
return ret;
}
-static int __init spu_map_device(struct spu *spu, struct device_node *node)
+static int __init spu_map_device(struct spu *spu)
{
+ struct device_node *np = spu_get_pdata(spu)->devnode;
int ret = -ENODEV;
- spu->name = get_property(node, "name", NULL);
+
+ spu->name = get_property(np, "name", NULL);
if (!spu->name)
goto out;
- ret = spu_map_resource(node, 0, (void __iomem**)&spu->local_store,
- &spu->local_store_phys);
+ ret = spu_map_resource(spu, 0, (void __iomem**)&spu->local_store,
+ &spu->local_store_phys);
if (ret) {
pr_debug("spu_new: failed to map %s resource 0\n",
- node->full_name);
+ np->full_name);
goto out;
}
- ret = spu_map_resource(node, 1, (void __iomem**)&spu->problem,
- &spu->problem_phys);
+ ret = spu_map_resource(spu, 1, (void __iomem**)&spu->problem,
+ &spu->problem_phys);
if (ret) {
pr_debug("spu_new: failed to map %s resource 1\n",
- node->full_name);
+ np->full_name);
goto out_unmap;
}
- ret = spu_map_resource(node, 2, (void __iomem**)&spu->priv2,
- NULL);
+ ret = spu_map_resource(spu, 2, (void __iomem**)&spu->priv2, NULL);
if (ret) {
pr_debug("spu_new: failed to map %s resource 2\n",
- node->full_name);
+ np->full_name);
goto out_unmap;
}
if (!firmware_has_feature(FW_FEATURE_LPAR))
- ret = spu_map_resource(node, 3,
- (void __iomem**)&spu_get_pdata(spu)->priv1, NULL);
+ ret = spu_map_resource(spu, 3,
+ (void __iomem**)&spu_get_pdata(spu)->priv1, NULL);
if (ret) {
pr_debug("spu_new: failed to map %s resource 3\n",
- node->full_name);
+ np->full_name);
goto out_unmap;
}
- pr_debug("spu_new: %s maps:\n", node->full_name);
+ pr_debug("spu_new: %s maps:\n", np->full_name);
pr_debug(" local store : 0x%016lx -> 0x%p\n",
spu->local_store_phys, spu->local_store);
pr_debug(" problem state : 0x%016lx -> 0x%p\n",
spu->problem_phys, spu->problem);
pr_debug(" priv2 : 0x%p\n", spu->priv2);
pr_debug(" priv1 : 0x%p\n",
- spu_get_pdata(spu)->priv1);
+ spu_get_pdata(spu)->priv1);
return 0;
@@ -340,8 +356,9 @@ static int __init of_create_spu(struct spu *spu, void *data)
ret = -ENOMEM;
goto out;
}
+ spu_get_pdata(spu)->devnode = of_node_get(spe);
- spu->node = find_spu_node_id(spe);
+ spu->node = of_node_to_nid(spe);
if (spu->node >= MAX_NUMNODES) {
printk(KERN_WARNING "SPE %s on node %d ignored,"
" node number too big\n", spe->full_name, spu->node);
@@ -350,11 +367,7 @@ static int __init of_create_spu(struct spu *spu, void *data)
goto out_free;
}
- spu_get_pdata(spu)->nid = of_node_to_nid(spe);
- if (spu_get_pdata(spu)->nid == -1)
- spu_get_pdata(spu)->nid = 0;
-
- ret = spu_map_device(spu, spe);
+ ret = spu_map_device(spu);
/* try old method */
if (ret)
ret = spu_map_device_old(spu, spe);
@@ -367,8 +380,6 @@ static int __init of_create_spu(struct spu *spu, void *data)
if (ret)
goto out_unmap;
- spu_get_pdata(spu)->devnode = of_node_get(spe);
-
pr_debug(KERN_DEBUG "Using SPE %s %p %p %p %p %d\n", spu->name,
spu->local_store, spu->problem, spu_get_pdata(spu)->priv1,
spu->priv2, spu->number);
diff --git a/arch/powerpc/platforms/iseries/Kconfig b/arch/powerpc/platforms/iseries/Kconfig
index 887b68804e6d..54e6b3b6f261 100644
--- a/arch/powerpc/platforms/iseries/Kconfig
+++ b/arch/powerpc/platforms/iseries/Kconfig
@@ -31,5 +31,5 @@ endmenu
config VIOPATH
bool
- depends on VIOCONS || VIODASD || VIOCD || VIOTAPE || VETH
+ depends on VIOCONS || VIODASD || VIOCD || VIOTAPE || ISERIES_VETH
default y
diff --git a/arch/powerpc/platforms/pseries/eeh_cache.c b/arch/powerpc/platforms/pseries/eeh_cache.c
index b6b462d3c604..f2bae04424f8 100644
--- a/arch/powerpc/platforms/pseries/eeh_cache.c
+++ b/arch/powerpc/platforms/pseries/eeh_cache.c
@@ -153,7 +153,7 @@ pci_addr_cache_insert(struct pci_dev *dev, unsigned long alo,
return piar;
}
}
- piar = (struct pci_io_addr_range *)kmalloc(sizeof(struct pci_io_addr_range), GFP_ATOMIC);
+ piar = kmalloc(sizeof(struct pci_io_addr_range), GFP_ATOMIC);
if (!piar)
return NULL;
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 411480d5c626..d01ced11694d 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -390,7 +390,7 @@ static void __init mpic_scan_ht_pic(struct mpic *mpic, u8 __iomem *devbase,
u8 id = readb(devbase + pos + PCI_CAP_LIST_ID);
if (id == PCI_CAP_ID_HT) {
id = readb(devbase + pos + 3);
- if (id == HT_CAPTYPE_IRQ)
+ if ((id & HT_5BIT_CAP_MASK) == HT_CAPTYPE_IRQ)
break;
}
}
diff --git a/arch/ppc/8260_io/fcc_enet.c b/arch/ppc/8260_io/fcc_enet.c
index 709952c25f29..06b84c372e58 100644
--- a/arch/ppc/8260_io/fcc_enet.c
+++ b/arch/ppc/8260_io/fcc_enet.c
@@ -1892,10 +1892,10 @@ init_fcc_param(fcc_info_t *fip, struct net_device *dev,
/* Allocate space for the buffer descriptors from regular memory.
* Initialize base addresses for the buffer descriptors.
*/
- cep->rx_bd_base = (cbd_t *)kmalloc(sizeof(cbd_t) * RX_RING_SIZE,
+ cep->rx_bd_base = kmalloc(sizeof(cbd_t) * RX_RING_SIZE,
GFP_KERNEL | GFP_DMA);
ep->fen_genfcc.fcc_rbase = __pa(cep->rx_bd_base);
- cep->tx_bd_base = (cbd_t *)kmalloc(sizeof(cbd_t) * TX_RING_SIZE,
+ cep->tx_bd_base = kmalloc(sizeof(cbd_t) * TX_RING_SIZE,
GFP_KERNEL | GFP_DMA);
ep->fen_genfcc.fcc_tbase = __pa(cep->tx_bd_base);
diff --git a/arch/ppc/8xx_io/cs4218_tdm.c b/arch/ppc/8xx_io/cs4218_tdm.c
index c71ef3c2e7bf..b7bb5f0b3c5f 100644
--- a/arch/ppc/8xx_io/cs4218_tdm.c
+++ b/arch/ppc/8xx_io/cs4218_tdm.c
@@ -2601,7 +2601,7 @@ int __init tdm8xx_sound_init(void)
/* Initialize beep stuff */
orig_mksound = kd_mksound;
kd_mksound = cs_mksound;
- beep_buf = (short *) kmalloc(BEEP_BUFLEN * 4, GFP_KERNEL);
+ beep_buf = kmalloc(BEEP_BUFLEN * 4, GFP_KERNEL);
if (beep_buf == NULL)
printk(KERN_WARNING "dmasound: no memory for "
"beep buffer\n");
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index ff690564edbd..12272361c018 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -407,7 +407,7 @@ config APPLDATA_BASE
config APPLDATA_MEM
tristate "Monitor memory management statistics"
- depends on APPLDATA_BASE
+ depends on APPLDATA_BASE && VM_EVENT_COUNTERS
help
This provides memory management related data to the Linux - VM Monitor
Stream, like paging/swapping rate, memory utilisation, etc.
diff --git a/arch/s390/defconfig b/arch/s390/defconfig
index a6ec919ba83f..5368cf4a350e 100644
--- a/arch/s390/defconfig
+++ b/arch/s390/defconfig
@@ -1,14 +1,15 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.19-rc2
-# Wed Oct 18 17:11:10 2006
+# Linux kernel version: 2.6.20-rc1
+# Fri Dec 15 16:52:28 2006
#
CONFIG_MMU=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_GENERIC_TIME=y
CONFIG_S390=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -37,12 +38,13 @@ CONFIG_AUDIT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
# CONFIG_CPUSETS is not set
+CONFIG_SYSFS_DEPRECATED=y
# CONFIG_RELAY is not set
CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
# CONFIG_EMBEDDED is not set
-# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -119,6 +121,7 @@ CONFIG_PACK_STACK=y
CONFIG_CHECK_STACK=y
CONFIG_STACK_GUARD=256
# CONFIG_WARN_STACK is not set
+CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
# CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -128,6 +131,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y
# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_RESOURCES_64BIT=y
+CONFIG_HOLES_IN_ZONE=y
#
# I/O subsystem configuration
@@ -196,6 +200,7 @@ CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_CUBIC=y
CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
CONFIG_IPV6=y
# CONFIG_IPV6_PRIVACY is not set
# CONFIG_IPV6_ROUTER_PREF is not set
@@ -211,7 +216,6 @@ CONFIG_INET6_XFRM_MODE_BEET=y
# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
CONFIG_IPV6_SIT=y
# CONFIG_IPV6_TUNNEL is not set
-# CONFIG_IPV6_SUBTREES is not set
# CONFIG_IPV6_MULTIPLE_TABLES is not set
# CONFIG_NETWORK_SECMARK is not set
# CONFIG_NETFILTER is not set
@@ -246,6 +250,7 @@ CONFIG_IPV6_SIT=y
# QoS and/or fair queueing
#
CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_FIFO=y
CONFIG_NET_SCH_CLK_JIFFIES=y
# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
# CONFIG_NET_SCH_CLK_CPU is not set
@@ -277,6 +282,7 @@ CONFIG_NET_CLS_ROUTE=y
CONFIG_NET_CLS_FW=m
CONFIG_NET_CLS_U32=m
# CONFIG_CLS_U32_PERF is not set
+CONFIG_CLS_U32_MARK=y
CONFIG_NET_CLS_RSVP=m
CONFIG_NET_CLS_RSVP6=m
# CONFIG_NET_EMATCH is not set
@@ -315,6 +321,7 @@ CONFIG_SYS_HYPERVISOR=y
#
# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
+# CONFIG_SCSI_TGT is not set
CONFIG_SCSI_NETLINK=y
CONFIG_SCSI_PROC_FS=y
@@ -335,6 +342,7 @@ CONFIG_CHR_DEV_SG=y
CONFIG_SCSI_MULTI_LUN=y
CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
#
# SCSI Transports
@@ -546,6 +554,7 @@ CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
# CONFIG_FUSE_FS is not set
+CONFIG_GENERIC_ACL=y
#
# CD-ROM/DVD Filesystems
@@ -571,7 +580,7 @@ CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=m
#
# Miscellaneous filesystems
@@ -616,7 +625,6 @@ CONFIG_SUNRPC=y
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
# CONFIG_9P_FS is not set
-CONFIG_GENERIC_ACL=y
#
# Partition Types
@@ -646,6 +654,14 @@ CONFIG_MSDOS_PARTITION=y
# CONFIG_NLS is not set
#
+# Distributed Lock Manager
+#
+CONFIG_DLM=m
+CONFIG_DLM_TCP=y
+# CONFIG_DLM_SCTP is not set
+# CONFIG_DLM_DEBUG is not set
+
+#
# Instrumentation Support
#
@@ -663,6 +679,8 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+CONFIG_HEADERS_CHECK=y
CONFIG_DEBUG_KERNEL=y
CONFIG_LOG_BUF_SHIFT=17
# CONFIG_SCHEDSTATS is not set
@@ -679,13 +697,11 @@ CONFIG_DEBUG_SPINLOCK_SLEEP=y
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_DEBUG_KOBJECT is not set
# CONFIG_DEBUG_INFO is not set
-CONFIG_DEBUG_FS=y
# CONFIG_DEBUG_VM is not set
# CONFIG_DEBUG_LIST is not set
# CONFIG_FRAME_POINTER is not set
# CONFIG_UNWIND_INFO is not set
CONFIG_FORCED_INLINING=y
-CONFIG_HEADERS_CHECK=y
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_LKDTM is not set
@@ -699,10 +715,11 @@ CONFIG_HEADERS_CHECK=y
# Cryptographic options
#
CONFIG_CRYPTO=y
-CONFIG_CRYPTO_ALGAPI=m
-CONFIG_CRYPTO_BLKCIPHER=m
-CONFIG_CRYPTO_MANAGER=m
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_MANAGER=y
# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
# CONFIG_CRYPTO_NULL is not set
# CONFIG_CRYPTO_MD4 is not set
# CONFIG_CRYPTO_MD5 is not set
@@ -713,8 +730,10 @@ CONFIG_CRYPTO_MANAGER=m
# CONFIG_CRYPTO_SHA512 is not set
# CONFIG_CRYPTO_WP512 is not set
# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
CONFIG_CRYPTO_ECB=m
-CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_LRW is not set
# CONFIG_CRYPTO_DES is not set
# CONFIG_CRYPTO_DES_S390 is not set
# CONFIG_CRYPTO_BLOWFISH is not set
@@ -740,8 +759,10 @@ CONFIG_CRYPTO_CBC=m
#
# Library routines
#
+CONFIG_BITREVERSE=m
# CONFIG_CRC_CCITT is not set
# CONFIG_CRC16 is not set
CONFIG_CRC32=m
# CONFIG_LIBCRC32C is not set
CONFIG_PLIST=y
+CONFIG_IOMAP_COPY=y
diff --git a/arch/s390/hypfs/hypfs_diag.c b/arch/s390/hypfs/hypfs_diag.c
index 443fa377d9ff..2782cf9da5b4 100644
--- a/arch/s390/hypfs/hypfs_diag.c
+++ b/arch/s390/hypfs/hypfs_diag.c
@@ -379,7 +379,7 @@ static void *diag204_alloc_vbuf(int pages)
static void *diag204_alloc_rbuf(void)
{
diag204_buf = (void*)__get_free_pages(GFP_KERNEL,0);
- if (diag204_buf)
+ if (!diag204_buf)
return ERR_PTR(-ENOMEM);
diag204_buf_pages = 1;
return diag204_buf;
@@ -521,7 +521,7 @@ __init int hypfs_diag_init(void)
}
rc = diag224_get_name_table();
if (rc) {
- diag224_delete_name_table();
+ diag204_free_buffer();
printk(KERN_ERR "hypfs: could not get name table.\n");
}
return rc;
diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c
index ef5266fbce62..bb57bc0e3fc8 100644
--- a/arch/s390/kernel/debug.c
+++ b/arch/s390/kernel/debug.c
@@ -191,13 +191,13 @@ debug_areas_alloc(int pages_per_area, int nr_areas)
debug_entry_t*** areas;
int i,j;
- areas = (debug_entry_t ***) kmalloc(nr_areas *
+ areas = kmalloc(nr_areas *
sizeof(debug_entry_t**),
GFP_KERNEL);
if (!areas)
goto fail_malloc_areas;
for (i = 0; i < nr_areas; i++) {
- areas[i] = (debug_entry_t**) kmalloc(pages_per_area *
+ areas[i] = kmalloc(pages_per_area *
sizeof(debug_entry_t*),GFP_KERNEL);
if (!areas[i]) {
goto fail_malloc_areas2;
@@ -242,7 +242,7 @@ debug_info_alloc(char *name, int pages_per_area, int nr_areas, int buf_size,
/* alloc everything */
- rc = (debug_info_t*) kmalloc(sizeof(debug_info_t), GFP_KERNEL);
+ rc = kmalloc(sizeof(debug_info_t), GFP_KERNEL);
if(!rc)
goto fail_malloc_rc;
rc->active_entries = kcalloc(nr_areas, sizeof(int), GFP_KERNEL);
@@ -634,7 +634,7 @@ found:
rc = -ENOMEM;
goto out;
}
- p_info = (file_private_info_t *) kmalloc(sizeof(file_private_info_t),
+ p_info = kmalloc(sizeof(file_private_info_t),
GFP_KERNEL);
if(!p_info){
if(debug_info_snapshot)
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index a36bea1188d9..9e9972e8a52b 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -609,42 +609,12 @@ static ssize_t on_panic_store(struct subsystem *subsys, const char *buf,
static struct subsys_attribute on_panic_attr =
__ATTR(on_panic, 0644, on_panic_show, on_panic_store);
-static void print_fcp_block(struct ipl_parameter_block *fcp_block)
-{
- printk(KERN_EMERG "wwpn: %016llx\n",
- (unsigned long long)fcp_block->ipl_info.fcp.wwpn);
- printk(KERN_EMERG "lun: %016llx\n",
- (unsigned long long)fcp_block->ipl_info.fcp.lun);
- printk(KERN_EMERG "bootprog: %lld\n",
- (unsigned long long)fcp_block->ipl_info.fcp.bootprog);
- printk(KERN_EMERG "br_lba: %lld\n",
- (unsigned long long)fcp_block->ipl_info.fcp.br_lba);
- printk(KERN_EMERG "device: %llx\n",
- (unsigned long long)fcp_block->ipl_info.fcp.devno);
- printk(KERN_EMERG "opt: %x\n", fcp_block->ipl_info.fcp.opt);
-}
-
void do_reipl(void)
{
struct ccw_dev_id devid;
static char buf[100];
char loadparm[LOADPARM_LEN + 1];
- switch (reipl_type) {
- case IPL_TYPE_CCW:
- reipl_get_ascii_loadparm(loadparm);
- printk(KERN_EMERG "reboot on ccw device: 0.0.%04x\n",
- reipl_block_ccw->ipl_info.ccw.devno);
- printk(KERN_EMERG "loadparm = '%s'\n", loadparm);
- break;
- case IPL_TYPE_FCP:
- printk(KERN_EMERG "reboot on fcp device:\n");
- print_fcp_block(reipl_block_fcp);
- break;
- default:
- break;
- }
-
switch (reipl_method) {
case IPL_METHOD_CCW_CIO:
devid.devno = reipl_block_ccw->ipl_info.ccw.devno;
@@ -654,6 +624,7 @@ void do_reipl(void)
reipl_ccw_dev(&devid);
break;
case IPL_METHOD_CCW_VM:
+ reipl_get_ascii_loadparm(loadparm);
if (strlen(loadparm) == 0)
sprintf(buf, "IPL %X",
reipl_block_ccw->ipl_info.ccw.devno);
@@ -683,7 +654,6 @@ void do_reipl(void)
diag308(DIAG308_IPL, NULL);
break;
}
- printk(KERN_EMERG "reboot failed!\n");
signal_processor(smp_processor_id(), sigp_stop_and_store_status);
}
@@ -692,19 +662,6 @@ static void do_dump(void)
struct ccw_dev_id devid;
static char buf[100];
- switch (dump_type) {
- case IPL_TYPE_CCW:
- printk(KERN_EMERG "Automatic dump on ccw device: 0.0.%04x\n",
- dump_block_ccw->ipl_info.ccw.devno);
- break;
- case IPL_TYPE_FCP:
- printk(KERN_EMERG "Automatic dump on fcp device:\n");
- print_fcp_block(dump_block_fcp);
- break;
- default:
- return;
- }
-
switch (dump_method) {
case IPL_METHOD_CCW_CIO:
smp_send_stop();
@@ -1037,15 +994,21 @@ static void do_reset_calls(void)
}
extern void reset_mcck_handler(void);
+extern void reset_pgm_handler(void);
+extern __u32 dump_prefix_page;
void s390_reset_system(void)
{
struct _lowcore *lc;
- /* Stack for interrupt/machine check handler */
lc = (struct _lowcore *)(unsigned long) store_prefix();
+
+ /* Stack for interrupt/machine check handler */
lc->panic_stack = S390_lowcore.panic_stack;
+ /* Save prefix page address for dump case */
+ dump_prefix_page = (unsigned long) lc;
+
/* Disable prefixing */
set_prefix(0);
@@ -1056,5 +1019,11 @@ void s390_reset_system(void)
S390_lowcore.mcck_new_psw.mask = PSW_KERNEL_BITS & ~PSW_MASK_MCHECK;
S390_lowcore.mcck_new_psw.addr =
PSW_ADDR_AMODE | (unsigned long) &reset_mcck_handler;
+
+ /* Set new program check handler */
+ S390_lowcore.program_new_psw.mask = PSW_KERNEL_BITS & ~PSW_MASK_MCHECK;
+ S390_lowcore.program_new_psw.addr =
+ PSW_ADDR_AMODE | (unsigned long) &reset_pgm_handler;
+
do_reset_calls();
}
diff --git a/arch/s390/kernel/reipl.S b/arch/s390/kernel/reipl.S
index f9434d42ce9f..c3f4d9b95083 100644
--- a/arch/s390/kernel/reipl.S
+++ b/arch/s390/kernel/reipl.S
@@ -16,7 +16,7 @@ do_reipl_asm: basr %r13,0
stm %r0,%r15,__LC_GPREGS_SAVE_AREA
stctl %c0,%c15,__LC_CREGS_SAVE_AREA
stam %a0,%a15,__LC_AREGS_SAVE_AREA
- stpx __LC_PREFIX_SAVE_AREA
+ mvc __LC_PREFIX_SAVE_AREA(4),dump_prefix_page-.Lpg0(%r13)
stckc .Lclkcmp-.Lpg0(%r13)
mvc __LC_CLOCK_COMP_SAVE_AREA(8),.Lclkcmp-.Lpg0(%r13)
stpt __LC_CPU_TIMER_SAVE_AREA
@@ -79,3 +79,7 @@ do_reipl_asm: basr %r13,0
.long 0x00000000,0x00000000
.long 0x00000000,0x00000000
.long 0x00000000,0x00000000
+ .globl dump_prefix_page
+dump_prefix_page:
+ .long 0x00000000
+
diff --git a/arch/s390/kernel/reipl64.S b/arch/s390/kernel/reipl64.S
index f18ef260ca23..dbb3eed38865 100644
--- a/arch/s390/kernel/reipl64.S
+++ b/arch/s390/kernel/reipl64.S
@@ -20,7 +20,7 @@ do_reipl_asm: basr %r13,0
stg %r0,__LC_GPREGS_SAVE_AREA-0x1000+8(%r1)
stctg %c0,%c15,__LC_CREGS_SAVE_AREA-0x1000(%r1)
stam %a0,%a15,__LC_AREGS_SAVE_AREA-0x1000(%r1)
- stpx __LC_PREFIX_SAVE_AREA-0x1000(%r1)
+ mvc __LC_PREFIX_SAVE_AREA-0x1000(4,%r1),dump_prefix_page-.Lpg0(%r13)
stfpc __LC_FP_CREG_SAVE_AREA-0x1000(%r1)
stckc .Lclkcmp-.Lpg0(%r13)
mvc __LC_CLOCK_COMP_SAVE_AREA-0x1000(8,%r1),.Lclkcmp-.Lpg0(%r13)
@@ -103,3 +103,6 @@ do_reipl_asm: basr %r13,0
.long 0x00000000,0x00000000
.long 0x00000000,0x00000000
.long 0x00000000,0x00000000
+ .globl dump_prefix_page
+dump_prefix_page:
+ .long 0x00000000
diff --git a/arch/s390/kernel/reset.S b/arch/s390/kernel/reset.S
index be8688c0665c..8a87355161fa 100644
--- a/arch/s390/kernel/reset.S
+++ b/arch/s390/kernel/reset.S
@@ -3,6 +3,7 @@
*
* Copyright (C) IBM Corp. 2006
* Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
+ * Michael Holzheu <holzheu@de.ibm.com>
*/
#include <asm/ptrace.h>
@@ -27,6 +28,26 @@ reset_mcck_handler:
s390_reset_mcck_handler:
.quad 0
+ .globl reset_pgm_handler
+reset_pgm_handler:
+ stmg %r0,%r15,__LC_SAVE_AREA
+ basr %r13,0
+0: lg %r15,__LC_PANIC_STACK # load panic stack
+ aghi %r15,-STACK_FRAME_OVERHEAD
+ lg %r1,s390_reset_pgm_handler-0b(%r13)
+ ltgr %r1,%r1
+ jz 1f
+ basr %r14,%r1
+ lmg %r0,%r15,__LC_SAVE_AREA
+ lpswe __LC_PGM_OLD_PSW
+1: lpswe disabled_wait_psw-0b(%r13)
+ .globl s390_reset_pgm_handler
+s390_reset_pgm_handler:
+ .quad 0
+ .align 8
+disabled_wait_psw:
+ .quad 0x0002000180000000,0x0000000000000000 + reset_pgm_handler
+
#else /* CONFIG_64BIT */
.globl reset_mcck_handler
@@ -45,4 +66,25 @@ reset_mcck_handler:
s390_reset_mcck_handler:
.long 0
+ .globl reset_pgm_handler
+reset_pgm_handler:
+ stm %r0,%r15,__LC_SAVE_AREA
+ basr %r13,0
+0: l %r15,__LC_PANIC_STACK # load panic stack
+ ahi %r15,-STACK_FRAME_OVERHEAD
+ l %r1,s390_reset_pgm_handler-0b(%r13)
+ ltr %r1,%r1
+ jz 1f
+ basr %r14,%r1
+ lm %r0,%r15,__LC_SAVE_AREA
+ lpsw __LC_PGM_OLD_PSW
+
+1: lpsw disabled_wait_psw-0b(%r13)
+ .globl s390_reset_pgm_handler
+s390_reset_pgm_handler:
+ .long 0
+disabled_wait_psw:
+ .align 8
+ .long 0x000a0000,0x00000000 + reset_pgm_handler
+
#endif /* CONFIG_64BIT */
diff --git a/arch/s390/kernel/s390_ext.c b/arch/s390/kernel/s390_ext.c
index 4faf96f8a834..bc5beaa8f98e 100644
--- a/arch/s390/kernel/s390_ext.c
+++ b/arch/s390/kernel/s390_ext.c
@@ -37,7 +37,7 @@ int register_external_interrupt(__u16 code, ext_int_handler_t handler)
ext_int_info_t *p;
int index;
- p = (ext_int_info_t *) kmalloc(sizeof(ext_int_info_t), GFP_ATOMIC);
+ p = kmalloc(sizeof(ext_int_info_t), GFP_ATOMIC);
if (p == NULL)
return -ENOMEM;
p->code = code;
diff --git a/arch/sparc/defconfig b/arch/sparc/defconfig
index a69856263009..79e54894529d 100644
--- a/arch/sparc/defconfig
+++ b/arch/sparc/defconfig
@@ -1,41 +1,59 @@
#
# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.20-rc1
+# Sun Dec 17 14:20:47 2006
#
CONFIG_MMU=y
-CONFIG_UID16=y
CONFIG_HIGHMEM=y
CONFIG_GENERIC_ISA_DMA=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_STANDALONE=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_IPC_NS is not set
CONFIG_POSIX_MQUEUE=y
# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
# CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
#
# Loadable module support
@@ -43,17 +61,36 @@ CONFIG_IOSCHED_CFQ=y
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
#
-# General setup
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+
+#
+# General machine setup
#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
# CONFIG_SMP is not set
+CONFIG_SPARC=y
CONFIG_SPARC32=y
CONFIG_SBUS=y
CONFIG_SBUSCHAR=y
@@ -61,73 +98,170 @@ CONFIG_SERIAL_CONSOLE=y
CONFIG_SUN_AUXIO=y
CONFIG_SUN_IO=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_SUN_PM=y
# CONFIG_SUN4 is not set
CONFIG_PCI=y
-# CONFIG_PCI_LEGACY_PROC is not set
-# CONFIG_PCI_NAMES is not set
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
+# CONFIG_PCI_DEBUG is not set
CONFIG_SUN_OPENPROMFS=m
+# CONFIG_SPARC_LED is not set
CONFIG_BINFMT_ELF=y
CONFIG_BINFMT_AOUT=y
CONFIG_BINFMT_MISC=m
CONFIG_SUNOS_EMUL=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_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
#
-# Parallel port support
+# Networking
#
-# CONFIG_PARPORT is not set
+CONFIG_NET=y
#
-# Generic Driver Options
+# Networking options
#
-# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_NET_KEY=m
+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 is not set
+# 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=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+CONFIG_INET_XFRM_TUNNEL=y
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+# CONFIG_IPV6_ROUTER_PREF is not set
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+# CONFIG_IPV6_MIP6 is not set
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_TUNNEL=m
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
#
-# Graphics support
+# DCCP Configuration (EXPERIMENTAL)
#
-# CONFIG_FB is not set
+# CONFIG_IP_DCCP is not set
#
-# Console display driver support
+# SCTP Configuration (EXPERIMENTAL)
#
-# CONFIG_MDA_CONSOLE is not set
-# CONFIG_PROM_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+CONFIG_SCTP_DBG_OBJCNT=y
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
#
-# Memory Technology Devices (MTD)
+# TIPC Configuration (EXPERIMENTAL)
#
-# CONFIG_MTD is not set
+# CONFIG_TIPC 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_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
#
-# Serial drivers
+# QoS and/or fair queueing
#
-# CONFIG_SERIAL_8250 is not set
+# CONFIG_NET_SCHED is not set
#
-# Non-8250 serial port support
+# Network testing
#
-CONFIG_SERIAL_SUNCORE=y
-CONFIG_SERIAL_SUNZILOG=y
-CONFIG_SERIAL_SUNZILOG_CONSOLE=y
-CONFIG_SERIAL_SUNSU=y
-CONFIG_SERIAL_SUNSU_CONSOLE=y
-# CONFIG_SERIAL_SUNSAB is not set
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_NET_PKTGEN=m
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
#
-# Misc Linux/SPARC drivers
+# 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
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
#
-CONFIG_SUN_OPENPROMIO=m
-CONFIG_SUN_MOSTEK_RTC=m
-# CONFIG_SUN_BPP is not set
-# CONFIG_SUN_VIDEOPIX is not set
-# CONFIG_SUN_AURORA is not set
-# CONFIG_TADPOLE_TS102_UCTRL is not set
-# CONFIG_SUN_JSFLASH is not set
-CONFIG_APM_RTC_IS_GMT=y
-CONFIG_RTC=m
#
# Block devices
@@ -137,28 +271,37 @@ CONFIG_RTC=m
# 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=m
# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_CARMEL is not set
+# CONFIG_BLK_DEV_SX8 is not set
CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
#
-# ATA/ATAPI/MFM/RLL support
+# Misc devices
#
-# CONFIG_IDE is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
#
-# ISDN subsystem
+# ATA/ATAPI/MFM/RLL support
#
-# CONFIG_ISDN is not set
+# CONFIG_IDE is not set
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
CONFIG_SCSI_PROC_FS=y
#
@@ -170,6 +313,7 @@ CONFIG_BLK_DEV_SD=y
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
@@ -177,57 +321,58 @@ CONFIG_CHR_DEV_SG=m
# CONFIG_SCSI_MULTI_LUN is not set
# CONFIG_SCSI_CONSTANTS is not set
# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
#
-# SCSI Transport Attributes
+# SCSI Transports
#
CONFIG_SCSI_SPI_ATTRS=m
# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
#
# SCSI low-level drivers
#
+# CONFIG_ISCSI_TCP is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX 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_AIC94XX is not set
# CONFIG_SCSI_DPT_I2O is not set
-# CONFIG_SCSI_ADVANSYS is not set
-# CONFIG_SCSI_MEGARAID is not set
-# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_ARCMSR is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_HPTIOP is not set
# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
# CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
# CONFIG_SCSI_QLOGIC_1280 is not set
CONFIG_SCSI_QLOGICPTI=m
-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_QLA6322 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI 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
CONFIG_SCSI_SUNESP=y
+# CONFIG_SCSI_SRP is not set
#
-# Fibre Channel support
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
#
-# CONFIG_FC4 is not set
+# CONFIG_ATA is not set
#
# Multi-device support (RAID and LVM)
@@ -235,85 +380,31 @@ CONFIG_SCSI_SUNESP=y
# CONFIG_MD is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
+# Fusion MPT device support
#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=m
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER 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_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-CONFIG_INET_AH=y
-CONFIG_INET_ESP=y
-CONFIG_INET_IPCOMP=y
-CONFIG_IPV6=m
-CONFIG_IPV6_PRIVACY=y
-CONFIG_INET6_AH=m
-CONFIG_INET6_ESP=m
-CONFIG_INET6_IPCOMP=m
-CONFIG_IPV6_TUNNEL=m
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
#
-# SCTP Configuration (EXPERIMENTAL)
+# IEEE 1394 (FireWire) support
#
-CONFIG_IP_SCTP=m
-# CONFIG_SCTP_DBG_MSG is not set
-CONFIG_SCTP_DBG_OBJCNT=y
-# CONFIG_SCTP_HMAC_NONE is not set
-# CONFIG_SCTP_HMAC_SHA1 is not set
-CONFIG_SCTP_HMAC_MD5=y
-# 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_HW_FLOWCONTROL is not set
+# CONFIG_IEEE1394 is not set
#
-# QoS and/or fair queueing
+# I2O device support
#
-# CONFIG_NET_SCHED is not set
+# CONFIG_I2O is not set
#
-# Network testing
+# Network device support
#
-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=m
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
CONFIG_TUN=m
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -321,6 +412,11 @@ CONFIG_TUN=m
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -330,6 +426,7 @@ CONFIG_HAPPYMEAL=m
CONFIG_SUNBMAC=m
CONFIG_SUNQE=m
# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
#
@@ -350,14 +447,22 @@ CONFIG_SUNQE=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_SKY2 is not set
# CONFIG_SK98LIN is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
#
# Token Ring devices
@@ -380,17 +485,24 @@ CONFIG_SUNQE=m
# CONFIG_NET_FC 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
#
-# Unix98 PTY support
+# ISDN subsystem
#
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=256
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
#
# Input device support
#
CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
#
# Userland interfaces
@@ -405,17 +517,6 @@ CONFIG_INPUT_EVDEV=m
CONFIG_INPUT_EVBUG=m
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=m
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=m
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-
-#
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
@@ -424,6 +525,7 @@ CONFIG_KEYBOARD_SUNKBD=m
# CONFIG_KEYBOARD_LKKBD is not set
# CONFIG_KEYBOARD_XTKBD is not set
# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
CONFIG_INPUT_MOUSE=y
CONFIG_MOUSE_PS2=m
CONFIG_MOUSE_SERIAL=m
@@ -433,29 +535,239 @@ CONFIG_MOUSE_SERIAL=m
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=m
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=m
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=m
+# 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_VT_HW_CONSOLE_BINDING is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_SUNCORE=y
+CONFIG_SERIAL_SUNZILOG=y
+CONFIG_SERIAL_SUNZILOG_CONSOLE=y
+CONFIG_SERIAL_SUNSU=y
+CONFIG_SERIAL_SUNSU_CONSOLE=y
+# CONFIG_SERIAL_SUNSAB is not set
+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
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+CONFIG_HW_RANDOM=m
+CONFIG_RTC=m
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+CONFIG_FIRMWARE_EDID=y
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_PROM_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# HID Devices
+#
+CONFIG_HID=y
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# Virtualization
+#
+
+#
+# Misc Linux/SPARC drivers
+#
+CONFIG_SUN_OPENPROMIO=m
+CONFIG_SUN_MOSTEK_RTC=m
+# CONFIG_SUN_BPP is not set
+# CONFIG_SUN_VIDEOPIX is not set
+# CONFIG_TADPOLE_TS102_UCTRL is not set
+# CONFIG_SUN_JSFLASH is not set
+
+#
+# Unix98 PTY support
+#
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
# 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_EXT4DEV_FS 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=m
-CONFIG_XFS_RT=y
CONFIG_XFS_QUOTA=y
CONFIG_XFS_SECURITY=y
CONFIG_XFS_POSIX_ACL=y
+CONFIG_XFS_RT=y
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
# CONFIG_MINIX_FS is not set
CONFIG_ROMFS_FS=m
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
CONFIG_QUOTACTL=y
+CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=m
CONFIG_AUTOFS4_FS=m
+# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
@@ -468,7 +780,8 @@ CONFIG_ISO9660_FS=m
#
# DOS/FAT/NT Filesystems
#
-# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
# CONFIG_NTFS_FS is not set
#
@@ -476,13 +789,12 @@ CONFIG_ISO9660_FS=m
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-# CONFIG_DEVPTS_FS_SECURITY is not set
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
#
# Miscellaneous filesystems
@@ -512,17 +824,23 @@ CONFIG_NFS_FS=y
# CONFIG_NFSD is not set
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
-# CONFIG_EXPORTFS is not set
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
CONFIG_SUNRPC_GSS=m
CONFIG_RPCSEC_GSS_KRB5=m
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
CONFIG_CIFS=m
# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
CONFIG_AFS_FS=m
CONFIG_RXRPC=m
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -559,6 +877,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
# 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
@@ -575,70 +894,104 @@ CONFIG_NLS_DEFAULT="iso8859-1"
# CONFIG_NLS_UTF8 is not set
#
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# USB support
+# Distributed Lock Manager
#
-# CONFIG_USB is not set
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
+# CONFIG_DLM is not set
#
-# Watchdog Cards
+# Instrumentation Support
#
-# CONFIG_WATCHDOG is not set
+# CONFIG_PROFILING is not set
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
# CONFIG_DEBUG_SLAB is not set
-CONFIG_MAGIC_SYSRQ=y
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_HIGHMEM is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_RWSEMS is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_HIGHMEM is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
#
# Security options
#
+# CONFIG_KEYS is not set
# CONFIG_SECURITY is not set
#
# Cryptographic options
#
CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
CONFIG_CRYPTO_NULL=m
CONFIG_CRYPTO_MD4=y
CONFIG_CRYPTO_MD5=y
CONFIG_CRYPTO_SHA1=y
CONFIG_CRYPTO_SHA256=m
CONFIG_CRYPTO_SHA512=m
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_LRW is not set
CONFIG_CRYPTO_DES=y
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_AES=m
CONFIG_CRYPTO_CAST5=m
CONFIG_CRYPTO_CAST6=m
+# CONFIG_CRYPTO_TEA is not set
CONFIG_CRYPTO_ARC4=m
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
CONFIG_CRYPTO_DEFLATE=y
CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_CRC32C=m
# CONFIG_CRYPTO_TEST is not set
#
+# Hardware crypto devices
+#
+
+#
# Library routines
#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_IOMAP_COPY=y
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index cbbc98846b00..987ec6782f99 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -153,7 +153,7 @@ void __iomem *of_ioremap(struct resource *res, unsigned long offset,
}
EXPORT_SYMBOL(of_ioremap);
-void of_iounmap(void __iomem *base, unsigned long size)
+void of_iounmap(struct resource *res, void __iomem *base, unsigned long size)
{
iounmap(base);
}
@@ -726,7 +726,8 @@ int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents,
/* IIep is write-through, not flushing. */
for (n = 0; n < nents; n++) {
BUG_ON(page_address(sg->page) == NULL);
- sg->dvma_address = virt_to_phys(page_address(sg->page));
+ sg->dvma_address =
+ virt_to_phys(page_address(sg->page)) + sg->offset;
sg->dvma_length = sg->length;
sg++;
}
diff --git a/arch/sparc/kernel/irq.c b/arch/sparc/kernel/irq.c
index c8cb211b9072..5b4841d067c1 100644
--- a/arch/sparc/kernel/irq.c
+++ b/arch/sparc/kernel/irq.c
@@ -425,7 +425,7 @@ int request_fast_irq(unsigned int irq,
}
if (action == NULL)
- action = (struct irqaction *)kmalloc(sizeof(struct irqaction),
+ action = kmalloc(sizeof(struct irqaction),
GFP_ATOMIC);
if (!action) {
@@ -528,7 +528,7 @@ int request_irq(unsigned int irq,
}
if (action == NULL)
- action = (struct irqaction *)kmalloc(sizeof(struct irqaction),
+ action = kmalloc(sizeof(struct irqaction),
GFP_ATOMIC);
if (!action) {
diff --git a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c
index 33dadd9f2871..d8e008a04e2b 100644
--- a/arch/sparc/kernel/sparc_ksyms.c
+++ b/arch/sparc/kernel/sparc_ksyms.c
@@ -83,9 +83,6 @@ extern int __divdi3(int, int);
/* Private functions with odd calling conventions. */
extern void ___atomic24_add(void);
extern void ___atomic24_sub(void);
-extern void ___set_bit(void);
-extern void ___clear_bit(void);
-extern void ___change_bit(void);
extern void ___rw_read_enter(void);
extern void ___rw_read_try(void);
extern void ___rw_read_exit(void);
@@ -125,11 +122,6 @@ EXPORT_SYMBOL(pfn_base);
EXPORT_SYMBOL(___atomic24_add);
EXPORT_SYMBOL(___atomic24_sub);
-/* Bit operations. */
-EXPORT_SYMBOL(___set_bit);
-EXPORT_SYMBOL(___clear_bit);
-EXPORT_SYMBOL(___change_bit);
-
/* Per-CPU information table */
EXPORT_PER_CPU_SYMBOL(__cpu_data);
diff --git a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c
index cf1b8baa57ea..0e27e226e0e2 100644
--- a/arch/sparc/kernel/sun4d_irq.c
+++ b/arch/sparc/kernel/sun4d_irq.c
@@ -327,7 +327,7 @@ int sun4d_request_irq(unsigned int irq,
}
if (action == NULL)
- action = (struct irqaction *)kmalloc(sizeof(struct irqaction),
+ action = kmalloc(sizeof(struct irqaction),
GFP_ATOMIC);
if (!action) {
diff --git a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c
index 6c7aa51b590f..2fcce000d877 100644
--- a/arch/sparc/kernel/time.c
+++ b/arch/sparc/kernel/time.c
@@ -78,7 +78,6 @@ unsigned long profile_pc(struct pt_regs *regs)
extern char __copy_user_begin[], __copy_user_end[];
extern char __atomic_begin[], __atomic_end[];
extern char __bzero_begin[], __bzero_end[];
- extern char __bitops_begin[], __bitops_end[];
unsigned long pc = regs->pc;
@@ -88,9 +87,7 @@ unsigned long profile_pc(struct pt_regs *regs)
(pc >= (unsigned long) __atomic_begin &&
pc < (unsigned long) __atomic_end) ||
(pc >= (unsigned long) __bzero_begin &&
- pc < (unsigned long) __bzero_end) ||
- (pc >= (unsigned long) __bitops_begin &&
- pc < (unsigned long) __bitops_end))
+ pc < (unsigned long) __bzero_end))
pc = regs->u_regs[UREG_RETPC];
return pc;
}
diff --git a/arch/sparc/lib/Makefile b/arch/sparc/lib/Makefile
index 5db7e1d85385..9ddc5b9ce3bd 100644
--- a/arch/sparc/lib/Makefile
+++ b/arch/sparc/lib/Makefile
@@ -7,7 +7,7 @@ EXTRA_AFLAGS := -ansi -DST_DIV0=0x02
lib-y := mul.o rem.o sdiv.o udiv.o umul.o urem.o ashrdi3.o memcpy.o memset.o \
strlen.o checksum.o blockops.o memscan.o memcmp.o strncmp.o \
strncpy_from_user.o divdi3.o udivdi3.o strlen_user.o \
- copy_user.o locks.o atomic.o atomic32.o bitops.o \
+ copy_user.o locks.o atomic.o \
lshrdi3.o ashldi3.o rwsem.o muldi3.o bitext.o
-obj-y += iomap.o
+obj-y += iomap.o atomic32.o
diff --git a/arch/sparc/lib/atomic32.c b/arch/sparc/lib/atomic32.c
index de84f8534bac..53ddcd9d1e60 100644
--- a/arch/sparc/lib/atomic32.c
+++ b/arch/sparc/lib/atomic32.c
@@ -76,3 +76,42 @@ void atomic_set(atomic_t *v, int i)
spin_unlock_irqrestore(ATOMIC_HASH(v), flags);
}
EXPORT_SYMBOL(atomic_set);
+
+unsigned long ___set_bit(unsigned long *addr, unsigned long mask)
+{
+ unsigned long old, flags;
+
+ spin_lock_irqsave(ATOMIC_HASH(addr), flags);
+ old = *addr;
+ *addr = old | mask;
+ spin_unlock_irqrestore(ATOMIC_HASH(addr), flags);
+
+ return old & mask;
+}
+EXPORT_SYMBOL(___set_bit);
+
+unsigned long ___clear_bit(unsigned long *addr, unsigned long mask)
+{
+ unsigned long old, flags;
+
+ spin_lock_irqsave(ATOMIC_HASH(addr), flags);
+ old = *addr;
+ *addr = old & ~mask;
+ spin_unlock_irqrestore(ATOMIC_HASH(addr), flags);
+
+ return old & mask;
+}
+EXPORT_SYMBOL(___clear_bit);
+
+unsigned long ___change_bit(unsigned long *addr, unsigned long mask)
+{
+ unsigned long old, flags;
+
+ spin_lock_irqsave(ATOMIC_HASH(addr), flags);
+ old = *addr;
+ *addr = old ^ mask;
+ spin_unlock_irqrestore(ATOMIC_HASH(addr), flags);
+
+ return old & mask;
+}
+EXPORT_SYMBOL(___change_bit);
diff --git a/arch/sparc/lib/bitops.S b/arch/sparc/lib/bitops.S
deleted file mode 100644
index cb7fb66a40c8..000000000000
--- a/arch/sparc/lib/bitops.S
+++ /dev/null
@@ -1,109 +0,0 @@
-/* bitops.S: Low level assembler bit operations.
- *
- * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
- */
-
-#include <asm/ptrace.h>
-#include <asm/psr.h>
-
- .text
- .align 4
-
- .globl __bitops_begin
-__bitops_begin:
-
- /* Take bits in %g2 and set them in word at %g1,
- * return whether bits were set in original value
- * in %g2. %g4 holds value to restore into %o7
- * in delay slot of jmpl return, %g3 + %g5 + %g7 can be
- * used as temporaries and thus is considered clobbered
- * by all callers.
- */
- .globl ___set_bit
-___set_bit:
- rd %psr, %g3
- nop; nop; nop;
- or %g3, PSR_PIL, %g5
- wr %g5, 0x0, %psr
- nop; nop; nop
-#ifdef CONFIG_SMP
- set bitops_spinlock, %g5
-2: ldstub [%g5], %g7 ! Spin on the byte lock for SMP.
- orcc %g7, 0x0, %g0 ! Did we get it?
- bne 2b ! Nope...
-#endif
- ld [%g1], %g7
- or %g7, %g2, %g5
- and %g7, %g2, %g2
-#ifdef CONFIG_SMP
- st %g5, [%g1]
- set bitops_spinlock, %g5
- stb %g0, [%g5]
-#else
- st %g5, [%g1]
-#endif
- wr %g3, 0x0, %psr
- nop; nop; nop
- jmpl %o7, %g0
- mov %g4, %o7
-
- /* Same as above, but clears the bits from %g2 instead. */
- .globl ___clear_bit
-___clear_bit:
- rd %psr, %g3
- nop; nop; nop
- or %g3, PSR_PIL, %g5
- wr %g5, 0x0, %psr
- nop; nop; nop
-#ifdef CONFIG_SMP
- set bitops_spinlock, %g5
-2: ldstub [%g5], %g7 ! Spin on the byte lock for SMP.
- orcc %g7, 0x0, %g0 ! Did we get it?
- bne 2b ! Nope...
-#endif
- ld [%g1], %g7
- andn %g7, %g2, %g5
- and %g7, %g2, %g2
-#ifdef CONFIG_SMP
- st %g5, [%g1]
- set bitops_spinlock, %g5
- stb %g0, [%g5]
-#else
- st %g5, [%g1]
-#endif
- wr %g3, 0x0, %psr
- nop; nop; nop
- jmpl %o7, %g0
- mov %g4, %o7
-
- /* Same thing again, but this time toggles the bits from %g2. */
- .globl ___change_bit
-___change_bit:
- rd %psr, %g3
- nop; nop; nop
- or %g3, PSR_PIL, %g5
- wr %g5, 0x0, %psr
- nop; nop; nop
-#ifdef CONFIG_SMP
- set bitops_spinlock, %g5
-2: ldstub [%g5], %g7 ! Spin on the byte lock for SMP.
- orcc %g7, 0x0, %g0 ! Did we get it?
- bne 2b ! Nope...
-#endif
- ld [%g1], %g7
- xor %g7, %g2, %g5
- and %g7, %g2, %g2
-#ifdef CONFIG_SMP
- st %g5, [%g1]
- set bitops_spinlock, %g5
- stb %g0, [%g5]
-#else
- st %g5, [%g1]
-#endif
- wr %g3, 0x0, %psr
- nop; nop; nop
- jmpl %o7, %g0
- mov %g4, %o7
-
- .globl __bitops_end
-__bitops_end:
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig
index 0f0d38f6197c..5a9e68b13e60 100644
--- a/arch/sparc64/defconfig
+++ b/arch/sparc64/defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.19
-# Sat Dec 9 15:41:30 2006
+# Linux kernel version: 2.6.20-rc2
+# Thu Dec 28 15:09:49 2006
#
CONFIG_SPARC=y
CONFIG_SPARC64=y
@@ -334,7 +334,7 @@ CONFIG_BLK_DEV_LOOP=m
CONFIG_BLK_DEV_CRYPTOLOOP=m
CONFIG_BLK_DEV_NBD=m
# CONFIG_BLK_DEV_SX8 is not set
-CONFIG_BLK_DEV_UB=m
+# CONFIG_BLK_DEV_UB is not set
# CONFIG_BLK_DEV_RAM is not set
# CONFIG_BLK_DEV_INITRD is not set
CONFIG_CDROM_PKTCDVD=m
@@ -840,6 +840,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_LM92 is not set
# CONFIG_SENSORS_MAX1619 is not set
# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
# CONFIG_SENSORS_SIS5595 is not set
# CONFIG_SENSORS_SMSC47M1 is not set
# CONFIG_SENSORS_SMSC47M192 is not set
@@ -850,6 +851,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_W83781D is not set
# CONFIG_SENSORS_W83791D is not set
# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
# CONFIG_SENSORS_W83L785TS is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
@@ -962,7 +964,6 @@ CONFIG_SND_VERBOSE_PROCFS=y
#
CONFIG_SND_MPU401_UART=m
CONFIG_SND_AC97_CODEC=m
-CONFIG_SND_AC97_BUS=m
CONFIG_SND_DUMMY=m
CONFIG_SND_VIRMIDI=m
CONFIG_SND_MTPAV=m
@@ -1045,6 +1046,7 @@ CONFIG_SND_SUN_CS4231=m
# Open Sound System
#
# CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=m
#
# HID Devices
@@ -1096,14 +1098,26 @@ CONFIG_USB_UHCI_HCD=m
#
# may also be needed; see USB_STORAGE Help for more information
#
-# CONFIG_USB_STORAGE is not set
+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_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
# CONFIG_USB_LIBUSUAL is not set
#
# USB Input Devices
#
CONFIG_USB_HID=y
-# CONFIG_USB_HID_POWERBOOK is not set
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
# CONFIG_HID_FF is not set
CONFIG_USB_HIDDEV=y
# CONFIG_USB_AIPTEK is not set
@@ -1222,6 +1236,10 @@ CONFIG_USB_HIDDEV=y
#
#
+# Virtualization
+#
+
+#
# Misc Linux/SPARC drivers
#
CONFIG_SUN_OPENPROMIO=m
@@ -1397,6 +1415,8 @@ CONFIG_PRINTK_TIME=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
CONFIG_LOG_BUF_SHIFT=18
CONFIG_DETECT_SOFTLOCKUP=y
@@ -1414,12 +1434,9 @@ CONFIG_SCHEDSTATS=y
# CONFIG_DEBUG_KOBJECT is not set
CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_INFO is not set
-CONFIG_DEBUG_FS=y
# CONFIG_DEBUG_VM is not set
# CONFIG_DEBUG_LIST is not set
-# CONFIG_UNWIND_INFO is not set
CONFIG_FORCED_INLINING=y
-# CONFIG_HEADERS_CHECK is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_LKDTM is not set
# CONFIG_DEBUG_STACK_USAGE is not set
@@ -1489,3 +1506,4 @@ CONFIG_LIBCRC32C=m
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
CONFIG_PLIST=y
+CONFIG_IOMAP_COPY=y
diff --git a/arch/sparc64/kernel/head.S b/arch/sparc64/kernel/head.S
index 03ffaf895a22..baea10a98196 100644
--- a/arch/sparc64/kernel/head.S
+++ b/arch/sparc64/kernel/head.S
@@ -78,11 +78,7 @@ sparc_ramdisk_image64:
/* 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
+ mov %o4, %l7
/* We need to remap the kernel. Use position independant
* code to remap us to KERNBASE.
@@ -295,7 +291,6 @@ is_sun4v:
add %sp, (192 + 128), %sp
-sparc64_boot_after_remap:
sethi %hi(prom_root_compatible), %g1
or %g1, %lo(prom_root_compatible), %g1
sethi %hi(prom_sun4v_name), %g7
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
index d64b1ea848de..c3d068c7a412 100644
--- a/arch/sparc64/kernel/irq.c
+++ b/arch/sparc64/kernel/irq.c
@@ -372,14 +372,14 @@ static void run_pre_handler(unsigned int virt_irq)
}
}
-static struct hw_interrupt_type sun4u_irq = {
+static struct irq_chip sun4u_irq = {
.typename = "sun4u",
.enable = sun4u_irq_enable,
.disable = sun4u_irq_disable,
.end = sun4u_irq_end,
};
-static struct hw_interrupt_type sun4u_irq_ack = {
+static struct irq_chip sun4u_irq_ack = {
.typename = "sun4u+ack",
.enable = sun4u_irq_enable,
.disable = sun4u_irq_disable,
@@ -387,14 +387,14 @@ static struct hw_interrupt_type sun4u_irq_ack = {
.end = sun4u_irq_end,
};
-static struct hw_interrupt_type sun4v_irq = {
+static struct irq_chip sun4v_irq = {
.typename = "sun4v",
.enable = sun4v_irq_enable,
.disable = sun4v_irq_disable,
.end = sun4v_irq_end,
};
-static struct hw_interrupt_type sun4v_irq_ack = {
+static struct irq_chip sun4v_irq_ack = {
.typename = "sun4v+ack",
.enable = sun4v_irq_enable,
.disable = sun4v_irq_disable,
@@ -493,22 +493,6 @@ out:
return bucket->virt_irq;
}
-void hw_resend_irq(struct hw_interrupt_type *handler, unsigned int virt_irq)
-{
- struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq);
- unsigned long pstate;
- unsigned int *ent;
-
- __asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate));
- __asm__ __volatile__("wrpr %0, %1, %%pstate"
- : : "r" (pstate), "i" (PSTATE_IE));
- ent = irq_work(smp_processor_id());
- bucket->irq_chain = *ent;
- *ent = __irq(bucket);
- set_softint(1 << PIL_DEVICE_IRQ);
- __asm__ __volatile__("wrpr %0, 0x0, %%pstate" : : "r" (pstate));
-}
-
void ack_bad_irq(unsigned int virt_irq)
{
struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq);
diff --git a/arch/sparc64/kernel/isa.c b/arch/sparc64/kernel/isa.c
index ad1c4f55420f..98721a8f8619 100644
--- a/arch/sparc64/kernel/isa.c
+++ b/arch/sparc64/kernel/isa.c
@@ -22,14 +22,15 @@ static void __init report_dev(struct sparc_isa_device *isa_dev, int child)
printk(" [%s", isa_dev->prom_node->name);
}
-static struct linux_prom_registers * __init
-isa_dev_get_resource(struct sparc_isa_device *isa_dev)
+static void __init isa_dev_get_resource(struct sparc_isa_device *isa_dev)
{
struct linux_prom_registers *pregs;
unsigned long base, len;
int prop_len;
pregs = of_get_property(isa_dev->prom_node, "reg", &prop_len);
+ if (!pregs)
+ return;
/* Only the first one is interesting. */
len = pregs[0].reg_size;
@@ -44,12 +45,9 @@ isa_dev_get_resource(struct sparc_isa_device *isa_dev)
request_resource(&isa_dev->bus->parent->io_space,
&isa_dev->resource);
-
- return pregs;
}
-static void __init isa_dev_get_irq(struct sparc_isa_device *isa_dev,
- struct linux_prom_registers *pregs)
+static void __init isa_dev_get_irq(struct sparc_isa_device *isa_dev)
{
struct of_device *op = of_find_device_by_node(isa_dev->prom_node);
@@ -69,7 +67,6 @@ static void __init isa_fill_children(struct sparc_isa_device *parent_isa_dev)
printk(" ->");
while (dp) {
- struct linux_prom_registers *regs;
struct sparc_isa_device *isa_dev;
isa_dev = kzalloc(sizeof(*isa_dev), GFP_KERNEL);
@@ -85,8 +82,8 @@ static void __init isa_fill_children(struct sparc_isa_device *parent_isa_dev)
isa_dev->bus = parent_isa_dev->bus;
isa_dev->prom_node = dp;
- regs = isa_dev_get_resource(isa_dev);
- isa_dev_get_irq(isa_dev, regs);
+ isa_dev_get_resource(isa_dev);
+ isa_dev_get_irq(isa_dev);
report_dev(isa_dev, 1);
@@ -99,7 +96,6 @@ static void __init isa_fill_devices(struct sparc_isa_bridge *isa_br)
struct device_node *dp = isa_br->prom_node->child;
while (dp) {
- struct linux_prom_registers *regs;
struct sparc_isa_device *isa_dev;
isa_dev = kzalloc(sizeof(*isa_dev), GFP_KERNEL);
@@ -137,8 +133,8 @@ static void __init isa_fill_devices(struct sparc_isa_bridge *isa_br)
isa_dev->bus = isa_br;
isa_dev->prom_node = dp;
- regs = isa_dev_get_resource(isa_dev);
- isa_dev_get_irq(isa_dev, regs);
+ isa_dev_get_resource(isa_dev);
+ isa_dev_get_irq(isa_dev);
report_dev(isa_dev, 0);
diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c
index cec0eceae552..b0f3e0082a0d 100644
--- a/arch/sparc64/kernel/of_device.c
+++ b/arch/sparc64/kernel/of_device.c
@@ -144,9 +144,12 @@ void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned lo
}
EXPORT_SYMBOL(of_ioremap);
-void of_iounmap(void __iomem *base, unsigned long size)
+void of_iounmap(struct resource *res, void __iomem *base, unsigned long size)
{
- release_region((unsigned long) base, size);
+ if (res->flags & IORESOURCE_MEM)
+ release_mem_region((unsigned long) base, size);
+ else
+ release_region((unsigned long) base, size);
}
EXPORT_SYMBOL(of_iounmap);
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
index cc09d8266414..0a4958536bcd 100644
--- a/arch/sparc64/kernel/smp.c
+++ b/arch/sparc64/kernel/smp.c
@@ -1447,11 +1447,8 @@ void __init setup_per_cpu_areas(void)
char *ptr;
/* Copy section for each CPU (we discard the original) */
- goal = ALIGN(__per_cpu_end - __per_cpu_start, SMP_CACHE_BYTES);
-#ifdef CONFIG_MODULES
- if (goal < PERCPU_ENOUGH_ROOM)
- goal = PERCPU_ENOUGH_ROOM;
-#endif
+ goal = PERCPU_ENOUGH_ROOM;
+
__per_cpu_shift = 0;
for (size = 1UL; size < goal; size <<= 1UL)
__per_cpu_shift++;
diff --git a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c
index 4446f66590fa..2ebc2c051383 100644
--- a/arch/sparc64/kernel/sys_sunos32.c
+++ b/arch/sparc64/kernel/sys_sunos32.c
@@ -1055,7 +1055,7 @@ asmlinkage int sunos_msgsys(int op, u32 arg1, u32 arg2, u32 arg3, u32 arg4)
break;
case 2:
rval = -EFAULT;
- kmbuf = (struct msgbuf *)kmalloc(sizeof(struct msgbuf) + arg3,
+ kmbuf = kmalloc(sizeof(struct msgbuf) + arg3,
GFP_KERNEL);
if (!kmbuf)
break;
@@ -1078,7 +1078,7 @@ asmlinkage int sunos_msgsys(int op, u32 arg1, u32 arg2, u32 arg3, u32 arg4)
break;
case 3:
rval = -EFAULT;
- kmbuf = (struct msgbuf *)kmalloc(sizeof(struct msgbuf) + arg3,
+ kmbuf = kmalloc(sizeof(struct msgbuf) + arg3,
GFP_KERNEL);
if (!kmbuf || sunos_msgbuf_get((struct msgbuf32 __user *)(unsigned long)arg2,
kmbuf, arg3))
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c
index a8e8802eed4d..054822a3e05e 100644
--- a/arch/sparc64/mm/init.c
+++ b/arch/sparc64/mm/init.c
@@ -872,6 +872,115 @@ static unsigned long __init choose_bootmap_pfn(unsigned long start_pfn,
prom_halt();
}
+static void __init trim_pavail(unsigned long *cur_size_p,
+ unsigned long *end_of_phys_p)
+{
+ unsigned long to_trim = *cur_size_p - cmdline_memory_size;
+ unsigned long avoid_start, avoid_end;
+ int i;
+
+ to_trim = PAGE_ALIGN(to_trim);
+
+ avoid_start = avoid_end = 0;
+#ifdef CONFIG_BLK_DEV_INITRD
+ avoid_start = initrd_start;
+ avoid_end = PAGE_ALIGN(initrd_end);
+#endif
+
+ /* Trim some pavail[] entries in order to satisfy the
+ * requested "mem=xxx" kernel command line specification.
+ *
+ * We must not trim off the kernel image area nor the
+ * initial ramdisk range (if any). Also, we must not trim
+ * any pavail[] entry down to zero in order to preserve
+ * the invariant that all pavail[] entries have a non-zero
+ * size which is assumed by all of the code in here.
+ */
+ for (i = 0; i < pavail_ents; i++) {
+ unsigned long start, end, kern_end;
+ unsigned long trim_low, trim_high, n;
+
+ kern_end = PAGE_ALIGN(kern_base + kern_size);
+
+ trim_low = start = pavail[i].phys_addr;
+ trim_high = end = start + pavail[i].reg_size;
+
+ if (kern_base >= start &&
+ kern_base < end) {
+ trim_low = kern_base;
+ if (kern_end >= end)
+ continue;
+ }
+ if (kern_end >= start &&
+ kern_end < end) {
+ trim_high = kern_end;
+ }
+ if (avoid_start &&
+ avoid_start >= start &&
+ avoid_start < end) {
+ if (trim_low > avoid_start)
+ trim_low = avoid_start;
+ if (avoid_end >= end)
+ continue;
+ }
+ if (avoid_end &&
+ avoid_end >= start &&
+ avoid_end < end) {
+ if (trim_high < avoid_end)
+ trim_high = avoid_end;
+ }
+
+ if (trim_high <= trim_low)
+ continue;
+
+ if (trim_low == start && trim_high == end) {
+ /* Whole chunk is available for trimming.
+ * Trim all except one page, in order to keep
+ * entry non-empty.
+ */
+ n = (end - start) - PAGE_SIZE;
+ if (n > to_trim)
+ n = to_trim;
+
+ if (n) {
+ pavail[i].phys_addr += n;
+ pavail[i].reg_size -= n;
+ to_trim -= n;
+ }
+ } else {
+ n = (trim_low - start);
+ if (n > to_trim)
+ n = to_trim;
+
+ if (n) {
+ pavail[i].phys_addr += n;
+ pavail[i].reg_size -= n;
+ to_trim -= n;
+ }
+ if (to_trim) {
+ n = end - trim_high;
+ if (n > to_trim)
+ n = to_trim;
+ if (n) {
+ pavail[i].reg_size -= n;
+ to_trim -= n;
+ }
+ }
+ }
+
+ if (!to_trim)
+ break;
+ }
+
+ /* Recalculate. */
+ *cur_size_p = 0UL;
+ for (i = 0; i < pavail_ents; i++) {
+ *end_of_phys_p = pavail[i].phys_addr +
+ pavail[i].reg_size;
+ *cur_size_p += pavail[i].reg_size;
+ }
+}
+
static unsigned long __init bootmem_init(unsigned long *pages_avail,
unsigned long phys_base)
{
@@ -889,31 +998,13 @@ static unsigned long __init bootmem_init(unsigned long *pages_avail,
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;
-
- bytes_avail -= slack;
- end_of_phys_memory -= slack;
-
- 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 {
- pavail[i+1].reg_size = 0Ul;
- pavail[i+1].phys_addr = 0xdeadbeefUL;
- pavail_ents = i + 1;
- }
- break;
- }
- }
}
- *pages_avail = bytes_avail >> PAGE_SHIFT;
-
- end_pfn = end_of_phys_memory >> PAGE_SHIFT;
+ /* Determine the location of the initial ramdisk before trying
+ * to honor the "mem=xxx" command line argument. We must know
+ * where the kernel image and the ramdisk image are so that we
+ * do not trim those two areas from the physical memory map.
+ */
#ifdef CONFIG_BLK_DEV_INITRD
/* Now have to check initial ramdisk, so that bootmap does not overwrite it */
@@ -932,6 +1023,16 @@ static unsigned long __init bootmem_init(unsigned long *pages_avail,
}
}
#endif
+
+ if (cmdline_memory_size &&
+ bytes_avail > cmdline_memory_size)
+ trim_pavail(&bytes_avail,
+ &end_of_phys_memory);
+
+ *pages_avail = bytes_avail >> PAGE_SHIFT;
+
+ end_pfn = end_of_phys_memory >> PAGE_SHIFT;
+
/* Initialize the boot-time allocator. */
max_pfn = max_low_pfn = end_pfn;
min_low_pfn = (phys_base >> PAGE_SHIFT);
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index b2e9762e13c5..afe3d427ddfa 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -72,9 +72,11 @@ static int uml_net_rx(struct net_device *dev)
return pkt_len;
}
-static void uml_dev_close(void* dev)
+static void uml_dev_close(struct work_struct *work)
{
- dev_close( (struct net_device *) dev);
+ struct uml_net_private *lp =
+ container_of(work, struct uml_net_private, work);
+ dev_close(lp->dev);
}
irqreturn_t uml_net_interrupt(int irq, void *dev_id)
@@ -89,7 +91,6 @@ irqreturn_t uml_net_interrupt(int irq, void *dev_id)
spin_lock(&lp->lock);
while((err = uml_net_rx(dev)) > 0) ;
if(err < 0) {
- DECLARE_WORK(close_work, uml_dev_close, dev);
printk(KERN_ERR
"Device '%s' read returned %d, shutting it down\n",
dev->name, err);
@@ -97,9 +98,10 @@ irqreturn_t uml_net_interrupt(int irq, void *dev_id)
* again lp->lock.
* And dev_close() can be safely called multiple times on the
* same device, since it tests for (dev->flags & IFF_UP). So
- * there's no harm in delaying the device shutdown. */
- schedule_work(&close_work);
-#error this is not permitted - close_work will go out of scope
+ * there's no harm in delaying the device shutdown.
+ * Furthermore, the workqueue will not re-enqueue an already
+ * enqueued work item. */
+ schedule_work(&lp->work);
goto out;
}
reactivate_fd(lp->fd, UM_ETH_IRQ);
@@ -365,6 +367,7 @@ static int eth_configure(int n, void *init, char *mac,
/* This points to the transport private data. It's still clear, but we
* must memset it to 0 *now*. Let's help the drivers. */
memset(lp, 0, size);
+ INIT_WORK(&lp->work, uml_dev_close);
/* sysfs register */
if (!driver_registered) {
diff --git a/arch/um/include/net_kern.h b/arch/um/include/net_kern.h
index 280459fb0b26..218f8b47fdcd 100644
--- a/arch/um/include/net_kern.h
+++ b/arch/um/include/net_kern.h
@@ -11,6 +11,7 @@
#include <linux/skbuff.h>
#include <linux/socket.h>
#include <linux/list.h>
+#include <linux/workqueue.h>
struct uml_net {
struct list_head list;
@@ -26,6 +27,7 @@ struct uml_net_private {
struct net_device *dev;
struct timer_list tl;
struct net_device_stats stats;
+ struct work_struct work;
int fd;
unsigned char mac[ETH_ALEN];
unsigned short (*protocol)(struct sk_buff *);
diff --git a/arch/um/sys-i386/ldt.c b/arch/um/sys-i386/ldt.c
index 49057d8bc668..5db7737df0ff 100644
--- a/arch/um/sys-i386/ldt.c
+++ b/arch/um/sys-i386/ldt.c
@@ -166,7 +166,7 @@ static long read_ldt_from_host(void __user * ptr, unsigned long bytecount)
struct ptrace_ldt ptrace_ldt = (struct ptrace_ldt) {
.func = 0,
.bytecount = bytecount,
- .ptr = (void *)kmalloc(bytecount, GFP_KERNEL)};
+ .ptr = kmalloc(bytecount, GFP_KERNEL)};
u32 cpu;
if(ptrace_ldt.ptr == NULL)
@@ -426,7 +426,7 @@ void ldt_get_host_info(void)
host_ldt_entries = dummy_list;
else {
size = (size + 1) * sizeof(dummy_list[0]);
- host_ldt_entries = (short *)kmalloc(size, GFP_KERNEL);
+ host_ldt_entries = kmalloc(size, GFP_KERNEL);
if(host_ldt_entries == NULL) {
printk("ldt_get_host_info: couldn't allocate host ldt list\n");
goto out_free;
diff --git a/arch/x86_64/Makefile b/arch/x86_64/Makefile
index b471b8550d03..2941a915d4ef 100644
--- a/arch/x86_64/Makefile
+++ b/arch/x86_64/Makefile
@@ -45,9 +45,7 @@ cflags-kernel-$(CONFIG_REORDER) += -ffunction-sections
# actually it makes the kernel smaller too.
cflags-y += -fno-reorder-blocks
cflags-y += -Wno-sign-compare
-ifneq ($(CONFIG_UNWIND_INFO),y)
cflags-y += -fno-asynchronous-unwind-tables
-endif
ifneq ($(CONFIG_DEBUG_INFO),y)
# -fweb shrinks the kernel a bit, but the difference is very small
# it also messes up debugging, so don't use it for now.
diff --git a/arch/x86_64/defconfig b/arch/x86_64/defconfig
index 1a1c6a1a299b..9cc7c21547a2 100644
--- a/arch/x86_64/defconfig
+++ b/arch/x86_64/defconfig
@@ -1191,7 +1191,7 @@ CONFIG_USB_STORAGE=y
# USB Input Devices
#
CONFIG_USB_HID=y
-# CONFIG_USB_HID_POWERBOOK is not set
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
# CONFIG_HID_FF is not set
# CONFIG_USB_HIDDEV is not set
# CONFIG_USB_AIPTEK is not set
@@ -1523,8 +1523,6 @@ CONFIG_DEBUG_FS=y
# CONFIG_DEBUG_VM is not set
# CONFIG_DEBUG_LIST is not set
# CONFIG_FRAME_POINTER is not set
-CONFIG_UNWIND_INFO=y
-CONFIG_STACK_UNWIND=y
# CONFIG_FORCED_INLINING is not set
# CONFIG_HEADERS_CHECK is not set
# CONFIG_RCU_TORTURE_TEST is not set
diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S
index 601d332c4b79..9f5dac64aa8f 100644
--- a/arch/x86_64/kernel/entry.S
+++ b/arch/x86_64/kernel/entry.S
@@ -1155,36 +1155,3 @@ ENTRY(call_softirq)
ret
CFI_ENDPROC
ENDPROC(call_softirq)
-
-#ifdef CONFIG_STACK_UNWIND
-ENTRY(arch_unwind_init_running)
- CFI_STARTPROC
- movq %r15, R15(%rdi)
- movq %r14, R14(%rdi)
- xchgq %rsi, %rdx
- movq %r13, R13(%rdi)
- movq %r12, R12(%rdi)
- xorl %eax, %eax
- movq %rbp, RBP(%rdi)
- movq %rbx, RBX(%rdi)
- movq (%rsp), %rcx
- movq %rax, R11(%rdi)
- movq %rax, R10(%rdi)
- movq %rax, R9(%rdi)
- movq %rax, R8(%rdi)
- movq %rax, RAX(%rdi)
- movq %rax, RCX(%rdi)
- movq %rax, RDX(%rdi)
- movq %rax, RSI(%rdi)
- movq %rax, RDI(%rdi)
- movq %rax, ORIG_RAX(%rdi)
- movq %rcx, RIP(%rdi)
- leaq 8(%rsp), %rcx
- movq $__KERNEL_CS, CS(%rdi)
- movq %rax, EFLAGS(%rdi)
- movq %rcx, RSP(%rdi)
- movq $__KERNEL_DS, SS(%rdi)
- jmpq *%rdx
- CFI_ENDPROC
-ENDPROC(arch_unwind_init_running)
-#endif
diff --git a/arch/x86_64/kernel/pci-calgary.c b/arch/x86_64/kernel/pci-calgary.c
index 3215675ab128..87d90cb68a74 100644
--- a/arch/x86_64/kernel/pci-calgary.c
+++ b/arch/x86_64/kernel/pci-calgary.c
@@ -1052,7 +1052,7 @@ void __init detect_calgary(void)
void *tbl;
int calgary_found = 0;
unsigned long ptr;
- int offset;
+ unsigned int offset, prev_offset;
int ret;
/*
@@ -1071,15 +1071,20 @@ void __init detect_calgary(void)
ptr = (unsigned long)phys_to_virt(get_bios_ebda());
rio_table_hdr = NULL;
+ prev_offset = 0;
offset = 0x180;
- while (offset) {
+ /*
+ * The next offset is stored in the 1st word.
+ * Only parse up until the offset increases:
+ */
+ while (offset > prev_offset) {
/* The block id is stored in the 2nd word */
if (*((unsigned short *)(ptr + offset + 2)) == 0x4752){
/* set the pointer past the offset & block id */
rio_table_hdr = (struct rio_table_hdr *)(ptr + offset + 4);
break;
}
- /* The next offset is stored in the 1st word. 0 means no more */
+ prev_offset = offset;
offset = *((unsigned short *)(ptr + offset));
}
if (!rio_table_hdr) {
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
index a418ee4c8c62..cbbc6adc1a92 100644
--- a/arch/x86_64/kernel/process.c
+++ b/arch/x86_64/kernel/process.c
@@ -109,7 +109,11 @@ void exit_idle(void)
static void default_idle(void)
{
current_thread_info()->status &= ~TS_POLLING;
- smp_mb__after_clear_bit();
+ /*
+ * TS_POLLING-cleared state must be visible before we
+ * test NEED_RESCHED:
+ */
+ smp_mb();
local_irq_disable();
if (!need_resched()) {
/* Enables interrupts one instruction before HLT.
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c
index b54ccc07f379..09d2e8a10a49 100644
--- a/arch/x86_64/kernel/traps.c
+++ b/arch/x86_64/kernel/traps.c
@@ -110,11 +110,6 @@ static inline void preempt_conditional_cli(struct pt_regs *regs)
}
int kstack_depth_to_print = 12;
-#ifdef CONFIG_STACK_UNWIND
-static int call_trace = 1;
-#else
-#define call_trace (-1)
-#endif
#ifdef CONFIG_KALLSYMS
void printk_address(unsigned long address)
@@ -217,32 +212,6 @@ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack,
return NULL;
}
-struct ops_and_data {
- struct stacktrace_ops *ops;
- void *data;
-};
-
-static int dump_trace_unwind(struct unwind_frame_info *info, void *context)
-{
- struct ops_and_data *oad = (struct ops_and_data *)context;
- int n = 0;
- unsigned long sp = UNW_SP(info);
-
- if (arch_unw_user_mode(info))
- return -1;
- while (unwind(info) == 0 && UNW_PC(info)) {
- n++;
- oad->ops->address(oad->data, UNW_PC(info));
- if (arch_unw_user_mode(info))
- break;
- if ((sp & ~(PAGE_SIZE - 1)) == (UNW_SP(info) & ~(PAGE_SIZE - 1))
- && sp > UNW_SP(info))
- break;
- sp = UNW_SP(info);
- }
- return n;
-}
-
#define MSG(txt) ops->warning(data, txt)
/*
@@ -270,40 +239,6 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs,
if (!tsk)
tsk = current;
- if (call_trace >= 0) {
- int unw_ret = 0;
- struct unwind_frame_info info;
- struct ops_and_data oad = { .ops = ops, .data = data };
-
- if (regs) {
- if (unwind_init_frame_info(&info, tsk, regs) == 0)
- unw_ret = dump_trace_unwind(&info, &oad);
- } else if (tsk == current)
- unw_ret = unwind_init_running(&info, dump_trace_unwind,
- &oad);
- else {
- if (unwind_init_blocked(&info, tsk) == 0)
- unw_ret = dump_trace_unwind(&info, &oad);
- }
- if (unw_ret > 0) {
- if (call_trace == 1 && !arch_unw_user_mode(&info)) {
- ops->warning_symbol(data,
- "DWARF2 unwinder stuck at %s",
- UNW_PC(&info));
- if ((long)UNW_SP(&info) < 0) {
- MSG("Leftover inexact backtrace:");
- stack = (unsigned long *)UNW_SP(&info);
- if (!stack)
- goto out;
- } else
- MSG("Full inexact backtrace again:");
- } else if (call_trace >= 1)
- goto out;
- else
- MSG("Full inexact backtrace again:");
- } else
- MSG("Inexact backtrace:");
- }
if (!stack) {
unsigned long dummy;
stack = &dummy;
@@ -384,10 +319,9 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs,
/*
* This handles the process stack:
*/
- tinfo = current_thread_info();
+ tinfo = task_thread_info(tsk);
HANDLE_STACK (valid_stack_ptr(tinfo, stack));
#undef HANDLE_STACK
-out:
put_cpu();
}
EXPORT_SYMBOL(dump_trace);
@@ -1188,21 +1122,3 @@ static int __init kstack_setup(char *s)
return 0;
}
early_param("kstack", kstack_setup);
-
-#ifdef CONFIG_STACK_UNWIND
-static int __init call_trace_setup(char *s)
-{
- if (!s)
- return -EINVAL;
- if (strcmp(s, "old") == 0)
- call_trace = -1;
- else if (strcmp(s, "both") == 0)
- call_trace = 0;
- else if (strcmp(s, "newfallback") == 0)
- call_trace = 1;
- else if (strcmp(s, "new") == 0)
- call_trace = 2;
- return 0;
-}
-early_param("call_trace", call_trace_setup);
-#endif
diff --git a/arch/x86_64/kernel/vmlinux.lds.S b/arch/x86_64/kernel/vmlinux.lds.S
index 514be5dd2303..1e54ddf2338d 100644
--- a/arch/x86_64/kernel/vmlinux.lds.S
+++ b/arch/x86_64/kernel/vmlinux.lds.S
@@ -221,9 +221,7 @@ SECTIONS
/* Sections to be discarded */
/DISCARD/ : {
*(.exitcall.exit)
-#ifndef CONFIG_UNWIND_INFO
*(.eh_frame)
-#endif
}
STABS_DEBUG
diff --git a/arch/xtensa/kernel/Makefile b/arch/xtensa/kernel/Makefile
index d573017a5dde..71f733c4f66d 100644
--- a/arch/xtensa/kernel/Makefile
+++ b/arch/xtensa/kernel/Makefile
@@ -6,7 +6,7 @@ extra-y := head.o vmlinux.lds
obj-y := align.o entry.o irq.o coprocessor.o process.o ptrace.o semaphore.o \
- setup.o signal.o syscalls.o time.o traps.o vectors.o platform.o \
+ setup.o signal.o syscall.o time.o traps.o vectors.o platform.o \
pci-dma.o
## windowspill.o
diff --git a/arch/xtensa/kernel/syscall.c b/arch/xtensa/kernel/syscall.c
index 418268f49766..fe3834bc1dbf 100644
--- a/arch/xtensa/kernel/syscall.c
+++ b/arch/xtensa/kernel/syscall.c
@@ -16,7 +16,7 @@
*
*/
#include <asm/uaccess.h>
-#include <asm/syscalls.h>
+#include <asm/syscall.h>
#include <asm/unistd.h>
#include <linux/linkage.h>
#include <linux/stringify.h>
diff --git a/block/as-iosched.c b/block/as-iosched.c
index 5934c4bfd52a..ef126277b4b3 100644
--- a/block/as-iosched.c
+++ b/block/as-iosched.c
@@ -1462,20 +1462,7 @@ static struct elevator_type iosched_as = {
static int __init as_init(void)
{
- int ret;
-
- ret = elv_register(&iosched_as);
- if (!ret) {
- /*
- * don't allow AS to get unregistered, since we would have
- * to browse all tasks in the system and release their
- * as_io_context first
- */
- __module_get(THIS_MODULE);
- return 0;
- }
-
- return ret;
+ return elv_register(&iosched_as);
}
static void __exit as_exit(void)
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index 78c6b312bd30..07b706243772 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -219,9 +219,12 @@ static int cfq_queue_empty(request_queue_t *q)
return !cfqd->busy_queues;
}
-static inline pid_t cfq_queue_pid(struct task_struct *task, int rw)
+static inline pid_t cfq_queue_pid(struct task_struct *task, int rw, int is_sync)
{
- if (rw == READ || rw == WRITE_SYNC)
+ /*
+ * Use the per-process queue, for read requests and syncronous writes
+ */
+ if (!(rw & REQ_RW) || is_sync)
return task->pid;
return CFQ_KEY_ASYNC;
@@ -473,7 +476,7 @@ static struct request *
cfq_find_rq_fmerge(struct cfq_data *cfqd, struct bio *bio)
{
struct task_struct *tsk = current;
- pid_t key = cfq_queue_pid(tsk, bio_data_dir(bio));
+ pid_t key = cfq_queue_pid(tsk, bio_data_dir(bio), bio_sync(bio));
struct cfq_queue *cfqq;
cfqq = cfq_find_cfq_hash(cfqd, key, tsk->ioprio);
@@ -565,6 +568,33 @@ cfq_merged_requests(request_queue_t *q, struct request *rq,
cfq_remove_request(next);
}
+static int cfq_allow_merge(request_queue_t *q, struct request *rq,
+ struct bio *bio)
+{
+ struct cfq_data *cfqd = q->elevator->elevator_data;
+ const int rw = bio_data_dir(bio);
+ struct cfq_queue *cfqq;
+ pid_t key;
+
+ /*
+ * Disallow merge of a sync bio into an async request.
+ */
+ if ((bio_data_dir(bio) == READ || bio_sync(bio)) && !rq_is_sync(rq))
+ return 0;
+
+ /*
+ * Lookup the cfqq that this bio will be queued with. Allow
+ * merge only if rq is queued there.
+ */
+ key = cfq_queue_pid(current, rw, bio_sync(bio));
+ cfqq = cfq_find_cfq_hash(cfqd, key, current->ioprio);
+
+ if (cfqq == RQ_CFQQ(rq))
+ return 1;
+
+ return 0;
+}
+
static inline void
__cfq_set_active_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq)
{
@@ -1748,6 +1778,9 @@ static int cfq_may_queue(request_queue_t *q, int rw)
struct cfq_data *cfqd = q->elevator->elevator_data;
struct task_struct *tsk = current;
struct cfq_queue *cfqq;
+ unsigned int key;
+
+ key = cfq_queue_pid(tsk, rw, rw & REQ_RW_SYNC);
/*
* don't force setup of a queue from here, as a call to may_queue
@@ -1755,7 +1788,7 @@ static int cfq_may_queue(request_queue_t *q, int rw)
* so just lookup a possibly existing queue, or return 'may queue'
* if that fails
*/
- cfqq = cfq_find_cfq_hash(cfqd, cfq_queue_pid(tsk, rw), tsk->ioprio);
+ cfqq = cfq_find_cfq_hash(cfqd, key, tsk->ioprio);
if (cfqq) {
cfq_init_prio_data(cfqq);
cfq_prio_boost(cfqq);
@@ -1798,10 +1831,10 @@ cfq_set_request(request_queue_t *q, struct request *rq, gfp_t gfp_mask)
struct task_struct *tsk = current;
struct cfq_io_context *cic;
const int rw = rq_data_dir(rq);
- pid_t key = cfq_queue_pid(tsk, rw);
+ const int is_sync = rq_is_sync(rq);
+ pid_t key = cfq_queue_pid(tsk, rw, is_sync);
struct cfq_queue *cfqq;
unsigned long flags;
- int is_sync = key != CFQ_KEY_ASYNC;
might_sleep_if(gfp_mask & __GFP_WAIT);
@@ -2119,6 +2152,7 @@ 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_allow_merge_fn = cfq_allow_merge,
.elevator_dispatch_fn = cfq_dispatch_requests,
.elevator_add_req_fn = cfq_insert_request,
.elevator_activate_req_fn = cfq_activate_request,
diff --git a/block/elevator.c b/block/elevator.c
index c0063f345c5d..536be740ba4e 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -51,6 +51,21 @@ static const int elv_hash_shift = 6;
#define ELV_ON_HASH(rq) (!hlist_unhashed(&(rq)->hash))
/*
+ * Query io scheduler to see if the current process issuing bio may be
+ * merged with rq.
+ */
+static int elv_iosched_allow_merge(struct request *rq, struct bio *bio)
+{
+ request_queue_t *q = rq->q;
+ elevator_t *e = q->elevator;
+
+ if (e->ops->elevator_allow_merge_fn)
+ return e->ops->elevator_allow_merge_fn(q, rq, bio);
+
+ return 1;
+}
+
+/*
* can we safely merge with this request?
*/
inline int elv_rq_merge_ok(struct request *rq, struct bio *bio)
@@ -65,12 +80,15 @@ inline int elv_rq_merge_ok(struct request *rq, struct bio *bio)
return 0;
/*
- * same device and no special stuff set, merge is ok
+ * must be same device and not a special request
*/
- if (rq->rq_disk == bio->bi_bdev->bd_disk && !rq->special)
- return 1;
+ if (rq->rq_disk != bio->bi_bdev->bd_disk || rq->special)
+ return 0;
- return 0;
+ if (!elv_iosched_allow_merge(rq, bio))
+ return 0;
+
+ return 1;
}
EXPORT_SYMBOL(elv_rq_merge_ok);
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index a541b42c08e3..fb6789725e1b 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -1405,8 +1405,7 @@ static inline int ll_new_hw_segment(request_queue_t *q,
return 1;
}
-static int ll_back_merge_fn(request_queue_t *q, struct request *req,
- struct bio *bio)
+int ll_back_merge_fn(request_queue_t *q, struct request *req, struct bio *bio)
{
unsigned short max_sectors;
int len;
@@ -1442,6 +1441,7 @@ static int ll_back_merge_fn(request_queue_t *q, struct request *req,
return ll_new_hw_segment(q, req, bio);
}
+EXPORT_SYMBOL(ll_back_merge_fn);
static int ll_front_merge_fn(request_queue_t *q, struct request *req,
struct bio *bio)
@@ -1912,9 +1912,6 @@ blk_init_queue_node(request_fn_proc *rfn, spinlock_t *lock, int node_id)
}
q->request_fn = rfn;
- q->back_merge_fn = ll_back_merge_fn;
- q->front_merge_fn = ll_front_merge_fn;
- q->merge_requests_fn = ll_merge_requests_fn;
q->prep_rq_fn = NULL;
q->unplug_fn = generic_unplug_device;
q->queue_flags = (1 << QUEUE_FLAG_CLUSTER);
@@ -2058,15 +2055,16 @@ static void freed_request(request_queue_t *q, int rw, int priv)
* Returns NULL on failure, with queue_lock held.
* Returns !NULL on success, with queue_lock *not held*.
*/
-static struct request *get_request(request_queue_t *q, int rw, struct bio *bio,
- gfp_t gfp_mask)
+static struct request *get_request(request_queue_t *q, int rw_flags,
+ struct bio *bio, gfp_t gfp_mask)
{
struct request *rq = NULL;
struct request_list *rl = &q->rq;
struct io_context *ioc = NULL;
+ const int rw = rw_flags & 0x01;
int may_queue, priv;
- may_queue = elv_may_queue(q, rw);
+ may_queue = elv_may_queue(q, rw_flags);
if (may_queue == ELV_MQUEUE_NO)
goto rq_starved;
@@ -2114,7 +2112,7 @@ static struct request *get_request(request_queue_t *q, int rw, struct bio *bio,
spin_unlock_irq(q->queue_lock);
- rq = blk_alloc_request(q, rw, priv, gfp_mask);
+ rq = blk_alloc_request(q, rw_flags, priv, gfp_mask);
if (unlikely(!rq)) {
/*
* Allocation failed presumably due to memory. Undo anything
@@ -2162,12 +2160,13 @@ out:
*
* Called with q->queue_lock held, and returns with it unlocked.
*/
-static struct request *get_request_wait(request_queue_t *q, int rw,
+static struct request *get_request_wait(request_queue_t *q, int rw_flags,
struct bio *bio)
{
+ const int rw = rw_flags & 0x01;
struct request *rq;
- rq = get_request(q, rw, bio, GFP_NOIO);
+ rq = get_request(q, rw_flags, bio, GFP_NOIO);
while (!rq) {
DEFINE_WAIT(wait);
struct request_list *rl = &q->rq;
@@ -2175,7 +2174,7 @@ static struct request *get_request_wait(request_queue_t *q, int rw,
prepare_to_wait_exclusive(&rl->wait[rw], &wait,
TASK_UNINTERRUPTIBLE);
- rq = get_request(q, rw, bio, GFP_NOIO);
+ rq = get_request(q, rw_flags, bio, GFP_NOIO);
if (!rq) {
struct io_context *ioc;
@@ -2348,40 +2347,29 @@ static int __blk_rq_map_user(request_queue_t *q, struct request *rq,
else
bio = bio_copy_user(q, uaddr, len, reading);
- if (IS_ERR(bio)) {
+ if (IS_ERR(bio))
return PTR_ERR(bio);
- }
orig_bio = bio;
blk_queue_bounce(q, &bio);
+
/*
* We link the bounce buffer in and could have to traverse it
* later so we have to get a ref to prevent it from being freed
*/
bio_get(bio);
- /*
- * for most (all? don't know of any) queues we could
- * skip grabbing the queue lock here. only drivers with
- * funky private ->back_merge_fn() function could be
- * problematic.
- */
- spin_lock_irq(q->queue_lock);
if (!rq->bio)
blk_rq_bio_prep(q, rq, bio);
- else if (!q->back_merge_fn(q, rq, bio)) {
+ else if (!ll_back_merge_fn(q, rq, bio)) {
ret = -EINVAL;
- spin_unlock_irq(q->queue_lock);
goto unmap_bio;
} else {
rq->biotail->bi_next = bio;
rq->biotail = bio;
- rq->nr_sectors += bio_sectors(bio);
- rq->hard_nr_sectors = rq->nr_sectors;
rq->data_len += bio->bi_size;
}
- spin_unlock_irq(q->queue_lock);
return bio->bi_size;
@@ -2417,6 +2405,7 @@ int blk_rq_map_user(request_queue_t *q, struct request *rq, void __user *ubuf,
unsigned long len)
{
unsigned long bytes_read = 0;
+ struct bio *bio = NULL;
int ret;
if (len > (q->max_hw_sectors << 9))
@@ -2443,6 +2432,8 @@ int blk_rq_map_user(request_queue_t *q, struct request *rq, void __user *ubuf,
ret = __blk_rq_map_user(q, rq, ubuf, map_len);
if (ret < 0)
goto unmap_rq;
+ if (!bio)
+ bio = rq->bio;
bytes_read += ret;
ubuf += ret;
}
@@ -2450,7 +2441,7 @@ int blk_rq_map_user(request_queue_t *q, struct request *rq, void __user *ubuf,
rq->buffer = rq->data = NULL;
return 0;
unmap_rq:
- blk_rq_unmap_user(rq);
+ blk_rq_unmap_user(bio);
return ret;
}
@@ -2462,6 +2453,7 @@ EXPORT_SYMBOL(blk_rq_map_user);
* @rq: request to map data to
* @iov: pointer to the iovec
* @iov_count: number of elements in the iovec
+ * @len: I/O byte count
*
* Description:
* Data will be mapped directly for zero copy io, if possible. Otherwise
@@ -2507,27 +2499,33 @@ EXPORT_SYMBOL(blk_rq_map_user_iov);
/**
* blk_rq_unmap_user - unmap a request with user data
- * @rq: rq to be unmapped
+ * @bio: start of bio list
*
* Description:
- * Unmap a rq previously mapped by blk_rq_map_user().
- * rq->bio must be set to the original head of the request.
+ * Unmap a rq previously mapped by blk_rq_map_user(). The caller must
+ * supply the original rq->bio from the blk_rq_map_user() return, since
+ * the io completion may have changed rq->bio.
*/
-int blk_rq_unmap_user(struct request *rq)
+int blk_rq_unmap_user(struct bio *bio)
{
- struct bio *bio, *mapped_bio;
+ struct bio *mapped_bio;
+ int ret = 0, ret2;
- while ((bio = rq->bio)) {
- if (bio_flagged(bio, BIO_BOUNCED))
+ while (bio) {
+ mapped_bio = bio;
+ if (unlikely(bio_flagged(bio, BIO_BOUNCED)))
mapped_bio = bio->bi_private;
- else
- mapped_bio = bio;
- __blk_rq_unmap_user(mapped_bio);
- rq->bio = bio->bi_next;
- bio_put(bio);
+ ret2 = __blk_rq_unmap_user(mapped_bio);
+ if (ret2 && !ret)
+ ret = ret2;
+
+ mapped_bio = bio;
+ bio = bio->bi_next;
+ bio_put(mapped_bio);
}
- return 0;
+
+ return ret;
}
EXPORT_SYMBOL(blk_rq_unmap_user);
@@ -2820,7 +2818,7 @@ static int attempt_merge(request_queue_t *q, struct request *req,
* will have updated segment counts, update sector
* counts here.
*/
- if (!q->merge_requests_fn(q, req, next))
+ if (!ll_merge_requests_fn(q, req, next))
return 0;
/*
@@ -2910,6 +2908,7 @@ static int __make_request(request_queue_t *q, struct bio *bio)
int el_ret, nr_sectors, barrier, err;
const unsigned short prio = bio_prio(bio);
const int sync = bio_sync(bio);
+ int rw_flags;
nr_sectors = bio_sectors(bio);
@@ -2936,7 +2935,7 @@ static int __make_request(request_queue_t *q, struct bio *bio)
case ELEVATOR_BACK_MERGE:
BUG_ON(!rq_mergeable(req));
- if (!q->back_merge_fn(q, req, bio))
+ if (!ll_back_merge_fn(q, req, bio))
break;
blk_add_trace_bio(q, bio, BLK_TA_BACKMERGE);
@@ -2953,7 +2952,7 @@ static int __make_request(request_queue_t *q, struct bio *bio)
case ELEVATOR_FRONT_MERGE:
BUG_ON(!rq_mergeable(req));
- if (!q->front_merge_fn(q, req, bio))
+ if (!ll_front_merge_fn(q, req, bio))
break;
blk_add_trace_bio(q, bio, BLK_TA_FRONTMERGE);
@@ -2984,10 +2983,19 @@ static int __make_request(request_queue_t *q, struct bio *bio)
get_rq:
/*
+ * This sync check and mask will be re-done in init_request_from_bio(),
+ * but we need to set it earlier to expose the sync flag to the
+ * rq allocator and io schedulers.
+ */
+ rw_flags = bio_data_dir(bio);
+ if (sync)
+ rw_flags |= REQ_RW_SYNC;
+
+ /*
* Grab a free request. This is might sleep but can not fail.
* Returns with the queue unlocked.
*/
- req = get_request_wait(q, bio_data_dir(bio), bio);
+ req = get_request_wait(q, rw_flags, bio);
/*
* After dropping the lock and possibly sleeping here, our request
diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c
index f322b6a441d8..2528a0c0dec8 100644
--- a/block/scsi_ioctl.c
+++ b/block/scsi_ioctl.c
@@ -333,8 +333,7 @@ static int sg_io(struct file *file, request_queue_t *q,
hdr->sb_len_wr = len;
}
- rq->bio = bio;
- if (blk_rq_unmap_user(rq))
+ if (blk_rq_unmap_user(bio))
ret = -EFAULT;
/* may not have succeeded, but output values written to control
diff --git a/crypto/blkcipher.c b/crypto/blkcipher.c
index 034c939bf91a..6e93004f2181 100644
--- a/crypto/blkcipher.c
+++ b/crypto/blkcipher.c
@@ -17,7 +17,6 @@
#include <linux/crypto.h>
#include <linux/errno.h>
#include <linux/kernel.h>
-#include <linux/io.h>
#include <linux/module.h>
#include <linux/scatterlist.h>
#include <linux/seq_file.h>
diff --git a/drivers/acorn/block/fd1772.c b/drivers/acorn/block/fd1772.c
index 048542341204..674bf81c6e66 100644
--- a/drivers/acorn/block/fd1772.c
+++ b/drivers/acorn/block/fd1772.c
@@ -1549,12 +1549,12 @@ int fd1772_init(void)
#ifdef TRACKBUFFER
BufferDrive = BufferSide = BufferTrack = -1;
/* Atari uses 512 - I want to eventually cope with 1K sectors */
- DMABuffer = (char *)kmalloc((FD1772_MAX_SECTORS+1)*512,GFP_KERNEL);
+ DMABuffer = kmalloc((FD1772_MAX_SECTORS+1)*512,GFP_KERNEL);
TrackBuffer = DMABuffer + 512;
#else
/* Allocate memory for the DMAbuffer - on the Atari this takes it
out of some special memory... */
- DMABuffer = (char *) kmalloc(2048); /* Copes with pretty large sectors */
+ DMABuffer = kmalloc(2048); /* Copes with pretty large sectors */
#endif
err = -ENOMEM;
if (!DMAbuffer)
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 0f9d4be7ed75..1639998e4d27 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -11,7 +11,7 @@ config ACPI
bool "ACPI Support"
depends on IA64 || X86
depends on PCI
- select PM
+ depends on PM
default y
---help---
Advanced Configuration and Power Interface (ACPI) support for
@@ -97,6 +97,7 @@ config ACPI_BATTERY
config ACPI_BUTTON
tristate "Button"
+ depends on INPUT
default y
help
This driver handles events on the power, sleep and lid buttons.
@@ -172,6 +173,7 @@ config ACPI_NUMA
config ACPI_ASUS
tristate "ASUS/Medion Laptop Extras"
depends on X86
+ select BACKLIGHT_CLASS_DEVICE
---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
@@ -200,6 +202,7 @@ config ACPI_ASUS
config ACPI_IBM
tristate "IBM ThinkPad Laptop Extras"
depends on X86
+ select BACKLIGHT_CLASS_DEVICE
---help---
This is a Linux ACPI driver for the IBM ThinkPad laptops. It adds
support for Fn-Fx key combinations, Bluetooth control, video
@@ -222,9 +225,21 @@ config ACPI_IBM_DOCK
If you are not sure, say N here.
+config ACPI_IBM_BAY
+ bool "Legacy Removable Bay Support"
+ depends on ACPI_IBM
+ depends on ACPI_BAY=n
+ default n
+ ---help---
+ Allows the ibm_acpi driver to handle removable bays.
+ This support is obsoleted by CONFIG_ACPI_BAY.
+
+ If you are not sure, say N here.
+
config ACPI_TOSHIBA
tristate "Toshiba Laptop Extras"
depends on X86
+ select BACKLIGHT_CLASS_DEVICE
---help---
This driver adds support for access to certain system settings
on "legacy free" Toshiba laptops. These laptops can be recognized by
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index 11abc7bf777e..6daeace796a8 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -109,7 +109,7 @@ 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 = seq->private;
if (!ac)
@@ -187,7 +187,7 @@ static int acpi_ac_remove_fs(struct acpi_device *device)
static void acpi_ac_notify(acpi_handle handle, u32 event, void *data)
{
- struct acpi_ac *ac = (struct acpi_ac *)data;
+ struct acpi_ac *ac = data;
struct acpi_device *device = NULL;
@@ -221,10 +221,9 @@ static int acpi_ac_add(struct acpi_device *device)
if (!device)
return -EINVAL;
- ac = kmalloc(sizeof(struct acpi_ac), GFP_KERNEL);
+ ac = kzalloc(sizeof(struct acpi_ac), GFP_KERNEL);
if (!ac)
return -ENOMEM;
- memset(ac, 0, sizeof(struct acpi_ac));
ac->device = device;
strcpy(acpi_device_name(device), ACPI_AC_DEVICE_NAME);
@@ -269,7 +268,7 @@ static int acpi_ac_remove(struct acpi_device *device, int type)
if (!device || !acpi_driver_data(device))
return -EINVAL;
- ac = (struct acpi_ac *)acpi_driver_data(device);
+ ac = acpi_driver_data(device);
status = acpi_remove_notify_handler(device->handle,
ACPI_ALL_NOTIFY, acpi_ac_notify);
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c
index 6bcd9e8e7bcb..cd946ed192d3 100644
--- a/drivers/acpi/acpi_memhotplug.c
+++ b/drivers/acpi/acpi_memhotplug.c
@@ -395,10 +395,9 @@ static int acpi_memory_device_add(struct acpi_device *device)
if (!device)
return -EINVAL;
- mem_device = kmalloc(sizeof(struct acpi_memory_device), GFP_KERNEL);
+ mem_device = kzalloc(sizeof(struct acpi_memory_device), GFP_KERNEL);
if (!mem_device)
return -ENOMEM;
- memset(mem_device, 0, sizeof(struct acpi_memory_device));
INIT_LIST_HEAD(&mem_device->res_list);
mem_device->device = device;
@@ -429,7 +428,7 @@ static int acpi_memory_device_remove(struct acpi_device *device, int type)
if (!device || !acpi_driver_data(device))
return -EINVAL;
- mem_device = (struct acpi_memory_device *)acpi_driver_data(device);
+ mem_device = acpi_driver_data(device);
kfree(mem_device);
return 0;
diff --git a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c
index c7ac9297a204..396140bbbe57 100644
--- a/drivers/acpi/asus_acpi.c
+++ b/drivers/acpi/asus_acpi.c
@@ -35,6 +35,7 @@
#include <linux/init.h>
#include <linux/types.h>
#include <linux/proc_fs.h>
+#include <linux/backlight.h>
#include <acpi/acpi_drivers.h>
#include <acpi/acpi_bus.h>
#include <asm/uaccess.h>
@@ -402,6 +403,8 @@ static struct model_data model_conf[END_MODEL] = {
/* procdir we use */
static struct proc_dir_entry *asus_proc_dir;
+static struct backlight_device *asus_backlight_device;
+
/*
* This header is made available to allow proper configuration given model,
* revision number , ... this info cannot go in struct asus_hotk because it is
@@ -779,7 +782,7 @@ proc_write_lcd(struct file *file, const char __user * buffer,
return rv;
}
-static int read_brightness(void)
+static int read_brightness(struct backlight_device *bd)
{
int value;
@@ -801,9 +804,10 @@ static int read_brightness(void)
/*
* Change the brightness level
*/
-static void set_brightness(int value)
+static int set_brightness(int value)
{
acpi_status status = 0;
+ int ret = 0;
/* SPLV laptop */
if (hotk->methods->brightness_set) {
@@ -811,11 +815,12 @@ static void set_brightness(int value)
value, NULL))
printk(KERN_WARNING
"Asus ACPI: Error changing brightness\n");
- return;
+ ret = -EIO;
+ goto out;
}
/* No SPLV method if we are here, act as appropriate */
- value -= read_brightness();
+ value -= read_brightness(NULL);
while (value != 0) {
status = acpi_evaluate_object(NULL, (value > 0) ?
hotk->methods->brightness_up :
@@ -825,15 +830,22 @@ static void set_brightness(int value)
if (ACPI_FAILURE(status))
printk(KERN_WARNING
"Asus ACPI: Error changing brightness\n");
+ ret = -EIO;
}
- return;
+out:
+ return ret;
+}
+
+static int set_brightness_status(struct backlight_device *bd)
+{
+ return set_brightness(bd->props->brightness);
}
static int
proc_read_brn(char *page, char **start, off_t off, int count, int *eof,
void *data)
{
- return sprintf(page, "%d\n", read_brightness());
+ return sprintf(page, "%d\n", read_brightness(NULL));
}
static int
@@ -1134,7 +1146,7 @@ static int 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 = dsdt.pointer;
/* We have to write 0 on init this far for all ASUS models */
if (!write_acpi_int(hotk->handle, "INIT", 0, &buffer)) {
@@ -1156,7 +1168,7 @@ static int asus_hotk_get_info(void)
* asus_model_match() and try something completely different.
*/
if (buffer.pointer) {
- model = (union acpi_object *)buffer.pointer;
+ model = buffer.pointer;
switch (model->type) {
case ACPI_TYPE_STRING:
string = model->string.pointer;
@@ -1252,11 +1264,9 @@ static int asus_hotk_add(struct acpi_device *device)
printk(KERN_NOTICE "Asus Laptop ACPI Extras version %s\n",
ASUS_ACPI_VERSION);
- hotk =
- (struct asus_hotk *)kmalloc(sizeof(struct asus_hotk), GFP_KERNEL);
+ hotk = kzalloc(sizeof(struct asus_hotk), GFP_KERNEL);
if (!hotk)
return -ENOMEM;
- memset(hotk, 0, sizeof(struct asus_hotk));
hotk->handle = device->handle;
strcpy(acpi_device_name(device), ACPI_HOTK_DEVICE_NAME);
@@ -1333,6 +1343,26 @@ static int asus_hotk_remove(struct acpi_device *device, int type)
return 0;
}
+static struct backlight_properties asus_backlight_data = {
+ .owner = THIS_MODULE,
+ .get_brightness = read_brightness,
+ .update_status = set_brightness_status,
+ .max_brightness = 15,
+};
+
+static void __exit asus_acpi_exit(void)
+{
+ if (asus_backlight_device)
+ backlight_device_unregister(asus_backlight_device);
+
+ acpi_bus_unregister_driver(&asus_hotk_driver);
+ remove_proc_entry(PROC_ASUS, acpi_root_dir);
+
+ kfree(asus_info);
+
+ return;
+}
+
static int __init asus_acpi_init(void)
{
int result;
@@ -1370,17 +1400,15 @@ static int __init asus_acpi_init(void)
return result;
}
- return 0;
-}
-
-static void __exit asus_acpi_exit(void)
-{
- acpi_bus_unregister_driver(&asus_hotk_driver);
- remove_proc_entry(PROC_ASUS, acpi_root_dir);
-
- kfree(asus_info);
+ asus_backlight_device = backlight_device_register("asus",NULL,NULL,
+ &asus_backlight_data);
+ if (IS_ERR(asus_backlight_device)) {
+ printk(KERN_ERR "Could not register asus backlight device\n");
+ asus_backlight_device = NULL;
+ asus_acpi_exit();
+ }
- return;
+ return 0;
}
module_init(asus_acpi_init);
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 026e40755cdd..5f43e0d14899 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -149,7 +149,7 @@ acpi_battery_get_info(struct acpi_battery *battery,
return -ENODEV;
}
- package = (union acpi_object *)buffer.pointer;
+ package = buffer.pointer;
/* Extract Package Data */
@@ -160,12 +160,11 @@ acpi_battery_get_info(struct acpi_battery *battery,
goto end;
}
- data.pointer = kmalloc(data.length, GFP_KERNEL);
+ data.pointer = kzalloc(data.length, GFP_KERNEL);
if (!data.pointer) {
result = -ENOMEM;
goto end;
}
- memset(data.pointer, 0, data.length);
status = acpi_extract_package(package, &format, &data);
if (ACPI_FAILURE(status)) {
@@ -179,7 +178,7 @@ acpi_battery_get_info(struct acpi_battery *battery,
kfree(buffer.pointer);
if (!result)
- (*bif) = (struct acpi_battery_info *)data.pointer;
+ (*bif) = data.pointer;
return result;
}
@@ -209,7 +208,7 @@ acpi_battery_get_status(struct acpi_battery *battery,
return -ENODEV;
}
- package = (union acpi_object *)buffer.pointer;
+ package = buffer.pointer;
/* Extract Package Data */
@@ -220,12 +219,11 @@ acpi_battery_get_status(struct acpi_battery *battery,
goto end;
}
- data.pointer = kmalloc(data.length, GFP_KERNEL);
+ data.pointer = kzalloc(data.length, GFP_KERNEL);
if (!data.pointer) {
result = -ENOMEM;
goto end;
}
- memset(data.pointer, 0, data.length);
status = acpi_extract_package(package, &format, &data);
if (ACPI_FAILURE(status)) {
@@ -239,7 +237,7 @@ acpi_battery_get_status(struct acpi_battery *battery,
kfree(buffer.pointer);
if (!result)
- (*bst) = (struct acpi_battery_status *)data.pointer;
+ (*bst) = data.pointer;
return result;
}
@@ -334,7 +332,7 @@ 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;
+ struct acpi_battery *battery = seq->private;
struct acpi_battery_info *bif = NULL;
char *units = "?";
@@ -418,7 +416,7 @@ static int acpi_battery_info_open_fs(struct inode *inode, struct file *file)
static int acpi_battery_read_state(struct seq_file *seq, void *offset)
{
int result = 0;
- struct acpi_battery *battery = (struct acpi_battery *)seq->private;
+ struct acpi_battery *battery = seq->private;
struct acpi_battery_status *bst = NULL;
char *units = "?";
@@ -494,7 +492,7 @@ static int acpi_battery_state_open_fs(struct inode *inode, struct file *file)
static int acpi_battery_read_alarm(struct seq_file *seq, void *offset)
{
- struct acpi_battery *battery = (struct acpi_battery *)seq->private;
+ struct acpi_battery *battery = seq->private;
char *units = "?";
@@ -531,8 +529,8 @@ acpi_battery_write_alarm(struct file *file,
{
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;
+ struct seq_file *m = file->private_data;
+ struct acpi_battery *battery = m->private;
if (!battery || (count > sizeof(alarm_string) - 1))
@@ -658,7 +656,7 @@ static int acpi_battery_remove_fs(struct acpi_device *device)
static void acpi_battery_notify(acpi_handle handle, u32 event, void *data)
{
- struct acpi_battery *battery = (struct acpi_battery *)data;
+ struct acpi_battery *battery = data;
struct acpi_device *device = NULL;
@@ -694,10 +692,9 @@ static int acpi_battery_add(struct acpi_device *device)
if (!device)
return -EINVAL;
- battery = kmalloc(sizeof(struct acpi_battery), GFP_KERNEL);
+ battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL);
if (!battery)
return -ENOMEM;
- memset(battery, 0, sizeof(struct acpi_battery));
battery->device = device;
strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME);
@@ -742,7 +739,7 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
if (!device || !acpi_driver_data(device))
return -EINVAL;
- battery = (struct acpi_battery *)acpi_driver_data(device);
+ battery = acpi_driver_data(device);
status = acpi_remove_notify_handler(device->handle,
ACPI_ALL_NOTIFY,
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index 5ef885e82c78..ac860583c203 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -29,6 +29,7 @@
#include <linux/types.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
+#include <linux/input.h>
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
@@ -62,7 +63,7 @@
#define _COMPONENT ACPI_BUTTON_COMPONENT
ACPI_MODULE_NAME("acpi_button")
- MODULE_AUTHOR("Paul Diefenbaugh");
+MODULE_AUTHOR("Paul Diefenbaugh");
MODULE_DESCRIPTION(ACPI_BUTTON_DRIVER_NAME);
MODULE_LICENSE("GPL");
@@ -78,12 +79,14 @@ static struct acpi_driver acpi_button_driver = {
.ops = {
.add = acpi_button_add,
.remove = acpi_button_remove,
- },
+ },
};
struct acpi_button {
struct acpi_device *device; /* Fixed button kludge */
- u8 type;
+ unsigned int type;
+ struct input_dev *input;
+ char phys[32]; /* for input device */
unsigned long pushed;
};
@@ -109,8 +112,7 @@ 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 = seq->private;
if (!button || !button->device)
return 0;
@@ -128,22 +130,17 @@ static int acpi_button_info_open_fs(struct inode *inode, struct file *file)
static int acpi_button_state_seq_show(struct seq_file *seq, void *offset)
{
- struct acpi_button *button = (struct acpi_button *)seq->private;
+ struct acpi_button *button = seq->private;
acpi_status status;
unsigned long state;
-
if (!button || !button->device)
return 0;
status = acpi_evaluate_integer(button->device->handle, "_LID", NULL, &state);
- if (ACPI_FAILURE(status)) {
- seq_printf(seq, "state: unsupported\n");
- } else {
- seq_printf(seq, "state: %s\n",
- (state ? "open" : "closed"));
- }
-
+ seq_printf(seq, "state: %s\n",
+ ACPI_FAILURE(status) ? "unsupported" :
+ (state ? "open" : "closed"));
return 0;
}
@@ -159,8 +156,7 @@ static struct proc_dir_entry *acpi_lid_dir;
static int acpi_button_add_fs(struct acpi_device *device)
{
struct proc_dir_entry *entry = NULL;
- struct acpi_button *button = NULL;
-
+ struct acpi_button *button;
if (!device || !acpi_driver_data(device))
return -EINVAL;
@@ -228,10 +224,8 @@ static int acpi_button_add_fs(struct acpi_device *device)
static int acpi_button_remove_fs(struct acpi_device *device)
{
- struct acpi_button *button = NULL;
-
+ struct acpi_button *button = acpi_driver_data(device);
- button = acpi_driver_data(device);
if (acpi_device_dir(device)) {
if (button->type == ACPI_BUTTON_TYPE_LID)
remove_proc_entry(ACPI_BUTTON_FILE_STATE,
@@ -253,14 +247,34 @@ static int acpi_button_remove_fs(struct acpi_device *device)
static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
{
- struct acpi_button *button = (struct acpi_button *)data;
-
+ struct acpi_button *button = data;
+ struct input_dev *input;
if (!button || !button->device)
return;
switch (event) {
case ACPI_BUTTON_NOTIFY_STATUS:
+ input = button->input;
+
+ if (button->type == ACPI_BUTTON_TYPE_LID) {
+ struct acpi_handle *handle = button->device->handle;
+ unsigned long state;
+
+ if (!ACPI_FAILURE(acpi_evaluate_integer(handle, "_LID",
+ NULL, &state)))
+ input_report_switch(input, SW_LID, !state);
+
+ } else {
+ int keycode = test_bit(KEY_SLEEP, input->keybit) ?
+ KEY_SLEEP : KEY_POWER;
+
+ input_report_key(input, keycode, 1);
+ input_sync(input);
+ input_report_key(input, keycode, 0);
+ }
+ input_sync(input);
+
acpi_bus_generate_event(button->device, event,
++button->pushed);
break;
@@ -275,8 +289,7 @@ static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
static acpi_status acpi_button_notify_fixed(void *data)
{
- struct acpi_button *button = (struct acpi_button *)data;
-
+ struct acpi_button *button = data;
if (!button)
return AE_BAD_PARAMETER;
@@ -286,24 +299,75 @@ static acpi_status acpi_button_notify_fixed(void *data)
return AE_OK;
}
-static int acpi_button_add(struct acpi_device *device)
+static int acpi_button_install_notify_handlers(struct acpi_button *button)
{
- int result = 0;
- acpi_status status = AE_OK;
- struct acpi_button *button = NULL;
+ acpi_status status;
+ switch (button->type) {
+ case ACPI_BUTTON_TYPE_POWERF:
+ 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);
+ break;
+ default:
+ status = acpi_install_notify_handler(button->device->handle,
+ ACPI_DEVICE_NOTIFY,
+ acpi_button_notify,
+ button);
+ break;
+ }
+
+ return ACPI_FAILURE(status) ? -ENODEV : 0;
+}
+
+static void acpi_button_remove_notify_handlers(struct acpi_button *button)
+{
+ switch (button->type) {
+ case ACPI_BUTTON_TYPE_POWERF:
+ acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
+ acpi_button_notify_fixed);
+ break;
+ case ACPI_BUTTON_TYPE_SLEEPF:
+ acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
+ acpi_button_notify_fixed);
+ break;
+ default:
+ acpi_remove_notify_handler(button->device->handle,
+ ACPI_DEVICE_NOTIFY,
+ acpi_button_notify);
+ break;
+ }
+}
+
+static int acpi_button_add(struct acpi_device *device)
+{
+ int error;
+ struct acpi_button *button;
+ struct input_dev *input;
if (!device)
return -EINVAL;
- button = kmalloc(sizeof(struct acpi_button), GFP_KERNEL);
+ button = kzalloc(sizeof(struct acpi_button), GFP_KERNEL);
if (!button)
return -ENOMEM;
- memset(button, 0, sizeof(struct acpi_button));
button->device = device;
acpi_driver_data(device) = button;
+ button->input = input = input_allocate_device();
+ if (!input) {
+ error = -ENOMEM;
+ goto err_free_button;
+ }
+
/*
* Determine the button type (via hid), as fixed-feature buttons
* need to be handled a bit differently than generic-space.
@@ -338,39 +402,48 @@ static int acpi_button_add(struct acpi_device *device)
} else {
printk(KERN_ERR PREFIX "Unsupported hid [%s]\n",
acpi_device_hid(device));
- result = -ENODEV;
- goto end;
+ error = -ENODEV;
+ goto err_free_input;
}
- result = acpi_button_add_fs(device);
- if (result)
- goto end;
+ error = acpi_button_add_fs(device);
+ if (error)
+ goto err_free_input;
+
+ error = acpi_button_install_notify_handlers(button);
+ if (error)
+ goto err_remove_fs;
+
+ snprintf(button->phys, sizeof(button->phys),
+ "%s/button/input0", acpi_device_hid(device));
+
+ input->name = acpi_device_name(device);
+ input->phys = button->phys;
+ input->id.bustype = BUS_HOST;
+ input->id.product = button->type;
switch (button->type) {
+ case ACPI_BUTTON_TYPE_POWER:
case ACPI_BUTTON_TYPE_POWERF:
- status =
- acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
- acpi_button_notify_fixed,
- button);
+ input->evbit[0] = BIT(EV_KEY);
+ set_bit(KEY_POWER, input->keybit);
break;
+
+ case ACPI_BUTTON_TYPE_SLEEP:
case ACPI_BUTTON_TYPE_SLEEPF:
- status =
- acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
- acpi_button_notify_fixed,
- button);
+ input->evbit[0] = BIT(EV_KEY);
+ set_bit(KEY_SLEEP, input->keybit);
break;
- default:
- status = acpi_install_notify_handler(device->handle,
- ACPI_DEVICE_NOTIFY,
- acpi_button_notify,
- button);
+
+ case ACPI_BUTTON_TYPE_LID:
+ input->evbit[0] = BIT(EV_SW);
+ set_bit(SW_LID, input->swbit);
break;
}
- if (ACPI_FAILURE(status)) {
- result = -ENODEV;
- goto end;
- }
+ error = input_register_device(input);
+ if (error)
+ goto err_remove_handlers;
if (device->wakeup.flags.valid) {
/* Button's GPE is run-wake GPE */
@@ -385,47 +458,31 @@ static int acpi_button_add(struct acpi_device *device)
printk(KERN_INFO PREFIX "%s [%s]\n",
acpi_device_name(device), acpi_device_bid(device));
- end:
- if (result) {
- acpi_button_remove_fs(device);
- kfree(button);
- }
+ return 0;
- return result;
+ err_remove_handlers:
+ acpi_button_remove_notify_handlers(button);
+ err_remove_fs:
+ acpi_button_remove_fs(device);
+ err_free_input:
+ input_free_device(input);
+ err_free_button:
+ kfree(button);
+ return error;
}
static int acpi_button_remove(struct acpi_device *device, int type)
{
- acpi_status status = 0;
- struct acpi_button *button = NULL;
-
+ struct acpi_button *button;
if (!device || !acpi_driver_data(device))
return -EINVAL;
button = acpi_driver_data(device);
- /* 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);
- break;
- case ACPI_BUTTON_TYPE_SLEEPF:
- status =
- acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
- acpi_button_notify_fixed);
- break;
- default:
- status = acpi_remove_notify_handler(device->handle,
- ACPI_DEVICE_NOTIFY,
- acpi_button_notify);
- break;
- }
-
+ acpi_button_remove_notify_handlers(button);
acpi_button_remove_fs(device);
-
+ input_unregister_device(button->input);
kfree(button);
return 0;
@@ -433,8 +490,7 @@ static int acpi_button_remove(struct acpi_device *device, int type)
static int __init acpi_button_init(void)
{
- int result = 0;
-
+ int result;
acpi_button_dir = proc_mkdir(ACPI_BUTTON_CLASS, acpi_root_dir);
if (!acpi_button_dir)
@@ -451,7 +507,6 @@ static int __init acpi_button_init(void)
static void __exit acpi_button_exit(void)
{
-
acpi_bus_unregister_driver(&acpi_button_driver);
if (acpi_power_dir)
@@ -461,8 +516,6 @@ static void __exit acpi_button_exit(void)
if (acpi_lid_dir)
remove_proc_entry(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir);
remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
-
- return;
}
module_init(acpi_button_init);
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c
index 871aa520ece7..0a1863ec91f3 100644
--- a/drivers/acpi/container.c
+++ b/drivers/acpi/container.c
@@ -96,11 +96,10 @@ static int acpi_container_add(struct acpi_device *device)
return -EINVAL;
}
- container = kmalloc(sizeof(struct acpi_container), GFP_KERNEL);
+ container = kzalloc(sizeof(struct acpi_container), GFP_KERNEL);
if (!container)
return -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);
@@ -117,7 +116,7 @@ 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);
+ pc = acpi_driver_data(device);
kfree(pc);
return status;
}
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index bf5b79ed3613..90990a4b6526 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -27,6 +27,7 @@
#include <linux/init.h>
#include <linux/types.h>
#include <linux/notifier.h>
+#include <linux/platform_device.h>
#include <linux/jiffies.h>
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
@@ -39,13 +40,15 @@ MODULE_DESCRIPTION(ACPI_DOCK_DRIVER_NAME);
MODULE_LICENSE("GPL");
static struct atomic_notifier_head dock_notifier_list;
+static struct platform_device dock_device;
+static char dock_device_name[] = "dock";
struct dock_station {
acpi_handle handle;
unsigned long last_dock_time;
u32 flags;
spinlock_t dd_lock;
- spinlock_t hp_lock;
+ struct mutex hp_lock;
struct list_head dependent_devices;
struct list_head hotplug_devices;
};
@@ -115,9 +118,9 @@ static void
dock_add_hotplug_device(struct dock_station *ds,
struct dock_dependent_device *dd)
{
- spin_lock(&ds->hp_lock);
+ mutex_lock(&ds->hp_lock);
list_add_tail(&dd->hotplug_list, &ds->hotplug_devices);
- spin_unlock(&ds->hp_lock);
+ mutex_unlock(&ds->hp_lock);
}
/**
@@ -131,9 +134,9 @@ static void
dock_del_hotplug_device(struct dock_station *ds,
struct dock_dependent_device *dd)
{
- spin_lock(&ds->hp_lock);
+ mutex_lock(&ds->hp_lock);
list_del(&dd->hotplug_list);
- spin_unlock(&ds->hp_lock);
+ mutex_unlock(&ds->hp_lock);
}
/**
@@ -296,7 +299,7 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event)
{
struct dock_dependent_device *dd;
- spin_lock(&ds->hp_lock);
+ mutex_lock(&ds->hp_lock);
/*
* First call driver specific hotplug functions
@@ -318,15 +321,17 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event)
else
dock_create_acpi_device(dd->handle);
}
- spin_unlock(&ds->hp_lock);
+ mutex_unlock(&ds->hp_lock);
}
static void dock_event(struct dock_station *ds, u32 event, int num)
{
+ struct device *dev = &dock_device.dev;
/*
- * we don't do events until someone tells me that
- * they would like to have them.
+ * Indicate that the status of the dock station has
+ * changed.
*/
+ kobject_uevent(&dev->kobj, KOBJ_CHANGE);
}
/**
@@ -441,6 +446,9 @@ static int dock_in_progress(struct dock_station *ds)
*/
int register_dock_notifier(struct notifier_block *nb)
{
+ if (!dock_station)
+ return -ENODEV;
+
return atomic_notifier_chain_register(&dock_notifier_list, nb);
}
@@ -452,6 +460,9 @@ EXPORT_SYMBOL_GPL(register_dock_notifier);
*/
void unregister_dock_notifier(struct notifier_block *nb)
{
+ if (!dock_station)
+ return;
+
atomic_notifier_chain_unregister(&dock_notifier_list, nb);
}
@@ -512,6 +523,37 @@ void unregister_hotplug_dock_device(acpi_handle handle)
EXPORT_SYMBOL_GPL(unregister_hotplug_dock_device);
/**
+ * handle_eject_request - handle an undock request checking for error conditions
+ *
+ * Check to make sure the dock device is still present, then undock and
+ * hotremove all the devices that may need removing.
+ */
+static int handle_eject_request(struct dock_station *ds, u32 event)
+{
+ if (!dock_present(ds))
+ return -ENODEV;
+
+ if (dock_in_progress(ds))
+ return -EBUSY;
+
+ /*
+ * here we need to generate the undock
+ * event prior to actually doing the undock
+ * so that the device struct still exists.
+ */
+ dock_event(ds, event, UNDOCK_EVENT);
+ hotplug_dock_devices(ds, ACPI_NOTIFY_EJECT_REQUEST);
+ undock(ds);
+ eject_dock(ds);
+ if (dock_present(ds)) {
+ printk(KERN_ERR PREFIX "Unable to undock!\n");
+ return -EBUSY;
+ }
+
+ return 0;
+}
+
+/**
* dock_notify - act upon an acpi dock notification
* @handle: the dock station handle
* @event: the acpi event
@@ -519,13 +561,11 @@ EXPORT_SYMBOL_GPL(unregister_hotplug_dock_device);
*
* If we are notified to dock, then check to see if the dock is
* present and then dock. Notify all drivers of the dock event,
- * and then hotplug and devices that may need hotplugging. For undock
- * check to make sure the dock device is still present, then undock
- * and hotremove all the devices that may need removing.
+ * and then hotplug and devices that may need hotplugging.
*/
static void dock_notify(acpi_handle handle, u32 event, void *data)
{
- struct dock_station *ds = (struct dock_station *)data;
+ struct dock_station *ds = data;
switch (event) {
case ACPI_NOTIFY_BUS_CHECK:
@@ -553,19 +593,7 @@ static void dock_notify(acpi_handle handle, u32 event, void *data)
* to the driver who wish to hotplug.
*/
case ACPI_NOTIFY_EJECT_REQUEST:
- if (!dock_in_progress(ds) && dock_present(ds)) {
- /*
- * here we need to generate the undock
- * event prior to actually doing the undock
- * so that the device struct still exists.
- */
- dock_event(ds, event, UNDOCK_EVENT);
- hotplug_dock_devices(ds, ACPI_NOTIFY_EJECT_REQUEST);
- undock(ds);
- eject_dock(ds);
- if (dock_present(ds))
- printk(KERN_ERR PREFIX "Unable to undock!\n");
- }
+ handle_eject_request(ds, event);
break;
default:
printk(KERN_ERR PREFIX "Unknown dock event %d\n", event);
@@ -588,7 +616,7 @@ find_dock_devices(acpi_handle handle, u32 lvl, void *context, void **rv)
{
acpi_status status;
acpi_handle tmp;
- struct dock_station *ds = (struct dock_station *)context;
+ struct dock_station *ds = context;
struct dock_dependent_device *dd;
status = acpi_bus_get_ejd(handle, &tmp);
@@ -604,6 +632,33 @@ find_dock_devices(acpi_handle handle, u32 lvl, void *context, void **rv)
return AE_OK;
}
+/*
+ * show_docked - read method for "docked" file in sysfs
+ */
+static ssize_t show_docked(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "%d\n", dock_present(dock_station));
+
+}
+DEVICE_ATTR(docked, S_IRUGO, show_docked, NULL);
+
+/*
+ * write_undock - write method for "undock" file in sysfs
+ */
+static ssize_t write_undock(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret;
+
+ if (!count)
+ return -EINVAL;
+
+ ret = handle_eject_request(dock_station, ACPI_NOTIFY_EJECT_REQUEST);
+ return ret ? ret: count;
+}
+DEVICE_ATTR(undock, S_IWUSR, NULL, write_undock);
+
/**
* dock_add - add a new dock station
* @handle: the dock station handle
@@ -626,9 +681,33 @@ static int dock_add(acpi_handle handle)
INIT_LIST_HEAD(&dock_station->dependent_devices);
INIT_LIST_HEAD(&dock_station->hotplug_devices);
spin_lock_init(&dock_station->dd_lock);
- spin_lock_init(&dock_station->hp_lock);
+ mutex_init(&dock_station->hp_lock);
ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list);
+ /* initialize platform device stuff */
+ dock_device.name = dock_device_name;
+ ret = platform_device_register(&dock_device);
+ if (ret) {
+ printk(KERN_ERR PREFIX "Error %d registering dock device\n", ret);
+ kfree(dock_station);
+ return ret;
+ }
+ ret = device_create_file(&dock_device.dev, &dev_attr_docked);
+ if (ret) {
+ printk("Error %d adding sysfs file\n", ret);
+ platform_device_unregister(&dock_device);
+ kfree(dock_station);
+ return ret;
+ }
+ ret = device_create_file(&dock_device.dev, &dev_attr_undock);
+ if (ret) {
+ printk("Error %d adding sysfs file\n", ret);
+ device_remove_file(&dock_device.dev, &dev_attr_docked);
+ platform_device_unregister(&dock_device);
+ kfree(dock_station);
+ return ret;
+ }
+
/* Find dependent devices */
acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
ACPI_UINT32_MAX, find_dock_devices, dock_station,
@@ -638,7 +717,8 @@ static int dock_add(acpi_handle handle)
dd = alloc_dock_dependent_device(handle);
if (!dd) {
kfree(dock_station);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto dock_add_err_unregister;
}
add_dock_dependent_device(dock_station, dd);
@@ -658,8 +738,12 @@ static int dock_add(acpi_handle handle)
return 0;
dock_add_err:
- kfree(dock_station);
kfree(dd);
+dock_add_err_unregister:
+ device_remove_file(&dock_device.dev, &dev_attr_docked);
+ device_remove_file(&dock_device.dev, &dev_attr_undock);
+ platform_device_unregister(&dock_device);
+ kfree(dock_station);
return ret;
}
@@ -686,6 +770,11 @@ static int dock_remove(void)
if (ACPI_FAILURE(status))
printk(KERN_ERR "Error removing notify handler\n");
+ /* cleanup sysfs */
+ device_remove_file(&dock_device.dev, &dev_attr_docked);
+ device_remove_file(&dock_device.dev, &dev_attr_undock);
+ platform_device_unregister(&dock_device);
+
/* free dock station memory */
kfree(dock_station);
return 0;
@@ -703,7 +792,7 @@ static int dock_remove(void)
static acpi_status
find_dock(acpi_handle handle, u32 lvl, void *context, void **rv)
{
- int *count = (int *)context;
+ int *count = context;
acpi_status status = AE_OK;
if (is_dock(handle)) {
@@ -726,7 +815,7 @@ static int __init dock_init(void)
ACPI_UINT32_MAX, find_dock, &num, NULL);
if (!num)
- return -ENODEV;
+ printk(KERN_INFO "No dock devices found.\n");
return 0;
}
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index e6d4b084dca2..9c52d87d6f04 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -45,35 +45,34 @@ ACPI_MODULE_NAME("acpi_ec")
#define ACPI_EC_DRIVER_NAME "ACPI Embedded Controller Driver"
#define ACPI_EC_DEVICE_NAME "Embedded Controller"
#define ACPI_EC_FILE_INFO "info"
-
+#undef PREFIX
+#define PREFIX "ACPI: EC: "
/* EC status register */
#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 */
-
/* EC commands */
-#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
-
+enum ec_command {
+ ACPI_EC_COMMAND_READ = 0x80,
+ ACPI_EC_COMMAND_WRITE = 0x81,
+ ACPI_EC_BURST_ENABLE = 0x82,
+ ACPI_EC_BURST_DISABLE = 0x83,
+ ACPI_EC_COMMAND_QUERY = 0x84,
+};
/* EC events */
-enum {
+enum ec_event {
ACPI_EC_EVENT_OBF_1 = 1, /* Output buffer full */
- ACPI_EC_EVENT_IBF_0, /* Input buffer empty */
+ ACPI_EC_EVENT_IBF_0, /* Input buffer empty */
};
-#define ACPI_EC_DELAY 50 /* Wait 50ms max. during EC ops */
+#define ACPI_EC_DELAY 500 /* Wait 500ms 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 */
-enum {
- EC_INTR = 1, /* Output buffer full */
- EC_POLL, /* Input buffer empty */
-};
+static enum ec_mode {
+ EC_INTR = 1, /* Output buffer full */
+ EC_POLL, /* Input buffer empty */
+} acpi_ec_mode = EC_INTR;
static int acpi_ec_remove(struct acpi_device *device, int type);
static int acpi_ec_start(struct acpi_device *device);
@@ -93,22 +92,21 @@ static struct acpi_driver acpi_ec_driver = {
};
/* If we find an EC via the ECDT, we need to keep a ptr to its context */
-struct acpi_ec {
+static struct acpi_ec {
acpi_handle handle;
unsigned long uid;
- unsigned long gpe_bit;
+ unsigned long gpe;
unsigned long command_addr;
unsigned long data_addr;
unsigned long global_lock;
- struct semaphore sem;
- unsigned int expect_event;
+ struct mutex lock;
+ atomic_t query_pending;
atomic_t leaving_burst; /* 0 : No, 1 : Yes, 2: abort */
wait_queue_head_t wait;
} *ec_ecdt;
/* External interfaces use first EC only, so remember */
static struct acpi_device *first_ec;
-static int acpi_ec_mode = EC_INTR;
/* --------------------------------------------------------------------------
Transaction Management
@@ -134,54 +132,41 @@ static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data)
outb(data, ec->data_addr);
}
-static int acpi_ec_check_status(u8 status, u8 event)
+static inline int acpi_ec_check_status(struct acpi_ec *ec, enum ec_event event)
{
- switch (event) {
- case ACPI_EC_EVENT_OBF_1:
+ u8 status = acpi_ec_read_status(ec);
+
+ if (event == ACPI_EC_EVENT_OBF_1) {
if (status & ACPI_EC_FLAG_OBF)
return 1;
- break;
- case ACPI_EC_EVENT_IBF_0:
+ } else if (event == ACPI_EC_EVENT_IBF_0) {
if (!(status & ACPI_EC_FLAG_IBF))
return 1;
- break;
- default:
- break;
}
return 0;
}
-static int acpi_ec_wait(struct acpi_ec *ec, u8 event)
+static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event)
{
- int i = (acpi_ec_mode == EC_POLL) ? ACPI_EC_UDELAY_COUNT : 0;
- long time_left;
-
- ec->expect_event = event;
- if (acpi_ec_check_status(acpi_ec_read_status(ec), event)) {
- ec->expect_event = 0;
- return 0;
- }
-
- do {
- if (acpi_ec_mode == EC_POLL) {
- udelay(ACPI_EC_UDELAY);
- } else {
- time_left = wait_event_timeout(ec->wait,
- !ec->expect_event,
- msecs_to_jiffies(ACPI_EC_DELAY));
- if (time_left > 0) {
- ec->expect_event = 0;
+ if (acpi_ec_mode == EC_POLL) {
+ unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY);
+ while (time_before(jiffies, delay)) {
+ if (acpi_ec_check_status(ec, event))
return 0;
- }
}
- if (acpi_ec_check_status(acpi_ec_read_status(ec), event)) {
- ec->expect_event = 0;
+ } else {
+ if (wait_event_timeout(ec->wait,
+ acpi_ec_check_status(ec, event),
+ msecs_to_jiffies(ACPI_EC_DELAY)) ||
+ acpi_ec_check_status(ec, event)) {
return 0;
+ } else {
+ printk(KERN_ERR PREFIX "acpi_ec_wait timeout,"
+ " status = %d, expect_event = %d\n",
+ acpi_ec_read_status(ec), event);
}
- } while (--i > 0);
-
- ec->expect_event = 0;
+ }
return -ETIME;
}
@@ -196,7 +181,6 @@ int acpi_ec_enter_burst_mode(struct acpi_ec *ec)
u8 tmp = 0;
u8 status = 0;
-
status = acpi_ec_read_status(ec);
if (status != -EINVAL && !(status & ACPI_EC_FLAG_BURST)) {
status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
@@ -212,7 +196,7 @@ int acpi_ec_enter_burst_mode(struct acpi_ec *ec)
atomic_set(&ec->leaving_burst, 0);
return 0;
- end:
+ end:
ACPI_EXCEPTION((AE_INFO, status, "EC wait, burst mode"));
return -1;
}
@@ -221,58 +205,68 @@ int acpi_ec_leave_burst_mode(struct acpi_ec *ec)
{
u8 status = 0;
-
status = acpi_ec_read_status(ec);
- if (status != -EINVAL && (status & ACPI_EC_FLAG_BURST)){
+ if (status != -EINVAL && (status & ACPI_EC_FLAG_BURST)) {
status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
- if(status)
+ if (status)
goto end;
acpi_ec_write_cmd(ec, ACPI_EC_BURST_DISABLE);
acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
}
atomic_set(&ec->leaving_burst, 1);
return 0;
- end:
+ end:
ACPI_EXCEPTION((AE_INFO, status, "EC leave burst mode"));
return -1;
}
-#endif /* ACPI_FUTURE_USAGE */
+#endif /* ACPI_FUTURE_USAGE */
static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command,
- const u8 *wdata, unsigned wdata_len,
- u8 *rdata, unsigned rdata_len)
+ const u8 * wdata, unsigned wdata_len,
+ u8 * rdata, unsigned rdata_len)
{
- int result;
+ int result = 0;
acpi_ec_write_cmd(ec, command);
- for (; wdata_len > 0; wdata_len --) {
+ for (; wdata_len > 0; --wdata_len) {
result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
- if (result)
- return result;
+ if (result) {
+ printk(KERN_ERR PREFIX
+ "write_cmd timeout, command = %d\n", command);
+ goto end;
+ }
acpi_ec_write_data(ec, *(wdata++));
}
- if (command == ACPI_EC_COMMAND_WRITE) {
+ if (!rdata_len) {
result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
- if (result)
- return result;
+ if (result) {
+ printk(KERN_ERR PREFIX
+ "finish-write timeout, command = %d\n", command);
+ goto end;
+ }
+ } else if (command == ACPI_EC_COMMAND_QUERY) {
+ atomic_set(&ec->query_pending, 0);
}
- for (; rdata_len > 0; rdata_len --) {
+ for (; rdata_len > 0; --rdata_len) {
result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1);
- if (result)
- return result;
+ if (result) {
+ printk(KERN_ERR PREFIX "read timeout, command = %d\n",
+ command);
+ goto end;
+ }
*(rdata++) = acpi_ec_read_data(ec);
}
-
- return 0;
+ end:
+ return result;
}
static int acpi_ec_transaction(struct acpi_ec *ec, u8 command,
- const u8 *wdata, unsigned wdata_len,
- u8 *rdata, unsigned rdata_len)
+ const u8 * wdata, unsigned wdata_len,
+ u8 * rdata, unsigned rdata_len)
{
int status;
u32 glk;
@@ -280,36 +274,40 @@ static int acpi_ec_transaction(struct acpi_ec *ec, u8 command,
if (!ec || (wdata_len && !wdata) || (rdata_len && !rdata))
return -EINVAL;
- if (rdata)
- memset(rdata, 0, rdata_len);
+ if (rdata)
+ memset(rdata, 0, rdata_len);
+ mutex_lock(&ec->lock);
if (ec->global_lock) {
status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
if (ACPI_FAILURE(status))
return -ENODEV;
}
- down(&ec->sem);
+
+ /* Make sure GPE is enabled before doing transaction */
+ acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
if (status) {
- printk(KERN_DEBUG PREFIX "read EC, IB not empty\n");
+ printk(KERN_DEBUG PREFIX
+ "input buffer is not empty, aborting transaction\n");
goto end;
}
- status = acpi_ec_transaction_unlocked(ec, command,
- wdata, wdata_len,
- rdata, rdata_len);
+ status = acpi_ec_transaction_unlocked(ec, command,
+ wdata, wdata_len,
+ rdata, rdata_len);
-end:
- up(&ec->sem);
+ end:
if (ec->global_lock)
acpi_release_global_lock(glk);
+ mutex_unlock(&ec->lock);
return status;
}
-static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 *data)
+static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data)
{
int result;
u8 d;
@@ -322,15 +320,15 @@ static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 *data)
static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data)
{
- u8 wdata[2] = { address, data };
- return acpi_ec_transaction(ec, ACPI_EC_COMMAND_WRITE,
+ u8 wdata[2] = { address, data };
+ return acpi_ec_transaction(ec, ACPI_EC_COMMAND_WRITE,
wdata, 2, NULL, 0);
}
/*
* 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)
{
struct acpi_ec *ec;
int err;
@@ -369,9 +367,9 @@ int ec_write(u8 addr, u8 val)
EXPORT_SYMBOL(ec_write);
-extern int ec_transaction(u8 command,
- const u8 *wdata, unsigned wdata_len,
- u8 *rdata, unsigned rdata_len)
+int ec_transaction(u8 command,
+ const u8 * wdata, unsigned wdata_len,
+ u8 * rdata, unsigned rdata_len)
{
struct acpi_ec *ec;
@@ -386,65 +384,49 @@ extern int ec_transaction(u8 command,
EXPORT_SYMBOL(ec_transaction);
-static int acpi_ec_query(struct acpi_ec *ec, u8 *data)
+static int acpi_ec_query(struct acpi_ec *ec, u8 * data)
{
int result;
- u8 d;
+ u8 d;
- if (!ec || !data)
- return -EINVAL;
+ if (!ec || !data)
+ return -EINVAL;
- /*
- * 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).
- */
+ /*
+ * 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).
+ */
- result = acpi_ec_transaction(ec, ACPI_EC_COMMAND_QUERY, NULL, 0, &d, 1);
- if (result)
- return result;
+ result = acpi_ec_transaction(ec, ACPI_EC_COMMAND_QUERY, NULL, 0, &d, 1);
+ if (result)
+ return result;
- if (!d)
- return -ENODATA;
+ if (!d)
+ return -ENODATA;
- *data = d;
- return 0;
+ *data = d;
+ return 0;
}
/* --------------------------------------------------------------------------
Event Management
-------------------------------------------------------------------------- */
-struct acpi_ec_query_data {
- acpi_handle handle;
- u8 data;
-};
-
static void acpi_ec_gpe_query(void *ec_cxt)
{
struct acpi_ec *ec = (struct acpi_ec *)ec_cxt;
u8 value = 0;
- static char object_name[8];
+ char object_name[8];
- if (!ec)
- goto end;
-
- value = acpi_ec_read_status(ec);
-
- if (!(value & ACPI_EC_FLAG_SCI))
- goto end;
-
- if (acpi_ec_query(ec, &value))
- goto end;
+ if (!ec || acpi_ec_query(ec, &value))
+ return;
snprintf(object_name, 8, "_Q%2.2X", value);
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s", object_name));
+ printk(KERN_INFO PREFIX "evaluating %s\n", object_name);
acpi_evaluate_object(ec->handle, object_name, NULL, NULL);
-
- end:
- acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
}
static u32 acpi_ec_gpe_handler(void *data)
@@ -453,22 +435,18 @@ static u32 acpi_ec_gpe_handler(void *data)
u8 value;
struct acpi_ec *ec = (struct acpi_ec *)data;
- acpi_clear_gpe(NULL, ec->gpe_bit, ACPI_ISR);
- value = acpi_ec_read_status(ec);
-
if (acpi_ec_mode == EC_INTR) {
- if (acpi_ec_check_status(value, ec->expect_event)) {
- ec->expect_event = 0;
- wake_up(&ec->wait);
- }
+ wake_up(&ec->wait);
}
- if (value & ACPI_EC_FLAG_SCI) {
- status = acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query, ec);
- return status == AE_OK ?
- ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
+ value = acpi_ec_read_status(ec);
+ if ((value & ACPI_EC_FLAG_SCI) && !atomic_read(&ec->query_pending)) {
+ atomic_set(&ec->query_pending, 1);
+ status =
+ acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query,
+ ec);
}
- acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_ISR);
+
return status == AE_OK ?
ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
}
@@ -504,7 +482,6 @@ acpi_ec_space_handler(u32 function,
acpi_integer f_v = 0;
int i = 0;
-
if ((address > 0xFF) || !value || !handler_context)
return AE_BAD_PARAMETER;
@@ -518,7 +495,7 @@ acpi_ec_space_handler(u32 function,
switch (function) {
case ACPI_READ:
temp = 0;
- result = acpi_ec_read(ec, (u8) address, (u8 *) &temp);
+ result = acpi_ec_read(ec, (u8) address, (u8 *) & temp);
break;
case ACPI_WRITE:
result = acpi_ec_write(ec, (u8) address, (u8) temp);
@@ -571,18 +548,15 @@ static int acpi_ec_read_info(struct seq_file *seq, void *offset)
{
struct acpi_ec *ec = (struct acpi_ec *)seq->private;
-
if (!ec)
goto end;
- seq_printf(seq, "gpe bit: 0x%02x\n",
- (u32) ec->gpe_bit);
+ seq_printf(seq, "gpe: 0x%02x\n", (u32) ec->gpe);
seq_printf(seq, "ports: 0x%02x, 0x%02x\n",
- (u32) ec->command_addr,
- (u32) ec->data_addr);
+ (u32) ec->command_addr, (u32) ec->data_addr);
seq_printf(seq, "use global lock: %s\n",
ec->global_lock ? "yes" : "no");
- acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
+ acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
end:
return 0;
@@ -605,7 +579,6 @@ static int acpi_ec_add_fs(struct acpi_device *device)
{
struct proc_dir_entry *entry = NULL;
-
if (!acpi_device_dir(device)) {
acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
acpi_ec_dir);
@@ -648,18 +621,17 @@ static int acpi_ec_add(struct acpi_device *device)
acpi_status status = AE_OK;
struct acpi_ec *ec = NULL;
-
if (!device)
return -EINVAL;
- ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
+ ec = kzalloc(sizeof(struct acpi_ec), GFP_KERNEL);
if (!ec)
return -ENOMEM;
- memset(ec, 0, sizeof(struct acpi_ec));
ec->handle = device->handle;
ec->uid = -1;
- init_MUTEX(&ec->sem);
+ mutex_init(&ec->lock);
+ atomic_set(&ec->query_pending, 0);
if (acpi_ec_mode == EC_INTR) {
atomic_set(&ec->leaving_burst, 1);
init_waitqueue_head(&ec->wait);
@@ -669,8 +641,7 @@ static int acpi_ec_add(struct acpi_device *device)
acpi_driver_data(device) = ec;
/* Use the global lock for all EC transactions? */
- acpi_evaluate_integer(ec->handle, "_GLK", NULL,
- &ec->global_lock);
+ acpi_evaluate_integer(ec->handle, "_GLK", NULL, &ec->global_lock);
/* XXX we don't test uids, because on some boxes ecdt uid = 0, see:
http://bugzilla.kernel.org/show_bug.cgi?id=6111 */
@@ -679,7 +650,7 @@ static int acpi_ec_add(struct acpi_device *device)
ACPI_ADR_SPACE_EC,
&acpi_ec_space_handler);
- acpi_remove_gpe_handler(NULL, ec_ecdt->gpe_bit,
+ acpi_remove_gpe_handler(NULL, ec_ecdt->gpe,
&acpi_ec_gpe_handler);
kfree(ec_ecdt);
@@ -687,11 +658,10 @@ static int acpi_ec_add(struct acpi_device *device)
/* Get GPE bit assignment (EC events). */
/* TODO: Add support for _GPE returning a package */
- status =
- acpi_evaluate_integer(ec->handle, "_GPE", NULL,
- &ec->gpe_bit);
+ status = acpi_evaluate_integer(ec->handle, "_GPE", NULL, &ec->gpe);
if (ACPI_FAILURE(status)) {
- ACPI_EXCEPTION((AE_INFO, status, "Obtaining GPE bit assignment"));
+ ACPI_EXCEPTION((AE_INFO, status,
+ "Obtaining GPE bit assignment"));
result = -ENODEV;
goto end;
}
@@ -701,13 +671,13 @@ static int acpi_ec_add(struct acpi_device *device)
goto end;
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s [%s] (gpe %d) interrupt mode.",
- acpi_device_name(device), acpi_device_bid(device),
- (u32) ec->gpe_bit));
+ acpi_device_name(device), acpi_device_bid(device),
+ (u32) ec->gpe));
if (!first_ec)
first_ec = device;
- end:
+ end:
if (result)
kfree(ec);
@@ -718,7 +688,6 @@ static int acpi_ec_remove(struct acpi_device *device, int type)
{
struct acpi_ec *ec = NULL;
-
if (!device)
return -EINVAL;
@@ -761,7 +730,6 @@ static int acpi_ec_start(struct acpi_device *device)
acpi_status status = AE_OK;
struct acpi_ec *ec = NULL;
-
if (!device)
return -EINVAL;
@@ -782,27 +750,26 @@ static int acpi_ec_start(struct acpi_device *device)
}
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02lx, ports=0x%2lx,0x%2lx",
- ec->gpe_bit, ec->command_addr, ec->data_addr));
+ ec->gpe, ec->command_addr, ec->data_addr));
/*
* Install GPE handler
*/
- status = acpi_install_gpe_handler(NULL, ec->gpe_bit,
+ status = acpi_install_gpe_handler(NULL, ec->gpe,
ACPI_GPE_EDGE_TRIGGERED,
&acpi_ec_gpe_handler, ec);
if (ACPI_FAILURE(status)) {
return -ENODEV;
}
- acpi_set_gpe_type(NULL, ec->gpe_bit, ACPI_GPE_TYPE_RUNTIME);
- acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
+ acpi_set_gpe_type(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME);
+ acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
status = acpi_install_address_space_handler(ec->handle,
ACPI_ADR_SPACE_EC,
&acpi_ec_space_handler,
&acpi_ec_space_setup, ec);
if (ACPI_FAILURE(status)) {
- acpi_remove_gpe_handler(NULL, ec->gpe_bit,
- &acpi_ec_gpe_handler);
+ acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler);
return -ENODEV;
}
@@ -814,7 +781,6 @@ static int acpi_ec_stop(struct acpi_device *device, int type)
acpi_status status = AE_OK;
struct acpi_ec *ec = NULL;
-
if (!device)
return -EINVAL;
@@ -826,9 +792,7 @@ static int acpi_ec_stop(struct acpi_device *device, int type)
if (ACPI_FAILURE(status))
return -ENODEV;
- status =
- acpi_remove_gpe_handler(NULL, ec->gpe_bit,
- &acpi_ec_gpe_handler);
+ status = acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler);
if (ACPI_FAILURE(status))
return -ENODEV;
@@ -841,7 +805,7 @@ acpi_fake_ecdt_callback(acpi_handle handle,
{
acpi_status status;
- init_MUTEX(&ec_ecdt->sem);
+ mutex_init(&ec_ecdt->lock);
if (acpi_ec_mode == EC_INTR) {
init_waitqueue_head(&ec_ecdt->wait);
}
@@ -853,16 +817,15 @@ acpi_fake_ecdt_callback(acpi_handle handle,
ec_ecdt->uid = -1;
acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->uid);
- status =
- acpi_evaluate_integer(handle, "_GPE", NULL,
- &ec_ecdt->gpe_bit);
+ status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec_ecdt->gpe);
if (ACPI_FAILURE(status))
return status;
ec_ecdt->global_lock = TRUE;
ec_ecdt->handle = handle;
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "GPE=0x%02lx, ports=0x%2lx, 0x%2lx",
- ec_ecdt->gpe_bit, ec_ecdt->command_addr, ec_ecdt->data_addr));
+ ec_ecdt->gpe, ec_ecdt->command_addr,
+ ec_ecdt->data_addr));
return AE_CTRL_TERMINATE;
}
@@ -884,12 +847,11 @@ static int __init acpi_ec_fake_ecdt(void)
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Try to make an fake ECDT"));
- ec_ecdt = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
+ ec_ecdt = kzalloc(sizeof(struct acpi_ec), GFP_KERNEL);
if (!ec_ecdt) {
ret = -ENOMEM;
goto error;
}
- memset(ec_ecdt, 0, sizeof(struct acpi_ec));
status = acpi_get_devices(ACPI_EC_HID,
acpi_fake_ecdt_callback, NULL, NULL);
@@ -901,7 +863,7 @@ static int __init acpi_ec_fake_ecdt(void)
goto error;
}
return 0;
- error:
+ error:
return ret;
}
@@ -921,30 +883,28 @@ static int __init acpi_ec_get_real_ecdt(void)
/*
* Generate a temporary ec context to use until the namespace is scanned
*/
- ec_ecdt = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
+ ec_ecdt = kzalloc(sizeof(struct acpi_ec), GFP_KERNEL);
if (!ec_ecdt)
return -ENOMEM;
- memset(ec_ecdt, 0, sizeof(struct acpi_ec));
- init_MUTEX(&ec_ecdt->sem);
+ mutex_init(&ec_ecdt->lock);
if (acpi_ec_mode == EC_INTR) {
init_waitqueue_head(&ec_ecdt->wait);
}
ec_ecdt->command_addr = ecdt_ptr->ec_control.address;
ec_ecdt->data_addr = ecdt_ptr->ec_data.address;
- ec_ecdt->gpe_bit = ecdt_ptr->gpe_bit;
+ ec_ecdt->gpe = ecdt_ptr->gpe_bit;
/* use the GL just to be safe */
ec_ecdt->global_lock = TRUE;
ec_ecdt->uid = ecdt_ptr->uid;
- status =
- acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->handle);
+ status = acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->handle);
if (ACPI_FAILURE(status)) {
goto error;
}
return 0;
- error:
+ error:
ACPI_EXCEPTION((AE_INFO, status, "Could not use ECDT"));
kfree(ec_ecdt);
ec_ecdt = NULL;
@@ -970,14 +930,14 @@ int __init acpi_ec_ecdt_probe(void)
/*
* Install GPE handler
*/
- status = acpi_install_gpe_handler(NULL, ec_ecdt->gpe_bit,
+ status = acpi_install_gpe_handler(NULL, ec_ecdt->gpe,
ACPI_GPE_EDGE_TRIGGERED,
&acpi_ec_gpe_handler, ec_ecdt);
if (ACPI_FAILURE(status)) {
goto error;
}
- acpi_set_gpe_type(NULL, ec_ecdt->gpe_bit, ACPI_GPE_TYPE_RUNTIME);
- acpi_enable_gpe(NULL, ec_ecdt->gpe_bit, ACPI_NOT_ISR);
+ acpi_set_gpe_type(NULL, ec_ecdt->gpe, ACPI_GPE_TYPE_RUNTIME);
+ acpi_enable_gpe(NULL, ec_ecdt->gpe, ACPI_NOT_ISR);
status = acpi_install_address_space_handler(ACPI_ROOT_OBJECT,
ACPI_ADR_SPACE_EC,
@@ -985,7 +945,7 @@ int __init acpi_ec_ecdt_probe(void)
&acpi_ec_space_setup,
ec_ecdt);
if (ACPI_FAILURE(status)) {
- acpi_remove_gpe_handler(NULL, ec_ecdt->gpe_bit,
+ acpi_remove_gpe_handler(NULL, ec_ecdt->gpe,
&acpi_ec_gpe_handler);
goto error;
}
@@ -1004,7 +964,6 @@ static int __init acpi_ec_init(void)
{
int result = 0;
-
if (acpi_disabled)
return 0;
@@ -1057,7 +1016,8 @@ static int __init acpi_ec_set_intr_mode(char *str)
acpi_ec_mode = EC_POLL;
}
acpi_ec_driver.ops.add = acpi_ec_add;
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "EC %s mode.\n", intr ? "interrupt" : "polling"));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "EC %s mode.\n",
+ intr ? "interrupt" : "polling"));
return 1;
}
diff --git a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c
index ee2a10bf9077..bf63edc6608d 100644
--- a/drivers/acpi/events/evmisc.c
+++ b/drivers/acpi/events/evmisc.c
@@ -331,7 +331,6 @@ static void ACPI_SYSTEM_XFACE acpi_ev_global_lock_thread(void *context)
static u32 acpi_ev_global_lock_handler(void *context)
{
u8 acquired = FALSE;
- acpi_status status;
/*
* Attempt to get the lock
diff --git a/drivers/acpi/executer/exmutex.c b/drivers/acpi/executer/exmutex.c
index 3a39c2e8e104..bf90f04f2c60 100644
--- a/drivers/acpi/executer/exmutex.c
+++ b/drivers/acpi/executer/exmutex.c
@@ -266,10 +266,10 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
walk_state->thread->thread_id)
&& (obj_desc->mutex.os_mutex != ACPI_GLOBAL_LOCK)) {
ACPI_ERROR((AE_INFO,
- "Thread %X cannot release Mutex [%4.4s] acquired by thread %X",
- (u32) walk_state->thread->thread_id,
+ "Thread %lX cannot release Mutex [%4.4s] acquired by thread %lX",
+ (unsigned long)walk_state->thread->thread_id,
acpi_ut_get_node_name(obj_desc->mutex.node),
- (u32) obj_desc->mutex.owner_thread->thread_id));
+ (unsigned long)obj_desc->mutex.owner_thread->thread_id));
return_ACPI_STATUS(AE_AML_NOT_OWNER);
}
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c
index 045c89477e59..f305a826ca2d 100644
--- a/drivers/acpi/fan.c
+++ b/drivers/acpi/fan.c
@@ -99,8 +99,8 @@ 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;
+ struct seq_file *m = file->private_data;
+ struct acpi_fan *fan = m->private;
char state_string[12] = { '\0' };
@@ -186,10 +186,9 @@ static int acpi_fan_add(struct acpi_device *device)
if (!device)
return -EINVAL;
- fan = kmalloc(sizeof(struct acpi_fan), GFP_KERNEL);
+ fan = kzalloc(sizeof(struct acpi_fan), GFP_KERNEL);
if (!fan)
return -ENOMEM;
- memset(fan, 0, sizeof(struct acpi_fan));
fan->device = device;
strcpy(acpi_device_name(device), "Fan");
@@ -229,7 +228,7 @@ static int acpi_fan_remove(struct acpi_device *device, int type)
if (!device || !acpi_driver_data(device))
return -EINVAL;
- fan = (struct acpi_fan *)acpi_driver_data(device);
+ fan = acpi_driver_data(device);
acpi_fan_remove_fs(device);
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index a2f46d587d55..8a0324b43e53 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -96,7 +96,7 @@ struct acpi_find_pci_root {
static acpi_status
do_root_bridge_busnr_callback(struct acpi_resource *resource, void *data)
{
- unsigned long *busnr = (unsigned long *)data;
+ unsigned long *busnr = data;
struct acpi_resource_address64 address;
if (resource->type != ACPI_RESOURCE_TYPE_ADDRESS16 &&
@@ -189,8 +189,12 @@ find_pci_rootbridge(acpi_handle handle, u32 lvl, void *context, void **rv)
bus = tmp;
if (seg == find->seg && bus == find->bus)
+ {
find->handle = handle;
- status = AE_OK;
+ status = AE_CTRL_TERMINATE;
+ }
+ else
+ status = AE_OK;
exit:
kfree(buffer.pointer);
return status;
@@ -217,7 +221,7 @@ do_acpi_find_child(acpi_handle handle, u32 lvl, void *context, void **rv)
acpi_status status;
struct acpi_device_info *info;
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
- struct acpi_find_child *find = (struct acpi_find_child *)context;
+ struct acpi_find_child *find = context;
status = acpi_get_object_info(handle, &buffer);
if (ACPI_SUCCESS(status)) {
diff --git a/drivers/acpi/hotkey.c b/drivers/acpi/hotkey.c
index 1ba2db671865..8edfb92f7ede 100644
--- a/drivers/acpi/hotkey.c
+++ b/drivers/acpi/hotkey.c
@@ -265,8 +265,7 @@ static char *format_result(union acpi_object *object)
static int hotkey_polling_seq_show(struct seq_file *seq, void *offset)
{
- struct acpi_polling_hotkey *poll_hotkey =
- (struct acpi_polling_hotkey *)seq->private;
+ struct acpi_polling_hotkey *poll_hotkey = seq->private;
char *buf;
@@ -577,7 +576,7 @@ init_poll_hotkey_device(union acpi_hotkey *key, char **config_entry,
if (ACPI_FAILURE(status))
goto do_fail_zero;
key->poll_hotkey.poll_result =
- (union acpi_object *)kmalloc(sizeof(union acpi_object), GFP_KERNEL);
+ kmalloc(sizeof(union acpi_object), GFP_KERNEL);
if (!key->poll_hotkey.poll_result)
goto do_fail_zero;
return AE_OK;
diff --git a/drivers/acpi/i2c_ec.c b/drivers/acpi/i2c_ec.c
index 6342e612c203..8338be0990bc 100644
--- a/drivers/acpi/i2c_ec.c
+++ b/drivers/acpi/i2c_ec.c
@@ -309,18 +309,16 @@ static int acpi_ec_hc_add(struct acpi_device *device)
return -EINVAL;
}
- ec_hc = kmalloc(sizeof(struct acpi_ec_hc), GFP_KERNEL);
+ ec_hc = kzalloc(sizeof(struct acpi_ec_hc), GFP_KERNEL);
if (!ec_hc) {
return -ENOMEM;
}
- memset(ec_hc, 0, sizeof(struct acpi_ec_hc));
- smbus = kmalloc(sizeof(struct acpi_ec_smbus), GFP_KERNEL);
+ smbus = kzalloc(sizeof(struct acpi_ec_smbus), GFP_KERNEL);
if (!smbus) {
kfree(ec_hc);
return -ENOMEM;
}
- memset(smbus, 0, sizeof(struct acpi_ec_smbus));
ec_hc->handle = device->handle;
strcpy(acpi_device_name(device), ACPI_EC_HC_DEVICE_NAME);
@@ -393,7 +391,7 @@ static void __exit acpi_ec_hc_exit(void)
struct acpi_ec_hc *acpi_get_ec_hc(struct acpi_device *device)
{
- return ((struct acpi_ec_hc *)acpi_driver_data(device->parent));
+ return acpi_driver_data(device->parent);
}
EXPORT_SYMBOL(acpi_get_ec_hc);
diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
index 003a9876c968..b72d13d11a27 100644
--- a/drivers/acpi/ibm_acpi.c
+++ b/drivers/acpi/ibm_acpi.c
@@ -3,6 +3,7 @@
*
*
* Copyright (C) 2004-2005 Borislav Deianov <borislav@users.sf.net>
+ * Copyright (C) 2006 Henrique de Moraes Holschuh <hmh@hmh.eng.br>
*
* 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,10 +20,14 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#define IBM_VERSION "0.12a"
+#define IBM_VERSION "0.13"
/*
* Changelog:
+ *
+ * 2006-11-22 0.13 new maintainer
+ * changelog now lives in git commit history, and will
+ * not be updated further in-file.
*
* 2005-08-17 0.12 fix compilation on 2.6.13-rc kernels
* 2005-03-17 0.11 support for 600e, 770x
@@ -77,9 +82,16 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
+#include <linux/string.h>
+
#include <linux/proc_fs.h>
+#include <linux/backlight.h>
#include <asm/uaccess.h>
+#include <linux/dmi.h>
+#include <linux/jiffies.h>
+#include <linux/workqueue.h>
+
#include <acpi/acpi_drivers.h>
#include <acpi/acnamesp.h>
@@ -88,7 +100,7 @@
#define IBM_FILE "ibm_acpi"
#define IBM_URL "http://ibm-acpi.sf.net/"
-MODULE_AUTHOR("Borislav Deianov");
+MODULE_AUTHOR("Borislav Deianov, Henrique de Moraes Holschuh");
MODULE_DESCRIPTION(IBM_DESC);
MODULE_VERSION(IBM_VERSION);
MODULE_LICENSE("GPL");
@@ -116,28 +128,6 @@ static acpi_handle root_handle = NULL;
static char *object##_path; \
static char *object##_paths[] = { paths }
-/*
- * 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 */
@@ -167,8 +157,10 @@ IBM_HANDLE(dock, root, "\\_SB.GDCK", /* X30, X31, X40 */
"\\_SB.PCI.ISA.SLCE", /* 570 */
); /* A21e,G4x,R30,R31,R32,R40,R40e,R50e */
#endif
+#ifdef CONFIG_ACPI_IBM_BAY
IBM_HANDLE(bay, root, "\\_SB.PCI.IDE.SECN.MAST", /* 570 */
"\\_SB.PCI0.IDE0.IDES.IDSM", /* 600e/x, 770e, 770x */
+ "\\_SB.PCI0.SATA.SCND.MSTR", /* T60, X60, Z60 */
"\\_SB.PCI0.IDE0.SCND.MSTR", /* all others */
); /* A21e, R30, R31 */
@@ -183,6 +175,7 @@ IBM_HANDLE(bay2, root, "\\_SB.PCI0.IDE0.PRIM.SLAV", /* A3x, R32 */
IBM_HANDLE(bay2_ej, bay2, "_EJ3", /* 600e/x, 770e, A3x */
"_EJ0", /* 770x */
); /* all others */
+#endif
/* don't list other alternatives as we install a notify handler on the 570 */
IBM_HANDLE(pci, root, "\\_SB.PCI"); /* 570 */
@@ -203,7 +196,7 @@ IBM_HANDLE(led, ec, "SLED", /* 570 */
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(fans, ec, "FANS"); /* X31, X40, X41 */
IBM_HANDLE(gfan, ec, "GFAN", /* 570 */
"\\FSPD", /* 600e/x, 770e, 770x */
@@ -216,6 +209,152 @@ IBM_HANDLE(sfan, ec, "SFAN", /* 570 */
#define IBM_HKEY_HID "IBM0068"
#define IBM_PCI_HID "PNP0A03"
+enum thermal_access_mode {
+ IBMACPI_THERMAL_NONE = 0, /* No thermal support */
+ IBMACPI_THERMAL_ACPI_TMP07, /* Use ACPI TMP0-7 */
+ IBMACPI_THERMAL_ACPI_UPDT, /* Use ACPI TMP0-7 with UPDT */
+ IBMACPI_THERMAL_TPEC_8, /* Use ACPI EC regs, 8 sensors */
+ IBMACPI_THERMAL_TPEC_16, /* Use ACPI EC regs, 16 sensors */
+};
+
+#define IBMACPI_MAX_THERMAL_SENSORS 16 /* Max thermal sensors supported */
+struct ibm_thermal_sensors_struct {
+ s32 temp[IBMACPI_MAX_THERMAL_SENSORS];
+};
+
+/*
+ * FAN ACCESS MODES
+ *
+ * IBMACPI_FAN_RD_ACPI_GFAN:
+ * ACPI GFAN method: returns fan level
+ *
+ * see IBMACPI_FAN_WR_ACPI_SFAN
+ * EC 0x2f not available if GFAN exists
+ *
+ * IBMACPI_FAN_WR_ACPI_SFAN:
+ * ACPI SFAN method: sets fan level, 0 (stop) to 7 (max)
+ *
+ * EC 0x2f might be available *for reading*, but never for writing.
+ *
+ * IBMACPI_FAN_WR_TPEC:
+ * ThinkPad EC register 0x2f (HFSP): fan control loop mode Supported
+ * on almost all ThinkPads
+ *
+ * Fan speed changes of any sort (including those caused by the
+ * disengaged mode) are usually done slowly by the firmware as the
+ * maximum ammount of fan duty cycle change per second seems to be
+ * limited.
+ *
+ * Reading is not available if GFAN exists.
+ * Writing is not available if SFAN exists.
+ *
+ * Bits
+ * 7 automatic mode engaged;
+ * (default operation mode of the ThinkPad)
+ * fan level is ignored in this mode.
+ * 6 disengage mode (takes precedence over bit 7);
+ * not available on all thinkpads. May disable
+ * the tachometer, and speeds up fan to 100% duty-cycle,
+ * which speeds it up far above the standard RPM
+ * levels. It is not impossible that it could cause
+ * hardware damage.
+ * 5-3 unused in some models. Extra bits for fan level
+ * in others, but still useless as all values above
+ * 7 map to the same speed as level 7 in these models.
+ * 2-0 fan level (0..7 usually)
+ * 0x00 = stop
+ * 0x07 = max (set when temperatures critical)
+ * Some ThinkPads may have other levels, see
+ * IBMACPI_FAN_WR_ACPI_FANS (X31/X40/X41)
+ *
+ * FIRMWARE BUG: on some models, EC 0x2f might not be initialized at
+ * boot. Apparently the EC does not intialize it, so unless ACPI DSDT
+ * does so, its initial value is meaningless (0x07).
+ *
+ * For firmware bugs, refer to:
+ * http://thinkwiki.org/wiki/Embedded_Controller_Firmware#Firmware_Issues
+ *
+ * ----
+ *
+ * ThinkPad EC register 0x84 (LSB), 0x85 (MSB):
+ * Main fan tachometer reading (in RPM)
+ *
+ * This register is present on all ThinkPads with a new-style EC, and
+ * it is known not to be present on the A21m/e, and T22, as there is
+ * something else in offset 0x84 according to the ACPI DSDT. Other
+ * ThinkPads from this same time period (and earlier) probably lack the
+ * tachometer as well.
+ *
+ * Unfortunately a lot of ThinkPads with new-style ECs but whose firwmare
+ * was never fixed by IBM to report the EC firmware version string
+ * probably support the tachometer (like the early X models), so
+ * detecting it is quite hard. We need more data to know for sure.
+ *
+ * FIRMWARE BUG: always read 0x84 first, otherwise incorrect readings
+ * might result.
+ *
+ * FIRMWARE BUG: when EC 0x2f bit 6 is set (disengaged mode), this
+ * register is not invalidated in ThinkPads that disable tachometer
+ * readings. Thus, the tachometer readings go stale.
+ *
+ * For firmware bugs, refer to:
+ * http://thinkwiki.org/wiki/Embedded_Controller_Firmware#Firmware_Issues
+ *
+ * IBMACPI_FAN_WR_ACPI_FANS:
+ * ThinkPad X31, X40, X41. Not available in the X60.
+ *
+ * FANS ACPI handle: takes three arguments: low speed, medium speed,
+ * high speed. ACPI DSDT seems to map these three speeds to levels
+ * as follows: STOP LOW LOW MED MED HIGH HIGH HIGH HIGH
+ * (this map is stored on FAN0..FAN8 as "0,1,1,2,2,3,3,3,3")
+ *
+ * The speeds are stored on handles
+ * (FANA:FAN9), (FANC:FANB), (FANE:FAND).
+ *
+ * There are three default speed sets, acessible as handles:
+ * FS1L,FS1M,FS1H; FS2L,FS2M,FS2H; FS3L,FS3M,FS3H
+ *
+ * ACPI DSDT switches which set is in use depending on various
+ * factors.
+ *
+ * IBMACPI_FAN_WR_TPEC is also available and should be used to
+ * command the fan. The X31/X40/X41 seems to have 8 fan levels,
+ * but the ACPI tables just mention level 7.
+ */
+
+enum fan_status_access_mode {
+ IBMACPI_FAN_NONE = 0, /* No fan status or control */
+ IBMACPI_FAN_RD_ACPI_GFAN, /* Use ACPI GFAN */
+ IBMACPI_FAN_RD_TPEC, /* Use ACPI EC regs 0x2f, 0x84-0x85 */
+};
+
+enum fan_control_access_mode {
+ IBMACPI_FAN_WR_NONE = 0, /* No fan control */
+ IBMACPI_FAN_WR_ACPI_SFAN, /* Use ACPI SFAN */
+ IBMACPI_FAN_WR_TPEC, /* Use ACPI EC reg 0x2f */
+ IBMACPI_FAN_WR_ACPI_FANS, /* Use ACPI FANS and EC reg 0x2f */
+};
+
+enum fan_control_commands {
+ IBMACPI_FAN_CMD_SPEED = 0x0001, /* speed command */
+ IBMACPI_FAN_CMD_LEVEL = 0x0002, /* level command */
+ IBMACPI_FAN_CMD_ENABLE = 0x0004, /* enable/disable cmd,
+ * and also watchdog cmd */
+};
+
+enum { /* Fan control constants */
+ fan_status_offset = 0x2f, /* EC register 0x2f */
+ fan_rpm_offset = 0x84, /* EC register 0x84: LSB, 0x85 MSB (RPM)
+ * 0x84 must be read before 0x85 */
+
+ IBMACPI_FAN_EC_DISENGAGED = 0x40, /* EC mode: tachometer
+ * disengaged */
+ IBMACPI_FAN_EC_AUTO = 0x80, /* EC mode: auto fan
+ * control */
+};
+
+static char *ibm_thinkpad_ec_found = NULL;
+
struct ibm_struct {
char *name;
char param[32];
@@ -243,6 +382,8 @@ struct ibm_struct {
static struct proc_dir_entry *proc_dir = NULL;
+static struct backlight_device *ibm_backlight_device = NULL;
+
#define onoff(status,bit) ((status) & (1 << (bit)) ? "on" : "off")
#define enabled(status,bit) ((status) & (1 << (bit)) ? "enabled" : "disabled")
#define strlencmp(a,b) (strncmp((a), (b), strlen(b)))
@@ -352,7 +493,7 @@ static char *next_cmd(char **cmds)
return start;
}
-static int driver_init(void)
+static int ibm_acpi_driver_init(void)
{
printk(IBM_INFO "%s v%s\n", IBM_DESC, IBM_VERSION);
printk(IBM_INFO "%s\n", IBM_URL);
@@ -581,8 +722,7 @@ static int wan_status(void)
{
int status;
- if (!wan_supported ||
- !acpi_evalf(hkey_handle, &status, "GWAN", "d"))
+ if (!wan_supported || !acpi_evalf(hkey_handle, &status, "GWAN", "d"))
status = 0;
return status;
@@ -630,12 +770,15 @@ static int wan_write(char *buf)
return 0;
}
-static int video_supported;
-static int video_orig_autosw;
+enum video_access_mode {
+ IBMACPI_VIDEO_NONE = 0,
+ IBMACPI_VIDEO_570, /* 570 */
+ IBMACPI_VIDEO_770, /* 600e/x, 770e, 770x */
+ IBMACPI_VIDEO_NEW, /* all others */
+};
-#define VIDEO_570 1
-#define VIDEO_770 2
-#define VIDEO_NEW 3
+static enum video_access_mode video_supported;
+static int video_orig_autosw;
static int video_init(void)
{
@@ -647,16 +790,16 @@ static int video_init(void)
if (!vid_handle)
/* video switching not supported on R30, R31 */
- video_supported = 0;
+ video_supported = IBMACPI_VIDEO_NONE;
else if (acpi_evalf(vid_handle, &video_orig_autosw, "SWIT", "qd"))
/* 570 */
- video_supported = VIDEO_570;
+ video_supported = IBMACPI_VIDEO_570;
else if (acpi_evalf(vid_handle, &video_orig_autosw, "^VADL", "qd"))
/* 600e/x, 770e, 770x */
- video_supported = VIDEO_770;
+ video_supported = IBMACPI_VIDEO_770;
else
/* all others */
- video_supported = VIDEO_NEW;
+ video_supported = IBMACPI_VIDEO_NEW;
return 0;
}
@@ -666,15 +809,15 @@ static int video_status(void)
int status = 0;
int i;
- if (video_supported == VIDEO_570) {
+ if (video_supported == IBMACPI_VIDEO_570) {
if (acpi_evalf(NULL, &i, "\\_SB.PHS", "dd", 0x87))
status = i & 3;
- } else if (video_supported == VIDEO_770) {
+ } else if (video_supported == IBMACPI_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) {
+ } else if (video_supported == IBMACPI_VIDEO_NEW) {
acpi_evalf(NULL, NULL, "\\VUPS", "vd", 1);
if (acpi_evalf(NULL, &i, "\\VCDC", "d"))
status |= 0x02 * i;
@@ -693,9 +836,10 @@ static int video_autosw(void)
{
int autosw = 0;
- if (video_supported == VIDEO_570)
+ if (video_supported == IBMACPI_VIDEO_570)
acpi_evalf(vid_handle, &autosw, "SWIT", "d");
- else if (video_supported == VIDEO_770 || video_supported == VIDEO_NEW)
+ else if (video_supported == IBMACPI_VIDEO_770 ||
+ video_supported == IBMACPI_VIDEO_NEW)
acpi_evalf(vid_handle, &autosw, "^VDEE", "d");
return autosw & 1;
@@ -715,12 +859,12 @@ static int video_read(char *p)
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));
- if (video_supported == VIDEO_NEW)
+ if (video_supported == IBMACPI_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)
+ if (video_supported == IBMACPI_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");
@@ -735,7 +879,7 @@ static int video_switch(void)
if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd", 1))
return -EIO;
- ret = video_supported == VIDEO_570 ?
+ ret = video_supported == IBMACPI_VIDEO_570 ?
acpi_evalf(ec_handle, NULL, "_Q16", "v") :
acpi_evalf(vid_handle, NULL, "VSWT", "v");
acpi_evalf(vid_handle, NULL, "_DOS", "vd", autosw);
@@ -745,9 +889,9 @@ static int video_switch(void)
static int video_expand(void)
{
- if (video_supported == VIDEO_570)
+ if (video_supported == IBMACPI_VIDEO_570)
return acpi_evalf(ec_handle, NULL, "_Q17", "v");
- else if (video_supported == VIDEO_770)
+ else if (video_supported == IBMACPI_VIDEO_770)
return acpi_evalf(vid_handle, NULL, "VEXP", "v");
else
return acpi_evalf(NULL, NULL, "\\VEXP", "v");
@@ -757,10 +901,10 @@ static int video_switch2(int status)
{
int ret;
- if (video_supported == VIDEO_570) {
+ if (video_supported == IBMACPI_VIDEO_570) {
ret = acpi_evalf(NULL, NULL,
"\\_SB.PHS2", "vdd", 0x8b, status | 0x80);
- } else if (video_supported == VIDEO_770) {
+ } else if (video_supported == IBMACPI_VIDEO_770) {
int autosw = video_autosw();
if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd", 1))
return -EIO;
@@ -796,10 +940,10 @@ static int video_write(char *buf)
enable |= 0x02;
} else if (strlencmp(cmd, "crt_disable") == 0) {
disable |= 0x02;
- } else if (video_supported == VIDEO_NEW &&
+ } else if (video_supported == IBMACPI_VIDEO_NEW &&
strlencmp(cmd, "dvi_enable") == 0) {
enable |= 0x08;
- } else if (video_supported == VIDEO_NEW &&
+ } else if (video_supported == IBMACPI_VIDEO_NEW &&
strlencmp(cmd, "dvi_disable") == 0) {
disable |= 0x08;
} else if (strlencmp(cmd, "auto_enable") == 0) {
@@ -898,6 +1042,7 @@ static int light_write(char *buf)
return 0;
}
+#if defined(CONFIG_ACPI_IBM_DOCK) || defined(CONFIG_ACPI_IBM_BAY)
static int _sta(acpi_handle handle)
{
int status;
@@ -907,6 +1052,7 @@ static int _sta(acpi_handle handle)
return status;
}
+#endif
#ifdef CONFIG_ACPI_IBM_DOCK
#define dock_docked() (_sta(dock_handle) & 1)
@@ -972,6 +1118,7 @@ static void dock_notify(struct ibm_struct *ibm, u32 event)
}
#endif
+#ifdef CONFIG_ACPI_IBM_BAY
static int bay_status_supported;
static int bay_status2_supported;
static int bay_eject_supported;
@@ -1047,6 +1194,7 @@ static void bay_notify(struct ibm_struct *ibm, u32 event)
{
acpi_bus_generate_event(ibm->device, event, 0);
}
+#endif
static int cmos_read(char *p)
{
@@ -1094,26 +1242,28 @@ static int cmos_write(char *buf)
return 0;
}
-static int led_supported;
-
-#define LED_570 1
-#define LED_OLD 2
-#define LED_NEW 3
+enum led_access_mode {
+ IBMACPI_LED_NONE = 0,
+ IBMACPI_LED_570, /* 570 */
+ IBMACPI_LED_OLD, /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */
+ IBMACPI_LED_NEW, /* all others */
+};
+static enum led_access_mode led_supported;
static int led_init(void)
{
if (!led_handle)
/* led not supported on R30, R31 */
- led_supported = 0;
+ led_supported = IBMACPI_LED_NONE;
else if (strlencmp(led_path, "SLED") == 0)
/* 570 */
- led_supported = LED_570;
+ led_supported = IBMACPI_LED_570;
else if (strlencmp(led_path, "SYSL") == 0)
/* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */
- led_supported = LED_OLD;
+ led_supported = IBMACPI_LED_OLD;
else
/* all others */
- led_supported = LED_NEW;
+ led_supported = IBMACPI_LED_NEW;
return 0;
}
@@ -1130,7 +1280,7 @@ static int led_read(char *p)
}
len += sprintf(p + len, "status:\t\tsupported\n");
- if (led_supported == LED_570) {
+ if (led_supported == IBMACPI_LED_570) {
/* 570 */
int i, status;
for (i = 0; i < 8; i++) {
@@ -1179,13 +1329,13 @@ static int led_write(char *buf)
} else
return -EINVAL;
- if (led_supported == LED_570) {
+ if (led_supported == IBMACPI_LED_570) {
/* 570 */
led = 1 << led;
if (!acpi_evalf(led_handle, NULL, NULL, "vdd",
led, led_sled_arg1[ind]))
return -EIO;
- } else if (led_supported == LED_OLD) {
+ } else if (led_supported == IBMACPI_LED_OLD) {
/* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20 */
led = 1 << led;
ret = ec_write(EC_HLMS, led);
@@ -1272,50 +1422,142 @@ static int acpi_ec_write(int i, u8 v)
return 1;
}
-static int thermal_tmp_supported;
-static int thermal_updt_supported;
+static enum thermal_access_mode thermal_read_mode;
static int thermal_init(void)
{
- /* temperatures not supported on 570, G4x, R30, R31, R32 */
- thermal_tmp_supported = acpi_evalf(ec_handle, NULL, "TMP7", "qv");
+ u8 t, ta1, ta2;
+ int i;
+ int acpi_tmp7 = acpi_evalf(ec_handle, NULL, "TMP7", "qv");
+
+ if (ibm_thinkpad_ec_found && experimental) {
+ /*
+ * Direct EC access mode: sensors at registers
+ * 0x78-0x7F, 0xC0-0xC7. Registers return 0x00 for
+ * non-implemented, thermal sensors return 0x80 when
+ * not available
+ */
- /* 600e/x, 770e, 770x */
- thermal_updt_supported = acpi_evalf(ec_handle, NULL, "UPDT", "qv");
+ ta1 = ta2 = 0;
+ for (i = 0; i < 8; i++) {
+ if (likely(acpi_ec_read(0x78 + i, &t))) {
+ ta1 |= t;
+ } else {
+ ta1 = 0;
+ break;
+ }
+ if (likely(acpi_ec_read(0xC0 + i, &t))) {
+ ta2 |= t;
+ } else {
+ ta1 = 0;
+ break;
+ }
+ }
+ if (ta1 == 0) {
+ /* This is sheer paranoia, but we handle it anyway */
+ if (acpi_tmp7) {
+ printk(IBM_ERR
+ "ThinkPad ACPI EC access misbehaving, "
+ "falling back to ACPI TMPx access mode\n");
+ thermal_read_mode = IBMACPI_THERMAL_ACPI_TMP07;
+ } else {
+ printk(IBM_ERR
+ "ThinkPad ACPI EC access misbehaving, "
+ "disabling thermal sensors access\n");
+ thermal_read_mode = IBMACPI_THERMAL_NONE;
+ }
+ } else {
+ thermal_read_mode =
+ (ta2 != 0) ?
+ IBMACPI_THERMAL_TPEC_16 : IBMACPI_THERMAL_TPEC_8;
+ }
+ } else if (acpi_tmp7) {
+ if (acpi_evalf(ec_handle, NULL, "UPDT", "qv")) {
+ /* 600e/x, 770e, 770x */
+ thermal_read_mode = IBMACPI_THERMAL_ACPI_UPDT;
+ } else {
+ /* Standard ACPI TMPx access, max 8 sensors */
+ thermal_read_mode = IBMACPI_THERMAL_ACPI_TMP07;
+ }
+ } else {
+ /* temperatures not supported on 570, G4x, R30, R31, R32 */
+ thermal_read_mode = IBMACPI_THERMAL_NONE;
+ }
return 0;
}
-static int thermal_read(char *p)
+static int thermal_get_sensors(struct ibm_thermal_sensors_struct *s)
{
- int len = 0;
+ int i, t;
+ s8 tmp;
+ char tmpi[] = "TMPi";
- if (!thermal_tmp_supported)
- len += sprintf(p + len, "temperatures:\tnot supported\n");
- else {
- int i, t;
- char tmpi[] = "TMPi";
- s8 tmp[8];
+ if (!s)
+ return -EINVAL;
- if (thermal_updt_supported)
- if (!acpi_evalf(ec_handle, NULL, "UPDT", "v"))
+ switch (thermal_read_mode) {
+#if IBMACPI_MAX_THERMAL_SENSORS >= 16
+ case IBMACPI_THERMAL_TPEC_16:
+ for (i = 0; i < 8; i++) {
+ if (!acpi_ec_read(0xC0 + i, &tmp))
+ return -EIO;
+ s->temp[i + 8] = tmp * 1000;
+ }
+ /* fallthrough */
+#endif
+ case IBMACPI_THERMAL_TPEC_8:
+ for (i = 0; i < 8; i++) {
+ if (!acpi_ec_read(0x78 + i, &tmp))
return -EIO;
+ s->temp[i] = tmp * 1000;
+ }
+ return (thermal_read_mode == IBMACPI_THERMAL_TPEC_16) ? 16 : 8;
+ case IBMACPI_THERMAL_ACPI_UPDT:
+ 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;
+ s->temp[i] = (t - 2732) * 100;
}
+ return 8;
- 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]);
+ case IBMACPI_THERMAL_ACPI_TMP07:
+ for (i = 0; i < 8; i++) {
+ tmpi[3] = '0' + i;
+ if (!acpi_evalf(ec_handle, &t, tmpi, "d"))
+ return -EIO;
+ s->temp[i] = t * 1000;
+ }
+ return 8;
+
+ case IBMACPI_THERMAL_NONE:
+ default:
+ return 0;
}
+}
+
+static int thermal_read(char *p)
+{
+ int len = 0;
+ int n, i;
+ struct ibm_thermal_sensors_struct t;
+
+ n = thermal_get_sensors(&t);
+ if (unlikely(n < 0))
+ return n;
+
+ len += sprintf(p + len, "temperatures:\t");
+
+ if (n > 0) {
+ for (i = 0; i < (n - 1); i++)
+ len += sprintf(p + len, "%d ", t.temp[i] / 1000);
+ len += sprintf(p + len, "%d\n", t.temp[i] / 1000);
+ } else
+ len += sprintf(p + len, "not supported\n");
return len;
}
@@ -1381,12 +1623,23 @@ static int ecdump_write(char *buf)
static int brightness_offset = 0x31;
+static int brightness_get(struct backlight_device *bd)
+{
+ u8 level;
+ if (!acpi_ec_read(brightness_offset, &level))
+ return -EIO;
+
+ level &= 0x7;
+
+ return level;
+}
+
static int brightness_read(char *p)
{
int len = 0;
- u8 level;
+ int level;
- if (!acpi_ec_read(brightness_offset, &level)) {
+ if ((level = brightness_get(NULL)) < 0) {
len += sprintf(p + len, "level:\t\tunreadable\n");
} else {
len += sprintf(p + len, "level:\t\t%d\n", level & 0x7);
@@ -1401,16 +1654,34 @@ static int brightness_read(char *p)
#define BRIGHTNESS_UP 4
#define BRIGHTNESS_DOWN 5
-static int brightness_write(char *buf)
+static int brightness_set(int value)
{
int cmos_cmd, inc, i;
- u8 level;
+ int current_value = brightness_get(NULL);
+
+ value &= 7;
+
+ cmos_cmd = value > current_value ? BRIGHTNESS_UP : BRIGHTNESS_DOWN;
+ inc = value > current_value ? 1 : -1;
+ for (i = current_value; i != value; i += inc) {
+ if (!cmos_eval(cmos_cmd))
+ return -EIO;
+ if (!acpi_ec_write(brightness_offset, i + inc))
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int brightness_write(char *buf)
+{
+ int level;
int new_level;
char *cmd;
while ((cmd = next_cmd(&buf))) {
- if (!acpi_ec_read(brightness_offset, &level))
- return -EIO;
+ if ((level = brightness_get(NULL)) < 0)
+ return level;
level &= 7;
if (strlencmp(cmd, "up") == 0) {
@@ -1423,19 +1694,44 @@ static int brightness_write(char *buf)
} 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;
- }
+ brightness_set(new_level);
}
return 0;
}
+static int brightness_update_status(struct backlight_device *bd)
+{
+ return brightness_set(bd->props->brightness);
+}
+
+static struct backlight_properties ibm_backlight_data = {
+ .owner = THIS_MODULE,
+ .get_brightness = brightness_get,
+ .update_status = brightness_update_status,
+ .max_brightness = 7,
+};
+
+static int brightness_init(void)
+{
+ ibm_backlight_device = backlight_device_register("ibm", NULL, NULL,
+ &ibm_backlight_data);
+ if (IS_ERR(ibm_backlight_device)) {
+ printk(IBM_ERR "Could not register backlight device\n");
+ return PTR_ERR(ibm_backlight_device);
+ }
+
+ return 0;
+}
+
+static void brightness_exit(void)
+{
+ if (ibm_backlight_device) {
+ backlight_device_unregister(ibm_backlight_device);
+ ibm_backlight_device = NULL;
+ }
+}
+
static int volume_offset = 0x30;
static int volume_read(char *p)
@@ -1522,90 +1818,486 @@ static int volume_write(char *buf)
return 0;
}
-static int fan_status_offset = 0x2f;
-static int fan_rpm_offset = 0x84;
+static enum fan_status_access_mode fan_status_access_mode;
+static enum fan_control_access_mode fan_control_access_mode;
+static enum fan_control_commands fan_control_commands;
-static int fan_read(char *p)
+static int fan_control_status_known;
+static u8 fan_control_initial_status;
+
+static void fan_watchdog_fire(struct work_struct *ignored);
+static int fan_watchdog_maxinterval;
+static DECLARE_DELAYED_WORK(fan_watchdog_task, fan_watchdog_fire);
+
+static int fan_init(void)
{
- int len = 0;
- int s;
- u8 lo, hi, status;
+ fan_status_access_mode = IBMACPI_FAN_NONE;
+ fan_control_access_mode = IBMACPI_FAN_WR_NONE;
+ fan_control_commands = 0;
+ fan_control_status_known = 1;
+ fan_watchdog_maxinterval = 0;
if (gfan_handle) {
/* 570, 600e/x, 770e, 770x */
- if (!acpi_evalf(gfan_handle, &s, NULL, "d"))
- return -EIO;
+ fan_status_access_mode = IBMACPI_FAN_RD_ACPI_GFAN;
+ } else {
+ /* all other ThinkPads: note that even old-style
+ * ThinkPad ECs supports the fan control register */
+ if (likely(acpi_ec_read(fan_status_offset,
+ &fan_control_initial_status))) {
+ fan_status_access_mode = IBMACPI_FAN_RD_TPEC;
+
+ /* In some ThinkPads, neither the EC nor the ACPI
+ * DSDT initialize the fan status, and it ends up
+ * being set to 0x07 when it *could* be either
+ * 0x07 or 0x80.
+ *
+ * Enable for TP-1Y (T43), TP-78 (R51e),
+ * TP-76 (R52), TP-70 (T43, R52), which are known
+ * to be buggy. */
+ if (fan_control_initial_status == 0x07 &&
+ ibm_thinkpad_ec_found &&
+ ((ibm_thinkpad_ec_found[0] == '1' &&
+ ibm_thinkpad_ec_found[1] == 'Y') ||
+ (ibm_thinkpad_ec_found[0] == '7' &&
+ (ibm_thinkpad_ec_found[1] == '6' ||
+ ibm_thinkpad_ec_found[1] == '8' ||
+ ibm_thinkpad_ec_found[1] == '0'))
+ )) {
+ printk(IBM_NOTICE
+ "fan_init: initial fan status is "
+ "unknown, assuming it is in auto "
+ "mode\n");
+ fan_control_status_known = 0;
+ }
+ } else {
+ printk(IBM_ERR
+ "ThinkPad ACPI EC access misbehaving, "
+ "fan status and control unavailable\n");
+ return 0;
+ }
+ }
- len += sprintf(p + len, "level:\t\t%d\n", s);
+ if (sfan_handle) {
+ /* 570, 770x-JL */
+ fan_control_access_mode = IBMACPI_FAN_WR_ACPI_SFAN;
+ fan_control_commands |=
+ IBMACPI_FAN_CMD_LEVEL | IBMACPI_FAN_CMD_ENABLE;
} else {
+ if (!gfan_handle) {
+ /* gfan without sfan means no fan control */
+ /* all other models implement TP EC 0x2f control */
+
+ if (fans_handle) {
+ /* X31, X40, X41 */
+ fan_control_access_mode =
+ IBMACPI_FAN_WR_ACPI_FANS;
+ fan_control_commands |=
+ IBMACPI_FAN_CMD_SPEED |
+ IBMACPI_FAN_CMD_LEVEL |
+ IBMACPI_FAN_CMD_ENABLE;
+ } else {
+ fan_control_access_mode = IBMACPI_FAN_WR_TPEC;
+ fan_control_commands |=
+ IBMACPI_FAN_CMD_LEVEL |
+ IBMACPI_FAN_CMD_ENABLE;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int fan_get_status(u8 *status)
+{
+ u8 s;
+
+ /* TODO:
+ * Add IBMACPI_FAN_RD_ACPI_FANS ? */
+
+ switch (fan_status_access_mode) {
+ case IBMACPI_FAN_RD_ACPI_GFAN:
+ /* 570, 600e/x, 770e, 770x */
+
+ if (unlikely(!acpi_evalf(gfan_handle, &s, NULL, "d")))
+ return -EIO;
+
+ if (likely(status))
+ *status = s & 0x07;
+
+ break;
+
+ case IBMACPI_FAN_RD_TPEC:
/* 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 (unlikely(!acpi_ec_read(fan_status_offset, &s)))
+ return -EIO;
- 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 (likely(status))
+ *status = s;
+
+ break;
+
+ default:
+ return -ENXIO;
}
- if (sfan_handle)
- /* 570, 770x-JL */
- len += sprintf(p + len, "commands:\tlevel <level>"
- " (<level> is 0-7)\n");
- if (!gfan_handle)
+ return 0;
+}
+
+static int fan_get_speed(unsigned int *speed)
+{
+ u8 hi, lo;
+
+ switch (fan_status_access_mode) {
+ case IBMACPI_FAN_RD_TPEC:
/* all except 570, 600e/x, 770e, 770x */
- len += sprintf(p + len, "commands:\tenable, disable\n");
- if (fans_handle)
- /* X31, X40 */
+ if (unlikely(!acpi_ec_read(fan_rpm_offset, &lo) ||
+ !acpi_ec_read(fan_rpm_offset + 1, &hi)))
+ return -EIO;
+
+ if (likely(speed))
+ *speed = (hi << 8) | lo;
+
+ break;
+
+ default:
+ return -ENXIO;
+ }
+
+ return 0;
+}
+
+static void fan_exit(void)
+{
+ cancel_delayed_work(&fan_watchdog_task);
+ flush_scheduled_work();
+}
+
+static void fan_watchdog_reset(void)
+{
+ static int fan_watchdog_active = 0;
+
+ if (fan_watchdog_active)
+ cancel_delayed_work(&fan_watchdog_task);
+
+ if (fan_watchdog_maxinterval > 0) {
+ fan_watchdog_active = 1;
+ if (!schedule_delayed_work(&fan_watchdog_task,
+ msecs_to_jiffies(fan_watchdog_maxinterval
+ * 1000))) {
+ printk(IBM_ERR "failed to schedule the fan watchdog, "
+ "watchdog will not trigger\n");
+ }
+ } else
+ fan_watchdog_active = 0;
+}
+
+static int fan_read(char *p)
+{
+ int len = 0;
+ int rc;
+ u8 status;
+ unsigned int speed = 0;
+
+ switch (fan_status_access_mode) {
+ case IBMACPI_FAN_RD_ACPI_GFAN:
+ /* 570, 600e/x, 770e, 770x */
+ if ((rc = fan_get_status(&status)) < 0)
+ return rc;
+
+ len += sprintf(p + len, "status:\t\t%s\n"
+ "level:\t\t%d\n",
+ (status != 0) ? "enabled" : "disabled", status);
+ break;
+
+ case IBMACPI_FAN_RD_TPEC:
+ /* all except 570, 600e/x, 770e, 770x */
+ if ((rc = fan_get_status(&status)) < 0)
+ return rc;
+
+ if (unlikely(!fan_control_status_known)) {
+ if (status != fan_control_initial_status)
+ fan_control_status_known = 1;
+ else
+ /* Return most likely status. In fact, it
+ * might be the only possible status */
+ status = IBMACPI_FAN_EC_AUTO;
+ }
+
+ len += sprintf(p + len, "status:\t\t%s\n",
+ (status != 0) ? "enabled" : "disabled");
+
+ /* No ThinkPad boots on disengaged mode, we can safely
+ * assume the tachometer is online if fan control status
+ * was unknown */
+ if ((rc = fan_get_speed(&speed)) < 0)
+ return rc;
+
+ len += sprintf(p + len, "speed:\t\t%d\n", speed);
+
+ if (status & IBMACPI_FAN_EC_DISENGAGED)
+ /* Disengaged mode takes precedence */
+ len += sprintf(p + len, "level:\t\tdisengaged\n");
+ else if (status & IBMACPI_FAN_EC_AUTO)
+ len += sprintf(p + len, "level:\t\tauto\n");
+ else
+ len += sprintf(p + len, "level:\t\t%d\n", status);
+ break;
+
+ case IBMACPI_FAN_NONE:
+ default:
+ len += sprintf(p + len, "status:\t\tnot supported\n");
+ }
+
+ if (fan_control_commands & IBMACPI_FAN_CMD_LEVEL) {
+ len += sprintf(p + len, "commands:\tlevel <level>");
+
+ switch (fan_control_access_mode) {
+ case IBMACPI_FAN_WR_ACPI_SFAN:
+ len += sprintf(p + len, " (<level> is 0-7)\n");
+ break;
+
+ default:
+ len += sprintf(p + len, " (<level> is 0-7, "
+ "auto, disengaged)\n");
+ break;
+ }
+ }
+
+ if (fan_control_commands & IBMACPI_FAN_CMD_ENABLE)
+ len += sprintf(p + len, "commands:\tenable, disable\n"
+ "commands:\twatchdog <timeout> (<timeout> is 0 (off), "
+ "1-120 (seconds))\n");
+
+ if (fan_control_commands & IBMACPI_FAN_CMD_SPEED)
len += sprintf(p + len, "commands:\tspeed <speed>"
" (<speed> is 0-65535)\n");
return len;
}
-static int fan_write(char *buf)
+static int fan_set_level(int level)
{
- 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 */
+ switch (fan_control_access_mode) {
+ case IBMACPI_FAN_WR_ACPI_SFAN:
+ if (level >= 0 && level <= 7) {
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 */
+ } else
+ return -EINVAL;
+ break;
+
+ case IBMACPI_FAN_WR_ACPI_FANS:
+ case IBMACPI_FAN_WR_TPEC:
+ if ((level != IBMACPI_FAN_EC_AUTO) &&
+ (level != IBMACPI_FAN_EC_DISENGAGED) &&
+ ((level < 0) || (level > 7)))
+ return -EINVAL;
+
+ if (!acpi_ec_write(fan_status_offset, level))
+ return -EIO;
+ else
+ fan_control_status_known = 1;
+ break;
+
+ default:
+ return -ENXIO;
+ }
+ return 0;
+}
+
+static int fan_set_enable(void)
+{
+ u8 s;
+ int rc;
+
+ switch (fan_control_access_mode) {
+ case IBMACPI_FAN_WR_ACPI_FANS:
+ case IBMACPI_FAN_WR_TPEC:
+ if ((rc = fan_get_status(&s)) < 0)
+ return rc;
+
+ /* Don't go out of emergency fan mode */
+ if (s != 7)
+ s = IBMACPI_FAN_EC_AUTO;
+
+ if (!acpi_ec_write(fan_status_offset, s))
+ return -EIO;
+ else
+ fan_control_status_known = 1;
+ break;
+
+ case IBMACPI_FAN_WR_ACPI_SFAN:
+ if ((rc = fan_get_status(&s)) < 0)
+ return rc;
+
+ s &= 0x07;
+
+ /* Set fan to at least level 4 */
+ if (s < 4)
+ s = 4;
+
+ if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", s))
+ return -EIO;
+ break;
+
+ default:
+ return -ENXIO;
+ }
+ return 0;
+}
+
+static int fan_set_disable(void)
+{
+ switch (fan_control_access_mode) {
+ case IBMACPI_FAN_WR_ACPI_FANS:
+ case IBMACPI_FAN_WR_TPEC:
+ if (!acpi_ec_write(fan_status_offset, 0x00))
+ return -EIO;
+ else
+ fan_control_status_known = 1;
+ break;
+
+ case IBMACPI_FAN_WR_ACPI_SFAN:
+ if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", 0x00))
+ return -EIO;
+ break;
+
+ default:
+ return -ENXIO;
+ }
+ return 0;
+}
+
+static int fan_set_speed(int speed)
+{
+ switch (fan_control_access_mode) {
+ case IBMACPI_FAN_WR_ACPI_FANS:
+ if (speed >= 0 && speed <= 65535) {
if (!acpi_evalf(fans_handle, NULL, NULL, "vddd",
speed, speed, speed))
return -EIO;
} else
return -EINVAL;
- }
+ break;
+ default:
+ return -ENXIO;
+ }
return 0;
}
+static int fan_write_cmd_level(const char *cmd, int *rc)
+{
+ int level;
+
+ if (strlencmp(cmd, "level auto") == 0)
+ level = IBMACPI_FAN_EC_AUTO;
+ else if (strlencmp(cmd, "level disengaged") == 0)
+ level = IBMACPI_FAN_EC_DISENGAGED;
+ else if (sscanf(cmd, "level %d", &level) != 1)
+ return 0;
+
+ if ((*rc = fan_set_level(level)) == -ENXIO)
+ printk(IBM_ERR "level command accepted for unsupported "
+ "access mode %d", fan_control_access_mode);
+
+ return 1;
+}
+
+static int fan_write_cmd_enable(const char *cmd, int *rc)
+{
+ if (strlencmp(cmd, "enable") != 0)
+ return 0;
+
+ if ((*rc = fan_set_enable()) == -ENXIO)
+ printk(IBM_ERR "enable command accepted for unsupported "
+ "access mode %d", fan_control_access_mode);
+
+ return 1;
+}
+
+static int fan_write_cmd_disable(const char *cmd, int *rc)
+{
+ if (strlencmp(cmd, "disable") != 0)
+ return 0;
+
+ if ((*rc = fan_set_disable()) == -ENXIO)
+ printk(IBM_ERR "disable command accepted for unsupported "
+ "access mode %d", fan_control_access_mode);
+
+ return 1;
+}
+
+static int fan_write_cmd_speed(const char *cmd, int *rc)
+{
+ int speed;
+
+ /* TODO:
+ * Support speed <low> <medium> <high> ? */
+
+ if (sscanf(cmd, "speed %d", &speed) != 1)
+ return 0;
+
+ if ((*rc = fan_set_speed(speed)) == -ENXIO)
+ printk(IBM_ERR "speed command accepted for unsupported "
+ "access mode %d", fan_control_access_mode);
+
+ return 1;
+}
+
+static int fan_write_cmd_watchdog(const char *cmd, int *rc)
+{
+ int interval;
+
+ if (sscanf(cmd, "watchdog %d", &interval) != 1)
+ return 0;
+
+ if (interval < 0 || interval > 120)
+ *rc = -EINVAL;
+ else
+ fan_watchdog_maxinterval = interval;
+
+ return 1;
+}
+
+static int fan_write(char *buf)
+{
+ char *cmd;
+ int rc = 0;
+
+ while (!rc && (cmd = next_cmd(&buf))) {
+ if (!((fan_control_commands & IBMACPI_FAN_CMD_LEVEL) &&
+ fan_write_cmd_level(cmd, &rc)) &&
+ !((fan_control_commands & IBMACPI_FAN_CMD_ENABLE) &&
+ (fan_write_cmd_enable(cmd, &rc) ||
+ fan_write_cmd_disable(cmd, &rc) ||
+ fan_write_cmd_watchdog(cmd, &rc))) &&
+ !((fan_control_commands & IBMACPI_FAN_CMD_SPEED) &&
+ fan_write_cmd_speed(cmd, &rc))
+ )
+ rc = -EINVAL;
+ else if (!rc)
+ fan_watchdog_reset();
+ }
+
+ return rc;
+}
+
+static void fan_watchdog_fire(struct work_struct *ignored)
+{
+ printk(IBM_NOTICE "fan watchdog: enabling fan\n");
+ if (fan_set_enable()) {
+ printk(IBM_ERR "fan watchdog: error while enabling fan\n");
+ /* reschedule for later */
+ fan_watchdog_reset();
+ }
+}
+
static struct ibm_struct ibms[] = {
{
.name = "driver",
- .init = driver_init,
+ .init = ibm_acpi_driver_init,
.read = driver_read,
},
{
@@ -1662,6 +2354,7 @@ static struct ibm_struct ibms[] = {
.type = ACPI_SYSTEM_NOTIFY,
},
#endif
+#ifdef CONFIG_ACPI_IBM_BAY
{
.name = "bay",
.init = bay_init,
@@ -1671,6 +2364,7 @@ static struct ibm_struct ibms[] = {
.handle = &bay_handle,
.type = ACPI_SYSTEM_NOTIFY,
},
+#endif
{
.name = "cmos",
.read = cmos_read,
@@ -1702,6 +2396,8 @@ static struct ibm_struct ibms[] = {
.name = "brightness",
.read = brightness_read,
.write = brightness_write,
+ .init = brightness_init,
+ .exit = brightness_exit,
},
{
.name = "volume",
@@ -1712,6 +2408,8 @@ static struct ibm_struct ibms[] = {
.name = "fan",
.read = fan_read,
.write = fan_write,
+ .init = fan_init,
+ .exit = fan_exit,
.experimental = 1,
},
};
@@ -1719,7 +2417,7 @@ static struct ibm_struct ibms[] = {
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;
+ struct ibm_struct *ibm = data;
int len;
if (!ibm || !ibm->read)
@@ -1744,7 +2442,7 @@ static int dispatch_read(char *page, char **start, off_t off, int count,
static int dispatch_write(struct file *file, const char __user * userbuf,
unsigned long count, void *data)
{
- struct ibm_struct *ibm = (struct ibm_struct *)data;
+ struct ibm_struct *ibm = data;
char *kernbuf;
int ret;
@@ -1773,7 +2471,7 @@ static int dispatch_write(struct file *file, const char __user * userbuf,
static void dispatch_notify(acpi_handle handle, u32 event, void *data)
{
- struct ibm_struct *ibm = (struct ibm_struct *)data;
+ struct ibm_struct *ibm = data;
if (!ibm || !ibm->notify)
return;
@@ -1805,7 +2503,7 @@ static int __init setup_notify(struct ibm_struct *ibm)
ibm->name, status);
return -ENODEV;
}
-
+ ibm->notify_installed = 1;
return 0;
}
@@ -1818,14 +2516,13 @@ static int __init register_driver(struct ibm_struct *ibm)
{
int ret;
- ibm->driver = kmalloc(sizeof(struct acpi_driver), GFP_KERNEL);
+ ibm->driver = kzalloc(sizeof(struct acpi_driver), GFP_KERNEL);
if (!ibm->driver) {
printk(IBM_ERR "kmalloc(ibm->driver) failed\n");
return -1;
}
- memset(ibm->driver, 0, sizeof(struct acpi_driver));
- sprintf(ibm->driver->name, "%s/%s", IBM_NAME, ibm->name);
+ sprintf(ibm->driver->name, "%s_%s", IBM_NAME, ibm->name);
ibm->driver->ids = ibm->hid;
ibm->driver->ops.add = &ibm_device_add;
@@ -1882,7 +2579,6 @@ static int __init ibm_init(struct ibm_struct *ibm)
ret = setup_notify(ibm);
if (ret < 0)
return ret;
- ibm->notify_installed = 1;
}
return 0;
@@ -1954,7 +2650,9 @@ IBM_PARAM(light);
#ifdef CONFIG_ACPI_IBM_DOCK
IBM_PARAM(dock);
#endif
+#ifdef CONFIG_ACPI_IBM_BAY
IBM_PARAM(bay);
+#endif
IBM_PARAM(cmos);
IBM_PARAM(led);
IBM_PARAM(beep);
@@ -1971,6 +2669,33 @@ static void acpi_ibm_exit(void)
ibm_exit(&ibms[i]);
remove_proc_entry(IBM_DIR, acpi_root_dir);
+
+ if (ibm_thinkpad_ec_found)
+ kfree(ibm_thinkpad_ec_found);
+}
+
+static char* __init check_dmi_for_ec(void)
+{
+ struct dmi_device *dev = NULL;
+ char ec_fw_string[18];
+
+ /*
+ * ThinkPad T23 or newer, A31 or newer, R50e or newer,
+ * X32 or newer, all Z series; Some models must have an
+ * up-to-date BIOS or they will not be detected.
+ *
+ * See http://thinkwiki.org/wiki/List_of_DMI_IDs
+ */
+ while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) {
+ if (sscanf(dev->name,
+ "IBM ThinkPad Embedded Controller -[%17c",
+ ec_fw_string) == 1) {
+ ec_fw_string[sizeof(ec_fw_string) - 1] = 0;
+ ec_fw_string[strcspn(ec_fw_string, " ]")] = 0;
+ return kstrdup(ec_fw_string, GFP_KERNEL);
+ }
+ }
+ return NULL;
}
static int __init acpi_ibm_init(void)
@@ -1992,6 +2717,12 @@ static int __init acpi_ibm_init(void)
return -ENODEV;
}
+ /* Models with newer firmware report the EC in DMI */
+ ibm_thinkpad_ec_found = check_dmi_for_ec();
+ if (ibm_thinkpad_ec_found)
+ printk(IBM_INFO "ThinkPad EC firmware %s\n",
+ ibm_thinkpad_ec_found);
+
/* these handles are not required */
IBM_HANDLE_INIT(vid);
IBM_HANDLE_INIT(vid2);
@@ -2004,12 +2735,14 @@ static int __init acpi_ibm_init(void)
IBM_HANDLE_INIT(dock);
#endif
IBM_HANDLE_INIT(pci);
+#ifdef CONFIG_ACPI_IBM_BAY
IBM_HANDLE_INIT(bay);
if (bay_handle)
IBM_HANDLE_INIT(bay_ej);
IBM_HANDLE_INIT(bay2);
if (bay2_handle)
IBM_HANDLE_INIT(bay2_ej);
+#endif
IBM_HANDLE_INIT(beep);
IBM_HANDLE_INIT(ecrd);
IBM_HANDLE_INIT(ecwr);
diff --git a/drivers/acpi/namespace/nsxfobj.c b/drivers/acpi/namespace/nsxfobj.c
index a163e1d3708d..a18b1c223129 100644
--- a/drivers/acpi/namespace/nsxfobj.c
+++ b/drivers/acpi/namespace/nsxfobj.c
@@ -50,6 +50,50 @@ ACPI_MODULE_NAME("nsxfobj")
/*******************************************************************************
*
+ * FUNCTION: acpi_get_id
+ *
+ * PARAMETERS: Handle - Handle of object whose id is desired
+ * ret_id - Where the id will be placed
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: This routine returns the owner id associated with a handle
+ *
+ ******************************************************************************/
+acpi_status acpi_get_id(acpi_handle handle, acpi_owner_id * ret_id)
+{
+ struct acpi_namespace_node *node;
+ acpi_status status;
+
+ /* Parameter Validation */
+
+ if (!ret_id) {
+ return (AE_BAD_PARAMETER);
+ }
+
+ 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);
+ if (!node) {
+ (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+ return (AE_BAD_PARAMETER);
+ }
+
+ *ret_id = node->owner_id;
+
+ status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+ return (status);
+}
+
+ACPI_EXPORT_SYMBOL(acpi_get_id)
+
+/*******************************************************************************
+ *
* FUNCTION: acpi_get_type
*
* PARAMETERS: Handle - Handle of object whose type is desired
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c
index e5e448edca41..bd96a7045925 100644
--- a/drivers/acpi/numa.c
+++ b/drivers/acpi/numa.c
@@ -248,7 +248,7 @@ int acpi_get_pxm(acpi_handle h)
handle = phandle;
status = acpi_evaluate_integer(handle, "_PXM", NULL, &pxm);
if (ACPI_SUCCESS(status))
- return (int)pxm;
+ return pxm;
status = acpi_get_parent(handle, &phandle);
} while (ACPI_SUCCESS(status));
return -1;
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 02b30ae6a68e..57ae1e5cde0a 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -568,6 +568,7 @@ void acpi_os_derive_pci_id(acpi_handle rhandle, /* upper bound */
static void acpi_os_execute_deferred(struct work_struct *work)
{
struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work);
+
if (!dpc) {
printk(KERN_ERR PREFIX "Invalid (NULL) context\n");
return;
@@ -1031,7 +1032,7 @@ 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);
- if (cache == NULL)
+ if (*cache == NULL)
return AE_ERROR;
else
return AE_OK;
@@ -1051,7 +1052,7 @@ acpi_os_create_cache(char *name, u16 size, u16 depth, acpi_cache_t ** cache)
acpi_status acpi_os_purge_cache(acpi_cache_t * cache)
{
- (void)kmem_cache_shrink(cache);
+ kmem_cache_shrink(cache);
return (AE_OK);
}
diff --git a/drivers/acpi/pci_bind.c b/drivers/acpi/pci_bind.c
index 1e2ae6e7a7e4..55f57a61c55e 100644
--- a/drivers/acpi/pci_bind.c
+++ b/drivers/acpi/pci_bind.c
@@ -122,19 +122,17 @@ int acpi_pci_bind(struct acpi_device *device)
if (!device || !device->parent)
return -EINVAL;
- pathname = kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
+ pathname = kzalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
if (!pathname)
return -ENOMEM;
- memset(pathname, 0, ACPI_PATHNAME_MAX);
buffer.length = ACPI_PATHNAME_MAX;
buffer.pointer = pathname;
- data = kmalloc(sizeof(struct acpi_pci_data), GFP_KERNEL);
+ data = kzalloc(sizeof(struct acpi_pci_data), GFP_KERNEL);
if (!data) {
kfree(pathname);
return -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",
@@ -281,10 +279,9 @@ int acpi_pci_unbind(struct acpi_device *device)
if (!device || !device->parent)
return -EINVAL;
- pathname = (char *)kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
+ pathname = kzalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
if (!pathname)
return -ENOMEM;
- memset(pathname, 0, ACPI_PATHNAME_MAX);
buffer.length = ACPI_PATHNAME_MAX;
buffer.pointer = pathname;
@@ -331,11 +328,9 @@ acpi_pci_bind_root(struct acpi_device *device,
char *pathname = NULL;
struct acpi_buffer buffer = { 0, NULL };
-
- pathname = (char *)kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
+ pathname = kzalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
if (!pathname)
return -ENOMEM;
- memset(pathname, 0, ACPI_PATHNAME_MAX);
buffer.length = ACPI_PATHNAME_MAX;
buffer.pointer = pathname;
@@ -345,12 +340,11 @@ acpi_pci_bind_root(struct acpi_device *device,
return -EINVAL;
}
- data = kmalloc(sizeof(struct acpi_pci_data), GFP_KERNEL);
+ data = kzalloc(sizeof(struct acpi_pci_data), GFP_KERNEL);
if (!data) {
kfree(pathname);
return -ENOMEM;
}
- memset(data, 0, sizeof(struct acpi_pci_data));
data->id = *id;
data->bus = bus;
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
index feda0341f5a7..fe7d007833ad 100644
--- a/drivers/acpi/pci_irq.c
+++ b/drivers/acpi/pci_irq.c
@@ -89,10 +89,9 @@ acpi_pci_irq_add_entry(acpi_handle handle,
if (!prt)
return -EINVAL;
- entry = kmalloc(sizeof(struct acpi_prt_entry), GFP_KERNEL);
+ entry = kzalloc(sizeof(struct acpi_prt_entry), GFP_KERNEL);
if (!entry)
return -ENOMEM;
- memset(entry, 0, sizeof(struct acpi_prt_entry));
entry->id.segment = segment;
entry->id.bus = bus;
@@ -161,10 +160,9 @@ int acpi_pci_irq_add_prt(acpi_handle handle, int segment, int bus)
static int first_time = 1;
- pathname = (char *)kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
+ pathname = kzalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
if (!pathname)
return -ENOMEM;
- memset(pathname, 0, ACPI_PATHNAME_MAX);
if (first_time) {
acpi_prt.count = 0;
@@ -198,11 +196,10 @@ int acpi_pci_irq_add_prt(acpi_handle handle, int segment, int bus)
return -ENODEV;
}
- prt = kmalloc(buffer.length, GFP_KERNEL);
+ prt = kzalloc(buffer.length, GFP_KERNEL);
if (!prt) {
return -ENOMEM;
}
- memset(prt, 0, buffer.length);
buffer.pointer = prt;
status = acpi_get_irq_routing_table(handle, &buffer);
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
index d53bd9878ca2..481e633bbf41 100644
--- a/drivers/acpi/pci_link.c
+++ b/drivers/acpi/pci_link.c
@@ -103,7 +103,7 @@ DEFINE_MUTEX(acpi_link_lock);
static acpi_status
acpi_pci_link_check_possible(struct acpi_resource *resource, void *context)
{
- struct acpi_pci_link *link = (struct acpi_pci_link *)context;
+ struct acpi_pci_link *link = context;
u32 i = 0;
@@ -307,11 +307,10 @@ static int acpi_pci_link_set(struct acpi_pci_link *link, int irq)
if (!link || !irq)
return -EINVAL;
- resource = kmalloc(sizeof(*resource) + 1, irqs_disabled() ? GFP_ATOMIC: GFP_KERNEL);
+ resource = kzalloc(sizeof(*resource) + 1, irqs_disabled() ? GFP_ATOMIC: GFP_KERNEL);
if (!resource)
return -ENOMEM;
- memset(resource, 0, sizeof(*resource) + 1);
buffer.length = sizeof(*resource) + 1;
buffer.pointer = resource;
@@ -613,7 +612,7 @@ acpi_pci_link_allocate_irq(acpi_handle handle,
return -1;
}
- link = (struct acpi_pci_link *)acpi_driver_data(device);
+ link = acpi_driver_data(device);
if (!link) {
printk(KERN_ERR PREFIX "Invalid link context\n");
return -1;
@@ -668,7 +667,7 @@ int acpi_pci_link_free_irq(acpi_handle handle)
return -1;
}
- link = (struct acpi_pci_link *)acpi_driver_data(device);
+ link = acpi_driver_data(device);
if (!link) {
printk(KERN_ERR PREFIX "Invalid link context\n");
return -1;
@@ -718,10 +717,9 @@ static int acpi_pci_link_add(struct acpi_device *device)
if (!device)
return -EINVAL;
- link = kmalloc(sizeof(struct acpi_pci_link), GFP_KERNEL);
+ link = kzalloc(sizeof(struct acpi_pci_link), GFP_KERNEL);
if (!link)
return -ENOMEM;
- memset(link, 0, sizeof(struct acpi_pci_link));
link->device = device;
strcpy(acpi_device_name(device), ACPI_PCI_LINK_DEVICE_NAME);
@@ -808,7 +806,7 @@ static int acpi_pci_link_remove(struct acpi_device *device, int type)
if (!device || !acpi_driver_data(device))
return -EINVAL;
- link = (struct acpi_pci_link *)acpi_driver_data(device);
+ link = acpi_driver_data(device);
mutex_lock(&acpi_link_lock);
list_del(&link->node);
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 0984a1ee24ed..a860efa2c562 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -98,11 +98,12 @@ void acpi_pci_unregister_driver(struct acpi_pci_driver *driver)
struct acpi_pci_driver **pptr = &sub_driver;
while (*pptr) {
- if (*pptr != driver)
- continue;
- *pptr = (*pptr)->next;
- break;
+ if (*pptr == driver)
+ break;
+ pptr = &(*pptr)->next;
}
+ BUG_ON(!*pptr);
+ *pptr = (*pptr)->next;
if (!driver->remove)
return;
@@ -119,7 +120,7 @@ EXPORT_SYMBOL(acpi_pci_unregister_driver);
static acpi_status
get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data)
{
- int *busnr = (int *)data;
+ int *busnr = data;
struct acpi_resource_address64 address;
if (resource->type != ACPI_RESOURCE_TYPE_ADDRESS16 &&
@@ -164,10 +165,9 @@ static int acpi_pci_root_add(struct acpi_device *device)
if (!device)
return -EINVAL;
- root = kmalloc(sizeof(struct acpi_pci_root), GFP_KERNEL);
+ root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL);
if (!root)
return -ENOMEM;
- memset(root, 0, sizeof(struct acpi_pci_root));
INIT_LIST_HEAD(&root->node);
root->device = device;
@@ -331,7 +331,7 @@ static int acpi_pci_root_remove(struct acpi_device *device, int type)
if (!device || !acpi_driver_data(device))
return -EINVAL;
- root = (struct acpi_pci_root *)acpi_driver_data(device);
+ root = acpi_driver_data(device);
kfree(root);
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
index fe67a8af520e..0ba7dfbbb2ee 100644
--- a/drivers/acpi/power.c
+++ b/drivers/acpi/power.c
@@ -108,7 +108,7 @@ acpi_power_get_context(acpi_handle handle,
return result;
}
- *resource = (struct acpi_power_resource *)acpi_driver_data(device);
+ *resource = acpi_driver_data(device);
if (!resource)
return -ENODEV;
@@ -442,7 +442,7 @@ static int acpi_power_seq_show(struct seq_file *seq, void *offset)
struct acpi_power_resource *resource = NULL;
- resource = (struct acpi_power_resource *)seq->private;
+ resource = seq->private;
if (!resource)
goto end;
@@ -532,10 +532,9 @@ static int acpi_power_add(struct acpi_device *device)
if (!device)
return -EINVAL;
- resource = kmalloc(sizeof(struct acpi_power_resource), GFP_KERNEL);
+ resource = kzalloc(sizeof(struct acpi_power_resource), GFP_KERNEL);
if (!resource)
return -ENOMEM;
- memset(resource, 0, sizeof(struct acpi_power_resource));
resource->device = device;
strcpy(resource->name, device->pnp.bus_id);
@@ -590,7 +589,7 @@ static int acpi_power_remove(struct acpi_device *device, int type)
if (!device || !acpi_driver_data(device))
return -EINVAL;
- resource = (struct acpi_power_resource *)acpi_driver_data(device);
+ resource = acpi_driver_data(device);
acpi_power_remove_fs(device);
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 1908e0d20222..25718fed39f1 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -277,7 +277,7 @@ 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 = seq->private;
if (!pr)
@@ -542,12 +542,12 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device)
* Don't trust it blindly
*/
if (processor_device_array[pr->id] != NULL &&
- processor_device_array[pr->id] != (void *)device) {
+ processor_device_array[pr->id] != device) {
printk(KERN_WARNING "BIOS reported wrong ACPI id"
"for the processor\n");
return -ENODEV;
}
- processor_device_array[pr->id] = (void *)device;
+ processor_device_array[pr->id] = device;
processors[pr->id] = pr;
@@ -578,7 +578,7 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device)
static void acpi_processor_notify(acpi_handle handle, u32 event, void *data)
{
- struct acpi_processor *pr = (struct acpi_processor *)data;
+ struct acpi_processor *pr = data;
struct acpi_device *device = NULL;
@@ -615,10 +615,9 @@ static int acpi_processor_add(struct acpi_device *device)
if (!device)
return -EINVAL;
- pr = kmalloc(sizeof(struct acpi_processor), GFP_KERNEL);
+ pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL);
if (!pr)
return -ENOMEM;
- memset(pr, 0, sizeof(struct acpi_processor));
pr->handle = device->handle;
strcpy(acpi_device_name(device), ACPI_PROCESSOR_DEVICE_NAME);
@@ -637,7 +636,7 @@ static int acpi_processor_remove(struct acpi_device *device, int type)
if (!device || !acpi_driver_data(device))
return -EINVAL;
- pr = (struct acpi_processor *)acpi_driver_data(device);
+ pr = acpi_driver_data(device);
if (pr->id >= NR_CPUS) {
kfree(pr);
@@ -901,13 +900,13 @@ static int __init acpi_processor_init(void)
acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir);
if (!acpi_processor_dir)
- return 0;
+ return -ENOMEM;
acpi_processor_dir->owner = THIS_MODULE;
result = acpi_bus_register_driver(&acpi_processor_driver);
if (result < 0) {
remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
- return 0;
+ return result;
}
acpi_processor_install_hotplug_notify();
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 65b3f056ad89..3f30af21574e 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -211,7 +211,11 @@ acpi_processor_power_activate(struct acpi_processor *pr,
static void acpi_safe_halt(void)
{
current_thread_info()->status &= ~TS_POLLING;
- smp_mb__after_clear_bit();
+ /*
+ * TS_POLLING-cleared state must be visible before we
+ * test NEED_RESCHED:
+ */
+ smp_mb();
if (!need_resched())
safe_halt();
current_thread_info()->status |= TS_POLLING;
@@ -345,7 +349,11 @@ static void acpi_processor_idle(void)
*/
if (cx->type == ACPI_STATE_C2 || cx->type == ACPI_STATE_C3) {
current_thread_info()->status &= ~TS_POLLING;
- smp_mb__after_clear_bit();
+ /*
+ * TS_POLLING-cleared state must be visible before we
+ * test NEED_RESCHED:
+ */
+ smp_mb();
if (need_resched()) {
current_thread_info()->status |= TS_POLLING;
local_irq_enable();
@@ -673,7 +681,7 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr)
return -ENODEV;
}
- cst = (union acpi_object *)buffer.pointer;
+ cst = buffer.pointer;
/* There must be at least 2 elements */
if (!cst || (cst->type != ACPI_TYPE_PACKAGE) || cst->package.count < 2) {
@@ -702,14 +710,14 @@ 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 = &(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 = &(element->package.elements[0]);
if (obj->type != ACPI_TYPE_BUFFER)
continue;
@@ -721,7 +729,7 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr)
continue;
/* There should be an easy way to extract an integer... */
- obj = (union acpi_object *)&(element->package.elements[1]);
+ obj = &(element->package.elements[1]);
if (obj->type != ACPI_TYPE_INTEGER)
continue;
@@ -754,13 +762,13 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr)
}
}
- obj = (union acpi_object *)&(element->package.elements[2]);
+ obj = &(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 = &(element->package.elements[3]);
if (obj->type != ACPI_TYPE_INTEGER)
continue;
@@ -1029,7 +1037,7 @@ 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;
+ struct acpi_processor *pr = seq->private;
unsigned int i;
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
index 6fd174a37149..0e60382714bb 100644
--- a/drivers/acpi/processor_perflib.c
+++ b/drivers/acpi/processor_perflib.c
@@ -236,7 +236,7 @@ static int acpi_processor_get_performance_states(struct acpi_processor *pr)
return -ENODEV;
}
- pss = (union acpi_object *)buffer.pointer;
+ pss = buffer.pointer;
if (!pss || (pss->type != ACPI_TYPE_PACKAGE)) {
printk(KERN_ERR PREFIX "Invalid _PSS data\n");
result = -EFAULT;
@@ -410,7 +410,7 @@ static struct file_operations acpi_processor_perf_fops = {
static int acpi_processor_perf_seq_show(struct seq_file *seq, void *offset)
{
- struct acpi_processor *pr = (struct acpi_processor *)seq->private;
+ struct acpi_processor *pr = seq->private;
int i;
@@ -451,8 +451,8 @@ acpi_processor_write_performance(struct file *file,
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;
+ struct seq_file *m = file->private_data;
+ struct acpi_processor *pr = m->private;
struct acpi_processor_performance *perf;
char state_string[12] = { '\0' };
unsigned int new_state = 0;
@@ -551,7 +551,7 @@ static int acpi_processor_get_psd(struct acpi_processor *pr)
return -ENODEV;
}
- psd = (union acpi_object *) buffer.pointer;
+ psd = buffer.pointer;
if (!psd || (psd->type != ACPI_TYPE_PACKAGE)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSD data\n"));
result = -EFAULT;
diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c
index ef5e0f6efdba..40fecd67ad83 100644
--- a/drivers/acpi/processor_thermal.c
+++ b/drivers/acpi/processor_thermal.c
@@ -208,7 +208,7 @@ int acpi_processor_set_thermal_limit(acpi_handle handle, int type)
if (result)
return result;
- pr = (struct acpi_processor *)acpi_driver_data(device);
+ pr = acpi_driver_data(device);
if (!pr)
return -ENODEV;
@@ -348,8 +348,8 @@ static ssize_t acpi_processor_write_limit(struct file * file,
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;
+ struct seq_file *m = file->private_data;
+ struct acpi_processor *pr = m->private;
char limit_string[25] = { '\0' };
int px = 0;
int tx = 0;
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c
index d044ec519db0..0ec7dcde0063 100644
--- a/drivers/acpi/processor_throttling.c
+++ b/drivers/acpi/processor_throttling.c
@@ -259,7 +259,7 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr)
static int acpi_processor_throttling_seq_show(struct seq_file *seq,
void *offset)
{
- struct acpi_processor *pr = (struct acpi_processor *)seq->private;
+ struct acpi_processor *pr = seq->private;
int i = 0;
int result = 0;
@@ -307,8 +307,8 @@ static ssize_t acpi_processor_write_throttling(struct file * file,
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;
+ struct seq_file *m = file->private_data;
+ struct acpi_processor *pr = m->private;
char state_string[12] = { '\0' };
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c
index 8908a975e575..f58fc7447ab4 100644
--- a/drivers/acpi/sbs.c
+++ b/drivers/acpi/sbs.c
@@ -923,7 +923,7 @@ static struct proc_dir_entry *acpi_battery_dir = NULL;
static int acpi_battery_read_info(struct seq_file *seq, void *offset)
{
- struct acpi_battery *battery = (struct acpi_battery *)seq->private;
+ struct acpi_battery *battery = seq->private;
int cscale;
int result = 0;
@@ -1076,7 +1076,7 @@ static int acpi_battery_state_open_fs(struct inode *inode, struct file *file)
static int acpi_battery_read_alarm(struct seq_file *seq, void *offset)
{
- struct acpi_battery *battery = (struct acpi_battery *)seq->private;
+ struct acpi_battery *battery = seq->private;
int result = 0;
int cscale;
@@ -1125,8 +1125,8 @@ static ssize_t
acpi_battery_write_alarm(struct file *file, const char __user * buffer,
size_t count, loff_t * ppos)
{
- struct seq_file *seq = (struct seq_file *)file->private_data;
- struct acpi_battery *battery = (struct acpi_battery *)seq->private;
+ struct seq_file *seq = file->private_data;
+ struct acpi_battery *battery = seq->private;
char alarm_string[12] = { '\0' };
int result, old_alarm, new_alarm;
@@ -1160,14 +1160,14 @@ acpi_battery_write_alarm(struct file *file, const char __user * buffer,
if (result) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
"acpi_battery_set_alarm() failed\n"));
- (void)acpi_battery_set_alarm(battery, old_alarm);
+ acpi_battery_set_alarm(battery, old_alarm);
goto end;
}
result = acpi_battery_get_alarm(battery);
if (result) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
"acpi_battery_get_alarm() failed\n"));
- (void)acpi_battery_set_alarm(battery, old_alarm);
+ acpi_battery_set_alarm(battery, old_alarm);
goto end;
}
@@ -1217,7 +1217,7 @@ static struct proc_dir_entry *acpi_ac_dir = NULL;
static int acpi_ac_read_state(struct seq_file *seq, void *offset)
{
- struct acpi_sbs *sbs = (struct acpi_sbs *)seq->private;
+ struct acpi_sbs *sbs = seq->private;
int result;
if (sbs->zombie) {
@@ -1302,7 +1302,7 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)
battery->init_state = 1;
}
- (void)sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id);
+ sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id);
result = acpi_sbs_generic_add_fs(&battery->battery_entry,
acpi_battery_dir,
@@ -1485,7 +1485,7 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int data_type)
}
if (old_battery_present != new_battery_present) {
- (void)sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id);
+ sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id);
result = acpi_sbs_generate_event(sbs->device,
ACPI_SBS_BATTERY_NOTIFY_STATUS,
new_battery_present,
@@ -1498,7 +1498,7 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int data_type)
}
}
if (old_remaining_capacity != battery->state.remaining_capacity) {
- (void)sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id);
+ sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id);
result = acpi_sbs_generate_event(sbs->device,
ACPI_SBS_BATTERY_NOTIFY_STATUS,
new_battery_present,
@@ -1576,12 +1576,11 @@ static int acpi_sbs_add(struct acpi_device *device)
int id, cnt;
acpi_status status = AE_OK;
- sbs = kmalloc(sizeof(struct acpi_sbs), GFP_KERNEL);
+ sbs = kzalloc(sizeof(struct acpi_sbs), GFP_KERNEL);
if (!sbs) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "kmalloc() failed\n"));
return -ENOMEM;
}
- memset(sbs, 0, sizeof(struct acpi_sbs));
cnt = 0;
while (cnt < 10) {
@@ -1659,7 +1658,7 @@ static int acpi_sbs_add(struct acpi_device *device)
init_timer(&sbs->update_timer);
if (update_mode == QUEUE_UPDATE_MODE) {
status = acpi_os_execute(OSL_GPE_HANDLER,
- acpi_sbs_update_queue, (void *)sbs);
+ acpi_sbs_update_queue, sbs);
if (status != AE_OK) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
"acpi_os_execute() failed\n"));
@@ -1685,7 +1684,7 @@ static int acpi_sbs_add(struct acpi_device *device)
int acpi_sbs_remove(struct acpi_device *device, int type)
{
- struct acpi_sbs *sbs = NULL;
+ struct acpi_sbs *sbs;
int id;
if (!device) {
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 698a1540e303..283d87522c5d 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -984,12 +984,11 @@ acpi_add_single_object(struct acpi_device **child,
if (!child)
return -EINVAL;
- device = kmalloc(sizeof(struct acpi_device), GFP_KERNEL);
+ device = kzalloc(sizeof(struct acpi_device), GFP_KERNEL);
if (!device) {
printk(KERN_ERR PREFIX "Memory allocation error\n");
return -ENOMEM;
}
- memset(device, 0, sizeof(struct acpi_device));
device->handle = handle;
device->parent = parent;
diff --git a/drivers/acpi/sleep/wakeup.c b/drivers/acpi/sleep/wakeup.c
index af1dbabaf0b1..fab8f2694f03 100644
--- a/drivers/acpi/sleep/wakeup.c
+++ b/drivers/acpi/sleep/wakeup.c
@@ -183,11 +183,11 @@ late_initcall(acpi_wakeup_device_init);
#endif
/*
- * Disable all wakeup GPEs before power off.
- *
+ * Disable all wakeup GPEs before entering requested sleep state.
+ * @sleep_state: ACPI state
* Since acpi_enter_sleep_state() will disable all
* RUNTIME GPEs, we simply mark all GPES that
- * are not enabled for wakeup from S5 as RUNTIME.
+ * are not enabled for wakeup from requested state as RUNTIME.
*/
void acpi_gpe_sleep_prepare(u32 sleep_state)
{
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index bfb3bfcf9e91..ffa30c9fccbf 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -228,7 +228,7 @@ void acpi_table_print_madt_entry(acpi_table_entry_header * header)
static int
acpi_table_compute_checksum(void *table_pointer, unsigned long length)
{
- u8 *p = (u8 *) table_pointer;
+ u8 *p = table_pointer;
unsigned long remains = length;
unsigned long sum = 0;
diff --git a/drivers/acpi/tables/tbxface.c b/drivers/acpi/tables/tbxface.c
index 7767987be15a..5ba9303293ad 100644
--- a/drivers/acpi/tables/tbxface.c
+++ b/drivers/acpi/tables/tbxface.c
@@ -123,7 +123,6 @@ acpi_status acpi_load_tables(void)
ACPI_EXPORT_SYMBOL(acpi_load_tables)
-#ifdef ACPI_FUTURE_USAGE
/*******************************************************************************
*
* FUNCTION: acpi_load_table
@@ -221,6 +220,59 @@ ACPI_EXPORT_SYMBOL(acpi_load_table)
/*******************************************************************************
*
+ * FUNCTION: acpi_unload_table_id
+ *
+ * PARAMETERS: table_type - Type of table to be unloaded
+ * id - Owner ID of the table to be removed.
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: This routine is used to force the unload of a table (by id)
+ *
+ ******************************************************************************/
+acpi_status acpi_unload_table_id(acpi_table_type table_type, acpi_owner_id id)
+{
+ struct acpi_table_desc *table_desc;
+ acpi_status status;
+
+ ACPI_FUNCTION_TRACE(acpi_unload_table);
+
+ /* Parameter validation */
+ if (table_type > ACPI_TABLE_ID_MAX)
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
+
+ /* Find table from the requested type list */
+ table_desc = acpi_gbl_table_lists[table_type].next;
+ while (table_desc && table_desc->owner_id != id)
+ table_desc = table_desc->next;
+
+ if (!table_desc)
+ return_ACPI_STATUS(AE_NOT_EXIST);
+
+ /*
+ * Delete all namespace objects owned by this table. Note that these
+ * objects can appear anywhere in the namespace by virtue of the AML
+ * "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->owner_id);
+
+ status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
+ if (ACPI_FAILURE(status))
+ return_ACPI_STATUS(status);
+
+ (void)acpi_tb_uninstall_table(table_desc);
+
+ (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
+
+ return_ACPI_STATUS(AE_OK);
+}
+
+ACPI_EXPORT_SYMBOL(acpi_unload_table_id)
+
+#ifdef ACPI_FUTURE_USAGE
+/*******************************************************************************
+ *
* FUNCTION: acpi_unload_table
*
* PARAMETERS: table_type - Type of table to be unloaded
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 5753d06b7860..40ddb4dd9631 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -663,7 +663,7 @@ static void acpi_thermal_run(unsigned long data)
static void acpi_thermal_check(void *data)
{
int result = 0;
- struct acpi_thermal *tz = (struct acpi_thermal *)data;
+ struct acpi_thermal *tz = data;
unsigned long sleep_time = 0;
int i = 0;
struct acpi_thermal_state state;
@@ -778,7 +778,7 @@ 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 = seq->private;
if (!tz)
@@ -813,7 +813,7 @@ static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file)
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;
+ struct acpi_thermal *tz = seq->private;
if (!tz)
@@ -837,7 +837,7 @@ static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file)
static int acpi_thermal_trip_seq_show(struct seq_file *seq, void *offset)
{
- struct acpi_thermal *tz = (struct acpi_thermal *)seq->private;
+ struct acpi_thermal *tz = seq->private;
int i = 0;
int j = 0;
@@ -893,8 +893,8 @@ 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 = file->private_data;
+ struct acpi_thermal *tz = m->private;
char *limit_string;
int num, critical, hot, passive;
@@ -902,12 +902,10 @@ acpi_thermal_write_trip_points(struct file *file,
int i = 0;
- limit_string = kmalloc(ACPI_THERMAL_MAX_LIMIT_STR_LEN, GFP_KERNEL);
+ limit_string = kzalloc(ACPI_THERMAL_MAX_LIMIT_STR_LEN, GFP_KERNEL);
if (!limit_string)
return -ENOMEM;
- memset(limit_string, 0, ACPI_THERMAL_MAX_LIMIT_STR_LEN);
-
active = kmalloc(ACPI_THERMAL_MAX_ACTIVE * sizeof(int), GFP_KERNEL);
if (!active) {
kfree(limit_string);
@@ -953,7 +951,7 @@ acpi_thermal_write_trip_points(struct file *file,
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 = seq->private;
if (!tz)
@@ -984,8 +982,8 @@ 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;
+ struct seq_file *m = file->private_data;
+ struct acpi_thermal *tz = m->private;
int result = 0;
char mode_string[12] = { '\0' };
@@ -1014,7 +1012,7 @@ acpi_thermal_write_cooling_mode(struct file *file,
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 = seq->private;
if (!tz)
@@ -1043,8 +1041,8 @@ 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;
+ struct seq_file *m = file->private_data;
+ struct acpi_thermal *tz = m->private;
int result = 0;
char polling_string[12] = { '\0' };
int seconds = 0;
@@ -1170,7 +1168,7 @@ static int acpi_thermal_remove_fs(struct acpi_device *device)
static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data)
{
- struct acpi_thermal *tz = (struct acpi_thermal *)data;
+ struct acpi_thermal *tz = data;
struct acpi_device *device = NULL;
@@ -1271,10 +1269,9 @@ static int acpi_thermal_add(struct acpi_device *device)
if (!device)
return -EINVAL;
- tz = kmalloc(sizeof(struct acpi_thermal), GFP_KERNEL);
+ tz = kzalloc(sizeof(struct acpi_thermal), GFP_KERNEL);
if (!tz)
return -ENOMEM;
- memset(tz, 0, sizeof(struct acpi_thermal));
tz->device = device;
strcpy(tz->name, device->pnp.bus_id);
@@ -1324,7 +1321,7 @@ static int acpi_thermal_remove(struct acpi_device *device, int type)
if (!device || !acpi_driver_data(device))
return -EINVAL;
- tz = (struct acpi_thermal *)acpi_driver_data(device);
+ tz = acpi_driver_data(device);
/* avoid timer adding new defer task */
tz->zombie = 1;
@@ -1364,7 +1361,7 @@ static int acpi_thermal_resume(struct acpi_device *device, int state)
if (!device || !acpi_driver_data(device))
return -EINVAL;
- tz = (struct acpi_thermal *)acpi_driver_data(device);
+ tz = acpi_driver_data(device);
acpi_thermal_get_temperature(tz);
diff --git a/drivers/acpi/toshiba_acpi.c b/drivers/acpi/toshiba_acpi.c
index 7fe0b7ae9733..88aeccbafaaf 100644
--- a/drivers/acpi/toshiba_acpi.c
+++ b/drivers/acpi/toshiba_acpi.c
@@ -41,6 +41,8 @@
#include <linux/init.h>
#include <linux/types.h>
#include <linux/proc_fs.h>
+#include <linux/backlight.h>
+
#include <asm/uaccess.h>
#include <acpi/acpi_drivers.h>
@@ -210,6 +212,7 @@ static acpi_status hci_read1(u32 reg, u32 * out1, u32 * result)
}
static struct proc_dir_entry *toshiba_proc_dir /*= 0*/ ;
+static struct backlight_device *toshiba_backlight_device;
static int force_fan;
static int last_key_event;
static int key_event_valid;
@@ -271,14 +274,23 @@ dispatch_write(struct file *file, const char __user * buffer,
return result;
}
-static char *read_lcd(char *p)
+static int get_lcd(struct backlight_device *bd)
{
u32 hci_result;
u32 value;
hci_read1(HCI_LCD_BRIGHTNESS, &value, &hci_result);
if (hci_result == HCI_SUCCESS) {
- value = value >> HCI_LCD_BRIGHTNESS_SHIFT;
+ return (value >> HCI_LCD_BRIGHTNESS_SHIFT);
+ } else
+ return -EFAULT;
+}
+
+static char *read_lcd(char *p)
+{
+ int value = get_lcd(NULL);
+
+ if (value >= 0) {
p += sprintf(p, "brightness: %d\n", value);
p += sprintf(p, "brightness_levels: %d\n",
HCI_LCD_BRIGHTNESS_LEVELS);
@@ -289,22 +301,34 @@ static char *read_lcd(char *p)
return p;
}
+static int set_lcd(int value)
+{
+ u32 hci_result;
+
+ value = value << HCI_LCD_BRIGHTNESS_SHIFT;
+ hci_write1(HCI_LCD_BRIGHTNESS, value, &hci_result);
+ if (hci_result != HCI_SUCCESS)
+ return -EFAULT;
+
+ return 0;
+}
+
+static int set_lcd_status(struct backlight_device *bd)
+{
+ return set_lcd(bd->props->brightness);
+}
+
static unsigned long write_lcd(const char *buffer, unsigned long count)
{
int value;
- u32 hci_result;
+ int ret = count;
if (sscanf(buffer, " brightness : %i", &value) == 1 &&
- 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)
- return -EFAULT;
- } else {
- return -EINVAL;
- }
-
- return count;
+ value >= 0 && value < HCI_LCD_BRIGHTNESS_LEVELS)
+ ret = set_lcd(value);
+ else
+ ret = -EINVAL;
+ return ret;
}
static char *read_video(char *p)
@@ -506,6 +530,26 @@ static acpi_status __exit remove_device(void)
return AE_OK;
}
+static struct backlight_properties toshiba_backlight_data = {
+ .owner = THIS_MODULE,
+ .get_brightness = get_lcd,
+ .update_status = set_lcd_status,
+ .max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1,
+};
+
+static void __exit toshiba_acpi_exit(void)
+{
+ if (toshiba_backlight_device)
+ backlight_device_unregister(toshiba_backlight_device);
+
+ remove_device();
+
+ if (toshiba_proc_dir)
+ remove_proc_entry(PROC_TOSHIBA, acpi_root_dir);
+
+ return;
+}
+
static int __init toshiba_acpi_init(void)
{
acpi_status status = AE_OK;
@@ -546,17 +590,16 @@ static int __init toshiba_acpi_init(void)
remove_proc_entry(PROC_TOSHIBA, acpi_root_dir);
}
- return (ACPI_SUCCESS(status)) ? 0 : -ENODEV;
-}
-
-static void __exit toshiba_acpi_exit(void)
-{
- remove_device();
-
- if (toshiba_proc_dir)
- remove_proc_entry(PROC_TOSHIBA, acpi_root_dir);
+ toshiba_backlight_device = backlight_device_register("toshiba",NULL,
+ NULL,
+ &toshiba_backlight_data);
+ if (IS_ERR(toshiba_backlight_device)) {
+ printk(KERN_ERR "Could not register toshiba backlight device\n");
+ toshiba_backlight_device = NULL;
+ toshiba_acpi_exit();
+ }
- return;
+ return (ACPI_SUCCESS(status)) ? 0 : -ENODEV;
}
module_init(toshiba_acpi_init);
diff --git a/drivers/acpi/utilities/utdebug.c b/drivers/acpi/utilities/utdebug.c
index bb1eaf9aa653..9e9054e155c1 100644
--- a/drivers/acpi/utilities/utdebug.c
+++ b/drivers/acpi/utilities/utdebug.c
@@ -180,8 +180,9 @@ acpi_ut_debug_print(u32 requested_debug_level,
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",
- (u32) acpi_gbl_prev_thread_id, (u32) thread_id);
+ ("\n**** Context Switch from TID %lX to TID %lX ****\n\n",
+ (unsigned long) acpi_gbl_prev_thread_id,
+ (unsigned long) thread_id);
}
acpi_gbl_prev_thread_id = thread_id;
diff --git a/drivers/acpi/utilities/utmutex.c b/drivers/acpi/utilities/utmutex.c
index c39062a047cd..180e73ceb6e2 100644
--- a/drivers/acpi/utilities/utmutex.c
+++ b/drivers/acpi/utilities/utmutex.c
@@ -243,23 +243,24 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id)
#endif
ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
- "Thread %X attempting to acquire Mutex [%s]\n",
- (u32) this_thread_id, acpi_ut_get_mutex_name(mutex_id)));
+ "Thread %lX attempting to acquire Mutex [%s]\n",
+ (unsigned long) this_thread_id,
+ acpi_ut_get_mutex_name(mutex_id)));
status = acpi_os_acquire_mutex(acpi_gbl_mutex_info[mutex_id].mutex,
ACPI_WAIT_FOREVER);
if (ACPI_SUCCESS(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
- "Thread %X acquired Mutex [%s]\n",
- (u32) this_thread_id,
+ "Thread %lX acquired Mutex [%s]\n",
+ (unsigned long) 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_EXCEPTION((AE_INFO, status,
- "Thread %X could not acquire Mutex [%X]",
- (u32) this_thread_id, mutex_id));
+ "Thread %lX could not acquire Mutex [%X]",
+ (unsigned long) this_thread_id, mutex_id));
}
return (status);
@@ -285,7 +286,8 @@ acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id)
this_thread_id = acpi_os_get_thread_id();
ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
- "Thread %X releasing Mutex [%s]\n", (u32) this_thread_id,
+ "Thread %lX releasing Mutex [%s]\n",
+ (unsigned long) this_thread_id,
acpi_ut_get_mutex_name(mutex_id)));
if (mutex_id > ACPI_MAX_MUTEX) {
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c
index d0d84c43a9d4..68a809fa7b19 100644
--- a/drivers/acpi/utils.c
+++ b/drivers/acpi/utils.c
@@ -83,7 +83,7 @@ acpi_extract_package(union acpi_object *package,
return AE_BAD_DATA;
}
- format_string = (char *)format->pointer;
+ format_string = format->pointer;
/*
* Calculate size_required.
@@ -262,11 +262,10 @@ acpi_evaluate_integer(acpi_handle handle,
if (!data)
return AE_BAD_PARAMETER;
- element = kmalloc(sizeof(union acpi_object), irqs_disabled() ? GFP_ATOMIC: GFP_KERNEL);
+ element = kzalloc(sizeof(union acpi_object), irqs_disabled() ? GFP_ATOMIC: GFP_KERNEL);
if (!element)
return AE_NO_MEMORY;
- memset(element, 0, sizeof(union acpi_object));
buffer.length = sizeof(union acpi_object);
buffer.pointer = element;
status = acpi_evaluate_object(handle, pathname, arguments, &buffer);
@@ -321,12 +320,11 @@ acpi_evaluate_string(acpi_handle handle,
return AE_BAD_DATA;
}
- *data = kmalloc(element->string.length + 1, GFP_KERNEL);
+ *data = kzalloc(element->string.length + 1, GFP_KERNEL);
if (!data) {
printk(KERN_ERR PREFIX "Memory allocation\n");
return -ENOMEM;
}
- memset(*data, 0, element->string.length + 1);
memcpy(*data, element->string.pointer, element->string.length);
@@ -361,7 +359,7 @@ acpi_evaluate_reference(acpi_handle handle,
if (ACPI_FAILURE(status))
goto end;
- package = (union acpi_object *)buffer.pointer;
+ package = buffer.pointer;
if ((buffer.length == 0) || !package) {
printk(KERN_ERR PREFIX "No return object (len %X ptr %p)\n",
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 56666a982476..36b37d755dbc 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -3,6 +3,7 @@
*
* Copyright (C) 2004 Luming Yu <luming.yu@intel.com>
* Copyright (C) 2004 Bruno Ducrot <ducrot@poupinou.org>
+ * Copyright (C) 2006 Thomas Tuttle <linux-kernel@ttuttle.net>
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
@@ -47,11 +48,11 @@
#define ACPI_VIDEO_NOTIFY_NEXT_OUTPUT 0x83
#define ACPI_VIDEO_NOTIFY_PREV_OUTPUT 0x84
-#define ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS 0x82
-#define ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS 0x83
-#define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS 0x84
-#define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS 0x85
-#define ACPI_VIDEO_NOTIFY_DISPLAY_OFF 0x86
+#define ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS 0x85
+#define ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS 0x86
+#define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS 0x87
+#define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS 0x88
+#define ACPI_VIDEO_NOTIFY_DISPLAY_OFF 0x89
#define ACPI_VIDEO_HEAD_INVALID (~0u - 1)
#define ACPI_VIDEO_HEAD_END (~0u)
@@ -386,7 +387,7 @@ acpi_video_device_EDID(struct acpi_video_device *device,
if (ACPI_FAILURE(status))
return -ENODEV;
- obj = (union acpi_object *)buffer.pointer;
+ obj = buffer.pointer;
if (obj && obj->type == ACPI_TYPE_BUFFER)
*edid = obj;
@@ -532,11 +533,10 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
int count = 0;
union acpi_object *o;
- br = kmalloc(sizeof(*br), GFP_KERNEL);
+ br = kzalloc(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);
if (!br->levels)
@@ -654,8 +654,7 @@ static struct proc_dir_entry *acpi_video_dir;
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 = seq->private;
if (!dev)
@@ -688,8 +687,7 @@ acpi_video_device_info_open_fs(struct inode *inode, struct file *file)
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;
+ struct acpi_video_device *dev = seq->private;
unsigned long state;
@@ -727,8 +725,8 @@ acpi_video_device_write_state(struct file *file,
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;
+ struct seq_file *m = file->private_data;
+ struct acpi_video_device *dev = m->private;
char str[12] = { 0 };
u32 state = 0;
@@ -754,8 +752,7 @@ acpi_video_device_write_state(struct file *file,
static int
acpi_video_device_brightness_seq_show(struct seq_file *seq, void *offset)
{
- struct acpi_video_device *dev =
- (struct acpi_video_device *)seq->private;
+ struct acpi_video_device *dev = seq->private;
int i;
@@ -784,8 +781,8 @@ 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;
+ struct seq_file *m = file->private_data;
+ struct acpi_video_device *dev = m->private;
char str[4] = { 0 };
unsigned int level = 0;
int i;
@@ -817,8 +814,7 @@ acpi_video_device_write_brightness(struct file *file,
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;
+ struct acpi_video_device *dev = seq->private;
int status;
int i;
union acpi_object *edid = NULL;
@@ -866,7 +862,7 @@ static int acpi_video_device_add_fs(struct acpi_device *device)
if (!device)
return -ENODEV;
- vid_dev = (struct acpi_video_device *)acpi_driver_data(device);
+ vid_dev = acpi_driver_data(device);
if (!vid_dev)
return -ENODEV;
@@ -931,7 +927,7 @@ static int acpi_video_device_remove_fs(struct acpi_device *device)
{
struct acpi_video_device *vid_dev;
- vid_dev = (struct acpi_video_device *)acpi_driver_data(device);
+ vid_dev = acpi_driver_data(device);
if (!vid_dev || !vid_dev->video || !vid_dev->video->dir)
return -ENODEV;
@@ -950,7 +946,7 @@ static int acpi_video_device_remove_fs(struct acpi_device *device)
/* video bus */
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 = seq->private;
if (!video)
@@ -975,7 +971,7 @@ static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file)
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 = seq->private;
if (!video)
@@ -995,7 +991,7 @@ static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file)
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;
+ struct acpi_video_bus *video = seq->private;
unsigned long options;
int status;
@@ -1033,7 +1029,7 @@ acpi_video_bus_POST_info_open_fs(struct inode *inode, struct file *file)
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;
+ struct acpi_video_bus *video = seq->private;
int status;
unsigned long id;
@@ -1054,7 +1050,7 @@ static int acpi_video_bus_POST_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 = seq->private;
seq_printf(seq, "DOS setting: <%d>\n", video->dos_setting);
@@ -1079,8 +1075,8 @@ acpi_video_bus_write_POST(struct file *file,
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;
+ struct seq_file *m = file->private_data;
+ struct acpi_video_bus *video = m->private;
char str[12] = { 0 };
unsigned long opt, options;
@@ -1119,8 +1115,8 @@ acpi_video_bus_write_DOS(struct file *file,
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;
+ struct seq_file *m = file->private_data;
+ struct acpi_video_bus *video = m->private;
char str[12] = { 0 };
unsigned long opt;
@@ -1150,7 +1146,7 @@ static int acpi_video_bus_add_fs(struct acpi_device *device)
struct acpi_video_bus *video;
- video = (struct acpi_video_bus *)acpi_driver_data(device);
+ video = acpi_driver_data(device);
if (!acpi_device_dir(device)) {
acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
@@ -1226,7 +1222,7 @@ static int acpi_video_bus_remove_fs(struct acpi_device *device)
struct acpi_video_bus *video;
- video = (struct acpi_video_bus *)acpi_driver_data(device);
+ video = acpi_driver_data(device);
if (acpi_device_dir(device)) {
remove_proc_entry("info", acpi_device_dir(device));
@@ -1263,12 +1259,10 @@ acpi_video_bus_get_one_device(struct acpi_device *device,
acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id);
if (ACPI_SUCCESS(status)) {
- data = kmalloc(sizeof(struct acpi_video_device), GFP_KERNEL);
+ data = kzalloc(sizeof(struct acpi_video_device), GFP_KERNEL);
if (!data)
return -ENOMEM;
- memset(data, 0, sizeof(struct acpi_video_device));
-
strcpy(acpi_device_name(device), ACPI_VIDEO_DEVICE_NAME);
strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS);
acpi_driver_data(device) = data;
@@ -1403,7 +1397,7 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video)
return status;
}
- dod = (union acpi_object *)buffer.pointer;
+ dod = buffer.pointer;
if (!dod || (dod->type != ACPI_TYPE_PACKAGE)) {
ACPI_EXCEPTION((AE_INFO, status, "Invalid _DOD data"));
status = -EFAULT;
@@ -1426,7 +1420,7 @@ 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 = &dod->package.elements[i];
if (obj->type != ACPI_TYPE_INTEGER) {
printk(KERN_ERR PREFIX "Invalid _DOD data\n");
@@ -1509,8 +1503,34 @@ static int
acpi_video_get_next_level(struct acpi_video_device *device,
u32 level_current, u32 event)
{
- /*Fix me */
- return level_current;
+ int min, max, min_above, max_below, i, l;
+ max = max_below = 0;
+ min = min_above = 255;
+ for (i = 0; i < device->brightness->count; i++) {
+ l = device->brightness->levels[i];
+ if (l < min)
+ min = l;
+ if (l > max)
+ max = l;
+ if (l < min_above && l > level_current)
+ min_above = l;
+ if (l > max_below && l < level_current)
+ max_below = l;
+ }
+
+ switch (event) {
+ case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS:
+ return (level_current < max) ? min_above : min;
+ case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS:
+ return (level_current < max) ? min_above : max;
+ case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS:
+ return (level_current > min) ? max_below : min;
+ case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS:
+ case ACPI_VIDEO_NOTIFY_DISPLAY_OFF:
+ return 0;
+ default:
+ return level_current;
+ }
}
static void
@@ -1612,7 +1632,7 @@ static int acpi_video_bus_stop_devices(struct acpi_video_bus *video)
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_video_bus *video = data;
struct acpi_device *device = NULL;
printk("video bus notify\n");
@@ -1654,8 +1674,7 @@ static void acpi_video_bus_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_video_device *video_device = data;
struct acpi_device *device = NULL;
@@ -1696,10 +1715,9 @@ static int acpi_video_bus_add(struct acpi_device *device)
if (!device)
return -EINVAL;
- video = kmalloc(sizeof(struct acpi_video_bus), GFP_KERNEL);
+ video = kzalloc(sizeof(struct acpi_video_bus), GFP_KERNEL);
if (!video)
return -ENOMEM;
- memset(video, 0, sizeof(struct acpi_video_bus));
video->device = device;
strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME);
@@ -1757,7 +1775,7 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type)
if (!device || !acpi_driver_data(device))
return -EINVAL;
- video = (struct acpi_video_bus *)acpi_driver_data(device);
+ video = acpi_driver_data(device);
acpi_video_bus_stop_devices(video);
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 984ab284382a..b34e0a958d0f 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -40,9 +40,9 @@ config ATA_PIIX
tristate "Intel PIIX/ICH SATA support"
depends on PCI
help
- This option enables support for ICH5/6/7/8 Serial ATA.
- If PATA support was enabled previously, this enables
- support for select Intel PIIX/ICH PATA host controllers.
+ This option enables support for ICH5/6/7/8 Serial ATA
+ and support for PATA on the Intel PIIX3/PIIX4/ICH series
+ PATA host controllers.
If unsure, say N.
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index f36da488a2c1..b517d2493551 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -402,6 +402,14 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VDEVICE(NVIDIA, 0x044d), board_ahci }, /* MCP65 */
{ PCI_VDEVICE(NVIDIA, 0x044e), board_ahci }, /* MCP65 */
{ PCI_VDEVICE(NVIDIA, 0x044f), board_ahci }, /* MCP65 */
+ { PCI_VDEVICE(NVIDIA, 0x045c), board_ahci }, /* MCP65 */
+ { PCI_VDEVICE(NVIDIA, 0x045d), board_ahci }, /* MCP65 */
+ { PCI_VDEVICE(NVIDIA, 0x045e), board_ahci }, /* MCP65 */
+ { PCI_VDEVICE(NVIDIA, 0x045f), board_ahci }, /* MCP65 */
+ { PCI_VDEVICE(NVIDIA, 0x0550), board_ahci }, /* MCP67 */
+ { PCI_VDEVICE(NVIDIA, 0x0551), board_ahci }, /* MCP67 */
+ { PCI_VDEVICE(NVIDIA, 0x0552), board_ahci }, /* MCP67 */
+ { PCI_VDEVICE(NVIDIA, 0x0553), board_ahci }, /* MCP67 */
{ PCI_VDEVICE(NVIDIA, 0x0554), board_ahci }, /* MCP67 */
{ PCI_VDEVICE(NVIDIA, 0x0555), board_ahci }, /* MCP67 */
{ PCI_VDEVICE(NVIDIA, 0x0556), board_ahci }, /* MCP67 */
@@ -645,8 +653,6 @@ static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev)
u32 cap_save, impl_save, tmp;
cap_save = readl(mmio + HOST_CAP);
- cap_save &= ( (1<<28) | (1<<17) );
- cap_save |= (1 << 27);
impl_save = readl(mmio + HOST_PORTS_IMPL);
/* global controller reset */
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index c7de0bb1591f..47701b286f8b 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -226,14 +226,26 @@ static const struct pci_device_id piix_pci_tbl[] = {
{ 0x8086, 0x27c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
/* 2801GBM/GHM (ICH7M, identical to ICH6M) */
{ 0x8086, 0x27c4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6m_sata_ahci },
- /* Enterprise Southbridge 2 (where's the datasheet?) */
+ /* Enterprise Southbridge 2 (631xESB/632xESB) */
{ 0x8086, 0x2680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
- /* SATA Controller 1 IDE (ICH8, no datasheet yet) */
+ /* SATA Controller 1 IDE (ICH8) */
{ 0x8086, 0x2820, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
- /* SATA Controller 2 IDE (ICH8, ditto) */
+ /* SATA Controller 2 IDE (ICH8) */
{ 0x8086, 0x2825, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
- /* Mobile SATA Controller IDE (ICH8M, ditto) */
+ /* Mobile SATA Controller IDE (ICH8M) */
{ 0x8086, 0x2828, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
+ /* SATA Controller IDE (ICH9) */
+ { 0x8086, 0x2920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
+ /* SATA Controller IDE (ICH9) */
+ { 0x8086, 0x2921, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
+ /* SATA Controller IDE (ICH9) */
+ { 0x8086, 0x2926, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
+ /* SATA Controller IDE (ICH9M) */
+ { 0x8086, 0x2928, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
+ /* SATA Controller IDE (ICH9M) */
+ { 0x8086, 0x292d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
+ /* SATA Controller IDE (ICH9M) */
+ { 0x8086, 0x292e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
{ } /* terminate list */
};
@@ -330,7 +342,7 @@ static const struct ata_port_operations ich_pata_ops = {
.port_start = ata_port_start,
.port_stop = ata_port_stop,
- .host_stop = ata_host_stop,
+ .host_stop = piix_host_stop,
};
static const struct ata_port_operations piix_sata_ops = {
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 011c0a8a2dcc..0d51d13b16bf 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -1332,7 +1332,7 @@ unsigned ata_exec_internal_sg(struct ata_device *dev,
}
/**
- * ata_exec_internal_sg - execute libata internal command
+ * ata_exec_internal - execute libata internal command
* @dev: Device to which the command is sent
* @tf: Taskfile registers for the command and the result
* @cdb: CDB for packet command
@@ -1353,11 +1353,17 @@ unsigned ata_exec_internal(struct ata_device *dev,
struct ata_taskfile *tf, const u8 *cdb,
int dma_dir, void *buf, unsigned int buflen)
{
- struct scatterlist sg;
+ struct scatterlist *psg = NULL, sg;
+ unsigned int n_elem = 0;
- sg_init_one(&sg, buf, buflen);
+ if (dma_dir != DMA_NONE) {
+ WARN_ON(!buf);
+ sg_init_one(&sg, buf, buflen);
+ psg = &sg;
+ n_elem++;
+ }
- return ata_exec_internal_sg(dev, tf, cdb, dma_dir, &sg, 1);
+ return ata_exec_internal_sg(dev, tf, cdb, dma_dir, psg, n_elem);
}
/**
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 664e1377b54c..836947da5b14 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -51,7 +51,7 @@
#define SECTOR_SIZE 512
-typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc, const u8 *scsicmd);
+typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc);
static struct ata_device * __ata_scsi_find_dev(struct ata_port *ap,
const struct scsi_device *scsidev);
@@ -935,7 +935,6 @@ int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth)
/**
* ata_scsi_start_stop_xlat - Translate SCSI START STOP UNIT command
* @qc: Storage for translated ATA taskfile
- * @scsicmd: SCSI command to translate
*
* Sets up an ATA taskfile to issue STANDBY (to stop) or READ VERIFY
* (to start). Perhaps these commands should be preceded by
@@ -948,22 +947,25 @@ int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth)
* RETURNS:
* Zero on success, non-zero on error.
*/
-
-static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc,
- const u8 *scsicmd)
+static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc)
{
+ struct scsi_cmnd *scmd = qc->scsicmd;
struct ata_taskfile *tf = &qc->tf;
+ const u8 *cdb = scmd->cmnd;
+
+ if (scmd->cmd_len < 5)
+ goto invalid_fld;
tf->flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR;
tf->protocol = ATA_PROT_NODATA;
- if (scsicmd[1] & 0x1) {
+ if (cdb[1] & 0x1) {
; /* ignore IMMED bit, violates sat-r05 */
}
- if (scsicmd[4] & 0x2)
+ if (cdb[4] & 0x2)
goto invalid_fld; /* LOEJ bit set not supported */
- if (((scsicmd[4] >> 4) & 0xf) != 0)
+ if (((cdb[4] >> 4) & 0xf) != 0)
goto invalid_fld; /* power conditions not supported */
- if (scsicmd[4] & 0x1) {
+ if (cdb[4] & 0x1) {
tf->nsect = 1; /* 1 sector, lba=0 */
if (qc->dev->flags & ATA_DFLAG_LBA) {
@@ -996,7 +998,7 @@ 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);
+ ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x0);
/* "Invalid field in cbd" */
return 1;
}
@@ -1005,7 +1007,6 @@ invalid_fld:
/**
* ata_scsi_flush_xlat - Translate SCSI SYNCHRONIZE CACHE command
* @qc: Storage for translated ATA taskfile
- * @scsicmd: SCSI command to translate (ignored)
*
* Sets up an ATA taskfile to issue FLUSH CACHE or
* FLUSH CACHE EXT.
@@ -1016,8 +1017,7 @@ invalid_fld:
* RETURNS:
* Zero on success, non-zero on error.
*/
-
-static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
+static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc)
{
struct ata_taskfile *tf = &qc->tf;
@@ -1034,7 +1034,7 @@ static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc, const u8 *scs
/**
* scsi_6_lba_len - Get LBA and transfer length
- * @scsicmd: SCSI command to translate
+ * @cdb: SCSI command to translate
*
* Calculate LBA and transfer length for 6-byte commands.
*
@@ -1042,18 +1042,17 @@ static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc, const u8 *scs
* @plba: the LBA
* @plen: the transfer length
*/
-
-static void scsi_6_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
+static void scsi_6_lba_len(const u8 *cdb, u64 *plba, u32 *plen)
{
u64 lba = 0;
u32 len = 0;
VPRINTK("six-byte command\n");
- lba |= ((u64)scsicmd[2]) << 8;
- lba |= ((u64)scsicmd[3]);
+ lba |= ((u64)cdb[2]) << 8;
+ lba |= ((u64)cdb[3]);
- len |= ((u32)scsicmd[4]);
+ len |= ((u32)cdb[4]);
*plba = lba;
*plen = len;
@@ -1061,7 +1060,7 @@ static void scsi_6_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
/**
* scsi_10_lba_len - Get LBA and transfer length
- * @scsicmd: SCSI command to translate
+ * @cdb: SCSI command to translate
*
* Calculate LBA and transfer length for 10-byte commands.
*
@@ -1069,21 +1068,20 @@ static void scsi_6_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
* @plba: the LBA
* @plen: the transfer length
*/
-
-static void scsi_10_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
+static void scsi_10_lba_len(const u8 *cdb, 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]);
+ lba |= ((u64)cdb[2]) << 24;
+ lba |= ((u64)cdb[3]) << 16;
+ lba |= ((u64)cdb[4]) << 8;
+ lba |= ((u64)cdb[5]);
- len |= ((u32)scsicmd[7]) << 8;
- len |= ((u32)scsicmd[8]);
+ len |= ((u32)cdb[7]) << 8;
+ len |= ((u32)cdb[8]);
*plba = lba;
*plen = len;
@@ -1091,7 +1089,7 @@ static void scsi_10_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
/**
* scsi_16_lba_len - Get LBA and transfer length
- * @scsicmd: SCSI command to translate
+ * @cdb: SCSI command to translate
*
* Calculate LBA and transfer length for 16-byte commands.
*
@@ -1099,27 +1097,26 @@ static void scsi_10_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
* @plba: the LBA
* @plen: the transfer length
*/
-
-static void scsi_16_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
+static void scsi_16_lba_len(const u8 *cdb, 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]);
+ lba |= ((u64)cdb[2]) << 56;
+ lba |= ((u64)cdb[3]) << 48;
+ lba |= ((u64)cdb[4]) << 40;
+ lba |= ((u64)cdb[5]) << 32;
+ lba |= ((u64)cdb[6]) << 24;
+ lba |= ((u64)cdb[7]) << 16;
+ lba |= ((u64)cdb[8]) << 8;
+ lba |= ((u64)cdb[9]);
- len |= ((u32)scsicmd[10]) << 24;
- len |= ((u32)scsicmd[11]) << 16;
- len |= ((u32)scsicmd[12]) << 8;
- len |= ((u32)scsicmd[13]);
+ len |= ((u32)cdb[10]) << 24;
+ len |= ((u32)cdb[11]) << 16;
+ len |= ((u32)cdb[12]) << 8;
+ len |= ((u32)cdb[13]);
*plba = lba;
*plen = len;
@@ -1128,7 +1125,6 @@ static void scsi_16_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
/**
* ata_scsi_verify_xlat - Translate SCSI VERIFY command into an ATA one
* @qc: Storage for translated ATA taskfile
- * @scsicmd: SCSI command to translate
*
* Converts SCSI VERIFY command to an ATA READ VERIFY command.
*
@@ -1138,23 +1134,28 @@ static void scsi_16_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
* RETURNS:
* Zero on success, non-zero on error.
*/
-
-static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
+static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc)
{
+ struct scsi_cmnd *scmd = qc->scsicmd;
struct ata_taskfile *tf = &qc->tf;
struct ata_device *dev = qc->dev;
u64 dev_sectors = qc->dev->n_sectors;
+ const u8 *cdb = scmd->cmnd;
u64 block;
u32 n_block;
tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
tf->protocol = ATA_PROT_NODATA;
- 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
+ if (cdb[0] == VERIFY) {
+ if (scmd->cmd_len < 10)
+ goto invalid_fld;
+ scsi_10_lba_len(cdb, &block, &n_block);
+ } else if (cdb[0] == VERIFY_16) {
+ if (scmd->cmd_len < 16)
+ goto invalid_fld;
+ scsi_16_lba_len(cdb, &block, &n_block);
+ } else
goto invalid_fld;
if (!n_block)
@@ -1229,24 +1230,23 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, const u8 *sc
return 0;
invalid_fld:
- ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x0);
+ ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x0);
/* "Invalid field in cbd" */
return 1;
out_of_range:
- ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x21, 0x0);
+ ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x21, 0x0);
/* "Logical Block Address out of range" */
return 1;
nothing_to_do:
- qc->scsicmd->result = SAM_STAT_GOOD;
+ scmd->result = SAM_STAT_GOOD;
return 1;
}
/**
* ata_scsi_rw_xlat - Translate SCSI r/w command into an ATA one
* @qc: Storage for translated ATA taskfile
- * @scsicmd: SCSI command to translate
*
* Converts any of six SCSI read/write commands into the
* ATA counterpart, including starting sector (LBA),
@@ -1262,29 +1262,33 @@ nothing_to_do:
* RETURNS:
* Zero on success, non-zero on error.
*/
-
-static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
+static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc)
{
+ struct scsi_cmnd *scmd = qc->scsicmd;
+ const u8 *cdb = scmd->cmnd;
unsigned int tf_flags = 0;
u64 block;
u32 n_block;
int rc;
- if (scsicmd[0] == WRITE_10 || scsicmd[0] == WRITE_6 ||
- scsicmd[0] == WRITE_16)
+ if (cdb[0] == WRITE_10 || cdb[0] == WRITE_6 || cdb[0] == WRITE_16)
tf_flags |= ATA_TFLAG_WRITE;
/* Calculate the SCSI LBA, transfer length and FUA. */
- switch (scsicmd[0]) {
+ switch (cdb[0]) {
case READ_10:
case WRITE_10:
- scsi_10_lba_len(scsicmd, &block, &n_block);
- if (unlikely(scsicmd[1] & (1 << 3)))
+ if (unlikely(scmd->cmd_len < 10))
+ goto invalid_fld;
+ scsi_10_lba_len(cdb, &block, &n_block);
+ if (unlikely(cdb[1] & (1 << 3)))
tf_flags |= ATA_TFLAG_FUA;
break;
case READ_6:
case WRITE_6:
- scsi_6_lba_len(scsicmd, &block, &n_block);
+ if (unlikely(scmd->cmd_len < 6))
+ goto invalid_fld;
+ scsi_6_lba_len(cdb, &block, &n_block);
/* for 6-byte r/w commands, transfer length 0
* means 256 blocks of data, not 0 block.
@@ -1294,8 +1298,10 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm
break;
case READ_16:
case WRITE_16:
- scsi_16_lba_len(scsicmd, &block, &n_block);
- if (unlikely(scsicmd[1] & (1 << 3)))
+ if (unlikely(scmd->cmd_len < 16))
+ goto invalid_fld;
+ scsi_16_lba_len(cdb, &block, &n_block);
+ if (unlikely(cdb[1] & (1 << 3)))
tf_flags |= ATA_TFLAG_FUA;
break;
default:
@@ -1326,17 +1332,17 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm
goto out_of_range;
/* treat all other errors as -EINVAL, fall through */
invalid_fld:
- ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x0);
+ ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x0);
/* "Invalid field in cbd" */
return 1;
out_of_range:
- ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x21, 0x0);
+ ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x21, 0x0);
/* "Logical Block Address out of range" */
return 1;
nothing_to_do:
- qc->scsicmd->result = SAM_STAT_GOOD;
+ scmd->result = SAM_STAT_GOOD;
return 1;
}
@@ -1456,7 +1462,6 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd,
ata_xlat_func_t xlat_func)
{
struct ata_queued_cmd *qc;
- u8 *scsicmd = cmd->cmnd;
int is_io = xlat_func == ata_scsi_rw_xlat;
VPRINTK("ENTER\n");
@@ -1488,7 +1493,7 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd,
qc->complete_fn = ata_scsi_qc_complete;
- if (xlat_func(qc, scsicmd))
+ if (xlat_func(qc))
goto early_finish;
/* select device, send command to hardware */
@@ -1539,7 +1544,7 @@ static unsigned int ata_scsi_rbuf_get(struct scsi_cmnd *cmd, u8 **buf_out)
struct scatterlist *sg;
sg = (struct scatterlist *) cmd->request_buffer;
- buf = kmap_atomic(sg->page, KM_USER0) + sg->offset;
+ buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
buflen = sg->length;
} else {
buf = cmd->request_buffer;
@@ -1567,7 +1572,7 @@ static inline void ata_scsi_rbuf_put(struct scsi_cmnd *cmd, u8 *buf)
struct scatterlist *sg;
sg = (struct scatterlist *) cmd->request_buffer;
- kunmap_atomic(buf - sg->offset, KM_USER0);
+ kunmap_atomic(buf - sg->offset, KM_IRQ0);
}
}
@@ -2344,7 +2349,6 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc)
/**
* atapi_xlat - Initialize PACKET taskfile
* @qc: command structure to be initialized
- * @scsicmd: SCSI CDB associated with this PACKET command
*
* LOCKING:
* spin_lock_irqsave(host lock)
@@ -2352,25 +2356,25 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc)
* RETURNS:
* Zero on success, non-zero on failure.
*/
-
-static unsigned int atapi_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
+static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
{
- struct scsi_cmnd *cmd = qc->scsicmd;
+ struct scsi_cmnd *scmd = qc->scsicmd;
struct ata_device *dev = qc->dev;
int using_pio = (dev->flags & ATA_DFLAG_PIO);
- int nodata = (cmd->sc_data_direction == DMA_NONE);
+ int nodata = (scmd->sc_data_direction == DMA_NONE);
if (!using_pio)
/* Check whether ATAPI DMA is safe */
if (ata_check_atapi_dma(qc))
using_pio = 1;
- memcpy(&qc->cdb, scsicmd, dev->cdb_len);
+ memset(qc->cdb, 0, dev->cdb_len);
+ memcpy(qc->cdb, scmd->cmnd, scmd->cmd_len);
qc->complete_fn = atapi_qc_complete;
qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
- if (cmd->sc_data_direction == DMA_TO_DEVICE) {
+ if (scmd->sc_data_direction == DMA_TO_DEVICE) {
qc->tf.flags |= ATA_TFLAG_WRITE;
DPRINTK("direction: write\n");
}
@@ -2392,12 +2396,12 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
qc->tf.protocol = ATA_PROT_ATAPI_DMA;
qc->tf.feature |= ATAPI_PKT_DMA;
- if (atapi_dmadir && (cmd->sc_data_direction != DMA_TO_DEVICE))
+ if (atapi_dmadir && (scmd->sc_data_direction != DMA_TO_DEVICE))
/* some SATA bridges need us to indicate data xfer direction */
qc->tf.feature |= ATAPI_DMADIR;
}
- qc->nbytes = cmd->request_bufflen;
+ qc->nbytes = scmd->request_bufflen;
return 0;
}
@@ -2517,28 +2521,27 @@ ata_scsi_map_proto(u8 byte1)
/**
* ata_scsi_pass_thru - convert ATA pass-thru CDB to taskfile
* @qc: command structure to be initialized
- * @scsicmd: SCSI command to convert
*
* Handles either 12 or 16-byte versions of the CDB.
*
* RETURNS:
* Zero on success, non-zero on failure.
*/
-static unsigned int
-ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd)
+static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
{
struct ata_taskfile *tf = &(qc->tf);
- struct scsi_cmnd *cmd = qc->scsicmd;
+ struct scsi_cmnd *scmd = qc->scsicmd;
struct ata_device *dev = qc->dev;
+ const u8 *cdb = scmd->cmnd;
- if ((tf->protocol = ata_scsi_map_proto(scsicmd[1])) == ATA_PROT_UNKNOWN)
+ if ((tf->protocol = ata_scsi_map_proto(cdb[1])) == ATA_PROT_UNKNOWN)
goto invalid_fld;
/* We may not issue DMA commands if no DMA mode is set */
if (tf->protocol == ATA_PROT_DMA && dev->dma_mode == 0)
goto invalid_fld;
- if (scsicmd[1] & 0xe0)
+ if (cdb[1] & 0xe0)
/* PIO multi not supported yet */
goto invalid_fld;
@@ -2546,18 +2549,18 @@ ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd)
* 12 and 16 byte CDBs use different offsets to
* provide the various register values.
*/
- if (scsicmd[0] == ATA_16) {
+ if (cdb[0] == ATA_16) {
/*
* 16-byte CDB - may contain extended commands.
*
* If that is the case, copy the upper byte register values.
*/
- if (scsicmd[1] & 0x01) {
- tf->hob_feature = scsicmd[3];
- tf->hob_nsect = scsicmd[5];
- tf->hob_lbal = scsicmd[7];
- tf->hob_lbam = scsicmd[9];
- tf->hob_lbah = scsicmd[11];
+ if (cdb[1] & 0x01) {
+ tf->hob_feature = cdb[3];
+ tf->hob_nsect = cdb[5];
+ tf->hob_lbal = cdb[7];
+ tf->hob_lbam = cdb[9];
+ tf->hob_lbah = cdb[11];
tf->flags |= ATA_TFLAG_LBA48;
} else
tf->flags &= ~ATA_TFLAG_LBA48;
@@ -2565,26 +2568,26 @@ ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd)
/*
* Always copy low byte, device and command registers.
*/
- tf->feature = scsicmd[4];
- tf->nsect = scsicmd[6];
- tf->lbal = scsicmd[8];
- tf->lbam = scsicmd[10];
- tf->lbah = scsicmd[12];
- tf->device = scsicmd[13];
- tf->command = scsicmd[14];
+ tf->feature = cdb[4];
+ tf->nsect = cdb[6];
+ tf->lbal = cdb[8];
+ tf->lbam = cdb[10];
+ tf->lbah = cdb[12];
+ tf->device = cdb[13];
+ tf->command = cdb[14];
} else {
/*
* 12-byte CDB - incapable of extended commands.
*/
tf->flags &= ~ATA_TFLAG_LBA48;
- tf->feature = scsicmd[3];
- tf->nsect = scsicmd[4];
- tf->lbal = scsicmd[5];
- tf->lbam = scsicmd[6];
- tf->lbah = scsicmd[7];
- tf->device = scsicmd[8];
- tf->command = scsicmd[9];
+ tf->feature = cdb[3];
+ tf->nsect = cdb[4];
+ tf->lbal = cdb[5];
+ tf->lbam = cdb[6];
+ tf->lbah = cdb[7];
+ tf->device = cdb[8];
+ tf->command = cdb[9];
}
/*
* If slave is possible, enforce correct master/slave bit
@@ -2611,7 +2614,7 @@ ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd)
*/
tf->flags |= (ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE);
- if (cmd->sc_data_direction == DMA_TO_DEVICE)
+ if (scmd->sc_data_direction == DMA_TO_DEVICE)
tf->flags |= ATA_TFLAG_WRITE;
/*
@@ -2620,7 +2623,7 @@ ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd)
* TODO: find out if we need to do more here to
* cover scatter/gather case.
*/
- qc->nsect = cmd->request_bufflen / ATA_SECT_SIZE;
+ qc->nsect = scmd->request_bufflen / ATA_SECT_SIZE;
/* request result TF */
qc->flags |= ATA_QCFLAG_RESULT_TF;
@@ -2628,7 +2631,7 @@ ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd)
return 0;
invalid_fld:
- ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x00);
+ ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x00);
/* "Invalid field in cdb" */
return 1;
}
@@ -2701,22 +2704,29 @@ static inline void ata_scsi_dump_cdb(struct ata_port *ap,
#endif
}
-static inline int __ata_scsi_queuecmd(struct scsi_cmnd *cmd,
+static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd,
void (*done)(struct scsi_cmnd *),
struct ata_device *dev)
{
int rc = 0;
+ if (unlikely(!scmd->cmd_len)) {
+ ata_dev_printk(dev, KERN_WARNING, "WARNING: zero len CDB\n");
+ scmd->result = DID_ERROR << 16;
+ done(scmd);
+ return 0;
+ }
+
if (dev->class == ATA_DEV_ATA) {
ata_xlat_func_t xlat_func = ata_get_xlat_func(dev,
- cmd->cmnd[0]);
+ scmd->cmnd[0]);
if (xlat_func)
- rc = ata_scsi_translate(dev, cmd, done, xlat_func);
+ rc = ata_scsi_translate(dev, scmd, done, xlat_func);
else
- ata_scsi_simulate(dev, cmd, done);
+ ata_scsi_simulate(dev, scmd, done);
} else
- rc = ata_scsi_translate(dev, cmd, done, atapi_xlat);
+ rc = ata_scsi_translate(dev, scmd, done, atapi_xlat);
return rc;
}
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 10ee22ae5c15..623cec914c9b 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -1027,13 +1027,15 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
#endif
}
- rc = pci_request_regions(pdev, DRV_NAME);
- if (rc) {
- disable_dev_on_err = 0;
- goto err_out;
- }
-
- if (legacy_mode) {
+ if (!legacy_mode) {
+ rc = pci_request_regions(pdev, DRV_NAME);
+ if (rc) {
+ disable_dev_on_err = 0;
+ goto err_out;
+ }
+ } else {
+ /* Deal with combined mode hack. This side of the logic all
+ goes away once the combined mode hack is killed in 2.6.21 */
if (!request_region(ATA_PRIMARY_CMD, 8, "libata")) {
struct resource *conflict, res;
res.start = ATA_PRIMARY_CMD;
@@ -1071,6 +1073,13 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
}
} else
legacy_mode |= ATA_PORT_SECONDARY;
+
+ if (legacy_mode & ATA_PORT_PRIMARY)
+ pci_request_region(pdev, 1, DRV_NAME);
+ if (legacy_mode & ATA_PORT_SECONDARY)
+ pci_request_region(pdev, 3, DRV_NAME);
+ /* If there is a DMA resource, allocate it */
+ pci_request_region(pdev, 4, DRV_NAME);
}
/* we have legacy mode, but all ports are unavailable */
@@ -1114,11 +1123,20 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
err_out_ent:
kfree(probe_ent);
err_out_regions:
- if (legacy_mode & ATA_PORT_PRIMARY)
- release_region(ATA_PRIMARY_CMD, 8);
- if (legacy_mode & ATA_PORT_SECONDARY)
- release_region(ATA_SECONDARY_CMD, 8);
- pci_release_regions(pdev);
+ /* All this conditional stuff is needed for the combined mode hack
+ until 2.6.21 when it can go */
+ if (legacy_mode) {
+ pci_release_region(pdev, 4);
+ if (legacy_mode & ATA_PORT_PRIMARY) {
+ release_region(ATA_PRIMARY_CMD, 8);
+ pci_release_region(pdev, 1);
+ }
+ if (legacy_mode & ATA_PORT_SECONDARY) {
+ release_region(ATA_SECONDARY_CMD, 8);
+ pci_release_region(pdev, 3);
+ }
+ } else
+ pci_release_regions(pdev);
err_out:
if (disable_dev_on_err)
pci_disable_device(pdev);
diff --git a/drivers/ata/pata_cs5530.c b/drivers/ata/pata_cs5530.c
index 1c628014dae6..b1ca207e3545 100644
--- a/drivers/ata/pata_cs5530.c
+++ b/drivers/ata/pata_cs5530.c
@@ -372,7 +372,8 @@ static int cs5530_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
static int cs5530_reinit_one(struct pci_dev *pdev)
{
/* If we fail on resume we are doomed */
- BUG_ON(cs5530_init_chip());
+ if (cs5530_init_chip())
+ BUG();
return ata_pci_device_resume(pdev);
}
diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c
index c7d1738e4e69..e7bf9d89c8ee 100644
--- a/drivers/ata/pata_legacy.c
+++ b/drivers/ata/pata_legacy.c
@@ -698,8 +698,10 @@ static __init int legacy_init_one(int port, unsigned long io, unsigned long ctrl
goto fail_io;
pdev = platform_device_register_simple(DRV_NAME, nr_legacy_host, NULL, 0);
- if (pdev == NULL)
+ if (IS_ERR(pdev)) {
+ ret = PTR_ERR(pdev);
goto fail_dev;
+ }
if (ht6560a & mask) {
ops = &ht6560a_port_ops;
diff --git a/drivers/ata/pata_qdi.c b/drivers/ata/pata_qdi.c
index 36f621abc390..afc0d990e7d6 100644
--- a/drivers/ata/pata_qdi.c
+++ b/drivers/ata/pata_qdi.c
@@ -247,8 +247,8 @@ static __init int qdi_init_one(unsigned long port, int type, unsigned long io, i
*/
pdev = platform_device_register_simple(DRV_NAME, nr_qdi_host, NULL, 0);
- if (pdev == NULL)
- return -ENOMEM;
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
memset(&ae, 0, sizeof(struct ata_probe_ent));
INIT_LIST_HEAD(&ae.node);
diff --git a/drivers/ata/pata_rz1000.c b/drivers/ata/pata_rz1000.c
index 3677c642c9f9..adf4cc134f25 100644
--- a/drivers/ata/pata_rz1000.c
+++ b/drivers/ata/pata_rz1000.c
@@ -105,8 +105,6 @@ static struct ata_port_operations rz1000_port_ops = {
.exec_command = ata_exec_command,
.dev_select = ata_std_dev_select,
- .error_handler = rz1000_error_handler,
-
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
.bmdma_stop = ata_bmdma_stop,
diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c
index cc09d47fb927..f0d4f7e9ed31 100644
--- a/drivers/ata/pata_via.c
+++ b/drivers/ata/pata_via.c
@@ -161,10 +161,15 @@ static int via_pre_reset(struct ata_port *ap)
return -ENOENT;
}
- if ((config->flags & VIA_UDMA) >= VIA_UDMA_66)
+ if ((config->flags & VIA_UDMA) >= VIA_UDMA_100)
ap->cbl = via_cable_detect(ap);
- else
+ /* The UDMA66 series has no cable detect so do drive side detect */
+ else if ((config->flags & VIA_UDMA) < VIA_UDMA_66)
ap->cbl = ATA_CBL_PATA40;
+ else
+ ap->cbl = ATA_CBL_PATA_UNK;
+
+
return ata_std_prereset(ap);
}
@@ -390,7 +395,7 @@ static void via_config_fifo(struct pci_dev *pdev, unsigned int flags)
enable &= 3;
if (flags & VIA_SET_FIFO) {
- u8 fifo_setting[4] = {0x00, 0x60, 0x00, 0x20};
+ static const u8 fifo_setting[4] = {0x00, 0x60, 0x00, 0x20};
u8 fifo;
pci_read_config_byte(pdev, 0x43, &fifo);
diff --git a/drivers/ata/pata_winbond.c b/drivers/ata/pata_winbond.c
index 3ea345cde52e..5d1f518e1cc7 100644
--- a/drivers/ata/pata_winbond.c
+++ b/drivers/ata/pata_winbond.c
@@ -206,8 +206,8 @@ static __init int winbond_init_one(unsigned long port)
*/
pdev = platform_device_register_simple(DRV_NAME, nr_winbond_host, NULL, 0);
- if (pdev == NULL)
- return -ENOMEM;
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
memset(&ae, 0, sizeof(struct ata_probe_ent));
INIT_LIST_HEAD(&ae.node);
diff --git a/drivers/ata/pdc_adma.c b/drivers/ata/pdc_adma.c
index 9021e34d2096..90786d7a20bb 100644
--- a/drivers/ata/pdc_adma.c
+++ b/drivers/ata/pdc_adma.c
@@ -551,7 +551,7 @@ static int adma_port_start(struct ata_port *ap)
return rc;
adma_enter_reg_mode(ap);
rc = -ENOMEM;
- pp = kcalloc(1, sizeof(*pp), GFP_KERNEL);
+ pp = kzalloc(sizeof(*pp), GFP_KERNEL);
if (!pp)
goto err_out;
pp->pkt = dma_alloc_coherent(dev, ADMA_PKT_BYTES, &pp->pkt_dma,
@@ -672,7 +672,7 @@ static int adma_ata_init_one(struct pci_dev *pdev,
if (rc)
goto err_out_iounmap;
- probe_ent = kcalloc(1, sizeof(*probe_ent), GFP_KERNEL);
+ probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL);
if (probe_ent == NULL) {
rc = -ENOMEM;
goto err_out_iounmap;
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index 0d316eb3c214..f6d498e1cf80 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -270,14 +270,6 @@ static const struct pci_device_id nv_pci_tbl[] = {
{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA), GENERIC },
{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2), GENERIC },
{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3), GENERIC },
- { PCI_VDEVICE(NVIDIA, 0x045c), GENERIC }, /* MCP65 */
- { PCI_VDEVICE(NVIDIA, 0x045d), GENERIC }, /* MCP65 */
- { PCI_VDEVICE(NVIDIA, 0x045e), GENERIC }, /* MCP65 */
- { PCI_VDEVICE(NVIDIA, 0x045f), GENERIC }, /* MCP65 */
- { PCI_VDEVICE(NVIDIA, 0x0550), GENERIC }, /* MCP67 */
- { PCI_VDEVICE(NVIDIA, 0x0551), GENERIC }, /* MCP67 */
- { PCI_VDEVICE(NVIDIA, 0x0552), GENERIC }, /* MCP67 */
- { PCI_VDEVICE(NVIDIA, 0x0553), GENERIC }, /* MCP67 */
{ PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
PCI_ANY_ID, PCI_ANY_ID,
PCI_CLASS_STORAGE_IDE<<8, 0xffff00, GENERIC },
diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c
index db32d15b7fa1..46d8a94669b4 100644
--- a/drivers/ata/sata_svw.c
+++ b/drivers/ata/sata_svw.c
@@ -56,6 +56,8 @@
#define DRV_VERSION "2.0"
enum {
+ K2_FLAG_NO_ATAPI_DMA = (1 << 29),
+
/* Taskfile registers offsets */
K2_SATA_TF_CMD_OFFSET = 0x00,
K2_SATA_TF_DATA_OFFSET = 0x00,
@@ -83,11 +85,33 @@ enum {
/* Port stride */
K2_SATA_PORT_OFFSET = 0x100,
+
+ board_svw4 = 0,
+ board_svw8 = 1,
+};
+
+static const struct k2_board_info {
+ unsigned int n_ports;
+ unsigned long port_flags;
+} k2_board_info[] = {
+ /* board_svw4 */
+ { 4, K2_FLAG_NO_ATAPI_DMA },
+
+ /* board_svw8 */
+ { 8, K2_FLAG_NO_ATAPI_DMA },
};
static u8 k2_stat_check_status(struct ata_port *ap);
+static int k2_sata_check_atapi_dma(struct ata_queued_cmd *qc)
+{
+ if (qc->ap->flags & K2_FLAG_NO_ATAPI_DMA)
+ return -1; /* ATAPI DMA not supported */
+
+ return 0;
+}
+
static u32 k2_sata_scr_read (struct ata_port *ap, unsigned int sc_reg)
{
if (sc_reg > SCR_CONTROL)
@@ -111,26 +135,31 @@ static void k2_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
if (tf->ctl != ap->last_ctl) {
- writeb(tf->ctl, ioaddr->ctl_addr);
+ writeb(tf->ctl, (void __iomem *) ioaddr->ctl_addr);
ap->last_ctl = tf->ctl;
ata_wait_idle(ap);
}
if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
- writew(tf->feature | (((u16)tf->hob_feature) << 8), ioaddr->feature_addr);
- writew(tf->nsect | (((u16)tf->hob_nsect) << 8), ioaddr->nsect_addr);
- writew(tf->lbal | (((u16)tf->hob_lbal) << 8), ioaddr->lbal_addr);
- writew(tf->lbam | (((u16)tf->hob_lbam) << 8), ioaddr->lbam_addr);
- writew(tf->lbah | (((u16)tf->hob_lbah) << 8), ioaddr->lbah_addr);
+ writew(tf->feature | (((u16)tf->hob_feature) << 8),
+ (void __iomem *) ioaddr->feature_addr);
+ writew(tf->nsect | (((u16)tf->hob_nsect) << 8),
+ (void __iomem *) ioaddr->nsect_addr);
+ writew(tf->lbal | (((u16)tf->hob_lbal) << 8),
+ (void __iomem *) ioaddr->lbal_addr);
+ writew(tf->lbam | (((u16)tf->hob_lbam) << 8),
+ (void __iomem *) ioaddr->lbam_addr);
+ writew(tf->lbah | (((u16)tf->hob_lbah) << 8),
+ (void __iomem *) ioaddr->lbah_addr);
} else if (is_addr) {
- writew(tf->feature, ioaddr->feature_addr);
- writew(tf->nsect, ioaddr->nsect_addr);
- writew(tf->lbal, ioaddr->lbal_addr);
- writew(tf->lbam, ioaddr->lbam_addr);
- writew(tf->lbah, ioaddr->lbah_addr);
+ writew(tf->feature, (void __iomem *) ioaddr->feature_addr);
+ writew(tf->nsect, (void __iomem *) ioaddr->nsect_addr);
+ writew(tf->lbal, (void __iomem *) ioaddr->lbal_addr);
+ writew(tf->lbam, (void __iomem *) ioaddr->lbam_addr);
+ writew(tf->lbah, (void __iomem *) ioaddr->lbah_addr);
}
if (tf->flags & ATA_TFLAG_DEVICE)
- writeb(tf->device, ioaddr->device_addr);
+ writeb(tf->device, (void __iomem *) ioaddr->device_addr);
ata_wait_idle(ap);
}
@@ -142,12 +171,12 @@ static void k2_sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
u16 nsect, lbal, lbam, lbah, feature;
tf->command = k2_stat_check_status(ap);
- tf->device = readw(ioaddr->device_addr);
- feature = readw(ioaddr->error_addr);
- nsect = readw(ioaddr->nsect_addr);
- lbal = readw(ioaddr->lbal_addr);
- lbam = readw(ioaddr->lbam_addr);
- lbah = readw(ioaddr->lbah_addr);
+ tf->device = readw((void __iomem *)ioaddr->device_addr);
+ feature = readw((void __iomem *)ioaddr->error_addr);
+ nsect = readw((void __iomem *)ioaddr->nsect_addr);
+ lbal = readw((void __iomem *)ioaddr->lbal_addr);
+ lbam = readw((void __iomem *)ioaddr->lbam_addr);
+ lbah = readw((void __iomem *)ioaddr->lbah_addr);
tf->feature = feature;
tf->nsect = nsect;
@@ -313,6 +342,7 @@ static const struct ata_port_operations k2_sata_ops = {
.check_status = k2_stat_check_status,
.exec_command = ata_exec_command,
.dev_select = ata_std_dev_select,
+ .check_atapi_dma = k2_sata_check_atapi_dma,
.bmdma_setup = k2_bmdma_setup_mmio,
.bmdma_start = k2_bmdma_start_mmio,
.bmdma_stop = ata_bmdma_stop,
@@ -359,6 +389,8 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
struct ata_probe_ent *probe_ent = NULL;
unsigned long base;
void __iomem *mmio_base;
+ const struct k2_board_info *board_info =
+ &k2_board_info[ent->driver_data];
int pci_dev_busy = 0;
int rc;
int i;
@@ -424,7 +456,7 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
probe_ent->sht = &k2_sata_sht;
probe_ent->port_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
- ATA_FLAG_MMIO;
+ ATA_FLAG_MMIO | board_info->port_flags;
probe_ent->port_ops = &k2_sata_ops;
probe_ent->n_ports = 4;
probe_ent->irq = pdev->irq;
@@ -441,7 +473,7 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
/* different controllers have different number of ports - currently 4 or 8 */
/* All ports are on the same function. Multi-function device is no
* longer available. This should not be seen in any system. */
- for (i = 0; i < ent->driver_data; i++)
+ for (i = 0; i < board_info->n_ports; i++)
k2_sata_setup_port(&probe_ent->port[i], base + i * K2_SATA_PORT_OFFSET);
pci_set_master(pdev);
@@ -469,11 +501,11 @@ err_out:
* controller
* */
static const struct pci_device_id k2_sata_pci_tbl[] = {
- { PCI_VDEVICE(SERVERWORKS, 0x0240), 4 },
- { PCI_VDEVICE(SERVERWORKS, 0x0241), 4 },
- { PCI_VDEVICE(SERVERWORKS, 0x0242), 8 },
- { PCI_VDEVICE(SERVERWORKS, 0x024a), 4 },
- { PCI_VDEVICE(SERVERWORKS, 0x024b), 4 },
+ { PCI_VDEVICE(SERVERWORKS, 0x0240), board_svw4 },
+ { PCI_VDEVICE(SERVERWORKS, 0x0241), board_svw4 },
+ { PCI_VDEVICE(SERVERWORKS, 0x0242), board_svw8 },
+ { PCI_VDEVICE(SERVERWORKS, 0x024a), board_svw4 },
+ { PCI_VDEVICE(SERVERWORKS, 0x024b), board_svw4 },
{ }
};
diff --git a/drivers/ata/sata_vsc.c b/drivers/ata/sata_vsc.c
index e654b990b905..0fa1b89f76d5 100644
--- a/drivers/ata/sata_vsc.c
+++ b/drivers/ata/sata_vsc.c
@@ -149,21 +149,26 @@ static void vsc_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
vsc_intr_mask_update(ap, tf->ctl & ATA_NIEN);
}
if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
- writew(tf->feature | (((u16)tf->hob_feature) << 8), ioaddr->feature_addr);
- writew(tf->nsect | (((u16)tf->hob_nsect) << 8), ioaddr->nsect_addr);
- writew(tf->lbal | (((u16)tf->hob_lbal) << 8), ioaddr->lbal_addr);
- writew(tf->lbam | (((u16)tf->hob_lbam) << 8), ioaddr->lbam_addr);
- writew(tf->lbah | (((u16)tf->hob_lbah) << 8), ioaddr->lbah_addr);
+ writew(tf->feature | (((u16)tf->hob_feature) << 8),
+ (void __iomem *) ioaddr->feature_addr);
+ writew(tf->nsect | (((u16)tf->hob_nsect) << 8),
+ (void __iomem *) ioaddr->nsect_addr);
+ writew(tf->lbal | (((u16)tf->hob_lbal) << 8),
+ (void __iomem *) ioaddr->lbal_addr);
+ writew(tf->lbam | (((u16)tf->hob_lbam) << 8),
+ (void __iomem *) ioaddr->lbam_addr);
+ writew(tf->lbah | (((u16)tf->hob_lbah) << 8),
+ (void __iomem *) ioaddr->lbah_addr);
} else if (is_addr) {
- writew(tf->feature, ioaddr->feature_addr);
- writew(tf->nsect, ioaddr->nsect_addr);
- writew(tf->lbal, ioaddr->lbal_addr);
- writew(tf->lbam, ioaddr->lbam_addr);
- writew(tf->lbah, ioaddr->lbah_addr);
+ writew(tf->feature, (void __iomem *) ioaddr->feature_addr);
+ writew(tf->nsect, (void __iomem *) ioaddr->nsect_addr);
+ writew(tf->lbal, (void __iomem *) ioaddr->lbal_addr);
+ writew(tf->lbam, (void __iomem *) ioaddr->lbam_addr);
+ writew(tf->lbah, (void __iomem *) ioaddr->lbah_addr);
}
if (tf->flags & ATA_TFLAG_DEVICE)
- writeb(tf->device, ioaddr->device_addr);
+ writeb(tf->device, (void __iomem *) ioaddr->device_addr);
ata_wait_idle(ap);
}
@@ -175,12 +180,12 @@ static void vsc_sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
u16 nsect, lbal, lbam, lbah, feature;
tf->command = ata_check_status(ap);
- tf->device = readw(ioaddr->device_addr);
- feature = readw(ioaddr->error_addr);
- nsect = readw(ioaddr->nsect_addr);
- lbal = readw(ioaddr->lbal_addr);
- lbam = readw(ioaddr->lbam_addr);
- lbah = readw(ioaddr->lbah_addr);
+ tf->device = readw((void __iomem *) ioaddr->device_addr);
+ feature = readw((void __iomem *) ioaddr->error_addr);
+ nsect = readw((void __iomem *) ioaddr->nsect_addr);
+ lbal = readw((void __iomem *) ioaddr->lbal_addr);
+ lbam = readw((void __iomem *) ioaddr->lbam_addr);
+ lbah = readw((void __iomem *) ioaddr->lbah_addr);
tf->feature = feature;
tf->nsect = nsect;
@@ -327,8 +332,8 @@ static void __devinit vsc_sata_setup_port(struct ata_ioports *port, unsigned lon
port->ctl_addr = base + VSC_SATA_TF_CTL_OFFSET;
port->bmdma_addr = base + VSC_SATA_DMA_CMD_OFFSET;
port->scr_addr = base + VSC_SATA_SCR_STATUS_OFFSET;
- writel(0, base + VSC_SATA_UP_DESCRIPTOR_OFFSET);
- writel(0, base + VSC_SATA_UP_DATA_BUFFER_OFFSET);
+ writel(0, (void __iomem *) base + VSC_SATA_UP_DESCRIPTOR_OFFSET);
+ writel(0, (void __iomem *) base + VSC_SATA_UP_DATA_BUFFER_OFFSET);
}
diff --git a/drivers/atm/Kconfig b/drivers/atm/Kconfig
index 2ddd76fdbc43..33687454eb32 100644
--- a/drivers/atm/Kconfig
+++ b/drivers/atm/Kconfig
@@ -167,10 +167,6 @@ config ATM_ZATM_DEBUG
Note that extended debugging may create certain race conditions
itself. Enable this ONLY if you suspect problems with the driver.
-# bool 'Rolfs TI TNETA1570' CONFIG_ATM_TNETA1570 y
-# if [ "$CONFIG_ATM_TNETA1570" = "y" ]; then
-# bool ' Enable extended debugging' CONFIG_ATM_TNETA1570_DEBUG n
-# fi
config ATM_NICSTAR
tristate "IDT 77201 (NICStAR) (ForeRunnerLE)"
depends on PCI && ATM && !64BIT
diff --git a/drivers/atm/eni.c b/drivers/atm/eni.c
index bc1b13c8f5d7..5aab7bd473ac 100644
--- a/drivers/atm/eni.c
+++ b/drivers/atm/eni.c
@@ -1832,7 +1832,7 @@ static int __devinit eni_start(struct atm_dev *dev)
/* initialize memory management */
buffer_mem = eni_dev->mem - (buf - eni_dev->ram);
eni_dev->free_list_size = buffer_mem/MID_MIN_BUF_SIZE/2;
- eni_dev->free_list = (struct eni_free *) kmalloc(
+ eni_dev->free_list = kmalloc(
sizeof(struct eni_free)*(eni_dev->free_list_size+1),GFP_KERNEL);
if (!eni_dev->free_list) {
printk(KERN_ERR DEV_LABEL "(itf %d): couldn't get free page\n",
@@ -2232,7 +2232,7 @@ static int __devinit eni_init_one(struct pci_dev *pci_dev,
goto out0;
}
- eni_dev = (struct eni_dev *) kmalloc(sizeof(struct eni_dev),GFP_KERNEL);
+ eni_dev = kmalloc(sizeof(struct eni_dev),GFP_KERNEL);
if (!eni_dev) goto out0;
if (!cpu_zeroes) {
cpu_zeroes = pci_alloc_consistent(pci_dev,ENI_ZEROES_SIZE,
diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c
index 3a7b21ff30a5..4aeb3d062ff6 100644
--- a/drivers/atm/fore200e.c
+++ b/drivers/atm/fore200e.c
@@ -172,25 +172,6 @@ fore200e_irq_itoa(int irq)
}
-static void*
-fore200e_kmalloc(int size, gfp_t flags)
-{
- void *chunk = kzalloc(size, flags);
-
- if (!chunk)
- printk(FORE200E "kmalloc() failed, requested size = %d, flags = 0x%x\n", size, flags);
-
- return chunk;
-}
-
-
-static void
-fore200e_kfree(void* chunk)
-{
- kfree(chunk);
-}
-
-
/* allocate and align a chunk of memory intended to hold the data behing exchanged
between the driver and the adapter (using streaming DVMA) */
@@ -206,7 +187,7 @@ fore200e_chunk_alloc(struct fore200e* fore200e, struct chunk* chunk, int size, i
chunk->align_size = size;
chunk->direction = direction;
- chunk->alloc_addr = fore200e_kmalloc(chunk->alloc_size, GFP_KERNEL | GFP_DMA);
+ chunk->alloc_addr = kzalloc(chunk->alloc_size, GFP_KERNEL | GFP_DMA);
if (chunk->alloc_addr == NULL)
return -ENOMEM;
@@ -228,7 +209,7 @@ fore200e_chunk_free(struct fore200e* fore200e, struct chunk* chunk)
{
fore200e->bus->dma_unmap(fore200e, chunk->dma_addr, chunk->dma_size, chunk->direction);
- fore200e_kfree(chunk->alloc_addr);
+ kfree(chunk->alloc_addr);
}
@@ -882,7 +863,7 @@ fore200e_sba_detect(const struct fore200e_bus* bus, int index)
return NULL;
}
- fore200e = fore200e_kmalloc(sizeof(struct fore200e), GFP_KERNEL);
+ fore200e = kzalloc(sizeof(struct fore200e), GFP_KERNEL);
if (fore200e == NULL)
return NULL;
@@ -1505,7 +1486,7 @@ fore200e_open(struct atm_vcc *vcc)
spin_unlock_irqrestore(&fore200e->q_lock, flags);
- fore200e_vcc = fore200e_kmalloc(sizeof(struct fore200e_vcc), GFP_ATOMIC);
+ fore200e_vcc = kzalloc(sizeof(struct fore200e_vcc), GFP_ATOMIC);
if (fore200e_vcc == NULL) {
vc_map->vcc = NULL;
return -ENOMEM;
@@ -1526,7 +1507,7 @@ fore200e_open(struct atm_vcc *vcc)
if (fore200e->available_cell_rate < vcc->qos.txtp.max_pcr) {
up(&fore200e->rate_sf);
- fore200e_kfree(fore200e_vcc);
+ kfree(fore200e_vcc);
vc_map->vcc = NULL;
return -EAGAIN;
}
@@ -1554,7 +1535,7 @@ fore200e_open(struct atm_vcc *vcc)
fore200e->available_cell_rate += vcc->qos.txtp.max_pcr;
- fore200e_kfree(fore200e_vcc);
+ kfree(fore200e_vcc);
return -EINVAL;
}
@@ -1630,7 +1611,7 @@ fore200e_close(struct atm_vcc* vcc)
clear_bit(ATM_VF_PARTIAL,&vcc->flags);
ASSERT(fore200e_vcc);
- fore200e_kfree(fore200e_vcc);
+ kfree(fore200e_vcc);
}
@@ -1831,7 +1812,7 @@ fore200e_getstats(struct fore200e* fore200e)
u32 stats_dma_addr;
if (fore200e->stats == NULL) {
- fore200e->stats = fore200e_kmalloc(sizeof(struct stats), GFP_KERNEL | GFP_DMA);
+ fore200e->stats = kzalloc(sizeof(struct stats), GFP_KERNEL | GFP_DMA);
if (fore200e->stats == NULL)
return -ENOMEM;
}
@@ -2002,17 +1983,6 @@ fore200e_setloop(struct fore200e* fore200e, int loop_mode)
}
-static inline unsigned int
-fore200e_swap(unsigned int in)
-{
-#if defined(__LITTLE_ENDIAN)
- return swab32(in);
-#else
- return in;
-#endif
-}
-
-
static int
fore200e_fetch_stats(struct fore200e* fore200e, struct sonet_stats __user *arg)
{
@@ -2021,19 +1991,19 @@ fore200e_fetch_stats(struct fore200e* fore200e, struct sonet_stats __user *arg)
if (fore200e_getstats(fore200e) < 0)
return -EIO;
- tmp.section_bip = fore200e_swap(fore200e->stats->oc3.section_bip8_errors);
- tmp.line_bip = fore200e_swap(fore200e->stats->oc3.line_bip24_errors);
- tmp.path_bip = fore200e_swap(fore200e->stats->oc3.path_bip8_errors);
- tmp.line_febe = fore200e_swap(fore200e->stats->oc3.line_febe_errors);
- tmp.path_febe = fore200e_swap(fore200e->stats->oc3.path_febe_errors);
- tmp.corr_hcs = fore200e_swap(fore200e->stats->oc3.corr_hcs_errors);
- tmp.uncorr_hcs = fore200e_swap(fore200e->stats->oc3.ucorr_hcs_errors);
- tmp.tx_cells = fore200e_swap(fore200e->stats->aal0.cells_transmitted) +
- fore200e_swap(fore200e->stats->aal34.cells_transmitted) +
- fore200e_swap(fore200e->stats->aal5.cells_transmitted);
- tmp.rx_cells = fore200e_swap(fore200e->stats->aal0.cells_received) +
- fore200e_swap(fore200e->stats->aal34.cells_received) +
- fore200e_swap(fore200e->stats->aal5.cells_received);
+ tmp.section_bip = cpu_to_be32(fore200e->stats->oc3.section_bip8_errors);
+ tmp.line_bip = cpu_to_be32(fore200e->stats->oc3.line_bip24_errors);
+ tmp.path_bip = cpu_to_be32(fore200e->stats->oc3.path_bip8_errors);
+ tmp.line_febe = cpu_to_be32(fore200e->stats->oc3.line_febe_errors);
+ tmp.path_febe = cpu_to_be32(fore200e->stats->oc3.path_febe_errors);
+ tmp.corr_hcs = cpu_to_be32(fore200e->stats->oc3.corr_hcs_errors);
+ tmp.uncorr_hcs = cpu_to_be32(fore200e->stats->oc3.ucorr_hcs_errors);
+ tmp.tx_cells = cpu_to_be32(fore200e->stats->aal0.cells_transmitted) +
+ cpu_to_be32(fore200e->stats->aal34.cells_transmitted) +
+ cpu_to_be32(fore200e->stats->aal5.cells_transmitted);
+ tmp.rx_cells = cpu_to_be32(fore200e->stats->aal0.cells_received) +
+ cpu_to_be32(fore200e->stats->aal34.cells_received) +
+ cpu_to_be32(fore200e->stats->aal5.cells_received);
if (arg)
return copy_to_user(arg, &tmp, sizeof(struct sonet_stats)) ? -EFAULT : 0;
@@ -2146,7 +2116,7 @@ fore200e_irq_request(struct fore200e* fore200e)
static int __devinit
fore200e_get_esi(struct fore200e* fore200e)
{
- struct prom_data* prom = fore200e_kmalloc(sizeof(struct prom_data), GFP_KERNEL | GFP_DMA);
+ struct prom_data* prom = kzalloc(sizeof(struct prom_data), GFP_KERNEL | GFP_DMA);
int ok, i;
if (!prom)
@@ -2154,7 +2124,7 @@ fore200e_get_esi(struct fore200e* fore200e)
ok = fore200e->bus->prom_read(fore200e, prom);
if (ok < 0) {
- fore200e_kfree(prom);
+ kfree(prom);
return -EBUSY;
}
@@ -2169,7 +2139,7 @@ fore200e_get_esi(struct fore200e* fore200e)
fore200e->esi[ i ] = fore200e->atm_dev->esi[ i ] = prom->mac_addr[ i + 2 ];
}
- fore200e_kfree(prom);
+ kfree(prom);
return 0;
}
@@ -2194,7 +2164,7 @@ fore200e_alloc_rx_buf(struct fore200e* fore200e)
DPRINTK(2, "rx buffers %d / %d are being allocated\n", scheme, magn);
/* allocate the array of receive buffers */
- buffer = bsq->buffer = fore200e_kmalloc(nbr * sizeof(struct buffer), GFP_KERNEL);
+ buffer = bsq->buffer = kzalloc(nbr * sizeof(struct buffer), GFP_KERNEL);
if (buffer == NULL)
return -ENOMEM;
@@ -2217,7 +2187,7 @@ fore200e_alloc_rx_buf(struct fore200e* fore200e)
while (i > 0)
fore200e_chunk_free(fore200e, &buffer[ --i ].data);
- fore200e_kfree(buffer);
+ kfree(buffer);
return -ENOMEM;
}
@@ -2736,7 +2706,7 @@ fore200e_pca_detect(struct pci_dev *pci_dev, const struct pci_device_id *pci_ent
goto out;
}
- fore200e = fore200e_kmalloc(sizeof(struct fore200e), GFP_KERNEL);
+ fore200e = kzalloc(sizeof(struct fore200e), GFP_KERNEL);
if (fore200e == NULL) {
err = -ENOMEM;
goto out_disable;
@@ -2999,8 +2969,8 @@ fore200e_proc_read(struct atm_dev *dev, loff_t* pos, char* page)
" 4b5b:\n"
" crc_header_errors:\t\t%10u\n"
" framing_errors:\t\t%10u\n",
- fore200e_swap(fore200e->stats->phy.crc_header_errors),
- fore200e_swap(fore200e->stats->phy.framing_errors));
+ cpu_to_be32(fore200e->stats->phy.crc_header_errors),
+ cpu_to_be32(fore200e->stats->phy.framing_errors));
if (!left--)
return sprintf(page, "\n"
@@ -3012,13 +2982,13 @@ fore200e_proc_read(struct atm_dev *dev, loff_t* pos, char* page)
" path_febe_errors:\t\t%10u\n"
" corr_hcs_errors:\t\t%10u\n"
" ucorr_hcs_errors:\t\t%10u\n",
- fore200e_swap(fore200e->stats->oc3.section_bip8_errors),
- fore200e_swap(fore200e->stats->oc3.path_bip8_errors),
- fore200e_swap(fore200e->stats->oc3.line_bip24_errors),
- fore200e_swap(fore200e->stats->oc3.line_febe_errors),
- fore200e_swap(fore200e->stats->oc3.path_febe_errors),
- fore200e_swap(fore200e->stats->oc3.corr_hcs_errors),
- fore200e_swap(fore200e->stats->oc3.ucorr_hcs_errors));
+ cpu_to_be32(fore200e->stats->oc3.section_bip8_errors),
+ cpu_to_be32(fore200e->stats->oc3.path_bip8_errors),
+ cpu_to_be32(fore200e->stats->oc3.line_bip24_errors),
+ cpu_to_be32(fore200e->stats->oc3.line_febe_errors),
+ cpu_to_be32(fore200e->stats->oc3.path_febe_errors),
+ cpu_to_be32(fore200e->stats->oc3.corr_hcs_errors),
+ cpu_to_be32(fore200e->stats->oc3.ucorr_hcs_errors));
if (!left--)
return sprintf(page,"\n"
@@ -3029,12 +2999,12 @@ fore200e_proc_read(struct atm_dev *dev, loff_t* pos, char* page)
" vpi no conn:\t\t%10u\n"
" vci out of range:\t\t%10u\n"
" vci no conn:\t\t%10u\n",
- fore200e_swap(fore200e->stats->atm.cells_transmitted),
- fore200e_swap(fore200e->stats->atm.cells_received),
- fore200e_swap(fore200e->stats->atm.vpi_bad_range),
- fore200e_swap(fore200e->stats->atm.vpi_no_conn),
- fore200e_swap(fore200e->stats->atm.vci_bad_range),
- fore200e_swap(fore200e->stats->atm.vci_no_conn));
+ cpu_to_be32(fore200e->stats->atm.cells_transmitted),
+ cpu_to_be32(fore200e->stats->atm.cells_received),
+ cpu_to_be32(fore200e->stats->atm.vpi_bad_range),
+ cpu_to_be32(fore200e->stats->atm.vpi_no_conn),
+ cpu_to_be32(fore200e->stats->atm.vci_bad_range),
+ cpu_to_be32(fore200e->stats->atm.vci_no_conn));
if (!left--)
return sprintf(page,"\n"
@@ -3042,9 +3012,9 @@ fore200e_proc_read(struct atm_dev *dev, loff_t* pos, char* page)
" TX:\t\t\t%10u\n"
" RX:\t\t\t%10u\n"
" dropped:\t\t\t%10u\n",
- fore200e_swap(fore200e->stats->aal0.cells_transmitted),
- fore200e_swap(fore200e->stats->aal0.cells_received),
- fore200e_swap(fore200e->stats->aal0.cells_dropped));
+ cpu_to_be32(fore200e->stats->aal0.cells_transmitted),
+ cpu_to_be32(fore200e->stats->aal0.cells_received),
+ cpu_to_be32(fore200e->stats->aal0.cells_dropped));
if (!left--)
return sprintf(page,"\n"
@@ -3060,15 +3030,15 @@ fore200e_proc_read(struct atm_dev *dev, loff_t* pos, char* page)
" RX:\t\t\t%10u\n"
" dropped:\t\t\t%10u\n"
" protocol errors:\t\t%10u\n",
- fore200e_swap(fore200e->stats->aal34.cells_transmitted),
- fore200e_swap(fore200e->stats->aal34.cells_received),
- fore200e_swap(fore200e->stats->aal34.cells_dropped),
- fore200e_swap(fore200e->stats->aal34.cells_crc_errors),
- fore200e_swap(fore200e->stats->aal34.cells_protocol_errors),
- fore200e_swap(fore200e->stats->aal34.cspdus_transmitted),
- fore200e_swap(fore200e->stats->aal34.cspdus_received),
- fore200e_swap(fore200e->stats->aal34.cspdus_dropped),
- fore200e_swap(fore200e->stats->aal34.cspdus_protocol_errors));
+ cpu_to_be32(fore200e->stats->aal34.cells_transmitted),
+ cpu_to_be32(fore200e->stats->aal34.cells_received),
+ cpu_to_be32(fore200e->stats->aal34.cells_dropped),
+ cpu_to_be32(fore200e->stats->aal34.cells_crc_errors),
+ cpu_to_be32(fore200e->stats->aal34.cells_protocol_errors),
+ cpu_to_be32(fore200e->stats->aal34.cspdus_transmitted),
+ cpu_to_be32(fore200e->stats->aal34.cspdus_received),
+ cpu_to_be32(fore200e->stats->aal34.cspdus_dropped),
+ cpu_to_be32(fore200e->stats->aal34.cspdus_protocol_errors));
if (!left--)
return sprintf(page,"\n"
@@ -3084,15 +3054,15 @@ fore200e_proc_read(struct atm_dev *dev, loff_t* pos, char* page)
" dropped:\t\t\t%10u\n"
" CRC errors:\t\t%10u\n"
" protocol errors:\t\t%10u\n",
- fore200e_swap(fore200e->stats->aal5.cells_transmitted),
- fore200e_swap(fore200e->stats->aal5.cells_received),
- fore200e_swap(fore200e->stats->aal5.cells_dropped),
- fore200e_swap(fore200e->stats->aal5.congestion_experienced),
- fore200e_swap(fore200e->stats->aal5.cspdus_transmitted),
- fore200e_swap(fore200e->stats->aal5.cspdus_received),
- fore200e_swap(fore200e->stats->aal5.cspdus_dropped),
- fore200e_swap(fore200e->stats->aal5.cspdus_crc_errors),
- fore200e_swap(fore200e->stats->aal5.cspdus_protocol_errors));
+ cpu_to_be32(fore200e->stats->aal5.cells_transmitted),
+ cpu_to_be32(fore200e->stats->aal5.cells_received),
+ cpu_to_be32(fore200e->stats->aal5.cells_dropped),
+ cpu_to_be32(fore200e->stats->aal5.congestion_experienced),
+ cpu_to_be32(fore200e->stats->aal5.cspdus_transmitted),
+ cpu_to_be32(fore200e->stats->aal5.cspdus_received),
+ cpu_to_be32(fore200e->stats->aal5.cspdus_dropped),
+ cpu_to_be32(fore200e->stats->aal5.cspdus_crc_errors),
+ cpu_to_be32(fore200e->stats->aal5.cspdus_protocol_errors));
if (!left--)
return sprintf(page,"\n"
@@ -3103,11 +3073,11 @@ fore200e_proc_read(struct atm_dev *dev, loff_t* pos, char* page)
" large b2:\t\t\t%10u\n"
" RX PDUs:\t\t\t%10u\n"
" TX PDUs:\t\t\t%10lu\n",
- fore200e_swap(fore200e->stats->aux.small_b1_failed),
- fore200e_swap(fore200e->stats->aux.large_b1_failed),
- fore200e_swap(fore200e->stats->aux.small_b2_failed),
- fore200e_swap(fore200e->stats->aux.large_b2_failed),
- fore200e_swap(fore200e->stats->aux.rpd_alloc_failed),
+ cpu_to_be32(fore200e->stats->aux.small_b1_failed),
+ cpu_to_be32(fore200e->stats->aux.large_b1_failed),
+ cpu_to_be32(fore200e->stats->aux.small_b2_failed),
+ cpu_to_be32(fore200e->stats->aux.large_b2_failed),
+ cpu_to_be32(fore200e->stats->aux.rpd_alloc_failed),
fore200e->tx_sat);
if (!left--)
diff --git a/drivers/atm/he.c b/drivers/atm/he.c
index 7d9b4e52f0bf..db33f6f4dd2a 100644
--- a/drivers/atm/he.c
+++ b/drivers/atm/he.c
@@ -2351,7 +2351,7 @@ he_open(struct atm_vcc *vcc)
cid = he_mkcid(he_dev, vpi, vci);
- he_vcc = (struct he_vcc *) kmalloc(sizeof(struct he_vcc), GFP_ATOMIC);
+ he_vcc = kmalloc(sizeof(struct he_vcc), GFP_ATOMIC);
if (he_vcc == NULL) {
hprintk("unable to allocate he_vcc during open\n");
return -ENOMEM;
diff --git a/drivers/atm/lanai.c b/drivers/atm/lanai.c
index 267825501dfe..09f477d4237a 100644
--- a/drivers/atm/lanai.c
+++ b/drivers/atm/lanai.c
@@ -2602,7 +2602,7 @@ static int __devinit lanai_init_one(struct pci_dev *pci,
struct atm_dev *atmdev;
int result;
- lanai = (struct lanai_dev *) kmalloc(sizeof(*lanai), GFP_KERNEL);
+ lanai = kmalloc(sizeof(*lanai), GFP_KERNEL);
if (lanai == NULL) {
printk(KERN_ERR DEV_LABEL
": couldn't allocate dev_data structure!\n");
diff --git a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c
index bd0904594805..aab9b3733d52 100644
--- a/drivers/atm/nicstar.c
+++ b/drivers/atm/nicstar.c
@@ -997,7 +997,7 @@ static scq_info *get_scq(int size, u32 scd)
if (size != VBR_SCQSIZE && size != CBR_SCQSIZE)
return NULL;
- scq = (scq_info *) kmalloc(sizeof(scq_info), GFP_KERNEL);
+ scq = kmalloc(sizeof(scq_info), GFP_KERNEL);
if (scq == NULL)
return NULL;
scq->org = kmalloc(2 * size, GFP_KERNEL);
@@ -1006,7 +1006,7 @@ static scq_info *get_scq(int size, u32 scd)
kfree(scq);
return NULL;
}
- scq->skb = (struct sk_buff **) kmalloc(sizeof(struct sk_buff *) *
+ scq->skb = kmalloc(sizeof(struct sk_buff *) *
(size / NS_SCQE_SIZE), GFP_KERNEL);
if (scq->skb == NULL)
{
diff --git a/drivers/atm/zatm.c b/drivers/atm/zatm.c
index 7df0f373188e..756d4f760da3 100644
--- a/drivers/atm/zatm.c
+++ b/drivers/atm/zatm.c
@@ -996,7 +996,7 @@ static int start_tx(struct atm_dev *dev)
DPRINTK("start_tx\n");
zatm_dev = ZATM_DEV(dev);
- zatm_dev->tx_map = (struct atm_vcc **) kmalloc(sizeof(struct atm_vcc *)*
+ zatm_dev->tx_map = kmalloc(sizeof(struct atm_vcc *)*
zatm_dev->chans,GFP_KERNEL);
if (!zatm_dev->tx_map) return -ENOMEM;
zatm_dev->tx_bw = ATM_OC3_PCR;
@@ -1591,7 +1591,7 @@ static int __devinit zatm_init_one(struct pci_dev *pci_dev,
struct zatm_dev *zatm_dev;
int ret = -ENOMEM;
- zatm_dev = (struct zatm_dev *) kmalloc(sizeof(*zatm_dev), GFP_KERNEL);
+ zatm_dev = kmalloc(sizeof(*zatm_dev), GFP_KERNEL);
if (!zatm_dev) {
printk(KERN_EMERG "%s: memory shortage\n", DEV_LABEL);
goto out;
diff --git a/drivers/base/class.c b/drivers/base/class.c
index f098881f45b2..8bf2ca2e56b5 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -163,6 +163,8 @@ int class_register(struct class * cls)
void class_unregister(struct class * cls)
{
pr_debug("device class '%s': unregistering\n", cls->name);
+ if (cls->virtual_dir)
+ kobject_unregister(cls->virtual_dir);
remove_class_attrs(cls);
subsystem_unregister(&cls->subsys);
}
diff --git a/drivers/base/dmapool.c b/drivers/base/dmapool.c
index dbe0735f8c9e..f95d50277274 100644
--- a/drivers/base/dmapool.c
+++ b/drivers/base/dmapool.c
@@ -173,7 +173,7 @@ pool_alloc_page (struct dma_pool *pool, gfp_t mem_flags)
mapsize = (mapsize + BITS_PER_LONG - 1) / BITS_PER_LONG;
mapsize *= sizeof (long);
- page = (struct dma_page *) kmalloc (mapsize + sizeof *page, mem_flags);
+ page = kmalloc(mapsize + sizeof *page, mem_flags);
if (!page)
return NULL;
page->vaddr = dma_alloc_coherent (pool->dev,
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 4bad2870c485..64558f45e6bc 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -127,6 +127,7 @@ static ssize_t firmware_loading_show(struct device *dev,
/**
* firmware_loading_store - set value in the 'loading' control file
* @dev: device pointer
+ * @attr: device attribute pointer
* @buf: buffer to scan for loading control value
* @count: number of bytes in @buf
*
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index d1df4a087924..f9c903ba9fcd 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -212,7 +212,7 @@ EXPORT_SYMBOL_GPL(platform_device_add_resources);
* pointer. The memory associated with the platform data will be freed
* when the platform device is released.
*/
-int platform_device_add_data(struct platform_device *pdev, void *data, size_t size)
+int platform_device_add_data(struct platform_device *pdev, const void *data, size_t size)
{
void *d;
@@ -473,7 +473,7 @@ EXPORT_SYMBOL_GPL(platform_driver_unregister);
* Returns zero if the driver registered and bound to a device, else returns
* a negative error code and with the driver not registered.
*/
-int platform_driver_probe(struct platform_driver *drv,
+int __init_or_module platform_driver_probe(struct platform_driver *drv,
int (*probe)(struct platform_device *))
{
int retval, code;
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index ce9cfcb6071c..58c1debf86f1 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -28,13 +28,6 @@ config ATARI_FLOPPY
tristate "Atari floppy support"
depends on ATARI
-config BLK_DEV_SWIM_IOP
- bool "Macintosh IIfx/Quadra 900/Quadra 950 floppy support (EXPERIMENTAL)"
- depends on MAC && EXPERIMENTAL && BROKEN
- help
- Say Y here to support the SWIM (Super Woz Integrated Machine) IOP
- floppy controller on the Macintosh IIfx and Quadra 900/950.
-
config MAC_FLOPPY
tristate "Support for PowerMac floppy"
depends on PPC_PMAC && !PPC_PMAC64
diff --git a/drivers/block/Makefile b/drivers/block/Makefile
index 410f259a8031..dd88e33c1eb1 100644
--- a/drivers/block/Makefile
+++ b/drivers/block/Makefile
@@ -9,7 +9,6 @@ obj-$(CONFIG_MAC_FLOPPY) += swim3.o
obj-$(CONFIG_BLK_DEV_FD) += floppy.o
obj-$(CONFIG_AMIGA_FLOPPY) += amiflop.o
obj-$(CONFIG_ATARI_FLOPPY) += ataflop.o
-obj-$(CONFIG_BLK_DEV_SWIM_IOP) += swim_iop.o
obj-$(CONFIG_ATARI_ACSI) += acsi.o
obj-$(CONFIG_ATARI_SLM) += acsi_slm.o
obj-$(CONFIG_AMIGA_Z2RAM) += z2ram.o
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c
index 97f7f535f412..bb022ed4a866 100644
--- a/drivers/block/aoe/aoecmd.c
+++ b/drivers/block/aoe/aoecmd.c
@@ -30,8 +30,6 @@ new_skb(ulong len)
skb->nh.raw = skb->mac.raw = skb->data;
skb->protocol = __constant_htons(ETH_P_AOE);
skb->priority = 0;
- skb_put(skb, len);
- memset(skb->head, 0, len);
skb->next = skb->prev = NULL;
/* tell the network layer not to perform IP checksums
@@ -122,8 +120,8 @@ aoecmd_ata_rw(struct aoedev *d, struct frame *f)
skb = f->skb;
h = (struct aoe_hdr *) skb->mac.raw;
ah = (struct aoe_atahdr *) (h+1);
- skb->len = sizeof *h + sizeof *ah;
- memset(h, 0, ETH_ZLEN);
+ skb_put(skb, sizeof *h + sizeof *ah);
+ memset(h, 0, skb->len);
f->tag = aoehdr_atainit(d, h);
f->waited = 0;
f->buf = buf;
@@ -149,7 +147,6 @@ aoecmd_ata_rw(struct aoedev *d, struct frame *f)
skb->len += bcnt;
skb->data_len = bcnt;
} else {
- skb->len = ETH_ZLEN;
writebit = 0;
}
@@ -206,6 +203,7 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail)
printk(KERN_INFO "aoe: skb alloc failure\n");
continue;
}
+ skb_put(skb, sizeof *h + sizeof *ch);
skb->dev = ifp;
if (sl_tail == NULL)
sl_tail = skb;
@@ -243,6 +241,7 @@ freeframe(struct aoedev *d)
continue;
if (atomic_read(&skb_shinfo(f->skb)->dataref) == 1) {
skb_shinfo(f->skb)->nr_frags = f->skb->data_len = 0;
+ skb_trim(f->skb, 0);
return f;
}
n++;
@@ -698,8 +697,8 @@ aoecmd_ata_id(struct aoedev *d)
skb = f->skb;
h = (struct aoe_hdr *) skb->mac.raw;
ah = (struct aoe_atahdr *) (h+1);
- skb->len = ETH_ZLEN;
- memset(h, 0, ETH_ZLEN);
+ skb_put(skb, sizeof *h + sizeof *ah);
+ memset(h, 0, skb->len);
f->tag = aoehdr_atainit(d, h);
f->waited = 0;
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index ee159edb6b88..05dfe357527c 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -225,6 +225,8 @@ static inline CommandList_struct *removeQ(CommandList_struct **Qptr,
#include "cciss_scsi.c" /* For SCSI tape support */
+#define RAID_UNKNOWN 6
+
#ifdef CONFIG_PROC_FS
/*
@@ -232,7 +234,6 @@ static inline CommandList_struct *removeQ(CommandList_struct **Qptr,
*/
#define ENG_GIG 1000000000
#define ENG_GIG_FACTOR (ENG_GIG/512)
-#define RAID_UNKNOWN 6
static const char *raid_label[] = { "0", "4", "1(1+0)", "5", "5+1", "ADG",
"UNKNOWN"
};
@@ -1039,7 +1040,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
status = -ENOMEM;
goto cleanup1;
}
- buff_size = (int *)kmalloc(MAXSGENTRIES * sizeof(int),
+ buff_size = kmalloc(MAXSGENTRIES * sizeof(int),
GFP_KERNEL);
if (!buff_size) {
status = -ENOMEM;
@@ -1907,6 +1908,7 @@ static void cciss_geometry_inquiry(int ctlr, int logvol,
"does not support reading geometry\n");
drv->heads = 255;
drv->sectors = 32; // Sectors per track
+ drv->raid_level = RAID_UNKNOWN;
} else {
drv->heads = inq_buff->data_byte[6];
drv->sectors = inq_buff->data_byte[7];
@@ -2491,7 +2493,7 @@ static void do_cciss_request(request_queue_t *q)
c->Request.Type.Type = TYPE_CMD; // It is a command.
c->Request.Type.Attribute = ATTR_SIMPLE;
c->Request.Type.Direction =
- (rq_data_dir(creq) == READ) ? h->cciss_read : h->cciss_write;
+ (rq_data_dir(creq) == READ) ? XFER_READ : XFER_WRITE;
c->Request.Timeout = 0; // Don't time out
c->Request.CDB[0] =
(rq_data_dir(creq) == READ) ? h->cciss_read : h->cciss_write;
@@ -2837,7 +2839,7 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
if (err) {
printk(KERN_ERR "cciss: Cannot obtain PCI resources, "
"aborting\n");
- goto err_out_disable_pdev;
+ return err;
}
subsystem_vendor_id = pdev->subsystem_vendor;
@@ -2865,7 +2867,7 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
#ifdef CCISS_DEBUG
printk("address 0 = %x\n", c->paddr);
#endif /* CCISS_DEBUG */
- c->vaddr = remap_pci_mem(c->paddr, 200);
+ c->vaddr = remap_pci_mem(c->paddr, 0x250);
/* Wait for the board to become ready. (PCI hotplug needs this.)
* We poll for up to 120 secs, once per 100ms. */
@@ -3004,11 +3006,12 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
}
return 0;
- err_out_free_res:
+err_out_free_res:
+ /*
+ * Deliberately omit pci_disable_device(): it does something nasty to
+ * Smart Array controllers that pci_enable_device does not undo
+ */
pci_release_regions(pdev);
-
- err_out_disable_pdev:
- pci_disable_device(pdev);
return err;
}
@@ -3382,8 +3385,11 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
if (drv->queue)
blk_cleanup_queue(drv->queue);
}
+ /*
+ * Deliberately omit pci_disable_device(): it does something nasty to
+ * Smart Array controllers that pci_enable_device does not undo
+ */
pci_release_regions(pdev);
- pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
free_hba(i);
return -1;
@@ -3452,8 +3458,11 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev)
#ifdef CONFIG_CISS_SCSI_TAPE
kfree(hba[i]->scsi_rejects.complete);
#endif
+ /*
+ * Deliberately omit pci_disable_device(): it does something nasty to
+ * Smart Array controllers that pci_enable_device does not undo
+ */
pci_release_regions(pdev);
- pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
free_hba(i);
}
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
index d5f519ebbc08..b94cd1c32131 100644
--- a/drivers/block/cpqarray.c
+++ b/drivers/block/cpqarray.c
@@ -1625,7 +1625,7 @@ static void start_fwbk(int ctlr)
" processing\n");
/* Command does not return anything, but idasend command needs a
buffer */
- id_ctlr_buf = (id_ctlr_t *)kmalloc(sizeof(id_ctlr_t), GFP_KERNEL);
+ id_ctlr_buf = kmalloc(sizeof(id_ctlr_t), GFP_KERNEL);
if(id_ctlr_buf==NULL)
{
printk(KERN_WARNING "cpqarray: Out of memory. "
@@ -1660,14 +1660,14 @@ static void getgeometry(int ctlr)
info_p->log_drv_map = 0;
- id_ldrive = (id_log_drv_t *)kmalloc(sizeof(id_log_drv_t), GFP_KERNEL);
+ id_ldrive = kmalloc(sizeof(id_log_drv_t), GFP_KERNEL);
if(id_ldrive == NULL)
{
printk( KERN_ERR "cpqarray: out of memory.\n");
return;
}
- id_ctlr_buf = (id_ctlr_t *)kmalloc(sizeof(id_ctlr_t), GFP_KERNEL);
+ id_ctlr_buf = kmalloc(sizeof(id_ctlr_t), GFP_KERNEL);
if(id_ctlr_buf == NULL)
{
kfree(id_ldrive);
@@ -1675,7 +1675,7 @@ static void getgeometry(int ctlr)
return;
}
- id_lstatus_buf = (sense_log_drv_stat_t *)kmalloc(sizeof(sense_log_drv_stat_t), GFP_KERNEL);
+ id_lstatus_buf = kmalloc(sizeof(sense_log_drv_stat_t), GFP_KERNEL);
if(id_lstatus_buf == NULL)
{
kfree(id_ctlr_buf);
@@ -1684,7 +1684,7 @@ static void getgeometry(int ctlr)
return;
}
- sense_config_buf = (config_t *)kmalloc(sizeof(config_t), GFP_KERNEL);
+ sense_config_buf = kmalloc(sizeof(config_t), GFP_KERNEL);
if(sense_config_buf == NULL)
{
kfree(id_lstatus_buf);
diff --git a/drivers/block/swim_iop.c b/drivers/block/swim_iop.c
deleted file mode 100644
index ed7b06cf3e68..000000000000
--- a/drivers/block/swim_iop.c
+++ /dev/null
@@ -1,578 +0,0 @@
-/*
- * Driver for the SWIM (Super Woz Integrated Machine) IOP
- * floppy controller on the Macintosh IIfx and Quadra 900/950
- *
- * Written by Joshua M. Thompson (funaho@jurai.org)
- * based on the SWIM3 driver (c) 1996 by Paul Mackerras.
- *
- * 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.
- *
- * 1999-06-12 (jmt) - Initial implementation.
- */
-
-/*
- * -------------------
- * Theory of Operation
- * -------------------
- *
- * Since the SWIM IOP is message-driven we implement a simple request queue
- * system. One outstanding request may be queued at any given time (this is
- * an IOP limitation); only when that request has completed can a new request
- * be sent.
- */
-
-#include <linux/stddef.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/timer.h>
-#include <linux/delay.h>
-#include <linux/fd.h>
-#include <linux/ioctl.h>
-#include <linux/blkdev.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/mac_iop.h>
-#include <asm/swim_iop.h>
-
-#define DRIVER_VERSION "Version 0.1 (1999-06-12)"
-
-#define MAX_FLOPPIES 4
-
-enum swim_state {
- idle,
- available,
- revalidating,
- transferring,
- ejecting
-};
-
-struct floppy_state {
- enum swim_state state;
- int drive_num; /* device number */
- int secpercyl; /* disk geometry information */
- int secpertrack;
- int total_secs;
- int write_prot; /* 1 if write-protected, 0 if not, -1 dunno */
- int ref_count;
- struct timer_list timeout;
- int ejected;
- struct wait_queue *wait;
- int wanted;
- int timeout_pending;
-};
-
-struct swim_iop_req {
- int sent;
- int complete;
- __u8 command[32];
- struct floppy_state *fs;
- void (*done)(struct swim_iop_req *);
-};
-
-static struct swim_iop_req *current_req;
-static int floppy_count;
-
-static struct floppy_state floppy_states[MAX_FLOPPIES];
-static DEFINE_SPINLOCK(swim_iop_lock);
-
-#define CURRENT elv_next_request(swim_queue)
-
-static char *drive_names[7] = {
- "not installed", /* DRV_NONE */
- "unknown (1)", /* DRV_UNKNOWN */
- "a 400K drive", /* DRV_400K */
- "an 800K drive" /* DRV_800K */
- "unknown (4)", /* ???? */
- "an FDHD", /* DRV_FDHD */
- "unknown (6)", /* ???? */
- "an Apple HD20" /* DRV_HD20 */
-};
-
-int swimiop_init(void);
-static void swimiop_init_request(struct swim_iop_req *);
-static int swimiop_send_request(struct swim_iop_req *);
-static void swimiop_receive(struct iop_msg *);
-static void swimiop_status_update(int, struct swim_drvstatus *);
-static int swimiop_eject(struct floppy_state *fs);
-
-static int floppy_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long param);
-static int floppy_open(struct inode *inode, struct file *filp);
-static int floppy_release(struct inode *inode, struct file *filp);
-static int floppy_check_change(struct gendisk *disk);
-static int floppy_revalidate(struct gendisk *disk);
-static int grab_drive(struct floppy_state *fs, enum swim_state state,
- int interruptible);
-static void release_drive(struct floppy_state *fs);
-static void set_timeout(struct floppy_state *fs, int nticks,
- void (*proc)(unsigned long));
-static void fd_request_timeout(unsigned long);
-static void do_fd_request(request_queue_t * q);
-static void start_request(struct floppy_state *fs);
-
-static struct block_device_operations floppy_fops = {
- .open = floppy_open,
- .release = floppy_release,
- .ioctl = floppy_ioctl,
- .media_changed = floppy_check_change,
- .revalidate_disk= floppy_revalidate,
-};
-
-static struct request_queue *swim_queue;
-/*
- * SWIM IOP initialization
- */
-
-int swimiop_init(void)
-{
- volatile struct swim_iop_req req;
- struct swimcmd_status *cmd = (struct swimcmd_status *) &req.command[0];
- struct swim_drvstatus *ds = &cmd->status;
- struct floppy_state *fs;
- int i;
-
- current_req = NULL;
- floppy_count = 0;
-
- if (!iop_ism_present)
- return -ENODEV;
-
- if (register_blkdev(FLOPPY_MAJOR, "fd"))
- return -EBUSY;
-
- swim_queue = blk_init_queue(do_fd_request, &swim_iop_lock);
- if (!swim_queue) {
- unregister_blkdev(FLOPPY_MAJOR, "fd");
- return -ENOMEM;
- }
-
- printk("SWIM-IOP: %s by Joshua M. Thompson (funaho@jurai.org)\n",
- DRIVER_VERSION);
-
- if (iop_listen(SWIM_IOP, SWIM_CHAN, swimiop_receive, "SWIM") != 0) {
- printk(KERN_ERR "SWIM-IOP: IOP channel already in use; can't initialize.\n");
- unregister_blkdev(FLOPPY_MAJOR, "fd");
- blk_cleanup_queue(swim_queue);
- return -EBUSY;
- }
-
- printk(KERN_ERR "SWIM_IOP: probing for installed drives.\n");
-
- for (i = 0 ; i < MAX_FLOPPIES ; i++) {
- memset(&floppy_states[i], 0, sizeof(struct floppy_state));
- fs = &floppy_states[floppy_count];
-
- swimiop_init_request(&req);
- cmd->code = CMD_STATUS;
- cmd->drive_num = i + 1;
- if (swimiop_send_request(&req) != 0) continue;
- while (!req.complete);
- if (cmd->error != 0) {
- printk(KERN_ERR "SWIM-IOP: probe on drive %d returned error %d\n", i, (uint) cmd->error);
- continue;
- }
- if (ds->installed != 0x01) continue;
- printk("SWIM-IOP: drive %d is %s (%s, %s, %s, %s)\n", i,
- drive_names[ds->info.type],
- ds->info.external? "ext" : "int",
- ds->info.scsi? "scsi" : "floppy",
- ds->info.fixed? "fixed" : "removable",
- ds->info.secondary? "secondary" : "primary");
- swimiop_status_update(floppy_count, ds);
- fs->state = idle;
-
- init_timer(&fs->timeout);
- floppy_count++;
- }
- printk("SWIM-IOP: detected %d installed drives.\n", floppy_count);
-
- for (i = 0; i < floppy_count; i++) {
- struct gendisk *disk = alloc_disk(1);
- if (!disk)
- continue;
- disk->major = FLOPPY_MAJOR;
- disk->first_minor = i;
- disk->fops = &floppy_fops;
- sprintf(disk->disk_name, "fd%d", i);
- disk->private_data = &floppy_states[i];
- disk->queue = swim_queue;
- set_capacity(disk, 2880 * 2);
- add_disk(disk);
- }
-
- return 0;
-}
-
-static void swimiop_init_request(struct swim_iop_req *req)
-{
- req->sent = 0;
- req->complete = 0;
- req->done = NULL;
-}
-
-static int swimiop_send_request(struct swim_iop_req *req)
-{
- unsigned long flags;
- int err;
-
- /* It's doubtful an interrupt routine would try to send */
- /* a SWIM request, but I'd rather play it safe here. */
-
- local_irq_save(flags);
-
- if (current_req != NULL) {
- local_irq_restore(flags);
- return -ENOMEM;
- }
-
- current_req = req;
-
- /* Interrupts should be back on for iop_send_message() */
-
- local_irq_restore(flags);
-
- err = iop_send_message(SWIM_IOP, SWIM_CHAN, (void *) req,
- sizeof(req->command), (__u8 *) &req->command[0],
- swimiop_receive);
-
- /* No race condition here; we own current_req at this point */
-
- if (err) {
- current_req = NULL;
- } else {
- req->sent = 1;
- }
- return err;
-}
-
-/*
- * Receive a SWIM message from the IOP.
- *
- * This will be called in two cases:
- *
- * 1. A message has been successfully sent to the IOP.
- * 2. An unsolicited message was received from the IOP.
- */
-
-void swimiop_receive(struct iop_msg *msg)
-{
- struct swim_iop_req *req;
- struct swimmsg_status *sm;
- struct swim_drvstatus *ds;
-
- req = current_req;
-
- switch(msg->status) {
- case IOP_MSGSTATUS_COMPLETE:
- memcpy(&req->command[0], &msg->reply[0], sizeof(req->command));
- req->complete = 1;
- if (req->done) (*req->done)(req);
- current_req = NULL;
- break;
- case IOP_MSGSTATUS_UNSOL:
- sm = (struct swimmsg_status *) &msg->message[0];
- ds = &sm->status;
- swimiop_status_update(sm->drive_num, ds);
- iop_complete_message(msg);
- break;
- }
-}
-
-static void swimiop_status_update(int drive_num, struct swim_drvstatus *ds)
-{
- struct floppy_state *fs = &floppy_states[drive_num];
-
- fs->write_prot = (ds->write_prot == 0x80);
- if ((ds->disk_in_drive != 0x01) && (ds->disk_in_drive != 0x02)) {
- fs->ejected = 1;
- } else {
- fs->ejected = 0;
- }
- switch(ds->info.type) {
- case DRV_400K:
- fs->secpercyl = 10;
- fs->secpertrack = 10;
- fs->total_secs = 800;
- break;
- case DRV_800K:
- fs->secpercyl = 20;
- fs->secpertrack = 10;
- fs->total_secs = 1600;
- break;
- case DRV_FDHD:
- fs->secpercyl = 36;
- fs->secpertrack = 18;
- fs->total_secs = 2880;
- break;
- default:
- fs->secpercyl = 0;
- fs->secpertrack = 0;
- fs->total_secs = 0;
- break;
- }
-}
-
-static int swimiop_eject(struct floppy_state *fs)
-{
- int err, n;
- struct swim_iop_req req;
- struct swimcmd_eject *cmd = (struct swimcmd_eject *) &req.command[0];
-
- err = grab_drive(fs, ejecting, 1);
- if (err) return err;
-
- swimiop_init_request(&req);
- cmd->code = CMD_EJECT;
- cmd->drive_num = fs->drive_num;
- err = swimiop_send_request(&req);
- if (err) {
- release_drive(fs);
- return err;
- }
- for (n = 2*HZ; n > 0; --n) {
- if (req.complete) break;
- if (signal_pending(current)) {
- err = -EINTR;
- break;
- }
- schedule_timeout_interruptible(1);
- }
- release_drive(fs);
- return cmd->error;
-}
-
-static struct floppy_struct floppy_type =
- { 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,NULL }; /* 7 1.44MB 3.5" */
-
-static int floppy_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long param)
-{
- struct floppy_state *fs = inode->i_bdev->bd_disk->private_data;
- int err;
-
- if ((cmd & 0x80) && !capable(CAP_SYS_ADMIN))
- return -EPERM;
-
- switch (cmd) {
- case FDEJECT:
- if (fs->ref_count != 1)
- return -EBUSY;
- err = swimiop_eject(fs);
- return err;
- case FDGETPRM:
- if (copy_to_user((void *) param, (void *) &floppy_type,
- sizeof(struct floppy_struct)))
- return -EFAULT;
- return 0;
- }
- return -ENOTTY;
-}
-
-static int floppy_open(struct inode *inode, struct file *filp)
-{
- struct floppy_state *fs = inode->i_bdev->bd_disk->private_data;
-
- if (fs->ref_count == -1 || filp->f_flags & O_EXCL)
- return -EBUSY;
-
- if ((filp->f_flags & O_NDELAY) == 0 && (filp->f_mode & 3)) {
- check_disk_change(inode->i_bdev);
- if (fs->ejected)
- return -ENXIO;
- }
-
- if ((filp->f_mode & 2) && fs->write_prot)
- return -EROFS;
-
- if (filp->f_flags & O_EXCL)
- fs->ref_count = -1;
- else
- ++fs->ref_count;
-
- return 0;
-}
-
-static int floppy_release(struct inode *inode, struct file *filp)
-{
- struct floppy_state *fs = inode->i_bdev->bd_disk->private_data;
- if (fs->ref_count > 0)
- fs->ref_count--;
- return 0;
-}
-
-static int floppy_check_change(struct gendisk *disk)
-{
- struct floppy_state *fs = disk->private_data;
- return fs->ejected;
-}
-
-static int floppy_revalidate(struct gendisk *disk)
-{
- struct floppy_state *fs = disk->private_data;
- grab_drive(fs, revalidating, 0);
- /* yadda, yadda */
- release_drive(fs);
- return 0;
-}
-
-static void floppy_off(unsigned int nr)
-{
-}
-
-static int grab_drive(struct floppy_state *fs, enum swim_state state,
- int interruptible)
-{
- unsigned long flags;
-
- local_irq_save(flags);
- if (fs->state != idle) {
- ++fs->wanted;
- while (fs->state != available) {
- if (interruptible && signal_pending(current)) {
- --fs->wanted;
- local_irq_restore(flags);
- return -EINTR;
- }
- interruptible_sleep_on(&fs->wait);
- }
- --fs->wanted;
- }
- fs->state = state;
- local_irq_restore(flags);
- return 0;
-}
-
-static void release_drive(struct floppy_state *fs)
-{
- unsigned long flags;
-
- local_irq_save(flags);
- fs->state = idle;
- start_request(fs);
- local_irq_restore(flags);
-}
-
-static void set_timeout(struct floppy_state *fs, int nticks,
- void (*proc)(unsigned long))
-{
- unsigned long flags;
-
- local_irq_save(flags);
- if (fs->timeout_pending)
- del_timer(&fs->timeout);
- init_timer(&fs->timeout);
- fs->timeout.expires = jiffies + nticks;
- fs->timeout.function = proc;
- fs->timeout.data = (unsigned long) fs;
- add_timer(&fs->timeout);
- fs->timeout_pending = 1;
- local_irq_restore(flags);
-}
-
-static void do_fd_request(request_queue_t * q)
-{
- int i;
-
- for (i = 0 ; i < floppy_count ; i++) {
- start_request(&floppy_states[i]);
- }
-}
-
-static void fd_request_complete(struct swim_iop_req *req)
-{
- struct floppy_state *fs = req->fs;
- struct swimcmd_rw *cmd = (struct swimcmd_rw *) &req->command[0];
-
- del_timer(&fs->timeout);
- fs->timeout_pending = 0;
- fs->state = idle;
- if (cmd->error) {
- printk(KERN_ERR "SWIM-IOP: error %d on read/write request.\n", cmd->error);
- end_request(CURRENT, 0);
- } else {
- CURRENT->sector += cmd->num_blocks;
- CURRENT->current_nr_sectors -= cmd->num_blocks;
- if (CURRENT->current_nr_sectors <= 0) {
- end_request(CURRENT, 1);
- return;
- }
- }
- start_request(fs);
-}
-
-static void fd_request_timeout(unsigned long data)
-{
- struct floppy_state *fs = (struct floppy_state *) data;
-
- fs->timeout_pending = 0;
- end_request(CURRENT, 0);
- fs->state = idle;
-}
-
-static void start_request(struct floppy_state *fs)
-{
- volatile struct swim_iop_req req;
- struct swimcmd_rw *cmd = (struct swimcmd_rw *) &req.command[0];
-
- if (fs->state == idle && fs->wanted) {
- fs->state = available;
- wake_up(&fs->wait);
- return;
- }
- while (CURRENT && fs->state == idle) {
- if (CURRENT->bh && !buffer_locked(CURRENT->bh))
- panic("floppy: block not locked");
-#if 0
- printk("do_fd_req: dev=%s cmd=%d sec=%ld nr_sec=%ld buf=%p\n",
- CURRENT->rq_disk->disk_name, CURRENT->cmd,
- CURRENT->sector, CURRENT->nr_sectors, CURRENT->buffer);
- printk(" errors=%d current_nr_sectors=%ld\n",
- CURRENT->errors, CURRENT->current_nr_sectors);
-#endif
-
- if (CURRENT->sector < 0 || CURRENT->sector >= fs->total_secs) {
- end_request(CURRENT, 0);
- continue;
- }
- if (CURRENT->current_nr_sectors == 0) {
- end_request(CURRENT, 1);
- continue;
- }
- if (fs->ejected) {
- end_request(CURRENT, 0);
- continue;
- }
-
- swimiop_init_request(&req);
- req.fs = fs;
- req.done = fd_request_complete;
-
- if (CURRENT->cmd == WRITE) {
- if (fs->write_prot) {
- end_request(CURRENT, 0);
- continue;
- }
- cmd->code = CMD_WRITE;
- } else {
- cmd->code = CMD_READ;
-
- }
- cmd->drive_num = fs->drive_num;
- cmd->buffer = CURRENT->buffer;
- cmd->first_block = CURRENT->sector;
- cmd->num_blocks = CURRENT->current_nr_sectors;
-
- if (swimiop_send_request(&req)) {
- end_request(CURRENT, 0);
- continue;
- }
-
- set_timeout(fs, HZ*CURRENT->current_nr_sectors,
- fd_request_timeout);
-
- fs->state = transferring;
- }
-}
diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c
index e19ba4ebcd4e..68592c336011 100644
--- a/drivers/block/viodasd.c
+++ b/drivers/block/viodasd.c
@@ -49,6 +49,7 @@
#include <asm/iseries/hv_lp_event.h>
#include <asm/iseries/hv_lp_config.h>
#include <asm/iseries/vio.h>
+#include <asm/firmware.h>
MODULE_DESCRIPTION("iSeries Virtual DASD");
MODULE_AUTHOR("Dave Boutcher");
@@ -769,6 +770,11 @@ static int __init viodasd_init(void)
{
int rc;
+ if (!firmware_has_feature(FW_FEATURE_ISERIES)) {
+ rc = -ENODEV;
+ goto early_fail;
+ }
+
/* Try to open to our host lp */
if (viopath_hostLp == HvLpIndexInvalid)
vio_set_hostlp();
diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c
index fdea58ae16b2..aeefec97fdee 100644
--- a/drivers/bluetooth/hci_usb.c
+++ b/drivers/bluetooth/hci_usb.c
@@ -126,6 +126,7 @@ static struct usb_device_id blacklist_ids[] = {
/* Kensington Bluetooth USB adapter */
{ USB_DEVICE(0x047d, 0x105d), .driver_info = HCI_RESET },
+ { USB_DEVICE(0x047d, 0x105e), .driver_info = HCI_WRONG_SCO_MTU },
/* ISSC Bluetooth Adapter v3.1 */
{ USB_DEVICE(0x1131, 0x1001), .driver_info = HCI_RESET },
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
index 2df5cf4ec743..3105dddf59f1 100644
--- a/drivers/cdrom/cdrom.c
+++ b/drivers/cdrom/cdrom.c
@@ -337,6 +337,12 @@ static const char *mrw_address_space[] = { "DMA", "GAA" };
/* used in the audio ioctls */
#define CHECKAUDIO if ((ret=check_for_audio_disc(cdi, cdo))) return ret
+/*
+ * Another popular OS uses 7 seconds as the hard timeout for default
+ * commands, so it is a good choice for us as well.
+ */
+#define CDROM_DEF_TIMEOUT (7 * HZ)
+
/* Not-exported routines. */
static int open_for_data(struct cdrom_device_info * cdi);
static int check_for_audio_disc(struct cdrom_device_info * cdi,
@@ -1528,7 +1534,7 @@ void init_cdrom_command(struct packet_command *cgc, void *buf, int len,
cgc->buffer = (char *) buf;
cgc->buflen = len;
cgc->data_direction = type;
- cgc->timeout = 5*HZ;
+ cgc->timeout = CDROM_DEF_TIMEOUT;
}
/* DVD handling */
@@ -1810,7 +1816,7 @@ static int dvd_read_disckey(struct cdrom_device_info *cdi, dvd_struct *s)
size = sizeof(s->disckey.value) + 4;
- if ((buf = (u_char *) kmalloc(size, GFP_KERNEL)) == NULL)
+ if ((buf = kmalloc(size, GFP_KERNEL)) == NULL)
return -ENOMEM;
init_cdrom_command(&cgc, buf, size, CGC_DATA_READ);
@@ -1861,7 +1867,7 @@ static int dvd_read_manufact(struct cdrom_device_info *cdi, dvd_struct *s)
size = sizeof(s->manufact.value) + 4;
- if ((buf = (u_char *) kmalloc(size, GFP_KERNEL)) == NULL)
+ if ((buf = kmalloc(size, GFP_KERNEL)) == NULL)
return -ENOMEM;
init_cdrom_command(&cgc, buf, size, CGC_DATA_READ);
@@ -2139,8 +2145,7 @@ static int cdrom_read_cdda_bpc(struct cdrom_device_info *cdi, __u8 __user *ubuf,
cdi->last_sense = s->sense_key;
}
- rq->bio = bio;
- if (blk_rq_unmap_user(rq))
+ if (blk_rq_unmap_user(bio))
ret = -EFAULT;
if (ret)
@@ -2849,7 +2854,7 @@ static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
/* FIXME: we need upper bound checking, too!! */
if (lba < 0)
return -EINVAL;
- cgc.buffer = (char *) kmalloc(blocksize, GFP_KERNEL);
+ cgc.buffer = kmalloc(blocksize, GFP_KERNEL);
if (cgc.buffer == NULL)
return -ENOMEM;
memset(&sense, 0, sizeof(sense));
@@ -3031,7 +3036,7 @@ static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
int size = sizeof(dvd_struct);
if (!CDROM_CAN(CDC_DVD))
return -ENOSYS;
- if ((s = (dvd_struct *) kmalloc(size, GFP_KERNEL)) == NULL)
+ if ((s = kmalloc(size, GFP_KERNEL)) == NULL)
return -ENOMEM;
cdinfo(CD_DO_IOCTL, "entering DVD_READ_STRUCT\n");
if (copy_from_user(s, (dvd_struct __user *)arg, size)) {
diff --git a/drivers/cdrom/cm206.c b/drivers/cdrom/cm206.c
index e6d8e9ededea..b6c61bbb20e1 100644
--- a/drivers/cdrom/cm206.c
+++ b/drivers/cdrom/cm206.c
@@ -1420,7 +1420,7 @@ int __init cm206_init(void)
return -EIO;
}
printk(" adapter at 0x%x", cm206_base);
- cd = (struct cm206_struct *) kmalloc(size, GFP_KERNEL);
+ cd = kmalloc(size, GFP_KERNEL);
if (!cd)
goto out_base;
/* Now we have found the adaptor card, try to reset it. As we have
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c
index 54ca931e19ea..93fbf84dcc4a 100644
--- a/drivers/cdrom/viocd.c
+++ b/drivers/cdrom/viocd.c
@@ -47,6 +47,7 @@
#include <asm/iseries/hv_types.h>
#include <asm/iseries/hv_lp_event.h>
#include <asm/iseries/vio.h>
+#include <asm/firmware.h>
#define VIOCD_DEVICE "iseries/vcd"
@@ -748,6 +749,9 @@ static int __init viocd_init(void)
struct proc_dir_entry *e;
int ret = 0;
+ if (!firmware_has_feature(FW_FEATURE_ISERIES))
+ return -ENODEV;
+
if (viopath_hostLp == HvLpIndexInvalid) {
vio_set_hostlp();
/* If we don't have a host, bail out */
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 0a3aee29e067..9e43e39dc35c 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -97,7 +97,7 @@ config SERIAL_NONSTANDARD
config COMPUTONE
tristate "Computone IntelliPort Plus serial support"
- depends on SERIAL_NONSTANDARD
+ depends on SERIAL_NONSTANDARD && (ISA || EISA || PCI)
---help---
This driver supports the entire family of Intelliport II/Plus
controllers with the exception of the MicroChannel controllers and
@@ -203,7 +203,7 @@ config MOXA_SMARTIO
config MOXA_SMARTIO_NEW
tristate "Moxa SmartIO support v. 2.0 (EXPERIMENTAL)"
- depends on SERIAL_NONSTANDARD
+ depends on SERIAL_NONSTANDARD && (PCI || EISA || ISA)
help
Say Y here if you have a Moxa SmartIO multiport serial card and/or
want to help develop a new version of this driver.
@@ -218,7 +218,7 @@ config MOXA_SMARTIO_NEW
config ISI
tristate "Multi-Tech multiport card support (EXPERIMENTAL)"
- depends on SERIAL_NONSTANDARD
+ depends on SERIAL_NONSTANDARD && PCI
select FW_LOADER
help
This is a driver for the Multi-Tech cards which provide several
@@ -312,7 +312,7 @@ config SPECIALIX_RTSCTS
config SX
tristate "Specialix SX (and SI) card support"
- depends on SERIAL_NONSTANDARD
+ depends on SERIAL_NONSTANDARD && (PCI || EISA || ISA)
help
This is a driver for the SX and SI multiport serial cards.
Please read the file <file:Documentation/sx.txt> for details.
diff --git a/drivers/char/consolemap.c b/drivers/char/consolemap.c
index 04a12027a740..b99b7561260d 100644
--- a/drivers/char/consolemap.c
+++ b/drivers/char/consolemap.c
@@ -443,7 +443,7 @@ int con_clear_unimap(struct vc_data *vc, struct unimapinit *ui)
p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc;
if (p && p->readonly) return -EIO;
if (!p || --p->refcount) {
- q = (struct uni_pagedir *)kmalloc(sizeof(*p), GFP_KERNEL);
+ q = kmalloc(sizeof(*p), GFP_KERNEL);
if (!q) {
if (p) p->refcount++;
return -ENOMEM;
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
index 0bbb04f2390f..6dcdceb81203 100644
--- a/drivers/char/drm/drmP.h
+++ b/drivers/char/drm/drmP.h
@@ -561,8 +561,7 @@ struct drm_driver {
int (*context_dtor) (struct drm_device * dev, int context);
int (*kernel_context_switch) (struct drm_device * dev, int old,
int new);
- void (*kernel_context_switch_unlock) (struct drm_device * dev,
- drm_lock_t *lock);
+ void (*kernel_context_switch_unlock) (struct drm_device * dev);
int (*vblank_wait) (struct drm_device * dev, unsigned int *sequence);
int (*vblank_wait2) (struct drm_device * dev, unsigned int *sequence);
int (*dri_library_name) (struct drm_device *dev, char *buf);
@@ -1143,9 +1142,5 @@ 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_lock.c b/drivers/char/drm/drm_lock.c
index 116ed0f2ac09..e9993ba461a2 100644
--- a/drivers/char/drm/drm_lock.c
+++ b/drivers/char/drm/drm_lock.c
@@ -182,7 +182,7 @@ int drm_unlock(struct inode *inode, struct file *filp,
* modules but is required by the Sparc driver.
*/
if (dev->driver->kernel_context_switch_unlock)
- dev->driver->kernel_context_switch_unlock(dev, &lock);
+ dev->driver->kernel_context_switch_unlock(dev);
else {
drm_lock_transfer(dev, &dev->lock.hw_lock->lock,
DRM_KERNEL_CONTEXT);
diff --git a/drivers/char/drm/drm_stub.c b/drivers/char/drm/drm_stub.c
index 5fd6dc0870cf..120d10256feb 100644
--- a/drivers/char/drm/drm_stub.c
+++ b/drivers/char/drm/drm_stub.c
@@ -211,14 +211,16 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
if (!dev)
return -ENOMEM;
- pci_enable_device(pdev);
+ ret = pci_enable_device(pdev);
+ if (ret)
+ goto err_g1;
if ((ret = drm_fill_in_dev(dev, pdev, ent, driver))) {
printk(KERN_ERR "DRM: Fill_in_dev failed.\n");
- goto err_g1;
+ goto err_g2;
}
if ((ret = drm_get_head(dev, &dev->primary)))
- goto err_g1;
+ goto err_g2;
DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
driver->name, driver->major, driver->minor, driver->patchlevel,
@@ -226,7 +228,9 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
return 0;
- err_g1:
+err_g2:
+ pci_disable_device(pdev);
+err_g1:
drm_free(dev, sizeof(*dev), DRM_MEM_STUB);
return ret;
}
diff --git a/drivers/char/drm/drm_sysfs.c b/drivers/char/drm/drm_sysfs.c
index ba4b8de83cf0..cc8e2ebe128c 100644
--- a/drivers/char/drm/drm_sysfs.c
+++ b/drivers/char/drm/drm_sysfs.c
@@ -45,8 +45,8 @@ struct class *drm_sysfs_create(struct module *owner, char *name)
int err;
class = class_create(owner, name);
- if (!class) {
- err = -ENOMEM;
+ if (IS_ERR(class)) {
+ err = PTR_ERR(class);
goto err_out;
}
@@ -113,8 +113,8 @@ struct class_device *drm_sysfs_device_add(struct class *cs, drm_head_t *head)
MKDEV(DRM_MAJOR, head->minor),
&(head->dev->pdev)->dev,
"card%d", head->minor);
- if (!class_dev) {
- err = -ENOMEM;
+ if (IS_ERR(class_dev)) {
+ err = PTR_ERR(class_dev);
goto err_out;
}
diff --git a/drivers/char/drm/i915_irq.c b/drivers/char/drm/i915_irq.c
index e5463b111fc0..e2c4b3a41b1e 100644
--- a/drivers/char/drm/i915_irq.c
+++ b/drivers/char/drm/i915_irq.c
@@ -46,88 +46,167 @@ static void i915_vblank_tasklet(drm_device_t *dev)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
unsigned long irqflags;
- struct list_head *list, *tmp;
+ struct list_head *list, *tmp, hits, *hit;
+ int nhits, nrects, slice[2], upper[2], lower[2], i;
+ unsigned counter[2] = { atomic_read(&dev->vbl_received),
+ atomic_read(&dev->vbl_received2) };
+ drm_drawable_info_t *drw;
+ drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ u32 cpp = dev_priv->cpp;
+ u32 cmd = (cpp == 4) ? (XY_SRC_COPY_BLT_CMD |
+ XY_SRC_COPY_BLT_WRITE_ALPHA |
+ XY_SRC_COPY_BLT_WRITE_RGB)
+ : XY_SRC_COPY_BLT_CMD;
+ u32 pitchropcpp = (sarea_priv->pitch * cpp) | (0xcc << 16) |
+ (cpp << 23) | (1 << 24);
+ RING_LOCALS;
DRM_DEBUG("\n");
+ INIT_LIST_HEAD(&hits);
+
+ nhits = nrects = 0;
+
spin_lock_irqsave(&dev_priv->swaps_lock, irqflags);
+ /* Find buffer swaps scheduled for this vertical blank */
list_for_each_safe(list, tmp, &dev_priv->vbl_swaps.head) {
drm_i915_vbl_swap_t *vbl_swap =
list_entry(list, drm_i915_vbl_swap_t, head);
- atomic_t *counter = vbl_swap->pipe ? &dev->vbl_received2 :
- &dev->vbl_received;
-
- if ((atomic_read(counter) - vbl_swap->sequence) <= (1<<23)) {
- drm_drawable_info_t *drw;
-
- spin_unlock(&dev_priv->swaps_lock);
-
- spin_lock(&dev->drw_lock);
-
- drw = drm_get_drawable_info(dev, vbl_swap->drw_id);
-
- if (drw) {
- int i, num_rects = drw->num_rects;
- drm_clip_rect_t *rect = drw->rects;
- drm_i915_sarea_t *sarea_priv =
- dev_priv->sarea_priv;
- u32 cpp = dev_priv->cpp;
- u32 cmd = (cpp == 4) ? (XY_SRC_COPY_BLT_CMD |
- XY_SRC_COPY_BLT_WRITE_ALPHA |
- XY_SRC_COPY_BLT_WRITE_RGB)
- : XY_SRC_COPY_BLT_CMD;
- u32 pitchropcpp = (sarea_priv->pitch * cpp) |
- (0xcc << 16) | (cpp << 23) |
- (1 << 24);
- RING_LOCALS;
-
- i915_kernel_lost_context(dev);
-
- BEGIN_LP_RING(6);
-
- OUT_RING(GFX_OP_DRAWRECT_INFO);
- OUT_RING(0);
- OUT_RING(0);
- OUT_RING(sarea_priv->width |
- sarea_priv->height << 16);
- OUT_RING(sarea_priv->width |
- sarea_priv->height << 16);
- OUT_RING(0);
- ADVANCE_LP_RING();
+ if ((counter[vbl_swap->pipe] - vbl_swap->sequence) > (1<<23))
+ continue;
+
+ list_del(list);
+ dev_priv->swaps_pending--;
- sarea_priv->ctxOwner = DRM_KERNEL_CONTEXT;
+ spin_unlock(&dev_priv->swaps_lock);
+ spin_lock(&dev->drw_lock);
- for (i = 0; i < num_rects; i++, rect++) {
- BEGIN_LP_RING(8);
+ drw = drm_get_drawable_info(dev, vbl_swap->drw_id);
+
+ if (!drw) {
+ spin_unlock(&dev->drw_lock);
+ drm_free(vbl_swap, sizeof(*vbl_swap), DRM_MEM_DRIVER);
+ spin_lock(&dev_priv->swaps_lock);
+ continue;
+ }
- OUT_RING(cmd);
- OUT_RING(pitchropcpp);
- OUT_RING((rect->y1 << 16) | rect->x1);
- OUT_RING((rect->y2 << 16) | rect->x2);
- OUT_RING(sarea_priv->front_offset);
- OUT_RING((rect->y1 << 16) | rect->x1);
- OUT_RING(pitchropcpp & 0xffff);
- OUT_RING(sarea_priv->back_offset);
+ list_for_each(hit, &hits) {
+ drm_i915_vbl_swap_t *swap_cmp =
+ list_entry(hit, drm_i915_vbl_swap_t, head);
+ drm_drawable_info_t *drw_cmp =
+ drm_get_drawable_info(dev, swap_cmp->drw_id);
- ADVANCE_LP_RING();
- }
+ if (drw_cmp &&
+ drw_cmp->rects[0].y1 > drw->rects[0].y1) {
+ list_add_tail(list, hit);
+ break;
}
+ }
- spin_unlock(&dev->drw_lock);
+ spin_unlock(&dev->drw_lock);
- spin_lock(&dev_priv->swaps_lock);
+ /* List of hits was empty, or we reached the end of it */
+ if (hit == &hits)
+ list_add_tail(list, hits.prev);
- list_del(list);
+ nhits++;
- drm_free(vbl_swap, sizeof(*vbl_swap), DRM_MEM_DRIVER);
+ spin_lock(&dev_priv->swaps_lock);
+ }
+
+ if (nhits == 0) {
+ spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags);
+ return;
+ }
+
+ spin_unlock(&dev_priv->swaps_lock);
- dev_priv->swaps_pending--;
+ i915_kernel_lost_context(dev);
+
+ BEGIN_LP_RING(6);
+
+ OUT_RING(GFX_OP_DRAWRECT_INFO);
+ OUT_RING(0);
+ OUT_RING(0);
+ OUT_RING(sarea_priv->width | sarea_priv->height << 16);
+ OUT_RING(sarea_priv->width | sarea_priv->height << 16);
+ OUT_RING(0);
+
+ ADVANCE_LP_RING();
+
+ sarea_priv->ctxOwner = DRM_KERNEL_CONTEXT;
+
+ upper[0] = upper[1] = 0;
+ slice[0] = max(sarea_priv->pipeA_h / nhits, 1);
+ slice[1] = max(sarea_priv->pipeB_h / nhits, 1);
+ lower[0] = sarea_priv->pipeA_y + slice[0];
+ lower[1] = sarea_priv->pipeB_y + slice[0];
+
+ spin_lock(&dev->drw_lock);
+
+ /* Emit blits for buffer swaps, partitioning both outputs into as many
+ * slices as there are buffer swaps scheduled in order to avoid tearing
+ * (based on the assumption that a single buffer swap would always
+ * complete before scanout starts).
+ */
+ for (i = 0; i++ < nhits;
+ upper[0] = lower[0], lower[0] += slice[0],
+ upper[1] = lower[1], lower[1] += slice[1]) {
+ if (i == nhits)
+ lower[0] = lower[1] = sarea_priv->height;
+
+ list_for_each(hit, &hits) {
+ drm_i915_vbl_swap_t *swap_hit =
+ list_entry(hit, drm_i915_vbl_swap_t, head);
+ drm_clip_rect_t *rect;
+ int num_rects, pipe;
+ unsigned short top, bottom;
+
+ drw = drm_get_drawable_info(dev, swap_hit->drw_id);
+
+ if (!drw)
+ continue;
+
+ rect = drw->rects;
+ pipe = swap_hit->pipe;
+ top = upper[pipe];
+ bottom = lower[pipe];
+
+ for (num_rects = drw->num_rects; num_rects--; rect++) {
+ int y1 = max(rect->y1, top);
+ int y2 = min(rect->y2, bottom);
+
+ if (y1 >= y2)
+ continue;
+
+ BEGIN_LP_RING(8);
+
+ OUT_RING(cmd);
+ OUT_RING(pitchropcpp);
+ OUT_RING((y1 << 16) | rect->x1);
+ OUT_RING((y2 << 16) | rect->x2);
+ OUT_RING(sarea_priv->front_offset);
+ OUT_RING((y1 << 16) | rect->x1);
+ OUT_RING(pitchropcpp & 0xffff);
+ OUT_RING(sarea_priv->back_offset);
+
+ ADVANCE_LP_RING();
+ }
}
}
- spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags);
+ spin_unlock_irqrestore(&dev->drw_lock, irqflags);
+
+ list_for_each_safe(hit, tmp, &hits) {
+ drm_i915_vbl_swap_t *swap_hit =
+ list_entry(hit, drm_i915_vbl_swap_t, head);
+
+ list_del(hit);
+
+ drm_free(swap_hit, sizeof(*swap_hit), DRM_MEM_DRIVER);
+ }
}
irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
diff --git a/drivers/char/drm/r128_drm.h b/drivers/char/drm/r128_drm.h
index 5d835b006f55..6e8af313f2b4 100644
--- a/drivers/char/drm/r128_drm.h
+++ b/drivers/char/drm/r128_drm.h
@@ -1,7 +1,8 @@
/* r128_drm.h -- Public header for the r128 driver -*- linux-c -*-
* Created: Wed Apr 5 19:24:19 2000 by kevin@precisioninsight.com
*/
-/* Copyright 2000 Precision Insight, Inc., Cedar Park, Texas.
+/*
+ * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All rights reserved.
*
diff --git a/drivers/char/drm/r128_drv.h b/drivers/char/drm/r128_drv.h
index 94abffb2cca5..f1efb49de8df 100644
--- a/drivers/char/drm/r128_drv.h
+++ b/drivers/char/drm/r128_drv.h
@@ -1,7 +1,8 @@
/* r128_drv.h -- Private header for r128 driver -*- linux-c -*-
* Created: Mon Dec 13 09:51:11 1999 by faith@precisioninsight.com
*/
-/* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+/*
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All rights reserved.
*
diff --git a/drivers/char/drm/r128_state.c b/drivers/char/drm/r128_state.c
index a080cdd6081e..17b11e7d8f32 100644
--- a/drivers/char/drm/r128_state.c
+++ b/drivers/char/drm/r128_state.c
@@ -1,7 +1,8 @@
/* r128_state.c -- State support for r128 -*- linux-c -*-
* Created: Thu Jan 27 02:53:43 2000 by gareth@valinux.com
*/
-/* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+/*
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
diff --git a/drivers/char/drm/r300_cmdbuf.c b/drivers/char/drm/r300_cmdbuf.c
index d14477ba3679..032a022ec6a8 100644
--- a/drivers/char/drm/r300_cmdbuf.c
+++ b/drivers/char/drm/r300_cmdbuf.c
@@ -242,26 +242,6 @@ static __inline__ int r300_check_range(unsigned reg, int count)
return 0;
}
-/*
- * we expect offsets passed to the framebuffer to be either within video
- * memory or within AGP space
- */
-static __inline__ int r300_check_offset(drm_radeon_private_t *dev_priv,
- u32 offset)
-{
- /* we realy want to check against end of video aperture
- but this value is not being kept.
- This code is correct for now (does the same thing as the
- code that sets MC_FB_LOCATION) in radeon_cp.c */
- if (offset >= dev_priv->fb_location &&
- offset < (dev_priv->fb_location + dev_priv->fb_size))
- return 0;
- if (offset >= dev_priv->gart_vm_start &&
- offset < (dev_priv->gart_vm_start + dev_priv->gart_size))
- return 0;
- return 1;
-}
-
static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t *
dev_priv,
drm_radeon_kcmd_buffer_t
@@ -290,7 +270,7 @@ static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t *
case MARK_SAFE:
break;
case MARK_CHECK_OFFSET:
- if (r300_check_offset(dev_priv, (u32) values[i])) {
+ if (!radeon_check_offset(dev_priv, (u32) values[i])) {
DRM_ERROR
("Offset failed range check (reg=%04x sz=%d)\n",
reg, sz);
@@ -452,7 +432,7 @@ static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t *dev_priv,
i = 1;
while ((k < narrays) && (i < (count + 1))) {
i++; /* skip attribute field */
- if (r300_check_offset(dev_priv, payload[i])) {
+ if (!radeon_check_offset(dev_priv, payload[i])) {
DRM_ERROR
("Offset failed range check (k=%d i=%d) while processing 3D_LOAD_VBPNTR packet.\n",
k, i);
@@ -463,7 +443,7 @@ static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t *dev_priv,
if (k == narrays)
break;
/* have one more to process, they come in pairs */
- if (r300_check_offset(dev_priv, payload[i])) {
+ if (!radeon_check_offset(dev_priv, payload[i])) {
DRM_ERROR
("Offset failed range check (k=%d i=%d) while processing 3D_LOAD_VBPNTR packet.\n",
k, i);
@@ -508,7 +488,7 @@ static __inline__ int r300_emit_bitblt_multi(drm_radeon_private_t *dev_priv,
if (cmd[1] & (RADEON_GMC_SRC_PITCH_OFFSET_CNTL
| RADEON_GMC_DST_PITCH_OFFSET_CNTL)) {
offset = cmd[2] << 10;
- ret = r300_check_offset(dev_priv, offset);
+ ret = !radeon_check_offset(dev_priv, offset);
if (ret) {
DRM_ERROR("Invalid bitblt first offset is %08X\n", offset);
return DRM_ERR(EINVAL);
@@ -518,7 +498,7 @@ static __inline__ int r300_emit_bitblt_multi(drm_radeon_private_t *dev_priv,
if ((cmd[1] & RADEON_GMC_SRC_PITCH_OFFSET_CNTL) &&
(cmd[1] & RADEON_GMC_DST_PITCH_OFFSET_CNTL)) {
offset = cmd[3] << 10;
- ret = r300_check_offset(dev_priv, offset);
+ ret = !radeon_check_offset(dev_priv, offset);
if (ret) {
DRM_ERROR("Invalid bitblt second offset is %08X\n", offset);
return DRM_ERR(EINVAL);
@@ -551,7 +531,7 @@ static __inline__ int r300_emit_indx_buffer(drm_radeon_private_t *dev_priv,
DRM_ERROR("Invalid indx_buffer reg address %08X\n", cmd[1]);
return DRM_ERR(EINVAL);
}
- ret = r300_check_offset(dev_priv, cmd[2]);
+ ret = !radeon_check_offset(dev_priv, cmd[2]);
if (ret) {
DRM_ERROR("Invalid indx_buffer offset is %08X\n", cmd[2]);
return DRM_ERR(EINVAL);
diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h
index f45cd7f147a5..8b105f1460a7 100644
--- a/drivers/char/drm/radeon_drv.h
+++ b/drivers/char/drm/radeon_drv.h
@@ -303,6 +303,21 @@ extern int radeon_no_wb;
extern drm_ioctl_desc_t radeon_ioctls[];
extern int radeon_max_ioctl;
+/* Check whether the given hardware address is inside the framebuffer or the
+ * GART area.
+ */
+static __inline__ int radeon_check_offset(drm_radeon_private_t *dev_priv,
+ u64 off)
+{
+ u32 fb_start = dev_priv->fb_location;
+ u32 fb_end = fb_start + dev_priv->fb_size - 1;
+ u32 gart_start = dev_priv->gart_vm_start;
+ u32 gart_end = gart_start + dev_priv->gart_size - 1;
+
+ return ((off >= fb_start && off <= fb_end) ||
+ (off >= gart_start && off <= gart_end));
+}
+
/* radeon_cp.c */
extern int radeon_cp_init(DRM_IOCTL_ARGS);
extern int radeon_cp_start(DRM_IOCTL_ARGS);
diff --git a/drivers/char/drm/radeon_irq.c b/drivers/char/drm/radeon_irq.c
index d60519de887b..3ff0baa2fbfa 100644
--- a/drivers/char/drm/radeon_irq.c
+++ b/drivers/char/drm/radeon_irq.c
@@ -1,5 +1,5 @@
-/* radeon_irq.c -- IRQ handling for radeon -*- linux-c -*-
- *
+/* radeon_irq.c -- IRQ handling for radeon -*- linux-c -*- */
+/*
* Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
*
* The Weather Channel (TM) funded Tungsten Graphics to develop the
diff --git a/drivers/char/drm/radeon_mem.c b/drivers/char/drm/radeon_mem.c
index 030a6fad0d86..517cad8b6e3a 100644
--- a/drivers/char/drm/radeon_mem.c
+++ b/drivers/char/drm/radeon_mem.c
@@ -1,5 +1,5 @@
-/* radeon_mem.c -- Simple GART/fb memory manager for radeon -*- linux-c -*-
- *
+/* radeon_mem.c -- Simple GART/fb memory manager for radeon -*- linux-c -*- */
+/*
* Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
*
* The Weather Channel (TM) funded Tungsten Graphics to develop the
diff --git a/drivers/char/drm/radeon_state.c b/drivers/char/drm/radeon_state.c
index 6e04fdd732ac..938eccb78cc0 100644
--- a/drivers/char/drm/radeon_state.c
+++ b/drivers/char/drm/radeon_state.c
@@ -43,10 +43,7 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t *
u32 *offset)
{
u64 off = *offset;
- u32 fb_start = dev_priv->fb_location;
- u32 fb_end = fb_start + dev_priv->fb_size - 1;
- u32 gart_start = dev_priv->gart_vm_start;
- u32 gart_end = gart_start + dev_priv->gart_size - 1;
+ u32 fb_end = dev_priv->fb_location + dev_priv->fb_size - 1;
struct drm_radeon_driver_file_fields *radeon_priv;
/* Hrm ... the story of the offset ... So this function converts
@@ -66,8 +63,7 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t *
/* First, the best case, the offset already lands in either the
* framebuffer or the GART mapped space
*/
- if ((off >= fb_start && off <= fb_end) ||
- (off >= gart_start && off <= gart_end))
+ if (radeon_check_offset(dev_priv, off))
return 0;
/* Ok, that didn't happen... now check if we have a zero based
@@ -81,11 +77,10 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t *
/* Finally, assume we aimed at a GART offset if beyond the fb */
if (off > fb_end)
- off = off - fb_end - 1 + gart_start;
+ off = off - fb_end - 1 + dev_priv->gart_vm_start;
/* Now recheck and fail if out of bounds */
- if ((off >= fb_start && off <= fb_end) ||
- (off >= gart_start && off <= gart_end)) {
+ if (radeon_check_offset(dev_priv, off)) {
DRM_DEBUG("offset fixed up to 0x%x\n", (unsigned int)off);
*offset = off;
return 0;
diff --git a/drivers/char/drm/savage_bci.c b/drivers/char/drm/savage_bci.c
index a9a84f88df5e..b94fab556809 100644
--- a/drivers/char/drm/savage_bci.c
+++ b/drivers/char/drm/savage_bci.c
@@ -963,8 +963,8 @@ static int savage_bci_event_emit(DRM_IOCTL_ARGS)
event.count = savage_bci_emit_event(dev_priv, event.flags);
event.count |= dev_priv->event_wrap << 16;
- DRM_COPY_TO_USER_IOCTL(&((drm_savage_event_emit_t __user *) data)->
- count, event.count, sizeof(event.count));
+ DRM_COPY_TO_USER_IOCTL((drm_savage_event_emit_t __user *) data,
+ event, sizeof(event));
return 0;
}
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c
index 78280380a905..6b634e8d9519 100644
--- a/drivers/char/ipmi/ipmi_watchdog.c
+++ b/drivers/char/ipmi/ipmi_watchdog.c
@@ -216,13 +216,13 @@ static int set_param_str(const char *val, struct kernel_param *kp)
{
action_fn fn = (action_fn) kp->arg;
int rv = 0;
- char *dup, *s;
+ char valcp[16];
+ char *s;
- dup = kstrdup(val, GFP_KERNEL);
- if (!dup)
- return -ENOMEM;
+ strncpy(valcp, val, 16);
+ valcp[15] = '\0';
- s = strstrip(dup);
+ s = strstrip(valcp);
down_read(&register_sem);
rv = fn(s, NULL);
@@ -235,7 +235,6 @@ static int set_param_str(const char *val, struct kernel_param *kp)
out_unlock:
up_read(&register_sem);
- kfree(dup);
return rv;
}
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index 5a747e685993..01084abffddf 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -230,6 +230,20 @@ static struct isi_port isi_ports[PORT_COUNT];
* it wants to talk.
*/
+static inline int WaitTillCardIsFree(u16 base)
+{
+ unsigned int count = 0;
+ unsigned int a = in_atomic(); /* do we run under spinlock? */
+
+ while (!(inw(base + 0xe) & 0x1) && count++ < 100)
+ if (a)
+ mdelay(1);
+ else
+ msleep(1);
+
+ return !(inw(base + 0xe) & 0x1);
+}
+
static int lock_card(struct isi_board *card)
{
char retries;
@@ -276,69 +290,71 @@ static void unlock_card(struct isi_board *card)
* ISI Card specific ops ...
*/
+/* card->lock HAS to be held */
static void raise_dtr(struct isi_port *port)
{
struct isi_board *card = port->card;
unsigned long base = card->base;
u16 channel = port->channel;
- if (!lock_card(card))
+ if (WaitTillCardIsFree(base))
return;
outw(0x8000 | (channel << card->shift_count) | 0x02, base);
outw(0x0504, base);
InterruptTheCard(base);
port->status |= ISI_DTR;
- unlock_card(card);
}
+/* card->lock HAS to be held */
static inline void drop_dtr(struct isi_port *port)
{
struct isi_board *card = port->card;
unsigned long base = card->base;
u16 channel = port->channel;
- if (!lock_card(card))
+ if (WaitTillCardIsFree(base))
return;
outw(0x8000 | (channel << card->shift_count) | 0x02, base);
outw(0x0404, base);
InterruptTheCard(base);
port->status &= ~ISI_DTR;
- unlock_card(card);
}
+/* card->lock HAS to be held */
static inline void raise_rts(struct isi_port *port)
{
struct isi_board *card = port->card;
unsigned long base = card->base;
u16 channel = port->channel;
- if (!lock_card(card))
+ if (WaitTillCardIsFree(base))
return;
outw(0x8000 | (channel << card->shift_count) | 0x02, base);
outw(0x0a04, base);
InterruptTheCard(base);
port->status |= ISI_RTS;
- unlock_card(card);
}
+
+/* card->lock HAS to be held */
static inline void drop_rts(struct isi_port *port)
{
struct isi_board *card = port->card;
unsigned long base = card->base;
u16 channel = port->channel;
- if (!lock_card(card))
+ if (WaitTillCardIsFree(base))
return;
outw(0x8000 | (channel << card->shift_count) | 0x02, base);
outw(0x0804, base);
InterruptTheCard(base);
port->status &= ~ISI_RTS;
- unlock_card(card);
}
+/* card->lock MUST NOT be held */
static inline void raise_dtr_rts(struct isi_port *port)
{
struct isi_board *card = port->card;
@@ -355,35 +371,20 @@ static inline void raise_dtr_rts(struct isi_port *port)
unlock_card(card);
}
+/* card->lock HAS to be held */
static void drop_dtr_rts(struct isi_port *port)
{
struct isi_board *card = port->card;
unsigned long base = card->base;
u16 channel = port->channel;
- if (!lock_card(card))
+ if (WaitTillCardIsFree(base))
return;
outw(0x8000 | (channel << card->shift_count) | 0x02, base);
outw(0x0c04, base);
InterruptTheCard(base);
port->status &= ~(ISI_RTS | ISI_DTR);
- unlock_card(card);
-}
-
-static inline void kill_queue(struct isi_port *port, short queue)
-{
- struct isi_board *card = port->card;
- unsigned long base = card->base;
- u16 channel = port->channel;
-
- if (!lock_card(card))
- return;
-
- outw(0x8000 | (channel << card->shift_count) | 0x02, base);
- outw((queue << 8) | 0x06, base);
- InterruptTheCard(base);
- unlock_card(card);
}
/*
@@ -744,7 +745,7 @@ static void isicom_config_port(struct isi_port *port)
else
raise_dtr(port);
- if (lock_card(card)) {
+ if (WaitTillCardIsFree(base) == 0) {
outw(0x8000 | (channel << shift_count) |0x03, base);
outw(linuxb_to_isib[baud] << 8 | 0x03, base);
channel_setup = 0;
@@ -772,7 +773,6 @@ static void isicom_config_port(struct isi_port *port)
}
outw(channel_setup, base);
InterruptTheCard(base);
- unlock_card(card);
}
if (C_CLOCAL(tty))
port->flags &= ~ASYNC_CHECK_CD;
@@ -791,12 +791,11 @@ static void isicom_config_port(struct isi_port *port)
if (I_IXOFF(tty))
flow_ctrl |= ISICOM_INITIATE_XONXOFF;
- if (lock_card(card)) {
+ if (WaitTillCardIsFree(base) == 0) {
outw(0x8000 | (channel << shift_count) |0x04, base);
outw(flow_ctrl << 8 | 0x05, base);
outw((STOP_CHAR(tty)) << 8 | (START_CHAR(tty)), base);
InterruptTheCard(base);
- unlock_card(card);
}
/* rx enabled -> enable port for rx on the card */
@@ -821,10 +820,9 @@ static inline void isicom_setup_board(struct isi_board *bp)
}
port = bp->ports;
bp->status |= BOARD_ACTIVE;
- spin_unlock_irqrestore(&bp->card_lock, flags);
for (channel = 0; channel < bp->port_count; channel++, port++)
drop_dtr_rts(port);
- return;
+ spin_unlock_irqrestore(&bp->card_lock, flags);
}
static int isicom_setup_port(struct isi_port *port)
@@ -857,7 +855,12 @@ static int isicom_setup_port(struct isi_port *port)
port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
/* discard any residual data */
- kill_queue(port, ISICOM_KILLTX | ISICOM_KILLRX);
+ if (WaitTillCardIsFree(card->base) == 0) {
+ outw(0x8000 | (port->channel << card->shift_count) | 0x02,
+ card->base);
+ outw(((ISICOM_KILLTX | ISICOM_KILLRX) << 8) | 0x06, card->base);
+ InterruptTheCard(card->base);
+ }
isicom_config_port(port);
port->flags |= ASYNC_INITIALIZED;
@@ -983,28 +986,22 @@ static int isicom_open(struct tty_struct *tty, struct file *filp)
static inline void isicom_shutdown_board(struct isi_board *bp)
{
- unsigned long flags;
-
- spin_lock_irqsave(&bp->card_lock, flags);
if (bp->status & BOARD_ACTIVE) {
bp->status &= ~BOARD_ACTIVE;
}
- spin_unlock_irqrestore(&bp->card_lock, flags);
}
+/* card->lock HAS to be held */
static void isicom_shutdown_port(struct isi_port *port)
{
struct isi_board *card = port->card;
struct tty_struct *tty;
- unsigned long flags;
tty = port->tty;
- spin_lock_irqsave(&card->card_lock, flags);
- if (!(port->flags & ASYNC_INITIALIZED)) {
- spin_unlock_irqrestore(&card->card_lock, flags);
+ if (!(port->flags & ASYNC_INITIALIZED))
return;
- }
+
if (port->xmit_buf) {
free_page((unsigned long) port->xmit_buf);
port->xmit_buf = NULL;
@@ -1012,7 +1009,6 @@ static void isicom_shutdown_port(struct isi_port *port)
port->flags &= ~ASYNC_INITIALIZED;
/* 3rd October 2000 : Vinayak P Risbud */
port->tty = NULL;
- spin_unlock_irqrestore(&card->card_lock, flags);
/*Fix done by Anil .S on 30-04-2001
remote login through isi port has dtr toggle problem
@@ -1258,10 +1254,12 @@ static int isicom_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear)
{
struct isi_port *port = tty->driver_data;
+ unsigned long flags;
if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
return -ENODEV;
+ spin_lock_irqsave(&port->card->card_lock, flags);
if (set & TIOCM_RTS)
raise_rts(port);
if (set & TIOCM_DTR)
@@ -1271,6 +1269,7 @@ static int isicom_tiocmset(struct tty_struct *tty, struct file *file,
drop_rts(port);
if (clear & TIOCM_DTR)
drop_dtr(port);
+ spin_unlock_irqrestore(&port->card->card_lock, flags);
return 0;
}
@@ -1303,7 +1302,10 @@ static int isicom_set_serial_info(struct isi_port *port,
(newinfo.flags & ASYNC_FLAGS));
}
if (reconfig_port) {
+ unsigned long flags;
+ spin_lock_irqsave(&port->card->card_lock, flags);
isicom_config_port(port);
+ spin_unlock_irqrestore(&port->card->card_lock, flags);
}
return 0;
}
@@ -1384,6 +1386,7 @@ static void isicom_set_termios(struct tty_struct *tty,
struct ktermios *old_termios)
{
struct isi_port *port = tty->driver_data;
+ unsigned long flags;
if (isicom_paranoia_check(port, tty->name, "isicom_set_termios"))
return;
@@ -1392,7 +1395,9 @@ static void isicom_set_termios(struct tty_struct *tty,
tty->termios->c_iflag == old_termios->c_iflag)
return;
+ spin_lock_irqsave(&port->card->card_lock, flags);
isicom_config_port(port);
+ spin_unlock_irqrestore(&port->card->card_lock, flags);
if ((old_termios->c_cflag & CRTSCTS) &&
!(tty->termios->c_cflag & CRTSCTS)) {
@@ -1469,11 +1474,15 @@ static void do_isicom_hangup(struct work_struct *work)
static void isicom_hangup(struct tty_struct *tty)
{
struct isi_port *port = tty->driver_data;
+ unsigned long flags;
if (isicom_paranoia_check(port, tty->name, "isicom_hangup"))
return;
+ spin_lock_irqsave(&port->card->card_lock, flags);
isicom_shutdown_port(port);
+ spin_unlock_irqrestore(&port->card->card_lock, flags);
+
port->count = 0;
port->flags &= ~ASYNC_NORMAL_ACTIVE;
port->tty = NULL;
@@ -1578,16 +1587,6 @@ end:
return retval;
}
-static inline int WaitTillCardIsFree(u16 base)
-{
- unsigned long count = 0;
-
- while (!(inw(base + 0xe) & 0x1) && count++ < 100)
- msleep(5);
-
- return !(inw(base + 0xe) & 0x1);
-}
-
static int __devinit load_firmware(struct pci_dev *pdev,
const unsigned int index, const unsigned int signature)
{
diff --git a/drivers/char/lcd.c b/drivers/char/lcd.c
index da601fd6c07a..d649abbf0857 100644
--- a/drivers/char/lcd.c
+++ b/drivers/char/lcd.c
@@ -459,7 +459,7 @@ static int lcd_ioctl(struct inode *inode, struct file *file,
(&display, (struct lcd_display *) arg,
sizeof(struct lcd_display)))
return -EFAULT;
- rom = (unsigned char *) kmalloc((128), GFP_ATOMIC);
+ rom = kmalloc((128), GFP_ATOMIC);
if (rom == NULL) {
printk(KERN_ERR LCD "kmalloc() failed in %s\n",
__FUNCTION__);
diff --git a/drivers/char/lp.c b/drivers/char/lp.c
index b70b5388b5a8..b51d08be0bcf 100644
--- a/drivers/char/lp.c
+++ b/drivers/char/lp.c
@@ -525,7 +525,7 @@ static int lp_open(struct inode * inode, struct file * file)
return -EIO;
}
}
- lp_table[minor].lp_buffer = (char *) kmalloc(LP_BUFFER_SIZE, GFP_KERNEL);
+ lp_table[minor].lp_buffer = kmalloc(LP_BUFFER_SIZE, GFP_KERNEL);
if (!lp_table[minor].lp_buffer) {
LP_F(minor) &= ~LP_BUSY;
return -ENOMEM;
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index c063359baf78..83f604b19290 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -717,6 +717,7 @@ static int mxser_init(void)
/* Initialize the tty_driver structure */
memset(mxvar_sdriver, 0, sizeof(struct tty_driver));
+ mxvar_sdriver->owner = THIS_MODULE;
mxvar_sdriver->magic = TTY_DRIVER_MAGIC;
mxvar_sdriver->name = "ttyMI";
mxvar_sdriver->major = ttymajor;
diff --git a/drivers/char/mxser_new.c b/drivers/char/mxser_new.c
index efa8076c33e0..1bb030b3a51a 100644
--- a/drivers/char/mxser_new.c
+++ b/drivers/char/mxser_new.c
@@ -315,6 +315,7 @@ static struct mxser_mon_ext mon_data_ext;
static int mxser_set_baud_method[MXSER_PORTS + 1];
static spinlock_t gm_lock;
+#ifdef CONFIG_PCI
static int CheckIsMoxaMust(int io)
{
u8 oldmcr, hwid;
@@ -337,6 +338,7 @@ static int CheckIsMoxaMust(int io)
}
return MOXA_OTHER_UART;
}
+#endif
static void process_txrx_fifo(struct mxser_port *info)
{
@@ -2380,9 +2382,11 @@ static void mxser_release_res(struct mxser_board *brd, struct pci_dev *pdev,
if (irq)
free_irq(brd->irq, brd);
if (pdev != NULL) { /* PCI */
+#ifdef CONFIG_PCI
pci_release_region(pdev, 2);
pci_release_region(pdev, 3);
pci_dev_put(pdev);
+#endif
} else {
release_region(brd->ports[0].ioaddr, 8 * brd->info->nports);
release_region(brd->vector, 1);
@@ -2546,6 +2550,7 @@ static int __init mxser_get_ISA_conf(int cap, struct mxser_board *brd)
static int __devinit mxser_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
+#ifdef CONFIG_PCI
struct mxser_board *brd;
unsigned int i, j;
unsigned long ioaddress;
@@ -2644,6 +2649,9 @@ err_relio:
brd->info = NULL;
err:
return retval;
+#else
+ return -ENODEV;
+#endif
}
static void __devexit mxser_remove(struct pci_dev *pdev)
@@ -2682,6 +2690,7 @@ static int __init mxser_module_init(void)
MXSER_VERSION);
/* Initialize the tty_driver structure */
+ mxvar_sdriver->owner = THIS_MODULE;
mxvar_sdriver->magic = TTY_DRIVER_MAGIC;
mxvar_sdriver->name = "ttyMI";
mxvar_sdriver->major = ttymajor;
diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c
index 103d338f21e2..dc6d41841457 100644
--- a/drivers/char/n_r3964.c
+++ b/drivers/char/n_r3964.c
@@ -125,8 +125,8 @@ static void transmit_block(struct r3964_info *pInfo);
static void receive_char(struct r3964_info *pInfo, const unsigned char c);
static void receive_error(struct r3964_info *pInfo, const char flag);
static void on_timeout(unsigned long priv);
-static int enable_signals(struct r3964_info *pInfo, pid_t pid, int arg);
-static int read_telegram(struct r3964_info *pInfo, pid_t pid, unsigned char __user *buf);
+static int enable_signals(struct r3964_info *pInfo, struct pid *pid, int arg);
+static int read_telegram(struct r3964_info *pInfo, struct pid *pid, unsigned char __user *buf);
static void add_msg(struct r3964_client_info *pClient, int msg_id, int arg,
int error_code, struct r3964_block_header *pBlock);
static struct r3964_message* remove_msg(struct r3964_info *pInfo,
@@ -829,7 +829,7 @@ static void on_timeout(unsigned long priv)
}
static struct r3964_client_info *findClient(
- struct r3964_info *pInfo, pid_t pid)
+ struct r3964_info *pInfo, struct pid *pid)
{
struct r3964_client_info *pClient;
@@ -843,7 +843,7 @@ static struct r3964_client_info *findClient(
return NULL;
}
-static int enable_signals(struct r3964_info *pInfo, pid_t pid, int arg)
+static int enable_signals(struct r3964_info *pInfo, struct pid *pid, int arg)
{
struct r3964_client_info *pClient;
struct r3964_client_info **ppClient;
@@ -858,7 +858,7 @@ static int enable_signals(struct r3964_info *pInfo, pid_t pid, int arg)
if(pClient->pid == pid)
{
- TRACE_PS("removing client %d from client list", pid);
+ TRACE_PS("removing client %d from client list", pid_nr(pid));
*ppClient = pClient->next;
while(pClient->msg_count)
{
@@ -869,6 +869,7 @@ static int enable_signals(struct r3964_info *pInfo, pid_t pid, int arg)
TRACE_M("enable_signals - msg kfree %p",pMsg);
}
}
+ put_pid(pClient->pid);
kfree(pClient);
TRACE_M("enable_signals - kfree %p",pClient);
return 0;
@@ -892,10 +893,10 @@ static int enable_signals(struct r3964_info *pInfo, pid_t pid, int arg)
if(pClient==NULL)
return -ENOMEM;
- TRACE_PS("add client %d to client list", pid);
+ TRACE_PS("add client %d to client list", pid_nr(pid));
spin_lock_init(&pClient->lock);
pClient->sig_flags=arg;
- pClient->pid = pid;
+ pClient->pid = get_pid(pid);
pClient->next=pInfo->firstClient;
pClient->first_msg = NULL;
pClient->last_msg = NULL;
@@ -908,7 +909,7 @@ static int enable_signals(struct r3964_info *pInfo, pid_t pid, int arg)
return 0;
}
-static int read_telegram(struct r3964_info *pInfo, pid_t pid, unsigned char __user *buf)
+static int read_telegram(struct r3964_info *pInfo, struct pid *pid, unsigned char __user *buf)
{
struct r3964_client_info *pClient;
struct r3964_block_header *block;
@@ -1005,7 +1006,7 @@ queue_the_message:
/* Send SIGIO signal to client process: */
if(pClient->sig_flags & R3964_USE_SIGIO)
{
- kill_proc(pClient->pid, SIGIO, 1);
+ kill_pid(pClient->pid, SIGIO, 1);
}
}
@@ -1042,7 +1043,7 @@ static void remove_client_block(struct r3964_info *pInfo,
{
struct r3964_block_header *block;
- TRACE_PS("remove_client_block PID %d", pClient->pid);
+ TRACE_PS("remove_client_block PID %d", pid_nr(pClient->pid));
block=pClient->next_block_to_read;
if(block)
@@ -1157,6 +1158,7 @@ static void r3964_close(struct tty_struct *tty)
TRACE_M("r3964_close - msg kfree %p",pMsg);
}
}
+ put_pid(pClient->pid);
kfree(pClient);
TRACE_M("r3964_close - client kfree %p",pClient);
pClient=pNext;
@@ -1193,12 +1195,11 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
struct r3964_client_message theMsg;
DECLARE_WAITQUEUE (wait, current);
- int pid = current->pid;
int count;
TRACE_L("read()");
- pClient=findClient(pInfo, pid);
+ pClient=findClient(pInfo, task_pid(current));
if(pClient)
{
pMsg = remove_msg(pInfo, pClient);
@@ -1252,7 +1253,6 @@ static ssize_t r3964_write(struct tty_struct * tty, struct file * file,
struct r3964_block_header *pHeader;
struct r3964_client_info *pClient;
unsigned char *new_data;
- int pid;
TRACE_L("write request, %d characters", count);
/*
@@ -1295,9 +1295,7 @@ static ssize_t r3964_write(struct tty_struct * tty, struct file * file,
pHeader->locks = 0;
pHeader->owner = NULL;
- pid=current->pid;
-
- pClient=findClient(pInfo, pid);
+ pClient=findClient(pInfo, task_pid(current));
if(pClient)
{
pHeader->owner = pClient;
@@ -1328,7 +1326,7 @@ static int r3964_ioctl(struct tty_struct * tty, struct file * file,
switch(cmd)
{
case R3964_ENABLE_SIGNALS:
- return enable_signals(pInfo, current->pid, arg);
+ return enable_signals(pInfo, task_pid(current), arg);
case R3964_SETPRIORITY:
if(arg<R3964_MASTER || arg>R3964_SLAVE)
return -EINVAL;
@@ -1341,7 +1339,7 @@ static int r3964_ioctl(struct tty_struct * tty, struct file * file,
pInfo->flags &= ~R3964_BCC;
return 0;
case R3964_READ_TELEGRAM:
- return read_telegram(pInfo, current->pid, (unsigned char __user *)arg);
+ return read_telegram(pInfo, task_pid(current), (unsigned char __user *)arg);
default:
return -ENOIOCTLCMD;
}
@@ -1357,7 +1355,6 @@ static unsigned int r3964_poll(struct tty_struct * tty, struct file * file,
struct poll_table_struct *wait)
{
struct r3964_info *pInfo=(struct r3964_info*)tty->disc_data;
- int pid=current->pid;
struct r3964_client_info *pClient;
struct r3964_message *pMsg=NULL;
unsigned long flags;
@@ -1365,7 +1362,7 @@ static unsigned int r3964_poll(struct tty_struct * tty, struct file * file,
TRACE_L("POLL");
- pClient=findClient(pInfo,pid);
+ pClient=findClient(pInfo, task_pid(current));
if(pClient)
{
poll_wait(file, &pInfo->read_wait, wait);
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c
index e96a00fe1389..2bdb0144a22e 100644
--- a/drivers/char/n_tty.c
+++ b/drivers/char/n_tty.c
@@ -1151,7 +1151,6 @@ static int copy_from_read_buf(struct tty_struct *tty,
n = min(*nr, n);
spin_unlock_irqrestore(&tty->read_lock, flags);
if (n) {
- mb();
retval = copy_to_user(*b, &tty->read_buf[tty->read_tail], n);
n -= retval;
spin_lock_irqsave(&tty->read_lock, flags);
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index 5152cedd8878..f108c136800a 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -541,7 +541,7 @@ static int mgslpc_probe(struct pcmcia_device *link)
if (debug_level >= DEBUG_LEVEL_INFO)
printk("mgslpc_attach\n");
- info = (MGSLPC_INFO *)kmalloc(sizeof(MGSLPC_INFO), GFP_KERNEL);
+ info = kmalloc(sizeof(MGSLPC_INFO), GFP_KERNEL);
if (!info) {
printk("Error can't allocate device instance data\n");
return -ENOMEM;
diff --git a/drivers/char/rio/riocmd.c b/drivers/char/rio/riocmd.c
index 167ebc84e8d7..245f03195b7c 100644
--- a/drivers/char/rio/riocmd.c
+++ b/drivers/char/rio/riocmd.c
@@ -556,7 +556,7 @@ struct CmdBlk *RIOGetCmdBlk(void)
{
struct CmdBlk *CmdBlkP;
- CmdBlkP = (struct CmdBlk *)kmalloc(sizeof(struct CmdBlk), GFP_ATOMIC);
+ CmdBlkP = kmalloc(sizeof(struct CmdBlk), GFP_ATOMIC);
if (CmdBlkP)
memset(CmdBlkP, 0, sizeof(struct CmdBlk));
return CmdBlkP;
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c
index 66a7385bc34a..664f36c98e6a 100644
--- a/drivers/char/rtc.c
+++ b/drivers/char/rtc.c
@@ -113,7 +113,12 @@ static int rtc_has_irq = 1;
#define hpet_set_rtc_irq_bit(arg) 0
#define hpet_rtc_timer_init() do { } while (0)
#define hpet_rtc_dropped_irq() 0
-static inline irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id) {return 0;}
+#ifdef RTC_IRQ
+static irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id)
+{
+ return 0;
+}
+#endif
#else
extern irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id);
#endif
@@ -165,7 +170,9 @@ static void mask_rtc_irq_bit(unsigned char bit)
}
#endif
+#ifdef CONFIG_PROC_FS
static int rtc_proc_open(struct inode *inode, struct file *file);
+#endif
/*
* Bits in rtc_status. (6 bits of room for future expansion)
@@ -906,6 +913,7 @@ static struct miscdevice rtc_dev = {
.fops = &rtc_fops,
};
+#ifdef CONFIG_PROC_FS
static const struct file_operations rtc_proc_fops = {
.owner = THIS_MODULE,
.open = rtc_proc_open,
@@ -913,14 +921,13 @@ static const struct file_operations rtc_proc_fops = {
.llseek = seq_lseek,
.release = single_release,
};
-
-#if defined(RTC_IRQ) && !defined(__sparc__)
-static irq_handler_t rtc_int_handler_ptr;
#endif
static int __init rtc_init(void)
{
+#ifdef CONFIG_PROC_FS
struct proc_dir_entry *ent;
+#endif
#if defined(__alpha__) || defined(__mips__)
unsigned int year, ctrl;
char *guess = NULL;
@@ -932,9 +939,11 @@ static int __init rtc_init(void)
struct sparc_isa_bridge *isa_br;
struct sparc_isa_device *isa_dev;
#endif
-#endif
-#ifndef __sparc__
+#else
void *r;
+#ifdef RTC_IRQ
+ irq_handler_t rtc_int_handler_ptr;
+#endif
#endif
#ifdef __sparc__
@@ -958,6 +967,7 @@ static int __init rtc_init(void)
}
}
#endif
+ rtc_has_irq = 0;
printk(KERN_ERR "rtc_init: no PC rtc found\n");
return -EIO;
@@ -972,6 +982,7 @@ found:
* PCI Slot 2 INTA# (and some INTx# in Slot 1).
*/
if (request_irq(rtc_irq, rtc_interrupt, IRQF_SHARED, "rtc", (void *)&rtc_port)) {
+ rtc_has_irq = 0;
printk(KERN_ERR "rtc: cannot register IRQ %d\n", rtc_irq);
return -EIO;
}
@@ -982,6 +993,9 @@ no_irq:
else
r = request_mem_region(RTC_PORT(0), RTC_IO_EXTENT, "rtc");
if (!r) {
+#ifdef RTC_IRQ
+ rtc_has_irq = 0;
+#endif
printk(KERN_ERR "rtc: I/O resource %lx is not free.\n",
(long)(RTC_PORT(0)));
return -EIO;
@@ -996,6 +1010,7 @@ no_irq:
if(request_irq(RTC_IRQ, rtc_int_handler_ptr, IRQF_DISABLED, "rtc", NULL)) {
/* Yeah right, seeing as irq 8 doesn't even hit the bus. */
+ rtc_has_irq = 0;
printk(KERN_ERR "rtc: IRQ %d is not free.\n", RTC_IRQ);
if (RTC_IOMAPPED)
release_region(RTC_PORT(0), RTC_IO_EXTENT);
@@ -1012,21 +1027,19 @@ no_irq:
if (misc_register(&rtc_dev)) {
#ifdef RTC_IRQ
free_irq(RTC_IRQ, NULL);
+ rtc_has_irq = 0;
#endif
release_region(RTC_PORT(0), RTC_IO_EXTENT);
return -ENODEV;
}
+#ifdef CONFIG_PROC_FS
ent = create_proc_entry("driver/rtc", 0, NULL);
- if (!ent) {
-#ifdef RTC_IRQ
- free_irq(RTC_IRQ, NULL);
+ if (ent)
+ ent->proc_fops = &rtc_proc_fops;
+ else
+ printk(KERN_WARNING "rtc: Failed to register with procfs.\n");
#endif
- release_region(RTC_PORT(0), RTC_IO_EXTENT);
- misc_deregister(&rtc_dev);
- return -ENOMEM;
- }
- ent->proc_fops = &rtc_proc_fops;
#if defined(__alpha__) || defined(__mips__)
rtc_freq = HZ;
@@ -1159,6 +1172,7 @@ static void rtc_dropped_irq(unsigned long data)
}
#endif
+#ifdef CONFIG_PROC_FS
/*
* Info exported via "/proc/driver/rtc".
*/
@@ -1243,6 +1257,7 @@ static int rtc_proc_open(struct inode *inode, struct file *file)
{
return single_open(file, rtc_proc_show, NULL);
}
+#endif
void rtc_get_rtc_time(struct rtc_time *rtc_tm)
{
diff --git a/drivers/char/sx.c b/drivers/char/sx.c
index a3008ce13015..1da92a689ae4 100644
--- a/drivers/char/sx.c
+++ b/drivers/char/sx.c
@@ -2498,8 +2498,10 @@ static void __devexit sx_remove_card(struct sx_board *board,
/* It is safe/allowed to del_timer a non-active timer */
del_timer(&board->timer);
if (pdev) {
+#ifdef CONFIG_PCI
pci_iounmap(pdev, board->base);
pci_release_region(pdev, IS_CF_BOARD(board) ? 3 : 2);
+#endif
} else {
iounmap(board->base);
release_region(board->hw_base, board->hw_len);
@@ -2601,6 +2603,7 @@ static struct eisa_driver sx_eisadriver = {
#endif
+#ifdef CONFIG_PCI
/********************************************************
* Setting bit 17 in the CNTRL register of the PLX 9050 *
* chip forces a retry on writes while a read is pending.*
@@ -2632,10 +2635,12 @@ static void __devinit fix_sx_pci(struct pci_dev *pdev, struct sx_board *board)
}
iounmap(rebase);
}
+#endif
static int __devinit sx_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
+#ifdef CONFIG_PCI
struct sx_board *board;
unsigned int i, reg;
int retval = -EIO;
@@ -2700,6 +2705,9 @@ err_flag:
board->flags &= ~SX_BOARD_PRESENT;
err:
return retval;
+#else
+ return -ENODEV;
+#endif
}
static void __devexit sx_pci_remove(struct pci_dev *pdev)
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index acc6fab601cc..3fa625db9e4b 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -4332,7 +4332,7 @@ static struct mgsl_struct* mgsl_allocate_device(void)
{
struct mgsl_struct *info;
- info = (struct mgsl_struct *)kmalloc(sizeof(struct mgsl_struct),
+ info = kmalloc(sizeof(struct mgsl_struct),
GFP_KERNEL);
if (!info) {
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c
index 53e8ccf94fe3..8f4d67afe5bf 100644
--- a/drivers/char/synclinkmp.c
+++ b/drivers/char/synclinkmp.c
@@ -2730,7 +2730,7 @@ static int startup(SLMP_INFO * info)
return 0;
if (!info->tx_buf) {
- info->tx_buf = (unsigned char *)kmalloc(info->max_frame_size, GFP_KERNEL);
+ info->tx_buf = kmalloc(info->max_frame_size, GFP_KERNEL);
if (!info->tx_buf) {
printk(KERN_ERR"%s(%d):%s can't allocate transmit buffer\n",
__FILE__,__LINE__,info->device_name);
@@ -3798,7 +3798,7 @@ static SLMP_INFO *alloc_dev(int adapter_num, int port_num, struct pci_dev *pdev)
{
SLMP_INFO *info;
- info = (SLMP_INFO *)kmalloc(sizeof(SLMP_INFO),
+ info = kmalloc(sizeof(SLMP_INFO),
GFP_KERNEL);
if (!info) {
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index 05810c8d20bc..13935235e066 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -41,7 +41,34 @@
#include <asm/irq_regs.h>
/* Whether we react on sysrq keys or just ignore them */
-int sysrq_enabled = 1;
+int __read_mostly __sysrq_enabled = 1;
+
+static int __read_mostly sysrq_always_enabled;
+
+int sysrq_on(void)
+{
+ return __sysrq_enabled || sysrq_always_enabled;
+}
+
+/*
+ * A value of 1 means 'all', other nonzero values are an op mask:
+ */
+static inline int sysrq_on_mask(int mask)
+{
+ return sysrq_always_enabled || __sysrq_enabled == 1 ||
+ (__sysrq_enabled & mask);
+}
+
+static int __init sysrq_always_enabled_setup(char *str)
+{
+ sysrq_always_enabled = 1;
+ printk(KERN_INFO "debug: sysrq always enabled.\n");
+
+ return 1;
+}
+
+__setup("sysrq_always_enabled", sysrq_always_enabled_setup);
+
static void sysrq_handle_loglevel(int key, struct tty_struct *tty)
{
@@ -379,8 +406,7 @@ void __handle_sysrq(int key, struct tty_struct *tty, int check_mask)
* Should we check for enabled operations (/proc/sysrq-trigger
* should not) and is the invoked operation enabled?
*/
- if (!check_mask || sysrq_enabled == 1 ||
- (sysrq_enabled & op_p->enable_mask)) {
+ if (!check_mask || sysrq_on_mask(op_p->enable_mask)) {
printk("%s\n", op_p->action_msg);
console_loglevel = orig_log_level;
op_p->handler(key, tty);
@@ -414,9 +440,8 @@ void __handle_sysrq(int key, struct tty_struct *tty, int check_mask)
*/
void handle_sysrq(int key, struct tty_struct *tty)
{
- if (!sysrq_enabled)
- return;
- __handle_sysrq(key, tty, 1);
+ if (sysrq_on())
+ __handle_sysrq(key, tty, 1);
}
EXPORT_SYMBOL(handle_sysrq);
diff --git a/drivers/char/tlclk.c b/drivers/char/tlclk.c
index 244d30a03fef..448d5083c381 100644
--- a/drivers/char/tlclk.c
+++ b/drivers/char/tlclk.c
@@ -807,8 +807,6 @@ static int __init tlclk_init(void)
&tlclk_attribute_group);
if (ret) {
printk(KERN_ERR "tlclk: failed to create sysfs device attributes.\n");
- sysfs_remove_group(&tlclk_device->dev.kobj,
- &tlclk_attribute_group);
goto out5;
}
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 4044c864fdd4..47a6eacb10bc 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -3335,18 +3335,13 @@ static void __do_SAK(struct work_struct *work)
int session;
int i;
struct file *filp;
- struct tty_ldisc *disc;
struct fdtable *fdt;
if (!tty)
return;
session = tty->session;
- /* We don't want an ldisc switch during this */
- disc = tty_ldisc_ref(tty);
- if (disc && disc->flush_buffer)
- disc->flush_buffer(tty);
- tty_ldisc_deref(disc);
+ tty_ldisc_flush(tty);
if (tty->driver->flush_buffer)
tty->driver->flush_buffer(tty);
@@ -3821,6 +3816,7 @@ struct tty_struct *get_current_tty(void)
barrier();
return tty;
}
+EXPORT_SYMBOL_GPL(get_current_tty);
/*
* Initialize the console device. This is called *early*, so
diff --git a/drivers/char/viocons.c b/drivers/char/viocons.c
index 6d2e314860df..8de6b95aeb84 100644
--- a/drivers/char/viocons.c
+++ b/drivers/char/viocons.c
@@ -42,6 +42,7 @@
#include <linux/tty_flip.h>
#include <linux/sysrq.h>
+#include <asm/firmware.h>
#include <asm/iseries/vio.h>
#include <asm/iseries/hv_lp_event.h>
#include <asm/iseries/hv_call_event.h>
@@ -61,10 +62,7 @@
static DEFINE_SPINLOCK(consolelock);
static DEFINE_SPINLOCK(consoleloglock);
-#ifdef CONFIG_MAGIC_SYSRQ
static int vio_sysrq_pressed;
-extern int sysrq_enabled;
-#endif
#define VIOCHAR_NUM_BUF 16
@@ -936,8 +934,10 @@ static void vioHandleData(struct HvLpEvent *event)
*/
num_pushed = 0;
for (index = 0; index < cevent->len; index++) {
-#ifdef CONFIG_MAGIC_SYSRQ
- if (sysrq_enabled) {
+ /*
+ * Will be optimized away if !CONFIG_MAGIC_SYSRQ:
+ */
+ if (sysrq_on()) {
/* 0x0f is the ascii character for ^O */
if (cevent->data[index] == '\x0f') {
vio_sysrq_pressed = 1;
@@ -956,7 +956,6 @@ static void vioHandleData(struct HvLpEvent *event)
continue;
}
}
-#endif
/*
* The sysrq sequence isn't included in this check if
* sysrq is enabled and compiled into the kernel because
@@ -1062,6 +1061,9 @@ static int __init viocons_init2(void)
atomic_t wait_flag;
int rc;
+ if (!firmware_has_feature(FW_FEATURE_ISERIES))
+ return -ENODEV;
+
/* +2 for fudge */
rc = viopath_open(HvLpConfig_getPrimaryLpIndex(),
viomajorsubtype_chario, VIOCHAR_WINDOW + 2);
@@ -1147,6 +1149,9 @@ static int __init viocons_init(void)
{
int i;
+ if (!firmware_has_feature(FW_FEATURE_ISERIES))
+ return -ENODEV;
+
printk(VIOCONS_KERN_INFO "registering console\n");
for (i = 0; i < VTTY_PORTS; i++) {
port_info[i].lp = HvLpIndexInvalid;
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c
index 94d79cb8ce8d..9438512b17f1 100644
--- a/drivers/char/viotape.c
+++ b/drivers/char/viotape.c
@@ -49,7 +49,7 @@
#include <asm/uaccess.h>
#include <asm/ioctls.h>
-
+#include <asm/firmware.h>
#include <asm/vio.h>
#include <asm/iseries/vio.h>
#include <asm/iseries/hv_lp_event.h>
@@ -997,6 +997,9 @@ int __init viotap_init(void)
int ret;
struct proc_dir_entry *e;
+ if (!firmware_has_feature(FW_FEATURE_ISERIES))
+ return -ENODEV;
+
op_struct_list = NULL;
if ((ret = add_op_structs(VIOTAPE_MAXREQ)) < 0) {
printk(VIOTAPE_KERN_WARN "couldn't allocate op structs\n");
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index a8239dac994f..06c32a3e3ca4 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -784,7 +784,7 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines)
if (new_cols == vc->vc_cols && new_rows == vc->vc_rows)
return 0;
- newscreen = (unsigned short *) kmalloc(new_screen_size, GFP_USER);
+ newscreen = kmalloc(new_screen_size, GFP_USER);
if (!newscreen)
return -ENOMEM;
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
index ac5d60edbafa..dc8368ebb1ac 100644
--- a/drivers/char/vt_ioctl.c
+++ b/drivers/char/vt_ioctl.c
@@ -129,7 +129,7 @@ do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm, struct kbd_str
!capable(CAP_SYS_RESOURCE))
return -EPERM;
- key_map = (ushort *) kmalloc(sizeof(plain_map),
+ key_map = kmalloc(sizeof(plain_map),
GFP_KERNEL);
if (!key_map)
return -ENOMEM;
@@ -259,7 +259,7 @@ do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
sz = 256;
while (sz < funcbufsize - funcbufleft + delta)
sz <<= 1;
- fnw = (char *) kmalloc(sz, GFP_KERNEL);
+ fnw = kmalloc(sz, GFP_KERNEL);
if(!fnw) {
ret = -ENOMEM;
goto reterr;
@@ -1087,7 +1087,7 @@ static void complete_change_console(struct vc_data *vc)
switch_screen(vc);
/*
- * This can't appear below a successful kill_proc(). If it did,
+ * This can't appear below a successful kill_pid(). If it did,
* then the *blank_screen operation could occur while X, having
* received acqsig, is waking up on another processor. This
* condition can lead to overlapping accesses to the VGA range
@@ -1110,7 +1110,7 @@ static void complete_change_console(struct vc_data *vc)
*/
if (vc->vt_mode.mode == VT_PROCESS) {
/*
- * Send the signal as privileged - kill_proc() will
+ * Send the signal as privileged - kill_pid() will
* tell us if the process has gone or something else
* is awry
*/
@@ -1170,7 +1170,7 @@ void change_console(struct vc_data *new_vc)
vc = vc_cons[fg_console].d;
if (vc->vt_mode.mode == VT_PROCESS) {
/*
- * Send the signal as privileged - kill_proc() will
+ * Send the signal as privileged - kill_pid() will
* tell us if the process has gone or something else
* is awry
*/
diff --git a/drivers/connector/cn_queue.c b/drivers/connector/cn_queue.c
index b418b16e910e..296f51002b55 100644
--- a/drivers/connector/cn_queue.c
+++ b/drivers/connector/cn_queue.c
@@ -34,7 +34,7 @@
void cn_queue_wrapper(struct work_struct *work)
{
struct cn_callback_entry *cbq =
- container_of(work, struct cn_callback_entry, work.work);
+ container_of(work, struct cn_callback_entry, work);
struct cn_callback_data *d = &cbq->data;
d->callback(d->callback_priv);
@@ -59,13 +59,12 @@ static struct cn_callback_entry *cn_queue_alloc_callback_entry(char *name, struc
memcpy(&cbq->id.id, id, sizeof(struct cb_id));
cbq->data.callback = callback;
- INIT_DELAYED_WORK(&cbq->work, &cn_queue_wrapper);
+ INIT_WORK(&cbq->work, &cn_queue_wrapper);
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);
diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c
index 5e7cd45d10ee..a44db75bc25b 100644
--- a/drivers/connector/connector.c
+++ b/drivers/connector/connector.c
@@ -135,17 +135,15 @@ static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), v
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(WORK_STRUCT_PENDING,
- &__cbq->work.work.management) &&
+ if (likely(!work_pending(&__cbq->work) &&
__cbq->data.ddata == NULL)) {
__cbq->data.callback_priv = msg;
__cbq->data.ddata = data;
__cbq->data.destruct_data = destruct_data;
- if (queue_delayed_work(
- dev->cbdev->cn_queue,
- &__cbq->work, 0))
+ if (queue_work(dev->cbdev->cn_queue,
+ &__cbq->work))
err = 0;
} else {
struct cn_callback_data *d;
@@ -159,12 +157,11 @@ static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), v
d->destruct_data = destruct_data;
d->free = __cbq;
- INIT_DELAYED_WORK(&__cbq->work,
- &cn_queue_wrapper);
+ INIT_WORK(&__cbq->work,
+ &cn_queue_wrapper);
- if (queue_delayed_work(
- dev->cbdev->cn_queue,
- &__cbq->work, 0))
+ if (queue_work(dev->cbdev->cn_queue,
+ &__cbq->work))
err = 0;
else {
kfree(__cbq);
diff --git a/drivers/fc4/fc.c b/drivers/fc4/fc.c
index ca4e67a022d0..22b62b3cd14e 100644
--- a/drivers/fc4/fc.c
+++ b/drivers/fc4/fc.c
@@ -266,7 +266,7 @@ static void fcp_report_map_done(fc_channel *fc, int i, int status)
printk ("FC: Bad magic from REPORT_AL_MAP on %s - %08x\n", fc->name, p->magic);
fc->state = FC_STATE_OFFLINE;
} else {
- fc->posmap = (fcp_posmap *)kzalloc(sizeof(fcp_posmap)+p->len, GFP_KERNEL);
+ fc->posmap = kzalloc(sizeof(fcp_posmap)+p->len, GFP_KERNEL);
if (!fc->posmap) {
printk("FC: Not enough memory, offlining channel\n");
fc->state = FC_STATE_OFFLINE;
@@ -355,7 +355,7 @@ void fcp_register(fc_channel *fc, u8 type, int unregister)
for (i = fc->can_queue; i < fc->scsi_bitmap_end; i++)
set_bit (i, fc->scsi_bitmap);
fc->scsi_free = fc->can_queue;
- fc->cmd_slots = (fcp_cmnd **)kzalloc(slots * sizeof(fcp_cmnd*), GFP_KERNEL);
+ fc->cmd_slots = kzalloc(slots * sizeof(fcp_cmnd*), GFP_KERNEL);
fc->abort_count = 0;
} else {
fc->scsi_name[0] = 0;
@@ -933,7 +933,7 @@ int fcp_scsi_dev_reset(struct scsi_cmnd *SCpnt)
DECLARE_MUTEX_LOCKED(sem);
if (!fc->rst_pkt) {
- fc->rst_pkt = (struct scsi_cmnd *) kmalloc(sizeof(SCpnt), GFP_KERNEL);
+ fc->rst_pkt = kmalloc(sizeof(SCpnt), GFP_KERNEL);
if (!fc->rst_pkt) return FAILED;
fcmd = FCP_CMND(fc->rst_pkt);
@@ -1107,7 +1107,7 @@ int fc_do_plogi(fc_channel *fc, unsigned char alpa, fc_wwn *node, fc_wwn *nport)
logi *l;
int status;
- l = (logi *)kzalloc(2 * sizeof(logi), GFP_KERNEL);
+ l = kzalloc(2 * sizeof(logi), GFP_KERNEL);
if (!l) return -ENOMEM;
l->code = LS_PLOGI;
memcpy (&l->nport_wwn, &fc->wwn_nport, sizeof(fc_wwn));
@@ -1141,7 +1141,7 @@ int fc_do_prli(fc_channel *fc, unsigned char alpa)
prli *p;
int status;
- p = (prli *)kzalloc(2 * sizeof(prli), GFP_KERNEL);
+ p = kzalloc(2 * sizeof(prli), GFP_KERNEL);
if (!p) return -ENOMEM;
p->code = LS_PRLI;
p->params[0] = 0x08002000;
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 14cdf09316ce..998638020ea0 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -415,12 +415,31 @@ 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 0x040: map_key_clear(KEY_MENU); break;
case 0x045: map_key_clear(KEY_RADIO); break;
+
+ case 0x088: map_key_clear(KEY_PC); break;
+ case 0x089: map_key_clear(KEY_TV); break;
case 0x08a: map_key_clear(KEY_WWW); break;
+ case 0x08b: map_key_clear(KEY_DVD); break;
+ case 0x08c: map_key_clear(KEY_PHONE); break;
case 0x08d: map_key_clear(KEY_PROGRAM); break;
+ case 0x08e: map_key_clear(KEY_VIDEOPHONE); break;
+ case 0x08f: map_key_clear(KEY_GAMES); break;
+ case 0x090: map_key_clear(KEY_MEMO); break;
+ case 0x091: map_key_clear(KEY_CD); break;
+ case 0x092: map_key_clear(KEY_VCR); break;
+ case 0x093: map_key_clear(KEY_TUNER); break;
+ case 0x094: map_key_clear(KEY_EXIT); break;
case 0x095: map_key_clear(KEY_HELP); break;
+ case 0x096: map_key_clear(KEY_TAPE); break;
+ case 0x097: map_key_clear(KEY_TV2); break;
+ case 0x098: map_key_clear(KEY_SAT); break;
+
case 0x09c: map_key_clear(KEY_CHANNELUP); break;
case 0x09d: map_key_clear(KEY_CHANNELDOWN); break;
+ case 0x0a0: map_key_clear(KEY_VCR2); 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;
@@ -430,6 +449,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
case 0x0b6: map_key_clear(KEY_PREVIOUSSONG); break;
case 0x0b7: map_key_clear(KEY_STOPCD); break;
case 0x0b8: map_key_clear(KEY_EJECTCD); break;
+
case 0x0cd: map_key_clear(KEY_PLAYPAUSE); break;
case 0x0e0: map_abs_clear(ABS_VOLUME); break;
case 0x0e2: map_key_clear(KEY_MUTE); break;
@@ -437,11 +457,30 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
case 0x0e9: map_key_clear(KEY_VOLUMEUP); break;
case 0x0ea: map_key_clear(KEY_VOLUMEDOWN); break;
case 0x183: map_key_clear(KEY_CONFIG); break;
+ case 0x184: map_key_clear(KEY_WORDPROCESSOR); break;
+ case 0x185: map_key_clear(KEY_EDITOR); break;
+ case 0x186: map_key_clear(KEY_SPREADSHEET); break;
+ case 0x187: map_key_clear(KEY_GRAPHICSEDITOR); break;
+ case 0x188: map_key_clear(KEY_PRESENTATION); break;
+ case 0x189: map_key_clear(KEY_DATABASE); break;
case 0x18a: map_key_clear(KEY_MAIL); break;
+ case 0x18b: map_key_clear(KEY_NEWS); break;
+ case 0x18c: map_key_clear(KEY_VOICEMAIL); break;
+ case 0x18d: map_key_clear(KEY_ADDRESSBOOK); break;
+ case 0x18e: map_key_clear(KEY_CALENDAR); break;
+ case 0x191: map_key_clear(KEY_FINANCE); break;
case 0x192: map_key_clear(KEY_CALC); break;
case 0x194: map_key_clear(KEY_FILE); break;
+ case 0x196: map_key_clear(KEY_WWW); break;
+ case 0x19e: map_key_clear(KEY_COFFEE); break;
+ case 0x1a6: map_key_clear(KEY_HELP); break;
case 0x1a7: map_key_clear(KEY_DOCUMENTS); break;
+ case 0x1bc: map_key_clear(KEY_MESSENGER); break;
+ case 0x1bd: map_key_clear(KEY_INFO); break;
case 0x201: map_key_clear(KEY_NEW); break;
+ case 0x202: map_key_clear(KEY_OPEN); break;
+ case 0x203: map_key_clear(KEY_CLOSE); break;
+ case 0x204: map_key_clear(KEY_EXIT); 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;
@@ -456,10 +495,15 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
case 0x226: map_key_clear(KEY_STOP); break;
case 0x227: map_key_clear(KEY_REFRESH); break;
case 0x22a: map_key_clear(KEY_BOOKMARKS); break;
+ case 0x22d: map_key_clear(KEY_ZOOMIN); break;
+ case 0x22e: map_key_clear(KEY_ZOOMOUT); break;
+ case 0x22f: map_key_clear(KEY_ZOOMRESET); break;
case 0x233: map_key_clear(KEY_SCROLLUP); break;
case 0x234: map_key_clear(KEY_SCROLLDOWN); break;
case 0x238: map_rel(REL_HWHEEL); break;
+ case 0x25f: map_key_clear(KEY_CANCEL); break;
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;
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index e76d91906c99..891ef6d0b1bf 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -106,6 +106,31 @@ config SENSORS_K8TEMP
This driver can also be built as a module. If so, the module
will be called k8temp.
+config SENSORS_AMS
+ tristate "Apple Motion Sensor driver"
+ depends on HWMON && PPC_PMAC && !PPC64 && INPUT && ((ADB_PMU && I2C = y) || (ADB_PMU && !I2C) || I2C) && EXPERIMENTAL
+ help
+ Support for the motion sensor included in PowerBooks. Includes
+ implementations for PMU and I2C.
+
+ This driver can also be built as a module. If so, the module
+ will be called ams.
+
+config SENSORS_AMS_PMU
+ bool "PMU variant"
+ depends on SENSORS_AMS && ADB_PMU
+ default y
+ help
+ PMU variant of motion sensor, found in late 2005 PowerBooks.
+
+config SENSORS_AMS_I2C
+ bool "I2C variant"
+ depends on SENSORS_AMS && I2C
+ default y
+ help
+ I2C variant of motion sensor, found in early 2005 PowerBooks and
+ iBooks.
+
config SENSORS_ASB100
tristate "Asus ASB100 Bach"
depends on HWMON && I2C && EXPERIMENTAL
@@ -142,11 +167,12 @@ config SENSORS_DS1621
will be called ds1621.
config SENSORS_F71805F
- tristate "Fintek F71805F/FG"
+ tristate "Fintek F71805F/FG and F71872F/FG"
depends on HWMON && EXPERIMENTAL
help
If you say yes here you get support for hardware monitoring
- features of the Fintek F71805F/FG chips.
+ features of the Fintek F71805F/FG and F71872F/FG Super-I/O
+ chips.
This driver can also be built as a module. If so, the module
will be called f71805f.
@@ -353,6 +379,19 @@ config SENSORS_PC87360
This driver can also be built as a module. If so, the module
will be called pc87360.
+config SENSORS_PC87427
+ tristate "National Semiconductor PC87427"
+ depends on HWMON && EXPERIMENTAL
+ help
+ If you say yes here you get access to the hardware monitoring
+ functions of the National Semiconductor PC87427 Super-I/O chip.
+ The chip has two distinct logical devices, one for fan speed
+ monitoring and control, and one for voltage and temperature
+ monitoring. Only fan speed monitoring is supported right now.
+
+ This driver can also be built as a module. If so, the module
+ will be called pc87427.
+
config SENSORS_SIS5595
tristate "Silicon Integrated Systems Corp. SiS5595"
depends on HWMON && I2C && PCI && EXPERIMENTAL
@@ -474,6 +513,16 @@ config SENSORS_W83792D
This driver can also be built as a module. If so, the module
will be called w83792d.
+config SENSORS_W83793
+ tristate "Winbond W83793"
+ depends on HWMON && I2C && EXPERIMENTAL
+ help
+ If you say yes here you get support for the Winbond W83793
+ hardware monitoring chip.
+
+ This driver can also be built as a module. If so, the module
+ will be called w83793.
+
config SENSORS_W83L785TS
tristate "Winbond W83L785TS-S"
depends on HWMON && I2C && EXPERIMENTAL
@@ -527,6 +576,9 @@ config SENSORS_HDAPS
This driver also provides an absolute input class device, allowing
the laptop to act as a pinball machine-esque joystick.
+ If your ThinkPad is not recognized by the driver, please update to latest
+ BIOS. This is especially the case for some R52 ThinkPads.
+
Say Y here if you have an applicable laptop and want to experience
the awesome power of hdaps.
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index af01cc64f7d2..31661124271e 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_HWMON_VID) += hwmon-vid.o
obj-$(CONFIG_SENSORS_ASB100) += asb100.o
obj-$(CONFIG_SENSORS_W83627HF) += w83627hf.o
obj-$(CONFIG_SENSORS_W83792D) += w83792d.o
+obj-$(CONFIG_SENSORS_W83793) += w83793.o
obj-$(CONFIG_SENSORS_W83781D) += w83781d.o
obj-$(CONFIG_SENSORS_W83791D) += w83791d.o
@@ -18,6 +19,7 @@ obj-$(CONFIG_SENSORS_ADM1025) += adm1025.o
obj-$(CONFIG_SENSORS_ADM1026) += adm1026.o
obj-$(CONFIG_SENSORS_ADM1031) += adm1031.o
obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o
+obj-$(CONFIG_SENSORS_AMS) += ams/
obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o
obj-$(CONFIG_SENSORS_DS1621) += ds1621.o
obj-$(CONFIG_SENSORS_F71805F) += f71805f.o
@@ -41,6 +43,7 @@ obj-$(CONFIG_SENSORS_LM90) += lm90.o
obj-$(CONFIG_SENSORS_LM92) += lm92.o
obj-$(CONFIG_SENSORS_MAX1619) += max1619.o
obj-$(CONFIG_SENSORS_PC87360) += pc87360.o
+obj-$(CONFIG_SENSORS_PC87427) += pc87427.o
obj-$(CONFIG_SENSORS_SIS5595) += sis5595.o
obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o
obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o
diff --git a/drivers/hwmon/ams/Makefile b/drivers/hwmon/ams/Makefile
new file mode 100644
index 000000000000..41c95b2089dc
--- /dev/null
+++ b/drivers/hwmon/ams/Makefile
@@ -0,0 +1,8 @@
+#
+# Makefile for Apple Motion Sensor driver
+#
+
+ams-y := ams-core.o ams-input.o
+ams-$(CONFIG_SENSORS_AMS_PMU) += ams-pmu.o
+ams-$(CONFIG_SENSORS_AMS_I2C) += ams-i2c.o
+obj-$(CONFIG_SENSORS_AMS) += ams.o
diff --git a/drivers/hwmon/ams/ams-core.c b/drivers/hwmon/ams/ams-core.c
new file mode 100644
index 000000000000..f1f0f5d0442c
--- /dev/null
+++ b/drivers/hwmon/ams/ams-core.c
@@ -0,0 +1,265 @@
+/*
+ * Apple Motion Sensor driver
+ *
+ * Copyright (C) 2005 Stelian Pop (stelian@popies.net)
+ * Copyright (C) 2006 Michael Hanselmann (linux-kernel@hansmi.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
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <asm/pmac_pfunc.h>
+#include <asm/of_platform.h>
+
+#include "ams.h"
+
+/* There is only one motion sensor per machine */
+struct ams ams_info;
+
+static unsigned int verbose;
+module_param(verbose, bool, 0644);
+MODULE_PARM_DESC(verbose, "Show free falls and shocks in kernel output");
+
+/* Call with ams_info.lock held! */
+void ams_sensors(s8 *x, s8 *y, s8 *z)
+{
+ u32 orient = ams_info.vflag? ams_info.orient1 : ams_info.orient2;
+
+ if (orient & 0x80)
+ /* X and Y swapped */
+ ams_info.get_xyz(y, x, z);
+ else
+ ams_info.get_xyz(x, y, z);
+
+ if (orient & 0x04)
+ *z = ~(*z);
+ if (orient & 0x02)
+ *y = ~(*y);
+ if (orient & 0x01)
+ *x = ~(*x);
+}
+
+static ssize_t ams_show_current(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ s8 x, y, z;
+
+ mutex_lock(&ams_info.lock);
+ ams_sensors(&x, &y, &z);
+ mutex_unlock(&ams_info.lock);
+
+ return snprintf(buf, PAGE_SIZE, "%d %d %d\n", x, y, z);
+}
+
+static DEVICE_ATTR(current, S_IRUGO, ams_show_current, NULL);
+
+static void ams_handle_irq(void *data)
+{
+ enum ams_irq irq = *((enum ams_irq *)data);
+
+ spin_lock(&ams_info.irq_lock);
+
+ ams_info.worker_irqs |= irq;
+ schedule_work(&ams_info.worker);
+
+ spin_unlock(&ams_info.irq_lock);
+}
+
+static enum ams_irq ams_freefall_irq_data = AMS_IRQ_FREEFALL;
+static struct pmf_irq_client ams_freefall_client = {
+ .owner = THIS_MODULE,
+ .handler = ams_handle_irq,
+ .data = &ams_freefall_irq_data,
+};
+
+static enum ams_irq ams_shock_irq_data = AMS_IRQ_SHOCK;
+static struct pmf_irq_client ams_shock_client = {
+ .owner = THIS_MODULE,
+ .handler = ams_handle_irq,
+ .data = &ams_shock_irq_data,
+};
+
+/* Once hard disk parking is implemented in the kernel, this function can
+ * trigger it.
+ */
+static void ams_worker(struct work_struct *work)
+{
+ mutex_lock(&ams_info.lock);
+
+ if (ams_info.has_device) {
+ unsigned long flags;
+
+ spin_lock_irqsave(&ams_info.irq_lock, flags);
+
+ if (ams_info.worker_irqs & AMS_IRQ_FREEFALL) {
+ if (verbose)
+ printk(KERN_INFO "ams: freefall detected!\n");
+
+ ams_info.worker_irqs &= ~AMS_IRQ_FREEFALL;
+
+ /* we must call this with interrupts enabled */
+ spin_unlock_irqrestore(&ams_info.irq_lock, flags);
+ ams_info.clear_irq(AMS_IRQ_FREEFALL);
+ spin_lock_irqsave(&ams_info.irq_lock, flags);
+ }
+
+ if (ams_info.worker_irqs & AMS_IRQ_SHOCK) {
+ if (verbose)
+ printk(KERN_INFO "ams: shock detected!\n");
+
+ ams_info.worker_irqs &= ~AMS_IRQ_SHOCK;
+
+ /* we must call this with interrupts enabled */
+ spin_unlock_irqrestore(&ams_info.irq_lock, flags);
+ ams_info.clear_irq(AMS_IRQ_SHOCK);
+ spin_lock_irqsave(&ams_info.irq_lock, flags);
+ }
+
+ spin_unlock_irqrestore(&ams_info.irq_lock, flags);
+ }
+
+ mutex_unlock(&ams_info.lock);
+}
+
+/* Call with ams_info.lock held! */
+int ams_sensor_attach(void)
+{
+ int result;
+ u32 *prop;
+
+ /* Get orientation */
+ prop = (u32*)get_property(ams_info.of_node, "orientation", NULL);
+ if (!prop)
+ return -ENODEV;
+ ams_info.orient1 = *prop;
+ ams_info.orient2 = *(prop + 1);
+
+ /* Register freefall interrupt handler */
+ result = pmf_register_irq_client(ams_info.of_node,
+ "accel-int-1",
+ &ams_freefall_client);
+ if (result < 0)
+ return -ENODEV;
+
+ /* Reset saved irqs */
+ ams_info.worker_irqs = 0;
+
+ /* Register shock interrupt handler */
+ result = pmf_register_irq_client(ams_info.of_node,
+ "accel-int-2",
+ &ams_shock_client);
+ if (result < 0)
+ goto release_freefall;
+
+ /* Create device */
+ ams_info.of_dev = of_platform_device_create(ams_info.of_node, "ams", NULL);
+ if (!ams_info.of_dev) {
+ result = -ENODEV;
+ goto release_shock;
+ }
+
+ /* Create attributes */
+ result = device_create_file(&ams_info.of_dev->dev, &dev_attr_current);
+ if (result)
+ goto release_of;
+
+ ams_info.vflag = !!(ams_info.get_vendor() & 0x10);
+
+ /* Init input device */
+ result = ams_input_init();
+ if (result)
+ goto release_device_file;
+
+ return result;
+release_device_file:
+ device_remove_file(&ams_info.of_dev->dev, &dev_attr_current);
+release_of:
+ of_device_unregister(ams_info.of_dev);
+release_shock:
+ pmf_unregister_irq_client(&ams_shock_client);
+release_freefall:
+ pmf_unregister_irq_client(&ams_freefall_client);
+ return result;
+}
+
+int __init ams_init(void)
+{
+ struct device_node *np;
+
+ spin_lock_init(&ams_info.irq_lock);
+ mutex_init(&ams_info.lock);
+ INIT_WORK(&ams_info.worker, ams_worker);
+
+#ifdef CONFIG_SENSORS_AMS_I2C
+ np = of_find_node_by_name(NULL, "accelerometer");
+ if (np && device_is_compatible(np, "AAPL,accelerometer_1"))
+ /* Found I2C motion sensor */
+ return ams_i2c_init(np);
+#endif
+
+#ifdef CONFIG_SENSORS_AMS_PMU
+ np = of_find_node_by_name(NULL, "sms");
+ if (np && device_is_compatible(np, "sms"))
+ /* Found PMU motion sensor */
+ return ams_pmu_init(np);
+#endif
+
+ printk(KERN_ERR "ams: No motion sensor found.\n");
+
+ return -ENODEV;
+}
+
+void ams_exit(void)
+{
+ mutex_lock(&ams_info.lock);
+
+ if (ams_info.has_device) {
+ /* Remove input device */
+ ams_input_exit();
+
+ /* Shut down implementation */
+ ams_info.exit();
+
+ /* Flush interrupt worker
+ *
+ * We do this after ams_info.exit(), because an interrupt might
+ * have arrived before disabling them.
+ */
+ flush_scheduled_work();
+
+ /* Remove attributes */
+ device_remove_file(&ams_info.of_dev->dev, &dev_attr_current);
+
+ /* Remove device */
+ of_device_unregister(ams_info.of_dev);
+
+ /* Remove handler */
+ pmf_unregister_irq_client(&ams_shock_client);
+ pmf_unregister_irq_client(&ams_freefall_client);
+ }
+
+ mutex_unlock(&ams_info.lock);
+}
+
+MODULE_AUTHOR("Stelian Pop, Michael Hanselmann");
+MODULE_DESCRIPTION("Apple Motion Sensor driver");
+MODULE_LICENSE("GPL");
+
+module_init(ams_init);
+module_exit(ams_exit);
diff --git a/drivers/hwmon/ams/ams-i2c.c b/drivers/hwmon/ams/ams-i2c.c
new file mode 100644
index 000000000000..0d24bdfea53e
--- /dev/null
+++ b/drivers/hwmon/ams/ams-i2c.c
@@ -0,0 +1,299 @@
+/*
+ * Apple Motion Sensor driver (I2C variant)
+ *
+ * Copyright (C) 2005 Stelian Pop (stelian@popies.net)
+ * Copyright (C) 2006 Michael Hanselmann (linux-kernel@hansmi.ch)
+ *
+ * Clean room implementation based on the reverse engineered Mac OS X driver by
+ * Johannes Berg <johannes@sipsolutions.net>, documentation available at
+ * http://johannes.sipsolutions.net/PowerBook/Apple_Motion_Sensor_Specification
+ *
+ * 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/types.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+
+#include "ams.h"
+
+/* AMS registers */
+#define AMS_COMMAND 0x00 /* command register */
+#define AMS_STATUS 0x01 /* status register */
+#define AMS_CTRL1 0x02 /* read control 1 (number of values) */
+#define AMS_CTRL2 0x03 /* read control 2 (offset?) */
+#define AMS_CTRL3 0x04 /* read control 3 (size of each value?) */
+#define AMS_DATA1 0x05 /* read data 1 */
+#define AMS_DATA2 0x06 /* read data 2 */
+#define AMS_DATA3 0x07 /* read data 3 */
+#define AMS_DATA4 0x08 /* read data 4 */
+#define AMS_DATAX 0x20 /* data X */
+#define AMS_DATAY 0x21 /* data Y */
+#define AMS_DATAZ 0x22 /* data Z */
+#define AMS_FREEFALL 0x24 /* freefall int control */
+#define AMS_SHOCK 0x25 /* shock int control */
+#define AMS_SENSLOW 0x26 /* sensitivity low limit */
+#define AMS_SENSHIGH 0x27 /* sensitivity high limit */
+#define AMS_CTRLX 0x28 /* control X */
+#define AMS_CTRLY 0x29 /* control Y */
+#define AMS_CTRLZ 0x2A /* control Z */
+#define AMS_UNKNOWN1 0x2B /* unknown 1 */
+#define AMS_UNKNOWN2 0x2C /* unknown 2 */
+#define AMS_UNKNOWN3 0x2D /* unknown 3 */
+#define AMS_VENDOR 0x2E /* vendor */
+
+/* AMS commands - use with the AMS_COMMAND register */
+enum ams_i2c_cmd {
+ AMS_CMD_NOOP = 0,
+ AMS_CMD_VERSION,
+ AMS_CMD_READMEM,
+ AMS_CMD_WRITEMEM,
+ AMS_CMD_ERASEMEM,
+ AMS_CMD_READEE,
+ AMS_CMD_WRITEEE,
+ AMS_CMD_RESET,
+ AMS_CMD_START,
+};
+
+static int ams_i2c_attach(struct i2c_adapter *adapter);
+static int ams_i2c_detach(struct i2c_adapter *adapter);
+
+static struct i2c_driver ams_i2c_driver = {
+ .driver = {
+ .name = "ams",
+ .owner = THIS_MODULE,
+ },
+ .attach_adapter = ams_i2c_attach,
+ .detach_adapter = ams_i2c_detach,
+};
+
+static s32 ams_i2c_read(u8 reg)
+{
+ return i2c_smbus_read_byte_data(&ams_info.i2c_client, reg);
+}
+
+static int ams_i2c_write(u8 reg, u8 value)
+{
+ return i2c_smbus_write_byte_data(&ams_info.i2c_client, reg, value);
+}
+
+static int ams_i2c_cmd(enum ams_i2c_cmd cmd)
+{
+ s32 result;
+ int remaining = HZ / 20;
+
+ ams_i2c_write(AMS_COMMAND, cmd);
+ mdelay(5);
+
+ while (remaining) {
+ result = ams_i2c_read(AMS_COMMAND);
+ if (result == 0 || result & 0x80)
+ return 0;
+
+ remaining = schedule_timeout(remaining);
+ }
+
+ return -1;
+}
+
+static void ams_i2c_set_irq(enum ams_irq reg, char enable)
+{
+ if (reg & AMS_IRQ_FREEFALL) {
+ u8 val = ams_i2c_read(AMS_CTRLX);
+ if (enable)
+ val |= 0x80;
+ else
+ val &= ~0x80;
+ ams_i2c_write(AMS_CTRLX, val);
+ }
+
+ if (reg & AMS_IRQ_SHOCK) {
+ u8 val = ams_i2c_read(AMS_CTRLY);
+ if (enable)
+ val |= 0x80;
+ else
+ val &= ~0x80;
+ ams_i2c_write(AMS_CTRLY, val);
+ }
+
+ if (reg & AMS_IRQ_GLOBAL) {
+ u8 val = ams_i2c_read(AMS_CTRLZ);
+ if (enable)
+ val |= 0x80;
+ else
+ val &= ~0x80;
+ ams_i2c_write(AMS_CTRLZ, val);
+ }
+}
+
+static void ams_i2c_clear_irq(enum ams_irq reg)
+{
+ if (reg & AMS_IRQ_FREEFALL)
+ ams_i2c_write(AMS_FREEFALL, 0);
+
+ if (reg & AMS_IRQ_SHOCK)
+ ams_i2c_write(AMS_SHOCK, 0);
+}
+
+static u8 ams_i2c_get_vendor(void)
+{
+ return ams_i2c_read(AMS_VENDOR);
+}
+
+static void ams_i2c_get_xyz(s8 *x, s8 *y, s8 *z)
+{
+ *x = ams_i2c_read(AMS_DATAX);
+ *y = ams_i2c_read(AMS_DATAY);
+ *z = ams_i2c_read(AMS_DATAZ);
+}
+
+static int ams_i2c_attach(struct i2c_adapter *adapter)
+{
+ unsigned long bus;
+ int vmaj, vmin;
+ int result;
+
+ /* There can be only one */
+ if (unlikely(ams_info.has_device))
+ return -ENODEV;
+
+ if (strncmp(adapter->name, "uni-n", 5))
+ return -ENODEV;
+
+ bus = simple_strtoul(adapter->name + 6, NULL, 10);
+ if (bus != ams_info.i2c_bus)
+ return -ENODEV;
+
+ ams_info.i2c_client.addr = ams_info.i2c_address;
+ ams_info.i2c_client.adapter = adapter;
+ ams_info.i2c_client.driver = &ams_i2c_driver;
+ strcpy(ams_info.i2c_client.name, "Apple Motion Sensor");
+
+ if (ams_i2c_cmd(AMS_CMD_RESET)) {
+ printk(KERN_INFO "ams: Failed to reset the device\n");
+ return -ENODEV;
+ }
+
+ if (ams_i2c_cmd(AMS_CMD_START)) {
+ printk(KERN_INFO "ams: Failed to start the device\n");
+ return -ENODEV;
+ }
+
+ /* get version/vendor information */
+ ams_i2c_write(AMS_CTRL1, 0x02);
+ ams_i2c_write(AMS_CTRL2, 0x85);
+ ams_i2c_write(AMS_CTRL3, 0x01);
+
+ ams_i2c_cmd(AMS_CMD_READMEM);
+
+ vmaj = ams_i2c_read(AMS_DATA1);
+ vmin = ams_i2c_read(AMS_DATA2);
+ if (vmaj != 1 || vmin != 52) {
+ printk(KERN_INFO "ams: Incorrect device version (%d.%d)\n",
+ vmaj, vmin);
+ return -ENODEV;
+ }
+
+ ams_i2c_cmd(AMS_CMD_VERSION);
+
+ vmaj = ams_i2c_read(AMS_DATA1);
+ vmin = ams_i2c_read(AMS_DATA2);
+ if (vmaj != 0 || vmin != 1) {
+ printk(KERN_INFO "ams: Incorrect firmware version (%d.%d)\n",
+ vmaj, vmin);
+ return -ENODEV;
+ }
+
+ /* Disable interrupts */
+ ams_i2c_set_irq(AMS_IRQ_ALL, 0);
+
+ result = ams_sensor_attach();
+ if (result < 0)
+ return result;
+
+ /* Set default values */
+ ams_i2c_write(AMS_SENSLOW, 0x15);
+ ams_i2c_write(AMS_SENSHIGH, 0x60);
+ ams_i2c_write(AMS_CTRLX, 0x08);
+ ams_i2c_write(AMS_CTRLY, 0x0F);
+ ams_i2c_write(AMS_CTRLZ, 0x4F);
+ ams_i2c_write(AMS_UNKNOWN1, 0x14);
+
+ /* Clear interrupts */
+ ams_i2c_clear_irq(AMS_IRQ_ALL);
+
+ ams_info.has_device = 1;
+
+ /* Enable interrupts */
+ ams_i2c_set_irq(AMS_IRQ_ALL, 1);
+
+ printk(KERN_INFO "ams: Found I2C based motion sensor\n");
+
+ return 0;
+}
+
+static int ams_i2c_detach(struct i2c_adapter *adapter)
+{
+ if (ams_info.has_device) {
+ /* Disable interrupts */
+ ams_i2c_set_irq(AMS_IRQ_ALL, 0);
+
+ /* Clear interrupts */
+ ams_i2c_clear_irq(AMS_IRQ_ALL);
+
+ printk(KERN_INFO "ams: Unloading\n");
+
+ ams_info.has_device = 0;
+ }
+
+ return 0;
+}
+
+static void ams_i2c_exit(void)
+{
+ i2c_del_driver(&ams_i2c_driver);
+}
+
+int __init ams_i2c_init(struct device_node *np)
+{
+ char *tmp_bus;
+ int result;
+ u32 *prop;
+
+ mutex_lock(&ams_info.lock);
+
+ /* Set implementation stuff */
+ ams_info.of_node = np;
+ ams_info.exit = ams_i2c_exit;
+ ams_info.get_vendor = ams_i2c_get_vendor;
+ ams_info.get_xyz = ams_i2c_get_xyz;
+ ams_info.clear_irq = ams_i2c_clear_irq;
+ ams_info.bustype = BUS_I2C;
+
+ /* look for bus either using "reg" or by path */
+ prop = (u32*)get_property(ams_info.of_node, "reg", NULL);
+ if (!prop) {
+ result = -ENODEV;
+
+ goto exit;
+ }
+
+ tmp_bus = strstr(ams_info.of_node->full_name, "/i2c-bus@");
+ if (tmp_bus)
+ ams_info.i2c_bus = *(tmp_bus + 9) - '0';
+ else
+ ams_info.i2c_bus = ((*prop) >> 8) & 0x0f;
+ ams_info.i2c_address = ((*prop) & 0xff) >> 1;
+
+ result = i2c_add_driver(&ams_i2c_driver);
+
+exit:
+ mutex_unlock(&ams_info.lock);
+
+ return result;
+}
diff --git a/drivers/hwmon/ams/ams-input.c b/drivers/hwmon/ams/ams-input.c
new file mode 100644
index 000000000000..f126aa485134
--- /dev/null
+++ b/drivers/hwmon/ams/ams-input.c
@@ -0,0 +1,160 @@
+/*
+ * Apple Motion Sensor driver (joystick emulation)
+ *
+ * Copyright (C) 2005 Stelian Pop (stelian@popies.net)
+ * Copyright (C) 2006 Michael Hanselmann (linux-kernel@hansmi.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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+
+#include "ams.h"
+
+static unsigned int joystick;
+module_param(joystick, bool, 0644);
+MODULE_PARM_DESC(joystick, "Enable the input class device on module load");
+
+static unsigned int invert;
+module_param(invert, bool, 0644);
+MODULE_PARM_DESC(invert, "Invert input data on X and Y axis");
+
+static int ams_input_kthread(void *data)
+{
+ s8 x, y, z;
+
+ while (!kthread_should_stop()) {
+ mutex_lock(&ams_info.lock);
+
+ ams_sensors(&x, &y, &z);
+
+ x -= ams_info.xcalib;
+ y -= ams_info.ycalib;
+ z -= ams_info.zcalib;
+
+ input_report_abs(ams_info.idev, ABS_X, invert ? -x : x);
+ input_report_abs(ams_info.idev, ABS_Y, invert ? -y : y);
+ input_report_abs(ams_info.idev, ABS_Z, z);
+
+ input_sync(ams_info.idev);
+
+ mutex_unlock(&ams_info.lock);
+
+ msleep(25);
+ }
+
+ return 0;
+}
+
+static int ams_input_open(struct input_dev *dev)
+{
+ ams_info.kthread = kthread_run(ams_input_kthread, NULL, "kams");
+ return IS_ERR(ams_info.kthread) ? PTR_ERR(ams_info.kthread) : 0;
+}
+
+static void ams_input_close(struct input_dev *dev)
+{
+ kthread_stop(ams_info.kthread);
+}
+
+/* Call with ams_info.lock held! */
+static void ams_input_enable(void)
+{
+ s8 x, y, z;
+
+ if (ams_info.idev)
+ return;
+
+ ams_sensors(&x, &y, &z);
+ ams_info.xcalib = x;
+ ams_info.ycalib = y;
+ ams_info.zcalib = z;
+
+ ams_info.idev = input_allocate_device();
+ if (!ams_info.idev)
+ return;
+
+ ams_info.idev->name = "Apple Motion Sensor";
+ ams_info.idev->id.bustype = ams_info.bustype;
+ ams_info.idev->id.vendor = 0;
+ ams_info.idev->open = ams_input_open;
+ ams_info.idev->close = ams_input_close;
+ ams_info.idev->cdev.dev = &ams_info.of_dev->dev;
+
+ input_set_abs_params(ams_info.idev, ABS_X, -50, 50, 3, 0);
+ input_set_abs_params(ams_info.idev, ABS_Y, -50, 50, 3, 0);
+ input_set_abs_params(ams_info.idev, ABS_Z, -50, 50, 3, 0);
+
+ set_bit(EV_ABS, ams_info.idev->evbit);
+ set_bit(EV_KEY, ams_info.idev->evbit);
+ set_bit(BTN_TOUCH, ams_info.idev->keybit);
+
+ if (input_register_device(ams_info.idev)) {
+ input_free_device(ams_info.idev);
+ ams_info.idev = NULL;
+ return;
+ }
+}
+
+/* Call with ams_info.lock held! */
+static void ams_input_disable(void)
+{
+ if (ams_info.idev) {
+ input_unregister_device(ams_info.idev);
+ ams_info.idev = NULL;
+ }
+}
+
+static ssize_t ams_input_show_joystick(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%d\n", joystick);
+}
+
+static ssize_t ams_input_store_joystick(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ if (sscanf(buf, "%d\n", &joystick) != 1)
+ return -EINVAL;
+
+ mutex_lock(&ams_info.lock);
+
+ if (joystick)
+ ams_input_enable();
+ else
+ ams_input_disable();
+
+ mutex_unlock(&ams_info.lock);
+
+ return count;
+}
+
+static DEVICE_ATTR(joystick, S_IRUGO | S_IWUSR,
+ ams_input_show_joystick, ams_input_store_joystick);
+
+/* Call with ams_info.lock held! */
+int ams_input_init(void)
+{
+ int result;
+
+ result = device_create_file(&ams_info.of_dev->dev, &dev_attr_joystick);
+
+ if (!result && joystick)
+ ams_input_enable();
+ return result;
+}
+
+/* Call with ams_info.lock held! */
+void ams_input_exit()
+{
+ ams_input_disable();
+ device_remove_file(&ams_info.of_dev->dev, &dev_attr_joystick);
+}
diff --git a/drivers/hwmon/ams/ams-pmu.c b/drivers/hwmon/ams/ams-pmu.c
new file mode 100644
index 000000000000..4636ae031a53
--- /dev/null
+++ b/drivers/hwmon/ams/ams-pmu.c
@@ -0,0 +1,207 @@
+/*
+ * Apple Motion Sensor driver (PMU variant)
+ *
+ * Copyright (C) 2006 Michael Hanselmann (linux-kernel@hansmi.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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/adb.h>
+#include <linux/pmu.h>
+
+#include "ams.h"
+
+/* Attitude */
+#define AMS_X 0x00
+#define AMS_Y 0x01
+#define AMS_Z 0x02
+
+/* Not exactly known, maybe chip vendor */
+#define AMS_VENDOR 0x03
+
+/* Freefall registers */
+#define AMS_FF_CLEAR 0x04
+#define AMS_FF_ENABLE 0x05
+#define AMS_FF_LOW_LIMIT 0x06
+#define AMS_FF_DEBOUNCE 0x07
+
+/* Shock registers */
+#define AMS_SHOCK_CLEAR 0x08
+#define AMS_SHOCK_ENABLE 0x09
+#define AMS_SHOCK_HIGH_LIMIT 0x0a
+#define AMS_SHOCK_DEBOUNCE 0x0b
+
+/* Global interrupt and power control register */
+#define AMS_CONTROL 0x0c
+
+static u8 ams_pmu_cmd;
+
+static void ams_pmu_req_complete(struct adb_request *req)
+{
+ complete((struct completion *)req->arg);
+}
+
+/* Only call this function from task context */
+static void ams_pmu_set_register(u8 reg, u8 value)
+{
+ static struct adb_request req;
+ DECLARE_COMPLETION(req_complete);
+
+ req.arg = &req_complete;
+ if (pmu_request(&req, ams_pmu_req_complete, 4, ams_pmu_cmd, 0x00, reg, value))
+ return;
+
+ wait_for_completion(&req_complete);
+}
+
+/* Only call this function from task context */
+static u8 ams_pmu_get_register(u8 reg)
+{
+ static struct adb_request req;
+ DECLARE_COMPLETION(req_complete);
+
+ req.arg = &req_complete;
+ if (pmu_request(&req, ams_pmu_req_complete, 3, ams_pmu_cmd, 0x01, reg))
+ return 0;
+
+ wait_for_completion(&req_complete);
+
+ if (req.reply_len > 0)
+ return req.reply[0];
+ else
+ return 0;
+}
+
+/* Enables or disables the specified interrupts */
+static void ams_pmu_set_irq(enum ams_irq reg, char enable)
+{
+ if (reg & AMS_IRQ_FREEFALL) {
+ u8 val = ams_pmu_get_register(AMS_FF_ENABLE);
+ if (enable)
+ val |= 0x80;
+ else
+ val &= ~0x80;
+ ams_pmu_set_register(AMS_FF_ENABLE, val);
+ }
+
+ if (reg & AMS_IRQ_SHOCK) {
+ u8 val = ams_pmu_get_register(AMS_SHOCK_ENABLE);
+ if (enable)
+ val |= 0x80;
+ else
+ val &= ~0x80;
+ ams_pmu_set_register(AMS_SHOCK_ENABLE, val);
+ }
+
+ if (reg & AMS_IRQ_GLOBAL) {
+ u8 val = ams_pmu_get_register(AMS_CONTROL);
+ if (enable)
+ val |= 0x80;
+ else
+ val &= ~0x80;
+ ams_pmu_set_register(AMS_CONTROL, val);
+ }
+}
+
+static void ams_pmu_clear_irq(enum ams_irq reg)
+{
+ if (reg & AMS_IRQ_FREEFALL)
+ ams_pmu_set_register(AMS_FF_CLEAR, 0x00);
+
+ if (reg & AMS_IRQ_SHOCK)
+ ams_pmu_set_register(AMS_SHOCK_CLEAR, 0x00);
+}
+
+static u8 ams_pmu_get_vendor(void)
+{
+ return ams_pmu_get_register(AMS_VENDOR);
+}
+
+static void ams_pmu_get_xyz(s8 *x, s8 *y, s8 *z)
+{
+ *x = ams_pmu_get_register(AMS_X);
+ *y = ams_pmu_get_register(AMS_Y);
+ *z = ams_pmu_get_register(AMS_Z);
+}
+
+static void ams_pmu_exit(void)
+{
+ /* Disable interrupts */
+ ams_pmu_set_irq(AMS_IRQ_ALL, 0);
+
+ /* Clear interrupts */
+ ams_pmu_clear_irq(AMS_IRQ_ALL);
+
+ ams_info.has_device = 0;
+
+ printk(KERN_INFO "ams: Unloading\n");
+}
+
+int __init ams_pmu_init(struct device_node *np)
+{
+ u32 *prop;
+ int result;
+
+ mutex_lock(&ams_info.lock);
+
+ /* Set implementation stuff */
+ ams_info.of_node = np;
+ ams_info.exit = ams_pmu_exit;
+ ams_info.get_vendor = ams_pmu_get_vendor;
+ ams_info.get_xyz = ams_pmu_get_xyz;
+ ams_info.clear_irq = ams_pmu_clear_irq;
+ ams_info.bustype = BUS_HOST;
+
+ /* Get PMU command, should be 0x4e, but we can never know */
+ prop = (u32*)get_property(ams_info.of_node, "reg", NULL);
+ if (!prop) {
+ result = -ENODEV;
+ goto exit;
+ }
+ ams_pmu_cmd = ((*prop) >> 8) & 0xff;
+
+ /* Disable interrupts */
+ ams_pmu_set_irq(AMS_IRQ_ALL, 0);
+
+ /* Clear interrupts */
+ ams_pmu_clear_irq(AMS_IRQ_ALL);
+
+ result = ams_sensor_attach();
+ if (result < 0)
+ goto exit;
+
+ /* Set default values */
+ ams_pmu_set_register(AMS_FF_LOW_LIMIT, 0x15);
+ ams_pmu_set_register(AMS_FF_ENABLE, 0x08);
+ ams_pmu_set_register(AMS_FF_DEBOUNCE, 0x14);
+
+ ams_pmu_set_register(AMS_SHOCK_HIGH_LIMIT, 0x60);
+ ams_pmu_set_register(AMS_SHOCK_ENABLE, 0x0f);
+ ams_pmu_set_register(AMS_SHOCK_DEBOUNCE, 0x14);
+
+ ams_pmu_set_register(AMS_CONTROL, 0x4f);
+
+ /* Clear interrupts */
+ ams_pmu_clear_irq(AMS_IRQ_ALL);
+
+ ams_info.has_device = 1;
+
+ /* Enable interrupts */
+ ams_pmu_set_irq(AMS_IRQ_ALL, 1);
+
+ printk(KERN_INFO "ams: Found PMU based motion sensor\n");
+
+ result = 0;
+
+exit:
+ mutex_unlock(&ams_info.lock);
+
+ return result;
+}
diff --git a/drivers/hwmon/ams/ams.h b/drivers/hwmon/ams/ams.h
new file mode 100644
index 000000000000..240730e6bcde
--- /dev/null
+++ b/drivers/hwmon/ams/ams.h
@@ -0,0 +1,72 @@
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/kthread.h>
+#include <linux/mutex.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+#include <asm/of_device.h>
+
+enum ams_irq {
+ AMS_IRQ_FREEFALL = 0x01,
+ AMS_IRQ_SHOCK = 0x02,
+ AMS_IRQ_GLOBAL = 0x04,
+ AMS_IRQ_ALL =
+ AMS_IRQ_FREEFALL |
+ AMS_IRQ_SHOCK |
+ AMS_IRQ_GLOBAL,
+};
+
+struct ams {
+ /* Locks */
+ spinlock_t irq_lock;
+ struct mutex lock;
+
+ /* General properties */
+ struct device_node *of_node;
+ struct of_device *of_dev;
+ char has_device;
+ char vflag;
+ u32 orient1;
+ u32 orient2;
+
+ /* Interrupt worker */
+ struct work_struct worker;
+ u8 worker_irqs;
+
+ /* Implementation
+ *
+ * Only call these functions with the main lock held.
+ */
+ void (*exit)(void);
+
+ void (*get_xyz)(s8 *x, s8 *y, s8 *z);
+ u8 (*get_vendor)(void);
+
+ void (*clear_irq)(enum ams_irq reg);
+
+#ifdef CONFIG_SENSORS_AMS_I2C
+ /* I2C properties */
+ int i2c_bus;
+ int i2c_address;
+ struct i2c_client i2c_client;
+#endif
+
+ /* Joystick emulation */
+ struct task_struct *kthread;
+ struct input_dev *idev;
+ __u16 bustype;
+
+ /* calibrated null values */
+ int xcalib, ycalib, zcalib;
+};
+
+extern struct ams ams_info;
+
+extern void ams_sensors(s8 *x, s8 *y, s8 *z);
+extern int ams_sensor_attach(void);
+
+extern int ams_pmu_init(struct device_node *np);
+extern int ams_i2c_init(struct device_node *np);
+
+extern int ams_input_init(void);
+extern void ams_input_exit(void);
diff --git a/drivers/hwmon/f71805f.c b/drivers/hwmon/f71805f.c
index de17a72149d9..a272cae8f60e 100644
--- a/drivers/hwmon/f71805f.c
+++ b/drivers/hwmon/f71805f.c
@@ -1,12 +1,15 @@
/*
- * f71805f.c - driver for the Fintek F71805F/FG Super-I/O chip integrated
- * hardware monitoring features
+ * f71805f.c - driver for the Fintek F71805F/FG and F71872F/FG Super-I/O
+ * chips integrated hardware monitoring features
* Copyright (C) 2005-2006 Jean Delvare <khali@linux-fr.org>
*
* The F71805F/FG is a LPC Super-I/O chip made by Fintek. It integrates
* complete hardware monitoring features: voltage, fan and temperature
* sensors, and manual and automatic fan speed control.
*
+ * The F71872F/FG is almost the same, with two more voltages monitored,
+ * and 6 VID 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
@@ -37,6 +40,7 @@
static struct platform_device *pdev;
#define DRVNAME "f71805f"
+enum kinds { f71805f, f71872f };
/*
* Super-I/O constants and functions
@@ -48,11 +52,13 @@ static struct platform_device *pdev;
#define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */
#define SIO_REG_DEVREV 0x22 /* Device revision */
#define SIO_REG_MANID 0x23 /* Fintek ID (2 bytes) */
+#define SIO_REG_FNSEL1 0x29 /* Multi Function Select 1 (F71872F) */
#define SIO_REG_ENABLE 0x30 /* Logical device enable */
#define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */
#define SIO_FINTEK_ID 0x1934
#define SIO_F71805F_ID 0x0406
+#define SIO_F71872F_ID 0x0341
static inline int
superio_inb(int base, int reg)
@@ -96,22 +102,25 @@ superio_exit(int base)
* ISA constants
*/
-#define REGION_LENGTH 2
-#define ADDR_REG_OFFSET 0
-#define DATA_REG_OFFSET 1
+#define REGION_LENGTH 8
+#define ADDR_REG_OFFSET 5
+#define DATA_REG_OFFSET 6
/*
* Registers
*/
-/* in nr from 0 to 8 (8-bit values) */
+/* in nr from 0 to 10 (8-bit values) */
#define F71805F_REG_IN(nr) (0x10 + (nr))
-#define F71805F_REG_IN_HIGH(nr) (0x40 + 2 * (nr))
-#define F71805F_REG_IN_LOW(nr) (0x41 + 2 * (nr))
+#define F71805F_REG_IN_HIGH(nr) ((nr) < 10 ? 0x40 + 2 * (nr) : 0x2E)
+#define F71805F_REG_IN_LOW(nr) ((nr) < 10 ? 0x41 + 2 * (nr) : 0x2F)
/* fan nr from 0 to 2 (12-bit values, two registers) */
#define F71805F_REG_FAN(nr) (0x20 + 2 * (nr))
#define F71805F_REG_FAN_LOW(nr) (0x28 + 2 * (nr))
+#define F71805F_REG_FAN_TARGET(nr) (0x69 + 16 * (nr))
#define F71805F_REG_FAN_CTRL(nr) (0x60 + 16 * (nr))
+#define F71805F_REG_PWM_FREQ(nr) (0x63 + 16 * (nr))
+#define F71805F_REG_PWM_DUTY(nr) (0x6B + 16 * (nr))
/* temp nr from 0 to 2 (8-bit values) */
#define F71805F_REG_TEMP(nr) (0x1B + (nr))
#define F71805F_REG_TEMP_HIGH(nr) (0x54 + 2 * (nr))
@@ -122,6 +131,14 @@ superio_exit(int base)
/* status nr from 0 to 2 */
#define F71805F_REG_STATUS(nr) (0x36 + (nr))
+/* individual register bits */
+#define FAN_CTRL_DC_MODE 0x10
+#define FAN_CTRL_LATCH_FULL 0x08
+#define FAN_CTRL_MODE_MASK 0x03
+#define FAN_CTRL_MODE_SPEED 0x00
+#define FAN_CTRL_MODE_TEMPERATURE 0x01
+#define FAN_CTRL_MODE_MANUAL 0x02
+
/*
* Data structures and manipulation thereof
*/
@@ -138,12 +155,16 @@ struct f71805f_data {
unsigned long last_limits; /* In jiffies */
/* Register values */
- u8 in[9];
- u8 in_high[9];
- u8 in_low[9];
+ u8 in[11];
+ u8 in_high[11];
+ u8 in_low[11];
+ u16 has_in;
u16 fan[3];
u16 fan_low[3];
- u8 fan_enabled; /* Read once at init time */
+ u16 fan_target[3];
+ u8 fan_ctrl[3];
+ u8 pwm[3];
+ u8 pwm_freq[3];
u8 temp[3];
u8 temp_high[3];
u8 temp_hyst[3];
@@ -151,6 +172,11 @@ struct f71805f_data {
unsigned long alarms;
};
+struct f71805f_sio_data {
+ enum kinds kind;
+ u8 fnsel1;
+};
+
static inline long in_from_reg(u8 reg)
{
return (reg * 8);
@@ -200,6 +226,33 @@ static inline u16 fan_to_reg(long rpm)
return (1500000 / rpm);
}
+static inline unsigned long pwm_freq_from_reg(u8 reg)
+{
+ unsigned long clock = (reg & 0x80) ? 48000000UL : 1000000UL;
+
+ reg &= 0x7f;
+ if (reg == 0)
+ reg++;
+ return clock / (reg << 8);
+}
+
+static inline u8 pwm_freq_to_reg(unsigned long val)
+{
+ if (val >= 187500) /* The highest we can do */
+ return 0x80;
+ if (val >= 1475) /* Use 48 MHz clock */
+ return 0x80 | (48000000UL / (val << 8));
+ if (val < 31) /* The lowest we can do */
+ return 0x7f;
+ else /* Use 1 MHz clock */
+ return 1000000UL / (val << 8);
+}
+
+static inline int pwm_mode_from_reg(u8 reg)
+{
+ return !(reg & FAN_CTRL_DC_MODE);
+}
+
static inline long temp_from_reg(u8 reg)
{
return (reg * 1000);
@@ -274,16 +327,21 @@ static struct f71805f_data *f71805f_update_device(struct device *dev)
/* Limit registers cache is refreshed after 60 seconds */
if (time_after(jiffies, data->last_updated + 60 * HZ)
|| !data->valid) {
- for (nr = 0; nr < 9; nr++) {
+ for (nr = 0; nr < 11; nr++) {
+ if (!(data->has_in & (1 << nr)))
+ continue;
data->in_high[nr] = f71805f_read8(data,
F71805F_REG_IN_HIGH(nr));
data->in_low[nr] = f71805f_read8(data,
F71805F_REG_IN_LOW(nr));
}
for (nr = 0; nr < 3; nr++) {
- if (data->fan_enabled & (1 << nr))
- data->fan_low[nr] = f71805f_read16(data,
- F71805F_REG_FAN_LOW(nr));
+ data->fan_low[nr] = f71805f_read16(data,
+ F71805F_REG_FAN_LOW(nr));
+ data->fan_target[nr] = f71805f_read16(data,
+ F71805F_REG_FAN_TARGET(nr));
+ data->pwm_freq[nr] = f71805f_read8(data,
+ F71805F_REG_PWM_FREQ(nr));
}
for (nr = 0; nr < 3; nr++) {
data->temp_high[nr] = f71805f_read8(data,
@@ -299,14 +357,19 @@ static struct f71805f_data *f71805f_update_device(struct device *dev)
/* Measurement registers cache is refreshed after 1 second */
if (time_after(jiffies, data->last_updated + HZ)
|| !data->valid) {
- for (nr = 0; nr < 9; nr++) {
+ for (nr = 0; nr < 11; nr++) {
+ if (!(data->has_in & (1 << nr)))
+ continue;
data->in[nr] = f71805f_read8(data,
F71805F_REG_IN(nr));
}
for (nr = 0; nr < 3; nr++) {
- if (data->fan_enabled & (1 << nr))
- data->fan[nr] = f71805f_read16(data,
- F71805F_REG_FAN(nr));
+ data->fan[nr] = f71805f_read16(data,
+ F71805F_REG_FAN(nr));
+ data->fan_ctrl[nr] = f71805f_read8(data,
+ F71805F_REG_FAN_CTRL(nr));
+ data->pwm[nr] = f71805f_read8(data,
+ F71805F_REG_PWM_DUTY(nr));
}
for (nr = 0; nr < 3; nr++) {
data->temp[nr] = f71805f_read8(data,
@@ -333,35 +396,43 @@ static ssize_t show_in0(struct device *dev, struct device_attribute *devattr,
char *buf)
{
struct f71805f_data *data = f71805f_update_device(dev);
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ int nr = attr->index;
- return sprintf(buf, "%ld\n", in0_from_reg(data->in[0]));
+ return sprintf(buf, "%ld\n", in0_from_reg(data->in[nr]));
}
static ssize_t show_in0_max(struct device *dev, struct device_attribute
*devattr, char *buf)
{
struct f71805f_data *data = f71805f_update_device(dev);
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ int nr = attr->index;
- return sprintf(buf, "%ld\n", in0_from_reg(data->in_high[0]));
+ return sprintf(buf, "%ld\n", in0_from_reg(data->in_high[nr]));
}
static ssize_t show_in0_min(struct device *dev, struct device_attribute
*devattr, char *buf)
{
struct f71805f_data *data = f71805f_update_device(dev);
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ int nr = attr->index;
- return sprintf(buf, "%ld\n", in0_from_reg(data->in_low[0]));
+ return sprintf(buf, "%ld\n", in0_from_reg(data->in_low[nr]));
}
static ssize_t set_in0_max(struct device *dev, struct device_attribute
*devattr, const char *buf, size_t count)
{
struct f71805f_data *data = dev_get_drvdata(dev);
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ int nr = attr->index;
long val = simple_strtol(buf, NULL, 10);
mutex_lock(&data->update_lock);
- data->in_high[0] = in0_to_reg(val);
- f71805f_write8(data, F71805F_REG_IN_HIGH(0), data->in_high[0]);
+ data->in_high[nr] = in0_to_reg(val);
+ f71805f_write8(data, F71805F_REG_IN_HIGH(nr), data->in_high[nr]);
mutex_unlock(&data->update_lock);
return count;
@@ -371,11 +442,13 @@ static ssize_t set_in0_min(struct device *dev, struct device_attribute
*devattr, const char *buf, size_t count)
{
struct f71805f_data *data = dev_get_drvdata(dev);
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ int nr = attr->index;
long val = simple_strtol(buf, NULL, 10);
mutex_lock(&data->update_lock);
- data->in_low[0] = in0_to_reg(val);
- f71805f_write8(data, F71805F_REG_IN_LOW(0), data->in_low[0]);
+ data->in_low[nr] = in0_to_reg(val);
+ f71805f_write8(data, F71805F_REG_IN_LOW(nr), data->in_low[nr]);
mutex_unlock(&data->update_lock);
return count;
@@ -463,6 +536,16 @@ static ssize_t show_fan_min(struct device *dev, struct device_attribute
return sprintf(buf, "%ld\n", fan_from_reg(data->fan_low[nr]));
}
+static ssize_t show_fan_target(struct device *dev, struct device_attribute
+ *devattr, char *buf)
+{
+ struct f71805f_data *data = f71805f_update_device(dev);
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ int nr = attr->index;
+
+ return sprintf(buf, "%ld\n", fan_from_reg(data->fan_target[nr]));
+}
+
static ssize_t set_fan_min(struct device *dev, struct device_attribute
*devattr, const char *buf, size_t count)
{
@@ -479,6 +562,157 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute
return count;
}
+static ssize_t set_fan_target(struct device *dev, struct device_attribute
+ *devattr, const char *buf, size_t count)
+{
+ struct f71805f_data *data = dev_get_drvdata(dev);
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ int nr = attr->index;
+ long val = simple_strtol(buf, NULL, 10);
+
+ mutex_lock(&data->update_lock);
+ data->fan_target[nr] = fan_to_reg(val);
+ f71805f_write16(data, F71805F_REG_FAN_TARGET(nr),
+ data->fan_target[nr]);
+ mutex_unlock(&data->update_lock);
+
+ return count;
+}
+
+static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr,
+ char *buf)
+{
+ struct f71805f_data *data = f71805f_update_device(dev);
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ int nr = attr->index;
+
+ return sprintf(buf, "%d\n", (int)data->pwm[nr]);
+}
+
+static ssize_t show_pwm_enable(struct device *dev, struct device_attribute
+ *devattr, char *buf)
+{
+ struct f71805f_data *data = f71805f_update_device(dev);
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ int nr = attr->index;
+ int mode;
+
+ switch (data->fan_ctrl[nr] & FAN_CTRL_MODE_MASK) {
+ case FAN_CTRL_MODE_SPEED:
+ mode = 3;
+ break;
+ case FAN_CTRL_MODE_TEMPERATURE:
+ mode = 2;
+ break;
+ default: /* MANUAL */
+ mode = 1;
+ }
+
+ return sprintf(buf, "%d\n", mode);
+}
+
+static ssize_t show_pwm_freq(struct device *dev, struct device_attribute
+ *devattr, char *buf)
+{
+ struct f71805f_data *data = f71805f_update_device(dev);
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ int nr = attr->index;
+
+ return sprintf(buf, "%lu\n", pwm_freq_from_reg(data->pwm_freq[nr]));
+}
+
+static ssize_t show_pwm_mode(struct device *dev, struct device_attribute
+ *devattr, char *buf)
+{
+ struct f71805f_data *data = f71805f_update_device(dev);
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ int nr = attr->index;
+
+ return sprintf(buf, "%d\n", pwm_mode_from_reg(data->fan_ctrl[nr]));
+}
+
+static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr,
+ const char *buf, size_t count)
+{
+ struct f71805f_data *data = dev_get_drvdata(dev);
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ int nr = attr->index;
+ unsigned long val = simple_strtoul(buf, NULL, 10);
+
+ if (val > 255)
+ return -EINVAL;
+
+ mutex_lock(&data->update_lock);
+ data->pwm[nr] = val;
+ f71805f_write8(data, F71805F_REG_PWM_DUTY(nr), data->pwm[nr]);
+ mutex_unlock(&data->update_lock);
+
+ return count;
+}
+
+static struct attribute *f71805f_attr_pwm[];
+
+static ssize_t set_pwm_enable(struct device *dev, struct device_attribute
+ *devattr, const char *buf, size_t count)
+{
+ struct f71805f_data *data = dev_get_drvdata(dev);
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ int nr = attr->index;
+ unsigned long val = simple_strtoul(buf, NULL, 10);
+ u8 reg;
+
+ if (val < 1 || val > 3)
+ return -EINVAL;
+
+ if (val > 1) { /* Automatic mode, user can't set PWM value */
+ if (sysfs_chmod_file(&dev->kobj, f71805f_attr_pwm[nr],
+ S_IRUGO))
+ dev_dbg(dev, "chmod -w pwm%d failed\n", nr + 1);
+ }
+
+ mutex_lock(&data->update_lock);
+ reg = f71805f_read8(data, F71805F_REG_FAN_CTRL(nr))
+ & ~FAN_CTRL_MODE_MASK;
+ switch (val) {
+ case 1:
+ reg |= FAN_CTRL_MODE_MANUAL;
+ break;
+ case 2:
+ reg |= FAN_CTRL_MODE_TEMPERATURE;
+ break;
+ case 3:
+ reg |= FAN_CTRL_MODE_SPEED;
+ break;
+ }
+ data->fan_ctrl[nr] = reg;
+ f71805f_write8(data, F71805F_REG_FAN_CTRL(nr), reg);
+ mutex_unlock(&data->update_lock);
+
+ if (val == 1) { /* Manual mode, user can set PWM value */
+ if (sysfs_chmod_file(&dev->kobj, f71805f_attr_pwm[nr],
+ S_IRUGO | S_IWUSR))
+ dev_dbg(dev, "chmod +w pwm%d failed\n", nr + 1);
+ }
+
+ return count;
+}
+
+static ssize_t set_pwm_freq(struct device *dev, struct device_attribute
+ *devattr, const char *buf, size_t count)
+{
+ struct f71805f_data *data = dev_get_drvdata(dev);
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ int nr = attr->index;
+ unsigned long val = simple_strtoul(buf, NULL, 10);
+
+ mutex_lock(&data->update_lock);
+ data->pwm_freq[nr] = pwm_freq_to_reg(val);
+ f71805f_write8(data, F71805F_REG_PWM_FREQ(nr), data->pwm_freq[nr]);
+ mutex_unlock(&data->update_lock);
+
+ return count;
+}
+
static ssize_t show_temp(struct device *dev, struct device_attribute *devattr,
char *buf)
{
@@ -557,7 +791,7 @@ static ssize_t show_alarms_in(struct device *dev, struct device_attribute
{
struct f71805f_data *data = f71805f_update_device(dev);
- return sprintf(buf, "%lu\n", data->alarms & 0x1ff);
+ return sprintf(buf, "%lu\n", data->alarms & 0x7ff);
}
static ssize_t show_alarms_fan(struct device *dev, struct device_attribute
@@ -594,9 +828,11 @@ static ssize_t show_name(struct device *dev, struct device_attribute
return sprintf(buf, "%s\n", data->name);
}
-static DEVICE_ATTR(in0_input, S_IRUGO, show_in0, NULL);
-static DEVICE_ATTR(in0_max, S_IRUGO| S_IWUSR, show_in0_max, set_in0_max);
-static DEVICE_ATTR(in0_min, S_IRUGO| S_IWUSR, show_in0_min, set_in0_min);
+static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, show_in0, NULL, 0);
+static SENSOR_DEVICE_ATTR(in0_max, S_IRUGO| S_IWUSR,
+ show_in0_max, set_in0_max, 0);
+static SENSOR_DEVICE_ATTR(in0_min, S_IRUGO| S_IWUSR,
+ show_in0_min, set_in0_min, 0);
static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_in, NULL, 1);
static SENSOR_DEVICE_ATTR(in1_max, S_IRUGO | S_IWUSR,
show_in_max, set_in_max, 1);
@@ -637,16 +873,32 @@ static SENSOR_DEVICE_ATTR(in8_max, S_IRUGO | S_IWUSR,
show_in_max, set_in_max, 8);
static SENSOR_DEVICE_ATTR(in8_min, S_IRUGO | S_IWUSR,
show_in_min, set_in_min, 8);
+static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, show_in0, NULL, 9);
+static SENSOR_DEVICE_ATTR(in9_max, S_IRUGO | S_IWUSR,
+ show_in0_max, set_in0_max, 9);
+static SENSOR_DEVICE_ATTR(in9_min, S_IRUGO | S_IWUSR,
+ show_in0_min, set_in0_min, 9);
+static SENSOR_DEVICE_ATTR(in10_input, S_IRUGO, show_in0, NULL, 10);
+static SENSOR_DEVICE_ATTR(in10_max, S_IRUGO | S_IWUSR,
+ show_in0_max, set_in0_max, 10);
+static SENSOR_DEVICE_ATTR(in10_min, S_IRUGO | S_IWUSR,
+ show_in0_min, set_in0_min, 10);
static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0);
static SENSOR_DEVICE_ATTR(fan1_min, S_IRUGO | S_IWUSR,
show_fan_min, set_fan_min, 0);
+static SENSOR_DEVICE_ATTR(fan1_target, S_IRUGO | S_IWUSR,
+ show_fan_target, set_fan_target, 0);
static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1);
static SENSOR_DEVICE_ATTR(fan2_min, S_IRUGO | S_IWUSR,
show_fan_min, set_fan_min, 1);
+static SENSOR_DEVICE_ATTR(fan2_target, S_IRUGO | S_IWUSR,
+ show_fan_target, set_fan_target, 1);
static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2);
static SENSOR_DEVICE_ATTR(fan3_min, S_IRUGO | S_IWUSR,
show_fan_min, set_fan_min, 2);
+static SENSOR_DEVICE_ATTR(fan3_target, S_IRUGO | S_IWUSR,
+ show_fan_target, set_fan_target, 2);
static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0);
static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR,
@@ -667,6 +919,27 @@ static SENSOR_DEVICE_ATTR(temp3_max_hyst, S_IRUGO | S_IWUSR,
show_temp_hyst, set_temp_hyst, 2);
static SENSOR_DEVICE_ATTR(temp3_type, S_IRUGO, show_temp_type, NULL, 2);
+/* pwm (value) files are created read-only, write permission is
+ then added or removed dynamically as needed */
+static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO, show_pwm, set_pwm, 0);
+static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
+ show_pwm_enable, set_pwm_enable, 0);
+static SENSOR_DEVICE_ATTR(pwm1_freq, S_IRUGO | S_IWUSR,
+ show_pwm_freq, set_pwm_freq, 0);
+static SENSOR_DEVICE_ATTR(pwm1_mode, S_IRUGO, show_pwm_mode, NULL, 0);
+static SENSOR_DEVICE_ATTR(pwm2, S_IRUGO, show_pwm, set_pwm, 1);
+static SENSOR_DEVICE_ATTR(pwm2_enable, S_IRUGO | S_IWUSR,
+ show_pwm_enable, set_pwm_enable, 1);
+static SENSOR_DEVICE_ATTR(pwm2_freq, S_IRUGO | S_IWUSR,
+ show_pwm_freq, set_pwm_freq, 1);
+static SENSOR_DEVICE_ATTR(pwm2_mode, S_IRUGO, show_pwm_mode, NULL, 1);
+static SENSOR_DEVICE_ATTR(pwm3, S_IRUGO, show_pwm, set_pwm, 2);
+static SENSOR_DEVICE_ATTR(pwm3_enable, S_IRUGO | S_IWUSR,
+ show_pwm_enable, set_pwm_enable, 2);
+static SENSOR_DEVICE_ATTR(pwm3_freq, S_IRUGO | S_IWUSR,
+ show_pwm_freq, set_pwm_freq, 2);
+static SENSOR_DEVICE_ATTR(pwm3_mode, S_IRUGO, show_pwm_mode, NULL, 2);
+
static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0);
static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1);
static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2);
@@ -676,6 +949,8 @@ static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 5);
static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 6);
static SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 7);
static SENSOR_DEVICE_ATTR(in8_alarm, S_IRUGO, show_alarm, NULL, 8);
+static SENSOR_DEVICE_ATTR(in9_alarm, S_IRUGO, show_alarm, NULL, 9);
+static SENSOR_DEVICE_ATTR(in10_alarm, S_IRUGO, show_alarm, NULL, 10);
static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 11);
static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 12);
static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 13);
@@ -689,9 +964,9 @@ static DEVICE_ATTR(alarms_temp, S_IRUGO, show_alarms_temp, NULL);
static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
static struct attribute *f71805f_attributes[] = {
- &dev_attr_in0_input.attr,
- &dev_attr_in0_max.attr,
- &dev_attr_in0_min.attr,
+ &sensor_dev_attr_in0_input.dev_attr.attr,
+ &sensor_dev_attr_in0_max.dev_attr.attr,
+ &sensor_dev_attr_in0_min.dev_attr.attr,
&sensor_dev_attr_in1_input.dev_attr.attr,
&sensor_dev_attr_in1_max.dev_attr.attr,
&sensor_dev_attr_in1_min.dev_attr.attr,
@@ -701,9 +976,6 @@ static struct attribute *f71805f_attributes[] = {
&sensor_dev_attr_in3_input.dev_attr.attr,
&sensor_dev_attr_in3_max.dev_attr.attr,
&sensor_dev_attr_in3_min.dev_attr.attr,
- &sensor_dev_attr_in4_input.dev_attr.attr,
- &sensor_dev_attr_in4_max.dev_attr.attr,
- &sensor_dev_attr_in4_min.dev_attr.attr,
&sensor_dev_attr_in5_input.dev_attr.attr,
&sensor_dev_attr_in5_max.dev_attr.attr,
&sensor_dev_attr_in5_min.dev_attr.attr,
@@ -713,9 +985,29 @@ static struct attribute *f71805f_attributes[] = {
&sensor_dev_attr_in7_input.dev_attr.attr,
&sensor_dev_attr_in7_max.dev_attr.attr,
&sensor_dev_attr_in7_min.dev_attr.attr,
- &sensor_dev_attr_in8_input.dev_attr.attr,
- &sensor_dev_attr_in8_max.dev_attr.attr,
- &sensor_dev_attr_in8_min.dev_attr.attr,
+
+ &sensor_dev_attr_fan1_input.dev_attr.attr,
+ &sensor_dev_attr_fan1_min.dev_attr.attr,
+ &sensor_dev_attr_fan1_alarm.dev_attr.attr,
+ &sensor_dev_attr_fan1_target.dev_attr.attr,
+ &sensor_dev_attr_fan2_input.dev_attr.attr,
+ &sensor_dev_attr_fan2_min.dev_attr.attr,
+ &sensor_dev_attr_fan2_alarm.dev_attr.attr,
+ &sensor_dev_attr_fan2_target.dev_attr.attr,
+ &sensor_dev_attr_fan3_input.dev_attr.attr,
+ &sensor_dev_attr_fan3_min.dev_attr.attr,
+ &sensor_dev_attr_fan3_alarm.dev_attr.attr,
+ &sensor_dev_attr_fan3_target.dev_attr.attr,
+
+ &sensor_dev_attr_pwm1.dev_attr.attr,
+ &sensor_dev_attr_pwm1_enable.dev_attr.attr,
+ &sensor_dev_attr_pwm1_mode.dev_attr.attr,
+ &sensor_dev_attr_pwm2.dev_attr.attr,
+ &sensor_dev_attr_pwm2_enable.dev_attr.attr,
+ &sensor_dev_attr_pwm2_mode.dev_attr.attr,
+ &sensor_dev_attr_pwm3.dev_attr.attr,
+ &sensor_dev_attr_pwm3_enable.dev_attr.attr,
+ &sensor_dev_attr_pwm3_mode.dev_attr.attr,
&sensor_dev_attr_temp1_input.dev_attr.attr,
&sensor_dev_attr_temp1_max.dev_attr.attr,
@@ -734,11 +1026,9 @@ static struct attribute *f71805f_attributes[] = {
&sensor_dev_attr_in1_alarm.dev_attr.attr,
&sensor_dev_attr_in2_alarm.dev_attr.attr,
&sensor_dev_attr_in3_alarm.dev_attr.attr,
- &sensor_dev_attr_in4_alarm.dev_attr.attr,
&sensor_dev_attr_in5_alarm.dev_attr.attr,
&sensor_dev_attr_in6_alarm.dev_attr.attr,
&sensor_dev_attr_in7_alarm.dev_attr.attr,
- &sensor_dev_attr_in8_alarm.dev_attr.attr,
&dev_attr_alarms_in.attr,
&sensor_dev_attr_temp1_alarm.dev_attr.attr,
&sensor_dev_attr_temp2_alarm.dev_attr.attr,
@@ -754,29 +1044,59 @@ static const struct attribute_group f71805f_group = {
.attrs = f71805f_attributes,
};
-static struct attribute *f71805f_attributes_fan[3][4] = {
+static struct attribute *f71805f_attributes_optin[4][5] = {
{
- &sensor_dev_attr_fan1_input.dev_attr.attr,
- &sensor_dev_attr_fan1_min.dev_attr.attr,
- &sensor_dev_attr_fan1_alarm.dev_attr.attr,
+ &sensor_dev_attr_in4_input.dev_attr.attr,
+ &sensor_dev_attr_in4_max.dev_attr.attr,
+ &sensor_dev_attr_in4_min.dev_attr.attr,
+ &sensor_dev_attr_in4_alarm.dev_attr.attr,
+ NULL
+ }, {
+ &sensor_dev_attr_in8_input.dev_attr.attr,
+ &sensor_dev_attr_in8_max.dev_attr.attr,
+ &sensor_dev_attr_in8_min.dev_attr.attr,
+ &sensor_dev_attr_in8_alarm.dev_attr.attr,
NULL
}, {
- &sensor_dev_attr_fan2_input.dev_attr.attr,
- &sensor_dev_attr_fan2_min.dev_attr.attr,
- &sensor_dev_attr_fan2_alarm.dev_attr.attr,
+ &sensor_dev_attr_in9_input.dev_attr.attr,
+ &sensor_dev_attr_in9_max.dev_attr.attr,
+ &sensor_dev_attr_in9_min.dev_attr.attr,
+ &sensor_dev_attr_in9_alarm.dev_attr.attr,
NULL
}, {
- &sensor_dev_attr_fan3_input.dev_attr.attr,
- &sensor_dev_attr_fan3_min.dev_attr.attr,
- &sensor_dev_attr_fan3_alarm.dev_attr.attr,
+ &sensor_dev_attr_in10_input.dev_attr.attr,
+ &sensor_dev_attr_in10_max.dev_attr.attr,
+ &sensor_dev_attr_in10_min.dev_attr.attr,
+ &sensor_dev_attr_in10_alarm.dev_attr.attr,
NULL
}
};
-static const struct attribute_group f71805f_group_fan[3] = {
- { .attrs = f71805f_attributes_fan[0] },
- { .attrs = f71805f_attributes_fan[1] },
- { .attrs = f71805f_attributes_fan[2] },
+static const struct attribute_group f71805f_group_optin[4] = {
+ { .attrs = f71805f_attributes_optin[0] },
+ { .attrs = f71805f_attributes_optin[1] },
+ { .attrs = f71805f_attributes_optin[2] },
+ { .attrs = f71805f_attributes_optin[3] },
+};
+
+/* We don't include pwm_freq files in the arrays above, because they must be
+ created conditionally (only if pwm_mode is 1 == PWM) */
+static struct attribute *f71805f_attributes_pwm_freq[] = {
+ &sensor_dev_attr_pwm1_freq.dev_attr.attr,
+ &sensor_dev_attr_pwm2_freq.dev_attr.attr,
+ &sensor_dev_attr_pwm3_freq.dev_attr.attr,
+ NULL
+};
+
+static const struct attribute_group f71805f_group_pwm_freq = {
+ .attrs = f71805f_attributes_pwm_freq,
+};
+
+/* We also need an indexed access to pwmN files to toggle writability */
+static struct attribute *f71805f_attr_pwm[] = {
+ &sensor_dev_attr_pwm1.dev_attr.attr,
+ &sensor_dev_attr_pwm2.dev_attr.attr,
+ &sensor_dev_attr_pwm3.dev_attr.attr,
};
/*
@@ -798,18 +1118,30 @@ static void __devinit f71805f_init_device(struct f71805f_data *data)
/* Fan monitoring can be disabled. If it is, we won't be polling
the register values, and won't create the related sysfs files. */
for (i = 0; i < 3; i++) {
- reg = f71805f_read8(data, F71805F_REG_FAN_CTRL(i));
- if (!(reg & 0x80))
- data->fan_enabled |= (1 << i);
+ data->fan_ctrl[i] = f71805f_read8(data,
+ F71805F_REG_FAN_CTRL(i));
+ /* Clear latch full bit, else "speed mode" fan speed control
+ doesn't work */
+ if (data->fan_ctrl[i] & FAN_CTRL_LATCH_FULL) {
+ data->fan_ctrl[i] &= ~FAN_CTRL_LATCH_FULL;
+ f71805f_write8(data, F71805F_REG_FAN_CTRL(i),
+ data->fan_ctrl[i]);
+ }
}
}
static int __devinit f71805f_probe(struct platform_device *pdev)
{
+ struct f71805f_sio_data *sio_data = pdev->dev.platform_data;
struct f71805f_data *data;
struct resource *res;
int i, err;
+ static const char *names[] = {
+ "f71805f",
+ "f71872f",
+ };
+
if (!(data = kzalloc(sizeof(struct f71805f_data), GFP_KERNEL))) {
err = -ENOMEM;
printk(KERN_ERR DRVNAME ": Out of memory\n");
@@ -819,24 +1151,69 @@ static int __devinit f71805f_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
data->addr = res->start;
mutex_init(&data->lock);
- data->name = "f71805f";
+ data->name = names[sio_data->kind];
mutex_init(&data->update_lock);
platform_set_drvdata(pdev, data);
+ /* Some voltage inputs depend on chip model and configuration */
+ switch (sio_data->kind) {
+ case f71805f:
+ data->has_in = 0x1ff;
+ break;
+ case f71872f:
+ data->has_in = 0x6ef;
+ if (sio_data->fnsel1 & 0x01)
+ data->has_in |= (1 << 4); /* in4 */
+ if (sio_data->fnsel1 & 0x02)
+ data->has_in |= (1 << 8); /* in8 */
+ break;
+ }
+
/* Initialize the F71805F chip */
f71805f_init_device(data);
/* Register sysfs interface files */
if ((err = sysfs_create_group(&pdev->dev.kobj, &f71805f_group)))
goto exit_free;
- for (i = 0; i < 3; i++) {
- if (!(data->fan_enabled & (1 << i)))
- continue;
+ if (data->has_in & (1 << 4)) { /* in4 */
+ if ((err = sysfs_create_group(&pdev->dev.kobj,
+ &f71805f_group_optin[0])))
+ goto exit_remove_files;
+ }
+ if (data->has_in & (1 << 8)) { /* in8 */
+ if ((err = sysfs_create_group(&pdev->dev.kobj,
+ &f71805f_group_optin[1])))
+ goto exit_remove_files;
+ }
+ if (data->has_in & (1 << 9)) { /* in9 (F71872F/FG only) */
if ((err = sysfs_create_group(&pdev->dev.kobj,
- &f71805f_group_fan[i])))
+ &f71805f_group_optin[2])))
goto exit_remove_files;
}
+ if (data->has_in & (1 << 10)) { /* in9 (F71872F/FG only) */
+ if ((err = sysfs_create_group(&pdev->dev.kobj,
+ &f71805f_group_optin[3])))
+ goto exit_remove_files;
+ }
+ for (i = 0; i < 3; i++) {
+ /* If control mode is PWM, create pwm_freq file */
+ if (!(data->fan_ctrl[i] & FAN_CTRL_DC_MODE)) {
+ if ((err = sysfs_create_file(&pdev->dev.kobj,
+ f71805f_attributes_pwm_freq[i])))
+ goto exit_remove_files;
+ }
+ /* If PWM is in manual mode, add write permission */
+ if (data->fan_ctrl[i] & FAN_CTRL_MODE_MANUAL) {
+ if ((err = sysfs_chmod_file(&pdev->dev.kobj,
+ f71805f_attr_pwm[i],
+ S_IRUGO | S_IWUSR))) {
+ dev_err(&pdev->dev, "chmod +w pwm%d failed\n",
+ i + 1);
+ goto exit_remove_files;
+ }
+ }
+ }
data->class_dev = hwmon_device_register(&pdev->dev);
if (IS_ERR(data->class_dev)) {
@@ -849,8 +1226,9 @@ static int __devinit f71805f_probe(struct platform_device *pdev)
exit_remove_files:
sysfs_remove_group(&pdev->dev.kobj, &f71805f_group);
- for (i = 0; i < 3; i++)
- sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_fan[i]);
+ for (i = 0; i < 4; i++)
+ sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_optin[i]);
+ sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_pwm_freq);
exit_free:
platform_set_drvdata(pdev, NULL);
kfree(data);
@@ -866,8 +1244,9 @@ static int __devexit f71805f_remove(struct platform_device *pdev)
platform_set_drvdata(pdev, NULL);
hwmon_device_unregister(data->class_dev);
sysfs_remove_group(&pdev->dev.kobj, &f71805f_group);
- for (i = 0; i < 3; i++)
- sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_fan[i]);
+ for (i = 0; i < 4; i++)
+ sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_optin[i]);
+ sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_pwm_freq);
kfree(data);
return 0;
@@ -882,7 +1261,8 @@ static struct platform_driver f71805f_driver = {
.remove = __devexit_p(f71805f_remove),
};
-static int __init f71805f_device_add(unsigned short address)
+static int __init f71805f_device_add(unsigned short address,
+ const struct f71805f_sio_data *sio_data)
{
struct resource res = {
.start = address,
@@ -906,26 +1286,45 @@ static int __init f71805f_device_add(unsigned short address)
goto exit_device_put;
}
+ pdev->dev.platform_data = kmalloc(sizeof(struct f71805f_sio_data),
+ GFP_KERNEL);
+ if (!pdev->dev.platform_data) {
+ err = -ENOMEM;
+ printk(KERN_ERR DRVNAME ": Platform data allocation failed\n");
+ goto exit_device_put;
+ }
+ memcpy(pdev->dev.platform_data, sio_data,
+ sizeof(struct f71805f_sio_data));
+
err = platform_device_add(pdev);
if (err) {
printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
err);
- goto exit_device_put;
+ goto exit_kfree_data;
}
return 0;
+exit_kfree_data:
+ kfree(pdev->dev.platform_data);
+ pdev->dev.platform_data = NULL;
exit_device_put:
platform_device_put(pdev);
exit:
return err;
}
-static int __init f71805f_find(int sioaddr, unsigned short *address)
+static int __init f71805f_find(int sioaddr, unsigned short *address,
+ struct f71805f_sio_data *sio_data)
{
int err = -ENODEV;
u16 devid;
+ static const char *names[] = {
+ "F71805F/FG",
+ "F71872F/FG",
+ };
+
superio_enter(sioaddr);
devid = superio_inw(sioaddr, SIO_REG_MANID);
@@ -933,7 +1332,15 @@ static int __init f71805f_find(int sioaddr, unsigned short *address)
goto exit;
devid = superio_inw(sioaddr, SIO_REG_DEVID);
- if (devid != SIO_F71805F_ID) {
+ switch (devid) {
+ case SIO_F71805F_ID:
+ sio_data->kind = f71805f;
+ break;
+ case SIO_F71872F_ID:
+ sio_data->kind = f71872f;
+ sio_data->fnsel1 = superio_inb(sioaddr, SIO_REG_FNSEL1);
+ break;
+ default:
printk(KERN_INFO DRVNAME ": Unsupported Fintek device, "
"skipping\n");
goto exit;
@@ -952,10 +1359,12 @@ static int __init f71805f_find(int sioaddr, unsigned short *address)
"skipping\n");
goto exit;
}
+ *address &= ~(REGION_LENGTH - 1); /* Ignore 3 LSB */
err = 0;
- printk(KERN_INFO DRVNAME ": Found F71805F chip at %#x, revision %u\n",
- *address, superio_inb(sioaddr, SIO_REG_DEVREV));
+ printk(KERN_INFO DRVNAME ": Found %s chip at %#x, revision %u\n",
+ names[sio_data->kind], *address,
+ superio_inb(sioaddr, SIO_REG_DEVREV));
exit:
superio_exit(sioaddr);
@@ -966,9 +1375,10 @@ static int __init f71805f_init(void)
{
int err;
unsigned short address;
+ struct f71805f_sio_data sio_data;
- if (f71805f_find(0x2e, &address)
- && f71805f_find(0x4e, &address))
+ if (f71805f_find(0x2e, &address, &sio_data)
+ && f71805f_find(0x4e, &address, &sio_data))
return -ENODEV;
err = platform_driver_register(&f71805f_driver);
@@ -976,7 +1386,7 @@ static int __init f71805f_init(void)
goto exit;
/* Sets global pdev as a side effect */
- err = f71805f_device_add(address);
+ err = f71805f_device_add(address, &sio_data);
if (err)
goto exit_driver;
@@ -990,13 +1400,16 @@ exit:
static void __exit f71805f_exit(void)
{
+ kfree(pdev->dev.platform_data);
+ pdev->dev.platform_data = NULL;
platform_device_unregister(pdev);
+
platform_driver_unregister(&f71805f_driver);
}
MODULE_AUTHOR("Jean Delvare <khali@linux-fr>");
MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("F71805F hardware monitoring driver");
+MODULE_DESCRIPTION("F71805F/F71872F hardware monitoring driver");
module_init(f71805f_init);
module_exit(f71805f_exit);
diff --git a/drivers/hwmon/hdaps.c b/drivers/hwmon/hdaps.c
index e8ef62b83d6b..bf759ea545ac 100644
--- a/drivers/hwmon/hdaps.c
+++ b/drivers/hwmon/hdaps.c
@@ -478,74 +478,64 @@ static struct attribute_group hdaps_attribute_group = {
/* Module stuff */
/* hdaps_dmi_match - found a match. return one, short-circuiting the hunt. */
-static int hdaps_dmi_match(struct dmi_system_id *id)
+static int __init 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)
+static int __init 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, \
+#define HDAPS_DMI_MATCH_NORMAL(vendor, model) { \
+ .ident = vendor " " model, \
.callback = hdaps_dmi_match, \
.matches = { \
- DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), \
+ DMI_MATCH(DMI_BOARD_VENDOR, vendor), \
DMI_MATCH(DMI_PRODUCT_VERSION, model) \
} \
}
-#define HDAPS_DMI_MATCH_INVERT(model) { \
- .ident = "IBM " model, \
+#define HDAPS_DMI_MATCH_INVERT(vendor, model) { \
+ .ident = vendor " " model, \
.callback = hdaps_dmi_match_invert, \
.matches = { \
- DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), \
+ DMI_MATCH(DMI_BOARD_VENDOR, vendor), \
DMI_MATCH(DMI_PRODUCT_VERSION, model) \
} \
}
-#define HDAPS_DMI_MATCH_LENOVO(model) { \
- .ident = "Lenovo " model, \
- .callback = hdaps_dmi_match_invert, \
- .matches = { \
- DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), \
- DMI_MATCH(DMI_PRODUCT_VERSION, model) \
- } \
-}
+/* Note that HDAPS_DMI_MATCH_NORMAL("ThinkPad T42") would match
+ "ThinkPad T42p", so the order of the entries matters.
+ If your ThinkPad is not recognized, please update to latest
+ BIOS. This is especially the case for some R52 ThinkPads. */
+static struct dmi_system_id __initdata hdaps_whitelist[] = {
+ HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad R50p"),
+ HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R50"),
+ HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R51"),
+ HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R52"),
+ HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T41p"),
+ HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T41"),
+ HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T42p"),
+ HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T42"),
+ HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T43"),
+ HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T60"),
+ HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad X40"),
+ HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad X41"),
+ HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X60"),
+ HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad Z60m"),
+ { .ident = NULL }
+};
static int __init hdaps_init(void)
{
int ret;
- /* Note that HDAPS_DMI_MATCH_NORMAL("ThinkPad T42") would match
- "ThinkPad T42p", so the order of the entries matters */
- struct dmi_system_id hdaps_whitelist[] = {
- HDAPS_DMI_MATCH_NORMAL("ThinkPad H"),
- 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_NORMAL("ThinkPad H"), /* R52 (1846AQG) */
- 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_LENOVO("ThinkPad T60p"),
- HDAPS_DMI_MATCH_LENOVO("ThinkPad T60"),
- HDAPS_DMI_MATCH_NORMAL("ThinkPad X40"),
- HDAPS_DMI_MATCH_NORMAL("ThinkPad X41"),
- HDAPS_DMI_MATCH_LENOVO("ThinkPad X60"),
- HDAPS_DMI_MATCH_NORMAL("ThinkPad Z60m"),
- { .ident = NULL }
- };
-
if (!dmi_check_system(hdaps_whitelist)) {
printk(KERN_WARNING "hdaps: supported laptop not found!\n");
ret = -ENODEV;
diff --git a/drivers/hwmon/hwmon-vid.c b/drivers/hwmon/hwmon-vid.c
index 9d67320e6840..31c42002708f 100644
--- a/drivers/hwmon/hwmon-vid.c
+++ b/drivers/hwmon/hwmon-vid.c
@@ -1,7 +1,7 @@
/*
hwmon-vid.c - VID/VRM/VRD voltage conversions
- Copyright (c) 2004 Rudolf Marek <r.marek@sh.cvut.cz>
+ Copyright (c) 2004 Rudolf Marek <r.marek@assembler.cz>
Partly imported from i2c-vid.h of the lm_sensors project
Copyright (c) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com>
@@ -232,7 +232,7 @@ u8 vid_which_vrm(void)
EXPORT_SYMBOL(vid_from_reg);
EXPORT_SYMBOL(vid_which_vrm);
-MODULE_AUTHOR("Rudolf Marek <r.marek@sh.cvut.cz>");
+MODULE_AUTHOR("Rudolf Marek <r.marek@assembler.cz>");
MODULE_DESCRIPTION("hwmon-vid driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 323ef06719c1..1ed8b7e2c35d 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -3,7 +3,7 @@
monitoring.
Supports: IT8705F Super I/O chip w/LPC interface
- IT8712F Super I/O chip w/LPC interface & SMBus
+ IT8712F Super I/O chip w/LPC interface
IT8716F Super I/O chip w/LPC interface
IT8718F Super I/O chip w/LPC interface
Sis950 A clone of the IT8705F
@@ -41,12 +41,8 @@
#include <asm/io.h>
-/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x2d, I2C_CLIENT_END };
static unsigned short isa_address;
-
-/* Insmod parameters */
-I2C_CLIENT_INSMOD_4(it87, it8712, it8716, it8718);
+enum chips { it87, it8712, it8716, it8718 };
#define REG 0x2e /* The register to read/write */
#define DEV 0x07 /* Register: Logical device select */
@@ -162,8 +158,6 @@ static u8 vid_value;
#define IT87_REG_TEMP_HIGH(nr) (0x40 + (nr) * 2)
#define IT87_REG_TEMP_LOW(nr) (0x41 + (nr) * 2)
-#define IT87_REG_I2C_ADDR 0x48
-
#define IT87_REG_VIN_ENABLE 0x50
#define IT87_REG_TEMP_ENABLE 0x51
@@ -242,33 +236,22 @@ struct it87_data {
};
-static int it87_attach_adapter(struct i2c_adapter *adapter);
-static int it87_isa_attach_adapter(struct i2c_adapter *adapter);
-static int it87_detect(struct i2c_adapter *adapter, int address, int kind);
+static int it87_detect(struct i2c_adapter *adapter);
static int it87_detach_client(struct i2c_client *client);
static int it87_read_value(struct i2c_client *client, u8 reg);
-static int it87_write_value(struct i2c_client *client, u8 reg, u8 value);
+static void it87_write_value(struct i2c_client *client, u8 reg, u8 value);
static struct it87_data *it87_update_device(struct device *dev);
static int it87_check_pwm(struct i2c_client *client);
static void it87_init_client(struct i2c_client *client, struct it87_data *data);
-static struct i2c_driver it87_driver = {
- .driver = {
- .name = "it87",
- },
- .id = I2C_DRIVERID_IT87,
- .attach_adapter = it87_attach_adapter,
- .detach_client = it87_detach_client,
-};
-
static struct i2c_driver it87_isa_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "it87-isa",
},
- .attach_adapter = it87_isa_attach_adapter,
+ .attach_adapter = it87_detect,
.detach_client = it87_detach_client,
};
@@ -850,22 +833,6 @@ static const struct attribute_group it87_group_opt = {
.attrs = it87_attributes_opt,
};
-/* This function is called when:
- * it87_driver is inserted (when this module is loaded), for each
- available adapter
- * when a new adapter is inserted (and it87_driver is still present) */
-static int it87_attach_adapter(struct i2c_adapter *adapter)
-{
- if (!(adapter->class & I2C_CLASS_HWMON))
- return 0;
- return i2c_probe(adapter, &addr_data, it87_detect);
-}
-
-static int it87_isa_attach_adapter(struct i2c_adapter *adapter)
-{
- return it87_detect(adapter, isa_address, -1);
-}
-
/* SuperIO detection - will change isa_address if a chip is found */
static int __init it87_find(unsigned short *address)
{
@@ -916,29 +883,20 @@ exit:
}
/* This function is called by i2c_probe */
-static int it87_detect(struct i2c_adapter *adapter, int address, int kind)
+static int it87_detect(struct i2c_adapter *adapter)
{
- int i;
struct i2c_client *new_client;
struct it87_data *data;
int err = 0;
- const char *name = "";
- int is_isa = i2c_is_isa_adapter(adapter);
+ const char *name;
int enable_pwm_interface;
- if (!is_isa &&
- !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- goto ERROR0;
-
/* Reserve the ISA region */
- if (is_isa)
- if (!request_region(address, IT87_EXTENT,
- it87_isa_driver.driver.name))
- goto ERROR0;
-
- /* For now, we presume we have a valid client. We create the
- client structure, even though we cannot fill it completely yet.
- But it allows us to access it87_{read,write}_value. */
+ if (!request_region(isa_address, IT87_EXTENT,
+ it87_isa_driver.driver.name)){
+ err = -EBUSY;
+ goto ERROR0;
+ }
if (!(data = kzalloc(sizeof(struct it87_data), GFP_KERNEL))) {
err = -ENOMEM;
@@ -946,80 +904,46 @@ static int it87_detect(struct i2c_adapter *adapter, int address, int kind)
}
new_client = &data->client;
- if (is_isa)
- mutex_init(&data->lock);
+ mutex_init(&data->lock);
i2c_set_clientdata(new_client, data);
- new_client->addr = address;
+ new_client->addr = isa_address;
new_client->adapter = adapter;
- new_client->driver = is_isa ? &it87_isa_driver : &it87_driver;
- new_client->flags = 0;
+ new_client->driver = &it87_isa_driver;
/* Now, we do the remaining detection. */
-
- if (kind < 0) {
- if ((it87_read_value(new_client, IT87_REG_CONFIG) & 0x80)
- || (!is_isa
- && it87_read_value(new_client, IT87_REG_I2C_ADDR) != address)) {
- err = -ENODEV;
- goto ERROR2;
- }
+ if ((it87_read_value(new_client, IT87_REG_CONFIG) & 0x80)
+ || it87_read_value(new_client, IT87_REG_CHIPID) != 0x90) {
+ err = -ENODEV;
+ goto ERROR2;
}
/* Determine the chip type. */
- if (kind <= 0) {
- i = it87_read_value(new_client, IT87_REG_CHIPID);
- if (i == 0x90) {
- kind = it87;
- if (is_isa) {
- switch (chip_type) {
- case IT8712F_DEVID:
- kind = it8712;
- break;
- case IT8716F_DEVID:
- kind = it8716;
- break;
- case IT8718F_DEVID:
- kind = it8718;
- break;
- }
- }
- }
- else {
- if (kind == 0)
- dev_info(&adapter->dev,
- "Ignoring 'force' parameter for unknown chip at "
- "adapter %d, address 0x%02x\n",
- i2c_adapter_id(adapter), address);
- err = -ENODEV;
- goto ERROR2;
- }
- }
-
- if (kind == it87) {
- name = "it87";
- } else if (kind == it8712) {
+ switch (chip_type) {
+ case IT8712F_DEVID:
+ data->type = it8712;
name = "it8712";
- } else if (kind == it8716) {
+ break;
+ case IT8716F_DEVID:
+ data->type = it8716;
name = "it8716";
- } else if (kind == it8718) {
+ break;
+ case IT8718F_DEVID:
+ data->type = it8718;
name = "it8718";
+ break;
+ default:
+ data->type = it87;
+ name = "it87";
}
/* Fill in the remaining client fields and put it into the global list */
strlcpy(new_client->name, name, I2C_NAME_SIZE);
- data->type = kind;
- data->valid = 0;
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client)))
goto ERROR2;
- if (!is_isa)
- dev_info(&new_client->dev, "The I2C interface to IT87xxF "
- "hardware monitoring chips is deprecated. Please "
- "report if you still rely on it.\n");
-
/* Check PWM configuration */
enable_pwm_interface = it87_check_pwm(new_client);
@@ -1129,8 +1053,7 @@ ERROR3:
ERROR2:
kfree(data);
ERROR1:
- if (is_isa)
- release_region(address, IT87_EXTENT);
+ release_region(isa_address, IT87_EXTENT);
ERROR0:
return err;
}
@@ -1147,50 +1070,39 @@ static int it87_detach_client(struct i2c_client *client)
if ((err = i2c_detach_client(client)))
return err;
- if(i2c_is_isa_client(client))
- release_region(client->addr, IT87_EXTENT);
+ release_region(client->addr, IT87_EXTENT);
kfree(data);
return 0;
}
-/* The SMBus locks itself, but ISA access must be locked explicitly!
- We don't want to lock the whole ISA bus, so we lock each client
- separately.
+/* ISA access must be locked explicitly!
We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks,
would slow down the IT87 access and should not be necessary. */
static int it87_read_value(struct i2c_client *client, u8 reg)
{
struct it87_data *data = i2c_get_clientdata(client);
-
int res;
- if (i2c_is_isa_client(client)) {
- mutex_lock(&data->lock);
- outb_p(reg, client->addr + IT87_ADDR_REG_OFFSET);
- res = inb_p(client->addr + IT87_DATA_REG_OFFSET);
- mutex_unlock(&data->lock);
- return res;
- } else
- return i2c_smbus_read_byte_data(client, reg);
+
+ mutex_lock(&data->lock);
+ outb_p(reg, client->addr + IT87_ADDR_REG_OFFSET);
+ res = inb_p(client->addr + IT87_DATA_REG_OFFSET);
+ mutex_unlock(&data->lock);
+
+ return res;
}
-/* The SMBus locks itself, but ISA access muse be locked explicitly!
- We don't want to lock the whole ISA bus, so we lock each client
- separately.
+/* ISA access must be locked explicitly!
We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks,
would slow down the IT87 access and should not be necessary. */
-static int it87_write_value(struct i2c_client *client, u8 reg, u8 value)
+static void it87_write_value(struct i2c_client *client, u8 reg, u8 value)
{
struct it87_data *data = i2c_get_clientdata(client);
- if (i2c_is_isa_client(client)) {
- mutex_lock(&data->lock);
- outb_p(reg, client->addr + IT87_ADDR_REG_OFFSET);
- outb_p(value, client->addr + IT87_DATA_REG_OFFSET);
- mutex_unlock(&data->lock);
- return 0;
- } else
- return i2c_smbus_write_byte_data(client, reg, value);
+ mutex_lock(&data->lock);
+ outb_p(reg, client->addr + IT87_ADDR_REG_OFFSET);
+ outb_p(value, client->addr + IT87_DATA_REG_OFFSET);
+ mutex_unlock(&data->lock);
}
/* Return 1 if and only if the PWM interface is safe to use */
@@ -1426,26 +1338,14 @@ static int __init sm_it87_init(void)
{
int res;
- res = i2c_add_driver(&it87_driver);
- if (res)
+ if ((res = it87_find(&isa_address)))
return res;
-
- if (!it87_find(&isa_address)) {
- res = i2c_isa_add_driver(&it87_isa_driver);
- if (res) {
- i2c_del_driver(&it87_driver);
- return res;
- }
- }
-
- return 0;
+ return i2c_isa_add_driver(&it87_isa_driver);
}
static void __exit sm_it87_exit(void)
{
- if (isa_address)
- i2c_isa_del_driver(&it87_isa_driver);
- i2c_del_driver(&it87_driver);
+ i2c_isa_del_driver(&it87_isa_driver);
}
diff --git a/drivers/hwmon/k8temp.c b/drivers/hwmon/k8temp.c
index f58b64ed09e3..5d8d0ca08fa9 100644
--- a/drivers/hwmon/k8temp.c
+++ b/drivers/hwmon/k8temp.c
@@ -1,7 +1,7 @@
/*
* k8temp.c - Linux kernel module for hardware monitoring
*
- * Copyright (C) 2006 Rudolf Marek <r.marek@sh.cvut.cz>
+ * Copyright (C) 2006 Rudolf Marek <r.marek@assembler.cz>
*
* Inspired from the w83785 and amd756 drivers.
*
@@ -286,7 +286,7 @@ static void __exit k8temp_exit(void)
pci_unregister_driver(&k8temp_driver);
}
-MODULE_AUTHOR("Rudolf Marek <r.marek@sh.cvut.cz>");
+MODULE_AUTHOR("Rudolf Marek <r.marek@assembler.cz>");
MODULE_DESCRIPTION("AMD K8 core temperature monitor");
MODULE_LICENSE("GPL");
diff --git a/drivers/hwmon/pc87360.c b/drivers/hwmon/pc87360.c
index 3b8b81984ad4..c8a21be09d87 100644
--- a/drivers/hwmon/pc87360.c
+++ b/drivers/hwmon/pc87360.c
@@ -1000,7 +1000,7 @@ static int pc87360_detect(struct i2c_adapter *adapter)
(i&0x02) ? "external" : "internal");
data->vid_conf = confreg[3];
- data->vrm = 90;
+ data->vrm = vid_which_vrm();
}
/* Fan clock dividers may be needed before any data is read */
diff --git a/drivers/hwmon/pc87427.c b/drivers/hwmon/pc87427.c
new file mode 100644
index 000000000000..affa21a5ccfd
--- /dev/null
+++ b/drivers/hwmon/pc87427.c
@@ -0,0 +1,627 @@
+/*
+ * pc87427.c - hardware monitoring driver for the
+ * National Semiconductor PC87427 Super-I/O chip
+ * Copyright (C) 2006 Jean Delvare <khali@linux-fr.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.
+ *
+ * Supports the following chips:
+ *
+ * Chip #vin #fan #pwm #temp devid
+ * PC87427 - 8 - - 0xF2
+ *
+ * This driver assumes that no more than one chip is present.
+ * Only fan inputs are supported so far, although the chip can do much more.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/platform_device.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/sysfs.h>
+#include <asm/io.h>
+
+static struct platform_device *pdev;
+
+#define DRVNAME "pc87427"
+
+/* The lock mutex protects both the I/O accesses (needed because the
+ device is using banked registers) and the register cache (needed to keep
+ the data in the registers and the cache in sync at any time). */
+struct pc87427_data {
+ struct class_device *class_dev;
+ struct mutex lock;
+ int address[2];
+ const char *name;
+
+ unsigned long last_updated; /* in jiffies */
+ u8 fan_enabled; /* bit vector */
+ u16 fan[8]; /* register values */
+ u16 fan_min[8]; /* register values */
+ u8 fan_status[8]; /* register values */
+};
+
+/*
+ * Super-I/O registers and operations
+ */
+
+#define SIOREG_LDSEL 0x07 /* Logical device select */
+#define SIOREG_DEVID 0x20 /* Device ID */
+#define SIOREG_ACT 0x30 /* Device activation */
+#define SIOREG_MAP 0x50 /* I/O or memory mapping */
+#define SIOREG_IOBASE 0x60 /* I/O base address */
+
+static const u8 logdev[2] = { 0x09, 0x14 };
+static const char *logdev_str[2] = { DRVNAME " FMC", DRVNAME " HMC" };
+#define LD_FAN 0
+#define LD_IN 1
+#define LD_TEMP 1
+
+static inline void superio_outb(int sioaddr, int reg, int val)
+{
+ outb(reg, sioaddr);
+ outb(val, sioaddr + 1);
+}
+
+static inline int superio_inb(int sioaddr, int reg)
+{
+ outb(reg, sioaddr);
+ return inb(sioaddr + 1);
+}
+
+static inline void superio_exit(int sioaddr)
+{
+ outb(0x02, sioaddr);
+ outb(0x02, sioaddr + 1);
+}
+
+/*
+ * Logical devices
+ */
+
+#define REGION_LENGTH 32
+#define PC87427_REG_BANK 0x0f
+#define BANK_FM(nr) (nr)
+#define BANK_FT(nr) (0x08 + (nr))
+#define BANK_FC(nr) (0x10 + (nr) * 2)
+
+/*
+ * I/O access functions
+ */
+
+/* ldi is the logical device index */
+static inline int pc87427_read8(struct pc87427_data *data, u8 ldi, u8 reg)
+{
+ return inb(data->address[ldi] + reg);
+}
+
+/* Must be called with data->lock held, except during init */
+static inline int pc87427_read8_bank(struct pc87427_data *data, u8 ldi,
+ u8 bank, u8 reg)
+{
+ outb(bank, data->address[ldi] + PC87427_REG_BANK);
+ return inb(data->address[ldi] + reg);
+}
+
+/* Must be called with data->lock held, except during init */
+static inline void pc87427_write8_bank(struct pc87427_data *data, u8 ldi,
+ u8 bank, u8 reg, u8 value)
+{
+ outb(bank, data->address[ldi] + PC87427_REG_BANK);
+ outb(value, data->address[ldi] + reg);
+}
+
+/*
+ * Fan registers and conversions
+ */
+
+/* fan data registers are 16-bit wide */
+#define PC87427_REG_FAN 0x12
+#define PC87427_REG_FAN_MIN 0x14
+#define PC87427_REG_FAN_STATUS 0x10
+
+#define FAN_STATUS_STALL (1 << 3)
+#define FAN_STATUS_LOSPD (1 << 1)
+#define FAN_STATUS_MONEN (1 << 0)
+
+/* Dedicated function to read all registers related to a given fan input.
+ This saves us quite a few locks and bank selections.
+ Must be called with data->lock held.
+ nr is from 0 to 7 */
+static void pc87427_readall_fan(struct pc87427_data *data, u8 nr)
+{
+ int iobase = data->address[LD_FAN];
+
+ outb(BANK_FM(nr), iobase + PC87427_REG_BANK);
+ data->fan[nr] = inw(iobase + PC87427_REG_FAN);
+ data->fan_min[nr] = inw(iobase + PC87427_REG_FAN_MIN);
+ data->fan_status[nr] = inb(iobase + PC87427_REG_FAN_STATUS);
+ /* Clear fan alarm bits */
+ outb(data->fan_status[nr], iobase + PC87427_REG_FAN_STATUS);
+}
+
+/* The 2 LSB of fan speed registers are used for something different.
+ The actual 2 LSB of the measurements are not available. */
+static inline unsigned long fan_from_reg(u16 reg)
+{
+ reg &= 0xfffc;
+ if (reg == 0x0000 || reg == 0xfffc)
+ return 0;
+ return 5400000UL / reg;
+}
+
+/* The 2 LSB of the fan speed limit registers are not significant. */
+static inline u16 fan_to_reg(unsigned long val)
+{
+ if (val < 83UL)
+ return 0xffff;
+ if (val >= 1350000UL)
+ return 0x0004;
+ return ((1350000UL + val / 2) / val) << 2;
+}
+
+/*
+ * Data interface
+ */
+
+static struct pc87427_data *pc87427_update_device(struct device *dev)
+{
+ struct pc87427_data *data = dev_get_drvdata(dev);
+ int i;
+
+ mutex_lock(&data->lock);
+ if (!time_after(jiffies, data->last_updated + HZ)
+ && data->last_updated)
+ goto done;
+
+ /* Fans */
+ for (i = 0; i < 8; i++) {
+ if (!(data->fan_enabled & (1 << i)))
+ continue;
+ pc87427_readall_fan(data, i);
+ }
+ data->last_updated = jiffies;
+
+done:
+ mutex_unlock(&data->lock);
+ return data;
+}
+
+static ssize_t show_fan_input(struct device *dev, struct device_attribute
+ *devattr, char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct pc87427_data *data = pc87427_update_device(dev);
+ int nr = attr->index;
+
+ return sprintf(buf, "%lu\n", fan_from_reg(data->fan[nr]));
+}
+
+static ssize_t show_fan_min(struct device *dev, struct device_attribute
+ *devattr, char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct pc87427_data *data = pc87427_update_device(dev);
+ int nr = attr->index;
+
+ return sprintf(buf, "%lu\n", fan_from_reg(data->fan_min[nr]));
+}
+
+static ssize_t show_fan_alarm(struct device *dev, struct device_attribute
+ *devattr, char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct pc87427_data *data = pc87427_update_device(dev);
+ int nr = attr->index;
+
+ return sprintf(buf, "%d\n", !!(data->fan_status[nr]
+ & FAN_STATUS_LOSPD));
+}
+
+static ssize_t show_fan_fault(struct device *dev, struct device_attribute
+ *devattr, char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct pc87427_data *data = pc87427_update_device(dev);
+ int nr = attr->index;
+
+ return sprintf(buf, "%d\n", !!(data->fan_status[nr]
+ & FAN_STATUS_STALL));
+}
+
+static ssize_t set_fan_min(struct device *dev, struct device_attribute
+ *devattr, const char *buf, size_t count)
+{
+ struct pc87427_data *data = dev_get_drvdata(dev);
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ int nr = attr->index;
+ unsigned long val = simple_strtoul(buf, NULL, 10);
+ int iobase = data->address[LD_FAN];
+
+ mutex_lock(&data->lock);
+ outb(BANK_FM(nr), iobase + PC87427_REG_BANK);
+ /* The low speed limit registers are read-only while monitoring
+ is enabled, so we have to disable monitoring, then change the
+ limit, and finally enable monitoring again. */
+ outb(0, iobase + PC87427_REG_FAN_STATUS);
+ data->fan_min[nr] = fan_to_reg(val);
+ outw(data->fan_min[nr], iobase + PC87427_REG_FAN_MIN);
+ outb(FAN_STATUS_MONEN, iobase + PC87427_REG_FAN_STATUS);
+ mutex_unlock(&data->lock);
+
+ return count;
+}
+
+static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan_input, NULL, 0);
+static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan_input, NULL, 1);
+static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan_input, NULL, 2);
+static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_fan_input, NULL, 3);
+static SENSOR_DEVICE_ATTR(fan5_input, S_IRUGO, show_fan_input, NULL, 4);
+static SENSOR_DEVICE_ATTR(fan6_input, S_IRUGO, show_fan_input, NULL, 5);
+static SENSOR_DEVICE_ATTR(fan7_input, S_IRUGO, show_fan_input, NULL, 6);
+static SENSOR_DEVICE_ATTR(fan8_input, S_IRUGO, show_fan_input, NULL, 7);
+
+static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO,
+ show_fan_min, set_fan_min, 0);
+static SENSOR_DEVICE_ATTR(fan2_min, S_IWUSR | S_IRUGO,
+ show_fan_min, set_fan_min, 1);
+static SENSOR_DEVICE_ATTR(fan3_min, S_IWUSR | S_IRUGO,
+ show_fan_min, set_fan_min, 2);
+static SENSOR_DEVICE_ATTR(fan4_min, S_IWUSR | S_IRUGO,
+ show_fan_min, set_fan_min, 3);
+static SENSOR_DEVICE_ATTR(fan5_min, S_IWUSR | S_IRUGO,
+ show_fan_min, set_fan_min, 4);
+static SENSOR_DEVICE_ATTR(fan6_min, S_IWUSR | S_IRUGO,
+ show_fan_min, set_fan_min, 5);
+static SENSOR_DEVICE_ATTR(fan7_min, S_IWUSR | S_IRUGO,
+ show_fan_min, set_fan_min, 6);
+static SENSOR_DEVICE_ATTR(fan8_min, S_IWUSR | S_IRUGO,
+ show_fan_min, set_fan_min, 7);
+
+static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_fan_alarm, NULL, 0);
+static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_fan_alarm, NULL, 1);
+static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 2);
+static SENSOR_DEVICE_ATTR(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 3);
+static SENSOR_DEVICE_ATTR(fan5_alarm, S_IRUGO, show_fan_alarm, NULL, 4);
+static SENSOR_DEVICE_ATTR(fan6_alarm, S_IRUGO, show_fan_alarm, NULL, 5);
+static SENSOR_DEVICE_ATTR(fan7_alarm, S_IRUGO, show_fan_alarm, NULL, 6);
+static SENSOR_DEVICE_ATTR(fan8_alarm, S_IRUGO, show_fan_alarm, NULL, 7);
+
+static SENSOR_DEVICE_ATTR(fan1_fault, S_IRUGO, show_fan_fault, NULL, 0);
+static SENSOR_DEVICE_ATTR(fan2_fault, S_IRUGO, show_fan_fault, NULL, 1);
+static SENSOR_DEVICE_ATTR(fan3_fault, S_IRUGO, show_fan_fault, NULL, 2);
+static SENSOR_DEVICE_ATTR(fan4_fault, S_IRUGO, show_fan_fault, NULL, 3);
+static SENSOR_DEVICE_ATTR(fan5_fault, S_IRUGO, show_fan_fault, NULL, 4);
+static SENSOR_DEVICE_ATTR(fan6_fault, S_IRUGO, show_fan_fault, NULL, 5);
+static SENSOR_DEVICE_ATTR(fan7_fault, S_IRUGO, show_fan_fault, NULL, 6);
+static SENSOR_DEVICE_ATTR(fan8_fault, S_IRUGO, show_fan_fault, NULL, 7);
+
+static struct attribute *pc87427_attributes_fan[8][5] = {
+ {
+ &sensor_dev_attr_fan1_input.dev_attr.attr,
+ &sensor_dev_attr_fan1_min.dev_attr.attr,
+ &sensor_dev_attr_fan1_alarm.dev_attr.attr,
+ &sensor_dev_attr_fan1_fault.dev_attr.attr,
+ NULL
+ }, {
+ &sensor_dev_attr_fan2_input.dev_attr.attr,
+ &sensor_dev_attr_fan2_min.dev_attr.attr,
+ &sensor_dev_attr_fan2_alarm.dev_attr.attr,
+ &sensor_dev_attr_fan2_fault.dev_attr.attr,
+ NULL
+ }, {
+ &sensor_dev_attr_fan3_input.dev_attr.attr,
+ &sensor_dev_attr_fan3_min.dev_attr.attr,
+ &sensor_dev_attr_fan3_alarm.dev_attr.attr,
+ &sensor_dev_attr_fan3_fault.dev_attr.attr,
+ NULL
+ }, {
+ &sensor_dev_attr_fan4_input.dev_attr.attr,
+ &sensor_dev_attr_fan4_min.dev_attr.attr,
+ &sensor_dev_attr_fan4_alarm.dev_attr.attr,
+ &sensor_dev_attr_fan4_fault.dev_attr.attr,
+ NULL
+ }, {
+ &sensor_dev_attr_fan5_input.dev_attr.attr,
+ &sensor_dev_attr_fan5_min.dev_attr.attr,
+ &sensor_dev_attr_fan5_alarm.dev_attr.attr,
+ &sensor_dev_attr_fan5_fault.dev_attr.attr,
+ NULL
+ }, {
+ &sensor_dev_attr_fan6_input.dev_attr.attr,
+ &sensor_dev_attr_fan6_min.dev_attr.attr,
+ &sensor_dev_attr_fan6_alarm.dev_attr.attr,
+ &sensor_dev_attr_fan6_fault.dev_attr.attr,
+ NULL
+ }, {
+ &sensor_dev_attr_fan7_input.dev_attr.attr,
+ &sensor_dev_attr_fan7_min.dev_attr.attr,
+ &sensor_dev_attr_fan7_alarm.dev_attr.attr,
+ &sensor_dev_attr_fan7_fault.dev_attr.attr,
+ NULL
+ }, {
+ &sensor_dev_attr_fan8_input.dev_attr.attr,
+ &sensor_dev_attr_fan8_min.dev_attr.attr,
+ &sensor_dev_attr_fan8_alarm.dev_attr.attr,
+ &sensor_dev_attr_fan8_fault.dev_attr.attr,
+ NULL
+ }
+};
+
+static const struct attribute_group pc87427_group_fan[8] = {
+ { .attrs = pc87427_attributes_fan[0] },
+ { .attrs = pc87427_attributes_fan[1] },
+ { .attrs = pc87427_attributes_fan[2] },
+ { .attrs = pc87427_attributes_fan[3] },
+ { .attrs = pc87427_attributes_fan[4] },
+ { .attrs = pc87427_attributes_fan[5] },
+ { .attrs = pc87427_attributes_fan[6] },
+ { .attrs = pc87427_attributes_fan[7] },
+};
+
+static ssize_t show_name(struct device *dev, struct device_attribute
+ *devattr, char *buf)
+{
+ struct pc87427_data *data = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%s\n", data->name);
+}
+static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
+
+
+/*
+ * Device detection, attach and detach
+ */
+
+static void __devinit pc87427_init_device(struct device *dev)
+{
+ struct pc87427_data *data = dev_get_drvdata(dev);
+ int i;
+ u8 reg;
+
+ /* The FMC module should be ready */
+ reg = pc87427_read8(data, LD_FAN, PC87427_REG_BANK);
+ if (!(reg & 0x80))
+ dev_warn(dev, "FMC module not ready!\n");
+
+ /* Check which fans are enabled */
+ for (i = 0; i < 8; i++) {
+ reg = pc87427_read8_bank(data, LD_FAN, BANK_FM(i),
+ PC87427_REG_FAN_STATUS);
+ if (reg & FAN_STATUS_MONEN)
+ data->fan_enabled |= (1 << i);
+ }
+
+ if (!data->fan_enabled) {
+ dev_dbg(dev, "Enabling all fan inputs\n");
+ for (i = 0; i < 8; i++)
+ pc87427_write8_bank(data, LD_FAN, BANK_FM(i),
+ PC87427_REG_FAN_STATUS,
+ FAN_STATUS_MONEN);
+ data->fan_enabled = 0xff;
+ }
+}
+
+static int __devinit pc87427_probe(struct platform_device *pdev)
+{
+ struct pc87427_data *data;
+ struct resource *res;
+ int i, err;
+
+ if (!(data = kzalloc(sizeof(struct pc87427_data), GFP_KERNEL))) {
+ err = -ENOMEM;
+ printk(KERN_ERR DRVNAME ": Out of memory\n");
+ goto exit;
+ }
+
+ /* This will need to be revisited when we add support for
+ temperature and voltage monitoring. */
+ res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ data->address[0] = res->start;
+
+ mutex_init(&data->lock);
+ data->name = "pc87427";
+ platform_set_drvdata(pdev, data);
+ pc87427_init_device(&pdev->dev);
+
+ /* Register sysfs hooks */
+ if ((err = device_create_file(&pdev->dev, &dev_attr_name)))
+ goto exit_kfree;
+ for (i = 0; i < 8; i++) {
+ if (!(data->fan_enabled & (1 << i)))
+ continue;
+ if ((err = sysfs_create_group(&pdev->dev.kobj,
+ &pc87427_group_fan[i])))
+ goto exit_remove_files;
+ }
+
+ data->class_dev = hwmon_device_register(&pdev->dev);
+ if (IS_ERR(data->class_dev)) {
+ err = PTR_ERR(data->class_dev);
+ dev_err(&pdev->dev, "Class registration failed (%d)\n", err);
+ goto exit_remove_files;
+ }
+
+ return 0;
+
+exit_remove_files:
+ for (i = 0; i < 8; i++) {
+ if (!(data->fan_enabled & (1 << i)))
+ continue;
+ sysfs_remove_group(&pdev->dev.kobj, &pc87427_group_fan[i]);
+ }
+exit_kfree:
+ platform_set_drvdata(pdev, NULL);
+ kfree(data);
+exit:
+ return err;
+}
+
+static int __devexit pc87427_remove(struct platform_device *pdev)
+{
+ struct pc87427_data *data = platform_get_drvdata(pdev);
+ int i;
+
+ platform_set_drvdata(pdev, NULL);
+ hwmon_device_unregister(data->class_dev);
+ device_remove_file(&pdev->dev, &dev_attr_name);
+ for (i = 0; i < 8; i++) {
+ if (!(data->fan_enabled & (1 << i)))
+ continue;
+ sysfs_remove_group(&pdev->dev.kobj, &pc87427_group_fan[i]);
+ }
+ kfree(data);
+
+ return 0;
+}
+
+
+static struct platform_driver pc87427_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = DRVNAME,
+ },
+ .probe = pc87427_probe,
+ .remove = __devexit_p(pc87427_remove),
+};
+
+static int __init pc87427_device_add(unsigned short address)
+{
+ struct resource res = {
+ .start = address,
+ .end = address + REGION_LENGTH - 1,
+ .name = logdev_str[0],
+ .flags = IORESOURCE_IO,
+ };
+ int err;
+
+ pdev = platform_device_alloc(DRVNAME, address);
+ if (!pdev) {
+ err = -ENOMEM;
+ printk(KERN_ERR DRVNAME ": Device allocation failed\n");
+ goto exit;
+ }
+
+ err = platform_device_add_resources(pdev, &res, 1);
+ if (err) {
+ printk(KERN_ERR DRVNAME ": Device resource addition failed "
+ "(%d)\n", err);
+ goto exit_device_put;
+ }
+
+ err = platform_device_add(pdev);
+ if (err) {
+ printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
+ err);
+ goto exit_device_put;
+ }
+
+ return 0;
+
+exit_device_put:
+ platform_device_put(pdev);
+exit:
+ return err;
+}
+
+static int __init pc87427_find(int sioaddr, unsigned short *address)
+{
+ u16 val;
+ int i, err = 0;
+
+ /* Identify device */
+ val = superio_inb(sioaddr, SIOREG_DEVID);
+ if (val != 0xf2) { /* PC87427 */
+ err = -ENODEV;
+ goto exit;
+ }
+
+ for (i = 0; i < 2; i++) {
+ address[i] = 0;
+ /* Select logical device */
+ superio_outb(sioaddr, SIOREG_LDSEL, logdev[i]);
+
+ val = superio_inb(sioaddr, SIOREG_ACT);
+ if (!(val & 0x01)) {
+ printk(KERN_INFO DRVNAME ": Logical device 0x%02x "
+ "not activated\n", logdev[i]);
+ continue;
+ }
+
+ val = superio_inb(sioaddr, SIOREG_MAP);
+ if (val & 0x01) {
+ printk(KERN_WARNING DRVNAME ": Logical device 0x%02x "
+ "is memory-mapped, can't use\n", logdev[i]);
+ continue;
+ }
+
+ val = (superio_inb(sioaddr, SIOREG_IOBASE) << 8)
+ | superio_inb(sioaddr, SIOREG_IOBASE + 1);
+ if (!val) {
+ printk(KERN_INFO DRVNAME ": I/O base address not set "
+ "for logical device 0x%02x\n", logdev[i]);
+ continue;
+ }
+ address[i] = val;
+ }
+
+exit:
+ superio_exit(sioaddr);
+ return err;
+}
+
+static int __init pc87427_init(void)
+{
+ int err;
+ unsigned short address[2];
+
+ if (pc87427_find(0x2e, address)
+ && pc87427_find(0x4e, address))
+ return -ENODEV;
+
+ /* For now the driver only handles fans so we only care about the
+ first address. */
+ if (!address[0])
+ return -ENODEV;
+
+ err = platform_driver_register(&pc87427_driver);
+ if (err)
+ goto exit;
+
+ /* Sets global pdev as a side effect */
+ err = pc87427_device_add(address[0]);
+ if (err)
+ goto exit_driver;
+
+ return 0;
+
+exit_driver:
+ platform_driver_unregister(&pc87427_driver);
+exit:
+ return err;
+}
+
+static void __exit pc87427_exit(void)
+{
+ platform_device_unregister(pdev);
+ platform_driver_unregister(&pc87427_driver);
+}
+
+MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
+MODULE_DESCRIPTION("PC87427 hardware monitoring driver");
+MODULE_LICENSE("GPL");
+
+module_init(pc87427_init);
+module_exit(pc87427_exit);
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c
index 2257806d0102..212a1558c63b 100644
--- a/drivers/hwmon/w83627ehf.c
+++ b/drivers/hwmon/w83627ehf.c
@@ -3,7 +3,7 @@
the Winbond W83627EHF Super-I/O chip
Copyright (C) 2005 Jean Delvare <khali@linux-fr.org>
Copyright (C) 2006 Yuan Mu (Winbond),
- Rudolf Marek <r.marek@sh.cvut.cz>
+ Rudolf Marek <r.marek@assembler.cz>
David Hubbard <david.c.hubbard@gmail.com>
Shamelessly ripped from the w83627hf driver
diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c
index 4e108262576f..b0fa296740d1 100644
--- a/drivers/hwmon/w83792d.c
+++ b/drivers/hwmon/w83792d.c
@@ -3,7 +3,7 @@
monitoring
Copyright (C) 2004, 2005 Winbond Electronics Corp.
Chunhao Huang <DZShen@Winbond.com.tw>,
- Rudolf Marek <r.marek@sh.cvut.cz>
+ Rudolf Marek <r.marek@assembler.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
diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c
new file mode 100644
index 000000000000..c12ac5abc2bb
--- /dev/null
+++ b/drivers/hwmon/w83793.c
@@ -0,0 +1,1609 @@
+/*
+ w83793.c - Linux kernel driver for hardware monitoring
+ Copyright (C) 2006 Winbond Electronics Corp.
+ Yuan Mu
+ Rudolf Marek <r.marek@assembler.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 - version 2.
+
+ 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.
+*/
+
+/*
+ Supports following chips:
+
+ Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA
+ w83793 10 12 8 6 0x7b 0x5ca3 yes no
+*/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-vid.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+
+/* Addresses to scan */
+static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, I2C_CLIENT_END };
+
+/* Insmod parameters */
+I2C_CLIENT_INSMOD_1(w83793);
+I2C_CLIENT_MODULE_PARM(force_subclients, "List of subclient addresses: "
+ "{bus, clientaddr, subclientaddr1, subclientaddr2}");
+
+static int reset;
+module_param(reset, bool, 0);
+MODULE_PARM_DESC(reset, "Set to 1 to reset chip, not recommended");
+
+/*
+ Address 0x00, 0x0d, 0x0e, 0x0f in all three banks are reserved
+ as ID, Bank Select registers
+*/
+#define W83793_REG_BANKSEL 0x00
+#define W83793_REG_VENDORID 0x0d
+#define W83793_REG_CHIPID 0x0e
+#define W83793_REG_DEVICEID 0x0f
+
+#define W83793_REG_CONFIG 0x40
+#define W83793_REG_MFC 0x58
+#define W83793_REG_FANIN_CTRL 0x5c
+#define W83793_REG_FANIN_SEL 0x5d
+#define W83793_REG_I2C_ADDR 0x0b
+#define W83793_REG_I2C_SUBADDR 0x0c
+#define W83793_REG_VID_INA 0x05
+#define W83793_REG_VID_INB 0x06
+#define W83793_REG_VID_LATCHA 0x07
+#define W83793_REG_VID_LATCHB 0x08
+#define W83793_REG_VID_CTRL 0x59
+
+static u16 W83793_REG_TEMP_MODE[2] = { 0x5e, 0x5f };
+
+#define TEMP_READ 0
+#define TEMP_CRIT 1
+#define TEMP_CRIT_HYST 2
+#define TEMP_WARN 3
+#define TEMP_WARN_HYST 4
+/* only crit and crit_hyst affect real-time alarm status
+ current crit crit_hyst warn warn_hyst */
+static u16 W83793_REG_TEMP[][5] = {
+ {0x1c, 0x78, 0x79, 0x7a, 0x7b},
+ {0x1d, 0x7c, 0x7d, 0x7e, 0x7f},
+ {0x1e, 0x80, 0x81, 0x82, 0x83},
+ {0x1f, 0x84, 0x85, 0x86, 0x87},
+ {0x20, 0x88, 0x89, 0x8a, 0x8b},
+ {0x21, 0x8c, 0x8d, 0x8e, 0x8f},
+};
+
+#define W83793_REG_TEMP_LOW_BITS 0x22
+
+#define W83793_REG_BEEP(index) (0x53 + (index))
+#define W83793_REG_ALARM(index) (0x4b + (index))
+
+#define W83793_REG_CLR_CHASSIS 0x4a /* SMI MASK4 */
+#define W83793_REG_IRQ_CTRL 0x50
+#define W83793_REG_OVT_CTRL 0x51
+#define W83793_REG_OVT_BEEP 0x52
+
+#define IN_READ 0
+#define IN_MAX 1
+#define IN_LOW 2
+static const u16 W83793_REG_IN[][3] = {
+ /* Current, High, Low */
+ {0x10, 0x60, 0x61}, /* Vcore A */
+ {0x11, 0x62, 0x63}, /* Vcore B */
+ {0x12, 0x64, 0x65}, /* Vtt */
+ {0x14, 0x6a, 0x6b}, /* VSEN1 */
+ {0x15, 0x6c, 0x6d}, /* VSEN2 */
+ {0x16, 0x6e, 0x6f}, /* +3VSEN */
+ {0x17, 0x70, 0x71}, /* +12VSEN */
+ {0x18, 0x72, 0x73}, /* 5VDD */
+ {0x19, 0x74, 0x75}, /* 5VSB */
+ {0x1a, 0x76, 0x77}, /* VBAT */
+};
+
+/* Low Bits of Vcore A/B Vtt Read/High/Low */
+static const u16 W83793_REG_IN_LOW_BITS[] = { 0x1b, 0x68, 0x69 };
+static u8 scale_in[] = { 2, 2, 2, 16, 16, 16, 8, 24, 24, 16 };
+
+#define W83793_REG_FAN(index) (0x23 + 2 * (index)) /* High byte */
+#define W83793_REG_FAN_MIN(index) (0x90 + 2 * (index)) /* High byte */
+
+#define W83793_REG_PWM_DEFAULT 0xb2
+#define W83793_REG_PWM_ENABLE 0x207
+#define W83793_REG_PWM_UPTIME 0xc3 /* Unit in 0.1 second */
+#define W83793_REG_PWM_DOWNTIME 0xc4 /* Unit in 0.1 second */
+#define W83793_REG_TEMP_CRITICAL 0xc5
+
+#define PWM_DUTY 0
+#define PWM_START 1
+#define PWM_NONSTOP 2
+#define W83793_REG_PWM(index, nr) (((nr) == 0 ? 0xb3 : \
+ (nr) == 1 ? 0x220 : 0x218) + (index))
+
+/* bit field, fan1 is bit0, fan2 is bit1 ... */
+#define W83793_REG_TEMP_FAN_MAP(index) (0x201 + (index))
+#define W83793_REG_TEMP_TOL(index) (0x208 + (index))
+#define W83793_REG_TEMP_CRUISE(index) (0x210 + (index))
+#define W83793_REG_PWM_STOP_TIME(index) (0x228 + (index))
+#define W83793_REG_SF2_TEMP(index, nr) (0x230 + ((index) << 4) + (nr))
+#define W83793_REG_SF2_PWM(index, nr) (0x238 + ((index) << 4) + (nr))
+
+static inline unsigned long FAN_FROM_REG(u16 val)
+{
+ if ((val >= 0xfff) || (val == 0))
+ return 0;
+ return (1350000UL / val);
+}
+
+static inline u16 FAN_TO_REG(long rpm)
+{
+ if (rpm <= 0)
+ return 0x0fff;
+ return SENSORS_LIMIT((1350000 + (rpm >> 1)) / rpm, 1, 0xffe);
+}
+
+static inline unsigned long TIME_FROM_REG(u8 reg)
+{
+ return (reg * 100);
+}
+
+static inline u8 TIME_TO_REG(unsigned long val)
+{
+ return SENSORS_LIMIT((val + 50) / 100, 0, 0xff);
+}
+
+static inline long TEMP_FROM_REG(s8 reg)
+{
+ return (reg * 1000);
+}
+
+static inline s8 TEMP_TO_REG(long val, s8 min, s8 max)
+{
+ return SENSORS_LIMIT((val + (val < 0 ? -500 : 500)) / 1000, min, max);
+}
+
+struct w83793_data {
+ struct i2c_client client;
+ struct i2c_client *lm75[2];
+ struct class_device *class_dev;
+ struct mutex update_lock;
+ char valid; /* !=0 if following fields are valid */
+ unsigned long last_updated; /* In jiffies */
+ unsigned long last_nonvolatile; /* In jiffies, last time we update the
+ nonvolatile registers */
+
+ u8 bank;
+ u8 vrm;
+ u8 vid[2];
+ u8 in[10][3]; /* Register value, read/high/low */
+ u8 in_low_bits[3]; /* Additional resolution for VCore A/B Vtt */
+
+ u16 has_fan; /* Only fan1- fan5 has own pins */
+ u16 fan[12]; /* Register value combine */
+ u16 fan_min[12]; /* Register value combine */
+
+ s8 temp[6][5]; /* current, crit, crit_hyst,warn, warn_hyst */
+ u8 temp_low_bits; /* Additional resolution TD1-TD4 */
+ u8 temp_mode[2]; /* byte 0: Temp D1-D4 mode each has 2 bits
+ byte 1: Temp R1,R2 mode, each has 1 bit */
+ u8 temp_critical; /* If reached all fan will be at full speed */
+ u8 temp_fan_map[6]; /* Temp controls which pwm fan, bit field */
+
+ u8 has_pwm;
+ u8 pwm_enable; /* Register value, each Temp has 1 bit */
+ u8 pwm_uptime; /* Register value */
+ u8 pwm_downtime; /* Register value */
+ u8 pwm_default; /* All fan default pwm, next poweron valid */
+ u8 pwm[8][3]; /* Register value */
+ u8 pwm_stop_time[8];
+ u8 temp_cruise[6];
+
+ u8 alarms[5]; /* realtime status registers */
+ u8 beeps[5];
+ u8 beep_enable;
+ u8 tolerance[3]; /* Temp tolerance(Smart Fan I/II) */
+ u8 sf2_pwm[6][7]; /* Smart FanII: Fan duty cycle */
+ u8 sf2_temp[6][7]; /* Smart FanII: Temp level point */
+};
+
+static u8 w83793_read_value(struct i2c_client *client, u16 reg);
+static int w83793_write_value(struct i2c_client *client, u16 reg, u8 value);
+static int w83793_attach_adapter(struct i2c_adapter *adapter);
+static int w83793_detect(struct i2c_adapter *adapter, int address, int kind);
+static int w83793_detach_client(struct i2c_client *client);
+static void w83793_init_client(struct i2c_client *client);
+static void w83793_update_nonvolatile(struct device *dev);
+static struct w83793_data *w83793_update_device(struct device *dev);
+
+static struct i2c_driver w83793_driver = {
+ .driver = {
+ .name = "w83793",
+ },
+ .attach_adapter = w83793_attach_adapter,
+ .detach_client = w83793_detach_client,
+};
+
+static ssize_t
+show_vrm(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct w83793_data *data = i2c_get_clientdata(client);
+
+ return sprintf(buf, "%d\n", data->vrm);
+}
+
+static ssize_t
+show_vid(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct w83793_data *data = w83793_update_device(dev);
+ struct sensor_device_attribute_2 *sensor_attr =
+ to_sensor_dev_attr_2(attr);
+ int index = sensor_attr->index;
+
+ return sprintf(buf, "%d\n", vid_from_reg(data->vid[index], data->vrm));
+}
+
+static ssize_t
+store_vrm(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct w83793_data *data = i2c_get_clientdata(client);
+
+ data->vrm = simple_strtoul(buf, NULL, 10);
+ return count;
+}
+
+#define ALARM_STATUS 0
+#define BEEP_ENABLE 1
+static ssize_t
+show_alarm_beep(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct w83793_data *data = w83793_update_device(dev);
+ struct sensor_device_attribute_2 *sensor_attr =
+ to_sensor_dev_attr_2(attr);
+ int nr = sensor_attr->nr;
+ int index = sensor_attr->index >> 3;
+ int bit = sensor_attr->index & 0x07;
+ u8 val;
+
+ if (ALARM_STATUS == nr) {
+ val = (data->alarms[index] >> (bit)) & 1;
+ } else { /* BEEP_ENABLE */
+ val = (data->beeps[index] >> (bit)) & 1;
+ }
+
+ return sprintf(buf, "%u\n", val);
+}
+
+static ssize_t
+store_beep(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct w83793_data *data = i2c_get_clientdata(client);
+ struct sensor_device_attribute_2 *sensor_attr =
+ to_sensor_dev_attr_2(attr);
+ int index = sensor_attr->index >> 3;
+ int shift = sensor_attr->index & 0x07;
+ u8 beep_bit = 1 << shift;
+ u8 val;
+
+ val = simple_strtoul(buf, NULL, 10);
+ if (val != 0 && val != 1)
+ return -EINVAL;
+
+ mutex_lock(&data->update_lock);
+ data->beeps[index] = w83793_read_value(client, W83793_REG_BEEP(index));
+ data->beeps[index] &= ~beep_bit;
+ data->beeps[index] |= val << shift;
+ w83793_write_value(client, W83793_REG_BEEP(index), data->beeps[index]);
+ mutex_unlock(&data->update_lock);
+
+ return count;
+}
+
+static ssize_t
+show_beep_enable(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct w83793_data *data = w83793_update_device(dev);
+ return sprintf(buf, "%u\n", (data->beep_enable >> 1) & 0x01);
+}
+
+static ssize_t
+store_beep_enable(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct w83793_data *data = i2c_get_clientdata(client);
+ u8 val = simple_strtoul(buf, NULL, 10);
+
+ if (val != 0 && val != 1)
+ return -EINVAL;
+
+ mutex_lock(&data->update_lock);
+ data->beep_enable = w83793_read_value(client, W83793_REG_OVT_BEEP)
+ & 0xfd;
+ data->beep_enable |= val << 1;
+ w83793_write_value(client, W83793_REG_OVT_BEEP, data->beep_enable);
+ mutex_unlock(&data->update_lock);
+
+ return count;
+}
+
+/* Write any value to clear chassis alarm */
+static ssize_t
+store_chassis_clear(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct w83793_data *data = i2c_get_clientdata(client);
+ u8 val;
+
+ mutex_lock(&data->update_lock);
+ val = w83793_read_value(client, W83793_REG_CLR_CHASSIS);
+ val |= 0x80;
+ w83793_write_value(client, W83793_REG_CLR_CHASSIS, val);
+ mutex_unlock(&data->update_lock);
+ return count;
+}
+
+#define FAN_INPUT 0
+#define FAN_MIN 1
+static ssize_t
+show_fan(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct sensor_device_attribute_2 *sensor_attr =
+ to_sensor_dev_attr_2(attr);
+ int nr = sensor_attr->nr;
+ int index = sensor_attr->index;
+ struct w83793_data *data = w83793_update_device(dev);
+ u16 val;
+
+ if (FAN_INPUT == nr) {
+ val = data->fan[index] & 0x0fff;
+ } else {
+ val = data->fan_min[index] & 0x0fff;
+ }
+
+ return sprintf(buf, "%lu\n", FAN_FROM_REG(val));
+}
+
+static ssize_t
+store_fan_min(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct sensor_device_attribute_2 *sensor_attr =
+ to_sensor_dev_attr_2(attr);
+ int index = sensor_attr->index;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct w83793_data *data = i2c_get_clientdata(client);
+ u16 val = FAN_TO_REG(simple_strtoul(buf, NULL, 10));
+
+ mutex_lock(&data->update_lock);
+ data->fan_min[index] = val;
+ w83793_write_value(client, W83793_REG_FAN_MIN(index),
+ (val >> 8) & 0xff);
+ w83793_write_value(client, W83793_REG_FAN_MIN(index) + 1, val & 0xff);
+ mutex_unlock(&data->update_lock);
+
+ return count;
+}
+
+#define PWM_DUTY 0
+#define PWM_START 1
+#define PWM_NONSTOP 2
+#define PWM_STOP_TIME 3
+static ssize_t
+show_pwm(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct sensor_device_attribute_2 *sensor_attr =
+ to_sensor_dev_attr_2(attr);
+ struct w83793_data *data = w83793_update_device(dev);
+ u16 val;
+ int nr = sensor_attr->nr;
+ int index = sensor_attr->index;
+
+ if (PWM_STOP_TIME == nr)
+ val = TIME_FROM_REG(data->pwm_stop_time[index]);
+ else
+ val = (data->pwm[index][nr] & 0x3f) << 2;
+
+ return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t
+store_pwm(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct w83793_data *data = i2c_get_clientdata(client);
+ struct sensor_device_attribute_2 *sensor_attr =
+ to_sensor_dev_attr_2(attr);
+ int nr = sensor_attr->nr;
+ int index = sensor_attr->index;
+ u8 val;
+
+ mutex_lock(&data->update_lock);
+ if (PWM_STOP_TIME == nr) {
+ val = TIME_TO_REG(simple_strtoul(buf, NULL, 10));
+ data->pwm_stop_time[index] = val;
+ w83793_write_value(client, W83793_REG_PWM_STOP_TIME(index),
+ val);
+ } else {
+ val = SENSORS_LIMIT(simple_strtoul(buf, NULL, 10), 0, 0xff)
+ >> 2;
+ data->pwm[index][nr] =
+ w83793_read_value(client, W83793_REG_PWM(index, nr)) & 0xc0;
+ data->pwm[index][nr] |= val;
+ w83793_write_value(client, W83793_REG_PWM(index, nr),
+ data->pwm[index][nr]);
+ }
+
+ mutex_unlock(&data->update_lock);
+ return count;
+}
+
+static ssize_t
+show_temp(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct sensor_device_attribute_2 *sensor_attr =
+ to_sensor_dev_attr_2(attr);
+ int nr = sensor_attr->nr;
+ int index = sensor_attr->index;
+ struct w83793_data *data = w83793_update_device(dev);
+ long temp = TEMP_FROM_REG(data->temp[index][nr]);
+
+ if (TEMP_READ == nr && index < 4) { /* Only TD1-TD4 have low bits */
+ int low = ((data->temp_low_bits >> (index * 2)) & 0x03) * 250;
+ temp += temp > 0 ? low : -low;
+ }
+ return sprintf(buf, "%ld\n", temp);
+}
+
+static ssize_t
+store_temp(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct sensor_device_attribute_2 *sensor_attr =
+ to_sensor_dev_attr_2(attr);
+ int nr = sensor_attr->nr;
+ int index = sensor_attr->index;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct w83793_data *data = i2c_get_clientdata(client);
+ long tmp = simple_strtol(buf, NULL, 10);
+
+ mutex_lock(&data->update_lock);
+ data->temp[index][nr] = TEMP_TO_REG(tmp, -128, 127);
+ w83793_write_value(client, W83793_REG_TEMP[index][nr],
+ data->temp[index][nr]);
+ mutex_unlock(&data->update_lock);
+ return count;
+}
+
+/*
+ TD1-TD4
+ each has 4 mode:(2 bits)
+ 0: Stop monitor
+ 1: Use internal temp sensor(default)
+ 2: Use sensor in AMD CPU and get result by AMDSI
+ 3: Use sensor in Intel CPU and get result by PECI
+
+ TR1-TR2
+ each has 2 mode:(1 bit)
+ 0: Disable temp sensor monitor
+ 1: To enable temp sensors monitor
+*/
+
+/* 0 disable, 5 AMDSI, 6 PECI */
+static u8 TO_TEMP_MODE[] = { 0, 0, 5, 6 };
+
+static ssize_t
+show_temp_mode(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct w83793_data *data = w83793_update_device(dev);
+ struct sensor_device_attribute_2 *sensor_attr =
+ to_sensor_dev_attr_2(attr);
+ int index = sensor_attr->index;
+ u8 mask = (index < 4) ? 0x03 : 0x01;
+ u8 shift = (index < 4) ? (2 * index) : (index - 4);
+ u8 tmp;
+ index = (index < 4) ? 0 : 1;
+
+ tmp = (data->temp_mode[index] >> shift) & mask;
+
+ /* for the internal sensor, found out if diode or thermistor */
+ if (tmp == 1) {
+ tmp = index == 0 ? 3 : 4;
+ } else {
+ tmp = TO_TEMP_MODE[tmp];
+ }
+
+ return sprintf(buf, "%d\n", tmp);
+}
+
+static ssize_t
+store_temp_mode(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct w83793_data *data = i2c_get_clientdata(client);
+ struct sensor_device_attribute_2 *sensor_attr =
+ to_sensor_dev_attr_2(attr);
+ int index = sensor_attr->index;
+ u8 mask = (index < 4) ? 0x03 : 0x01;
+ u8 shift = (index < 4) ? (2 * index) : (index - 4);
+ u8 val = simple_strtoul(buf, NULL, 10);
+
+ /* transform the sysfs interface values into table above */
+ if ((val == 5 || val == 6) && (index < 4)) {
+ val -= 3;
+ } else if ((val == 3 && index < 4)
+ || (val == 4 && index >= 4)
+ || val == 0) {
+ /* transform diode or thermistor into internal enable */
+ val = !!val;
+ } else {
+ return -EINVAL;
+ }
+
+ index = (index < 4) ? 0 : 1;
+ mutex_lock(&data->update_lock);
+ data->temp_mode[index] =
+ w83793_read_value(client, W83793_REG_TEMP_MODE[index]);
+ data->temp_mode[index] &= ~(mask << shift);
+ data->temp_mode[index] |= val << shift;
+ w83793_write_value(client, W83793_REG_TEMP_MODE[index],
+ data->temp_mode[index]);
+ mutex_unlock(&data->update_lock);
+
+ return count;
+}
+
+#define SETUP_PWM_DEFAULT 0
+#define SETUP_PWM_UPTIME 1 /* Unit in 0.1s */
+#define SETUP_PWM_DOWNTIME 2 /* Unit in 0.1s */
+#define SETUP_TEMP_CRITICAL 3
+static ssize_t
+show_sf_setup(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct sensor_device_attribute_2 *sensor_attr =
+ to_sensor_dev_attr_2(attr);
+ int nr = sensor_attr->nr;
+ struct w83793_data *data = w83793_update_device(dev);
+ u32 val = 0;
+
+ if (SETUP_PWM_DEFAULT == nr) {
+ val = (data->pwm_default & 0x3f) << 2;
+ } else if (SETUP_PWM_UPTIME == nr) {
+ val = TIME_FROM_REG(data->pwm_uptime);
+ } else if (SETUP_PWM_DOWNTIME == nr) {
+ val = TIME_FROM_REG(data->pwm_downtime);
+ } else if (SETUP_TEMP_CRITICAL == nr) {
+ val = TEMP_FROM_REG(data->temp_critical & 0x7f);
+ }
+
+ return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t
+store_sf_setup(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct sensor_device_attribute_2 *sensor_attr =
+ to_sensor_dev_attr_2(attr);
+ int nr = sensor_attr->nr;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct w83793_data *data = i2c_get_clientdata(client);
+
+ mutex_lock(&data->update_lock);
+ if (SETUP_PWM_DEFAULT == nr) {
+ data->pwm_default =
+ w83793_read_value(client, W83793_REG_PWM_DEFAULT) & 0xc0;
+ data->pwm_default |= SENSORS_LIMIT(simple_strtoul(buf, NULL,
+ 10),
+ 0, 0xff) >> 2;
+ w83793_write_value(client, W83793_REG_PWM_DEFAULT,
+ data->pwm_default);
+ } else if (SETUP_PWM_UPTIME == nr) {
+ data->pwm_uptime = TIME_TO_REG(simple_strtoul(buf, NULL, 10));
+ data->pwm_uptime += data->pwm_uptime == 0 ? 1 : 0;
+ w83793_write_value(client, W83793_REG_PWM_UPTIME,
+ data->pwm_uptime);
+ } else if (SETUP_PWM_DOWNTIME == nr) {
+ data->pwm_downtime = TIME_TO_REG(simple_strtoul(buf, NULL, 10));
+ data->pwm_downtime += data->pwm_downtime == 0 ? 1 : 0;
+ w83793_write_value(client, W83793_REG_PWM_DOWNTIME,
+ data->pwm_downtime);
+ } else { /* SETUP_TEMP_CRITICAL */
+ data->temp_critical =
+ w83793_read_value(client, W83793_REG_TEMP_CRITICAL) & 0x80;
+ data->temp_critical |= TEMP_TO_REG(simple_strtol(buf, NULL, 10),
+ 0, 0x7f);
+ w83793_write_value(client, W83793_REG_TEMP_CRITICAL,
+ data->temp_critical);
+ }
+
+ mutex_unlock(&data->update_lock);
+ return count;
+}
+
+/*
+ Temp SmartFan control
+ TEMP_FAN_MAP
+ Temp channel control which pwm fan, bitfield, bit 0 indicate pwm1...
+ It's possible two or more temp channels control the same fan, w83793
+ always prefers to pick the most critical request and applies it to
+ the related Fan.
+ It's possible one fan is not in any mapping of 6 temp channels, this
+ means the fan is manual mode
+
+ TEMP_PWM_ENABLE
+ Each temp channel has its own SmartFan mode, and temp channel
+ control fans that are set by TEMP_FAN_MAP
+ 0: SmartFanII mode
+ 1: Thermal Cruise Mode
+
+ TEMP_CRUISE
+ Target temperature in thermal cruise mode, w83793 will try to turn
+ fan speed to keep the temperature of target device around this
+ temperature.
+
+ TEMP_TOLERANCE
+ If Temp higher or lower than target with this tolerance, w83793
+ will take actions to speed up or slow down the fan to keep the
+ temperature within the tolerance range.
+*/
+
+#define TEMP_FAN_MAP 0
+#define TEMP_PWM_ENABLE 1
+#define TEMP_CRUISE 2
+#define TEMP_TOLERANCE 3
+static ssize_t
+show_sf_ctrl(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct sensor_device_attribute_2 *sensor_attr =
+ to_sensor_dev_attr_2(attr);
+ int nr = sensor_attr->nr;
+ int index = sensor_attr->index;
+ struct w83793_data *data = w83793_update_device(dev);
+ u32 val;
+
+ if (TEMP_FAN_MAP == nr) {
+ val = data->temp_fan_map[index];
+ } else if (TEMP_PWM_ENABLE == nr) {
+ /* +2 to transfrom into 2 and 3 to conform with sysfs intf */
+ val = ((data->pwm_enable >> index) & 0x01) + 2;
+ } else if (TEMP_CRUISE == nr) {
+ val = TEMP_FROM_REG(data->temp_cruise[index] & 0x7f);
+ } else { /* TEMP_TOLERANCE */
+ val = data->tolerance[index >> 1] >> ((index & 0x01) ? 4 : 0);
+ val = TEMP_FROM_REG(val & 0x0f);
+ }
+ return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t
+store_sf_ctrl(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct sensor_device_attribute_2 *sensor_attr =
+ to_sensor_dev_attr_2(attr);
+ int nr = sensor_attr->nr;
+ int index = sensor_attr->index;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct w83793_data *data = i2c_get_clientdata(client);
+ u32 val;
+
+ mutex_lock(&data->update_lock);
+ if (TEMP_FAN_MAP == nr) {
+ val = simple_strtoul(buf, NULL, 10) & 0xff;
+ w83793_write_value(client, W83793_REG_TEMP_FAN_MAP(index), val);
+ data->temp_fan_map[index] = val;
+ } else if (TEMP_PWM_ENABLE == nr) {
+ val = simple_strtoul(buf, NULL, 10);
+ if (2 == val || 3 == val) {
+ data->pwm_enable =
+ w83793_read_value(client, W83793_REG_PWM_ENABLE);
+ if (val - 2)
+ data->pwm_enable |= 1 << index;
+ else
+ data->pwm_enable &= ~(1 << index);
+ w83793_write_value(client, W83793_REG_PWM_ENABLE,
+ data->pwm_enable);
+ } else {
+ mutex_unlock(&data->update_lock);
+ return -EINVAL;
+ }
+ } else if (TEMP_CRUISE == nr) {
+ data->temp_cruise[index] =
+ w83793_read_value(client, W83793_REG_TEMP_CRUISE(index));
+ val = TEMP_TO_REG(simple_strtol(buf, NULL, 10), 0, 0x7f);
+ data->temp_cruise[index] &= 0x80;
+ data->temp_cruise[index] |= val;
+
+ w83793_write_value(client, W83793_REG_TEMP_CRUISE(index),
+ data->temp_cruise[index]);
+ } else { /* TEMP_TOLERANCE */
+ int i = index >> 1;
+ u8 shift = (index & 0x01) ? 4 : 0;
+ data->tolerance[i] =
+ w83793_read_value(client, W83793_REG_TEMP_TOL(i));
+
+ val = TEMP_TO_REG(simple_strtol(buf, NULL, 10), 0, 0x0f);
+ data->tolerance[i] &= ~(0x0f << shift);
+ data->tolerance[i] |= val << shift;
+ w83793_write_value(client, W83793_REG_TEMP_TOL(i),
+ data->tolerance[i]);
+ }
+
+ mutex_unlock(&data->update_lock);
+ return count;
+}
+
+static ssize_t
+show_sf2_pwm(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct sensor_device_attribute_2 *sensor_attr =
+ to_sensor_dev_attr_2(attr);
+ int nr = sensor_attr->nr;
+ int index = sensor_attr->index;
+ struct w83793_data *data = w83793_update_device(dev);
+
+ return sprintf(buf, "%d\n", (data->sf2_pwm[index][nr] & 0x3f) << 2);
+}
+
+static ssize_t
+store_sf2_pwm(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct w83793_data *data = i2c_get_clientdata(client);
+ struct sensor_device_attribute_2 *sensor_attr =
+ to_sensor_dev_attr_2(attr);
+ int nr = sensor_attr->nr;
+ int index = sensor_attr->index;
+ u8 val = SENSORS_LIMIT(simple_strtoul(buf, NULL, 10), 0, 0xff) >> 2;
+
+ mutex_lock(&data->update_lock);
+ data->sf2_pwm[index][nr] =
+ w83793_read_value(client, W83793_REG_SF2_PWM(index, nr)) & 0xc0;
+ data->sf2_pwm[index][nr] |= val;
+ w83793_write_value(client, W83793_REG_SF2_PWM(index, nr),
+ data->sf2_pwm[index][nr]);
+ mutex_unlock(&data->update_lock);
+ return count;
+}
+
+static ssize_t
+show_sf2_temp(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct sensor_device_attribute_2 *sensor_attr =
+ to_sensor_dev_attr_2(attr);
+ int nr = sensor_attr->nr;
+ int index = sensor_attr->index;
+ struct w83793_data *data = w83793_update_device(dev);
+
+ return sprintf(buf, "%ld\n",
+ TEMP_FROM_REG(data->sf2_temp[index][nr] & 0x7f));
+}
+
+static ssize_t
+store_sf2_temp(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct w83793_data *data = i2c_get_clientdata(client);
+ struct sensor_device_attribute_2 *sensor_attr =
+ to_sensor_dev_attr_2(attr);
+ int nr = sensor_attr->nr;
+ int index = sensor_attr->index;
+ u8 val = TEMP_TO_REG(simple_strtol(buf, NULL, 10), 0, 0x7f);
+
+ mutex_lock(&data->update_lock);
+ data->sf2_temp[index][nr] =
+ w83793_read_value(client, W83793_REG_SF2_TEMP(index, nr)) & 0x80;
+ data->sf2_temp[index][nr] |= val;
+ w83793_write_value(client, W83793_REG_SF2_TEMP(index, nr),
+ data->sf2_temp[index][nr]);
+ mutex_unlock(&data->update_lock);
+ return count;
+}
+
+/* only Vcore A/B and Vtt have additional 2 bits precision */
+static ssize_t
+show_in(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct sensor_device_attribute_2 *sensor_attr =
+ to_sensor_dev_attr_2(attr);
+ int nr = sensor_attr->nr;
+ int index = sensor_attr->index;
+ struct w83793_data *data = w83793_update_device(dev);
+ u16 val = data->in[index][nr];
+
+ if (index < 3) {
+ val <<= 2;
+ val += (data->in_low_bits[nr] >> (index * 2)) & 0x3;
+ }
+ return sprintf(buf, "%d\n", val * scale_in[index]);
+}
+
+static ssize_t
+store_in(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct sensor_device_attribute_2 *sensor_attr =
+ to_sensor_dev_attr_2(attr);
+ int nr = sensor_attr->nr;
+ int index = sensor_attr->index;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct w83793_data *data = i2c_get_clientdata(client);
+ u32 val;
+
+ val =
+ (simple_strtoul(buf, NULL, 10) +
+ scale_in[index] / 2) / scale_in[index];
+ mutex_lock(&data->update_lock);
+ if (index > 2) {
+ val = SENSORS_LIMIT(val, 0, 255);
+ } else {
+ val = SENSORS_LIMIT(val, 0, 0x3FF);
+ data->in_low_bits[nr] =
+ w83793_read_value(client, W83793_REG_IN_LOW_BITS[nr]);
+ data->in_low_bits[nr] &= ~(0x03 << (2 * index));
+ data->in_low_bits[nr] |= (val & 0x03) << (2 * index);
+ w83793_write_value(client, W83793_REG_IN_LOW_BITS[nr],
+ data->in_low_bits[nr]);
+ val >>= 2;
+ }
+ data->in[index][nr] = val;
+ w83793_write_value(client, W83793_REG_IN[index][nr],
+ data->in[index][nr]);
+ mutex_unlock(&data->update_lock);
+ return count;
+}
+
+#define NOT_USED -1
+
+#define SENSOR_ATTR_IN(index) \
+ SENSOR_ATTR_2(in##index##_input, S_IRUGO, show_in, NULL, \
+ IN_READ, index), \
+ SENSOR_ATTR_2(in##index##_max, S_IRUGO | S_IWUSR, show_in, \
+ store_in, IN_MAX, index), \
+ SENSOR_ATTR_2(in##index##_min, S_IRUGO | S_IWUSR, show_in, \
+ store_in, IN_LOW, index), \
+ SENSOR_ATTR_2(in##index##_alarm, S_IRUGO, show_alarm_beep, \
+ NULL, ALARM_STATUS, index + ((index > 2) ? 1 : 0)), \
+ SENSOR_ATTR_2(in##index##_beep, S_IWUSR | S_IRUGO, \
+ show_alarm_beep, store_beep, BEEP_ENABLE, \
+ index + ((index > 2) ? 1 : 0))
+
+#define SENSOR_ATTR_FAN(index) \
+ SENSOR_ATTR_2(fan##index##_alarm, S_IRUGO, show_alarm_beep, \
+ NULL, ALARM_STATUS, index + 17), \
+ SENSOR_ATTR_2(fan##index##_beep, S_IWUSR | S_IRUGO, \
+ show_alarm_beep, store_beep, BEEP_ENABLE, index + 17), \
+ SENSOR_ATTR_2(fan##index##_input, S_IRUGO, show_fan, \
+ NULL, FAN_INPUT, index - 1), \
+ SENSOR_ATTR_2(fan##index##_min, S_IWUSR | S_IRUGO, \
+ show_fan, store_fan_min, FAN_MIN, index - 1)
+
+#define SENSOR_ATTR_PWM(index) \
+ SENSOR_ATTR_2(pwm##index, S_IWUSR | S_IRUGO, show_pwm, \
+ store_pwm, PWM_DUTY, index - 1), \
+ SENSOR_ATTR_2(pwm##index##_nonstop, S_IWUSR | S_IRUGO, \
+ show_pwm, store_pwm, PWM_NONSTOP, index - 1), \
+ SENSOR_ATTR_2(pwm##index##_start, S_IWUSR | S_IRUGO, \
+ show_pwm, store_pwm, PWM_START, index - 1), \
+ SENSOR_ATTR_2(pwm##index##_stop_time, S_IWUSR | S_IRUGO, \
+ show_pwm, store_pwm, PWM_STOP_TIME, index - 1)
+
+#define SENSOR_ATTR_TEMP(index) \
+ SENSOR_ATTR_2(temp##index##_type, S_IRUGO | S_IWUSR, \
+ show_temp_mode, store_temp_mode, NOT_USED, index - 1), \
+ SENSOR_ATTR_2(temp##index##_input, S_IRUGO, show_temp, \
+ NULL, TEMP_READ, index - 1), \
+ SENSOR_ATTR_2(temp##index##_max, S_IRUGO | S_IWUSR, show_temp, \
+ store_temp, TEMP_CRIT, index - 1), \
+ SENSOR_ATTR_2(temp##index##_max_hyst, S_IRUGO | S_IWUSR, \
+ show_temp, store_temp, TEMP_CRIT_HYST, index - 1), \
+ SENSOR_ATTR_2(temp##index##_warn, S_IRUGO | S_IWUSR, show_temp, \
+ store_temp, TEMP_WARN, index - 1), \
+ SENSOR_ATTR_2(temp##index##_warn_hyst, S_IRUGO | S_IWUSR, \
+ show_temp, store_temp, TEMP_WARN_HYST, index - 1), \
+ SENSOR_ATTR_2(temp##index##_alarm, S_IRUGO, \
+ show_alarm_beep, NULL, ALARM_STATUS, index + 11), \
+ SENSOR_ATTR_2(temp##index##_beep, S_IWUSR | S_IRUGO, \
+ show_alarm_beep, store_beep, BEEP_ENABLE, index + 11), \
+ SENSOR_ATTR_2(temp##index##_auto_channels_pwm, \
+ S_IRUGO | S_IWUSR, show_sf_ctrl, store_sf_ctrl, \
+ TEMP_FAN_MAP, index - 1), \
+ SENSOR_ATTR_2(temp##index##_pwm_enable, S_IWUSR | S_IRUGO, \
+ show_sf_ctrl, store_sf_ctrl, TEMP_PWM_ENABLE, \
+ index - 1), \
+ SENSOR_ATTR_2(thermal_cruise##index, S_IRUGO | S_IWUSR, \
+ show_sf_ctrl, store_sf_ctrl, TEMP_CRUISE, index - 1), \
+ SENSOR_ATTR_2(tolerance##index, S_IRUGO | S_IWUSR, show_sf_ctrl,\
+ store_sf_ctrl, TEMP_TOLERANCE, index - 1), \
+ SENSOR_ATTR_2(temp##index##_auto_point1_pwm, S_IRUGO | S_IWUSR, \
+ show_sf2_pwm, store_sf2_pwm, 0, index - 1), \
+ SENSOR_ATTR_2(temp##index##_auto_point2_pwm, S_IRUGO | S_IWUSR, \
+ show_sf2_pwm, store_sf2_pwm, 1, index - 1), \
+ SENSOR_ATTR_2(temp##index##_auto_point3_pwm, S_IRUGO | S_IWUSR, \
+ show_sf2_pwm, store_sf2_pwm, 2, index - 1), \
+ SENSOR_ATTR_2(temp##index##_auto_point4_pwm, S_IRUGO | S_IWUSR, \
+ show_sf2_pwm, store_sf2_pwm, 3, index - 1), \
+ SENSOR_ATTR_2(temp##index##_auto_point5_pwm, S_IRUGO | S_IWUSR, \
+ show_sf2_pwm, store_sf2_pwm, 4, index - 1), \
+ SENSOR_ATTR_2(temp##index##_auto_point6_pwm, S_IRUGO | S_IWUSR, \
+ show_sf2_pwm, store_sf2_pwm, 5, index - 1), \
+ SENSOR_ATTR_2(temp##index##_auto_point7_pwm, S_IRUGO | S_IWUSR, \
+ show_sf2_pwm, store_sf2_pwm, 6, index - 1), \
+ SENSOR_ATTR_2(temp##index##_auto_point1_temp, S_IRUGO | S_IWUSR,\
+ show_sf2_temp, store_sf2_temp, 0, index - 1), \
+ SENSOR_ATTR_2(temp##index##_auto_point2_temp, S_IRUGO | S_IWUSR,\
+ show_sf2_temp, store_sf2_temp, 1, index - 1), \
+ SENSOR_ATTR_2(temp##index##_auto_point3_temp, S_IRUGO | S_IWUSR,\
+ show_sf2_temp, store_sf2_temp, 2, index - 1), \
+ SENSOR_ATTR_2(temp##index##_auto_point4_temp, S_IRUGO | S_IWUSR,\
+ show_sf2_temp, store_sf2_temp, 3, index - 1), \
+ SENSOR_ATTR_2(temp##index##_auto_point5_temp, S_IRUGO | S_IWUSR,\
+ show_sf2_temp, store_sf2_temp, 4, index - 1), \
+ SENSOR_ATTR_2(temp##index##_auto_point6_temp, S_IRUGO | S_IWUSR,\
+ show_sf2_temp, store_sf2_temp, 5, index - 1), \
+ SENSOR_ATTR_2(temp##index##_auto_point7_temp, S_IRUGO | S_IWUSR,\
+ show_sf2_temp, store_sf2_temp, 6, index - 1)
+
+static struct sensor_device_attribute_2 w83793_sensor_attr_2[] = {
+ SENSOR_ATTR_IN(0),
+ SENSOR_ATTR_IN(1),
+ SENSOR_ATTR_IN(2),
+ SENSOR_ATTR_IN(3),
+ SENSOR_ATTR_IN(4),
+ SENSOR_ATTR_IN(5),
+ SENSOR_ATTR_IN(6),
+ SENSOR_ATTR_IN(7),
+ SENSOR_ATTR_IN(8),
+ SENSOR_ATTR_IN(9),
+ SENSOR_ATTR_TEMP(1),
+ SENSOR_ATTR_TEMP(2),
+ SENSOR_ATTR_TEMP(3),
+ SENSOR_ATTR_TEMP(4),
+ SENSOR_ATTR_TEMP(5),
+ SENSOR_ATTR_TEMP(6),
+ SENSOR_ATTR_FAN(1),
+ SENSOR_ATTR_FAN(2),
+ SENSOR_ATTR_FAN(3),
+ SENSOR_ATTR_FAN(4),
+ SENSOR_ATTR_FAN(5),
+ SENSOR_ATTR_PWM(1),
+ SENSOR_ATTR_PWM(2),
+ SENSOR_ATTR_PWM(3),
+};
+
+/* Fan6-Fan12 */
+static struct sensor_device_attribute_2 w83793_left_fan[] = {
+ SENSOR_ATTR_FAN(6),
+ SENSOR_ATTR_FAN(7),
+ SENSOR_ATTR_FAN(8),
+ SENSOR_ATTR_FAN(9),
+ SENSOR_ATTR_FAN(10),
+ SENSOR_ATTR_FAN(11),
+ SENSOR_ATTR_FAN(12),
+};
+
+/* Pwm4-Pwm8 */
+static struct sensor_device_attribute_2 w83793_left_pwm[] = {
+ SENSOR_ATTR_PWM(4),
+ SENSOR_ATTR_PWM(5),
+ SENSOR_ATTR_PWM(6),
+ SENSOR_ATTR_PWM(7),
+ SENSOR_ATTR_PWM(8),
+};
+
+static struct sensor_device_attribute_2 sda_single_files[] = {
+ SENSOR_ATTR_2(cpu0_vid, S_IRUGO, show_vid, NULL, NOT_USED, 0),
+ SENSOR_ATTR_2(cpu1_vid, S_IRUGO, show_vid, NULL, NOT_USED, 1),
+ SENSOR_ATTR_2(vrm, S_IWUSR | S_IRUGO, show_vrm, store_vrm,
+ NOT_USED, NOT_USED),
+ SENSOR_ATTR_2(chassis, S_IWUSR | S_IRUGO, show_alarm_beep,
+ store_chassis_clear, ALARM_STATUS, 30),
+ SENSOR_ATTR_2(beep_enable, S_IWUSR | S_IRUGO, show_beep_enable,
+ store_beep_enable, NOT_USED, NOT_USED),
+ SENSOR_ATTR_2(pwm_default, S_IWUSR | S_IRUGO, show_sf_setup,
+ store_sf_setup, SETUP_PWM_DEFAULT, NOT_USED),
+ SENSOR_ATTR_2(pwm_uptime, S_IWUSR | S_IRUGO, show_sf_setup,
+ store_sf_setup, SETUP_PWM_UPTIME, NOT_USED),
+ SENSOR_ATTR_2(pwm_downtime, S_IWUSR | S_IRUGO, show_sf_setup,
+ store_sf_setup, SETUP_PWM_DOWNTIME, NOT_USED),
+ SENSOR_ATTR_2(temp_critical, S_IWUSR | S_IRUGO, show_sf_setup,
+ store_sf_setup, SETUP_TEMP_CRITICAL, NOT_USED),
+};
+
+static void w83793_init_client(struct i2c_client *client)
+{
+ if (reset) {
+ w83793_write_value(client, W83793_REG_CONFIG, 0x80);
+ }
+
+ /* Start monitoring */
+ w83793_write_value(client, W83793_REG_CONFIG,
+ w83793_read_value(client, W83793_REG_CONFIG) | 0x01);
+
+}
+
+static int w83793_attach_adapter(struct i2c_adapter *adapter)
+{
+ if (!(adapter->class & I2C_CLASS_HWMON))
+ return 0;
+ return i2c_probe(adapter, &addr_data, w83793_detect);
+}
+
+static int w83793_detach_client(struct i2c_client *client)
+{
+ struct w83793_data *data = i2c_get_clientdata(client);
+ struct device *dev = &client->dev;
+ int err, i;
+
+ /* main client */
+ if (data) {
+ hwmon_device_unregister(data->class_dev);
+
+ for (i = 0; i < ARRAY_SIZE(w83793_sensor_attr_2); i++)
+ device_remove_file(dev,
+ &w83793_sensor_attr_2[i].dev_attr);
+
+ for (i = 0; i < ARRAY_SIZE(sda_single_files); i++)
+ device_remove_file(dev, &sda_single_files[i].dev_attr);
+
+ for (i = 0; i < ARRAY_SIZE(w83793_left_fan); i++)
+ device_remove_file(dev, &w83793_left_fan[i].dev_attr);
+
+ for (i = 0; i < ARRAY_SIZE(w83793_left_pwm); i++)
+ device_remove_file(dev, &w83793_left_pwm[i].dev_attr);
+ }
+
+ if ((err = i2c_detach_client(client)))
+ return err;
+
+ /* main client */
+ if (data)
+ kfree(data);
+ /* subclient */
+ else
+ kfree(client);
+
+ return 0;
+}
+
+static int
+w83793_create_subclient(struct i2c_adapter *adapter,
+ struct i2c_client *client, int addr,
+ struct i2c_client **sub_cli)
+{
+ int err = 0;
+ struct i2c_client *sub_client;
+
+ (*sub_cli) = sub_client =
+ kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
+ if (!(sub_client)) {
+ return -ENOMEM;
+ }
+ sub_client->addr = 0x48 + addr;
+ i2c_set_clientdata(sub_client, NULL);
+ sub_client->adapter = adapter;
+ sub_client->driver = &w83793_driver;
+ strlcpy(sub_client->name, "w83793 subclient", I2C_NAME_SIZE);
+ if ((err = i2c_attach_client(sub_client))) {
+ dev_err(&client->dev, "subclient registration "
+ "at address 0x%x failed\n", sub_client->addr);
+ kfree(sub_client);
+ }
+ return err;
+}
+
+static int
+w83793_detect_subclients(struct i2c_adapter *adapter, int address,
+ int kind, struct i2c_client *client)
+{
+ int i, id, err;
+ u8 tmp;
+ struct w83793_data *data = i2c_get_clientdata(client);
+
+ id = i2c_adapter_id(adapter);
+ if (force_subclients[0] == id && force_subclients[1] == address) {
+ for (i = 2; i <= 3; i++) {
+ if (force_subclients[i] < 0x48
+ || force_subclients[i] > 0x4f) {
+ dev_err(&client->dev,
+ "invalid subclient "
+ "address %d; must be 0x48-0x4f\n",
+ force_subclients[i]);
+ err = -EINVAL;
+ goto ERROR_SC_0;
+ }
+ }
+ w83793_write_value(client, W83793_REG_I2C_SUBADDR,
+ (force_subclients[2] & 0x07) |
+ ((force_subclients[3] & 0x07) << 4));
+ }
+
+ tmp = w83793_read_value(client, W83793_REG_I2C_SUBADDR);
+ if (!(tmp & 0x08)) {
+ err =
+ w83793_create_subclient(adapter, client, tmp & 0x7,
+ &data->lm75[0]);
+ if (err < 0)
+ goto ERROR_SC_0;
+ }
+ if (!(tmp & 0x80)) {
+ if ((data->lm75[0] != NULL)
+ && ((tmp & 0x7) == ((tmp >> 4) & 0x7))) {
+ dev_err(&client->dev,
+ "duplicate addresses 0x%x, "
+ "use force_subclients\n", data->lm75[0]->addr);
+ err = -ENODEV;
+ goto ERROR_SC_1;
+ }
+ err = w83793_create_subclient(adapter, client,
+ (tmp >> 4) & 0x7, &data->lm75[1]);
+ if (err < 0)
+ goto ERROR_SC_1;
+ }
+
+ return 0;
+
+ /* Undo inits in case of errors */
+
+ERROR_SC_1:
+ if (data->lm75[0] != NULL) {
+ i2c_detach_client(data->lm75[0]);
+ kfree(data->lm75[0]);
+ }
+ERROR_SC_0:
+ return err;
+}
+
+static int w83793_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+ int i;
+ u8 tmp, val;
+ struct i2c_client *client;
+ struct device *dev;
+ struct w83793_data *data;
+ int files_fan = ARRAY_SIZE(w83793_left_fan) / 7;
+ int files_pwm = ARRAY_SIZE(w83793_left_pwm) / 5;
+ int err = 0;
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
+ goto exit;
+ }
+
+ /* OK. For now, we presume we have a valid client. We now create the
+ client structure, even though we cannot fill it completely yet.
+ But it allows us to access w83793_{read,write}_value. */
+
+ if (!(data = kzalloc(sizeof(struct w83793_data), GFP_KERNEL))) {
+ err = -ENOMEM;
+ goto exit;
+ }
+
+ client = &data->client;
+ dev = &client->dev;
+ i2c_set_clientdata(client, data);
+ client->addr = address;
+ client->adapter = adapter;
+ client->driver = &w83793_driver;
+
+ data->bank = i2c_smbus_read_byte_data(client, W83793_REG_BANKSEL);
+
+ /* Now, we do the remaining detection. */
+ if (kind < 0) {
+ tmp = data->bank & 0x80 ? 0x5c : 0xa3;
+ /* Check Winbond vendor ID */
+ if (tmp != i2c_smbus_read_byte_data(client,
+ W83793_REG_VENDORID)) {
+ pr_debug("w83793: Detection failed at check "
+ "vendor id\n");
+ err = -ENODEV;
+ goto free_mem;
+ }
+
+ /* If Winbond chip, address of chip and W83793_REG_I2C_ADDR
+ should match */
+ if ((data->bank & 0x07) == 0
+ && i2c_smbus_read_byte_data(client, W83793_REG_I2C_ADDR) !=
+ (address << 1)) {
+ pr_debug("w83793: Detection failed at check "
+ "i2c addr\n");
+ err = -ENODEV;
+ goto free_mem;
+ }
+
+ }
+
+ /* We have either had a force parameter, or we have already detected the
+ Winbond. Determine the chip type now */
+
+ if (kind <= 0) {
+ if (0x7b == w83793_read_value(client, W83793_REG_CHIPID)) {
+ kind = w83793;
+ } else {
+ if (kind == 0)
+ dev_warn(&adapter->dev, "w83793: Ignoring "
+ "'force' parameter for unknown chip "
+ "at address 0x%02x\n", address);
+ err = -ENODEV;
+ goto free_mem;
+ }
+ }
+
+ /* Fill in the remaining client fields and put into the global list */
+ strlcpy(client->name, "w83793", I2C_NAME_SIZE);
+
+ mutex_init(&data->update_lock);
+
+ /* Tell the I2C layer a new client has arrived */
+ if ((err = i2c_attach_client(client)))
+ goto free_mem;
+
+ if ((err = w83793_detect_subclients(adapter, address, kind, client)))
+ goto detach_client;
+
+ /* Initialize the chip */
+ w83793_init_client(client);
+
+ data->vrm = vid_which_vrm();
+ /*
+ Only fan 1-5 has their own input pins,
+ Pwm 1-3 has their own pins
+ */
+ data->has_fan = 0x1f;
+ data->has_pwm = 0x07;
+ tmp = w83793_read_value(client, W83793_REG_MFC);
+ val = w83793_read_value(client, W83793_REG_FANIN_CTRL);
+
+ /* check the function of pins 49-56 */
+ if (!(tmp & 0x80)) {
+ data->has_pwm |= 0x18; /* pwm 4,5 */
+ if (val & 0x01) { /* fan 6 */
+ data->has_fan |= 0x20;
+ data->has_pwm |= 0x20;
+ }
+ if (val & 0x02) { /* fan 7 */
+ data->has_fan |= 0x40;
+ data->has_pwm |= 0x40;
+ }
+ if (!(tmp & 0x40) && (val & 0x04)) { /* fan 8 */
+ data->has_fan |= 0x80;
+ data->has_pwm |= 0x80;
+ }
+ }
+
+ if (0x08 == (tmp & 0x0c)) {
+ if (val & 0x08) /* fan 9 */
+ data->has_fan |= 0x100;
+ if (val & 0x10) /* fan 10 */
+ data->has_fan |= 0x200;
+ }
+
+ if (0x20 == (tmp & 0x30)) {
+ if (val & 0x20) /* fan 11 */
+ data->has_fan |= 0x400;
+ if (val & 0x40) /* fan 12 */
+ data->has_fan |= 0x800;
+ }
+
+ if ((tmp & 0x01) && (val & 0x04)) { /* fan 8, second location */
+ data->has_fan |= 0x80;
+ data->has_pwm |= 0x80;
+ }
+
+ /* Register sysfs hooks */
+ for (i = 0; i < ARRAY_SIZE(w83793_sensor_attr_2); i++) {
+ err = device_create_file(dev,
+ &w83793_sensor_attr_2[i].dev_attr);
+ if (err)
+ goto exit_remove;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(sda_single_files); i++) {
+ err = device_create_file(dev, &sda_single_files[i].dev_attr);
+ if (err)
+ goto exit_remove;
+
+ }
+
+ for (i = 5; i < 12; i++) {
+ int j;
+ if (!(data->has_fan & (1 << i)))
+ continue;
+ for (j = 0; j < files_fan; j++) {
+ err = device_create_file(dev,
+ &w83793_left_fan[(i - 5) * files_fan
+ + j].dev_attr);
+ if (err)
+ goto exit_remove;
+ }
+ }
+
+ for (i = 3; i < 8; i++) {
+ int j;
+ if (!(data->has_pwm & (1 << i)))
+ continue;
+ for (j = 0; j < files_pwm; j++) {
+ err = device_create_file(dev,
+ &w83793_left_pwm[(i - 3) * files_pwm
+ + j].dev_attr);
+ if (err)
+ goto exit_remove;
+ }
+ }
+
+ data->class_dev = hwmon_device_register(dev);
+ if (IS_ERR(data->class_dev)) {
+ err = PTR_ERR(data->class_dev);
+ goto exit_remove;
+ }
+
+ return 0;
+
+ /* Unregister sysfs hooks */
+
+exit_remove:
+ for (i = 0; i < ARRAY_SIZE(w83793_sensor_attr_2); i++)
+ device_remove_file(dev, &w83793_sensor_attr_2[i].dev_attr);
+
+ for (i = 0; i < ARRAY_SIZE(sda_single_files); i++)
+ device_remove_file(dev, &sda_single_files[i].dev_attr);
+
+ for (i = 0; i < ARRAY_SIZE(w83793_left_fan); i++)
+ device_remove_file(dev, &w83793_left_fan[i].dev_attr);
+
+ for (i = 0; i < ARRAY_SIZE(w83793_left_pwm); i++)
+ device_remove_file(dev, &w83793_left_pwm[i].dev_attr);
+
+ if (data->lm75[0] != NULL) {
+ i2c_detach_client(data->lm75[0]);
+ kfree(data->lm75[0]);
+ }
+ if (data->lm75[1] != NULL) {
+ i2c_detach_client(data->lm75[1]);
+ kfree(data->lm75[1]);
+ }
+detach_client:
+ i2c_detach_client(client);
+free_mem:
+ kfree(data);
+exit:
+ return err;
+}
+
+static void w83793_update_nonvolatile(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct w83793_data *data = i2c_get_clientdata(client);
+ int i, j;
+ /*
+ They are somewhat "stable" registers, and to update them everytime
+ takes so much time, it's just not worthy. Update them in a long
+ interval to avoid exception.
+ */
+ if (!(time_after(jiffies, data->last_nonvolatile + HZ * 300)
+ || !data->valid))
+ return;
+ /* update voltage limits */
+ for (i = 1; i < 3; i++) {
+ for (j = 0; j < ARRAY_SIZE(data->in); j++) {
+ data->in[j][i] =
+ w83793_read_value(client, W83793_REG_IN[j][i]);
+ }
+ data->in_low_bits[i] =
+ w83793_read_value(client, W83793_REG_IN_LOW_BITS[i]);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(data->fan_min); i++) {
+ /* Update the Fan measured value and limits */
+ if (!(data->has_fan & (1 << i))) {
+ continue;
+ }
+ data->fan_min[i] =
+ w83793_read_value(client, W83793_REG_FAN_MIN(i)) << 8;
+ data->fan_min[i] |=
+ w83793_read_value(client, W83793_REG_FAN_MIN(i) + 1);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(data->temp_fan_map); i++) {
+ data->temp_fan_map[i] =
+ w83793_read_value(client, W83793_REG_TEMP_FAN_MAP(i));
+ for (j = 1; j < 5; j++) {
+ data->temp[i][j] =
+ w83793_read_value(client, W83793_REG_TEMP[i][j]);
+ }
+ data->temp_cruise[i] =
+ w83793_read_value(client, W83793_REG_TEMP_CRUISE(i));
+ for (j = 0; j < 7; j++) {
+ data->sf2_pwm[i][j] =
+ w83793_read_value(client, W83793_REG_SF2_PWM(i, j));
+ data->sf2_temp[i][j] =
+ w83793_read_value(client,
+ W83793_REG_SF2_TEMP(i, j));
+ }
+ }
+
+ for (i = 0; i < ARRAY_SIZE(data->temp_mode); i++)
+ data->temp_mode[i] =
+ w83793_read_value(client, W83793_REG_TEMP_MODE[i]);
+
+ for (i = 0; i < ARRAY_SIZE(data->tolerance); i++) {
+ data->tolerance[i] =
+ w83793_read_value(client, W83793_REG_TEMP_TOL(i));
+ }
+
+ for (i = 0; i < ARRAY_SIZE(data->pwm); i++) {
+ if (!(data->has_pwm & (1 << i)))
+ continue;
+ data->pwm[i][PWM_NONSTOP] =
+ w83793_read_value(client, W83793_REG_PWM(i, PWM_NONSTOP));
+ data->pwm[i][PWM_START] =
+ w83793_read_value(client, W83793_REG_PWM(i, PWM_START));
+ data->pwm_stop_time[i] =
+ w83793_read_value(client, W83793_REG_PWM_STOP_TIME(i));
+ }
+
+ data->pwm_default = w83793_read_value(client, W83793_REG_PWM_DEFAULT);
+ data->pwm_enable = w83793_read_value(client, W83793_REG_PWM_ENABLE);
+ data->pwm_uptime = w83793_read_value(client, W83793_REG_PWM_UPTIME);
+ data->pwm_downtime = w83793_read_value(client, W83793_REG_PWM_DOWNTIME);
+ data->temp_critical =
+ w83793_read_value(client, W83793_REG_TEMP_CRITICAL);
+ data->beep_enable = w83793_read_value(client, W83793_REG_OVT_BEEP);
+
+ for (i = 0; i < ARRAY_SIZE(data->beeps); i++) {
+ data->beeps[i] = w83793_read_value(client, W83793_REG_BEEP(i));
+ }
+
+ data->last_nonvolatile = jiffies;
+}
+
+static struct w83793_data *w83793_update_device(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct w83793_data *data = i2c_get_clientdata(client);
+ int i;
+
+ mutex_lock(&data->update_lock);
+
+ if (!(time_after(jiffies, data->last_updated + HZ * 2)
+ || !data->valid))
+ goto END;
+
+ /* Update the voltages measured value and limits */
+ for (i = 0; i < ARRAY_SIZE(data->in); i++)
+ data->in[i][IN_READ] =
+ w83793_read_value(client, W83793_REG_IN[i][IN_READ]);
+
+ data->in_low_bits[IN_READ] =
+ w83793_read_value(client, W83793_REG_IN_LOW_BITS[IN_READ]);
+
+ for (i = 0; i < ARRAY_SIZE(data->fan); i++) {
+ if (!(data->has_fan & (1 << i))) {
+ continue;
+ }
+ data->fan[i] =
+ w83793_read_value(client, W83793_REG_FAN(i)) << 8;
+ data->fan[i] |=
+ w83793_read_value(client, W83793_REG_FAN(i) + 1);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(data->temp); i++)
+ data->temp[i][TEMP_READ] =
+ w83793_read_value(client, W83793_REG_TEMP[i][TEMP_READ]);
+
+ data->temp_low_bits =
+ w83793_read_value(client, W83793_REG_TEMP_LOW_BITS);
+
+ for (i = 0; i < ARRAY_SIZE(data->pwm); i++) {
+ if (data->has_pwm & (1 << i))
+ data->pwm[i][PWM_DUTY] =
+ w83793_read_value(client,
+ W83793_REG_PWM(i, PWM_DUTY));
+ }
+
+ for (i = 0; i < ARRAY_SIZE(data->alarms); i++)
+ data->alarms[i] =
+ w83793_read_value(client, W83793_REG_ALARM(i));
+ data->vid[0] = w83793_read_value(client, W83793_REG_VID_INA);
+ data->vid[1] = w83793_read_value(client, W83793_REG_VID_INB);
+ w83793_update_nonvolatile(dev);
+ data->last_updated = jiffies;
+ data->valid = 1;
+
+END:
+ mutex_unlock(&data->update_lock);
+ return data;
+}
+
+/* Ignore the possibility that somebody change bank outside the driver
+ Must be called with data->update_lock held, except during initialization */
+static u8 w83793_read_value(struct i2c_client *client, u16 reg)
+{
+ struct w83793_data *data = i2c_get_clientdata(client);
+ u8 res = 0xff;
+ u8 new_bank = reg >> 8;
+
+ new_bank |= data->bank & 0xfc;
+ if (data->bank != new_bank) {
+ if (i2c_smbus_write_byte_data
+ (client, W83793_REG_BANKSEL, new_bank) >= 0)
+ data->bank = new_bank;
+ else {
+ dev_err(&client->dev,
+ "set bank to %d failed, fall back "
+ "to bank %d, read reg 0x%x error\n",
+ new_bank, data->bank, reg);
+ res = 0x0; /* read 0x0 from the chip */
+ goto END;
+ }
+ }
+ res = i2c_smbus_read_byte_data(client, reg & 0xff);
+END:
+ return res;
+}
+
+/* Must be called with data->update_lock held, except during initialization */
+static int w83793_write_value(struct i2c_client *client, u16 reg, u8 value)
+{
+ struct w83793_data *data = i2c_get_clientdata(client);
+ int res;
+ u8 new_bank = reg >> 8;
+
+ new_bank |= data->bank & 0xfc;
+ if (data->bank != new_bank) {
+ if ((res = i2c_smbus_write_byte_data
+ (client, W83793_REG_BANKSEL, new_bank)) >= 0)
+ data->bank = new_bank;
+ else {
+ dev_err(&client->dev,
+ "set bank to %d failed, fall back "
+ "to bank %d, write reg 0x%x error\n",
+ new_bank, data->bank, reg);
+ goto END;
+ }
+ }
+
+ res = i2c_smbus_write_byte_data(client, reg & 0xff, value);
+END:
+ return res;
+}
+
+static int __init sensors_w83793_init(void)
+{
+ return i2c_add_driver(&w83793_driver);
+}
+
+static void __exit sensors_w83793_exit(void)
+{
+ i2c_del_driver(&w83793_driver);
+}
+
+MODULE_AUTHOR("Yuan Mu");
+MODULE_DESCRIPTION("w83793 driver");
+MODULE_LICENSE("GPL");
+
+module_init(sensors_w83793_init);
+module_exit(sensors_w83793_exit);
diff --git a/drivers/i2c/busses/i2c-ali1563.c b/drivers/i2c/busses/i2c-ali1563.c
index 33fbb47100a3..8e1e3f8e40a4 100644
--- a/drivers/i2c/busses/i2c-ali1563.c
+++ b/drivers/i2c/busses/i2c-ali1563.c
@@ -2,7 +2,7 @@
* i2c-ali1563.c - i2c driver for the ALi 1563 Southbridge
*
* Copyright (C) 2004 Patrick Mochel
- * 2005 Rudolf Marek <r.marek@sh.cvut.cz>
+ * 2005 Rudolf Marek <r.marek@assembler.cz>
*
* The 1563 southbridge is deceptively similar to the 1533, with a
* few notable exceptions. One of those happens to be the fact they
diff --git a/drivers/i2c/chips/tps65010.c b/drivers/i2c/chips/tps65010.c
index 60bef94cd25f..4ee56def61f2 100644
--- a/drivers/i2c/chips/tps65010.c
+++ b/drivers/i2c/chips/tps65010.c
@@ -82,7 +82,7 @@ struct tps65010 {
struct i2c_client client;
struct mutex lock;
int irq;
- struct work_struct work;
+ struct delayed_work work;
struct dentry *file;
unsigned charging:1;
unsigned por:1;
@@ -328,7 +328,7 @@ static void tps65010_interrupt(struct tps65010 *tps)
{
u8 tmp = 0, mask, poll;
- /* IRQs won't trigger irqs for certain events, but we can get
+ /* IRQs won't trigger for certain events, but we can get
* others by polling (normally, with external power applied).
*/
poll = 0;
@@ -411,10 +411,11 @@ static void tps65010_interrupt(struct tps65010 *tps)
}
/* handle IRQs and polling using keventd for now */
-static void tps65010_work(void *_tps)
+static void tps65010_work(struct work_struct *work)
{
- struct tps65010 *tps = _tps;
+ struct tps65010 *tps;
+ tps = container_of(work, struct tps65010, work.work);
mutex_lock(&tps->lock);
tps65010_interrupt(tps);
@@ -452,7 +453,7 @@ static irqreturn_t tps65010_irq(int irq, void *_tps)
disable_irq_nosync(irq);
set_bit(FLAG_IRQ_ENABLE, &tps->flags);
- (void) schedule_work(&tps->work);
+ (void) schedule_work(&tps->work.work);
return IRQ_HANDLED;
}
@@ -465,13 +466,15 @@ static int __exit tps65010_detach_client(struct i2c_client *client)
struct tps65010 *tps;
tps = container_of(client, struct tps65010, client);
+ free_irq(tps->irq, tps);
#ifdef CONFIG_ARM
if (machine_is_omap_h2())
omap_free_gpio(58);
if (machine_is_omap_osk())
omap_free_gpio(OMAP_MPUIO(1));
#endif
- free_irq(tps->irq, tps);
+ cancel_delayed_work(&tps->work);
+ flush_scheduled_work();
debugfs_remove(tps->file);
if (i2c_detach_client(client) == 0)
kfree(tps);
@@ -505,7 +508,7 @@ tps65010_probe(struct i2c_adapter *bus, int address, int kind)
return 0;
mutex_init(&tps->lock);
- INIT_WORK(&tps->work, tps65010_work, tps);
+ INIT_DELAYED_WORK(&tps->work, tps65010_work);
tps->irq = -1;
tps->client.addr = address;
tps->client.adapter = bus;
@@ -620,7 +623,7 @@ tps65010_probe(struct i2c_adapter *bus, int address, int kind)
(void) i2c_smbus_write_byte_data(&tps->client, TPS_MASK3, 0x0f
| i2c_smbus_read_byte_data(&tps->client, TPS_MASK3));
- tps65010_work(tps);
+ tps65010_work(&tps->work.work);
tps->file = debugfs_create_file(DRIVER_NAME, S_IRUGO, NULL,
tps, DEBUG_FOPS);
@@ -672,7 +675,7 @@ int tps65010_set_vbus_draw(unsigned mA)
&& test_and_set_bit(
FLAG_VBUS_CHANGED, &the_tps->flags)) {
/* gadget drivers call this in_irq() */
- (void) schedule_work(&the_tps->work);
+ (void) schedule_work(&the_tps->work.work);
}
local_irq_restore(flags);
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index e3a267622bb6..d33717c8afd4 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -2147,7 +2147,7 @@ static int ide_floppy_probe(ide_drive_t *drive)
printk("ide-floppy: passing drive %s to ide-scsi emulation.\n", drive->name);
goto failed;
}
- if ((floppy = (idefloppy_floppy_t *) kzalloc (sizeof (idefloppy_floppy_t), GFP_KERNEL)) == NULL) {
+ if ((floppy = kzalloc(sizeof (idefloppy_floppy_t), GFP_KERNEL)) == NULL) {
printk (KERN_ERR "ide-floppy: %s: Can't allocate a floppy structure\n", drive->name);
goto failed;
}
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index e2f4bb549063..b3bcd1d7315e 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -2573,11 +2573,11 @@ static idetape_stage_t *__idetape_kmalloc_stage (idetape_tape_t *tape, int full,
int pages = tape->pages_per_stage;
char *b_data = NULL;
- if ((stage = (idetape_stage_t *) kmalloc (sizeof (idetape_stage_t),GFP_KERNEL)) == NULL)
+ if ((stage = kmalloc(sizeof (idetape_stage_t),GFP_KERNEL)) == NULL)
return NULL;
stage->next = NULL;
- bh = stage->bh = (struct idetape_bh *)kmalloc(sizeof(struct idetape_bh), GFP_KERNEL);
+ bh = stage->bh = kmalloc(sizeof(struct idetape_bh), GFP_KERNEL);
if (bh == NULL)
goto abort;
bh->b_reqnext = NULL;
@@ -2607,7 +2607,7 @@ static idetape_stage_t *__idetape_kmalloc_stage (idetape_tape_t *tape, int full,
continue;
}
prev_bh = bh;
- if ((bh = (struct idetape_bh *)kmalloc(sizeof(struct idetape_bh), GFP_KERNEL)) == NULL) {
+ if ((bh = kmalloc(sizeof(struct idetape_bh), GFP_KERNEL)) == NULL) {
free_page((unsigned long) b_data);
goto abort;
}
@@ -4860,7 +4860,7 @@ static int ide_tape_probe(ide_drive_t *drive)
printk(KERN_WARNING "ide-tape: Use drive %s with ide-scsi emulation and osst.\n", drive->name);
printk(KERN_WARNING "ide-tape: OnStream support will be removed soon from ide-tape!\n");
}
- tape = (idetape_tape_t *) kzalloc (sizeof (idetape_tape_t), GFP_KERNEL);
+ tape = kzalloc(sizeof (idetape_tape_t), GFP_KERNEL);
if (tape == NULL) {
printk(KERN_ERR "ide-tape: %s: Can't allocate a tape structure\n", drive->name);
goto failed;
diff --git a/drivers/ide/pci/atiixp.c b/drivers/ide/pci/atiixp.c
index d55b938b1aeb..ffdffb6379ef 100644
--- a/drivers/ide/pci/atiixp.c
+++ b/drivers/ide/pci/atiixp.c
@@ -368,7 +368,6 @@ static struct pci_device_id atiixp_pci_tbl[] = {
{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, PCI_ANY_ID, PCI_ANY_ID, (PCI_CLASS_STORAGE_IDE<<8)|0x8a, 0xffff05, 1},
{ 0, },
};
MODULE_DEVICE_TABLE(pci, atiixp_pci_tbl);
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c
index e993a51f250e..08119da06d54 100644
--- a/drivers/ide/pci/hpt366.c
+++ b/drivers/ide/pci/hpt366.c
@@ -4,6 +4,7 @@
* Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org>
* Portions Copyright (C) 2001 Sun Microsystems, Inc.
* Portions Copyright (C) 2003 Red Hat Inc
+ * Portions Copyright (C) 2005-2006 MontaVista Software, Inc.
*
* Thanks to HighPoint Technologies for their assistance, and hardware.
* Special Thanks to Jon Burchmore in SanDiego for the deep pockets, his
@@ -11,9 +12,11 @@
* development and support.
*
*
- * Highpoint have their own driver (source except for the raid part)
- * available from http://www.highpoint-tech.com/hpt3xx-opensource-v131.tgz
- * This may be useful to anyone wanting to work on the mainstream hpt IDE.
+ * HighPoint has its own drivers (open source except for the RAID part)
+ * available from http://www.highpoint-tech.com/BIOS%20+%20Driver/.
+ * This may be useful to anyone wanting to work on this driver, however do not
+ * trust them too much since the code tends to become less and less meaningful
+ * as the time passes... :-/
*
* Note that final HPT370 support was done by force extraction of GPL.
*
@@ -52,6 +55,29 @@
* keeping me sane.
* Alan Cox <alan@redhat.com>
*
+ * - fix the clock turnaround code: it was writing to the wrong ports when
+ * called for the secondary channel, caching the current clock mode per-
+ * channel caused the cached register value to get out of sync with the
+ * actual one, the channels weren't serialized, the turnaround shouldn't
+ * be done on 66 MHz PCI bus
+ * - avoid calibrating PLL twice as the second time results in a wrong PCI
+ * frequency and thus in the wrong timings for the secondary channel
+ * - disable UltraATA/133 for HPT372 by default (50 MHz DPLL clock do not
+ * allow for this speed anyway)
+ * - add support for HPT302N and HPT371N clocking (the same as for HPT372N)
+ * - HPT371/N are single channel chips, so avoid touching the primary channel
+ * which exists only virtually (there's no pins for it)
+ * - fix/remove bad/unused timing tables and use one set of tables for the whole
+ * HPT37x chip family; save space by introducing the separate transfer mode
+ * table in which the mode lookup is done
+ * - use f_CNT value saved by the HighPoint BIOS as reading it directly gives
+ * the wrong PCI frequency since DPLL has already been calibrated by BIOS
+ * - fix the hotswap code: it caused RESET- to glitch when tristating the bus,
+ * and for HPT36x the obsolete HDIO_TRISTATE_HWIF handler was called instead
+ * - pass to init_chipset() handlers a copy of the IDE PCI device structure as
+ * they tamper with its fields
+ * <source@mvista.com>
+ *
*/
@@ -76,8 +102,8 @@
/* various tuning parameters */
#define HPT_RESET_STATE_ENGINE
-#undef HPT_DELAY_INTERRUPT
-#undef HPT_SERIALIZE_IO
+#undef HPT_DELAY_INTERRUPT
+#define HPT_SERIALIZE_IO 0
static const char *quirk_drives[] = {
"QUANTUM FIREBALLlct08 08",
@@ -141,305 +167,175 @@ static const char *bad_ata33[] = {
NULL
};
-struct chipset_bus_clock_list_entry {
- u8 xfer_speed;
- unsigned int chipset_settings;
+static u8 xfer_speeds[] = {
+ XFER_UDMA_6,
+ XFER_UDMA_5,
+ XFER_UDMA_4,
+ XFER_UDMA_3,
+ XFER_UDMA_2,
+ XFER_UDMA_1,
+ XFER_UDMA_0,
+
+ XFER_MW_DMA_2,
+ XFER_MW_DMA_1,
+ XFER_MW_DMA_0,
+
+ XFER_PIO_4,
+ XFER_PIO_3,
+ XFER_PIO_2,
+ XFER_PIO_1,
+ XFER_PIO_0
};
-/* key for bus clock timings
- * bit
- * 0:3 data_high_time. inactive time of DIOW_/DIOR_ for PIO and MW
- * DMA. cycles = value + 1
- * 4:8 data_low_time. active time of DIOW_/DIOR_ for PIO and MW
- * DMA. cycles = value + 1
- * 9:12 cmd_high_time. inactive time of DIOW_/DIOR_ during task file
- * register access.
- * 13:17 cmd_low_time. active time of DIOW_/DIOR_ during task file
- * register access.
- * 18:21 udma_cycle_time. clock freq and clock cycles for UDMA xfer.
- * during task file register access.
- * 22:24 pre_high_time. time to initialize 1st cycle for PIO and MW DMA
- * xfer.
- * 25:27 cmd_pre_high_time. time to initialize 1st PIO cycle for task
- * register access.
- * 28 UDMA enable
- * 29 DMA enable
- * 30 PIO_MST enable. if set, the chip is in bus master mode during
- * PIO.
- * 31 FIFO enable.
+/* Key for bus clock timings
+ * 36x 37x
+ * bits bits
+ * 0:3 0:3 data_high_time. Inactive time of DIOW_/DIOR_ for PIO and MW DMA.
+ * cycles = value + 1
+ * 4:7 4:8 data_low_time. Active time of DIOW_/DIOR_ for PIO and MW DMA.
+ * cycles = value + 1
+ * 8:11 9:12 cmd_high_time. Inactive time of DIOW_/DIOR_ during task file
+ * register access.
+ * 12:15 13:17 cmd_low_time. Active time of DIOW_/DIOR_ during task file
+ * register access.
+ * 16:18 18:20 udma_cycle_time. Clock cycles for UDMA xfer.
+ * - 21 CLK frequency: 0=ATA clock, 1=dual ATA clock.
+ * 19:21 22:24 pre_high_time. Time to initialize the 1st cycle for PIO and
+ * MW DMA xfer.
+ * 22:24 25:27 cmd_pre_high_time. Time to initialize the 1st PIO cycle for
+ * task file register access.
+ * 28 28 UDMA enable.
+ * 29 29 DMA enable.
+ * 30 30 PIO MST enable. If set, the chip is in bus master mode during
+ * PIO xfer.
+ * 31 31 FIFO enable.
*/
-static struct chipset_bus_clock_list_entry forty_base_hpt366[] = {
- { XFER_UDMA_4, 0x900fd943 },
- { XFER_UDMA_3, 0x900ad943 },
- { XFER_UDMA_2, 0x900bd943 },
- { XFER_UDMA_1, 0x9008d943 },
- { XFER_UDMA_0, 0x9008d943 },
-
- { XFER_MW_DMA_2, 0xa008d943 },
- { XFER_MW_DMA_1, 0xa010d955 },
- { XFER_MW_DMA_0, 0xa010d9fc },
-
- { XFER_PIO_4, 0xc008d963 },
- { XFER_PIO_3, 0xc010d974 },
- { XFER_PIO_2, 0xc010d997 },
- { XFER_PIO_1, 0xc010d9c7 },
- { XFER_PIO_0, 0xc018d9d9 },
- { 0, 0x0120d9d9 }
-};
-
-static struct chipset_bus_clock_list_entry thirty_three_base_hpt366[] = {
- { XFER_UDMA_4, 0x90c9a731 },
- { XFER_UDMA_3, 0x90cfa731 },
- { XFER_UDMA_2, 0x90caa731 },
- { XFER_UDMA_1, 0x90cba731 },
- { XFER_UDMA_0, 0x90c8a731 },
-
- { XFER_MW_DMA_2, 0xa0c8a731 },
- { XFER_MW_DMA_1, 0xa0c8a732 }, /* 0xa0c8a733 */
- { XFER_MW_DMA_0, 0xa0c8a797 },
-
- { XFER_PIO_4, 0xc0c8a731 },
- { XFER_PIO_3, 0xc0c8a742 },
- { XFER_PIO_2, 0xc0d0a753 },
- { XFER_PIO_1, 0xc0d0a7a3 }, /* 0xc0d0a793 */
- { XFER_PIO_0, 0xc0d0a7aa }, /* 0xc0d0a7a7 */
- { 0, 0x0120a7a7 }
-};
-
-static struct chipset_bus_clock_list_entry twenty_five_base_hpt366[] = {
- { XFER_UDMA_4, 0x90c98521 },
- { XFER_UDMA_3, 0x90cf8521 },
- { XFER_UDMA_2, 0x90cf8521 },
- { XFER_UDMA_1, 0x90cb8521 },
- { XFER_UDMA_0, 0x90cb8521 },
-
- { XFER_MW_DMA_2, 0xa0ca8521 },
- { XFER_MW_DMA_1, 0xa0ca8532 },
- { XFER_MW_DMA_0, 0xa0ca8575 },
-
- { XFER_PIO_4, 0xc0ca8521 },
- { XFER_PIO_3, 0xc0ca8532 },
- { XFER_PIO_2, 0xc0ca8542 },
- { XFER_PIO_1, 0xc0d08572 },
- { XFER_PIO_0, 0xc0d08585 },
- { 0, 0x01208585 }
-};
-
-/* from highpoint documentation. these are old values */
-static struct chipset_bus_clock_list_entry thirty_three_base_hpt370[] = {
-/* { XFER_UDMA_5, 0x1A85F442, 0x16454e31 }, */
- { XFER_UDMA_5, 0x16454e31 },
- { XFER_UDMA_4, 0x16454e31 },
- { XFER_UDMA_3, 0x166d4e31 },
- { XFER_UDMA_2, 0x16494e31 },
- { XFER_UDMA_1, 0x164d4e31 },
- { XFER_UDMA_0, 0x16514e31 },
-
- { XFER_MW_DMA_2, 0x26514e21 },
- { XFER_MW_DMA_1, 0x26514e33 },
- { XFER_MW_DMA_0, 0x26514e97 },
-
- { XFER_PIO_4, 0x06514e21 },
- { XFER_PIO_3, 0x06514e22 },
- { XFER_PIO_2, 0x06514e33 },
- { XFER_PIO_1, 0x06914e43 },
- { XFER_PIO_0, 0x06914e57 },
- { 0, 0x06514e57 }
-};
-
-static struct chipset_bus_clock_list_entry sixty_six_base_hpt370[] = {
- { XFER_UDMA_5, 0x14846231 },
- { XFER_UDMA_4, 0x14886231 },
- { XFER_UDMA_3, 0x148c6231 },
- { XFER_UDMA_2, 0x148c6231 },
- { XFER_UDMA_1, 0x14906231 },
- { XFER_UDMA_0, 0x14986231 },
-
- { XFER_MW_DMA_2, 0x26514e21 },
- { XFER_MW_DMA_1, 0x26514e33 },
- { XFER_MW_DMA_0, 0x26514e97 },
-
- { XFER_PIO_4, 0x06514e21 },
- { XFER_PIO_3, 0x06514e22 },
- { XFER_PIO_2, 0x06514e33 },
- { XFER_PIO_1, 0x06914e43 },
- { XFER_PIO_0, 0x06914e57 },
- { 0, 0x06514e57 }
-};
-
-/* these are the current (4 sep 2001) timings from highpoint */
-static struct chipset_bus_clock_list_entry thirty_three_base_hpt370a[] = {
- { XFER_UDMA_5, 0x12446231 },
- { XFER_UDMA_4, 0x12446231 },
- { XFER_UDMA_3, 0x126c6231 },
- { XFER_UDMA_2, 0x12486231 },
- { XFER_UDMA_1, 0x124c6233 },
- { XFER_UDMA_0, 0x12506297 },
-
- { XFER_MW_DMA_2, 0x22406c31 },
- { XFER_MW_DMA_1, 0x22406c33 },
- { XFER_MW_DMA_0, 0x22406c97 },
-
- { XFER_PIO_4, 0x06414e31 },
- { XFER_PIO_3, 0x06414e42 },
- { XFER_PIO_2, 0x06414e53 },
- { XFER_PIO_1, 0x06814e93 },
- { XFER_PIO_0, 0x06814ea7 },
- { 0, 0x06814ea7 }
-};
-
-/* 2x 33MHz timings */
-static struct chipset_bus_clock_list_entry sixty_six_base_hpt370a[] = {
- { XFER_UDMA_5, 0x1488e673 },
- { XFER_UDMA_4, 0x1488e673 },
- { XFER_UDMA_3, 0x1498e673 },
- { XFER_UDMA_2, 0x1490e673 },
- { XFER_UDMA_1, 0x1498e677 },
- { XFER_UDMA_0, 0x14a0e73f },
-
- { XFER_MW_DMA_2, 0x2480fa73 },
- { XFER_MW_DMA_1, 0x2480fa77 },
- { XFER_MW_DMA_0, 0x2480fb3f },
-
- { XFER_PIO_4, 0x0c82be73 },
- { XFER_PIO_3, 0x0c82be95 },
- { XFER_PIO_2, 0x0c82beb7 },
- { XFER_PIO_1, 0x0d02bf37 },
- { XFER_PIO_0, 0x0d02bf5f },
- { 0, 0x0d02bf5f }
-};
-static struct chipset_bus_clock_list_entry fifty_base_hpt370a[] = {
- { XFER_UDMA_5, 0x12848242 },
- { XFER_UDMA_4, 0x12ac8242 },
- { XFER_UDMA_3, 0x128c8242 },
- { XFER_UDMA_2, 0x120c8242 },
- { XFER_UDMA_1, 0x12148254 },
- { XFER_UDMA_0, 0x121882ea },
-
- { XFER_MW_DMA_2, 0x22808242 },
- { XFER_MW_DMA_1, 0x22808254 },
- { XFER_MW_DMA_0, 0x228082ea },
-
- { XFER_PIO_4, 0x0a81f442 },
- { XFER_PIO_3, 0x0a81f443 },
- { XFER_PIO_2, 0x0a81f454 },
- { XFER_PIO_1, 0x0ac1f465 },
- { XFER_PIO_0, 0x0ac1f48a },
- { 0, 0x0ac1f48a }
+static u32 forty_base_hpt36x[] = {
+ /* XFER_UDMA_6 */ 0x900fd943,
+ /* XFER_UDMA_5 */ 0x900fd943,
+ /* XFER_UDMA_4 */ 0x900fd943,
+ /* XFER_UDMA_3 */ 0x900ad943,
+ /* XFER_UDMA_2 */ 0x900bd943,
+ /* XFER_UDMA_1 */ 0x9008d943,
+ /* XFER_UDMA_0 */ 0x9008d943,
+
+ /* XFER_MW_DMA_2 */ 0xa008d943,
+ /* XFER_MW_DMA_1 */ 0xa010d955,
+ /* XFER_MW_DMA_0 */ 0xa010d9fc,
+
+ /* XFER_PIO_4 */ 0xc008d963,
+ /* XFER_PIO_3 */ 0xc010d974,
+ /* XFER_PIO_2 */ 0xc010d997,
+ /* XFER_PIO_1 */ 0xc010d9c7,
+ /* XFER_PIO_0 */ 0xc018d9d9
};
-static struct chipset_bus_clock_list_entry thirty_three_base_hpt372[] = {
- { XFER_UDMA_6, 0x1c81dc62 },
- { XFER_UDMA_5, 0x1c6ddc62 },
- { XFER_UDMA_4, 0x1c8ddc62 },
- { XFER_UDMA_3, 0x1c8edc62 }, /* checkme */
- { XFER_UDMA_2, 0x1c91dc62 },
- { XFER_UDMA_1, 0x1c9adc62 }, /* checkme */
- { XFER_UDMA_0, 0x1c82dc62 }, /* checkme */
-
- { XFER_MW_DMA_2, 0x2c829262 },
- { XFER_MW_DMA_1, 0x2c829266 }, /* checkme */
- { XFER_MW_DMA_0, 0x2c82922e }, /* checkme */
-
- { XFER_PIO_4, 0x0c829c62 },
- { XFER_PIO_3, 0x0c829c84 },
- { XFER_PIO_2, 0x0c829ca6 },
- { XFER_PIO_1, 0x0d029d26 },
- { XFER_PIO_0, 0x0d029d5e },
- { 0, 0x0d029d5e }
+static u32 thirty_three_base_hpt36x[] = {
+ /* XFER_UDMA_6 */ 0x90c9a731,
+ /* XFER_UDMA_5 */ 0x90c9a731,
+ /* XFER_UDMA_4 */ 0x90c9a731,
+ /* XFER_UDMA_3 */ 0x90cfa731,
+ /* XFER_UDMA_2 */ 0x90caa731,
+ /* XFER_UDMA_1 */ 0x90cba731,
+ /* XFER_UDMA_0 */ 0x90c8a731,
+
+ /* XFER_MW_DMA_2 */ 0xa0c8a731,
+ /* XFER_MW_DMA_1 */ 0xa0c8a732, /* 0xa0c8a733 */
+ /* XFER_MW_DMA_0 */ 0xa0c8a797,
+
+ /* XFER_PIO_4 */ 0xc0c8a731,
+ /* XFER_PIO_3 */ 0xc0c8a742,
+ /* XFER_PIO_2 */ 0xc0d0a753,
+ /* XFER_PIO_1 */ 0xc0d0a7a3, /* 0xc0d0a793 */
+ /* XFER_PIO_0 */ 0xc0d0a7aa /* 0xc0d0a7a7 */
};
-static struct chipset_bus_clock_list_entry fifty_base_hpt372[] = {
- { XFER_UDMA_5, 0x12848242 },
- { XFER_UDMA_4, 0x12ac8242 },
- { XFER_UDMA_3, 0x128c8242 },
- { XFER_UDMA_2, 0x120c8242 },
- { XFER_UDMA_1, 0x12148254 },
- { XFER_UDMA_0, 0x121882ea },
-
- { XFER_MW_DMA_2, 0x22808242 },
- { XFER_MW_DMA_1, 0x22808254 },
- { XFER_MW_DMA_0, 0x228082ea },
-
- { XFER_PIO_4, 0x0a81f442 },
- { XFER_PIO_3, 0x0a81f443 },
- { XFER_PIO_2, 0x0a81f454 },
- { XFER_PIO_1, 0x0ac1f465 },
- { XFER_PIO_0, 0x0ac1f48a },
- { 0, 0x0a81f443 }
+static u32 twenty_five_base_hpt36x[] = {
+ /* XFER_UDMA_6 */ 0x90c98521,
+ /* XFER_UDMA_5 */ 0x90c98521,
+ /* XFER_UDMA_4 */ 0x90c98521,
+ /* XFER_UDMA_3 */ 0x90cf8521,
+ /* XFER_UDMA_2 */ 0x90cf8521,
+ /* XFER_UDMA_1 */ 0x90cb8521,
+ /* XFER_UDMA_0 */ 0x90cb8521,
+
+ /* XFER_MW_DMA_2 */ 0xa0ca8521,
+ /* XFER_MW_DMA_1 */ 0xa0ca8532,
+ /* XFER_MW_DMA_0 */ 0xa0ca8575,
+
+ /* XFER_PIO_4 */ 0xc0ca8521,
+ /* XFER_PIO_3 */ 0xc0ca8532,
+ /* XFER_PIO_2 */ 0xc0ca8542,
+ /* XFER_PIO_1 */ 0xc0d08572,
+ /* XFER_PIO_0 */ 0xc0d08585
};
-static struct chipset_bus_clock_list_entry sixty_six_base_hpt372[] = {
- { XFER_UDMA_6, 0x1c869c62 },
- { XFER_UDMA_5, 0x1cae9c62 },
- { XFER_UDMA_4, 0x1c8a9c62 },
- { XFER_UDMA_3, 0x1c8e9c62 },
- { XFER_UDMA_2, 0x1c929c62 },
- { XFER_UDMA_1, 0x1c9a9c62 },
- { XFER_UDMA_0, 0x1c829c62 },
-
- { XFER_MW_DMA_2, 0x2c829c62 },
- { XFER_MW_DMA_1, 0x2c829c66 },
- { XFER_MW_DMA_0, 0x2c829d2e },
-
- { XFER_PIO_4, 0x0c829c62 },
- { XFER_PIO_3, 0x0c829c84 },
- { XFER_PIO_2, 0x0c829ca6 },
- { XFER_PIO_1, 0x0d029d26 },
- { XFER_PIO_0, 0x0d029d5e },
- { 0, 0x0d029d26 }
+static u32 thirty_three_base_hpt37x[] = {
+ /* XFER_UDMA_6 */ 0x12446231, /* 0x12646231 ?? */
+ /* XFER_UDMA_5 */ 0x12446231,
+ /* XFER_UDMA_4 */ 0x12446231,
+ /* XFER_UDMA_3 */ 0x126c6231,
+ /* XFER_UDMA_2 */ 0x12486231,
+ /* XFER_UDMA_1 */ 0x124c6233,
+ /* XFER_UDMA_0 */ 0x12506297,
+
+ /* XFER_MW_DMA_2 */ 0x22406c31,
+ /* XFER_MW_DMA_1 */ 0x22406c33,
+ /* XFER_MW_DMA_0 */ 0x22406c97,
+
+ /* XFER_PIO_4 */ 0x06414e31,
+ /* XFER_PIO_3 */ 0x06414e42,
+ /* XFER_PIO_2 */ 0x06414e53,
+ /* XFER_PIO_1 */ 0x06814e93,
+ /* XFER_PIO_0 */ 0x06814ea7
};
-static struct chipset_bus_clock_list_entry thirty_three_base_hpt374[] = {
- { XFER_UDMA_6, 0x12808242 },
- { XFER_UDMA_5, 0x12848242 },
- { XFER_UDMA_4, 0x12ac8242 },
- { XFER_UDMA_3, 0x128c8242 },
- { XFER_UDMA_2, 0x120c8242 },
- { XFER_UDMA_1, 0x12148254 },
- { XFER_UDMA_0, 0x121882ea },
-
- { XFER_MW_DMA_2, 0x22808242 },
- { XFER_MW_DMA_1, 0x22808254 },
- { XFER_MW_DMA_0, 0x228082ea },
-
- { XFER_PIO_4, 0x0a81f442 },
- { XFER_PIO_3, 0x0a81f443 },
- { XFER_PIO_2, 0x0a81f454 },
- { XFER_PIO_1, 0x0ac1f465 },
- { XFER_PIO_0, 0x0ac1f48a },
- { 0, 0x06814e93 }
+static u32 fifty_base_hpt37x[] = {
+ /* XFER_UDMA_6 */ 0x12848242,
+ /* XFER_UDMA_5 */ 0x12848242,
+ /* XFER_UDMA_4 */ 0x12ac8242,
+ /* XFER_UDMA_3 */ 0x128c8242,
+ /* XFER_UDMA_2 */ 0x120c8242,
+ /* XFER_UDMA_1 */ 0x12148254,
+ /* XFER_UDMA_0 */ 0x121882ea,
+
+ /* XFER_MW_DMA_2 */ 0x22808242,
+ /* XFER_MW_DMA_1 */ 0x22808254,
+ /* XFER_MW_DMA_0 */ 0x228082ea,
+
+ /* XFER_PIO_4 */ 0x0a81f442,
+ /* XFER_PIO_3 */ 0x0a81f443,
+ /* XFER_PIO_2 */ 0x0a81f454,
+ /* XFER_PIO_1 */ 0x0ac1f465,
+ /* XFER_PIO_0 */ 0x0ac1f48a
};
-/* FIXME: 50MHz timings for HPT374 */
-
-#if 0
-static struct chipset_bus_clock_list_entry sixty_six_base_hpt374[] = {
- { XFER_UDMA_6, 0x12406231 }, /* checkme */
- { XFER_UDMA_5, 0x12446231 }, /* 0x14846231 */
- { XFER_UDMA_4, 0x16814ea7 }, /* 0x14886231 */
- { XFER_UDMA_3, 0x16814ea7 }, /* 0x148c6231 */
- { XFER_UDMA_2, 0x16814ea7 }, /* 0x148c6231 */
- { XFER_UDMA_1, 0x16814ea7 }, /* 0x14906231 */
- { XFER_UDMA_0, 0x16814ea7 }, /* 0x14986231 */
- { XFER_MW_DMA_2, 0x16814ea7 }, /* 0x26514e21 */
- { XFER_MW_DMA_1, 0x16814ea7 }, /* 0x26514e97 */
- { XFER_MW_DMA_0, 0x16814ea7 }, /* 0x26514e97 */
- { XFER_PIO_4, 0x06814ea7 }, /* 0x06514e21 */
- { XFER_PIO_3, 0x06814ea7 }, /* 0x06514e22 */
- { XFER_PIO_2, 0x06814ea7 }, /* 0x06514e33 */
- { XFER_PIO_1, 0x06814ea7 }, /* 0x06914e43 */
- { XFER_PIO_0, 0x06814ea7 }, /* 0x06914e57 */
- { 0, 0x06814ea7 }
+static u32 sixty_six_base_hpt37x[] = {
+ /* XFER_UDMA_6 */ 0x1c869c62,
+ /* XFER_UDMA_5 */ 0x1cae9c62, /* 0x1c8a9c62 */
+ /* XFER_UDMA_4 */ 0x1c8a9c62,
+ /* XFER_UDMA_3 */ 0x1c8e9c62,
+ /* XFER_UDMA_2 */ 0x1c929c62,
+ /* XFER_UDMA_1 */ 0x1c9a9c62,
+ /* XFER_UDMA_0 */ 0x1c829c62,
+
+ /* XFER_MW_DMA_2 */ 0x2c829c62,
+ /* XFER_MW_DMA_1 */ 0x2c829c66,
+ /* XFER_MW_DMA_0 */ 0x2c829d2e,
+
+ /* XFER_PIO_4 */ 0x0c829c62,
+ /* XFER_PIO_3 */ 0x0c829c84,
+ /* XFER_PIO_2 */ 0x0c829ca6,
+ /* XFER_PIO_1 */ 0x0d029d26,
+ /* XFER_PIO_0 */ 0x0d029d5e
};
-#endif
#define HPT366_DEBUG_DRIVE_INFO 0
#define HPT374_ALLOW_ATA133_6 0
#define HPT371_ALLOW_ATA133_6 0
#define HPT302_ALLOW_ATA133_6 0
-#define HPT372_ALLOW_ATA133_6 1
+#define HPT372_ALLOW_ATA133_6 0
#define HPT370_ALLOW_ATA100_5 1
#define HPT366_ALLOW_ATA66_4 1
#define HPT366_ALLOW_ATA66_3 1
@@ -461,9 +357,10 @@ struct hpt_info
int revision; /* Chipset revision */
int flags; /* Chipset properties */
#define PLL_MODE 1
-#define IS_372N 2
+#define IS_3xxN 2
+#define PCI_66MHZ 4
/* Speed table */
- struct chipset_bus_clock_list_entry *speed;
+ u32 *speed;
};
/*
@@ -600,12 +497,20 @@ static int check_in_drive_lists (ide_drive_t *drive, const char **list)
return 0;
}
-static unsigned int pci_bus_clock_list (u8 speed, struct chipset_bus_clock_list_entry * chipset_table)
+static u32 pci_bus_clock_list(u8 speed, u32 *chipset_table)
{
- for ( ; chipset_table->xfer_speed ; chipset_table++)
- if (chipset_table->xfer_speed == speed)
- return chipset_table->chipset_settings;
- return chipset_table->chipset_settings;
+ int i;
+
+ /*
+ * Lookup the transfer mode table to get the index into
+ * the timing table.
+ *
+ * NOTE: For XFER_PIO_SLOW, PIO mode 0 timings will be used.
+ */
+ for (i = 0; i < ARRAY_SIZE(xfer_speeds) - 1; i++)
+ if (xfer_speeds[i] == speed)
+ break;
+ return chipset_table[i];
}
static int hpt36x_tune_chipset(ide_drive_t *drive, u8 xferspeed)
@@ -956,156 +861,127 @@ static int hpt374_ide_dma_end (ide_drive_t *drive)
}
/**
- * hpt372n_set_clock - perform clock switching dance
- * @drive: Drive to switch
- * @mode: Switching mode (0x21 for write, 0x23 otherwise)
+ * hpt3xxn_set_clock - perform clock switching dance
+ * @hwif: hwif to switch
+ * @mode: clocking mode (0x21 for write, 0x23 otherwise)
*
- * Switch the DPLL clock on the HPT372N devices. This is a
- * right mess.
+ * Switch the DPLL clock on the HPT3xxN devices. This is a right mess.
+ * NOTE: avoid touching the disabled primary channel on HPT371N -- it
+ * doesn't physically exist anyway...
*/
-
-static void hpt372n_set_clock(ide_drive_t *drive, int mode)
+
+static void hpt3xxn_set_clock(ide_hwif_t *hwif, u8 mode)
{
- ide_hwif_t *hwif = HWIF(drive);
-
- /* FIXME: should we check for DMA active and BUG() */
+ u8 mcr1, scr2 = hwif->INB(hwif->dma_master + 0x7b);
+
+ if ((scr2 & 0x7f) == mode)
+ return;
+
+ /* MISC. control register 1 has the channel enable bit... */
+ mcr1 = hwif->INB(hwif->dma_master + 0x70);
+
/* Tristate the bus */
- outb(0x80, hwif->dma_base+0x73);
- outb(0x80, hwif->dma_base+0x77);
-
+ if (mcr1 & 0x04)
+ hwif->OUTB(0x80, hwif->dma_master + 0x73);
+ hwif->OUTB(0x80, hwif->dma_master + 0x77);
+
/* Switch clock and reset channels */
- outb(mode, hwif->dma_base+0x7B);
- outb(0xC0, hwif->dma_base+0x79);
-
+ hwif->OUTB(mode, hwif->dma_master + 0x7b);
+ hwif->OUTB(0xc0, hwif->dma_master + 0x79);
+
/* Reset state machines */
- outb(0x37, hwif->dma_base+0x70);
- outb(0x37, hwif->dma_base+0x74);
-
+ if (mcr1 & 0x04)
+ hwif->OUTB(0x37, hwif->dma_master + 0x70);
+ hwif->OUTB(0x37, hwif->dma_master + 0x74);
+
/* Complete reset */
- outb(0x00, hwif->dma_base+0x79);
-
+ hwif->OUTB(0x00, hwif->dma_master + 0x79);
+
/* Reconnect channels to bus */
- outb(0x00, hwif->dma_base+0x73);
- outb(0x00, hwif->dma_base+0x77);
+ if (mcr1 & 0x04)
+ hwif->OUTB(0x00, hwif->dma_master + 0x73);
+ hwif->OUTB(0x00, hwif->dma_master + 0x77);
}
/**
- * hpt372n_rw_disk - prepare for I/O
+ * hpt3xxn_rw_disk - prepare for I/O
* @drive: drive for command
* @rq: block request structure
*
- * This is called when a disk I/O is issued to the 372N.
+ * This is called when a disk I/O is issued to HPT3xxN.
* We need it because of the clock switching.
*/
-static void hpt372n_rw_disk(ide_drive_t *drive, struct request *rq)
-{
- ide_hwif_t *hwif = drive->hwif;
- int wantclock;
-
- wantclock = rq_data_dir(rq) ? 0x23 : 0x21;
-
- if (hwif->config_data != wantclock) {
- hpt372n_set_clock(drive, wantclock);
- hwif->config_data = wantclock;
- }
-}
-
-/*
- * Since SUN Cobalt is attempting to do this operation, I should disclose
- * this has been a long time ago Thu Jul 27 16:40:57 2000 was the patch date
- * HOTSWAP ATA Infrastructure.
- */
-
-static void hpt3xx_reset (ide_drive_t *drive)
-{
-}
-
-static int hpt3xx_tristate (ide_drive_t * drive, int state)
+static void hpt3xxn_rw_disk(ide_drive_t *drive, struct request *rq)
{
ide_hwif_t *hwif = HWIF(drive);
- struct pci_dev *dev = hwif->pci_dev;
- u8 reg59h = 0, reset = (hwif->channel) ? 0x80 : 0x40;
- u8 regXXh = 0, state_reg= (hwif->channel) ? 0x57 : 0x53;
-
- pci_read_config_byte(dev, 0x59, &reg59h);
- pci_read_config_byte(dev, state_reg, &regXXh);
+ u8 wantclock = rq_data_dir(rq) ? 0x23 : 0x21;
- if (state) {
- (void) ide_do_reset(drive);
- pci_write_config_byte(dev, state_reg, regXXh|0x80);
- pci_write_config_byte(dev, 0x59, reg59h|reset);
- } else {
- pci_write_config_byte(dev, 0x59, reg59h & ~(reset));
- pci_write_config_byte(dev, state_reg, regXXh & ~(0x80));
- (void) ide_do_reset(drive);
- }
- return 0;
+ hpt3xxn_set_clock(hwif, wantclock);
}
/*
- * set/get power state for a drive.
- * turning the power off does the following things:
- * 1) soft-reset the drive
- * 2) tri-states the ide bus
+ * Set/get power state for a drive.
*
- * when we turn things back on, we need to re-initialize things.
+ * When we turn the power back on, we need to re-initialize things.
*/
#define TRISTATE_BIT 0x8000
-static int hpt370_busproc(ide_drive_t * drive, int state)
+
+static int hpt3xx_busproc(ide_drive_t *drive, int state)
{
ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = hwif->pci_dev;
- u8 tristate = 0, resetmask = 0, bus_reg = 0;
- u16 tri_reg;
+ u8 tristate, resetmask, bus_reg = 0;
+ u16 tri_reg = 0;
hwif->bus_state = state;
if (hwif->channel) {
/* secondary channel */
- tristate = 0x56;
- resetmask = 0x80;
+ tristate = 0x56;
+ resetmask = 0x80;
} else {
/* primary channel */
- tristate = 0x52;
+ tristate = 0x52;
resetmask = 0x40;
}
- /* grab status */
+ /* Grab the status. */
pci_read_config_word(dev, tristate, &tri_reg);
pci_read_config_byte(dev, 0x59, &bus_reg);
- /* set the state. we don't set it if we don't need to do so.
- * make sure that the drive knows that it has failed if it's off */
+ /*
+ * Set the state. We don't set it if we don't need to do so.
+ * Make sure that the drive knows that it has failed if it's off.
+ */
switch (state) {
case BUSSTATE_ON:
- hwif->drives[0].failures = 0;
- hwif->drives[1].failures = 0;
- if ((bus_reg & resetmask) == 0)
+ if (!(bus_reg & resetmask))
return 0;
- tri_reg &= ~TRISTATE_BIT;
- bus_reg &= ~resetmask;
- break;
+ hwif->drives[0].failures = hwif->drives[1].failures = 0;
+
+ pci_write_config_byte(dev, 0x59, bus_reg & ~resetmask);
+ pci_write_config_word(dev, tristate, tri_reg & ~TRISTATE_BIT);
+ return 0;
case BUSSTATE_OFF:
- hwif->drives[0].failures = hwif->drives[0].max_failures + 1;
- hwif->drives[1].failures = hwif->drives[1].max_failures + 1;
- if ((tri_reg & TRISTATE_BIT) == 0 && (bus_reg & resetmask))
+ if ((bus_reg & resetmask) && !(tri_reg & TRISTATE_BIT))
return 0;
tri_reg &= ~TRISTATE_BIT;
- bus_reg |= resetmask;
break;
case BUSSTATE_TRISTATE:
- hwif->drives[0].failures = hwif->drives[0].max_failures + 1;
- hwif->drives[1].failures = hwif->drives[1].max_failures + 1;
- if ((tri_reg & TRISTATE_BIT) && (bus_reg & resetmask))
+ if ((bus_reg & resetmask) && (tri_reg & TRISTATE_BIT))
return 0;
tri_reg |= TRISTATE_BIT;
- bus_reg |= resetmask;
break;
+ default:
+ return -EINVAL;
}
- pci_write_config_byte(dev, 0x59, bus_reg);
- pci_write_config_word(dev, tristate, tri_reg);
+ hwif->drives[0].failures = hwif->drives[0].max_failures + 1;
+ hwif->drives[1].failures = hwif->drives[1].max_failures + 1;
+
+ pci_write_config_word(dev, tristate, tri_reg);
+ pci_write_config_byte(dev, 0x59, bus_reg | resetmask);
return 0;
}
@@ -1119,14 +995,14 @@ static void __devinit hpt366_clocking(ide_hwif_t *hwif)
/* detect bus speed by looking at control reg timing: */
switch((reg1 >> 8) & 7) {
case 5:
- info->speed = forty_base_hpt366;
+ info->speed = forty_base_hpt36x;
break;
case 9:
- info->speed = twenty_five_base_hpt366;
+ info->speed = twenty_five_base_hpt36x;
break;
case 7:
default:
- info->speed = thirty_three_base_hpt366;
+ info->speed = thirty_three_base_hpt36x;
break;
}
}
@@ -1136,9 +1012,9 @@ static void __devinit hpt37x_clocking(ide_hwif_t *hwif)
struct hpt_info *info = ide_get_hwifdata(hwif);
struct pci_dev *dev = hwif->pci_dev;
int adjust, i;
- u16 freq;
- u32 pll;
- u8 reg5bh;
+ u16 freq = 0;
+ u32 pll, temp = 0;
+ u8 reg5bh = 0, mcr1 = 0;
/*
* default to pci clock. make sure MA15/16 are set to output
@@ -1151,27 +1027,40 @@ static void __devinit hpt37x_clocking(ide_hwif_t *hwif)
pci_write_config_byte(dev, 0x5b, 0x23);
/*
- * set up the PLL. we need to adjust it so that it's stable.
- * freq = Tpll * 192 / Tpci
+ * We'll have to read f_CNT value in order to determine
+ * the PCI clock frequency according to the following ratio:
+ *
+ * f_CNT = Fpci * 192 / Fdpll
+ *
+ * First try reading the register in which the HighPoint BIOS
+ * saves f_CNT value before reprogramming the DPLL from its
+ * default setting (which differs for the various chips).
+ * NOTE: This register is only accessible via I/O space.
*
- * Todo. For non x86 should probably check the dword is
- * set to 0xABCDExxx indicating the BIOS saved f_CNT
+ * In case the signature check fails, we'll have to resort to
+ * reading the f_CNT register itself in hopes that nobody has
+ * touched the DPLL yet...
*/
- pci_read_config_word(dev, 0x78, &freq);
- freq &= 0x1FF;
-
+ temp = inl(pci_resource_start(dev, 4) + 0x90);
+ if ((temp & 0xFFFFF000) != 0xABCDE000) {
+ printk(KERN_WARNING "HPT37X: no clock data saved by BIOS\n");
+
+ /* Calculate the average value of f_CNT */
+ for (temp = i = 0; i < 128; i++) {
+ pci_read_config_word(dev, 0x78, &freq);
+ temp += freq & 0x1ff;
+ mdelay(1);
+ }
+ freq = temp / 128;
+ } else
+ freq = temp & 0x1ff;
+
/*
- * The 372N uses different PCI clock information and has
- * some other complications
- * On PCI33 timing we must clock switch
- * On PCI66 timing we must NOT use the PCI clock
- *
- * Currently we always set up the PLL for the 372N
+ * HPT3xxN chips use different PCI clock information.
+ * Currently we always set up the PLL for them.
*/
-
- if(info->flags & IS_372N)
- {
- printk(KERN_INFO "hpt: HPT372N detected, using 372N timing.\n");
+
+ if (info->flags & IS_3xxN) {
if(freq < 0x55)
pll = F_LOW_PCI_33;
else if(freq < 0x70)
@@ -1180,10 +1069,8 @@ static void __devinit hpt37x_clocking(ide_hwif_t *hwif)
pll = F_LOW_PCI_50;
else
pll = F_LOW_PCI_66;
-
- printk(KERN_INFO "FREQ: %d PLL: %d\n", freq, pll);
-
- /* We always use the pll not the PCI clock on 372N */
+
+ printk(KERN_INFO "HPT3xxN detected, FREQ: %d, PLL: %d\n", freq, pll);
}
else
{
@@ -1197,41 +1084,22 @@ static void __devinit hpt37x_clocking(ide_hwif_t *hwif)
pll = F_LOW_PCI_66;
if (pll == F_LOW_PCI_33) {
- if (info->revision >= 8)
- info->speed = thirty_three_base_hpt374;
- else if (info->revision >= 5)
- info->speed = thirty_three_base_hpt372;
- else if (info->revision >= 4)
- info->speed = thirty_three_base_hpt370a;
- else
- info->speed = thirty_three_base_hpt370;
+ info->speed = thirty_three_base_hpt37x;
printk(KERN_DEBUG "HPT37X: using 33MHz PCI clock\n");
} else if (pll == F_LOW_PCI_40) {
/* Unsupported */
} else if (pll == F_LOW_PCI_50) {
- if (info->revision >= 8)
- info->speed = fifty_base_hpt370a;
- else if (info->revision >= 5)
- info->speed = fifty_base_hpt372;
- else if (info->revision >= 4)
- info->speed = fifty_base_hpt370a;
- else
- info->speed = fifty_base_hpt370a;
+ info->speed = fifty_base_hpt37x;
printk(KERN_DEBUG "HPT37X: using 50MHz PCI clock\n");
} else {
- if (info->revision >= 8) {
- printk(KERN_ERR "HPT37x: 66MHz timings are not supported.\n");
- }
- else if (info->revision >= 5)
- info->speed = sixty_six_base_hpt372;
- else if (info->revision >= 4)
- info->speed = sixty_six_base_hpt370a;
- else
- info->speed = sixty_six_base_hpt370;
+ info->speed = sixty_six_base_hpt37x;
printk(KERN_DEBUG "HPT37X: using 66MHz PCI clock\n");
}
}
-
+
+ if (pll == F_LOW_PCI_66)
+ info->flags |= PCI_66MHZ;
+
/*
* only try the pll if we don't have a table for the clock
* speed that we're running at. NOTE: the internal PLL will
@@ -1248,11 +1116,8 @@ static void __devinit hpt37x_clocking(ide_hwif_t *hwif)
info->flags |= PLL_MODE;
/*
- * FIXME: make this work correctly, esp with 372N as per
- * reference driver code.
- *
- * adjust PLL based upon PCI clock, enable it, and wait for
- * stabilization.
+ * Adjust the PLL based upon the PCI clock, enable it, and
+ * wait for stabilization...
*/
adjust = 0;
freq = (pll < F_LOW_PCI_50) ? 2 : 4;
@@ -1275,22 +1140,12 @@ static void __devinit hpt37x_clocking(ide_hwif_t *hwif)
pci_write_config_dword(dev, 0x5c,
pll & ~0x100);
pci_write_config_byte(dev, 0x5b, 0x21);
- if (info->revision >= 8)
- info->speed = fifty_base_hpt370a;
- else if (info->revision >= 5)
- info->speed = fifty_base_hpt372;
- else if (info->revision >= 4)
- info->speed = fifty_base_hpt370a;
- else
- info->speed = fifty_base_hpt370a;
+
+ info->speed = fifty_base_hpt37x;
printk("HPT37X: using 50MHz internal PLL\n");
goto init_hpt37X_done;
}
}
- if (!pci_get_drvdata(dev)) {
- printk("No Clock Stabilization!!!\n");
- return;
- }
pll_recal:
if (adjust & 1)
pll -= (adjust >> 1);
@@ -1300,11 +1155,16 @@ pll_recal:
init_hpt37X_done:
if (!info->speed)
- printk(KERN_ERR "HPT37X%s: unknown bus timing [%d %d].\n",
- (info->flags & IS_372N)?"N":"", pll, freq);
- /* reset state engine */
- pci_write_config_byte(dev, 0x50, 0x37);
- pci_write_config_byte(dev, 0x54, 0x37);
+ printk(KERN_ERR "HPT37x%s: unknown bus timing [%d %d].\n",
+ (info->flags & IS_3xxN) ? "N" : "", pll, freq);
+ /*
+ * Reset the state engines.
+ * NOTE: avoid accidentally enabling the primary channel on HPT371N.
+ */
+ pci_read_config_byte(dev, 0x50, &mcr1);
+ if (mcr1 & 0x04)
+ pci_write_config_byte(dev, 0x50, 0x37);
+ pci_write_config_byte(dev, 0x54, 0x37);
udelay(100);
}
@@ -1367,6 +1227,7 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
struct pci_dev *dev = hwif->pci_dev;
struct hpt_info *info = ide_get_hwifdata(hwif);
u8 ata66 = 0, regmask = (hwif->channel) ? 0x01 : 0x02;
+ int serialize = HPT_SERIALIZE_IO;
hwif->tuneproc = &hpt3xx_tune_drive;
hwif->speedproc = &hpt3xx_tune_chipset;
@@ -1374,8 +1235,20 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
hwif->intrproc = &hpt3xx_intrproc;
hwif->maskproc = &hpt3xx_maskproc;
- if(info->flags & IS_372N)
- hwif->rw_disk = &hpt372n_rw_disk;
+ /*
+ * HPT3xxN chips have some complications:
+ *
+ * - on 33 MHz PCI we must clock switch
+ * - on 66 MHz PCI we must NOT use the PCI clock
+ */
+ if ((info->flags & (IS_3xxN | PCI_66MHZ)) == IS_3xxN) {
+ /*
+ * Clock is shared between the channels,
+ * so we'll have to serialize them... :-(
+ */
+ serialize = 1;
+ hwif->rw_disk = &hpt3xxn_rw_disk;
+ }
/*
* The HPT37x uses the CBLID pins as outputs for MA15/MA16
@@ -1418,29 +1291,15 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
PCI_FUNC(hwif->pci_dev->devfn));
#endif /* DEBUG */
-#ifdef HPT_SERIALIZE_IO
- /* serialize access to this device */
- if (hwif->mate)
+ /* Serialize access to this device */
+ if (serialize && hwif->mate)
hwif->serialized = hwif->mate->serialized = 1;
-#endif
- if (info->revision >= 3) {
- u8 reg5ah = 0;
- pci_write_config_byte(dev, 0x5a, reg5ah & ~0x10);
- /*
- * set up ioctl for power status.
- * note: power affects both
- * drives on each channel
- */
- hwif->resetproc = &hpt3xx_reset;
- hwif->busproc = &hpt370_busproc;
- } else if (info->revision >= 2) {
- hwif->resetproc = &hpt3xx_reset;
- hwif->busproc = &hpt3xx_tristate;
- } else {
- hwif->resetproc = &hpt3xx_reset;
- hwif->busproc = &hpt3xx_tristate;
- }
+ /*
+ * Set up ioctl for power status.
+ * NOTE: power affects both drives on each channel.
+ */
+ hwif->busproc = &hpt3xx_busproc;
if (!hwif->dma_base) {
hwif->drives[0].autotune = 1;
@@ -1490,7 +1349,7 @@ static void __devinit init_dma_hpt366(ide_hwif_t *hwif, unsigned long dmabase)
return;
if(info->speed == NULL) {
- printk(KERN_WARNING "hpt: no known IDE timings, disabling DMA.\n");
+ printk(KERN_WARNING "hpt366: no known IDE timings, disabling DMA.\n");
return;
}
@@ -1519,9 +1378,10 @@ static void __devinit init_dma_hpt366(ide_hwif_t *hwif, unsigned long dmabase)
static void __devinit init_iops_hpt366(ide_hwif_t *hwif)
{
- struct hpt_info *info = kzalloc(sizeof(struct hpt_info), GFP_KERNEL);
- unsigned long dmabase = pci_resource_start(hwif->pci_dev, 4);
- u8 did, rid;
+ struct hpt_info *info = kzalloc(sizeof(struct hpt_info), GFP_KERNEL);
+ struct pci_dev *dev = hwif->pci_dev;
+ u16 did = dev->device;
+ u8 rid = 0;
if(info == NULL) {
printk(KERN_WARNING "hpt366: out of memory.\n");
@@ -1529,15 +1389,22 @@ static void __devinit init_iops_hpt366(ide_hwif_t *hwif)
}
ide_set_hwifdata(hwif, info);
- if(dmabase) {
- did = inb(dmabase + 0x22);
- rid = inb(dmabase + 0x28);
-
- if((did == 4 && rid == 6) || (did == 5 && rid > 1))
- info->flags |= IS_372N;
+ /* Avoid doing the same thing twice. */
+ if (hwif->channel && hwif->mate) {
+ memcpy(info, ide_get_hwifdata(hwif->mate), sizeof(struct hpt_info));
+ return;
}
- info->revision = hpt_revision(hwif->pci_dev);
+ pci_read_config_byte(dev, PCI_CLASS_REVISION, &rid);
+
+ if (( did == PCI_DEVICE_ID_TTI_HPT366 && rid == 6) ||
+ ((did == PCI_DEVICE_ID_TTI_HPT372 ||
+ did == PCI_DEVICE_ID_TTI_HPT302 ||
+ did == PCI_DEVICE_ID_TTI_HPT371) && rid > 1) ||
+ did == PCI_DEVICE_ID_TTI_HPT372N)
+ info->flags |= IS_3xxN;
+
+ info->revision = hpt_revision(dev);
if (info->revision >= 3)
hpt37x_clocking(hwif);
@@ -1574,6 +1441,23 @@ static int __devinit init_setup_hpt37x(struct pci_dev *dev, ide_pci_device_t *d)
return ide_setup_pci_device(dev, d);
}
+static int __devinit init_setup_hpt371(struct pci_dev *dev, ide_pci_device_t *d)
+{
+ u8 mcr1 = 0;
+
+ /*
+ * HPT371 chips physically have only one channel, the secondary one,
+ * but the primary channel registers do exist! Go figure...
+ * So, we manually disable the non-existing channel here
+ * (if the BIOS hasn't done this already).
+ */
+ pci_read_config_byte(dev, 0x50, &mcr1);
+ if (mcr1 & 0x04)
+ pci_write_config_byte(dev, 0x50, (mcr1 & ~0x04));
+
+ return ide_setup_pci_device(dev, d);
+}
+
static int __devinit init_setup_hpt366(struct pci_dev *dev, ide_pci_device_t *d)
{
struct pci_dev *findev = NULL;
@@ -1661,13 +1545,14 @@ static ide_pci_device_t hpt366_chipsets[] __devinitdata = {
.bootable = OFF_BOARD,
},{ /* 3 */
.name = "HPT371",
- .init_setup = init_setup_hpt37x,
+ .init_setup = init_setup_hpt371,
.init_chipset = init_chipset_hpt366,
.init_iops = init_iops_hpt366,
.init_hwif = init_hwif_hpt366,
.init_dma = init_dma_hpt366,
.channels = 2,
.autodma = AUTODMA,
+ .enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
.bootable = OFF_BOARD,
},{ /* 4 */
.name = "HPT374",
@@ -1699,13 +1584,16 @@ static ide_pci_device_t hpt366_chipsets[] __devinitdata = {
*
* Called when the PCI registration layer (or the IDE initialization)
* finds a device matching our IDE device tables.
+ *
+ * NOTE: since we'll have to modify some fields of the ide_pci_device_t
+ * structure depending on the chip's revision, we'd better pass a local
+ * copy down the call chain...
*/
-
static int __devinit hpt366_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- ide_pci_device_t *d = &hpt366_chipsets[id->driver_data];
+ ide_pci_device_t d = hpt366_chipsets[id->driver_data];
- return d->init_setup(dev, d);
+ return d.init_setup(dev, &d);
}
static struct pci_device_id hpt366_pci_tbl[] = {
diff --git a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c
index b1e9a8eba6b6..edb37f3d558d 100644
--- a/drivers/ide/pci/piix.c
+++ b/drivers/ide/pci/piix.c
@@ -1,13 +1,14 @@
/*
- * linux/drivers/ide/pci/piix.c Version 0.44 March 20, 2003
+ * linux/drivers/ide/pci/piix.c Version 0.45 May 12, 2006
*
* Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer
* Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org>
* Copyright (C) 2003 Red Hat Inc <alan@redhat.com>
+ * Copyright (C) 2006 MontaVista Software, Inc. <source@mvista.com>
*
* May be copied or modified under the terms of the GNU General Public License
*
- * PIO mode setting function for Intel chipsets.
+ * PIO mode setting function for Intel chipsets.
* For use instead of BIOS settings.
*
* 40-41
@@ -25,7 +26,7 @@
* sitre = word42 & 0x4000; secondary
*
* 44 8421|8421 hdd|hdb
- *
+ *
* 48 8421 hdd|hdc|hdb|hda udma enabled
*
* 0001 hda
@@ -353,56 +354,24 @@ static int piix_tune_chipset (ide_drive_t *drive, u8 xferspeed)
}
/**
- * piix_faulty_dma0 - check for DMA0 errata
- * @hwif: IDE interface to check
- *
- * If an ICH/ICH0/ICH2 interface is is operating in multi-word
- * DMA mode with 600nS cycle time the IDE PIO prefetch buffer will
- * inadvertently provide an extra piece of secondary data to the primary
- * device resulting in data corruption.
- *
- * With such a device this test function returns true. This allows
- * our tuning code to follow Intel recommendations and use PIO on
- * such devices.
- */
-
-static int piix_faulty_dma0(ide_hwif_t *hwif)
-{
- switch(hwif->pci_dev->device)
- {
- case PCI_DEVICE_ID_INTEL_82801AA_1: /* ICH */
- case PCI_DEVICE_ID_INTEL_82801AB_1: /* ICH0 */
- case PCI_DEVICE_ID_INTEL_82801BA_8: /* ICH2 */
- case PCI_DEVICE_ID_INTEL_82801BA_9: /* ICH2 */
- return 1;
- }
- return 0;
-}
-
-/**
* piix_config_drive_for_dma - configure drive for DMA
* @drive: IDE drive to configure
*
* Set up a PIIX interface channel for the best available speed.
- * We prefer UDMA if it is available and then MWDMA. If DMA is
- * not available we switch to PIO and return 0.
+ * We prefer UDMA if it is available and then MWDMA. If DMA is
+ * not available we switch to PIO and return 0.
*/
static int piix_config_drive_for_dma (ide_drive_t *drive)
{
u8 speed = ide_dma_speed(drive, piix_ratemask(drive));
-
- /* Some ICH devices cannot support DMA mode 0 */
- if(speed == XFER_MW_DMA_0 && piix_faulty_dma0(HWIF(drive)))
- speed = 0;
-
- /* If no DMA speed was available or the chipset has DMA bugs
- then disable DMA and use PIO */
-
- if (!speed || no_piix_dma) {
- u8 tspeed = ide_get_best_pio_mode(drive, 255, 5, NULL);
- speed = piix_dma_2_pio(XFER_PIO_0 + tspeed);
- }
+
+ /*
+ * If no DMA speed was available or the chipset has DMA bugs
+ * then disable DMA and use PIO
+ */
+ if (!speed || no_piix_dma)
+ return 0;
(void) piix_tune_chipset(drive, speed);
return ide_dma_enable(drive);
@@ -425,17 +394,16 @@ static int piix_config_drive_xfer_rate (ide_drive_t *drive)
if ((id->capability & 1) && drive->autodma) {
- if (ide_use_dma(drive)) {
- if (piix_config_drive_for_dma(drive))
- return hwif->ide_dma_on(drive);
- }
+ if (ide_use_dma(drive) && piix_config_drive_for_dma(drive))
+ return hwif->ide_dma_on(drive);
goto fast_ata_pio;
} else if ((id->capability & 8) || (id->field_valid & 2)) {
fast_ata_pio:
/* Find best PIO mode. */
- hwif->tuneproc(drive, 255);
+ (void) hwif->speedproc(drive, XFER_PIO_0 +
+ ide_get_best_pio_mode(drive, 255, 4, NULL));
return hwif->ide_dma_off_quietly(drive);
}
/* IORDY not supported */
diff --git a/drivers/ide/pci/slc90e66.c b/drivers/ide/pci/slc90e66.c
index 4a1853af3bbb..9be7e49cba0e 100644
--- a/drivers/ide/pci/slc90e66.c
+++ b/drivers/ide/pci/slc90e66.c
@@ -1,9 +1,10 @@
/*
- * linux/drivers/ide/pci/slc90e66.c Version 0.11 September 11, 2002
+ * linux/drivers/ide/pci/slc90e66.c Version 0.12 May 12, 2006
*
* Copyright (C) 2000-2002 Andre Hedrick <andre@linux-ide.org>
+ * Copyright (C) 2006 MontaVista Software, Inc. <source@mvista.com>
*
- * This a look-a-like variation of the ICH0 PIIX4 Ultra-66,
+ * This is a look-alike variation of the ICH0 PIIX4 Ultra-66,
* but this keeps the ISA-Bridge and slots alive.
*
*/
@@ -158,10 +159,8 @@ static int slc90e66_config_drive_for_dma (ide_drive_t *drive)
{
u8 speed = ide_dma_speed(drive, slc90e66_ratemask(drive));
- if (!(speed)) {
- u8 tspeed = ide_get_best_pio_mode(drive, 255, 5, NULL);
- speed = slc90e66_dma_2_pio(XFER_PIO_0 + tspeed);
- }
+ if (!speed)
+ return 0;
(void) slc90e66_tune_chipset(drive, speed);
return ide_dma_enable(drive);
@@ -176,16 +175,15 @@ static int slc90e66_config_drive_xfer_rate (ide_drive_t *drive)
if (id && (id->capability & 1) && drive->autodma) {
- if (ide_use_dma(drive)) {
- if (slc90e66_config_drive_for_dma(drive))
- return hwif->ide_dma_on(drive);
- }
+ if (ide_use_dma(drive) && slc90e66_config_drive_for_dma(drive))
+ return hwif->ide_dma_on(drive);
goto fast_ata_pio;
} else if ((id->capability & 8) || (id->field_valid & 2)) {
fast_ata_pio:
- hwif->tuneproc(drive, 5);
+ (void) hwif->speedproc(drive, XFER_PIO_0 +
+ ide_get_best_pio_mode(drive, 255, 4, NULL));
return hwif->ide_dma_off_quietly(drive);
}
/* IORDY not supported */
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
index e68b80b7340d..2b5d7ab3adf7 100644
--- a/drivers/ieee1394/sbp2.c
+++ b/drivers/ieee1394/sbp2.c
@@ -490,11 +490,11 @@ static int sbp2util_create_command_orb_pool(struct sbp2_lu *lu)
spin_unlock_irqrestore(&lu->cmd_orb_lock, flags);
return -ENOMEM;
}
- cmd->command_orb_dma = dma_map_single(&hi->host->device,
+ cmd->command_orb_dma = dma_map_single(hi->host->device.parent,
&cmd->command_orb,
sizeof(struct sbp2_command_orb),
DMA_TO_DEVICE);
- cmd->sge_dma = dma_map_single(&hi->host->device,
+ cmd->sge_dma = dma_map_single(hi->host->device.parent,
&cmd->scatter_gather_element,
sizeof(cmd->scatter_gather_element),
DMA_BIDIRECTIONAL);
@@ -516,10 +516,11 @@ static void sbp2util_remove_command_orb_pool(struct sbp2_lu *lu)
if (!list_empty(&lu->cmd_orb_completed))
list_for_each_safe(lh, next, &lu->cmd_orb_completed) {
cmd = list_entry(lh, struct sbp2_command_info, list);
- dma_unmap_single(&host->device, cmd->command_orb_dma,
+ dma_unmap_single(host->device.parent,
+ cmd->command_orb_dma,
sizeof(struct sbp2_command_orb),
DMA_TO_DEVICE);
- dma_unmap_single(&host->device, cmd->sge_dma,
+ dma_unmap_single(host->device.parent, cmd->sge_dma,
sizeof(cmd->scatter_gather_element),
DMA_BIDIRECTIONAL);
kfree(cmd);
@@ -601,17 +602,17 @@ static void sbp2util_mark_command_completed(struct sbp2_lu *lu,
if (cmd->cmd_dma) {
if (cmd->dma_type == CMD_DMA_SINGLE)
- dma_unmap_single(&host->device, cmd->cmd_dma,
+ dma_unmap_single(host->device.parent, cmd->cmd_dma,
cmd->dma_size, cmd->dma_dir);
else if (cmd->dma_type == CMD_DMA_PAGE)
- dma_unmap_page(&host->device, cmd->cmd_dma,
+ dma_unmap_page(host->device.parent, cmd->cmd_dma,
cmd->dma_size, cmd->dma_dir);
/* XXX: Check for CMD_DMA_NONE bug */
cmd->dma_type = CMD_DMA_NONE;
cmd->cmd_dma = 0;
}
if (cmd->sge_buffer) {
- dma_unmap_sg(&host->device, cmd->sge_buffer,
+ dma_unmap_sg(host->device.parent, cmd->sge_buffer,
cmd->dma_size, cmd->dma_dir);
cmd->sge_buffer = NULL;
}
@@ -836,37 +837,37 @@ static int sbp2_start_device(struct sbp2_lu *lu)
struct sbp2_fwhost_info *hi = lu->hi;
int error;
- lu->login_response = dma_alloc_coherent(&hi->host->device,
+ lu->login_response = dma_alloc_coherent(hi->host->device.parent,
sizeof(struct sbp2_login_response),
&lu->login_response_dma, GFP_KERNEL);
if (!lu->login_response)
goto alloc_fail;
- lu->query_logins_orb = dma_alloc_coherent(&hi->host->device,
+ lu->query_logins_orb = dma_alloc_coherent(hi->host->device.parent,
sizeof(struct sbp2_query_logins_orb),
&lu->query_logins_orb_dma, GFP_KERNEL);
if (!lu->query_logins_orb)
goto alloc_fail;
- lu->query_logins_response = dma_alloc_coherent(&hi->host->device,
+ lu->query_logins_response = dma_alloc_coherent(hi->host->device.parent,
sizeof(struct sbp2_query_logins_response),
&lu->query_logins_response_dma, GFP_KERNEL);
if (!lu->query_logins_response)
goto alloc_fail;
- lu->reconnect_orb = dma_alloc_coherent(&hi->host->device,
+ lu->reconnect_orb = dma_alloc_coherent(hi->host->device.parent,
sizeof(struct sbp2_reconnect_orb),
&lu->reconnect_orb_dma, GFP_KERNEL);
if (!lu->reconnect_orb)
goto alloc_fail;
- lu->logout_orb = dma_alloc_coherent(&hi->host->device,
+ lu->logout_orb = dma_alloc_coherent(hi->host->device.parent,
sizeof(struct sbp2_logout_orb),
&lu->logout_orb_dma, GFP_KERNEL);
if (!lu->logout_orb)
goto alloc_fail;
- lu->login_orb = dma_alloc_coherent(&hi->host->device,
+ lu->login_orb = dma_alloc_coherent(hi->host->device.parent,
sizeof(struct sbp2_login_orb),
&lu->login_orb_dma, GFP_KERNEL);
if (!lu->login_orb)
@@ -929,32 +930,32 @@ static void sbp2_remove_device(struct sbp2_lu *lu)
list_del(&lu->lu_list);
if (lu->login_response)
- dma_free_coherent(&hi->host->device,
+ dma_free_coherent(hi->host->device.parent,
sizeof(struct sbp2_login_response),
lu->login_response,
lu->login_response_dma);
if (lu->login_orb)
- dma_free_coherent(&hi->host->device,
+ dma_free_coherent(hi->host->device.parent,
sizeof(struct sbp2_login_orb),
lu->login_orb,
lu->login_orb_dma);
if (lu->reconnect_orb)
- dma_free_coherent(&hi->host->device,
+ dma_free_coherent(hi->host->device.parent,
sizeof(struct sbp2_reconnect_orb),
lu->reconnect_orb,
lu->reconnect_orb_dma);
if (lu->logout_orb)
- dma_free_coherent(&hi->host->device,
+ dma_free_coherent(hi->host->device.parent,
sizeof(struct sbp2_logout_orb),
lu->logout_orb,
lu->logout_orb_dma);
if (lu->query_logins_orb)
- dma_free_coherent(&hi->host->device,
+ dma_free_coherent(hi->host->device.parent,
sizeof(struct sbp2_query_logins_orb),
lu->query_logins_orb,
lu->query_logins_orb_dma);
if (lu->query_logins_response)
- dma_free_coherent(&hi->host->device,
+ dma_free_coherent(hi->host->device.parent,
sizeof(struct sbp2_query_logins_response),
lu->query_logins_response,
lu->query_logins_response_dma);
@@ -1445,7 +1446,7 @@ static void sbp2_prep_command_orb_sg(struct sbp2_command_orb *orb,
cmd->dma_size = sgpnt[0].length;
cmd->dma_type = CMD_DMA_PAGE;
- cmd->cmd_dma = dma_map_page(&hi->host->device,
+ cmd->cmd_dma = dma_map_page(hi->host->device.parent,
sgpnt[0].page, sgpnt[0].offset,
cmd->dma_size, cmd->dma_dir);
@@ -1457,8 +1458,8 @@ static void sbp2_prep_command_orb_sg(struct sbp2_command_orb *orb,
&cmd->scatter_gather_element[0];
u32 sg_count, sg_len;
dma_addr_t sg_addr;
- int i, count = dma_map_sg(&hi->host->device, sgpnt, scsi_use_sg,
- dma_dir);
+ int i, count = dma_map_sg(hi->host->device.parent, sgpnt,
+ scsi_use_sg, dma_dir);
cmd->dma_size = scsi_use_sg;
cmd->sge_buffer = sgpnt;
@@ -1508,7 +1509,8 @@ static void sbp2_prep_command_orb_no_sg(struct sbp2_command_orb *orb,
cmd->dma_dir = dma_dir;
cmd->dma_size = scsi_request_bufflen;
cmd->dma_type = CMD_DMA_SINGLE;
- cmd->cmd_dma = dma_map_single(&hi->host->device, scsi_request_buffer,
+ cmd->cmd_dma = dma_map_single(hi->host->device.parent,
+ scsi_request_buffer,
cmd->dma_size, cmd->dma_dir);
orb->data_descriptor_hi = ORB_SET_NODE_ID(hi->host->node_id);
orb->misc |= ORB_SET_DIRECTION(orb_direction);
@@ -1626,10 +1628,11 @@ static void sbp2_link_orb_command(struct sbp2_lu *lu,
size_t length;
unsigned long flags;
- dma_sync_single_for_device(&hi->host->device, cmd->command_orb_dma,
+ dma_sync_single_for_device(hi->host->device.parent,
+ cmd->command_orb_dma,
sizeof(struct sbp2_command_orb),
DMA_TO_DEVICE);
- dma_sync_single_for_device(&hi->host->device, cmd->sge_dma,
+ dma_sync_single_for_device(hi->host->device.parent, cmd->sge_dma,
sizeof(cmd->scatter_gather_element),
DMA_BIDIRECTIONAL);
@@ -1655,14 +1658,15 @@ static void sbp2_link_orb_command(struct sbp2_lu *lu,
* The target's fetch agent may or may not have read this
* previous ORB yet.
*/
- dma_sync_single_for_cpu(&hi->host->device, last_orb_dma,
+ dma_sync_single_for_cpu(hi->host->device.parent, last_orb_dma,
sizeof(struct sbp2_command_orb),
DMA_TO_DEVICE);
last_orb->next_ORB_lo = cpu_to_be32(cmd->command_orb_dma);
wmb();
/* Tells hardware that this pointer is valid */
last_orb->next_ORB_hi = 0;
- dma_sync_single_for_device(&hi->host->device, last_orb_dma,
+ dma_sync_single_for_device(hi->host->device.parent,
+ last_orb_dma,
sizeof(struct sbp2_command_orb),
DMA_TO_DEVICE);
addr += SBP2_DOORBELL_OFFSET;
@@ -1790,10 +1794,11 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid,
else
cmd = sbp2util_find_command_for_orb(lu, sb->ORB_offset_lo);
if (cmd) {
- dma_sync_single_for_cpu(&hi->host->device, cmd->command_orb_dma,
+ dma_sync_single_for_cpu(hi->host->device.parent,
+ cmd->command_orb_dma,
sizeof(struct sbp2_command_orb),
DMA_TO_DEVICE);
- dma_sync_single_for_cpu(&hi->host->device, cmd->sge_dma,
+ dma_sync_single_for_cpu(hi->host->device.parent, cmd->sge_dma,
sizeof(cmd->scatter_gather_element),
DMA_BIDIRECTIONAL);
/* Grab SCSI command pointers and check status. */
@@ -1882,16 +1887,6 @@ static int sbp2scsi_queuecommand(struct scsi_cmnd *SCpnt,
if (unlikely(SCpnt->device->lun))
goto done;
- /* handle the request sense command here (auto-request sense) */
- if (SCpnt->cmnd[0] == REQUEST_SENSE) {
- memcpy(SCpnt->request_buffer, SCpnt->sense_buffer,
- SCpnt->request_bufflen);
- memset(SCpnt->sense_buffer, 0, sizeof(SCpnt->sense_buffer));
- sbp2scsi_complete_command(lu, SBP2_SCSI_STATUS_GOOD, SCpnt,
- done);
- return 0;
- }
-
if (unlikely(!hpsb_node_entry_valid(lu->ne))) {
SBP2_ERR("Bus reset in progress - rejecting command");
result = DID_BUS_BUSY << 16;
@@ -1931,10 +1926,11 @@ static void sbp2scsi_complete_all_commands(struct sbp2_lu *lu, u32 status)
while (!list_empty(&lu->cmd_orb_inuse)) {
lh = lu->cmd_orb_inuse.next;
cmd = list_entry(lh, struct sbp2_command_info, list);
- dma_sync_single_for_cpu(&hi->host->device, cmd->command_orb_dma,
+ dma_sync_single_for_cpu(hi->host->device.parent,
+ cmd->command_orb_dma,
sizeof(struct sbp2_command_orb),
DMA_TO_DEVICE);
- dma_sync_single_for_cpu(&hi->host->device, cmd->sge_dma,
+ dma_sync_single_for_cpu(hi->host->device.parent, cmd->sge_dma,
sizeof(cmd->scatter_gather_element),
DMA_BIDIRECTIONAL);
sbp2util_mark_command_completed(lu, cmd);
@@ -2059,11 +2055,12 @@ static int sbp2scsi_abort(struct scsi_cmnd *SCpnt)
spin_lock_irqsave(&lu->cmd_orb_lock, flags);
cmd = sbp2util_find_command_for_SCpnt(lu, SCpnt);
if (cmd) {
- dma_sync_single_for_cpu(&hi->host->device,
+ dma_sync_single_for_cpu(hi->host->device.parent,
cmd->command_orb_dma,
sizeof(struct sbp2_command_orb),
DMA_TO_DEVICE);
- dma_sync_single_for_cpu(&hi->host->device, cmd->sge_dma,
+ dma_sync_single_for_cpu(hi->host->device.parent,
+ cmd->sge_dma,
sizeof(cmd->scatter_gather_element),
DMA_BIDIRECTIONAL);
sbp2util_mark_command_completed(lu, cmd);
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c
index 0491ec7a7c0a..44bc6cc734ab 100644
--- a/drivers/infiniband/hw/mthca/mthca_main.c
+++ b/drivers/infiniband/hw/mthca/mthca_main.c
@@ -80,24 +80,61 @@ static int tune_pci = 0;
module_param(tune_pci, int, 0444);
MODULE_PARM_DESC(tune_pci, "increase PCI burst from the default set by BIOS if nonzero");
-struct mutex mthca_device_mutex;
+DEFINE_MUTEX(mthca_device_mutex);
+
+#define MTHCA_DEFAULT_NUM_QP (1 << 16)
+#define MTHCA_DEFAULT_RDB_PER_QP (1 << 2)
+#define MTHCA_DEFAULT_NUM_CQ (1 << 16)
+#define MTHCA_DEFAULT_NUM_MCG (1 << 13)
+#define MTHCA_DEFAULT_NUM_MPT (1 << 17)
+#define MTHCA_DEFAULT_NUM_MTT (1 << 20)
+#define MTHCA_DEFAULT_NUM_UDAV (1 << 15)
+#define MTHCA_DEFAULT_NUM_RESERVED_MTTS (1 << 18)
+#define MTHCA_DEFAULT_NUM_UARC_SIZE (1 << 18)
+
+static struct mthca_profile hca_profile = {
+ .num_qp = MTHCA_DEFAULT_NUM_QP,
+ .rdb_per_qp = MTHCA_DEFAULT_RDB_PER_QP,
+ .num_cq = MTHCA_DEFAULT_NUM_CQ,
+ .num_mcg = MTHCA_DEFAULT_NUM_MCG,
+ .num_mpt = MTHCA_DEFAULT_NUM_MPT,
+ .num_mtt = MTHCA_DEFAULT_NUM_MTT,
+ .num_udav = MTHCA_DEFAULT_NUM_UDAV, /* Tavor only */
+ .fmr_reserved_mtts = MTHCA_DEFAULT_NUM_RESERVED_MTTS, /* Tavor only */
+ .uarc_size = MTHCA_DEFAULT_NUM_UARC_SIZE, /* Arbel only */
+};
+
+module_param_named(num_qp, hca_profile.num_qp, int, 0444);
+MODULE_PARM_DESC(num_qp, "maximum number of QPs per HCA");
+
+module_param_named(rdb_per_qp, hca_profile.rdb_per_qp, int, 0444);
+MODULE_PARM_DESC(rdb_per_qp, "number of RDB buffers per QP");
+
+module_param_named(num_cq, hca_profile.num_cq, int, 0444);
+MODULE_PARM_DESC(num_cq, "maximum number of CQs per HCA");
+
+module_param_named(num_mcg, hca_profile.num_mcg, int, 0444);
+MODULE_PARM_DESC(num_mcg, "maximum number of multicast groups per HCA");
+
+module_param_named(num_mpt, hca_profile.num_mpt, int, 0444);
+MODULE_PARM_DESC(num_mpt,
+ "maximum number of memory protection table entries per HCA");
+
+module_param_named(num_mtt, hca_profile.num_mtt, int, 0444);
+MODULE_PARM_DESC(num_mtt,
+ "maximum number of memory translation table segments per HCA");
+
+module_param_named(num_udav, hca_profile.num_udav, int, 0444);
+MODULE_PARM_DESC(num_udav, "maximum number of UD address vectors per HCA");
+
+module_param_named(fmr_reserved_mtts, hca_profile.fmr_reserved_mtts, int, 0444);
+MODULE_PARM_DESC(fmr_reserved_mtts,
+ "number of memory translation table segments reserved for FMR");
static const char mthca_version[] __devinitdata =
DRV_NAME ": Mellanox InfiniBand HCA driver v"
DRV_VERSION " (" DRV_RELDATE ")\n";
-static struct mthca_profile default_profile = {
- .num_qp = 1 << 16,
- .rdb_per_qp = 4,
- .num_cq = 1 << 16,
- .num_mcg = 1 << 13,
- .num_mpt = 1 << 17,
- .num_mtt = 1 << 20,
- .num_udav = 1 << 15, /* Tavor only */
- .fmr_reserved_mtts = 1 << 18, /* Tavor only */
- .uarc_size = 1 << 18, /* Arbel only */
-};
-
static int mthca_tune_pci(struct mthca_dev *mdev)
{
int cap;
@@ -303,7 +340,7 @@ static int mthca_init_tavor(struct mthca_dev *mdev)
goto err_disable;
}
- profile = default_profile;
+ profile = hca_profile;
profile.num_uar = dev_lim.uar_size / PAGE_SIZE;
profile.uarc_size = 0;
if (mdev->mthca_flags & MTHCA_FLAG_SRQ)
@@ -621,7 +658,7 @@ static int mthca_init_arbel(struct mthca_dev *mdev)
goto err_stop_fw;
}
- profile = default_profile;
+ profile = hca_profile;
profile.num_uar = dev_lim.uar_size / PAGE_SIZE;
profile.num_udav = 0;
if (mdev->mthca_flags & MTHCA_FLAG_SRQ)
@@ -1278,11 +1315,55 @@ static struct pci_driver mthca_driver = {
.remove = __devexit_p(mthca_remove_one)
};
+static void __init __mthca_check_profile_val(const char *name, int *pval,
+ int pval_default)
+{
+ /* value must be positive and power of 2 */
+ int old_pval = *pval;
+
+ if (old_pval <= 0)
+ *pval = pval_default;
+ else
+ *pval = roundup_pow_of_two(old_pval);
+
+ if (old_pval != *pval) {
+ printk(KERN_WARNING PFX "Invalid value %d for %s in module parameter.\n",
+ old_pval, name);
+ printk(KERN_WARNING PFX "Corrected %s to %d.\n", name, *pval);
+ }
+}
+
+#define mthca_check_profile_val(name, default) \
+ __mthca_check_profile_val(#name, &hca_profile.name, default)
+
+static void __init mthca_validate_profile(void)
+{
+ mthca_check_profile_val(num_qp, MTHCA_DEFAULT_NUM_QP);
+ mthca_check_profile_val(rdb_per_qp, MTHCA_DEFAULT_RDB_PER_QP);
+ mthca_check_profile_val(num_cq, MTHCA_DEFAULT_NUM_CQ);
+ mthca_check_profile_val(num_mcg, MTHCA_DEFAULT_NUM_MCG);
+ mthca_check_profile_val(num_mpt, MTHCA_DEFAULT_NUM_MPT);
+ mthca_check_profile_val(num_mtt, MTHCA_DEFAULT_NUM_MTT);
+ mthca_check_profile_val(num_udav, MTHCA_DEFAULT_NUM_UDAV);
+ mthca_check_profile_val(fmr_reserved_mtts, MTHCA_DEFAULT_NUM_RESERVED_MTTS);
+
+ if (hca_profile.fmr_reserved_mtts >= hca_profile.num_mtt) {
+ printk(KERN_WARNING PFX "Invalid fmr_reserved_mtts module parameter %d.\n",
+ hca_profile.fmr_reserved_mtts);
+ printk(KERN_WARNING PFX "(Must be smaller than num_mtt %d)\n",
+ hca_profile.num_mtt);
+ hca_profile.fmr_reserved_mtts = hca_profile.num_mtt / 2;
+ printk(KERN_WARNING PFX "Corrected fmr_reserved_mtts to %d.\n",
+ hca_profile.fmr_reserved_mtts);
+ }
+}
+
static int __init mthca_init(void)
{
int ret;
- mutex_init(&mthca_device_mutex);
+ mthca_validate_profile();
+
ret = mthca_catas_init();
if (ret)
return ret;
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c
index 7ec7c4b937f9..7b96751695ea 100644
--- a/drivers/infiniband/hw/mthca/mthca_provider.c
+++ b/drivers/infiniband/hw/mthca/mthca_provider.c
@@ -1100,10 +1100,11 @@ static struct ib_fmr *mthca_alloc_fmr(struct ib_pd *pd, int mr_access_flags,
struct mthca_fmr *fmr;
int err;
- fmr = kmemdup(fmr_attr, sizeof *fmr, GFP_KERNEL);
+ fmr = kmalloc(sizeof *fmr, GFP_KERNEL);
if (!fmr)
return ERR_PTR(-ENOMEM);
+ memcpy(&fmr->attr, fmr_attr, sizeof *fmr_attr);
err = mthca_fmr_alloc(to_mdev(pd->device), to_mpd(pd)->pd_num,
convert_access(mr_access_flags), fmr);
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index e9b6a6f07dd7..cdecbf5911c8 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -1898,7 +1898,7 @@ static void srp_add_one(struct ib_device *device)
*/
srp_dev->fmr_page_shift = max(9, ffs(dev_attr->page_size_cap) - 1);
srp_dev->fmr_page_size = 1 << srp_dev->fmr_page_shift;
- srp_dev->fmr_page_mask = ~((unsigned long) srp_dev->fmr_page_size - 1);
+ srp_dev->fmr_page_mask = ~((u64) srp_dev->fmr_page_size - 1);
INIT_LIST_HEAD(&srp_dev->dev_list);
diff --git a/drivers/infiniband/ulp/srp/ib_srp.h b/drivers/infiniband/ulp/srp/ib_srp.h
index 868a540ef7cd..c21772317b86 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.h
+++ b/drivers/infiniband/ulp/srp/ib_srp.h
@@ -87,7 +87,7 @@ struct srp_device {
struct ib_fmr_pool *fmr_pool;
int fmr_page_shift;
int fmr_page_size;
- unsigned long fmr_page_mask;
+ u64 fmr_page_mask;
};
struct srp_host {
diff --git a/drivers/input/keyboard/amikbd.c b/drivers/input/keyboard/amikbd.c
index 16583d71753b..c67e84ec2d6a 100644
--- a/drivers/input/keyboard/amikbd.c
+++ b/drivers/input/keyboard/amikbd.c
@@ -187,7 +187,7 @@ static irqreturn_t amikbd_interrupt(int irq, void *dummy)
static int __init amikbd_init(void)
{
- int i, j;
+ int i, j, err;
if (!AMIGAHW_PRESENT(AMI_KEYBOARD))
return -ENODEV;
diff --git a/drivers/input/keyboard/hilkbd.c b/drivers/input/keyboard/hilkbd.c
index 54bc569db4b0..35461eab2faf 100644
--- a/drivers/input/keyboard/hilkbd.c
+++ b/drivers/input/keyboard/hilkbd.c
@@ -23,7 +23,12 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/hil.h>
+#include <linux/io.h>
#include <linux/spinlock.h>
+#include <asm/irq.h>
+#ifdef CONFIG_HP300
+#include <asm/hwtest.h>
+#endif
MODULE_AUTHOR("Philip Blundell, Matthew Wilcox, Helge Deller");
diff --git a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c
index 3826db9403e6..cc0238366414 100644
--- a/drivers/input/keyboard/sunkbd.c
+++ b/drivers/input/keyboard/sunkbd.c
@@ -225,7 +225,7 @@ static void sunkbd_reinit(struct work_struct *work)
static void sunkbd_enable(struct sunkbd *sunkbd, int enable)
{
serio_pause_rx(sunkbd->serio);
- sunkbd->enabled = 1;
+ sunkbd->enabled = enable;
serio_continue_rx(sunkbd->serio);
}
diff --git a/drivers/input/serio/i8042-sparcio.h b/drivers/input/serio/i8042-sparcio.h
index 54adba2d8ed5..d9ca55891cd7 100644
--- a/drivers/input/serio/i8042-sparcio.h
+++ b/drivers/input/serio/i8042-sparcio.h
@@ -16,6 +16,7 @@ static int i8042_aux_irq = -1;
#define I8042_MUX_PHYS_DESC "sparcps2/serio%d"
static void __iomem *kbd_iobase;
+static struct resource *kbd_res;
#define I8042_COMMAND_REG (kbd_iobase + 0x64UL)
#define I8042_DATA_REG (kbd_iobase + 0x60UL)
@@ -60,6 +61,7 @@ static int __devinit sparc_i8042_probe(struct of_device *op, const struct of_dev
i8042_kbd_irq = irq;
kbd_iobase = of_ioremap(&kbd->resource[0],
0, 8, "kbd");
+ kbd_res = &kbd->resource[0];
} else if (!strcmp(dp->name, OBP_PS2MS_NAME1) ||
!strcmp(dp->name, OBP_PS2MS_NAME2)) {
struct of_device *ms = of_find_device_by_node(dp);
@@ -77,7 +79,7 @@ static int __devinit sparc_i8042_probe(struct of_device *op, const struct of_dev
static int __devexit sparc_i8042_remove(struct of_device *op)
{
- of_iounmap(kbd_iobase, 8);
+ of_iounmap(kbd_res, kbd_iobase, 8);
return 0;
}
@@ -119,7 +121,7 @@ static int __init i8042_platform_init(void)
if (i8042_kbd_irq == -1 ||
i8042_aux_irq == -1) {
if (kbd_iobase) {
- of_iounmap(kbd_iobase, 8);
+ of_iounmap(kbd_res, kbd_iobase, 8);
kbd_iobase = (void __iomem *) NULL;
}
return -ENODEV;
diff --git a/drivers/isdn/act2000/act2000_isa.c b/drivers/isdn/act2000/act2000_isa.c
index 3cac23739344..09ea50dd3459 100644
--- a/drivers/isdn/act2000/act2000_isa.c
+++ b/drivers/isdn/act2000/act2000_isa.c
@@ -408,7 +408,7 @@ act2000_isa_download(act2000_card * card, act2000_ddef __user * cb)
p = cblock.buffer;
if (!access_ok(VERIFY_READ, p, length))
return -EFAULT;
- buf = (u_char *) kmalloc(1024, GFP_KERNEL);
+ buf = kmalloc(1024, GFP_KERNEL);
if (!buf)
return -ENOMEM;
timeout = 0;
diff --git a/drivers/isdn/capi/capidrv.c b/drivers/isdn/capi/capidrv.c
index 097bfa7bc323..c4d438c17dab 100644
--- a/drivers/isdn/capi/capidrv.c
+++ b/drivers/isdn/capi/capidrv.c
@@ -2013,7 +2013,7 @@ static int capidrv_addcontr(u16 contr, struct capi_profile *profp)
strcpy(card->name, id);
card->contrnr = contr;
card->nbchan = profp->nbchannel;
- card->bchans = (capidrv_bchan *) kmalloc(sizeof(capidrv_bchan) * card->nbchan, GFP_ATOMIC);
+ card->bchans = kmalloc(sizeof(capidrv_bchan) * card->nbchan, GFP_ATOMIC);
if (!card->bchans) {
printk(KERN_WARNING
"capidrv: (%s) Could not allocate bchan-structs.\n", id);
diff --git a/drivers/isdn/divert/divert_procfs.c b/drivers/isdn/divert/divert_procfs.c
index 399b316111f7..06967da7c4a8 100644
--- a/drivers/isdn/divert/divert_procfs.c
+++ b/drivers/isdn/divert/divert_procfs.c
@@ -45,7 +45,7 @@ put_info_buffer(char *cp)
return;
if (!*cp)
return;
- if (!(ib = (struct divert_info *) kmalloc(sizeof(struct divert_info) + strlen(cp), GFP_ATOMIC)))
+ if (!(ib = kmalloc(sizeof(struct divert_info) + strlen(cp), GFP_ATOMIC)))
return; /* no memory */
strcpy(ib->info_start, cp); /* set output string */
ib->next = NULL;
diff --git a/drivers/isdn/divert/isdn_divert.c b/drivers/isdn/divert/isdn_divert.c
index 03319ea5aa0c..7d97d54588d9 100644
--- a/drivers/isdn/divert/isdn_divert.c
+++ b/drivers/isdn/divert/isdn_divert.c
@@ -153,7 +153,7 @@ int cf_command(int drvid, int mode,
*ielenp = p - ielenp - 1; /* set total IE length */
/* allocate mem for information struct */
- if (!(cs = (struct call_struc *) kmalloc(sizeof(struct call_struc), GFP_ATOMIC)))
+ if (!(cs = kmalloc(sizeof(struct call_struc), GFP_ATOMIC)))
return(-ENOMEM); /* no memory */
init_timer(&cs->timer);
cs->info[0] = '\0';
@@ -276,7 +276,7 @@ int insertrule(int idx, divert_rule *newrule)
{ struct deflect_struc *ds,*ds1=NULL;
unsigned long flags;
- if (!(ds = (struct deflect_struc *) kmalloc(sizeof(struct deflect_struc),
+ if (!(ds = kmalloc(sizeof(struct deflect_struc),
GFP_KERNEL)))
return(-ENOMEM); /* no memory */
@@ -451,7 +451,7 @@ static int isdn_divert_icall(isdn_ctrl *ic)
if (dv->rule.action == DEFLECT_PROCEED)
if ((!if_used) || ((!extern_wait_max) && (!dv->rule.waittime)))
return(0); /* no external deflection needed */
- if (!(cs = (struct call_struc *) kmalloc(sizeof(struct call_struc), GFP_ATOMIC)))
+ if (!(cs = kmalloc(sizeof(struct call_struc), GFP_ATOMIC)))
return(0); /* no memory */
init_timer(&cs->timer);
cs->info[0] = '\0';
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c
index 63b629b1cdb2..b5e7f9c7d74e 100644
--- a/drivers/isdn/gigaset/bas-gigaset.c
+++ b/drivers/isdn/gigaset/bas-gigaset.c
@@ -1853,20 +1853,24 @@ static int gigaset_write_cmd(struct cardstate *cs,
{
struct cmdbuf_t *cb;
unsigned long flags;
- int status;
+ int rc;
gigaset_dbg_buffer(atomic_read(&cs->mstate) != MS_LOCKED ?
DEBUG_TRANSCMD : DEBUG_LOCKCMD,
"CMD Transmit", len, buf);
- if (len <= 0)
- return 0; /* nothing to do */
+ if (len <= 0) {
+ /* nothing to do */
+ rc = 0;
+ goto notqueued;
+ }
if (len > IF_WRITEBUF)
len = IF_WRITEBUF;
if (!(cb = kmalloc(sizeof(struct cmdbuf_t) + len, GFP_ATOMIC))) {
dev_err(cs->dev, "%s: out of memory\n", __func__);
- return -ENOMEM;
+ rc = -ENOMEM;
+ goto notqueued;
}
memcpy(cb->buf, buf, len);
@@ -1891,11 +1895,21 @@ static int gigaset_write_cmd(struct cardstate *cs,
if (unlikely(!cs->connected)) {
spin_unlock_irqrestore(&cs->lock, flags);
gig_dbg(DEBUG_USBREQ, "%s: not connected", __func__);
+ /* flush command queue */
+ spin_lock_irqsave(&cs->cmdlock, flags);
+ while (cs->cmdbuf != NULL)
+ complete_cb(cs);
+ spin_unlock_irqrestore(&cs->cmdlock, flags);
return -ENODEV;
}
- status = start_cbsend(cs);
+ rc = start_cbsend(cs);
spin_unlock_irqrestore(&cs->lock, flags);
- return status < 0 ? status : len;
+ return rc < 0 ? rc : len;
+
+notqueued: /* request handled without queuing */
+ if (wake_tasklet)
+ tasklet_schedule(wake_tasklet);
+ return rc;
}
/* gigaset_write_room
@@ -1964,20 +1978,15 @@ static int gigaset_freebcshw(struct bc_state *bcs)
/* kill URBs and tasklets before freeing - better safe than sorry */
atomic_set(&ubc->running, 0);
- for (i = 0; i < BAS_OUTURBS; ++i)
- if (ubc->isoouturbs[i].urb) {
- gig_dbg(DEBUG_INIT, "%s: killing iso out URB %d",
- __func__, i);
- usb_kill_urb(ubc->isoouturbs[i].urb);
- usb_free_urb(ubc->isoouturbs[i].urb);
- }
- for (i = 0; i < BAS_INURBS; ++i)
- if (ubc->isoinurbs[i]) {
- gig_dbg(DEBUG_INIT, "%s: killing iso in URB %d",
- __func__, i);
- usb_kill_urb(ubc->isoinurbs[i]);
- usb_free_urb(ubc->isoinurbs[i]);
- }
+ gig_dbg(DEBUG_INIT, "%s: killing iso URBs", __func__);
+ for (i = 0; i < BAS_OUTURBS; ++i) {
+ usb_kill_urb(ubc->isoouturbs[i].urb);
+ usb_free_urb(ubc->isoouturbs[i].urb);
+ }
+ for (i = 0; i < BAS_INURBS; ++i) {
+ usb_kill_urb(ubc->isoinurbs[i]);
+ usb_free_urb(ubc->isoinurbs[i]);
+ }
tasklet_kill(&ubc->sent_tasklet);
tasklet_kill(&ubc->rcvd_tasklet);
kfree(ubc->isooutbuf);
@@ -2099,55 +2108,32 @@ static void freeurbs(struct cardstate *cs)
struct bas_bc_state *ubc;
int i, j;
+ gig_dbg(DEBUG_INIT, "%s: killing URBs", __func__);
for (j = 0; j < 2; ++j) {
ubc = cs->bcs[j].hw.bas;
- for (i = 0; i < BAS_OUTURBS; ++i)
- if (ubc->isoouturbs[i].urb) {
- usb_kill_urb(ubc->isoouturbs[i].urb);
- gig_dbg(DEBUG_INIT,
- "%s: isoc output URB %d/%d unlinked",
- __func__, j, i);
- usb_free_urb(ubc->isoouturbs[i].urb);
- ubc->isoouturbs[i].urb = NULL;
- }
- for (i = 0; i < BAS_INURBS; ++i)
- if (ubc->isoinurbs[i]) {
- usb_kill_urb(ubc->isoinurbs[i]);
- gig_dbg(DEBUG_INIT,
- "%s: isoc input URB %d/%d unlinked",
- __func__, j, i);
- usb_free_urb(ubc->isoinurbs[i]);
- ubc->isoinurbs[i] = NULL;
- }
- }
- if (ucs->urb_int_in) {
- usb_kill_urb(ucs->urb_int_in);
- gig_dbg(DEBUG_INIT, "%s: interrupt input URB unlinked",
- __func__);
- usb_free_urb(ucs->urb_int_in);
- ucs->urb_int_in = NULL;
- }
- if (ucs->urb_cmd_out) {
- usb_kill_urb(ucs->urb_cmd_out);
- gig_dbg(DEBUG_INIT, "%s: command output URB unlinked",
- __func__);
- usb_free_urb(ucs->urb_cmd_out);
- ucs->urb_cmd_out = NULL;
- }
- if (ucs->urb_cmd_in) {
- usb_kill_urb(ucs->urb_cmd_in);
- gig_dbg(DEBUG_INIT, "%s: command input URB unlinked",
- __func__);
- usb_free_urb(ucs->urb_cmd_in);
- ucs->urb_cmd_in = NULL;
- }
- if (ucs->urb_ctrl) {
- usb_kill_urb(ucs->urb_ctrl);
- gig_dbg(DEBUG_INIT, "%s: control output URB unlinked",
- __func__);
- usb_free_urb(ucs->urb_ctrl);
- ucs->urb_ctrl = NULL;
+ for (i = 0; i < BAS_OUTURBS; ++i) {
+ usb_kill_urb(ubc->isoouturbs[i].urb);
+ usb_free_urb(ubc->isoouturbs[i].urb);
+ ubc->isoouturbs[i].urb = NULL;
+ }
+ for (i = 0; i < BAS_INURBS; ++i) {
+ usb_kill_urb(ubc->isoinurbs[i]);
+ usb_free_urb(ubc->isoinurbs[i]);
+ ubc->isoinurbs[i] = NULL;
+ }
}
+ usb_kill_urb(ucs->urb_int_in);
+ usb_free_urb(ucs->urb_int_in);
+ ucs->urb_int_in = NULL;
+ usb_kill_urb(ucs->urb_cmd_out);
+ usb_free_urb(ucs->urb_cmd_out);
+ ucs->urb_cmd_out = NULL;
+ usb_kill_urb(ucs->urb_cmd_in);
+ usb_free_urb(ucs->urb_cmd_in);
+ ucs->urb_cmd_in = NULL;
+ usb_kill_urb(ucs->urb_ctrl);
+ usb_free_urb(ucs->urb_ctrl);
+ ucs->urb_ctrl = NULL;
}
/* gigaset_probe
diff --git a/drivers/isdn/hysdn/hysdn_procconf.c b/drivers/isdn/hysdn/hysdn_procconf.c
index 8e2b03889f3c..94a935089119 100644
--- a/drivers/isdn/hysdn/hysdn_procconf.c
+++ b/drivers/isdn/hysdn/hysdn_procconf.c
@@ -275,7 +275,7 @@ hysdn_conf_open(struct inode *ino, struct file *filep)
} else if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) {
/* read access -> output card info data */
- if (!(tmp = (char *) kmalloc(INFO_OUT_LEN * 2 + 2, GFP_KERNEL))) {
+ if (!(tmp = kmalloc(INFO_OUT_LEN * 2 + 2, GFP_KERNEL))) {
unlock_kernel();
return (-EFAULT); /* out of memory */
}
diff --git a/drivers/isdn/hysdn/hysdn_proclog.c b/drivers/isdn/hysdn/hysdn_proclog.c
index f241f5e551cb..375d956884d7 100644
--- a/drivers/isdn/hysdn/hysdn_proclog.c
+++ b/drivers/isdn/hysdn/hysdn_proclog.c
@@ -111,7 +111,7 @@ put_log_buffer(hysdn_card * card, char *cp)
if (pd->if_used <= 0)
return; /* no open file for read */
- if (!(ib = (struct log_data *) kmalloc(sizeof(struct log_data) + strlen(cp), GFP_ATOMIC)))
+ if (!(ib = kmalloc(sizeof(struct log_data) + strlen(cp), GFP_ATOMIC)))
return; /* no memory */
strcpy(ib->log_start, cp); /* set output string */
ib->next = NULL;
diff --git a/drivers/isdn/i4l/isdn_audio.c b/drivers/isdn/i4l/isdn_audio.c
index 2cc56d6a9fae..fb350c567c6b 100644
--- a/drivers/isdn/i4l/isdn_audio.c
+++ b/drivers/isdn/i4l/isdn_audio.c
@@ -328,7 +328,7 @@ adpcm_state *
isdn_audio_adpcm_init(adpcm_state * s, int nbits)
{
if (!s)
- s = (adpcm_state *) kmalloc(sizeof(adpcm_state), GFP_ATOMIC);
+ s = kmalloc(sizeof(adpcm_state), GFP_ATOMIC);
if (s) {
s->a = 0;
s->d = 5;
@@ -343,7 +343,7 @@ dtmf_state *
isdn_audio_dtmf_init(dtmf_state * s)
{
if (!s)
- s = (dtmf_state *) kmalloc(sizeof(dtmf_state), GFP_ATOMIC);
+ s = kmalloc(sizeof(dtmf_state), GFP_ATOMIC);
if (s) {
s->idx = 0;
s->last = ' ';
@@ -621,7 +621,7 @@ silence_state *
isdn_audio_silence_init(silence_state * s)
{
if (!s)
- s = (silence_state *) kmalloc(sizeof(silence_state), GFP_ATOMIC);
+ s = kmalloc(sizeof(silence_state), GFP_ATOMIC);
if (s) {
s->idx = 0;
s->state = 0;
diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c
index c36c817578cb..838b3734e2b6 100644
--- a/drivers/isdn/i4l/isdn_net.c
+++ b/drivers/isdn/i4l/isdn_net.c
@@ -2948,7 +2948,7 @@ isdn_net_addphone(isdn_net_ioctl_phone * phone)
isdn_net_phone *n;
if (p) {
- if (!(n = (isdn_net_phone *) kmalloc(sizeof(isdn_net_phone), GFP_KERNEL)))
+ if (!(n = kmalloc(sizeof(isdn_net_phone), GFP_KERNEL)))
return -ENOMEM;
strcpy(n->num, phone->phone);
n->next = p->local->phone[phone->outgoing & 1];
diff --git a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c
index 43811795b46b..4e3f127e4003 100644
--- a/drivers/isdn/i4l/isdn_ppp.c
+++ b/drivers/isdn/i4l/isdn_ppp.c
@@ -717,7 +717,7 @@ isdn_ppp_fill_rq(unsigned char *buf, int len, int proto, int slot)
printk(KERN_DEBUG "ippp: device not activated.\n");
return 0;
}
- nbuf = (unsigned char *) kmalloc(len + 4, GFP_ATOMIC);
+ nbuf = kmalloc(len + 4, GFP_ATOMIC);
if (!nbuf) {
printk(KERN_WARNING "ippp: Can't alloc buf\n");
return 0;
@@ -2339,6 +2339,7 @@ static struct ippp_ccp_reset_state *isdn_ppp_ccp_reset_alloc_state(struct ippp_s
rs->state = CCPResetIdle;
rs->is = is;
rs->id = id;
+ init_timer(&rs->timer);
rs->timer.data = (unsigned long)rs;
rs->timer.function = isdn_ppp_ccp_timer_callback;
is->reset->rs[id] = rs;
diff --git a/drivers/isdn/pcbit/layer2.c b/drivers/isdn/pcbit/layer2.c
index 6ff85574e941..eafcce5e656a 100644
--- a/drivers/isdn/pcbit/layer2.c
+++ b/drivers/isdn/pcbit/layer2.c
@@ -100,7 +100,7 @@ pcbit_l2_write(struct pcbit_dev *dev, ulong msg, ushort refnum,
dev_kfree_skb(skb);
return -1;
}
- if ((frame = (struct frame_buf *) kmalloc(sizeof(struct frame_buf),
+ if ((frame = kmalloc(sizeof(struct frame_buf),
GFP_ATOMIC)) == NULL) {
printk(KERN_WARNING "pcbit_2_write: kmalloc failed\n");
dev_kfree_skb(skb);
diff --git a/drivers/kvm/Kconfig b/drivers/kvm/Kconfig
index 36412e90f09b..703cc88d1ef9 100644
--- a/drivers/kvm/Kconfig
+++ b/drivers/kvm/Kconfig
@@ -1,6 +1,8 @@
#
# KVM configuration
#
+menu "Virtualization"
+
config KVM
tristate "Kernel-based Virtual Machine (KVM) support"
depends on X86 && EXPERIMENTAL
@@ -31,3 +33,5 @@ config KVM_AMD
---help---
Provides support for KVM on AMD processors equipped with the AMD-V
(SVM) extensions.
+
+endmenu
diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index 5785d0870ab6..100df6f38d92 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -140,7 +140,7 @@ enum {
VCPU_REGS_RBP = 5,
VCPU_REGS_RSI = 6,
VCPU_REGS_RDI = 7,
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
VCPU_REGS_R8 = 8,
VCPU_REGS_R9 = 9,
VCPU_REGS_R10 = 10,
@@ -278,7 +278,6 @@ struct kvm_arch_ops {
struct kvm_segment *var, int seg);
void (*set_segment)(struct kvm_vcpu *vcpu,
struct kvm_segment *var, int seg);
- int (*is_long_mode)(struct kvm_vcpu *vcpu);
void (*get_cs_db_l_bits)(struct kvm_vcpu *vcpu, int *db, int *l);
void (*set_cr0)(struct kvm_vcpu *vcpu, unsigned long cr0);
void (*set_cr0_no_modeswitch)(struct kvm_vcpu *vcpu,
@@ -320,7 +319,8 @@ int kvm_init_arch(struct kvm_arch_ops *ops, struct module *module);
void kvm_exit_arch(void);
void kvm_mmu_destroy(struct kvm_vcpu *vcpu);
-int kvm_mmu_init(struct kvm_vcpu *vcpu);
+int kvm_mmu_create(struct kvm_vcpu *vcpu);
+int kvm_mmu_setup(struct kvm_vcpu *vcpu);
int kvm_mmu_reset_context(struct kvm_vcpu *vcpu);
void kvm_mmu_slot_remove_write_access(struct kvm *kvm, int slot);
@@ -375,9 +375,8 @@ void set_cr4(struct kvm_vcpu *vcpu, unsigned long cr0);
void set_cr8(struct kvm_vcpu *vcpu, unsigned long cr0);
void lmsw(struct kvm_vcpu *vcpu, unsigned long msw);
-#ifdef __x86_64__
-void set_efer(struct kvm_vcpu *vcpu, u64 efer);
-#endif
+int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata);
+int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data);
void fx_init(struct kvm_vcpu *vcpu);
@@ -403,6 +402,15 @@ static inline struct page *_gfn_to_page(struct kvm *kvm, gfn_t gfn)
return (slot) ? slot->phys_mem[gfn - slot->base_gfn] : NULL;
}
+static inline int is_long_mode(struct kvm_vcpu *vcpu)
+{
+#ifdef CONFIG_X86_64
+ return vcpu->shadow_efer & EFER_LME;
+#else
+ return 0;
+#endif
+}
+
static inline int is_pae(struct kvm_vcpu *vcpu)
{
return vcpu->cr4 & CR4_PAE_MASK;
@@ -485,7 +493,7 @@ static inline unsigned long read_tr_base(void)
return segment_base(tr);
}
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
static inline unsigned long read_msr(unsigned long msr)
{
u64 value;
@@ -533,7 +541,7 @@ static inline u32 get_rdx_init_val(void)
#define TSS_REDIRECTION_SIZE (256 / 8)
#define RMODE_TSS_SIZE (TSS_BASE_SIZE + TSS_REDIRECTION_SIZE + TSS_IOPB_SIZE + 1)
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
/*
* When emulating 32-bit mode, cr3 is only 32 bits even on x86_64. Therefore
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index b6b8a41b5ec8..ce7fe640f18d 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -72,18 +72,7 @@ static struct dentry *debugfs_dir;
#define CR8_RESEVED_BITS (~0x0fULL)
#define EFER_RESERVED_BITS 0xfffffffffffff2fe
-struct vmx_msr_entry *find_msr_entry(struct kvm_vcpu *vcpu, u32 msr)
-{
- int i;
-
- for (i = 0; i < vcpu->nmsrs; ++i)
- if (vcpu->guest_msrs[i].index == msr)
- return &vcpu->guest_msrs[i];
- return 0;
-}
-EXPORT_SYMBOL_GPL(find_msr_entry);
-
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
// LDT or TSS descriptor in the GDT. 16 bytes.
struct segment_descriptor_64 {
struct segment_descriptor s;
@@ -115,7 +104,7 @@ unsigned long segment_base(u16 selector)
}
d = (struct segment_descriptor *)(table_base + (selector & ~7));
v = d->base_low | ((ul)d->base_mid << 16) | ((ul)d->base_high << 24);
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
if (d->system == 0
&& (d->type == 2 || d->type == 9 || d->type == 11))
v |= ((ul)((struct segment_descriptor_64 *)d)->base_higher) << 32;
@@ -124,6 +113,11 @@ unsigned long segment_base(u16 selector)
}
EXPORT_SYMBOL_GPL(segment_base);
+static inline int valid_vcpu(int n)
+{
+ return likely(n >= 0 && n < KVM_MAX_VCPUS);
+}
+
int kvm_read_guest(struct kvm_vcpu *vcpu,
gva_t addr,
unsigned long size,
@@ -216,7 +210,6 @@ static struct kvm_vcpu *vcpu_load(struct kvm *kvm, int vcpu_slot)
static void vcpu_put(struct kvm_vcpu *vcpu)
{
kvm_arch_ops->vcpu_put(vcpu);
- put_cpu();
mutex_unlock(&vcpu->mutex);
}
@@ -252,7 +245,8 @@ static void kvm_free_physmem_slot(struct kvm_memory_slot *free,
if (!dont || free->phys_mem != dont->phys_mem)
if (free->phys_mem) {
for (i = 0; i < free->npages; ++i)
- __free_page(free->phys_mem[i]);
+ if (free->phys_mem[i])
+ __free_page(free->phys_mem[i]);
vfree(free->phys_mem);
}
@@ -351,7 +345,7 @@ void set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
}
if (!is_paging(vcpu) && (cr0 & CR0_PG_MASK)) {
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
if ((vcpu->shadow_efer & EFER_LME)) {
int cs_db, cs_l;
@@ -405,7 +399,7 @@ void set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
return;
}
- if (kvm_arch_ops->is_long_mode(vcpu)) {
+ if (is_long_mode(vcpu)) {
if (!(cr4 & CR4_PAE_MASK)) {
printk(KERN_DEBUG "set_cr4: #GP, clearing PAE while "
"in long mode\n");
@@ -432,7 +426,7 @@ EXPORT_SYMBOL_GPL(set_cr4);
void set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
{
- if (kvm_arch_ops->is_long_mode(vcpu)) {
+ if (is_long_mode(vcpu)) {
if ( cr3 & CR3_L_MODE_RESEVED_BITS) {
printk(KERN_DEBUG "set_cr3: #GP, reserved bits\n");
inject_gp(vcpu);
@@ -506,7 +500,7 @@ static int kvm_dev_ioctl_create_vcpu(struct kvm *kvm, int n)
struct kvm_vcpu *vcpu;
r = -EINVAL;
- if (n < 0 || n >= KVM_MAX_VCPUS)
+ if (!valid_vcpu(n))
goto out;
vcpu = &kvm->vcpus[n];
@@ -528,12 +522,14 @@ static int kvm_dev_ioctl_create_vcpu(struct kvm *kvm, int n)
if (r < 0)
goto out_free_vcpus;
- kvm_arch_ops->vcpu_load(vcpu);
+ r = kvm_mmu_create(vcpu);
+ if (r < 0)
+ goto out_free_vcpus;
- r = kvm_arch_ops->vcpu_setup(vcpu);
+ kvm_arch_ops->vcpu_load(vcpu);
+ r = kvm_mmu_setup(vcpu);
if (r >= 0)
- r = kvm_mmu_init(vcpu);
-
+ r = kvm_arch_ops->vcpu_setup(vcpu);
vcpu_put(vcpu);
if (r < 0)
@@ -1110,6 +1106,51 @@ void realmode_set_cr(struct kvm_vcpu *vcpu, int cr, unsigned long val,
}
}
+int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
+{
+ u64 data;
+
+ switch (msr) {
+ case 0xc0010010: /* SYSCFG */
+ case 0xc0010015: /* HWCR */
+ case MSR_IA32_PLATFORM_ID:
+ case MSR_IA32_P5_MC_ADDR:
+ case MSR_IA32_P5_MC_TYPE:
+ case MSR_IA32_MC0_CTL:
+ case MSR_IA32_MCG_STATUS:
+ case MSR_IA32_MCG_CAP:
+ case MSR_IA32_MC0_MISC:
+ case MSR_IA32_MC0_MISC+4:
+ case MSR_IA32_MC0_MISC+8:
+ case MSR_IA32_MC0_MISC+12:
+ case MSR_IA32_MC0_MISC+16:
+ case MSR_IA32_UCODE_REV:
+ case MSR_IA32_PERF_STATUS:
+ /* MTRR registers */
+ case 0xfe:
+ case 0x200 ... 0x2ff:
+ data = 0;
+ break;
+ case 0xcd: /* fsb frequency */
+ data = 3;
+ break;
+ case MSR_IA32_APICBASE:
+ data = vcpu->apic_base;
+ break;
+#ifdef CONFIG_X86_64
+ case MSR_EFER:
+ data = vcpu->shadow_efer;
+ break;
+#endif
+ default:
+ printk(KERN_ERR "kvm: unhandled rdmsr: 0x%x\n", msr);
+ return 1;
+ }
+ *pdata = data;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(kvm_get_msr_common);
+
/*
* Reads an msr value (of 'msr_index') into 'pdata'.
* Returns 0 on success, non-0 otherwise.
@@ -1120,12 +1161,10 @@ static int get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata)
return kvm_arch_ops->get_msr(vcpu, msr_index, pdata);
}
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
-void set_efer(struct kvm_vcpu *vcpu, u64 efer)
+static void set_efer(struct kvm_vcpu *vcpu, u64 efer)
{
- struct vmx_msr_entry *msr;
-
if (efer & EFER_RESERVED_BITS) {
printk(KERN_DEBUG "set_efer: 0x%llx #GP, reserved bits\n",
efer);
@@ -1140,21 +1179,43 @@ void set_efer(struct kvm_vcpu *vcpu, u64 efer)
return;
}
+ kvm_arch_ops->set_efer(vcpu, efer);
+
efer &= ~EFER_LMA;
efer |= vcpu->shadow_efer & EFER_LMA;
vcpu->shadow_efer = efer;
-
- msr = find_msr_entry(vcpu, MSR_EFER);
-
- if (!(efer & EFER_LMA))
- efer &= ~EFER_LME;
- msr->data = efer;
}
-EXPORT_SYMBOL_GPL(set_efer);
#endif
+int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
+{
+ switch (msr) {
+#ifdef CONFIG_X86_64
+ case MSR_EFER:
+ set_efer(vcpu, data);
+ break;
+#endif
+ case MSR_IA32_MC0_STATUS:
+ printk(KERN_WARNING "%s: MSR_IA32_MC0_STATUS 0x%llx, nop\n",
+ __FUNCTION__, data);
+ break;
+ case MSR_IA32_UCODE_REV:
+ case MSR_IA32_UCODE_WRITE:
+ case 0x200 ... 0x2ff: /* MTRRs */
+ break;
+ case MSR_IA32_APICBASE:
+ vcpu->apic_base = data;
+ break;
+ default:
+ printk(KERN_ERR "kvm: unhandled wrmsr: 0x%x\n", msr);
+ return 1;
+ }
+ return 0;
+}
+EXPORT_SYMBOL_GPL(kvm_set_msr_common);
+
/*
* Writes msr value into into the appropriate "register".
* Returns 0 on success, non-0 otherwise.
@@ -1197,7 +1258,7 @@ static int kvm_dev_ioctl_run(struct kvm *kvm, struct kvm_run *kvm_run)
struct kvm_vcpu *vcpu;
int r;
- if (kvm_run->vcpu < 0 || kvm_run->vcpu >= KVM_MAX_VCPUS)
+ if (!valid_vcpu(kvm_run->vcpu))
return -EINVAL;
vcpu = vcpu_load(kvm, kvm_run->vcpu);
@@ -1226,7 +1287,7 @@ static int kvm_dev_ioctl_get_regs(struct kvm *kvm, struct kvm_regs *regs)
{
struct kvm_vcpu *vcpu;
- if (regs->vcpu < 0 || regs->vcpu >= KVM_MAX_VCPUS)
+ if (!valid_vcpu(regs->vcpu))
return -EINVAL;
vcpu = vcpu_load(kvm, regs->vcpu);
@@ -1243,7 +1304,7 @@ static int kvm_dev_ioctl_get_regs(struct kvm *kvm, struct kvm_regs *regs)
regs->rdi = vcpu->regs[VCPU_REGS_RDI];
regs->rsp = vcpu->regs[VCPU_REGS_RSP];
regs->rbp = vcpu->regs[VCPU_REGS_RBP];
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
regs->r8 = vcpu->regs[VCPU_REGS_R8];
regs->r9 = vcpu->regs[VCPU_REGS_R9];
regs->r10 = vcpu->regs[VCPU_REGS_R10];
@@ -1272,7 +1333,7 @@ static int kvm_dev_ioctl_set_regs(struct kvm *kvm, struct kvm_regs *regs)
{
struct kvm_vcpu *vcpu;
- if (regs->vcpu < 0 || regs->vcpu >= KVM_MAX_VCPUS)
+ if (!valid_vcpu(regs->vcpu))
return -EINVAL;
vcpu = vcpu_load(kvm, regs->vcpu);
@@ -1287,7 +1348,7 @@ static int kvm_dev_ioctl_set_regs(struct kvm *kvm, struct kvm_regs *regs)
vcpu->regs[VCPU_REGS_RDI] = regs->rdi;
vcpu->regs[VCPU_REGS_RSP] = regs->rsp;
vcpu->regs[VCPU_REGS_RBP] = regs->rbp;
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
vcpu->regs[VCPU_REGS_R8] = regs->r8;
vcpu->regs[VCPU_REGS_R9] = regs->r9;
vcpu->regs[VCPU_REGS_R10] = regs->r10;
@@ -1319,7 +1380,7 @@ static int kvm_dev_ioctl_get_sregs(struct kvm *kvm, struct kvm_sregs *sregs)
struct kvm_vcpu *vcpu;
struct descriptor_table dt;
- if (sregs->vcpu < 0 || sregs->vcpu >= KVM_MAX_VCPUS)
+ if (!valid_vcpu(sregs->vcpu))
return -EINVAL;
vcpu = vcpu_load(kvm, sregs->vcpu);
if (!vcpu)
@@ -1371,7 +1432,7 @@ static int kvm_dev_ioctl_set_sregs(struct kvm *kvm, struct kvm_sregs *sregs)
int i;
struct descriptor_table dt;
- if (sregs->vcpu < 0 || sregs->vcpu >= KVM_MAX_VCPUS)
+ if (!valid_vcpu(sregs->vcpu))
return -EINVAL;
vcpu = vcpu_load(kvm, sregs->vcpu);
if (!vcpu)
@@ -1401,7 +1462,7 @@ static int kvm_dev_ioctl_set_sregs(struct kvm *kvm, struct kvm_sregs *sregs)
vcpu->cr8 = sregs->cr8;
mmu_reset_needed |= vcpu->shadow_efer != sregs->efer;
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
kvm_arch_ops->set_efer(vcpu, sregs->efer);
#endif
vcpu->apic_base = sregs->apic_base;
@@ -1430,16 +1491,35 @@ static int kvm_dev_ioctl_set_sregs(struct kvm *kvm, struct kvm_sregs *sregs)
/*
* List of msr numbers which we expose to userspace through KVM_GET_MSRS
* and KVM_SET_MSRS, and KVM_GET_MSR_INDEX_LIST.
+ *
+ * This list is modified at module load time to reflect the
+ * capabilities of the host cpu.
*/
static u32 msrs_to_save[] = {
MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP,
MSR_K6_STAR,
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
MSR_CSTAR, MSR_KERNEL_GS_BASE, MSR_SYSCALL_MASK, MSR_LSTAR,
#endif
MSR_IA32_TIME_STAMP_COUNTER,
};
+static unsigned num_msrs_to_save;
+
+static __init void kvm_init_msr_list(void)
+{
+ u32 dummy[2];
+ unsigned i, j;
+
+ for (i = j = 0; i < ARRAY_SIZE(msrs_to_save); i++) {
+ if (rdmsr_safe(msrs_to_save[i], &dummy[0], &dummy[1]) < 0)
+ continue;
+ if (j < i)
+ msrs_to_save[j] = msrs_to_save[i];
+ j++;
+ }
+ num_msrs_to_save = j;
+}
/*
* Adapt set_msr() to msr_io()'s calling convention
@@ -1462,7 +1542,7 @@ static int __msr_io(struct kvm *kvm, struct kvm_msrs *msrs,
struct kvm_vcpu *vcpu;
int i;
- if (msrs->vcpu < 0 || msrs->vcpu >= KVM_MAX_VCPUS)
+ if (!valid_vcpu(msrs->vcpu))
return -EINVAL;
vcpu = vcpu_load(kvm, msrs->vcpu);
@@ -1555,7 +1635,7 @@ static int kvm_dev_ioctl_interrupt(struct kvm *kvm, struct kvm_interrupt *irq)
{
struct kvm_vcpu *vcpu;
- if (irq->vcpu < 0 || irq->vcpu >= KVM_MAX_VCPUS)
+ if (!valid_vcpu(irq->vcpu))
return -EINVAL;
if (irq->irq < 0 || irq->irq >= 256)
return -EINVAL;
@@ -1577,7 +1657,7 @@ static int kvm_dev_ioctl_debug_guest(struct kvm *kvm,
struct kvm_vcpu *vcpu;
int r;
- if (dbg->vcpu < 0 || dbg->vcpu >= KVM_MAX_VCPUS)
+ if (!valid_vcpu(dbg->vcpu))
return -EINVAL;
vcpu = vcpu_load(kvm, dbg->vcpu);
if (!vcpu)
@@ -1597,6 +1677,9 @@ static long kvm_dev_ioctl(struct file *filp,
int r = -EINVAL;
switch (ioctl) {
+ case KVM_GET_API_VERSION:
+ r = KVM_API_VERSION;
+ break;
case KVM_CREATE_VCPU: {
r = kvm_dev_ioctl_create_vcpu(kvm, arg);
if (r)
@@ -1748,15 +1831,15 @@ static long kvm_dev_ioctl(struct file *filp,
if (copy_from_user(&msr_list, user_msr_list, sizeof msr_list))
goto out;
n = msr_list.nmsrs;
- msr_list.nmsrs = ARRAY_SIZE(msrs_to_save);
+ msr_list.nmsrs = num_msrs_to_save;
if (copy_to_user(user_msr_list, &msr_list, sizeof msr_list))
goto out;
r = -E2BIG;
- if (n < ARRAY_SIZE(msrs_to_save))
+ if (n < num_msrs_to_save)
goto out;
r = -EFAULT;
if (copy_to_user(user_msr_list->indices, &msrs_to_save,
- sizeof msrs_to_save))
+ num_msrs_to_save * sizeof(u32)))
goto out;
r = 0;
}
@@ -1856,6 +1939,11 @@ int kvm_init_arch(struct kvm_arch_ops *ops, struct module *module)
{
int r;
+ if (kvm_arch_ops) {
+ printk(KERN_ERR "kvm: already loaded the other module\n");
+ return -EEXIST;
+ }
+
kvm_arch_ops = ops;
if (!kvm_arch_ops->cpu_has_kvm_support()) {
@@ -1898,6 +1986,7 @@ void kvm_exit_arch(void)
unregister_reboot_notifier(&kvm_reboot_notifier);
on_each_cpu(kvm_arch_ops->hardware_disable, 0, 0, 1);
kvm_arch_ops->hardware_unsetup();
+ kvm_arch_ops = NULL;
}
static __init int kvm_init(void)
@@ -1907,6 +1996,8 @@ static __init int kvm_init(void)
kvm_init_debug();
+ kvm_init_msr_list();
+
if ((bad_page = alloc_page(GFP_KERNEL)) == NULL) {
r = -ENOMEM;
goto out;
diff --git a/drivers/kvm/kvm_svm.h b/drivers/kvm/kvm_svm.h
index 7d7f2aa10960..74cc862f4935 100644
--- a/drivers/kvm/kvm_svm.h
+++ b/drivers/kvm/kvm_svm.h
@@ -9,7 +9,7 @@
#include "kvm.h"
static const u32 host_save_msrs[] = {
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
MSR_STAR, MSR_LSTAR, MSR_CSTAR, MSR_SYSCALL_MASK, MSR_KERNEL_GS_BASE,
MSR_FS_BASE, MSR_GS_BASE,
#endif
diff --git a/drivers/kvm/kvm_vmx.h b/drivers/kvm/kvm_vmx.h
index 87e12d2bfa16..d139f73fb6e1 100644
--- a/drivers/kvm/kvm_vmx.h
+++ b/drivers/kvm/kvm_vmx.h
@@ -1,7 +1,7 @@
#ifndef __KVM_VMX_H
#define __KVM_VMX_H
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
/*
* avoid save/load MSR_SYSCALL_MASK and MSR_LSTAR by std vt
* mechanism (cpu bug AA24)
diff --git a/drivers/kvm/mmu.c b/drivers/kvm/mmu.c
index 4e29d9b7211c..790423c5f23d 100644
--- a/drivers/kvm/mmu.c
+++ b/drivers/kvm/mmu.c
@@ -61,22 +61,9 @@
#define PT32_PTE_COPY_MASK \
- (PT_PRESENT_MASK | PT_PWT_MASK | PT_PCD_MASK | \
- PT_ACCESSED_MASK | PT_DIRTY_MASK | PT_PAT_MASK | \
- PT_GLOBAL_MASK )
-
-#define PT32_NON_PTE_COPY_MASK \
- (PT_PRESENT_MASK | PT_PWT_MASK | PT_PCD_MASK | \
- PT_ACCESSED_MASK | PT_DIRTY_MASK)
-
-
-#define PT64_PTE_COPY_MASK \
- (PT64_NX_MASK | PT32_PTE_COPY_MASK)
-
-#define PT64_NON_PTE_COPY_MASK \
- (PT64_NX_MASK | PT32_NON_PTE_COPY_MASK)
-
+ (PT_PRESENT_MASK | PT_ACCESSED_MASK | PT_DIRTY_MASK | PT_GLOBAL_MASK)
+#define PT64_PTE_COPY_MASK (PT64_NX_MASK | PT32_PTE_COPY_MASK)
#define PT_FIRST_AVAIL_BITS_SHIFT 9
#define PT64_SECOND_AVAIL_BITS_SHIFT 52
@@ -591,7 +578,7 @@ static int init_kvm_mmu(struct kvm_vcpu *vcpu)
if (!is_paging(vcpu))
return nonpaging_init_context(vcpu);
- else if (kvm_arch_ops->is_long_mode(vcpu))
+ else if (is_long_mode(vcpu))
return paging64_init_context(vcpu);
else if (is_pae(vcpu))
return paging32E_init_context(vcpu);
@@ -652,22 +639,22 @@ error_1:
return -ENOMEM;
}
-int kvm_mmu_init(struct kvm_vcpu *vcpu)
+int kvm_mmu_create(struct kvm_vcpu *vcpu)
{
- int r;
-
ASSERT(vcpu);
ASSERT(!VALID_PAGE(vcpu->mmu.root_hpa));
ASSERT(list_empty(&vcpu->free_pages));
- if ((r = alloc_mmu_pages(vcpu)))
- return r;
+ return alloc_mmu_pages(vcpu);
+}
+
+int kvm_mmu_setup(struct kvm_vcpu *vcpu)
+{
+ ASSERT(vcpu);
+ ASSERT(!VALID_PAGE(vcpu->mmu.root_hpa));
+ ASSERT(!list_empty(&vcpu->free_pages));
- if ((r = init_kvm_mmu(vcpu))) {
- free_mmu_pages(vcpu);
- return r;
- }
- return 0;
+ return init_kvm_mmu(vcpu);
}
void kvm_mmu_destroy(struct kvm_vcpu *vcpu)
diff --git a/drivers/kvm/paging_tmpl.h b/drivers/kvm/paging_tmpl.h
index 765c2e1a048e..09bb9b4ed12d 100644
--- a/drivers/kvm/paging_tmpl.h
+++ b/drivers/kvm/paging_tmpl.h
@@ -32,7 +32,6 @@
#define SHADOW_PT_INDEX(addr, level) PT64_INDEX(addr, level)
#define PT_LEVEL_MASK(level) PT64_LEVEL_MASK(level)
#define PT_PTE_COPY_MASK PT64_PTE_COPY_MASK
- #define PT_NON_PTE_COPY_MASK PT64_NON_PTE_COPY_MASK
#elif PTTYPE == 32
#define pt_element_t u32
#define guest_walker guest_walker32
@@ -43,7 +42,6 @@
#define SHADOW_PT_INDEX(addr, level) PT64_INDEX(addr, level)
#define PT_LEVEL_MASK(level) PT32_LEVEL_MASK(level)
#define PT_PTE_COPY_MASK PT32_PTE_COPY_MASK
- #define PT_NON_PTE_COPY_MASK PT32_NON_PTE_COPY_MASK
#else
#error Invalid PTTYPE value
#endif
@@ -70,7 +68,7 @@ static void FNAME(init_walker)(struct guest_walker *walker,
hpa = safe_gpa_to_hpa(vcpu, vcpu->cr3 & PT64_BASE_ADDR_MASK);
walker->table = kmap_atomic(pfn_to_page(hpa >> PAGE_SHIFT), KM_USER0);
- ASSERT((!kvm_arch_ops->is_long_mode(vcpu) && is_pae(vcpu)) ||
+ ASSERT((!is_long_mode(vcpu) && is_pae(vcpu)) ||
(vcpu->cr3 & ~(PAGE_MASK | CR3_FLAGS_MASK)) == 0);
walker->table = (pt_element_t *)( (unsigned long)walker->table |
@@ -105,9 +103,7 @@ static void FNAME(set_pde)(struct kvm_vcpu *vcpu, u64 guest_pde,
if (PTTYPE == 32 && is_cpuid_PSE36())
gaddr |= (guest_pde & PT32_DIR_PSE36_MASK) <<
(32 - PT32_DIR_PSE36_SHIFT);
- *shadow_pte = (guest_pde & (PT_NON_PTE_COPY_MASK | PT_GLOBAL_MASK)) |
- ((guest_pde & PT_DIR_PAT_MASK) >>
- (PT_DIR_PAT_SHIFT - PT_PAT_SHIFT));
+ *shadow_pte = guest_pde & PT_PTE_COPY_MASK;
set_pte_common(vcpu, shadow_pte, gaddr,
guest_pde & PT_DIRTY_MASK, access_bits);
}
@@ -135,7 +131,7 @@ static pt_element_t *FNAME(fetch_guest)(struct kvm_vcpu *vcpu,
(walker->table[index] & PT_PAGE_SIZE_MASK) &&
(PTTYPE == 64 || is_pse(vcpu))))
return &walker->table[index];
- if (walker->level != 3 || kvm_arch_ops->is_long_mode(vcpu))
+ if (walker->level != 3 || is_long_mode(vcpu))
walker->inherited_ar &= walker->table[index];
paddr = safe_gpa_to_hpa(vcpu, walker->table[index] & PT_BASE_ADDR_MASK);
kunmap_atomic(walker->table, KM_USER0);
@@ -162,6 +158,7 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
u32 index = SHADOW_PT_INDEX(addr, level);
u64 *shadow_ent = ((u64 *)__va(shadow_addr)) + index;
pt_element_t *guest_ent;
+ u64 shadow_pte;
if (is_present_pte(*shadow_ent) || is_io_pte(*shadow_ent)) {
if (level == PT_PAGE_TABLE_LEVEL)
@@ -204,14 +201,11 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
shadow_addr = kvm_mmu_alloc_page(vcpu, shadow_ent);
if (!VALID_PAGE(shadow_addr))
return ERR_PTR(-ENOMEM);
- if (!kvm_arch_ops->is_long_mode(vcpu) && level == 3)
- *shadow_ent = shadow_addr |
- (*guest_ent & (PT_PRESENT_MASK | PT_PWT_MASK | PT_PCD_MASK));
- else {
- *shadow_ent = shadow_addr |
- (*guest_ent & PT_NON_PTE_COPY_MASK);
- *shadow_ent |= (PT_WRITABLE_MASK | PT_USER_MASK);
- }
+ shadow_pte = shadow_addr | PT_PRESENT_MASK;
+ if (vcpu->mmu.root_level > 3 || level != 3)
+ shadow_pte |= PT_ACCESSED_MASK
+ | PT_WRITABLE_MASK | PT_USER_MASK;
+ *shadow_ent = shadow_pte;
prev_shadow_ent = shadow_ent;
}
}
diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c
index a33a89c68138..fa0428735717 100644
--- a/drivers/kvm/svm.c
+++ b/drivers/kvm/svm.c
@@ -166,11 +166,6 @@ static inline void write_dr7(unsigned long val)
asm volatile ("mov %0, %%dr7" :: "r" (val));
}
-static inline int svm_is_long_mode(struct kvm_vcpu *vcpu)
-{
- return vcpu->svm->vmcb->save.efer & KVM_EFER_LMA;
-}
-
static inline void force_new_asid(struct kvm_vcpu *vcpu)
{
vcpu->svm->asid_generation--;
@@ -246,7 +241,7 @@ static int has_svm(void)
{
uint32_t eax, ebx, ecx, edx;
- if (current_cpu_data.x86_vendor != X86_VENDOR_AMD) {
+ if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) {
printk(KERN_INFO "has_svm: not amd\n");
return 0;
}
@@ -287,7 +282,7 @@ static void svm_hardware_enable(void *garbage)
struct svm_cpu_data *svm_data;
uint64_t efer;
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
struct desc_ptr gdt_descr;
#else
struct Xgt_desc_struct gdt_descr;
@@ -377,6 +372,7 @@ static __init int svm_hardware_setup(void)
void *msrpm_va;
int r;
+ kvm_emulator_want_group7_invlpg();
iopm_pages = alloc_pages(GFP_KERNEL, IOPM_ALLOC_ORDER);
@@ -397,15 +393,15 @@ static __init int svm_hardware_setup(void)
memset(msrpm_va, 0xff, PAGE_SIZE * (1 << MSRPM_ALLOC_ORDER));
msrpm_base = page_to_pfn(msrpm_pages) << PAGE_SHIFT;
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
set_msr_interception(msrpm_va, MSR_GS_BASE, 1, 1);
set_msr_interception(msrpm_va, MSR_FS_BASE, 1, 1);
set_msr_interception(msrpm_va, MSR_KERNEL_GS_BASE, 1, 1);
- set_msr_interception(msrpm_va, MSR_STAR, 1, 1);
set_msr_interception(msrpm_va, MSR_LSTAR, 1, 1);
set_msr_interception(msrpm_va, MSR_CSTAR, 1, 1);
set_msr_interception(msrpm_va, MSR_SYSCALL_MASK, 1, 1);
#endif
+ set_msr_interception(msrpm_va, MSR_K6_STAR, 1, 1);
set_msr_interception(msrpm_va, MSR_IA32_SYSENTER_CS, 1, 1);
set_msr_interception(msrpm_va, MSR_IA32_SYSENTER_ESP, 1, 1);
set_msr_interception(msrpm_va, MSR_IA32_SYSENTER_EIP, 1, 1);
@@ -574,6 +570,8 @@ static int svm_create_vcpu(struct kvm_vcpu *vcpu)
memset(vcpu->svm->db_regs, 0, sizeof(vcpu->svm->db_regs));
init_vmcb(vcpu->svm->vmcb);
+ fx_init(vcpu);
+
return 0;
out2:
@@ -704,7 +702,7 @@ static void svm_set_gdt(struct kvm_vcpu *vcpu, struct descriptor_table *dt)
static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
{
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
if (vcpu->shadow_efer & KVM_EFER_LME) {
if (!is_paging(vcpu) && (cr0 & CR0_PG_MASK)) {
vcpu->shadow_efer |= KVM_EFER_LMA;
@@ -1070,20 +1068,6 @@ static int emulate_on_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_ru
static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data)
{
switch (ecx) {
- case MSR_IA32_MC0_CTL:
- case MSR_IA32_MCG_STATUS:
- case MSR_IA32_MCG_CAP:
- case MSR_IA32_MC0_MISC:
- case MSR_IA32_MC0_MISC+4:
- case MSR_IA32_MC0_MISC+8:
- case MSR_IA32_MC0_MISC+12:
- case MSR_IA32_MC0_MISC+16:
- case MSR_IA32_UCODE_REV:
- /* MTRR registers */
- case 0xfe:
- case 0x200 ... 0x2ff:
- *data = 0;
- break;
case MSR_IA32_TIME_STAMP_COUNTER: {
u64 tsc;
@@ -1091,16 +1075,10 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data)
*data = vcpu->svm->vmcb->control.tsc_offset + tsc;
break;
}
- case MSR_EFER:
- *data = vcpu->shadow_efer;
- break;
- case MSR_IA32_APICBASE:
- *data = vcpu->apic_base;
- break;
-#ifdef __x86_64__
- case MSR_STAR:
+ case MSR_K6_STAR:
*data = vcpu->svm->vmcb->save.star;
break;
+#ifdef CONFIG_X86_64
case MSR_LSTAR:
*data = vcpu->svm->vmcb->save.lstar;
break;
@@ -1124,8 +1102,7 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data)
*data = vcpu->svm->vmcb->save.sysenter_esp;
break;
default:
- printk(KERN_ERR "kvm: unhandled rdmsr: 0x%x\n", ecx);
- return 1;
+ return kvm_get_msr_common(vcpu, ecx, data);
}
return 0;
}
@@ -1149,15 +1126,6 @@ static int rdmsr_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data)
{
switch (ecx) {
-#ifdef __x86_64__
- case MSR_EFER:
- set_efer(vcpu, data);
- break;
-#endif
- case MSR_IA32_MC0_STATUS:
- printk(KERN_WARNING "%s: MSR_IA32_MC0_STATUS 0x%llx, nop\n"
- , __FUNCTION__, data);
- break;
case MSR_IA32_TIME_STAMP_COUNTER: {
u64 tsc;
@@ -1165,17 +1133,10 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data)
vcpu->svm->vmcb->control.tsc_offset = data - tsc;
break;
}
- case MSR_IA32_UCODE_REV:
- case MSR_IA32_UCODE_WRITE:
- case 0x200 ... 0x2ff: /* MTRRs */
- break;
- case MSR_IA32_APICBASE:
- vcpu->apic_base = data;
- break;
-#ifdef __x86_64___
- case MSR_STAR:
+ case MSR_K6_STAR:
vcpu->svm->vmcb->save.star = data;
break;
+#ifdef CONFIG_X86_64_
case MSR_LSTAR:
vcpu->svm->vmcb->save.lstar = data;
break;
@@ -1199,8 +1160,7 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data)
vcpu->svm->vmcb->save.sysenter_esp = data;
break;
default:
- printk(KERN_ERR "kvm: unhandled wrmsr: %x\n", ecx);
- return 1;
+ return kvm_set_msr_common(vcpu, ecx, data);
}
return 0;
}
@@ -1345,53 +1305,18 @@ static void kvm_reput_irq(struct kvm_vcpu *vcpu)
static void save_db_regs(unsigned long *db_regs)
{
-#ifdef __x86_64__
- asm ("mov %%dr0, %%rax \n\t"
- "mov %%rax, %[dr0] \n\t"
- "mov %%dr1, %%rax \n\t"
- "mov %%rax, %[dr1] \n\t"
- "mov %%dr2, %%rax \n\t"
- "mov %%rax, %[dr2] \n\t"
- "mov %%dr3, %%rax \n\t"
- "mov %%rax, %[dr3] \n\t"
- : [dr0] "=m"(db_regs[0]),
- [dr1] "=m"(db_regs[1]),
- [dr2] "=m"(db_regs[2]),
- [dr3] "=m"(db_regs[3])
- : : "rax");
-#else
- asm ("mov %%dr0, %%eax \n\t"
- "mov %%eax, %[dr0] \n\t"
- "mov %%dr1, %%eax \n\t"
- "mov %%eax, %[dr1] \n\t"
- "mov %%dr2, %%eax \n\t"
- "mov %%eax, %[dr2] \n\t"
- "mov %%dr3, %%eax \n\t"
- "mov %%eax, %[dr3] \n\t"
- : [dr0] "=m"(db_regs[0]),
- [dr1] "=m"(db_regs[1]),
- [dr2] "=m"(db_regs[2]),
- [dr3] "=m"(db_regs[3])
- : : "eax");
-#endif
+ asm volatile ("mov %%dr0, %0" : "=r"(db_regs[0]));
+ asm volatile ("mov %%dr1, %0" : "=r"(db_regs[1]));
+ asm volatile ("mov %%dr2, %0" : "=r"(db_regs[2]));
+ asm volatile ("mov %%dr3, %0" : "=r"(db_regs[3]));
}
static void load_db_regs(unsigned long *db_regs)
{
- asm volatile ("mov %[dr0], %%dr0 \n\t"
- "mov %[dr1], %%dr1 \n\t"
- "mov %[dr2], %%dr2 \n\t"
- "mov %[dr3], %%dr3 \n\t"
- :
- : [dr0] "r"(db_regs[0]),
- [dr1] "r"(db_regs[1]),
- [dr2] "r"(db_regs[2]),
- [dr3] "r"(db_regs[3])
-#ifdef __x86_64__
- : "rax");
-#else
- : "eax");
-#endif
+ asm volatile ("mov %0, %%dr0" : : "r"(db_regs[0]));
+ asm volatile ("mov %0, %%dr1" : : "r"(db_regs[1]));
+ asm volatile ("mov %0, %%dr2" : : "r"(db_regs[2]));
+ asm volatile ("mov %0, %%dr3" : : "r"(db_regs[3]));
}
static int svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
@@ -1421,8 +1346,12 @@ again:
save_db_regs(vcpu->svm->host_db_regs);
load_db_regs(vcpu->svm->db_regs);
}
+
+ fx_save(vcpu->host_fx_image);
+ fx_restore(vcpu->guest_fx_image);
+
asm volatile (
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
"push %%rbx; push %%rcx; push %%rdx;"
"push %%rsi; push %%rdi; push %%rbp;"
"push %%r8; push %%r9; push %%r10; push %%r11;"
@@ -1432,7 +1361,7 @@ again:
"push %%esi; push %%edi; push %%ebp;"
#endif
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
"mov %c[rbx](%[vcpu]), %%rbx \n\t"
"mov %c[rcx](%[vcpu]), %%rcx \n\t"
"mov %c[rdx](%[vcpu]), %%rdx \n\t"
@@ -1456,7 +1385,7 @@ again:
"mov %c[rbp](%[vcpu]), %%ebp \n\t"
#endif
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
/* Enter guest mode */
"push %%rax \n\t"
"mov %c[svm](%[vcpu]), %%rax \n\t"
@@ -1477,7 +1406,7 @@ again:
#endif
/* Save guest registers, load host registers */
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
"mov %%rbx, %c[rbx](%[vcpu]) \n\t"
"mov %%rcx, %c[rcx](%[vcpu]) \n\t"
"mov %%rdx, %c[rdx](%[vcpu]) \n\t"
@@ -1518,7 +1447,7 @@ again:
[rsi]"i"(offsetof(struct kvm_vcpu, regs[VCPU_REGS_RSI])),
[rdi]"i"(offsetof(struct kvm_vcpu, regs[VCPU_REGS_RDI])),
[rbp]"i"(offsetof(struct kvm_vcpu, regs[VCPU_REGS_RBP]))
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
,[r8 ]"i"(offsetof(struct kvm_vcpu, regs[VCPU_REGS_R8 ])),
[r9 ]"i"(offsetof(struct kvm_vcpu, regs[VCPU_REGS_R9 ])),
[r10]"i"(offsetof(struct kvm_vcpu, regs[VCPU_REGS_R10])),
@@ -1530,6 +1459,9 @@ again:
#endif
: "cc", "memory" );
+ fx_save(vcpu->guest_fx_image);
+ fx_restore(vcpu->host_fx_image);
+
if ((vcpu->svm->vmcb->save.dr7 & 0xff))
load_db_regs(vcpu->svm->host_db_regs);
@@ -1632,7 +1564,6 @@ static struct kvm_arch_ops svm_arch_ops = {
.get_segment_base = svm_get_segment_base,
.get_segment = svm_get_segment,
.set_segment = svm_set_segment,
- .is_long_mode = svm_is_long_mode,
.get_cs_db_l_bits = svm_get_cs_db_l_bits,
.set_cr0 = svm_set_cr0,
.set_cr0_no_modeswitch = svm_set_cr0,
@@ -1663,9 +1594,7 @@ static struct kvm_arch_ops svm_arch_ops = {
static int __init svm_init(void)
{
- kvm_emulator_want_group7_invlpg();
- kvm_init_arch(&svm_arch_ops, THIS_MODULE);
- return 0;
+ return kvm_init_arch(&svm_arch_ops, THIS_MODULE);
}
static void __exit svm_exit(void)
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index bda7a7ae2167..d0a2c2d5342a 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -22,10 +22,10 @@
#include <linux/mm.h>
#include <linux/highmem.h>
#include <asm/io.h>
+#include <asm/desc.h>
#include "segment_descriptor.h"
-#define MSR_IA32_FEATURE_CONTROL 0x03a
MODULE_AUTHOR("Qumranet");
MODULE_LICENSE("GPL");
@@ -33,7 +33,7 @@ MODULE_LICENSE("GPL");
static DEFINE_PER_CPU(struct vmcs *, vmxarea);
static DEFINE_PER_CPU(struct vmcs *, current_vmcs);
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
#define HOST_IS_64 1
#else
#define HOST_IS_64 0
@@ -70,15 +70,13 @@ static struct kvm_vmx_segment_field {
};
static const u32 vmx_msr_index[] = {
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
MSR_SYSCALL_MASK, MSR_LSTAR, MSR_CSTAR, MSR_KERNEL_GS_BASE,
#endif
MSR_EFER, MSR_K6_STAR,
};
#define NR_VMX_MSR (sizeof(vmx_msr_index) / sizeof(*vmx_msr_index))
-struct vmx_msr_entry *find_msr_entry(struct kvm_vcpu *vcpu, u32 msr);
-
static inline int is_page_fault(u32 intr_info)
{
return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK |
@@ -92,6 +90,16 @@ static inline int is_external_interrupt(u32 intr_info)
== (INTR_TYPE_EXT_INTR | INTR_INFO_VALID_MASK);
}
+static struct vmx_msr_entry *find_msr_entry(struct kvm_vcpu *vcpu, u32 msr)
+{
+ int i;
+
+ for (i = 0; i < vcpu->nmsrs; ++i)
+ if (vcpu->guest_msrs[i].index == msr)
+ return &vcpu->guest_msrs[i];
+ return 0;
+}
+
static void vmcs_clear(struct vmcs *vmcs)
{
u64 phys_addr = __pa(vmcs);
@@ -137,7 +145,7 @@ static u32 vmcs_read32(unsigned long field)
static u64 vmcs_read64(unsigned long field)
{
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
return vmcs_readl(field);
#else
return vmcs_readl(field) | ((u64)vmcs_readl(field+1) << 32);
@@ -167,7 +175,7 @@ static void vmcs_write32(unsigned long field, u32 value)
static void vmcs_write64(unsigned long field, u64 value)
{
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
vmcs_writel(field, value);
#else
vmcs_writel(field, value);
@@ -296,7 +304,7 @@ static void guest_write_tsc(u64 guest_tsc)
static void reload_tss(void)
{
-#ifndef __x86_64__
+#ifndef CONFIG_X86_64
/*
* VT restores TR but not its size. Useless.
@@ -327,7 +335,7 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata)
}
switch (msr_index) {
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
case MSR_FS_BASE:
data = vmcs_readl(GUEST_FS_BASE);
break;
@@ -335,8 +343,7 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata)
data = vmcs_readl(GUEST_GS_BASE);
break;
case MSR_EFER:
- data = vcpu->shadow_efer;
- break;
+ return kvm_get_msr_common(vcpu, msr_index, pdata);
#endif
case MSR_IA32_TIME_STAMP_COUNTER:
data = guest_read_tsc();
@@ -350,31 +357,13 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata)
case MSR_IA32_SYSENTER_ESP:
data = vmcs_read32(GUEST_SYSENTER_ESP);
break;
- case MSR_IA32_MC0_CTL:
- case MSR_IA32_MCG_STATUS:
- case MSR_IA32_MCG_CAP:
- case MSR_IA32_MC0_MISC:
- case MSR_IA32_MC0_MISC+4:
- case MSR_IA32_MC0_MISC+8:
- case MSR_IA32_MC0_MISC+12:
- case MSR_IA32_MC0_MISC+16:
- case MSR_IA32_UCODE_REV:
- /* MTRR registers */
- case 0xfe:
- case 0x200 ... 0x2ff:
- data = 0;
- break;
- case MSR_IA32_APICBASE:
- data = vcpu->apic_base;
- break;
default:
msr = find_msr_entry(vcpu, msr_index);
- if (!msr) {
- printk(KERN_ERR "kvm: unhandled rdmsr: %x\n", msr_index);
- return 1;
+ if (msr) {
+ data = msr->data;
+ break;
}
- data = msr->data;
- break;
+ return kvm_get_msr_common(vcpu, msr_index, pdata);
}
*pdata = data;
@@ -390,7 +379,9 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data)
{
struct vmx_msr_entry *msr;
switch (msr_index) {
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
+ case MSR_EFER:
+ return kvm_set_msr_common(vcpu, msr_index, data);
case MSR_FS_BASE:
vmcs_writel(GUEST_FS_BASE, data);
break;
@@ -407,32 +398,17 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data)
case MSR_IA32_SYSENTER_ESP:
vmcs_write32(GUEST_SYSENTER_ESP, data);
break;
-#ifdef __x86_64
- case MSR_EFER:
- set_efer(vcpu, data);
- break;
- case MSR_IA32_MC0_STATUS:
- printk(KERN_WARNING "%s: MSR_IA32_MC0_STATUS 0x%llx, nop\n"
- , __FUNCTION__, data);
- break;
-#endif
case MSR_IA32_TIME_STAMP_COUNTER: {
guest_write_tsc(data);
break;
}
- case MSR_IA32_UCODE_REV:
- case MSR_IA32_UCODE_WRITE:
- case 0x200 ... 0x2ff: /* MTRRs */
- break;
- case MSR_IA32_APICBASE:
- vcpu->apic_base = data;
- break;
default:
msr = find_msr_entry(vcpu, msr_index);
- if (!msr) {
- printk(KERN_ERR "kvm: unhandled wrmsr: 0x%x\n", msr_index);
- return 1;
+ if (msr) {
+ msr->data = data;
+ break;
}
+ return kvm_set_msr_common(vcpu, msr_index, data);
msr->data = data;
break;
}
@@ -525,7 +501,7 @@ static __init void hardware_enable(void *garbage)
u64 old;
rdmsrl(MSR_IA32_FEATURE_CONTROL, old);
- if ((old & 5) == 0)
+ if ((old & 5) != 5)
/* enable and lock */
wrmsrl(MSR_IA32_FEATURE_CONTROL, old | 5);
write_cr4(read_cr4() | CR4_VMXE); /* FIXME: not cpu hotplug safe */
@@ -542,11 +518,11 @@ static __init void setup_vmcs_descriptor(void)
{
u32 vmx_msr_low, vmx_msr_high;
- rdmsr(MSR_IA32_VMX_BASIC_MSR, vmx_msr_low, vmx_msr_high);
+ rdmsr(MSR_IA32_VMX_BASIC, vmx_msr_low, vmx_msr_high);
vmcs_descriptor.size = vmx_msr_high & 0x1fff;
vmcs_descriptor.order = get_order(vmcs_descriptor.size);
vmcs_descriptor.revision_id = vmx_msr_low;
-};
+}
static struct vmcs *alloc_vmcs_cpu(int cpu)
{
@@ -717,6 +693,7 @@ static void enter_rmode(struct kvm_vcpu *vcpu)
vmcs_write32(GUEST_SS_AR_BYTES, 0xf3);
vmcs_write32(GUEST_CS_AR_BYTES, 0xf3);
+ vmcs_write32(GUEST_CS_LIMIT, 0xffff);
vmcs_write16(GUEST_CS_SELECTOR, vmcs_readl(GUEST_CS_BASE) >> 4);
fix_rmode_seg(VCPU_SREG_ES, &vcpu->rmode.es);
@@ -725,7 +702,7 @@ static void enter_rmode(struct kvm_vcpu *vcpu)
fix_rmode_seg(VCPU_SREG_FS, &vcpu->rmode.fs);
}
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
static void enter_lmode(struct kvm_vcpu *vcpu)
{
@@ -767,7 +744,7 @@ static void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
if (!vcpu->rmode.active && !(cr0 & CR0_PE_MASK))
enter_rmode(vcpu);
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
if (vcpu->shadow_efer & EFER_LME) {
if (!is_paging(vcpu) && (cr0 & CR0_PG_MASK))
enter_lmode(vcpu);
@@ -808,7 +785,7 @@ static void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
vcpu->cr4 = cr4;
}
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
static void vmx_set_efer(struct kvm_vcpu *vcpu, u64 efer)
{
@@ -883,14 +860,11 @@ static void vmx_set_segment(struct kvm_vcpu *vcpu,
ar |= (var->db & 1) << 14;
ar |= (var->g & 1) << 15;
}
+ if (ar == 0) /* a 0 value means unusable */
+ ar = AR_UNUSABLE_MASK;
vmcs_write32(sf->ar_bytes, ar);
}
-static int vmx_is_long_mode(struct kvm_vcpu *vcpu)
-{
- return vmcs_read32(VM_ENTRY_CONTROLS) & VM_ENTRY_CONTROLS_IA32E_MASK;
-}
-
static void vmx_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l)
{
u32 ar = vmcs_read32(GUEST_CS_AR_BYTES);
@@ -1064,12 +1038,12 @@ static int vmx_vcpu_setup(struct kvm_vcpu *vcpu)
vmcs_write64(GUEST_IA32_DEBUGCTL, 0);
/* Control */
- vmcs_write32_fixedbits(MSR_IA32_VMX_PINBASED_CTLS_MSR,
+ vmcs_write32_fixedbits(MSR_IA32_VMX_PINBASED_CTLS,
PIN_BASED_VM_EXEC_CONTROL,
PIN_BASED_EXT_INTR_MASK /* 20.6.1 */
| PIN_BASED_NMI_EXITING /* 20.6.1 */
);
- vmcs_write32_fixedbits(MSR_IA32_VMX_PROCBASED_CTLS_MSR,
+ vmcs_write32_fixedbits(MSR_IA32_VMX_PROCBASED_CTLS,
CPU_BASED_VM_EXEC_CONTROL,
CPU_BASED_HLT_EXITING /* 20.6.2 */
| CPU_BASED_CR8_LOAD_EXITING /* 20.6.2 */
@@ -1095,7 +1069,7 @@ static int vmx_vcpu_setup(struct kvm_vcpu *vcpu)
vmcs_write16(HOST_FS_SELECTOR, read_fs()); /* 22.2.4 */
vmcs_write16(HOST_GS_SELECTOR, read_gs()); /* 22.2.4 */
vmcs_write16(HOST_SS_SELECTOR, __KERNEL_DS); /* 22.2.4 */
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
rdmsrl(MSR_FS_BASE, a);
vmcs_writel(HOST_FS_BASE, a); /* 22.2.4 */
rdmsrl(MSR_GS_BASE, a);
@@ -1152,7 +1126,7 @@ static int vmx_vcpu_setup(struct kvm_vcpu *vcpu)
virt_to_phys(vcpu->guest_msrs + NR_BAD_MSRS));
vmcs_writel(VM_EXIT_MSR_LOAD_ADDR,
virt_to_phys(vcpu->host_msrs + NR_BAD_MSRS));
- vmcs_write32_fixedbits(MSR_IA32_VMX_EXIT_CTLS_MSR, VM_EXIT_CONTROLS,
+ vmcs_write32_fixedbits(MSR_IA32_VMX_EXIT_CTLS, VM_EXIT_CONTROLS,
(HOST_IS_64 << 9)); /* 22.2,1, 20.7.1 */
vmcs_write32(VM_EXIT_MSR_STORE_COUNT, nr_good_msrs); /* 22.2.2 */
vmcs_write32(VM_EXIT_MSR_LOAD_COUNT, nr_good_msrs); /* 22.2.2 */
@@ -1160,12 +1134,14 @@ static int vmx_vcpu_setup(struct kvm_vcpu *vcpu)
/* 22.2.1, 20.8.1 */
- vmcs_write32_fixedbits(MSR_IA32_VMX_ENTRY_CTLS_MSR,
+ vmcs_write32_fixedbits(MSR_IA32_VMX_ENTRY_CTLS,
VM_ENTRY_CONTROLS, 0);
vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, 0); /* 22.2.1 */
+#ifdef CONFIG_X86_64
vmcs_writel(VIRTUAL_APIC_PAGE_ADDR, 0);
vmcs_writel(TPR_THRESHOLD, 0);
+#endif
vmcs_writel(CR0_GUEST_HOST_MASK, KVM_GUEST_CR0_MASK);
vmcs_writel(CR4_GUEST_HOST_MASK, KVM_GUEST_CR4_MASK);
@@ -1173,7 +1149,7 @@ static int vmx_vcpu_setup(struct kvm_vcpu *vcpu)
vcpu->cr0 = 0x60000010;
vmx_set_cr0(vcpu, vcpu->cr0); // enter rmode
vmx_set_cr4(vcpu, 0);
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
vmx_set_efer(vcpu, 0);
#endif
@@ -1689,7 +1665,7 @@ again:
vmcs_write16(HOST_GS_SELECTOR, 0);
}
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
vmcs_writel(HOST_FS_BASE, read_msr(MSR_FS_BASE));
vmcs_writel(HOST_GS_BASE, read_msr(MSR_GS_BASE));
#else
@@ -1713,7 +1689,7 @@ again:
asm (
/* Store host registers */
"pushf \n\t"
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
"push %%rax; push %%rbx; push %%rdx;"
"push %%rsi; push %%rdi; push %%rbp;"
"push %%r8; push %%r9; push %%r10; push %%r11;"
@@ -1727,7 +1703,7 @@ again:
/* Check if vmlaunch of vmresume is needed */
"cmp $0, %1 \n\t"
/* Load guest registers. Don't clobber flags. */
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
"mov %c[cr2](%3), %%rax \n\t"
"mov %%rax, %%cr2 \n\t"
"mov %c[rax](%3), %%rax \n\t"
@@ -1764,7 +1740,7 @@ again:
".globl kvm_vmx_return \n\t"
"kvm_vmx_return: "
/* Save guest registers, load host registers, keep flags */
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
"xchg %3, 0(%%rsp) \n\t"
"mov %%rax, %c[rax](%3) \n\t"
"mov %%rbx, %c[rbx](%3) \n\t"
@@ -1816,7 +1792,7 @@ again:
[rsi]"i"(offsetof(struct kvm_vcpu, regs[VCPU_REGS_RSI])),
[rdi]"i"(offsetof(struct kvm_vcpu, regs[VCPU_REGS_RDI])),
[rbp]"i"(offsetof(struct kvm_vcpu, regs[VCPU_REGS_RBP])),
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
[r8 ]"i"(offsetof(struct kvm_vcpu, regs[VCPU_REGS_R8 ])),
[r9 ]"i"(offsetof(struct kvm_vcpu, regs[VCPU_REGS_R9 ])),
[r10]"i"(offsetof(struct kvm_vcpu, regs[VCPU_REGS_R10])),
@@ -1837,7 +1813,7 @@ again:
fx_save(vcpu->guest_fx_image);
fx_restore(vcpu->host_fx_image);
-#ifndef __x86_64__
+#ifndef CONFIG_X86_64
asm ("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS));
#endif
@@ -1855,7 +1831,7 @@ again:
*/
local_irq_disable();
load_gs(gs_sel);
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
wrmsrl(MSR_GS_BASE, vmcs_readl(HOST_GS_BASE));
#endif
local_irq_enable();
@@ -1959,13 +1935,12 @@ static struct kvm_arch_ops vmx_arch_ops = {
.get_segment_base = vmx_get_segment_base,
.get_segment = vmx_get_segment,
.set_segment = vmx_set_segment,
- .is_long_mode = vmx_is_long_mode,
.get_cs_db_l_bits = vmx_get_cs_db_l_bits,
.set_cr0 = vmx_set_cr0,
.set_cr0_no_modeswitch = vmx_set_cr0_no_modeswitch,
.set_cr3 = vmx_set_cr3,
.set_cr4 = vmx_set_cr4,
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
.set_efer = vmx_set_efer,
#endif
.get_idt = vmx_get_idt,
@@ -1989,8 +1964,7 @@ static struct kvm_arch_ops vmx_arch_ops = {
static int __init vmx_init(void)
{
- kvm_init_arch(&vmx_arch_ops, THIS_MODULE);
- return 0;
+ return kvm_init_arch(&vmx_arch_ops, THIS_MODULE);
}
static void __exit vmx_exit(void)
diff --git a/drivers/kvm/vmx.h b/drivers/kvm/vmx.h
index 797278341581..4c0ab151836a 100644
--- a/drivers/kvm/vmx.h
+++ b/drivers/kvm/vmx.h
@@ -286,11 +286,11 @@ enum vmcs_field {
#define CR4_VMXE 0x2000
-#define MSR_IA32_VMX_BASIC_MSR 0x480
+#define MSR_IA32_VMX_BASIC 0x480
#define MSR_IA32_FEATURE_CONTROL 0x03a
-#define MSR_IA32_VMX_PINBASED_CTLS_MSR 0x481
-#define MSR_IA32_VMX_PROCBASED_CTLS_MSR 0x482
-#define MSR_IA32_VMX_EXIT_CTLS_MSR 0x483
-#define MSR_IA32_VMX_ENTRY_CTLS_MSR 0x484
+#define MSR_IA32_VMX_PINBASED_CTLS 0x481
+#define MSR_IA32_VMX_PROCBASED_CTLS 0x482
+#define MSR_IA32_VMX_EXIT_CTLS 0x483
+#define MSR_IA32_VMX_ENTRY_CTLS 0x484
#endif
diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c
index 7e838bf0592d..1bff3e925fda 100644
--- a/drivers/kvm/x86_emulate.c
+++ b/drivers/kvm/x86_emulate.c
@@ -238,7 +238,7 @@ struct operand {
* any modified flags.
*/
-#if defined(__x86_64__)
+#if defined(CONFIG_X86_64)
#define _LO32 "k" /* force 32-bit operand */
#define _STK "%%rsp" /* stack pointer */
#elif defined(__i386__)
@@ -385,7 +385,7 @@ struct operand {
} while (0)
/* Emulate an instruction with quadword operands (x86/64 only). */
-#if defined(__x86_64__)
+#if defined(CONFIG_X86_64)
#define __emulate_2op_8byte(_op, _src, _dst, _eflags, _qx, _qy) \
do { \
__asm__ __volatile__ ( \
@@ -495,7 +495,7 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
case X86EMUL_MODE_PROT32:
op_bytes = ad_bytes = 4;
break;
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
case X86EMUL_MODE_PROT64:
op_bytes = 4;
ad_bytes = 8;
@@ -1341,7 +1341,7 @@ twobyte_special_insn:
}
break;
}
-#elif defined(__x86_64__)
+#elif defined(CONFIG_X86_64)
{
unsigned long old, new;
if ((rc = ops->read_emulated(cr2, &old, 8, ctxt)) != 0)
diff --git a/drivers/kvm/x86_emulate.h b/drivers/kvm/x86_emulate.h
index 658b58de30fc..5d41bd55125e 100644
--- a/drivers/kvm/x86_emulate.h
+++ b/drivers/kvm/x86_emulate.h
@@ -162,7 +162,7 @@ struct x86_emulate_ctxt {
/* Host execution mode. */
#if defined(__i386__)
#define X86EMUL_MODE_HOST X86EMUL_MODE_PROT32
-#elif defined(__x86_64__)
+#elif defined(CONFIG_X86_64)
#define X86EMUL_MODE_HOST X86EMUL_MODE_PROT64
#endif
diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c
index d43ea81d6df9..7cec6de5e2b0 100644
--- a/drivers/macintosh/adb.c
+++ b/drivers/macintosh/adb.c
@@ -828,7 +828,7 @@ static ssize_t adb_write(struct file *file, const char __user *buf,
if (!access_ok(VERIFY_READ, buf, count))
return -EFAULT;
- req = (struct adb_request *) kmalloc(sizeof(struct adb_request),
+ req = kmalloc(sizeof(struct adb_request),
GFP_KERNEL);
if (req == NULL)
return -ENOMEM;
diff --git a/drivers/macintosh/apm_emu.c b/drivers/macintosh/apm_emu.c
index 8862a83b8d84..4300c628f8af 100644
--- a/drivers/macintosh/apm_emu.c
+++ b/drivers/macintosh/apm_emu.c
@@ -321,7 +321,7 @@ static int do_open(struct inode * inode, struct file * filp)
{
struct apm_user * as;
- as = (struct apm_user *)kmalloc(sizeof(*as), GFP_KERNEL);
+ as = kmalloc(sizeof(*as), GFP_KERNEL);
if (as == NULL) {
printk(KERN_ERR "apm: cannot allocate struct of size %d bytes\n",
sizeof(*as));
diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c
index 6dde27ab79a8..6f30459b9385 100644
--- a/drivers/macintosh/smu.c
+++ b/drivers/macintosh/smu.c
@@ -945,7 +945,7 @@ static struct smu_sdbp_header *smu_create_sdb_partition(int id)
*/
tlen = sizeof(struct property) + len + 18;
- prop = kcalloc(tlen, 1, GFP_KERNEL);
+ prop = kzalloc(tlen, GFP_KERNEL);
if (prop == NULL)
return NULL;
hdr = (struct smu_sdbp_header *)(prop + 1);
diff --git a/drivers/macintosh/via-pmu-backlight.c b/drivers/macintosh/via-pmu-backlight.c
index 6c29fe727c0f..801a974342f9 100644
--- a/drivers/macintosh/via-pmu-backlight.c
+++ b/drivers/macintosh/via-pmu-backlight.c
@@ -147,7 +147,7 @@ void __init pmu_backlight_init()
snprintf(name, sizeof(name), "pmubl");
- bd = backlight_device_register(name, NULL, &pmu_backlight_data);
+ bd = backlight_device_register(name, NULL, NULL, &pmu_backlight_data);
if (IS_ERR(bd)) {
printk("pmubl: Backlight registration failed\n");
goto error;
diff --git a/drivers/macintosh/via-pmu68k.c b/drivers/macintosh/via-pmu68k.c
index d9986f3a3fbf..93e6ef9233f9 100644
--- a/drivers/macintosh/via-pmu68k.c
+++ b/drivers/macintosh/via-pmu68k.c
@@ -847,7 +847,7 @@ pbook_pci_save(void)
n_pbook_pci_saves = npci;
if (npci == 0)
return;
- ps = (struct pci_save *) kmalloc(npci * sizeof(*ps), GFP_KERNEL);
+ ps = kmalloc(npci * sizeof(*ps), GFP_KERNEL);
pbook_pci_saves = ps;
if (ps == NULL)
return;
diff --git a/drivers/md/faulty.c b/drivers/md/faulty.c
index a7a5ab554338..4ebd0f2a75ec 100644
--- a/drivers/md/faulty.c
+++ b/drivers/md/faulty.c
@@ -173,7 +173,7 @@ static int make_request(request_queue_t *q, struct bio *bio)
conf_t *conf = (conf_t*)mddev->private;
int failit = 0;
- if (bio->bi_rw & 1) {
+ if (bio_data_dir(bio) == WRITE) {
/* write request */
if (atomic_read(&conf->counters[WriteAll])) {
/* special case - don't decrement, don't generic_make_request,
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 21e2a7b08841..d1cb45f6d6a9 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -1792,7 +1792,8 @@ state_store(mdk_rdev_t *rdev, const char *buf, size_t len)
else {
mddev_t *mddev = rdev->mddev;
kick_rdev_from_array(rdev);
- md_update_sb(mddev, 1);
+ if (mddev->pers)
+ md_update_sb(mddev, 1);
md_new_event(mddev);
err = 0;
}
@@ -2004,6 +2005,7 @@ static mdk_rdev_t *md_import_device(dev_t newdev, int super_format, int super_mi
rdev->desc_nr = -1;
rdev->saved_raid_disk = -1;
+ rdev->raid_disk = -1;
rdev->flags = 0;
rdev->data_offset = 0;
rdev->sb_events = 0;
@@ -2233,7 +2235,6 @@ static int update_raid_disks(mddev_t *mddev, int raid_disks);
static ssize_t
raid_disks_store(mddev_t *mddev, const char *buf, size_t len)
{
- /* can only set raid_disks if array is not yet active */
char *e;
int rv = 0;
unsigned long n = simple_strtoul(buf, &e, 10);
@@ -2631,7 +2632,7 @@ metadata_store(mddev_t *mddev, const char *buf, size_t len)
return -EINVAL;
buf = e+1;
minor = simple_strtoul(buf, &e, 10);
- if (e==buf || *e != '\n')
+ if (e==buf || (*e && *e != '\n') )
return -EINVAL;
if (major >= sizeof(super_types)/sizeof(super_types[0]) ||
super_types[major].name == NULL)
@@ -3980,6 +3981,7 @@ static int set_array_info(mddev_t * mddev, mdu_array_info_t *info)
mddev->major_version = info->major_version;
mddev->minor_version = info->minor_version;
mddev->patch_version = info->patch_version;
+ mddev->persistent = !info->not_persistent;
return 0;
}
mddev->major_version = MD_MAJOR_VERSION;
@@ -4304,9 +4306,10 @@ static int md_ioctl(struct inode *inode, struct file *file,
* Commands querying/configuring an existing array:
*/
/* if we are not initialised yet, only ADD_NEW_DISK, STOP_ARRAY,
- * RUN_ARRAY, and SET_BITMAP_FILE are allowed */
+ * RUN_ARRAY, and GET_ and SET_BITMAP_FILE are allowed */
if (!mddev->raid_disks && cmd != ADD_NEW_DISK && cmd != STOP_ARRAY
- && cmd != RUN_ARRAY && cmd != SET_BITMAP_FILE) {
+ && cmd != RUN_ARRAY && cmd != SET_BITMAP_FILE
+ && cmd != GET_BITMAP_FILE) {
err = -ENODEV;
goto abort_unlock;
}
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index b3c5e12f081d..b30f74be3982 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1736,7 +1736,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
/* take from bio_init */
bio->bi_next = NULL;
bio->bi_flags |= 1 << BIO_UPTODATE;
- bio->bi_rw = 0;
+ bio->bi_rw = READ;
bio->bi_vcnt = 0;
bio->bi_idx = 0;
bio->bi_phys_segments = 0;
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 7492d6033ac6..f0141910bb8d 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -1785,7 +1785,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
biolist = bio;
bio->bi_private = r10_bio;
bio->bi_end_io = end_sync_read;
- bio->bi_rw = 0;
+ bio->bi_rw = READ;
bio->bi_sector = r10_bio->devs[j].addr +
conf->mirrors[d].rdev->data_offset;
bio->bi_bdev = conf->mirrors[d].rdev->bdev;
@@ -1801,7 +1801,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
biolist = bio;
bio->bi_private = r10_bio;
bio->bi_end_io = end_sync_write;
- bio->bi_rw = 1;
+ bio->bi_rw = WRITE;
bio->bi_sector = r10_bio->devs[k].addr +
conf->mirrors[i].rdev->data_offset;
bio->bi_bdev = conf->mirrors[i].rdev->bdev;
@@ -1870,7 +1870,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
biolist = bio;
bio->bi_private = r10_bio;
bio->bi_end_io = end_sync_read;
- bio->bi_rw = 0;
+ bio->bi_rw = READ;
bio->bi_sector = r10_bio->devs[i].addr +
conf->mirrors[d].rdev->data_offset;
bio->bi_bdev = conf->mirrors[d].rdev->bdev;
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 377f8bc9b78b..be008f034ada 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -1827,16 +1827,16 @@ static void handle_stripe5(struct stripe_head *sh)
struct bio *bi;
mdk_rdev_t *rdev;
if (test_and_clear_bit(R5_Wantwrite, &sh->dev[i].flags))
- rw = 1;
+ rw = WRITE;
else if (test_and_clear_bit(R5_Wantread, &sh->dev[i].flags))
- rw = 0;
+ rw = READ;
else
continue;
bi = &sh->dev[i].req;
bi->bi_rw = rw;
- if (rw)
+ if (rw == WRITE)
bi->bi_end_io = raid5_end_write_request;
else
bi->bi_end_io = raid5_end_read_request;
@@ -1872,7 +1872,7 @@ static void handle_stripe5(struct stripe_head *sh)
atomic_add(STRIPE_SECTORS, &rdev->corrected_errors);
generic_make_request(bi);
} else {
- if (rw == 1)
+ if (rw == WRITE)
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);
@@ -2370,16 +2370,16 @@ static void handle_stripe6(struct stripe_head *sh, struct page *tmp_page)
struct bio *bi;
mdk_rdev_t *rdev;
if (test_and_clear_bit(R5_Wantwrite, &sh->dev[i].flags))
- rw = 1;
+ rw = WRITE;
else if (test_and_clear_bit(R5_Wantread, &sh->dev[i].flags))
- rw = 0;
+ rw = READ;
else
continue;
bi = &sh->dev[i].req;
bi->bi_rw = rw;
- if (rw)
+ if (rw == WRITE)
bi->bi_end_io = raid5_end_write_request;
else
bi->bi_end_io = raid5_end_read_request;
@@ -2415,7 +2415,7 @@ static void handle_stripe6(struct stripe_head *sh, struct page *tmp_page)
atomic_add(STRIPE_SECTORS, &rdev->corrected_errors);
generic_make_request(bi);
} else {
- if (rw == 1)
+ if (rw == WRITE)
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);
@@ -2567,7 +2567,7 @@ static int raid5_mergeable_bvec(request_queue_t *q, struct bio *bio, struct bio_
unsigned int chunk_sectors = mddev->chunk_size >> 9;
unsigned int bio_sectors = bio->bi_size >> 9;
- if (bio_data_dir(bio))
+ if (bio_data_dir(bio) == WRITE)
return biovec->bv_len; /* always allow writes to be mergeable */
max = (chunk_sectors - ((sector & (chunk_sectors - 1)) + bio_sectors)) << 9;
@@ -2751,7 +2751,7 @@ static int make_request(request_queue_t *q, struct bio * bi)
disk_stat_inc(mddev->gendisk, ios[rw]);
disk_stat_add(mddev->gendisk, sectors[rw], bio_sectors(bi));
- if (bio_data_dir(bi) == READ &&
+ if (rw == READ &&
mddev->reshape_position == MaxSector &&
chunk_aligned_read(q,bi))
return 0;
diff --git a/drivers/media/common/ir-functions.c b/drivers/media/common/ir-functions.c
index 8eaa88fd8b9b..9a8dd8764c99 100644
--- a/drivers/media/common/ir-functions.c
+++ b/drivers/media/common/ir-functions.c
@@ -23,6 +23,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/string.h>
+#include <linux/jiffies.h>
#include <media/ir-common.h>
/* -------------------------------------------------------------------------- */
diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c
index 240ad084fa78..50bc32a8bd55 100644
--- a/drivers/media/dvb/bt8xx/dst_ca.c
+++ b/drivers/media/dvb/bt8xx/dst_ca.c
@@ -480,7 +480,7 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message,
struct ca_msg *hw_buffer;
int result = 0;
- if ((hw_buffer = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) {
+ if ((hw_buffer = kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) {
dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure");
return -ENOMEM;
}
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
index 80a85cb4975f..3e35931af35d 100644
--- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c
+++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
@@ -657,7 +657,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
case BTTV_BOARD_TWINHAN_DST:
/* DST is not a frontend driver !!! */
- state = (struct dst_state *) kmalloc(sizeof (struct dst_state), GFP_KERNEL);
+ state = kmalloc(sizeof (struct dst_state), GFP_KERNEL);
if (!state) {
printk("dvb_bt8xx: No memory\n");
break;
diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c
index ebf4dc5190f6..76e9c36597eb 100644
--- a/drivers/media/dvb/dvb-core/dvb_net.c
+++ b/drivers/media/dvb/dvb-core/dvb_net.c
@@ -605,7 +605,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
{ &utype, sizeof utype },
{ priv->ule_skb->data, priv->ule_skb->len - 4 }
};
- unsigned long ule_crc = ~0L, expected_crc;
+ u32 ule_crc = ~0L, expected_crc;
if (priv->ule_dbit) {
/* Set D-bit for CRC32 verification,
* if it was set originally. */
@@ -618,7 +618,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
*((u8 *)priv->ule_skb->tail - 2) << 8 |
*((u8 *)priv->ule_skb->tail - 1);
if (ule_crc != expected_crc) {
- printk(KERN_WARNING "%lu: CRC32 check FAILED: %#lx / %#lx, SNDU len %d type %#x, ts_remain %d, next 2: %x.\n",
+ printk(KERN_WARNING "%lu: CRC32 check FAILED: %08x / %08x, SNDU len %d type %#x, ts_remain %d, next 2: %x.\n",
priv->ts_count, ule_crc, expected_crc, priv->ule_sndu_len, priv->ule_sndu_type, ts_remain, ts_remain > 2 ? *(unsigned short *)from_where : 0);
#ifdef ULE_DEBUG
diff --git a/drivers/media/dvb/dvb-usb/nova-t-usb2.c b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
index d48622e76b1b..badc468170ea 100644
--- a/drivers/media/dvb/dvb-usb/nova-t-usb2.c
+++ b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
@@ -90,9 +90,11 @@ static int nova_t_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
deb_rc("raw key code 0x%02x, 0x%02x, 0x%02x to c: %02x d: %02x toggle: %d\n",key[1],key[2],key[3],custom,data,toggle);
for (i = 0; i < ARRAY_SIZE(haupp_rc_keys); i++) {
- deb_rc("c: %x, d: %x\n",haupp_rc_keys[i].data,haupp_rc_keys[i].custom);
if (haupp_rc_keys[i].data == data &&
haupp_rc_keys[i].custom == custom) {
+
+ deb_rc("c: %x, d: %x\n",haupp_rc_keys[i].data,haupp_rc_keys[i].custom);
+
*event = haupp_rc_keys[i].event;
*state = REMOTE_KEY_PRESSED;
if (st->old_toggle == toggle) {
diff --git a/drivers/media/dvb/frontends/dib3000mc.c b/drivers/media/dvb/frontends/dib3000mc.c
index 5da66178006c..23aa75a27c1f 100644
--- a/drivers/media/dvb/frontends/dib3000mc.c
+++ b/drivers/media/dvb/frontends/dib3000mc.c
@@ -515,7 +515,7 @@ static int dib3000mc_autosearch_start(struct dvb_frontend *demod, struct dibx000
fchan.vit_alpha = 1; fchan.vit_code_rate_hp = 2; fchan.vit_code_rate_lp = 2;
fchan.vit_hrch = 0; fchan.vit_select_hp = 1;
- dib3000mc_set_channel_cfg(state, &fchan, 7);
+ dib3000mc_set_channel_cfg(state, &fchan, 11);
reg = dib3000mc_read_word(state, 0);
dib3000mc_write_word(state, 0, reg | (1 << 8));
diff --git a/drivers/media/dvb/ttusb-dec/ttusbdecfe.c b/drivers/media/dvb/ttusb-dec/ttusbdecfe.c
index 42f39a89bc4d..a6fb1d6a7b5d 100644
--- a/drivers/media/dvb/ttusb-dec/ttusbdecfe.c
+++ b/drivers/media/dvb/ttusb-dec/ttusbdecfe.c
@@ -195,7 +195,7 @@ struct dvb_frontend* ttusbdecfe_dvbt_attach(const struct ttusbdecfe_config* conf
struct ttusbdecfe_state* state = NULL;
/* allocate memory for the internal state */
- state = (struct ttusbdecfe_state*) kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL);
+ state = kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL);
if (state == NULL)
return NULL;
@@ -215,7 +215,7 @@ struct dvb_frontend* ttusbdecfe_dvbs_attach(const struct ttusbdecfe_config* conf
struct ttusbdecfe_state* state = NULL;
/* allocate memory for the internal state */
- state = (struct ttusbdecfe_state*) kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL);
+ state = kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL);
if (state == NULL)
return NULL;
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 29a11c1db1b7..57357db31b8a 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -668,7 +668,7 @@ config VIDEO_M32R_AR_M64278
config VIDEO_CAFE_CCIC
tristate "Marvell 88ALP01 (Cafe) CMOS Camera Controller support"
- depends on I2C && VIDEO_V4L2
+ depends on PCI && I2C && VIDEO_V4L2
select VIDEO_OV7670
---help---
This is a video4linux2 driver for the Marvell 88ALP01 integrated
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index 3c8e4742dccc..ab8f970760f2 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -4050,8 +4050,8 @@ static int __devinit bttv_probe(struct pci_dev *dev,
(unsigned long long)pci_resource_start(dev,0));
schedule();
- btv->bt848_mmio=ioremap(pci_resource_start(dev,0), 0x1000);
- if (NULL == ioremap(pci_resource_start(dev,0), 0x1000)) {
+ btv->bt848_mmio = ioremap(pci_resource_start(dev, 0), 0x1000);
+ if (NULL == btv->bt848_mmio) {
printk("bttv%d: ioremap() failed\n", btv->c.nr);
result = -EIO;
goto fail1;
diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c
index e347c7ebc984..3083c8075d13 100644
--- a/drivers/media/video/cafe_ccic.c
+++ b/drivers/media/video/cafe_ccic.c
@@ -2166,7 +2166,7 @@ static void cafe_pci_remove(struct pci_dev *pdev)
struct cafe_camera *cam = cafe_find_by_pdev(pdev);
if (cam == NULL) {
- cam_warn(cam, "pci_remove on unknown pdev %p\n", pdev);
+ printk(KERN_WARNING "pci_remove on unknown pdev %p\n", pdev);
return;
}
mutex_lock(&cam->s_mutex);
diff --git a/drivers/media/video/cpia2/cpia2_usb.c b/drivers/media/video/cpia2/cpia2_usb.c
index 28dc6a1a1e43..d8e929863a88 100644
--- a/drivers/media/video/cpia2/cpia2_usb.c
+++ b/drivers/media/video/cpia2/cpia2_usb.c
@@ -640,6 +640,10 @@ static int submit_urbs(struct camera_data *cam)
cam->sbuf[i].data =
kmalloc(FRAMES_PER_DESC * FRAME_SIZE_PER_DESC, GFP_KERNEL);
if (!cam->sbuf[i].data) {
+ while (--i >= 0) {
+ kfree(cam->sbuf[i].data);
+ cam->sbuf[i].data = NULL;
+ }
return -ENOMEM;
}
}
diff --git a/drivers/media/video/cx2341x.c b/drivers/media/video/cx2341x.c
index 657e0b969145..2f5ca71e0261 100644
--- a/drivers/media/video/cx2341x.c
+++ b/drivers/media/video/cx2341x.c
@@ -742,7 +742,6 @@ int cx2341x_update(void *priv, cx2341x_mbox_func func,
if (old == NULL || old->width != new->width || old->height != new->height ||
old->video_encoding != new->video_encoding) {
- int is_scaling;
u16 w = new->width;
u16 h = new->height;
@@ -752,20 +751,18 @@ int cx2341x_update(void *priv, cx2341x_mbox_func func,
}
err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_SIZE, 2, h, w);
if (err) return err;
+ }
+ if (new->width != 720 || new->height != (new->is_50hz ? 576 : 480)) {
/* Adjust temporal filter if necessary. The problem with the temporal
filter is that it works well with full resolution capturing, but
not when the capture window is scaled (the filter introduces
- a ghosting effect). So if the capture window changed, and there is
- no updated filter value, then the filter is set depending on whether
- the new window is full resolution or not.
+ a ghosting effect). So if the capture window is scaled, then
+ force the filter to 0.
- For full resolution a setting of 8 really improves the video
+ For full resolution the filter really improves the video
quality, especially if the original video quality is suboptimal. */
- is_scaling = new->width != 720 || new->height != (new->is_50hz ? 576 : 480);
- if (old && old->video_temporal_filter == temporal) {
- temporal = is_scaling ? 0 : 8;
- }
+ temporal = 0;
}
if (old == NULL || old->stream_type != new->stream_type) {
@@ -866,6 +863,7 @@ invalid:
void cx2341x_log_status(struct cx2341x_mpeg_params *p, const char *prefix)
{
int is_mpeg1 = p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
+ int temporal = p->video_temporal_filter;
/* Stream */
printk(KERN_INFO "%s: Stream: %s\n",
@@ -922,10 +920,13 @@ void cx2341x_log_status(struct cx2341x_mpeg_params *p, const char *prefix)
cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE),
cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE),
p->video_spatial_filter);
+ if (p->width != 720 || p->height != (p->is_50hz ? 576 : 480)) {
+ temporal = 0;
+ }
printk(KERN_INFO "%s: Temporal Filter: %s, %d\n",
prefix,
cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE),
- p->video_temporal_filter);
+ temporal);
printk(KERN_INFO "%s: Median Filter: %s, Luma [%d, %d], Chroma [%d, %d]\n",
prefix,
cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE),
diff --git a/drivers/media/video/cx25840/cx25840-vbi.c b/drivers/media/video/cx25840/cx25840-vbi.c
index f85f2084324f..ced13febed89 100644
--- a/drivers/media/video/cx25840/cx25840-vbi.c
+++ b/drivers/media/video/cx25840/cx25840-vbi.c
@@ -128,7 +128,14 @@ void cx25840_vbi_setup(struct i2c_client *client)
uv_lpf=1;
src_decimation=0x21f;
- if (std == V4L2_STD_PAL_M) {
+ if (std == V4L2_STD_PAL_60) {
+ vblank=26;
+ vblank656=26;
+ burst=0x5b;
+ luma_lpf=2;
+ comb=0x20;
+ sc=0x0a8263;
+ } else if (std == V4L2_STD_PAL_M) {
vblank=20;
vblank656=24;
burst=0x61;
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index c791708b1336..434b78ab37d8 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -1632,7 +1632,7 @@ const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids);
/* ----------------------------------------------------------------------- */
/* some leadtek specific stuff */
-static void __devinit leadtek_eeprom(struct cx88_core *core, u8 *eeprom_data)
+static void leadtek_eeprom(struct cx88_core *core, u8 *eeprom_data)
{
/* This is just for the "Winfast 2000XP Expert" board ATM; I don't have data on
* any others.
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
index 453af5e943ff..18997361c75a 100644
--- a/drivers/media/video/cx88/cx88-core.c
+++ b/drivers/media/video/cx88/cx88-core.c
@@ -633,12 +633,12 @@ int cx88_reset(struct cx88_core *core)
static unsigned int inline norm_swidth(struct cx88_tvnorm *norm)
{
- return (norm->id & V4L2_STD_625_50) ? 922 : 754;
+ return (norm->id & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 754 : 922;
}
static unsigned int inline norm_hdelay(struct cx88_tvnorm *norm)
{
- return (norm->id & V4L2_STD_625_50) ? 186 : 135;
+ return (norm->id & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 135 : 186;
}
static unsigned int inline norm_vdelay(struct cx88_tvnorm *norm)
@@ -648,24 +648,33 @@ static unsigned int inline norm_vdelay(struct cx88_tvnorm *norm)
static unsigned int inline norm_fsc8(struct cx88_tvnorm *norm)
{
- static const unsigned int ntsc = 28636360;
- static const unsigned int pal = 35468950;
- static const unsigned int palm = 28604892;
-
if (norm->id & V4L2_STD_PAL_M)
- return palm;
+ return 28604892; // 3.575611 MHz
+
+ if (norm->id & (V4L2_STD_PAL_Nc))
+ return 28656448; // 3.582056 MHz
+
+ if (norm->id & V4L2_STD_NTSC) // All NTSC/M and variants
+ return 28636360; // 3.57954545 MHz +/- 10 Hz
- return (norm->id & V4L2_STD_625_50) ? pal : ntsc;
+ /* SECAM have also different sub carrier for chroma,
+ but step_db and step_dr, at cx88_set_tvnorm already handles that.
+
+ The same FSC applies to PAL/BGDKIH, PAL/60, NTSC/4.43 and PAL/N
+ */
+
+ return 35468950; // 4.43361875 MHz +/- 5 Hz
}
static unsigned int inline norm_htotal(struct cx88_tvnorm *norm)
{
- /* Should always be Line Draw Time / (4*FSC) */
- if (norm->id & V4L2_STD_PAL_M)
- return 909;
+ unsigned int fsc4=norm_fsc8(norm)/2;
- return (norm->id & V4L2_STD_625_50) ? 1135 : 910;
+ /* returns 4*FSC / vtotal / frames per seconds */
+ return (norm->id & V4L2_STD_625_50) ?
+ ((fsc4+312)/625+12)/25 :
+ ((fsc4+262)/525*1001+15000)/30000;
}
static unsigned int inline norm_vbipack(struct cx88_tvnorm *norm)
@@ -692,7 +701,7 @@ int cx88_set_scale(struct cx88_core *core, unsigned int width, unsigned int heig
value &= 0x3fe;
cx_write(MO_HDELAY_EVEN, value);
cx_write(MO_HDELAY_ODD, value);
- dprintk(1,"set_scale: hdelay 0x%04x\n", value);
+ dprintk(1,"set_scale: hdelay 0x%04x (width %d)\n", value,swidth);
value = (swidth * 4096 / width) - 4096;
cx_write(MO_HSCALE_EVEN, value);
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index 7054e941f1d7..a9575ad8ca27 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -91,7 +91,7 @@ struct cx88_tvnorm {
static unsigned int inline norm_maxw(struct cx88_tvnorm *norm)
{
- return (norm->id & V4L2_STD_625_50) ? 768 : 640;
+ return (norm->id & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 720 : 768;
}
diff --git a/drivers/media/video/dabusb.c b/drivers/media/video/dabusb.c
index b1012e92ee04..917021fc2993 100644
--- a/drivers/media/video/dabusb.c
+++ b/drivers/media/video/dabusb.c
@@ -218,7 +218,7 @@ static int dabusb_alloc_buffers (pdabusb_t s)
pipesize, packets, transfer_buffer_length);
while (buffers < (s->total_buffer_size << 10)) {
- b = (pbuff_t) kzalloc (sizeof (buff_t), GFP_KERNEL);
+ b = kzalloc(sizeof (buff_t), GFP_KERNEL);
if (!b) {
err("kzalloc(sizeof(buff_t))==NULL");
goto err;
@@ -659,7 +659,7 @@ static int dabusb_ioctl (struct inode *inode, struct file *file, unsigned int cm
switch (cmd) {
case IOCTL_DAB_BULK:
- pbulk = (pbulk_transfer_t) kmalloc (sizeof (bulk_transfer_t), GFP_KERNEL);
+ pbulk = kmalloc(sizeof (bulk_transfer_t), GFP_KERNEL);
if (!pbulk) {
ret = -ENOMEM;
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 2a461dde480c..36e72c207a8f 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -1674,9 +1674,9 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
if (dev->has_msp34xx) {
/* Send a reset to other chips via gpio */
em28xx_write_regs_req(dev, 0x00, 0x08, "\xf7", 1);
- udelay(2500);
+ msleep(3);
em28xx_write_regs_req(dev, 0x00, 0x08, "\xff", 1);
- udelay(2500);
+ msleep(3);
}
video_mux(dev, 0);
diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c
index b083338823df..616a35da191d 100644
--- a/drivers/media/video/meye.c
+++ b/drivers/media/video/meye.c
@@ -923,7 +923,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file,
struct video_picture *p = arg;
if (p->depth != 16)
return -EINVAL;
- if (p->palette != VIDEO_PALETTE_YUV422)
+ if (p->palette != VIDEO_PALETTE_YUV422 && p->palette != VIDEO_PALETTE_YUYV)
return -EINVAL;
mutex_lock(&meye.lock);
sonypi_camera_command(SONYPI_COMMAND_SETCAMERABRIGHTNESS,
@@ -978,7 +978,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file,
if (vm->frame >= gbuffers || vm->frame < 0)
return -EINVAL;
- if (vm->format != VIDEO_PALETTE_YUV422)
+ if (vm->format != VIDEO_PALETTE_YUV422 && vm->format != VIDEO_PALETTE_YUYV)
return -EINVAL;
if (vm->height * vm->width * 2 > gbufsize)
return -EINVAL;
diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c
index e1b56dc13c3f..2fb9fe6a1ae7 100644
--- a/drivers/media/video/msp3400-driver.c
+++ b/drivers/media/video/msp3400-driver.c
@@ -633,10 +633,8 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
if (((rt->input >> (4 + i * 4)) & 0xf) == 0)
extern_input = 0;
}
- if (extern_input)
- state->mode = MSP_MODE_EXTERN;
- else
- state->mode = MSP_MODE_AM_DETECT;
+ state->mode = extern_input ? MSP_MODE_EXTERN : MSP_MODE_AM_DETECT;
+ state->rxsubchans = V4L2_TUNER_SUB_STEREO;
msp_set_scart(client, sc_in, 0);
msp_set_scart(client, sc1_out, 1);
msp_set_scart(client, sc2_out, 2);
@@ -951,7 +949,7 @@ static int msp_attach(struct i2c_adapter *adapter, int address, int kind)
if (thread_func) {
state->kthread = kthread_run(thread_func, client, "msp34xx");
- if (state->kthread == NULL)
+ if (IS_ERR(state->kthread))
v4l_warn(client, "kernel_thread() failed\n");
msp_wake_thread(client);
}
diff --git a/drivers/media/video/msp3400-kthreads.c b/drivers/media/video/msp3400-kthreads.c
index 4c7f85b566a0..e1821eb82fb5 100644
--- a/drivers/media/video/msp3400-kthreads.c
+++ b/drivers/media/video/msp3400-kthreads.c
@@ -483,7 +483,6 @@ int msp3400c_thread(void *data)
/* no carrier scan, just unmute */
v4l_dbg(1, msp_debug, client, "thread: no carrier scan\n");
state->scan_in_progress = 0;
- state->rxsubchans = V4L2_TUNER_SUB_STEREO;
msp_set_audio(client);
continue;
}
@@ -851,12 +850,15 @@ static void msp34xxg_set_source(struct i2c_client *client, u16 reg, int in)
source = 1; /* stereo or A|B */
matrix = 0x20;
break;
- case V4L2_TUNER_MODE_STEREO:
case V4L2_TUNER_MODE_LANG1:
- default:
source = 3; /* stereo or A */
matrix = 0x00;
break;
+ case V4L2_TUNER_MODE_STEREO:
+ default:
+ source = 3; /* stereo or A */
+ matrix = 0x20;
+ break;
}
if (in == MSP_DSP_IN_TUNER)
@@ -1030,6 +1032,9 @@ static int msp34xxg_detect_stereo(struct i2c_client *client)
int is_stereo = status & 0x40;
int oldrx = state->rxsubchans;
+ if (state->mode == MSP_MODE_EXTERN)
+ return 0;
+
state->rxsubchans = 0;
if (is_stereo)
state->rxsubchans = V4L2_TUNER_SUB_STEREO;
diff --git a/drivers/media/video/planb.c b/drivers/media/video/planb.c
index 368d6e219fa4..86d2884e16c6 100644
--- a/drivers/media/video/planb.c
+++ b/drivers/media/video/planb.c
@@ -138,7 +138,7 @@ static int grabbuf_alloc(struct planb *pb)
+ MAX_LNUM
#endif /* PLANB_GSCANLINE */
);
- if ((pb->rawbuf = (unsigned char**) kmalloc (npage
+ if ((pb->rawbuf = kmalloc(npage
* sizeof(unsigned long), GFP_KERNEL)) == 0)
return -ENOMEM;
for (i = 0; i < npage; i++) {
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index fa8339879095..c33f6a69a247 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -50,9 +50,9 @@ static unsigned int antenna_pwr = 0;
module_param(antenna_pwr, int, 0444);
MODULE_PARM_DESC(antenna_pwr,"enable antenna power (Pinnacle 300i)");
-static int use_frontent = 0;
-module_param(use_frontent, int, 0644);
-MODULE_PARM_DESC(use_frontent,"for cards with multiple frontends (0: terrestrial, 1: satellite)");
+static int use_frontend = 0;
+module_param(use_frontend, int, 0644);
+MODULE_PARM_DESC(use_frontend,"for cards with multiple frontends (0: terrestrial, 1: satellite)");
/* ------------------------------------------------------------------ */
static int pinnacle_antenna_pwr(struct saa7134_dev *dev, int on)
@@ -1303,7 +1303,7 @@ static int dvb_init(struct saa7134_dev *dev)
}
break;
case SAA7134_BOARD_FLYDVB_TRIO:
- if(! use_frontent) { //terrestrial
+ if(! use_frontend) { //terrestrial
dev->dvb.frontend = dvb_attach(tda10046_attach,
&lifeview_trio_config,
&dev->i2c_adap);
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 705daaa2a4ff..ee4a493032d6 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -267,6 +267,10 @@ static int tuner_fixup_std(struct tuner *t)
{
if ((t->std & V4L2_STD_PAL) == V4L2_STD_PAL) {
switch (pal[0]) {
+ case '6':
+ tuner_dbg ("insmod fixup: PAL => PAL-60\n");
+ t->std = V4L2_STD_PAL_60;
+ break;
case 'b':
case 'B':
case 'g':
diff --git a/drivers/media/video/usbvideo/usbvideo.c b/drivers/media/video/usbvideo/usbvideo.c
index d8b88024bc2f..b560c9d7c516 100644
--- a/drivers/media/video/usbvideo/usbvideo.c
+++ b/drivers/media/video/usbvideo/usbvideo.c
@@ -690,7 +690,7 @@ int usbvideo_register(
}
base_size = num_cams * sizeof(struct uvd) + sizeof(struct usbvideo);
- cams = (struct usbvideo *) kzalloc(base_size, GFP_KERNEL);
+ cams = kzalloc(base_size, GFP_KERNEL);
if (cams == NULL) {
err("Failed to allocate %d. bytes for usbvideo struct", base_size);
return -ENOMEM;
diff --git a/drivers/media/video/usbvision/usbvision-cards.c b/drivers/media/video/usbvision/usbvision-cards.c
index 134eb9865df6..a40e5838515b 100644
--- a/drivers/media/video/usbvision/usbvision-cards.c
+++ b/drivers/media/video/usbvision/usbvision-cards.c
@@ -39,8 +39,8 @@ struct usbvision_device_data_st usbvision_device_data[] = {
{0x0573, 0x0400, -1, CODEC_SAA7113, 4, V4L2_STD_NTSC, 0, 0, 1, 0, 0, -1, -1, 0, 3, 7, "D-Link V100"},
{0x0573, 0x2000, -1, CODEC_SAA7111, 2, V4L2_STD_NTSC, 1, 0, 1, 0, 0, -1, -1, -1, -1, -1, "X10 USB Camera"},
{0x0573, 0x2d00, -1, CODEC_SAA7111, 2, V4L2_STD_PAL, 1, 0, 1, 0, 0, -1, -1, -1, 3, 7, "Osprey 50"},
- {0x0573, 0x2d01, -1, CODEC_SAA7113, 2, V4L2_STD_NTSC, 0, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Hauppauge USB-Live Model 600"},
- {0x0573, 0x2101, -1, CODEC_SAA7113, 2, V4L2_STD_PAL, 2, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Zoran Co. PMD (Nogatech) AV-grabber Manhattan"},
+ {0x0573, 0x2d01, -1, CODEC_SAA7113, 2, V4L2_STD_NTSC, 0, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Hauppauge USB-Live Model 600"},
+ {0x0573, 0x2101, -1, CODEC_SAA7113, 2, V4L2_STD_PAL, 2, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Zoran Co. PMD (Nogatech) AV-grabber Manhattan"},
{0x0573, 0x4100, -1, CODEC_SAA7111, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, -1, 20, -1, "Nogatech USB-TV (NTSC) FM"},
{0x0573, 0x4110, -1, CODEC_SAA7111, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, -1, 20, -1, "PNY USB-TV (NTSC) FM"},
{0x0573, 0x4450, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_PAL, -1, -1, 0, 3, 7, "PixelView PlayTv-USB PRO (PAL) FM"},
@@ -71,10 +71,10 @@ struct usbvision_device_data_st usbvision_device_data[] = {
{0x0573, 0x4d37, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_FM1216ME_MK3, -1, -1, 0, 3, 7, "Hauppauge WinTV USB device Model 40219 Rev E189"},
{0x0768, 0x0006, -1, CODEC_SAA7113, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, 5, 5, -1, "Camtel Technology USB TV Genie Pro FM Model TVB330"},
{0x07d0, 0x0001, -1, CODEC_SAA7113, 2, V4L2_STD_PAL, 0, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Digital Video Creator I"},
- {0x07d0, 0x0002, -1, CODEC_SAA7111, 2, V4L2_STD_NTSC, 0, 0, 1, 0, 0, -1, -1, 82, 20, 7, "Global Village GV-007 (NTSC)"},
+ {0x07d0, 0x0002, -1, CODEC_SAA7111, 2, V4L2_STD_NTSC, 0, 0, 1, 0, 0, -1, -1, 82, 20, 7, "Global Village GV-007 (NTSC)"},
{0x07d0, 0x0003, 0, CODEC_SAA7113, 2, V4L2_STD_NTSC, 0, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Dazzle Fusion Model DVC-50 Rev 1 (NTSC)"},
{0x07d0, 0x0004, 0, CODEC_SAA7113, 2, V4L2_STD_PAL, 0, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Dazzle Fusion Model DVC-80 Rev 1 (PAL)"},
- {0x07d0, 0x0005, 0, CODEC_SAA7113, 2, V4L2_STD_SECAM, 0, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Dazzle Fusion Model DVC-90 Rev 1 (SECAM)"},
+ {0x07d0, 0x0005, 0, CODEC_SAA7113, 2, V4L2_STD_SECAM, 0, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Dazzle Fusion Model DVC-90 Rev 1 (SECAM)"},
{0x2304, 0x010d, -1, CODEC_SAA7111, 3, V4L2_STD_PAL, 1, 0, 0, 1, TUNER_TEMIC_4066FY5_PAL_I, -1, -1, -1, -1, -1, "Pinnacle Studio PCTV USB (PAL)"},
{0x2304, 0x0109, -1, CODEC_SAA7111, 3, V4L2_STD_SECAM, 1, 0, 1, 1, TUNER_PHILIPS_SECAM, -1, -1, -1, -1, -1, "Pinnacle Studio PCTV USB (SECAM)"},
{0x2304, 0x0110, -1, CODEC_SAA7111, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_PAL, -1, -1,128, 23, -1, "Pinnacle Studio PCTV USB (PAL) FM"},
@@ -86,7 +86,7 @@ struct usbvision_device_data_st usbvision_device_data[] = {
{0x2304, 0x0300, -1, CODEC_SAA7113, 2, V4L2_STD_NTSC, 1, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Pinnacle Studio Linx Video input cable (NTSC)"},
{0x2304, 0x0301, -1, CODEC_SAA7113, 2, V4L2_STD_PAL, 1, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Pinnacle Studio Linx Video input cable (PAL)"},
{0x2304, 0x0419, -1, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_TEMIC_4009FR5_PAL, -1, -1, 0, 3, 7, "Pinnacle PCTV Bungee USB (PAL) FM"},
- {0x2400, 0x4200, -1, CODEC_SAA7111, 3, VIDEO_MODE_NTSC, 1, 0, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, -1, -1, -1, "Hauppauge WinTv-USB"},
+ {0x2400, 0x4200, -1, CODEC_SAA7111, 3, V4L2_STD_NTSC, 1, 0, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, -1, -1, -1, "Hauppauge WinTv-USB"},
{} /* Terminating entry */
};
@@ -148,7 +148,6 @@ struct usb_device_id usbvision_table [] = {
{ USB_DEVICE(0x2304, 0x0300) }, /* Pinnacle Studio Linx Video input cable (NTSC) */
{ USB_DEVICE(0x2304, 0x0301) }, /* Pinnacle Studio Linx Video input cable (PAL) */
{ USB_DEVICE(0x2304, 0x0419) }, /* Pinnacle PCTV Bungee USB (PAL) FM */
-
{ USB_DEVICE(0x2400, 0x4200) }, /* Hauppauge WinTv-USB2 Model 42012 */
{ } /* Terminating entry */
diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c
index 797b97baf9ed..a807d971e273 100644
--- a/drivers/media/video/usbvision/usbvision-core.c
+++ b/drivers/media/video/usbvision/usbvision-core.c
@@ -118,7 +118,7 @@ static int usbvision_measure_bandwidth (struct usb_usbvision *usbvision);
* This is used when initializing the contents of the area.
*/
-void *usbvision_rvmalloc(unsigned long size)
+static void *usbvision_rvmalloc(unsigned long size)
{
void *mem;
unsigned long adr;
@@ -181,7 +181,7 @@ static void usbvision_hexdump(const unsigned char *data, int len)
/********************************
* scratch ring buffer handling
********************************/
-int scratch_len(struct usb_usbvision *usbvision) /*This returns the amount of data actually in the buffer */
+static int scratch_len(struct usb_usbvision *usbvision) /*This returns the amount of data actually in the buffer */
{
int len = usbvision->scratch_write_ptr - usbvision->scratch_read_ptr;
if (len < 0) {
@@ -194,7 +194,7 @@ int scratch_len(struct usb_usbvision *usbvision) /*This returns the amount of
/* This returns the free space left in the buffer */
-int scratch_free(struct usb_usbvision *usbvision)
+static int scratch_free(struct usb_usbvision *usbvision)
{
int free = usbvision->scratch_read_ptr - usbvision->scratch_write_ptr;
if (free <= 0) {
@@ -211,7 +211,8 @@ int scratch_free(struct usb_usbvision *usbvision)
/* This puts data into the buffer */
-int scratch_put(struct usb_usbvision *usbvision, unsigned char *data, int len)
+static int scratch_put(struct usb_usbvision *usbvision, unsigned char *data,
+ int len)
{
int len_part;
@@ -237,7 +238,7 @@ int scratch_put(struct usb_usbvision *usbvision, unsigned char *data, int len)
}
/* This marks the write_ptr as position of new frame header */
-void scratch_mark_header(struct usb_usbvision *usbvision)
+static void scratch_mark_header(struct usb_usbvision *usbvision)
{
PDEBUG(DBG_SCRATCH, "header at write_ptr=%d\n", usbvision->scratch_headermarker_write_ptr);
@@ -248,7 +249,8 @@ void scratch_mark_header(struct usb_usbvision *usbvision)
}
/* This gets data from the buffer at the given "ptr" position */
-int scratch_get_extra(struct usb_usbvision *usbvision, unsigned char *data, int *ptr, int len)
+static int scratch_get_extra(struct usb_usbvision *usbvision,
+ unsigned char *data, int *ptr, int len)
{
int len_part;
if (*ptr + len < scratch_buf_size) {
@@ -274,7 +276,8 @@ int scratch_get_extra(struct usb_usbvision *usbvision, unsigned char *data, int
/* This sets the scratch extra read pointer */
-void scratch_set_extra_ptr(struct usb_usbvision *usbvision, int *ptr, int len)
+static void scratch_set_extra_ptr(struct usb_usbvision *usbvision, int *ptr,
+ int len)
{
*ptr = (usbvision->scratch_read_ptr + len)%scratch_buf_size;
@@ -283,7 +286,7 @@ void scratch_set_extra_ptr(struct usb_usbvision *usbvision, int *ptr, int len)
/*This increments the scratch extra read pointer */
-void scratch_inc_extra_ptr(int *ptr, int len)
+static void scratch_inc_extra_ptr(int *ptr, int len)
{
*ptr = (*ptr + len) % scratch_buf_size;
@@ -292,7 +295,8 @@ void scratch_inc_extra_ptr(int *ptr, int len)
/* This gets data from the buffer */
-int scratch_get(struct usb_usbvision *usbvision, unsigned char *data, int len)
+static int scratch_get(struct usb_usbvision *usbvision, unsigned char *data,
+ int len)
{
int len_part;
if (usbvision->scratch_read_ptr + len < scratch_buf_size) {
@@ -318,7 +322,8 @@ int scratch_get(struct usb_usbvision *usbvision, unsigned char *data, int len)
/* This sets read pointer to next header and returns it */
-int scratch_get_header(struct usb_usbvision *usbvision,struct usbvision_frame_header *header)
+static int scratch_get_header(struct usb_usbvision *usbvision,
+ struct usbvision_frame_header *header)
{
int errCode = 0;
@@ -346,7 +351,7 @@ int scratch_get_header(struct usb_usbvision *usbvision,struct usbvision_frame_he
/*This removes len bytes of old data from the buffer */
-void scratch_rm_old(struct usb_usbvision *usbvision, int len)
+static void scratch_rm_old(struct usb_usbvision *usbvision, int len)
{
usbvision->scratch_read_ptr += len;
@@ -356,7 +361,7 @@ void scratch_rm_old(struct usb_usbvision *usbvision, int len)
/*This resets the buffer - kills all data in it too */
-void scratch_reset(struct usb_usbvision *usbvision)
+static void scratch_reset(struct usb_usbvision *usbvision)
{
PDEBUG(DBG_SCRATCH, "\n");
@@ -369,7 +374,7 @@ void scratch_reset(struct usb_usbvision *usbvision)
int usbvision_scratch_alloc(struct usb_usbvision *usbvision)
{
- usbvision->scratch = vmalloc(scratch_buf_size);
+ usbvision->scratch = vmalloc_32(scratch_buf_size);
scratch_reset(usbvision);
if(usbvision->scratch == NULL) {
err("%s: unable to allocate %d bytes for scratch",
@@ -399,8 +404,8 @@ void usbvision_scratch_free(struct usb_usbvision *usbvision)
* 1: Draw a colored grid
*
*/
-void usbvision_testpattern(struct usb_usbvision *usbvision, int fullframe,
- int pmode)
+static void usbvision_testpattern(struct usb_usbvision *usbvision,
+ int fullframe, int pmode)
{
static const char proc[] = "usbvision_testpattern";
struct usbvision_frame *frame;
@@ -480,7 +485,7 @@ void usbvision_testpattern(struct usb_usbvision *usbvision, int fullframe,
int usbvision_decompress_alloc(struct usb_usbvision *usbvision)
{
int IFB_size = MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT * 3 / 2;
- usbvision->IntraFrameBuffer = vmalloc(IFB_size);
+ usbvision->IntraFrameBuffer = vmalloc_32(IFB_size);
if (usbvision->IntraFrameBuffer == NULL) {
err("%s: unable to allocate %d for compr. frame buffer", __FUNCTION__, IFB_size);
return -ENOMEM;
@@ -2199,6 +2204,7 @@ int usbvision_power_on(struct usb_usbvision *usbvision)
usbvision_write_reg(usbvision, USBVISION_PWR_REG, USBVISION_SSPND_EN);
usbvision_write_reg(usbvision, USBVISION_PWR_REG,
USBVISION_SSPND_EN | USBVISION_RES2);
+
usbvision_write_reg(usbvision, USBVISION_PWR_REG,
USBVISION_SSPND_EN | USBVISION_PWR_VID);
errCode = usbvision_write_reg(usbvision, USBVISION_PWR_REG,
@@ -2305,7 +2311,7 @@ int usbvision_restart_isoc(struct usb_usbvision *usbvision)
usbvision->Vin_Reg2_Preset)) < 0) return ret;
/* TODO: schedule timeout */
- while ((usbvision_read_reg(usbvision, USBVISION_STATUS_REG) && 0x01) != 1);
+ while ((usbvision_read_reg(usbvision, USBVISION_STATUS_REG) & 0x01) != 1);
return 0;
}
@@ -2346,40 +2352,6 @@ int usbvision_setup(struct usb_usbvision *usbvision,int format)
return USBVISION_IS_OPERATIONAL(usbvision);
}
-
-int usbvision_sbuf_alloc(struct usb_usbvision *usbvision)
-{
- int i, errCode = 0;
- const int sb_size = USBVISION_URB_FRAMES * USBVISION_MAX_ISOC_PACKET_SIZE;
-
- /* Clean pointers so we know if we allocated something */
- for (i = 0; i < USBVISION_NUMSBUF; i++)
- usbvision->sbuf[i].data = NULL;
-
- for (i = 0; i < USBVISION_NUMSBUF; i++) {
- usbvision->sbuf[i].data = kzalloc(sb_size, GFP_KERNEL);
- if (usbvision->sbuf[i].data == NULL) {
- err("%s: unable to allocate %d bytes for sbuf", __FUNCTION__, sb_size);
- errCode = -ENOMEM;
- break;
- }
- }
- return errCode;
-}
-
-
-void usbvision_sbuf_free(struct usb_usbvision *usbvision)
-{
- int i;
-
- for (i = 0; i < USBVISION_NUMSBUF; i++) {
- if (usbvision->sbuf[i].data != NULL) {
- kfree(usbvision->sbuf[i].data);
- usbvision->sbuf[i].data = NULL;
- }
- }
-}
-
/*
* usbvision_init_isoc()
*
@@ -2388,6 +2360,7 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
{
struct usb_device *dev = usbvision->dev;
int bufIdx, errCode, regValue;
+ const int sb_size = USBVISION_URB_FRAMES * USBVISION_MAX_ISOC_PACKET_SIZE;
if (!USBVISION_IS_OPERATIONAL(usbvision))
return -EFAULT;
@@ -2423,6 +2396,7 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
return -ENOMEM;
}
usbvision->sbuf[bufIdx].urb = urb;
+ usbvision->sbuf[bufIdx].data = usb_buffer_alloc(usbvision->dev, sb_size, GFP_KERNEL,&urb->transfer_dma);
urb->dev = dev;
urb->context = usbvision;
urb->pipe = usb_rcvisocpipe(dev, usbvision->video_endp);
@@ -2464,6 +2438,7 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
void usbvision_stop_isoc(struct usb_usbvision *usbvision)
{
int bufIdx, errCode, regValue;
+ const int sb_size = USBVISION_URB_FRAMES * USBVISION_MAX_ISOC_PACKET_SIZE;
if ((usbvision->streaming == Stream_Off) || (usbvision->dev == NULL))
return;
@@ -2471,6 +2446,12 @@ void usbvision_stop_isoc(struct usb_usbvision *usbvision)
/* Unschedule all of the iso td's */
for (bufIdx = 0; bufIdx < USBVISION_NUMSBUF; bufIdx++) {
usb_kill_urb(usbvision->sbuf[bufIdx].urb);
+ if (usbvision->sbuf[bufIdx].data){
+ usb_buffer_free(usbvision->dev,
+ sb_size,
+ usbvision->sbuf[bufIdx].data,
+ usbvision->sbuf[bufIdx].urb->transfer_dma);
+ }
usb_free_urb(usbvision->sbuf[bufIdx].urb);
usbvision->sbuf[bufIdx].urb = NULL;
}
diff --git a/drivers/media/video/usbvision/usbvision-i2c.c b/drivers/media/video/usbvision/usbvision-i2c.c
index 0f3fba7ea6fe..858252c15084 100644
--- a/drivers/media/video/usbvision/usbvision-i2c.c
+++ b/drivers/media/video/usbvision/usbvision-i2c.c
@@ -58,7 +58,6 @@ static int usbvision_i2c_read(void *data, unsigned char addr, char *buf,
static inline int try_write_address(struct i2c_adapter *i2c_adap,
unsigned char addr, int retries)
{
- struct i2c_algo_usb_data *adap = i2c_adap->algo_data;
void *data;
int i, ret = -1;
char buf[4];
@@ -69,10 +68,10 @@ static inline int try_write_address(struct i2c_adapter *i2c_adap,
ret = (usbvision_i2c_write(data, addr, buf, 1));
if (ret == 1)
break; /* success! */
- udelay(5 /*adap->udelay */ );
+ udelay(5);
if (i == retries) /* no success */
break;
- udelay(adap->udelay);
+ udelay(10);
}
if (i) {
PDEBUG(DBG_ALGO,"Needed %d retries for address %#2x", i, addr);
@@ -84,7 +83,6 @@ static inline int try_write_address(struct i2c_adapter *i2c_adap,
static inline int try_read_address(struct i2c_adapter *i2c_adap,
unsigned char addr, int retries)
{
- struct i2c_algo_usb_data *adap = i2c_adap->algo_data;
void *data;
int i, ret = -1;
char buf[4];
@@ -94,10 +92,10 @@ static inline int try_read_address(struct i2c_adapter *i2c_adap,
ret = (usbvision_i2c_read(data, addr, buf, 1));
if (ret == 1)
break; /* success! */
- udelay(5 /*adap->udelay */ );
+ udelay(5);
if (i == retries) /* no success */
break;
- udelay(adap->udelay);
+ udelay(10);
}
if (i) {
PDEBUG(DBG_ALGO,"Needed %d retries for address %#2x", i, addr);
@@ -213,7 +211,7 @@ static struct i2c_algorithm i2c_usb_algo = {
/*
* registering functions to load algorithms at runtime
*/
-int usbvision_i2c_usb_add_bus(struct i2c_adapter *adap)
+static int usbvision_i2c_usb_add_bus(struct i2c_adapter *adap)
{
PDEBUG(DBG_I2C, "I2C debugging is enabled [i2c]");
PDEBUG(DBG_ALGO, "ALGO debugging is enabled [i2c]");
@@ -248,15 +246,12 @@ int usbvision_i2c_usb_del_bus(struct i2c_adapter *adap)
/* usbvision specific I2C functions */
/* ----------------------------------------------------------------------- */
static struct i2c_adapter i2c_adap_template;
-static struct i2c_algo_usb_data i2c_algo_template;
static struct i2c_client i2c_client_template;
int usbvision_init_i2c(struct usb_usbvision *usbvision)
{
memcpy(&usbvision->i2c_adap, &i2c_adap_template,
sizeof(struct i2c_adapter));
- memcpy(&usbvision->i2c_algo, &i2c_algo_template,
- sizeof(struct i2c_algo_usb_data));
memcpy(&usbvision->i2c_client, &i2c_client_template,
sizeof(struct i2c_client));
@@ -266,9 +261,7 @@ int usbvision_init_i2c(struct usb_usbvision *usbvision)
i2c_set_adapdata(&usbvision->i2c_adap, usbvision);
i2c_set_clientdata(&usbvision->i2c_client, usbvision);
- i2c_set_algo_usb_data(&usbvision->i2c_algo, usbvision);
- usbvision->i2c_adap.algo_data = &usbvision->i2c_algo;
usbvision->i2c_client.adapter = &usbvision->i2c_adap;
if (usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_IIC_LRNACK) < 0) {
@@ -297,7 +290,6 @@ int usbvision_init_i2c(struct usb_usbvision *usbvision)
void call_i2c_clients(struct usb_usbvision *usbvision, unsigned int cmd,
void *arg)
{
- BUG_ON(NULL == usbvision->i2c_adap.algo_data);
i2c_clients_command(&usbvision->i2c_adap, cmd, arg);
}
@@ -327,6 +319,9 @@ static int attach_inform(struct i2c_client *client)
case 0x4a:
PDEBUG(DBG_I2C,"attach_inform: saa7113 detected.");
break;
+ case 0x48:
+ PDEBUG(DBG_I2C,"attach_inform: saa7111 detected.");
+ break;
case 0xa0:
PDEBUG(DBG_I2C,"attach_inform: eeprom detected.");
break;
@@ -531,21 +526,10 @@ static int usbvision_i2c_read(void *data, unsigned char addr, char *buf,
return rdcount;
}
-static struct i2c_algo_usb_data i2c_algo_template = {
- .data = NULL,
- .inb = usbvision_i2c_read,
- .outb = usbvision_i2c_write,
- .udelay = 10,
- .mdelay = 10,
- .timeout = 100,
-};
-
static struct i2c_adapter i2c_adap_template = {
.owner = THIS_MODULE,
.name = "usbvision",
.id = I2C_HW_B_BT848, /* FIXME */
- .algo = NULL,
- .algo_data = NULL,
.client_register = attach_inform,
.client_unregister = detach_inform,
#ifdef I2C_ADAP_CLASS_TV_ANALOG
@@ -559,9 +543,6 @@ static struct i2c_client i2c_client_template = {
.name = "usbvision internal",
};
-EXPORT_SYMBOL(usbvision_i2c_usb_add_bus);
-EXPORT_SYMBOL(usbvision_i2c_usb_del_bus);
-
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* ---------------------------------------------------------------------------
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c
index 864446c012eb..8c7eba2a728e 100644
--- a/drivers/media/video/usbvision/usbvision-video.c
+++ b/drivers/media/video/usbvision/usbvision-video.c
@@ -204,7 +204,7 @@ MODULE_ALIAS(DRIVER_ALIAS);
static inline struct usb_usbvision *cd_to_usbvision(struct class_device *cd)
{
- struct video_device *vdev = to_video_device(cd);
+ struct video_device *vdev = container_of(cd, struct video_device, class_dev);
return video_get_drvdata(vdev);
}
@@ -214,81 +214,85 @@ static ssize_t show_version(struct class_device *cd, char *buf)
}
static CLASS_DEVICE_ATTR(version, S_IRUGO, show_version, NULL);
-static ssize_t show_model(struct class_device *class_dev, char *buf)
+static ssize_t show_model(struct class_device *cd, char *buf)
{
- struct video_device *vdev = to_video_device(class_dev);
+ struct video_device *vdev = container_of(cd, struct video_device, class_dev);
struct usb_usbvision *usbvision = video_get_drvdata(vdev);
return sprintf(buf, "%s\n", usbvision_device_data[usbvision->DevModel].ModelString);
}
static CLASS_DEVICE_ATTR(model, S_IRUGO, show_model, NULL);
-static ssize_t show_hue(struct class_device *class_dev, char *buf)
+static ssize_t show_hue(struct class_device *cd, char *buf)
{
- struct video_device *vdev = to_video_device(class_dev);
+ struct video_device *vdev = container_of(cd, struct video_device, class_dev);
struct usb_usbvision *usbvision = video_get_drvdata(vdev);
struct v4l2_control ctrl;
ctrl.id = V4L2_CID_HUE;
ctrl.value = 0;
- call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl);
+ if(usbvision->user)
+ call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl);
return sprintf(buf, "%d\n", ctrl.value >> 8);
}
static CLASS_DEVICE_ATTR(hue, S_IRUGO, show_hue, NULL);
-static ssize_t show_contrast(struct class_device *class_dev, char *buf)
+static ssize_t show_contrast(struct class_device *cd, char *buf)
{
- struct video_device *vdev = to_video_device(class_dev);
+ struct video_device *vdev = container_of(cd, struct video_device, class_dev);
struct usb_usbvision *usbvision = video_get_drvdata(vdev);
struct v4l2_control ctrl;
ctrl.id = V4L2_CID_CONTRAST;
ctrl.value = 0;
- call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl);
+ if(usbvision->user)
+ call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl);
return sprintf(buf, "%d\n", ctrl.value >> 8);
}
static CLASS_DEVICE_ATTR(contrast, S_IRUGO, show_contrast, NULL);
-static ssize_t show_brightness(struct class_device *class_dev, char *buf)
+static ssize_t show_brightness(struct class_device *cd, char *buf)
{
- struct video_device *vdev = to_video_device(class_dev);
+ struct video_device *vdev = container_of(cd, struct video_device, class_dev);
struct usb_usbvision *usbvision = video_get_drvdata(vdev);
struct v4l2_control ctrl;
ctrl.id = V4L2_CID_BRIGHTNESS;
ctrl.value = 0;
- call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl);
+ if(usbvision->user)
+ call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl);
return sprintf(buf, "%d\n", ctrl.value >> 8);
}
static CLASS_DEVICE_ATTR(brightness, S_IRUGO, show_brightness, NULL);
-static ssize_t show_saturation(struct class_device *class_dev, char *buf)
+static ssize_t show_saturation(struct class_device *cd, char *buf)
{
- struct video_device *vdev = to_video_device(class_dev);
+ struct video_device *vdev = container_of(cd, struct video_device, class_dev);
struct usb_usbvision *usbvision = video_get_drvdata(vdev);
struct v4l2_control ctrl;
ctrl.id = V4L2_CID_SATURATION;
ctrl.value = 0;
- call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl);
+ if(usbvision->user)
+ call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl);
return sprintf(buf, "%d\n", ctrl.value >> 8);
}
static CLASS_DEVICE_ATTR(saturation, S_IRUGO, show_saturation, NULL);
-static ssize_t show_streaming(struct class_device *class_dev, char *buf)
+static ssize_t show_streaming(struct class_device *cd, char *buf)
{
- struct video_device *vdev = to_video_device(class_dev);
+ struct video_device *vdev = container_of(cd, struct video_device, class_dev);
struct usb_usbvision *usbvision = video_get_drvdata(vdev);
return sprintf(buf, "%s\n", YES_NO(usbvision->streaming==Stream_On?1:0));
}
static CLASS_DEVICE_ATTR(streaming, S_IRUGO, show_streaming, NULL);
-static ssize_t show_compression(struct class_device *class_dev, char *buf)
+static ssize_t show_compression(struct class_device *cd, char *buf)
{
- struct video_device *vdev = to_video_device(class_dev);
+ struct video_device *vdev = container_of(cd, struct video_device, class_dev);
struct usb_usbvision *usbvision = video_get_drvdata(vdev);
return sprintf(buf, "%s\n", YES_NO(usbvision->isocMode==ISOC_MODE_COMPRESS));
}
static CLASS_DEVICE_ATTR(compression, S_IRUGO, show_compression, NULL);
-static ssize_t show_device_bridge(struct class_device *class_dev, char *buf)
+static ssize_t show_device_bridge(struct class_device *cd, char *buf)
{
- struct video_device *vdev = to_video_device(class_dev);
+ struct video_device *vdev = container_of(cd, struct video_device, class_dev);
struct usb_usbvision *usbvision = video_get_drvdata(vdev);
return sprintf(buf, "%d\n", usbvision->bridgeType);
}
@@ -297,31 +301,71 @@ static CLASS_DEVICE_ATTR(bridge, S_IRUGO, show_device_bridge, NULL);
static void usbvision_create_sysfs(struct video_device *vdev)
{
int res;
- if (vdev) {
- res=video_device_create_file(vdev, &class_device_attr_version);
- res=video_device_create_file(vdev, &class_device_attr_model);
- res=video_device_create_file(vdev, &class_device_attr_hue);
- res=video_device_create_file(vdev, &class_device_attr_contrast);
- res=video_device_create_file(vdev, &class_device_attr_brightness);
- res=video_device_create_file(vdev, &class_device_attr_saturation);
- res=video_device_create_file(vdev, &class_device_attr_streaming);
- res=video_device_create_file(vdev, &class_device_attr_compression);
- res=video_device_create_file(vdev, &class_device_attr_bridge);
- }
+ if (!vdev)
+ return;
+ do {
+ res=class_device_create_file(&vdev->class_dev,
+ &class_device_attr_version);
+ if (res<0)
+ break;
+ res=class_device_create_file(&vdev->class_dev,
+ &class_device_attr_model);
+ if (res<0)
+ break;
+ res=class_device_create_file(&vdev->class_dev,
+ &class_device_attr_hue);
+ if (res<0)
+ break;
+ res=class_device_create_file(&vdev->class_dev,
+ &class_device_attr_contrast);
+ if (res<0)
+ break;
+ res=class_device_create_file(&vdev->class_dev,
+ &class_device_attr_brightness);
+ if (res<0)
+ break;
+ res=class_device_create_file(&vdev->class_dev,
+ &class_device_attr_saturation);
+ if (res<0)
+ break;
+ res=class_device_create_file(&vdev->class_dev,
+ &class_device_attr_streaming);
+ if (res<0)
+ break;
+ res=class_device_create_file(&vdev->class_dev,
+ &class_device_attr_compression);
+ if (res<0)
+ break;
+ res=class_device_create_file(&vdev->class_dev,
+ &class_device_attr_bridge);
+ if (res>=0)
+ return;
+ } while (0);
+
+ err("%s error: %d\n", __FUNCTION__, res);
}
static void usbvision_remove_sysfs(struct video_device *vdev)
{
if (vdev) {
- video_device_remove_file(vdev, &class_device_attr_version);
- video_device_remove_file(vdev, &class_device_attr_model);
- video_device_remove_file(vdev, &class_device_attr_hue);
- video_device_remove_file(vdev, &class_device_attr_contrast);
- video_device_remove_file(vdev, &class_device_attr_brightness);
- video_device_remove_file(vdev, &class_device_attr_saturation);
- video_device_remove_file(vdev, &class_device_attr_streaming);
- video_device_remove_file(vdev, &class_device_attr_compression);
- video_device_remove_file(vdev, &class_device_attr_bridge);
+ class_device_remove_file(&vdev->class_dev,
+ &class_device_attr_version);
+ class_device_remove_file(&vdev->class_dev,
+ &class_device_attr_model);
+ class_device_remove_file(&vdev->class_dev,
+ &class_device_attr_hue);
+ class_device_remove_file(&vdev->class_dev,
+ &class_device_attr_contrast);
+ class_device_remove_file(&vdev->class_dev,
+ &class_device_attr_brightness);
+ class_device_remove_file(&vdev->class_dev,
+ &class_device_attr_saturation);
+ class_device_remove_file(&vdev->class_dev,
+ &class_device_attr_streaming);
+ class_device_remove_file(&vdev->class_dev,
+ &class_device_attr_compression);
+ class_device_remove_file(&vdev->class_dev,
+ &class_device_attr_bridge);
}
}
@@ -353,20 +397,15 @@ static int usbvision_v4l2_open(struct inode *inode, struct file *file)
if(!errCode) {
/* Allocate memory for the scratch ring buffer */
errCode = usbvision_scratch_alloc(usbvision);
- if(!errCode) {
- /* Allocate memory for the USB S buffers */
- errCode = usbvision_sbuf_alloc(usbvision);
- if ((!errCode) && (usbvision->isocMode==ISOC_MODE_COMPRESS)) {
- /* Allocate intermediate decompression buffers only if needed */
- errCode = usbvision_decompress_alloc(usbvision);
- }
+ if ((!errCode) && (isocMode==ISOC_MODE_COMPRESS)) {
+ /* Allocate intermediate decompression buffers only if needed */
+ errCode = usbvision_decompress_alloc(usbvision);
}
}
if (errCode) {
/* Deallocate all buffers if trouble */
usbvision_frames_free(usbvision);
usbvision_scratch_free(usbvision);
- usbvision_sbuf_free(usbvision);
usbvision_decompress_free(usbvision);
}
}
@@ -437,9 +476,8 @@ static int usbvision_v4l2_close(struct inode *inode, struct file *file)
usbvision_stop_isoc(usbvision);
usbvision_decompress_free(usbvision);
- usbvision_rvfree(usbvision->fbuf, usbvision->fbuf_size);
+ usbvision_frames_free(usbvision);
usbvision_scratch_free(usbvision);
- usbvision_sbuf_free(usbvision);
usbvision->user--;
@@ -1884,7 +1922,7 @@ static struct usb_driver usbvision_driver = {
* This procedure preprocesses CustomDevice parameter if any
*
*/
-void customdevice_process(void)
+static void customdevice_process(void)
{
usbvision_device_data[0]=usbvision_device_data[1];
usbvision_table[0]=usbvision_table[1];
@@ -1939,22 +1977,22 @@ void customdevice_process(void)
{
case 'P':
PDEBUG(DBG_PROBE, "VideoNorm=PAL");
- usbvision_device_data[0].VideoNorm=VIDEO_MODE_PAL;
+ usbvision_device_data[0].VideoNorm=V4L2_STD_PAL;
break;
case 'S':
PDEBUG(DBG_PROBE, "VideoNorm=SECAM");
- usbvision_device_data[0].VideoNorm=VIDEO_MODE_SECAM;
+ usbvision_device_data[0].VideoNorm=V4L2_STD_SECAM;
break;
case 'N':
PDEBUG(DBG_PROBE, "VideoNorm=NTSC");
- usbvision_device_data[0].VideoNorm=VIDEO_MODE_NTSC;
+ usbvision_device_data[0].VideoNorm=V4L2_STD_NTSC;
break;
default:
PDEBUG(DBG_PROBE, "VideoNorm=PAL (by default)");
- usbvision_device_data[0].VideoNorm=VIDEO_MODE_PAL;
+ usbvision_device_data[0].VideoNorm=V4L2_STD_PAL;
break;
}
goto2next(parse);
diff --git a/drivers/media/video/usbvision/usbvision.h b/drivers/media/video/usbvision/usbvision.h
index 0e7e3d653cac..e2bcaba93871 100644
--- a/drivers/media/video/usbvision/usbvision.h
+++ b/drivers/media/video/usbvision/usbvision.h
@@ -219,18 +219,6 @@ enum {
((udevice)->last_error == 0) && \
(!(udevice)->remove_pending))
-/* I2C structures */
-struct i2c_algo_usb_data {
- void *data; /* private data for lowlevel routines */
- int (*inb) (void *data, unsigned char addr, char *buf, short len);
- int (*outb) (void *data, unsigned char addr, char *buf, short len);
-
- /* local settings */
- int udelay;
- int mdelay;
- int timeout;
-};
-
#define I2C_USB_ADAP_MAX 16
/* ----------------------------------------------------------------- */
@@ -383,7 +371,6 @@ struct usb_usbvision {
/* i2c Declaration Section*/
struct i2c_adapter i2c_adap;
- struct i2c_algo_usb_data i2c_algo;
struct i2c_client i2c_client;
struct urb *ctrlUrb;
@@ -489,19 +476,8 @@ struct usb_usbvision {
/* i2c-algo-usb declaration */
/* --------------------------------------------------------------- */
-int usbvision_i2c_usb_add_bus(struct i2c_adapter *);
int usbvision_i2c_usb_del_bus(struct i2c_adapter *);
-static inline void *i2c_get_algo_usb_data (struct i2c_algo_usb_data *dev)
-{
- return dev->data;
-}
-
-static inline void i2c_set_algo_usb_data (struct i2c_algo_usb_data *dev, void *data)
-{
- dev->data = data;
-}
-
/* ----------------------------------------------------------------------- */
/* usbvision specific I2C functions */
@@ -510,7 +486,6 @@ int usbvision_init_i2c(struct usb_usbvision *usbvision);
void call_i2c_clients(struct usb_usbvision *usbvision, unsigned int cmd,void *arg);
/* defined in usbvision-core.c */
-void *usbvision_rvmalloc(unsigned long size);
void usbvision_rvfree(void *mem, unsigned long size);
int usbvision_read_reg(struct usb_usbvision *usbvision, unsigned char reg);
int usbvision_write_reg(struct usb_usbvision *usbvision, unsigned char reg,
@@ -520,8 +495,6 @@ int usbvision_frames_alloc(struct usb_usbvision *usbvision);
void usbvision_frames_free(struct usb_usbvision *usbvision);
int usbvision_scratch_alloc(struct usb_usbvision *usbvision);
void usbvision_scratch_free(struct usb_usbvision *usbvision);
-int usbvision_sbuf_alloc(struct usb_usbvision *usbvision);
-void usbvision_sbuf_free(struct usb_usbvision *usbvision);
int usbvision_decompress_alloc(struct usb_usbvision *usbvision);
void usbvision_decompress_free(struct usb_usbvision *usbvision);
diff --git a/drivers/media/video/videocodec.c b/drivers/media/video/videocodec.c
index 2ae3fb250630..290e64135650 100644
--- a/drivers/media/video/videocodec.c
+++ b/drivers/media/video/videocodec.c
@@ -346,7 +346,7 @@ videocodec_build_table (void)
size);
kfree(videocodec_buf);
- videocodec_buf = (char *) kmalloc(size, GFP_KERNEL);
+ videocodec_buf = kmalloc(size, GFP_KERNEL);
i = 0;
i += scnprintf(videocodec_buf + i, size - 1,
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index 474ddb779643..bacb311b4f24 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -535,9 +535,9 @@ static int vivi_start_thread(struct vivi_dmaqueue *dma_q)
dma_q->kthread = kthread_run(vivi_thread, dma_q, "vivi");
- if (dma_q->kthread == NULL) {
+ if (IS_ERR(dma_q->kthread)) {
printk(KERN_ERR "vivi: kernel_thread() failed\n");
- return -EINVAL;
+ return PTR_ERR(dma_q->kthread);
}
dprintk(1,"returning from %s\n",__FUNCTION__);
return 0;
@@ -1363,7 +1363,9 @@ static void __exit vivi_exit(void)
struct vivi_dev *h;
struct list_head *list;
- list_for_each(list,&vivi_devlist) {
+ while (!list_empty(&vivi_devlist)) {
+ list = vivi_devlist.next;
+ list_del(list);
h = list_entry(list, struct vivi_dev, vivi_devlist);
kfree (h);
}
diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c
index 4bdc886abc4c..8d14f308f171 100644
--- a/drivers/media/video/w9966.c
+++ b/drivers/media/video/w9966.c
@@ -789,7 +789,7 @@ static int w9966_v4l_do_ioctl(struct inode *inode, struct file *file,
case VIDIOCSPICT:
{
struct video_picture *vpic = arg;
- if (vpic->depth != 16 || vpic->palette != VIDEO_PALETTE_YUV422)
+ if (vpic->depth != 16 || (vpic->palette != VIDEO_PALETTE_YUV422 && vpic->palette != VIDEO_PALETTE_YUYV))
return -EINVAL;
cam->brightness = vpic->brightness >> 8;
diff --git a/drivers/media/video/w9968cf.c b/drivers/media/video/w9968cf.c
index ddce2fb83424..9f403af7b040 100644
--- a/drivers/media/video/w9968cf.c
+++ b/drivers/media/video/w9968cf.c
@@ -1827,8 +1827,8 @@ w9968cf_set_window(struct w9968cf_device* cam, struct video_window win)
int err = 0;
/* Work around to avoid FP arithmetics */
- #define __SC(x) ((x) << 10)
- #define __UNSC(x) ((x) >> 10)
+ #define SC(x) ((x) << 10)
+ #define UNSC(x) ((x) >> 10)
/* Make sure we are using a supported resolution */
if ((err = w9968cf_adjust_window_size(cam, (u16*)&win.width,
@@ -1836,15 +1836,15 @@ w9968cf_set_window(struct w9968cf_device* cam, struct video_window win)
goto error;
/* Scaling factors */
- fw = __SC(win.width) / cam->maxwidth;
- fh = __SC(win.height) / cam->maxheight;
+ fw = SC(win.width) / cam->maxwidth;
+ fh = SC(win.height) / cam->maxheight;
/* Set up the width and height values used by the chip */
if ((win.width > cam->maxwidth) || (win.height > cam->maxheight)) {
cam->vpp_flag |= VPP_UPSCALE;
/* Calculate largest w,h mantaining the same w/h ratio */
- w = (fw >= fh) ? cam->maxwidth : __SC(win.width)/fh;
- h = (fw >= fh) ? __SC(win.height)/fw : cam->maxheight;
+ w = (fw >= fh) ? cam->maxwidth : SC(win.width)/fh;
+ h = (fw >= fh) ? SC(win.height)/fw : cam->maxheight;
if (w < cam->minwidth) /* just in case */
w = cam->minwidth;
if (h < cam->minheight) /* just in case */
@@ -1861,8 +1861,8 @@ w9968cf_set_window(struct w9968cf_device* cam, struct video_window win)
/* Calculate cropped area manteining the right w/h ratio */
if (cam->largeview && !(cam->vpp_flag & VPP_UPSCALE)) {
- cw = (fw >= fh) ? cam->maxwidth : __SC(win.width)/fh;
- ch = (fw >= fh) ? __SC(win.height)/fw : cam->maxheight;
+ cw = (fw >= fh) ? cam->maxwidth : SC(win.width)/fh;
+ ch = (fw >= fh) ? SC(win.height)/fw : cam->maxheight;
} else {
cw = w;
ch = h;
@@ -1901,8 +1901,8 @@ w9968cf_set_window(struct w9968cf_device* cam, struct video_window win)
/* We have to scale win.x and win.y offsets */
if ( (cam->largeview && !(cam->vpp_flag & VPP_UPSCALE))
|| (cam->vpp_flag & VPP_UPSCALE) ) {
- ax = __SC(win.x)/fw;
- ay = __SC(win.y)/fh;
+ ax = SC(win.x)/fw;
+ ay = SC(win.y)/fh;
} else {
ax = win.x;
ay = win.y;
@@ -1917,8 +1917,8 @@ w9968cf_set_window(struct w9968cf_device* cam, struct video_window win)
/* Adjust win.x, win.y */
if ( (cam->largeview && !(cam->vpp_flag & VPP_UPSCALE))
|| (cam->vpp_flag & VPP_UPSCALE) ) {
- win.x = __UNSC(ax*fw);
- win.y = __UNSC(ay*fh);
+ win.x = UNSC(ax*fw);
+ win.y = UNSC(ay*fh);
} else {
win.x = ax;
win.y = ay;
diff --git a/drivers/media/video/zoran_device.c b/drivers/media/video/zoran_device.c
index 168e431d7c71..b0752767ee4f 100644
--- a/drivers/media/video/zoran_device.c
+++ b/drivers/media/video/zoran_device.c
@@ -429,7 +429,7 @@ zr36057_set_vfe (struct zoran *zr,
reg |= (HorDcm << ZR36057_VFESPFR_HorDcm);
reg |= (VerDcm << ZR36057_VFESPFR_VerDcm);
reg |= (DispMode << ZR36057_VFESPFR_DispMode);
- if (format->palette != VIDEO_PALETTE_YUV422)
+ if (format->palette != VIDEO_PALETTE_YUV422 && format->palette != VIDEO_PALETTE_YUYV)
reg |= ZR36057_VFESPFR_LittleEndian;
/* RJ: I don't know, why the following has to be the opposite
* of the corresponding ZR36060 setting, but only this way
@@ -441,6 +441,7 @@ zr36057_set_vfe (struct zoran *zr,
reg |= ZR36057_VFESPFR_TopField;
switch (format->palette) {
+ case VIDEO_PALETTE_YUYV:
case VIDEO_PALETTE_YUV422:
reg |= ZR36057_VFESPFR_YUV422;
break;
diff --git a/drivers/message/i2o/core.h b/drivers/message/i2o/core.h
index dc388a3ff5e0..cbe384fb848c 100644
--- a/drivers/message/i2o/core.h
+++ b/drivers/message/i2o/core.h
@@ -18,7 +18,7 @@ extern struct i2o_driver i2o_exec_driver;
extern int i2o_exec_lct_get(struct i2o_controller *);
extern int __init i2o_exec_init(void);
-extern void __exit i2o_exec_exit(void);
+extern void i2o_exec_exit(void);
/* driver */
extern struct bus_type i2o_bus_type;
@@ -26,7 +26,7 @@ extern struct bus_type i2o_bus_type;
extern int i2o_driver_dispatch(struct i2o_controller *, u32);
extern int __init i2o_driver_init(void);
-extern void __exit i2o_driver_exit(void);
+extern void i2o_driver_exit(void);
/* PCI */
extern int __init i2o_pci_init(void);
diff --git a/drivers/message/i2o/driver.c b/drivers/message/i2o/driver.c
index 9104b65ff70f..d3235f213c89 100644
--- a/drivers/message/i2o/driver.c
+++ b/drivers/message/i2o/driver.c
@@ -362,7 +362,7 @@ int __init i2o_driver_init(void)
*
* Unregisters the I2O bus and frees driver array.
*/
-void __exit i2o_driver_exit(void)
+void i2o_driver_exit(void)
{
bus_unregister(&i2o_bus_type);
kfree(i2o_drivers);
diff --git a/drivers/message/i2o/exec-osm.c b/drivers/message/i2o/exec-osm.c
index 902753b2c661..5278aad92bc4 100644
--- a/drivers/message/i2o/exec-osm.c
+++ b/drivers/message/i2o/exec-osm.c
@@ -367,7 +367,7 @@ static int i2o_exec_remove(struct device *dev)
/**
* i2o_exec_lct_modified - Called on LCT NOTIFY reply
- * @work: work struct for a specific controller
+ * @_work: work struct for a specific controller
*
* This function handles asynchronus LCT NOTIFY replies. It parses the
* new LCT and if the buffer for the LCT was to small sends a LCT NOTIFY
@@ -595,7 +595,7 @@ int __init i2o_exec_init(void)
*
* Unregisters the Exec OSM from the I2O core.
*/
-void __exit i2o_exec_exit(void)
+void i2o_exec_exit(void)
{
i2o_driver_unregister(&i2o_exec_driver);
};
diff --git a/drivers/message/i2o/i2o_config.c b/drivers/message/i2o/i2o_config.c
index 1de30d711671..e33d446e7493 100644
--- a/drivers/message/i2o/i2o_config.c
+++ b/drivers/message/i2o/i2o_config.c
@@ -186,7 +186,7 @@ static int i2o_cfg_parms(unsigned long arg, unsigned int type)
if (!dev)
return -ENXIO;
- ops = (u8 *) kmalloc(kcmd.oplen, GFP_KERNEL);
+ ops = kmalloc(kcmd.oplen, GFP_KERNEL);
if (!ops)
return -ENOMEM;
@@ -199,7 +199,7 @@ static int i2o_cfg_parms(unsigned long arg, unsigned int type)
* It's possible to have a _very_ large table
* and that the user asks for all of it at once...
*/
- res = (u8 *) kmalloc(65536, GFP_KERNEL);
+ res = kmalloc(65536, GFP_KERNEL);
if (!res) {
kfree(ops);
return -ENOMEM;
diff --git a/drivers/misc/msi-laptop.c b/drivers/misc/msi-laptop.c
index fdb7153f4426..8e5e07e4c1cf 100644
--- a/drivers/misc/msi-laptop.c
+++ b/drivers/misc/msi-laptop.c
@@ -317,7 +317,8 @@ static int __init msi_init(void)
/* Register backlight stuff */
- msibl_device = backlight_device_register("msi-laptop-bl", NULL, &msibl_props);
+ msibl_device = backlight_device_register("msi-laptop-bl", NULL, NULL,
+ &msibl_props);
if (IS_ERR(msibl_device))
return PTR_ERR(msibl_device);
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 334e078ffaff..78c2511ae9e0 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -437,7 +437,7 @@ static int __devinit m25p_probe(struct spi_device *spi)
* or JEDEC get-id commands. Try them ...
*/
DEBUG(MTD_DEBUG_LEVEL1, "%s: no chip id\n",
- flash->spi->dev.bus_id);
+ spi->dev.bus_id);
return -ENODEV;
}
@@ -447,7 +447,7 @@ static int __devinit m25p_probe(struct spi_device *spi)
}
if (i == ARRAY_SIZE(m25p_data)) {
DEBUG(MTD_DEBUG_LEVEL1, "%s: unrecognized id %s\n",
- flash->spi->dev.bus_id, data->type);
+ spi->dev.bus_id, data->type);
return -ENODEV;
}
diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c
index 5db716045927..910e4061dfd2 100644
--- a/drivers/mtd/devices/mtd_dataflash.c
+++ b/drivers/mtd/devices/mtd_dataflash.c
@@ -459,7 +459,7 @@ add_dataflash(struct spi_device *spi, char *name,
struct mtd_info *device;
struct flash_platform_data *pdata = spi->dev.platform_data;
- priv = (struct dataflash *) kzalloc(sizeof *priv, GFP_KERNEL);
+ priv = kzalloc(sizeof *priv, GFP_KERNEL);
if (!priv)
return -ENOMEM;
@@ -536,7 +536,7 @@ static int __devinit dataflash_probe(struct spi_device *spi)
if (status <= 0 || status == 0xff) {
DEBUG(MTD_DEBUG_LEVEL1, "%s: status error %d\n",
spi->dev.bus_id, status);
- if (status == 0xff)
+ if (status == 0 || status == 0xff)
status = -ENODEV;
return status;
}
diff --git a/drivers/mtd/rfd_ftl.c b/drivers/mtd/rfd_ftl.c
index fa4362fb4dd8..0f3baa5d9c2a 100644
--- a/drivers/mtd/rfd_ftl.c
+++ b/drivers/mtd/rfd_ftl.c
@@ -768,7 +768,7 @@ static void rfd_ftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
if (mtd->type != MTD_NORFLASH)
return;
- part = kcalloc(1, sizeof(struct partition), GFP_KERNEL);
+ part = kzalloc(sizeof(struct partition), GFP_KERNEL);
if (!part)
return;
diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c
index 458dd9f830c4..e2cb19b582a1 100644
--- a/drivers/net/8139cp.c
+++ b/drivers/net/8139cp.c
@@ -617,13 +617,15 @@ rx_next:
* this round of polling
*/
if (rx_work) {
+ unsigned long flags;
+
if (cpr16(IntrStatus) & cp_rx_intr_mask)
goto rx_status_loop;
- local_irq_disable();
+ local_irq_save(flags);
cpw16_f(IntrMask, cp_intr_mask);
__netif_rx_complete(dev);
- local_irq_enable();
+ local_irq_restore(flags);
return 0; /* done */
}
diff --git a/drivers/net/appletalk/ipddp.c b/drivers/net/appletalk/ipddp.c
index b98592a8bac8..f22e46dfd770 100644
--- a/drivers/net/appletalk/ipddp.c
+++ b/drivers/net/appletalk/ipddp.c
@@ -186,7 +186,7 @@ static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev)
*/
static int ipddp_create(struct ipddp_route *new_rt)
{
- struct ipddp_route *rt =(struct ipddp_route*) kmalloc(sizeof(*rt), GFP_KERNEL);
+ struct ipddp_route *rt = kmalloc(sizeof(*rt), GFP_KERNEL);
if (rt == NULL)
return -ENOMEM;
diff --git a/drivers/net/arm/ep93xx_eth.c b/drivers/net/arm/ep93xx_eth.c
index 8ebd68e2af98..dd698b033a62 100644
--- a/drivers/net/arm/ep93xx_eth.c
+++ b/drivers/net/arm/ep93xx_eth.c
@@ -780,12 +780,10 @@ static struct ethtool_ops ep93xx_ethtool_ops = {
struct net_device *ep93xx_dev_alloc(struct ep93xx_eth_data *data)
{
struct net_device *dev;
- struct ep93xx_priv *ep;
dev = alloc_etherdev(sizeof(struct ep93xx_priv));
if (dev == NULL)
return NULL;
- ep = netdev_priv(dev);
memcpy(dev->dev_addr, data->dev_addr, ETH_ALEN);
@@ -840,9 +838,9 @@ static int ep93xx_eth_probe(struct platform_device *pdev)
struct ep93xx_priv *ep;
int err;
- data = pdev->dev.platform_data;
if (pdev == NULL)
return -ENODEV;
+ data = pdev->dev.platform_data;
dev = ep93xx_dev_alloc(data);
if (dev == NULL) {
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index 474a4e3438db..5eb2ec68393f 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -879,12 +879,14 @@ static int b44_poll(struct net_device *netdev, int *budget)
}
if (bp->istat & ISTAT_ERRORS) {
- spin_lock_irq(&bp->lock);
+ unsigned long flags;
+
+ spin_lock_irqsave(&bp->lock, flags);
b44_halt(bp);
b44_init_rings(bp);
b44_init_hw(bp, 1);
netif_wake_queue(bp->dev);
- spin_unlock_irq(&bp->lock);
+ spin_unlock_irqrestore(&bp->lock, flags);
done = 1;
}
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 7d824cf8ee2d..ada5e9b9988c 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -57,8 +57,8 @@
#define DRV_MODULE_NAME "bnx2"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "1.5.1"
-#define DRV_MODULE_RELDATE "November 15, 2006"
+#define DRV_MODULE_VERSION "1.5.2"
+#define DRV_MODULE_RELDATE "December 13, 2006"
#define RUN_AT(x) (jiffies + (x))
@@ -217,9 +217,16 @@ static inline u32 bnx2_tx_avail(struct bnx2 *bp)
u32 diff;
smp_mb();
- diff = TX_RING_IDX(bp->tx_prod) - TX_RING_IDX(bp->tx_cons);
- if (diff > MAX_TX_DESC_CNT)
- diff = (diff & MAX_TX_DESC_CNT) - 1;
+
+ /* The ring uses 256 indices for 255 entries, one of them
+ * needs to be skipped.
+ */
+ diff = bp->tx_prod - bp->tx_cons;
+ if (unlikely(diff >= TX_DESC_CNT)) {
+ diff &= 0xffff;
+ if (diff == TX_DESC_CNT)
+ diff = MAX_TX_DESC_CNT;
+ }
return (bp->tx_ring_size - diff);
}
@@ -3089,7 +3096,7 @@ bnx2_nvram_write(struct bnx2 *bp, u32 offset, u8 *data_buf,
if ((align_start = (offset32 & 3))) {
offset32 &= ~3;
- len32 += align_start;
+ len32 += (4 - align_start);
if ((rc = bnx2_nvram_read(bp, offset32, start, 4)))
return rc;
}
@@ -3107,7 +3114,7 @@ bnx2_nvram_write(struct bnx2 *bp, u32 offset, u8 *data_buf,
if (align_start || align_end) {
buf = kmalloc(len32, GFP_KERNEL);
- if (buf == 0)
+ if (buf == NULL)
return -ENOMEM;
if (align_start) {
memcpy(buf, start, 4);
@@ -3998,7 +4005,7 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode)
if (!skb)
return -ENOMEM;
packet = skb_put(skb, pkt_size);
- memcpy(packet, bp->mac_addr, 6);
+ memcpy(packet, bp->dev->dev_addr, 6);
memset(packet + 6, 0x0, 8);
for (i = 14; i < pkt_size; i++)
packet[i] = (unsigned char) (i & 0xff);
diff --git a/drivers/net/bsd_comp.c b/drivers/net/bsd_comp.c
index bae1de1e7802..7845eaf6f29f 100644
--- a/drivers/net/bsd_comp.c
+++ b/drivers/net/bsd_comp.c
@@ -395,7 +395,7 @@ static void *bsd_alloc (unsigned char *options, int opt_len, int decomp)
* Allocate the main control structure for this instance.
*/
maxmaxcode = MAXCODE(bits);
- db = (struct bsd_db *) kmalloc (sizeof (struct bsd_db),
+ db = kmalloc(sizeof (struct bsd_db),
GFP_KERNEL);
if (!db)
{
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index da459f7177c6..fb96c87f9e56 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -100,6 +100,9 @@ static const struct e1000_stats e1000_gstrings_stats[] = {
{ "rx_csum_offload_errors", E1000_STAT(hw_csum_err) },
{ "rx_header_split", E1000_STAT(rx_hdr_split) },
{ "alloc_rx_buff_failed", E1000_STAT(alloc_rx_buff_failed) },
+ { "tx_smbus", E1000_STAT(stats.mgptc) },
+ { "rx_smbus", E1000_STAT(stats.mgprc) },
+ { "dropped_smbus", E1000_STAT(stats.mgpdc) },
};
#define E1000_QUEUE_STATS_LEN 0
diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c
index 3655d902b0bd..9be44699300b 100644
--- a/drivers/net/e1000/e1000_hw.c
+++ b/drivers/net/e1000/e1000_hw.c
@@ -308,141 +308,160 @@ e1000_phy_init_script(struct e1000_hw *hw)
int32_t
e1000_set_mac_type(struct e1000_hw *hw)
{
- DEBUGFUNC("e1000_set_mac_type");
-
- switch (hw->device_id) {
- case E1000_DEV_ID_82542:
- switch (hw->revision_id) {
- case E1000_82542_2_0_REV_ID:
- hw->mac_type = e1000_82542_rev2_0;
- break;
- case E1000_82542_2_1_REV_ID:
- hw->mac_type = e1000_82542_rev2_1;
- break;
- default:
- /* Invalid 82542 revision ID */
- return -E1000_ERR_MAC_TYPE;
- }
- break;
- case E1000_DEV_ID_82543GC_FIBER:
- case E1000_DEV_ID_82543GC_COPPER:
- hw->mac_type = e1000_82543;
- break;
- case E1000_DEV_ID_82544EI_COPPER:
- case E1000_DEV_ID_82544EI_FIBER:
- case E1000_DEV_ID_82544GC_COPPER:
- case E1000_DEV_ID_82544GC_LOM:
- hw->mac_type = e1000_82544;
- break;
- case E1000_DEV_ID_82540EM:
- case E1000_DEV_ID_82540EM_LOM:
- case E1000_DEV_ID_82540EP:
- case E1000_DEV_ID_82540EP_LOM:
- case E1000_DEV_ID_82540EP_LP:
- hw->mac_type = e1000_82540;
- break;
- case E1000_DEV_ID_82545EM_COPPER:
- case E1000_DEV_ID_82545EM_FIBER:
- hw->mac_type = e1000_82545;
- break;
- case E1000_DEV_ID_82545GM_COPPER:
- case E1000_DEV_ID_82545GM_FIBER:
- case E1000_DEV_ID_82545GM_SERDES:
- hw->mac_type = e1000_82545_rev_3;
- break;
- case E1000_DEV_ID_82546EB_COPPER:
- case E1000_DEV_ID_82546EB_FIBER:
- case E1000_DEV_ID_82546EB_QUAD_COPPER:
- hw->mac_type = e1000_82546;
- break;
- case E1000_DEV_ID_82546GB_COPPER:
- 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:
- case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
- hw->mac_type = e1000_82546_rev_3;
- break;
- case E1000_DEV_ID_82541EI:
- case E1000_DEV_ID_82541EI_MOBILE:
- case E1000_DEV_ID_82541ER_LOM:
- hw->mac_type = e1000_82541;
- break;
- case E1000_DEV_ID_82541ER:
- case E1000_DEV_ID_82541GI:
- case E1000_DEV_ID_82541GI_LF:
- case E1000_DEV_ID_82541GI_MOBILE:
- hw->mac_type = e1000_82541_rev_2;
- break;
- case E1000_DEV_ID_82547EI:
- case E1000_DEV_ID_82547EI_MOBILE:
- hw->mac_type = e1000_82547;
- break;
- 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:
- case E1000_DEV_ID_82571EB_QUAD_COPPER:
- case E1000_DEV_ID_82571EB_QUAD_COPPER_LOWPROFILE:
- hw->mac_type = e1000_82571;
- break;
- case E1000_DEV_ID_82572EI_COPPER:
- case E1000_DEV_ID_82572EI_FIBER:
- case E1000_DEV_ID_82572EI_SERDES:
- case E1000_DEV_ID_82572EI:
- 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;
- case E1000_DEV_ID_80003ES2LAN_COPPER_SPT:
- case E1000_DEV_ID_80003ES2LAN_SERDES_SPT:
- case E1000_DEV_ID_80003ES2LAN_COPPER_DPT:
- case E1000_DEV_ID_80003ES2LAN_SERDES_DPT:
- hw->mac_type = e1000_80003es2lan;
- break;
- case E1000_DEV_ID_ICH8_IGP_M_AMT:
- case E1000_DEV_ID_ICH8_IGP_AMT:
- case E1000_DEV_ID_ICH8_IGP_C:
- case E1000_DEV_ID_ICH8_IFE:
- case E1000_DEV_ID_ICH8_IFE_GT:
- case E1000_DEV_ID_ICH8_IFE_G:
- case E1000_DEV_ID_ICH8_IGP_M:
- hw->mac_type = e1000_ich8lan;
- break;
- default:
- /* Should never have loaded on this device */
- return -E1000_ERR_MAC_TYPE;
- }
-
- switch (hw->mac_type) {
- case e1000_ich8lan:
- hw->swfwhw_semaphore_present = TRUE;
- hw->asf_firmware_present = TRUE;
- break;
- case e1000_80003es2lan:
- hw->swfw_sync_present = TRUE;
- /* fall through */
- case e1000_82571:
- case e1000_82572:
- case e1000_82573:
- hw->eeprom_semaphore_present = TRUE;
- /* fall through */
- case e1000_82541:
- case e1000_82547:
- case e1000_82541_rev_2:
- case e1000_82547_rev_2:
- hw->asf_firmware_present = TRUE;
- break;
- default:
- break;
- }
-
- return E1000_SUCCESS;
+ DEBUGFUNC("e1000_set_mac_type");
+
+ switch (hw->device_id) {
+ case E1000_DEV_ID_82542:
+ switch (hw->revision_id) {
+ case E1000_82542_2_0_REV_ID:
+ hw->mac_type = e1000_82542_rev2_0;
+ break;
+ case E1000_82542_2_1_REV_ID:
+ hw->mac_type = e1000_82542_rev2_1;
+ break;
+ default:
+ /* Invalid 82542 revision ID */
+ return -E1000_ERR_MAC_TYPE;
+ }
+ break;
+ case E1000_DEV_ID_82543GC_FIBER:
+ case E1000_DEV_ID_82543GC_COPPER:
+ hw->mac_type = e1000_82543;
+ break;
+ case E1000_DEV_ID_82544EI_COPPER:
+ case E1000_DEV_ID_82544EI_FIBER:
+ case E1000_DEV_ID_82544GC_COPPER:
+ case E1000_DEV_ID_82544GC_LOM:
+ hw->mac_type = e1000_82544;
+ break;
+ case E1000_DEV_ID_82540EM:
+ case E1000_DEV_ID_82540EM_LOM:
+ case E1000_DEV_ID_82540EP:
+ case E1000_DEV_ID_82540EP_LOM:
+ case E1000_DEV_ID_82540EP_LP:
+ hw->mac_type = e1000_82540;
+ break;
+ case E1000_DEV_ID_82545EM_COPPER:
+ case E1000_DEV_ID_82545EM_FIBER:
+ hw->mac_type = e1000_82545;
+ break;
+ case E1000_DEV_ID_82545GM_COPPER:
+ case E1000_DEV_ID_82545GM_FIBER:
+ case E1000_DEV_ID_82545GM_SERDES:
+ hw->mac_type = e1000_82545_rev_3;
+ break;
+ case E1000_DEV_ID_82546EB_COPPER:
+ case E1000_DEV_ID_82546EB_FIBER:
+ case E1000_DEV_ID_82546EB_QUAD_COPPER:
+ hw->mac_type = e1000_82546;
+ break;
+ case E1000_DEV_ID_82546GB_COPPER:
+ 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:
+ case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
+ hw->mac_type = e1000_82546_rev_3;
+ break;
+ case E1000_DEV_ID_82541EI:
+ case E1000_DEV_ID_82541EI_MOBILE:
+ case E1000_DEV_ID_82541ER_LOM:
+ hw->mac_type = e1000_82541;
+ break;
+ case E1000_DEV_ID_82541ER:
+ case E1000_DEV_ID_82541GI:
+ case E1000_DEV_ID_82541GI_LF:
+ case E1000_DEV_ID_82541GI_MOBILE:
+ hw->mac_type = e1000_82541_rev_2;
+ break;
+ case E1000_DEV_ID_82547EI:
+ case E1000_DEV_ID_82547EI_MOBILE:
+ hw->mac_type = e1000_82547;
+ break;
+ 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:
+ case E1000_DEV_ID_82571EB_QUAD_COPPER:
+ case E1000_DEV_ID_82571EB_QUAD_COPPER_LOWPROFILE:
+ hw->mac_type = e1000_82571;
+ break;
+ case E1000_DEV_ID_82572EI_COPPER:
+ case E1000_DEV_ID_82572EI_FIBER:
+ case E1000_DEV_ID_82572EI_SERDES:
+ case E1000_DEV_ID_82572EI:
+ 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;
+ case E1000_DEV_ID_80003ES2LAN_COPPER_SPT:
+ case E1000_DEV_ID_80003ES2LAN_SERDES_SPT:
+ case E1000_DEV_ID_80003ES2LAN_COPPER_DPT:
+ case E1000_DEV_ID_80003ES2LAN_SERDES_DPT:
+ hw->mac_type = e1000_80003es2lan;
+ break;
+ case E1000_DEV_ID_ICH8_IGP_M_AMT:
+ case E1000_DEV_ID_ICH8_IGP_AMT:
+ case E1000_DEV_ID_ICH8_IGP_C:
+ case E1000_DEV_ID_ICH8_IFE:
+ case E1000_DEV_ID_ICH8_IFE_GT:
+ case E1000_DEV_ID_ICH8_IFE_G:
+ case E1000_DEV_ID_ICH8_IGP_M:
+ hw->mac_type = e1000_ich8lan;
+ break;
+ default:
+ /* Should never have loaded on this device */
+ return -E1000_ERR_MAC_TYPE;
+ }
+
+ switch (hw->mac_type) {
+ case e1000_ich8lan:
+ hw->swfwhw_semaphore_present = TRUE;
+ hw->asf_firmware_present = TRUE;
+ break;
+ case e1000_80003es2lan:
+ hw->swfw_sync_present = TRUE;
+ /* fall through */
+ case e1000_82571:
+ case e1000_82572:
+ case e1000_82573:
+ hw->eeprom_semaphore_present = TRUE;
+ /* fall through */
+ case e1000_82541:
+ case e1000_82547:
+ case e1000_82541_rev_2:
+ case e1000_82547_rev_2:
+ hw->asf_firmware_present = TRUE;
+ break;
+ default:
+ break;
+ }
+
+ /* The 82543 chip does not count tx_carrier_errors properly in
+ * FD mode
+ */
+ if (hw->mac_type == e1000_82543)
+ hw->bad_tx_carr_stats_fd = TRUE;
+
+ /* capable of receiving management packets to the host */
+ if (hw->mac_type >= e1000_82571)
+ hw->has_manc2h = TRUE;
+
+ /* In rare occasions, ESB2 systems would end up started without
+ * the RX unit being turned on.
+ */
+ if (hw->mac_type == e1000_80003es2lan)
+ hw->rx_needs_kicking = TRUE;
+
+ if (hw->mac_type > e1000_82544)
+ hw->has_smbus = TRUE;
+
+ return E1000_SUCCESS;
}
/*****************************************************************************
@@ -6575,7 +6594,7 @@ e1000_get_bus_info(struct e1000_hw *hw)
switch (hw->mac_type) {
case e1000_82542_rev2_0:
case e1000_82542_rev2_1:
- hw->bus_type = e1000_bus_type_unknown;
+ hw->bus_type = e1000_bus_type_pci;
hw->bus_speed = e1000_bus_speed_unknown;
hw->bus_width = e1000_bus_width_unknown;
break;
@@ -7817,9 +7836,8 @@ e1000_enable_mng_pass_thru(struct e1000_hw *hw)
fwsm = E1000_READ_REG(hw, FWSM);
factps = E1000_READ_REG(hw, FACTPS);
- if (((fwsm & E1000_FWSM_MODE_MASK) ==
- (e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT)) &&
- (factps & E1000_FACTPS_MNGCG))
+ if ((((fwsm & E1000_FWSM_MODE_MASK) >> E1000_FWSM_MODE_SHIFT) ==
+ e1000_mng_mode_pt) && !(factps & E1000_FACTPS_MNGCG))
return TRUE;
} else
if ((manc & E1000_MANC_SMBUS_EN) && !(manc & E1000_MANC_ASF_EN))
diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h
index 3321fb13bfa9..d67105883341 100644
--- a/drivers/net/e1000/e1000_hw.h
+++ b/drivers/net/e1000/e1000_hw.h
@@ -1301,165 +1301,170 @@ struct e1000_ffvt_entry {
#define E1000_82542_RSSIR E1000_RSSIR
#define E1000_82542_KUMCTRLSTA E1000_KUMCTRLSTA
#define E1000_82542_SW_FW_SYNC E1000_SW_FW_SYNC
+#define E1000_82542_MANC2H E1000_MANC2H
/* Statistics counters collected by the MAC */
struct e1000_hw_stats {
- uint64_t crcerrs;
- uint64_t algnerrc;
- uint64_t symerrs;
- uint64_t rxerrc;
- uint64_t txerrc;
- uint64_t mpc;
- uint64_t scc;
- uint64_t ecol;
- uint64_t mcc;
- uint64_t latecol;
- uint64_t colc;
- uint64_t dc;
- uint64_t tncrs;
- uint64_t sec;
- uint64_t cexterr;
- uint64_t rlec;
- uint64_t xonrxc;
- uint64_t xontxc;
- uint64_t xoffrxc;
- uint64_t xofftxc;
- uint64_t fcruc;
- uint64_t prc64;
- uint64_t prc127;
- uint64_t prc255;
- uint64_t prc511;
- uint64_t prc1023;
- uint64_t prc1522;
- uint64_t gprc;
- uint64_t bprc;
- uint64_t mprc;
- uint64_t gptc;
- uint64_t gorcl;
- uint64_t gorch;
- uint64_t gotcl;
- uint64_t gotch;
- uint64_t rnbc;
- uint64_t ruc;
- uint64_t rfc;
- uint64_t roc;
- uint64_t rlerrc;
- uint64_t rjc;
- uint64_t mgprc;
- uint64_t mgpdc;
- uint64_t mgptc;
- uint64_t torl;
- uint64_t torh;
- uint64_t totl;
- uint64_t toth;
- uint64_t tpr;
- uint64_t tpt;
- uint64_t ptc64;
- uint64_t ptc127;
- uint64_t ptc255;
- uint64_t ptc511;
- uint64_t ptc1023;
- uint64_t ptc1522;
- uint64_t mptc;
- uint64_t bptc;
- uint64_t tsctc;
- uint64_t tsctfc;
- uint64_t iac;
- uint64_t icrxptc;
- uint64_t icrxatc;
- uint64_t ictxptc;
- uint64_t ictxatc;
- uint64_t ictxqec;
- uint64_t ictxqmtc;
- uint64_t icrxdmtc;
- uint64_t icrxoc;
+ uint64_t crcerrs;
+ uint64_t algnerrc;
+ uint64_t symerrs;
+ uint64_t rxerrc;
+ uint64_t txerrc;
+ uint64_t mpc;
+ uint64_t scc;
+ uint64_t ecol;
+ uint64_t mcc;
+ uint64_t latecol;
+ uint64_t colc;
+ uint64_t dc;
+ uint64_t tncrs;
+ uint64_t sec;
+ uint64_t cexterr;
+ uint64_t rlec;
+ uint64_t xonrxc;
+ uint64_t xontxc;
+ uint64_t xoffrxc;
+ uint64_t xofftxc;
+ uint64_t fcruc;
+ uint64_t prc64;
+ uint64_t prc127;
+ uint64_t prc255;
+ uint64_t prc511;
+ uint64_t prc1023;
+ uint64_t prc1522;
+ uint64_t gprc;
+ uint64_t bprc;
+ uint64_t mprc;
+ uint64_t gptc;
+ uint64_t gorcl;
+ uint64_t gorch;
+ uint64_t gotcl;
+ uint64_t gotch;
+ uint64_t rnbc;
+ uint64_t ruc;
+ uint64_t rfc;
+ uint64_t roc;
+ uint64_t rlerrc;
+ uint64_t rjc;
+ uint64_t mgprc;
+ uint64_t mgpdc;
+ uint64_t mgptc;
+ uint64_t torl;
+ uint64_t torh;
+ uint64_t totl;
+ uint64_t toth;
+ uint64_t tpr;
+ uint64_t tpt;
+ uint64_t ptc64;
+ uint64_t ptc127;
+ uint64_t ptc255;
+ uint64_t ptc511;
+ uint64_t ptc1023;
+ uint64_t ptc1522;
+ uint64_t mptc;
+ uint64_t bptc;
+ uint64_t tsctc;
+ uint64_t tsctfc;
+ uint64_t iac;
+ uint64_t icrxptc;
+ uint64_t icrxatc;
+ uint64_t ictxptc;
+ uint64_t ictxatc;
+ uint64_t ictxqec;
+ uint64_t ictxqmtc;
+ uint64_t icrxdmtc;
+ uint64_t icrxoc;
};
/* Structure containing variables used by the shared code (e1000_hw.c) */
struct e1000_hw {
- uint8_t __iomem *hw_addr;
- uint8_t __iomem *flash_address;
- e1000_mac_type mac_type;
- e1000_phy_type phy_type;
- uint32_t phy_init_script;
- e1000_media_type media_type;
- void *back;
- struct e1000_shadow_ram *eeprom_shadow_ram;
- uint32_t flash_bank_size;
- uint32_t flash_base_addr;
- e1000_fc_type fc;
- e1000_bus_speed bus_speed;
- e1000_bus_width bus_width;
- e1000_bus_type bus_type;
- struct e1000_eeprom_info eeprom;
- e1000_ms_type master_slave;
- e1000_ms_type original_master_slave;
- e1000_ffe_config ffe_config_state;
- uint32_t asf_firmware_present;
- uint32_t eeprom_semaphore_present;
- uint32_t swfw_sync_present;
- uint32_t swfwhw_semaphore_present;
- unsigned long io_base;
- uint32_t phy_id;
- uint32_t phy_revision;
- uint32_t phy_addr;
- uint32_t original_fc;
- uint32_t txcw;
- uint32_t autoneg_failed;
- uint32_t max_frame_size;
- uint32_t min_frame_size;
- uint32_t mc_filter_type;
- uint32_t num_mc_addrs;
- uint32_t collision_delta;
- uint32_t tx_packet_delta;
- uint32_t ledctl_default;
- uint32_t ledctl_mode1;
- uint32_t ledctl_mode2;
- boolean_t tx_pkt_filtering;
- struct e1000_host_mng_dhcp_cookie mng_cookie;
- uint16_t phy_spd_default;
- uint16_t autoneg_advertised;
- uint16_t pci_cmd_word;
- uint16_t fc_high_water;
- uint16_t fc_low_water;
- uint16_t fc_pause_time;
- uint16_t current_ifs_val;
- uint16_t ifs_min_val;
- uint16_t ifs_max_val;
- uint16_t ifs_step_size;
- uint16_t ifs_ratio;
- uint16_t device_id;
- uint16_t vendor_id;
- uint16_t subsystem_id;
- uint16_t subsystem_vendor_id;
- uint8_t revision_id;
- uint8_t autoneg;
- uint8_t mdix;
- uint8_t forced_speed_duplex;
- uint8_t wait_autoneg_complete;
- uint8_t dma_fairness;
- uint8_t mac_addr[NODE_ADDRESS_SIZE];
- uint8_t perm_mac_addr[NODE_ADDRESS_SIZE];
- boolean_t disable_polarity_correction;
- boolean_t speed_downgraded;
- e1000_smart_speed smart_speed;
- e1000_dsp_config dsp_config_state;
- boolean_t get_link_status;
- 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 initialize_hw_bits_disable;
- boolean_t fc_send_xon;
- boolean_t fc_strict_ieee;
- boolean_t report_tx_early;
- boolean_t adaptive_ifs;
- boolean_t ifs_params_forced;
- boolean_t in_ifs_mode;
- boolean_t mng_reg_access_disabled;
- boolean_t leave_av_bit_off;
- boolean_t kmrn_lock_loss_workaround_disabled;
+ uint8_t __iomem *hw_addr;
+ uint8_t __iomem *flash_address;
+ e1000_mac_type mac_type;
+ e1000_phy_type phy_type;
+ uint32_t phy_init_script;
+ e1000_media_type media_type;
+ void *back;
+ struct e1000_shadow_ram *eeprom_shadow_ram;
+ uint32_t flash_bank_size;
+ uint32_t flash_base_addr;
+ e1000_fc_type fc;
+ e1000_bus_speed bus_speed;
+ e1000_bus_width bus_width;
+ e1000_bus_type bus_type;
+ struct e1000_eeprom_info eeprom;
+ e1000_ms_type master_slave;
+ e1000_ms_type original_master_slave;
+ e1000_ffe_config ffe_config_state;
+ uint32_t asf_firmware_present;
+ uint32_t eeprom_semaphore_present;
+ uint32_t swfw_sync_present;
+ uint32_t swfwhw_semaphore_present;
+ unsigned long io_base;
+ uint32_t phy_id;
+ uint32_t phy_revision;
+ uint32_t phy_addr;
+ uint32_t original_fc;
+ uint32_t txcw;
+ uint32_t autoneg_failed;
+ uint32_t max_frame_size;
+ uint32_t min_frame_size;
+ uint32_t mc_filter_type;
+ uint32_t num_mc_addrs;
+ uint32_t collision_delta;
+ uint32_t tx_packet_delta;
+ uint32_t ledctl_default;
+ uint32_t ledctl_mode1;
+ uint32_t ledctl_mode2;
+ boolean_t tx_pkt_filtering;
+ struct e1000_host_mng_dhcp_cookie mng_cookie;
+ uint16_t phy_spd_default;
+ uint16_t autoneg_advertised;
+ uint16_t pci_cmd_word;
+ uint16_t fc_high_water;
+ uint16_t fc_low_water;
+ uint16_t fc_pause_time;
+ uint16_t current_ifs_val;
+ uint16_t ifs_min_val;
+ uint16_t ifs_max_val;
+ uint16_t ifs_step_size;
+ uint16_t ifs_ratio;
+ uint16_t device_id;
+ uint16_t vendor_id;
+ uint16_t subsystem_id;
+ uint16_t subsystem_vendor_id;
+ uint8_t revision_id;
+ uint8_t autoneg;
+ uint8_t mdix;
+ uint8_t forced_speed_duplex;
+ uint8_t wait_autoneg_complete;
+ uint8_t dma_fairness;
+ uint8_t mac_addr[NODE_ADDRESS_SIZE];
+ uint8_t perm_mac_addr[NODE_ADDRESS_SIZE];
+ boolean_t disable_polarity_correction;
+ boolean_t speed_downgraded;
+ e1000_smart_speed smart_speed;
+ e1000_dsp_config dsp_config_state;
+ boolean_t get_link_status;
+ 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 initialize_hw_bits_disable;
+ boolean_t fc_send_xon;
+ boolean_t fc_strict_ieee;
+ boolean_t report_tx_early;
+ boolean_t adaptive_ifs;
+ boolean_t ifs_params_forced;
+ boolean_t in_ifs_mode;
+ boolean_t mng_reg_access_disabled;
+ boolean_t leave_av_bit_off;
+ boolean_t kmrn_lock_loss_workaround_disabled;
+ boolean_t bad_tx_carr_stats_fd;
+ boolean_t has_manc2h;
+ boolean_t rx_needs_kicking;
+ boolean_t has_smbus;
};
@@ -2418,6 +2423,7 @@ struct e1000_host_command_info {
#define E1000_PBA_8K 0x0008 /* 8KB, default Rx allocation */
#define E1000_PBA_12K 0x000C /* 12KB, default Rx allocation */
#define E1000_PBA_16K 0x0010 /* 16KB, default TX allocation */
+#define E1000_PBA_20K 0x0014
#define E1000_PBA_22K 0x0016
#define E1000_PBA_24K 0x0018
#define E1000_PBA_30K 0x001E
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 73f3a85fd238..4c1ff752048c 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -213,6 +213,12 @@ static void e1000_netpoll (struct net_device *netdev);
extern void e1000_check_options(struct e1000_adapter *adapter);
+#define COPYBREAK_DEFAULT 256
+static unsigned int copybreak __read_mostly = COPYBREAK_DEFAULT;
+module_param(copybreak, uint, 0644);
+MODULE_PARM_DESC(copybreak,
+ "Maximum size of packet that is copied to a new buffer on receive");
+
static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
pci_channel_state_t state);
static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev);
@@ -264,7 +270,13 @@ e1000_init_module(void)
printk(KERN_INFO "%s\n", e1000_copyright);
ret = pci_register_driver(&e1000_driver);
-
+ if (copybreak != COPYBREAK_DEFAULT) {
+ if (copybreak == 0)
+ printk(KERN_INFO "e1000: copybreak disabled\n");
+ else
+ printk(KERN_INFO "e1000: copybreak enabled for "
+ "packets <= %u bytes\n", copybreak);
+ }
return ret;
}
@@ -464,6 +476,52 @@ e1000_get_hw_control(struct e1000_adapter *adapter)
}
}
+static void
+e1000_init_manageability(struct e1000_adapter *adapter)
+{
+ if (adapter->en_mng_pt) {
+ uint32_t manc = E1000_READ_REG(&adapter->hw, MANC);
+
+ /* disable hardware interception of ARP */
+ manc &= ~(E1000_MANC_ARP_EN);
+
+ /* enable receiving management packets to the host */
+ /* this will probably generate destination unreachable messages
+ * from the host OS, but the packets will be handled on SMBUS */
+ if (adapter->hw.has_manc2h) {
+ uint32_t manc2h = E1000_READ_REG(&adapter->hw, MANC2H);
+
+ manc |= E1000_MANC_EN_MNG2HOST;
+#define E1000_MNG2HOST_PORT_623 (1 << 5)
+#define E1000_MNG2HOST_PORT_664 (1 << 6)
+ manc2h |= E1000_MNG2HOST_PORT_623;
+ manc2h |= E1000_MNG2HOST_PORT_664;
+ E1000_WRITE_REG(&adapter->hw, MANC2H, manc2h);
+ }
+
+ E1000_WRITE_REG(&adapter->hw, MANC, manc);
+ }
+}
+
+static void
+e1000_release_manageability(struct e1000_adapter *adapter)
+{
+ if (adapter->en_mng_pt) {
+ uint32_t manc = E1000_READ_REG(&adapter->hw, MANC);
+
+ /* re-enable hardware interception of ARP */
+ manc |= E1000_MANC_ARP_EN;
+
+ if (adapter->hw.has_manc2h)
+ manc &= ~E1000_MANC_EN_MNG2HOST;
+
+ /* don't explicitly have to mess with MANC2H since
+ * MANC has an enable disable that gates MANC2H */
+
+ E1000_WRITE_REG(&adapter->hw, MANC, manc);
+ }
+}
+
int
e1000_up(struct e1000_adapter *adapter)
{
@@ -475,6 +533,7 @@ e1000_up(struct e1000_adapter *adapter)
e1000_set_multi(netdev);
e1000_restore_vlan(adapter);
+ e1000_init_manageability(adapter);
e1000_configure_tx(adapter);
e1000_setup_rctl(adapter);
@@ -497,7 +556,8 @@ e1000_up(struct e1000_adapter *adapter)
clear_bit(__E1000_DOWN, &adapter->flags);
- mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
+ /* fire a link change interrupt to start the watchdog */
+ E1000_WRITE_REG(&adapter->hw, ICS, E1000_ICS_LSC);
return 0;
}
@@ -614,16 +674,34 @@ e1000_reinit_locked(struct e1000_adapter *adapter)
void
e1000_reset(struct e1000_adapter *adapter)
{
- uint32_t pba, manc;
+ uint32_t pba = 0, tx_space, min_tx_space, min_rx_space;
uint16_t fc_high_water_mark = E1000_FC_HIGH_DIFF;
+ boolean_t legacy_pba_adjust = FALSE;
/* Repartition Pba for greater than 9k mtu
* To take effect CTRL.RST is required.
*/
switch (adapter->hw.mac_type) {
+ case e1000_82542_rev2_0:
+ case e1000_82542_rev2_1:
+ case e1000_82543:
+ case e1000_82544:
+ case e1000_82540:
+ case e1000_82541:
+ case e1000_82541_rev_2:
+ legacy_pba_adjust = TRUE;
+ pba = E1000_PBA_48K;
+ break;
+ case e1000_82545:
+ case e1000_82545_rev_3:
+ case e1000_82546:
+ case e1000_82546_rev_3:
+ pba = E1000_PBA_48K;
+ break;
case e1000_82547:
case e1000_82547_rev_2:
+ legacy_pba_adjust = TRUE;
pba = E1000_PBA_30K;
break;
case e1000_82571:
@@ -632,27 +710,80 @@ e1000_reset(struct e1000_adapter *adapter)
pba = E1000_PBA_38K;
break;
case e1000_82573:
- pba = E1000_PBA_12K;
+ pba = E1000_PBA_20K;
break;
case e1000_ich8lan:
pba = E1000_PBA_8K;
- break;
- default:
- pba = E1000_PBA_48K;
+ case e1000_undefined:
+ case e1000_num_macs:
break;
}
- if ((adapter->hw.mac_type != e1000_82573) &&
- (adapter->netdev->mtu > E1000_RXBUFFER_8192))
- pba -= 8; /* allocate more FIFO for Tx */
+ if (legacy_pba_adjust == TRUE) {
+ if (adapter->netdev->mtu > E1000_RXBUFFER_8192)
+ pba -= 8; /* allocate more FIFO for Tx */
+ if (adapter->hw.mac_type == e1000_82547) {
+ adapter->tx_fifo_head = 0;
+ adapter->tx_head_addr = pba << E1000_TX_HEAD_ADDR_SHIFT;
+ adapter->tx_fifo_size =
+ (E1000_PBA_40K - pba) << E1000_PBA_BYTES_SHIFT;
+ atomic_set(&adapter->tx_fifo_stall, 0);
+ }
+ } else if (adapter->hw.max_frame_size > MAXIMUM_ETHERNET_FRAME_SIZE) {
+ /* adjust PBA for jumbo frames */
+ E1000_WRITE_REG(&adapter->hw, PBA, pba);
+
+ /* To maintain wire speed transmits, the Tx FIFO should be
+ * large enough to accomodate two full transmit packets,
+ * rounded up to the next 1KB and expressed in KB. Likewise,
+ * the Rx FIFO should be large enough to accomodate at least
+ * one full receive packet and is similarly rounded up and
+ * expressed in KB. */
+ pba = E1000_READ_REG(&adapter->hw, PBA);
+ /* upper 16 bits has Tx packet buffer allocation size in KB */
+ tx_space = pba >> 16;
+ /* lower 16 bits has Rx packet buffer allocation size in KB */
+ pba &= 0xffff;
+ /* don't include ethernet FCS because hardware appends/strips */
+ min_rx_space = adapter->netdev->mtu + ENET_HEADER_SIZE +
+ VLAN_TAG_SIZE;
+ min_tx_space = min_rx_space;
+ min_tx_space *= 2;
+ E1000_ROUNDUP(min_tx_space, 1024);
+ min_tx_space >>= 10;
+ E1000_ROUNDUP(min_rx_space, 1024);
+ min_rx_space >>= 10;
+
+ /* If current Tx allocation is less than the min Tx FIFO size,
+ * and the min Tx FIFO size is less than the current Rx FIFO
+ * allocation, take space away from current Rx allocation */
+ if (tx_space < min_tx_space &&
+ ((min_tx_space - tx_space) < pba)) {
+ pba = pba - (min_tx_space - tx_space);
+
+ /* PCI/PCIx hardware has PBA alignment constraints */
+ switch (adapter->hw.mac_type) {
+ case e1000_82545 ... e1000_82546_rev_3:
+ pba &= ~(E1000_PBA_8K - 1);
+ break;
+ default:
+ break;
+ }
- if (adapter->hw.mac_type == e1000_82547) {
- adapter->tx_fifo_head = 0;
- adapter->tx_head_addr = pba << E1000_TX_HEAD_ADDR_SHIFT;
- adapter->tx_fifo_size =
- (E1000_PBA_40K - pba) << E1000_PBA_BYTES_SHIFT;
- atomic_set(&adapter->tx_fifo_stall, 0);
+ /* if short on rx space, rx wins and must trump tx
+ * adjustment or use Early Receive if available */
+ if (pba < min_rx_space) {
+ switch (adapter->hw.mac_type) {
+ case e1000_82573:
+ /* ERT enabled in e1000_configure_rx */
+ break;
+ default:
+ pba = min_rx_space;
+ break;
+ }
+ }
+ }
}
E1000_WRITE_REG(&adapter->hw, PBA, pba);
@@ -685,6 +816,20 @@ e1000_reset(struct e1000_adapter *adapter)
if (e1000_init_hw(&adapter->hw))
DPRINTK(PROBE, ERR, "Hardware Error\n");
e1000_update_mng_vlan(adapter);
+
+ /* if (adapter->hwflags & HWFLAGS_PHY_PWR_BIT) { */
+ if (adapter->hw.mac_type >= e1000_82544 &&
+ adapter->hw.mac_type <= e1000_82547_rev_2 &&
+ adapter->hw.autoneg == 1 &&
+ adapter->hw.autoneg_advertised == ADVERTISE_1000_FULL) {
+ uint32_t ctrl = E1000_READ_REG(&adapter->hw, CTRL);
+ /* clear phy power management bit if we are in gig only mode,
+ * which if enabled will attempt negotiation to 100Mb, which
+ * can cause a loss of link at power off or driver unload */
+ ctrl &= ~E1000_CTRL_SWDPIN3;
+ E1000_WRITE_REG(&adapter->hw, CTRL, ctrl);
+ }
+
/* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */
E1000_WRITE_REG(&adapter->hw, VET, ETHERNET_IEEE_VLAN_TYPE);
@@ -705,14 +850,7 @@ e1000_reset(struct e1000_adapter *adapter)
phy_data);
}
- if ((adapter->en_mng_pt) &&
- (adapter->hw.mac_type >= e1000_82540) &&
- (adapter->hw.mac_type < e1000_82571) &&
- (adapter->hw.media_type == e1000_media_type_copper)) {
- manc = E1000_READ_REG(&adapter->hw, MANC);
- manc |= (E1000_MANC_ARP_EN | E1000_MANC_EN_MNG2HOST);
- E1000_WRITE_REG(&adapter->hw, MANC, manc);
- }
+ e1000_release_manageability(adapter);
}
/**
@@ -857,6 +995,12 @@ e1000_probe(struct pci_dev *pdev,
(adapter->hw.mac_type != e1000_82547))
netdev->features |= NETIF_F_TSO;
+#ifdef CONFIG_DEBUG_SLAB
+ /* 82544's work arounds do not play nicely with DEBUG SLAB */
+ if (adapter->hw.mac_type == e1000_82544)
+ netdev->features &= ~NETIF_F_TSO;
+#endif
+
#ifdef NETIF_F_TSO6
if (adapter->hw.mac_type > e1000_82547_rev_2)
netdev->features |= NETIF_F_TSO6;
@@ -1078,22 +1222,13 @@ e1000_remove(struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct e1000_adapter *adapter = netdev_priv(netdev);
- uint32_t manc;
#ifdef CONFIG_E1000_NAPI
int i;
#endif
flush_scheduled_work();
- if (adapter->hw.mac_type >= e1000_82540 &&
- adapter->hw.mac_type < e1000_82571 &&
- adapter->hw.media_type == e1000_media_type_copper) {
- manc = E1000_READ_REG(&adapter->hw, MANC);
- if (manc & E1000_MANC_SMBUS_EN) {
- manc |= E1000_MANC_ARP_EN;
- E1000_WRITE_REG(&adapter->hw, MANC, manc);
- }
- }
+ e1000_release_manageability(adapter);
/* Release control of h/w to f/w. If f/w is AMT enabled, this
* would have already happened in close and is redundant. */
@@ -1531,9 +1666,9 @@ e1000_configure_tx(struct e1000_adapter *adapter)
}
/* Set the default values for the Tx Inter Packet Gap timer */
-
- if (hw->media_type == e1000_media_type_fiber ||
- hw->media_type == e1000_media_type_internal_serdes)
+ if (adapter->hw.mac_type <= e1000_82547_rev_2 &&
+ (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;
@@ -2528,6 +2663,13 @@ e1000_watchdog(unsigned long data)
netif_wake_queue(netdev);
mod_timer(&adapter->phy_info_timer, jiffies + 2 * HZ);
adapter->smartspeed = 0;
+ } else {
+ /* make sure the receive unit is started */
+ if (adapter->hw.rx_needs_kicking) {
+ struct e1000_hw *hw = &adapter->hw;
+ uint32_t rctl = E1000_READ_REG(hw, RCTL);
+ E1000_WRITE_REG(hw, RCTL, rctl | E1000_RCTL_EN);
+ }
}
} else {
if (netif_carrier_ok(netdev)) {
@@ -2628,29 +2770,34 @@ static unsigned int e1000_update_itr(struct e1000_adapter *adapter,
if (packets == 0)
goto update_itr_done;
-
switch (itr_setting) {
case lowest_latency:
- if ((packets < 5) && (bytes > 512))
+ /* jumbo frames get bulk treatment*/
+ if (bytes/packets > 8000)
+ retval = bulk_latency;
+ else if ((packets < 5) && (bytes > 512))
retval = low_latency;
break;
case low_latency: /* 50 usec aka 20000 ints/s */
if (bytes > 10000) {
- if ((packets < 10) ||
- ((bytes/packets) > 1200))
+ /* jumbo frames need bulk latency setting */
+ if (bytes/packets > 8000)
+ retval = bulk_latency;
+ else if ((packets < 10) || ((bytes/packets) > 1200))
retval = bulk_latency;
else if ((packets > 35))
retval = lowest_latency;
- } else if (packets <= 2 && bytes < 512)
+ } else if (bytes/packets > 2000)
+ retval = bulk_latency;
+ else if (packets <= 2 && bytes < 512)
retval = lowest_latency;
break;
case bulk_latency: /* 250 usec aka 4000 ints/s */
if (bytes > 25000) {
if (packets > 35)
retval = low_latency;
- } else {
- if (bytes < 6000)
- retval = low_latency;
+ } else if (bytes < 6000) {
+ retval = low_latency;
}
break;
}
@@ -2679,17 +2826,20 @@ static void e1000_set_itr(struct e1000_adapter *adapter)
adapter->tx_itr,
adapter->total_tx_packets,
adapter->total_tx_bytes);
+ /* conservative mode (itr 3) eliminates the lowest_latency setting */
+ if (adapter->itr_setting == 3 && adapter->tx_itr == lowest_latency)
+ adapter->tx_itr = low_latency;
+
adapter->rx_itr = e1000_update_itr(adapter,
adapter->rx_itr,
adapter->total_rx_packets,
adapter->total_rx_bytes);
+ /* conservative mode (itr 3) eliminates the lowest_latency setting */
+ if (adapter->itr_setting == 3 && adapter->rx_itr == lowest_latency)
+ adapter->rx_itr = low_latency;
current_itr = max(adapter->rx_itr, adapter->tx_itr);
- /* conservative mode eliminates the lowest_latency setting */
- if (current_itr == lowest_latency && (adapter->itr_setting == 3))
- current_itr = low_latency;
-
switch (current_itr) {
/* counts and packets in update_itr are dependent on these numbers */
case lowest_latency:
@@ -3168,6 +3318,16 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
if (skb->data_len && (hdr_len == (skb->len - skb->data_len))) {
switch (adapter->hw.mac_type) {
unsigned int pull_size;
+ case e1000_82544:
+ /* Make sure we have room to chop off 4 bytes,
+ * and that the end alignment will work out to
+ * this hardware's requirements
+ * NOTE: this is a TSO only workaround
+ * if end byte alignment not correct move us
+ * into the next dword */
+ if ((unsigned long)(skb->tail - 1) & 4)
+ break;
+ /* fall through */
case e1000_82571:
case e1000_82572:
case e1000_82573:
@@ -3419,12 +3579,11 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu)
adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
netdev->mtu = new_mtu;
+ adapter->hw.max_frame_size = max_frame;
if (netif_running(netdev))
e1000_reinit_locked(adapter);
- adapter->hw.max_frame_size = max_frame;
-
return 0;
}
@@ -3573,6 +3732,11 @@ e1000_update_stats(struct e1000_adapter *adapter)
adapter->net_stats.tx_aborted_errors = adapter->stats.ecol;
adapter->net_stats.tx_window_errors = adapter->stats.latecol;
adapter->net_stats.tx_carrier_errors = adapter->stats.tncrs;
+ if (adapter->hw.bad_tx_carr_stats_fd &&
+ adapter->link_duplex == FULL_DUPLEX) {
+ adapter->net_stats.tx_carrier_errors = 0;
+ adapter->stats.tncrs = 0;
+ }
/* Tx Dropped needs to be maintained elsewhere */
@@ -3590,6 +3754,13 @@ e1000_update_stats(struct e1000_adapter *adapter)
adapter->phy_stats.receive_errors += phy_tmp;
}
+ /* Management Stats */
+ if (adapter->hw.has_smbus) {
+ adapter->stats.mgptc += E1000_READ_REG(hw, MGTPTC);
+ adapter->stats.mgprc += E1000_READ_REG(hw, MGTPRC);
+ adapter->stats.mgpdc += E1000_READ_REG(hw, MGTPDC);
+ }
+
spin_unlock_irqrestore(&adapter->stats_lock, flags);
}
#ifdef CONFIG_PCI_MSI
@@ -3868,11 +4039,11 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter,
cleaned = (i == eop);
if (cleaned) {
- /* this packet count is wrong for TSO but has a
- * tendency to make dynamic ITR change more
- * towards bulk */
+ struct sk_buff *skb = buffer_info->skb;
+ unsigned int segs = skb_shinfo(skb)->gso_segs;
+ total_tx_packets += segs;
total_tx_packets++;
- total_tx_bytes += buffer_info->skb->len;
+ total_tx_bytes += skb->len;
}
e1000_unmap_and_free_tx_resource(adapter, buffer_info);
tx_desc->upper.data = 0;
@@ -4094,8 +4265,7 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter,
/* code added for copybreak, this should improve
* performance for small packets with large amounts
* of reassembly being done in the stack */
-#define E1000_CB_LENGTH 256
- if (length < E1000_CB_LENGTH) {
+ if (length < copybreak) {
struct sk_buff *new_skb =
netdev_alloc_skb(netdev, length + NET_IP_ALIGN);
if (new_skb) {
@@ -4253,7 +4423,7 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
/* page alloc/put takes too long and effects small packet
* throughput, so unsplit small packets and save the alloc/put*/
- if (l1 && ((length + l1) <= adapter->rx_ps_bsize0)) {
+ if (l1 && (l1 <= copybreak) && ((length + l1) <= adapter->rx_ps_bsize0)) {
u8 *vaddr;
/* there is no documentation about how to call
* kmap_atomic, so we can't hold the mapping
@@ -4998,7 +5168,7 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct e1000_adapter *adapter = netdev_priv(netdev);
- uint32_t ctrl, ctrl_ext, rctl, manc, status;
+ uint32_t ctrl, ctrl_ext, rctl, status;
uint32_t wufc = adapter->wol;
#ifdef CONFIG_PM
int retval = 0;
@@ -5067,16 +5237,12 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state)
pci_enable_wake(pdev, PCI_D3cold, 0);
}
- if (adapter->hw.mac_type >= e1000_82540 &&
- adapter->hw.mac_type < e1000_82571 &&
- adapter->hw.media_type == e1000_media_type_copper) {
- manc = E1000_READ_REG(&adapter->hw, MANC);
- if (manc & E1000_MANC_SMBUS_EN) {
- manc |= E1000_MANC_ARP_EN;
- E1000_WRITE_REG(&adapter->hw, MANC, manc);
- pci_enable_wake(pdev, PCI_D3hot, 1);
- pci_enable_wake(pdev, PCI_D3cold, 1);
- }
+ e1000_release_manageability(adapter);
+
+ /* make sure adapter isn't asleep if manageability is enabled */
+ if (adapter->en_mng_pt) {
+ pci_enable_wake(pdev, PCI_D3hot, 1);
+ pci_enable_wake(pdev, PCI_D3cold, 1);
}
if (adapter->hw.phy_type == e1000_phy_igp_3)
@@ -5102,7 +5268,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, err;
+ uint32_t err;
pci_set_power_state(pdev, PCI_D0);
e1000_pci_restore_state(adapter);
@@ -5122,19 +5288,13 @@ e1000_resume(struct pci_dev *pdev)
e1000_reset(adapter);
E1000_WRITE_REG(&adapter->hw, WUS, ~0);
+ e1000_init_manageability(adapter);
+
if (netif_running(netdev))
e1000_up(adapter);
netif_device_attach(netdev);
- if (adapter->hw.mac_type >= e1000_82540 &&
- adapter->hw.mac_type < e1000_82571 &&
- adapter->hw.media_type == e1000_media_type_copper) {
- manc = E1000_READ_REG(&adapter->hw, MANC);
- manc &= ~(E1000_MANC_ARP_EN);
- E1000_WRITE_REG(&adapter->hw, MANC, manc);
- }
-
/* If the controller is 82573 and f/w is AMT, do not set
* DRV_LOAD until the interface is up. For all other cases,
* let the f/w know that the h/w is now under the control
@@ -5235,7 +5395,8 @@ static void e1000_io_resume(struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct e1000_adapter *adapter = netdev->priv;
- uint32_t manc, swsm;
+
+ e1000_init_manageability(adapter);
if (netif_running(netdev)) {
if (e1000_up(adapter)) {
@@ -5246,26 +5407,14 @@ static void e1000_io_resume(struct pci_dev *pdev)
netif_device_attach(netdev);
- if (adapter->hw.mac_type >= e1000_82540 &&
- adapter->hw.mac_type < e1000_82571 &&
- adapter->hw.media_type == e1000_media_type_copper) {
- manc = E1000_READ_REG(&adapter->hw, MANC);
- manc &= ~(E1000_MANC_ARP_EN);
- E1000_WRITE_REG(&adapter->hw, MANC, manc);
- }
-
- switch (adapter->hw.mac_type) {
- case e1000_82573:
- swsm = E1000_READ_REG(&adapter->hw, SWSM);
- E1000_WRITE_REG(&adapter->hw, SWSM,
- swsm | E1000_SWSM_DRV_LOAD);
- break;
- default:
- break;
- }
+ /* If the controller is 82573 and f/w is AMT, do not set
+ * DRV_LOAD until the interface is up. For all other cases,
+ * let the f/w know that the h/w is now under the control
+ * of the driver. */
+ if (adapter->hw.mac_type != e1000_82573 ||
+ !e1000_check_mng_mode(&adapter->hw))
+ e1000_get_hw_control(adapter);
- if (netif_running(netdev))
- mod_timer(&adapter->watchdog_timer, jiffies);
}
/* e1000_main.c */
diff --git a/drivers/net/e1000/e1000_param.c b/drivers/net/e1000/e1000_param.c
index cbfcd7f2889f..cf2a279307e1 100644
--- a/drivers/net/e1000/e1000_param.c
+++ b/drivers/net/e1000/e1000_param.c
@@ -487,7 +487,9 @@ e1000_check_options(struct e1000_adapter *adapter)
e1000_validate_option(&adapter->itr, &opt,
adapter);
/* save the setting, because the dynamic bits change itr */
- adapter->itr_setting = adapter->itr;
+ /* clear the lower two bits because they are
+ * used as control */
+ adapter->itr_setting = adapter->itr & ~3;
break;
}
} else {
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 439f41338291..2f48fe9a29a7 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -3,8 +3,7 @@
*
* Note: This driver is a cleanroom reimplementation based on reverse
* engineered documentation written by Carl-Daniel Hailfinger
- * and Andrew de Quincey. It's neither supported nor endorsed
- * by NVIDIA Corp. Use at your own risk.
+ * and Andrew de Quincey.
*
* NVIDIA, nForce and other NVIDIA marks are trademarks or registered
* trademarks of NVIDIA Corporation in the United States and other
@@ -14,7 +13,7 @@
* Copyright (C) 2004 Andrew de Quincey (wol support)
* Copyright (C) 2004 Carl-Daniel Hailfinger (invalid MAC handling, insane
* IRQ rate fixes, bigendian fixes, cleanups, verification)
- * Copyright (c) 2004 NVIDIA Corporation
+ * Copyright (c) 2004,5,6 NVIDIA 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
@@ -2576,14 +2575,15 @@ static int nv_napi_poll(struct net_device *dev, int *budget)
int pkts, limit = min(*budget, dev->quota);
struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
+ unsigned long flags;
pkts = nv_rx_process(dev, limit);
if (nv_alloc_rx(dev)) {
- spin_lock_irq(&np->lock);
+ spin_lock_irqsave(&np->lock, flags);
if (!np->in_shutdown)
mod_timer(&np->oom_kick, jiffies + OOM_REFILL);
- spin_unlock_irq(&np->lock);
+ spin_unlock_irqrestore(&np->lock, flags);
}
if (pkts < limit) {
@@ -2591,13 +2591,15 @@ static int nv_napi_poll(struct net_device *dev, int *budget)
netif_rx_complete(dev);
/* re-enable receive interrupts */
- spin_lock_irq(&np->lock);
+ spin_lock_irqsave(&np->lock, flags);
+
np->irqmask |= NVREG_IRQ_RX_ALL;
if (np->msi_flags & NV_MSI_X_ENABLED)
writel(NVREG_IRQ_RX_ALL, base + NvRegIrqMask);
else
writel(np->irqmask, base + NvRegIrqMask);
- spin_unlock_irq(&np->lock);
+
+ spin_unlock_irqrestore(&np->lock, flags);
return 0;
} else {
/* used up our quantum, so reschedule */
diff --git a/drivers/net/ibm_emac/ibm_emac_phy.c b/drivers/net/ibm_emac/ibm_emac_phy.c
index 4a97024061e5..9074f76ee2bf 100644
--- a/drivers/net/ibm_emac/ibm_emac_phy.c
+++ b/drivers/net/ibm_emac/ibm_emac_phy.c
@@ -309,7 +309,7 @@ int mii_phy_probe(struct mii_phy *phy, int address)
{
struct mii_phy_def *def;
int i;
- u32 id;
+ int id;
phy->autoneg = AUTONEG_DISABLE;
phy->advertising = 0;
@@ -324,6 +324,8 @@ int mii_phy_probe(struct mii_phy *phy, int address)
/* Read ID and find matching entry */
id = (phy_read(phy, MII_PHYSID1) << 16) | phy_read(phy, MII_PHYSID2);
+ if (id < 0)
+ return -ENODEV;
for (i = 0; (def = mii_phy_table[i]) != NULL; i++)
if ((id & def->phy_id_mask) == def->phy_id)
break;
diff --git a/drivers/net/irda/donauboe.c b/drivers/net/irda/donauboe.c
index 16620bd97fbf..11af0ae7510e 100644
--- a/drivers/net/irda/donauboe.c
+++ b/drivers/net/irda/donauboe.c
@@ -1603,7 +1603,7 @@ toshoboe_open (struct pci_dev *pci_dev, const struct pci_device_id *pdid)
irda_qos_bits_to_value (&self->qos);
/* Allocate twice the size to guarantee alignment */
- self->ringbuf = (void *) kmalloc (OBOE_RING_LEN << 1, GFP_KERNEL);
+ self->ringbuf = kmalloc(OBOE_RING_LEN << 1, GFP_KERNEL);
if (!self->ringbuf)
{
printk (KERN_ERR DRIVER_NAME ": can't allocate DMA buffers\n");
diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c
index 6e95645e7245..3ca1082ec776 100644
--- a/drivers/net/irda/irda-usb.c
+++ b/drivers/net/irda/irda-usb.c
@@ -1747,7 +1747,7 @@ static int irda_usb_probe(struct usb_interface *intf,
/* Don't change this buffer size and allocation without doing
* some heavy and complete testing. Don't ask why :-(
* Jean II */
- self->speed_buff = (char *) kmalloc(IRDA_USB_SPEED_MTU, GFP_KERNEL);
+ self->speed_buff = kmalloc(IRDA_USB_SPEED_MTU, GFP_KERNEL);
if (self->speed_buff == NULL)
goto err_out_3;
diff --git a/drivers/net/irda/irport.c b/drivers/net/irda/irport.c
index 654a68b490ae..3098960dc2a1 100644
--- a/drivers/net/irda/irport.c
+++ b/drivers/net/irda/irport.c
@@ -164,7 +164,7 @@ irport_open(int i, unsigned int iobase, unsigned int irq)
/* Allocate memory if needed */
if (self->tx_buff.truesize > 0) {
- self->tx_buff.head = (__u8 *) kmalloc(self->tx_buff.truesize,
+ self->tx_buff.head = kmalloc(self->tx_buff.truesize,
GFP_KERNEL);
if (self->tx_buff.head == NULL) {
IRDA_ERROR("%s(), can't allocate memory for "
diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c
index d6f4f185bf37..2194b567239f 100644
--- a/drivers/net/iseries_veth.c
+++ b/drivers/net/iseries_veth.c
@@ -73,7 +73,7 @@
#include <asm/abs_addr.h>
#include <asm/iseries/mf.h>
#include <asm/uaccess.h>
-
+#include <asm/firmware.h>
#include <asm/iseries/hv_lp_config.h>
#include <asm/iseries/hv_types.h>
#include <asm/iseries/hv_lp_event.h>
@@ -1668,7 +1668,7 @@ static struct vio_driver veth_driver = {
* Module initialization/cleanup
*/
-void __exit veth_module_cleanup(void)
+static void __exit veth_module_cleanup(void)
{
int i;
struct veth_lpar_connection *cnx;
@@ -1697,11 +1697,14 @@ void __exit veth_module_cleanup(void)
}
module_exit(veth_module_cleanup);
-int __init veth_module_init(void)
+static int __init veth_module_init(void)
{
int i;
int rc;
+ if (!firmware_has_feature(FW_FEATURE_ISERIES))
+ return -ENODEV;
+
this_lp = HvLpConfig_getLpIndex_outline();
for (i = 0; i < HVMAXARCHITECTEDLPS; ++i) {
diff --git a/drivers/net/lp486e.c b/drivers/net/lp486e.c
index b833016f1825..177c502f7385 100644
--- a/drivers/net/lp486e.c
+++ b/drivers/net/lp486e.c
@@ -884,7 +884,7 @@ static int i596_start_xmit (struct sk_buff *skb, struct net_device *dev) {
dev->trans_start = jiffies;
- tx_cmd = (struct tx_cmd *) kmalloc ((sizeof (struct tx_cmd) + sizeof (struct i596_tbd)), GFP_ATOMIC);
+ tx_cmd = kmalloc((sizeof (struct tx_cmd) + sizeof (struct i596_tbd)), GFP_ATOMIC);
if (tx_cmd == NULL) {
printk(KERN_WARNING "%s: i596_xmit Memory squeeze, dropping packet.\n", dev->name);
lp->stats.tx_dropped++;
@@ -1266,7 +1266,7 @@ static void set_multicast_list(struct net_device *dev) {
if (dev->mc_count > 0) {
struct dev_mc_list *dmi;
char *cp;
- cmd = (struct i596_cmd *)kmalloc(sizeof(struct i596_cmd)+2+dev->mc_count*6, GFP_ATOMIC);
+ cmd = kmalloc(sizeof(struct i596_cmd)+2+dev->mc_count*6, GFP_ATOMIC);
if (cmd == NULL) {
printk (KERN_ERR "%s: set_multicast Memory squeeze.\n", dev->name);
return;
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index 94ac168be593..07cf574197e5 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -199,8 +199,6 @@ struct myri10ge_priv {
unsigned long serial_number;
int vendor_specific_offset;
int fw_multicast_support;
- u32 devctl;
- u16 msi_flags;
u32 read_dma;
u32 write_dma;
u32 read_write_dma;
@@ -228,7 +226,7 @@ module_param(myri10ge_small_bytes, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(myri10ge_small_bytes, "Threshold of small packets\n");
static int myri10ge_msi = 1; /* enable msi by default */
-module_param(myri10ge_msi, int, S_IRUGO);
+module_param(myri10ge_msi, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(myri10ge_msi, "Enable Message Signalled Interrupts\n");
static int myri10ge_intr_coal_delay = 25;
@@ -721,12 +719,10 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
status |=
myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_IRQ_ACK_OFFSET, &cmd, 0);
mgp->irq_claim = (__iomem __be32 *) (mgp->sram + cmd.data0);
- if (!mgp->msi_enabled) {
- status |= myri10ge_send_cmd
- (mgp, MXGEFW_CMD_GET_IRQ_DEASSERT_OFFSET, &cmd, 0);
- mgp->irq_deassert = (__iomem __be32 *) (mgp->sram + cmd.data0);
+ status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_IRQ_DEASSERT_OFFSET,
+ &cmd, 0);
+ mgp->irq_deassert = (__iomem __be32 *) (mgp->sram + cmd.data0);
- }
status |= myri10ge_send_cmd
(mgp, MXGEFW_CMD_GET_INTR_COAL_DELAY_OFFSET, &cmd, 0);
mgp->intr_coal_delay_ptr = (__iomem __be32 *) (mgp->sram + cmd.data0);
@@ -1619,6 +1615,41 @@ static void myri10ge_free_rings(struct net_device *dev)
mgp->tx.req_list = NULL;
}
+static int myri10ge_request_irq(struct myri10ge_priv *mgp)
+{
+ struct pci_dev *pdev = mgp->pdev;
+ int status;
+
+ if (myri10ge_msi) {
+ status = pci_enable_msi(pdev);
+ if (status != 0)
+ dev_err(&pdev->dev,
+ "Error %d setting up MSI; falling back to xPIC\n",
+ status);
+ else
+ mgp->msi_enabled = 1;
+ } else {
+ mgp->msi_enabled = 0;
+ }
+ status = request_irq(pdev->irq, myri10ge_intr, IRQF_SHARED,
+ mgp->dev->name, mgp);
+ if (status != 0) {
+ dev_err(&pdev->dev, "failed to allocate IRQ\n");
+ if (mgp->msi_enabled)
+ pci_disable_msi(pdev);
+ }
+ return status;
+}
+
+static void myri10ge_free_irq(struct myri10ge_priv *mgp)
+{
+ struct pci_dev *pdev = mgp->pdev;
+
+ free_irq(pdev->irq, mgp);
+ if (mgp->msi_enabled)
+ pci_disable_msi(pdev);
+}
+
static int myri10ge_open(struct net_device *dev)
{
struct myri10ge_priv *mgp;
@@ -1634,10 +1665,13 @@ static int myri10ge_open(struct net_device *dev)
status = myri10ge_reset(mgp);
if (status != 0) {
printk(KERN_ERR "myri10ge: %s: failed reset\n", dev->name);
- mgp->running = MYRI10GE_ETH_STOPPED;
- return -ENXIO;
+ goto abort_with_nothing;
}
+ status = myri10ge_request_irq(mgp);
+ if (status != 0)
+ goto abort_with_nothing;
+
/* decide what small buffer size to use. For good TCP rx
* performance, it is important to not receive 1514 byte
* frames into jumbo buffers, as it confuses the socket buffer
@@ -1677,7 +1711,7 @@ static int myri10ge_open(struct net_device *dev)
"myri10ge: %s: failed to get ring sizes or locations\n",
dev->name);
mgp->running = MYRI10GE_ETH_STOPPED;
- return -ENXIO;
+ goto abort_with_irq;
}
if (mgp->mtrr >= 0) {
@@ -1708,7 +1742,7 @@ static int myri10ge_open(struct net_device *dev)
status = myri10ge_allocate_rings(dev);
if (status != 0)
- goto abort_with_nothing;
+ goto abort_with_irq;
/* now give firmware buffers sizes, and MTU */
cmd.data0 = dev->mtu + ETH_HLEN + VLAN_HLEN;
@@ -1771,6 +1805,9 @@ static int myri10ge_open(struct net_device *dev)
abort_with_rings:
myri10ge_free_rings(dev);
+abort_with_irq:
+ myri10ge_free_irq(mgp);
+
abort_with_nothing:
mgp->running = MYRI10GE_ETH_STOPPED;
return -ENOMEM;
@@ -1807,7 +1844,7 @@ static int myri10ge_close(struct net_device *dev)
printk(KERN_ERR "myri10ge: %s never got down irq\n", dev->name);
netif_tx_disable(dev);
-
+ myri10ge_free_irq(mgp);
myri10ge_free_rings(dev);
mgp->running = MYRI10GE_ETH_STOPPED;
@@ -2481,34 +2518,6 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
}
}
-static void myri10ge_save_state(struct myri10ge_priv *mgp)
-{
- struct pci_dev *pdev = mgp->pdev;
- int cap;
-
- pci_save_state(pdev);
- /* now save PCIe and MSI state that Linux will not
- * save for us */
- cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
- pci_read_config_dword(pdev, cap + PCI_EXP_DEVCTL, &mgp->devctl);
- cap = pci_find_capability(pdev, PCI_CAP_ID_MSI);
- pci_read_config_word(pdev, cap + PCI_MSI_FLAGS, &mgp->msi_flags);
-}
-
-static void myri10ge_restore_state(struct myri10ge_priv *mgp)
-{
- struct pci_dev *pdev = mgp->pdev;
- int cap;
-
- /* restore PCIe and MSI state that linux will not */
- cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
- pci_write_config_dword(pdev, cap + PCI_CAP_ID_EXP, mgp->devctl);
- cap = pci_find_capability(pdev, PCI_CAP_ID_MSI);
- pci_write_config_word(pdev, cap + PCI_MSI_FLAGS, mgp->msi_flags);
-
- pci_restore_state(pdev);
-}
-
#ifdef CONFIG_PM
static int myri10ge_suspend(struct pci_dev *pdev, pm_message_t state)
@@ -2529,11 +2538,10 @@ static int myri10ge_suspend(struct pci_dev *pdev, pm_message_t state)
rtnl_unlock();
}
myri10ge_dummy_rdma(mgp, 0);
- free_irq(pdev->irq, mgp);
- myri10ge_save_state(mgp);
+ pci_save_state(pdev);
pci_disable_device(pdev);
- pci_set_power_state(pdev, pci_choose_state(pdev, state));
- return 0;
+
+ return pci_set_power_state(pdev, pci_choose_state(pdev, state));
}
static int myri10ge_resume(struct pci_dev *pdev)
@@ -2555,34 +2563,33 @@ static int myri10ge_resume(struct pci_dev *pdev)
mgp->dev->name);
return -EIO;
}
- myri10ge_restore_state(mgp);
+
+ status = pci_restore_state(pdev);
+ if (status)
+ return status;
status = pci_enable_device(pdev);
- if (status < 0) {
+ if (status) {
dev_err(&pdev->dev, "failed to enable device\n");
- return -EIO;
+ return status;
}
pci_set_master(pdev);
- status = request_irq(pdev->irq, myri10ge_intr, IRQF_SHARED,
- netdev->name, mgp);
- if (status != 0) {
- dev_err(&pdev->dev, "failed to allocate IRQ\n");
- goto abort_with_enabled;
- }
-
myri10ge_reset(mgp);
myri10ge_dummy_rdma(mgp, 1);
/* Save configuration space to be restored if the
* nic resets due to a parity error */
- myri10ge_save_state(mgp);
+ pci_save_state(pdev);
if (netif_running(netdev)) {
rtnl_lock();
- myri10ge_open(netdev);
+ status = myri10ge_open(netdev);
rtnl_unlock();
+ if (status != 0)
+ goto abort_with_enabled;
+
}
netif_device_attach(netdev);
@@ -2640,7 +2647,11 @@ static void myri10ge_watchdog(struct work_struct *work)
* when the driver was loaded, or the last time the
* nic was resumed from power saving mode.
*/
- myri10ge_restore_state(mgp);
+ pci_restore_state(mgp->pdev);
+
+ /* save state again for accounting reasons */
+ pci_save_state(mgp->pdev);
+
} else {
/* if we get back -1's from our slot, perhaps somebody
* powered off our card. Don't try to reset it in
@@ -2856,23 +2867,6 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto abort_with_firmware;
}
- if (myri10ge_msi) {
- status = pci_enable_msi(pdev);
- if (status != 0)
- dev_err(&pdev->dev,
- "Error %d setting up MSI; falling back to xPIC\n",
- status);
- else
- mgp->msi_enabled = 1;
- }
-
- status = request_irq(pdev->irq, myri10ge_intr, IRQF_SHARED,
- netdev->name, mgp);
- if (status != 0) {
- dev_err(&pdev->dev, "failed to allocate IRQ\n");
- goto abort_with_firmware;
- }
-
pci_set_drvdata(pdev, mgp);
if ((myri10ge_initial_mtu + ETH_HLEN) > MYRI10GE_MAX_ETHER_MTU)
myri10ge_initial_mtu = MYRI10GE_MAX_ETHER_MTU - ETH_HLEN;
@@ -2896,7 +2890,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* Save configuration space to be restored if the
* nic resets due to a parity error */
- myri10ge_save_state(mgp);
+ pci_save_state(pdev);
/* Setup the watchdog timer */
setup_timer(&mgp->watchdog_timer, myri10ge_watchdog_timer,
@@ -2907,19 +2901,16 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
status = register_netdev(netdev);
if (status != 0) {
dev_err(&pdev->dev, "register_netdev failed: %d\n", status);
- goto abort_with_irq;
+ goto abort_with_state;
}
- dev_info(dev, "%s IRQ %d, tx bndry %d, fw %s, WC %s\n",
- (mgp->msi_enabled ? "MSI" : "xPIC"),
+ dev_info(dev, "%d, tx bndry %d, fw %s, WC %s\n",
pdev->irq, mgp->tx.boundary, mgp->fw_name,
(mgp->mtrr >= 0 ? "Enabled" : "Disabled"));
return 0;
-abort_with_irq:
- free_irq(pdev->irq, mgp);
- if (mgp->msi_enabled)
- pci_disable_msi(pdev);
+abort_with_state:
+ pci_restore_state(pdev);
abort_with_firmware:
myri10ge_dummy_rdma(mgp, 0);
@@ -2970,12 +2961,12 @@ static void myri10ge_remove(struct pci_dev *pdev)
flush_scheduled_work();
netdev = mgp->dev;
unregister_netdev(netdev);
- free_irq(pdev->irq, mgp);
- if (mgp->msi_enabled)
- pci_disable_msi(pdev);
myri10ge_dummy_rdma(mgp, 0);
+ /* avoid a memory leak */
+ pci_restore_state(pdev);
+
bytes = myri10ge_max_intr_slots * sizeof(*mgp->rx_done.entry);
dma_free_coherent(&pdev->dev, bytes,
mgp->rx_done.entry, mgp->rx_done.bus);
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index b5410bee5f21..6490acf05305 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -63,7 +63,7 @@
#include "netxen_nic_hw.h"
-#define NETXEN_NIC_BUILD_NO "1"
+#define NETXEN_NIC_BUILD_NO "4"
#define _NETXEN_NIC_LINUX_MAJOR 3
#define _NETXEN_NIC_LINUX_MINOR 3
#define _NETXEN_NIC_LINUX_SUBVERSION 2
@@ -137,7 +137,7 @@ extern struct workqueue_struct *netxen_workq;
#define THIRD_PAGE_GROUP_SIZE THIRD_PAGE_GROUP_END - THIRD_PAGE_GROUP_START
#define MAX_RX_BUFFER_LENGTH 1760
-#define MAX_RX_JUMBO_BUFFER_LENGTH 9046
+#define MAX_RX_JUMBO_BUFFER_LENGTH 8062
#define MAX_RX_LRO_BUFFER_LENGTH ((48*1024)-512)
#define RX_DMA_MAP_LEN (MAX_RX_BUFFER_LENGTH - 2)
#define RX_JUMBO_DMA_MAP_LEN \
@@ -199,9 +199,9 @@ enum {
(RCV_DESC_NORMAL)))
#define MAX_CMD_DESCRIPTORS 1024
-#define MAX_RCV_DESCRIPTORS 32768
-#define MAX_JUMBO_RCV_DESCRIPTORS 4096
-#define MAX_LRO_RCV_DESCRIPTORS 2048
+#define MAX_RCV_DESCRIPTORS 16384
+#define MAX_JUMBO_RCV_DESCRIPTORS 1024
+#define MAX_LRO_RCV_DESCRIPTORS 64
#define MAX_RCVSTATUS_DESCRIPTORS MAX_RCV_DESCRIPTORS
#define MAX_JUMBO_RCV_DESC MAX_JUMBO_RCV_DESCRIPTORS
#define MAX_RCV_DESC MAX_RCV_DESCRIPTORS
@@ -852,8 +852,6 @@ struct netxen_adapter {
spinlock_t tx_lock;
spinlock_t lock;
struct work_struct watchdog_task;
- struct work_struct tx_timeout_task;
- struct net_device *netdev;
struct timer_list watchdog_timer;
u32 curr_window;
@@ -887,7 +885,6 @@ struct netxen_adapter {
struct netxen_recv_context recv_ctx[MAX_RCV_CTX];
int is_up;
- int number;
struct netxen_dummy_dma dummy_dma;
/* Context interface shared between card and host */
@@ -950,6 +947,7 @@ struct netxen_port {
struct pci_dev *pdev;
struct net_device_stats net_stats;
struct netxen_port_stats stats;
+ struct work_struct tx_timeout_task;
};
#define PCI_OFFSET_FIRST_RANGE(adapter, off) \
@@ -1027,14 +1025,6 @@ int netxen_nic_hw_read_wx(struct netxen_adapter *adapter, u64 off, void *data,
int len);
int netxen_nic_hw_write_wx(struct netxen_adapter *adapter, u64 off, void *data,
int len);
-int netxen_nic_hw_read_ioctl(struct netxen_adapter *adapter, u64 off,
- void *data, int len);
-int netxen_nic_hw_write_ioctl(struct netxen_adapter *adapter, u64 off,
- void *data, int len);
-int netxen_nic_pci_mem_write_ioctl(struct netxen_adapter *adapter,
- u64 off, void *data, int size);
-int netxen_nic_pci_mem_read_ioctl(struct netxen_adapter *adapter,
- u64 off, void *data, int size);
void netxen_crb_writelit_adapter(struct netxen_adapter *adapter,
unsigned long off, int data);
@@ -1067,9 +1057,6 @@ void netxen_tso_check(struct netxen_adapter *adapter,
struct cmd_desc_type0 *desc, struct sk_buff *skb);
int netxen_nic_hw_resources(struct netxen_adapter *adapter);
void netxen_nic_clear_stats(struct netxen_adapter *adapter);
-int
-netxen_nic_do_ioctl(struct netxen_adapter *adapter, void *u_data,
- struct netxen_port *port);
int netxen_nic_rx_has_work(struct netxen_adapter *adapter);
int netxen_nic_tx_has_work(struct netxen_adapter *adapter);
void netxen_watchdog_task(struct work_struct *work);
diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c
index 2ab4885cc950..34044616b3c8 100644
--- a/drivers/net/netxen/netxen_nic_ethtool.c
+++ b/drivers/net/netxen/netxen_nic_ethtool.c
@@ -42,7 +42,6 @@
#include "netxen_nic_hw.h"
#include "netxen_nic.h"
#include "netxen_nic_phan_reg.h"
-#include "netxen_nic_ioctl.h"
struct netxen_nic_stats {
char stat_string[ETH_GSTRING_LEN];
@@ -79,8 +78,7 @@ static const struct netxen_nic_stats netxen_nic_gstrings_stats[] = {
{"tx_bytes", NETXEN_NIC_STAT(stats.txbytes)},
};
-#define NETXEN_NIC_STATS_LEN \
- sizeof(netxen_nic_gstrings_stats) / sizeof(struct netxen_nic_stats)
+#define NETXEN_NIC_STATS_LEN ARRAY_SIZE(netxen_nic_gstrings_stats)
static const char netxen_nic_gstrings_test[][ETH_GSTRING_LEN] = {
"Register_Test_offline", "EEPROM_Test_offline",
@@ -711,7 +709,6 @@ netxen_nic_get_ethtool_stats(struct net_device *dev,
(netxen_nic_gstrings_stats[index].sizeof_stat ==
sizeof(u64)) ? *(u64 *) p : *(u32 *) p;
}
-
}
struct ethtool_ops netxen_nic_ethtool_ops = {
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index 9147b6048dfb..c0c31d1914a7 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -376,7 +376,7 @@ void netxen_tso_check(struct netxen_adapter *adapter,
((skb->nh.iph)->ihl * sizeof(u32)) +
((skb->h.th)->doff * sizeof(u32));
netxen_set_cmd_desc_opcode(desc, TX_TCP_LSO);
- } else if (skb->ip_summed == CHECKSUM_COMPLETE) {
+ } else if (skb->ip_summed == CHECKSUM_PARTIAL) {
if (skb->nh.iph->protocol == IPPROTO_TCP) {
netxen_set_cmd_desc_opcode(desc, TX_TCP_PKT);
} else if (skb->nh.iph->protocol == IPPROTO_UDP) {
@@ -997,297 +997,3 @@ void netxen_nic_flash_print(struct netxen_adapter *adapter)
fw_major, fw_minor);
}
-int netxen_crb_read_val(struct netxen_adapter *adapter, unsigned long off)
-{
- int data;
- netxen_nic_hw_read_wx(adapter, off, &data, 4);
- return data;
-}
-
-int netxen_nic_hw_write_ioctl(struct netxen_adapter *adapter, u64 off,
- void *data, int len)
-{
- void *addr;
- u64 offset = off;
- u8 *mem_ptr = NULL;
- unsigned long mem_base;
- unsigned long mem_page;
-
- if (ADDR_IN_WINDOW1(off)) {
- addr = NETXEN_CRB_NORMALIZE(adapter, off);
- if (!addr) {
- mem_base = pci_resource_start(adapter->ahw.pdev, 0);
- offset = NETXEN_CRB_NORMAL(off);
- mem_page = offset & PAGE_MASK;
- if (mem_page != ((offset + len - 1) & PAGE_MASK))
- mem_ptr =
- ioremap(mem_base + mem_page, PAGE_SIZE * 2);
- else
- mem_ptr =
- ioremap(mem_base + mem_page, PAGE_SIZE);
- if (mem_ptr == 0UL) {
- return 1;
- }
- addr = mem_ptr;
- addr += offset & (PAGE_SIZE - 1);
- }
- } else {
- addr = pci_base_offset(adapter, off);
- if (!addr) {
- mem_base = pci_resource_start(adapter->ahw.pdev, 0);
- mem_page = off & PAGE_MASK;
- if (mem_page != ((off + len - 1) & PAGE_MASK))
- mem_ptr =
- ioremap(mem_base + mem_page, PAGE_SIZE * 2);
- else
- mem_ptr =
- ioremap(mem_base + mem_page, PAGE_SIZE);
- if (mem_ptr == 0UL) {
- return 1;
- }
- addr = mem_ptr;
- addr += off & (PAGE_SIZE - 1);
- }
- netxen_nic_pci_change_crbwindow(adapter, 0);
- }
- switch (len) {
- case 1:
- writeb(*(u8 *) data, addr);
- break;
- case 2:
- writew(*(u16 *) data, addr);
- break;
- case 4:
- writel(*(u32 *) data, addr);
- break;
- case 8:
- writeq(*(u64 *) data, addr);
- break;
- default:
- DPRINTK(INFO,
- "writing data %lx to offset %llx, num words=%d\n",
- *(unsigned long *)data, off, (len >> 3));
-
- netxen_nic_hw_block_write64((u64 __iomem *) data, addr,
- (len >> 3));
- break;
- }
-
- if (!ADDR_IN_WINDOW1(off))
- netxen_nic_pci_change_crbwindow(adapter, 1);
- if (mem_ptr)
- iounmap(mem_ptr);
- return 0;
-}
-
-int netxen_nic_hw_read_ioctl(struct netxen_adapter *adapter, u64 off,
- void *data, int len)
-{
- void *addr;
- u64 offset;
- u8 *mem_ptr = NULL;
- unsigned long mem_base;
- unsigned long mem_page;
-
- if (ADDR_IN_WINDOW1(off)) {
- addr = NETXEN_CRB_NORMALIZE(adapter, off);
- if (!addr) {
- mem_base = pci_resource_start(adapter->ahw.pdev, 0);
- offset = NETXEN_CRB_NORMAL(off);
- mem_page = offset & PAGE_MASK;
- if (mem_page != ((offset + len - 1) & PAGE_MASK))
- mem_ptr =
- ioremap(mem_base + mem_page, PAGE_SIZE * 2);
- else
- mem_ptr =
- ioremap(mem_base + mem_page, PAGE_SIZE);
- if (mem_ptr == 0UL) {
- *(u8 *) data = 0;
- return 1;
- }
- addr = mem_ptr;
- addr += offset & (PAGE_SIZE - 1);
- }
- } else {
- addr = pci_base_offset(adapter, off);
- if (!addr) {
- mem_base = pci_resource_start(adapter->ahw.pdev, 0);
- mem_page = off & PAGE_MASK;
- if (mem_page != ((off + len - 1) & PAGE_MASK))
- mem_ptr =
- ioremap(mem_base + mem_page, PAGE_SIZE * 2);
- else
- mem_ptr =
- ioremap(mem_base + mem_page, PAGE_SIZE);
- if (mem_ptr == 0UL)
- return 1;
- addr = mem_ptr;
- addr += off & (PAGE_SIZE - 1);
- }
- netxen_nic_pci_change_crbwindow(adapter, 0);
- }
- switch (len) {
- case 1:
- *(u8 *) data = readb(addr);
- break;
- case 2:
- *(u16 *) data = readw(addr);
- break;
- case 4:
- *(u32 *) data = readl(addr);
- break;
- case 8:
- *(u64 *) data = readq(addr);
- break;
- default:
- netxen_nic_hw_block_read64((u64 __iomem *) data, addr,
- (len >> 3));
- break;
- }
- if (!ADDR_IN_WINDOW1(off))
- netxen_nic_pci_change_crbwindow(adapter, 1);
- if (mem_ptr)
- iounmap(mem_ptr);
- return 0;
-}
-
-int netxen_nic_pci_mem_write_ioctl(struct netxen_adapter *adapter, u64 off,
- void *data, int size)
-{
- void *addr;
- int ret = 0;
- u8 *mem_ptr = NULL;
- unsigned long mem_base;
- unsigned long mem_page;
-
- if (data == NULL || off > (128 * 1024 * 1024)) {
- printk(KERN_ERR "%s: data: %p off:%llx\n",
- netxen_nic_driver_name, data, off);
- return 1;
- }
- off = netxen_nic_pci_set_window(adapter, off);
- /* Corner case : Malicious user tried to break the driver by reading
- last few bytes in ranges and tries to read further addresses.
- */
- if (!pci_base(adapter, off + size - 1) && pci_base(adapter, off)) {
- printk(KERN_ERR "%s: Invalid access to memory address range"
- " 0x%llx - 0x%llx\n", netxen_nic_driver_name, off,
- off + size);
- return 1;
- }
- addr = pci_base_offset(adapter, off);
- DPRINTK(INFO, "writing data %llx to offset %llx\n",
- *(unsigned long long *)data, off);
- if (!addr) {
- mem_base = pci_resource_start(adapter->ahw.pdev, 0);
- mem_page = off & PAGE_MASK;
- /* Map two pages whenever user tries to access addresses in two
- consecutive pages.
- */
- if (mem_page != ((off + size - 1) & PAGE_MASK))
- mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE * 2);
- else
- mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE);
- if (mem_ptr == 0UL) {
- return 1;
- }
- addr = mem_ptr;
- addr += off & (PAGE_SIZE - 1);
- }
- switch (size) {
- case 1:
- writeb(*(u8 *) data, addr);
- break;
- case 2:
- writew(*(u16 *) data, addr);
- break;
- case 4:
- writel(*(u32 *) data, addr);
- break;
- case 8:
- writeq(*(u64 *) data, addr);
- break;
- default:
- DPRINTK(INFO,
- "writing data %lx to offset %llx, num words=%d\n",
- *(unsigned long *)data, off, (size >> 3));
-
- netxen_nic_hw_block_write64((u64 __iomem *) data, addr,
- (size >> 3));
- break;
- }
-
- if (mem_ptr)
- iounmap(mem_ptr);
- DPRINTK(INFO, "wrote %llx\n", *(unsigned long long *)data);
-
- return ret;
-}
-
-int netxen_nic_pci_mem_read_ioctl(struct netxen_adapter *adapter,
- u64 off, void *data, int size)
-{
- void *addr;
- int ret = 0;
- u8 *mem_ptr = NULL;
- unsigned long mem_base;
- unsigned long mem_page;
-
- if (data == NULL || off > (128 * 1024 * 1024)) {
- printk(KERN_ERR "%s: data: %p off:%llx\n",
- netxen_nic_driver_name, data, off);
- return 1;
- }
- off = netxen_nic_pci_set_window(adapter, off);
- /* Corner case : Malicious user tried to break the driver by reading
- last few bytes in ranges and tries to read further addresses.
- */
- if (!pci_base(adapter, off + size - 1) && pci_base(adapter, off)) {
- printk(KERN_ERR "%s: Invalid access to memory address range"
- " 0x%llx - 0x%llx\n", netxen_nic_driver_name, off,
- off + size);
- return 1;
- }
- addr = pci_base_offset(adapter, off);
- if (!addr) {
- mem_base = pci_resource_start(adapter->ahw.pdev, 0);
- mem_page = off & PAGE_MASK;
- /* Map two pages whenever user tries to access addresses in two
- consecutive pages.
- */
- if (mem_page != ((off + size - 1) & PAGE_MASK))
- mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE * 2);
- else
- mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE);
- if (mem_ptr == 0UL) {
- *(u8 *) data = 0;
- return 1;
- }
- addr = mem_ptr;
- addr += off & (PAGE_SIZE - 1);
- }
- switch (size) {
- case 1:
- *(u8 *) data = readb(addr);
- break;
- case 2:
- *(u16 *) data = readw(addr);
- break;
- case 4:
- *(u32 *) data = readl(addr);
- break;
- case 8:
- *(u64 *) data = readq(addr);
- break;
- default:
- netxen_nic_hw_block_read64((u64 __iomem *) data, addr,
- (size >> 3));
- break;
- }
-
- if (mem_ptr)
- iounmap(mem_ptr);
- DPRINTK(INFO, "read %llx\n", *(unsigned long long *)data);
-
- return ret;
-}
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index 869725f0bb18..c3e41f368554 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -35,7 +35,6 @@
#include <linux/delay.h>
#include "netxen_nic.h"
#include "netxen_nic_hw.h"
-#include "netxen_nic_ioctl.h"
#include "netxen_nic_phan_reg.h"
struct crb_addr_pair {
@@ -928,7 +927,7 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max)
}
netxen_process_rcv(adapter, ctxid, desc);
netxen_clear_sts_owner(desc);
- netxen_set_sts_owner(desc, STATUS_OWNER_PHANTOM);
+ netxen_set_sts_owner(desc, cpu_to_le16(STATUS_OWNER_PHANTOM));
consumer = (consumer + 1) & (adapter->max_rx_desc_count - 1);
count++;
}
@@ -1023,7 +1022,7 @@ int netxen_process_cmd_ring(unsigned long data)
&& netif_carrier_ok(port->netdev))
&& ((jiffies - port->netdev->trans_start) >
port->netdev->watchdog_timeo)) {
- SCHEDULE_WORK(&port->adapter->tx_timeout_task);
+ SCHEDULE_WORK(&port->tx_timeout_task);
}
last_consumer = get_next_index(last_consumer,
@@ -1138,13 +1137,13 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid)
*/
dma = pci_map_single(pdev, skb->data, rcv_desc->dma_size,
PCI_DMA_FROMDEVICE);
- pdesc->addr_buffer = dma;
+ pdesc->addr_buffer = cpu_to_le64(dma);
buffer->skb = skb;
buffer->state = NETXEN_BUFFER_BUSY;
buffer->dma = dma;
/* make a rcv descriptor */
- pdesc->reference_handle = buffer->ref_handle;
- pdesc->buffer_length = rcv_desc->dma_size;
+ pdesc->reference_handle = cpu_to_le16(buffer->ref_handle);
+ pdesc->buffer_length = cpu_to_le32(rcv_desc->dma_size);
DPRINTK(INFO, "done writing descripter\n");
producer =
get_next_index(producer, rcv_desc->max_rx_desc_count);
@@ -1232,8 +1231,8 @@ void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, uint32_t ctx,
PCI_DMA_FROMDEVICE);
/* make a rcv descriptor */
- pdesc->reference_handle = le16_to_cpu(buffer->ref_handle);
- pdesc->buffer_length = le16_to_cpu(rcv_desc->dma_size);
+ pdesc->reference_handle = cpu_to_le16(buffer->ref_handle);
+ pdesc->buffer_length = cpu_to_le16(rcv_desc->dma_size);
pdesc->addr_buffer = cpu_to_le64(buffer->dma);
DPRINTK(INFO, "done writing descripter\n");
producer =
@@ -1273,52 +1272,6 @@ int netxen_nic_tx_has_work(struct netxen_adapter *adapter)
return 0;
}
-int
-netxen_nic_fill_statistics(struct netxen_adapter *adapter,
- struct netxen_port *port,
- struct netxen_statistics *netxen_stats)
-{
- void __iomem *addr;
-
- if (adapter->ahw.board_type == NETXEN_NIC_XGBE) {
- netxen_nic_pci_change_crbwindow(adapter, 0);
- NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_TX_BYTE_CNT,
- &(netxen_stats->tx_bytes));
- NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_TX_FRAME_CNT,
- &(netxen_stats->tx_packets));
- NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_RX_BYTE_CNT,
- &(netxen_stats->rx_bytes));
- NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_RX_FRAME_CNT,
- &(netxen_stats->rx_packets));
- NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_AGGR_ERROR_CNT,
- &(netxen_stats->rx_errors));
- NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_CRC_ERROR_CNT,
- &(netxen_stats->rx_crc_errors));
- NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_OVERSIZE_FRAME_ERR,
- &(netxen_stats->
- rx_long_length_error));
- NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_UNDERSIZE_FRAME_ERR,
- &(netxen_stats->
- rx_short_length_error));
-
- netxen_nic_pci_change_crbwindow(adapter, 1);
- } else {
- spin_lock_bh(&adapter->tx_lock);
- netxen_stats->tx_bytes = port->stats.txbytes;
- netxen_stats->tx_packets = port->stats.xmitedframes +
- port->stats.xmitfinished;
- netxen_stats->rx_bytes = port->stats.rxbytes;
- netxen_stats->rx_packets = port->stats.no_rcv;
- netxen_stats->rx_errors = port->stats.rcvdbadskb;
- netxen_stats->tx_errors = port->stats.nocmddescriptor;
- netxen_stats->rx_short_length_error = port->stats.uplcong;
- netxen_stats->rx_long_length_error = port->stats.uphcong;
- netxen_stats->rx_crc_errors = 0;
- netxen_stats->rx_mac_errors = 0;
- spin_unlock_bh(&adapter->tx_lock);
- }
- return 0;
-}
void netxen_nic_clear_stats(struct netxen_adapter *adapter)
{
@@ -1332,193 +1285,3 @@ void netxen_nic_clear_stats(struct netxen_adapter *adapter)
}
}
-int
-netxen_nic_clear_statistics(struct netxen_adapter *adapter,
- struct netxen_port *port)
-{
- int data = 0;
-
- netxen_nic_pci_change_crbwindow(adapter, 0);
-
- netxen_nic_locked_write_reg(adapter, NETXEN_NIU_XGE_TX_BYTE_CNT, &data);
- netxen_nic_locked_write_reg(adapter, NETXEN_NIU_XGE_TX_FRAME_CNT,
- &data);
- netxen_nic_locked_write_reg(adapter, NETXEN_NIU_XGE_RX_BYTE_CNT, &data);
- netxen_nic_locked_write_reg(adapter, NETXEN_NIU_XGE_RX_FRAME_CNT,
- &data);
- netxen_nic_locked_write_reg(adapter, NETXEN_NIU_XGE_AGGR_ERROR_CNT,
- &data);
- netxen_nic_locked_write_reg(adapter, NETXEN_NIU_XGE_CRC_ERROR_CNT,
- &data);
- netxen_nic_locked_write_reg(adapter, NETXEN_NIU_XGE_OVERSIZE_FRAME_ERR,
- &data);
- netxen_nic_locked_write_reg(adapter, NETXEN_NIU_XGE_UNDERSIZE_FRAME_ERR,
- &data);
-
- netxen_nic_pci_change_crbwindow(adapter, 1);
- netxen_nic_clear_stats(adapter);
- return 0;
-}
-
-int
-netxen_nic_do_ioctl(struct netxen_adapter *adapter, void *u_data,
- struct netxen_port *port)
-{
- struct netxen_nic_ioctl_data data;
- struct netxen_nic_ioctl_data *up_data;
- int retval = 0;
- struct netxen_statistics netxen_stats;
-
- up_data = (void *)u_data;
-
- DPRINTK(INFO, "doing ioctl for %p\n", adapter);
- if (copy_from_user(&data, (void __user *)up_data, sizeof(data))) {
- /* evil user tried to crash the kernel */
- DPRINTK(ERR, "bad copy from userland: %d\n", (int)sizeof(data));
- retval = -EFAULT;
- goto error_out;
- }
-
- /* Shouldn't access beyond legal limits of "char u[64];" member */
- if (!data.ptr && (data.size > sizeof(data.u))) {
- /* evil user tried to crash the kernel */
- DPRINTK(ERR, "bad size: %d\n", data.size);
- retval = -EFAULT;
- goto error_out;
- }
-
- switch (data.cmd) {
- case netxen_nic_cmd_pci_read:
- if ((retval = netxen_nic_hw_read_ioctl(adapter, data.off,
- &(data.u), data.size)))
- goto error_out;
- if (copy_to_user
- ((void __user *)&(up_data->u), &(data.u), data.size)) {
- DPRINTK(ERR, "bad copy to userland: %d\n",
- (int)sizeof(data));
- retval = -EFAULT;
- goto error_out;
- }
- data.rv = 0;
- break;
-
- case netxen_nic_cmd_pci_write:
- if ((retval = netxen_nic_hw_write_ioctl(adapter, data.off,
- &(data.u), data.size)))
- goto error_out;
- data.rv = 0;
- break;
-
- case netxen_nic_cmd_pci_mem_read:
- if (netxen_nic_pci_mem_read_ioctl(adapter, data.off, &(data.u),
- data.size)) {
- DPRINTK(ERR, "Failed to read the data.\n");
- retval = -EFAULT;
- goto error_out;
- }
- if (copy_to_user
- ((void __user *)&(up_data->u), &(data.u), data.size)) {
- DPRINTK(ERR, "bad copy to userland: %d\n",
- (int)sizeof(data));
- retval = -EFAULT;
- goto error_out;
- }
- data.rv = 0;
- break;
-
- case netxen_nic_cmd_pci_mem_write:
- if ((retval = netxen_nic_pci_mem_write_ioctl(adapter, data.off,
- &(data.u),
- data.size)))
- goto error_out;
- data.rv = 0;
- break;
-
- case netxen_nic_cmd_pci_config_read:
- switch (data.size) {
- case 1:
- data.rv = pci_read_config_byte(adapter->ahw.pdev,
- data.off,
- (char *)&(data.u));
- break;
- case 2:
- data.rv = pci_read_config_word(adapter->ahw.pdev,
- data.off,
- (short *)&(data.u));
- break;
- case 4:
- data.rv = pci_read_config_dword(adapter->ahw.pdev,
- data.off,
- (u32 *) & (data.u));
- break;
- }
- if (copy_to_user
- ((void __user *)&(up_data->u), &(data.u), data.size)) {
- DPRINTK(ERR, "bad copy to userland: %d\n",
- (int)sizeof(data));
- retval = -EFAULT;
- goto error_out;
- }
- break;
-
- case netxen_nic_cmd_pci_config_write:
- switch (data.size) {
- case 1:
- data.rv = pci_write_config_byte(adapter->ahw.pdev,
- data.off,
- *(char *)&(data.u));
- break;
- case 2:
- data.rv = pci_write_config_word(adapter->ahw.pdev,
- data.off,
- *(short *)&(data.u));
- break;
- case 4:
- data.rv = pci_write_config_dword(adapter->ahw.pdev,
- data.off,
- *(u32 *) & (data.u));
- break;
- }
- break;
-
- case netxen_nic_cmd_get_stats:
- data.rv =
- netxen_nic_fill_statistics(adapter, port, &netxen_stats);
- if (copy_to_user
- ((void __user *)(up_data->ptr), (void *)&netxen_stats,
- sizeof(struct netxen_statistics))) {
- DPRINTK(ERR, "bad copy to userland: %d\n",
- (int)sizeof(netxen_stats));
- retval = -EFAULT;
- goto error_out;
- }
- up_data->rv = data.rv;
- break;
-
- case netxen_nic_cmd_clear_stats:
- data.rv = netxen_nic_clear_statistics(adapter, port);
- up_data->rv = data.rv;
- break;
-
- case netxen_nic_cmd_get_version:
- if (copy_to_user
- ((void __user *)&(up_data->u), NETXEN_NIC_LINUX_VERSIONID,
- sizeof(NETXEN_NIC_LINUX_VERSIONID))) {
- DPRINTK(ERR, "bad copy to userland: %d\n",
- (int)sizeof(data));
- retval = -EFAULT;
- goto error_out;
- }
- break;
-
- default:
- DPRINTK(INFO, "bad command %d for %p\n", data.cmd, adapter);
- retval = -EOPNOTSUPP;
- goto error_out;
- }
- put_user(data.rv, (&(up_data->rv)));
- DPRINTK(INFO, "done ioctl for %p well.\n", adapter);
-
- error_out:
- return retval;
-}
diff --git a/drivers/net/netxen/netxen_nic_ioctl.h b/drivers/net/netxen/netxen_nic_ioctl.h
deleted file mode 100644
index 1221fa527552..000000000000
--- a/drivers/net/netxen/netxen_nic_ioctl.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2003 - 2006 NetXen, Inc.
- * 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.
- *
- * The full GNU General Public License is included in this distribution
- * in the file called LICENSE.
- *
- * Contact Information:
- * info@netxen.com
- * NetXen,
- * 3965 Freedom Circle, Fourth floor,
- * Santa Clara, CA 95054
- */
-
-#ifndef __NETXEN_NIC_IOCTL_H__
-#define __NETXEN_NIC_IOCTL_H__
-
-#include <linux/sockios.h>
-
-#define NETXEN_CMD_START SIOCDEVPRIVATE
-#define NETXEN_NIC_CMD (NETXEN_CMD_START + 1)
-#define NETXEN_NIC_NAME (NETXEN_CMD_START + 2)
-#define NETXEN_NIC_NAME_LEN 16
-#define NETXEN_NIC_NAME_RSP "NETXEN-UNM"
-
-typedef enum {
- netxen_nic_cmd_none = 0,
- netxen_nic_cmd_pci_read,
- netxen_nic_cmd_pci_write,
- netxen_nic_cmd_pci_mem_read,
- netxen_nic_cmd_pci_mem_write,
- netxen_nic_cmd_pci_config_read,
- netxen_nic_cmd_pci_config_write,
- netxen_nic_cmd_get_stats,
- netxen_nic_cmd_clear_stats,
- netxen_nic_cmd_get_version
-} netxen_nic_ioctl_cmd_t;
-
-struct netxen_nic_ioctl_data {
- u32 cmd;
- u32 unused1;
- u64 off;
- u32 size;
- u32 rv;
- char u[64];
- void *ptr;
-};
-
-struct netxen_statistics {
- u64 rx_packets;
- u64 tx_packets;
- u64 rx_bytes;
- u64 rx_errors;
- u64 tx_bytes;
- u64 tx_errors;
- u64 rx_crc_errors;
- u64 rx_short_length_error;
- u64 rx_long_length_error;
- u64 rx_mac_errors;
-};
-
-#endif /* __NETXEN_NIC_IOCTL_H_ */
diff --git a/drivers/net/netxen/netxen_nic_isr.c b/drivers/net/netxen/netxen_nic_isr.c
index 1b45f50fa6aa..06847d4252c3 100644
--- a/drivers/net/netxen/netxen_nic_isr.c
+++ b/drivers/net/netxen/netxen_nic_isr.c
@@ -157,7 +157,8 @@ void netxen_nic_isr_other(struct netxen_adapter *adapter)
for (portno = 0; portno < NETXEN_NIU_MAX_GBE_PORTS; portno++) {
linkup = val & 1;
if (linkup != (qg_linksup & 1)) {
- printk(KERN_INFO "%s: PORT %d link %s\n",
+ printk(KERN_INFO "%s: %s PORT %d link %s\n",
+ adapter->port[portno]->netdev->name,
netxen_nic_driver_name, portno,
((linkup == 0) ? "down" : "up"));
netxen_indicate_link_status(adapter, portno, linkup);
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 575b71b67202..8a5792fea774 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -38,7 +38,6 @@
#include "netxen_nic.h"
#define DEFINE_GLOBAL_RECV_CRB
#include "netxen_nic_phan_reg.h"
-#include "netxen_nic_ioctl.h"
#include <linux/dma-mapping.h>
#include <linux/vmalloc.h>
@@ -53,8 +52,6 @@ char netxen_nic_driver_name[] = "netxen-nic";
static char netxen_nic_driver_string[] = "NetXen Network Driver version "
NETXEN_NIC_LINUX_VERSIONID;
-struct netxen_adapter *g_adapter = NULL;
-
#define NETXEN_NETDEV_WEIGHT 120
#define NETXEN_ADAPTER_UP_MAGIC 777
#define NETXEN_NIC_PEG_TUNE 0
@@ -75,8 +72,6 @@ static void netxen_tx_timeout(struct net_device *netdev);
static void netxen_tx_timeout_task(struct work_struct *work);
static void netxen_watchdog(unsigned long);
static int netxen_handle_int(struct netxen_adapter *, struct net_device *);
-static int netxen_nic_ioctl(struct net_device *netdev,
- struct ifreq *ifr, int cmd);
static int netxen_nic_poll(struct net_device *dev, int *budget);
#ifdef CONFIG_NET_POLL_CONTROLLER
static void netxen_nic_poll_controller(struct net_device *netdev);
@@ -90,6 +85,8 @@ static struct pci_device_id netxen_pci_tbl[] __devinitdata = {
{PCI_DEVICE(0x4040, 0x0003)},
{PCI_DEVICE(0x4040, 0x0004)},
{PCI_DEVICE(0x4040, 0x0005)},
+ {PCI_DEVICE(0x4040, 0x0024)},
+ {PCI_DEVICE(0x4040, 0x0025)},
{0,}
};
@@ -129,7 +126,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
struct netxen_cmd_buffer *cmd_buf_arr = NULL;
u64 mac_addr[FLASH_NUM_PORTS + 1];
int valid_mac = 0;
- static int netxen_cards_found = 0;
printk(KERN_INFO "%s \n", netxen_nic_driver_string);
/* In current scheme, we use only PCI function 0 */
@@ -220,9 +216,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_out_dbunmap;
}
- if (netxen_cards_found == 0) {
- g_adapter = adapter;
- }
adapter->max_tx_desc_count = MAX_CMD_DESCRIPTORS;
adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS;
adapter->max_jumbo_rx_desc_count = MAX_JUMBO_RCV_DESCRIPTORS;
@@ -383,7 +376,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
netdev->set_multicast_list = netxen_nic_set_multi;
netdev->set_mac_address = netxen_nic_set_mac;
netdev->change_mtu = netxen_nic_change_mtu;
- netdev->do_ioctl = netxen_nic_ioctl;
netdev->tx_timeout = netxen_tx_timeout;
netdev->watchdog_timeo = HZ;
@@ -428,8 +420,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
netdev->dev_addr);
}
}
- adapter->netdev = netdev;
- INIT_WORK(&adapter->tx_timeout_task, netxen_tx_timeout_task);
+ INIT_WORK(&port->tx_timeout_task, netxen_tx_timeout_task);
netif_carrier_off(netdev);
netif_stop_queue(netdev);
@@ -444,6 +435,11 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
adapter->port[i] = port;
}
+ writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE));
+ netxen_pinit_from_rom(adapter, 0);
+ udelay(500);
+ netxen_load_firmware(adapter);
+ netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
/*
* delay a while to ensure that the Pegs are up & running.
* Otherwise, we might see some flaky behaviour.
@@ -461,7 +457,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
break;
}
- adapter->number = netxen_cards_found;
adapter->driver_mismatch = 0;
return 0;
@@ -531,6 +526,8 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
netxen_nic_stop_all_ports(adapter);
/* leave the hw in the same state as reboot */
+ netxen_pinit_from_rom(adapter, 0);
+ writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE));
netxen_load_firmware(adapter);
netxen_free_adapter_offload(adapter);
@@ -821,8 +818,8 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
/* Take skb->data itself */
pbuf = &adapter->cmd_buf_arr[producer];
if ((netdev->features & NETIF_F_TSO) && skb_shinfo(skb)->gso_size > 0) {
- pbuf->mss = skb_shinfo(skb)->gso_size;
- hwdesc->mss = skb_shinfo(skb)->gso_size;
+ pbuf->mss = cpu_to_le16(skb_shinfo(skb)->gso_size);
+ hwdesc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size);
} else {
pbuf->mss = 0;
hwdesc->mss = 0;
@@ -956,11 +953,6 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
static void netxen_watchdog(unsigned long v)
{
struct netxen_adapter *adapter = (struct netxen_adapter *)v;
- if (adapter != g_adapter) {
- printk("%s: ***BUG*** adapter[%p] != g_adapter[%p]\n",
- __FUNCTION__, adapter, g_adapter);
- return;
- }
SCHEDULE_WORK(&adapter->watchdog_task);
}
@@ -969,23 +961,23 @@ static void netxen_tx_timeout(struct net_device *netdev)
{
struct netxen_port *port = (struct netxen_port *)netdev_priv(netdev);
- SCHEDULE_WORK(&port->adapter->tx_timeout_task);
+ SCHEDULE_WORK(&port->tx_timeout_task);
}
static void netxen_tx_timeout_task(struct work_struct *work)
{
- struct netxen_adapter *adapter =
- container_of(work, struct netxen_adapter, tx_timeout_task);
- struct net_device *netdev = adapter->netdev;
+ struct netxen_port *port =
+ container_of(work, struct netxen_port, tx_timeout_task);
+ struct net_device *netdev = port->netdev;
unsigned long flags;
printk(KERN_ERR "%s %s: transmit timeout, resetting.\n",
netxen_nic_driver_name, netdev->name);
- spin_lock_irqsave(&adapter->lock, flags);
+ spin_lock_irqsave(&port->adapter->lock, flags);
netxen_nic_close(netdev);
netxen_nic_open(netdev);
- spin_unlock_irqrestore(&adapter->lock, flags);
+ spin_unlock_irqrestore(&port->adapter->lock, flags);
netdev->trans_start = jiffies;
netif_wake_queue(netdev);
}
@@ -1137,47 +1129,6 @@ static void netxen_nic_poll_controller(struct net_device *netdev)
enable_irq(adapter->irq);
}
#endif
-/*
- * netxen_nic_ioctl () We provide the tcl/phanmon support through these
- * ioctls.
- */
-static int
-netxen_nic_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
-{
- int err = 0;
- unsigned long nr_bytes = 0;
- struct netxen_port *port = netdev_priv(netdev);
- struct netxen_adapter *adapter = port->adapter;
- char dev_name[NETXEN_NIC_NAME_LEN];
-
- DPRINTK(INFO, "doing ioctl for %s\n", netdev->name);
- switch (cmd) {
- case NETXEN_NIC_CMD:
- err = netxen_nic_do_ioctl(adapter, (void *)ifr->ifr_data, port);
- break;
-
- case NETXEN_NIC_NAME:
- DPRINTK(INFO, "ioctl cmd for NetXen\n");
- if (ifr->ifr_data) {
- sprintf(dev_name, "%s-%d", NETXEN_NIC_NAME_RSP,
- port->portnum);
- nr_bytes =
- copy_to_user((char __user *)ifr->ifr_data, dev_name,
- NETXEN_NIC_NAME_LEN);
- if (nr_bytes)
- err = -EIO;
-
- }
- break;
-
- default:
- DPRINTK(INFO, "ioctl cmd %x not supported\n", cmd);
- err = -EOPNOTSUPP;
- break;
- }
-
- return err;
-}
static struct pci_driver netxen_driver = {
.name = netxen_nic_driver_name,
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index b01fc70a57db..a4d7529ef415 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -50,7 +50,7 @@ struct phy_device* phy_device_create(struct mii_bus *bus, int addr, int phy_id)
struct phy_device *dev;
/* We allocate the device, and initialize the
* default values */
- dev = kcalloc(1, sizeof(*dev), GFP_KERNEL);
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (NULL == dev)
return (struct phy_device*) PTR_ERR((void*)-ENOMEM);
diff --git a/drivers/net/ppp_deflate.c b/drivers/net/ppp_deflate.c
index f54c55242f4a..72c8d6628f58 100644
--- a/drivers/net/ppp_deflate.c
+++ b/drivers/net/ppp_deflate.c
@@ -121,7 +121,7 @@ static void *z_comp_alloc(unsigned char *options, int opt_len)
if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE)
return NULL;
- state = (struct ppp_deflate_state *) kmalloc(sizeof(*state),
+ state = kmalloc(sizeof(*state),
GFP_KERNEL);
if (state == NULL)
return NULL;
@@ -341,7 +341,7 @@ static void *z_decomp_alloc(unsigned char *options, int opt_len)
if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE)
return NULL;
- state = (struct ppp_deflate_state *) kmalloc(sizeof(*state), GFP_KERNEL);
+ state = kmalloc(sizeof(*state), GFP_KERNEL);
if (state == NULL)
return NULL;
diff --git a/drivers/net/ppp_mppe.c b/drivers/net/ppp_mppe.c
index f3655fd772f5..d5bdd2574659 100644
--- a/drivers/net/ppp_mppe.c
+++ b/drivers/net/ppp_mppe.c
@@ -200,7 +200,7 @@ static void *mppe_alloc(unsigned char *options, int optlen)
|| options[0] != CI_MPPE || options[1] != CILEN_MPPE)
goto out;
- state = (struct ppp_mppe_state *) kmalloc(sizeof(*state), GFP_KERNEL);
+ state = kmalloc(sizeof(*state), GFP_KERNEL);
if (state == NULL)
goto out;
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index f83b41d4cb0e..577babd4c938 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -225,7 +225,6 @@ MODULE_DEVICE_TABLE(pci, rtl8169_pci_tbl);
static int rx_copybreak = 200;
static int use_dac;
-static int ignore_parity_err;
static struct {
u32 msg_enable;
} debug = { -1 };
@@ -471,8 +470,6 @@ module_param(use_dac, int, 0);
MODULE_PARM_DESC(use_dac, "Enable PCI DAC. Unsafe on 32 bit PCI slot.");
module_param_named(debug, debug.msg_enable, int, 0);
MODULE_PARM_DESC(debug, "Debug verbosity level (0=none, ..., 16=all)");
-module_param_named(ignore_parity_err, ignore_parity_err, bool, 0);
-MODULE_PARM_DESC(ignore_parity_err, "Ignore PCI parity error as target. Default: false");
MODULE_LICENSE("GPL");
MODULE_VERSION(RTL8169_VERSION);
@@ -1885,7 +1882,6 @@ static void rtl8169_hw_start(struct net_device *dev)
(tp->mac_version == RTL_GIGA_MAC_VER_02) ||
(tp->mac_version == RTL_GIGA_MAC_VER_03) ||
(tp->mac_version == RTL_GIGA_MAC_VER_04))
- RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
rtl8169_set_rx_tx_config_registers(tp);
cmd = RTL_R16(CPlusCmd);
@@ -2388,7 +2384,7 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev)
*
* Feel free to adjust to your needs.
*/
- if (ignore_parity_err)
+ if (pdev->broken_parity_status)
pci_cmd &= ~PCI_COMMAND_PARITY;
else
pci_cmd |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY;
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index b60f0451f6cd..deedfd5f8226 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -749,7 +749,7 @@ static int skge_ring_alloc(struct skge_ring *ring, void *vaddr, u32 base)
struct skge_element *e;
int i;
- ring->start = kcalloc(sizeof(*e), ring->count, GFP_KERNEL);
+ ring->start = kcalloc(ring->count, sizeof(*e), GFP_KERNEL);
if (!ring->start)
return -ENOMEM;
@@ -2920,6 +2920,7 @@ static int skge_poll(struct net_device *dev, int *budget)
struct skge_hw *hw = skge->hw;
struct skge_ring *ring = &skge->rx_ring;
struct skge_element *e;
+ unsigned long flags;
int to_do = min(dev->quota, *budget);
int work_done = 0;
@@ -2957,12 +2958,12 @@ static int skge_poll(struct net_device *dev, int *budget)
if (work_done >= to_do)
return 1; /* not done */
- spin_lock_irq(&hw->hw_lock);
+ spin_lock_irqsave(&hw->hw_lock, flags);
__netif_rx_complete(dev);
hw->intr_mask |= irqmask[skge->port];
skge_write32(hw, B0_IMSK, hw->intr_mask);
skge_read32(hw, B0_IMSK);
- spin_unlock_irq(&hw->hw_lock);
+ spin_unlock_irqrestore(&hw->hw_lock, flags);
return 0;
}
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index fb1d2c30c1bb..a6601e8d423c 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -569,8 +569,8 @@ static void sky2_phy_power(struct sky2_hw *hw, unsigned port, int onoff)
if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1)
onoff = !onoff;
+ sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
reg1 = sky2_pci_read32(hw, PCI_DEV_REG1);
-
if (onoff)
/* Turn off phy power saving */
reg1 &= ~phy_power[port];
@@ -579,6 +579,7 @@ static void sky2_phy_power(struct sky2_hw *hw, unsigned port, int onoff)
sky2_pci_write32(hw, PCI_DEV_REG1, reg1);
sky2_pci_read32(hw, PCI_DEV_REG1);
+ sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
udelay(100);
}
@@ -1511,6 +1512,13 @@ static int sky2_down(struct net_device *dev)
imask &= ~portirq_msk[port];
sky2_write32(hw, B0_IMSK, imask);
+ /*
+ * Both ports share the NAPI poll on port 0, so if necessary undo the
+ * the disable that is done in dev_close.
+ */
+ if (sky2->port == 0 && hw->ports > 1)
+ netif_poll_enable(dev);
+
sky2_gmac_reset(hw, port);
/* Stop transmitter */
@@ -3631,6 +3639,29 @@ static int sky2_resume(struct pci_dev *pdev)
out:
return err;
}
+
+/* BIOS resume runs after device (it's a bug in PM)
+ * as a temporary workaround on suspend/resume leave MSI disabled
+ */
+static int sky2_suspend_late(struct pci_dev *pdev, pm_message_t state)
+{
+ struct sky2_hw *hw = pci_get_drvdata(pdev);
+
+ free_irq(pdev->irq, hw);
+ if (hw->msi) {
+ pci_disable_msi(pdev);
+ hw->msi = 0;
+ }
+ return 0;
+}
+
+static int sky2_resume_early(struct pci_dev *pdev)
+{
+ struct sky2_hw *hw = pci_get_drvdata(pdev);
+ struct net_device *dev = hw->dev[0];
+
+ return request_irq(pdev->irq, sky2_intr, IRQF_SHARED, dev->name, hw);
+}
#endif
static struct pci_driver sky2_driver = {
@@ -3641,6 +3672,8 @@ static struct pci_driver sky2_driver = {
#ifdef CONFIG_PM
.suspend = sky2_suspend,
.resume = sky2_resume,
+ .suspend_late = sky2_suspend_late,
+ .resume_early = sky2_resume_early,
#endif
};
diff --git a/drivers/net/slip.c b/drivers/net/slip.c
index 39c2152a07f4..a0806d262fc6 100644
--- a/drivers/net/slip.c
+++ b/drivers/net/slip.c
@@ -229,10 +229,10 @@ static int sl_realloc_bufs(struct slip *sl, int mtu)
if (len < 576 * 2)
len = 576 * 2;
- xbuff = (unsigned char *) kmalloc (len + 4, GFP_ATOMIC);
- rbuff = (unsigned char *) kmalloc (len + 4, GFP_ATOMIC);
+ xbuff = kmalloc(len + 4, GFP_ATOMIC);
+ rbuff = kmalloc(len + 4, GFP_ATOMIC);
#ifdef SL_INCLUDE_CSLIP
- cbuff = (unsigned char *) kmalloc (len + 4, GFP_ATOMIC);
+ cbuff = kmalloc(len + 4, GFP_ATOMIC);
#endif
diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c
index 2c4343395a4d..880d9fdd7c67 100644
--- a/drivers/net/smc911x.c
+++ b/drivers/net/smc911x.c
@@ -148,6 +148,8 @@ struct smc911x_local {
int tx_throttle;
spinlock_t lock;
+ struct net_device *netdev;
+
#ifdef SMC_USE_DMA
/* DMA needs the physical address of the chip */
u_long physaddr;
@@ -948,10 +950,11 @@ static void smc911x_phy_check_media(struct net_device *dev, int init)
* of autonegotiation.) If the RPC ANEG bit is cleared, the selection
* is controlled by the RPC SPEED and RPC DPLX bits.
*/
-static void smc911x_phy_configure(void *data)
+static void smc911x_phy_configure(struct work_struct *work)
{
- struct net_device *dev = data;
- struct smc911x_local *lp = netdev_priv(dev);
+ struct smc911x_local *lp = container_of(work, struct smc911x_local,
+ phy_configure);
+ struct net_device *dev = lp->netdev;
unsigned long ioaddr = dev->base_addr;
int phyaddr = lp->mii.phy_id;
int my_phy_caps; /* My PHY capabilities */
@@ -1331,7 +1334,7 @@ smc911x_rx_dma_irq(int dma, void *data)
static void smc911x_poll_controller(struct net_device *dev)
{
disable_irq(dev->irq);
- smc911x_interrupt(dev->irq, dev, NULL);
+ smc911x_interrupt(dev->irq, dev);
enable_irq(dev->irq);
}
#endif
@@ -1495,6 +1498,8 @@ static void smc911x_set_multicast_list(struct net_device *dev)
static int
smc911x_open(struct net_device *dev)
{
+ struct smc911x_local *lp = netdev_priv(dev);
+
DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
/*
@@ -1511,7 +1516,7 @@ smc911x_open(struct net_device *dev)
smc911x_reset(dev);
/* Configure the PHY, initialize the link state */
- smc911x_phy_configure(dev);
+ smc911x_phy_configure(&lp->phy_configure);
/* Turn on Tx + Rx */
smc911x_enable(dev);
@@ -2060,7 +2065,7 @@ static int __init smc911x_probe(struct net_device *dev, unsigned long ioaddr)
dev->poll_controller = smc911x_poll_controller;
#endif
- INIT_WORK(&lp->phy_configure, smc911x_phy_configure, dev);
+ INIT_WORK(&lp->phy_configure, smc911x_phy_configure);
lp->mii.phy_id_mask = 0x1f;
lp->mii.reg_num_mask = 0x1f;
lp->mii.force_media = 0;
@@ -2154,6 +2159,7 @@ static int smc911x_drv_probe(struct platform_device *pdev)
{
struct net_device *ndev;
struct resource *res;
+ struct smc911x_local *lp;
unsigned int *addr;
int ret;
@@ -2183,6 +2189,8 @@ static int smc911x_drv_probe(struct platform_device *pdev)
ndev->dma = (unsigned char)-1;
ndev->irq = platform_get_irq(pdev, 0);
+ lp = netdev_priv(ndev);
+ lp->netdev = ndev;
addr = ioremap(res->start, SMC911X_IO_EXTENT);
if (!addr) {
@@ -2204,7 +2212,6 @@ out:
}
#ifdef SMC_USE_DMA
else {
- struct smc911x_local *lp = netdev_priv(ndev);
lp->physaddr = res->start;
lp->dev = &pdev->dev;
}
@@ -2275,7 +2282,7 @@ static int smc911x_drv_resume(struct platform_device *dev)
smc911x_reset(ndev);
smc911x_enable(ndev);
if (lp->phy_type != 0)
- smc911x_phy_configure(ndev);
+ smc911x_phy_configure(&lp->phy_configure);
netif_device_attach(ndev);
}
}
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 571320ae87ab..4056ba1ff3c7 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -68,8 +68,8 @@
#define DRV_MODULE_NAME "tg3"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "3.70"
-#define DRV_MODULE_RELDATE "December 1, 2006"
+#define DRV_MODULE_VERSION "3.71"
+#define DRV_MODULE_RELDATE "December 15, 2006"
#define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0
@@ -959,6 +959,13 @@ static int tg3_phy_reset(struct tg3 *tp)
u32 phy_status;
int err;
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
+ u32 val;
+
+ val = tr32(GRC_MISC_CFG);
+ tw32_f(GRC_MISC_CFG, val & ~GRC_MISC_CFG_EPHY_IDDQ);
+ udelay(40);
+ }
err = tg3_readphy(tp, MII_BMSR, &phy_status);
err |= tg3_readphy(tp, MII_BMSR, &phy_status);
if (err != 0)
@@ -1170,7 +1177,15 @@ static void tg3_power_down_phy(struct tg3 *tp)
if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)
return;
- if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906) {
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
+ u32 val;
+
+ tg3_bmcr_reset(tp);
+ val = tr32(GRC_MISC_CFG);
+ tw32_f(GRC_MISC_CFG, val | GRC_MISC_CFG_EPHY_IDDQ);
+ udelay(40);
+ return;
+ } else {
tg3_writephy(tp, MII_TG3_EXT_CTRL,
MII_TG3_EXT_CTRL_FORCE_LED_OFF);
tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x01b2);
@@ -4426,7 +4441,7 @@ static void tg3_free_consistent(struct tg3 *tp)
*/
static int tg3_alloc_consistent(struct tg3 *tp)
{
- tp->rx_std_buffers = kmalloc((sizeof(struct ring_info) *
+ tp->rx_std_buffers = kzalloc((sizeof(struct ring_info) *
(TG3_RX_RING_SIZE +
TG3_RX_JUMBO_RING_SIZE)) +
(sizeof(struct tx_ring_info) *
@@ -4435,13 +4450,6 @@ static int tg3_alloc_consistent(struct tg3 *tp)
if (!tp->rx_std_buffers)
return -ENOMEM;
- memset(tp->rx_std_buffers, 0,
- (sizeof(struct ring_info) *
- (TG3_RX_RING_SIZE +
- TG3_RX_JUMBO_RING_SIZE)) +
- (sizeof(struct tx_ring_info) *
- TG3_TX_RING_SIZE));
-
tp->rx_jumbo_buffers = &tp->rx_std_buffers[TG3_RX_RING_SIZE];
tp->tx_buffers = (struct tx_ring_info *)
&tp->rx_jumbo_buffers[TG3_RX_JUMBO_RING_SIZE];
@@ -6988,6 +6996,8 @@ static int tg3_open(struct net_device *dev)
struct tg3 *tp = netdev_priv(dev);
int err;
+ netif_carrier_off(tp->dev);
+
tg3_full_lock(tp, 0);
err = tg3_set_power_state(tp, PCI_D0);
@@ -7981,6 +7991,10 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
tp->link_config.duplex = cmd->duplex;
}
+ tp->link_config.orig_speed = tp->link_config.speed;
+ tp->link_config.orig_duplex = tp->link_config.duplex;
+ tp->link_config.orig_autoneg = tp->link_config.autoneg;
+
if (netif_running(dev))
tg3_setup_phy(tp, 1);
@@ -11923,6 +11937,8 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
*/
pci_save_state(tp->pdev);
+ pci_set_drvdata(pdev, dev);
+
err = register_netdev(dev);
if (err) {
printk(KERN_ERR PFX "Cannot register net device, "
@@ -11930,8 +11946,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
goto err_out_iounmap;
}
- pci_set_drvdata(pdev, dev);
-
printk(KERN_INFO "%s: Tigon3 [partno(%s) rev %04x PHY(%s)] (%s) %s Ethernet ",
dev->name,
tp->board_part_number,
@@ -11962,8 +11976,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
(pdev->dma_mask == DMA_32BIT_MASK) ? 32 :
(((u64) pdev->dma_mask == DMA_40BIT_MASK) ? 40 : 64));
- netif_carrier_off(tp->dev);
-
return 0;
err_out_iounmap:
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index dfaf4ed127bd..cf78a7e5997b 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -1350,6 +1350,7 @@
#define GRC_MISC_CFG_BOARD_ID_5788 0x00010000
#define GRC_MISC_CFG_BOARD_ID_5788M 0x00018000
#define GRC_MISC_CFG_BOARD_ID_AC91002A1 0x00018000
+#define GRC_MISC_CFG_EPHY_IDDQ 0x00200000
#define GRC_MISC_CFG_KEEP_GPHY_POWER 0x04000000
#define GRC_LOCAL_CTRL 0x00006808
#define GRC_LCLCTRL_INT_ACTIVE 0x00000001
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
index 4587f23f4e4b..8e5d82051bd4 100644
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@ -265,15 +265,19 @@ static int velocity_set_media_mode(struct velocity_info *vptr, u32 mii_status);
static int velocity_suspend(struct pci_dev *pdev, pm_message_t state);
static int velocity_resume(struct pci_dev *pdev);
+static DEFINE_SPINLOCK(velocity_dev_list_lock);
+static LIST_HEAD(velocity_dev_list);
+
+#endif
+
+#if defined(CONFIG_PM) && defined(CONFIG_INET)
+
static int velocity_netdev_event(struct notifier_block *nb, unsigned long notification, void *ptr);
static struct notifier_block velocity_inetaddr_notifier = {
.notifier_call = velocity_netdev_event,
};
-static DEFINE_SPINLOCK(velocity_dev_list_lock);
-static LIST_HEAD(velocity_dev_list);
-
static void velocity_register_notifier(void)
{
register_inetaddr_notifier(&velocity_inetaddr_notifier);
@@ -284,12 +288,12 @@ static void velocity_unregister_notifier(void)
unregister_inetaddr_notifier(&velocity_inetaddr_notifier);
}
-#else /* CONFIG_PM */
+#else
#define velocity_register_notifier() do {} while (0)
#define velocity_unregister_notifier() do {} while (0)
-#endif /* !CONFIG_PM */
+#endif
/*
* Internal board variants. At the moment we have only one
@@ -3292,6 +3296,8 @@ static int velocity_resume(struct pci_dev *pdev)
return 0;
}
+#ifdef CONFIG_INET
+
static int velocity_netdev_event(struct notifier_block *nb, unsigned long notification, void *ptr)
{
struct in_ifaddr *ifa = (struct in_ifaddr *) ptr;
@@ -3312,4 +3318,6 @@ static int velocity_netdev_event(struct notifier_block *nb, unsigned long notifi
}
return NOTIFY_DONE;
}
+
+#endif
#endif
diff --git a/drivers/net/wan/hostess_sv11.c b/drivers/net/wan/hostess_sv11.c
index a4f735723c41..a02c5fb40567 100644
--- a/drivers/net/wan/hostess_sv11.c
+++ b/drivers/net/wan/hostess_sv11.c
@@ -231,7 +231,7 @@ static struct sv11_device *sv11_init(int iobase, int irq)
return NULL;
}
- sv=(struct sv11_device *)kmalloc(sizeof(struct sv11_device), GFP_KERNEL);
+ sv = kmalloc(sizeof(struct sv11_device), GFP_KERNEL);
if(!sv)
goto fail3;
diff --git a/drivers/net/wan/pc300_drv.c b/drivers/net/wan/pc300_drv.c
index 36d1c3ff7078..62184dee377c 100644
--- a/drivers/net/wan/pc300_drv.c
+++ b/drivers/net/wan/pc300_drv.c
@@ -3455,7 +3455,7 @@ cpc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if ((err = pci_enable_device(pdev)) < 0)
return err;
- card = (pc300_t *) kmalloc(sizeof(pc300_t), GFP_KERNEL);
+ card = kmalloc(sizeof(pc300_t), GFP_KERNEL);
if (card == NULL) {
printk("PC300 found at RAM 0x%016llx, "
"but could not allocate card structure.\n",
diff --git a/drivers/net/wan/pc300_tty.c b/drivers/net/wan/pc300_tty.c
index b2a23aed4428..5873c346e7e9 100644
--- a/drivers/net/wan/pc300_tty.c
+++ b/drivers/net/wan/pc300_tty.c
@@ -784,7 +784,7 @@ void cpc_tty_receive(pc300dev_t *pc300dev)
continue;
}
- new = (st_cpc_rx_buf *)kmalloc(rx_len + sizeof(st_cpc_rx_buf), GFP_ATOMIC);
+ new = kmalloc(rx_len + sizeof(st_cpc_rx_buf), GFP_ATOMIC);
if (new == 0) {
cpc_tty_rx_disc_frame(pc300chan);
continue;
diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c
index 9c3ccc669143..1c9edd97accd 100644
--- a/drivers/net/wan/x25_asy.c
+++ b/drivers/net/wan/x25_asy.c
@@ -123,8 +123,8 @@ static int x25_asy_change_mtu(struct net_device *dev, int newmtu)
unsigned char *xbuff, *rbuff;
int len = 2* newmtu;
- xbuff = (unsigned char *) kmalloc (len + 4, GFP_ATOMIC);
- rbuff = (unsigned char *) kmalloc (len + 4, GFP_ATOMIC);
+ xbuff = kmalloc(len + 4, GFP_ATOMIC);
+ rbuff = kmalloc(len + 4, GFP_ATOMIC);
if (xbuff == NULL || rbuff == NULL)
{
@@ -465,11 +465,11 @@ static int x25_asy_open(struct net_device *dev)
len = dev->mtu * 2;
- sl->rbuff = (unsigned char *) kmalloc(len + 4, GFP_KERNEL);
+ sl->rbuff = kmalloc(len + 4, GFP_KERNEL);
if (sl->rbuff == NULL) {
goto norbuff;
}
- sl->xbuff = (unsigned char *) kmalloc(len + 4, GFP_KERNEL);
+ sl->xbuff = kmalloc(len + 4, GFP_KERNEL);
if (sl->xbuff == NULL) {
goto noxbuff;
}
diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c
index 974a8e5bec8b..efb8cf3bd8ad 100644
--- a/drivers/net/wireless/hostap/hostap_ap.c
+++ b/drivers/net/wireless/hostap/hostap_ap.c
@@ -1253,7 +1253,7 @@ static char * ap_auth_make_challenge(struct ap_data *ap)
return NULL;
}
- tmpbuf = (char *) kmalloc(WLAN_AUTH_CHALLENGE_LEN, GFP_ATOMIC);
+ tmpbuf = kmalloc(WLAN_AUTH_CHALLENGE_LEN, GFP_ATOMIC);
if (tmpbuf == NULL) {
PDEBUG(DEBUG_AP, "AP: kmalloc failed for challenge\n");
return NULL;
diff --git a/drivers/net/wireless/hostap/hostap_download.c b/drivers/net/wireless/hostap/hostap_download.c
index 24fc387bba67..c7678e67697d 100644
--- a/drivers/net/wireless/hostap/hostap_download.c
+++ b/drivers/net/wireless/hostap/hostap_download.c
@@ -201,7 +201,7 @@ static u8 * prism2_read_pda(struct net_device *dev)
0x7f0002 /* Intel PRO/Wireless 2011B (PCI) */,
};
- buf = (u8 *) kmalloc(PRISM2_PDA_SIZE, GFP_KERNEL);
+ buf = kmalloc(PRISM2_PDA_SIZE, GFP_KERNEL);
if (buf == NULL)
return NULL;
diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c
index a394a23b9a20..3079378fb8cd 100644
--- a/drivers/net/wireless/hostap/hostap_hw.c
+++ b/drivers/net/wireless/hostap/hostap_hw.c
@@ -2252,7 +2252,7 @@ static int hostap_tx_compl_read(local_info_t *local, int error,
if (txdesc->sw_support) {
len = le16_to_cpu(txdesc->data_len);
if (len < PRISM2_DATA_MAXLEN) {
- *payload = (char *) kmalloc(len, GFP_ATOMIC);
+ *payload = kmalloc(len, GFP_ATOMIC);
if (*payload == NULL ||
hfa384x_from_bap(dev, BAP0, *payload, len)) {
PDEBUG(DEBUG_EXTRA, "%s: could not read TX "
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c
index 3b7b8063ff1c..cb08bc5db2bd 100644
--- a/drivers/net/wireless/hostap/hostap_ioctl.c
+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
@@ -3829,7 +3829,7 @@ static int prism2_ioctl_priv_hostapd(local_info_t *local, struct iw_point *p)
p->length > PRISM2_HOSTAPD_MAX_BUF_SIZE || !p->pointer)
return -EINVAL;
- param = (struct prism2_hostapd_param *) kmalloc(p->length, GFP_KERNEL);
+ param = kmalloc(p->length, GFP_KERNEL);
if (param == NULL)
return -ENOMEM;
diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c
index 0796be9d9e77..04c19cefa1da 100644
--- a/drivers/net/wireless/hostap/hostap_main.c
+++ b/drivers/net/wireless/hostap/hostap_main.c
@@ -250,7 +250,7 @@ u16 hostap_tx_callback_register(local_info_t *local,
unsigned long flags;
struct hostap_tx_callback_info *entry;
- entry = (struct hostap_tx_callback_info *) kmalloc(sizeof(*entry),
+ entry = kmalloc(sizeof(*entry),
GFP_ATOMIC);
if (entry == NULL)
return 0;
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index dd9ba4aad7bb..0e94fbbf7a94 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -2246,7 +2246,7 @@ static int ipw2100_snapshot_alloc(struct ipw2100_priv *priv)
if (priv->snapshot[0])
return 1;
for (i = 0; i < 0x30; i++) {
- priv->snapshot[i] = (u8 *) kmalloc(0x1000, GFP_ATOMIC);
+ priv->snapshot[i] = kmalloc(0x1000, GFP_ATOMIC);
if (!priv->snapshot[i]) {
IPW_DEBUG_INFO("%s: Error allocating snapshot "
"buffer %d\n", priv->net_dev->name, i);
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
index 96606ed10076..838d510213c6 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.c
+++ b/drivers/net/wireless/prism54/isl_ioctl.c
@@ -2775,7 +2775,7 @@ prism54_hostapd(struct net_device *ndev, struct iw_point *p)
p->length > PRISM2_HOSTAPD_MAX_BUF_SIZE || !p->pointer)
return -EINVAL;
- param = (struct prism2_hostapd_param *) kmalloc(p->length, GFP_KERNEL);
+ param = kmalloc(p->length, GFP_KERNEL);
if (param == NULL)
return -ENOMEM;
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
index 233d906c08f0..5eb81638e846 100644
--- a/drivers/net/wireless/wavelan_cs.c
+++ b/drivers/net/wireless/wavelan_cs.c
@@ -603,7 +603,7 @@ static wavepoint_history *wl_new_wavepoint(unsigned short nwid, unsigned char se
if(lp->wavepoint_table.num_wavepoints==MAX_WAVEPOINTS)
return NULL;
- new_wavepoint=(wavepoint_history *) kmalloc(sizeof(wavepoint_history),GFP_ATOMIC);
+ new_wavepoint = kmalloc(sizeof(wavepoint_history),GFP_ATOMIC);
if(new_wavepoint==NULL)
return NULL;
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c
index 77e11ddad836..78ea72fb8f0c 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.c
+++ b/drivers/net/wireless/zd1211rw/zd_chip.c
@@ -101,7 +101,7 @@ int zd_ioread32v_locked(struct zd_chip *chip, u32 *values, const zd_addr_t *addr
/* Allocate a single memory block for values and addresses. */
count16 = 2*count;
- a16 = (zd_addr_t *)kmalloc(count16 * (sizeof(zd_addr_t) + sizeof(u16)),
+ a16 = kmalloc(count16 * (sizeof(zd_addr_t) + sizeof(u16)),
GFP_NOFS);
if (!a16) {
dev_dbg_f(zd_chip_dev(chip),
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index 00ca704ece35..a08524191b5d 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -41,6 +41,8 @@ static void housekeeping_disable(struct zd_mac *mac);
static void set_multicast_hash_handler(struct work_struct *work);
+static void do_rx(unsigned long mac_ptr);
+
int zd_mac_init(struct zd_mac *mac,
struct net_device *netdev,
struct usb_interface *intf)
@@ -53,6 +55,10 @@ int zd_mac_init(struct zd_mac *mac,
INIT_DELAYED_WORK(&mac->set_rts_cts_work, set_rts_cts_work);
INIT_DELAYED_WORK(&mac->set_basic_rates_work, set_basic_rates_work);
+ skb_queue_head_init(&mac->rx_queue);
+ tasklet_init(&mac->rx_tasklet, do_rx, (unsigned long)mac);
+ tasklet_disable(&mac->rx_tasklet);
+
ieee_init(ieee);
softmac_init(ieee80211_priv(netdev));
zd_chip_init(&mac->chip, netdev, intf);
@@ -140,6 +146,8 @@ out:
void zd_mac_clear(struct zd_mac *mac)
{
flush_workqueue(zd_workqueue);
+ skb_queue_purge(&mac->rx_queue);
+ tasklet_kill(&mac->rx_tasklet);
zd_chip_clear(&mac->chip);
ZD_ASSERT(!spin_is_locked(&mac->lock));
ZD_MEMCLEAR(mac, sizeof(struct zd_mac));
@@ -168,6 +176,8 @@ int zd_mac_open(struct net_device *netdev)
struct zd_chip *chip = &mac->chip;
int r;
+ tasklet_enable(&mac->rx_tasklet);
+
r = zd_chip_enable_int(chip);
if (r < 0)
goto out;
@@ -218,6 +228,8 @@ int zd_mac_stop(struct net_device *netdev)
*/
zd_chip_disable_rx(chip);
+ skb_queue_purge(&mac->rx_queue);
+ tasklet_disable(&mac->rx_tasklet);
housekeeping_disable(mac);
ieee80211softmac_stop(netdev);
@@ -470,13 +482,13 @@ static void bssinfo_change(struct net_device *netdev, u32 changes)
if (changes & IEEE80211SOFTMAC_BSSINFOCHG_RATES) {
/* Set RTS rate to highest available basic rate */
- u8 rate = ieee80211softmac_highest_supported_rate(softmac,
+ u8 hi_rate = ieee80211softmac_highest_supported_rate(softmac,
&bssinfo->supported_rates, 1);
- rate = rate_to_zd_rate(rate);
+ hi_rate = rate_to_zd_rate(hi_rate);
spin_lock_irqsave(&mac->lock, flags);
- if (rate != mac->rts_rate) {
- mac->rts_rate = rate;
+ if (hi_rate != mac->rts_rate) {
+ mac->rts_rate = hi_rate;
need_set_rts_cts = 1;
}
spin_unlock_irqrestore(&mac->lock, flags);
@@ -1072,43 +1084,75 @@ static int fill_rx_stats(struct ieee80211_rx_stats *stats,
return 0;
}
-int zd_mac_rx(struct zd_mac *mac, const u8 *buffer, unsigned int length)
+static void zd_mac_rx(struct zd_mac *mac, struct sk_buff *skb)
{
int r;
struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac);
struct ieee80211_rx_stats stats;
const struct rx_status *status;
- struct sk_buff *skb;
- if (length < ZD_PLCP_HEADER_SIZE + IEEE80211_1ADDR_LEN +
- IEEE80211_FCS_LEN + sizeof(struct rx_status))
- return -EINVAL;
+ if (skb->len < ZD_PLCP_HEADER_SIZE + IEEE80211_1ADDR_LEN +
+ IEEE80211_FCS_LEN + sizeof(struct rx_status))
+ {
+ dev_dbg_f(zd_mac_dev(mac), "Packet with length %u to small.\n",
+ skb->len);
+ goto free_skb;
+ }
- r = fill_rx_stats(&stats, &status, mac, buffer, length);
- if (r)
- return r;
+ r = fill_rx_stats(&stats, &status, mac, skb->data, skb->len);
+ if (r) {
+ /* Only packets with rx errors are included here. */
+ goto free_skb;
+ }
- length -= ZD_PLCP_HEADER_SIZE+IEEE80211_FCS_LEN+
- sizeof(struct rx_status);
- buffer += ZD_PLCP_HEADER_SIZE;
+ __skb_pull(skb, ZD_PLCP_HEADER_SIZE);
+ __skb_trim(skb, skb->len -
+ (IEEE80211_FCS_LEN + sizeof(struct rx_status)));
- update_qual_rssi(mac, buffer, length, stats.signal, stats.rssi);
+ update_qual_rssi(mac, skb->data, skb->len, stats.signal,
+ status->signal_strength);
- r = filter_rx(ieee, buffer, length, &stats);
- if (r <= 0)
- return r;
+ r = filter_rx(ieee, skb->data, skb->len, &stats);
+ if (r <= 0) {
+ if (r < 0)
+ dev_dbg_f(zd_mac_dev(mac), "Error in packet.\n");
+ goto free_skb;
+ }
- skb = dev_alloc_skb(sizeof(struct zd_rt_hdr) + length);
- if (!skb)
- return -ENOMEM;
if (ieee->iw_mode == IW_MODE_MONITOR)
- fill_rt_header(skb_put(skb, sizeof(struct zd_rt_hdr)), mac,
+ fill_rt_header(skb_push(skb, sizeof(struct zd_rt_hdr)), mac,
&stats, status);
- memcpy(skb_put(skb, length), buffer, length);
r = ieee80211_rx(ieee, skb, &stats);
- if (!r)
- dev_kfree_skb_any(skb);
+ if (r)
+ return;
+free_skb:
+ /* We are always in a soft irq. */
+ dev_kfree_skb(skb);
+}
+
+static void do_rx(unsigned long mac_ptr)
+{
+ struct zd_mac *mac = (struct zd_mac *)mac_ptr;
+ struct sk_buff *skb;
+
+ while ((skb = skb_dequeue(&mac->rx_queue)) != NULL)
+ zd_mac_rx(mac, skb);
+}
+
+int zd_mac_rx_irq(struct zd_mac *mac, const u8 *buffer, unsigned int length)
+{
+ struct sk_buff *skb;
+
+ skb = dev_alloc_skb(sizeof(struct zd_rt_hdr) + length);
+ if (!skb) {
+ dev_warn(zd_mac_dev(mac), "Could not allocate skb.\n");
+ return -ENOMEM;
+ }
+ skb_reserve(skb, sizeof(struct zd_rt_hdr));
+ memcpy(__skb_put(skb, length), buffer, length);
+ skb_queue_tail(&mac->rx_queue, skb);
+ tasklet_schedule(&mac->rx_tasklet);
return 0;
}
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.h b/drivers/net/wireless/zd1211rw/zd_mac.h
index f0cf05dc7d3e..faf4c7828d4e 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.h
+++ b/drivers/net/wireless/zd1211rw/zd_mac.h
@@ -138,6 +138,9 @@ struct zd_mac {
struct delayed_work set_rts_cts_work;
struct delayed_work set_basic_rates_work;
+ struct tasklet_struct rx_tasklet;
+ struct sk_buff_head rx_queue;
+
unsigned int stats_count;
u8 qual_buffer[ZD_MAC_STATS_BUFFER_SIZE];
u8 rssi_buffer[ZD_MAC_STATS_BUFFER_SIZE];
@@ -193,7 +196,7 @@ int zd_mac_stop(struct net_device *netdev);
int zd_mac_set_mac_address(struct net_device *dev, void *p);
void zd_mac_set_multicast_list(struct net_device *netdev);
-int zd_mac_rx(struct zd_mac *mac, const u8 *buffer, unsigned int length);
+int zd_mac_rx_irq(struct zd_mac *mac, const u8 *buffer, unsigned int length);
int zd_mac_set_regdomain(struct zd_mac *zd_mac, u8 regdomain);
u8 zd_mac_get_regdomain(struct zd_mac *zd_mac);
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index aa782e88754b..605e96e74057 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -598,13 +598,13 @@ static void handle_rx_packet(struct zd_usb *usb, const u8 *buffer,
n = l+k;
if (n > length)
return;
- zd_mac_rx(mac, buffer+l, k);
+ zd_mac_rx_irq(mac, buffer+l, k);
if (i >= 2)
return;
l = (n+3) & ~3;
}
} else {
- zd_mac_rx(mac, buffer, length);
+ zd_mac_rx_irq(mac, buffer, length);
}
}
diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c
index 12bab64a62a1..6fb3f7979f21 100644
--- a/drivers/parisc/iosapic.c
+++ b/drivers/parisc/iosapic.c
@@ -874,7 +874,7 @@ void *iosapic_register(unsigned long hpa)
return NULL;
}
- isi = (struct iosapic_info *)kzalloc(sizeof(struct iosapic_info), GFP_KERNEL);
+ isi = kzalloc(sizeof(struct iosapic_info), GFP_KERNEL);
if (!isi) {
BUG();
return NULL;
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 0b9d0db1590a..bd1faebf61a0 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -1682,7 +1682,7 @@ int __init acpiphp_glue_init(void)
*
* This function frees all data allocated in acpiphp_glue_init()
*/
-void __exit acpiphp_glue_exit(void)
+void acpiphp_glue_exit(void)
{
acpi_pci_unregister_driver(&acpi_pci_hp_driver);
}
diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c
index bd40aee10e16..7f03881a8b68 100644
--- a/drivers/pci/hotplug/acpiphp_ibm.c
+++ b/drivers/pci/hotplug/acpiphp_ibm.c
@@ -319,13 +319,12 @@ static int ibm_get_table_from_acpi(char **bufp)
if (bufp == NULL)
goto read_table_done;
- lbuf = kmalloc(size, GFP_KERNEL);
+ lbuf = kzalloc(size, GFP_KERNEL);
dbg("%s: element count: %i, ASL table size: %i, &table = 0x%p\n",
__FUNCTION__, package->package.count, size, lbuf);
if (lbuf) {
*bufp = lbuf;
- memset(lbuf, 0, size);
} else {
size = -ENOMEM;
goto read_table_done;
diff --git a/drivers/pci/hotplug/cpqphp_nvram.c b/drivers/pci/hotplug/cpqphp_nvram.c
index 298a6cfd8406..ae5e974c45a7 100644
--- a/drivers/pci/hotplug/cpqphp_nvram.c
+++ b/drivers/pci/hotplug/cpqphp_nvram.c
@@ -520,7 +520,7 @@ int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl)
return 2;
while (nummem--) {
- mem_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+ mem_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
if (!mem_node)
break;
@@ -548,7 +548,7 @@ int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl)
}
while (numpmem--) {
- p_mem_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+ p_mem_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
if (!p_mem_node)
break;
@@ -576,7 +576,7 @@ int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl)
}
while (numio--) {
- io_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+ io_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
if (!io_node)
break;
@@ -604,7 +604,7 @@ int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl)
}
while (numbus--) {
- bus_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+ bus_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
if (!bus_node)
break;
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 6d3f580f2666..25d3aadfddbf 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -1320,7 +1320,7 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
DBG_ENTER_ROUTINE
spin_lock_init(&list_lock);
- php_ctlr = (struct php_ctlr_state_s *) kmalloc(sizeof(struct php_ctlr_state_s), GFP_KERNEL);
+ php_ctlr = kmalloc(sizeof(struct php_ctlr_state_s), GFP_KERNEL);
if (!php_ctlr) { /* allocate controller state data */
err("%s: HPC controller memory allocation error!\n", __FUNCTION__);
diff --git a/drivers/pci/hotplug/rpaphp_slot.c b/drivers/pci/hotplug/rpaphp_slot.c
index b771196a654e..3009193f0058 100644
--- a/drivers/pci/hotplug/rpaphp_slot.c
+++ b/drivers/pci/hotplug/rpaphp_slot.c
@@ -47,21 +47,11 @@ static ssize_t location_read_file (struct hotplug_slot *php_slot, char *buf)
return retval;
}
-static struct hotplug_slot_attribute hotplug_slot_attr_location = {
+static struct hotplug_slot_attribute php_attr_location = {
.attr = {.name = "phy_location", .mode = S_IFREG | S_IRUGO},
.show = location_read_file,
};
-static void rpaphp_sysfs_add_attr_location (struct hotplug_slot *slot)
-{
- sysfs_create_file(&slot->kobj, &hotplug_slot_attr_location.attr);
-}
-
-static void rpaphp_sysfs_remove_attr_location (struct hotplug_slot *slot)
-{
- sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_location.attr);
-}
-
/* free up the memory used by a slot */
static void rpaphp_release_slot(struct hotplug_slot *hotplug_slot)
{
@@ -145,7 +135,7 @@ int rpaphp_deregister_slot(struct slot *slot)
list_del(&slot->rpaphp_slot_list);
/* remove "phy_location" file */
- rpaphp_sysfs_remove_attr_location(php_slot);
+ sysfs_remove_file(&php_slot->kobj, &php_attr_location.attr);
retval = pci_hp_deregister(php_slot);
if (retval)
@@ -160,36 +150,45 @@ EXPORT_SYMBOL_GPL(rpaphp_deregister_slot);
int rpaphp_register_slot(struct slot *slot)
{
+ struct hotplug_slot *php_slot = slot->hotplug_slot;
int retval;
dbg("%s registering slot:path[%s] index[%x], name[%s] pdomain[%x] type[%d]\n",
__FUNCTION__, slot->dn->full_name, slot->index, slot->name,
slot->power_domain, slot->type);
+
/* should not try to register the same slot twice */
- if (is_registered(slot)) { /* should't be here */
+ if (is_registered(slot)) {
err("rpaphp_register_slot: slot[%s] is already registered\n", slot->name);
- rpaphp_release_slot(slot->hotplug_slot);
- return -EAGAIN;
+ retval = -EAGAIN;
+ goto register_fail;
}
- retval = pci_hp_register(slot->hotplug_slot);
+
+ retval = pci_hp_register(php_slot);
if (retval) {
err("pci_hp_register failed with error %d\n", retval);
- rpaphp_release_slot(slot->hotplug_slot);
- return retval;
+ goto register_fail;
}
-
- /* create "phy_locatoin" file */
- rpaphp_sysfs_add_attr_location(slot->hotplug_slot);
- /* add slot to our internal list */
- dbg("%s adding slot[%s] to rpaphp_slot_list\n",
- __FUNCTION__, slot->name);
+ /* create "phy_location" file */
+ retval = sysfs_create_file(&php_slot->kobj, &php_attr_location.attr);
+ if (retval) {
+ err("sysfs_create_file failed with error %d\n", retval);
+ goto sysfs_fail;
+ }
+ /* add slot to our internal list */
list_add(&slot->rpaphp_slot_list, &rpaphp_slot_head);
info("Slot [%s](PCI location=%s) registered\n", slot->name,
slot->location);
num_slots++;
return 0;
+
+sysfs_fail:
+ pci_hp_deregister(php_slot);
+register_fail:
+ rpaphp_release_slot(php_slot);
+ return retval;
}
int rpaphp_get_power_status(struct slot *slot, u8 * value)
diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h
index 50757695844f..3ca6a4f574b3 100644
--- a/drivers/pci/hotplug/shpchp.h
+++ b/drivers/pci/hotplug/shpchp.h
@@ -47,11 +47,17 @@ extern int shpchp_poll_time;
extern int shpchp_debug;
extern struct workqueue_struct *shpchp_wq;
-/*#define dbg(format, arg...) do { if (shpchp_debug) printk(KERN_DEBUG "%s: " format, MY_NAME , ## arg); } while (0)*/
-#define dbg(format, arg...) do { if (shpchp_debug) printk("%s: " format, MY_NAME , ## arg); } while (0)
-#define err(format, arg...) printk(KERN_ERR "%s: " format, MY_NAME , ## arg)
-#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
-#define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)
+#define dbg(format, arg...) \
+ do { \
+ if (shpchp_debug) \
+ printk("%s: " format, MY_NAME , ## arg); \
+ } while (0)
+#define err(format, arg...) \
+ printk(KERN_ERR "%s: " format, MY_NAME , ## arg)
+#define info(format, arg...) \
+ printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
+#define warn(format, arg...) \
+ printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)
#define SLOT_NAME_SIZE 10
struct slot {
@@ -83,34 +89,27 @@ struct event_info {
struct controller {
struct mutex crit_sect; /* critical section mutex */
struct mutex cmd_lock; /* command lock */
- struct php_ctlr_state_s *hpc_ctlr_handle; /* HPC controller handle */
int num_slots; /* Number of slots on ctlr */
int slot_num_inc; /* 1 or -1 */
struct pci_dev *pci_dev;
struct list_head slot_list;
struct hpc_ops *hpc_ops;
wait_queue_head_t queue; /* sleep & wake process */
- u8 bus;
- u8 device;
- u8 function;
u8 slot_device_offset;
- u8 add_support;
u32 pcix_misc2_reg; /* for amd pogo errata */
- enum pci_bus_speed speed;
u32 first_slot; /* First physical slot number */
- u8 slot_bus; /* Bus where the slots handled by this controller sit */
u32 cap_offset;
unsigned long mmio_base;
unsigned long mmio_size;
+ void __iomem *creg;
+ struct timer_list poll_timer;
};
-
/* Define AMD SHPC ID */
#define PCI_DEVICE_ID_AMD_GOLAM_7450 0x7450
#define PCI_DEVICE_ID_AMD_POGO_7458 0x7458
/* AMD PCIX bridge registers */
-
#define PCIX_MEM_BASE_LIMIT_OFFSET 0x1C
#define PCIX_MISCII_OFFSET 0x48
#define PCIX_MISC_BRIDGE_ERRORS_OFFSET 0x80
@@ -145,8 +144,6 @@ struct controller {
#define POWERON_STATE 3
#define POWEROFF_STATE 4
-#define PCI_TO_PCI_BRIDGE_CLASS 0x00060400
-
/* Error messages */
#define INTERLOCK_OPEN 0x00000002
#define ADD_NOT_SUPPORTED 0x00000003
@@ -158,50 +155,32 @@ struct controller {
#define WRONG_BUS_FREQUENCY 0x0000000D
#define POWER_FAILURE 0x0000000E
-#define REMOVE_NOT_SUPPORTED 0x00000003
-
-#define DISABLE_CARD 1
-
-/*
- * error Messages
- */
-#define msg_initialization_err "Initialization failure, error=%d\n"
-#define msg_button_on "PCI slot #%s - powering on due to button press.\n"
-#define msg_button_off "PCI slot #%s - powering off due to button press.\n"
-#define msg_button_cancel "PCI slot #%s - action canceled due to button press.\n"
-
-/* sysfs functions for the hotplug controller info */
extern int __must_check shpchp_create_ctrl_files(struct controller *ctrl);
-
-extern int shpchp_sysfs_enable_slot(struct slot *slot);
-extern int shpchp_sysfs_disable_slot(struct slot *slot);
-
-extern u8 shpchp_handle_attention_button(u8 hp_slot, void *inst_id);
-extern u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id);
-extern u8 shpchp_handle_presence_change(u8 hp_slot, void *inst_id);
-extern u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id);
-
-/* pci functions */
-extern int shpchp_save_config(struct controller *ctrl, int busnumber, int num_ctlr_slots, int first_device_num);
-extern int shpchp_configure_device(struct slot *p_slot);
-extern int shpchp_unconfigure_device(struct slot *p_slot);
-extern void shpchp_remove_ctrl_files(struct controller *ctrl);
-extern void cleanup_slots(struct controller *ctrl);
-extern void queue_pushbutton_work(struct work_struct *work);
-
+extern void shpchp_remove_ctrl_files(struct controller *ctrl);
+extern int shpchp_sysfs_enable_slot(struct slot *slot);
+extern int shpchp_sysfs_disable_slot(struct slot *slot);
+extern u8 shpchp_handle_attention_button(u8 hp_slot, struct controller *ctrl);
+extern u8 shpchp_handle_switch_change(u8 hp_slot, struct controller *ctrl);
+extern u8 shpchp_handle_presence_change(u8 hp_slot, struct controller *ctrl);
+extern u8 shpchp_handle_power_fault(u8 hp_slot, struct controller *ctrl);
+extern int shpchp_configure_device(struct slot *p_slot);
+extern int shpchp_unconfigure_device(struct slot *p_slot);
+extern void cleanup_slots(struct controller *ctrl);
+extern void queue_pushbutton_work(struct work_struct *work);
+extern int shpc_init( struct controller *ctrl, struct pci_dev *pdev);
#ifdef CONFIG_ACPI
static inline int get_hp_params_from_firmware(struct pci_dev *dev,
- struct hotplug_params *hpp)
+ struct hotplug_params *hpp)
{
if (ACPI_FAILURE(acpi_get_hp_params_from_firmware(dev->bus, hpp)))
return -ENODEV;
return 0;
}
-#define get_hp_hw_control_from_firmware(pdev) \
- do { \
- if (DEVICE_ACPI_HANDLE(&(pdev->dev))) \
- acpi_run_oshp(DEVICE_ACPI_HANDLE(&(pdev->dev))); \
+#define get_hp_hw_control_from_firmware(pdev) \
+ do { \
+ if (DEVICE_ACPI_HANDLE(&(pdev->dev))) \
+ acpi_run_oshp(DEVICE_ACPI_HANDLE(&(pdev->dev)));\
} while (0)
#else
#define get_hp_params_from_firmware(dev, hpp) (-ENODEV)
@@ -222,108 +201,40 @@ struct ctrl_reg {
volatile u32 serr_loc;
volatile u32 serr_intr_enable;
volatile u32 slot1;
- volatile u32 slot2;
- volatile u32 slot3;
- volatile u32 slot4;
- volatile u32 slot5;
- volatile u32 slot6;
- volatile u32 slot7;
- volatile u32 slot8;
- volatile u32 slot9;
- volatile u32 slot10;
- volatile u32 slot11;
- volatile u32 slot12;
} __attribute__ ((packed));
/* offsets to the controller registers based on the above structure layout */
enum ctrl_offsets {
- BASE_OFFSET = offsetof(struct ctrl_reg, base_offset),
- SLOT_AVAIL1 = offsetof(struct ctrl_reg, slot_avail1),
- SLOT_AVAIL2 = offsetof(struct ctrl_reg, slot_avail2),
- SLOT_CONFIG = offsetof(struct ctrl_reg, slot_config),
- SEC_BUS_CONFIG = offsetof(struct ctrl_reg, sec_bus_config),
- MSI_CTRL = offsetof(struct ctrl_reg, msi_ctrl),
- PROG_INTERFACE = offsetof(struct ctrl_reg, prog_interface),
- CMD = offsetof(struct ctrl_reg, cmd),
- CMD_STATUS = offsetof(struct ctrl_reg, cmd_status),
- INTR_LOC = offsetof(struct ctrl_reg, intr_loc),
- SERR_LOC = offsetof(struct ctrl_reg, serr_loc),
- SERR_INTR_ENABLE = offsetof(struct ctrl_reg, serr_intr_enable),
- SLOT1 = offsetof(struct ctrl_reg, slot1),
- SLOT2 = offsetof(struct ctrl_reg, slot2),
- SLOT3 = offsetof(struct ctrl_reg, slot3),
- SLOT4 = offsetof(struct ctrl_reg, slot4),
- SLOT5 = offsetof(struct ctrl_reg, slot5),
- SLOT6 = offsetof(struct ctrl_reg, slot6),
- SLOT7 = offsetof(struct ctrl_reg, slot7),
- SLOT8 = offsetof(struct ctrl_reg, slot8),
- SLOT9 = offsetof(struct ctrl_reg, slot9),
- SLOT10 = offsetof(struct ctrl_reg, slot10),
- SLOT11 = offsetof(struct ctrl_reg, slot11),
- SLOT12 = offsetof(struct ctrl_reg, slot12),
-};
-typedef u8(*php_intr_callback_t) (u8 hp_slot, void *instance_id);
-struct php_ctlr_state_s {
- struct php_ctlr_state_s *pnext;
- struct pci_dev *pci_dev;
- unsigned int irq;
- unsigned long flags; /* spinlock's */
- u32 slot_device_offset;
- u32 num_slots;
- struct timer_list int_poll_timer; /* Added for poll event */
- php_intr_callback_t attention_button_callback;
- php_intr_callback_t switch_change_callback;
- php_intr_callback_t presence_change_callback;
- php_intr_callback_t power_fault_callback;
- void *callback_instance_id;
- void __iomem *creg; /* Ptr to controller register space */
+ BASE_OFFSET = offsetof(struct ctrl_reg, base_offset),
+ SLOT_AVAIL1 = offsetof(struct ctrl_reg, slot_avail1),
+ SLOT_AVAIL2 = offsetof(struct ctrl_reg, slot_avail2),
+ SLOT_CONFIG = offsetof(struct ctrl_reg, slot_config),
+ SEC_BUS_CONFIG = offsetof(struct ctrl_reg, sec_bus_config),
+ MSI_CTRL = offsetof(struct ctrl_reg, msi_ctrl),
+ PROG_INTERFACE = offsetof(struct ctrl_reg, prog_interface),
+ CMD = offsetof(struct ctrl_reg, cmd),
+ CMD_STATUS = offsetof(struct ctrl_reg, cmd_status),
+ INTR_LOC = offsetof(struct ctrl_reg, intr_loc),
+ SERR_LOC = offsetof(struct ctrl_reg, serr_loc),
+ SERR_INTR_ENABLE = offsetof(struct ctrl_reg, serr_intr_enable),
+ SLOT1 = offsetof(struct ctrl_reg, slot1),
};
-/* Inline functions */
-
-/* Inline functions to check the sanity of a pointer that is passed to us */
-static inline int slot_paranoia_check (struct slot *slot, const char *function)
-{
- if (!slot) {
- dbg("%s - slot == NULL", function);
- return -1;
- }
- if (!slot->hotplug_slot) {
- dbg("%s - slot->hotplug_slot == NULL!", function);
- return -1;
- }
- return 0;
-}
-
-static inline struct slot *get_slot (struct hotplug_slot *hotplug_slot, const char *function)
+static inline struct slot *get_slot(struct hotplug_slot *hotplug_slot)
{
- struct slot *slot;
-
- if (!hotplug_slot) {
- dbg("%s - hotplug_slot == NULL\n", function);
- return NULL;
- }
-
- slot = (struct slot *)hotplug_slot->private;
- if (slot_paranoia_check (slot, function))
- return NULL;
- return slot;
+ return hotplug_slot->private;
}
-static inline struct slot *shpchp_find_slot (struct controller *ctrl, u8 device)
+static inline struct slot *shpchp_find_slot(struct controller *ctrl, u8 device)
{
struct slot *slot;
- if (!ctrl)
- return NULL;
-
list_for_each_entry(slot, &ctrl->slot_list, slot_list) {
if (slot->device == device)
return slot;
}
err("%s: slot (device=0x%x) not found\n", __FUNCTION__, device);
-
return NULL;
}
@@ -400,44 +311,27 @@ static inline void amd_pogo_errata_restore_misc_reg(struct slot *p_slot)
pci_write_config_dword(p_slot->ctrl->pci_dev, PCIX_MISCII_OFFSET, pcix_misc2_temp);
}
-enum php_ctlr_type {
- PCI,
- ISA,
- ACPI
-};
-
-int shpc_init( struct controller *ctrl, struct pci_dev *pdev);
-
-int shpc_get_ctlr_slot_config( struct controller *ctrl,
- int *num_ctlr_slots,
- int *first_device_num,
- int *physical_slot_num,
- int *updown,
- int *flags);
-
struct hpc_ops {
- int (*power_on_slot ) (struct slot *slot);
- int (*slot_enable ) (struct slot *slot);
- int (*slot_disable ) (struct slot *slot);
- int (*set_bus_speed_mode) (struct slot *slot, enum pci_bus_speed speed);
- int (*get_power_status) (struct slot *slot, u8 *status);
- int (*get_attention_status) (struct slot *slot, u8 *status);
- int (*set_attention_status) (struct slot *slot, u8 status);
- int (*get_latch_status) (struct slot *slot, u8 *status);
- int (*get_adapter_status) (struct slot *slot, u8 *status);
-
- int (*get_max_bus_speed) (struct slot *slot, enum pci_bus_speed *speed);
- int (*get_cur_bus_speed) (struct slot *slot, enum pci_bus_speed *speed);
- int (*get_adapter_speed) (struct slot *slot, enum pci_bus_speed *speed);
- int (*get_mode1_ECC_cap) (struct slot *slot, u8 *mode);
- int (*get_prog_int) (struct slot *slot, u8 *prog_int);
-
- int (*query_power_fault) (struct slot *slot);
- void (*green_led_on) (struct slot *slot);
- void (*green_led_off) (struct slot *slot);
- void (*green_led_blink) (struct slot *slot);
- void (*release_ctlr) (struct controller *ctrl);
- int (*check_cmd_status) (struct controller *ctrl);
+ int (*power_on_slot)(struct slot *slot);
+ int (*slot_enable)(struct slot *slot);
+ int (*slot_disable)(struct slot *slot);
+ int (*set_bus_speed_mode)(struct slot *slot, enum pci_bus_speed speed);
+ int (*get_power_status)(struct slot *slot, u8 *status);
+ int (*get_attention_status)(struct slot *slot, u8 *status);
+ int (*set_attention_status)(struct slot *slot, u8 status);
+ int (*get_latch_status)(struct slot *slot, u8 *status);
+ int (*get_adapter_status)(struct slot *slot, u8 *status);
+ int (*get_max_bus_speed)(struct slot *slot, enum pci_bus_speed *speed);
+ int (*get_cur_bus_speed)(struct slot *slot, enum pci_bus_speed *speed);
+ int (*get_adapter_speed)(struct slot *slot, enum pci_bus_speed *speed);
+ int (*get_mode1_ECC_cap)(struct slot *slot, u8 *mode);
+ int (*get_prog_int)(struct slot *slot, u8 *prog_int);
+ int (*query_power_fault)(struct slot *slot);
+ void (*green_led_on)(struct slot *slot);
+ void (*green_led_off)(struct slot *slot);
+ void (*green_led_blink)(struct slot *slot);
+ void (*release_ctlr)(struct controller *ctrl);
+ int (*check_cmd_status)(struct controller *ctrl);
};
#endif /* _SHPCHP_H */
diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c
index 4eac85b3d90e..590cd3cbe010 100644
--- a/drivers/pci/hotplug/shpchp_core.c
+++ b/drivers/pci/hotplug/shpchp_core.c
@@ -104,23 +104,6 @@ static void make_slot_name(struct slot *slot)
slot->bus, slot->number);
}
-
-
-
-static int
-shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun,
- u8 busnum, u8 devnum)
-{
- int offset = devnum - ctrl->slot_device_offset;
-
- dbg("%s: ctrl->slot_num_inc %d, offset %d\n", __FUNCTION__,
- ctrl->slot_num_inc, offset);
- *sun = (u8) (ctrl->first_slot + ctrl->slot_num_inc *offset);
- return 0;
-}
-
-
-
static int init_slots(struct controller *ctrl)
{
struct slot *slot;
@@ -128,7 +111,6 @@ static int init_slots(struct controller *ctrl)
struct hotplug_slot_info *info;
int retval = -ENOMEM;
int i;
- u32 sun;
for (i = 0; i < ctrl->num_slots; i++) {
slot = kzalloc(sizeof(*slot), GFP_KERNEL);
@@ -149,16 +131,11 @@ static int init_slots(struct controller *ctrl)
slot->hp_slot = i;
slot->ctrl = ctrl;
- slot->bus = ctrl->slot_bus;
+ slot->bus = ctrl->pci_dev->subordinate->number;
slot->device = ctrl->slot_device_offset + i;
slot->hpc_ops = ctrl->hpc_ops;
+ slot->number = ctrl->first_slot + (ctrl->slot_num_inc * i);
mutex_init(&slot->lock);
-
- if (shpchprm_get_physical_slot_number(ctrl, &sun,
- slot->bus, slot->device))
- goto error_info;
-
- slot->number = sun;
INIT_DELAYED_WORK(&slot->work, queue_pushbutton_work);
/* register this slot with the hotplug pci core */
@@ -211,42 +188,12 @@ void cleanup_slots(struct controller *ctrl)
}
}
-static int get_ctlr_slot_config(struct controller *ctrl)
-{
- int num_ctlr_slots;
- int first_device_num;
- int physical_slot_num;
- int updown;
- int rc;
- int flags;
-
- rc = shpc_get_ctlr_slot_config(ctrl, &num_ctlr_slots,
- &first_device_num, &physical_slot_num,
- &updown, &flags);
- if (rc) {
- err("%s: get_ctlr_slot_config fail for b:d (%x:%x)\n",
- __FUNCTION__, ctrl->bus, ctrl->device);
- return -1;
- }
-
- ctrl->num_slots = num_ctlr_slots;
- ctrl->slot_device_offset = first_device_num;
- ctrl->first_slot = physical_slot_num;
- ctrl->slot_num_inc = updown; /* either -1 or 1 */
-
- dbg("%s: num_slot(0x%x) 1st_dev(0x%x) psn(0x%x) updown(%d) for b:d "
- "(%x:%x)\n", __FUNCTION__, num_ctlr_slots, first_device_num,
- physical_slot_num, updown, ctrl->bus, ctrl->device);
-
- return 0;
-}
-
/*
* set_attention_status - Turns the Amber LED for a slot on, off or blink
*/
static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status)
{
- struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
+ struct slot *slot = get_slot(hotplug_slot);
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
@@ -258,7 +205,7 @@ static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status)
static int enable_slot (struct hotplug_slot *hotplug_slot)
{
- struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
+ struct slot *slot = get_slot(hotplug_slot);
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
@@ -267,7 +214,7 @@ static int enable_slot (struct hotplug_slot *hotplug_slot)
static int disable_slot (struct hotplug_slot *hotplug_slot)
{
- struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
+ struct slot *slot = get_slot(hotplug_slot);
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
@@ -276,7 +223,7 @@ static int disable_slot (struct hotplug_slot *hotplug_slot)
static int get_power_status (struct hotplug_slot *hotplug_slot, u8 *value)
{
- struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
+ struct slot *slot = get_slot(hotplug_slot);
int retval;
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
@@ -290,7 +237,7 @@ static int get_power_status (struct hotplug_slot *hotplug_slot, u8 *value)
static int get_attention_status (struct hotplug_slot *hotplug_slot, u8 *value)
{
- struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
+ struct slot *slot = get_slot(hotplug_slot);
int retval;
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
@@ -304,7 +251,7 @@ static int get_attention_status (struct hotplug_slot *hotplug_slot, u8 *value)
static int get_latch_status (struct hotplug_slot *hotplug_slot, u8 *value)
{
- struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
+ struct slot *slot = get_slot(hotplug_slot);
int retval;
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
@@ -318,7 +265,7 @@ static int get_latch_status (struct hotplug_slot *hotplug_slot, u8 *value)
static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value)
{
- struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
+ struct slot *slot = get_slot(hotplug_slot);
int retval;
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
@@ -332,7 +279,7 @@ static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value)
static int get_address (struct hotplug_slot *hotplug_slot, u32 *value)
{
- struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
+ struct slot *slot = get_slot(hotplug_slot);
struct pci_bus *bus = slot->ctrl->pci_dev->subordinate;
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
@@ -344,7 +291,7 @@ static int get_address (struct hotplug_slot *hotplug_slot, u32 *value)
static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
{
- struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
+ struct slot *slot = get_slot(hotplug_slot);
int retval;
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
@@ -358,7 +305,7 @@ static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_sp
static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
{
- struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
+ struct slot *slot = get_slot(hotplug_slot);
int retval;
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
@@ -385,9 +332,6 @@ static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
int rc;
struct controller *ctrl;
- struct slot *t_slot;
- int first_device_num; /* first PCI device number */
- int num_ctlr_slots; /* number of slots implemented */
if (!is_shpc_capable(pdev))
return -ENODEV;
@@ -408,47 +352,13 @@ static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_set_drvdata(pdev, ctrl);
- ctrl->bus = pdev->bus->number;
- ctrl->slot_bus = pdev->subordinate->number;
- ctrl->device = PCI_SLOT(pdev->devfn);
- ctrl->function = PCI_FUNC(pdev->devfn);
-
- dbg("ctrl bus=0x%x, device=%x, function=%x, irq=%x\n",
- ctrl->bus, ctrl->device, ctrl->function, pdev->irq);
-
- /*
- * Save configuration headers for this and subordinate PCI buses
- */
- rc = get_ctlr_slot_config(ctrl);
- if (rc) {
- err(msg_initialization_err, rc);
- goto err_out_release_ctlr;
- }
- first_device_num = ctrl->slot_device_offset;
- num_ctlr_slots = ctrl->num_slots;
-
- ctrl->add_support = 1;
-
/* Setup the slot information structures */
rc = init_slots(ctrl);
if (rc) {
- err(msg_initialization_err, 6);
+ err("%s: slot initialization failed\n", SHPC_MODULE_NAME);
goto err_out_release_ctlr;
}
- /* Now hpc_functions (slot->hpc_ops->functions) are ready */
- t_slot = shpchp_find_slot(ctrl, first_device_num);
-
- /* Check for operation bus speed */
- rc = t_slot->hpc_ops->get_cur_bus_speed(t_slot, &ctrl->speed);
- dbg("%s: t_slot->hp_slot %x\n", __FUNCTION__,t_slot->hp_slot);
-
- if (rc || ctrl->speed == PCI_SPEED_UNKNOWN) {
- err(SHPC_MODULE_NAME ": Can't get current bus speed. "
- "Set to 33MHz PCI.\n");
- ctrl->speed = PCI_SPEED_33MHz;
- }
-
rc = shpchp_create_ctrl_files(ctrl);
if (rc)
goto err_cleanup_slots;
diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c
index 158ac7836096..6bb84734cd6c 100644
--- a/drivers/pci/hotplug/shpchp_ctrl.c
+++ b/drivers/pci/hotplug/shpchp_ctrl.c
@@ -57,9 +57,8 @@ static int queue_interrupt_event(struct slot *p_slot, u32 event_type)
return 0;
}
-u8 shpchp_handle_attention_button(u8 hp_slot, void *inst_id)
+u8 shpchp_handle_attention_button(u8 hp_slot, struct controller *ctrl)
{
- struct controller *ctrl = (struct controller *) inst_id;
struct slot *p_slot;
u32 event_type;
@@ -81,9 +80,8 @@ u8 shpchp_handle_attention_button(u8 hp_slot, void *inst_id)
}
-u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id)
+u8 shpchp_handle_switch_change(u8 hp_slot, struct controller *ctrl)
{
- struct controller *ctrl = (struct controller *) inst_id;
struct slot *p_slot;
u8 getstatus;
u32 event_type;
@@ -120,9 +118,8 @@ u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id)
return 1;
}
-u8 shpchp_handle_presence_change(u8 hp_slot, void *inst_id)
+u8 shpchp_handle_presence_change(u8 hp_slot, struct controller *ctrl)
{
- struct controller *ctrl = (struct controller *) inst_id;
struct slot *p_slot;
u32 event_type;
@@ -154,9 +151,8 @@ u8 shpchp_handle_presence_change(u8 hp_slot, void *inst_id)
return 1;
}
-u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id)
+u8 shpchp_handle_power_fault(u8 hp_slot, struct controller *ctrl)
{
- struct controller *ctrl = (struct controller *) inst_id;
struct slot *p_slot;
u32 event_type;
@@ -497,10 +493,12 @@ static void handle_button_press_event(struct slot *p_slot)
p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
if (getstatus) {
p_slot->state = BLINKINGOFF_STATE;
- info(msg_button_off, p_slot->name);
+ info("PCI slot #%s - powering off due to button "
+ "press.\n", p_slot->name);
} else {
p_slot->state = BLINKINGON_STATE;
- info(msg_button_on, p_slot->name);
+ info("PCI slot #%s - powering on due to button "
+ "press.\n", p_slot->name);
}
/* blink green LED and turn off amber */
p_slot->hpc_ops->green_led_blink(p_slot);
@@ -523,7 +521,8 @@ static void handle_button_press_event(struct slot *p_slot)
else
p_slot->hpc_ops->green_led_off(p_slot);
p_slot->hpc_ops->set_attention_status(p_slot, 0);
- info(msg_button_cancel, p_slot->name);
+ info("PCI slot #%s - action canceled due to button press\n",
+ p_slot->name);
p_slot->state = STATIC_STATE;
break;
case POWEROFF_STATE:
diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c
index 83a5226ba9ed..b7bede4b7c27 100644
--- a/drivers/pci/hotplug/shpchp_hpc.c
+++ b/drivers/pci/hotplug/shpchp_hpc.c
@@ -212,44 +212,40 @@
#define SLOT_SERR_INT_MASK 0x3
DEFINE_DBG_BUFFER /* Debug string buffer for entire HPC defined here */
-static struct php_ctlr_state_s *php_ctlr_list_head; /* HPC state linked list */
-static int ctlr_seq_num = 0; /* Controller sequenc # */
-static spinlock_t list_lock;
-
static atomic_t shpchp_num_controllers = ATOMIC_INIT(0);
static irqreturn_t shpc_isr(int irq, void *dev_id);
-static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int sec);
+static void start_int_poll_timer(struct controller *ctrl, int sec);
static int hpc_check_cmd_status(struct controller *ctrl);
static inline u8 shpc_readb(struct controller *ctrl, int reg)
{
- return readb(ctrl->hpc_ctlr_handle->creg + reg);
+ return readb(ctrl->creg + reg);
}
static inline void shpc_writeb(struct controller *ctrl, int reg, u8 val)
{
- writeb(val, ctrl->hpc_ctlr_handle->creg + reg);
+ writeb(val, ctrl->creg + reg);
}
static inline u16 shpc_readw(struct controller *ctrl, int reg)
{
- return readw(ctrl->hpc_ctlr_handle->creg + reg);
+ return readw(ctrl->creg + reg);
}
static inline void shpc_writew(struct controller *ctrl, int reg, u16 val)
{
- writew(val, ctrl->hpc_ctlr_handle->creg + reg);
+ writew(val, ctrl->creg + reg);
}
static inline u32 shpc_readl(struct controller *ctrl, int reg)
{
- return readl(ctrl->hpc_ctlr_handle->creg + reg);
+ return readl(ctrl->creg + reg);
}
static inline void shpc_writel(struct controller *ctrl, int reg, u32 val)
{
- writel(val, ctrl->hpc_ctlr_handle->creg + reg);
+ writel(val, ctrl->creg + reg);
}
static inline int shpc_indirect_read(struct controller *ctrl, int index,
@@ -268,21 +264,20 @@ static inline int shpc_indirect_read(struct controller *ctrl, int index,
/*
* This is the interrupt polling timeout function.
*/
-static void int_poll_timeout(unsigned long lphp_ctlr)
+static void int_poll_timeout(unsigned long data)
{
- struct php_ctlr_state_s *php_ctlr =
- (struct php_ctlr_state_s *)lphp_ctlr;
+ struct controller *ctrl = (struct controller *)data;
DBG_ENTER_ROUTINE
/* Poll for interrupt events. regs == NULL => polling */
- shpc_isr(0, php_ctlr->callback_instance_id);
+ shpc_isr(0, ctrl);
- init_timer(&php_ctlr->int_poll_timer);
+ init_timer(&ctrl->poll_timer);
if (!shpchp_poll_time)
shpchp_poll_time = 2; /* default polling interval is 2 sec */
- start_int_poll_timer(php_ctlr, shpchp_poll_time);
+ start_int_poll_timer(ctrl, shpchp_poll_time);
DBG_LEAVE_ROUTINE
}
@@ -290,16 +285,16 @@ static void int_poll_timeout(unsigned long lphp_ctlr)
/*
* This function starts the interrupt polling timer.
*/
-static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int sec)
+static void start_int_poll_timer(struct controller *ctrl, int sec)
{
/* Clamp to sane value */
if ((sec <= 0) || (sec > 60))
sec = 2;
- php_ctlr->int_poll_timer.function = &int_poll_timeout;
- php_ctlr->int_poll_timer.data = (unsigned long)php_ctlr;
- php_ctlr->int_poll_timer.expires = jiffies + sec * HZ;
- add_timer(&php_ctlr->int_poll_timer);
+ ctrl->poll_timer.function = &int_poll_timeout;
+ ctrl->poll_timer.data = (unsigned long)ctrl;
+ ctrl->poll_timer.expires = jiffies + sec * HZ;
+ add_timer(&ctrl->poll_timer);
}
static inline int is_ctrl_busy(struct controller *ctrl)
@@ -666,33 +661,8 @@ static void hpc_set_green_led_blink(struct slot *slot)
shpc_write_cmd(slot, slot->hp_slot, SET_PWR_BLINK);
}
-int shpc_get_ctlr_slot_config(struct controller *ctrl,
- int *num_ctlr_slots, /* number of slots in this HPC */
- int *first_device_num, /* PCI dev num of the first slot in this SHPC */
- int *physical_slot_num, /* phy slot num of the first slot in this SHPC */
- int *updown, /* physical_slot_num increament: 1 or -1 */
- int *flags)
-{
- u32 slot_config;
-
- DBG_ENTER_ROUTINE
-
- slot_config = shpc_readl(ctrl, SLOT_CONFIG);
- *first_device_num = (slot_config & FIRST_DEV_NUM) >> 8;
- *num_ctlr_slots = slot_config & SLOT_NUM;
- *physical_slot_num = (slot_config & PSN) >> 16;
- *updown = ((slot_config & UPDOWN) >> 29) ? 1 : -1;
-
- dbg("%s: physical_slot_num = %x\n", __FUNCTION__, *physical_slot_num);
-
- DBG_LEAVE_ROUTINE
- return 0;
-}
-
static void hpc_release_ctlr(struct controller *ctrl)
{
- struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle;
- struct php_ctlr_state_s *p, *p_prev;
int i;
u32 slot_reg, serr_int;
@@ -722,40 +692,15 @@ static void hpc_release_ctlr(struct controller *ctrl)
serr_int &= ~SERR_INTR_RSVDZ_MASK;
shpc_writel(ctrl, SERR_INTR_ENABLE, serr_int);
- if (shpchp_poll_mode) {
- del_timer(&php_ctlr->int_poll_timer);
- } else {
- if (php_ctlr->irq) {
- free_irq(php_ctlr->irq, ctrl);
- php_ctlr->irq = 0;
- pci_disable_msi(php_ctlr->pci_dev);
- }
- }
-
- if (php_ctlr->pci_dev) {
- iounmap(php_ctlr->creg);
- release_mem_region(ctrl->mmio_base, ctrl->mmio_size);
- php_ctlr->pci_dev = NULL;
- }
-
- spin_lock(&list_lock);
- p = php_ctlr_list_head;
- p_prev = NULL;
- while (p) {
- if (p == php_ctlr) {
- if (p_prev)
- p_prev->pnext = p->pnext;
- else
- php_ctlr_list_head = p->pnext;
- break;
- } else {
- p_prev = p;
- p = p->pnext;
- }
+ if (shpchp_poll_mode)
+ del_timer(&ctrl->poll_timer);
+ else {
+ free_irq(ctrl->pci_dev->irq, ctrl);
+ pci_disable_msi(ctrl->pci_dev);
}
- spin_unlock(&list_lock);
- kfree(php_ctlr);
+ iounmap(ctrl->creg);
+ release_mem_region(ctrl->mmio_base, ctrl->mmio_size);
/*
* If this is the last controller to be released, destroy the
@@ -764,8 +709,7 @@ static void hpc_release_ctlr(struct controller *ctrl)
if (atomic_dec_and_test(&shpchp_num_controllers))
destroy_workqueue(shpchp_wq);
-DBG_LEAVE_ROUTINE
-
+ DBG_LEAVE_ROUTINE
}
static int hpc_power_on_slot(struct slot * slot)
@@ -891,7 +835,6 @@ static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value)
static irqreturn_t shpc_isr(int irq, void *dev_id)
{
struct controller *ctrl = (struct controller *)dev_id;
- struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle;
u32 serr_int, slot_reg, intr_loc, intr_loc2;
int hp_slot;
@@ -942,20 +885,16 @@ static irqreturn_t shpc_isr(int irq, void *dev_id)
__FUNCTION__, hp_slot, slot_reg);
if (slot_reg & MRL_CHANGE_DETECTED)
- php_ctlr->switch_change_callback(
- hp_slot, php_ctlr->callback_instance_id);
+ shpchp_handle_switch_change(hp_slot, ctrl);
if (slot_reg & BUTTON_PRESS_DETECTED)
- php_ctlr->attention_button_callback(
- hp_slot, php_ctlr->callback_instance_id);
+ shpchp_handle_attention_button(hp_slot, ctrl);
if (slot_reg & PRSNT_CHANGE_DETECTED)
- php_ctlr->presence_change_callback(
- hp_slot , php_ctlr->callback_instance_id);
+ shpchp_handle_presence_change(hp_slot, ctrl);
if (slot_reg & (ISO_PFAULT_DETECTED | CON_PFAULT_DETECTED))
- php_ctlr->power_fault_callback(
- hp_slot, php_ctlr->callback_instance_id);
+ shpchp_handle_power_fault(hp_slot, ctrl);
/* Clear all slot events */
slot_reg &= ~SLOT_REG_RSVDZ_MASK;
@@ -1114,10 +1053,8 @@ static struct hpc_ops shpchp_hpc_ops = {
.release_ctlr = hpc_release_ctlr,
};
-int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
+int shpc_init(struct controller *ctrl, struct pci_dev *pdev)
{
- struct php_ctlr_state_s *php_ctlr, *p;
- void *instance_id = ctrl;
int rc = -1, num_slots = 0;
u8 hp_slot;
u32 shpc_base_offset;
@@ -1128,16 +1065,6 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
ctrl->pci_dev = pdev; /* pci_dev of the P2P bridge */
- spin_lock_init(&list_lock);
- php_ctlr = kzalloc(sizeof(*php_ctlr), GFP_KERNEL);
-
- if (!php_ctlr) { /* allocate controller state data */
- err("%s: HPC controller memory allocation error!\n", __FUNCTION__);
- goto abort;
- }
-
- php_ctlr->pci_dev = pdev; /* save pci_dev in context */
-
if ((pdev->vendor == PCI_VENDOR_ID_AMD) || (pdev->device ==
PCI_DEVICE_ID_AMD_GOLAM_7450)) {
/* amd shpc driver doesn't use Base Offset; assume 0 */
@@ -1147,20 +1074,20 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
ctrl->cap_offset = pci_find_capability(pdev, PCI_CAP_ID_SHPC);
if (!ctrl->cap_offset) {
err("%s : cap_offset == 0\n", __FUNCTION__);
- goto abort_free_ctlr;
+ goto abort;
}
dbg("%s: cap_offset = %x\n", __FUNCTION__, ctrl->cap_offset);
rc = shpc_indirect_read(ctrl, 0, &shpc_base_offset);
if (rc) {
err("%s: cannot read base_offset\n", __FUNCTION__);
- goto abort_free_ctlr;
+ goto abort;
}
rc = shpc_indirect_read(ctrl, 3, &tempdword);
if (rc) {
err("%s: cannot read slot config\n", __FUNCTION__);
- goto abort_free_ctlr;
+ goto abort;
}
num_slots = tempdword & SLOT_NUM;
dbg("%s: num_slots (indirect) %x\n", __FUNCTION__, num_slots);
@@ -1170,7 +1097,7 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
if (rc) {
err("%s: cannot read creg (index = %d)\n",
__FUNCTION__, i);
- goto abort_free_ctlr;
+ goto abort;
}
dbg("%s: offset %d: value %x\n", __FUNCTION__,i,
tempdword);
@@ -1187,24 +1114,24 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
rc = pci_enable_device(pdev);
if (rc) {
err("%s: pci_enable_device failed\n", __FUNCTION__);
- goto abort_free_ctlr;
+ goto abort;
}
if (!request_mem_region(ctrl->mmio_base, ctrl->mmio_size, MY_NAME)) {
err("%s: cannot reserve MMIO region\n", __FUNCTION__);
rc = -1;
- goto abort_free_ctlr;
+ goto abort;
}
- php_ctlr->creg = ioremap(ctrl->mmio_base, ctrl->mmio_size);
- if (!php_ctlr->creg) {
+ ctrl->creg = ioremap(ctrl->mmio_base, ctrl->mmio_size);
+ if (!ctrl->creg) {
err("%s: cannot remap MMIO region %lx @ %lx\n", __FUNCTION__,
ctrl->mmio_size, ctrl->mmio_base);
release_mem_region(ctrl->mmio_base, ctrl->mmio_size);
rc = -1;
- goto abort_free_ctlr;
+ goto abort;
}
- dbg("%s: php_ctlr->creg %p\n", __FUNCTION__, php_ctlr->creg);
+ dbg("%s: ctrl->creg %p\n", __FUNCTION__, ctrl->creg);
mutex_init(&ctrl->crit_sect);
mutex_init(&ctrl->cmd_lock);
@@ -1212,23 +1139,14 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
/* Setup wait queue */
init_waitqueue_head(&ctrl->queue);
- /* Find the IRQ */
- php_ctlr->irq = pdev->irq;
- php_ctlr->attention_button_callback = shpchp_handle_attention_button,
- php_ctlr->switch_change_callback = shpchp_handle_switch_change;
- php_ctlr->presence_change_callback = shpchp_handle_presence_change;
- php_ctlr->power_fault_callback = shpchp_handle_power_fault;
- php_ctlr->callback_instance_id = instance_id;
-
- ctrl->hpc_ctlr_handle = php_ctlr;
ctrl->hpc_ops = &shpchp_hpc_ops;
/* Return PCI Controller Info */
slot_config = shpc_readl(ctrl, SLOT_CONFIG);
- php_ctlr->slot_device_offset = (slot_config & FIRST_DEV_NUM) >> 8;
- php_ctlr->num_slots = slot_config & SLOT_NUM;
- dbg("%s: slot_device_offset %x\n", __FUNCTION__, php_ctlr->slot_device_offset);
- dbg("%s: num_slots %x\n", __FUNCTION__, php_ctlr->num_slots);
+ ctrl->slot_device_offset = (slot_config & FIRST_DEV_NUM) >> 8;
+ ctrl->num_slots = slot_config & SLOT_NUM;
+ ctrl->first_slot = (slot_config & PSN) >> 16;
+ ctrl->slot_num_inc = ((slot_config & UPDOWN) >> 29) ? 1 : -1;
/* Mask Global Interrupt Mask & Command Complete Interrupt Mask */
tempdword = shpc_readl(ctrl, SERR_INTR_ENABLE);
@@ -1243,7 +1161,7 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
/* Mask the MRL sensor SERR Mask of individual slot in
* Slot SERR-INT Mask & clear all the existing event if any
*/
- for (hp_slot = 0; hp_slot < php_ctlr->num_slots; hp_slot++) {
+ for (hp_slot = 0; hp_slot < ctrl->num_slots; hp_slot++) {
slot_reg = shpc_readl(ctrl, SLOT_REG(hp_slot));
dbg("%s: Default Logical Slot Register %d value %x\n", __FUNCTION__,
hp_slot, slot_reg);
@@ -1255,24 +1173,27 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
shpc_writel(ctrl, SLOT_REG(hp_slot), slot_reg);
}
- if (shpchp_poll_mode) {/* Install interrupt polling code */
- /* Install and start the interrupt polling timer */
- init_timer(&php_ctlr->int_poll_timer);
- start_int_poll_timer( php_ctlr, 10 ); /* start with 10 second delay */
+ if (shpchp_poll_mode) {
+ /* Install interrupt polling timer. Start with 10 sec delay */
+ init_timer(&ctrl->poll_timer);
+ start_int_poll_timer(ctrl, 10);
} else {
/* Installs the interrupt handler */
rc = pci_enable_msi(pdev);
if (rc) {
info("Can't get msi for the hotplug controller\n");
info("Use INTx for the hotplug controller\n");
- } else
- php_ctlr->irq = pdev->irq;
+ }
- rc = request_irq(php_ctlr->irq, shpc_isr, IRQF_SHARED, MY_NAME, (void *) ctrl);
- dbg("%s: request_irq %d for hpc%d (returns %d)\n", __FUNCTION__, php_ctlr->irq, ctlr_seq_num, rc);
+ rc = request_irq(ctrl->pci_dev->irq, shpc_isr, IRQF_SHARED,
+ MY_NAME, (void *)ctrl);
+ dbg("%s: request_irq %d for hpc%d (returns %d)\n",
+ __FUNCTION__, ctrl->pci_dev->irq,
+ atomic_read(&shpchp_num_controllers), rc);
if (rc) {
- err("Can't get irq %d for the hotplug controller\n", php_ctlr->irq);
- goto abort_free_ctlr;
+ err("Can't get irq %d for the hotplug controller\n",
+ ctrl->pci_dev->irq);
+ goto abort_iounmap;
}
}
dbg("%s: HPC at b:d:f:irq=0x%x:%x:%x:%x\n", __FUNCTION__,
@@ -1280,24 +1201,6 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
PCI_FUNC(pdev->devfn), pdev->irq);
get_hp_hw_control_from_firmware(pdev);
- /* Add this HPC instance into the HPC list */
- spin_lock(&list_lock);
- if (php_ctlr_list_head == 0) {
- php_ctlr_list_head = php_ctlr;
- p = php_ctlr_list_head;
- p->pnext = NULL;
- } else {
- p = php_ctlr_list_head;
-
- while (p->pnext)
- p = p->pnext;
-
- p->pnext = php_ctlr;
- }
- spin_unlock(&list_lock);
-
- ctlr_seq_num++;
-
/*
* If this is the first controller to be initialized,
* initialize the shpchpd work queue
@@ -1306,14 +1209,14 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
shpchp_wq = create_singlethread_workqueue("shpchpd");
if (!shpchp_wq) {
rc = -ENOMEM;
- goto abort_free_ctlr;
+ goto abort_iounmap;
}
}
/*
* Unmask all event interrupts of all slots
*/
- for (hp_slot = 0; hp_slot < php_ctlr->num_slots; hp_slot++) {
+ for (hp_slot = 0; hp_slot < ctrl->num_slots; hp_slot++) {
slot_reg = shpc_readl(ctrl, SLOT_REG(hp_slot));
dbg("%s: Default Logical Slot Register %d value %x\n", __FUNCTION__,
hp_slot, slot_reg);
@@ -1336,10 +1239,8 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
return 0;
/* We end up here for the many possible ways to fail this API. */
-abort_free_ctlr:
- if (php_ctlr->creg)
- iounmap(php_ctlr->creg);
- kfree(php_ctlr);
+abort_iounmap:
+ iounmap(ctrl->creg);
abort:
DBG_LEAVE_ROUTINE
return rc;
diff --git a/drivers/pci/htirq.c b/drivers/pci/htirq.c
index 0a8d1cce9fa0..279c940a0039 100644
--- a/drivers/pci/htirq.c
+++ b/drivers/pci/htirq.c
@@ -99,14 +99,7 @@ int __ht_create_irq(struct pci_dev *dev, int idx, ht_irq_update_t *update)
int pos;
int irq;
- pos = pci_find_capability(dev, PCI_CAP_ID_HT);
- while (pos) {
- u8 subtype;
- pci_read_config_byte(dev, pos + 3, &subtype);
- if (subtype == HT_CAPTYPE_IRQ)
- break;
- pos = pci_find_next_capability(dev, pos, PCI_CAP_ID_HT);
- }
+ pos = pci_find_ht_capability(dev, HT_CAPTYPE_IRQ);
if (!pos)
return -EINVAL;
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index e5ae3a0c13bb..b8d2385e29bc 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -162,14 +162,9 @@ const struct pci_device_id *pci_match_id(const struct pci_device_id *ids,
const struct pci_device_id *pci_match_device(struct pci_driver *drv,
struct pci_dev *dev)
{
- const struct pci_device_id *id;
struct pci_dynid *dynid;
- id = pci_match_id(drv->id_table, dev);
- if (id)
- return id;
-
- /* static ids didn't match, lets look at the dynamic ones */
+ /* Look at the dynamic ids first, before the static ones */
spin_lock(&drv->dynids.lock);
list_for_each_entry(dynid, &drv->dynids.list, node) {
if (pci_match_one_device(&dynid->id, dev)) {
@@ -178,7 +173,8 @@ const struct pci_device_id *pci_match_device(struct pci_driver *drv,
}
}
spin_unlock(&drv->dynids.lock);
- return NULL;
+
+ return pci_match_id(drv->id_table, dev);
}
static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev,
@@ -357,6 +353,8 @@ static int pci_device_resume_early(struct device * dev)
struct pci_dev * pci_dev = to_pci_dev(dev);
struct pci_driver * drv = pci_dev->driver;
+ pci_fixup_device(pci_fixup_resume, pci_dev);
+
if (drv && drv->resume_early)
error = drv->resume_early(pci_dev);
return error;
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 5a14b73cf3a1..6bfb942428e4 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -68,12 +68,14 @@ pci_max_busnr(void)
#endif /* 0 */
-static int __pci_find_next_cap(struct pci_bus *bus, unsigned int devfn, u8 pos, int cap)
+#define PCI_FIND_CAP_TTL 48
+
+static int __pci_find_next_cap_ttl(struct pci_bus *bus, unsigned int devfn,
+ u8 pos, int cap, int *ttl)
{
u8 id;
- int ttl = 48;
- while (ttl--) {
+ while ((*ttl)--) {
pci_bus_read_config_byte(bus, devfn, pos, &pos);
if (pos < 0x40)
break;
@@ -89,6 +91,14 @@ static int __pci_find_next_cap(struct pci_bus *bus, unsigned int devfn, u8 pos,
return 0;
}
+static int __pci_find_next_cap(struct pci_bus *bus, unsigned int devfn,
+ u8 pos, int cap)
+{
+ int ttl = PCI_FIND_CAP_TTL;
+
+ return __pci_find_next_cap_ttl(bus, devfn, pos, cap, &ttl);
+}
+
int pci_find_next_capability(struct pci_dev *dev, u8 pos, int cap)
{
return __pci_find_next_cap(dev->bus, dev->devfn,
@@ -96,10 +106,10 @@ int pci_find_next_capability(struct pci_dev *dev, u8 pos, int cap)
}
EXPORT_SYMBOL_GPL(pci_find_next_capability);
-static int __pci_bus_find_cap(struct pci_bus *bus, unsigned int devfn, u8 hdr_type, int cap)
+static int __pci_bus_find_cap_start(struct pci_bus *bus,
+ unsigned int devfn, u8 hdr_type)
{
u16 status;
- u8 pos;
pci_bus_read_config_word(bus, devfn, PCI_STATUS, &status);
if (!(status & PCI_STATUS_CAP_LIST))
@@ -108,15 +118,14 @@ static int __pci_bus_find_cap(struct pci_bus *bus, unsigned int devfn, u8 hdr_ty
switch (hdr_type) {
case PCI_HEADER_TYPE_NORMAL:
case PCI_HEADER_TYPE_BRIDGE:
- pos = PCI_CAPABILITY_LIST;
- break;
+ return PCI_CAPABILITY_LIST;
case PCI_HEADER_TYPE_CARDBUS:
- pos = PCI_CB_CAPABILITY_LIST;
- break;
+ return PCI_CB_CAPABILITY_LIST;
default:
return 0;
}
- return __pci_find_next_cap(bus, devfn, pos, cap);
+
+ return 0;
}
/**
@@ -140,7 +149,13 @@ static int __pci_bus_find_cap(struct pci_bus *bus, unsigned int devfn, u8 hdr_ty
*/
int pci_find_capability(struct pci_dev *dev, int cap)
{
- return __pci_bus_find_cap(dev->bus, dev->devfn, dev->hdr_type, cap);
+ int pos;
+
+ pos = __pci_bus_find_cap_start(dev->bus, dev->devfn, dev->hdr_type);
+ if (pos)
+ pos = __pci_find_next_cap(dev->bus, dev->devfn, pos, cap);
+
+ return pos;
}
/**
@@ -158,11 +173,16 @@ int pci_find_capability(struct pci_dev *dev, int cap)
*/
int pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap)
{
+ int pos;
u8 hdr_type;
pci_bus_read_config_byte(bus, devfn, PCI_HEADER_TYPE, &hdr_type);
- return __pci_bus_find_cap(bus, devfn, hdr_type & 0x7f, cap);
+ pos = __pci_bus_find_cap_start(bus, devfn, hdr_type & 0x7f);
+ if (pos)
+ pos = __pci_find_next_cap(bus, devfn, pos, cap);
+
+ return pos;
}
/**
@@ -214,6 +234,74 @@ int pci_find_ext_capability(struct pci_dev *dev, int cap)
}
EXPORT_SYMBOL_GPL(pci_find_ext_capability);
+static int __pci_find_next_ht_cap(struct pci_dev *dev, int pos, int ht_cap)
+{
+ int rc, ttl = PCI_FIND_CAP_TTL;
+ u8 cap, mask;
+
+ if (ht_cap == HT_CAPTYPE_SLAVE || ht_cap == HT_CAPTYPE_HOST)
+ mask = HT_3BIT_CAP_MASK;
+ else
+ mask = HT_5BIT_CAP_MASK;
+
+ pos = __pci_find_next_cap_ttl(dev->bus, dev->devfn, pos,
+ PCI_CAP_ID_HT, &ttl);
+ while (pos) {
+ rc = pci_read_config_byte(dev, pos + 3, &cap);
+ if (rc != PCIBIOS_SUCCESSFUL)
+ return 0;
+
+ if ((cap & mask) == ht_cap)
+ return pos;
+
+ pos = __pci_find_next_cap_ttl(dev->bus, dev->devfn, pos,
+ PCI_CAP_ID_HT, &ttl);
+ }
+
+ return 0;
+}
+/**
+ * pci_find_next_ht_capability - query a device's Hypertransport capabilities
+ * @dev: PCI device to query
+ * @pos: Position from which to continue searching
+ * @ht_cap: Hypertransport capability code
+ *
+ * To be used in conjunction with pci_find_ht_capability() to search for
+ * all capabilities matching @ht_cap. @pos should always be a value returned
+ * from pci_find_ht_capability().
+ *
+ * NB. To be 100% safe against broken PCI devices, the caller should take
+ * steps to avoid an infinite loop.
+ */
+int pci_find_next_ht_capability(struct pci_dev *dev, int pos, int ht_cap)
+{
+ return __pci_find_next_ht_cap(dev, pos + PCI_CAP_LIST_NEXT, ht_cap);
+}
+EXPORT_SYMBOL_GPL(pci_find_next_ht_capability);
+
+/**
+ * pci_find_ht_capability - query a device's Hypertransport capabilities
+ * @dev: PCI device to query
+ * @ht_cap: Hypertransport capability code
+ *
+ * Tell if a device supports a given Hypertransport capability.
+ * Returns an address within the device's PCI configuration space
+ * or 0 in case the device does not support the request capability.
+ * The address points to the PCI capability, of type PCI_CAP_ID_HT,
+ * which has a Hypertransport capability matching @ht_cap.
+ */
+int pci_find_ht_capability(struct pci_dev *dev, int ht_cap)
+{
+ int pos;
+
+ pos = __pci_bus_find_cap_start(dev->bus, dev->devfn, dev->hdr_type);
+ if (pos)
+ pos = __pci_find_next_ht_cap(dev, pos, ht_cap);
+
+ return pos;
+}
+EXPORT_SYMBOL_GPL(pci_find_ht_capability);
+
/**
* pci_find_parent_resource - return resource region of parent bus of given region
* @dev: PCI device structure contains resources to be searched
diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c
index 55866b6b26fa..6f5fabbd14e5 100644
--- a/drivers/pci/pcie/aer/aerdrv.c
+++ b/drivers/pci/pcie/aer/aerdrv.c
@@ -148,7 +148,7 @@ static struct aer_rpc* aer_alloc_rpc(struct pcie_device *dev)
{
struct aer_rpc *rpc;
- if (!(rpc = (struct aer_rpc *)kmalloc(sizeof(struct aer_rpc),
+ if (!(rpc = kmalloc(sizeof(struct aer_rpc),
GFP_KERNEL)))
return NULL;
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
index b4da7954611e..f17e7ed2b2a5 100644
--- a/drivers/pci/pcie/portdrv_pci.c
+++ b/drivers/pci/pcie/portdrv_pci.c
@@ -90,7 +90,7 @@ static int __devinit pcie_portdrv_probe (struct pci_dev *dev,
return -ENODEV;
pci_set_master(dev);
- if (!dev->irq) {
+ if (!dev->irq && dev->pin) {
printk(KERN_WARNING
"%s->Dev[%04x:%04x] has invalid IRQ. Check vendor BIOS\n",
__FUNCTION__, dev->device, dev->vendor);
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 6a3c1e728900..0e0401dd02cb 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -639,6 +639,8 @@ static void pci_read_irq(struct pci_dev *dev)
dev->irq = irq;
}
+#define LEGACY_IO_RESOURCE (IORESOURCE_IO | IORESOURCE_PCI_FIXED)
+
/**
* pci_setup_device - fill in class and map information of a device
* @dev: the device structure to fill
@@ -692,18 +694,18 @@ static int pci_setup_device(struct pci_dev * dev)
if ((progif & 1) == 0) {
dev->resource[0].start = 0x1F0;
dev->resource[0].end = 0x1F7;
- dev->resource[0].flags = IORESOURCE_IO;
+ dev->resource[0].flags = LEGACY_IO_RESOURCE;
dev->resource[1].start = 0x3F6;
dev->resource[1].end = 0x3F6;
- dev->resource[1].flags = IORESOURCE_IO;
+ dev->resource[1].flags = LEGACY_IO_RESOURCE;
}
if ((progif & 4) == 0) {
dev->resource[2].start = 0x170;
dev->resource[2].end = 0x177;
- dev->resource[2].flags = IORESOURCE_IO;
+ dev->resource[2].flags = LEGACY_IO_RESOURCE;
dev->resource[3].start = 0x376;
dev->resource[3].end = 0x376;
- dev->resource[3].flags = IORESOURCE_IO;
+ dev->resource[3].flags = LEGACY_IO_RESOURCE;
}
}
break;
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 9ca9b9bf6160..8f0322d6f3bf 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -36,7 +36,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_MELLANOX,PCI_DEVICE_ID_MELLANOX_TAVOR_BRID
/* Deal with broken BIOS'es that neglect to enable passive release,
which can cause problems in combination with the 82441FX/PPro MTRRs */
-static void __devinit quirk_passive_release(struct pci_dev *dev)
+static void quirk_passive_release(struct pci_dev *dev)
{
struct pci_dev *d = NULL;
unsigned char dlc;
@@ -53,6 +53,7 @@ static void __devinit quirk_passive_release(struct pci_dev *dev)
}
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441, quirk_passive_release );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441, quirk_passive_release );
/* The VIA VP2/VP3/MVP3 seem to have some 'features'. There may be a workaround
but VIA don't answer queries. If you happen to have good contacts at VIA
@@ -134,7 +135,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82439TX, quir
* Updated based on further information from the site and also on
* information provided by VIA
*/
-static void __devinit quirk_vialatency(struct pci_dev *dev)
+static void quirk_vialatency(struct pci_dev *dev)
{
struct pci_dev *p;
u8 rev;
@@ -185,6 +186,10 @@ exit:
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8363_0, quirk_vialatency );
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8371_1, quirk_vialatency );
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8361, quirk_vialatency );
+/* Must restore this on a resume from RAM */
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8363_0, quirk_vialatency );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8371_1, quirk_vialatency );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8361, quirk_vialatency );
/*
* VIA Apollo VP3 needs ETBF on BT848/878
@@ -532,7 +537,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, quirk_vt8235
* TODO: When we have device-specific interrupt routers,
* this code will go away from quirks.
*/
-static void __devinit quirk_via_ioapic(struct pci_dev *dev)
+static void quirk_via_ioapic(struct pci_dev *dev)
{
u8 tmp;
@@ -548,6 +553,7 @@ static void __devinit quirk_via_ioapic(struct pci_dev *dev)
pci_write_config_byte (dev, 0x58, tmp);
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_ioapic );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_ioapic );
/*
* VIA 8237: Some BIOSs don't set the 'Bypass APIC De-Assert Message' Bit.
@@ -555,7 +561,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_i
* Set this bit to get rid of cycle wastage.
* Otherwise uncritical.
*/
-static void __devinit quirk_via_vt8237_bypass_apic_deassert(struct pci_dev *dev)
+static void quirk_via_vt8237_bypass_apic_deassert(struct pci_dev *dev)
{
u8 misc_control2;
#define BYPASS_APIC_DEASSERT 8
@@ -567,6 +573,7 @@ static void __devinit quirk_via_vt8237_bypass_apic_deassert(struct pci_dev *dev)
}
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, quirk_via_vt8237_bypass_apic_deassert);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, quirk_via_vt8237_bypass_apic_deassert);
/*
* The AMD io apic can hang the box when an apic irq is masked.
@@ -600,7 +607,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI, PCI_ANY_ID, quirk_ioapic_rmw );
#define AMD8131_revB0 0x11
#define AMD8131_MISC 0x40
#define AMD8131_NIOAMODE_BIT 0
-static void __init quirk_amd_8131_ioapic(struct pci_dev *dev)
+static void quirk_amd_8131_ioapic(struct pci_dev *dev)
{
unsigned char revid, tmp;
@@ -616,6 +623,7 @@ static void __init quirk_amd_8131_ioapic(struct pci_dev *dev)
}
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_ioapic);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_ioapic);
#endif /* CONFIG_X86_IO_APIC */
@@ -641,65 +649,84 @@ static void __devinit quirk_via_acpi(struct pci_dev *d)
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_via_acpi );
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_via_acpi );
-/*
- * Via 686A/B: The PCI_INTERRUPT_LINE register for the on-chip
- * devices, USB0/1, AC97, MC97, and ACPI, has an unusual feature:
- * when written, it makes an internal connection to the PIC.
- * For these devices, this register is defined to be 4 bits wide.
- * Normally this is fine. However for IO-APIC motherboards, or
- * non-x86 architectures (yes Via exists on PPC among other places),
- * we must mask the PCI_INTERRUPT_LINE value versus 0xf to get
- * interrupts delivered properly.
- *
- * Some of the on-chip devices are actually '586 devices' so they are
- * listed here.
- */
-
-static int via_irq_fixup_needed = -1;
/*
- * As some VIA hardware is available in PCI-card form, we need to restrict
- * this quirk to VIA PCI hardware built onto VIA-based motherboards only.
- * We try to locate a VIA southbridge before deciding whether the quirk
- * should be applied.
+ * VIA bridges which have VLink
*/
-static const struct pci_device_id via_irq_fixup_tbl[] = {
- {
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_ANY_ID,
- .subvendor = PCI_ANY_ID,
- .subdevice = PCI_ANY_ID,
- .class = PCI_CLASS_BRIDGE_ISA << 8,
- .class_mask = 0xffff00,
- },
+
+static const struct pci_device_id via_vlink_fixup_tbl[] = {
+ /* Internal devices need IRQ line routing, pre VLink */
+ { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C686), 0 },
+ { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8231), 17 },
+ /* Devices with VLink */
+ { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8233_0), 17},
+ { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8233A), 17 },
+ { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8233C_0), 17 },
+ { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8235), 16 },
+ { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8237), 15 },
+ { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8237A), 15 },
{ 0, },
};
-static void quirk_via_irq(struct pci_dev *dev)
+/**
+ * quirk_via_vlink - VIA VLink IRQ number update
+ * @dev: PCI device
+ *
+ * If the device we are dealing with is on a PIC IRQ we need to
+ * ensure that the IRQ line register which usually is not relevant
+ * for PCI cards, is actually written so that interrupts get sent
+ * to the right place
+ */
+
+static void quirk_via_vlink(struct pci_dev *dev)
{
+ const struct pci_device_id *via_vlink_fixup;
+ static int dev_lo = -1, dev_hi = 18;
u8 irq, new_irq;
- if (via_irq_fixup_needed == -1)
- via_irq_fixup_needed = pci_dev_present(via_irq_fixup_tbl);
+ /* Check if we have VLink and cache the result */
- if (!via_irq_fixup_needed)
+ /* Checked already - no */
+ if (dev_lo == -2)
return;
+ /* Not checked - see what bridge we have and find the device
+ ranges */
+
+ if (dev_lo == -1) {
+ via_vlink_fixup = pci_find_present(via_vlink_fixup_tbl);
+ if (via_vlink_fixup == NULL) {
+ dev_lo = -2;
+ return;
+ }
+ dev_lo = via_vlink_fixup->driver_data;
+ /* 82C686 is special - 0/0 */
+ if (dev_lo == 0)
+ dev_hi = 0;
+ }
new_irq = dev->irq;
/* Don't quirk interrupts outside the legacy IRQ range */
if (!new_irq || new_irq > 15)
return;
+ /* Internal device ? */
+ if (dev->bus->number != 0 || PCI_SLOT(dev->devfn) > dev_hi ||
+ PCI_SLOT(dev->devfn) < dev_lo)
+ return;
+
+ /* This is an internal VLink device on a PIC interrupt. The BIOS
+ ought to have set this but may not have, so we redo it */
+
pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
if (new_irq != irq) {
- printk(KERN_INFO "PCI: VIA IRQ fixup for %s, from %d to %d\n",
+ printk(KERN_INFO "PCI: VIA VLink IRQ fixup for %s, from %d to %d\n",
pci_name(dev), irq, new_irq);
udelay(15); /* unknown if delay really needed */
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq);
}
}
-DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_irq);
+DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_vlink);
/*
* VIA VT82C598 has its device ID settable and many BIOSes
@@ -720,13 +747,14 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C597_0, quirk_vt
* do this even if the Linux CardBus driver is not loaded, because
* the Linux i82365 driver does not (and should not) handle CardBus.
*/
-static void __devinit quirk_cardbus_legacy(struct pci_dev *dev)
+static void quirk_cardbus_legacy(struct pci_dev *dev)
{
if ((PCI_CLASS_BRIDGE_CARDBUS << 8) ^ dev->class)
return;
pci_write_config_dword(dev, PCI_CB_LEGACY_MODE_BASE, 0);
}
DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, quirk_cardbus_legacy);
+DECLARE_PCI_FIXUP_RESUME(PCI_ANY_ID, PCI_ANY_ID, quirk_cardbus_legacy);
/*
* Following the PCI ordering rules is optional on the AMD762. I'm not
@@ -735,7 +763,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, quirk_cardbus_legacy);
* To be fair to AMD, it follows the spec by default, its BIOS people
* who turn it off!
*/
-static void __devinit quirk_amd_ordering(struct pci_dev *dev)
+static void quirk_amd_ordering(struct pci_dev *dev)
{
u32 pcic;
pci_read_config_dword(dev, 0x4C, &pcic);
@@ -749,6 +777,7 @@ static void __devinit quirk_amd_ordering(struct pci_dev *dev)
}
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering );
/*
* DreamWorks provided workaround for Dunord I-3000 problem
@@ -784,7 +813,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TOSHIBA, 0x605, quirk_transparent_bridge
* datasheets found at http://www.national.com/ds/GX for info on what
* these bits do. <christer@weinigel.se>
*/
-static void __init quirk_mediagx_master(struct pci_dev *dev)
+static void quirk_mediagx_master(struct pci_dev *dev)
{
u8 reg;
pci_read_config_byte(dev, 0x41, &reg);
@@ -795,13 +824,14 @@ static void __init quirk_mediagx_master(struct pci_dev *dev)
}
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_PCI_MASTER, quirk_mediagx_master );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_PCI_MASTER, quirk_mediagx_master );
/*
* Ensure C0 rev restreaming is off. This is normally done by
* the BIOS but in the odd case it is not the results are corruption
* hence the presence of a Linux check
*/
-static void __init quirk_disable_pxb(struct pci_dev *pdev)
+static void quirk_disable_pxb(struct pci_dev *pdev)
{
u16 config;
u8 rev;
@@ -817,7 +847,25 @@ static void __init quirk_disable_pxb(struct pci_dev *pdev)
}
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb );
+
+
+static void __devinit quirk_sb600_sata(struct pci_dev *pdev)
+{
+ /* set sb600 sata to ahci mode */
+ if ((pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) {
+ u8 tmp;
+ pci_read_config_byte(pdev, 0x40, &tmp);
+ pci_write_config_byte(pdev, 0x40, tmp|1);
+ pci_write_config_byte(pdev, 0x9, 1);
+ pci_write_config_byte(pdev, 0xa, 6);
+ pci_write_config_byte(pdev, 0x40, tmp);
+
+ pdev->class = 0x010601;
+ }
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_sb600_sata);
/*
* Serverworks CSB5 IDE does not fully support native mode
@@ -874,7 +922,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82375, quirk_e
* runs everywhere at present we suppress the printk output in most
* irrelevant cases.
*/
-static void __init k8t_sound_hostbridge(struct pci_dev *dev)
+static void k8t_sound_hostbridge(struct pci_dev *dev)
{
unsigned char val;
@@ -893,8 +941,8 @@ static void __init k8t_sound_hostbridge(struct pci_dev *dev)
}
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, k8t_sound_hostbridge);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, k8t_sound_hostbridge);
-#ifndef CONFIG_ACPI_SLEEP
/*
* On ASUS P4B boards, the SMBus PCI Device within the ICH2/4 southbridge
* is not activated. The myth is that Asus said that they do not want the
@@ -906,10 +954,6 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, k8t_sound_ho
* bridge. Unfortunately, this device has no subvendor/subdevice ID. So it
* becomes necessary to do this tweak in two steps -- I've chosen the Host
* bridge as trigger.
- *
- * Actually, leaving it unhidden and not redoing the quirk over suspend2ram
- * will cause thermal management to break down, and causing machine to
- * overheat.
*/
static int __initdata asus_hides_smbus;
@@ -1019,7 +1063,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855PM_HB, as
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855GM_HB, asus_hides_smbus_hostbridge );
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82915GM_HB, asus_hides_smbus_hostbridge );
-static void __init asus_hides_smbus_lpc(struct pci_dev *dev)
+static void asus_hides_smbus_lpc(struct pci_dev *dev)
{
u16 val;
@@ -1042,8 +1086,14 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, asu
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc );
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc );
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, asus_hides_smbus_lpc );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, asus_hides_smbus_lpc );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, asus_hides_smbus_lpc );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc );
-static void __init asus_hides_smbus_lpc_ich6(struct pci_dev *dev)
+static void asus_hides_smbus_lpc_ich6(struct pci_dev *dev)
{
u32 val, rcba;
void __iomem *base;
@@ -1059,13 +1109,12 @@ static void __init asus_hides_smbus_lpc_ich6(struct pci_dev *dev)
printk(KERN_INFO "PCI: Enabled ICH6/i801 SMBus device\n");
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6 );
-
-#endif
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6 );
/*
* SiS 96x south bridge: BIOS typically hides SMBus device...
*/
-static void __init quirk_sis_96x_smbus(struct pci_dev *dev)
+static void quirk_sis_96x_smbus(struct pci_dev *dev)
{
u8 val = 0;
printk(KERN_INFO "Enabling SiS 96x SMBus.\n");
@@ -1086,7 +1135,7 @@ static int __devinitdata sis_96x_compatible = 0;
#define SIS_DETECT_REGISTER 0x40
-static void __init quirk_sis_503(struct pci_dev *dev)
+static void quirk_sis_503(struct pci_dev *dev)
{
u8 reg;
u16 devid;
@@ -1122,13 +1171,14 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_651, quirk_sis_96x_
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_735, quirk_sis_96x_compatible );
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, quirk_sis_503 );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, quirk_sis_503 );
/*
* On ASUS A8V and A8V Deluxe boards, the onboard AC97 audio controller
* and MC97 modem controller are disabled when a second PCI soundcard is
* present. This patch, tweaking the VT8237 ISA bridge, enables them.
* -- bjd
*/
-static void __init asus_hides_ac97_lpc(struct pci_dev *dev)
+static void asus_hides_ac97_lpc(struct pci_dev *dev)
{
u8 val;
int asus_hides_ac97 = 0;
@@ -1159,6 +1209,14 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_962, quirk_sis_96x_
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_963, quirk_sis_96x_smbus );
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_smbus );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, asus_hides_ac97_lpc );
+
+
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_961, quirk_sis_96x_smbus );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_962, quirk_sis_96x_smbus );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_963, quirk_sis_96x_smbus );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_smbus );
+
#if defined(CONFIG_ATA) || defined(CONFIG_ATA_MODULE)
/*
@@ -1167,7 +1225,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_
* the PCI scanning.
*/
-static void __devinit quirk_jmicron_dualfn(struct pci_dev *pdev)
+static void quirk_jmicron_dualfn(struct pci_dev *pdev)
{
u32 conf;
u8 hdr;
@@ -1205,6 +1263,7 @@ static void __devinit quirk_jmicron_dualfn(struct pci_dev *pdev)
}
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, quirk_jmicron_dualfn);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, quirk_jmicron_dualfn);
#endif
@@ -1532,6 +1591,8 @@ extern struct pci_fixup __start_pci_fixups_final[];
extern struct pci_fixup __end_pci_fixups_final[];
extern struct pci_fixup __start_pci_fixups_enable[];
extern struct pci_fixup __end_pci_fixups_enable[];
+extern struct pci_fixup __start_pci_fixups_resume[];
+extern struct pci_fixup __end_pci_fixups_resume[];
void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev)
@@ -1559,6 +1620,11 @@ void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev)
end = __end_pci_fixups_enable;
break;
+ case pci_fixup_resume:
+ start = __start_pci_fixups_resume;
+ end = __end_pci_fixups_resume;
+ break;
+
default:
/* stupid compiler warning, you would think with an enum... */
return;
@@ -1596,7 +1662,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1460, quirk_p64h2_1k_io);
* Force it to be linked by setting the corresponding control bit in the
* config space.
*/
-static void __devinit quirk_nvidia_ck804_pcie_aer_ext_cap(struct pci_dev *dev)
+static void quirk_nvidia_ck804_pcie_aer_ext_cap(struct pci_dev *dev)
{
uint8_t b;
if (pci_read_config_byte(dev, 0xf41, &b) == 0) {
@@ -1610,6 +1676,8 @@ static void __devinit quirk_nvidia_ck804_pcie_aer_ext_cap(struct pci_dev *dev)
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE,
quirk_nvidia_ck804_pcie_aer_ext_cap);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE,
+ quirk_nvidia_ck804_pcie_aer_ext_cap);
#ifdef CONFIG_PCI_MSI
/* To disable MSI globally */
@@ -1644,19 +1712,23 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_
* return 1 if a HT MSI capability is found and enabled */
static int __devinit msi_ht_cap_enabled(struct pci_dev *dev)
{
- u8 pos;
- int ttl;
- for (pos = pci_find_capability(dev, PCI_CAP_ID_HT), ttl = 48;
- pos && ttl;
- pos = pci_find_next_capability(dev, pos, PCI_CAP_ID_HT), ttl--) {
- u32 cap_hdr;
- /* MSI mapping section according to Hypertransport spec */
- if (pci_read_config_dword(dev, pos, &cap_hdr) == 0
- && (cap_hdr & 0xf8000000) == 0xa8000000 /* MSI mapping */) {
- printk(KERN_INFO "PCI: Found HT MSI mapping on %s with capability %s\n",
- pci_name(dev), cap_hdr & 0x10000 ? "enabled" : "disabled");
- return (cap_hdr & 0x10000) != 0; /* MSI mapping cap enabled */
+ int pos, ttl = 48;
+
+ pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING);
+ while (pos && ttl--) {
+ u8 flags;
+
+ if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS,
+ &flags) == 0)
+ {
+ printk(KERN_INFO "PCI: Found %s HT MSI Mapping on %s\n",
+ flags & HT_MSI_FLAGS_ENABLE ?
+ "enabled" : "disabled", pci_name(dev));
+ return (flags & HT_MSI_FLAGS_ENABLE) != 0;
}
+
+ pos = pci_find_next_ht_capability(dev, pos,
+ HT_CAPTYPE_MSI_MAPPING);
}
return 0;
}
@@ -1688,8 +1760,9 @@ static void __devinit quirk_nvidia_ck804_msi_ht_cap(struct pci_dev *dev)
* a single one having MSI is enough to be sure that MSI are supported.
*/
pdev = pci_get_slot(dev->bus, 0);
- if (dev->subordinate && !msi_ht_cap_enabled(dev)
- && !msi_ht_cap_enabled(pdev)) {
+ if (!pdev)
+ return;
+ if (!msi_ht_cap_enabled(dev) && !msi_ht_cap_enabled(pdev)) {
printk(KERN_WARNING "PCI: MSI quirk detected. "
"MSI disabled on chipset %s.\n",
pci_name(dev));
diff --git a/drivers/pci/search.c b/drivers/pci/search.c
index 2f13eba5d5ae..45f2b20ef513 100644
--- a/drivers/pci/search.c
+++ b/drivers/pci/search.c
@@ -413,6 +413,24 @@ exit:
return dev;
}
+const struct pci_device_id *pci_find_present(const struct pci_device_id *ids)
+{
+ struct pci_dev *dev;
+ const struct pci_device_id *found = NULL;
+
+ WARN_ON(in_interrupt());
+ down_read(&pci_bus_sem);
+ while (ids->vendor || ids->subvendor || ids->class_mask) {
+ list_for_each_entry(dev, &pci_devices, global_list) {
+ if ((found = pci_match_one_device(ids, dev)) != NULL)
+ break;
+ }
+ ids++;
+ }
+ up_read(&pci_bus_sem);
+ return found;
+}
+
/**
* pci_dev_present - Returns 1 if device matching the device list is present, 0 if not.
* @ids: A pointer to a null terminated list of struct pci_device_id structures
@@ -426,25 +444,11 @@ exit:
*/
int pci_dev_present(const struct pci_device_id *ids)
{
- struct pci_dev *dev;
- int found = 0;
-
- WARN_ON(in_interrupt());
- down_read(&pci_bus_sem);
- while (ids->vendor || ids->subvendor || ids->class_mask) {
- list_for_each_entry(dev, &pci_devices, global_list) {
- if (pci_match_one_device(ids, dev)) {
- found = 1;
- goto exit;
- }
- }
- ids++;
- }
-exit:
- up_read(&pci_bus_sem);
- return found;
+ return pci_find_present(ids) == NULL ? 0 : 1;
}
+
EXPORT_SYMBOL(pci_dev_present);
+EXPORT_SYMBOL(pci_find_present);
EXPORT_SYMBOL(pci_find_device);
EXPORT_SYMBOL(pci_find_device_reverse);
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 8f7bcf56f149..89f3036f0de8 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -41,7 +41,7 @@
* have a P2P bridge below a cardbus bridge, we need 4K.
*/
#define CARDBUS_IO_SIZE (256)
-#define CARDBUS_MEM_SIZE (32*1024*1024)
+#define CARDBUS_MEM_SIZE (64*1024*1024)
static void __devinit
pbus_assign_resources_sorted(struct pci_bus *bus)
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
index ab78e4bbdd83..cb4ced3560e9 100644
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -33,11 +33,22 @@ pci_update_resource(struct pci_dev *dev, struct resource *res, int resno)
u32 new, check, mask;
int reg;
- /* Ignore resources for unimplemented BARs and unused resource slots
- for 64 bit BARs. */
+ /*
+ * Ignore resources for unimplemented BARs and unused resource slots
+ * for 64 bit BARs.
+ */
if (!res->flags)
return;
+ /*
+ * Ignore non-moveable resources. This might be legacy resources for
+ * which no functional BAR register exists or another important
+ * system resource we should better not move around in system address
+ * space.
+ */
+ if (res->flags & IORESOURCE_PCI_FIXED)
+ return;
+
pcibios_resource_to_bus(dev, &region, res);
pr_debug(" got res [%llx:%llx] bus [%lx:%lx] flags %lx for "
@@ -212,6 +223,10 @@ pdev_sort_resources(struct pci_dev *dev, struct resource_list *head)
resource_size_t r_align;
r = &dev->resource[i];
+
+ if (r->flags & IORESOURCE_PCI_FIXED)
+ continue;
+
r_align = r->end - r->start;
if (!(r->flags) || r->parent)
diff --git a/drivers/pcmcia/at91_cf.c b/drivers/pcmcia/at91_cf.c
index 52d4a38b3667..3334f22a86c0 100644
--- a/drivers/pcmcia/at91_cf.c
+++ b/drivers/pcmcia/at91_cf.c
@@ -230,7 +230,7 @@ static int __init at91_cf_probe(struct platform_device *pdev)
if (!io)
return -ENODEV;
- cf = kcalloc(1, sizeof *cf, GFP_KERNEL);
+ cf = kzalloc(sizeof *cf, GFP_KERNEL);
if (!cf)
return -ENOMEM;
diff --git a/drivers/pcmcia/omap_cf.c b/drivers/pcmcia/omap_cf.c
index 06bf7f48836e..e65a6b8188f6 100644
--- a/drivers/pcmcia/omap_cf.c
+++ b/drivers/pcmcia/omap_cf.c
@@ -220,7 +220,7 @@ static int __devinit omap_cf_probe(struct device *dev)
if (irq < 0)
return -EINVAL;
- cf = kcalloc(1, sizeof *cf, GFP_KERNEL);
+ cf = kzalloc(sizeof *cf, GFP_KERNEL);
if (!cf)
return -ENOMEM;
init_timer(&cf->timer);
diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c
index 3ac5b123215a..a0b158704ca1 100644
--- a/drivers/pnp/isapnp/core.c
+++ b/drivers/pnp/isapnp/core.c
@@ -395,7 +395,7 @@ static void isapnp_parse_id(struct pnp_dev * dev, unsigned short vendor, unsigne
struct pnp_id * id;
if (!dev)
return;
- id = kcalloc(1, sizeof(struct pnp_id), GFP_KERNEL);
+ id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL);
if (!id)
return;
sprintf(id->id, "%c%c%c%x%x%x%x",
@@ -419,7 +419,7 @@ static struct pnp_dev * __init isapnp_parse_device(struct pnp_card *card, int si
struct pnp_dev *dev;
isapnp_peek(tmp, size);
- dev = kcalloc(1, sizeof(struct pnp_dev), GFP_KERNEL);
+ dev = kzalloc(sizeof(struct pnp_dev), GFP_KERNEL);
if (!dev)
return NULL;
dev->number = number;
@@ -450,7 +450,7 @@ static void __init isapnp_parse_irq_resource(struct pnp_option *option,
unsigned long bits;
isapnp_peek(tmp, size);
- irq = kcalloc(1, sizeof(struct pnp_irq), GFP_KERNEL);
+ irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
if (!irq)
return;
bits = (tmp[1] << 8) | tmp[0];
@@ -474,7 +474,7 @@ static void __init isapnp_parse_dma_resource(struct pnp_option *option,
struct pnp_dma *dma;
isapnp_peek(tmp, size);
- dma = kcalloc(1, sizeof(struct pnp_dma), GFP_KERNEL);
+ dma = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL);
if (!dma)
return;
dma->map = tmp[0];
@@ -494,7 +494,7 @@ static void __init isapnp_parse_port_resource(struct pnp_option *option,
struct pnp_port *port;
isapnp_peek(tmp, size);
- port = kcalloc(1, sizeof(struct pnp_port), GFP_KERNEL);
+ port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
if (!port)
return;
port->min = (tmp[2] << 8) | tmp[1];
@@ -517,7 +517,7 @@ static void __init isapnp_parse_fixed_port_resource(struct pnp_option *option,
struct pnp_port *port;
isapnp_peek(tmp, size);
- port = kcalloc(1, sizeof(struct pnp_port), GFP_KERNEL);
+ port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
if (!port)
return;
port->min = port->max = (tmp[1] << 8) | tmp[0];
@@ -539,7 +539,7 @@ static void __init isapnp_parse_mem_resource(struct pnp_option *option,
struct pnp_mem *mem;
isapnp_peek(tmp, size);
- mem = kcalloc(1, sizeof(struct pnp_mem), GFP_KERNEL);
+ mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
if (!mem)
return;
mem->min = ((tmp[2] << 8) | tmp[1]) << 8;
@@ -562,7 +562,7 @@ static void __init isapnp_parse_mem32_resource(struct pnp_option *option,
struct pnp_mem *mem;
isapnp_peek(tmp, size);
- mem = kcalloc(1, sizeof(struct pnp_mem), GFP_KERNEL);
+ mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
if (!mem)
return;
mem->min = (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1];
@@ -584,7 +584,7 @@ static void __init isapnp_parse_fixed_mem32_resource(struct pnp_option *option,
struct pnp_mem *mem;
isapnp_peek(tmp, size);
- mem = kcalloc(1, sizeof(struct pnp_mem), GFP_KERNEL);
+ mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
if (!mem)
return;
mem->min = mem->max = (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1];
@@ -829,7 +829,7 @@ static unsigned char __init isapnp_checksum(unsigned char *data)
static void isapnp_parse_card_id(struct pnp_card * card, unsigned short vendor, unsigned short device)
{
- struct pnp_id * id = kcalloc(1, sizeof(struct pnp_id), GFP_KERNEL);
+ struct pnp_id * id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL);
if (!id)
return;
sprintf(id->id, "%c%c%c%x%x%x%x",
@@ -865,7 +865,7 @@ static int __init isapnp_build_device_list(void)
header[4], header[5], header[6], header[7], header[8]);
printk(KERN_DEBUG "checksum = 0x%x\n", checksum);
#endif
- if ((card = kcalloc(1, sizeof(struct pnp_card), GFP_KERNEL)) == NULL)
+ if ((card = kzalloc(sizeof(struct pnp_card), GFP_KERNEL)) == NULL)
continue;
card->number = csn;
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c
index 6cf34a63c790..62eda5d59024 100644
--- a/drivers/pnp/pnpacpi/core.c
+++ b/drivers/pnp/pnpacpi/core.c
@@ -139,7 +139,7 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
return 0;
pnp_dbg("ACPI device : hid %s", acpi_device_hid(device));
- dev = kcalloc(1, sizeof(struct pnp_dev), GFP_KERNEL);
+ dev = kzalloc(sizeof(struct pnp_dev), GFP_KERNEL);
if (!dev) {
pnp_err("Out of memory");
return -ENOMEM;
@@ -169,7 +169,7 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
dev->number = num;
/* set the initial values for the PnP device */
- dev_id = kcalloc(1, sizeof(struct pnp_id), GFP_KERNEL);
+ dev_id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL);
if (!dev_id)
goto err;
pnpidacpi_to_pnpid(acpi_device_hid(device), dev_id->id);
@@ -201,7 +201,7 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
for (i = 0; i < cid_list->count; i++) {
if (!ispnpidacpi(cid_list->id[i].value))
continue;
- dev_id = kcalloc(1, sizeof(struct pnp_id), GFP_KERNEL);
+ dev_id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL);
if (!dev_id)
continue;
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c
index 379048fdf05d..7a535542fe92 100644
--- a/drivers/pnp/pnpacpi/rsparser.c
+++ b/drivers/pnp/pnpacpi/rsparser.c
@@ -298,7 +298,7 @@ static void pnpacpi_parse_dma_option(struct pnp_option *option, struct acpi_reso
if (p->channel_count == 0)
return;
- dma = kcalloc(1, sizeof(struct pnp_dma), GFP_KERNEL);
+ dma = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL);
if (!dma)
return;
@@ -354,7 +354,7 @@ static void pnpacpi_parse_irq_option(struct pnp_option *option,
if (p->interrupt_count == 0)
return;
- irq = kcalloc(1, sizeof(struct pnp_irq), GFP_KERNEL);
+ irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
if (!irq)
return;
@@ -375,7 +375,7 @@ static void pnpacpi_parse_ext_irq_option(struct pnp_option *option,
if (p->interrupt_count == 0)
return;
- irq = kcalloc(1, sizeof(struct pnp_irq), GFP_KERNEL);
+ irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
if (!irq)
return;
@@ -396,7 +396,7 @@ pnpacpi_parse_port_option(struct pnp_option *option,
if (io->address_length == 0)
return;
- port = kcalloc(1, sizeof(struct pnp_port), GFP_KERNEL);
+ port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
if (!port)
return;
port->min = io->minimum;
@@ -417,7 +417,7 @@ pnpacpi_parse_fixed_port_option(struct pnp_option *option,
if (io->address_length == 0)
return;
- port = kcalloc(1, sizeof(struct pnp_port), GFP_KERNEL);
+ port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
if (!port)
return;
port->min = port->max = io->address;
@@ -436,7 +436,7 @@ pnpacpi_parse_mem24_option(struct pnp_option *option,
if (p->address_length == 0)
return;
- mem = kcalloc(1, sizeof(struct pnp_mem), GFP_KERNEL);
+ mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
if (!mem)
return;
mem->min = p->minimum;
@@ -459,7 +459,7 @@ pnpacpi_parse_mem32_option(struct pnp_option *option,
if (p->address_length == 0)
return;
- mem = kcalloc(1, sizeof(struct pnp_mem), GFP_KERNEL);
+ mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
if (!mem)
return;
mem->min = p->minimum;
@@ -482,7 +482,7 @@ pnpacpi_parse_fixed_mem32_option(struct pnp_option *option,
if (p->address_length == 0)
return;
- mem = kcalloc(1, sizeof(struct pnp_mem), GFP_KERNEL);
+ mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
if (!mem)
return;
mem->min = mem->max = p->address;
@@ -514,7 +514,7 @@ pnpacpi_parse_address_option(struct pnp_option *option, struct acpi_resource *r)
return;
if (p->resource_type == ACPI_MEMORY_RANGE) {
- mem = kcalloc(1, sizeof(struct pnp_mem), GFP_KERNEL);
+ mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
if (!mem)
return;
mem->min = mem->max = p->minimum;
@@ -524,7 +524,7 @@ pnpacpi_parse_address_option(struct pnp_option *option, struct acpi_resource *r)
ACPI_READ_WRITE_MEMORY) ? IORESOURCE_MEM_WRITEABLE : 0;
pnp_register_mem_resource(option, mem);
} else if (p->resource_type == ACPI_IO_RANGE) {
- port = kcalloc(1, sizeof(struct pnp_port), GFP_KERNEL);
+ port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
if (!port)
return;
port->min = port->max = p->minimum;
@@ -721,7 +721,7 @@ int pnpacpi_build_resource_template(acpi_handle handle,
if (!res_cnt)
return -EINVAL;
buffer->length = sizeof(struct acpi_resource) * (res_cnt + 1) + 1;
- buffer->pointer = kcalloc(1, buffer->length - 1, GFP_KERNEL);
+ buffer->pointer = kzalloc(buffer->length - 1, GFP_KERNEL);
if (!buffer->pointer)
return -ENOMEM;
pnp_dbg("Res cnt %d", res_cnt);
diff --git a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c
index 33adeba1a31f..95738dbd5d45 100644
--- a/drivers/pnp/pnpbios/core.c
+++ b/drivers/pnp/pnpbios/core.c
@@ -109,10 +109,10 @@ static int pnp_dock_event(int dock, struct pnp_docking_station_info *info)
if (!current->fs->root) {
return -EAGAIN;
}
- if (!(envp = (char **) kcalloc (20, sizeof (char *), GFP_KERNEL))) {
+ if (!(envp = kcalloc(20, sizeof (char *), GFP_KERNEL))) {
return -ENOMEM;
}
- if (!(buf = kcalloc (1, 256, GFP_KERNEL))) {
+ if (!(buf = kzalloc(256, GFP_KERNEL))) {
kfree (envp);
return -ENOMEM;
}
@@ -220,7 +220,7 @@ static int pnpbios_get_resources(struct pnp_dev * dev, struct pnp_resource_table
if(!pnpbios_is_dynamic(dev))
return -EPERM;
- node = kcalloc(1, node_info.max_node_size, GFP_KERNEL);
+ node = kzalloc(node_info.max_node_size, GFP_KERNEL);
if (!node)
return -1;
if (pnp_bios_get_dev_node(&nodenum, (char )PNPMODE_DYNAMIC, node)) {
@@ -243,7 +243,7 @@ static int pnpbios_set_resources(struct pnp_dev * dev, struct pnp_resource_table
if (!pnpbios_is_dynamic(dev))
return -EPERM;
- node = kcalloc(1, node_info.max_node_size, GFP_KERNEL);
+ node = kzalloc(node_info.max_node_size, GFP_KERNEL);
if (!node)
return -1;
if (pnp_bios_get_dev_node(&nodenum, (char )PNPMODE_DYNAMIC, node)) {
@@ -294,7 +294,7 @@ static int pnpbios_disable_resources(struct pnp_dev *dev)
if(dev->flags & PNPBIOS_NO_DISABLE || !pnpbios_is_dynamic(dev))
return -EPERM;
- node = kcalloc(1, node_info.max_node_size, GFP_KERNEL);
+ node = kzalloc(node_info.max_node_size, GFP_KERNEL);
if (!node)
return -ENOMEM;
@@ -336,7 +336,7 @@ static int insert_device(struct pnp_dev *dev, struct pnp_bios_node * node)
}
/* set the initial values for the PnP device */
- dev_id = kcalloc(1, sizeof(struct pnp_id), GFP_KERNEL);
+ dev_id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL);
if (!dev_id)
return -1;
pnpid32_to_pnpid(node->eisa_id,id);
@@ -374,7 +374,7 @@ static void __init build_devlist(void)
struct pnp_bios_node *node;
struct pnp_dev *dev;
- node = kcalloc(1, node_info.max_node_size, GFP_KERNEL);
+ node = kzalloc(node_info.max_node_size, GFP_KERNEL);
if (!node)
return;
@@ -391,7 +391,7 @@ static void __init build_devlist(void)
break;
}
nodes_got++;
- dev = kcalloc(1, sizeof (struct pnp_dev), GFP_KERNEL);
+ dev = kzalloc(sizeof (struct pnp_dev), GFP_KERNEL);
if (!dev)
break;
if(insert_device(dev,node)<0)
diff --git a/drivers/pnp/pnpbios/proc.c b/drivers/pnp/pnpbios/proc.c
index 5a3dfc97f5e9..8027073f7919 100644
--- a/drivers/pnp/pnpbios/proc.c
+++ b/drivers/pnp/pnpbios/proc.c
@@ -87,7 +87,7 @@ static int proc_read_escd(char *buf, char **start, off_t pos,
return -EFBIG;
}
- tmpbuf = kcalloc(1, escd.escd_size, GFP_KERNEL);
+ tmpbuf = kzalloc(escd.escd_size, GFP_KERNEL);
if (!tmpbuf) return -ENOMEM;
if (pnp_bios_read_escd(tmpbuf, escd.nv_storage_base)) {
@@ -133,7 +133,7 @@ static int proc_read_devices(char *buf, char **start, off_t pos,
if (pos >= 0xff)
return 0;
- node = kcalloc(1, node_info.max_node_size, GFP_KERNEL);
+ node = kzalloc(node_info.max_node_size, GFP_KERNEL);
if (!node) return -ENOMEM;
for (nodenum=pos; nodenum<0xff; ) {
@@ -168,7 +168,7 @@ static int proc_read_node(char *buf, char **start, off_t pos,
u8 nodenum = (long)data;
int len;
- node = kcalloc(1, node_info.max_node_size, GFP_KERNEL);
+ node = kzalloc(node_info.max_node_size, GFP_KERNEL);
if (!node) return -ENOMEM;
if (pnp_bios_get_dev_node(&nodenum, boot, node)) {
kfree(node);
@@ -188,7 +188,7 @@ static int proc_write_node(struct file *file, const char __user *buf,
u8 nodenum = (long)data;
int ret = count;
- node = kcalloc(1, node_info.max_node_size, GFP_KERNEL);
+ node = kzalloc(node_info.max_node_size, GFP_KERNEL);
if (!node)
return -ENOMEM;
if (pnp_bios_get_dev_node(&nodenum, boot, node)) {
diff --git a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c
index ef508a4de557..95b79685a9d1 100644
--- a/drivers/pnp/pnpbios/rsparser.c
+++ b/drivers/pnp/pnpbios/rsparser.c
@@ -248,7 +248,7 @@ static void
pnpbios_parse_mem_option(unsigned char *p, int size, struct pnp_option *option)
{
struct pnp_mem * mem;
- mem = kcalloc(1, sizeof(struct pnp_mem), GFP_KERNEL);
+ mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
if (!mem)
return;
mem->min = ((p[5] << 8) | p[4]) << 8;
@@ -264,7 +264,7 @@ static void
pnpbios_parse_mem32_option(unsigned char *p, int size, struct pnp_option *option)
{
struct pnp_mem * mem;
- mem = kcalloc(1, sizeof(struct pnp_mem), GFP_KERNEL);
+ mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
if (!mem)
return;
mem->min = (p[7] << 24) | (p[6] << 16) | (p[5] << 8) | p[4];
@@ -280,7 +280,7 @@ static void
pnpbios_parse_fixed_mem32_option(unsigned char *p, int size, struct pnp_option *option)
{
struct pnp_mem * mem;
- mem = kcalloc(1, sizeof(struct pnp_mem), GFP_KERNEL);
+ mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
if (!mem)
return;
mem->min = mem->max = (p[7] << 24) | (p[6] << 16) | (p[5] << 8) | p[4];
@@ -297,7 +297,7 @@ pnpbios_parse_irq_option(unsigned char *p, int size, struct pnp_option *option)
struct pnp_irq * irq;
unsigned long bits;
- irq = kcalloc(1, sizeof(struct pnp_irq), GFP_KERNEL);
+ irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
if (!irq)
return;
bits = (p[2] << 8) | p[1];
@@ -314,7 +314,7 @@ static void
pnpbios_parse_dma_option(unsigned char *p, int size, struct pnp_option *option)
{
struct pnp_dma * dma;
- dma = kcalloc(1, sizeof(struct pnp_dma), GFP_KERNEL);
+ dma = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL);
if (!dma)
return;
dma->map = p[1];
@@ -327,7 +327,7 @@ static void
pnpbios_parse_port_option(unsigned char *p, int size, struct pnp_option *option)
{
struct pnp_port * port;
- port = kcalloc(1, sizeof(struct pnp_port), GFP_KERNEL);
+ port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
if (!port)
return;
port->min = (p[3] << 8) | p[2];
@@ -343,7 +343,7 @@ static void
pnpbios_parse_fixed_port_option(unsigned char *p, int size, struct pnp_option *option)
{
struct pnp_port * port;
- port = kcalloc(1, sizeof(struct pnp_port), GFP_KERNEL);
+ port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
if (!port)
return;
port->min = port->max = (p[2] << 8) | p[1];
@@ -527,7 +527,7 @@ pnpbios_parse_compatible_ids(unsigned char *p, unsigned char *end, struct pnp_de
case SMALL_TAG_COMPATDEVID: /* compatible ID */
if (len != 4)
goto len_err;
- dev_id = kcalloc(1, sizeof (struct pnp_id), GFP_KERNEL);
+ dev_id = kzalloc(sizeof (struct pnp_id), GFP_KERNEL);
if (!dev_id)
return NULL;
memset(dev_id, 0, sizeof(struct pnp_id));
diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c
index 5c8addcaf1fb..4f654c901c64 100644
--- a/drivers/rtc/rtc-at91rm9200.c
+++ b/drivers/rtc/rtc-at91rm9200.c
@@ -137,6 +137,9 @@ static int at91_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year);
tm->tm_year = at91_alarm_year - 1900;
+ alrm->enabled = (at91_sys_read(AT91_RTC_IMR) & AT91_RTC_ALARM)
+ ? 1 : 0;
+
pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __FUNCTION__,
1900 + tm->tm_year, tm->tm_mon, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
@@ -223,8 +226,6 @@ static int at91_rtc_proc(struct device *dev, struct seq_file *seq)
{
unsigned long imr = at91_sys_read(AT91_RTC_IMR);
- seq_printf(seq, "alarm_IRQ\t: %s\n",
- (imr & AT91_RTC_ALARM) ? "yes" : "no");
seq_printf(seq, "update_IRQ\t: %s\n",
(imr & AT91_RTC_ACKUPD) ? "yes" : "no");
seq_printf(seq, "periodic_IRQ\t: %s\n",
diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c
index 828b329e08e0..94d3df62a5fa 100644
--- a/drivers/rtc/rtc-dev.c
+++ b/drivers/rtc/rtc-dev.c
@@ -435,7 +435,7 @@ static int rtc_dev_add_device(struct class_device *class_dev,
goto err_cdev_del;
}
- dev_info(class_dev->dev, "rtc intf: dev (%d:%d)\n",
+ dev_dbg(class_dev->dev, "rtc intf: dev (%d:%d)\n",
MAJOR(rtc->rtc_dev->devt),
MINOR(rtc->rtc_dev->devt));
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index eac5fb1fc02f..d59880d44fba 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -279,9 +279,8 @@ static int omap_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
local_irq_enable();
bcd2tm(&alm->time);
- alm->pending = !!(rtc_read(OMAP_RTC_INTERRUPTS_REG)
+ alm->enabled = !!(rtc_read(OMAP_RTC_INTERRUPTS_REG)
& OMAP_RTC_INTERRUPTS_IT_ALARM);
- alm->enabled = alm->pending && device_may_wakeup(dev);
return 0;
}
diff --git a/drivers/rtc/rtc-proc.c b/drivers/rtc/rtc-proc.c
index d51d8f20e634..c272afd62173 100644
--- a/drivers/rtc/rtc-proc.c
+++ b/drivers/rtc/rtc-proc.c
@@ -65,7 +65,7 @@ static int rtc_proc_show(struct seq_file *seq, void *offset)
seq_printf(seq, "%02d\n", alrm.time.tm_mday);
else
seq_printf(seq, "**\n");
- seq_printf(seq, "alrm_wakeup\t: %s\n",
+ seq_printf(seq, "alarm_IRQ\t: %s\n",
alrm.enabled ? "yes" : "no");
seq_printf(seq, "alrm_pending\t: %s\n",
alrm.pending ? "yes" : "no");
@@ -120,7 +120,7 @@ static int rtc_proc_add_device(struct class_device *class_dev,
ent->owner = rtc->owner;
ent->data = class_dev;
- dev_info(class_dev->dev, "rtc intf: proc\n");
+ dev_dbg(class_dev->dev, "rtc intf: proc\n");
}
else
rtc_dev = NULL;
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c
index e301dea57bb3..f406a2b55aea 100644
--- a/drivers/rtc/rtc-s3c.c
+++ b/drivers/rtc/rtc-s3c.c
@@ -191,6 +191,8 @@ static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm)
alm_en = readb(base + S3C2410_RTCALM);
+ alrm->enabled = (alm_en & S3C2410_RTCALM_ALMEN) ? 1 : 0;
+
pr_debug("read alarm %02x %02x.%02x.%02x %02x/%02x/%02x\n",
alm_en,
alm_tm->tm_year, alm_tm->tm_mon, alm_tm->tm_mday,
@@ -331,12 +333,8 @@ static int s3c_rtc_ioctl(struct device *dev,
static int s3c_rtc_proc(struct device *dev, struct seq_file *seq)
{
- unsigned int rtcalm = readb(s3c_rtc_base + S3C2410_RTCALM);
unsigned int ticnt = readb(s3c_rtc_base + S3C2410_TICNT);
- seq_printf(seq, "alarm_IRQ\t: %s\n",
- (rtcalm & S3C2410_RTCALM_ALMEN) ? "yes" : "no" );
-
seq_printf(seq, "periodic_IRQ\t: %s\n",
(ticnt & S3C2410_TICNT_ENABLE) ? "yes" : "no" );
diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c
index bd4d7d174ef4..9c8ead43a59c 100644
--- a/drivers/rtc/rtc-sa1100.c
+++ b/drivers/rtc/rtc-sa1100.c
@@ -289,9 +289,7 @@ static int sa1100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
static int sa1100_rtc_proc(struct device *dev, struct seq_file *seq)
{
- seq_printf(seq, "trim/divider\t: 0x%08lx\n", RTTR);
- seq_printf(seq, "alarm_IRQ\t: %s\n",
- (RTSR & RTSR_ALE) ? "yes" : "no" );
+ seq_printf(seq, "trim/divider\t: 0x%08x\n", (u32) RTTR);
seq_printf(seq, "update_IRQ\t: %s\n",
(RTSR & RTSR_HZE) ? "yes" : "no");
seq_printf(seq, "periodic_IRQ\t: %s\n",
diff --git a/drivers/rtc/rtc-sysfs.c b/drivers/rtc/rtc-sysfs.c
index 625637b84d33..9418a59fb368 100644
--- a/drivers/rtc/rtc-sysfs.c
+++ b/drivers/rtc/rtc-sysfs.c
@@ -83,7 +83,7 @@ static int __devinit rtc_sysfs_add_device(struct class_device *class_dev,
{
int err;
- dev_info(class_dev->dev, "rtc intf: sysfs\n");
+ dev_dbg(class_dev->dev, "rtc intf: sysfs\n");
err = sysfs_create_group(&class_dev->kobj, &rtc_attr_group);
if (err)
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c
index c9321b920e90..25b5d7a66417 100644
--- a/drivers/s390/char/con3215.c
+++ b/drivers/s390/char/con3215.c
@@ -688,7 +688,7 @@ raw3215_probe (struct ccw_device *cdev)
raw->cdev = cdev;
raw->inbuf = (char *) raw + sizeof(struct raw3215_info);
memset(raw, 0, sizeof(struct raw3215_info));
- raw->buffer = (char *) kmalloc(RAW3215_BUFFER_SIZE,
+ raw->buffer = kmalloc(RAW3215_BUFFER_SIZE,
GFP_KERNEL|GFP_DMA);
if (raw->buffer == NULL) {
spin_lock(&raw3215_device_lock);
diff --git a/drivers/s390/char/keyboard.c b/drivers/s390/char/keyboard.c
index e3491a5f5219..3e86fd1756e5 100644
--- a/drivers/s390/char/keyboard.c
+++ b/drivers/s390/char/keyboard.c
@@ -377,7 +377,7 @@ do_kdsk_ioctl(struct kbd_data *kbd, struct kbentry __user *user_kbe,
if (!(key_map = kbd->key_maps[tmp.kb_table])) {
int j;
- key_map = (ushort *) kmalloc(sizeof(plain_map),
+ key_map = kmalloc(sizeof(plain_map),
GFP_KERNEL);
if (!key_map)
return -ENOMEM;
diff --git a/drivers/s390/char/monwriter.c b/drivers/s390/char/monwriter.c
index b9b0fc3f812b..cdb24f528112 100644
--- a/drivers/s390/char/monwriter.c
+++ b/drivers/s390/char/monwriter.c
@@ -23,7 +23,7 @@
#include <asm/appldata.h>
#include <asm/monwriter.h>
-#define MONWRITE_MAX_DATALEN 4024
+#define MONWRITE_MAX_DATALEN 4010
static int mon_max_bufs = 255;
static int mon_buf_count;
diff --git a/drivers/s390/char/sclp_cpi.c b/drivers/s390/char/sclp_cpi.c
index 732dfbdb85c4..4f873ae148b7 100644
--- a/drivers/s390/char/sclp_cpi.c
+++ b/drivers/s390/char/sclp_cpi.c
@@ -49,6 +49,8 @@ static struct sclp_register sclp_cpi_event =
.send_mask = EvTyp_CtlProgIdent_Mask
};
+MODULE_LICENSE("GPL");
+
MODULE_AUTHOR(
"Martin Peschke, IBM Deutschland Entwicklung GmbH "
"<mpeschke@de.ibm.com>");
@@ -127,7 +129,7 @@ cpi_prepare_req(void)
struct cpi_sccb *sccb;
struct cpi_evbuf *evb;
- req = (struct sclp_req *) kmalloc(sizeof(struct sclp_req), GFP_KERNEL);
+ req = kmalloc(sizeof(struct sclp_req), GFP_KERNEL);
if (req == NULL)
return ERR_PTR(-ENOMEM);
sccb = (struct cpi_sccb *) __get_free_page(GFP_KERNEL | GFP_DMA);
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index 7835a714a405..b471ac4a1bf6 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -2,8 +2,7 @@
* drivers/s390/cio/cio.c
* S/390 common I/O routines -- low level i/o calls
*
- * Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
- * IBM Corporation
+ * Copyright (C) IBM Corp. 1999,2006
* Author(s): Ingo Adlung (adlung@de.ibm.com)
* Cornelia Huck (cornelia.huck@de.ibm.com)
* Arnd Bergmann (arndb@de.ibm.com)
@@ -871,11 +870,40 @@ __clear_subchannel_easy(struct subchannel_id schid)
return -EBUSY;
}
+static int pgm_check_occured;
+
+static void cio_reset_pgm_check_handler(void)
+{
+ pgm_check_occured = 1;
+}
+
+static int stsch_reset(struct subchannel_id schid, volatile struct schib *addr)
+{
+ int rc;
+ register struct subchannel_id reg1 asm ("1") = schid;
+
+ pgm_check_occured = 0;
+ s390_reset_pgm_handler = cio_reset_pgm_check_handler;
+
+ asm volatile(
+ " stsch 0(%2)\n"
+ " ipm %0\n"
+ " srl %0,28"
+ : "=d" (rc)
+ : "d" (reg1), "a" (addr), "m" (*addr) : "memory", "cc");
+
+ s390_reset_pgm_handler = NULL;
+ if (pgm_check_occured)
+ return -EIO;
+ else
+ return rc;
+}
+
static int __shutdown_subchannel_easy(struct subchannel_id schid, void *data)
{
struct schib schib;
- if (stsch_err(schid, &schib))
+ if (stsch_reset(schid, &schib))
return -ENXIO;
if (!schib.pmcw.ena)
return 0;
@@ -972,7 +1000,7 @@ static int __reipl_subchannel_match(struct subchannel_id schid, void *data)
struct schib schib;
struct sch_match_id *match_id = data;
- if (stsch_err(schid, &schib))
+ if (stsch_reset(schid, &schib))
return -ENXIO;
if (schib.pmcw.dnv &&
(schib.pmcw.dev == match_id->devid.devno) &&
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 4c81d890791e..9d6c02446863 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -139,6 +139,8 @@ css_register_subchannel(struct subchannel *sch)
sch->dev.release = &css_subchannel_release;
sch->dev.groups = subch_attr_groups;
+ css_get_ssd_info(sch);
+
/* make it known to the system */
ret = css_sch_device_register(sch);
if (ret) {
@@ -146,7 +148,6 @@ css_register_subchannel(struct subchannel *sch)
__func__, sch->dev.bus_id);
return ret;
}
- css_get_ssd_info(sch);
return ret;
}
diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c
index 9d4ea449a608..6fd1940842eb 100644
--- a/drivers/s390/cio/qdio.c
+++ b/drivers/s390/cio/qdio.c
@@ -979,12 +979,11 @@ __qdio_outbound_processing(struct qdio_q *q)
if (q->is_iqdio_q) {
/*
- * for asynchronous queues, we better check, if the fill
- * level is too high. for synchronous queues, the fill
- * level will never be that high.
+ * for asynchronous queues, we better check, if the sent
+ * buffer is already switched from PRIMED to EMPTY.
*/
- if (atomic_read(&q->number_of_buffers_used)>
- IQDIO_FILL_LEVEL_TO_POLL)
+ if ((q->queue_type == QDIO_IQDIO_QFMT_ASYNCH) &&
+ !qdio_is_outbound_q_done(q))
qdio_mark_q(q);
} else if (!q->hydra_gives_outbound_pcis)
@@ -1825,6 +1824,10 @@ qdio_fill_qs(struct qdio_irq *irq_ptr, struct ccw_device *cdev,
q->sbal[j]=*(outbound_sbals_array++);
q->queue_type=q_format;
+ if ((q->queue_type == QDIO_IQDIO_QFMT) &&
+ (no_output_qs > 1) &&
+ (i == no_output_qs-1))
+ q->queue_type = QDIO_IQDIO_QFMT_ASYNCH;
q->int_parm=int_parm;
q->is_input_q=0;
q->schid = irq_ptr->schid;
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
index ad60afe5dd11..81b5899f4010 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -1129,7 +1129,15 @@ static void ap_poll_thread_stop(void)
mutex_unlock(&ap_poll_thread_mutex);
}
-static void ap_reset(void)
+static void ap_reset_domain(void)
+{
+ int i;
+
+ for (i = 0; i < AP_DEVICES; i++)
+ ap_reset_queue(AP_MKQID(i, ap_domain_index));
+}
+
+static void ap_reset_all(void)
{
int i, j;
@@ -1139,7 +1147,7 @@ static void ap_reset(void)
}
static struct reset_call ap_reset_call = {
- .fn = ap_reset,
+ .fn = ap_reset_all,
};
/**
@@ -1229,10 +1237,12 @@ void ap_module_exit(void)
int i;
struct device *dev;
+ ap_reset_domain();
ap_poll_thread_stop();
del_timer_sync(&ap_config_timer);
del_timer_sync(&ap_poll_timer);
destroy_workqueue(ap_work_queue);
+ tasklet_kill(&ap_tasklet);
s390_root_dev_unregister(ap_root_device);
while ((dev = bus_find_device(&ap_bus_type, NULL, NULL,
__ap_match_all)))
diff --git a/drivers/s390/crypto/zcrypt_cex2a.c b/drivers/s390/crypto/zcrypt_cex2a.c
index a62b00083d0c..5bb13a9d0898 100644
--- a/drivers/s390/crypto/zcrypt_cex2a.c
+++ b/drivers/s390/crypto/zcrypt_cex2a.c
@@ -295,7 +295,7 @@ static long zcrypt_cex2a_modexpo(struct zcrypt_device *zdev,
struct completion work;
int rc;
- ap_msg.message = (void *) kmalloc(CEX2A_MAX_MESSAGE_SIZE, GFP_KERNEL);
+ ap_msg.message = kmalloc(CEX2A_MAX_MESSAGE_SIZE, GFP_KERNEL);
if (!ap_msg.message)
return -ENOMEM;
ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
@@ -337,7 +337,7 @@ static long zcrypt_cex2a_modexpo_crt(struct zcrypt_device *zdev,
struct completion work;
int rc;
- ap_msg.message = (void *) kmalloc(CEX2A_MAX_MESSAGE_SIZE, GFP_KERNEL);
+ ap_msg.message = kmalloc(CEX2A_MAX_MESSAGE_SIZE, GFP_KERNEL);
if (!ap_msg.message)
return -ENOMEM;
ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
diff --git a/drivers/s390/crypto/zcrypt_pcica.c b/drivers/s390/crypto/zcrypt_pcica.c
index b6a4ecdc8025..32e37014345c 100644
--- a/drivers/s390/crypto/zcrypt_pcica.c
+++ b/drivers/s390/crypto/zcrypt_pcica.c
@@ -279,7 +279,7 @@ static long zcrypt_pcica_modexpo(struct zcrypt_device *zdev,
struct completion work;
int rc;
- ap_msg.message = (void *) kmalloc(PCICA_MAX_MESSAGE_SIZE, GFP_KERNEL);
+ ap_msg.message = kmalloc(PCICA_MAX_MESSAGE_SIZE, GFP_KERNEL);
if (!ap_msg.message)
return -ENOMEM;
ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
@@ -321,7 +321,7 @@ static long zcrypt_pcica_modexpo_crt(struct zcrypt_device *zdev,
struct completion work;
int rc;
- ap_msg.message = (void *) kmalloc(PCICA_MAX_MESSAGE_SIZE, GFP_KERNEL);
+ ap_msg.message = kmalloc(PCICA_MAX_MESSAGE_SIZE, GFP_KERNEL);
if (!ap_msg.message)
return -ENOMEM;
ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
diff --git a/drivers/s390/crypto/zcrypt_pcixcc.c b/drivers/s390/crypto/zcrypt_pcixcc.c
index 2da8b9381407..b7153c1e15cd 100644
--- a/drivers/s390/crypto/zcrypt_pcixcc.c
+++ b/drivers/s390/crypto/zcrypt_pcixcc.c
@@ -717,7 +717,7 @@ long zcrypt_pcixcc_send_cprb(struct zcrypt_device *zdev, struct ica_xcRB *xcRB)
};
int rc;
- ap_msg.message = (void *) kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL);
+ ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL);
if (!ap_msg.message)
return -ENOMEM;
ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
diff --git a/drivers/s390/net/ctcmain.c b/drivers/s390/net/ctcmain.c
index 3257c22dd79c..03cc263fe0da 100644
--- a/drivers/s390/net/ctcmain.c
+++ b/drivers/s390/net/ctcmain.c
@@ -1646,7 +1646,7 @@ add_channel(struct ccw_device *cdev, enum channel_types type)
return -1;
}
memset(ch, 0, sizeof (struct channel));
- if ((ch->ccw = (struct ccw1 *) kmalloc(8*sizeof(struct ccw1),
+ if ((ch->ccw = kmalloc(8*sizeof(struct ccw1),
GFP_KERNEL | GFP_DMA)) == NULL) {
kfree(ch);
ctc_pr_warn("ctc: Out of memory in add_channel\n");
@@ -1693,7 +1693,7 @@ add_channel(struct ccw_device *cdev, enum channel_types type)
return -1;
}
fsm_newstate(ch->fsm, CH_STATE_IDLE);
- if ((ch->irb = (struct irb *) kmalloc(sizeof (struct irb),
+ if ((ch->irb = kmalloc(sizeof (struct irb),
GFP_KERNEL)) == NULL) {
ctc_pr_warn("ctc: Out of memory in add_channel\n");
kfree_fsm(ch->fsm);
@@ -2535,7 +2535,7 @@ ctc_print_statistics(struct ctc_priv *priv)
DBF_TEXT(trace, 4, __FUNCTION__);
if (!priv)
return;
- sbuf = (char *)kmalloc(2048, GFP_KERNEL);
+ sbuf = kmalloc(2048, GFP_KERNEL);
if (sbuf == NULL)
return;
p = sbuf;
diff --git a/drivers/s390/net/iucv.c b/drivers/s390/net/iucv.c
index 1476ce2b437c..229aeb5fc399 100644
--- a/drivers/s390/net/iucv.c
+++ b/drivers/s390/net/iucv.c
@@ -772,7 +772,7 @@ iucv_register_program (__u8 pgmname[16],
}
/* Allocate handler entry */
- new_handler = (handler *)kmalloc(sizeof(handler), GFP_ATOMIC);
+ new_handler = kmalloc(sizeof(handler), GFP_ATOMIC);
if (new_handler == NULL) {
printk(KERN_WARNING "%s: storage allocation for new handler "
"failed.\n", __FUNCTION__);
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index 5d39b2df0cc4..85093b71f9fa 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -237,7 +237,7 @@ zfcp_device_setup(char *devstr)
return 0;
len = strlen(devstr) + 1;
- str = (char *) kmalloc(len, GFP_KERNEL);
+ str = kmalloc(len, GFP_KERNEL);
if (!str)
goto err_out;
memcpy(str, devstr, len);
diff --git a/drivers/sbus/char/vfc_dev.c b/drivers/sbus/char/vfc_dev.c
index 2722af5d3404..386e7de0b7e3 100644
--- a/drivers/sbus/char/vfc_dev.c
+++ b/drivers/sbus/char/vfc_dev.c
@@ -659,7 +659,7 @@ static int vfc_probe(void)
if (!cards)
return -ENODEV;
- vfc_dev_lst = (struct vfc_dev **)kmalloc(sizeof(struct vfc_dev *) *
+ vfc_dev_lst = kmalloc(sizeof(struct vfc_dev *) *
(cards+1),
GFP_KERNEL);
if (vfc_dev_lst == NULL)
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index ac108f9e2674..426cd6f49f5d 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -288,7 +288,7 @@ int aac_get_containers(struct aac_dev *dev)
if (maximum_num_containers < MAXIMUM_NUM_CONTAINERS)
maximum_num_containers = MAXIMUM_NUM_CONTAINERS;
- fsa_dev_ptr = (struct fsa_dev_info *) kmalloc(
+ fsa_dev_ptr = kmalloc(
sizeof(*fsa_dev_ptr) * maximum_num_containers, GFP_KERNEL);
if (!fsa_dev_ptr) {
aac_fib_free(fibptr);
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c
index d5cf8b91a0e7..6d305b2f854e 100644
--- a/drivers/scsi/aacraid/comminit.c
+++ b/drivers/scsi/aacraid/comminit.c
@@ -386,7 +386,7 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
* Ok now init the communication subsystem
*/
- dev->queues = (struct aac_queue_block *) kmalloc(sizeof(struct aac_queue_block), GFP_KERNEL);
+ dev->queues = kmalloc(sizeof(struct aac_queue_block), GFP_KERNEL);
if (dev->queues == NULL) {
printk(KERN_ERR "Error could not allocate comm region.\n");
return NULL;
diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c
index d7a61a6bdaae..1d239f6c0103 100644
--- a/drivers/scsi/aha1542.c
+++ b/drivers/scsi/aha1542.c
@@ -699,7 +699,7 @@ static int aha1542_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
#endif
int i;
ccb[mbo].op = 2; /* SCSI Initiator Command w/scatter-gather */
- SCpnt->host_scribble = (unsigned char *) kmalloc(512, GFP_KERNEL | GFP_DMA);
+ SCpnt->host_scribble = kmalloc(512, GFP_KERNEL | GFP_DMA);
sgpnt = (struct scatterlist *) SCpnt->request_buffer;
cptr = (struct chain *) SCpnt->host_scribble;
if (cptr == NULL) {
diff --git a/drivers/scsi/aic7xxx_old.c b/drivers/scsi/aic7xxx_old.c
index 46eed10b25d9..7d1fec620948 100644
--- a/drivers/scsi/aic7xxx_old.c
+++ b/drivers/scsi/aic7xxx_old.c
@@ -2565,7 +2565,7 @@ aic7xxx_allocate_scb(struct aic7xxx_host *p)
}
}
scb_count = min( (i-1), p->scb_data->maxscbs - p->scb_data->numscbs);
- scb_ap = (struct aic7xxx_scb *)kmalloc(sizeof (struct aic7xxx_scb) * scb_count
+ scb_ap = kmalloc(sizeof (struct aic7xxx_scb) * scb_count
+ sizeof(struct aic7xxx_scb_dma), GFP_ATOMIC);
if (scb_ap == NULL)
return(0);
diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c
index e95b367d09ed..a965ed3548d5 100644
--- a/drivers/scsi/dc395x.c
+++ b/drivers/scsi/dc395x.c
@@ -4319,7 +4319,7 @@ static int __devinit adapter_sg_tables_alloc(struct AdapterCtlBlk *acb)
dprintkdbg(DBG_1, "Allocate %i pages for SG tables\n", pages);
while (pages--) {
- ptr = (struct SGentry *)kmalloc(PAGE_SIZE, GFP_KERNEL);
+ ptr = kmalloc(PAGE_SIZE, GFP_KERNEL);
if (!ptr) {
adapter_sg_tables_free(acb);
return 1;
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
index 60b1b434eba7..365db537a28d 100644
--- a/drivers/scsi/dpt_i2o.c
+++ b/drivers/scsi/dpt_i2o.c
@@ -297,7 +297,7 @@ static void adpt_inquiry(adpt_hba* pHba)
s32 rcode;
memset(msg, 0, sizeof(msg));
- buf = (u8*)kmalloc(80,GFP_KERNEL|ADDR32);
+ buf = kmalloc(80,GFP_KERNEL|ADDR32);
if(!buf){
printk(KERN_ERR"%s: Could not allocate buffer\n",pHba->name);
return;
@@ -1311,7 +1311,7 @@ static s32 adpt_i2o_reset_hba(adpt_hba* pHba)
schedule_timeout_uninterruptible(1);
} while (m == EMPTY_QUEUE);
- status = (u8*)kmalloc(4, GFP_KERNEL|ADDR32);
+ status = kmalloc(4, GFP_KERNEL|ADDR32);
if(status == NULL) {
adpt_send_nop(pHba, m);
printk(KERN_ERR"IOP reset failed - no free memory.\n");
@@ -1444,7 +1444,7 @@ static int adpt_i2o_parse_lct(adpt_hba* pHba)
}
continue;
}
- d = (struct i2o_device *)kmalloc(sizeof(struct i2o_device), GFP_KERNEL);
+ d = kmalloc(sizeof(struct i2o_device), GFP_KERNEL);
if(d==NULL)
{
printk(KERN_CRIT"%s: Out of memory for I2O device data.\n",pHba->name);
@@ -2425,7 +2425,7 @@ static s32 adpt_i2o_reparse_lct(adpt_hba* pHba)
pDev = pDev->next_lun;
}
if(!pDev ) { // Something new add it
- d = (struct i2o_device *)kmalloc(sizeof(struct i2o_device), GFP_KERNEL);
+ d = kmalloc(sizeof(struct i2o_device), GFP_KERNEL);
if(d==NULL)
{
printk(KERN_CRIT "Out of memory for I2O device data.\n");
@@ -2728,7 +2728,7 @@ static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba)
kfree(pHba->reply_pool);
- pHba->reply_pool = (u32*)kmalloc(pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4, GFP_KERNEL|ADDR32);
+ pHba->reply_pool = kmalloc(pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4, GFP_KERNEL|ADDR32);
if(!pHba->reply_pool){
printk(KERN_ERR"%s: Could not allocate reply pool\n",pHba->name);
return -1;
diff --git a/drivers/scsi/ibmvscsi/Makefile b/drivers/scsi/ibmvscsi/Makefile
index 6ac0633d5452..f67d9efc7a99 100644
--- a/drivers/scsi/ibmvscsi/Makefile
+++ b/drivers/scsi/ibmvscsi/Makefile
@@ -1,7 +1,9 @@
obj-$(CONFIG_SCSI_IBMVSCSI) += ibmvscsic.o
ibmvscsic-y += ibmvscsi.o
+ifndef CONFIG_PPC_PSERIES
ibmvscsic-$(CONFIG_PPC_ISERIES) += iseries_vscsi.o
+endif
ibmvscsic-$(CONFIG_PPC_PSERIES) += rpa_vscsi.o
obj-$(CONFIG_SCSI_IBMVSCSIS) += ibmvstgt.o
diff --git a/drivers/scsi/initio.c b/drivers/scsi/initio.c
index f160357e37a6..d561663fb4e4 100644
--- a/drivers/scsi/initio.c
+++ b/drivers/scsi/initio.c
@@ -2828,7 +2828,7 @@ static int i91u_detect(struct scsi_host_template * tpnt)
for (; tul_num_scb >= MAX_TARGETS + 3; tul_num_scb--) {
i = tul_num_ch * tul_num_scb * sizeof(SCB);
- if ((tul_scb = (SCB *) kmalloc(i, GFP_ATOMIC | GFP_DMA)) != NULL)
+ if ((tul_scb = kmalloc(i, GFP_ATOMIC | GFP_DMA)) != NULL)
break;
}
if (tul_scb == NULL) {
diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c
index 824fe080d1dc..7d2311067903 100644
--- a/drivers/scsi/osst.c
+++ b/drivers/scsi/osst.c
@@ -5777,7 +5777,7 @@ static int osst_probe(struct device *dev)
dev_num = i;
/* allocate a struct osst_tape for this device */
- tpnt = (struct osst_tape *)kmalloc(sizeof(struct osst_tape), GFP_ATOMIC);
+ tpnt = kmalloc(sizeof(struct osst_tape), GFP_ATOMIC);
if (tpnt == NULL) {
write_unlock(&os_scsi_tapes_lock);
printk(KERN_ERR "osst :E: Can't allocate device descriptor, device not attached.\n");
diff --git a/drivers/scsi/pluto.c b/drivers/scsi/pluto.c
index aa60a5f1fbc3..3b2e1a53e6e2 100644
--- a/drivers/scsi/pluto.c
+++ b/drivers/scsi/pluto.c
@@ -117,7 +117,7 @@ int __init pluto_detect(struct scsi_host_template *tpnt)
#endif
return 0;
}
- fcs = (struct ctrl_inquiry *) kmalloc (sizeof (struct ctrl_inquiry) * fcscount, GFP_DMA);
+ fcs = kmalloc(sizeof (struct ctrl_inquiry) * fcscount, GFP_DMA);
if (!fcs) {
printk ("PLUTO: Not enough memory to probe\n");
return 0;
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 1748e27501cd..f02f48a882a9 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -265,13 +265,11 @@ static int scsi_merge_bio(struct request *rq, struct bio *bio)
if (!rq->bio)
blk_rq_bio_prep(q, rq, bio);
- else if (!q->back_merge_fn(q, rq, bio))
+ else if (!ll_back_merge_fn(q, rq, bio))
return -EINVAL;
else {
rq->biotail->bi_next = bio;
rq->biotail = bio;
- rq->hard_nr_sectors += bio_sectors(bio);
- rq->nr_sectors = rq->hard_nr_sectors;
}
return 0;
diff --git a/drivers/scsi/sr_ioctl.c b/drivers/scsi/sr_ioctl.c
index d1268cb46837..0578ba42718b 100644
--- a/drivers/scsi/sr_ioctl.c
+++ b/drivers/scsi/sr_ioctl.c
@@ -546,7 +546,7 @@ int sr_is_xa(Scsi_CD *cd)
if (!xa_test)
return 0;
- raw_sector = (unsigned char *) kmalloc(2048, GFP_KERNEL | SR_GFP_DMA(cd));
+ raw_sector = kmalloc(2048, GFP_KERNEL | SR_GFP_DMA(cd));
if (!raw_sector)
return -ENOMEM;
if (0 == sr_read_sector(cd, cd->ms_offset + 16,
diff --git a/drivers/scsi/sr_vendor.c b/drivers/scsi/sr_vendor.c
index a3e9d0f2eb5b..4eb3da996b36 100644
--- a/drivers/scsi/sr_vendor.c
+++ b/drivers/scsi/sr_vendor.c
@@ -117,7 +117,7 @@ int sr_set_blocklength(Scsi_CD *cd, int blocklength)
density = (blocklength > 2048) ? 0x81 : 0x83;
#endif
- buffer = (unsigned char *) kmalloc(512, GFP_KERNEL | GFP_DMA);
+ buffer = kmalloc(512, GFP_KERNEL | GFP_DMA);
if (!buffer)
return -ENOMEM;
@@ -164,7 +164,7 @@ int sr_cd_check(struct cdrom_device_info *cdi)
if (cd->cdi.mask & CDC_MULTI_SESSION)
return 0;
- buffer = (unsigned char *) kmalloc(512, GFP_KERNEL | GFP_DMA);
+ buffer = kmalloc(512, GFP_KERNEL | GFP_DMA);
if (!buffer)
return -ENOMEM;
diff --git a/drivers/scsi/sun3_NCR5380.c b/drivers/scsi/sun3_NCR5380.c
index 43f5b6aa7dc4..98e3fe10c1dc 100644
--- a/drivers/scsi/sun3_NCR5380.c
+++ b/drivers/scsi/sun3_NCR5380.c
@@ -266,7 +266,7 @@ static struct scsi_host_template *the_template = NULL;
(struct NCR5380_hostdata *)(in)->hostdata
#define HOSTDATA(in) ((struct NCR5380_hostdata *)(in)->hostdata)
-#define NEXT(cmd) ((struct scsi_cmnd *)((cmd)->host_scribble))
+#define NEXT(cmd) (*(struct scsi_cmnd **)&((cmd)->host_scribble))
#define NEXTADDR(cmd) ((struct scsi_cmnd **)&((cmd)->host_scribble))
#define HOSTNO instance->host_no
@@ -650,7 +650,7 @@ __inline__ void NCR5380_print_phase(struct Scsi_Host *instance) { };
#include <linux/interrupt.h>
static volatile int main_running = 0;
-static DECLARE_WORK(NCR5380_tqueue, (void (*)(void*))NCR5380_main, NULL);
+static DECLARE_WORK(NCR5380_tqueue, NCR5380_main);
static __inline__ void queue_main(void)
{
@@ -1031,7 +1031,7 @@ static int NCR5380_queue_command(struct scsi_cmnd *cmd,
* reenable them. This prevents reentrancy and kernel stack overflow.
*/
-static void NCR5380_main (void *bl)
+static void NCR5380_main (struct work_struct *bl)
{
struct scsi_cmnd *tmp, *prev;
struct Scsi_Host *instance = first_instance;
diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.c b/drivers/scsi/sym53c8xx_2/sym_hipd.c
index 940fa1e6f994..21cd4c7f5289 100644
--- a/drivers/scsi/sym53c8xx_2/sym_hipd.c
+++ b/drivers/scsi/sym53c8xx_2/sym_hipd.c
@@ -5545,7 +5545,7 @@ int sym_hcb_attach(struct Scsi_Host *shost, struct sym_fw *fw, struct sym_nvram
/*
* Allocate the array of lists of CCBs hashed by DSA.
*/
- np->ccbh = kcalloc(sizeof(struct sym_ccb **), CCB_HASH_SIZE, GFP_KERNEL);
+ np->ccbh = kcalloc(CCB_HASH_SIZE, sizeof(struct sym_ccb **), GFP_KERNEL);
if (!np->ccbh)
goto attach_failed;
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c
index 4d0ff8f4a01b..52e2e64c6649 100644
--- a/drivers/serial/8250_pci.c
+++ b/drivers/serial/8250_pci.c
@@ -2239,6 +2239,30 @@ static struct pci_device_id serial_pci_tbl[] = {
pbn_b0_bt_1_460800 },
/*
+ * Korenix Jetcard F0/F1 cards (JC1204, JC1208, JC1404, JC1408).
+ * Cards are identified by their subsystem vendor IDs, which
+ * (in hex) match the model number.
+ *
+ * Note that JC140x are RS422/485 cards which require ox950
+ * ACR = 0x10, and as such are not currently fully supported.
+ */
+ { PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF0,
+ 0x1204, 0x0004, 0, 0,
+ pbn_b0_4_921600 },
+ { PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF0,
+ 0x1208, 0x0004, 0, 0,
+ pbn_b0_4_921600 },
+/* { PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF0,
+ 0x1402, 0x0002, 0, 0,
+ pbn_b0_2_921600 }, */
+/* { PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF0,
+ 0x1404, 0x0004, 0, 0,
+ pbn_b0_4_921600 }, */
+ { PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF1,
+ 0x1208, 0x0004, 0, 0,
+ pbn_b0_4_921600 },
+
+ /*
* Dell Remote Access Card 4 - Tim_T_Murphy@Dell.com
*/
{ PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_RAC4,
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c
index 493d5bbb661b..145d6236954b 100644
--- a/drivers/serial/sunsab.c
+++ b/drivers/serial/sunsab.c
@@ -1037,7 +1037,8 @@ static int __devinit sunsab_init_one(struct uart_sunsab_port *up,
err = request_irq(up->port.irq, sunsab_interrupt,
IRQF_SHARED, "sab", up);
if (err) {
- of_iounmap(up->port.membase,
+ of_iounmap(&op->resource[0],
+ up->port.membase,
sizeof(union sab82532_async_regs));
return err;
}
@@ -1064,7 +1065,8 @@ static int __devinit sab_probe(struct of_device *op, const struct of_device_id *
sizeof(union sab82532_async_regs),
(inst * 2) + 1);
if (err) {
- of_iounmap(up[0].port.membase,
+ of_iounmap(&op->resource[0],
+ up[0].port.membase,
sizeof(union sab82532_async_regs));
free_irq(up[0].port.irq, &up[0]);
return err;
@@ -1082,10 +1084,13 @@ static int __devinit sab_probe(struct of_device *op, const struct of_device_id *
static void __devexit sab_remove_one(struct uart_sunsab_port *up)
{
+ struct of_device *op = to_of_device(up->port.dev);
+
uart_remove_one_port(&sunsab_reg, &up->port);
if (!(up->port.line & 1))
free_irq(up->port.irq, up);
- of_iounmap(up->port.membase,
+ of_iounmap(&op->resource[0],
+ up->port.membase,
sizeof(union sab82532_async_regs));
}
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
index 564592b2b2ba..3ec3df21816b 100644
--- a/drivers/serial/sunsu.c
+++ b/drivers/serial/sunsu.c
@@ -1480,13 +1480,13 @@ static int __devinit su_probe(struct of_device *op, const struct of_device_id *m
return 0;
out_unmap:
- of_iounmap(up->port.membase, up->reg_size);
+ of_iounmap(&op->resource[0], up->port.membase, up->reg_size);
return err;
}
-static int __devexit su_remove(struct of_device *dev)
+static int __devexit su_remove(struct of_device *op)
{
- struct uart_sunsu_port *up = dev_get_drvdata(&dev->dev);;
+ struct uart_sunsu_port *up = dev_get_drvdata(&op->dev);
if (up->su_type == SU_PORT_MS ||
up->su_type == SU_PORT_KBD) {
@@ -1499,9 +1499,9 @@ static int __devexit su_remove(struct of_device *dev)
}
if (up->port.membase)
- of_iounmap(up->port.membase, up->reg_size);
+ of_iounmap(&op->resource[0], up->port.membase, up->reg_size);
- dev_set_drvdata(&dev->dev, NULL);
+ dev_set_drvdata(&op->dev, NULL);
return 0;
}
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
index 75de919a9471..244f796dc625 100644
--- a/drivers/serial/sunzilog.c
+++ b/drivers/serial/sunzilog.c
@@ -1379,13 +1379,15 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m
if (!keyboard_mouse) {
err = uart_add_one_port(&sunzilog_reg, &up[0].port);
if (err) {
- of_iounmap(rp, sizeof(struct zilog_layout));
+ of_iounmap(&op->resource[0],
+ rp, sizeof(struct zilog_layout));
return err;
}
err = uart_add_one_port(&sunzilog_reg, &up[1].port);
if (err) {
uart_remove_one_port(&sunzilog_reg, &up[0].port);
- of_iounmap(rp, sizeof(struct zilog_layout));
+ of_iounmap(&op->resource[0],
+ rp, sizeof(struct zilog_layout));
return err;
}
} else {
@@ -1414,18 +1416,18 @@ static void __devexit zs_remove_one(struct uart_sunzilog_port *up)
uart_remove_one_port(&sunzilog_reg, &up->port);
}
-static int __devexit zs_remove(struct of_device *dev)
+static int __devexit zs_remove(struct of_device *op)
{
- struct uart_sunzilog_port *up = dev_get_drvdata(&dev->dev);
+ struct uart_sunzilog_port *up = dev_get_drvdata(&op->dev);
struct zilog_layout __iomem *regs;
zs_remove_one(&up[0]);
zs_remove_one(&up[1]);
regs = sunzilog_chip_regs[up[0].port.line / 2];
- of_iounmap(regs, sizeof(struct zilog_layout));
+ of_iounmap(&op->resource[0], regs, sizeof(struct zilog_layout));
- dev_set_drvdata(&dev->dev, NULL);
+ dev_set_drvdata(&op->dev, NULL);
return 0;
}
diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c
index 92eba893559d..db8607e3d531 100644
--- a/drivers/serial/uartlite.c
+++ b/drivers/serial/uartlite.c
@@ -278,8 +278,8 @@ static int ulite_request_port(struct uart_port *port)
static void ulite_config_port(struct uart_port *port, int flags)
{
- ulite_request_port(port);
- port->type = PORT_UARTLITE;
+ if (!ulite_request_port(port))
+ port->type = PORT_UARTLITE;
}
static int ulite_verify_port(struct uart_port *port, struct serial_struct *ser)
diff --git a/drivers/spi/spi_mpc83xx.c b/drivers/spi/spi_mpc83xx.c
index ff0b04895db0..e9798bf7b8c6 100644
--- a/drivers/spi/spi_mpc83xx.c
+++ b/drivers/spi/spi_mpc83xx.c
@@ -112,6 +112,8 @@ u32 mpc83xx_spi_tx_buf_##type(struct mpc83xx_spi *mpc83xx_spi) \
{ \
u32 data; \
const type * tx = mpc83xx_spi->tx; \
+ if (!tx) \
+ return 0; \
data = *tx++; \
mpc83xx_spi->tx = tx; \
return data; \
diff --git a/drivers/spi/spi_s3c24xx.c b/drivers/spi/spi_s3c24xx.c
index 2ebe1fc4c398..8ca08713528e 100644
--- a/drivers/spi/spi_s3c24xx.c
+++ b/drivers/spi/spi_s3c24xx.c
@@ -174,7 +174,7 @@ static int s3c24xx_spi_setup(struct spi_device *spi)
static inline unsigned int hw_txbyte(struct s3c24xx_spi *hw, int count)
{
- return hw->tx ? hw->tx[count] : 0xff;
+ return hw->tx ? hw->tx[count] : 0;
}
static int s3c24xx_spi_txrx(struct spi_device *spi, struct spi_transfer *t)
diff --git a/drivers/spi/spi_s3c24xx_gpio.c b/drivers/spi/spi_s3c24xx_gpio.c
index a5d2cdfff46f..eda53ed04cbc 100644
--- a/drivers/spi/spi_s3c24xx_gpio.c
+++ b/drivers/spi/spi_s3c24xx_gpio.c
@@ -15,6 +15,7 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
+#include <linux/workqueue.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
@@ -22,7 +23,7 @@
#include <asm/arch/regs-gpio.h>
#include <asm/arch/spi-gpio.h>
-#include <asm/arch/hardware.h>
+#include <asm/hardware.h>
struct s3c2410_spigpio {
struct spi_bitbang bitbang;
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
index 6303970e93c1..24ee8be359f5 100644
--- a/drivers/usb/class/usblp.c
+++ b/drivers/usb/class/usblp.c
@@ -130,7 +130,7 @@ MFG:HEWLETT-PACKARD;MDL:DESKJET 970C;CMD:MLC,PCL,PML;CLASS:PRINTER;DESCRIPTION:H
struct usblp {
struct usb_device *dev; /* USB device */
- struct semaphore sem; /* locks this struct, especially "dev" */
+ struct mutex mut; /* locks this struct, especially "dev" */
char *writebuf; /* write transfer_buffer */
char *readbuf; /* read transfer_buffer */
char *statusbuf; /* status transfer_buffer */
@@ -465,7 +465,7 @@ static long usblp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
int twoints[2];
int retval = 0;
- down (&usblp->sem);
+ mutex_lock (&usblp->mut);
if (!usblp->present) {
retval = -ENODEV;
goto done;
@@ -644,14 +644,14 @@ static long usblp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
}
done:
- up (&usblp->sem);
+ mutex_unlock (&usblp->mut);
return retval;
}
static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
{
struct usblp *usblp = file->private_data;
- int timeout, rv, err = 0, transfer_length = 0;
+ int timeout, intr, rv, err = 0, transfer_length = 0;
size_t writecount = 0;
while (writecount < count) {
@@ -668,14 +668,16 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t
if (rv < 0)
return writecount ? writecount : -EINTR;
}
- down (&usblp->sem);
+ intr = mutex_lock_interruptible (&usblp->mut);
+ if (intr)
+ return writecount ? writecount : -EINTR;
if (!usblp->present) {
- up (&usblp->sem);
+ mutex_unlock (&usblp->mut);
return -ENODEV;
}
if (usblp->sleeping) {
- up (&usblp->sem);
+ mutex_unlock (&usblp->mut);
return writecount ? writecount : -ENODEV;
}
@@ -687,10 +689,10 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t
err = usblp->writeurb->status;
} else
err = usblp_check_status(usblp, err);
- up (&usblp->sem);
+ mutex_unlock (&usblp->mut);
/* if the fault was due to disconnect, let khubd's
- * call to usblp_disconnect() grab usblp->sem ...
+ * call to usblp_disconnect() grab usblp->mut ...
*/
schedule ();
continue;
@@ -702,7 +704,7 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t
*/
writecount += transfer_length;
if (writecount == count) {
- up(&usblp->sem);
+ mutex_unlock(&usblp->mut);
break;
}
@@ -714,7 +716,7 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t
if (copy_from_user(usblp->writeurb->transfer_buffer,
buffer + writecount, transfer_length)) {
- up(&usblp->sem);
+ mutex_unlock(&usblp->mut);
return writecount ? writecount : -EFAULT;
}
@@ -727,10 +729,10 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t
count = -EIO;
else
count = writecount ? writecount : -ENOMEM;
- up (&usblp->sem);
+ mutex_unlock (&usblp->mut);
break;
}
- up (&usblp->sem);
+ mutex_unlock (&usblp->mut);
}
return count;
@@ -739,12 +741,14 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t
static ssize_t usblp_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
{
struct usblp *usblp = file->private_data;
- int rv;
+ int rv, intr;
if (!usblp->bidir)
return -EINVAL;
- down (&usblp->sem);
+ intr = mutex_lock_interruptible (&usblp->mut);
+ if (intr)
+ return -EINTR;
if (!usblp->present) {
count = -ENODEV;
goto done;
@@ -757,9 +761,9 @@ static ssize_t usblp_read(struct file *file, char __user *buffer, size_t count,
count = -EAGAIN;
goto done;
}
- up(&usblp->sem);
+ mutex_unlock(&usblp->mut);
rv = wait_event_interruptible(usblp->wait, usblp->rcomplete || !usblp->present);
- down(&usblp->sem);
+ mutex_lock(&usblp->mut);
if (rv < 0) {
count = -EINTR;
goto done;
@@ -807,7 +811,7 @@ static ssize_t usblp_read(struct file *file, char __user *buffer, size_t count,
}
done:
- up (&usblp->sem);
+ mutex_unlock (&usblp->mut);
return count;
}
@@ -886,7 +890,7 @@ static int usblp_probe(struct usb_interface *intf,
goto abort;
}
usblp->dev = dev;
- init_MUTEX (&usblp->sem);
+ mutex_init (&usblp->mut);
init_waitqueue_head(&usblp->wait);
usblp->ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
usblp->intf = intf;
@@ -1178,7 +1182,7 @@ static void usblp_disconnect(struct usb_interface *intf)
device_remove_file(&intf->dev, &dev_attr_ieee1284_id);
mutex_lock (&usblp_mutex);
- down (&usblp->sem);
+ mutex_lock (&usblp->mut);
usblp->present = 0;
usb_set_intfdata (intf, NULL);
@@ -1187,7 +1191,7 @@ static void usblp_disconnect(struct usb_interface *intf)
usblp->writebuf, usblp->writeurb->transfer_dma);
usb_buffer_free (usblp->dev, USBLP_BUF_SIZE,
usblp->readbuf, usblp->readurb->transfer_dma);
- up (&usblp->sem);
+ mutex_unlock (&usblp->mut);
if (!usblp->used)
usblp_cleanup (usblp);
@@ -1200,11 +1204,11 @@ static int usblp_suspend (struct usb_interface *intf, pm_message_t message)
/* this races against normal access and open */
mutex_lock (&usblp_mutex);
- down (&usblp->sem);
+ mutex_lock (&usblp->mut);
/* we take no more IO */
usblp->sleeping = 1;
usblp_unlink_urbs(usblp);
- up (&usblp->sem);
+ mutex_unlock (&usblp->mut);
mutex_unlock (&usblp_mutex);
return 0;
@@ -1216,12 +1220,12 @@ static int usblp_resume (struct usb_interface *intf)
int r;
mutex_lock (&usblp_mutex);
- down (&usblp->sem);
+ mutex_lock (&usblp->mut);
usblp->sleeping = 0;
r = handle_bidir (usblp);
- up (&usblp->sem);
+ mutex_unlock (&usblp->mut);
mutex_unlock (&usblp_mutex);
return r;
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index 3ed4cb2d56d9..4b3a6ab29bd3 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -962,7 +962,11 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
kfree(dr);
return -EFAULT;
}
- snoop(&ps->dev->dev, "control urb\n");
+ snoop(&ps->dev->dev, "control urb: bRequest=%02x "
+ "bRrequestType=%02x wValue=%04x "
+ "wIndex=%04x wLength=%04x\n",
+ dr->bRequest, dr->bRequestType, dr->wValue,
+ dr->wIndex, dr->wLength);
break;
case USBDEVFS_URB_TYPE_BULK:
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c
index 72f3db99ff94..812c733ba8ce 100644
--- a/drivers/usb/gadget/at91_udc.c
+++ b/drivers/usb/gadget/at91_udc.c
@@ -43,14 +43,16 @@
#include <linux/usb_gadget.h>
#include <asm/byteorder.h>
+#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/system.h>
#include <asm/mach-types.h>
-#include <asm/arch/hardware.h>
#include <asm/arch/gpio.h>
#include <asm/arch/board.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/at91sam9261_matrix.h>
#include "at91_udc.h"
@@ -78,27 +80,11 @@
static const char driver_name [] = "at91_udc";
static const char ep0name[] = "ep0";
-/*-------------------------------------------------------------------------*/
-/*
- * Read from a UDP register.
- */
-static inline unsigned long at91_udp_read(unsigned int reg)
-{
- void __iomem *udp_base = (void __iomem *)AT91_VA_BASE_UDP;
-
- return __raw_readl(udp_base + reg);
-}
-
-/*
- * Write to a UDP register.
- */
-static inline void at91_udp_write(unsigned int reg, unsigned long value)
-{
- void __iomem *udp_base = (void __iomem *)AT91_VA_BASE_UDP;
-
- __raw_writel(value, udp_base + reg);
-}
+#define at91_udp_read(dev, reg) \
+ __raw_readl((dev)->udp_baseaddr + (reg))
+#define at91_udp_write(dev, reg, val) \
+ __raw_writel((val), (dev)->udp_baseaddr + (reg))
/*-------------------------------------------------------------------------*/
@@ -210,13 +196,13 @@ static int proc_udc_show(struct seq_file *s, void *unused)
return 0;
}
- tmp = at91_udp_read(AT91_UDP_FRM_NUM);
+ tmp = at91_udp_read(udc, AT91_UDP_FRM_NUM);
seq_printf(s, "frame %05x:%s%s frame=%d\n", tmp,
(tmp & AT91_UDP_FRM_OK) ? " ok" : "",
(tmp & AT91_UDP_FRM_ERR) ? " err" : "",
(tmp & AT91_UDP_NUM));
- tmp = at91_udp_read(AT91_UDP_GLB_STAT);
+ tmp = at91_udp_read(udc, AT91_UDP_GLB_STAT);
seq_printf(s, "glbstate %02x:%s" FOURBITS "\n", tmp,
(tmp & AT91_UDP_RMWUPE) ? " rmwupe" : "",
(tmp & AT91_UDP_RSMINPR) ? " rsminpr" : "",
@@ -224,13 +210,13 @@ static int proc_udc_show(struct seq_file *s, void *unused)
(tmp & AT91_UDP_CONFG) ? " confg" : "",
(tmp & AT91_UDP_FADDEN) ? " fadden" : "");
- tmp = at91_udp_read(AT91_UDP_FADDR);
+ tmp = at91_udp_read(udc, AT91_UDP_FADDR);
seq_printf(s, "faddr %03x:%s fadd=%d\n", tmp,
(tmp & AT91_UDP_FEN) ? " fen" : "",
(tmp & AT91_UDP_FADD));
- proc_irq_show(s, "imr ", at91_udp_read(AT91_UDP_IMR));
- proc_irq_show(s, "isr ", at91_udp_read(AT91_UDP_ISR));
+ proc_irq_show(s, "imr ", at91_udp_read(udc, AT91_UDP_IMR));
+ proc_irq_show(s, "isr ", at91_udp_read(udc, AT91_UDP_ISR));
if (udc->enabled && udc->vbus) {
proc_ep_show(s, &udc->ep[0]);
@@ -286,6 +272,7 @@ static inline void remove_debug_file(struct at91_udc *udc) {}
static void done(struct at91_ep *ep, struct at91_request *req, int status)
{
unsigned stopped = ep->stopped;
+ struct at91_udc *udc = ep->udc;
list_del_init(&req->queue);
if (req->req.status == -EINPROGRESS)
@@ -301,7 +288,7 @@ static void done(struct at91_ep *ep, struct at91_request *req, int status)
/* ep0 is always ready; other endpoints need a non-empty queue */
if (list_empty(&ep->queue) && ep->int_mask != (1 << 0))
- at91_udp_write(AT91_UDP_IDR, ep->int_mask);
+ at91_udp_write(udc, AT91_UDP_IDR, ep->int_mask);
}
/*-------------------------------------------------------------------------*/
@@ -554,8 +541,8 @@ ok:
* reset/init endpoint fifo. NOTE: leaves fifo_bank alone,
* since endpoint resets don't reset hw pingpong state.
*/
- at91_udp_write(AT91_UDP_RST_EP, ep->int_mask);
- at91_udp_write(AT91_UDP_RST_EP, 0);
+ at91_udp_write(dev, AT91_UDP_RST_EP, ep->int_mask);
+ at91_udp_write(dev, AT91_UDP_RST_EP, 0);
local_irq_restore(flags);
return 0;
@@ -564,6 +551,7 @@ ok:
static int at91_ep_disable (struct usb_ep * _ep)
{
struct at91_ep *ep = container_of(_ep, struct at91_ep, ep);
+ struct at91_udc *udc = ep->udc;
unsigned long flags;
if (ep == &ep->udc->ep[0])
@@ -579,8 +567,8 @@ static int at91_ep_disable (struct usb_ep * _ep)
/* reset fifos and endpoint */
if (ep->udc->clocked) {
- at91_udp_write(AT91_UDP_RST_EP, ep->int_mask);
- at91_udp_write(AT91_UDP_RST_EP, 0);
+ at91_udp_write(udc, AT91_UDP_RST_EP, ep->int_mask);
+ at91_udp_write(udc, AT91_UDP_RST_EP, 0);
__raw_writel(0, ep->creg);
}
@@ -598,7 +586,7 @@ at91_ep_alloc_request(struct usb_ep *_ep, unsigned int gfp_flags)
{
struct at91_request *req;
- req = kcalloc(1, sizeof (struct at91_request), gfp_flags);
+ req = kzalloc(sizeof (struct at91_request), gfp_flags);
if (!req)
return NULL;
@@ -695,10 +683,10 @@ static int at91_ep_queue(struct usb_ep *_ep,
* reconfigures the endpoints.
*/
if (dev->wait_for_config_ack) {
- tmp = at91_udp_read(AT91_UDP_GLB_STAT);
+ tmp = at91_udp_read(dev, AT91_UDP_GLB_STAT);
tmp ^= AT91_UDP_CONFG;
VDBG("toggle config\n");
- at91_udp_write(AT91_UDP_GLB_STAT, tmp);
+ at91_udp_write(dev, AT91_UDP_GLB_STAT, tmp);
}
if (req->req.length == 0) {
ep0_in_status:
@@ -727,7 +715,7 @@ ep0_in_status:
if (req && !status) {
list_add_tail (&req->queue, &ep->queue);
- at91_udp_write(AT91_UDP_IER, ep->int_mask);
+ at91_udp_write(dev, AT91_UDP_IER, ep->int_mask);
}
done:
local_irq_restore(flags);
@@ -758,6 +746,7 @@ static int at91_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
static int at91_ep_set_halt(struct usb_ep *_ep, int value)
{
struct at91_ep *ep = container_of(_ep, struct at91_ep, ep);
+ struct at91_udc *udc = ep->udc;
u32 __iomem *creg;
u32 csr;
unsigned long flags;
@@ -785,8 +774,8 @@ static int at91_ep_set_halt(struct usb_ep *_ep, int value)
csr |= AT91_UDP_FORCESTALL;
VDBG("halt %s\n", ep->ep.name);
} else {
- at91_udp_write(AT91_UDP_RST_EP, ep->int_mask);
- at91_udp_write(AT91_UDP_RST_EP, 0);
+ at91_udp_write(udc, AT91_UDP_RST_EP, ep->int_mask);
+ at91_udp_write(udc, AT91_UDP_RST_EP, 0);
csr &= ~AT91_UDP_FORCESTALL;
}
__raw_writel(csr, creg);
@@ -813,9 +802,11 @@ static struct usb_ep_ops at91_ep_ops = {
static int at91_get_frame(struct usb_gadget *gadget)
{
+ struct at91_udc *udc = to_udc(gadget);
+
if (!to_udc(gadget)->clocked)
return -EINVAL;
- return at91_udp_read(AT91_UDP_FRM_NUM) & AT91_UDP_NUM;
+ return at91_udp_read(udc, AT91_UDP_FRM_NUM) & AT91_UDP_NUM;
}
static int at91_wakeup(struct usb_gadget *gadget)
@@ -833,11 +824,11 @@ static int at91_wakeup(struct usb_gadget *gadget)
/* NOTE: some "early versions" handle ESR differently ... */
- glbstate = at91_udp_read(AT91_UDP_GLB_STAT);
+ glbstate = at91_udp_read(udc, AT91_UDP_GLB_STAT);
if (!(glbstate & AT91_UDP_ESR))
goto done;
glbstate |= AT91_UDP_ESR;
- at91_udp_write(AT91_UDP_GLB_STAT, glbstate);
+ at91_udp_write(udc, AT91_UDP_GLB_STAT, glbstate);
done:
local_irq_restore(flags);
@@ -861,6 +852,7 @@ static void udc_reinit(struct at91_udc *udc)
ep->stopped = 0;
ep->fifo_bank = 0;
ep->ep.maxpacket = ep->maxpacket;
+ ep->creg = (void __iomem *) udc->udp_baseaddr + AT91_UDP_CSR(i);
// initialiser une queue par endpoint
INIT_LIST_HEAD(&ep->queue);
}
@@ -915,14 +907,41 @@ static void pullup(struct at91_udc *udc, int is_on)
if (!udc->enabled || !udc->vbus)
is_on = 0;
DBG("%sactive\n", is_on ? "" : "in");
+
if (is_on) {
clk_on(udc);
- at91_udp_write(AT91_UDP_TXVC, 0);
- at91_set_gpio_value(udc->board.pullup_pin, 1);
- } else {
+ at91_udp_write(udc, AT91_UDP_TXVC, 0);
+ if (cpu_is_at91rm9200())
+ at91_set_gpio_value(udc->board.pullup_pin, 1);
+ else if (cpu_is_at91sam9260()) {
+ u32 txvc = at91_udp_read(udc, AT91_UDP_TXVC);
+
+ txvc |= AT91_UDP_TXVC_PUON;
+ at91_udp_write(udc, AT91_UDP_TXVC, txvc);
+ } else if (cpu_is_at91sam9261()) {
+ u32 usbpucr;
+
+ usbpucr = at91_sys_read(AT91_MATRIX_USBPUCR);
+ usbpucr |= AT91_MATRIX_USBPUCR_PUON;
+ at91_sys_write(AT91_MATRIX_USBPUCR, usbpucr);
+ }
+ } else {
stop_activity(udc);
- at91_udp_write(AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS);
- at91_set_gpio_value(udc->board.pullup_pin, 0);
+ at91_udp_write(udc, AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS);
+ if (cpu_is_at91rm9200())
+ at91_set_gpio_value(udc->board.pullup_pin, 0);
+ else if (cpu_is_at91sam9260()) {
+ u32 txvc = at91_udp_read(udc, AT91_UDP_TXVC);
+
+ txvc &= ~AT91_UDP_TXVC_PUON;
+ at91_udp_write(udc, AT91_UDP_TXVC, txvc);
+ } else if (cpu_is_at91sam9261()) {
+ u32 usbpucr;
+
+ usbpucr = at91_sys_read(AT91_MATRIX_USBPUCR);
+ usbpucr &= ~AT91_MATRIX_USBPUCR_PUON;
+ at91_sys_write(AT91_MATRIX_USBPUCR, usbpucr);
+ }
clk_off(udc);
}
}
@@ -936,7 +955,10 @@ static int at91_vbus_session(struct usb_gadget *gadget, int is_active)
// VDBG("vbus %s\n", is_active ? "on" : "off");
local_irq_save(flags);
udc->vbus = (is_active != 0);
- pullup(udc, is_active);
+ if (udc->driver)
+ pullup(udc, is_active);
+ else
+ pullup(udc, 0);
local_irq_restore(flags);
return 0;
}
@@ -1086,7 +1108,7 @@ static void handle_setup(struct at91_udc *udc, struct at91_ep *ep, u32 csr)
case ((USB_TYPE_STANDARD|USB_RECIP_DEVICE) << 8)
| USB_REQ_SET_CONFIGURATION:
- tmp = at91_udp_read(AT91_UDP_GLB_STAT) & AT91_UDP_CONFG;
+ tmp = at91_udp_read(udc, AT91_UDP_GLB_STAT) & AT91_UDP_CONFG;
if (pkt.r.wValue)
udc->wait_for_config_ack = (tmp == 0);
else
@@ -1103,7 +1125,7 @@ static void handle_setup(struct at91_udc *udc, struct at91_ep *ep, u32 csr)
case ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE) << 8)
| USB_REQ_GET_STATUS:
tmp = (udc->selfpowered << USB_DEVICE_SELF_POWERED);
- if (at91_udp_read(AT91_UDP_GLB_STAT) & AT91_UDP_ESR)
+ if (at91_udp_read(udc, AT91_UDP_GLB_STAT) & AT91_UDP_ESR)
tmp |= (1 << USB_DEVICE_REMOTE_WAKEUP);
PACKET("get device status\n");
__raw_writeb(tmp, dreg);
@@ -1114,17 +1136,17 @@ static void handle_setup(struct at91_udc *udc, struct at91_ep *ep, u32 csr)
| USB_REQ_SET_FEATURE:
if (w_value != USB_DEVICE_REMOTE_WAKEUP)
goto stall;
- tmp = at91_udp_read(AT91_UDP_GLB_STAT);
+ tmp = at91_udp_read(udc, AT91_UDP_GLB_STAT);
tmp |= AT91_UDP_ESR;
- at91_udp_write(AT91_UDP_GLB_STAT, tmp);
+ at91_udp_write(udc, AT91_UDP_GLB_STAT, tmp);
goto succeed;
case ((USB_TYPE_STANDARD|USB_RECIP_DEVICE) << 8)
| USB_REQ_CLEAR_FEATURE:
if (w_value != USB_DEVICE_REMOTE_WAKEUP)
goto stall;
- tmp = at91_udp_read(AT91_UDP_GLB_STAT);
+ tmp = at91_udp_read(udc, AT91_UDP_GLB_STAT);
tmp &= ~AT91_UDP_ESR;
- at91_udp_write(AT91_UDP_GLB_STAT, tmp);
+ at91_udp_write(udc, AT91_UDP_GLB_STAT, tmp);
goto succeed;
/*
@@ -1206,8 +1228,8 @@ static void handle_setup(struct at91_udc *udc, struct at91_ep *ep, u32 csr)
} else if (ep->is_in)
goto stall;
- at91_udp_write(AT91_UDP_RST_EP, ep->int_mask);
- at91_udp_write(AT91_UDP_RST_EP, 0);
+ at91_udp_write(udc, AT91_UDP_RST_EP, ep->int_mask);
+ at91_udp_write(udc, AT91_UDP_RST_EP, 0);
tmp = __raw_readl(ep->creg);
tmp |= CLR_FX;
tmp &= ~(SET_FX | AT91_UDP_FORCESTALL);
@@ -1222,7 +1244,10 @@ static void handle_setup(struct at91_udc *udc, struct at91_ep *ep, u32 csr)
#undef w_length
/* pass request up to the gadget driver */
- status = udc->driver->setup(&udc->gadget, &pkt.r);
+ if (udc->driver)
+ status = udc->driver->setup(&udc->gadget, &pkt.r);
+ else
+ status = -ENODEV;
if (status < 0) {
stall:
VDBG("req %02x.%02x protocol STALL; stat %d\n",
@@ -1300,13 +1325,13 @@ static void handle_ep0(struct at91_udc *udc)
if (udc->wait_for_addr_ack) {
u32 tmp;
- at91_udp_write(AT91_UDP_FADDR,
+ at91_udp_write(udc, AT91_UDP_FADDR,
AT91_UDP_FEN | udc->addr);
- tmp = at91_udp_read(AT91_UDP_GLB_STAT);
+ tmp = at91_udp_read(udc, AT91_UDP_GLB_STAT);
tmp &= ~AT91_UDP_FADDEN;
if (udc->addr)
tmp |= AT91_UDP_FADDEN;
- at91_udp_write(AT91_UDP_GLB_STAT, tmp);
+ at91_udp_write(udc, AT91_UDP_GLB_STAT, tmp);
udc->wait_for_addr_ack = 0;
VDBG("address %d\n", udc->addr);
@@ -1374,28 +1399,28 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc)
while (rescans--) {
u32 status;
- status = at91_udp_read(AT91_UDP_ISR)
- & at91_udp_read(AT91_UDP_IMR);
+ status = at91_udp_read(udc, AT91_UDP_ISR)
+ & at91_udp_read(udc, AT91_UDP_IMR);
if (!status)
break;
/* USB reset irq: not maskable */
if (status & AT91_UDP_ENDBUSRES) {
- at91_udp_write(AT91_UDP_IDR, ~MINIMUS_INTERRUPTUS);
- at91_udp_write(AT91_UDP_IER, MINIMUS_INTERRUPTUS);
+ at91_udp_write(udc, AT91_UDP_IDR, ~MINIMUS_INTERRUPTUS);
+ at91_udp_write(udc, AT91_UDP_IER, MINIMUS_INTERRUPTUS);
/* Atmel code clears this irq twice */
- at91_udp_write(AT91_UDP_ICR, AT91_UDP_ENDBUSRES);
- at91_udp_write(AT91_UDP_ICR, AT91_UDP_ENDBUSRES);
+ at91_udp_write(udc, AT91_UDP_ICR, AT91_UDP_ENDBUSRES);
+ at91_udp_write(udc, AT91_UDP_ICR, AT91_UDP_ENDBUSRES);
VDBG("end bus reset\n");
udc->addr = 0;
stop_activity(udc);
/* enable ep0 */
- at91_udp_write(AT91_UDP_CSR(0),
+ at91_udp_write(udc, AT91_UDP_CSR(0),
AT91_UDP_EPEDS | AT91_UDP_EPTYPE_CTRL);
udc->gadget.speed = USB_SPEED_FULL;
udc->suspended = 0;
- at91_udp_write(AT91_UDP_IER, AT91_UDP_EP(0));
+ at91_udp_write(udc, AT91_UDP_IER, AT91_UDP_EP(0));
/*
* NOTE: this driver keeps clocks off unless the
@@ -1406,9 +1431,9 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc)
/* host initiated suspend (3+ms bus idle) */
} else if (status & AT91_UDP_RXSUSP) {
- at91_udp_write(AT91_UDP_IDR, AT91_UDP_RXSUSP);
- at91_udp_write(AT91_UDP_IER, AT91_UDP_RXRSM);
- at91_udp_write(AT91_UDP_ICR, AT91_UDP_RXSUSP);
+ at91_udp_write(udc, AT91_UDP_IDR, AT91_UDP_RXSUSP);
+ at91_udp_write(udc, AT91_UDP_IER, AT91_UDP_RXRSM);
+ at91_udp_write(udc, AT91_UDP_ICR, AT91_UDP_RXSUSP);
// VDBG("bus suspend\n");
if (udc->suspended)
continue;
@@ -1425,9 +1450,9 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc)
/* host initiated resume */
} else if (status & AT91_UDP_RXRSM) {
- at91_udp_write(AT91_UDP_IDR, AT91_UDP_RXRSM);
- at91_udp_write(AT91_UDP_IER, AT91_UDP_RXSUSP);
- at91_udp_write(AT91_UDP_ICR, AT91_UDP_RXRSM);
+ at91_udp_write(udc, AT91_UDP_IDR, AT91_UDP_RXRSM);
+ at91_udp_write(udc, AT91_UDP_IER, AT91_UDP_RXSUSP);
+ at91_udp_write(udc, AT91_UDP_ICR, AT91_UDP_RXRSM);
// VDBG("bus resume\n");
if (!udc->suspended)
continue;
@@ -1485,8 +1510,6 @@ static struct at91_udc controller = {
},
.udc = &controller,
.maxpacket = 8,
- .creg = (void __iomem *)(AT91_VA_BASE_UDP
- + AT91_UDP_CSR(0)),
.int_mask = 1 << 0,
},
.ep[1] = {
@@ -1497,8 +1520,6 @@ static struct at91_udc controller = {
.udc = &controller,
.is_pingpong = 1,
.maxpacket = 64,
- .creg = (void __iomem *)(AT91_VA_BASE_UDP
- + AT91_UDP_CSR(1)),
.int_mask = 1 << 1,
},
.ep[2] = {
@@ -1509,8 +1530,6 @@ static struct at91_udc controller = {
.udc = &controller,
.is_pingpong = 1,
.maxpacket = 64,
- .creg = (void __iomem *)(AT91_VA_BASE_UDP
- + AT91_UDP_CSR(2)),
.int_mask = 1 << 2,
},
.ep[3] = {
@@ -1521,8 +1540,6 @@ static struct at91_udc controller = {
},
.udc = &controller,
.maxpacket = 8,
- .creg = (void __iomem *)(AT91_VA_BASE_UDP
- + AT91_UDP_CSR(3)),
.int_mask = 1 << 3,
},
.ep[4] = {
@@ -1533,8 +1550,6 @@ static struct at91_udc controller = {
.udc = &controller,
.is_pingpong = 1,
.maxpacket = 256,
- .creg = (void __iomem *)(AT91_VA_BASE_UDP
- + AT91_UDP_CSR(4)),
.int_mask = 1 << 4,
},
.ep[5] = {
@@ -1545,8 +1560,6 @@ static struct at91_udc controller = {
.udc = &controller,
.is_pingpong = 1,
.maxpacket = 256,
- .creg = (void __iomem *)(AT91_VA_BASE_UDP
- + AT91_UDP_CSR(5)),
.int_mask = 1 << 5,
},
/* ep6 and ep7 are also reserved (custom silicon might use them) */
@@ -1572,9 +1585,8 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver)
int retval;
if (!driver
- || driver->speed != USB_SPEED_FULL
+ || driver->speed < USB_SPEED_FULL
|| !driver->bind
- || !driver->unbind
|| !driver->setup) {
DBG("bad parameter.\n");
return -EINVAL;
@@ -1595,6 +1607,10 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver)
if (retval) {
DBG("driver->bind() returned %d\n", retval);
udc->driver = NULL;
+ udc->gadget.dev.driver = NULL;
+ udc->gadget.dev.driver_data = NULL;
+ udc->enabled = 0;
+ udc->selfpowered = 0;
return retval;
}
@@ -1611,12 +1627,12 @@ int usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
{
struct at91_udc *udc = &controller;
- if (!driver || driver != udc->driver)
+ if (!driver || driver != udc->driver || !driver->unbind)
return -EINVAL;
local_irq_disable();
udc->enabled = 0;
- at91_udp_write(AT91_UDP_IDR, ~0);
+ at91_udp_write(udc, AT91_UDP_IDR, ~0);
pullup(udc, 0);
local_irq_enable();
@@ -1641,6 +1657,7 @@ static int __devinit at91udc_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct at91_udc *udc;
int retval;
+ struct resource *res;
if (!dev->platform_data) {
/* small (so we copy it) but critical! */
@@ -1658,7 +1675,13 @@ static int __devinit at91udc_probe(struct platform_device *pdev)
return -ENODEV;
}
- if (!request_mem_region(AT91RM9200_BASE_UDP, SZ_16K, driver_name)) {
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -ENXIO;
+
+ if (!request_mem_region(res->start,
+ res->end - res->start + 1,
+ driver_name)) {
DBG("someone's using UDC memory\n");
return -EBUSY;
}
@@ -1668,15 +1691,23 @@ static int __devinit at91udc_probe(struct platform_device *pdev)
udc->gadget.dev.parent = dev;
udc->board = *(struct at91_udc_data *) dev->platform_data;
udc->pdev = pdev;
- udc_reinit(udc);
udc->enabled = 0;
+ udc->udp_baseaddr = ioremap(res->start, res->end - res->start + 1);
+ if (!udc->udp_baseaddr) {
+ release_mem_region(res->start, res->end - res->start + 1);
+ return -ENOMEM;
+ }
+
+ udc_reinit(udc);
+
/* get interface and function clocks */
udc->iclk = clk_get(dev, "udc_clk");
udc->fclk = clk_get(dev, "udpck");
if (IS_ERR(udc->iclk) || IS_ERR(udc->fclk)) {
DBG("clocks missing\n");
- return -ENODEV;
+ retval = -ENODEV;
+ goto fail0;
}
retval = device_register(&udc->gadget.dev);
@@ -1685,8 +1716,10 @@ static int __devinit at91udc_probe(struct platform_device *pdev)
/* don't do anything until we have both gadget driver and VBUS */
clk_enable(udc->iclk);
- at91_udp_write(AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS);
- at91_udp_write(AT91_UDP_IDR, 0xffffffff);
+ at91_udp_write(udc, AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS);
+ at91_udp_write(udc, AT91_UDP_IDR, 0xffffffff);
+ /* Clear all pending interrupts - UDP may be used by bootloader. */
+ at91_udp_write(udc, AT91_UDP_ICR, 0xffffffff);
clk_disable(udc->iclk);
/* request UDC and maybe VBUS irqs */
@@ -1698,6 +1731,11 @@ static int __devinit at91udc_probe(struct platform_device *pdev)
goto fail1;
}
if (udc->board.vbus_pin > 0) {
+ /*
+ * Get the initial state of VBUS - we cannot expect
+ * a pending interrupt.
+ */
+ udc->vbus = at91_get_gpio_value(udc->board.vbus_pin);
if (request_irq(udc->board.vbus_pin, at91_vbus_irq,
IRQF_DISABLED, driver_name, udc)) {
DBG("request vbus irq %d failed\n",
@@ -1720,7 +1758,7 @@ static int __devinit at91udc_probe(struct platform_device *pdev)
fail1:
device_unregister(&udc->gadget.dev);
fail0:
- release_mem_region(AT91RM9200_BASE_UDP, SZ_16K);
+ release_mem_region(res->start, res->end - res->start + 1);
DBG("%s probe failed, %d\n", driver_name, retval);
return retval;
}
@@ -1728,13 +1766,14 @@ fail0:
static int __devexit at91udc_remove(struct platform_device *pdev)
{
struct at91_udc *udc = platform_get_drvdata(pdev);
+ struct resource *res;
DBG("remove\n");
- pullup(udc, 0);
+ if (udc->driver)
+ return -EBUSY;
- if (udc->driver != 0)
- usb_gadget_unregister_driver(udc->driver);
+ pullup(udc, 0);
device_init_wakeup(&pdev->dev, 0);
remove_debug_file(udc);
@@ -1742,7 +1781,10 @@ static int __devexit at91udc_remove(struct platform_device *pdev)
free_irq(udc->board.vbus_pin, udc);
free_irq(udc->udp_irq, udc);
device_unregister(&udc->gadget.dev);
- release_mem_region(AT91RM9200_BASE_UDP, SZ_16K);
+
+ iounmap(udc->udp_baseaddr);
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ release_mem_region(res->start, res->end - res->start + 1);
clk_put(udc->iclk);
clk_put(udc->fclk);
diff --git a/drivers/usb/gadget/at91_udc.h b/drivers/usb/gadget/at91_udc.h
index 882af42e86cc..677089baa59d 100644
--- a/drivers/usb/gadget/at91_udc.h
+++ b/drivers/usb/gadget/at91_udc.h
@@ -51,10 +51,10 @@
#define AT91_UDP_EP(n) (1 << (n)) /* Endpoint Interrupt Status */
#define AT91_UDP_RXSUSP (1 << 8) /* USB Suspend Interrupt Status */
#define AT91_UDP_RXRSM (1 << 9) /* USB Resume Interrupt Status */
-#define AT91_UDP_EXTRSM (1 << 10) /* External Resume Interrupt Status */
+#define AT91_UDP_EXTRSM (1 << 10) /* External Resume Interrupt Status [AT91RM9200 only] */
#define AT91_UDP_SOFINT (1 << 11) /* Start of Frame Interrupt Status */
#define AT91_UDP_ENDBUSRES (1 << 12) /* End of Bus Reset Interrpt Status */
-#define AT91_UDP_WAKEUP (1 << 13) /* USB Wakeup Interrupt Status */
+#define AT91_UDP_WAKEUP (1 << 13) /* USB Wakeup Interrupt Status [AT91RM9200 only] */
#define AT91_UDP_ICR 0x20 /* Interrupt Clear Register */
#define AT91_UDP_RST_EP 0x28 /* Reset Endpoint Register */
@@ -84,7 +84,7 @@
#define AT91_UDP_TXVC 0x74 /* Transceiver Control Register */
#define AT91_UDP_TXVC_TXVDIS (1 << 8) /* Transceiver Disable */
-
+#define AT91_UDP_TXVC_PUON (1 << 9) /* PullUp On [AT91SAM9260 only] */
/*-------------------------------------------------------------------------*/
@@ -141,6 +141,7 @@ struct at91_udc {
struct clk *iclk, *fclk;
struct platform_device *pdev;
struct proc_dir_entry *pde;
+ void __iomem *udp_baseaddr;
int udp_irq;
};
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
index f1f32d7be5f9..3c2bc075ef4f 100644
--- a/drivers/usb/gadget/dummy_hcd.c
+++ b/drivers/usb/gadget/dummy_hcd.c
@@ -779,7 +779,7 @@ usb_gadget_register_driver (struct usb_gadget_driver *driver)
return -EINVAL;
if (dum->driver)
return -EBUSY;
- if (!driver->bind || !driver->unbind || !driver->setup
+ if (!driver->bind || !driver->setup
|| driver->speed == USB_SPEED_UNKNOWN)
return -EINVAL;
@@ -837,7 +837,8 @@ usb_gadget_register_driver (struct usb_gadget_driver *driver)
err_bind_driver:
driver_unregister (&driver->driver);
err_register:
- driver->unbind (&dum->gadget);
+ if (driver->unbind)
+ driver->unbind (&dum->gadget);
spin_lock_irq (&dum->lock);
dum->pullup = 0;
set_link_state (dum);
@@ -857,7 +858,7 @@ usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
if (!dum)
return -ENODEV;
- if (!driver || driver != dum->driver)
+ if (!driver || driver != dum->driver || !driver->unbind)
return -EINVAL;
dev_dbg (udc_dev(dum), "unregister gadget driver '%s'\n",
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index a265e262a2ee..72f2ae96fbf3 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -4100,7 +4100,7 @@ static struct usb_gadget_driver fsg_driver = {
#endif
.function = (char *) longname,
.bind = fsg_bind,
- .unbind = __exit_p(fsg_unbind),
+ .unbind = fsg_unbind,
.disconnect = fsg_disconnect,
.setup = fsg_setup,
.suspend = fsg_suspend,
diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c
index 31351826f2ba..f1a679656c96 100644
--- a/drivers/usb/gadget/gmidi.c
+++ b/drivers/usb/gadget/gmidi.c
@@ -123,7 +123,7 @@ struct gmidi_device {
struct usb_request *req; /* for control responses */
u8 config;
struct usb_ep *in_ep, *out_ep;
- struct snd_card *card;
+ struct snd_card *card;
struct snd_rawmidi *rmidi;
struct snd_rawmidi_substream *in_substream;
struct snd_rawmidi_substream *out_substream;
@@ -490,7 +490,7 @@ static void gmidi_complete(struct usb_ep *ep, struct usb_request *req)
int status = req->status;
switch (status) {
- case 0: /* normal completion */
+ case 0: /* normal completion */
if (ep == dev->out_ep) {
/* we received stuff.
req is queued again, below */
@@ -505,7 +505,7 @@ static void gmidi_complete(struct usb_ep *ep, struct usb_request *req)
break;
/* this endpoint is normally active while we're configured */
- case -ECONNABORTED: /* hardware forced ep reset */
+ case -ECONNABORTED: /* hardware forced ep reset */
case -ECONNRESET: /* request dequeued */
case -ESHUTDOWN: /* disconnect from host */
VDBG(dev, "%s gone (%d), %d/%d\n", ep->name, status,
@@ -656,7 +656,7 @@ gmidi_set_config(struct gmidi_device *dev, unsigned number, gfp_t gfp_flags)
case USB_SPEED_LOW: speed = "low"; break;
case USB_SPEED_FULL: speed = "full"; break;
case USB_SPEED_HIGH: speed = "high"; break;
- default: speed = "?"; break;
+ default: speed = "?"; break;
}
dev->config = number;
@@ -1308,7 +1308,7 @@ static struct usb_gadget_driver gmidi_driver = {
.speed = USB_SPEED_FULL,
.function = (char *)longname,
.bind = gmidi_bind,
- .unbind = __exit_p(gmidi_unbind),
+ .unbind = gmidi_unbind,
.setup = gmidi_setup,
.disconnect = gmidi_disconnect,
@@ -1316,7 +1316,7 @@ static struct usb_gadget_driver gmidi_driver = {
.suspend = gmidi_suspend,
.resume = gmidi_resume,
- .driver = {
+ .driver = {
.name = (char *)shortname,
.owner = THIS_MODULE,
},
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c
index 805a9826842d..d0ef1d6b3fac 100644
--- a/drivers/usb/gadget/goku_udc.c
+++ b/drivers/usb/gadget/goku_udc.c
@@ -1432,7 +1432,6 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
if (!driver
|| driver->speed != USB_SPEED_FULL
|| !driver->bind
- || !driver->unbind
|| !driver->disconnect
|| !driver->setup)
return -EINVAL;
@@ -1495,7 +1494,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
if (!dev)
return -ENODEV;
- if (!driver || driver != dev->driver)
+ if (!driver || driver != dev->driver || !driver->unbind)
return -EINVAL;
spin_lock_irqsave(&dev->lock, flags);
@@ -1808,13 +1807,8 @@ static void goku_remove(struct pci_dev *pdev)
struct goku_udc *dev = pci_get_drvdata(pdev);
DBG(dev, "%s\n", __FUNCTION__);
- /* start with the driver above us */
- if (dev->driver) {
- /* should have been done already by driver model core */
- WARN(dev, "pci remove, driver '%s' is still registered\n",
- dev->driver->driver.name);
- usb_gadget_unregister_driver(dev->driver);
- }
+
+ BUG_ON(dev->driver);
#ifdef CONFIG_USB_GADGET_DEBUG_FILES
remove_proc_entry(proc_node_name, NULL);
diff --git a/drivers/usb/gadget/lh7a40x_udc.c b/drivers/usb/gadget/lh7a40x_udc.c
index 4a991564a03e..a0a73c08a344 100644
--- a/drivers/usb/gadget/lh7a40x_udc.c
+++ b/drivers/usb/gadget/lh7a40x_udc.c
@@ -422,9 +422,10 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
DEBUG("%s: %s\n", __FUNCTION__, driver->driver.name);
if (!driver
- || driver->speed != USB_SPEED_FULL
- || !driver->bind
- || !driver->unbind || !driver->disconnect || !driver->setup)
+ || driver->speed != USB_SPEED_FULL
+ || !driver->bind
+ || !driver->disconnect
+ || !driver->setup)
return -EINVAL;
if (!dev)
return -ENODEV;
@@ -471,7 +472,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
if (!dev)
return -ENODEV;
- if (!driver || driver != dev->driver)
+ if (!driver || driver != dev->driver || !driver->unbind)
return -EINVAL;
spin_lock_irqsave(&dev->lock, flags);
@@ -2125,9 +2126,11 @@ static int lh7a40x_udc_remove(struct platform_device *pdev)
DEBUG("%s: %p\n", __FUNCTION__, pdev);
+ if (dev->driver)
+ return -EBUSY;
+
udc_disable(dev);
remove_proc_files();
- usb_gadget_unregister_driver(dev->driver);
free_irq(IRQ_USBINTR, dev);
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c
index 3024c679e38e..569eb8ccf232 100644
--- a/drivers/usb/gadget/net2280.c
+++ b/drivers/usb/gadget/net2280.c
@@ -2020,7 +2020,6 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver)
if (!driver
|| driver->speed != USB_SPEED_HIGH
|| !driver->bind
- || !driver->unbind
|| !driver->setup)
return -EINVAL;
if (!dev)
@@ -2107,7 +2106,7 @@ int usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
if (!dev)
return -ENODEV;
- if (!driver || driver != dev->driver)
+ if (!driver || driver != dev->driver || !driver->unbind)
return -EINVAL;
spin_lock_irqsave (&dev->lock, flags);
@@ -2803,13 +2802,7 @@ static void net2280_remove (struct pci_dev *pdev)
{
struct net2280 *dev = pci_get_drvdata (pdev);
- /* start with the driver above us */
- if (dev->driver) {
- /* should have been done already by driver model core */
- WARN (dev, "pci remove, driver '%s' is still registered\n",
- dev->driver->driver.name);
- usb_gadget_unregister_driver (dev->driver);
- }
+ BUG_ON(dev->driver);
/* then clean up the resources we allocated during probe() */
net2280_led_shutdown (dev);
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c
index 030d87c28c2f..15d77c307930 100644
--- a/drivers/usb/gadget/omap_udc.c
+++ b/drivers/usb/gadget/omap_udc.c
@@ -2043,7 +2043,6 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver)
// FIXME if otg, check: driver->is_otg
|| driver->speed < USB_SPEED_FULL
|| !driver->bind
- || !driver->unbind
|| !driver->setup)
return -EINVAL;
@@ -2087,9 +2086,11 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver)
status = otg_set_peripheral(udc->transceiver, &udc->gadget);
if (status < 0) {
ERR("can't bind to transceiver\n");
- driver->unbind (&udc->gadget);
- udc->gadget.dev.driver = NULL;
- udc->driver = NULL;
+ if (driver->unbind) {
+ driver->unbind (&udc->gadget);
+ udc->gadget.dev.driver = NULL;
+ udc->driver = NULL;
+ }
goto done;
}
} else {
@@ -2117,7 +2118,7 @@ int usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
if (!udc)
return -ENODEV;
- if (!driver || driver != udc->driver)
+ if (!driver || driver != udc->driver || !driver->unbind)
return -EINVAL;
if (machine_is_omap_innovator() || machine_is_omap_osk())
@@ -2870,6 +2871,8 @@ static int __exit omap_udc_remove(struct platform_device *pdev)
if (!udc)
return -ENODEV;
+ if (udc->driver)
+ return -EBUSY;
udc->done = &done;
diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c
index 1ed506e95985..b78de9694665 100644
--- a/drivers/usb/gadget/pxa2xx_udc.c
+++ b/drivers/usb/gadget/pxa2xx_udc.c
@@ -1623,7 +1623,6 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
if (!driver
|| driver->speed < USB_SPEED_FULL
|| !driver->bind
- || !driver->unbind
|| !driver->disconnect
|| !driver->setup)
return -EINVAL;
@@ -1694,7 +1693,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
if (!dev)
return -ENODEV;
- if (!driver || driver != dev->driver)
+ if (!driver || driver != dev->driver || !driver->unbind)
return -EINVAL;
local_irq_disable();
@@ -2638,9 +2637,11 @@ static int __exit pxa2xx_udc_remove(struct platform_device *pdev)
{
struct pxa2xx_udc *dev = platform_get_drvdata(pdev);
+ if (dev->driver)
+ return -EBUSY;
+
udc_disable(dev);
remove_proc_files();
- usb_gadget_unregister_driver(dev->driver);
if (dev->got_irq) {
free_irq(IRQ_USB, dev);
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
index 5516c59ed5ec..f8a3ec64635d 100644
--- a/drivers/usb/gadget/serial.c
+++ b/drivers/usb/gadget/serial.c
@@ -296,7 +296,7 @@ static struct usb_gadget_driver gs_gadget_driver = {
#endif /* CONFIG_USB_GADGET_DUALSPEED */
.function = GS_LONG_NAME,
.bind = gs_bind,
- .unbind = __exit_p(gs_unbind),
+ .unbind = gs_unbind,
.setup = gs_setup,
.disconnect = gs_disconnect,
.driver = {
@@ -2195,7 +2195,7 @@ static struct gs_buf *gs_buf_alloc(unsigned int size, gfp_t kmalloc_flags)
if (size == 0)
return NULL;
- gb = (struct gs_buf *)kmalloc(sizeof(struct gs_buf), kmalloc_flags);
+ gb = kmalloc(sizeof(struct gs_buf), kmalloc_flags);
if (gb == NULL)
return NULL;
diff --git a/drivers/usb/host/hc_crisv10.c b/drivers/usb/host/hc_crisv10.c
index 9325e46a68c0..282d82efc0b0 100644
--- a/drivers/usb/host/hc_crisv10.c
+++ b/drivers/usb/host/hc_crisv10.c
@@ -365,7 +365,7 @@ static inline struct urb *urb_list_first(int epid)
/* Adds an urb_entry last in the list for this epid. */
static inline void urb_list_add(struct urb *urb, int epid)
{
- urb_entry_t *urb_entry = (urb_entry_t *)kmalloc(sizeof(urb_entry_t), KMALLOC_FLAG);
+ urb_entry_t *urb_entry = kmalloc(sizeof(urb_entry_t), KMALLOC_FLAG);
assert(urb_entry);
urb_entry->urb = urb;
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index b466581beb4a..cc405512fa1c 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -187,7 +187,6 @@ ohci_at91_start (struct usb_hcd *hcd)
{
struct at91_usbh_data *board = hcd->self.controller->platform_data;
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
- struct usb_device *root = hcd->self.root_hub;
int ret;
if ((ret = ohci_init(ohci)) < 0)
@@ -221,7 +220,7 @@ static const struct hc_driver ohci_at91_hc_driver = {
*/
.start = ohci_at91_start,
.stop = ohci_stop,
- .shutdown = ohci_shutdown,
+ .shutdown = ohci_shutdown,
/*
* managing i/o requests and associated device resources
diff --git a/drivers/usb/host/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c
index 24e23c5783d8..e70b2430e2a9 100644
--- a/drivers/usb/host/ohci-au1xxx.c
+++ b/drivers/usb/host/ohci-au1xxx.c
@@ -269,7 +269,7 @@ static const struct hc_driver ohci_au1xxx_hc_driver = {
*/
.start = ohci_au1xxx_start,
.stop = ohci_stop,
- .shutdown = ohci_shutdown,
+ .shutdown = ohci_shutdown,
/*
* managing i/o requests and associated device resources
@@ -336,7 +336,7 @@ static int ohci_hcd_au1xxx_drv_resume(struct platform_device *dev)
static struct platform_driver ohci_hcd_au1xxx_driver = {
.probe = ohci_hcd_au1xxx_drv_probe,
.remove = ohci_hcd_au1xxx_drv_remove,
- .shutdown = usb_hcd_platform_shutdown,
+ .shutdown = usb_hcd_platform_shutdown,
/*.suspend = ohci_hcd_au1xxx_drv_suspend, */
/*.resume = ohci_hcd_au1xxx_drv_resume, */
.driver = {
diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c
index 0f47a57dac28..273d5ddb72be 100644
--- a/drivers/usb/host/ohci-dbg.c
+++ b/drivers/usb/host/ohci-dbg.c
@@ -16,7 +16,7 @@
case PIPE_CONTROL: temp = "ctrl"; break; \
case PIPE_BULK: temp = "bulk"; break; \
case PIPE_INTERRUPT: temp = "intr"; break; \
- default: temp = "isoc"; break; \
+ default: temp = "isoc"; break; \
}; temp;})
#define pipestring(pipe) edstring(usb_pipetype(pipe))
@@ -205,13 +205,13 @@ ohci_dump_status (struct ohci_hcd *controller, char **next, unsigned *size)
(temp & RH_PS_PSSC) ? " PSSC" : "", \
(temp & RH_PS_PESC) ? " PESC" : "", \
(temp & RH_PS_CSC) ? " CSC" : "", \
- \
+ \
(temp & RH_PS_LSDA) ? " LSDA" : "", \
(temp & RH_PS_PPS) ? " PPS" : "", \
(temp & RH_PS_PRS) ? " PRS" : "", \
(temp & RH_PS_POCI) ? " POCI" : "", \
(temp & RH_PS_PSS) ? " PSS" : "", \
- \
+ \
(temp & RH_PS_PES) ? " PES" : "", \
(temp & RH_PS_CCS) ? " CCS" : "" \
);
@@ -563,7 +563,7 @@ show_periodic (struct class_device *class_dev, char *buf)
(info & ED_SKIP) ? " K" : "",
(ed->hwHeadP &
cpu_to_hc32(ohci, ED_H)) ?
- " H" : "");
+ " H" : "");
size -= temp;
next += temp;
diff --git a/drivers/usb/host/ohci-ep93xx.c b/drivers/usb/host/ohci-ep93xx.c
index 1bf5e7a4e735..43ae696b2ec2 100644
--- a/drivers/usb/host/ohci-ep93xx.c
+++ b/drivers/usb/host/ohci-ep93xx.c
@@ -204,7 +204,7 @@ static int ohci_hcd_ep93xx_drv_resume(struct platform_device *pdev)
static struct platform_driver ohci_hcd_ep93xx_driver = {
.probe = ohci_hcd_ep93xx_drv_probe,
.remove = ohci_hcd_ep93xx_drv_remove,
- .shutdown = usb_hcd_platform_shutdown,
+ .shutdown = usb_hcd_platform_shutdown,
#ifdef CONFIG_PM
.suspend = ohci_hcd_ep93xx_drv_suspend,
.resume = ohci_hcd_ep93xx_drv_resume,
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index b28a9b602066..c1c1d871aba4 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -3,77 +3,21 @@
*
* (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
* (C) Copyright 2000-2004 David Brownell <dbrownell@users.sourceforge.net>
- *
+ *
* [ Initialisation is based on Linus' ]
* [ uhci code and gregs ohci fragments ]
* [ (C) Copyright 1999 Linus Torvalds ]
* [ (C) Copyright 1999 Gregory P. Smith]
- *
- *
+ *
+ *
* OHCI is the main "non-Intel/VIA" standard for USB 1.1 host controller
* interfaces (though some non-x86 Intel chips use it). It supports
* smarter hardware than UHCI. A download link for the spec available
* through the http://www.usb.org website.
*
- * History:
- *
- * 2004/03/24 LH7A404 support (Durgesh Pattamatta & Marc Singer)
- * 2004/02/04 use generic dma_* functions instead of pci_* (dsaxena@plexity.net)
- * 2003/02/24 show registers in sysfs (Kevin Brosius)
- *
- * 2002/09/03 get rid of ed hashtables, rework periodic scheduling and
- * bandwidth accounting; if debugging, show schedules in driverfs
- * 2002/07/19 fixes to management of ED and schedule state.
- * 2002/06/09 SA-1111 support (Christopher Hoover)
- * 2002/06/01 remember frame when HC won't see EDs any more; use that info
- * to fix urb unlink races caused by interrupt latency assumptions;
- * minor ED field and function naming updates
- * 2002/01/18 package as a patch for 2.5.3; this should match the
- * 2.4.17 kernel modulo some bugs being fixed.
- *
- * 2001/10/18 merge pmac cleanup (Benjamin Herrenschmidt) and bugfixes
- * from post-2.4.5 patches.
- * 2001/09/20 URB_ZERO_PACKET support; hcca_dma portability, OPTi warning
- * 2001/09/07 match PCI PM changes, errnos from Linus' tree
- * 2001/05/05 fork 2.4.5 version into "hcd" framework, cleanup, simplify;
- * pbook pci quirks gone (please fix pbook pci sw!) (db)
- *
- * 2001/04/08 Identify version on module load (gb)
- * 2001/03/24 td/ed hashing to remove bus_to_virt (Steve Longerbeam);
- pci_map_single (db)
- * 2001/03/21 td and dev/ed allocation uses new pci_pool API (db)
- * 2001/03/07 hcca allocation uses pci_alloc_consistent (Steve Longerbeam)
- *
- * 2000/09/26 fixed races in removing the private portion of the urb
- * 2000/09/07 disable bulk and control lists when unlinking the last
- * endpoint descriptor in order to avoid unrecoverable errors on
- * the Lucent chips. (rwc@sgi)
- * 2000/08/29 use bandwidth claiming hooks (thanks Randy!), fix some
- * urb unlink probs, indentation fixes
- * 2000/08/11 various oops fixes mostly affecting iso and cleanup from
- * device unplugs.
- * 2000/06/28 use PCI hotplug framework, for better power management
- * and for Cardbus support (David Brownell)
- * 2000/earlier: fixes for NEC/Lucent chips; suspend/resume handling
- * when the controller loses power; handle UE; cleanup; ...
- *
- * v5.2 1999/12/07 URB 3rd preview,
- * v5.1 1999/11/30 URB 2nd preview, cpia, (usb-scsi)
- * v5.0 1999/11/22 URB Technical preview, Paul Mackerras powerbook susp/resume
- * i386: HUB, Keyboard, Mouse, Printer
- *
- * v4.3 1999/10/27 multiple HCs, bulk_request
- * v4.2 1999/09/05 ISO API alpha, new dev alloc, neg Error-codes
- * v4.1 1999/08/27 Randy Dunlap's - ISO API first impl.
- * v4.0 1999/08/18
- * v3.0 1999/06/25
- * v2.1 1999/05/09 code clean up
- * v2.0 1999/05/04
- * v1.0 1999/04/27 initial release
- *
* This file is licenced under the GPL.
*/
-
+
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/pci.h>
@@ -89,7 +33,7 @@
#include <linux/list.h>
#include <linux/usb.h>
#include <linux/usb/otg.h>
-#include <linux/dma-mapping.h>
+#include <linux/dma-mapping.h>
#include <linux/dmapool.h>
#include <linux/reboot.h>
@@ -183,11 +127,11 @@ static int ohci_urb_enqueue (
int i, size = 0;
unsigned long flags;
int retval = 0;
-
+
#ifdef OHCI_VERBOSE_DEBUG
urb_print (urb, "SUB", usb_pipein (pipe));
#endif
-
+
/* every endpoint has a ed, locate and maybe (re)initialize it */
if (! (ed = ed_get (ohci, ep, urb->dev, pipe, urb->interval)))
return -ENOMEM;
@@ -232,7 +176,7 @@ static int ohci_urb_enqueue (
memset (urb_priv, 0, sizeof (urb_priv_t) + size * sizeof (struct td *));
INIT_LIST_HEAD (&urb_priv->pending);
urb_priv->length = size;
- urb_priv->ed = ed;
+ urb_priv->ed = ed;
/* allocate the TDs (deferring hash chain updates) */
for (i = 0; i < size; i++) {
@@ -242,7 +186,7 @@ static int ohci_urb_enqueue (
urb_free_priv (ohci, urb_priv);
return -ENOMEM;
}
- }
+ }
spin_lock_irqsave (&ohci->lock, flags);
@@ -313,13 +257,13 @@ static int ohci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb)
{
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
unsigned long flags;
-
+
#ifdef OHCI_VERBOSE_DEBUG
urb_print (urb, "UNLINK", 1);
-#endif
+#endif
spin_lock_irqsave (&ohci->lock, flags);
- if (HC_IS_RUNNING(hcd->state)) {
+ if (HC_IS_RUNNING(hcd->state)) {
urb_priv_t *urb_priv;
/* Unless an IRQ completed the unlink while it was being
@@ -512,11 +456,11 @@ static int ohci_init (struct ohci_hcd *ohci)
/* Start an OHCI controller, set the BUS operational
* resets USB and controller
- * enable interrupts
+ * enable interrupts
*/
static int ohci_run (struct ohci_hcd *ohci)
{
- u32 mask, temp;
+ u32 mask, temp;
int first = ohci->fminterval == 0;
struct usb_hcd *hcd = ohci_to_hcd(ohci);
@@ -534,7 +478,7 @@ static int ohci_run (struct ohci_hcd *ohci)
/* also: power/overcurrent flags in roothub.a */
}
- /* Reset USB nearly "by the book". RemoteWakeupConnected was
+ /* Reset USB nearly "by the book". RemoteWakeupConnected was
* saved if boot firmware (BIOS/SMM/...) told us it's connected,
* or if bus glue did the same (e.g. for PCI add-in cards with
* PCI PM support).
@@ -765,9 +709,9 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd)
dl_done_list (ohci);
spin_unlock (&ohci->lock);
if (HC_IS_RUNNING(hcd->state))
- ohci_writel (ohci, OHCI_INTR_WDH, &regs->intrenable);
+ ohci_writel (ohci, OHCI_INTR_WDH, &regs->intrenable);
}
-
+
/* could track INTR_SO to reduce available PCI/... bandwidth */
/* handle any pending URB/ED unlinks, leaving INTR_SF enabled
@@ -778,12 +722,12 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd)
finish_unlinks (ohci, ohci_frame_no(ohci));
if ((ints & OHCI_INTR_SF) != 0 && !ohci->ed_rm_list
&& HC_IS_RUNNING(hcd->state))
- ohci_writel (ohci, OHCI_INTR_SF, &regs->intrdisable);
+ ohci_writel (ohci, OHCI_INTR_SF, &regs->intrdisable);
spin_unlock (&ohci->lock);
if (HC_IS_RUNNING(hcd->state)) {
ohci_writel (ohci, ints, &regs->intrstatus);
- ohci_writel (ohci, OHCI_INTR_MIE, &regs->intrenable);
+ ohci_writel (ohci, OHCI_INTR_MIE, &regs->intrenable);
// flush those writes
(void) ohci_readl (ohci, &ohci->regs->control);
}
@@ -794,7 +738,7 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd)
/*-------------------------------------------------------------------------*/
static void ohci_stop (struct usb_hcd *hcd)
-{
+{
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
ohci_dbg (ohci, "stop %s controller (state 0x%02x)\n",
@@ -812,8 +756,8 @@ static void ohci_stop (struct usb_hcd *hcd)
remove_debug_files (ohci);
ohci_mem_cleanup (ohci);
if (ohci->hcca) {
- dma_free_coherent (hcd->self.controller,
- sizeof *ohci->hcca,
+ dma_free_coherent (hcd->self.controller,
+ sizeof *ohci->hcca,
ohci->hcca, ohci->hcca_dma);
ohci->hcca = NULL;
ohci->hcca_dma = 0;
@@ -836,7 +780,7 @@ static int ohci_restart (struct ohci_hcd *ohci)
* recycle any "live" eds/tds (and urbs) right away.
* later, khubd disconnect processing will recycle the other state,
* (either as disconnect/reconnect, or maybe someday as a reset).
- */
+ */
spin_lock_irq(&ohci->lock);
disable (ohci);
usb_root_hub_lost_power(ohci_to_hcd(ohci)->self.root_hub);
@@ -875,11 +819,11 @@ static int ohci_restart (struct ohci_hcd *ohci)
/* empty the interrupt branches */
for (i = 0; i < NUM_INTS; i++) ohci->load [i] = 0;
for (i = 0; i < NUM_INTS; i++) ohci->hcca->int_table [i] = 0;
-
+
/* no EDs to remove */
ohci->ed_rm_list = NULL;
- /* empty control and bulk lists */
+ /* empty control and bulk lists */
ohci->ed_controltail = NULL;
ohci->ed_bulktail = NULL;
@@ -941,6 +885,10 @@ MODULE_LICENSE ("GPL");
#include "ohci-au1xxx.c"
#endif
+#ifdef CONFIG_PNX8550
+#include "ohci-pnx8550.c"
+#endif
+
#ifdef CONFIG_USB_OHCI_HCD_PPC_SOC
#include "ohci-ppc-soc.c"
#endif
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c
index 2441642cb7b4..216c9c9d4d6d 100644
--- a/drivers/usb/host/ohci-hub.c
+++ b/drivers/usb/host/ohci-hub.c
@@ -1,9 +1,9 @@
/*
* OHCI HCD (Host Controller Driver) for USB.
- *
+ *
* (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
* (C) Copyright 2000-2004 David Brownell <dbrownell@users.sourceforge.net>
- *
+ *
* This file is licenced under GPL
*/
@@ -23,13 +23,13 @@
(temp & RH_PS_PSSC) ? " PSSC" : "", \
(temp & RH_PS_PESC) ? " PESC" : "", \
(temp & RH_PS_CSC) ? " CSC" : "", \
- \
+ \
(temp & RH_PS_LSDA) ? " LSDA" : "", \
(temp & RH_PS_PPS) ? " PPS" : "", \
(temp & RH_PS_PRS) ? " PRS" : "", \
(temp & RH_PS_POCI) ? " POCI" : "", \
(temp & RH_PS_PSS) ? " PSS" : "", \
- \
+ \
(temp & RH_PS_PES) ? " PES" : "", \
(temp & RH_PS_CCS) ? " CCS" : "" \
);
@@ -484,7 +484,7 @@ ohci_hub_descriptor (
temp = 0;
if (rh & RH_A_NPS) /* no power switching? */
temp |= 0x0002;
- if (rh & RH_A_PSM) /* per-port power switching? */
+ if (rh & RH_A_PSM) /* per-port power switching? */
temp |= 0x0001;
if (rh & RH_A_NOCP) /* no overcurrent reporting? */
temp |= 0x0010;
@@ -555,7 +555,7 @@ static void start_hnp(struct ohci_hcd *ohci);
#define tick_before(t1,t2) ((s16)(((s16)(t1))-((s16)(t2))) < 0)
/* called from some task, normally khubd */
-static inline void root_port_reset (struct ohci_hcd *ohci, unsigned port)
+static inline int root_port_reset (struct ohci_hcd *ohci, unsigned port)
{
__hc32 __iomem *portstat = &ohci->regs->roothub.portstatus [port];
u32 temp;
@@ -570,10 +570,13 @@ static inline void root_port_reset (struct ohci_hcd *ohci, unsigned port)
/* spin until any current reset finishes */
for (;;) {
temp = ohci_readl (ohci, portstat);
+ /* handle e.g. CardBus eject */
+ if (temp == ~(u32)0)
+ return -ESHUTDOWN;
if (!(temp & RH_PS_PRS))
break;
udelay (500);
- }
+ }
if (!(temp & RH_PS_CCS))
break;
@@ -586,6 +589,8 @@ static inline void root_port_reset (struct ohci_hcd *ohci, unsigned port)
now = ohci_readl(ohci, &ohci->regs->fmnumber);
} while (tick_before(now, reset_done));
/* caller synchronizes using PRSC */
+
+ return 0;
}
static int ohci_hub_control (
@@ -702,7 +707,7 @@ static int ohci_hub_control (
&ohci->regs->roothub.portstatus [wIndex]);
break;
case USB_PORT_FEAT_RESET:
- root_port_reset (ohci, wIndex);
+ retval = root_port_reset (ohci, wIndex);
break;
default:
goto error;
diff --git a/drivers/usb/host/ohci-lh7a404.c b/drivers/usb/host/ohci-lh7a404.c
index e121d97ed91c..e9807cf73a2f 100644
--- a/drivers/usb/host/ohci-lh7a404.c
+++ b/drivers/usb/host/ohci-lh7a404.c
@@ -38,7 +38,7 @@ static void lh7a404_start_hc(struct platform_device *dev)
CSC_PWRCNT |= CSC_PWRCNT_USBH_EN; /* Enable clock */
udelay(1000);
USBH_CMDSTATUS = OHCI_HCR;
-
+
printk(KERN_DEBUG __FILE__
": Clock to USB host has been enabled \n");
}
@@ -89,7 +89,7 @@ int usb_hcd_lh7a404_probe (const struct hc_driver *driver,
retval = -EBUSY;
goto err1;
}
-
+
hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
if (!hcd->regs) {
pr_debug("ioremap failed");
@@ -174,7 +174,7 @@ static const struct hc_driver ohci_lh7a404_hc_driver = {
*/
.start = ohci_lh7a404_start,
.stop = ohci_stop,
- .shutdown = ohci_shutdown,
+ .shutdown = ohci_shutdown,
/*
* managing i/o requests and associated device resources
@@ -242,7 +242,7 @@ static int ohci_hcd_lh7a404_drv_resume(struct platform_device *dev)
static struct platform_driver ohci_hcd_lh7a404_driver = {
.probe = ohci_hcd_lh7a404_drv_probe,
.remove = ohci_hcd_lh7a404_drv_remove,
- .shutdown = usb_hcd_platform_shutdown,
+ .shutdown = usb_hcd_platform_shutdown,
/*.suspend = ohci_hcd_lh7a404_drv_suspend, */
/*.resume = ohci_hcd_lh7a404_drv_resume, */
.driver = {
diff --git a/drivers/usb/host/ohci-mem.c b/drivers/usb/host/ohci-mem.c
index d976614eebd3..2f20d3dc895b 100644
--- a/drivers/usb/host/ohci-mem.c
+++ b/drivers/usb/host/ohci-mem.c
@@ -1,24 +1,24 @@
/*
* OHCI HCD (Host Controller Driver) for USB.
- *
+ *
* (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
* (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
- *
+ *
* This file is licenced under the GPL.
*/
/*-------------------------------------------------------------------------*/
/*
- * There's basically three types of memory:
+ * OHCI deals with three types of memory:
* - data used only by the HCD ... kmalloc is fine
* - async and periodic schedules, shared by HC and HCD ... these
* need to use dma_pool or dma_alloc_coherent
* - driver buffers, read/written by HC ... the hcd glue or the
* device driver provides us with dma addresses
*
- * There's also PCI "register" data, which is memory mapped.
- * No memory seen by this driver is pagable.
+ * There's also "register" data, which is memory mapped.
+ * No memory seen by this driver (or any HCD) may be paged out.
*/
/*-------------------------------------------------------------------------*/
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
index 9c02177de50a..27be1f936885 100644
--- a/drivers/usb/host/ohci-omap.c
+++ b/drivers/usb/host/ohci-omap.c
@@ -447,7 +447,7 @@ static const struct hc_driver ohci_omap_hc_driver = {
.reset = ohci_omap_init,
.start = ohci_omap_start,
.stop = ohci_omap_stop,
- .shutdown = ohci_shutdown,
+ .shutdown = ohci_shutdown,
/*
* managing i/o requests and associated device resources
@@ -533,7 +533,7 @@ static int ohci_omap_resume(struct platform_device *dev)
static struct platform_driver ohci_hcd_omap_driver = {
.probe = ohci_hcd_omap_drv_probe,
.remove = ohci_hcd_omap_drv_remove,
- .shutdown = usb_hcd_platform_shutdown,
+ .shutdown = usb_hcd_platform_shutdown,
#ifdef CONFIG_PM
.suspend = ohci_omap_suspend,
.resume = ohci_omap_resume,
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c
index 874418552789..596e0b41e606 100644
--- a/drivers/usb/host/ohci-pci.c
+++ b/drivers/usb/host/ohci-pci.c
@@ -3,17 +3,17 @@
*
* (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
* (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
- *
+ *
* [ Initialisation is based on Linus' ]
* [ uhci code and gregs ohci fragments ]
* [ (C) Copyright 1999 Linus Torvalds ]
* [ (C) Copyright 1999 Gregory P. Smith]
- *
+ *
* PCI Bus Glue
*
* This file is licenced under the GPL.
*/
-
+
#ifndef CONFIG_PCI
#error "This file is PCI bus glue. CONFIG_PCI must be defined."
#endif
@@ -83,7 +83,7 @@ ohci_pci_start (struct usb_hcd *hcd)
pci_dev_put(b);
}
- /* Check for Compaq's ZFMicro chipset, which needs short
+ /* Check for Compaq's ZFMicro chipset, which needs short
* delays before control or bulk queues get re-activated
* in finish_unlinks()
*/
@@ -238,8 +238,8 @@ static struct pci_driver ohci_pci_driver = {
.shutdown = usb_hcd_pci_shutdown,
};
-
-static int __init ohci_hcd_pci_init (void)
+
+static int __init ohci_hcd_pci_init (void)
{
printk (KERN_DEBUG "%s: " DRIVER_INFO " (PCI)\n", hcd_name);
if (usb_disabled())
@@ -253,8 +253,8 @@ module_init (ohci_hcd_pci_init);
/*-------------------------------------------------------------------------*/
-static void __exit ohci_hcd_pci_cleanup (void)
-{
+static void __exit ohci_hcd_pci_cleanup (void)
+{
pci_unregister_driver (&ohci_pci_driver);
}
module_exit (ohci_hcd_pci_cleanup);
diff --git a/drivers/usb/host/ohci-pnx4008.c b/drivers/usb/host/ohci-pnx4008.c
index 7f26f9bdbaf1..3a8cbfb69054 100644
--- a/drivers/usb/host/ohci-pnx4008.c
+++ b/drivers/usb/host/ohci-pnx4008.c
@@ -4,7 +4,7 @@
* driver for Philips PNX4008 USB Host
*
* Authors: Dmitry Chigirev <source@mvista.com>
- * Vitaly Wool <vitalywool@gmail.com>
+ * Vitaly Wool <vitalywool@gmail.com>
*
* register initialization is based on code examples provided by Philips
* Copyright (c) 2005 Koninklijke Philips Electronics N.V.
@@ -29,7 +29,7 @@
#include <asm/arch/irqs.h>
#include <asm/arch/gpio.h>
-#define USB_CTRL IO_ADDRESS(PNX4008_PWRMAN_BASE + 0x64)
+#define USB_CTRL IO_ADDRESS(PNX4008_PWRMAN_BASE + 0x64)
/* USB_CTRL bit defines */
#define USB_SLAVE_HCLK_EN (1 << 24)
diff --git a/drivers/usb/host/ohci-pnx8550.c b/drivers/usb/host/ohci-pnx8550.c
new file mode 100644
index 000000000000..6922b91b1704
--- /dev/null
+++ b/drivers/usb/host/ohci-pnx8550.c
@@ -0,0 +1,258 @@
+/*
+ * OHCI HCD (Host Controller Driver) for USB.
+ *
+ * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
+ * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
+ * (C) Copyright 2002 Hewlett-Packard Company
+ * (C) Copyright 2005 Embedded Alley Solutions, Inc.
+ *
+ * Bus Glue for PNX8550
+ *
+ * Written by Christopher Hoover <ch@hpl.hp.com>
+ * Based on fragments of previous driver by Russell King et al.
+ *
+ * Modified for LH7A404 from ohci-sa1111.c
+ * by Durgesh Pattamatta <pattamattad@sharpsec.com>
+ *
+ * Modified for PNX8550 from ohci-sa1111.c and sa-omap.c
+ * by Vitaly Wool <vitalywool@gmail.com>
+ *
+ * This file is licenced under the GPL.
+ */
+
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <asm/mach-pnx8550/usb.h>
+#include <asm/mach-pnx8550/int.h>
+#include <asm/mach-pnx8550/pci.h>
+
+#ifndef CONFIG_PNX8550
+#error "This file is PNX8550 bus glue. CONFIG_PNX8550 must be defined."
+#endif
+
+extern int usb_disabled(void);
+
+/*-------------------------------------------------------------------------*/
+
+static void pnx8550_start_hc(struct platform_device *dev)
+{
+ /*
+ * Set register CLK48CTL to enable and 48MHz
+ */
+ outl(0x00000003, PCI_BASE | 0x0004770c);
+
+ /*
+ * Set register CLK12CTL to enable and 48MHz
+ */
+ outl(0x00000003, PCI_BASE | 0x00047710);
+
+ udelay(100);
+}
+
+static void pnx8550_stop_hc(struct platform_device *dev)
+{
+ udelay(10);
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+/* configure so an HC device and id are always provided */
+/* always called with process context; sleeping is OK */
+
+
+/**
+ * usb_hcd_pnx8550_probe - initialize pnx8550-based 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.
+ *
+ */
+int usb_hcd_pnx8550_probe (const struct hc_driver *driver,
+ struct platform_device *dev)
+{
+ int retval;
+ struct usb_hcd *hcd;
+
+ if (dev->resource[0].flags != IORESOURCE_MEM ||
+ dev->resource[1].flags != IORESOURCE_IRQ) {
+ dev_err (&dev->dev,"invalid resource type\n");
+ return -ENOMEM;
+ }
+
+ hcd = usb_create_hcd (driver, &dev->dev, "pnx8550");
+ if (!hcd)
+ return -ENOMEM;
+ hcd->rsrc_start = dev->resource[0].start;
+ hcd->rsrc_len = dev->resource[0].end - dev->resource[0].start + 1;
+
+ if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
+ dev_err(&dev->dev, "request_mem_region [0x%08llx, 0x%08llx] "
+ "failed\n", hcd->rsrc_start, hcd->rsrc_len);
+ retval = -EBUSY;
+ goto err1;
+ }
+
+ hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
+ if (!hcd->regs) {
+ dev_err(&dev->dev, "ioremap [[0x%08llx, 0x%08llx] failed\n",
+ hcd->rsrc_start, hcd->rsrc_len);
+ retval = -ENOMEM;
+ goto err2;
+ }
+
+ pnx8550_start_hc(dev);
+
+ ohci_hcd_init(hcd_to_ohci(hcd));
+
+ retval = usb_add_hcd(hcd, dev->resource[1].start, SA_INTERRUPT);
+ if (retval == 0)
+ return retval;
+
+ pnx8550_stop_hc(dev);
+ iounmap(hcd->regs);
+ err2:
+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+ err1:
+ usb_put_hcd(hcd);
+ return retval;
+}
+
+
+/* may be called without controller electrically present */
+/* may be called with controller, bus, and devices active */
+
+/**
+ * usb_hcd_pnx8550_remove - shutdown processing for pnx8550-based HCDs
+ * @dev: USB Host Controller being removed
+ * Context: !in_interrupt()
+ *
+ * Reverses the effect of usb_hcd_pnx8550_probe(), first invoking
+ * the HCD's stop() method. It is always called from a thread
+ * context, normally "rmmod", "apmd", or something similar.
+ *
+ */
+void usb_hcd_pnx8550_remove (struct usb_hcd *hcd, struct platform_device *dev)
+{
+ usb_remove_hcd(hcd);
+ pnx8550_stop_hc(dev);
+ iounmap(hcd->regs);
+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+ usb_put_hcd(hcd);
+}
+
+/*-------------------------------------------------------------------------*/
+
+static int __devinit
+ohci_pnx8550_start (struct usb_hcd *hcd)
+{
+ struct ohci_hcd *ohci = hcd_to_ohci (hcd);
+ int ret;
+
+ ohci_dbg (ohci, "ohci_pnx8550_start, ohci:%p", ohci);
+
+ if ((ret = ohci_init(ohci)) < 0)
+ return ret;
+
+ if ((ret = ohci_run (ohci)) < 0) {
+ err ("can't start %s", hcd->self.bus_name);
+ ohci_stop (hcd);
+ return ret;
+ }
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static const struct hc_driver ohci_pnx8550_hc_driver = {
+ .description = hcd_name,
+ .product_desc = "PNX8550 OHCI",
+ .hcd_priv_size = sizeof(struct ohci_hcd),
+
+ /*
+ * generic hardware linkage
+ */
+ .irq = ohci_irq,
+ .flags = HCD_USB11 | HCD_MEMORY,
+
+ /*
+ * basic lifecycle operations
+ */
+ .start = ohci_pnx8550_start,
+ .stop = ohci_stop,
+
+ /*
+ * managing i/o requests and associated device resources
+ */
+ .urb_enqueue = ohci_urb_enqueue,
+ .urb_dequeue = ohci_urb_dequeue,
+ .endpoint_disable = ohci_endpoint_disable,
+
+ /*
+ * scheduling support
+ */
+ .get_frame_number = ohci_get_frame,
+
+ /*
+ * root hub support
+ */
+ .hub_status_data = ohci_hub_status_data,
+ .hub_control = ohci_hub_control,
+ .hub_irq_enable = ohci_rhsc_enable,
+#ifdef CONFIG_PM
+ .bus_suspend = ohci_bus_suspend,
+ .bus_resume = ohci_bus_resume,
+#endif
+ .start_port_reset = ohci_start_port_reset,
+};
+
+/*-------------------------------------------------------------------------*/
+
+static int ohci_hcd_pnx8550_drv_probe(struct platform_device *pdev)
+{
+ int ret;
+
+ if (usb_disabled())
+ return -ENODEV;
+
+ ret = usb_hcd_pnx8550_probe(&ohci_pnx8550_hc_driver, pdev);
+ return ret;
+}
+
+static int ohci_hcd_pnx8550_drv_remove(struct platform_device *pdev)
+{
+ struct usb_hcd *hcd = platform_get_drvdata(pdev);
+
+ usb_hcd_pnx8550_remove(hcd, pdev);
+ return 0;
+}
+
+MODULE_ALIAS("pnx8550-ohci");
+
+static struct platform_driver ohci_hcd_pnx8550_driver = {
+ .driver = {
+ .name = "pnx8550-ohci",
+ },
+ .probe = ohci_hcd_pnx8550_drv_probe,
+ .remove = ohci_hcd_pnx8550_drv_remove,
+};
+
+static int __init ohci_hcd_pnx8550_init (void)
+{
+ pr_debug (DRIVER_INFO " (pnx8550)");
+ pr_debug ("block sizes: ed %d td %d\n",
+ sizeof (struct ed), sizeof (struct td));
+
+ return platform_driver_register(&ohci_hcd_pnx8550_driver);
+}
+
+static void __exit ohci_hcd_pnx8550_cleanup (void)
+{
+ platform_driver_unregister(&ohci_hcd_pnx8550_driver);
+}
+
+module_init (ohci_hcd_pnx8550_init);
+module_exit (ohci_hcd_pnx8550_cleanup);
diff --git a/drivers/usb/host/ohci-ppc-soc.c b/drivers/usb/host/ohci-ppc-soc.c
index d9d1ae236bd5..e1a7eb817313 100644
--- a/drivers/usb/host/ohci-ppc-soc.c
+++ b/drivers/usb/host/ohci-ppc-soc.c
@@ -5,7 +5,7 @@
* (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
* (C) Copyright 2002 Hewlett-Packard Company
* (C) Copyright 2003-2005 MontaVista Software Inc.
- *
+ *
* Bus Glue for PPC On-Chip OHCI driver
* Tested on Freescale MPC5200 and IBM STB04xxx
*
@@ -85,7 +85,7 @@ static int usb_hcd_ppc_soc_probe(const struct hc_driver *driver,
err2:
release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
err1:
- usb_put_hcd(hcd);
+ usb_put_hcd(hcd);
return retval;
}
@@ -148,7 +148,7 @@ static const struct hc_driver ohci_ppc_soc_hc_driver = {
*/
.start = ohci_ppc_soc_start,
.stop = ohci_stop,
- .shutdown = ohci_shutdown,
+ .shutdown = ohci_shutdown,
/*
* managing i/o requests and associated device resources
@@ -197,7 +197,7 @@ static int ohci_hcd_ppc_soc_drv_remove(struct platform_device *pdev)
static struct platform_driver ohci_hcd_ppc_soc_driver = {
.probe = ohci_hcd_ppc_soc_drv_probe,
.remove = ohci_hcd_ppc_soc_drv_remove,
- .shutdown = usb_hcd_platform_shutdown,
+ .shutdown = usb_hcd_platform_shutdown,
#ifdef CONFIG_PM
/*.suspend = ohci_hcd_ppc_soc_drv_suspend,*/
/*.resume = ohci_hcd_ppc_soc_drv_resume,*/
diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c
index e176b04d7aeb..3bbea844a9e3 100644
--- a/drivers/usb/host/ohci-pxa27x.c
+++ b/drivers/usb/host/ohci-pxa27x.c
@@ -47,7 +47,7 @@ static int pxa27x_ohci_select_pmm( int mode )
switch ( mode ) {
case PMM_NPS_MODE:
UHCRHDA |= RH_A_NPS;
- break;
+ break;
case PMM_GLOBAL_MODE:
UHCRHDA &= ~(RH_A_NPS & RH_A_PSM);
break;
@@ -60,7 +60,7 @@ static int pxa27x_ohci_select_pmm( int mode )
break;
default:
printk( KERN_ERR
- "Invalid mode %d, set to non-power switch mode.\n",
+ "Invalid mode %d, set to non-power switch mode.\n",
mode );
UHCRHDA |= RH_A_NPS;
@@ -270,7 +270,7 @@ static const struct hc_driver ohci_pxa27x_hc_driver = {
*/
.start = ohci_pxa27x_start,
.stop = ohci_stop,
- .shutdown = ohci_shutdown,
+ .shutdown = ohci_shutdown,
/*
* managing i/o requests and associated device resources
@@ -359,9 +359,9 @@ static int ohci_hcd_pxa27x_drv_resume(struct platform_device *pdev)
static struct platform_driver ohci_hcd_pxa27x_driver = {
.probe = ohci_hcd_pxa27x_drv_probe,
.remove = ohci_hcd_pxa27x_drv_remove,
- .shutdown = usb_hcd_platform_shutdown,
+ .shutdown = usb_hcd_platform_shutdown,
#ifdef CONFIG_PM
- .suspend = ohci_hcd_pxa27x_drv_suspend,
+ .suspend = ohci_hcd_pxa27x_drv_suspend,
.resume = ohci_hcd_pxa27x_drv_resume,
#endif
.driver = {
diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c
index fe1fe2f97cb5..830a3fe8615e 100644
--- a/drivers/usb/host/ohci-q.c
+++ b/drivers/usb/host/ohci-q.c
@@ -1,9 +1,9 @@
/*
* OHCI HCD (Host Controller Driver) for USB.
- *
+ *
* (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
* (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
- *
+ *
* This file is licenced under the GPL.
*/
@@ -89,7 +89,7 @@ __acquires(ohci->lock)
/*-------------------------------------------------------------------------*
* ED handling functions
- *-------------------------------------------------------------------------*/
+ *-------------------------------------------------------------------------*/
/* search for the right schedule branch to use for a periodic ed.
* does some load balancing; returns the branch, or negative errno.
@@ -107,7 +107,6 @@ static int balance (struct ohci_hcd *ohci, int interval, int load)
*/
for (i = 0; i < interval ; i++) {
if (branch < 0 || ohci->load [branch] > ohci->load [i]) {
-#if 1 /* CONFIG_USB_BANDWIDTH */
int j;
/* usb 1.1 says 90% of one frame */
@@ -117,8 +116,7 @@ static int balance (struct ohci_hcd *ohci, int interval, int load)
}
if (j < NUM_INTS)
continue;
-#endif
- branch = i;
+ branch = i;
}
}
return branch;
@@ -171,7 +169,7 @@ static void periodic_link (struct ohci_hcd *ohci, struct ed *ed)
/* link an ed into one of the HC chains */
static int ed_schedule (struct ohci_hcd *ohci, struct ed *ed)
-{
+{
int branch;
if (ohci_to_hcd(ohci)->state == HC_STATE_QUIESCING)
@@ -248,7 +246,7 @@ static int ed_schedule (struct ohci_hcd *ohci, struct ed *ed)
}
ed->branch = branch;
periodic_link (ohci, ed);
- }
+ }
/* the HC may not see the schedule updates yet, but if it does
* then they'll be properly ordered.
@@ -277,7 +275,7 @@ static void periodic_unlink (struct ohci_hcd *ohci, struct ed *ed)
*prev = ed->ed_next;
}
ohci->load [i] -= ed->load;
- }
+ }
ohci_to_hcd(ohci)->self.bandwidth_allocated -= ed->load / ed->interval;
ohci_vdbg (ohci, "unlink %sed %p branch %d [%dus.], interval %d\n",
@@ -285,7 +283,7 @@ static void periodic_unlink (struct ohci_hcd *ohci, struct ed *ed)
ed, ed->branch, ed->load, ed->interval);
}
-/* unlink an ed from one of the HC chains.
+/* unlink an ed from one of the HC chains.
* just the link to the ed is unlinked.
* the link from the ed still points to another operational ed or 0
* so the HC can eventually finish the processing of the unlinked ed
@@ -307,7 +305,7 @@ static void periodic_unlink (struct ohci_hcd *ohci, struct ed *ed)
* When finish_unlinks() runs later, after SOF interrupt, it will often
* complete one or more URB unlinks before making that state change.
*/
-static void ed_deschedule (struct ohci_hcd *ohci, struct ed *ed)
+static void ed_deschedule (struct ohci_hcd *ohci, struct ed *ed)
{
ed->hwINFO |= cpu_to_hc32 (ohci, ED_SKIP);
wmb ();
@@ -397,7 +395,7 @@ static struct ed *ed_get (
unsigned int pipe,
int interval
) {
- struct ed *ed;
+ struct ed *ed;
unsigned long flags;
spin_lock_irqsave (&ohci->lock, flags);
@@ -413,9 +411,9 @@ static struct ed *ed_get (
goto done;
}
- /* dummy td; end of td list for ed */
+ /* dummy td; end of td list for ed */
td = td_alloc (ohci, GFP_ATOMIC);
- if (!td) {
+ if (!td) {
/* out of memory */
ed_free (ohci, ed);
ed = NULL;
@@ -462,7 +460,7 @@ static struct ed *ed_get (
done:
spin_unlock_irqrestore (&ohci->lock, flags);
- return ed;
+ return ed;
}
/*-------------------------------------------------------------------------*/
@@ -474,7 +472,7 @@ done:
* and that ed->state is ED_OPER
*/
static void start_ed_unlink (struct ohci_hcd *ohci, struct ed *ed)
-{
+{
ed->hwINFO |= cpu_to_hc32 (ohci, ED_DEQUEUE);
ed_deschedule (ohci, ed);
@@ -541,7 +539,7 @@ td_fill (struct ohci_hcd *ohci, u32 info,
td->ed = urb_priv->ed;
td->next_dl_td = NULL;
td->index = index;
- td->urb = urb;
+ td->urb = urb;
td->data_dma = data;
if (!len)
data = 0;
@@ -553,8 +551,8 @@ td_fill (struct ohci_hcd *ohci, u32 info,
(data & 0x0FFF) | 0xE000);
td->ed->last_iso = info & 0xffff;
} else {
- td->hwCBP = cpu_to_hc32 (ohci, data);
- }
+ td->hwCBP = cpu_to_hc32 (ohci, data);
+ }
if (data)
td->hwBE = cpu_to_hc32 (ohci, data + len - 1);
else
@@ -597,7 +595,7 @@ static void td_submit_urb (
* use the device toggle bits for resetting, and rely on the fact
* that resetting toggle is meaningless if the endpoint is active.
*/
- if (!usb_gettoggle (urb->dev, usb_pipeendpoint (urb->pipe), is_out)) {
+ if (!usb_gettoggle (urb->dev, usb_pipeendpoint (urb->pipe), is_out)) {
usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe),
is_out, 1);
urb_priv->ed->hwHeadP &= ~cpu_to_hc32 (ohci, ED_C);
@@ -721,16 +719,16 @@ static void td_done (struct ohci_hcd *ohci, struct urb *urb, struct td *td)
list_del (&td->td_list);
/* ISO ... drivers see per-TD length/status */
- if (tdINFO & TD_ISO) {
- u16 tdPSW = ohci_hwPSW (ohci, td, 0);
+ if (tdINFO & TD_ISO) {
+ u16 tdPSW = ohci_hwPSW (ohci, td, 0);
int dlen = 0;
/* NOTE: assumes FC in tdINFO == 0, and that
* only the first of 0..MAXPSW psws is used.
*/
- cc = (tdPSW >> 12) & 0xF;
- if (tdINFO & TD_CC) /* hc didn't touch? */
+ cc = (tdPSW >> 12) & 0xF;
+ if (tdINFO & TD_CC) /* hc didn't touch? */
return;
if (usb_pipeout (urb->pipe))
@@ -758,7 +756,7 @@ static void td_done (struct ohci_hcd *ohci, struct urb *urb, struct td *td)
int type = usb_pipetype (urb->pipe);
u32 tdBE = hc32_to_cpup (ohci, &td->hwBE);
- cc = TD_CC_GET (tdINFO);
+ cc = TD_CC_GET (tdINFO);
/* update packet status if needed (short is normally ok) */
if (cc == TD_DATAUNDERRUN
@@ -787,7 +785,7 @@ static void td_done (struct ohci_hcd *ohci, struct urb *urb, struct td *td)
urb, td, 1 + td->index, cc,
urb->actual_length,
urb->transfer_buffer_length);
- }
+ }
}
/*-------------------------------------------------------------------------*/
@@ -795,7 +793,7 @@ static void td_done (struct ohci_hcd *ohci, struct urb *urb, struct td *td)
static inline struct td *
ed_halted (struct ohci_hcd *ohci, struct td *td, int cc, struct td *rev)
{
- struct urb *urb = td->urb;
+ struct urb *urb = td->urb;
struct ed *ed = td->ed;
struct list_head *tmp = td->td_list.next;
__hc32 toggle = ed->hwHeadP & cpu_to_hc32 (ohci, ED_C);
@@ -805,7 +803,7 @@ ed_halted (struct ohci_hcd *ohci, struct td *td, int cc, struct td *rev)
*/
ed->hwINFO |= cpu_to_hc32 (ohci, ED_SKIP);
wmb ();
- ed->hwHeadP &= ~cpu_to_hc32 (ohci, ED_H);
+ ed->hwHeadP &= ~cpu_to_hc32 (ohci, ED_H);
/* put any later tds from this urb onto the donelist, after 'td',
* order won't matter here: no errors, and nothing was transferred.
@@ -833,7 +831,7 @@ ed_halted (struct ohci_hcd *ohci, struct td *td, int cc, struct td *rev)
info &= ~cpu_to_hc32 (ohci, TD_CC);
next->hwINFO = info;
- next->next_dl_td = rev;
+ next->next_dl_td = rev;
rev = next;
ed->hwHeadP = next->hwNextTD | toggle;
@@ -881,8 +879,8 @@ static struct td *dl_reverse_done_list (struct ohci_hcd *ohci)
/* get TD from hc's singly linked list, and
* prepend to ours. ed->td_list changes later.
*/
- while (td_dma) {
- int cc;
+ while (td_dma) {
+ int cc;
td = dma_to_td (ohci, td_dma);
if (!td) {
@@ -901,10 +899,10 @@ static struct td *dl_reverse_done_list (struct ohci_hcd *ohci)
&& (td->ed->hwHeadP & cpu_to_hc32 (ohci, ED_H)))
td_rev = ed_halted (ohci, td, cc, td_rev);
- td->next_dl_td = td_rev;
+ td->next_dl_td = td_rev;
td_rev = td;
td_dma = hc32_to_cpup (ohci, &td->hwNextTD);
- }
+ }
return td_rev;
}
@@ -1013,9 +1011,9 @@ rescan_this:
if (modified)
goto rescan_all;
- }
+ }
- /* maybe reenable control and bulk lists */
+ /* maybe reenable control and bulk lists */
if (HC_IS_RUNNING(ohci_to_hcd(ohci)->state)
&& ohci_to_hcd(ohci)->state != HC_STATE_QUIESCING
&& !ohci->ed_rm_list) {
@@ -1041,20 +1039,20 @@ rescan_this:
&ohci->regs->ed_bulkcurrent);
}
}
-
+
/* CLE/BLE to enable, CLF/BLF to (maybe) kickstart */
if (control) {
ohci->hc_control |= control;
if (ohci->flags & OHCI_QUIRK_ZFMICRO)
mdelay(1);
- ohci_writel (ohci, ohci->hc_control,
- &ohci->regs->control);
- }
+ ohci_writel (ohci, ohci->hc_control,
+ &ohci->regs->control);
+ }
if (command) {
if (ohci->flags & OHCI_QUIRK_ZFMICRO)
mdelay(1);
- ohci_writel (ohci, command, &ohci->regs->cmdstatus);
- }
+ ohci_writel (ohci, command, &ohci->regs->cmdstatus);
+ }
}
}
@@ -1074,19 +1072,19 @@ dl_done_list (struct ohci_hcd *ohci)
{
struct td *td = dl_reverse_done_list (ohci);
- while (td) {
+ while (td) {
struct td *td_next = td->next_dl_td;
struct urb *urb = td->urb;
urb_priv_t *urb_priv = urb->hcpriv;
struct ed *ed = td->ed;
/* update URB's length and status from TD */
- td_done (ohci, urb, td);
- urb_priv->td_cnt++;
+ td_done (ohci, urb, td);
+ urb_priv->td_cnt++;
/* If all this urb's TDs are done, call complete() */
- if (urb_priv->td_cnt == urb_priv->length)
- finish_urb (ohci, urb);
+ if (urb_priv->td_cnt == urb_priv->length)
+ finish_urb (ohci, urb);
/* clean schedule: unlink EDs that are no longer busy */
if (list_empty (&ed->td_list)) {
@@ -1094,25 +1092,26 @@ dl_done_list (struct ohci_hcd *ohci)
start_ed_unlink (ohci, ed);
/* ... reenabling halted EDs only after fault cleanup */
- } else if ((ed->hwINFO & cpu_to_hc32 (ohci, ED_SKIP | ED_DEQUEUE))
+ } else if ((ed->hwINFO & cpu_to_hc32 (ohci,
+ ED_SKIP | ED_DEQUEUE))
== cpu_to_hc32 (ohci, ED_SKIP)) {
td = list_entry (ed->td_list.next, struct td, td_list);
- if (!(td->hwINFO & cpu_to_hc32 (ohci, TD_DONE))) {
+ if (!(td->hwINFO & cpu_to_hc32 (ohci, TD_DONE))) {
ed->hwINFO &= ~cpu_to_hc32 (ohci, ED_SKIP);
/* ... hc may need waking-up */
switch (ed->type) {
case PIPE_CONTROL:
ohci_writel (ohci, OHCI_CLF,
- &ohci->regs->cmdstatus);
+ &ohci->regs->cmdstatus);
break;
case PIPE_BULK:
ohci_writel (ohci, OHCI_BLF,
- &ohci->regs->cmdstatus);
+ &ohci->regs->cmdstatus);
break;
}
}
}
- td = td_next;
- }
+ td = td_next;
+ }
}
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c
index 59e436424d41..b350d45033e7 100644
--- a/drivers/usb/host/ohci-s3c2410.c
+++ b/drivers/usb/host/ohci-s3c2410.c
@@ -447,7 +447,7 @@ static const struct hc_driver ohci_s3c2410_hc_driver = {
*/
.start = ohci_s3c2410_start,
.stop = ohci_stop,
- .shutdown = ohci_shutdown,
+ .shutdown = ohci_shutdown,
/*
* managing i/o requests and associated device resources
@@ -492,7 +492,7 @@ static int ohci_hcd_s3c2410_drv_remove(struct platform_device *pdev)
static struct platform_driver ohci_hcd_s3c2410_driver = {
.probe = ohci_hcd_s3c2410_drv_probe,
.remove = ohci_hcd_s3c2410_drv_remove,
- .shutdown = usb_hcd_platform_shutdown,
+ .shutdown = usb_hcd_platform_shutdown,
/*.suspend = ohci_hcd_s3c2410_drv_suspend, */
/*.resume = ohci_hcd_s3c2410_drv_resume, */
.driver = {
diff --git a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c
index 71371de32ada..fe0090e33675 100644
--- a/drivers/usb/host/ohci-sa1111.c
+++ b/drivers/usb/host/ohci-sa1111.c
@@ -4,7 +4,7 @@
* (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
* (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
* (C) Copyright 2002 Hewlett-Packard Company
- *
+ *
* SA1111 Bus Glue
*
* Written by Christopher Hoover <ch@hpl.hp.com>
@@ -12,7 +12,7 @@
*
* This file is licenced under the GPL.
*/
-
+
#include <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/arch/assabet.h>
@@ -31,7 +31,7 @@ static void sa1111_start_hc(struct sa1111_dev *dev)
{
unsigned int usb_rst = 0;
- printk(KERN_DEBUG __FILE__
+ printk(KERN_DEBUG __FILE__
": starting SA-1111 OHCI USB Controller\n");
#ifdef CONFIG_SA1100_BADGE4
@@ -65,7 +65,7 @@ static void sa1111_start_hc(struct sa1111_dev *dev)
static void sa1111_stop_hc(struct sa1111_dev *dev)
{
unsigned int usb_rst;
- printk(KERN_DEBUG __FILE__
+ printk(KERN_DEBUG __FILE__
": stopping SA-1111 OHCI USB Controller\n");
/*
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h
index a2f42a2f47c6..405257f3e853 100644
--- a/drivers/usb/host/ohci.h
+++ b/drivers/usb/host/ohci.h
@@ -1,9 +1,9 @@
/*
* OHCI HCD (Host Controller Driver) for USB.
- *
+ *
* (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
* (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
- *
+ *
* This file is licenced under the GPL.
*/
@@ -14,7 +14,7 @@
*/
typedef __u32 __bitwise __hc32;
typedef __u16 __bitwise __hc16;
-
+
/*
* OHCI Endpoint Descriptor (ED) ... holds TD queue
* See OHCI spec, section 4.2
@@ -24,7 +24,7 @@ typedef __u16 __bitwise __hc16;
*/
struct ed {
/* first fields are hardware-specified */
- __hc32 hwINFO; /* endpoint config bitmap */
+ __hc32 hwINFO; /* endpoint config bitmap */
/* info bits defined by hcd */
#define ED_DEQUEUE (1 << 27)
/* info bits defined by the hardware */
@@ -52,11 +52,11 @@ struct ed {
* usually: OPER --> UNLINK --> (IDLE | OPER) --> ...
*/
u8 state; /* ED_{IDLE,UNLINK,OPER} */
-#define ED_IDLE 0x00 /* NOT linked to HC */
-#define ED_UNLINK 0x01 /* being unlinked from hc */
+#define ED_IDLE 0x00 /* NOT linked to HC */
+#define ED_UNLINK 0x01 /* being unlinked from hc */
#define ED_OPER 0x02 /* IS linked to hc */
- u8 type; /* PIPE_{BULK,...} */
+ u8 type; /* PIPE_{BULK,...} */
/* periodic scheduling params (for intr and iso) */
u8 branch;
@@ -70,7 +70,7 @@ struct ed {
#define ED_MASK ((u32)~0x0f) /* strip hw status in low addr bits */
-
+
/*
* OHCI Transfer Descriptor (TD) ... one per transfer segment
* See OHCI spec, sections 4.3.1 (general = control/bulk/interrupt)
@@ -107,22 +107,22 @@ struct td {
/* (no hwINFO #defines yet for iso tds) */
- __hc32 hwCBP; /* Current Buffer Pointer (or 0) */
- __hc32 hwNextTD; /* Next TD Pointer */
- __hc32 hwBE; /* Memory Buffer End Pointer */
+ __hc32 hwCBP; /* Current Buffer Pointer (or 0) */
+ __hc32 hwNextTD; /* Next TD Pointer */
+ __hc32 hwBE; /* Memory Buffer End Pointer */
/* PSW is only for ISO. Only 1 PSW entry is used, but on
* big-endian PPC hardware that's the second entry.
*/
#define MAXPSW 2
- __hc16 hwPSW [MAXPSW];
+ __hc16 hwPSW [MAXPSW];
/* rest are purely for the driver's use */
- __u8 index;
- struct ed *ed;
- struct td *td_hash; /* dma-->td hashtable */
- struct td *next_dl_td;
- struct urb *urb;
+ __u8 index;
+ struct ed *ed;
+ struct td *td_hash; /* dma-->td hashtable */
+ struct td *next_dl_td;
+ struct urb *urb;
dma_addr_t td_dma; /* addr of this TD */
dma_addr_t data_dma; /* addr of data it points to */
@@ -152,8 +152,8 @@ struct td {
#define TD_NOTACCESSED 0x0F
-/* map OHCI TD status codes (CC) to errno values */
-static const int cc_to_error [16] = {
+/* map OHCI TD status codes (CC) to errno values */
+static const int cc_to_error [16] = {
/* No Error */ 0,
/* CRC Error */ -EILSEQ,
/* Bit Stuff */ -EPROTO,
@@ -169,7 +169,7 @@ static const int cc_to_error [16] = {
/* BufferOver */ -ECOMM,
/* BuffUnder */ -ENOSR,
/* (for HCD) */ -EALREADY,
- /* (for HCD) */ -EALREADY
+ /* (for HCD) */ -EALREADY
};
@@ -182,7 +182,7 @@ struct ohci_hcca {
#define NUM_INTS 32
__hc32 int_table [NUM_INTS]; /* periodic schedule */
- /*
+ /*
* OHCI defines u16 frame_no, followed by u16 zero pad.
* Since some processors can't do 16 bit bus accesses,
* portable access must be a 32 bits wide.
@@ -262,10 +262,10 @@ struct ohci_regs {
* HcCommandStatus (cmdstatus) register masks
*/
#define OHCI_HCR (1 << 0) /* host controller reset */
-#define OHCI_CLF (1 << 1) /* control list filled */
-#define OHCI_BLF (1 << 2) /* bulk list filled */
-#define OHCI_OCR (1 << 3) /* ownership change request */
-#define OHCI_SOC (3 << 16) /* scheduling overrun count */
+#define OHCI_CLF (1 << 1) /* control list filled */
+#define OHCI_BLF (1 << 2) /* bulk list filled */
+#define OHCI_OCR (1 << 3) /* ownership change request */
+#define OHCI_SOC (3 << 16) /* scheduling overrun count */
/*
* masks used with interrupt registers:
@@ -285,20 +285,20 @@ struct ohci_regs {
/* OHCI ROOT HUB REGISTER MASKS */
-
+
/* roothub.portstatus [i] bits */
-#define RH_PS_CCS 0x00000001 /* current connect status */
-#define RH_PS_PES 0x00000002 /* port enable status*/
-#define RH_PS_PSS 0x00000004 /* port suspend status */
-#define RH_PS_POCI 0x00000008 /* port over current indicator */
-#define RH_PS_PRS 0x00000010 /* port reset status */
-#define RH_PS_PPS 0x00000100 /* port power status */
-#define RH_PS_LSDA 0x00000200 /* low speed device attached */
-#define RH_PS_CSC 0x00010000 /* connect status change */
-#define RH_PS_PESC 0x00020000 /* port enable status change */
-#define RH_PS_PSSC 0x00040000 /* port suspend status change */
-#define RH_PS_OCIC 0x00080000 /* over current indicator change */
-#define RH_PS_PRSC 0x00100000 /* port reset status change */
+#define RH_PS_CCS 0x00000001 /* current connect status */
+#define RH_PS_PES 0x00000002 /* port enable status*/
+#define RH_PS_PSS 0x00000004 /* port suspend status */
+#define RH_PS_POCI 0x00000008 /* port over current indicator */
+#define RH_PS_PRS 0x00000010 /* port reset status */
+#define RH_PS_PPS 0x00000100 /* port power status */
+#define RH_PS_LSDA 0x00000200 /* low speed device attached */
+#define RH_PS_CSC 0x00010000 /* connect status change */
+#define RH_PS_PESC 0x00020000 /* port enable status change */
+#define RH_PS_PSSC 0x00040000 /* port suspend status change */
+#define RH_PS_OCIC 0x00080000 /* over current indicator change */
+#define RH_PS_PRSC 0x00100000 /* port reset status change */
/* roothub.status bits */
#define RH_HS_LPS 0x00000001 /* local power status */
@@ -333,7 +333,7 @@ typedef struct urb_priv {
} urb_priv_t;
#define TD_HASH_SIZE 64 /* power'o'two */
-// sizeof (struct td) ~= 64 == 2^6 ...
+// sizeof (struct td) ~= 64 == 2^6 ...
#define TD_HASH_FUNC(td_dma) ((td_dma ^ (td_dma >> 6)) % TD_HASH_SIZE)
@@ -364,11 +364,11 @@ struct ohci_hcd {
struct ed *ed_bulktail; /* last in bulk list */
struct ed *ed_controltail; /* last in ctrl list */
- struct ed *periodic [NUM_INTS]; /* shadow int_table */
+ struct ed *periodic [NUM_INTS]; /* shadow int_table */
/*
* OTG controllers and transceivers need software interaction;
- * other external transceivers should be software-transparent
+ * other external transceivers should be software-transparent
*/
struct otg_transceiver *transceiver;
@@ -385,7 +385,7 @@ struct ohci_hcd {
*/
int num_ports;
int load [NUM_INTS];
- u32 hc_control; /* copy of hc control reg */
+ u32 hc_control; /* copy of hc control reg */
unsigned long next_statechange; /* suspend/resume */
u32 fminterval; /* saved register */
unsigned autostop:1; /* rh auto stopping/stopped */
@@ -598,11 +598,11 @@ static inline void disable (struct ohci_hcd *ohci)
}
#define FI 0x2edf /* 12000 bits per frame (-1) */
-#define FSMP(fi) (0x7fff & ((6 * ((fi) - 210)) / 7))
+#define FSMP(fi) (0x7fff & ((6 * ((fi) - 210)) / 7))
#define FIT (1 << 31)
#define LSTHRESH 0x628 /* lowspeed bit threshold */
-static void periodic_reinit (struct ohci_hcd *ohci)
+static inline void periodic_reinit (struct ohci_hcd *ohci)
{
u32 fi = ohci->fminterval & 0x03fff;
u32 fit = ohci_readl(ohci, &ohci->regs->fminterval) & FIT;
@@ -626,11 +626,11 @@ static void periodic_reinit (struct ohci_hcd *ohci)
temp = ohci_readl (hc, &hc->regs->roothub.register); \
temp; })
-static u32 roothub_a (struct ohci_hcd *hc)
+static inline u32 roothub_a (struct ohci_hcd *hc)
{ return read_roothub (hc, a, 0xfc0fe000); }
static inline u32 roothub_b (struct ohci_hcd *hc)
{ return ohci_readl (hc, &hc->regs->roothub.b); }
static inline u32 roothub_status (struct ohci_hcd *hc)
{ return ohci_readl (hc, &hc->regs->roothub.status); }
-static u32 roothub_portstatus (struct ohci_hcd *hc, int i)
+static inline u32 roothub_portstatus (struct ohci_hcd *hc, int i)
{ return read_roothub (hc, portstatus [i], 0xffe0fce0); }
diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c
index a9d7119e3176..a7fa0d75567d 100644
--- a/drivers/usb/host/u132-hcd.c
+++ b/drivers/usb/host/u132-hcd.c
@@ -40,6 +40,7 @@
#include <linux/moduleparam.h>
#include <linux/delay.h>
#include <linux/ioport.h>
+#include <linux/pci_ids.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/smp_lock.h>
@@ -210,15 +211,16 @@ struct u132 {
* these cannot be inlines because we need the structure offset!!
* Does anyone have a better way?????
*/
+#define ftdi_read_pcimem(pdev, member, data) usb_ftdi_elan_read_pcimem(pdev, \
+ offsetof(struct ohci_regs, member), 0, data);
+#define ftdi_write_pcimem(pdev, member, data) usb_ftdi_elan_write_pcimem(pdev, \
+ offsetof(struct ohci_regs, member), 0, data);
#define u132_read_pcimem(u132, member, data) \
usb_ftdi_elan_read_pcimem(u132->platform_dev, offsetof(struct \
ohci_regs, member), 0, data);
#define u132_write_pcimem(u132, member, data) \
usb_ftdi_elan_write_pcimem(u132->platform_dev, offsetof(struct \
ohci_regs, member), 0, data);
-#define u132_write_pcimem_byte(u132, member, data) \
- usb_ftdi_elan_write_pcimem(u132->platform_dev, offsetof(struct \
- ohci_regs, member), 0x0e, data);
static inline struct u132 *udev_to_u132(struct u132_udev *udev)
{
u8 udev_number = udev->udev_number;
@@ -1574,59 +1576,12 @@ static char *hcfs2string(int state)
return "?";
}
-static int u132_usb_reset(struct u132 *u132)
-{
- int retval;
- retval = u132_read_pcimem(u132, control, &u132->hc_control);
- if (retval)
- return retval;
- u132->hc_control &= OHCI_CTRL_RWC;
- retval = u132_write_pcimem(u132, control, u132->hc_control);
- if (retval)
- return retval;
- return 0;
-}
-
static int u132_init(struct u132 *u132)
{
int retval;
u32 control;
u132_disable(u132);
- u132->next_statechange =
- jiffies; /* SMM owns the HC? not for long! */ {
- u32 control;
- retval = u132_read_pcimem(u132, control, &control);
- if (retval)
- return retval;
- if (control & OHCI_CTRL_IR) {
- u32 temp = 50;
- retval = u132_write_pcimem(u132, intrenable,
- OHCI_INTR_OC);
- if (retval)
- return retval;
- retval = u132_write_pcimem_byte(u132, cmdstatus,
- OHCI_OCR);
- if (retval)
- return retval;
- check:{
- retval = u132_read_pcimem(u132, control,
- &control);
- if (retval)
- return retval;
- }
- if (control & OHCI_CTRL_IR) {
- msleep(10);
- if (--temp == 0) {
- dev_err(&u132->platform_dev->dev, "USB "
- "HC takeover failed!(BIOS/SMM b"
- "ug) control=%08X\n", control);
- return -EBUSY;
- }
- goto check;
- }
- u132_usb_reset(u132);
- }
- }
+ u132->next_statechange = jiffies;
retval = u132_write_pcimem(u132, intrdisable, OHCI_INTR_MIE);
if (retval)
return retval;
@@ -1725,7 +1680,7 @@ static int u132_run(struct u132 *u132)
retry:retval = u132_read_pcimem(u132, cmdstatus, &status);
if (retval)
return retval;
- retval = u132_write_pcimem_byte(u132, cmdstatus, OHCI_HCR);
+ retval = u132_write_pcimem(u132, cmdstatus, OHCI_HCR);
if (retval)
return retval;
extra:{
@@ -1782,7 +1737,7 @@ static int u132_run(struct u132 *u132)
retval = u132_write_pcimem(u132, control, u132->hc_control);
if (retval)
return retval;
- retval = u132_write_pcimem_byte(u132, cmdstatus, OHCI_BLF);
+ retval = u132_write_pcimem(u132, cmdstatus, OHCI_BLF);
if (retval)
return retval;
retval = u132_read_pcimem(u132, cmdstatus, &cmdstatus);
@@ -1839,8 +1794,8 @@ static void u132_hcd_stop(struct usb_hcd *hcd)
{
struct u132 *u132 = hcd_to_u132(hcd);
if (u132->going > 1) {
- dev_err(&u132->platform_dev->dev, "device has been removed %d\n"
- , u132->going);
+ dev_err(&u132->platform_dev->dev, "u132 device %p(hcd=%p) has b"
+ "een removed %d\n", u132, hcd, u132->going);
} else if (u132->going > 0) {
dev_err(&u132->platform_dev->dev, "device hcd=%p is being remov"
"ed\n", hcd);
@@ -2545,8 +2500,9 @@ static void u132_endpoint_disable(struct usb_hcd *hcd,
{
struct u132 *u132 = hcd_to_u132(hcd);
if (u132->going > 2) {
- dev_err(&u132->platform_dev->dev, "device has been removed %d\n"
- , u132->going);
+ dev_err(&u132->platform_dev->dev, "u132 device %p(hcd=%p hep=%p"
+ ") has been removed %d\n", u132, hcd, hep,
+ u132->going);
} else {
struct u132_endp *endp = hep->hcpriv;
if (endp)
@@ -2790,7 +2746,6 @@ static int u132_hub_status_data(struct usb_hcd *hcd, char *buf)
} else if (u132->going > 0) {
dev_err(&u132->platform_dev->dev, "device hcd=%p is being remov"
"ed\n", hcd);
- dump_stack();
return -ESHUTDOWN;
} else {
int i, changed = 0, length = 1;
@@ -3034,12 +2989,15 @@ static int __devexit u132_remove(struct platform_device *pdev)
struct usb_hcd *hcd = platform_get_drvdata(pdev);
if (hcd) {
struct u132 *u132 = hcd_to_u132(hcd);
- dump_stack();
if (u132->going++ > 1) {
+ dev_err(&u132->platform_dev->dev, "already being remove"
+ "d\n");
return -ENODEV;
} else {
int rings = MAX_U132_RINGS;
int endps = MAX_U132_ENDPS;
+ dev_err(&u132->platform_dev->dev, "removing device u132"
+ ".%d\n", u132->sequence_num);
msleep(100);
down(&u132->sw_lock);
u132_monitor_cancel_work(u132);
@@ -3121,10 +3079,24 @@ static void u132_initialise(struct u132 *u132, struct platform_device *pdev)
static int __devinit u132_probe(struct platform_device *pdev)
{
struct usb_hcd *hcd;
+ int retval;
+ u32 control;
+ u32 rh_a = -1;
+ u32 num_ports;
msleep(100);
if (u132_exiting > 0) {
return -ENODEV;
- } /* refuse to confuse usbcore */
+ }
+ retval = ftdi_write_pcimem(pdev, intrdisable, OHCI_INTR_MIE);
+ if (retval)
+ return retval;
+ retval = ftdi_read_pcimem(pdev, control, &control);
+ if (retval)
+ return retval;
+ retval = ftdi_read_pcimem(pdev, roothub.a, &rh_a);
+ if (retval)
+ return retval;
+ num_ports = rh_a & RH_A_NDP; /* refuse to confuse usbcore */
if (pdev->dev.dma_mask) {
return -EINVAL;
}
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
index e87692c31be4..acd101caeeeb 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -60,6 +60,11 @@ Randy Dunlap, Georg Acher, Deti Fliegl, Thomas Sailer, Roman Weissgaerber, \
Alan Stern"
#define DRIVER_DESC "USB Universal Host Controller Interface driver"
+/* for flakey hardware, ignore overcurrent indicators */
+static int ignore_oc;
+module_param(ignore_oc, bool, S_IRUGO);
+MODULE_PARM_DESC(ignore_oc, "ignore hardware overcurrent indications");
+
/*
* debug = 0, no debugging messages
* debug = 1, dump failed URBs except for stalls
@@ -169,6 +174,11 @@ static int resume_detect_interrupts_are_broken(struct uhci_hcd *uhci)
{
int port;
+ /* If we have to ignore overcurrent events then almost by definition
+ * we can't depend on resume-detect interrupts. */
+ if (ignore_oc)
+ return 1;
+
switch (to_pci_dev(uhci_dev(uhci))->vendor) {
default:
break;
@@ -921,7 +931,8 @@ static int __init uhci_hcd_init(void)
{
int retval = -ENOMEM;
- printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION "\n");
+ printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION "%s\n",
+ ignore_oc ? ", overcurrent ignored" : "");
if (usb_disabled())
return -ENODEV;
diff --git a/drivers/usb/host/uhci-hub.c b/drivers/usb/host/uhci-hub.c
index f8347f1a10b6..bacc25c53ba3 100644
--- a/drivers/usb/host/uhci-hub.c
+++ b/drivers/usb/host/uhci-hub.c
@@ -52,10 +52,20 @@ static int any_ports_active(struct uhci_hcd *uhci)
static inline int get_hub_status_data(struct uhci_hcd *uhci, char *buf)
{
int port;
+ int mask = RWC_BITS;
+
+ /* Some boards (both VIA and Intel apparently) report bogus
+ * overcurrent indications, causing massive log spam unless
+ * we completely ignore them. This doesn't seem to be a problem
+ * with the chipset so much as with the way it is connected on
+ * the motherboard; if the overcurrent input is left to float
+ * then it may constantly register false positives. */
+ if (ignore_oc)
+ mask &= ~USBPORTSC_OCC;
*buf = 0;
for (port = 0; port < uhci->rh_numports; ++port) {
- if ((inw(uhci->io_addr + USBPORTSC1 + port * 2) & RWC_BITS) ||
+ if ((inw(uhci->io_addr + USBPORTSC1 + port * 2) & mask) ||
test_bit(port, &uhci->port_c_suspend))
*buf |= (1 << (port + 1));
}
@@ -263,7 +273,7 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
wPortChange |= USB_PORT_STAT_C_CONNECTION;
if (status & USBPORTSC_PEC)
wPortChange |= USB_PORT_STAT_C_ENABLE;
- if (status & USBPORTSC_OCC)
+ if ((status & USBPORTSC_OCC) && !ignore_oc)
wPortChange |= USB_PORT_STAT_C_OVERCURRENT;
if (test_bit(port, &uhci->port_c_suspend)) {
diff --git a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig
index 8a62d4785755..f877cd4f317a 100644
--- a/drivers/usb/input/Kconfig
+++ b/drivers/usb/input/Kconfig
@@ -7,7 +7,8 @@ comment "USB Input Devices"
config USB_HID
tristate "USB Human Interface Device (full HID) support"
default y
- depends on USB && HID
+ depends on USB
+ select HID
---help---
Say Y here if you want full HID support to connect USB keyboards,
mice, joysticks, graphic tablets, or any other HID based devices
@@ -28,7 +29,7 @@ config USB_HID
comment "Input core support is needed for USB HID input layer or HIDBP support"
depends on USB_HID && INPUT=n
-config USB_HID_POWERBOOK
+config USB_HIDINPUT_POWERBOOK
bool "Enable support for iBook/PowerBook special keys"
default n
depends on USB_HID
diff --git a/drivers/usb/input/wacom_sys.c b/drivers/usb/input/wacom_sys.c
index e7cc20ab8155..12b42746ded8 100644
--- a/drivers/usb/input/wacom_sys.c
+++ b/drivers/usb/input/wacom_sys.c
@@ -159,13 +159,13 @@ void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
{
input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER);
input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3);
- input_set_abs_params(input_dev, ABS_RX, 0, 4097, 0, 0);
+ input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0);
}
void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
{
input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7);
- input_set_abs_params(input_dev, ABS_RY, 0, 4097, 0, 0);
+ input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0);
}
void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
diff --git a/drivers/usb/input/wacom_wac.c b/drivers/usb/input/wacom_wac.c
index 92726fe89379..4142e36730fc 100644
--- a/drivers/usb/input/wacom_wac.c
+++ b/drivers/usb/input/wacom_wac.c
@@ -209,13 +209,15 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02);
wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x04);
}
- }
-
- if (data[1] & 0x10)
wacom_report_abs(wcombo, ABS_MISC, id); /* report tool id */
+ }
else
wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */
- wacom_report_key(wcombo, wacom->tool[0], data[1] & 0x10);
+
+ if (data[1] & 0x10) /* only report prox-in when in area */
+ wacom_report_key(wcombo, wacom->tool[0], 1);
+ if (!(data[1] & 0x90)) /* report prox-out when physically out */
+ wacom_report_key(wcombo, wacom->tool[0], 0);
wacom_input_sync(wcombo);
/* send pad data */
@@ -405,7 +407,7 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo)
if ((wacom->features->type == CINTIQ) && !(data[1] & 0x40))
return 0;
- if (wacom->features->type >= INTUOS3) {
+ if (wacom->features->type >= INTUOS3S) {
wacom_report_abs(wcombo, ABS_X, (data[2] << 9) | (data[3] << 1) | ((data[9] >> 1) & 1));
wacom_report_abs(wcombo, ABS_Y, (data[4] << 9) | (data[5] << 1) | (data[9] & 1));
wacom_report_abs(wcombo, ABS_DISTANCE, ((data[9] >> 2) & 0x3f));
@@ -423,7 +425,7 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo)
if (data[1] & 0x02) {
/* Rotation packet */
- if (wacom->features->type >= INTUOS3) {
+ if (wacom->features->type >= INTUOS3S) {
/* I3 marker pen rotation reported as wheel
* due to valuator limitation
*/
@@ -547,11 +549,11 @@ static struct wacom_features wacom_features[] = {
{ "Wacom Graphire3 6x8", 8, 16704, 12064, 511, 63, GRAPHIRE },
{ "Wacom Graphire4 4x5", 8, 10208, 7424, 511, 63, WACOM_G4 },
{ "Wacom Graphire4 6x8", 8, 16704, 12064, 511, 63, WACOM_G4 },
- { "Wacom Volito", 8, 5104, 3712, 511, 0, GRAPHIRE },
- { "Wacom PenStation2", 8, 3250, 2320, 255, 0, GRAPHIRE },
- { "Wacom Volito2 4x5", 8, 5104, 3712, 511, 0, GRAPHIRE },
- { "Wacom Volito2 2x3", 8, 3248, 2320, 511, 0, GRAPHIRE },
- { "Wacom PenPartner2", 8, 3250, 2320, 255, 0, GRAPHIRE },
+ { "Wacom Volito", 8, 5104, 3712, 511, 63, GRAPHIRE },
+ { "Wacom PenStation2", 8, 3250, 2320, 255, 63, GRAPHIRE },
+ { "Wacom Volito2 4x5", 8, 5104, 3712, 511, 63, GRAPHIRE },
+ { "Wacom Volito2 2x3", 8, 3248, 2320, 511, 63, GRAPHIRE },
+ { "Wacom PenPartner2", 8, 3250, 2320, 255, 63, GRAPHIRE },
{ "Wacom Intuos 4x5", 10, 12700, 10600, 1023, 63, INTUOS },
{ "Wacom Intuos 6x8", 10, 20320, 16240, 1023, 63, INTUOS },
{ "Wacom Intuos 9x12", 10, 30480, 24060, 1023, 63, INTUOS },
@@ -580,7 +582,7 @@ static struct wacom_features wacom_features[] = {
{ "Wacom Intuos3 12x12", 10, 60960, 60960, 1023, 63, INTUOS3L },
{ "Wacom Intuos3 12x19", 10, 97536, 60960, 1023, 63, INTUOS3L },
{ "Wacom Intuos3 6x11", 10, 54204, 31750, 1023, 63, INTUOS3 },
- { "Wacom Intuos3 4x6", 10, 31496, 19685, 1023, 15, INTUOS3S },
+ { "Wacom Intuos3 4x6", 10, 31496, 19685, 1023, 63, INTUOS3S },
{ "Wacom Cintiq 21UX", 10, 87200, 65600, 1023, 63, CINTIQ },
{ "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 63, INTUOS },
{ }
diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c
index 02cbb7fff24f..a7932a72d298 100644
--- a/drivers/usb/misc/appledisplay.c
+++ b/drivers/usb/misc/appledisplay.c
@@ -281,7 +281,7 @@ static int appledisplay_probe(struct usb_interface *iface,
/* Register backlight device */
snprintf(bl_name, sizeof(bl_name), "appledisplay%d",
atomic_inc_return(&count_displays) - 1);
- pdata->bd = backlight_device_register(bl_name, pdata,
+ pdata->bd = backlight_device_register(bl_name, NULL, NULL,
&appledisplay_bl_data);
if (IS_ERR(pdata->bd)) {
err("appledisplay: Backlight registration failed");
diff --git a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c
index c703f73e1655..b5332e679c46 100644
--- a/drivers/usb/misc/auerswald.c
+++ b/drivers/usb/misc/auerswald.c
@@ -766,7 +766,7 @@ static int auerbuf_setup (pauerbufctl_t bcp, unsigned int numElements, unsigned
bep->bufp = kmalloc (bufsize, GFP_KERNEL);
if (!bep->bufp)
goto bl_fail;
- bep->dr = (struct usb_ctrlrequest *) kmalloc (sizeof (struct usb_ctrlrequest), GFP_KERNEL);
+ bep->dr = kmalloc(sizeof (struct usb_ctrlrequest), GFP_KERNEL);
if (!bep->dr)
goto bl_fail;
bep->urbp = usb_alloc_urb (0, GFP_KERNEL);
@@ -1376,7 +1376,7 @@ static int auerchar_open (struct inode *inode, struct file *file)
}
/* we have access to the device. Now lets allocate memory */
- ccp = (pauerchar_t) kmalloc(sizeof(auerchar_t), GFP_KERNEL);
+ ccp = kzalloc(sizeof(auerchar_t), GFP_KERNEL);
if (ccp == NULL) {
err ("out of memory");
ret = -ENOMEM;
@@ -1384,7 +1384,6 @@ static int auerchar_open (struct inode *inode, struct file *file)
}
/* Initialize device descriptor */
- memset( ccp, 0, sizeof(auerchar_t));
init_MUTEX( &ccp->mutex);
init_MUTEX( &ccp->readmutex);
auerbuf_init (&ccp->bufctl);
@@ -1912,14 +1911,13 @@ static int auerswald_probe (struct usb_interface *intf,
return -ENODEV;
/* allocate memory for our device and initialize it */
- cp = kmalloc (sizeof(auerswald_t), GFP_KERNEL);
+ cp = kzalloc (sizeof(auerswald_t), GFP_KERNEL);
if (cp == NULL) {
err ("out of memory");
goto pfail;
}
/* Initialize device descriptor */
- memset (cp, 0, sizeof(auerswald_t));
init_MUTEX (&cp->mutex);
cp->usbdev = usbdev;
auerchain_init (&cp->controlchain);
@@ -1969,7 +1967,7 @@ static int auerswald_probe (struct usb_interface *intf,
info("device is a %s", cp->dev_desc);
/* get the maximum allowed control transfer length */
- pbuf = (__le16 *) kmalloc (2, GFP_KERNEL); /* use an allocated buffer because of urb target */
+ pbuf = kmalloc(2, GFP_KERNEL); /* use an allocated buffer because of urb target */
if (!pbuf) {
err( "out of memory");
goto pfail;
diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c
index 18b1925032a8..41c0161abdb9 100644
--- a/drivers/usb/misc/ftdi-elan.c
+++ b/drivers/usb/misc/ftdi-elan.c
@@ -40,6 +40,7 @@
#include <linux/init.h>
#include <linux/list.h>
#include <linux/ioctl.h>
+#include <linux/pci_ids.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/kref.h>
@@ -51,6 +52,10 @@ MODULE_AUTHOR("Tony Olech");
MODULE_DESCRIPTION("FTDI ELAN driver");
MODULE_LICENSE("GPL");
#define INT_MODULE_PARM(n, v) static int n = v;module_param(n, int, 0444)
+static int distrust_firmware = 1;
+module_param(distrust_firmware, bool, 0);
+MODULE_PARM_DESC(distrust_firmware, "true to distrust firmware power/overcurren"
+ "t setup");
extern struct platform_driver u132_platform_driver;
static struct workqueue_struct *status_queue;
static struct workqueue_struct *command_queue;
@@ -66,7 +71,9 @@ static struct list_head ftdi_static_list;
* end of the global variables protected by ftdi_module_lock
*/
#include "usb_u132.h"
-#define TD_DEVNOTRESP 5
+#include <asm/io.h>
+#include "../core/hcd.h"
+#include "../host/ohci.h"
/* Define these values to match your devices*/
#define USB_FTDI_ELAN_VENDOR_ID 0x0403
#define USB_FTDI_ELAN_PRODUCT_ID 0xd6ea
@@ -551,7 +558,7 @@ static void ftdi_elan_status_work(struct work_struct *work)
} else {
dev_err(&ftdi->udev->dev, "initialized failed - trying "
"again in 10 seconds\n");
- work_delay_in_msec = 10 *1000;
+ work_delay_in_msec = 1 *1000;
}
} else if (ftdi->registered == 0) {
work_delay_in_msec = 10;
@@ -2288,82 +2295,288 @@ static int ftdi_elan_checkingPCI(struct usb_ftdi *ftdi)
}
}
-static int ftdi_elan_enumeratePCI(struct usb_ftdi *ftdi)
+
+#define ftdi_read_pcimem(ftdi, member, data) ftdi_elan_read_pcimem(ftdi, \
+ offsetof(struct ohci_regs, member), 0, data);
+#define ftdi_write_pcimem(ftdi, member, data) ftdi_elan_write_pcimem(ftdi, \
+ offsetof(struct ohci_regs, member), 0, data);
+#define OHCI_QUIRK_AMD756 0x01
+#define OHCI_QUIRK_SUPERIO 0x02
+#define OHCI_QUIRK_INITRESET 0x04
+#define OHCI_BIG_ENDIAN 0x08
+#define OHCI_QUIRK_ZFMICRO 0x10
+#define OHCI_CONTROL_INIT OHCI_CTRL_CBSR
+#define OHCI_INTR_INIT (OHCI_INTR_MIE | OHCI_INTR_UE | OHCI_INTR_RD | \
+ OHCI_INTR_WDH)
+static int ftdi_elan_check_controller(struct usb_ftdi *ftdi, int quirk)
+{
+ int devices = 0;
+ int retval;
+ u32 hc_control;
+ int num_ports;
+ u32 control;
+ u32 rh_a = -1;
+ u32 status;
+ u32 fminterval;
+ u32 hc_fminterval;
+ u32 periodicstart;
+ u32 cmdstatus;
+ u32 roothub_a;
+ int mask = OHCI_INTR_INIT;
+ int sleep_time = 0;
+ int reset_timeout = 30; /* ... allow extra time */
+ int temp;
+ retval = ftdi_write_pcimem(ftdi, intrdisable, OHCI_INTR_MIE);
+ if (retval)
+ return retval;
+ retval = ftdi_read_pcimem(ftdi, control, &control);
+ if (retval)
+ return retval;
+ retval = ftdi_read_pcimem(ftdi, roothub.a, &rh_a);
+ if (retval)
+ return retval;
+ num_ports = rh_a & RH_A_NDP;
+ retval = ftdi_read_pcimem(ftdi, fminterval, &hc_fminterval);
+ if (retval)
+ return retval;
+ hc_fminterval &= 0x3fff;
+ if (hc_fminterval != FI) {
+ }
+ hc_fminterval |= FSMP(hc_fminterval) << 16;
+ retval = ftdi_read_pcimem(ftdi, control, &hc_control);
+ if (retval)
+ return retval;
+ switch (hc_control & OHCI_CTRL_HCFS) {
+ case OHCI_USB_OPER:
+ sleep_time = 0;
+ break;
+ case OHCI_USB_SUSPEND:
+ case OHCI_USB_RESUME:
+ hc_control &= OHCI_CTRL_RWC;
+ hc_control |= OHCI_USB_RESUME;
+ sleep_time = 10;
+ break;
+ default:
+ hc_control &= OHCI_CTRL_RWC;
+ hc_control |= OHCI_USB_RESET;
+ sleep_time = 50;
+ break;
+ }
+ retval = ftdi_write_pcimem(ftdi, control, hc_control);
+ if (retval)
+ return retval;
+ retval = ftdi_read_pcimem(ftdi, control, &control);
+ if (retval)
+ return retval;
+ msleep(sleep_time);
+ retval = ftdi_read_pcimem(ftdi, roothub.a, &roothub_a);
+ if (retval)
+ return retval;
+ if (!(roothub_a & RH_A_NPS)) { /* power down each port */
+ for (temp = 0; temp < num_ports; temp++) {
+ retval = ftdi_write_pcimem(ftdi,
+ roothub.portstatus[temp], RH_PS_LSDA);
+ if (retval)
+ return retval;
+ }
+ }
+ retval = ftdi_read_pcimem(ftdi, control, &control);
+ if (retval)
+ return retval;
+ retry:retval = ftdi_read_pcimem(ftdi, cmdstatus, &status);
+ if (retval)
+ return retval;
+ retval = ftdi_write_pcimem(ftdi, cmdstatus, OHCI_HCR);
+ if (retval)
+ return retval;
+ extra:{
+ retval = ftdi_read_pcimem(ftdi, cmdstatus, &status);
+ if (retval)
+ return retval;
+ if (0 != (status & OHCI_HCR)) {
+ if (--reset_timeout == 0) {
+ dev_err(&ftdi->udev->dev, "USB HC reset timed o"
+ "ut!\n");
+ return -ENODEV;
+ } else {
+ msleep(5);
+ goto extra;
+ }
+ }
+ }
+ if (quirk & OHCI_QUIRK_INITRESET) {
+ retval = ftdi_write_pcimem(ftdi, control, hc_control);
+ if (retval)
+ return retval;
+ retval = ftdi_read_pcimem(ftdi, control, &control);
+ if (retval)
+ return retval;
+ }
+ retval = ftdi_write_pcimem(ftdi, ed_controlhead, 0x00000000);
+ if (retval)
+ return retval;
+ retval = ftdi_write_pcimem(ftdi, ed_bulkhead, 0x11000000);
+ if (retval)
+ return retval;
+ retval = ftdi_write_pcimem(ftdi, hcca, 0x00000000);
+ if (retval)
+ return retval;
+ retval = ftdi_read_pcimem(ftdi, fminterval, &fminterval);
+ if (retval)
+ return retval;
+ retval = ftdi_write_pcimem(ftdi, fminterval,
+ ((fminterval & FIT) ^ FIT) | hc_fminterval);
+ if (retval)
+ return retval;
+ retval = ftdi_write_pcimem(ftdi, periodicstart,
+ ((9 *hc_fminterval) / 10) & 0x3fff);
+ if (retval)
+ return retval;
+ retval = ftdi_read_pcimem(ftdi, fminterval, &fminterval);
+ if (retval)
+ return retval;
+ retval = ftdi_read_pcimem(ftdi, periodicstart, &periodicstart);
+ if (retval)
+ return retval;
+ if (0 == (fminterval & 0x3fff0000) || 0 == periodicstart) {
+ if (!(quirk & OHCI_QUIRK_INITRESET)) {
+ quirk |= OHCI_QUIRK_INITRESET;
+ goto retry;
+ } else
+ dev_err(&ftdi->udev->dev, "init err(%08x %04x)\n",
+ fminterval, periodicstart);
+ } /* start controller operations */
+ hc_control &= OHCI_CTRL_RWC;
+ hc_control |= OHCI_CONTROL_INIT | OHCI_CTRL_BLE | OHCI_USB_OPER;
+ retval = ftdi_write_pcimem(ftdi, control, hc_control);
+ if (retval)
+ return retval;
+ retval = ftdi_write_pcimem(ftdi, cmdstatus, OHCI_BLF);
+ if (retval)
+ return retval;
+ retval = ftdi_read_pcimem(ftdi, cmdstatus, &cmdstatus);
+ if (retval)
+ return retval;
+ retval = ftdi_read_pcimem(ftdi, control, &control);
+ if (retval)
+ return retval;
+ retval = ftdi_write_pcimem(ftdi, roothub.status, RH_HS_DRWE);
+ if (retval)
+ return retval;
+ retval = ftdi_write_pcimem(ftdi, intrstatus, mask);
+ if (retval)
+ return retval;
+ retval = ftdi_write_pcimem(ftdi, intrdisable,
+ OHCI_INTR_MIE | OHCI_INTR_OC | OHCI_INTR_RHSC | OHCI_INTR_FNO |
+ OHCI_INTR_UE | OHCI_INTR_RD | OHCI_INTR_SF | OHCI_INTR_WDH |
+ OHCI_INTR_SO);
+ if (retval)
+ return retval; /* handle root hub init quirks ... */
+ retval = ftdi_read_pcimem(ftdi, roothub.a, &roothub_a);
+ if (retval)
+ return retval;
+ roothub_a &= ~(RH_A_PSM | RH_A_OCPM);
+ if (quirk & OHCI_QUIRK_SUPERIO) {
+ roothub_a |= RH_A_NOCP;
+ roothub_a &= ~(RH_A_POTPGT | RH_A_NPS);
+ retval = ftdi_write_pcimem(ftdi, roothub.a, roothub_a);
+ if (retval)
+ return retval;
+ } else if ((quirk & OHCI_QUIRK_AMD756) || distrust_firmware) {
+ roothub_a |= RH_A_NPS;
+ retval = ftdi_write_pcimem(ftdi, roothub.a, roothub_a);
+ if (retval)
+ return retval;
+ }
+ retval = ftdi_write_pcimem(ftdi, roothub.status, RH_HS_LPSC);
+ if (retval)
+ return retval;
+ retval = ftdi_write_pcimem(ftdi, roothub.b,
+ (roothub_a & RH_A_NPS) ? 0 : RH_B_PPCM);
+ if (retval)
+ return retval;
+ retval = ftdi_read_pcimem(ftdi, control, &control);
+ if (retval)
+ return retval;
+ mdelay((roothub_a >> 23) & 0x1fe);
+ for (temp = 0; temp < num_ports; temp++) {
+ u32 portstatus;
+ retval = ftdi_read_pcimem(ftdi, roothub.portstatus[temp],
+ &portstatus);
+ if (retval)
+ return retval;
+ if (1 & portstatus)
+ devices += 1;
+ }
+ return devices;
+}
+
+static int ftdi_elan_setup_controller(struct usb_ftdi *ftdi, int fn)
{
u32 latence_timer;
- u32 controlreg;
int UxxxStatus;
u32 pcidata;
int reg = 0;
- int foundOHCI = 0;
- u8 fn;
- int activePCIfn = 0;
- u32 pciVID = 0;
- u32 pciPID = 0;
- UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg);
- if (UxxxStatus)
- return UxxxStatus;
- UxxxStatus = ftdi_elan_write_reg(ftdi, 0x00000000L);
- if (UxxxStatus)
- return UxxxStatus;
- msleep(750);
- UxxxStatus = ftdi_elan_write_reg(ftdi, 0x00000200L | 0x100);
+ int activePCIfn = fn << 8;
+ UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000025FL | 0x2800);
if (UxxxStatus)
return UxxxStatus;
- UxxxStatus = ftdi_elan_write_reg(ftdi, 0x00000200L | 0x500);
+ reg = 16;
+ UxxxStatus = ftdi_elan_write_config(ftdi, activePCIfn | reg, 0,
+ 0xFFFFFFFF);
if (UxxxStatus)
return UxxxStatus;
- UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg);
+ UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0,
+ &pcidata);
if (UxxxStatus)
return UxxxStatus;
- UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000020CL | 0x000);
+ UxxxStatus = ftdi_elan_write_config(ftdi, activePCIfn | reg, 0,
+ 0xF0000000);
if (UxxxStatus)
return UxxxStatus;
- UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000020DL | 0x000);
+ UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0,
+ &pcidata);
if (UxxxStatus)
return UxxxStatus;
- msleep(250);
- UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000020FL | 0x000);
+ reg = 12;
+ UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0,
+ &latence_timer);
if (UxxxStatus)
return UxxxStatus;
- UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg);
+ latence_timer &= 0xFFFF00FF;
+ latence_timer |= 0x00001600;
+ UxxxStatus = ftdi_elan_write_config(ftdi, activePCIfn | reg, 0x00,
+ latence_timer);
if (UxxxStatus)
return UxxxStatus;
- UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000025FL | 0x800);
+ UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0,
+ &pcidata);
if (UxxxStatus)
return UxxxStatus;
- UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg);
+ reg = 4;
+ UxxxStatus = ftdi_elan_write_config(ftdi, activePCIfn | reg, 0x00,
+ 0x06);
if (UxxxStatus)
return UxxxStatus;
- UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg);
+ UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0,
+ &pcidata);
if (UxxxStatus)
return UxxxStatus;
- msleep(1000);
- for (fn = 0; (fn < 4) && (!foundOHCI); fn++) {
- activePCIfn = fn << 8;
- ftdi->function = fn + 1;
- UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0,
- &pcidata);
+ for (reg = 0; reg <= 0x54; reg += 4) {
+ UxxxStatus = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
if (UxxxStatus)
return UxxxStatus;
- pciVID = pcidata & 0xFFFF;
- pciPID = (pcidata >> 16) & 0xFFFF;
- if ((pciVID == 0x1045) && (pciPID == 0xc861)) {
- foundOHCI = 1;
- } else if ((pciVID == 0x1033) && (pciPID == 0x0035)) {
- foundOHCI = 1;
- } else if ((pciVID == 0x10b9) && (pciPID == 0x5237)) {
- foundOHCI = 1;
- } else if ((pciVID == 0x11c1) && (pciPID == 0x5802)) {
- foundOHCI = 1;
- } else if ((pciVID == 0x11AB) && (pciPID == 0x1FA6)) {
- }
- }
- if (foundOHCI == 0) {
- return -ENXIO;
}
- ftdi->platform_data.vendor = pciVID;
- ftdi->platform_data.device = pciPID;
+ return 0;
+}
+
+static int ftdi_elan_close_controller(struct usb_ftdi *ftdi, int fn)
+{
+ u32 latence_timer;
+ int UxxxStatus;
+ u32 pcidata;
+ int reg = 0;
+ int activePCIfn = fn << 8;
UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000025FL | 0x2800);
if (UxxxStatus)
return UxxxStatus;
@@ -2377,7 +2590,7 @@ static int ftdi_elan_enumeratePCI(struct usb_ftdi *ftdi)
if (UxxxStatus)
return UxxxStatus;
UxxxStatus = ftdi_elan_write_config(ftdi, activePCIfn | reg, 0,
- 0xF0000000);
+ 0x00000000);
if (UxxxStatus)
return UxxxStatus;
UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0,
@@ -2401,7 +2614,7 @@ static int ftdi_elan_enumeratePCI(struct usb_ftdi *ftdi)
return UxxxStatus;
reg = 4;
UxxxStatus = ftdi_elan_write_config(ftdi, activePCIfn | reg, 0x00,
- 0x06);
+ 0x00);
if (UxxxStatus)
return UxxxStatus;
UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0,
@@ -2411,159 +2624,139 @@ static int ftdi_elan_enumeratePCI(struct usb_ftdi *ftdi)
return 0;
}
+static int ftdi_elan_found_controller(struct usb_ftdi *ftdi, int fn, int quirk)
+{
+ int result;
+ int UxxxStatus;
+ UxxxStatus = ftdi_elan_setup_controller(ftdi, fn);
+ if (UxxxStatus)
+ return UxxxStatus;
+ result = ftdi_elan_check_controller(ftdi, quirk);
+ UxxxStatus = ftdi_elan_close_controller(ftdi, fn);
+ if (UxxxStatus)
+ return UxxxStatus;
+ return result;
+}
+
+static int ftdi_elan_enumeratePCI(struct usb_ftdi *ftdi)
+{
+ u32 controlreg;
+ u8 sensebits;
+ int UxxxStatus;
+ UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg);
+ if (UxxxStatus)
+ return UxxxStatus;
+ UxxxStatus = ftdi_elan_write_reg(ftdi, 0x00000000L);
+ if (UxxxStatus)
+ return UxxxStatus;
+ msleep(750);
+ UxxxStatus = ftdi_elan_write_reg(ftdi, 0x00000200L | 0x100);
+ if (UxxxStatus)
+ return UxxxStatus;
+ UxxxStatus = ftdi_elan_write_reg(ftdi, 0x00000200L | 0x500);
+ if (UxxxStatus)
+ return UxxxStatus;
+ UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg);
+ if (UxxxStatus)
+ return UxxxStatus;
+ UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000020CL | 0x000);
+ if (UxxxStatus)
+ return UxxxStatus;
+ UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000020DL | 0x000);
+ if (UxxxStatus)
+ return UxxxStatus;
+ msleep(250);
+ UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000020FL | 0x000);
+ if (UxxxStatus)
+ return UxxxStatus;
+ UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg);
+ if (UxxxStatus)
+ return UxxxStatus;
+ UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000025FL | 0x800);
+ if (UxxxStatus)
+ return UxxxStatus;
+ UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg);
+ if (UxxxStatus)
+ return UxxxStatus;
+ UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg);
+ if (UxxxStatus)
+ return UxxxStatus;
+ msleep(1000);
+ sensebits = (controlreg >> 16) & 0x000F;
+ if (0x0D == sensebits)
+ return 0;
+ else
+ return - ENXIO;
+}
+
static int ftdi_elan_setupOHCI(struct usb_ftdi *ftdi)
{
+ int UxxxStatus;
u32 pcidata;
- int U132Status;
- int reg;
- int reset_repeat = 0;
- do_reset:reg = 8;
- U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x0e, 0x01);
- if (U132Status)
- return U132Status;
- reset_check:{
- U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
- if (U132Status)
- return U132Status;
- if (pcidata & 1) {
- msleep(500);
- if (reset_repeat++ > 100) {
- reset_repeat = 0;
- goto do_reset;
- } else
- goto reset_check;
+ int reg = 0;
+ u8 fn;
+ int activePCIfn = 0;
+ int max_devices = 0;
+ int controllers = 0;
+ int unrecognized = 0;
+ ftdi->function = 0;
+ for (fn = 0; (fn < 4); fn++) {
+ u32 pciVID = 0;
+ u32 pciPID = 0;
+ int devices = 0;
+ activePCIfn = fn << 8;
+ UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0,
+ &pcidata);
+ if (UxxxStatus)
+ return UxxxStatus;
+ pciVID = pcidata & 0xFFFF;
+ pciPID = (pcidata >> 16) & 0xFFFF;
+ if ((pciVID == PCI_VENDOR_ID_OPTI) && (pciPID == 0xc861)) {
+ devices = ftdi_elan_found_controller(ftdi, fn, 0);
+ controllers += 1;
+ } else if ((pciVID == PCI_VENDOR_ID_NEC) && (pciPID == 0x0035))
+ {
+ devices = ftdi_elan_found_controller(ftdi, fn, 0);
+ controllers += 1;
+ } else if ((pciVID == PCI_VENDOR_ID_AL) && (pciPID == 0x5237)) {
+ devices = ftdi_elan_found_controller(ftdi, fn, 0);
+ controllers += 1;
+ } else if ((pciVID == PCI_VENDOR_ID_ATT) && (pciPID == 0x5802))
+ {
+ devices = ftdi_elan_found_controller(ftdi, fn, 0);
+ controllers += 1;
+ } else if (pciVID == PCI_VENDOR_ID_AMD && pciPID == 0x740c) {
+ devices = ftdi_elan_found_controller(ftdi, fn,
+ OHCI_QUIRK_AMD756);
+ controllers += 1;
+ } else if (pciVID == PCI_VENDOR_ID_COMPAQ && pciPID == 0xa0f8) {
+ devices = ftdi_elan_found_controller(ftdi, fn,
+ OHCI_QUIRK_ZFMICRO);
+ controllers += 1;
+ } else if (0 == pcidata) {
+ } else
+ unrecognized += 1;
+ if (devices > max_devices) {
+ max_devices = devices;
+ ftdi->function = fn + 1;
+ ftdi->platform_data.vendor = pciVID;
+ ftdi->platform_data.device = pciPID;
}
}
- goto dump_regs;
- msleep(500);
- reg = 0x28;
- U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0x11000000);
- if (U132Status)
- return U132Status;
- U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
- if (U132Status)
- return U132Status;
- reg = 0x40;
- U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0x2edf);
- if (U132Status)
- return U132Status;
- U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
- if (U132Status)
- return U132Status;
- reg = 0x34;
- U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0x2edf2edf);
- if (U132Status)
- return U132Status;
- U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
- if (U132Status)
- return U132Status;
- reg = 4;
- U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0xA0);
- if (U132Status)
- return U132Status;
- U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
- if (U132Status)
- return U132Status;
- msleep(250);
- reg = 8;
- U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x0e, 0x04);
- if (U132Status)
- return U132Status;
- U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
- if (U132Status)
- return U132Status;
- reg = 0x28;
- U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
- if (U132Status)
- return U132Status;
- reg = 8;
- U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
- if (U132Status)
- return U132Status;
- reg = 0x48;
- U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0x00001200);
- if (U132Status)
- return U132Status;
- U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
- if (U132Status)
- return U132Status;
- reg = 0x54;
- U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
- if (U132Status)
- return U132Status;
- reg = 0x58;
- U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
- if (U132Status)
- return U132Status;
- reg = 0x34;
- U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0x28002edf);
- if (U132Status)
- return U132Status;
- U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
- if (U132Status)
- return U132Status;
- msleep(100);
- reg = 0x50;
- U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0x10000);
- if (U132Status)
- return U132Status;
- reg = 0x54;
- power_check:U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
- if (U132Status)
- return U132Status;
- if (!(pcidata & 1)) {
- msleep(500);
- goto power_check;
- }
- msleep(3000);
- reg = 0x54;
- U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
- if (U132Status)
- return U132Status;
- reg = 0x58;
- U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
- if (U132Status)
- return U132Status;
- reg = 0x54;
- U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0x02);
- if (U132Status)
- return U132Status;
- U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
- if (U132Status)
- return U132Status;
- reg = 0x54;
- U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0x10);
- if (U132Status)
- return U132Status;
- U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
- if (U132Status)
- return U132Status;
- msleep(750);
- reg = 0x54;
- if (0) {
- U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0x02);
- if (U132Status)
- return U132Status;
- }
- if (0) {
- U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
- if (U132Status)
- return U132Status;
- }
- reg = 0x54;
- U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
- if (U132Status)
- return U132Status;
- reg = 0x58;
- U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
- if (U132Status)
- return U132Status;
- dump_regs:for (reg = 0; reg <= 0x54; reg += 4) {
- U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
- if (U132Status)
- return U132Status;
+ if (ftdi->function > 0) {
+ UxxxStatus = ftdi_elan_setup_controller(ftdi,
+ ftdi->function - 1);
+ if (UxxxStatus)
+ return UxxxStatus;
+ return 0;
+ } else if (controllers > 0) {
+ return -ENXIO;
+ } else if (unrecognized > 0) {
+ return -ENXIO;
+ } else {
+ ftdi->enumerated = 0;
+ return -ENXIO;
}
- return 0;
}
@@ -2688,6 +2881,7 @@ static void ftdi_elan_disconnect(struct usb_interface *interface)
platform_device_unregister(&ftdi->platform_dev);
ftdi->synchronized = 0;
ftdi->enumerated = 0;
+ ftdi->initialized = 0;
ftdi->registered = 0;
}
flush_workqueue(status_queue);
diff --git a/drivers/usb/misc/phidgetservo.c b/drivers/usb/misc/phidgetservo.c
index 7163f05c5b27..0d9de2f73930 100644
--- a/drivers/usb/misc/phidgetservo.c
+++ b/drivers/usb/misc/phidgetservo.c
@@ -282,6 +282,7 @@ servo_probe(struct usb_interface *interface, const struct usb_device_id *id)
dev->dev = NULL;
goto out;
}
+ dev_set_drvdata(dev->dev, dev);
servo_count = dev->type & SERVO_COUNT_QUAD ? 4 : 1;
diff --git a/drivers/usb/misc/trancevibrator.c b/drivers/usb/misc/trancevibrator.c
index 33cd91d11eca..67e2fc20eeeb 100644
--- a/drivers/usb/misc/trancevibrator.c
+++ b/drivers/usb/misc/trancevibrator.c
@@ -120,8 +120,8 @@ static void tv_disconnect(struct usb_interface *interface)
struct trancevibrator *dev;
dev = usb_get_intfdata (interface);
- usb_set_intfdata(interface, NULL);
device_remove_file(&interface->dev, &dev_attr_speed);
+ usb_set_intfdata(interface, NULL);
usb_put_dev(dev->udev);
kfree(dev);
}
diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c
index 7e8a0acd52ee..70250252ae2a 100644
--- a/drivers/usb/misc/uss720.c
+++ b/drivers/usb/misc/uss720.c
@@ -705,7 +705,7 @@ static int uss720_probe(struct usb_interface *intf,
/*
* Allocate parport interface
*/
- if (!(priv = kcalloc(sizeof(struct parport_uss720_private), 1, GFP_KERNEL))) {
+ if (!(priv = kzalloc(sizeof(struct parport_uss720_private), GFP_KERNEL))) {
usb_put_dev(usbdev);
return -ENOMEM;
}
diff --git a/drivers/usb/net/gl620a.c b/drivers/usb/net/gl620a.c
index a3242be21959..a6f0f4d934df 100644
--- a/drivers/usb/net/gl620a.c
+++ b/drivers/usb/net/gl620a.c
@@ -79,160 +79,6 @@ struct gl_header {
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)
-{
- 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;
diff --git a/drivers/usb/net/rndis_host.c b/drivers/usb/net/rndis_host.c
index 99f26b3e502f..ea5f44de3de2 100644
--- a/drivers/usb/net/rndis_host.c
+++ b/drivers/usb/net/rndis_host.c
@@ -469,7 +469,7 @@ 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, GFP_KERNEL);
+ halt = kzalloc(sizeof *halt, GFP_KERNEL);
if (halt) {
halt->msg_type = RNDIS_MSG_HALT;
halt->msg_len = ccpu2(sizeof *halt);
diff --git a/drivers/usb/net/rtl8150.c b/drivers/usb/net/rtl8150.c
index c54235f73cb6..e0eecda78ec1 100644
--- a/drivers/usb/net/rtl8150.c
+++ b/drivers/usb/net/rtl8150.c
@@ -124,10 +124,11 @@
#define RX_URB_FAIL 3
/* Define these values to match your device */
-#define VENDOR_ID_REALTEK 0x0bda
+#define VENDOR_ID_REALTEK 0x0bda
#define VENDOR_ID_MELCO 0x0411
-#define VENDOR_ID_MICRONET 0x3980
+#define VENDOR_ID_MICRONET 0x3980
#define VENDOR_ID_LONGSHINE 0x07b8
+#define VENDOR_ID_OQO 0x1557
#define VENDOR_ID_ZYXEL 0x0586
#define PRODUCT_ID_RTL8150 0x8150
@@ -144,6 +145,7 @@ static struct usb_device_id rtl8150_table[] = {
{USB_DEVICE(VENDOR_ID_MELCO, PRODUCT_ID_LUAKTX)},
{USB_DEVICE(VENDOR_ID_MICRONET, PRODUCT_ID_SP128AR)},
{USB_DEVICE(VENDOR_ID_LONGSHINE, PRODUCT_ID_LCS8138TX)},
+ {USB_DEVICE(VENDOR_ID_OQO, PRODUCT_ID_RTL8150)},
{USB_DEVICE(VENDOR_ID_ZYXEL, PRODUCT_ID_PRESTIGE)},
{}
};
diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c
index 96c73726d74a..f2ca76a9cbac 100644
--- a/drivers/usb/serial/airprime.c
+++ b/drivers/usb/serial/airprime.c
@@ -19,8 +19,11 @@
static struct usb_device_id id_table [] = {
{ USB_DEVICE(0x0c88, 0x17da) }, /* Kyocera Wireless KPC650/Passport */
{ USB_DEVICE(0x1410, 0x1110) }, /* Novatel Wireless Merlin CDMA */
+ { USB_DEVICE(0x1410, 0x1130) }, /* Novatel Wireless S720 CDMA/EV-DO */
+ { USB_DEVICE(0x1410, 0x2110) }, /* Novatel Wireless U720 CDMA/EV-DO */
{ USB_DEVICE(0x1410, 0x1430) }, /* Novatel Merlin XU870 HSDPA/3G */
{ USB_DEVICE(0x1410, 0x1100) }, /* ExpressCard34 Qualcomm 3G CDMA */
+ { USB_DEVICE(0x413c, 0x8115) }, /* Dell Wireless HSDPA 5500 */
{ },
};
MODULE_DEVICE_TABLE(usb, id_table);
diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c
index 2f9b7ac32663..7ebaffd6ed86 100644
--- a/drivers/usb/serial/cp2101.c
+++ b/drivers/usb/serial/cp2101.c
@@ -69,6 +69,7 @@ static struct usb_device_id id_table [] = {
{ USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */
{ USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
{ USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
+ { USB_DEVICE(0x13AD, 0x9999) }, /* Baltech card reader */
{ USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */
{ } /* Terminating Entry */
};
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
index a1fdb85b8c0a..6bc1f404e186 100644
--- a/drivers/usb/serial/cypress_m8.c
+++ b/drivers/usb/serial/cypress_m8.c
@@ -962,21 +962,6 @@ static int cypress_ioctl (struct usb_serial_port *port, struct file * file, unsi
cypress_set_termios(port, &priv->tmp_termios);
return (0);
break;
- /* these are called when setting baud rate from gpsd */
- case TCGETS:
- if (copy_to_user((void __user *)arg, port->tty->termios, sizeof(struct termios))) {
- return -EFAULT;
- }
- return (0);
- break;
- case TCSETS:
- if (copy_from_user(port->tty->termios, (void __user *)arg, sizeof(struct termios))) {
- return -EFAULT;
- }
- /* here we need to call cypress_set_termios to invoke the new settings */
- cypress_set_termios(port, &priv->tmp_termios);
- return (0);
- break;
/* This code comes from drivers/char/serial.c and ftdi_sio.c */
case TIOCMIWAIT:
while (priv != NULL) {
@@ -1493,7 +1478,7 @@ static struct cypress_buf *cypress_buf_alloc(unsigned int size)
if (size == 0)
return NULL;
- cb = (struct cypress_buf *)kmalloc(sizeof(struct cypress_buf), GFP_KERNEL);
+ cb = kmalloc(sizeof(struct cypress_buf), GFP_KERNEL);
if (cb == NULL)
return NULL;
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c
index 9d9ea874639c..efd9ce3f931f 100644
--- a/drivers/usb/serial/digi_acceleport.c
+++ b/drivers/usb/serial/digi_acceleport.c
@@ -1681,7 +1681,7 @@ dbg( "digi_startup: TOP" );
for( i=0; i<serial->type->num_ports+1; i++ ) {
/* allocate port private structure */
- priv = (struct digi_port *)kmalloc( sizeof(struct digi_port),
+ priv = kmalloc( sizeof(struct digi_port),
GFP_KERNEL );
if( priv == (struct digi_port *)0 ) {
while( --i >= 0 )
@@ -1714,7 +1714,7 @@ dbg( "digi_startup: TOP" );
}
/* allocate serial private structure */
- serial_priv = (struct digi_serial *)kmalloc( sizeof(struct digi_serial),
+ serial_priv = kmalloc( sizeof(struct digi_serial),
GFP_KERNEL );
if( serial_priv == (struct digi_serial *)0 ) {
for( i=0; i<serial->type->num_ports+1; i++ )
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 41b0ad2d56ac..6986e756f7c0 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -452,6 +452,7 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, LINX_FUTURE_2_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_CCSICDU20_0_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_CCSICDU40_1_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_CCSMACHX_2_PID) },
{ USB_DEVICE(FTDI_VID, INSIDE_ACCESSO) },
{ USB_DEVICE(INTREPID_VID, INTREPID_VALUECAN_PID) },
{ USB_DEVICE(INTREPID_VID, INTREPID_NEOVI_PID) },
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h
index bae117d359af..40dd394de58d 100644
--- a/drivers/usb/serial/ftdi_sio.h
+++ b/drivers/usb/serial/ftdi_sio.h
@@ -312,8 +312,9 @@
/* CCS Inc. ICDU/ICDU40 product ID - the FT232BM is used in an in-circuit-debugger */
/* unit for PIC16's/PIC18's */
-#define FTDI_CCSICDU20_0_PID 0xF9D0
-#define FTDI_CCSICDU40_1_PID 0xF9D1
+#define FTDI_CCSICDU20_0_PID 0xF9D0
+#define FTDI_CCSICDU40_1_PID 0xF9D1
+#define FTDI_CCSMACHX_2_PID 0xF9D2
/* Inside Accesso contactless reader (http://www.insidefr.com) */
#define INSIDE_ACCESSO 0xFAD0
diff --git a/drivers/usb/serial/funsoft.c b/drivers/usb/serial/funsoft.c
index 77b977206a8c..d3be9214c7c1 100644
--- a/drivers/usb/serial/funsoft.c
+++ b/drivers/usb/serial/funsoft.c
@@ -14,6 +14,9 @@
#include <linux/module.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
+#include <asm/uaccess.h>
+
+static int debug;
static struct usb_device_id id_table [] = {
{ USB_DEVICE(0x1404, 0xcddc) },
@@ -21,6 +24,26 @@ static struct usb_device_id id_table [] = {
};
MODULE_DEVICE_TABLE(usb, id_table);
+static int funsoft_ioctl(struct usb_serial_port *port, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ struct termios t;
+
+ dbg("%s - port %d, cmd 0x%04x", __FUNCTION__, port->number, cmd);
+
+ if (cmd == TCSETSF) {
+ if (user_termios_to_kernel_termios(&t, (void __user *)arg))
+ return -EFAULT;
+
+ dbg("%s - iflag:%x oflag:%x cflag:%x lflag:%x", __FUNCTION__,
+ t.c_iflag, t.c_oflag, t.c_cflag, t.c_lflag);
+
+ if (!(t.c_lflag & ICANON))
+ return -EINVAL;
+ }
+ return -ENOIOCTLCMD;
+}
+
static struct usb_driver funsoft_driver = {
.name = "funsoft",
.probe = usb_serial_probe,
@@ -39,6 +62,7 @@ static struct usb_serial_driver funsoft_device = {
.num_bulk_in = NUM_DONT_CARE,
.num_bulk_out = NUM_DONT_CARE,
.num_ports = 1,
+ .ioctl = funsoft_ioctl,
};
static int __init funsoft_init(void)
@@ -63,3 +87,6 @@ static void __exit funsoft_exit(void)
module_init(funsoft_init);
module_exit(funsoft_exit);
MODULE_LICENSE("GPL");
+
+module_param(debug, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Debug enabled or not");
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
index 2da2684e0809..980285c0233a 100644
--- a/drivers/usb/serial/io_ti.c
+++ b/drivers/usb/serial/io_ti.c
@@ -2811,7 +2811,7 @@ static struct edge_buf *edge_buf_alloc(unsigned int size)
if (size == 0)
return NULL;
- eb = (struct edge_buf *)kmalloc(sizeof(struct edge_buf), GFP_KERNEL);
+ eb = kmalloc(sizeof(struct edge_buf), GFP_KERNEL);
if (eb == NULL)
return NULL;
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c
index d72cf8bc7f76..42f757a5b876 100644
--- a/drivers/usb/serial/ipaq.c
+++ b/drivers/usb/serial/ipaq.c
@@ -595,7 +595,7 @@ static int ipaq_open(struct usb_serial_port *port, struct file *filp)
bytes_in = 0;
bytes_out = 0;
- priv = (struct ipaq_private *)kmalloc(sizeof(struct ipaq_private), GFP_KERNEL);
+ priv = kmalloc(sizeof(struct ipaq_private), GFP_KERNEL);
if (priv == NULL) {
err("%s - Out of memory", __FUNCTION__);
return -ENOMEM;
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c
index 73d755df4840..5c4b06a99ac0 100644
--- a/drivers/usb/serial/kl5kusb105.c
+++ b/drivers/usb/serial/kl5kusb105.c
@@ -87,10 +87,6 @@ static int klsi_105_write_room (struct usb_serial_port *port);
static void klsi_105_read_bulk_callback (struct urb *urb);
static void klsi_105_set_termios (struct usb_serial_port *port,
struct ktermios *old);
-static int klsi_105_ioctl (struct usb_serial_port *port,
- struct file * file,
- unsigned int cmd,
- unsigned long arg);
static void klsi_105_throttle (struct usb_serial_port *port);
static void klsi_105_unthrottle (struct usb_serial_port *port);
/*
@@ -140,7 +136,6 @@ static struct usb_serial_driver kl5kusb105d_device = {
.chars_in_buffer = klsi_105_chars_in_buffer,
.write_room = klsi_105_write_room,
.read_bulk_callback =klsi_105_read_bulk_callback,
- .ioctl = klsi_105_ioctl,
.set_termios = klsi_105_set_termios,
/*.break_ctl = klsi_105_break_ctl,*/
.tiocmget = klsi_105_tiocmget,
@@ -899,69 +894,6 @@ static int klsi_105_tiocmset (struct usb_serial_port *port, struct file *file,
*/
return retval;
}
-
-static int klsi_105_ioctl (struct usb_serial_port *port, struct file * file,
- unsigned int cmd, unsigned long arg)
-{
- struct klsi_105_private *priv = usb_get_serial_port_data(port);
- void __user *user_arg = (void __user *)arg;
-
- dbg("%scmd=0x%x", __FUNCTION__, cmd);
-
- /* Based on code from acm.c and others */
- switch (cmd) {
- case TIOCMIWAIT:
- /* wait for any of the 4 modem inputs (DCD,RI,DSR,CTS)*/
- /* TODO */
- dbg("%s - TIOCMIWAIT not handled", __FUNCTION__);
- return -ENOIOCTLCMD;
- case TIOCGICOUNT:
- /* return count of modemline transitions */
- /* TODO */
- dbg("%s - TIOCGICOUNT not handled", __FUNCTION__);
- return -ENOIOCTLCMD;
- case TCGETS:
- /* return current info to caller */
- dbg("%s - TCGETS data faked/incomplete", __FUNCTION__);
-
- if (!access_ok(VERIFY_WRITE, user_arg, sizeof(struct termios)))
- return -EFAULT;
-
- if (kernel_termios_to_user_termios((struct termios __user *)arg,
- &priv->termios))
- return -EFAULT;
- return 0;
- case TCSETS:
- /* set port termios to the one given by the user */
- dbg("%s - TCSETS not handled", __FUNCTION__);
-
- if (!access_ok(VERIFY_READ, user_arg, sizeof(struct termios)))
- return -EFAULT;
-
- if (user_termios_to_kernel_termios(&priv->termios,
- (struct termios __user *)arg))
- return -EFAULT;
- klsi_105_set_termios(port, &priv->termios);
- return 0;
- case TCSETSW: {
- /* set port termios and try to wait for completion of last
- * write operation */
- /* We guess here. If there are not too many write urbs
- * outstanding, we lie. */
- /* what is the right way to wait here? schedule() ? */
- /*
- while (klsi_105_chars_in_buffer(port) > (NUM_URBS / 4 ) * URB_TRANSFER_BUFFER_SIZE)
- schedule();
- */
- return -ENOIOCTLCMD;
- }
- default:
- dbg("%s: arg not supported - 0x%04x", __FUNCTION__,cmd);
- return(-ENOIOCTLCMD);
- break;
- }
- return 0;
-} /* klsi_105_ioctl */
static void klsi_105_throttle (struct usb_serial_port *port)
{
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c
index e284d6c0fd35..62bea0c923bd 100644
--- a/drivers/usb/serial/kobil_sct.c
+++ b/drivers/usb/serial/kobil_sct.c
@@ -269,7 +269,7 @@ static int kobil_open (struct usb_serial_port *port, struct file *filp)
}
// allocate memory for write_urb transfer buffer
- port->write_urb->transfer_buffer = (unsigned char *) kmalloc(write_urb_transfer_buffer_length, GFP_KERNEL);
+ port->write_urb->transfer_buffer = kmalloc(write_urb_transfer_buffer_length, GFP_KERNEL);
if (! port->write_urb->transfer_buffer) {
kfree(transfer_buffer);
usb_free_urb(port->write_urb);
@@ -696,7 +696,7 @@ static int kobil_ioctl(struct usb_serial_port *port, struct file *file,
return 0;
case TCFLSH: // 0x540B
- transfer_buffer = (unsigned char *) kmalloc(transfer_buffer_length, GFP_KERNEL);
+ transfer_buffer = kmalloc(transfer_buffer_length, GFP_KERNEL);
if (! transfer_buffer) {
return -ENOBUFS;
}
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
index 8cc728a49e41..83f661403ba1 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -2460,12 +2460,6 @@ static int mos7840_ioctl(struct usb_serial_port *port, struct file *file,
tty_ldisc_deref(ld);
return 0;
- case TCGETS:
- if (kernel_termios_to_user_termios
- ((struct termios __user *)argp, tty->termios))
- return -EFAULT;
- return 0;
-
case TIOCSERGETLSR:
dbg("%s (%d) TIOCSERGETLSR", __FUNCTION__, port->number);
return mos7840_get_lsr_info(mos7840_port, argp);
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 0ae4098718c3..819266b7e2f8 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -79,6 +79,7 @@ static int option_send_setup(struct usb_serial_port *port);
#define OPTION_PRODUCT_COBRA 0x6500
#define OPTION_PRODUCT_COBRA2 0x6600
#define HUAWEI_PRODUCT_E600 0x1001
+#define HUAWEI_PRODUCT_E220 0x1003
#define AUDIOVOX_PRODUCT_AIRCARD 0x0112
#define NOVATELWIRELESS_PRODUCT_U740 0x1400
#define ANYDATA_PRODUCT_ID 0x6501
@@ -90,6 +91,7 @@ static struct usb_device_id option_ids[] = {
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA2) },
{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) },
+ { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220) },
{ USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) },
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) },
{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) },
@@ -103,6 +105,7 @@ static struct usb_device_id option_ids1[] = {
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA2) },
{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) },
+ { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220) },
{ USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) },
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) },
{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) },
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index d124d780e42e..5dc2ac9afa90 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -159,7 +159,7 @@ static struct pl2303_buf *pl2303_buf_alloc(unsigned int size)
if (size == 0)
return NULL;
- pb = (struct pl2303_buf *)kmalloc(sizeof(struct pl2303_buf), GFP_KERNEL);
+ pb = kmalloc(sizeof(struct pl2303_buf), GFP_KERNEL);
if (pb == NULL)
return NULL;
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
index f42eb9ea6405..83189005c6fb 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -1710,7 +1710,7 @@ static struct circ_buf *ti_buf_alloc(void)
{
struct circ_buf *cb;
- cb = (struct circ_buf *)kmalloc(sizeof(struct circ_buf), GFP_KERNEL);
+ cb = kmalloc(sizeof(struct circ_buf), GFP_KERNEL);
if (cb == NULL)
return NULL;
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c
index dc45e58e2b8c..5483d8564c1b 100644
--- a/drivers/usb/serial/whiteheat.c
+++ b/drivers/usb/serial/whiteheat.c
@@ -416,7 +416,7 @@ static int whiteheat_attach (struct usb_serial *serial)
for (i = 0; i < serial->num_ports; i++) {
port = serial->port[i];
- info = (struct whiteheat_private *)kmalloc(sizeof(struct whiteheat_private), GFP_KERNEL);
+ info = kmalloc(sizeof(struct whiteheat_private), GFP_KERNEL);
if (info == NULL) {
err("%s: Out of memory for port structures\n", serial->type->description);
goto no_private;
@@ -487,7 +487,7 @@ static int whiteheat_attach (struct usb_serial *serial)
usb_set_serial_port_data(port, info);
}
- command_info = (struct whiteheat_command_private *)kmalloc(sizeof(struct whiteheat_command_private), GFP_KERNEL);
+ command_info = kmalloc(sizeof(struct whiteheat_command_private), GFP_KERNEL);
if (command_info == NULL) {
err("%s: Out of memory for port structures\n", serial->type->description);
goto no_command_private;
diff --git a/drivers/usb/storage/sddr09.c b/drivers/usb/storage/sddr09.c
index fb8bacaae27c..e3528eca29a5 100644
--- a/drivers/usb/storage/sddr09.c
+++ b/drivers/usb/storage/sddr09.c
@@ -646,7 +646,7 @@ sddr09_read_sg_test_only(struct us_data *us) {
return result;
}
- buf = (unsigned char *) kmalloc(bulklen, GFP_NOIO);
+ buf = kmalloc(bulklen, GFP_NOIO);
if (!buf)
return -ENOMEM;
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index db8b26012c75..5fe7ff441a09 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -153,6 +153,13 @@ UNUSUAL_DEV( 0x0421, 0x042e, 0x0100, 0x0100,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ),
+/* Reported by <honkkis@gmail.com> */
+UNUSUAL_DEV( 0x0421, 0x0433, 0x0100, 0x0100,
+ "Nokia",
+ "E70",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ),
+
/* Reported by Jon Hart <Jon.Hart@web.de> */
UNUSUAL_DEV( 0x0421, 0x0434, 0x0100, 0x0100,
"Nokia",
@@ -1328,6 +1335,15 @@ UNUSUAL_DEV( 0x1210, 0x0003, 0x0100, 0x0100,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_IGNORE_RESIDUE ),
+/* This prevents the kernel from detecting the virtual cd-drive with the
+ * Windows drivers. <johann.wilhelm@student.tugraz.at>
+*/
+UNUSUAL_DEV( 0x12d1, 0x1003, 0x0000, 0xffff,
+ "HUAWEI",
+ "E220 USB-UMTS Install",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_IGNORE_DEVICE),
+
/* Reported by Vilius Bilinkevicius <vilisas AT xxx DOT lt) */
UNUSUAL_DEV( 0x132b, 0x000b, 0x0001, 0x0001,
"Minolta",
diff --git a/drivers/video/amba-clcd.c b/drivers/video/amba-clcd.c
index 6761b68c35e9..6c9dc2e69c82 100644
--- a/drivers/video/amba-clcd.c
+++ b/drivers/video/amba-clcd.c
@@ -447,7 +447,7 @@ static int clcdfb_probe(struct amba_device *dev, void *id)
goto out;
}
- fb = (struct clcd_fb *) kmalloc(sizeof(struct clcd_fb), GFP_KERNEL);
+ fb = kmalloc(sizeof(struct clcd_fb), GFP_KERNEL);
if (!fb) {
printk(KERN_INFO "CLCD: could not allocate new clcd_fb struct\n");
ret = -ENOMEM;
diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c
index 88a47845c4f7..1a849b870bcc 100644
--- a/drivers/video/amifb.c
+++ b/drivers/video/amifb.c
@@ -2906,14 +2906,6 @@ static int ami_decode_var(struct fb_var_screeninfo *var,
par->crsr.spot_x = par->crsr.spot_y = 0;
par->crsr.height = par->crsr.width = 0;
-#if 0 /* fbmon not done. uncomment for 2.5.x -brad */
- if (!fbmon_valid_timings(pixclock[clk_shift], htotal, vtotal,
- &fb_info)) {
- DPRINTK("mode doesn't fit for monitor\n");
- return -EINVAL;
- }
-#endif
-
return 0;
}
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
index 3feddf89d100..2e976ffcde0f 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -1834,7 +1834,7 @@ static void aty128_bl_init(struct aty128fb_par *par)
snprintf(name, sizeof(name), "aty128bl%d", info->node);
- bd = backlight_device_register(name, par, &aty128_bl_data);
+ bd = backlight_device_register(name, info->dev, par, &aty128_bl_data);
if (IS_ERR(bd)) {
info->bl_dev = NULL;
printk(KERN_WARNING "aty128: Backlight registration failed\n");
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index 176f9b85cdbe..f2ebdd880085 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -1488,10 +1488,6 @@ static int atyfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
else
info->var.accel_flags = 0;
-#if 0 /* fbmon is not done. uncomment for 2.5.x -brad */
- if (!fbmon_valid_timings(pixclock, htotal, vtotal, info))
- return -EINVAL;
-#endif
aty_crtc_to_var(&crtc, var);
var->pixclock = par->pll_ops->pll_to_var(info, &pll);
return 0;
@@ -2215,7 +2211,7 @@ static void aty_bl_init(struct atyfb_par *par)
snprintf(name, sizeof(name), "atybl%d", info->node);
- bd = backlight_device_register(name, par, &aty_bl_data);
+ bd = backlight_device_register(name, info->dev, par, &aty_bl_data);
if (IS_ERR(bd)) {
info->bl_dev = NULL;
printk(KERN_WARNING "aty: Backlight registration failed\n");
diff --git a/drivers/video/aty/radeon_backlight.c b/drivers/video/aty/radeon_backlight.c
index 585eb7b9e636..3abfd4a380cc 100644
--- a/drivers/video/aty/radeon_backlight.c
+++ b/drivers/video/aty/radeon_backlight.c
@@ -163,7 +163,7 @@ void radeonfb_bl_init(struct radeonfb_info *rinfo)
snprintf(name, sizeof(name), "radeonbl%d", rinfo->info->node);
- bd = backlight_device_register(name, pdata, &radeon_bl_data);
+ bd = backlight_device_register(name, rinfo->info->dev, pdata, &radeon_bl_data);
if (IS_ERR(bd)) {
rinfo->info->bl_dev = NULL;
printk("radeonfb: Backlight registration failed\n");
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
index db8c191b1201..9601bfe309ac 100644
--- a/drivers/video/backlight/backlight.c
+++ b/drivers/video/backlight/backlight.c
@@ -216,8 +216,10 @@ static const struct class_device_attribute bl_class_device_attributes[] = {
* Creates and registers new backlight class_device. Returns either an
* ERR_PTR() or a pointer to the newly allocated device.
*/
-struct backlight_device *backlight_device_register(const char *name, void *devdata,
- struct backlight_properties *bp)
+struct backlight_device *backlight_device_register(const char *name,
+ struct device *dev,
+ void *devdata,
+ struct backlight_properties *bp)
{
int i, rc;
struct backlight_device *new_bd;
@@ -232,6 +234,7 @@ struct backlight_device *backlight_device_register(const char *name, void *devda
new_bd->props = bp;
memset(&new_bd->class_dev, 0, sizeof(new_bd->class_dev));
new_bd->class_dev.class = &backlight_class;
+ new_bd->class_dev.dev = dev;
strlcpy(new_bd->class_dev.class_id, name, KOBJ_NAME_LEN);
class_set_devdata(&new_bd->class_dev, devdata);
diff --git a/drivers/video/bw2.c b/drivers/video/bw2.c
index c66e3d52cbf3..9bb6257d6918 100644
--- a/drivers/video/bw2.c
+++ b/drivers/video/bw2.c
@@ -320,7 +320,7 @@ static int __devinit bw2_init_one(struct of_device *op)
all->info.fbops = &bw2_ops;
all->info.screen_base =
- sbus_ioremap(&op->resource[0], 0, all->par.fbsize, "bw2 ram");
+ of_ioremap(&op->resource[0], 0, all->par.fbsize, "bw2 ram");
all->info.par = &all->par;
bw2_blank(0, &all->info);
@@ -329,8 +329,10 @@ static int __devinit bw2_init_one(struct of_device *op)
err= register_framebuffer(&all->info);
if (err < 0) {
- of_iounmap(all->par.regs, sizeof(struct bw2_regs));
- of_iounmap(all->info.screen_base, all->par.fbsize);
+ of_iounmap(&op->resource[0],
+ all->par.regs, sizeof(struct bw2_regs));
+ of_iounmap(&op->resource[0],
+ all->info.screen_base, all->par.fbsize);
kfree(all);
return err;
}
@@ -351,18 +353,18 @@ static int __devinit bw2_probe(struct of_device *dev, const struct of_device_id
return bw2_init_one(op);
}
-static int __devexit bw2_remove(struct of_device *dev)
+static int __devexit bw2_remove(struct of_device *op)
{
- struct all_info *all = dev_get_drvdata(&dev->dev);
+ struct all_info *all = dev_get_drvdata(&op->dev);
unregister_framebuffer(&all->info);
- of_iounmap(all->par.regs, sizeof(struct bw2_regs));
- of_iounmap(all->info.screen_base, all->par.fbsize);
+ of_iounmap(&op->resource[0], all->par.regs, sizeof(struct bw2_regs));
+ of_iounmap(&op->resource[0], all->info.screen_base, all->par.fbsize);
kfree(all);
- dev_set_drvdata(&dev->dev, NULL);
+ dev_set_drvdata(&op->dev, NULL);
return 0;
}
diff --git a/drivers/video/cg14.c b/drivers/video/cg14.c
index 7f926c619b61..ec6a51a5822d 100644
--- a/drivers/video/cg14.c
+++ b/drivers/video/cg14.c
@@ -452,16 +452,20 @@ struct all_info {
struct cg14_par par;
};
-static void cg14_unmap_regs(struct all_info *all)
+static void cg14_unmap_regs(struct of_device *op, struct all_info *all)
{
if (all->par.regs)
- of_iounmap(all->par.regs, sizeof(struct cg14_regs));
+ of_iounmap(&op->resource[0],
+ all->par.regs, sizeof(struct cg14_regs));
if (all->par.clut)
- of_iounmap(all->par.clut, sizeof(struct cg14_clut));
+ of_iounmap(&op->resource[0],
+ all->par.clut, sizeof(struct cg14_clut));
if (all->par.cursor)
- of_iounmap(all->par.cursor, sizeof(struct cg14_cursor));
+ of_iounmap(&op->resource[0],
+ all->par.cursor, sizeof(struct cg14_cursor));
if (all->info.screen_base)
- of_iounmap(all->info.screen_base, all->par.fbsize);
+ of_iounmap(&op->resource[1],
+ all->info.screen_base, all->par.fbsize);
}
static int __devinit cg14_init_one(struct of_device *op)
@@ -506,7 +510,7 @@ static int __devinit cg14_init_one(struct of_device *op)
if (!all->par.regs || !all->par.clut || !all->par.cursor ||
!all->info.screen_base)
- cg14_unmap_regs(all);
+ cg14_unmap_regs(op, all);
is_8mb = (((op->resource[1].end - op->resource[1].start) + 1) ==
(8 * 1024 * 1024));
@@ -541,7 +545,7 @@ static int __devinit cg14_init_one(struct of_device *op)
__cg14_reset(&all->par);
if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
- cg14_unmap_regs(all);
+ cg14_unmap_regs(op, all);
kfree(all);
return -ENOMEM;
}
@@ -552,7 +556,7 @@ static int __devinit cg14_init_one(struct of_device *op)
err = register_framebuffer(&all->info);
if (err < 0) {
fb_dealloc_cmap(&all->info.cmap);
- cg14_unmap_regs(all);
+ cg14_unmap_regs(op, all);
kfree(all);
return err;
}
@@ -574,18 +578,18 @@ static int __devinit cg14_probe(struct of_device *dev, const struct of_device_id
return cg14_init_one(op);
}
-static int __devexit cg14_remove(struct of_device *dev)
+static int __devexit cg14_remove(struct of_device *op)
{
- struct all_info *all = dev_get_drvdata(&dev->dev);
+ struct all_info *all = dev_get_drvdata(&op->dev);
unregister_framebuffer(&all->info);
fb_dealloc_cmap(&all->info.cmap);
- cg14_unmap_regs(all);
+ cg14_unmap_regs(op, all);
kfree(all);
- dev_set_drvdata(&dev->dev, NULL);
+ dev_set_drvdata(&op->dev, NULL);
return 0;
}
diff --git a/drivers/video/cg3.c b/drivers/video/cg3.c
index 9c8c753ef454..ada6f7e3a891 100644
--- a/drivers/video/cg3.c
+++ b/drivers/video/cg3.c
@@ -403,8 +403,10 @@ static int __devinit cg3_init_one(struct of_device *op)
cg3_do_default_mode(&all->par);
if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
- of_iounmap(all->par.regs, sizeof(struct cg3_regs));
- of_iounmap(all->info.screen_base, all->par.fbsize);
+ of_iounmap(&op->resource[0],
+ all->par.regs, sizeof(struct cg3_regs));
+ of_iounmap(&op->resource[0],
+ all->info.screen_base, all->par.fbsize);
kfree(all);
return -ENOMEM;
}
@@ -415,8 +417,10 @@ static int __devinit cg3_init_one(struct of_device *op)
err = register_framebuffer(&all->info);
if (err < 0) {
fb_dealloc_cmap(&all->info.cmap);
- of_iounmap(all->par.regs, sizeof(struct cg3_regs));
- of_iounmap(all->info.screen_base, all->par.fbsize);
+ of_iounmap(&op->resource[0],
+ all->par.regs, sizeof(struct cg3_regs));
+ of_iounmap(&op->resource[0],
+ all->info.screen_base, all->par.fbsize);
kfree(all);
return err;
}
@@ -436,19 +440,19 @@ static int __devinit cg3_probe(struct of_device *dev, const struct of_device_id
return cg3_init_one(op);
}
-static int __devexit cg3_remove(struct of_device *dev)
+static int __devexit cg3_remove(struct of_device *op)
{
- struct all_info *all = dev_get_drvdata(&dev->dev);
+ struct all_info *all = dev_get_drvdata(&op->dev);
unregister_framebuffer(&all->info);
fb_dealloc_cmap(&all->info.cmap);
- of_iounmap(all->par.regs, sizeof(struct cg3_regs));
- of_iounmap(all->info.screen_base, all->par.fbsize);
+ of_iounmap(&op->resource[0], all->par.regs, sizeof(struct cg3_regs));
+ of_iounmap(&op->resource[0], all->info.screen_base, all->par.fbsize);
kfree(all);
- dev_set_drvdata(&dev->dev, NULL);
+ dev_set_drvdata(&op->dev, NULL);
return 0;
}
diff --git a/drivers/video/cg6.c b/drivers/video/cg6.c
index 64146be2eeb0..4dad23a28f58 100644
--- a/drivers/video/cg6.c
+++ b/drivers/video/cg6.c
@@ -658,21 +658,26 @@ struct all_info {
struct cg6_par par;
};
-static void cg6_unmap_regs(struct all_info *all)
+static void cg6_unmap_regs(struct of_device *op, struct all_info *all)
{
if (all->par.fbc)
- of_iounmap(all->par.fbc, 4096);
+ of_iounmap(&op->resource[0], all->par.fbc, 4096);
if (all->par.tec)
- of_iounmap(all->par.tec, sizeof(struct cg6_tec));
+ of_iounmap(&op->resource[0],
+ all->par.tec, sizeof(struct cg6_tec));
if (all->par.thc)
- of_iounmap(all->par.thc, sizeof(struct cg6_thc));
+ of_iounmap(&op->resource[0],
+ all->par.thc, sizeof(struct cg6_thc));
if (all->par.bt)
- of_iounmap(all->par.bt, sizeof(struct bt_regs));
+ of_iounmap(&op->resource[0],
+ all->par.bt, sizeof(struct bt_regs));
if (all->par.fhc)
- of_iounmap(all->par.fhc, sizeof(u32));
+ of_iounmap(&op->resource[0],
+ all->par.fhc, sizeof(u32));
if (all->info.screen_base)
- of_iounmap(all->info.screen_base, all->par.fbsize);
+ of_iounmap(&op->resource[0],
+ all->info.screen_base, all->par.fbsize);
}
static int __devinit cg6_init_one(struct of_device *op)
@@ -720,7 +725,7 @@ static int __devinit cg6_init_one(struct of_device *op)
all->par.fbsize, "cgsix ram");
if (!all->par.fbc || !all->par.tec || !all->par.thc ||
!all->par.bt || !all->par.fhc || !all->info.screen_base) {
- cg6_unmap_regs(all);
+ cg6_unmap_regs(op, all);
kfree(all);
return -ENOMEM;
}
@@ -734,7 +739,7 @@ static int __devinit cg6_init_one(struct of_device *op)
cg6_blank(0, &all->info);
if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
- cg6_unmap_regs(all);
+ cg6_unmap_regs(op, all);
kfree(all);
return -ENOMEM;
}
@@ -744,7 +749,7 @@ static int __devinit cg6_init_one(struct of_device *op)
err = register_framebuffer(&all->info);
if (err < 0) {
- cg6_unmap_regs(all);
+ cg6_unmap_regs(op, all);
fb_dealloc_cmap(&all->info.cmap);
kfree(all);
return err;
@@ -767,18 +772,18 @@ static int __devinit cg6_probe(struct of_device *dev, const struct of_device_id
return cg6_init_one(op);
}
-static int __devexit cg6_remove(struct of_device *dev)
+static int __devexit cg6_remove(struct of_device *op)
{
- struct all_info *all = dev_get_drvdata(&dev->dev);
+ struct all_info *all = dev_get_drvdata(&op->dev);
unregister_framebuffer(&all->info);
fb_dealloc_cmap(&all->info.cmap);
- cg6_unmap_regs(all);
+ cg6_unmap_regs(op, all);
kfree(all);
- dev_set_drvdata(&dev->dev, NULL);
+ dev_set_drvdata(&op->dev, NULL);
return 0;
}
diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c
index 949141bd44d4..15854aec3180 100644
--- a/drivers/video/ffb.c
+++ b/drivers/video/ffb.c
@@ -910,7 +910,8 @@ static int ffb_init_one(struct of_device *op)
all->par.dac = of_ioremap(&op->resource[1], 0,
sizeof(struct ffb_dac), "ffb dac");
if (!all->par.dac) {
- of_iounmap(all->par.fbc, sizeof(struct ffb_fbc));
+ of_iounmap(&op->resource[2],
+ all->par.fbc, sizeof(struct ffb_fbc));
kfree(all);
return -ENOMEM;
}
@@ -968,8 +969,10 @@ static int ffb_init_one(struct of_device *op)
if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
printk(KERN_ERR "ffb: Could not allocate color map.\n");
- of_iounmap(all->par.fbc, sizeof(struct ffb_fbc));
- of_iounmap(all->par.dac, sizeof(struct ffb_dac));
+ of_iounmap(&op->resource[2],
+ all->par.fbc, sizeof(struct ffb_fbc));
+ of_iounmap(&op->resource[1],
+ all->par.dac, sizeof(struct ffb_dac));
kfree(all);
return -ENOMEM;
}
@@ -980,8 +983,10 @@ static int ffb_init_one(struct of_device *op)
if (err < 0) {
printk(KERN_ERR "ffb: Could not register framebuffer.\n");
fb_dealloc_cmap(&all->info.cmap);
- of_iounmap(all->par.fbc, sizeof(struct ffb_fbc));
- of_iounmap(all->par.dac, sizeof(struct ffb_dac));
+ of_iounmap(&op->resource[2],
+ all->par.fbc, sizeof(struct ffb_fbc));
+ of_iounmap(&op->resource[1],
+ all->par.dac, sizeof(struct ffb_dac));
kfree(all);
return err;
}
@@ -1003,19 +1008,19 @@ static int __devinit ffb_probe(struct of_device *dev, const struct of_device_id
return ffb_init_one(op);
}
-static int __devexit ffb_remove(struct of_device *dev)
+static int __devexit ffb_remove(struct of_device *op)
{
- struct all_info *all = dev_get_drvdata(&dev->dev);
+ struct all_info *all = dev_get_drvdata(&op->dev);
unregister_framebuffer(&all->info);
fb_dealloc_cmap(&all->info.cmap);
- of_iounmap(all->par.fbc, sizeof(struct ffb_fbc));
- of_iounmap(all->par.dac, sizeof(struct ffb_dac));
+ of_iounmap(&op->resource[2], all->par.fbc, sizeof(struct ffb_fbc));
+ of_iounmap(&op->resource[1], all->par.dac, sizeof(struct ffb_dac));
kfree(all);
- dev_set_drvdata(&dev->dev, NULL);
+ dev_set_drvdata(&op->dev, NULL);
return 0;
}
diff --git a/drivers/video/gxt4500.c b/drivers/video/gxt4500.c
index 3adf6ab0768f..23a6bcc3e3ce 100644
--- a/drivers/video/gxt4500.c
+++ b/drivers/video/gxt4500.c
@@ -1,5 +1,5 @@
/*
- * Frame buffer device for IBM GXT4500P display adaptor
+ * Frame buffer device for IBM GXT4500P and GXT6000P display adaptors
*
* Copyright (C) 2006 Paul Mackerras, IBM Corp. <paulus@samba.org>
*/
@@ -11,8 +11,10 @@
#include <linux/pci.h>
#include <linux/pci_ids.h>
#include <linux/delay.h>
+#include <linux/string.h>
#define PCI_DEVICE_ID_IBM_GXT4500P 0x21c
+#define PCI_DEVICE_ID_IBM_GXT6000P 0x170
/* GXT4500P registers */
@@ -94,6 +96,7 @@ static const unsigned char pixsize[] = {
#define PLL_M 0x4040
#define PLL_N 0x4044
#define PLL_POSTDIV 0x4048
+#define PLL_C 0x404c
/* Hardware cursor */
#define CURSOR_X 0x4078
@@ -140,6 +143,7 @@ struct gxt4500_par {
int pixfmt; /* pixel format, see DFA_PIX_* values */
/* PLL parameters */
+ int refclk_ps; /* ref clock period in picoseconds */
int pll_m; /* ref clock divisor */
int pll_n; /* VCO divisor */
int pll_pd1; /* first post-divisor */
@@ -166,6 +170,21 @@ static const struct fb_videomode defaultmode __devinitdata = {
.vmode = FB_VMODE_NONINTERLACED
};
+/* List of supported cards */
+enum gxt_cards {
+ GXT4500P,
+ GXT6000P
+};
+
+/* Card-specific information */
+static const struct cardinfo {
+ int refclk_ps; /* period of PLL reference clock in ps */
+ const char *cardname;
+} cardinfo[] = {
+ [GXT4500P] = { .refclk_ps = 9259, .cardname = "IBM GXT4500P" },
+ [GXT6000P] = { .refclk_ps = 40000, .cardname = "IBM GXT6000P" },
+};
+
/*
* The refclk and VCO dividers appear to use a linear feedback shift
* register, which gets reloaded when it reaches a terminal value, at
@@ -203,27 +222,16 @@ static const unsigned char ndivtab[] = {
/* 130 */ 0x9e, 0x4f, 0x27, 0x93, 0xc9, 0xe4, 0x72, 0x39, 0x1c, 0x0e,
/* 140 */ 0x87, 0xc3, 0x61, 0x30, 0x18, 0x8c, 0xc6, 0x63, 0x31, 0x98,
/* 150 */ 0xcc, 0xe6, 0x73, 0xb9, 0x5c, 0x2e, 0x97, 0x4b, 0xa5, 0xd2,
-/* 160 */ 0x69, 0xb4, 0xda, 0xed, 0x76, 0xbb, 0x5d, 0xae, 0xd7, 0x6b,
-/* 170 */ 0xb5, 0x5a, 0xad, 0x56, 0xab, 0xd5, 0x6a, 0x35, 0x1a, 0x8d,
-/* 180 */ 0x46, 0x23, 0x11, 0x88, 0x44, 0x22, 0x91, 0xc8, 0x64, 0x32,
-/* 190 */ 0x19, 0x0c, 0x86, 0x43, 0x21, 0x10, 0x08, 0x04, 0x02, 0x81,
-/* 200 */ 0x40, 0xa0, 0xd0, 0x68, 0x34, 0x9a, 0xcd, 0x66, 0x33, 0x99,
-/* 210 */ 0x4c, 0xa6, 0x53, 0xa9, 0xd4, 0xea, 0x75, 0x3a, 0x9d, 0xce,
-/* 220 */ 0xe7, 0xf3, 0xf9, 0x7c, 0x3e, 0x1f, 0x8f, 0x47, 0xa3, 0x51,
-/* 230 */ 0xa8, 0x54, 0xaa, 0x55, 0x2a, 0x15, 0x0a, 0x05, 0x82, 0xc1,
-/* 240 */ 0x60, 0xb0, 0x58, 0xac, 0xd6, 0xeb, 0xf5, 0x7a, 0xbd, 0xde,
-/* 250 */ 0x6f, 0x37, 0x1b, 0x0d, 0x06, 0x03, 0x01,
+/* 160 */ 0x69,
};
-#define REF_PERIOD_PS 9259 /* period of reference clock in ps */
-
static int calc_pll(int period_ps, struct gxt4500_par *par)
{
int m, n, pdiv1, pdiv2, postdiv;
- int pll_period, best_error, t;
+ int pll_period, best_error, t, intf;
- /* only deal with range 1MHz - 400MHz */
- if (period_ps < 2500 || period_ps > 1000000)
+ /* only deal with range 5MHz - 300MHz */
+ if (period_ps < 3333 || period_ps > 200000)
return -1;
best_error = 1000000;
@@ -231,14 +239,17 @@ static int calc_pll(int period_ps, struct gxt4500_par *par)
for (pdiv2 = 1; pdiv2 <= pdiv1; ++pdiv2) {
postdiv = pdiv1 * pdiv2;
pll_period = (period_ps + postdiv - 1) / postdiv;
- /* keep pll in range 500..1250 MHz */
- if (pll_period < 800 || pll_period > 2000)
+ /* keep pll in range 350..600 MHz */
+ if (pll_period < 1666 || pll_period > 2857)
continue;
- for (m = 3; m <= 40; ++m) {
- n = REF_PERIOD_PS * m * postdiv / period_ps;
- if (n < 5 || n > 256)
+ for (m = 1; m <= 64; ++m) {
+ intf = m * par->refclk_ps;
+ if (intf > 500000)
+ break;
+ n = intf * postdiv / period_ps;
+ if (n < 3 || n > 160)
continue;
- t = REF_PERIOD_PS * m * postdiv / n;
+ t = par->refclk_ps * m * postdiv / n;
t -= period_ps;
if (t >= 0 && t < best_error) {
par->pll_m = m;
@@ -257,7 +268,7 @@ static int calc_pll(int period_ps, struct gxt4500_par *par)
static int calc_pixclock(struct gxt4500_par *par)
{
- return REF_PERIOD_PS * par->pll_m * par->pll_pd1 * par->pll_pd2
+ return par->refclk_ps * par->pll_m * par->pll_pd1 * par->pll_pd2
/ par->pll_n;
}
@@ -357,7 +368,7 @@ static int gxt4500_set_par(struct fb_info *info)
struct gxt4500_par *par = info->par;
struct fb_var_screeninfo *var = &info->var;
int err;
- u32 ctrlreg;
+ u32 ctrlreg, tmp;
unsigned int dfa_ctl, pixfmt, stride;
unsigned int wid_tiles, i;
unsigned int prefetch_pix, htot;
@@ -376,10 +387,25 @@ static int gxt4500_set_par(struct fb_info *info)
writereg(par, DTG_CONTROL, ctrlreg);
/* set PLL registers */
+ tmp = readreg(par, PLL_C) & ~0x7f;
+ if (par->pll_n < 38)
+ tmp |= 0x29;
+ if (par->pll_n < 69)
+ tmp |= 0x35;
+ else if (par->pll_n < 100)
+ tmp |= 0x76;
+ else
+ tmp |= 0x7e;
+ writereg(par, PLL_C, tmp);
writereg(par, PLL_M, mdivtab[par->pll_m - 1]);
writereg(par, PLL_N, ndivtab[par->pll_n - 2]);
- writereg(par, PLL_POSTDIV,
- ((8 - par->pll_pd1) << 3) | (8 - par->pll_pd2));
+ tmp = ((8 - par->pll_pd2) << 3) | (8 - par->pll_pd1);
+ if (par->pll_pd1 == 8 || par->pll_pd2 == 8) {
+ /* work around erratum */
+ writereg(par, PLL_POSTDIV, tmp | 0x9);
+ udelay(1);
+ }
+ writereg(par, PLL_POSTDIV, tmp);
msleep(20);
/* turn off hardware cursor */
@@ -483,8 +509,8 @@ static int gxt4500_setcolreg(unsigned int reg, unsigned int red,
if (reg > 1023)
return 1;
- cmap_entry = ((transp & 0xff00) << 16) | ((blue & 0xff00) << 8) |
- (green & 0xff00) | (red >> 8);
+ cmap_entry = ((transp & 0xff00) << 16) | ((red & 0xff00) << 8) |
+ (green & 0xff00) | (blue >> 8);
writereg(par, CMAP + reg * 4, cmap_entry);
if (reg < 16 && par->pixfmt != DFA_PIX_8BIT) {
@@ -585,6 +611,7 @@ static int __devinit gxt4500_probe(struct pci_dev *pdev,
struct gxt4500_par *par;
struct fb_info *info;
struct fb_var_screeninfo var;
+ enum gxt_cards cardtype;
err = pci_enable_device(pdev);
if (err) {
@@ -613,7 +640,11 @@ static int __devinit gxt4500_probe(struct pci_dev *pdev,
goto err_free_fb;
}
par = info->par;
+ cardtype = ent->driver_data;
+ par->refclk_ps = cardinfo[cardtype].refclk_ps;
info->fix = gxt4500_fix;
+ strlcpy(info->fix.id, cardinfo[cardtype].cardname,
+ sizeof(info->fix.id));
info->pseudo_palette = par->pseudo_palette;
info->fix.mmio_start = reg_phys;
@@ -703,8 +734,10 @@ static void __devexit gxt4500_remove(struct pci_dev *pdev)
/* supported chipsets */
static const struct pci_device_id gxt4500_pci_tbl[] = {
- { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_GXT4500P,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+ { PCI_DEVICE(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_GXT4500P),
+ .driver_data = GXT4500P },
+ { PCI_DEVICE(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_GXT6000P),
+ .driver_data = GXT6000P },
{ 0 }
};
@@ -735,7 +768,7 @@ static void __exit gxt4500_exit(void)
module_exit(gxt4500_exit);
MODULE_AUTHOR("Paul Mackerras <paulus@samba.org>");
-MODULE_DESCRIPTION("FBDev driver for IBM GXT4500P");
+MODULE_DESCRIPTION("FBDev driver for IBM GXT4500P/6000P");
MODULE_LICENSE("GPL");
module_param(mode_option, charp, 0);
MODULE_PARM_DESC(mode_option, "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\"");
diff --git a/drivers/video/leo.c b/drivers/video/leo.c
index f3a24338d9ac..a038aa5a9e1c 100644
--- a/drivers/video/leo.c
+++ b/drivers/video/leo.c
@@ -530,20 +530,21 @@ struct all_info {
struct leo_par par;
};
-static void leo_unmap_regs(struct all_info *all)
+static void leo_unmap_regs(struct of_device *op, struct all_info *all)
{
if (all->par.lc_ss0_usr)
- of_iounmap(all->par.lc_ss0_usr, 0x1000);
+ of_iounmap(&op->resource[0], all->par.lc_ss0_usr, 0x1000);
if (all->par.ld_ss0)
- of_iounmap(all->par.ld_ss0, 0x1000);
+ of_iounmap(&op->resource[0], all->par.ld_ss0, 0x1000);
if (all->par.ld_ss1)
- of_iounmap(all->par.ld_ss1, 0x1000);
+ of_iounmap(&op->resource[0], all->par.ld_ss1, 0x1000);
if (all->par.lx_krn)
- of_iounmap(all->par.lx_krn, 0x1000);
+ of_iounmap(&op->resource[0], all->par.lx_krn, 0x1000);
if (all->par.cursor)
- of_iounmap(all->par.cursor, sizeof(struct leo_cursor));
+ of_iounmap(&op->resource[0],
+ all->par.cursor, sizeof(struct leo_cursor));
if (all->info.screen_base)
- of_iounmap(all->info.screen_base, 0x800000);
+ of_iounmap(&op->resource[0], all->info.screen_base, 0x800000);
}
static int __devinit leo_init_one(struct of_device *op)
@@ -592,7 +593,7 @@ static int __devinit leo_init_one(struct of_device *op)
!all->par.lx_krn ||
!all->par.cursor ||
!all->info.screen_base) {
- leo_unmap_regs(all);
+ leo_unmap_regs(op, all);
kfree(all);
return -ENOMEM;
}
@@ -607,7 +608,7 @@ static int __devinit leo_init_one(struct of_device *op)
leo_blank(0, &all->info);
if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
- leo_unmap_regs(all);
+ leo_unmap_regs(op, all);
kfree(all);
return -ENOMEM;;
}
@@ -617,7 +618,7 @@ static int __devinit leo_init_one(struct of_device *op)
err = register_framebuffer(&all->info);
if (err < 0) {
fb_dealloc_cmap(&all->info.cmap);
- leo_unmap_regs(all);
+ leo_unmap_regs(op, all);
kfree(all);
return err;
}
@@ -638,18 +639,18 @@ static int __devinit leo_probe(struct of_device *dev, const struct of_device_id
return leo_init_one(op);
}
-static int __devexit leo_remove(struct of_device *dev)
+static int __devexit leo_remove(struct of_device *op)
{
- struct all_info *all = dev_get_drvdata(&dev->dev);
+ struct all_info *all = dev_get_drvdata(&op->dev);
unregister_framebuffer(&all->info);
fb_dealloc_cmap(&all->info.cmap);
- leo_unmap_regs(all);
+ leo_unmap_regs(op, all);
kfree(all);
- dev_set_drvdata(&dev->dev, NULL);
+ dev_set_drvdata(&op->dev, NULL);
return 0;
}
diff --git a/drivers/video/matrox/i2c-matroxfb.c b/drivers/video/matrox/i2c-matroxfb.c
index 797b42305b0f..fe28848e7b52 100644
--- a/drivers/video/matrox/i2c-matroxfb.c
+++ b/drivers/video/matrox/i2c-matroxfb.c
@@ -146,7 +146,7 @@ static void* i2c_matroxfb_probe(struct matrox_fb_info* minfo) {
unsigned long flags;
struct matroxfb_dh_maven_info* m2info;
- m2info = (struct matroxfb_dh_maven_info*)kmalloc(sizeof(*m2info), GFP_KERNEL);
+ m2info = kmalloc(sizeof(*m2info), GFP_KERNEL);
if (!m2info)
return NULL;
diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c
index e9b4115fcad0..cb2aa402ddfd 100644
--- a/drivers/video/matrox/matroxfb_base.c
+++ b/drivers/video/matrox/matroxfb_base.c
@@ -2028,7 +2028,7 @@ static int matroxfb_probe(struct pci_dev* pdev, const struct pci_device_id* dumm
}
#ifdef CONFIG_FB_MATROX_MULTIHEAD
- minfo = (struct matrox_fb_info*)kmalloc(sizeof(*minfo), GFP_KERNEL);
+ minfo = kmalloc(sizeof(*minfo), GFP_KERNEL);
if (!minfo)
return -1;
#else
diff --git a/drivers/video/matrox/matroxfb_crtc2.c b/drivers/video/matrox/matroxfb_crtc2.c
index 27eb4bb4f89f..2c9801090fae 100644
--- a/drivers/video/matrox/matroxfb_crtc2.c
+++ b/drivers/video/matrox/matroxfb_crtc2.c
@@ -694,7 +694,7 @@ static void* matroxfb_crtc2_probe(struct matrox_fb_info* minfo) {
/* hardware is CRTC2 incapable... */
if (!ACCESS_FBINFO(devflags.crtc2))
return NULL;
- m2info = (struct matroxfb_dh_fb_info*)kmalloc(sizeof(*m2info), GFP_KERNEL);
+ m2info = kmalloc(sizeof(*m2info), GFP_KERNEL);
if (!m2info) {
printk(KERN_ERR "matroxfb_crtc2: Not enough memory for CRTC2 control structs\n");
return NULL;
diff --git a/drivers/video/nvidia/nv_backlight.c b/drivers/video/nvidia/nv_backlight.c
index 5b75ae4e9457..df934bd21899 100644
--- a/drivers/video/nvidia/nv_backlight.c
+++ b/drivers/video/nvidia/nv_backlight.c
@@ -141,7 +141,7 @@ void nvidia_bl_init(struct nvidia_par *par)
snprintf(name, sizeof(name), "nvidiabl%d", info->node);
- bd = backlight_device_register(name, par, &nvidia_bl_data);
+ bd = backlight_device_register(name, info->dev, par, &nvidia_bl_data);
if (IS_ERR(bd)) {
info->bl_dev = NULL;
printk(KERN_WARNING "nvidia: Backlight registration failed\n");
diff --git a/drivers/video/p9100.c b/drivers/video/p9100.c
index 56ac51d6a7f3..637b78bb4bf7 100644
--- a/drivers/video/p9100.c
+++ b/drivers/video/p9100.c
@@ -297,7 +297,8 @@ static int __devinit p9100_init_one(struct of_device *op)
all->info.screen_base = of_ioremap(&op->resource[2], 0,
all->par.fbsize, "p9100 ram");
if (!all->info.screen_base) {
- of_iounmap(all->par.regs, sizeof(struct p9100_regs));
+ of_iounmap(&op->resource[0],
+ all->par.regs, sizeof(struct p9100_regs));
kfree(all);
return -ENOMEM;
}
@@ -306,8 +307,10 @@ static int __devinit p9100_init_one(struct of_device *op)
p9100_blank(0, &all->info);
if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
- of_iounmap(all->par.regs, sizeof(struct p9100_regs));
- of_iounmap(all->info.screen_base, all->par.fbsize);
+ of_iounmap(&op->resource[0],
+ all->par.regs, sizeof(struct p9100_regs));
+ of_iounmap(&op->resource[2],
+ all->info.screen_base, all->par.fbsize);
kfree(all);
return -ENOMEM;
}
@@ -317,8 +320,10 @@ static int __devinit p9100_init_one(struct of_device *op)
err = register_framebuffer(&all->info);
if (err < 0) {
fb_dealloc_cmap(&all->info.cmap);
- of_iounmap(all->par.regs, sizeof(struct p9100_regs));
- of_iounmap(all->info.screen_base, all->par.fbsize);
+ of_iounmap(&op->resource[0],
+ all->par.regs, sizeof(struct p9100_regs));
+ of_iounmap(&op->resource[2],
+ all->info.screen_base, all->par.fbsize);
kfree(all);
return err;
}
@@ -340,19 +345,19 @@ static int __devinit p9100_probe(struct of_device *dev, const struct of_device_i
return p9100_init_one(op);
}
-static int __devexit p9100_remove(struct of_device *dev)
+static int __devexit p9100_remove(struct of_device *op)
{
- struct all_info *all = dev_get_drvdata(&dev->dev);
+ struct all_info *all = dev_get_drvdata(&op->dev);
unregister_framebuffer(&all->info);
fb_dealloc_cmap(&all->info.cmap);
- of_iounmap(all->par.regs, sizeof(struct p9100_regs));
- of_iounmap(all->info.screen_base, all->par.fbsize);
+ of_iounmap(&op->resource[0], all->par.regs, sizeof(struct p9100_regs));
+ of_iounmap(&op->resource[2], all->info.screen_base, all->par.fbsize);
kfree(all);
- dev_set_drvdata(&dev->dev, NULL);
+ dev_set_drvdata(&op->dev, NULL);
return 0;
}
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 38eb0b69c2d7..b4947c810706 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -1216,7 +1216,7 @@ static int __init pxafb_parse_options(struct device *dev, char *options)
done:
if (res_specified) {
dev_info(dev, "overriding resolution: %dx%d\n", xres, yres);
- inf->xres = xres; inf->yres = yres;
+ inf->modes[0].xres = xres; inf->modes[0].yres = yres;
}
if (bpp_specified)
switch (bpp) {
@@ -1225,48 +1225,48 @@ static int __init pxafb_parse_options(struct device *dev, char *options)
case 4:
case 8:
case 16:
- inf->bpp = bpp;
+ inf->modes[0].bpp = bpp;
dev_info(dev, "overriding bit depth: %d\n", bpp);
break;
default:
dev_err(dev, "Depth %d is not valid\n", bpp);
}
} else if (!strncmp(this_opt, "pixclock:", 9)) {
- inf->pixclock = simple_strtoul(this_opt+9, NULL, 0);
- dev_info(dev, "override pixclock: %ld\n", inf->pixclock);
+ inf->modes[0].pixclock = simple_strtoul(this_opt+9, NULL, 0);
+ dev_info(dev, "override pixclock: %ld\n", inf->modes[0].pixclock);
} else if (!strncmp(this_opt, "left:", 5)) {
- inf->left_margin = simple_strtoul(this_opt+5, NULL, 0);
- dev_info(dev, "override left: %u\n", inf->left_margin);
+ inf->modes[0].left_margin = simple_strtoul(this_opt+5, NULL, 0);
+ dev_info(dev, "override left: %u\n", inf->modes[0].left_margin);
} else if (!strncmp(this_opt, "right:", 6)) {
- inf->right_margin = simple_strtoul(this_opt+6, NULL, 0);
- dev_info(dev, "override right: %u\n", inf->right_margin);
+ inf->modes[0].right_margin = simple_strtoul(this_opt+6, NULL, 0);
+ dev_info(dev, "override right: %u\n", inf->modes[0].right_margin);
} else if (!strncmp(this_opt, "upper:", 6)) {
- inf->upper_margin = simple_strtoul(this_opt+6, NULL, 0);
- dev_info(dev, "override upper: %u\n", inf->upper_margin);
+ inf->modes[0].upper_margin = simple_strtoul(this_opt+6, NULL, 0);
+ dev_info(dev, "override upper: %u\n", inf->modes[0].upper_margin);
} else if (!strncmp(this_opt, "lower:", 6)) {
- inf->lower_margin = simple_strtoul(this_opt+6, NULL, 0);
- dev_info(dev, "override lower: %u\n", inf->lower_margin);
+ inf->modes[0].lower_margin = simple_strtoul(this_opt+6, NULL, 0);
+ dev_info(dev, "override lower: %u\n", inf->modes[0].lower_margin);
} else if (!strncmp(this_opt, "hsynclen:", 9)) {
- inf->hsync_len = simple_strtoul(this_opt+9, NULL, 0);
- dev_info(dev, "override hsynclen: %u\n", inf->hsync_len);
+ inf->modes[0].hsync_len = simple_strtoul(this_opt+9, NULL, 0);
+ dev_info(dev, "override hsynclen: %u\n", inf->modes[0].hsync_len);
} else if (!strncmp(this_opt, "vsynclen:", 9)) {
- inf->vsync_len = simple_strtoul(this_opt+9, NULL, 0);
- dev_info(dev, "override vsynclen: %u\n", inf->vsync_len);
+ inf->modes[0].vsync_len = simple_strtoul(this_opt+9, NULL, 0);
+ dev_info(dev, "override vsynclen: %u\n", inf->modes[0].vsync_len);
} else if (!strncmp(this_opt, "hsync:", 6)) {
if (simple_strtoul(this_opt+6, NULL, 0) == 0) {
dev_info(dev, "override hsync: Active Low\n");
- inf->sync &= ~FB_SYNC_HOR_HIGH_ACT;
+ inf->modes[0].sync &= ~FB_SYNC_HOR_HIGH_ACT;
} else {
dev_info(dev, "override hsync: Active High\n");
- inf->sync |= FB_SYNC_HOR_HIGH_ACT;
+ inf->modes[0].sync |= FB_SYNC_HOR_HIGH_ACT;
}
} else if (!strncmp(this_opt, "vsync:", 6)) {
if (simple_strtoul(this_opt+6, NULL, 0) == 0) {
dev_info(dev, "override vsync: Active Low\n");
- inf->sync &= ~FB_SYNC_VERT_HIGH_ACT;
+ inf->modes[0].sync &= ~FB_SYNC_VERT_HIGH_ACT;
} else {
dev_info(dev, "override vsync: Active High\n");
- inf->sync |= FB_SYNC_VERT_HIGH_ACT;
+ inf->modes[0].sync |= FB_SYNC_VERT_HIGH_ACT;
}
} else if (!strncmp(this_opt, "dpc:", 4)) {
if (simple_strtoul(this_opt+4, NULL, 0) == 0) {
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c
index 345e8b1c1af8..1a13966b7d5b 100644
--- a/drivers/video/riva/fbdev.c
+++ b/drivers/video/riva/fbdev.c
@@ -384,7 +384,7 @@ static void riva_bl_init(struct riva_par *par)
snprintf(name, sizeof(name), "rivabl%d", info->node);
- bd = backlight_device_register(name, par, &riva_bl_data);
+ bd = backlight_device_register(name, info->dev, par, &riva_bl_data);
if (IS_ERR(bd)) {
info->bl_dev = NULL;
printk(KERN_WARNING "riva: Backlight registration failed\n");
diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c
index cd10b18150b8..5d2a4a4b731c 100644
--- a/drivers/video/sa1100fb.c
+++ b/drivers/video/sa1100fb.c
@@ -1200,9 +1200,9 @@ static void set_ctrlr_state(struct sa1100fb_info *fbi, u_int state)
* Our LCD controller task (which is called when we blank or unblank)
* via keventd.
*/
-static void sa1100fb_task(void *dummy)
+static void sa1100fb_task(struct work_struct *w)
{
- struct sa1100fb_info *fbi = dummy;
+ struct sa1100fb_info *fbi = container_of(w, struct sa1100fb_info, task);
u_int state = xchg(&fbi->task_state, -1);
set_ctrlr_state(fbi, state);
@@ -1444,7 +1444,7 @@ static struct sa1100fb_info * __init sa1100fb_init_fbinfo(struct device *dev)
fbi->max_bpp / 8;
init_waitqueue_head(&fbi->ctrlr_wait);
- INIT_WORK(&fbi->task, sa1100fb_task, fbi);
+ INIT_WORK(&fbi->task, sa1100fb_task);
init_MUTEX(&fbi->ctrlr_sem);
return fbi;
diff --git a/drivers/video/sstfb.c b/drivers/video/sstfb.c
index 711cb11d6eb3..59cd1e750f30 100644
--- a/drivers/video/sstfb.c
+++ b/drivers/video/sstfb.c
@@ -21,6 +21,11 @@
* Remove never finished and bogus 24/32bit support
* Clean up macro abuse
* Minor tidying for format.
+ * 12/2006 Helge Deller <deller@gmx.de>
+ * add /sys/class/graphics/fbX/vgapass sysfs-interface
+ * add module option "mode_option" to set initial screen mode
+ * use fbdev default videomode database
+ * remove debug functions from ioctl
*/
/*
@@ -65,19 +70,10 @@
*
* sstfb specific ioctls:
* toggle vga (0x46db) : toggle vga_pass_through
- * fill fb (0x46dc) : fills fb
- * test disp (0x46de) : draws a test image
*/
#undef SST_DEBUG
-/*
- Default video mode .
- 0 800x600@60 took from glide
- 1 640x480@75 took from glide
- 2 1024x768@76 std fb.mode
- 3 640x480@60 glide default */
-#define DEFAULT_MODE 3
/*
* Includes
@@ -92,20 +88,24 @@
#include <linux/init.h>
#include <linux/slab.h>
#include <asm/io.h>
-#include <asm/ioctl.h>
#include <asm/uaccess.h>
#include <video/sstfb.h>
/* initialized by setup */
-static int vgapass; /* enable Vga passthrough cable */
+static int vgapass; /* enable VGA passthrough cable */
static int mem; /* mem size in MB, 0 = autodetect */
static int clipping = 1; /* use clipping (slower, safer) */
static int gfxclk; /* force FBI freq in Mhz . Dangerous */
static int slowpci; /* slow PCI settings */
-static char *mode_option __devinitdata;
+/*
+ Possible default video modes: 800x600@60, 640x480@75, 1024x768@76, 640x480@60
+*/
+#define DEFAULT_VIDEO_MODE "640x480@60"
+
+static char *mode_option __devinitdata = DEFAULT_VIDEO_MODE;
enum {
ID_VOODOO1 = 0,
@@ -119,48 +119,11 @@ static struct sst_spec voodoo_spec[] __devinitdata = {
{ .name = "Voodoo2", .default_gfx_clock = 75000, .max_gfxclk = 85 },
};
-static struct fb_var_screeninfo sstfb_default =
-#if ( DEFAULT_MODE == 0 )
- { /* 800x600@60, 16 bpp .borowed from glide/sst1/include/sst1init.h */
- 800, 600, 800, 600, 0, 0, 16, 0,
- {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
- 0, 0, -1, -1, 0,
- 25000, 86, 41, 23, 1, 127, 4,
- 0, FB_VMODE_NONINTERLACED };
-#elif ( DEFAULT_MODE == 1 )
- {/* 640x480@75, 16 bpp .borowed from glide/sst1/include/sst1init.h */
- 640, 480, 640, 480, 0, 0, 16, 0,
- {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
- 0, 0, -1, -1, 0,
- 31746, 118, 17, 16, 1, 63, 3,
- 0, FB_VMODE_NONINTERLACED };
-#elif ( DEFAULT_MODE == 2 )
- { /* 1024x768@76 took from my /etc/fb.modes */
- 1024, 768, 1024, 768,0, 0, 16,0,
- {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
- 0, 0, -1, -1, 0,
- 11764, 208, 8, 36, 16, 120, 3 ,
- 0, FB_VMODE_NONINTERLACED };
-#elif ( DEFAULT_MODE == 3 )
- { /* 640x480@60 , 16bpp glide default ?*/
- 640, 480, 640, 480, 0, 0, 16, 0,
- {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
- 0, 0, -1, -1, 0,
- 39721 , 38, 26 , 25 ,18 , 96 ,2,
- 0, FB_VMODE_NONINTERLACED };
-#elif
- #error "Invalid DEFAULT_MODE value !"
-#endif
-
/*
* debug functions
*/
-static void sstfb_drawdebugimage(struct fb_info *info);
-static int sstfb_dump_regs(struct fb_info *info);
-
-
#if (SST_DEBUG_REG > 0)
static void sst_dbg_print_read_reg(u32 reg, u32 val) {
const char *regname;
@@ -726,51 +689,77 @@ static int sstfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
return 0;
}
-static int sstfb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
+static void sstfb_setvgapass( struct fb_info *info, int enable )
{
struct sstfb_par *par = info->par;
struct pci_dev *sst_dev = par->dev;
- u32 fbiinit0, tmp, val;
- u_long p;
+ u32 fbiinit0, tmp;
+
+ enable = enable ? 1:0;
+ if (par->vgapass == enable)
+ return;
+ par->vgapass = enable;
+
+ pci_read_config_dword(sst_dev, PCI_INIT_ENABLE, &tmp);
+ pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
+ tmp | PCI_EN_INIT_WR );
+ fbiinit0 = sst_read (FBIINIT0);
+ if (par->vgapass) {
+ sst_write(FBIINIT0, fbiinit0 & ~DIS_VGA_PASSTHROUGH);
+ printk(KERN_INFO "fb%d: Enabling VGA pass-through\n", info->node );
+ } else {
+ sst_write(FBIINIT0, fbiinit0 | DIS_VGA_PASSTHROUGH);
+ printk(KERN_INFO "fb%d: Disabling VGA pass-through\n", info->node );
+ }
+ pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, tmp);
+}
+
+static ssize_t store_vgapass(struct device *device, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct fb_info *info = dev_get_drvdata(device);
+ char ** last = NULL;
+ int val;
+
+ val = simple_strtoul(buf, last, 0);
+ sstfb_setvgapass(info, val);
+
+ return count;
+}
+
+static ssize_t show_vgapass(struct device *device, struct device_attribute *attr,
+ char *buf)
+{
+ struct fb_info *info = dev_get_drvdata(device);
+ struct sstfb_par *par = info->par;
+ return snprintf(buf, PAGE_SIZE, "%d\n", par->vgapass);
+}
+
+static struct device_attribute device_attrs[] = {
+ __ATTR(vgapass, S_IRUGO|S_IWUSR, show_vgapass, store_vgapass)
+ };
+
+static int sstfb_ioctl(struct fb_info *info, unsigned int cmd,
+ unsigned long arg)
+{
+ struct sstfb_par *par;
+ u32 val;
switch (cmd) {
-
- /* dump current FBIINIT values to system log */
- case _IO('F', 0xdb): /* 0x46db */
- return sstfb_dump_regs(info);
-
- /* fills lfb with #arg pixels */
- case _IOW('F', 0xdc, u32): /* 0x46dc */
+ /* set/get VGA pass_through mode */
+ case SSTFB_SET_VGAPASS:
if (copy_from_user(&val, (void __user *)arg, sizeof(val)))
return -EFAULT;
- if (val > info->fix.smem_len)
- val = info->fix.smem_len;
- for (p = 0 ; p < val; p += 2)
- writew(p >> 6, info->screen_base + p);
+ sstfb_setvgapass(info, val);
return 0;
-
- /* change VGA pass_through mode */
- case _IOW('F', 0xdd, u32): /* 0x46dd */
- if (copy_from_user(&val, (void __user *)arg, sizeof(val)))
+ case SSTFB_GET_VGAPASS:
+ par = info->par;
+ val = par->vgapass;
+ if (copy_to_user((void __user *)arg, &val, sizeof(val)))
return -EFAULT;
- pci_read_config_dword(sst_dev, PCI_INIT_ENABLE, &tmp);
- pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
- tmp | PCI_EN_INIT_WR );
- fbiinit0 = sst_read (FBIINIT0);
- if (val)
- sst_write(FBIINIT0, fbiinit0 & ~EN_VGA_PASSTHROUGH);
- else
- sst_write(FBIINIT0, fbiinit0 | EN_VGA_PASSTHROUGH);
- pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, tmp);
- return 0;
-
- /* draw test image */
- case _IO('F', 0xde): /* 0x46de */
- f_dprintk("test color display at %d bpp\n",
- info->var.bits_per_pixel);
- sstfb_drawdebugimage(info);
return 0;
}
+
return -EINVAL;
}
@@ -804,6 +793,7 @@ static void sstfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
/*
* FillRect 2D command (solidfill or invert (via ROP_XOR)) - Voodoo2 only
*/
+#if 0
static void sstfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
{
struct sstfb_par *par = info->par;
@@ -825,6 +815,7 @@ static void sstfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
| (BLT_16BPP_FMT << 3) /* | BIT(14) */ | BIT(15) | BIT(16) );
sst_wait_idle();
}
+#endif
@@ -1156,6 +1147,7 @@ static int __devinit sst_init(struct fb_info *info, struct sstfb_par *par)
struct pll_timing gfx_timings;
struct sst_spec *spec;
int Fout;
+ int gfx_clock;
spec = &voodoo_spec[par->type];
f_ddprintk(" fbiinit0 fbiinit1 fbiinit2 fbiinit3 fbiinit4 "
@@ -1196,15 +1188,15 @@ static int __devinit sst_init(struct fb_info *info, struct sstfb_par *par)
}
/* set graphic clock */
- par->gfx_clock = spec->default_gfx_clock;
+ gfx_clock = spec->default_gfx_clock;
if ((gfxclk >10 ) && (gfxclk < spec->max_gfxclk)) {
printk(KERN_INFO "sstfb: Using supplied graphic freq : %dMHz\n", gfxclk);
- par->gfx_clock = gfxclk *1000;
+ gfx_clock = gfxclk *1000;
} else if (gfxclk) {
printk(KERN_WARNING "sstfb: %dMhz is way out of spec! Using default\n", gfxclk);
}
- sst_calc_pll(par->gfx_clock, &Fout, &gfx_timings);
+ sst_calc_pll(gfx_clock, &Fout, &gfx_timings);
par->dac_sw.set_pll(info, &gfx_timings, GFX_CLOCK);
/* disable fbiinit remap */
@@ -1215,10 +1207,11 @@ static int __devinit sst_init(struct fb_info *info, struct sstfb_par *par)
fbiinit0 = FBIINIT0_DEFAULT;
fbiinit1 = FBIINIT1_DEFAULT;
fbiinit4 = FBIINIT4_DEFAULT;
- if (vgapass)
- fbiinit0 &= ~EN_VGA_PASSTHROUGH;
+ par->vgapass = vgapass;
+ if (par->vgapass)
+ fbiinit0 &= ~DIS_VGA_PASSTHROUGH;
else
- fbiinit0 |= EN_VGA_PASSTHROUGH;
+ fbiinit0 |= DIS_VGA_PASSTHROUGH;
if (slowpci) {
fbiinit1 |= SLOW_PCI_WRITES;
fbiinit4 |= SLOW_PCI_READS;
@@ -1267,7 +1260,7 @@ static void __devexit sst_shutdown(struct fb_info *info)
/* TODO maybe shutdown the dac, vrefresh and so on... */
pci_write_config_dword(dev, PCI_INIT_ENABLE,
PCI_EN_INIT_WR);
- sst_unset_bits(FBIINIT0, FBI_RESET | FIFO_RESET | EN_VGA_PASSTHROUGH);
+ sst_unset_bits(FBIINIT0, FBI_RESET | FIFO_RESET | DIS_VGA_PASSTHROUGH);
pci_write_config_dword(dev, PCI_VCLK_DISABLE,0);
/* maybe keep fbiinit* and PCI_INIT_enable in the fb_info struct
* from start ? */
@@ -1278,8 +1271,7 @@ static void __devexit sst_shutdown(struct fb_info *info)
/*
* Interface to the world
*/
-#ifndef MODULE
-static int __init sstfb_setup(char *options)
+static int __devinit sstfb_setup(char *options)
{
char *this_opt;
@@ -1312,7 +1304,7 @@ static int __init sstfb_setup(char *options)
}
return 0;
}
-#endif
+
static struct fb_ops sstfb_ops = {
.owner = THIS_MODULE,
@@ -1416,15 +1408,10 @@ static int __devinit sstfb_probe(struct pci_dev *pdev,
*/
fix->line_length = 2048; /* default value, for 24 or 32bit: 4096 */
- if ( mode_option &&
- fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 16)) {
- printk(KERN_ERR "sstfb: can't set supplied video mode. Using default\n");
- info->var = sstfb_default;
- } else
- info->var = sstfb_default;
+ fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 16);
if (sstfb_check_var(&info->var, info)) {
- printk(KERN_ERR "sstfb: invalid default video mode.\n");
+ printk(KERN_ERR "sstfb: invalid video mode.\n");
goto fail;
}
@@ -1442,10 +1429,11 @@ static int __devinit sstfb_probe(struct pci_dev *pdev,
goto fail;
}
- if (1) /* set to 0 to see an initial bitmap instead */
- sstfb_clear_screen(info);
- else
- sstfb_drawdebugimage(info);
+ sstfb_clear_screen(info);
+
+ if (device_create_file(info->dev, &device_attrs[0]))
+ printk(KERN_WARNING "sstfb: can't create sysfs entry.\n");
+
printk(KERN_INFO "fb%d: %s frame buffer device at 0x%p\n",
info->node, fix->id, info->screen_base);
@@ -1453,6 +1441,7 @@ static int __devinit sstfb_probe(struct pci_dev *pdev,
return 0;
fail:
+ fb_dealloc_cmap(&info->cmap);
iounmap(info->screen_base);
fail_fb_remap:
iounmap(par->mmio_vbase);
@@ -1473,21 +1462,23 @@ static void __devexit sstfb_remove(struct pci_dev *pdev)
info = pci_get_drvdata(pdev);
par = info->par;
+ device_remove_file(info->dev, &device_attrs[0]);
sst_shutdown(info);
- unregister_framebuffer(info);
iounmap(info->screen_base);
iounmap(par->mmio_vbase);
release_mem_region(info->fix.smem_start, 0x400000);
release_mem_region(info->fix.mmio_start, info->fix.mmio_len);
+ fb_dealloc_cmap(&info->cmap);
+ unregister_framebuffer(info);
framebuffer_release(info);
}
-static struct pci_device_id sstfb_id_tbl[] = {
- { PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_VOODOO1 },
- { PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO2,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_VOODOO2 },
+static const struct pci_device_id sstfb_id_tbl[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO ),
+ .driver_data = ID_VOODOO1, },
+ { PCI_DEVICE(PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO2),
+ .driver_data = ID_VOODOO2, },
{ 0 },
};
@@ -1501,142 +1492,23 @@ static struct pci_driver sstfb_driver = {
static int __devinit sstfb_init(void)
{
-#ifndef MODULE
char *option = NULL;
if (fb_get_options("sstfb", &option))
return -ENODEV;
sstfb_setup(option);
-#endif
+
return pci_register_driver(&sstfb_driver);
}
-#ifdef MODULE
static void __devexit sstfb_exit(void)
{
pci_unregister_driver(&sstfb_driver);
}
-#endif
-/*
- * testing and debugging functions
- */
-
-static int sstfb_dump_regs(struct fb_info *info)
-{
-#ifdef SST_DEBUG
- static struct { u32 reg ; const char *reg_name;} pci_regs[] = {
- { PCI_INIT_ENABLE, "initenable"},
- { PCI_VCLK_ENABLE, "enable vclk"},
- { PCI_VCLK_DISABLE, "disable vclk"},
- };
-
- static struct { u32 reg ; const char *reg_name;} sst_regs[] = {
- {FBIINIT0,"fbiinit0"},
- {FBIINIT1,"fbiinit1"},
- {FBIINIT2,"fbiinit2"},
- {FBIINIT3,"fbiinit3"},
- {FBIINIT4,"fbiinit4"},
- {FBIINIT5,"fbiinit5"},
- {FBIINIT6,"fbiinit6"},
- {FBIINIT7,"fbiinit7"},
- {LFBMODE,"lfbmode"},
- {FBZMODE,"fbzmode"},
- };
-
- const int pci_s = ARRAY_SIZE(pci_regs);
- const int sst_s = ARRAY_SIZE(sst_regs);
- struct sstfb_par *par = info->par;
- struct pci_dev *dev = par->dev;
- u32 pci_res[pci_s];
- u32 sst_res[sst_s];
- int i;
-
- for (i=0; i<pci_s; i++) {
- pci_read_config_dword(dev, pci_regs[i].reg, &pci_res[i]);
- }
- for (i=0; i<sst_s; i++) {
- sst_res[i] = sst_read(sst_regs[i].reg);
- }
-
- dprintk("hardware register dump:\n");
- for (i=0; i<pci_s; i++) {
- dprintk("%s %0#10x\n", pci_regs[i].reg_name, pci_res[i]);
- }
- for (i=0; i<sst_s; i++) {
- dprintk("%s %0#10x\n", sst_regs[i].reg_name, sst_res[i]);
- }
- return 0;
-#else
- return -EINVAL;
-#endif
-}
-
-static void sstfb_fillrect_softw( struct fb_info *info, const struct fb_fillrect *rect)
-{
- u8 __iomem *fbbase_virt = info->screen_base;
- int x, y, w = info->var.bits_per_pixel == 16 ? 2 : 4;
- u32 color = rect->color, height = rect->height;
- u8 __iomem *p;
-
- if (w==2) color |= color<<16;
- for (y=rect->dy; height; y++, height--) {
- p = fbbase_virt + y*info->fix.line_length + rect->dx*w;
- x = rect->width;
- if (w==2) x>>=1;
- while (x) {
- writel(color, p);
- p += 4;
- x--;
- }
- }
-}
-
-static void sstfb_drawrect_XY( struct fb_info *info, int x, int y,
- int w, int h, int color, int hwfunc)
-{
- struct fb_fillrect rect;
- rect.dx = x;
- rect.dy = y;
- rect.height = h;
- rect.width = w;
- rect.color = color;
- rect.rop = ROP_COPY;
- if (hwfunc)
- sstfb_fillrect(info, &rect);
- else
- sstfb_fillrect_softw(info, &rect);
-}
-
-/* print some squares on the fb */
-static void sstfb_drawdebugimage(struct fb_info *info)
-{
- static int idx;
-
- /* clear screen */
- sstfb_clear_screen(info);
-
- idx = (idx+1) & 1;
-
- /* white rect */
- sstfb_drawrect_XY(info, 0, 0, 50, 50, 0xffff, idx);
-
- /* blue rect */
- sstfb_drawrect_XY(info, 50, 50, 50, 50, 0x001f, idx);
-
- /* green rect */
- sstfb_drawrect_XY(info, 100, 100, 80, 80, 0x07e0, idx);
-
- /* red rect */
- sstfb_drawrect_XY(info, 250, 250, 120, 100, 0xf800, idx);
-}
-
module_init(sstfb_init);
-
-#ifdef MODULE
module_exit(sstfb_exit);
-#endif
MODULE_AUTHOR("(c) 2000,2002 Ghozlane Toumi <gtoumi@laposte.net>");
MODULE_DESCRIPTION("FBDev driver for 3dfx Voodoo Graphics and Voodoo2 based video boards");
@@ -1652,3 +1524,6 @@ module_param(gfxclk, int, 0);
MODULE_PARM_DESC(gfxclk, "Force graphic chip frequency in MHz. DANGEROUS. (default=auto)");
module_param(slowpci, bool, 0);
MODULE_PARM_DESC(slowpci, "Uses slow PCI settings (0 or 1) (default=0)");
+module_param(mode_option, charp, 0);
+MODULE_PARM_DESC(mode_option, "Initial video mode (default=" DEFAULT_VIDEO_MODE ")");
+
diff --git a/drivers/video/tcx.c b/drivers/video/tcx.c
index 6990ab11cd06..5a99669232ce 100644
--- a/drivers/video/tcx.c
+++ b/drivers/video/tcx.c
@@ -350,18 +350,23 @@ struct all_info {
struct tcx_par par;
};
-static void tcx_unmap_regs(struct all_info *all)
+static void tcx_unmap_regs(struct of_device *op, struct all_info *all)
{
if (all->par.tec)
- of_iounmap(all->par.tec, sizeof(struct tcx_tec));
+ of_iounmap(&op->resource[7],
+ all->par.tec, sizeof(struct tcx_tec));
if (all->par.thc)
- of_iounmap(all->par.thc, sizeof(struct tcx_thc));
+ of_iounmap(&op->resource[9],
+ all->par.thc, sizeof(struct tcx_thc));
if (all->par.bt)
- of_iounmap(all->par.bt, sizeof(struct bt_regs));
+ of_iounmap(&op->resource[8],
+ all->par.bt, sizeof(struct bt_regs));
if (all->par.cplane)
- of_iounmap(all->par.cplane, all->par.fbsize * sizeof(u32));
+ of_iounmap(&op->resource[4],
+ all->par.cplane, all->par.fbsize * sizeof(u32));
if (all->info.screen_base)
- of_iounmap(all->info.screen_base, all->par.fbsize);
+ of_iounmap(&op->resource[0],
+ all->info.screen_base, all->par.fbsize);
}
static int __devinit tcx_init_one(struct of_device *op)
@@ -398,7 +403,7 @@ static int __devinit tcx_init_one(struct of_device *op)
all->par.fbsize, "tcx ram");
if (!all->par.tec || !all->par.thc ||
!all->par.bt || !all->info.screen_base) {
- tcx_unmap_regs(all);
+ tcx_unmap_regs(op, all);
kfree(all);
return -ENOMEM;
}
@@ -409,7 +414,7 @@ static int __devinit tcx_init_one(struct of_device *op)
all->par.fbsize * sizeof(u32),
"tcx cplane");
if (!all->par.cplane) {
- tcx_unmap_regs(all);
+ tcx_unmap_regs(op, all);
kfree(all);
return -ENOMEM;
}
@@ -461,7 +466,7 @@ static int __devinit tcx_init_one(struct of_device *op)
tcx_blank(FB_BLANK_UNBLANK, &all->info);
if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
- tcx_unmap_regs(all);
+ tcx_unmap_regs(op, all);
kfree(all);
return -ENOMEM;
}
@@ -472,7 +477,7 @@ static int __devinit tcx_init_one(struct of_device *op)
err = register_framebuffer(&all->info);
if (err < 0) {
fb_dealloc_cmap(&all->info.cmap);
- tcx_unmap_regs(all);
+ tcx_unmap_regs(op, all);
kfree(all);
return err;
}
@@ -495,18 +500,18 @@ static int __devinit tcx_probe(struct of_device *dev, const struct of_device_id
return tcx_init_one(op);
}
-static int __devexit tcx_remove(struct of_device *dev)
+static int __devexit tcx_remove(struct of_device *op)
{
- struct all_info *all = dev_get_drvdata(&dev->dev);
+ struct all_info *all = dev_get_drvdata(&op->dev);
unregister_framebuffer(&all->info);
fb_dealloc_cmap(&all->info.cmap);
- tcx_unmap_regs(all);
+ tcx_unmap_regs(op, all);
kfree(all);
- dev_set_drvdata(&dev->dev, NULL);
+ dev_set_drvdata(&op->dev, NULL);
return 0;
}
diff --git a/drivers/w1/slaves/Kconfig b/drivers/w1/slaves/Kconfig
index d18d6424cd21..904e5aeb696c 100644
--- a/drivers/w1/slaves/Kconfig
+++ b/drivers/w1/slaves/Kconfig
@@ -9,7 +9,7 @@ config W1_SLAVE_THERM
tristate "Thermal family implementation"
depends on W1
help
- Say Y here if you want to connect 1-wire thermal sensors to you
+ Say Y here if you want to connect 1-wire thermal sensors to your
wire.
config W1_SLAVE_SMEM
@@ -17,7 +17,7 @@ config W1_SLAVE_SMEM
depends on W1
help
Say Y here if you want to connect 1-wire
- simple 64bit memory rom(ds2401/ds2411/ds1990*) to you wire.
+ simple 64bit memory rom(ds2401/ds2411/ds1990*) to your wire.
config W1_SLAVE_DS2433
tristate "4kb EEPROM family support (DS2433)"
diff --git a/fs/Kconfig b/fs/Kconfig
index 276ff3baaafe..8cd2417a14db 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -1198,13 +1198,16 @@ config EFS_FS
config JFFS_FS
tristate "Journalling Flash File System (JFFS) support"
- depends on MTD && BLOCK
+ depends on MTD && BLOCK && BROKEN
help
JFFS is the Journalling Flash File System developed by Axis
Communications in Sweden, aimed at providing a crash/powerdown-safe
file system for disk-less embedded devices. Further information is
available at (<http://developer.axis.com/software/jffs/>).
+ NOTE: This filesystem is deprecated and is scheduled for removal in
+ 2.6.21. See Documentation/feature-removal-schedule.txt
+
config JFFS_FS_VERBOSE
int "JFFS debugging verbosity (0 = quiet, 3 = noisy)"
depends on JFFS_FS
diff --git a/fs/aio.c b/fs/aio.c
index d3a6ec2c9627..ee20fc4240e0 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -586,7 +586,7 @@ static void use_mm(struct mm_struct *mm)
* Note that on UML this *requires* PF_BORROWED_MM to be set, otherwise
* it won't work. Update it accordingly if you change it here
*/
- activate_mm(active_mm, mm);
+ switch_mm(active_mm, mm, tsk);
task_unlock(tsk);
mmdrop(active_mm);
@@ -599,9 +599,6 @@ static void use_mm(struct mm_struct *mm)
* by the calling kernel thread
* (Note: this routine is intended to be called only
* from a kernel thread context)
- *
- * Comments: Called with ctx->ctx_lock held. This nests
- * task_lock instead ctx_lock.
*/
static void unuse_mm(struct mm_struct *mm)
{
@@ -850,14 +847,16 @@ static void aio_kick_handler(struct work_struct *work)
{
struct kioctx *ctx = container_of(work, struct kioctx, wq.work);
mm_segment_t oldfs = get_fs();
+ struct mm_struct *mm;
int requeue;
set_fs(USER_DS);
use_mm(ctx->mm);
spin_lock_irq(&ctx->ctx_lock);
requeue =__aio_run_iocbs(ctx);
- unuse_mm(ctx->mm);
+ mm = ctx->mm;
spin_unlock_irq(&ctx->ctx_lock);
+ unuse_mm(mm);
set_fs(oldfs);
/*
* we're in a worker thread already, don't use queue_delayed_work,
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c
index 9c48250fd726..e8f6c5ad3e90 100644
--- a/fs/autofs4/inode.c
+++ b/fs/autofs4/inode.c
@@ -313,7 +313,7 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)
struct autofs_sb_info *sbi;
struct autofs_info *ino;
- sbi = (struct autofs_sb_info *) kmalloc(sizeof(*sbi), GFP_KERNEL);
+ sbi = kmalloc(sizeof(*sbi), GFP_KERNEL);
if ( !sbi )
goto fail_unlock;
DPRINTK("starting up, sbi = %p",sbi);
diff --git a/fs/befs/btree.c b/fs/befs/btree.c
index 81b042ee24e6..af5bb93276f8 100644
--- a/fs/befs/btree.c
+++ b/fs/befs/btree.c
@@ -260,7 +260,7 @@ befs_btree_find(struct super_block *sb, befs_data_stream * ds,
goto error;
}
- this_node = (befs_btree_node *) kmalloc(sizeof (befs_btree_node),
+ this_node = kmalloc(sizeof (befs_btree_node),
GFP_NOFS);
if (!this_node) {
befs_error(sb, "befs_btree_find() failed to allocate %u "
diff --git a/fs/befs/debug.c b/fs/befs/debug.c
index e831a8f30849..b8e304a0661e 100644
--- a/fs/befs/debug.c
+++ b/fs/befs/debug.c
@@ -28,7 +28,7 @@ void
befs_error(const struct super_block *sb, const char *fmt, ...)
{
va_list args;
- char *err_buf = (char *) kmalloc(ERRBUFSIZE, GFP_KERNEL);
+ char *err_buf = kmalloc(ERRBUFSIZE, GFP_KERNEL);
if (err_buf == NULL) {
printk(KERN_ERR "could not allocate %d bytes\n", ERRBUFSIZE);
return;
@@ -46,7 +46,7 @@ void
befs_warning(const struct super_block *sb, const char *fmt, ...)
{
va_list args;
- char *err_buf = (char *) kmalloc(ERRBUFSIZE, GFP_KERNEL);
+ char *err_buf = kmalloc(ERRBUFSIZE, GFP_KERNEL);
if (err_buf == NULL) {
printk(KERN_ERR "could not allocate %d bytes\n", ERRBUFSIZE);
return;
@@ -70,7 +70,7 @@ befs_debug(const struct super_block *sb, const char *fmt, ...)
char *err_buf = NULL;
if (BEFS_SB(sb)->mount_opts.debug) {
- err_buf = (char *) kmalloc(ERRBUFSIZE, GFP_KERNEL);
+ err_buf = kmalloc(ERRBUFSIZE, GFP_KERNEL);
if (err_buf == NULL) {
printk(KERN_ERR "could not allocate %d bytes\n",
ERRBUFSIZE);
diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c
index eac175ed9f44..134c99941a63 100644
--- a/fs/bfs/inode.c
+++ b/fs/bfs/inode.c
@@ -1,7 +1,7 @@
/*
* fs/bfs/inode.c
* BFS superblock and inode operations.
- * Copyright (C) 1999,2000 Tigran Aivazian <tigran@veritas.com>
+ * Copyright (C) 1999-2006 Tigran Aivazian <tigran@aivazian.fsnet.co.uk>
* From fs/minix, Copyright (C) 1991, 1992 Linus Torvalds.
*
* Made endianness-clean by Andrew Stribblehill <ads@wompom.org>, 2005.
@@ -18,7 +18,7 @@
#include <asm/uaccess.h>
#include "bfs.h"
-MODULE_AUTHOR("Tigran A. Aivazian <tigran@veritas.com>");
+MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>");
MODULE_DESCRIPTION("SCO UnixWare BFS filesystem for Linux");
MODULE_LICENSE("GPL");
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
index 00687ea62738..c2e08252af35 100644
--- a/fs/binfmt_misc.c
+++ b/fs/binfmt_misc.c
@@ -311,7 +311,7 @@ static Node *create_entry(const char __user *buffer, size_t count)
err = -ENOMEM;
memsize = sizeof(Node) + count + 8;
- e = (Node *) kmalloc(memsize, GFP_USER);
+ e = kmalloc(memsize, GFP_USER);
if (!e)
goto out;
diff --git a/fs/bio.c b/fs/bio.c
index 7ec737eda72b..7618bcb18368 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -916,7 +916,7 @@ void bio_set_pages_dirty(struct bio *bio)
}
}
-static void bio_release_pages(struct bio *bio)
+void bio_release_pages(struct bio *bio)
{
struct bio_vec *bvec = bio->bi_io_vec;
int i;
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 197f93921847..1715d6b5f411 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -129,43 +129,191 @@ blkdev_get_block(struct inode *inode, sector_t iblock,
return 0;
}
-static int
-blkdev_get_blocks(struct inode *inode, sector_t iblock,
- struct buffer_head *bh, int create)
+static int blk_end_aio(struct bio *bio, unsigned int bytes_done, int error)
{
- sector_t end_block = max_block(I_BDEV(inode));
- unsigned long max_blocks = bh->b_size >> inode->i_blkbits;
+ struct kiocb *iocb = bio->bi_private;
+ atomic_t *bio_count = &iocb->ki_bio_count;
- if ((iblock + max_blocks) > end_block) {
- max_blocks = end_block - iblock;
- if ((long)max_blocks <= 0) {
- if (create)
- return -EIO; /* write fully beyond EOF */
- /*
- * It is a read which is fully beyond EOF. We return
- * a !buffer_mapped buffer
- */
- max_blocks = 0;
- }
+ if (bio_data_dir(bio) == READ)
+ bio_check_pages_dirty(bio);
+ else {
+ bio_release_pages(bio);
+ bio_put(bio);
+ }
+
+ /* iocb->ki_nbytes stores error code from LLDD */
+ if (error)
+ iocb->ki_nbytes = -EIO;
+
+ if (atomic_dec_and_test(bio_count)) {
+ if (iocb->ki_nbytes < 0)
+ aio_complete(iocb, iocb->ki_nbytes, 0);
+ else
+ aio_complete(iocb, iocb->ki_left, 0);
}
- bh->b_bdev = I_BDEV(inode);
- bh->b_blocknr = iblock;
- bh->b_size = max_blocks << inode->i_blkbits;
- if (max_blocks)
- set_buffer_mapped(bh);
return 0;
}
+#define VEC_SIZE 16
+struct pvec {
+ unsigned short nr;
+ unsigned short idx;
+ struct page *page[VEC_SIZE];
+};
+
+#define PAGES_SPANNED(addr, len) \
+ (DIV_ROUND_UP((addr) + (len), PAGE_SIZE) - (addr) / PAGE_SIZE);
+
+/*
+ * get page pointer for user addr, we internally cache struct page array for
+ * (addr, count) range in pvec to avoid frequent call to get_user_pages. If
+ * internal page list is exhausted, a batch count of up to VEC_SIZE is used
+ * to get next set of page struct.
+ */
+static struct page *blk_get_page(unsigned long addr, size_t count, int rw,
+ struct pvec *pvec)
+{
+ int ret, nr_pages;
+ if (pvec->idx == pvec->nr) {
+ nr_pages = PAGES_SPANNED(addr, count);
+ nr_pages = min(nr_pages, VEC_SIZE);
+ down_read(&current->mm->mmap_sem);
+ ret = get_user_pages(current, current->mm, addr, nr_pages,
+ rw == READ, 0, pvec->page, NULL);
+ up_read(&current->mm->mmap_sem);
+ if (ret < 0)
+ return ERR_PTR(ret);
+ pvec->nr = ret;
+ pvec->idx = 0;
+ }
+ return pvec->page[pvec->idx++];
+}
+
static ssize_t
blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
- loff_t offset, unsigned long nr_segs)
-{
- struct file *file = iocb->ki_filp;
- struct inode *inode = file->f_mapping->host;
+ loff_t pos, unsigned long nr_segs)
+{
+ struct inode *inode = iocb->ki_filp->f_mapping->host;
+ unsigned blkbits = blksize_bits(bdev_hardsect_size(I_BDEV(inode)));
+ unsigned blocksize_mask = (1 << blkbits) - 1;
+ unsigned long seg = 0; /* iov segment iterator */
+ unsigned long nvec; /* number of bio vec needed */
+ unsigned long cur_off; /* offset into current page */
+ unsigned long cur_len; /* I/O len of current page, up to PAGE_SIZE */
+
+ unsigned long addr; /* user iovec address */
+ size_t count; /* user iovec len */
+ size_t nbytes = iocb->ki_nbytes = iocb->ki_left; /* total xfer size */
+ loff_t size; /* size of block device */
+ struct bio *bio;
+ atomic_t *bio_count = &iocb->ki_bio_count;
+ struct page *page;
+ struct pvec pvec;
+
+ pvec.nr = 0;
+ pvec.idx = 0;
+
+ if (pos & blocksize_mask)
+ return -EINVAL;
+
+ size = i_size_read(inode);
+ if (pos + nbytes > size) {
+ nbytes = size - pos;
+ iocb->ki_left = nbytes;
+ }
+
+ /*
+ * check first non-zero iov alignment, the remaining
+ * iov alignment is checked inside bio loop below.
+ */
+ do {
+ addr = (unsigned long) iov[seg].iov_base;
+ count = min(iov[seg].iov_len, nbytes);
+ if (addr & blocksize_mask || count & blocksize_mask)
+ return -EINVAL;
+ } while (!count && ++seg < nr_segs);
+ atomic_set(bio_count, 1);
+
+ while (nbytes) {
+ /* roughly estimate number of bio vec needed */
+ nvec = (nbytes + PAGE_SIZE - 1) / PAGE_SIZE;
+ nvec = max(nvec, nr_segs - seg);
+ nvec = min(nvec, (unsigned long) BIO_MAX_PAGES);
+
+ /* bio_alloc should not fail with GFP_KERNEL flag */
+ bio = bio_alloc(GFP_KERNEL, nvec);
+ bio->bi_bdev = I_BDEV(inode);
+ bio->bi_end_io = blk_end_aio;
+ bio->bi_private = iocb;
+ bio->bi_sector = pos >> blkbits;
+same_bio:
+ cur_off = addr & ~PAGE_MASK;
+ cur_len = PAGE_SIZE - cur_off;
+ if (count < cur_len)
+ cur_len = count;
+
+ page = blk_get_page(addr, count, rw, &pvec);
+ if (unlikely(IS_ERR(page)))
+ goto backout;
+
+ if (bio_add_page(bio, page, cur_len, cur_off)) {
+ pos += cur_len;
+ addr += cur_len;
+ count -= cur_len;
+ nbytes -= cur_len;
+
+ if (count)
+ goto same_bio;
+ while (++seg < nr_segs) {
+ addr = (unsigned long) iov[seg].iov_base;
+ count = iov[seg].iov_len;
+ if (!count)
+ continue;
+ if (unlikely(addr & blocksize_mask ||
+ count & blocksize_mask)) {
+ page = ERR_PTR(-EINVAL);
+ goto backout;
+ }
+ count = min(count, nbytes);
+ goto same_bio;
+ }
+ }
- return blockdev_direct_IO_no_locking(rw, iocb, inode, I_BDEV(inode),
- iov, offset, nr_segs, blkdev_get_blocks, NULL);
+ /* bio is ready, submit it */
+ if (rw == READ)
+ bio_set_pages_dirty(bio);
+ atomic_inc(bio_count);
+ submit_bio(rw, bio);
+ }
+
+completion:
+ iocb->ki_left -= nbytes;
+ nbytes = iocb->ki_left;
+ iocb->ki_pos += nbytes;
+
+ blk_run_address_space(inode->i_mapping);
+ if (atomic_dec_and_test(bio_count))
+ aio_complete(iocb, nbytes, 0);
+
+ return -EIOCBQUEUED;
+
+backout:
+ /*
+ * back out nbytes count constructed so far for this bio,
+ * we will throw away current bio.
+ */
+ nbytes += bio->bi_size;
+ bio_release_pages(bio);
+ bio_put(bio);
+
+ /*
+ * if no bio was submmitted, return the error code.
+ * otherwise, proceed with pending I/O completion.
+ */
+ if (atomic_read(bio_count) == 1)
+ return PTR_ERR(page);
+ goto completion;
}
static int blkdev_writepage(struct page *page, struct writeback_control *wbc)
diff --git a/fs/buffer.c b/fs/buffer.c
index d1f1b54d3108..263f88e4dffb 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -2834,7 +2834,7 @@ int try_to_free_buffers(struct page *page)
int ret = 0;
BUG_ON(!PageLocked(page));
- if (PageWriteback(page))
+ if (PageDirty(page) || PageWriteback(page))
return 0;
if (mapping == NULL) { /* can this still happen? */
@@ -2845,22 +2845,6 @@ int try_to_free_buffers(struct page *page)
spin_lock(&mapping->private_lock);
ret = drop_buffers(page, &buffers_to_free);
spin_unlock(&mapping->private_lock);
- if (ret) {
- /*
- * If the filesystem writes its buffers by hand (eg ext3)
- * then we can have clean buffers against a dirty page. We
- * clean the page here; otherwise later reattachment of buffers
- * could encounter a non-uptodate page, which is unresolvable.
- * This only applies in the rare case where try_to_free_buffers
- * succeeds but the page is not freed.
- *
- * Also, during truncate, discard_buffer will have marked all
- * the page's buffers clean. We discover that here and clean
- * the page also.
- */
- if (test_clear_page_dirty(page))
- task_io_account_cancelled_write(PAGE_CACHE_SIZE);
- }
out:
if (buffers_to_free) {
struct buffer_head *bh = buffers_to_free;
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 098790eb2aa1..472e33e0f3cf 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -4876,7 +4876,7 @@ int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
} else {
/* Add file to outstanding requests */
/* BB change to kmem cache alloc */
- dnotify_req = (struct dir_notify_req *) kmalloc(
+ dnotify_req = kmalloc(
sizeof(struct dir_notify_req),
GFP_KERNEL);
if(dnotify_req) {
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 0f05cab5d24a..8a49b2e77d37 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -1245,14 +1245,21 @@ retry:
wait_on_page_writeback(page);
if (PageWriteback(page) ||
- !test_clear_page_dirty(page)) {
+ !clear_page_dirty_for_io(page)) {
unlock_page(page);
break;
}
+ /*
+ * This actually clears the dirty bit in the radix tree.
+ * See cifs_writepage() for more commentary.
+ */
+ set_page_writeback(page);
+
if (page_offset(page) >= mapping->host->i_size) {
done = 1;
unlock_page(page);
+ end_page_writeback(page);
break;
}
@@ -1316,6 +1323,7 @@ retry:
SetPageError(page);
kunmap(page);
unlock_page(page);
+ end_page_writeback(page);
page_cache_release(page);
}
if ((wbc->nr_to_write -= n_iov) <= 0)
@@ -1352,11 +1360,23 @@ static int cifs_writepage(struct page* page, struct writeback_control *wbc)
if (!PageUptodate(page)) {
cFYI(1, ("ppw - page not up to date"));
}
-
+
+ /*
+ * Set the "writeback" flag, and clear "dirty" in the radix tree.
+ *
+ * A writepage() implementation always needs to do either this,
+ * or re-dirty the page with "redirty_page_for_writepage()" in
+ * the case of a failure.
+ *
+ * Just unlocking the page will cause the radix tree tag-bits
+ * to fail to update with the state of the page correctly.
+ */
+ set_page_writeback(page);
rc = cifs_partialpagewrite(page, 0, PAGE_CACHE_SIZE);
SetPageUptodate(page); /* BB add check for error and Clearuptodate? */
unlock_page(page);
- page_cache_release(page);
+ end_page_writeback(page);
+ page_cache_release(page);
FreeXid(xid);
return rc;
}
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index 137d76c3f90a..c692487346ea 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -24,6 +24,7 @@
#include <linux/kobject.h>
#include <linux/namei.h>
#include <linux/debugfs.h>
+#include <linux/fsnotify.h>
#define DEBUGFS_MAGIC 0x64626720
@@ -54,7 +55,8 @@ static struct inode *debugfs_get_inode(struct super_block *sb, int mode, dev_t d
inode->i_op = &simple_dir_inode_operations;
inode->i_fop = &simple_dir_operations;
- /* directory inodes start off with i_nlink == 2 (for "." entry) */
+ /* directory inodes start off with i_nlink == 2
+ * (for "." entry) */
inc_nlink(inode);
break;
}
@@ -87,15 +89,22 @@ static int debugfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR;
res = debugfs_mknod(dir, dentry, mode, 0);
- if (!res)
+ if (!res) {
inc_nlink(dir);
+ fsnotify_mkdir(dir, dentry);
+ }
return res;
}
static int debugfs_create(struct inode *dir, struct dentry *dentry, int mode)
{
+ int res;
+
mode = (mode & S_IALLUGO) | S_IFREG;
- return debugfs_mknod(dir, dentry, mode, 0);
+ res = debugfs_mknod(dir, dentry, mode, 0);
+ if (!res)
+ fsnotify_create(dir, dentry);
+ return res;
}
static inline int debugfs_positive(struct dentry *dentry)
@@ -135,7 +144,7 @@ static int debugfs_create_by_name(const char *name, mode_t mode,
* block. A pointer to that is in the struct vfsmount that we
* have around.
*/
- if (!parent ) {
+ if (!parent) {
if (debugfs_mount && debugfs_mount->mnt_sb) {
parent = debugfs_mount->mnt_sb->s_root;
}
@@ -153,6 +162,7 @@ static int debugfs_create_by_name(const char *name, mode_t mode,
error = debugfs_mkdir(parent->d_inode, *dentry, mode);
else
error = debugfs_create(parent->d_inode, *dentry, mode);
+ dput(*dentry);
} else
error = PTR_ERR(*dentry);
mutex_unlock(&parent->d_inode->i_mutex);
@@ -197,13 +207,15 @@ struct dentry *debugfs_create_file(const char *name, mode_t mode,
pr_debug("debugfs: creating file '%s'\n",name);
- error = simple_pin_fs(&debug_fs_type, &debugfs_mount, &debugfs_mount_count);
+ error = simple_pin_fs(&debug_fs_type, &debugfs_mount,
+ &debugfs_mount_count);
if (error)
goto exit;
error = debugfs_create_by_name(name, mode, parent, &dentry);
if (error) {
dentry = NULL;
+ simple_release_fs(&debugfs_mount, &debugfs_mount_count);
goto exit;
}
@@ -262,6 +274,7 @@ EXPORT_SYMBOL_GPL(debugfs_create_dir);
void debugfs_remove(struct dentry *dentry)
{
struct dentry *parent;
+ int ret = 0;
if (!dentry)
return;
@@ -273,11 +286,19 @@ void debugfs_remove(struct dentry *dentry)
mutex_lock(&parent->d_inode->i_mutex);
if (debugfs_positive(dentry)) {
if (dentry->d_inode) {
- if (S_ISDIR(dentry->d_inode->i_mode))
- simple_rmdir(parent->d_inode, dentry);
- else
+ dget(dentry);
+ if (S_ISDIR(dentry->d_inode->i_mode)) {
+ ret = simple_rmdir(parent->d_inode, dentry);
+ if (ret)
+ printk(KERN_ERR
+ "DebugFS rmdir on %s failed : "
+ "directory not empty.\n",
+ dentry->d_name.name);
+ } else
simple_unlink(parent->d_inode, dentry);
- dput(dentry);
+ if (!ret)
+ d_delete(dentry);
+ dput(dentry);
}
}
mutex_unlock(&parent->d_inode->i_mutex);
diff --git a/fs/dlm/lowcomms-tcp.c b/fs/dlm/lowcomms-tcp.c
index 8f2791fc8447..9be3a440c42a 100644
--- a/fs/dlm/lowcomms-tcp.c
+++ b/fs/dlm/lowcomms-tcp.c
@@ -143,7 +143,7 @@ static DECLARE_WAIT_QUEUE_HEAD(lowcomms_recv_waitq);
/* An array of pointers to connections, indexed by NODEID */
static struct connection **connections;
static DECLARE_MUTEX(connections_lock);
-static kmem_cache_t *con_cache;
+static struct kmem_cache *con_cache;
static int conn_array_size;
/* List of sockets that have reads pending */
diff --git a/fs/file.c b/fs/file.c
index 857fa49e984c..c5575de01113 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -206,7 +206,7 @@ static int expand_fdtable(struct files_struct *files, int nr)
copy_fdtable(new_fdt, cur_fdt);
rcu_assign_pointer(files->fdt, new_fdt);
if (cur_fdt->max_fds > NR_OPEN_DEFAULT)
- call_rcu(&cur_fdt->rcu, free_fdtable_rcu);
+ free_fdtable(cur_fdt);
} else {
/* Somebody else expanded, so undo our attempt */
free_fdarr(new_fdt);
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 1387749201b3..f63efe1337ec 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -483,10 +483,8 @@ static int fuse_commit_write(struct file *file, struct page *page,
i_size_write(inode, pos);
spin_unlock(&fc->lock);
- if (offset == 0 && to == PAGE_CACHE_SIZE) {
- clear_page_dirty(page);
+ if (offset == 0 && to == PAGE_CACHE_SIZE)
SetPageUptodate(page);
- }
}
fuse_invalidate_attr(inode);
return err;
diff --git a/fs/gfs2/Kconfig b/fs/gfs2/Kconfig
index c0791cbacad9..6a2ffa2db14f 100644
--- a/fs/gfs2/Kconfig
+++ b/fs/gfs2/Kconfig
@@ -34,7 +34,9 @@ config GFS2_FS_LOCKING_NOLOCK
config GFS2_FS_LOCKING_DLM
tristate "GFS2 DLM locking module"
- depends on GFS2_FS
+ depends on GFS2_FS && NET && INET && (IPV6 || IPV6=n)
+ select IP_SCTP if DLM_SCTP
+ select CONFIGFS_FS
select DLM
help
Multiple node locking module for GFS2
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index ed2c22340ad7..4f4cd132b571 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -176,7 +176,7 @@ static int hugetlbfs_commit_write(struct file *file,
static void truncate_huge_page(struct page *page)
{
- clear_page_dirty(page);
+ cancel_dirty_page(page, /* No IO accounting for huge pages? */0);
ClearPageUptodate(page);
remove_from_page_cache(page);
put_page(page);
diff --git a/fs/inode.c b/fs/inode.c
index d00de182ecb9..bf21dc6d0dbd 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -1144,7 +1144,6 @@ sector_t bmap(struct inode * inode, sector_t block)
res = inode->i_mapping->a_ops->bmap(inode->i_mapping, block);
return res;
}
-
EXPORT_SYMBOL(bmap);
/**
@@ -1163,27 +1162,43 @@ void touch_atime(struct vfsmount *mnt, struct dentry *dentry)
if (IS_RDONLY(inode))
return;
-
- if ((inode->i_flags & S_NOATIME) ||
- (inode->i_sb->s_flags & MS_NOATIME) ||
- ((inode->i_sb->s_flags & MS_NODIRATIME) && S_ISDIR(inode->i_mode)))
+ if (inode->i_flags & S_NOATIME)
+ return;
+ if (inode->i_sb->s_flags & MS_NOATIME)
+ return;
+ if ((inode->i_sb->s_flags & MS_NODIRATIME) && S_ISDIR(inode->i_mode))
return;
/*
* We may have a NULL vfsmount when coming from NFSD
*/
- if (mnt &&
- ((mnt->mnt_flags & MNT_NOATIME) ||
- ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode))))
- return;
+ if (mnt) {
+ if (mnt->mnt_flags & MNT_NOATIME)
+ return;
+ if ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode))
+ return;
- now = current_fs_time(inode->i_sb);
- if (!timespec_equal(&inode->i_atime, &now)) {
- inode->i_atime = now;
- mark_inode_dirty_sync(inode);
+ if (mnt->mnt_flags & MNT_RELATIME) {
+ /*
+ * With relative atime, only update atime if the
+ * previous atime is earlier than either the ctime or
+ * mtime.
+ */
+ if (timespec_compare(&inode->i_mtime,
+ &inode->i_atime) < 0 &&
+ timespec_compare(&inode->i_ctime,
+ &inode->i_atime) < 0)
+ return;
+ }
}
-}
+ now = current_fs_time(inode->i_sb);
+ if (timespec_equal(&inode->i_atime, &now))
+ return;
+
+ inode->i_atime = now;
+ mark_inode_dirty_sync(inode);
+}
EXPORT_SYMBOL(touch_atime);
/**
diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c
index 10be51290a27..be4648bc7a2f 100644
--- a/fs/jbd/commit.c
+++ b/fs/jbd/commit.c
@@ -248,8 +248,12 @@ write_out_data:
bufs = 0;
goto write_out_data;
}
- }
- else {
+ } else if (!locked && buffer_locked(bh)) {
+ __journal_file_buffer(jh, commit_transaction,
+ BJ_Locked);
+ jbd_unlock_bh_state(bh);
+ put_bh(bh);
+ } else {
BUFFER_TRACE(bh, "writeout complete: unfile");
__journal_unfile_buffer(jh);
jbd_unlock_bh_state(bh);
diff --git a/fs/jffs/inode-v23.c b/fs/jffs/inode-v23.c
index 7b40c69f44eb..43baa1afa021 100644
--- a/fs/jffs/inode-v23.c
+++ b/fs/jffs/inode-v23.c
@@ -818,7 +818,7 @@ jffs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
D1({
int len = dentry->d_name.len;
- char *_name = (char *) kmalloc(len + 1, GFP_KERNEL);
+ char *_name = kmalloc(len + 1, GFP_KERNEL);
memcpy(_name, dentry->d_name.name, len);
_name[len] = '\0';
printk("***jffs_mkdir(): dir = 0x%p, name = \"%s\", "
@@ -964,7 +964,7 @@ jffs_remove(struct inode *dir, struct dentry *dentry, int type)
D1({
int len = dentry->d_name.len;
const char *name = dentry->d_name.name;
- char *_name = (char *) kmalloc(len + 1, GFP_KERNEL);
+ char *_name = kmalloc(len + 1, GFP_KERNEL);
memcpy(_name, name, len);
_name[len] = '\0';
printk("***jffs_remove(): file = \"%s\", ino = %ld\n", _name, dentry->d_inode->i_ino);
diff --git a/fs/jffs/intrep.c b/fs/jffs/intrep.c
index d0e783f199ea..6dd18911b44c 100644
--- a/fs/jffs/intrep.c
+++ b/fs/jffs/intrep.c
@@ -436,7 +436,7 @@ jffs_checksum_flash(struct mtd_info *mtd, loff_t start, int size, __u32 *result)
int i, length;
/* Allocate read buffer */
- read_buf = (__u8 *) kmalloc (sizeof(__u8) * 4096, GFP_KERNEL);
+ read_buf = kmalloc(sizeof(__u8) * 4096, GFP_KERNEL);
if (!read_buf) {
printk(KERN_NOTICE "kmalloc failed in jffs_checksum_flash()\n");
return -ENOMEM;
@@ -744,11 +744,11 @@ static int check_partly_erased_sectors(struct jffs_fmcontrol *fmc){
/* Allocate read buffers */
- read_buf1 = (__u8 *) kmalloc (sizeof(__u8) * READ_AHEAD_BYTES, GFP_KERNEL);
+ read_buf1 = kmalloc(sizeof(__u8) * READ_AHEAD_BYTES, GFP_KERNEL);
if (!read_buf1)
return -ENOMEM;
- read_buf2 = (__u8 *) kmalloc (sizeof(__u8) * READ_AHEAD_BYTES, GFP_KERNEL);
+ read_buf2 = kmalloc(sizeof(__u8) * READ_AHEAD_BYTES, GFP_KERNEL);
if (!read_buf2) {
kfree(read_buf1);
return -ENOMEM;
@@ -876,7 +876,7 @@ jffs_scan_flash(struct jffs_control *c)
}
/* Allocate read buffer */
- read_buf = (__u8 *) kmalloc (sizeof(__u8) * 4096, GFP_KERNEL);
+ read_buf = kmalloc(sizeof(__u8) * 4096, GFP_KERNEL);
if (!read_buf) {
flash_safe_release(fmc->mtd);
return -ENOMEM;
@@ -1463,7 +1463,7 @@ jffs_insert_node(struct jffs_control *c, struct jffs_file *f,
kfree(f->name);
DJM(no_name--);
}
- if (!(f->name = (char *) kmalloc(raw_inode->nsize + 1,
+ if (!(f->name = kmalloc(raw_inode->nsize + 1,
GFP_KERNEL))) {
return -ENOMEM;
}
@@ -1737,7 +1737,7 @@ jffs_find_child(struct jffs_file *dir, const char *name, int len)
printk("jffs_find_child(): Found \"%s\".\n", f->name);
}
else {
- char *copy = (char *) kmalloc(len + 1, GFP_KERNEL);
+ char *copy = kmalloc(len + 1, GFP_KERNEL);
if (copy) {
memcpy(copy, name, len);
copy[len] = '\0';
@@ -2627,7 +2627,7 @@ jffs_print_tree(struct jffs_file *first_file, int indent)
return;
}
- if (!(space = (char *) kmalloc(indent + 1, GFP_KERNEL))) {
+ if (!(space = kmalloc(indent + 1, GFP_KERNEL))) {
printk("jffs_print_tree(): Out of memory!\n");
return;
}
diff --git a/fs/jfs/jfs_dtree.c b/fs/jfs/jfs_dtree.c
index 47bc0b5d1324..6d62f3222892 100644
--- a/fs/jfs/jfs_dtree.c
+++ b/fs/jfs/jfs_dtree.c
@@ -3777,12 +3777,12 @@ static int ciGetLeafPrefixKey(dtpage_t * lp, int li, dtpage_t * rp,
struct component_name lkey;
struct component_name rkey;
- lkey.name = (wchar_t *) kmalloc((JFS_NAME_MAX + 1) * sizeof(wchar_t),
+ lkey.name = kmalloc((JFS_NAME_MAX + 1) * sizeof(wchar_t),
GFP_KERNEL);
if (lkey.name == NULL)
return -ENOMEM;
- rkey.name = (wchar_t *) kmalloc((JFS_NAME_MAX + 1) * sizeof(wchar_t),
+ rkey.name = kmalloc((JFS_NAME_MAX + 1) * sizeof(wchar_t),
GFP_KERNEL);
if (rkey.name == NULL) {
kfree(lkey.name);
diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c
index ee9b473b7b80..53f63b47a6d3 100644
--- a/fs/jfs/jfs_imap.c
+++ b/fs/jfs/jfs_imap.c
@@ -120,7 +120,7 @@ int diMount(struct inode *ipimap)
* allocate/initialize the in-memory inode map control structure
*/
/* allocate the in-memory inode map control structure. */
- imap = (struct inomap *) kmalloc(sizeof(struct inomap), GFP_KERNEL);
+ imap = kmalloc(sizeof(struct inomap), GFP_KERNEL);
if (imap == NULL) {
jfs_err("diMount: kmalloc returned NULL!");
return -ENOMEM;
diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c
index b1a1c7296014..ceaf03b94935 100644
--- a/fs/jfs/jfs_metapage.c
+++ b/fs/jfs/jfs_metapage.c
@@ -764,22 +764,9 @@ void release_metapage(struct metapage * mp)
} else if (mp->lsn) /* discard_metapage doesn't remove it */
remove_from_logsync(mp);
-#if MPS_PER_PAGE == 1
- /*
- * If we know this is the only thing in the page, we can throw
- * the page out of the page cache. If pages are larger, we
- * don't want to do this.
- */
-
- /* Retest mp->count since we may have released page lock */
- if (test_bit(META_discard, &mp->flag) && !mp->count) {
- clear_page_dirty(page);
- ClearPageUptodate(page);
- }
-#else
/* Try to keep metapages from using up too much memory */
drop_metapage(page, mp);
-#endif
+
unlock_page(page);
page_cache_release(page);
}
diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c
index 92681c9e9b20..062707745162 100644
--- a/fs/lockd/clntlock.c
+++ b/fs/lockd/clntlock.c
@@ -36,7 +36,7 @@ struct nlm_wait {
struct nlm_host * b_host;
struct file_lock * b_lock; /* local file lock */
unsigned short b_reclaim; /* got to reclaim lock */
- u32 b_status; /* grant callback status */
+ __be32 b_status; /* grant callback status */
};
static LIST_HEAD(nlm_blocked);
@@ -53,7 +53,7 @@ struct nlm_wait *nlmclnt_prepare_block(struct nlm_host *host, struct file_lock *
block->b_host = host;
block->b_lock = fl;
init_waitqueue_head(&block->b_wait);
- block->b_status = NLM_LCK_BLOCKED;
+ block->b_status = nlm_lck_blocked;
list_add(&block->b_list, &nlm_blocked);
}
return block;
@@ -89,7 +89,7 @@ int nlmclnt_block(struct nlm_wait *block, struct nlm_rqst *req, long timeout)
* nlmclnt_lock for an explanation.
*/
ret = wait_event_interruptible_timeout(block->b_wait,
- block->b_status != NLM_LCK_BLOCKED,
+ block->b_status != nlm_lck_blocked,
timeout);
if (ret < 0)
return -ERESTARTSYS;
@@ -131,7 +131,7 @@ __be32 nlmclnt_grant(const struct sockaddr_in *addr, const struct nlm_lock *lock
/* Alright, we found a lock. Set the return status
* and wake up the caller
*/
- block->b_status = NLM_LCK_GRANTED;
+ block->b_status = nlm_granted;
wake_up(&block->b_wait);
res = nlm_granted;
}
@@ -211,7 +211,7 @@ restart:
/* Now, wake up all processes that sleep on a blocked lock */
list_for_each_entry(block, &nlm_blocked, b_list) {
if (block->b_host == host) {
- block->b_status = NLM_LCK_DENIED_GRACE_PERIOD;
+ block->b_status = nlm_lck_denied_grace_period;
wake_up(&block->b_wait);
}
}
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c
index 80a1a6dccc8f..0b4acc1c5e7d 100644
--- a/fs/lockd/clntproc.c
+++ b/fs/lockd/clntproc.c
@@ -27,7 +27,7 @@
static int nlmclnt_test(struct nlm_rqst *, struct file_lock *);
static int nlmclnt_lock(struct nlm_rqst *, struct file_lock *);
static int nlmclnt_unlock(struct nlm_rqst *, struct file_lock *);
-static int nlm_stat_to_errno(u32 stat);
+static int nlm_stat_to_errno(__be32 stat);
static void nlmclnt_locks_init_private(struct file_lock *fl, struct nlm_host *host);
static int nlmclnt_cancel(struct nlm_host *, int , struct file_lock *);
@@ -325,7 +325,7 @@ nlmclnt_call(struct nlm_rqst *req, u32 proc)
}
break;
} else
- if (resp->status == NLM_LCK_DENIED_GRACE_PERIOD) {
+ if (resp->status == nlm_lck_denied_grace_period) {
dprintk("lockd: server in grace period\n");
if (argp->reclaim) {
printk(KERN_WARNING
@@ -411,10 +411,10 @@ nlmclnt_test(struct nlm_rqst *req, struct file_lock *fl)
goto out;
switch (req->a_res.status) {
- case NLM_LCK_GRANTED:
+ case nlm_granted:
fl->fl_type = F_UNLCK;
break;
- case NLM_LCK_DENIED:
+ case nlm_lck_denied:
/*
* Report the conflicting lock back to the application.
*/
@@ -524,9 +524,9 @@ again:
if (!req->a_args.block)
break;
/* Did a reclaimer thread notify us of a server reboot? */
- if (resp->status == NLM_LCK_DENIED_GRACE_PERIOD)
+ if (resp->status == nlm_lck_denied_grace_period)
continue;
- if (resp->status != NLM_LCK_BLOCKED)
+ if (resp->status != nlm_lck_blocked)
break;
/* Wait on an NLM blocking lock */
status = nlmclnt_block(block, req, NLMCLNT_POLL_TIMEOUT);
@@ -535,11 +535,11 @@ again:
*/
if (status < 0)
goto out_unblock;
- if (resp->status != NLM_LCK_BLOCKED)
+ if (resp->status != nlm_lck_blocked)
break;
}
- if (resp->status == NLM_LCK_GRANTED) {
+ if (resp->status == nlm_granted) {
down_read(&host->h_rwsem);
/* Check whether or not the server has rebooted */
if (fl->fl_u.nfs_fl.state != host->h_state) {
@@ -556,7 +556,7 @@ again:
out_unblock:
nlmclnt_finish_block(block);
/* Cancel the blocked request if it is still pending */
- if (resp->status == NLM_LCK_BLOCKED)
+ if (resp->status == nlm_lck_blocked)
nlmclnt_cancel(host, req->a_args.block, fl);
out:
nlm_release_call(req);
@@ -585,12 +585,12 @@ nlmclnt_reclaim(struct nlm_host *host, struct file_lock *fl)
req->a_args.reclaim = 1;
if ((status = nlmclnt_call(req, NLMPROC_LOCK)) >= 0
- && req->a_res.status == NLM_LCK_GRANTED)
+ && req->a_res.status == nlm_granted)
return 0;
printk(KERN_WARNING "lockd: failed to reclaim lock for pid %d "
"(errno %d, status %d)\n", fl->fl_pid,
- status, req->a_res.status);
+ status, ntohl(req->a_res.status));
/*
* FIXME: This is a serious failure. We can
@@ -637,10 +637,10 @@ nlmclnt_unlock(struct nlm_rqst *req, struct file_lock *fl)
if (status < 0)
goto out;
- if (resp->status == NLM_LCK_GRANTED)
+ if (resp->status == nlm_granted)
goto out;
- if (resp->status != NLM_LCK_DENIED_NOLOCKS)
+ if (resp->status != nlm_lck_denied_nolocks)
printk("lockd: unexpected unlock status: %d\n", resp->status);
/* What to do now? I'm out of my depth... */
status = -ENOLCK;
@@ -652,7 +652,7 @@ out:
static void nlmclnt_unlock_callback(struct rpc_task *task, void *data)
{
struct nlm_rqst *req = data;
- int status = req->a_res.status;
+ u32 status = ntohl(req->a_res.status);
if (RPC_ASSASSINATED(task))
goto die;
@@ -720,6 +720,7 @@ static int nlmclnt_cancel(struct nlm_host *host, int block, struct file_lock *fl
static void nlmclnt_cancel_callback(struct rpc_task *task, void *data)
{
struct nlm_rqst *req = data;
+ u32 status = ntohl(req->a_res.status);
if (RPC_ASSASSINATED(task))
goto die;
@@ -731,9 +732,9 @@ static void nlmclnt_cancel_callback(struct rpc_task *task, void *data)
}
dprintk("lockd: cancel status %u (task %u)\n",
- req->a_res.status, task->tk_pid);
+ status, task->tk_pid);
- switch (req->a_res.status) {
+ switch (status) {
case NLM_LCK_GRANTED:
case NLM_LCK_DENIED_GRACE_PERIOD:
case NLM_LCK_DENIED:
@@ -744,7 +745,7 @@ static void nlmclnt_cancel_callback(struct rpc_task *task, void *data)
goto retry_cancel;
default:
printk(KERN_NOTICE "lockd: weird return %d for CANCEL call\n",
- req->a_res.status);
+ status);
}
die:
@@ -768,9 +769,9 @@ static const struct rpc_call_ops nlmclnt_cancel_ops = {
* Convert an NLM status code to a generic kernel errno
*/
static int
-nlm_stat_to_errno(u32 status)
+nlm_stat_to_errno(__be32 status)
{
- switch(status) {
+ switch(ntohl(status)) {
case NLM_LCK_GRANTED:
return 0;
case NLM_LCK_DENIED:
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index 5c054b20fd5e..c7db0a5bccdc 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -645,7 +645,7 @@ static const struct rpc_call_ops nlmsvc_grant_ops = {
* block.
*/
void
-nlmsvc_grant_reply(struct nlm_cookie *cookie, u32 status)
+nlmsvc_grant_reply(struct nlm_cookie *cookie, __be32 status)
{
struct nlm_block *block;
@@ -655,7 +655,7 @@ nlmsvc_grant_reply(struct nlm_cookie *cookie, u32 status)
return;
if (block) {
- if (status == NLM_LCK_DENIED_GRACE_PERIOD) {
+ if (status == nlm_lck_denied_grace_period) {
/* Try again in a couple of seconds */
nlmsvc_insert_block(block, 10 * HZ);
} else {
diff --git a/fs/lockd/svcshare.c b/fs/lockd/svcshare.c
index 6220dc2a3f2c..068886de4dda 100644
--- a/fs/lockd/svcshare.c
+++ b/fs/lockd/svcshare.c
@@ -39,7 +39,7 @@ nlmsvc_share_file(struct nlm_host *host, struct nlm_file *file,
return nlm_lck_denied;
}
- share = (struct nlm_share *) kmalloc(sizeof(*share) + oh->len,
+ share = kmalloc(sizeof(*share) + oh->len,
GFP_KERNEL);
if (share == NULL)
return nlm_lck_denied_nolocks;
diff --git a/fs/lockd/xdr.c b/fs/lockd/xdr.c
index b7c949256e5a..34dae5d70738 100644
--- a/fs/lockd/xdr.c
+++ b/fs/lockd/xdr.c
@@ -361,7 +361,7 @@ nlmsvc_decode_res(struct svc_rqst *rqstp, __be32 *p, struct nlm_res *resp)
{
if (!(p = nlm_decode_cookie(p, &resp->cookie)))
return 0;
- resp->status = ntohl(*p++);
+ resp->status = *p++;
return xdr_argsize_check(rqstp, p);
}
@@ -407,8 +407,8 @@ nlmclt_decode_testres(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp)
{
if (!(p = nlm_decode_cookie(p, &resp->cookie)))
return -EIO;
- resp->status = ntohl(*p++);
- if (resp->status == NLM_LCK_DENIED) {
+ resp->status = *p++;
+ if (resp->status == nlm_lck_denied) {
struct file_lock *fl = &resp->lock.fl;
u32 excl;
s32 start, len, end;
@@ -506,7 +506,7 @@ nlmclt_decode_res(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp)
{
if (!(p = nlm_decode_cookie(p, &resp->cookie)))
return -EIO;
- resp->status = ntohl(*p++);
+ resp->status = *p++;
return 0;
}
diff --git a/fs/lockd/xdr4.c b/fs/lockd/xdr4.c
index f4c0b2b9f75a..a78240551219 100644
--- a/fs/lockd/xdr4.c
+++ b/fs/lockd/xdr4.c
@@ -367,7 +367,7 @@ nlm4svc_decode_res(struct svc_rqst *rqstp, __be32 *p, struct nlm_res *resp)
{
if (!(p = nlm4_decode_cookie(p, &resp->cookie)))
return 0;
- resp->status = ntohl(*p++);
+ resp->status = *p++;
return xdr_argsize_check(rqstp, p);
}
@@ -413,8 +413,8 @@ nlm4clt_decode_testres(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp)
{
if (!(p = nlm4_decode_cookie(p, &resp->cookie)))
return -EIO;
- resp->status = ntohl(*p++);
- if (resp->status == NLM_LCK_DENIED) {
+ resp->status = *p++;
+ if (resp->status == nlm_lck_denied) {
struct file_lock *fl = &resp->lock.fl;
u32 excl;
s64 start, end, len;
@@ -512,7 +512,7 @@ nlm4clt_decode_res(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp)
{
if (!(p = nlm4_decode_cookie(p, &resp->cookie)))
return -EIO;
- resp->status = ntohl(*p++);
+ resp->status = *p++;
return 0;
}
diff --git a/fs/namespace.c b/fs/namespace.c
index fde8553faa76..5ef336c1103c 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -368,6 +368,7 @@ static int show_vfsmnt(struct seq_file *m, void *v)
{ MNT_NOEXEC, ",noexec" },
{ MNT_NOATIME, ",noatime" },
{ MNT_NODIRATIME, ",nodiratime" },
+ { MNT_RELATIME, ",relatime" },
{ 0, NULL }
};
struct proc_fs_info *fs_infop;
@@ -1405,9 +1406,11 @@ long do_mount(char *dev_name, char *dir_name, char *type_page,
mnt_flags |= MNT_NOATIME;
if (flags & MS_NODIRATIME)
mnt_flags |= MNT_NODIRATIME;
+ if (flags & MS_RELATIME)
+ mnt_flags |= MNT_RELATIME;
flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE |
- MS_NOATIME | MS_NODIRATIME);
+ MS_NOATIME | MS_NODIRATIME | MS_RELATIME);
/* ... and get the mountpoint */
retval = path_lookup(dir_name, LOOKUP_FOLLOW, &nd);
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c
index 47462ac94474..67a90bf795d5 100644
--- a/fs/ncpfs/inode.c
+++ b/fs/ncpfs/inode.c
@@ -327,11 +327,12 @@ static int ncp_parse_options(struct ncp_mount_data_kernel *data, char *options)
char *optarg;
unsigned long optint;
int version = 0;
+ int ret;
data->flags = 0;
data->int_flags = 0;
data->mounted_uid = 0;
- data->wdog_pid = -1;
+ data->wdog_pid = NULL;
data->ncp_fd = ~0;
data->time_out = 10;
data->retry_count = 20;
@@ -343,8 +344,9 @@ static int ncp_parse_options(struct ncp_mount_data_kernel *data, char *options)
data->mounted_vol[0] = 0;
while ((optval = ncp_getopt("ncpfs", &options, ncp_opts, NULL, &optarg, &optint)) != 0) {
- if (optval < 0)
- return optval;
+ ret = optval;
+ if (ret < 0)
+ goto err;
switch (optval) {
case 'u':
data->uid = optint;
@@ -371,7 +373,7 @@ static int ncp_parse_options(struct ncp_mount_data_kernel *data, char *options)
data->flags = optint;
break;
case 'w':
- data->wdog_pid = optint;
+ data->wdog_pid = find_get_pid(optint);
break;
case 'n':
data->ncp_fd = optint;
@@ -380,18 +382,21 @@ static int ncp_parse_options(struct ncp_mount_data_kernel *data, char *options)
data->info_fd = optint;
break;
case 'v':
- if (optint < NCP_MOUNT_VERSION_V4) {
- return -ECHRNG;
- }
- if (optint > NCP_MOUNT_VERSION_V5) {
- return -ECHRNG;
- }
+ ret = -ECHRNG;
+ if (optint < NCP_MOUNT_VERSION_V4)
+ goto err;
+ if (optint > NCP_MOUNT_VERSION_V5)
+ goto err;
version = optint;
break;
}
}
return 0;
+err:
+ put_pid(data->wdog_pid);
+ data->wdog_pid = NULL;
+ return ret;
}
static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
@@ -409,6 +414,7 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
#endif
struct ncp_entry_info finfo;
+ data.wdog_pid = NULL;
server = kzalloc(sizeof(struct ncp_server), GFP_KERNEL);
if (!server)
return -ENOMEM;
@@ -425,7 +431,7 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
data.flags = md->flags;
data.int_flags = NCP_IMOUNT_LOGGEDIN_POSSIBLE;
data.mounted_uid = md->mounted_uid;
- data.wdog_pid = md->wdog_pid;
+ data.wdog_pid = find_get_pid(md->wdog_pid);
data.ncp_fd = md->ncp_fd;
data.time_out = md->time_out;
data.retry_count = md->retry_count;
@@ -445,7 +451,7 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
data.flags = md->flags;
data.int_flags = 0;
data.mounted_uid = md->mounted_uid;
- data.wdog_pid = md->wdog_pid;
+ data.wdog_pid = find_get_pid(md->wdog_pid);
data.ncp_fd = md->ncp_fd;
data.time_out = md->time_out;
data.retry_count = md->retry_count;
@@ -679,6 +685,7 @@ out_fput:
*/
fput(ncp_filp);
out:
+ put_pid(data.wdog_pid);
sb->s_fs_info = NULL;
kfree(server);
return error;
@@ -711,7 +718,8 @@ static void ncp_put_super(struct super_block *sb)
if (server->info_filp)
fput(server->info_filp);
fput(server->ncp_filp);
- kill_proc(server->m.wdog_pid, SIGTERM, 1);
+ kill_pid(server->m.wdog_pid, SIGTERM, 1);
+ put_pid(server->m.wdog_pid);
kfree(server->priv.data);
kfree(server->auth.object_name);
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index ee458aeab24a..b3fd29baadc3 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -1877,7 +1877,7 @@ static int nfs4_proc_unlink_setup(struct rpc_message *msg, struct dentry *dir,
struct nfs_server *server = NFS_SERVER(dir->d_inode);
struct unlink_desc *up;
- up = (struct unlink_desc *) kmalloc(sizeof(*up), GFP_KERNEL);
+ up = kmalloc(sizeof(*up), GFP_KERNEL);
if (!up)
return -ENOMEM;
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index f37df46d2eaa..248dd92e6a56 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -787,15 +787,20 @@ exp_get_by_name(svc_client *clp, struct vfsmount *mnt, struct dentry *dentry,
key.ex_dentry = dentry;
exp = svc_export_lookup(&key);
- if (exp != NULL)
- switch (cache_check(&svc_export_cache, &exp->h, reqp)) {
+ if (exp != NULL) {
+ int err;
+
+ err = cache_check(&svc_export_cache, &exp->h, reqp);
+ switch (err) {
case 0: break;
case -EAGAIN:
- exp = ERR_PTR(-EAGAIN);
+ case -ETIMEDOUT:
+ exp = ERR_PTR(err);
break;
default:
exp = NULL;
}
+ }
return exp;
}
@@ -950,6 +955,8 @@ exp_export(struct nfsctl_export *nxp)
exp = exp_get_by_name(clp, nd.mnt, nd.dentry, NULL);
+ memset(&new, 0, sizeof(new));
+
/* must make sure there won't be an ex_fsid clash */
if ((nxp->ex_flags & NFSEXP_FSID) &&
(fsid_key = exp_get_fsid_key(clp, nxp->ex_dev)) &&
@@ -980,6 +987,9 @@ exp_export(struct nfsctl_export *nxp)
new.h.expiry_time = NEVER;
new.h.flags = 0;
+ new.ex_path = kstrdup(nxp->ex_path, GFP_KERNEL);
+ if (!new.ex_path)
+ goto finish;
new.ex_client = clp;
new.ex_mnt = nd.mnt;
new.ex_dentry = nd.dentry;
@@ -1000,10 +1010,11 @@ exp_export(struct nfsctl_export *nxp)
/* failed to create at least one index */
exp_do_unexport(exp);
cache_flush();
- err = -ENOMEM;
- }
-
+ } else
+ err = 0;
finish:
+ if (new.ex_path)
+ kfree(new.ex_path);
if (exp)
exp_put(exp);
if (fsid_key && !IS_ERR(fsid_key))
@@ -1104,6 +1115,10 @@ exp_rootfh(svc_client *clp, char *path, struct knfsd_fh *f, int maxsize)
path, nd.dentry, clp->name,
inode->i_sb->s_id, inode->i_ino);
exp = exp_parent(clp, nd.mnt, nd.dentry, NULL);
+ if (IS_ERR(exp)) {
+ err = PTR_ERR(exp);
+ goto out;
+ }
if (!exp) {
dprintk("nfsd: exp_rootfh export not found.\n");
goto out;
@@ -1159,12 +1174,10 @@ exp_pseudoroot(struct auth_domain *clp, struct svc_fh *fhp,
mk_fsid_v1(fsidv, 0);
exp = exp_find(clp, 1, fsidv, creq);
- if (IS_ERR(exp) && PTR_ERR(exp) == -EAGAIN)
- return nfserr_dropit;
+ if (IS_ERR(exp))
+ return nfserrno(PTR_ERR(exp));
if (exp == NULL)
return nfserr_perm;
- else if (IS_ERR(exp))
- return nfserrno(PTR_ERR(exp));
rv = fh_compose(fhp, exp, exp->ex_dentry, NULL);
exp_put(exp);
return rv;
diff --git a/fs/nfsd/lockd.c b/fs/nfsd/lockd.c
index 11fdaf7721b4..221acd1f11f6 100644
--- a/fs/nfsd/lockd.c
+++ b/fs/nfsd/lockd.c
@@ -22,7 +22,7 @@
/*
* Note: we hold the dentry use count while the file is open.
*/
-static u32
+static __be32
nlm_fopen(struct svc_rqst *rqstp, struct nfs_fh *f, struct file **filp)
{
__be32 nfserr;
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 50bc94243ca1..8522729830db 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -33,13 +33,6 @@
* 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.
- *
- * Note: some routines in this file are just trivial wrappers
- * (e.g. nfsd4_lookup()) defined solely for the sake of consistent
- * naming. Since all such routines have been declared "inline",
- * there shouldn't be any associated overhead. At some point in
- * the future, I might inline these "by hand" to clean up a
- * little.
*/
#include <linux/param.h>
@@ -161,8 +154,9 @@ do_open_fhandle(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_
}
-static inline __be32
-nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open, struct nfs4_stateowner **replay_owner)
+static __be32
+nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ struct nfsd4_open *open)
{
__be32 status;
dprintk("NFSD: nfsd4_open filename %.*s op_stateowner %p\n",
@@ -179,11 +173,11 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open
status = nfsd4_process_open1(open);
if (status == nfserr_replay_me) {
struct nfs4_replay *rp = &open->op_stateowner->so_replay;
- fh_put(current_fh);
- current_fh->fh_handle.fh_size = rp->rp_openfh_len;
- memcpy(&current_fh->fh_handle.fh_base, rp->rp_openfh,
+ fh_put(&cstate->current_fh);
+ cstate->current_fh.fh_handle.fh_size = rp->rp_openfh_len;
+ memcpy(&cstate->current_fh.fh_handle.fh_base, rp->rp_openfh,
rp->rp_openfh_len);
- status = fh_verify(rqstp, current_fh, 0, MAY_NOP);
+ status = fh_verify(rqstp, &cstate->current_fh, 0, MAY_NOP);
if (status)
dprintk("nfsd4_open: replay failed"
" restoring previous filehandle\n");
@@ -215,7 +209,8 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open
* (3) set open->op_truncate if the file is to be
* truncated after opening, (4) do permission checking.
*/
- status = do_open_lookup(rqstp, current_fh, open);
+ status = do_open_lookup(rqstp, &cstate->current_fh,
+ open);
if (status)
goto out;
break;
@@ -227,7 +222,8 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open
* open->op_truncate if the file is to be truncated
* after opening, (3) do permission checking.
*/
- status = do_open_fhandle(rqstp, current_fh, open);
+ status = do_open_fhandle(rqstp, &cstate->current_fh,
+ open);
if (status)
goto out;
break;
@@ -248,11 +244,11 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open
* successful, it (1) truncates the file if open->op_truncate was
* set, (2) sets open->op_stateid, (3) sets open->op_delegation.
*/
- status = nfsd4_process_open2(rqstp, current_fh, open);
+ status = nfsd4_process_open2(rqstp, &cstate->current_fh, open);
out:
if (open->op_stateowner) {
nfs4_get_stateowner(open->op_stateowner);
- *replay_owner = open->op_stateowner;
+ cstate->replay_owner = open->op_stateowner;
}
nfs4_unlock_state();
return status;
@@ -261,71 +257,80 @@ out:
/*
* filehandle-manipulating ops.
*/
-static inline __be32
-nfsd4_getfh(struct svc_fh *current_fh, struct svc_fh **getfh)
+static __be32
+nfsd4_getfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ struct svc_fh **getfh)
{
- if (!current_fh->fh_dentry)
+ if (!cstate->current_fh.fh_dentry)
return nfserr_nofilehandle;
- *getfh = current_fh;
+ *getfh = &cstate->current_fh;
return nfs_ok;
}
-static inline __be32
-nfsd4_putfh(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_putfh *putfh)
+static __be32
+nfsd4_putfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ struct nfsd4_putfh *putfh)
{
- fh_put(current_fh);
- current_fh->fh_handle.fh_size = putfh->pf_fhlen;
- memcpy(&current_fh->fh_handle.fh_base, putfh->pf_fhval, putfh->pf_fhlen);
- return fh_verify(rqstp, current_fh, 0, MAY_NOP);
+ fh_put(&cstate->current_fh);
+ cstate->current_fh.fh_handle.fh_size = putfh->pf_fhlen;
+ memcpy(&cstate->current_fh.fh_handle.fh_base, putfh->pf_fhval,
+ putfh->pf_fhlen);
+ return fh_verify(rqstp, &cstate->current_fh, 0, MAY_NOP);
}
-static inline __be32
-nfsd4_putrootfh(struct svc_rqst *rqstp, struct svc_fh *current_fh)
+static __be32
+nfsd4_putrootfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ void *arg)
{
__be32 status;
- fh_put(current_fh);
- status = exp_pseudoroot(rqstp->rq_client, current_fh,
+ fh_put(&cstate->current_fh);
+ status = exp_pseudoroot(rqstp->rq_client, &cstate->current_fh,
&rqstp->rq_chandle);
return status;
}
-static inline __be32
-nfsd4_restorefh(struct svc_fh *current_fh, struct svc_fh *save_fh)
+static __be32
+nfsd4_restorefh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ void *arg)
{
- if (!save_fh->fh_dentry)
+ if (!cstate->save_fh.fh_dentry)
return nfserr_restorefh;
- fh_dup2(current_fh, save_fh);
+ fh_dup2(&cstate->current_fh, &cstate->save_fh);
return nfs_ok;
}
-static inline __be32
-nfsd4_savefh(struct svc_fh *current_fh, struct svc_fh *save_fh)
+static __be32
+nfsd4_savefh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ void *arg)
{
- if (!current_fh->fh_dentry)
+ if (!cstate->current_fh.fh_dentry)
return nfserr_nofilehandle;
- fh_dup2(save_fh, current_fh);
+ fh_dup2(&cstate->save_fh, &cstate->current_fh);
return nfs_ok;
}
/*
* misc nfsv4 ops
*/
-static inline __be32
-nfsd4_access(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_access *access)
+static __be32
+nfsd4_access(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ struct nfsd4_access *access)
{
if (access->ac_req_access & ~NFS3_ACCESS_FULL)
return nfserr_inval;
access->ac_resp_access = access->ac_req_access;
- return nfsd_access(rqstp, current_fh, &access->ac_resp_access, &access->ac_supported);
+ return nfsd_access(rqstp, &cstate->current_fh, &access->ac_resp_access,
+ &access->ac_supported);
}
-static inline __be32
-nfsd4_commit(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_commit *commit)
+static __be32
+nfsd4_commit(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ struct nfsd4_commit *commit)
{
__be32 status;
@@ -333,14 +338,16 @@ nfsd4_commit(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_com
*p++ = nfssvc_boot.tv_sec;
*p++ = nfssvc_boot.tv_usec;
- status = nfsd_commit(rqstp, current_fh, commit->co_offset, commit->co_count);
+ status = nfsd_commit(rqstp, &cstate->current_fh, commit->co_offset,
+ commit->co_count);
if (status == nfserr_symlink)
status = nfserr_inval;
return status;
}
static __be32
-nfsd4_create(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_create *create)
+nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ struct nfsd4_create *create)
{
struct svc_fh resfh;
__be32 status;
@@ -348,7 +355,7 @@ nfsd4_create(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_cre
fh_init(&resfh, NFS4_FHSIZE);
- status = fh_verify(rqstp, current_fh, S_IFDIR, MAY_CREATE);
+ status = fh_verify(rqstp, &cstate->current_fh, S_IFDIR, MAY_CREATE);
if (status == nfserr_symlink)
status = nfserr_notdir;
if (status)
@@ -365,9 +372,10 @@ nfsd4_create(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_cre
*/
create->cr_linkname[create->cr_linklen] = 0;
- status = nfsd_symlink(rqstp, current_fh, create->cr_name,
- create->cr_namelen, create->cr_linkname,
- create->cr_linklen, &resfh, &create->cr_iattr);
+ status = nfsd_symlink(rqstp, &cstate->current_fh,
+ create->cr_name, create->cr_namelen,
+ create->cr_linkname, create->cr_linklen,
+ &resfh, &create->cr_iattr);
break;
case NF4BLK:
@@ -375,9 +383,9 @@ nfsd4_create(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_cre
if (MAJOR(rdev) != create->cr_specdata1 ||
MINOR(rdev) != create->cr_specdata2)
return nfserr_inval;
- status = nfsd_create(rqstp, current_fh, create->cr_name,
- create->cr_namelen, &create->cr_iattr,
- S_IFBLK, rdev, &resfh);
+ status = nfsd_create(rqstp, &cstate->current_fh,
+ create->cr_name, create->cr_namelen,
+ &create->cr_iattr, S_IFBLK, rdev, &resfh);
break;
case NF4CHR:
@@ -385,28 +393,28 @@ nfsd4_create(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_cre
if (MAJOR(rdev) != create->cr_specdata1 ||
MINOR(rdev) != create->cr_specdata2)
return nfserr_inval;
- status = nfsd_create(rqstp, current_fh, create->cr_name,
- create->cr_namelen, &create->cr_iattr,
- S_IFCHR, rdev, &resfh);
+ status = nfsd_create(rqstp, &cstate->current_fh,
+ create->cr_name, create->cr_namelen,
+ &create->cr_iattr,S_IFCHR, rdev, &resfh);
break;
case NF4SOCK:
- status = nfsd_create(rqstp, current_fh, create->cr_name,
- create->cr_namelen, &create->cr_iattr,
- S_IFSOCK, 0, &resfh);
+ status = nfsd_create(rqstp, &cstate->current_fh,
+ create->cr_name, create->cr_namelen,
+ &create->cr_iattr, S_IFSOCK, 0, &resfh);
break;
case NF4FIFO:
- status = nfsd_create(rqstp, current_fh, create->cr_name,
- create->cr_namelen, &create->cr_iattr,
- S_IFIFO, 0, &resfh);
+ status = nfsd_create(rqstp, &cstate->current_fh,
+ create->cr_name, create->cr_namelen,
+ &create->cr_iattr, S_IFIFO, 0, &resfh);
break;
case NF4DIR:
create->cr_iattr.ia_valid &= ~ATTR_SIZE;
- status = nfsd_create(rqstp, current_fh, create->cr_name,
- create->cr_namelen, &create->cr_iattr,
- S_IFDIR, 0, &resfh);
+ status = nfsd_create(rqstp, &cstate->current_fh,
+ create->cr_name, create->cr_namelen,
+ &create->cr_iattr, S_IFDIR, 0, &resfh);
break;
default:
@@ -414,21 +422,22 @@ nfsd4_create(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_cre
}
if (!status) {
- fh_unlock(current_fh);
- set_change_info(&create->cr_cinfo, current_fh);
- fh_dup2(current_fh, &resfh);
+ fh_unlock(&cstate->current_fh);
+ set_change_info(&create->cr_cinfo, &cstate->current_fh);
+ fh_dup2(&cstate->current_fh, &resfh);
}
fh_put(&resfh);
return status;
}
-static inline __be32
-nfsd4_getattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_getattr *getattr)
+static __be32
+nfsd4_getattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ struct nfsd4_getattr *getattr)
{
__be32 status;
- status = fh_verify(rqstp, current_fh, 0, MAY_NOP);
+ status = fh_verify(rqstp, &cstate->current_fh, 0, MAY_NOP);
if (status)
return status;
@@ -438,26 +447,28 @@ nfsd4_getattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_ge
getattr->ga_bmval[0] &= NFSD_SUPPORTED_ATTRS_WORD0;
getattr->ga_bmval[1] &= NFSD_SUPPORTED_ATTRS_WORD1;
- getattr->ga_fhp = current_fh;
+ getattr->ga_fhp = &cstate->current_fh;
return nfs_ok;
}
-static inline __be32
-nfsd4_link(struct svc_rqst *rqstp, struct svc_fh *current_fh,
- struct svc_fh *save_fh, struct nfsd4_link *link)
+static __be32
+nfsd4_link(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ struct nfsd4_link *link)
{
__be32 status = nfserr_nofilehandle;
- if (!save_fh->fh_dentry)
+ if (!cstate->save_fh.fh_dentry)
return status;
- status = nfsd_link(rqstp, current_fh, link->li_name, link->li_namelen, save_fh);
+ status = nfsd_link(rqstp, &cstate->current_fh,
+ link->li_name, link->li_namelen, &cstate->save_fh);
if (!status)
- set_change_info(&link->li_cinfo, current_fh);
+ set_change_info(&link->li_cinfo, &cstate->current_fh);
return status;
}
static __be32
-nfsd4_lookupp(struct svc_rqst *rqstp, struct svc_fh *current_fh)
+nfsd4_lookupp(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ void *arg)
{
struct svc_fh tmp_fh;
__be32 ret;
@@ -466,22 +477,27 @@ nfsd4_lookupp(struct svc_rqst *rqstp, struct svc_fh *current_fh)
if((ret = exp_pseudoroot(rqstp->rq_client, &tmp_fh,
&rqstp->rq_chandle)) != 0)
return ret;
- if (tmp_fh.fh_dentry == current_fh->fh_dentry) {
+ if (tmp_fh.fh_dentry == cstate->current_fh.fh_dentry) {
fh_put(&tmp_fh);
return nfserr_noent;
}
fh_put(&tmp_fh);
- return nfsd_lookup(rqstp, current_fh, "..", 2, current_fh);
+ return nfsd_lookup(rqstp, &cstate->current_fh,
+ "..", 2, &cstate->current_fh);
}
-static inline __be32
-nfsd4_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lookup *lookup)
+static __be32
+nfsd4_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ struct nfsd4_lookup *lookup)
{
- return nfsd_lookup(rqstp, current_fh, lookup->lo_name, lookup->lo_len, current_fh);
+ return nfsd_lookup(rqstp, &cstate->current_fh,
+ lookup->lo_name, lookup->lo_len,
+ &cstate->current_fh);
}
-static inline __be32
-nfsd4_read(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_read *read)
+static __be32
+nfsd4_read(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ struct nfsd4_read *read)
{
__be32 status;
@@ -493,7 +509,8 @@ nfsd4_read(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_read
nfs4_lock_state();
/* check stateid */
- if ((status = nfs4_preprocess_stateid_op(current_fh, &read->rd_stateid,
+ if ((status = nfs4_preprocess_stateid_op(&cstate->current_fh,
+ &read->rd_stateid,
CHECK_FH | RD_STATE, &read->rd_filp))) {
dprintk("NFSD: nfsd4_read: couldn't process stateid!\n");
goto out;
@@ -504,12 +521,13 @@ nfsd4_read(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_read
out:
nfs4_unlock_state();
read->rd_rqstp = rqstp;
- read->rd_fhp = current_fh;
+ read->rd_fhp = &cstate->current_fh;
return status;
}
-static inline __be32
-nfsd4_readdir(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_readdir *readdir)
+static __be32
+nfsd4_readdir(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ struct nfsd4_readdir *readdir)
{
u64 cookie = readdir->rd_cookie;
static const nfs4_verifier zeroverf;
@@ -527,48 +545,51 @@ nfsd4_readdir(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_re
return nfserr_bad_cookie;
readdir->rd_rqstp = rqstp;
- readdir->rd_fhp = current_fh;
+ readdir->rd_fhp = &cstate->current_fh;
return nfs_ok;
}
-static inline __be32
-nfsd4_readlink(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_readlink *readlink)
+static __be32
+nfsd4_readlink(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ struct nfsd4_readlink *readlink)
{
readlink->rl_rqstp = rqstp;
- readlink->rl_fhp = current_fh;
+ readlink->rl_fhp = &cstate->current_fh;
return nfs_ok;
}
-static inline __be32
-nfsd4_remove(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_remove *remove)
+static __be32
+nfsd4_remove(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ struct nfsd4_remove *remove)
{
__be32 status;
if (nfs4_in_grace())
return nfserr_grace;
- status = nfsd_unlink(rqstp, current_fh, 0, remove->rm_name, remove->rm_namelen);
+ status = nfsd_unlink(rqstp, &cstate->current_fh, 0,
+ remove->rm_name, remove->rm_namelen);
if (status == nfserr_symlink)
return nfserr_notdir;
if (!status) {
- fh_unlock(current_fh);
- set_change_info(&remove->rm_cinfo, current_fh);
+ fh_unlock(&cstate->current_fh);
+ set_change_info(&remove->rm_cinfo, &cstate->current_fh);
}
return status;
}
-static inline __be32
-nfsd4_rename(struct svc_rqst *rqstp, struct svc_fh *current_fh,
- struct svc_fh *save_fh, struct nfsd4_rename *rename)
+static __be32
+nfsd4_rename(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ struct nfsd4_rename *rename)
{
__be32 status = nfserr_nofilehandle;
- if (!save_fh->fh_dentry)
+ if (!cstate->save_fh.fh_dentry)
return status;
- if (nfs4_in_grace() && !(save_fh->fh_export->ex_flags
+ if (nfs4_in_grace() && !(cstate->save_fh.fh_export->ex_flags
& NFSEXP_NOSUBTREECHECK))
return nfserr_grace;
- status = nfsd_rename(rqstp, save_fh, rename->rn_sname,
- rename->rn_snamelen, current_fh,
+ status = nfsd_rename(rqstp, &cstate->save_fh, rename->rn_sname,
+ rename->rn_snamelen, &cstate->current_fh,
rename->rn_tname, rename->rn_tnamelen);
/* the underlying filesystem returns different error's than required
@@ -576,27 +597,28 @@ nfsd4_rename(struct svc_rqst *rqstp, struct svc_fh *current_fh,
if (status == nfserr_isdir)
status = nfserr_exist;
else if ((status == nfserr_notdir) &&
- (S_ISDIR(save_fh->fh_dentry->d_inode->i_mode) &&
- S_ISDIR(current_fh->fh_dentry->d_inode->i_mode)))
+ (S_ISDIR(cstate->save_fh.fh_dentry->d_inode->i_mode) &&
+ S_ISDIR(cstate->current_fh.fh_dentry->d_inode->i_mode)))
status = nfserr_exist;
else if (status == nfserr_symlink)
status = nfserr_notdir;
if (!status) {
- set_change_info(&rename->rn_sinfo, current_fh);
- set_change_info(&rename->rn_tinfo, save_fh);
+ set_change_info(&rename->rn_sinfo, &cstate->current_fh);
+ set_change_info(&rename->rn_tinfo, &cstate->save_fh);
}
return status;
}
-static inline __be32
-nfsd4_setattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_setattr *setattr)
+static __be32
+nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ struct nfsd4_setattr *setattr)
{
__be32 status = nfs_ok;
if (setattr->sa_iattr.ia_valid & ATTR_SIZE) {
nfs4_lock_state();
- status = nfs4_preprocess_stateid_op(current_fh,
+ status = nfs4_preprocess_stateid_op(&cstate->current_fh,
&setattr->sa_stateid, CHECK_FH | WR_STATE, NULL);
nfs4_unlock_state();
if (status) {
@@ -606,16 +628,18 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_se
}
status = nfs_ok;
if (setattr->sa_acl != NULL)
- status = nfsd4_set_nfs4_acl(rqstp, current_fh, setattr->sa_acl);
+ status = nfsd4_set_nfs4_acl(rqstp, &cstate->current_fh,
+ setattr->sa_acl);
if (status)
return status;
- status = nfsd_setattr(rqstp, current_fh, &setattr->sa_iattr,
+ status = nfsd_setattr(rqstp, &cstate->current_fh, &setattr->sa_iattr,
0, (time_t)0);
return status;
}
-static inline __be32
-nfsd4_write(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_write *write)
+static __be32
+nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ struct nfsd4_write *write)
{
stateid_t *stateid = &write->wr_stateid;
struct file *filp = NULL;
@@ -628,7 +652,7 @@ nfsd4_write(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_writ
return nfserr_inval;
nfs4_lock_state();
- status = nfs4_preprocess_stateid_op(current_fh, stateid,
+ status = nfs4_preprocess_stateid_op(&cstate->current_fh, stateid,
CHECK_FH | WR_STATE, &filp);
if (filp)
get_file(filp);
@@ -645,9 +669,9 @@ nfsd4_write(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_writ
*p++ = nfssvc_boot.tv_sec;
*p++ = nfssvc_boot.tv_usec;
- status = nfsd_write(rqstp, current_fh, filp, write->wr_offset,
- rqstp->rq_vec, write->wr_vlen, write->wr_buflen,
- &write->wr_how_written);
+ status = nfsd_write(rqstp, &cstate->current_fh, filp,
+ write->wr_offset, rqstp->rq_vec, write->wr_vlen,
+ write->wr_buflen, &write->wr_how_written);
if (filp)
fput(filp);
@@ -662,13 +686,14 @@ nfsd4_write(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_writ
* to NFS_OK after the call; NVERIFY by mapping NFSERR_NOT_SAME to NFS_OK.
*/
static __be32
-nfsd4_verify(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_verify *verify)
+_nfsd4_verify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ struct nfsd4_verify *verify)
{
__be32 *buf, *p;
int count;
__be32 status;
- status = fh_verify(rqstp, current_fh, 0, MAY_NOP);
+ status = fh_verify(rqstp, &cstate->current_fh, 0, MAY_NOP);
if (status)
return status;
@@ -689,8 +714,9 @@ nfsd4_verify(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_ver
if (!buf)
return nfserr_resource;
- status = nfsd4_encode_fattr(current_fh, current_fh->fh_export,
- current_fh->fh_dentry, buf,
+ status = nfsd4_encode_fattr(&cstate->current_fh,
+ cstate->current_fh.fh_export,
+ cstate->current_fh.fh_dentry, buf,
&count, verify->ve_bmval,
rqstp);
@@ -712,6 +738,26 @@ out_kfree:
return status;
}
+static __be32
+nfsd4_nverify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ struct nfsd4_verify *verify)
+{
+ __be32 status;
+
+ status = _nfsd4_verify(rqstp, cstate, verify);
+ return status == nfserr_not_same ? nfs_ok : status;
+}
+
+static __be32
+nfsd4_verify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ struct nfsd4_verify *verify)
+{
+ __be32 status;
+
+ status = _nfsd4_verify(rqstp, cstate, verify);
+ return status == nfserr_same ? nfs_ok : status;
+}
+
/*
* NULL call.
*/
@@ -727,6 +773,42 @@ static inline void nfsd4_increment_op_stats(u32 opnum)
nfsdstats.nfs4_opcount[opnum]++;
}
+static void cstate_free(struct nfsd4_compound_state *cstate)
+{
+ if (cstate == NULL)
+ return;
+ fh_put(&cstate->current_fh);
+ fh_put(&cstate->save_fh);
+ BUG_ON(cstate->replay_owner);
+ kfree(cstate);
+}
+
+static struct nfsd4_compound_state *cstate_alloc(void)
+{
+ struct nfsd4_compound_state *cstate;
+
+ cstate = kmalloc(sizeof(struct nfsd4_compound_state), GFP_KERNEL);
+ if (cstate == NULL)
+ return NULL;
+ fh_init(&cstate->current_fh, NFS4_FHSIZE);
+ fh_init(&cstate->save_fh, NFS4_FHSIZE);
+ cstate->replay_owner = NULL;
+ return cstate;
+}
+
+typedef __be32(*nfsd4op_func)(struct svc_rqst *, struct nfsd4_compound_state *,
+ void *);
+
+struct nfsd4_operation {
+ nfsd4op_func op_func;
+ u32 op_flags;
+/* Most ops require a valid current filehandle; a few don't: */
+#define ALLOWED_WITHOUT_FH 1
+/* GETATTR and ops not listed as returning NFS4ERR_MOVED: */
+#define ALLOWED_ON_ABSENT_FS 2
+};
+
+static struct nfsd4_operation nfsd4_ops[];
/*
* COMPOUND call.
@@ -737,21 +819,15 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
struct nfsd4_compoundres *resp)
{
struct nfsd4_op *op;
- struct svc_fh *current_fh = NULL;
- struct svc_fh *save_fh = NULL;
- struct nfs4_stateowner *replay_owner = NULL;
- int slack_space; /* in words, not bytes! */
+ struct nfsd4_operation *opdesc;
+ struct nfsd4_compound_state *cstate = NULL;
+ int slack_bytes;
__be32 status;
status = nfserr_resource;
- current_fh = kmalloc(sizeof(*current_fh), GFP_KERNEL);
- if (current_fh == NULL)
- goto out;
- fh_init(current_fh, NFS4_FHSIZE);
- save_fh = kmalloc(sizeof(*save_fh), GFP_KERNEL);
- if (save_fh == NULL)
+ cstate = cstate_alloc();
+ if (cstate == NULL)
goto out;
- fh_init(save_fh, NFS4_FHSIZE);
resp->xbuf = &rqstp->rq_res;
resp->p = rqstp->rq_res.head[0].iov_base + rqstp->rq_res.head[0].iov_len;
@@ -790,164 +866,44 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
* failed response to the next operation. If we don't
* have enough room, fail with ERR_RESOURCE.
*/
-/* FIXME - is slack_space *really* words, or bytes??? - neilb */
- slack_space = (char *)resp->end - (char *)resp->p;
- if (slack_space < COMPOUND_SLACK_SPACE + COMPOUND_ERR_SLACK_SPACE) {
- BUG_ON(slack_space < COMPOUND_ERR_SLACK_SPACE);
+ slack_bytes = (char *)resp->end - (char *)resp->p;
+ if (slack_bytes < COMPOUND_SLACK_SPACE
+ + COMPOUND_ERR_SLACK_SPACE) {
+ BUG_ON(slack_bytes < COMPOUND_ERR_SLACK_SPACE);
op->status = nfserr_resource;
goto encode_op;
}
- /* All operations except RENEW, SETCLIENTID, RESTOREFH
- * SETCLIENTID_CONFIRM, PUTFH and PUTROOTFH
- * require a valid current filehandle
- */
- if (!current_fh->fh_dentry) {
- if (!((op->opnum == OP_PUTFH) ||
- (op->opnum == OP_PUTROOTFH) ||
- (op->opnum == OP_SETCLIENTID) ||
- (op->opnum == OP_SETCLIENTID_CONFIRM) ||
- (op->opnum == OP_RENEW) ||
- (op->opnum == OP_RESTOREFH) ||
- (op->opnum == OP_RELEASE_LOCKOWNER))) {
+ opdesc = &nfsd4_ops[op->opnum];
+
+ if (!cstate->current_fh.fh_dentry) {
+ if (!(opdesc->op_flags & ALLOWED_WITHOUT_FH)) {
op->status = nfserr_nofilehandle;
goto encode_op;
}
- }
- /* Check must be done at start of each operation, except
- * for GETATTR and ops not listed as returning NFS4ERR_MOVED
- */
- else if (current_fh->fh_export->ex_fslocs.migrated &&
- !((op->opnum == OP_GETATTR) ||
- (op->opnum == OP_PUTROOTFH) ||
- (op->opnum == OP_PUTPUBFH) ||
- (op->opnum == OP_RENEW) ||
- (op->opnum == OP_SETCLIENTID) ||
- (op->opnum == OP_RELEASE_LOCKOWNER))) {
+ } else if (cstate->current_fh.fh_export->ex_fslocs.migrated &&
+ !(opdesc->op_flags & ALLOWED_ON_ABSENT_FS)) {
op->status = nfserr_moved;
goto encode_op;
}
- switch (op->opnum) {
- case OP_ACCESS:
- 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);
- break;
- case OP_COMMIT:
- op->status = nfsd4_commit(rqstp, current_fh, &op->u.commit);
- break;
- case OP_CREATE:
- op->status = nfsd4_create(rqstp, current_fh, &op->u.create);
- break;
- case OP_DELEGRETURN:
- op->status = nfsd4_delegreturn(rqstp, current_fh, &op->u.delegreturn);
- break;
- case OP_GETATTR:
- op->status = nfsd4_getattr(rqstp, current_fh, &op->u.getattr);
- break;
- case OP_GETFH:
- op->status = nfsd4_getfh(current_fh, &op->u.getfh);
- break;
- case OP_LINK:
- 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);
- 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);
- break;
- case OP_LOOKUP:
- op->status = nfsd4_lookup(rqstp, current_fh, &op->u.lookup);
- break;
- case OP_LOOKUPP:
- op->status = nfsd4_lookupp(rqstp, current_fh);
- break;
- case OP_NVERIFY:
- op->status = nfsd4_verify(rqstp, current_fh, &op->u.nverify);
- if (op->status == nfserr_not_same)
- op->status = nfs_ok;
- break;
- case OP_OPEN:
- 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);
- break;
- case OP_OPEN_DOWNGRADE:
- 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);
- break;
- case OP_PUTROOTFH:
- op->status = nfsd4_putrootfh(rqstp, current_fh);
- break;
- case OP_READ:
- op->status = nfsd4_read(rqstp, current_fh, &op->u.read);
- break;
- case OP_READDIR:
- op->status = nfsd4_readdir(rqstp, current_fh, &op->u.readdir);
- break;
- case OP_READLINK:
- op->status = nfsd4_readlink(rqstp, current_fh, &op->u.readlink);
- break;
- case OP_REMOVE:
- op->status = nfsd4_remove(rqstp, current_fh, &op->u.remove);
- break;
- case OP_RENAME:
- op->status = nfsd4_rename(rqstp, current_fh, save_fh, &op->u.rename);
- break;
- case OP_RENEW:
- op->status = nfsd4_renew(&op->u.renew);
- break;
- case OP_RESTOREFH:
- op->status = nfsd4_restorefh(current_fh, save_fh);
- break;
- case OP_SAVEFH:
- op->status = nfsd4_savefh(current_fh, save_fh);
- break;
- case OP_SETATTR:
- op->status = nfsd4_setattr(rqstp, current_fh, &op->u.setattr);
- break;
- case OP_SETCLIENTID:
- op->status = nfsd4_setclientid(rqstp, &op->u.setclientid);
- break;
- case OP_SETCLIENTID_CONFIRM:
- op->status = nfsd4_setclientid_confirm(rqstp, &op->u.setclientid_confirm);
- break;
- case OP_VERIFY:
- op->status = nfsd4_verify(rqstp, current_fh, &op->u.verify);
- if (op->status == nfserr_same)
- op->status = nfs_ok;
- break;
- case OP_WRITE:
- op->status = nfsd4_write(rqstp, current_fh, &op->u.write);
- break;
- case OP_RELEASE_LOCKOWNER:
- op->status = nfsd4_release_lockowner(rqstp, &op->u.release_lockowner);
- break;
- default:
+
+ if (opdesc->op_func)
+ op->status = opdesc->op_func(rqstp, cstate, &op->u);
+ else
BUG_ON(op->status == nfs_ok);
- break;
- }
encode_op:
if (op->status == nfserr_replay_me) {
- op->replay = &replay_owner->so_replay;
+ op->replay = &cstate->replay_owner->so_replay;
nfsd4_encode_replay(resp, op);
status = op->status = op->replay->rp_status;
} else {
nfsd4_encode_operation(resp, op);
status = op->status;
}
- if (replay_owner && (replay_owner != (void *)(-1))) {
- nfs4_put_stateowner(replay_owner);
- replay_owner = NULL;
+ if (cstate->replay_owner) {
+ nfs4_put_stateowner(cstate->replay_owner);
+ cstate->replay_owner = NULL;
}
/* XXX Ugh, we need to get rid of this kind of special case: */
if (op->opnum == OP_READ && op->u.read.rd_filp)
@@ -958,15 +914,124 @@ encode_op:
out:
nfsd4_release_compoundargs(args);
- if (current_fh)
- fh_put(current_fh);
- kfree(current_fh);
- if (save_fh)
- fh_put(save_fh);
- kfree(save_fh);
+ cstate_free(cstate);
return status;
}
+static struct nfsd4_operation nfsd4_ops[OP_RELEASE_LOCKOWNER+1] = {
+ [OP_ACCESS] = {
+ .op_func = (nfsd4op_func)nfsd4_access,
+ },
+ [OP_CLOSE] = {
+ .op_func = (nfsd4op_func)nfsd4_close,
+ },
+ [OP_COMMIT] = {
+ .op_func = (nfsd4op_func)nfsd4_commit,
+ },
+ [OP_CREATE] = {
+ .op_func = (nfsd4op_func)nfsd4_create,
+ },
+ [OP_DELEGRETURN] = {
+ .op_func = (nfsd4op_func)nfsd4_delegreturn,
+ },
+ [OP_GETATTR] = {
+ .op_func = (nfsd4op_func)nfsd4_getattr,
+ .op_flags = ALLOWED_ON_ABSENT_FS,
+ },
+ [OP_GETFH] = {
+ .op_func = (nfsd4op_func)nfsd4_getfh,
+ },
+ [OP_LINK] = {
+ .op_func = (nfsd4op_func)nfsd4_link,
+ },
+ [OP_LOCK] = {
+ .op_func = (nfsd4op_func)nfsd4_lock,
+ },
+ [OP_LOCKT] = {
+ .op_func = (nfsd4op_func)nfsd4_lockt,
+ },
+ [OP_LOCKU] = {
+ .op_func = (nfsd4op_func)nfsd4_locku,
+ },
+ [OP_LOOKUP] = {
+ .op_func = (nfsd4op_func)nfsd4_lookup,
+ },
+ [OP_LOOKUPP] = {
+ .op_func = (nfsd4op_func)nfsd4_lookupp,
+ },
+ [OP_NVERIFY] = {
+ .op_func = (nfsd4op_func)nfsd4_nverify,
+ },
+ [OP_OPEN] = {
+ .op_func = (nfsd4op_func)nfsd4_open,
+ },
+ [OP_OPEN_CONFIRM] = {
+ .op_func = (nfsd4op_func)nfsd4_open_confirm,
+ },
+ [OP_OPEN_DOWNGRADE] = {
+ .op_func = (nfsd4op_func)nfsd4_open_downgrade,
+ },
+ [OP_PUTFH] = {
+ .op_func = (nfsd4op_func)nfsd4_putfh,
+ .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS,
+ },
+ [OP_PUTPUBFH] = {
+ /* unsupported; just for future reference: */
+ .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS,
+ },
+ [OP_PUTROOTFH] = {
+ .op_func = (nfsd4op_func)nfsd4_putrootfh,
+ .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS,
+ },
+ [OP_READ] = {
+ .op_func = (nfsd4op_func)nfsd4_read,
+ },
+ [OP_READDIR] = {
+ .op_func = (nfsd4op_func)nfsd4_readdir,
+ },
+ [OP_READLINK] = {
+ .op_func = (nfsd4op_func)nfsd4_readlink,
+ },
+ [OP_REMOVE] = {
+ .op_func = (nfsd4op_func)nfsd4_remove,
+ },
+ [OP_RENAME] = {
+ .op_func = (nfsd4op_func)nfsd4_rename,
+ },
+ [OP_RENEW] = {
+ .op_func = (nfsd4op_func)nfsd4_renew,
+ .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS,
+ },
+ [OP_RESTOREFH] = {
+ .op_func = (nfsd4op_func)nfsd4_restorefh,
+ .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS,
+ },
+ [OP_SAVEFH] = {
+ .op_func = (nfsd4op_func)nfsd4_savefh,
+ },
+ [OP_SETATTR] = {
+ .op_func = (nfsd4op_func)nfsd4_setattr,
+ },
+ [OP_SETCLIENTID] = {
+ .op_func = (nfsd4op_func)nfsd4_setclientid,
+ .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS,
+ },
+ [OP_SETCLIENTID_CONFIRM] = {
+ .op_func = (nfsd4op_func)nfsd4_setclientid_confirm,
+ .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS,
+ },
+ [OP_VERIFY] = {
+ .op_func = (nfsd4op_func)nfsd4_verify,
+ },
+ [OP_WRITE] = {
+ .op_func = (nfsd4op_func)nfsd4_write,
+ },
+ [OP_RELEASE_LOCKOWNER] = {
+ .op_func = (nfsd4op_func)nfsd4_release_lockowner,
+ .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS,
+ },
+};
+
#define nfs4svc_decode_voidargs NULL
#define nfs4svc_release_void NULL
#define nfsd4_voidres nfsd4_voidargs
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index b7179bd45a1e..9de89df961f4 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -711,7 +711,8 @@ out_err:
*
*/
__be32
-nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_setclientid *setclid)
+nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ struct nfsd4_setclientid *setclid)
{
__be32 ip_addr = rqstp->rq_addr.sin_addr.s_addr;
struct xdr_netobj clname = {
@@ -876,7 +877,9 @@ out:
* NOTE: callback information will be processed here in a future patch
*/
__be32
-nfsd4_setclientid_confirm(struct svc_rqst *rqstp, struct nfsd4_setclientid_confirm *setclientid_confirm)
+nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
+ struct nfsd4_compound_state *cstate,
+ struct nfsd4_setclientid_confirm *setclientid_confirm)
{
__be32 ip_addr = rqstp->rq_addr.sin_addr.s_addr;
struct nfs4_client *conf, *unconf;
@@ -1833,7 +1836,8 @@ static void laundromat_main(struct work_struct *);
static DECLARE_DELAYED_WORK(laundromat_work, laundromat_main);
__be32
-nfsd4_renew(clientid_t *clid)
+nfsd4_renew(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ clientid_t *clid)
{
struct nfs4_client *clp;
__be32 status;
@@ -2241,24 +2245,25 @@ check_replay:
}
__be32
-nfsd4_open_confirm(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_confirm *oc, struct nfs4_stateowner **replay_owner)
+nfsd4_open_confirm(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ struct nfsd4_open_confirm *oc)
{
__be32 status;
struct nfs4_stateowner *sop;
struct nfs4_stateid *stp;
dprintk("NFSD: nfsd4_open_confirm on file %.*s\n",
- (int)current_fh->fh_dentry->d_name.len,
- current_fh->fh_dentry->d_name.name);
+ (int)cstate->current_fh.fh_dentry->d_name.len,
+ cstate->current_fh.fh_dentry->d_name.name);
- status = fh_verify(rqstp, current_fh, S_IFREG, 0);
+ status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0);
if (status)
return status;
nfs4_lock_state();
- if ((status = nfs4_preprocess_seqid_op(current_fh, oc->oc_seqid,
- &oc->oc_req_stateid,
+ if ((status = nfs4_preprocess_seqid_op(&cstate->current_fh,
+ oc->oc_seqid, &oc->oc_req_stateid,
CHECK_FH | CONFIRM | OPEN_STATE,
&oc->oc_stateowner, &stp, NULL)))
goto out;
@@ -2278,7 +2283,7 @@ nfsd4_open_confirm(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfs
out:
if (oc->oc_stateowner) {
nfs4_get_stateowner(oc->oc_stateowner);
- *replay_owner = oc->oc_stateowner;
+ cstate->replay_owner = oc->oc_stateowner;
}
nfs4_unlock_state();
return status;
@@ -2310,22 +2315,25 @@ reset_union_bmap_deny(unsigned long deny, unsigned long *bmap)
}
__be32
-nfsd4_open_downgrade(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_downgrade *od, struct nfs4_stateowner **replay_owner)
+nfsd4_open_downgrade(struct svc_rqst *rqstp,
+ struct nfsd4_compound_state *cstate,
+ struct nfsd4_open_downgrade *od)
{
__be32 status;
struct nfs4_stateid *stp;
unsigned int share_access;
dprintk("NFSD: nfsd4_open_downgrade on file %.*s\n",
- (int)current_fh->fh_dentry->d_name.len,
- current_fh->fh_dentry->d_name.name);
+ (int)cstate->current_fh.fh_dentry->d_name.len,
+ cstate->current_fh.fh_dentry->d_name.name);
if (!access_valid(od->od_share_access)
|| !deny_valid(od->od_share_deny))
return nfserr_inval;
nfs4_lock_state();
- if ((status = nfs4_preprocess_seqid_op(current_fh, od->od_seqid,
+ if ((status = nfs4_preprocess_seqid_op(&cstate->current_fh,
+ od->od_seqid,
&od->od_stateid,
CHECK_FH | OPEN_STATE,
&od->od_stateowner, &stp, NULL)))
@@ -2355,7 +2363,7 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct n
out:
if (od->od_stateowner) {
nfs4_get_stateowner(od->od_stateowner);
- *replay_owner = od->od_stateowner;
+ cstate->replay_owner = od->od_stateowner;
}
nfs4_unlock_state();
return status;
@@ -2365,18 +2373,20 @@ out:
* nfs4_unlock_state() called after encode
*/
__be32
-nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_close *close, struct nfs4_stateowner **replay_owner)
+nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ struct nfsd4_close *close)
{
__be32 status;
struct nfs4_stateid *stp;
dprintk("NFSD: nfsd4_close on file %.*s\n",
- (int)current_fh->fh_dentry->d_name.len,
- current_fh->fh_dentry->d_name.name);
+ (int)cstate->current_fh.fh_dentry->d_name.len,
+ cstate->current_fh.fh_dentry->d_name.name);
nfs4_lock_state();
/* check close_lru for replay */
- if ((status = nfs4_preprocess_seqid_op(current_fh, close->cl_seqid,
+ if ((status = nfs4_preprocess_seqid_op(&cstate->current_fh,
+ close->cl_seqid,
&close->cl_stateid,
CHECK_FH | OPEN_STATE | CLOSE_STATE,
&close->cl_stateowner, &stp, NULL)))
@@ -2397,22 +2407,24 @@ nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_clos
out:
if (close->cl_stateowner) {
nfs4_get_stateowner(close->cl_stateowner);
- *replay_owner = close->cl_stateowner;
+ cstate->replay_owner = close->cl_stateowner;
}
nfs4_unlock_state();
return status;
}
__be32
-nfsd4_delegreturn(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_delegreturn *dr)
+nfsd4_delegreturn(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ struct nfsd4_delegreturn *dr)
{
__be32 status;
- if ((status = fh_verify(rqstp, current_fh, S_IFREG, 0)))
+ if ((status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0)))
goto out;
nfs4_lock_state();
- status = nfs4_preprocess_stateid_op(current_fh, &dr->dr_stateid, DELEG_RET, NULL);
+ status = nfs4_preprocess_stateid_op(&cstate->current_fh,
+ &dr->dr_stateid, DELEG_RET, NULL);
nfs4_unlock_state();
out:
return status;
@@ -2635,7 +2647,8 @@ check_lock_length(u64 offset, u64 length)
* LOCK operation
*/
__be32
-nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock *lock, struct nfs4_stateowner **replay_owner)
+nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ struct nfsd4_lock *lock)
{
struct nfs4_stateowner *open_sop = NULL;
struct nfs4_stateowner *lock_sop = NULL;
@@ -2654,7 +2667,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
if (check_lock_length(lock->lk_offset, lock->lk_length))
return nfserr_inval;
- if ((status = fh_verify(rqstp, current_fh, S_IFREG, MAY_LOCK))) {
+ if ((status = fh_verify(rqstp, &cstate->current_fh,
+ S_IFREG, MAY_LOCK))) {
dprintk("NFSD: nfsd4_lock: permission denied!\n");
return status;
}
@@ -2675,7 +2689,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
goto out;
/* validate and update open stateid and open seqid */
- status = nfs4_preprocess_seqid_op(current_fh,
+ status = nfs4_preprocess_seqid_op(&cstate->current_fh,
lock->lk_new_open_seqid,
&lock->lk_new_open_stateid,
CHECK_FH | OPEN_STATE,
@@ -2702,7 +2716,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
goto out;
} else {
/* lock (lock owner + lock stateid) already exists */
- status = nfs4_preprocess_seqid_op(current_fh,
+ status = nfs4_preprocess_seqid_op(&cstate->current_fh,
lock->lk_old_lock_seqid,
&lock->lk_old_lock_stateid,
CHECK_FH | LOCK_STATE,
@@ -2759,7 +2773,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
conflock.fl_ops = NULL;
conflock.fl_lmops = NULL;
err = posix_lock_file_conf(filp, &file_lock, &conflock);
- dprintk("NFSD: nfsd4_lock: posix_lock_file_conf status %d\n",status);
switch (-err) {
case 0: /* success! */
update_stateid(&lock_stp->st_stateid);
@@ -2785,7 +2798,7 @@ out:
release_stateowner(lock_sop);
if (lock->lk_replay_owner) {
nfs4_get_stateowner(lock->lk_replay_owner);
- *replay_owner = lock->lk_replay_owner;
+ cstate->replay_owner = lock->lk_replay_owner;
}
nfs4_unlock_state();
return status;
@@ -2795,7 +2808,8 @@ out:
* LOCKT operation
*/
__be32
-nfsd4_lockt(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lockt *lockt)
+nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ struct nfsd4_lockt *lockt)
{
struct inode *inode;
struct file file;
@@ -2816,14 +2830,14 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
if (STALE_CLIENTID(&lockt->lt_clientid))
goto out;
- if ((status = fh_verify(rqstp, current_fh, S_IFREG, 0))) {
+ if ((status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0))) {
dprintk("NFSD: nfsd4_lockt: fh_verify() failed!\n");
if (status == nfserr_symlink)
status = nfserr_inval;
goto out;
}
- inode = current_fh->fh_dentry->d_inode;
+ inode = cstate->current_fh.fh_dentry->d_inode;
locks_init_lock(&file_lock);
switch (lockt->lt_type) {
case NFS4_READ_LT:
@@ -2862,7 +2876,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
* only the dentry:inode set.
*/
memset(&file, 0, sizeof (struct file));
- file.f_path.dentry = current_fh->fh_dentry;
+ file.f_path.dentry = cstate->current_fh.fh_dentry;
status = nfs_ok;
if (posix_test_lock(&file, &file_lock, &conflock)) {
@@ -2875,7 +2889,8 @@ out:
}
__be32
-nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_locku *locku, struct nfs4_stateowner **replay_owner)
+nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ struct nfsd4_locku *locku)
{
struct nfs4_stateid *stp;
struct file *filp = NULL;
@@ -2892,7 +2907,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
nfs4_lock_state();
- if ((status = nfs4_preprocess_seqid_op(current_fh,
+ if ((status = nfs4_preprocess_seqid_op(&cstate->current_fh,
locku->lu_seqid,
&locku->lu_stateid,
CHECK_FH | LOCK_STATE,
@@ -2933,7 +2948,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
out:
if (locku->lu_stateowner) {
nfs4_get_stateowner(locku->lu_stateowner);
- *replay_owner = locku->lu_stateowner;
+ cstate->replay_owner = locku->lu_stateowner;
}
nfs4_unlock_state();
return status;
@@ -2968,7 +2983,9 @@ out:
}
__be32
-nfsd4_release_lockowner(struct svc_rqst *rqstp, struct nfsd4_release_lockowner *rlockowner)
+nfsd4_release_lockowner(struct svc_rqst *rqstp,
+ struct nfsd4_compound_state *cstate,
+ struct nfsd4_release_lockowner *rlockowner)
{
clientid_t *clid = &rlockowner->rl_clientid;
struct nfs4_stateowner *sop;
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index f3f239db04bb..fea46368afb2 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1845,15 +1845,11 @@ nfsd4_encode_dirent_fattr(struct nfsd4_readdir *cd,
exp_get(exp);
if (d_mountpoint(dentry)) {
- if (nfsd_cross_mnt(cd->rd_rqstp, &dentry, &exp)) {
- /*
- * -EAGAIN is the only error returned from
- * nfsd_cross_mnt() and it indicates that an
- * up-call has been initiated to fill in the export
- * options on exp. When the answer comes back,
- * this call will be retried.
- */
- nfserr = nfserr_dropit;
+ int err;
+
+ err = nfsd_cross_mnt(cd->rd_rqstp, &dentry, &exp);
+ if (err) {
+ nfserr = nfserrno(err);
goto out_put;
}
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
index 727ab3bd450d..b06bf9f70efc 100644
--- a/fs/nfsd/nfsfh.c
+++ b/fs/nfsd/nfsfh.c
@@ -169,9 +169,11 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
exp = exp_find(rqstp->rq_client, 0, tfh, &rqstp->rq_chandle);
}
- error = nfserr_dropit;
- if (IS_ERR(exp) && PTR_ERR(exp) == -EAGAIN)
+ if (IS_ERR(exp) && (PTR_ERR(exp) == -EAGAIN
+ || PTR_ERR(exp) == -ETIMEDOUT)) {
+ error = nfserrno(PTR_ERR(exp));
goto out;
+ }
error = nfserr_stale;
if (!exp || IS_ERR(exp))
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 4883d7586229..7a79c23aa6d4 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -99,7 +99,7 @@ static struct raparm_hbucket raparm_hash[RAPARM_HASH_SIZE];
/*
* Called from nfsd_lookup and encode_dirent. Check if we have crossed
* a mount point.
- * Returns -EAGAIN leaving *dpp and *expp unchanged,
+ * Returns -EAGAIN or -ETIMEDOUT leaving *dpp and *expp unchanged,
* or nfs_ok having possibly changed *dpp and *expp
*/
int
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
index edc91ca3792a..f27e5378caf2 100644
--- a/fs/ocfs2/alloc.c
+++ b/fs/ocfs2/alloc.c
@@ -1959,7 +1959,7 @@ int ocfs2_prepare_truncate(struct ocfs2_super *osb,
goto bail;
}
- *tc = kcalloc(1, sizeof(struct ocfs2_truncate_context), GFP_KERNEL);
+ *tc = kzalloc(sizeof(struct ocfs2_truncate_context), GFP_KERNEL);
if (!(*tc)) {
status = -ENOMEM;
mlog_errno(status);
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index ef6cd30108a9..93628b02ef5d 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -540,8 +540,7 @@ static int ocfs2_direct_IO_get_blocks(struct inode *inode, sector_t iblock,
struct buffer_head *bh_result, int create)
{
int ret;
- u64 vbo_max; /* file offset, max_blocks from iblock */
- u64 p_blkno;
+ u64 p_blkno, inode_blocks;
int contig_blocks;
unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits;
unsigned long max_blocks = bh_result->b_size >> inode->i_blkbits;
@@ -550,12 +549,23 @@ static int ocfs2_direct_IO_get_blocks(struct inode *inode, sector_t iblock,
* nicely aligned and of the right size, so there's no need
* for us to check any of that. */
- vbo_max = ((u64)iblock + max_blocks) << blocksize_bits;
-
spin_lock(&OCFS2_I(inode)->ip_lock);
- if ((iblock + max_blocks) >
- ocfs2_clusters_to_blocks(inode->i_sb,
- OCFS2_I(inode)->ip_clusters)) {
+ inode_blocks = ocfs2_clusters_to_blocks(inode->i_sb,
+ OCFS2_I(inode)->ip_clusters);
+
+ /*
+ * For a read which begins past the end of file, we return a hole.
+ */
+ if (!create && (iblock >= inode_blocks)) {
+ spin_unlock(&OCFS2_I(inode)->ip_lock);
+ ret = 0;
+ goto bail;
+ }
+
+ /*
+ * Any write past EOF is not allowed because we'd be extending.
+ */
+ if (create && (iblock + max_blocks) > inode_blocks) {
spin_unlock(&OCFS2_I(inode)->ip_lock);
ret = -EIO;
goto bail;
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c
index 4cd9a9580456..277ca67a2ad6 100644
--- a/fs/ocfs2/cluster/heartbeat.c
+++ b/fs/ocfs2/cluster/heartbeat.c
@@ -1447,6 +1447,15 @@ out:
return ret;
}
+static ssize_t o2hb_region_pid_read(struct o2hb_region *reg,
+ char *page)
+{
+ if (!reg->hr_task)
+ return 0;
+
+ return sprintf(page, "%u\n", reg->hr_task->pid);
+}
+
struct o2hb_region_attribute {
struct configfs_attribute attr;
ssize_t (*show)(struct o2hb_region *, char *);
@@ -1485,11 +1494,19 @@ static struct o2hb_region_attribute o2hb_region_attr_dev = {
.store = o2hb_region_dev_write,
};
+static struct o2hb_region_attribute o2hb_region_attr_pid = {
+ .attr = { .ca_owner = THIS_MODULE,
+ .ca_name = "pid",
+ .ca_mode = S_IRUGO | S_IRUSR },
+ .show = o2hb_region_pid_read,
+};
+
static struct configfs_attribute *o2hb_region_attrs[] = {
&o2hb_region_attr_block_bytes.attr,
&o2hb_region_attr_start_block.attr,
&o2hb_region_attr_blocks.attr,
&o2hb_region_attr_dev.attr,
+ &o2hb_region_attr_pid.attr,
NULL,
};
@@ -1553,7 +1570,7 @@ static struct config_item *o2hb_heartbeat_group_make_item(struct config_group *g
struct o2hb_region *reg = NULL;
struct config_item *ret = NULL;
- reg = kcalloc(1, sizeof(struct o2hb_region), GFP_KERNEL);
+ reg = kzalloc(sizeof(struct o2hb_region), GFP_KERNEL);
if (reg == NULL)
goto out; /* ENOMEM */
@@ -1679,7 +1696,7 @@ struct config_group *o2hb_alloc_hb_set(void)
struct o2hb_heartbeat_group *hs = NULL;
struct config_group *ret = NULL;
- hs = kcalloc(1, sizeof(struct o2hb_heartbeat_group), GFP_KERNEL);
+ hs = kzalloc(sizeof(struct o2hb_heartbeat_group), GFP_KERNEL);
if (hs == NULL)
goto out;
diff --git a/fs/ocfs2/cluster/nodemanager.c b/fs/ocfs2/cluster/nodemanager.c
index 357f1d551771..b17333a0606b 100644
--- a/fs/ocfs2/cluster/nodemanager.c
+++ b/fs/ocfs2/cluster/nodemanager.c
@@ -714,7 +714,7 @@ static struct config_item *o2nm_node_group_make_item(struct config_group *group,
if (strlen(name) > O2NM_MAX_NAME_LEN)
goto out; /* ENAMETOOLONG */
- node = kcalloc(1, sizeof(struct o2nm_node), GFP_KERNEL);
+ node = kzalloc(sizeof(struct o2nm_node), GFP_KERNEL);
if (node == NULL)
goto out; /* ENOMEM */
@@ -825,8 +825,8 @@ static struct config_group *o2nm_cluster_group_make_group(struct config_group *g
if (o2nm_single_cluster)
goto out; /* ENOSPC */
- cluster = kcalloc(1, sizeof(struct o2nm_cluster), GFP_KERNEL);
- ns = kcalloc(1, sizeof(struct o2nm_node_group), GFP_KERNEL);
+ cluster = kzalloc(sizeof(struct o2nm_cluster), GFP_KERNEL);
+ ns = kzalloc(sizeof(struct o2nm_node_group), GFP_KERNEL);
defs = kcalloc(3, sizeof(struct config_group *), GFP_KERNEL);
o2hb_group = o2hb_alloc_hb_set();
if (cluster == NULL || ns == NULL || o2hb_group == NULL || defs == NULL)
diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c
index 457753df1ae7..ae4ff4a6636b 100644
--- a/fs/ocfs2/cluster/tcp.c
+++ b/fs/ocfs2/cluster/tcp.c
@@ -324,7 +324,7 @@ static struct o2net_sock_container *sc_alloc(struct o2nm_node *node)
struct page *page = NULL;
page = alloc_page(GFP_NOFS);
- sc = kcalloc(1, sizeof(*sc), GFP_NOFS);
+ sc = kzalloc(sizeof(*sc), GFP_NOFS);
if (sc == NULL || page == NULL)
goto out;
@@ -714,7 +714,7 @@ int o2net_register_handler(u32 msg_type, u32 key, u32 max_len,
goto out;
}
- nmh = kcalloc(1, sizeof(struct o2net_msg_handler), GFP_NOFS);
+ nmh = kzalloc(sizeof(struct o2net_msg_handler), GFP_NOFS);
if (nmh == NULL) {
ret = -ENOMEM;
goto out;
@@ -1918,9 +1918,9 @@ int o2net_init(void)
o2quo_init();
- o2net_hand = kcalloc(1, sizeof(struct o2net_handshake), GFP_KERNEL);
- o2net_keep_req = kcalloc(1, sizeof(struct o2net_msg), GFP_KERNEL);
- o2net_keep_resp = kcalloc(1, sizeof(struct o2net_msg), GFP_KERNEL);
+ o2net_hand = kzalloc(sizeof(struct o2net_handshake), GFP_KERNEL);
+ o2net_keep_req = kzalloc(sizeof(struct o2net_msg), GFP_KERNEL);
+ o2net_keep_resp = kzalloc(sizeof(struct o2net_msg), GFP_KERNEL);
if (!o2net_hand || !o2net_keep_req || !o2net_keep_resp) {
kfree(o2net_hand);
kfree(o2net_keep_req);
diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c
index 420a375a3949..f0b25f2dd205 100644
--- a/fs/ocfs2/dlm/dlmdomain.c
+++ b/fs/ocfs2/dlm/dlmdomain.c
@@ -920,7 +920,7 @@ static int dlm_try_to_join_domain(struct dlm_ctxt *dlm)
mlog_entry("%p", dlm);
- ctxt = kcalloc(1, sizeof(*ctxt), GFP_KERNEL);
+ ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL);
if (!ctxt) {
status = -ENOMEM;
mlog_errno(status);
@@ -1223,7 +1223,7 @@ static struct dlm_ctxt *dlm_alloc_ctxt(const char *domain,
int i;
struct dlm_ctxt *dlm = NULL;
- dlm = kcalloc(1, sizeof(*dlm), GFP_KERNEL);
+ dlm = kzalloc(sizeof(*dlm), GFP_KERNEL);
if (!dlm) {
mlog_errno(-ENOMEM);
goto leave;
diff --git a/fs/ocfs2/dlm/dlmlock.c b/fs/ocfs2/dlm/dlmlock.c
index 42a1b91979b5..e5ca3db197f6 100644
--- a/fs/ocfs2/dlm/dlmlock.c
+++ b/fs/ocfs2/dlm/dlmlock.c
@@ -408,13 +408,13 @@ struct dlm_lock * dlm_new_lock(int type, u8 node, u64 cookie,
struct dlm_lock *lock;
int kernel_allocated = 0;
- lock = kcalloc(1, sizeof(*lock), GFP_NOFS);
+ lock = kzalloc(sizeof(*lock), GFP_NOFS);
if (!lock)
return NULL;
if (!lksb) {
/* zero memory only if kernel-allocated */
- lksb = kcalloc(1, sizeof(*lksb), GFP_NOFS);
+ lksb = kzalloc(sizeof(*lksb), GFP_NOFS);
if (!lksb) {
kfree(lock);
return NULL;
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c
index 856012b4fa49..0ad872055cb3 100644
--- a/fs/ocfs2/dlm/dlmmaster.c
+++ b/fs/ocfs2/dlm/dlmmaster.c
@@ -1939,7 +1939,7 @@ int dlm_dispatch_assert_master(struct dlm_ctxt *dlm,
int ignore_higher, u8 request_from, u32 flags)
{
struct dlm_work_item *item;
- item = kcalloc(1, sizeof(*item), GFP_NOFS);
+ item = kzalloc(sizeof(*item), GFP_NOFS);
if (!item)
return -ENOMEM;
diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c
index fb3e2b0817f1..367a11e9e2ed 100644
--- a/fs/ocfs2/dlm/dlmrecovery.c
+++ b/fs/ocfs2/dlm/dlmrecovery.c
@@ -757,7 +757,7 @@ static int dlm_init_recovery_area(struct dlm_ctxt *dlm, u8 dead_node)
}
BUG_ON(num == dead_node);
- ndata = kcalloc(1, sizeof(*ndata), GFP_NOFS);
+ ndata = kzalloc(sizeof(*ndata), GFP_NOFS);
if (!ndata) {
dlm_destroy_recovery_area(dlm, dead_node);
return -ENOMEM;
@@ -842,7 +842,7 @@ int dlm_request_all_locks_handler(struct o2net_msg *msg, u32 len, void *data)
}
BUG_ON(lr->dead_node != dlm->reco.dead_node);
- item = kcalloc(1, sizeof(*item), GFP_NOFS);
+ item = kzalloc(sizeof(*item), GFP_NOFS);
if (!item) {
dlm_put(dlm);
return -ENOMEM;
@@ -1323,7 +1323,7 @@ int dlm_mig_lockres_handler(struct o2net_msg *msg, u32 len, void *data)
ret = -ENOMEM;
buf = kmalloc(be16_to_cpu(msg->data_len), GFP_NOFS);
- item = kcalloc(1, sizeof(*item), GFP_NOFS);
+ item = kzalloc(sizeof(*item), GFP_NOFS);
if (!buf || !item)
goto leave;
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c
index e6220137bf69..e335541727f9 100644
--- a/fs/ocfs2/dlmglue.c
+++ b/fs/ocfs2/dlmglue.c
@@ -2718,6 +2718,15 @@ static int ocfs2_data_convert_worker(struct ocfs2_lock_res *lockres,
inode = ocfs2_lock_res_inode(lockres);
mapping = inode->i_mapping;
+ /*
+ * We need this before the filemap_fdatawrite() so that it can
+ * transfer the dirty bit from the PTE to the
+ * page. Unfortunately this means that even for EX->PR
+ * downconverts, we'll lose our mappings and have to build
+ * them up again.
+ */
+ unmap_mapping_range(mapping, 0, 0, 0);
+
if (filemap_fdatawrite(mapping)) {
mlog(ML_ERROR, "Could not sync inode %llu for downconvert!",
(unsigned long long)OCFS2_I(inode)->ip_blkno);
@@ -2725,7 +2734,6 @@ static int ocfs2_data_convert_worker(struct ocfs2_lock_res *lockres,
sync_mapping_buffers(mapping);
if (blocking == LKM_EXMODE) {
truncate_inode_pages(mapping, 0);
- unmap_mapping_range(mapping, 0, 0, 0);
} else {
/* We only need to wait on the I/O if we're not also
* truncating pages because truncate_inode_pages waits
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index e9a82ad95c1e..10953a508f2f 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -149,10 +149,29 @@ int ocfs2_should_update_atime(struct inode *inode,
((inode->i_sb->s_flags & MS_NODIRATIME) && S_ISDIR(inode->i_mode)))
return 0;
+ /*
+ * We can be called with no vfsmnt structure - NFSD will
+ * sometimes do this.
+ *
+ * Note that our action here is different than touch_atime() -
+ * if we can't tell whether this is a noatime mount, then we
+ * don't know whether to trust the value of s_atime_quantum.
+ */
+ if (vfsmnt == NULL)
+ return 0;
+
if ((vfsmnt->mnt_flags & MNT_NOATIME) ||
((vfsmnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode)))
return 0;
+ if (vfsmnt->mnt_flags & MNT_RELATIME) {
+ if ((timespec_compare(&inode->i_atime, &inode->i_mtime) <= 0) ||
+ (timespec_compare(&inode->i_atime, &inode->i_ctime) <= 0))
+ return 1;
+
+ return 0;
+ }
+
now = CURRENT_TIME;
if ((now.tv_sec - inode->i_atime.tv_sec <= osb->s_atime_quantum))
return 0;
@@ -958,8 +977,6 @@ int ocfs2_permission(struct inode *inode, int mask, struct nameidata *nd)
}
ret = generic_permission(inode, mask, NULL);
- if (ret)
- mlog_errno(ret);
ocfs2_meta_unlock(inode, 0);
out:
diff --git a/fs/ocfs2/localalloc.c b/fs/ocfs2/localalloc.c
index 698d79a74ef8..4dedd9789108 100644
--- a/fs/ocfs2/localalloc.c
+++ b/fs/ocfs2/localalloc.c
@@ -776,7 +776,7 @@ static int ocfs2_local_alloc_reserve_for_window(struct ocfs2_super *osb,
{
int status;
- *ac = kcalloc(1, sizeof(struct ocfs2_alloc_context), GFP_KERNEL);
+ *ac = kzalloc(sizeof(struct ocfs2_alloc_context), GFP_KERNEL);
if (!(*ac)) {
status = -ENOMEM;
mlog_errno(status);
diff --git a/fs/ocfs2/slot_map.c b/fs/ocfs2/slot_map.c
index aa6f5aadedc4..2d3ac32cb74e 100644
--- a/fs/ocfs2/slot_map.c
+++ b/fs/ocfs2/slot_map.c
@@ -175,7 +175,7 @@ int ocfs2_init_slot_info(struct ocfs2_super *osb)
struct buffer_head *bh = NULL;
struct ocfs2_slot_info *si;
- si = kcalloc(1, sizeof(struct ocfs2_slot_info), GFP_KERNEL);
+ si = kzalloc(sizeof(struct ocfs2_slot_info), GFP_KERNEL);
if (!si) {
status = -ENOMEM;
mlog_errno(status);
diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c
index 000d71cca6c5..6dbb11762759 100644
--- a/fs/ocfs2/suballoc.c
+++ b/fs/ocfs2/suballoc.c
@@ -488,7 +488,7 @@ int ocfs2_reserve_new_metadata(struct ocfs2_super *osb,
int status;
u32 slot;
- *ac = kcalloc(1, sizeof(struct ocfs2_alloc_context), GFP_KERNEL);
+ *ac = kzalloc(sizeof(struct ocfs2_alloc_context), GFP_KERNEL);
if (!(*ac)) {
status = -ENOMEM;
mlog_errno(status);
@@ -530,7 +530,7 @@ int ocfs2_reserve_new_inode(struct ocfs2_super *osb,
{
int status;
- *ac = kcalloc(1, sizeof(struct ocfs2_alloc_context), GFP_KERNEL);
+ *ac = kzalloc(sizeof(struct ocfs2_alloc_context), GFP_KERNEL);
if (!(*ac)) {
status = -ENOMEM;
mlog_errno(status);
@@ -595,7 +595,7 @@ int ocfs2_reserve_clusters(struct ocfs2_super *osb,
mlog_entry_void();
- *ac = kcalloc(1, sizeof(struct ocfs2_alloc_context), GFP_KERNEL);
+ *ac = kzalloc(sizeof(struct ocfs2_alloc_context), GFP_KERNEL);
if (!(*ac)) {
status = -ENOMEM;
mlog_errno(status);
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index a6d2f8cc165b..6e300a88a47e 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -1231,7 +1231,7 @@ static int ocfs2_setup_osb_uuid(struct ocfs2_super *osb, const unsigned char *uu
BUG_ON(uuid_bytes != OCFS2_VOL_UUID_LEN);
- osb->uuid_str = kcalloc(1, OCFS2_VOL_UUID_LEN * 2 + 1, GFP_KERNEL);
+ osb->uuid_str = kzalloc(OCFS2_VOL_UUID_LEN * 2 + 1, GFP_KERNEL);
if (osb->uuid_str == NULL)
return -ENOMEM;
@@ -1262,7 +1262,7 @@ static int ocfs2_initialize_super(struct super_block *sb,
mlog_entry_void();
- osb = kcalloc(1, sizeof(struct ocfs2_super), GFP_KERNEL);
+ osb = kzalloc(sizeof(struct ocfs2_super), GFP_KERNEL);
if (!osb) {
status = -ENOMEM;
mlog_errno(status);
@@ -1387,7 +1387,7 @@ static int ocfs2_initialize_super(struct super_block *sb,
*/
/* initialize our journal structure */
- journal = kcalloc(1, sizeof(struct ocfs2_journal), GFP_KERNEL);
+ journal = kzalloc(sizeof(struct ocfs2_journal), GFP_KERNEL);
if (!journal) {
mlog(ML_ERROR, "unable to alloc journal\n");
status = -ENOMEM;
diff --git a/fs/ocfs2/vote.c b/fs/ocfs2/vote.c
index 0315a8b61ed6..0afd8b9af70f 100644
--- a/fs/ocfs2/vote.c
+++ b/fs/ocfs2/vote.c
@@ -479,7 +479,7 @@ static struct ocfs2_net_wait_ctxt *ocfs2_new_net_wait_ctxt(unsigned int response
{
struct ocfs2_net_wait_ctxt *w;
- w = kcalloc(1, sizeof(*w), GFP_NOFS);
+ w = kzalloc(sizeof(*w), GFP_NOFS);
if (!w) {
mlog_errno(-ENOMEM);
goto bail;
@@ -642,7 +642,7 @@ static struct ocfs2_vote_msg * ocfs2_new_vote_request(struct ocfs2_super *osb,
BUG_ON(!ocfs2_is_valid_vote_request(type));
- request = kcalloc(1, sizeof(*request), GFP_NOFS);
+ request = kzalloc(sizeof(*request), GFP_NOFS);
if (!request) {
mlog_errno(-ENOMEM);
} else {
diff --git a/fs/pipe.c b/fs/pipe.c
index f8b6bdcb879a..68090e84f589 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -207,7 +207,7 @@ int generic_pipe_buf_pin(struct pipe_inode_info *info, struct pipe_buffer *buf)
return 0;
}
-static struct pipe_buf_operations anon_pipe_buf_ops = {
+static const struct pipe_buf_operations anon_pipe_buf_ops = {
.can_merge = 1,
.map = generic_pipe_buf_map,
.unmap = generic_pipe_buf_unmap,
@@ -243,7 +243,7 @@ pipe_read(struct kiocb *iocb, const struct iovec *_iov,
if (bufs) {
int curbuf = pipe->curbuf;
struct pipe_buffer *buf = pipe->bufs + curbuf;
- struct pipe_buf_operations *ops = buf->ops;
+ const struct pipe_buf_operations *ops = buf->ops;
void *addr;
size_t chars = buf->len;
int error, atomic;
@@ -365,7 +365,7 @@ pipe_write(struct kiocb *iocb, const struct iovec *_iov,
int lastbuf = (pipe->curbuf + pipe->nrbufs - 1) &
(PIPE_BUFFERS-1);
struct pipe_buffer *buf = pipe->bufs + lastbuf;
- struct pipe_buf_operations *ops = buf->ops;
+ const struct pipe_buf_operations *ops = buf->ops;
int offset = buf->offset + buf->len;
if (ops->can_merge && offset + chars <= PAGE_SIZE) {
@@ -756,7 +756,7 @@ const struct file_operations rdwr_fifo_fops = {
.fasync = pipe_rdwr_fasync,
};
-static struct file_operations read_pipe_fops = {
+static const struct file_operations read_pipe_fops = {
.llseek = no_llseek,
.read = do_sync_read,
.aio_read = pipe_read,
@@ -768,7 +768,7 @@ static struct file_operations read_pipe_fops = {
.fasync = pipe_read_fasync,
};
-static struct file_operations write_pipe_fops = {
+static const struct file_operations write_pipe_fops = {
.llseek = no_llseek,
.read = bad_pipe_r,
.write = do_sync_write,
@@ -780,7 +780,7 @@ static struct file_operations write_pipe_fops = {
.fasync = pipe_write_fasync,
};
-static struct file_operations rdwr_pipe_fops = {
+static const struct file_operations rdwr_pipe_fops = {
.llseek = no_llseek,
.read = do_sync_read,
.aio_read = pipe_read,
@@ -935,8 +935,9 @@ struct file *create_write_pipe(void)
void free_write_pipe(struct file *f)
{
- mntput(f->f_path.mnt);
+ free_pipe_info(f->f_dentry->d_inode);
dput(f->f_path.dentry);
+ mntput(f->f_path.mnt);
put_filp(f);
}
@@ -994,6 +995,8 @@ int do_pipe(int *fd)
err_fdr:
put_unused_fd(fdr);
err_read_pipe:
+ dput(fr->f_dentry);
+ mntput(fr->f_vfsmnt);
put_filp(fr);
err_write_pipe:
free_write_pipe(fw);
diff --git a/fs/ramfs/file-mmu.c b/fs/ramfs/file-mmu.c
index 0947fb57dcf3..54ebbc84207f 100644
--- a/fs/ramfs/file-mmu.c
+++ b/fs/ramfs/file-mmu.c
@@ -25,11 +25,13 @@
*/
#include <linux/fs.h>
+#include <linux/mm.h>
const struct address_space_operations ramfs_aops = {
.readpage = simple_readpage,
.prepare_write = simple_prepare_write,
- .commit_write = simple_commit_write
+ .commit_write = simple_commit_write,
+ .set_page_dirty = __set_page_dirty_nobuffers,
};
const struct file_operations ramfs_file_operations = {
diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c
index 61cbe1ef06b9..e9d6c4733282 100644
--- a/fs/ramfs/file-nommu.c
+++ b/fs/ramfs/file-nommu.c
@@ -11,6 +11,7 @@
#include <linux/module.h>
#include <linux/fs.h>
+#include <linux/mm.h>
#include <linux/pagemap.h>
#include <linux/highmem.h>
#include <linux/init.h>
@@ -30,7 +31,8 @@ static int ramfs_nommu_setattr(struct dentry *, struct iattr *);
const struct address_space_operations ramfs_aops = {
.readpage = simple_readpage,
.prepare_write = simple_prepare_write,
- .commit_write = simple_commit_write
+ .commit_write = simple_commit_write,
+ .set_page_dirty = __set_page_dirty_nobuffers,
};
const struct file_operations ramfs_file_operations = {
diff --git a/fs/read_write.c b/fs/read_write.c
index 1d3dda4fa70c..707ac21700d3 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -450,8 +450,6 @@ unsigned long iov_shorten(struct iovec *iov, unsigned long nr_segs, size_t to)
return seg;
}
-EXPORT_UNUSED_SYMBOL(iov_shorten); /* June 2006 */
-
ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov,
unsigned long nr_segs, size_t len, loff_t *ppos, iov_fn_t fn)
{
diff --git a/fs/reiserfs/stree.c b/fs/reiserfs/stree.c
index 47e7027ea39f..afb21ea45302 100644
--- a/fs/reiserfs/stree.c
+++ b/fs/reiserfs/stree.c
@@ -1459,7 +1459,7 @@ static void unmap_buffers(struct page *page, loff_t pos)
bh = next;
} while (bh != head);
if (PAGE_SIZE == bh->b_size) {
- clear_page_dirty(page);
+ cancel_dirty_page(page, PAGE_CACHE_SIZE);
}
}
}
diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c
index 97ae1b92bc47..5296a29cc5eb 100644
--- a/fs/reiserfs/xattr_acl.c
+++ b/fs/reiserfs/xattr_acl.c
@@ -135,7 +135,7 @@ static void *posix_acl_to_disk(const struct posix_acl *acl, size_t * size)
int n;
*size = reiserfs_acl_size(acl->a_count);
- ext_acl = (reiserfs_acl_header *) kmalloc(sizeof(reiserfs_acl_header) +
+ ext_acl = kmalloc(sizeof(reiserfs_acl_header) +
acl->a_count *
sizeof(reiserfs_acl_entry),
GFP_NOFS);
diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c
index 4af4cd729a5a..84dfe3f3482e 100644
--- a/fs/smbfs/inode.c
+++ b/fs/smbfs/inode.c
@@ -482,12 +482,13 @@ smb_put_super(struct super_block *sb)
smb_close_socket(server);
if (server->conn_pid)
- kill_proc(server->conn_pid, SIGTERM, 1);
+ kill_pid(server->conn_pid, SIGTERM, 1);
kfree(server->ops);
smb_unload_nls(server);
sb->s_fs_info = NULL;
smb_unlock_server(server);
+ put_pid(server->conn_pid);
kfree(server);
}
@@ -530,7 +531,7 @@ static int smb_fill_super(struct super_block *sb, void *raw_data, int silent)
INIT_LIST_HEAD(&server->xmitq);
INIT_LIST_HEAD(&server->recvq);
server->conn_error = 0;
- server->conn_pid = 0;
+ server->conn_pid = NULL;
server->state = CONN_INVALID; /* no connection yet */
server->generation = 0;
diff --git a/fs/smbfs/proc.c b/fs/smbfs/proc.c
index a5ced9e0c6c4..feac46050619 100644
--- a/fs/smbfs/proc.c
+++ b/fs/smbfs/proc.c
@@ -877,7 +877,7 @@ smb_newconn(struct smb_sb_info *server, struct smb_conn_opt *opt)
goto out_putf;
server->sock_file = filp;
- server->conn_pid = current->pid;
+ server->conn_pid = get_pid(task_pid(current));
server->opt = *opt;
server->generation += 1;
server->state = CONN_VALID;
@@ -971,8 +971,8 @@ smb_newconn(struct smb_sb_info *server, struct smb_conn_opt *opt)
}
VERBOSE("protocol=%d, max_xmit=%d, pid=%d capabilities=0x%x\n",
- server->opt.protocol, server->opt.max_xmit, server->conn_pid,
- server->opt.capabilities);
+ server->opt.protocol, server->opt.max_xmit,
+ pid_nr(server->conn_pid), server->opt.capabilities);
/* FIXME: this really should be done by smbmount. */
if (server->opt.max_xmit > SMB_MAX_PACKET_SIZE) {
diff --git a/fs/smbfs/smbiod.c b/fs/smbfs/smbiod.c
index e67540441288..89eaf31f1d46 100644
--- a/fs/smbfs/smbiod.c
+++ b/fs/smbfs/smbiod.c
@@ -152,7 +152,7 @@ int smbiod_retry(struct smb_sb_info *server)
{
struct list_head *head;
struct smb_request *req;
- pid_t pid = server->conn_pid;
+ struct pid *pid = get_pid(server->conn_pid);
int result = 0;
VERBOSE("state: %d\n", server->state);
@@ -222,7 +222,7 @@ int smbiod_retry(struct smb_sb_info *server)
/*
* Note: use the "priv" flag, as a user process may need to reconnect.
*/
- result = kill_proc(pid, SIGUSR1, 1);
+ result = kill_pid(pid, SIGUSR1, 1);
if (result) {
/* FIXME: this is most likely fatal, umount? */
printk(KERN_ERR "smb_retry: signal failed [%d]\n", result);
@@ -233,6 +233,7 @@ int smbiod_retry(struct smb_sb_info *server)
/* FIXME: The retried requests should perhaps get a "time boost". */
out:
+ put_pid(pid);
return result;
}
diff --git a/fs/splice.c b/fs/splice.c
index bbd0aeb3f68e..2fca6ebf4cc2 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -42,7 +42,7 @@ struct splice_pipe_desc {
struct partial_page *partial; /* pages[] may not be contig */
int nr_pages; /* number of pages in map */
unsigned int flags; /* splice flags */
- struct pipe_buf_operations *ops;/* ops associated with output pipe */
+ const struct pipe_buf_operations *ops;/* ops associated with output pipe */
};
/*
@@ -139,7 +139,7 @@ error:
return err;
}
-static struct pipe_buf_operations page_cache_pipe_buf_ops = {
+static const struct pipe_buf_operations page_cache_pipe_buf_ops = {
.can_merge = 0,
.map = generic_pipe_buf_map,
.unmap = generic_pipe_buf_unmap,
@@ -159,7 +159,7 @@ static int user_page_pipe_buf_steal(struct pipe_inode_info *pipe,
return generic_pipe_buf_steal(pipe, buf);
}
-static struct pipe_buf_operations user_page_pipe_buf_ops = {
+static const struct pipe_buf_operations user_page_pipe_buf_ops = {
.can_merge = 0,
.map = generic_pipe_buf_map,
.unmap = generic_pipe_buf_unmap,
@@ -724,7 +724,7 @@ static ssize_t __splice_from_pipe(struct pipe_inode_info *pipe,
for (;;) {
if (pipe->nrbufs) {
struct pipe_buffer *buf = pipe->bufs + pipe->curbuf;
- struct pipe_buf_operations *ops = buf->ops;
+ const struct pipe_buf_operations *ops = buf->ops;
sd.len = buf->len;
if (sd.len > sd.total_len)
diff --git a/fs/stack.c b/fs/stack.c
index 5ddbc34535f9..8ffb880d2f46 100644
--- a/fs/stack.c
+++ b/fs/stack.c
@@ -34,7 +34,5 @@ void fsstack_copy_attr_all(struct inode *dest, const struct inode *src,
dest->i_ctime = src->i_ctime;
dest->i_blkbits = src->i_blkbits;
dest->i_flags = src->i_flags;
-
- fsstack_copy_inode_size(dest, src);
}
EXPORT_SYMBOL_GPL(fsstack_copy_attr_all);
diff --git a/fs/sysv/super.c b/fs/sysv/super.c
index dc9e7dc07fb7..6f9707a1b954 100644
--- a/fs/sysv/super.c
+++ b/fs/sysv/super.c
@@ -528,9 +528,6 @@ static struct file_system_type v7_fs_type = {
.fs_flags = FS_REQUIRES_DEV,
};
-extern int sysv_init_icache(void) __init;
-extern void sysv_destroy_icache(void);
-
static int __init init_sysv_fs(void)
{
int error;
diff --git a/fs/sysv/sysv.h b/fs/sysv/sysv.h
index 9dcc82120935..dcb18b2171fe 100644
--- a/fs/sysv/sysv.h
+++ b/fs/sysv/sysv.h
@@ -143,6 +143,9 @@ extern int sysv_sync_inode(struct inode *);
extern int sysv_sync_file(struct file *, struct dentry *, int);
extern void sysv_set_inode(struct inode *, dev_t);
extern int sysv_getattr(struct vfsmount *, struct dentry *, struct kstat *);
+extern int sysv_init_icache(void);
+extern void sysv_destroy_icache(void);
+
/* dir.c */
extern struct sysv_dir_entry *sysv_find_entry(struct dentry *, struct page **);
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index b56eb754e2d2..7b54461695e2 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -341,9 +341,9 @@ xfs_start_page_writeback(
{
ASSERT(PageLocked(page));
ASSERT(!PageWriteback(page));
- set_page_writeback(page);
if (clear_dirty)
- clear_page_dirty(page);
+ clear_page_dirty_for_io(page);
+ set_page_writeback(page);
unlock_page(page);
if (!buffers) {
end_page_writeback(page);
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index 049e9aa1b867..81458767a90e 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -97,11 +97,12 @@ acpi_find_root_pointer(u32 flags, struct acpi_pointer *rsdp_address);
acpi_status acpi_load_tables(void);
-#ifdef ACPI_FUTURE_USAGE
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_id(acpi_table_type table_type, acpi_owner_id id);
+#ifdef ACPI_FUTURE_USAGE
+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);
@@ -180,6 +181,8 @@ acpi_get_next_object(acpi_object_type type,
acpi_status acpi_get_type(acpi_handle object, acpi_object_type * out_type);
+acpi_status acpi_get_id(acpi_handle object, acpi_owner_id * out_type);
+
acpi_status acpi_get_parent(acpi_handle object, acpi_handle * out_handle);
/*
diff --git a/include/asm-alpha/cacheflush.h b/include/asm-alpha/cacheflush.h
index 805640b41078..b686cc7fc44e 100644
--- a/include/asm-alpha/cacheflush.h
+++ b/include/asm-alpha/cacheflush.h
@@ -6,6 +6,7 @@
/* Caches aren't brain-dead on the Alpha. */
#define flush_cache_all() do { } while (0)
#define flush_cache_mm(mm) do { } while (0)
+#define flush_cache_dup_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_page(page) do { } while (0)
diff --git a/include/asm-arm/arch-ep93xx/irqs.h b/include/asm-arm/arch-ep93xx/irqs.h
index 9a42f5de9e57..ae532e304bf1 100644
--- a/include/asm-arm/arch-ep93xx/irqs.h
+++ b/include/asm-arm/arch-ep93xx/irqs.h
@@ -22,9 +22,9 @@
#define IRQ_EP93XX_DMAM2P9 16
#define IRQ_EP93XX_DMAM2M0 17
#define IRQ_EP93XX_DMAM2M1 18
-#define IRQ_EP93XX_GPIO0MUX 20
-#define IRQ_EP93XX_GPIO1MUX 21
-#define IRQ_EP93XX_GPIO2MUX 22
+#define IRQ_EP93XX_GPIO0MUX 19
+#define IRQ_EP93XX_GPIO1MUX 20
+#define IRQ_EP93XX_GPIO2MUX 21
#define IRQ_EP93XX_GPIO3MUX 22
#define IRQ_EP93XX_UART1RX 23
#define IRQ_EP93XX_UART1TX 24
diff --git a/include/asm-arm/arch-imx/imx-regs.h b/include/asm-arm/arch-imx/imx-regs.h
index a6912b3d8671..e56a4e247d62 100644
--- a/include/asm-arm/arch-imx/imx-regs.h
+++ b/include/asm-arm/arch-imx/imx-regs.h
@@ -41,7 +41,13 @@
/* PLL registers */
#define CSCR __REG(IMX_PLL_BASE) /* Clock Source Control Register */
-#define CSCR_SYSTEM_SEL (1<<16)
+#define CSCR_SPLL_RESTART (1<<22)
+#define CSCR_MPLL_RESTART (1<<21)
+#define CSCR_SYSTEM_SEL (1<<16)
+#define CSCR_BCLK_DIV (0xf<<10)
+#define CSCR_MPU_PRESC (1<<15)
+#define CSCR_SPEN (1<<1)
+#define CSCR_MPEN (1<<0)
#define MPCTL0 __REG(IMX_PLL_BASE + 0x4) /* MCU PLL Control Register 0 */
#define MPCTL1 __REG(IMX_PLL_BASE + 0x8) /* MCU PLL and System Clock Register 1 */
@@ -49,8 +55,6 @@
#define SPCTL1 __REG(IMX_PLL_BASE + 0x10) /* System PLL Control Register 1 */
#define PCDR __REG(IMX_PLL_BASE + 0x20) /* Peripheral Clock Divider Register */
-#define CSCR_MPLL_RESTART (1<<21)
-
/*
* GPIO Module and I/O Multiplexer
* x = 0..3 for reg_A, reg_B, reg_C, reg_D
diff --git a/include/asm-arm/arch-iop13xx/io.h b/include/asm-arm/arch-iop13xx/io.h
index db6de2480a24..5a7bdb526606 100644
--- a/include/asm-arm/arch-iop13xx/io.h
+++ b/include/asm-arm/arch-iop13xx/io.h
@@ -21,10 +21,11 @@
#define IO_SPACE_LIMIT 0xffffffff
-#define __io(a) (a)
+#define __io(a) __iop13xx_io(a)
#define __mem_pci(a) (a)
#define __mem_isa(a) (a)
+extern void __iomem * __iop13xx_io(unsigned long io_addr);
extern void __iomem * __ioremap(unsigned long, size_t, unsigned long);
extern void __iomem *__iop13xx_ioremap(unsigned long cookie, size_t size,
unsigned long flags);
diff --git a/include/asm-arm/arch-iop13xx/iq81340.h b/include/asm-arm/arch-iop13xx/iq81340.h
index b98f8f109c22..ba2cf931e9ce 100644
--- a/include/asm-arm/arch-iop13xx/iq81340.h
+++ b/include/asm-arm/arch-iop13xx/iq81340.h
@@ -24,8 +24,5 @@
#define PBI_CF_IDE_BASE (IQ81340_CMP_FLSH)
#define PBI_CF_BAR_ADDR (IOP13XX_PBI_BAR1)
-/* These are the values used in the Machine description */
-#define PHYS_IO 0xfeffff00
-#define IO_PG_OFFSET 0xffffff00
-#define BOOT_PARAM_OFFSET 0x00000100
+
#endif /* _IQ81340_H_ */
diff --git a/include/asm-arm/arch-ixp23xx/memory.h b/include/asm-arm/arch-ixp23xx/memory.h
index c85fc06a043c..6d859d742d7f 100644
--- a/include/asm-arm/arch-ixp23xx/memory.h
+++ b/include/asm-arm/arch-ixp23xx/memory.h
@@ -41,21 +41,7 @@
data = *((volatile int *)IXP23XX_PCI_SDRAM_BAR); \
__phys_to_virt((((b - (data & 0xfffffff0)) + 0x00000000))); })
-/*
- * Coherency support. Only supported on A2 CPUs or on A1
- * systems that have the cache coherency workaround.
- */
-static inline int __ixp23xx_arch_is_coherent(void)
-{
- extern unsigned int processor_id;
-
- if (((processor_id & 15) >= 4) || machine_is_roadrunner())
- return 1;
-
- return 0;
-}
-
-#define arch_is_coherent() __ixp23xx_arch_is_coherent()
+#define arch_is_coherent() 1
#endif
diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h
index 083e03c5639f..e24f6b6c79ae 100644
--- a/include/asm-arm/arch-pxa/pxa-regs.h
+++ b/include/asm-arm/arch-pxa/pxa-regs.h
@@ -1626,7 +1626,7 @@
#define SSCR0_RIM (1 << 22) /* Receive FIFO overrrun interrupt mask */
#define SSCR0_TUM (1 << 23) /* Transmit FIFO underrun interrupt mask */
#define SSCR0_FRDC (0x07000000) /* Frame rate divider control (mask) */
-#define SSCR0_SlotsPerFrm(x) ((x) - 1) /* Time slots per frame [1..8] */
+#define SSCR0_SlotsPerFrm(x) (((x) - 1) << 24) /* Time slots per frame [1..8] */
#define SSCR0_ADC (1 << 30) /* Audio clock select */
#define SSCR0_MOD (1 << 31) /* Mode (normal or network) */
#endif
@@ -1655,6 +1655,7 @@
#define SSCR0_EDSS (1 << 20) /* Extended Data Size Select */
/* extra bits in PXA255, PXA26x and PXA27x SSP ports */
+#define SSCR0_TISSP (1 << 4) /* TI Sync Serial Protocol */
#define SSCR0_PSP (3 << 4) /* PSP - Programmable Serial Protocol */
#define SSCR1_TTELP (1 << 31) /* TXD Tristate Enable Last Phase */
#define SSCR1_TTE (1 << 30) /* TXD Tristate Enable */
diff --git a/include/asm-arm/arch-s3c2410/anubis-cpld.h b/include/asm-arm/arch-s3c2410/anubis-cpld.h
index 40e8e270d337..dcebf6d61903 100644
--- a/include/asm-arm/arch-s3c2410/anubis-cpld.h
+++ b/include/asm-arm/arch-s3c2410/anubis-cpld.h
@@ -1,6 +1,6 @@
/* linux/include/asm-arm/arch-s3c2410/anubis-cpld.h
*
- * (c) 2005 Simtec Electronics
+ * Copyright (c) 2005 Simtec Electronics
* http://www.simtec.co.uk/products/
* Ben Dooks <ben@simtec.co.uk>
*
diff --git a/include/asm-arm/arch-s3c2410/anubis-irq.h b/include/asm-arm/arch-s3c2410/anubis-irq.h
index 4b5f423779df..cd77a70d45c0 100644
--- a/include/asm-arm/arch-s3c2410/anubis-irq.h
+++ b/include/asm-arm/arch-s3c2410/anubis-irq.h
@@ -1,6 +1,6 @@
/* linux/include/asm-arm/arch-s3c2410/anubis-irq.h
*
- * (c) 2005 Simtec Electronics
+ * Copyright (c) 2005 Simtec Electronics
* http://www.simtec.co.uk/products/
* Ben Dooks <ben@simtec.co.uk>
*
diff --git a/include/asm-arm/arch-s3c2410/anubis-map.h b/include/asm-arm/arch-s3c2410/anubis-map.h
index 058a2104b035..ab076de4a0d0 100644
--- a/include/asm-arm/arch-s3c2410/anubis-map.h
+++ b/include/asm-arm/arch-s3c2410/anubis-map.h
@@ -1,6 +1,6 @@
/* linux/include/asm-arm/arch-s3c2410/anubis-map.h
*
- * (c) 2005 Simtec Electronics
+ * Copyright (c) 2005 Simtec Electronics
* http://www.simtec.co.uk/products/
* Ben Dooks <ben@simtec.co.uk>
*
diff --git a/include/asm-arm/arch-s3c2410/audio.h b/include/asm-arm/arch-s3c2410/audio.h
index 7e0222276c98..65e0acffa1ad 100644
--- a/include/asm-arm/arch-s3c2410/audio.h
+++ b/include/asm-arm/arch-s3c2410/audio.h
@@ -1,6 +1,6 @@
/* linux/include/asm-arm/arch-s3c2410/audio.h
*
- * (c) 2004-2005 Simtec Electronics
+ * Copyright (c) 2004-2005 Simtec Electronics
* http://www.simtec.co.uk/products/SWLINUX/
* Ben Dooks <ben@simtec.co.uk>
*
diff --git a/include/asm-arm/arch-s3c2410/bast-cpld.h b/include/asm-arm/arch-s3c2410/bast-cpld.h
index 8969cffe83fa..034d2c5a47c4 100644
--- a/include/asm-arm/arch-s3c2410/bast-cpld.h
+++ b/include/asm-arm/arch-s3c2410/bast-cpld.h
@@ -1,7 +1,7 @@
/* linux/include/asm-arm/arch-s3c2410/bast-cpld.h
*
- * (c) 2003,2004 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
+ * Copyright (c) 2003,2004 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
*
* BAST - CPLD control constants
*
diff --git a/include/asm-arm/arch-s3c2410/bast-irq.h b/include/asm-arm/arch-s3c2410/bast-irq.h
index 15ffa66f5011..726c0466f85a 100644
--- a/include/asm-arm/arch-s3c2410/bast-irq.h
+++ b/include/asm-arm/arch-s3c2410/bast-irq.h
@@ -1,7 +1,7 @@
/* linux/include/asm-arm/arch-s3c2410/bast-irq.h
*
- * (c) 2003,2004 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
+ * Copyright (c) 2003,2004 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
*
* Machine BAST - IRQ Number definitions
*
diff --git a/include/asm-arm/arch-s3c2410/bast-map.h b/include/asm-arm/arch-s3c2410/bast-map.h
index 727cef84c70e..86ac1c108db8 100644
--- a/include/asm-arm/arch-s3c2410/bast-map.h
+++ b/include/asm-arm/arch-s3c2410/bast-map.h
@@ -1,7 +1,7 @@
/* linux/include/asm-arm/arch-s3c2410/bast-map.h
*
- * (c) 2003,2004 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
+ * Copyright (c) 2003,2004 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
*
* Machine BAST - Memory map definitions
*
diff --git a/include/asm-arm/arch-s3c2410/bast-pmu.h b/include/asm-arm/arch-s3c2410/bast-pmu.h
index 82836027f00f..37a11fe54a78 100644
--- a/include/asm-arm/arch-s3c2410/bast-pmu.h
+++ b/include/asm-arm/arch-s3c2410/bast-pmu.h
@@ -1,6 +1,6 @@
/* linux/include/asm-arm/arch-s3c2410/bast-pmu.h
*
- * (c) 2003,2004 Simtec Electronics
+ * Copyright (c) 2003,2004 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* Vincent Sanders <vince@simtec.co.uk>
*
diff --git a/include/asm-arm/arch-s3c2410/dma.h b/include/asm-arm/arch-s3c2410/dma.h
index 7ac224836971..58ffa7ba3c88 100644
--- a/include/asm-arm/arch-s3c2410/dma.h
+++ b/include/asm-arm/arch-s3c2410/dma.h
@@ -14,7 +14,7 @@
#define __ASM_ARCH_DMA_H __FILE__
#include <linux/sysdev.h>
-#include "hardware.h"
+#include <asm/hardware.h>
/*
* This is the maximum DMA address(physical address) that can be DMAd to.
diff --git a/include/asm-arm/arch-s3c2410/entry-macro.S b/include/asm-arm/arch-s3c2410/entry-macro.S
index e09a6b8ec153..1eb4e6b8d249 100644
--- a/include/asm-arm/arch-s3c2410/entry-macro.S
+++ b/include/asm-arm/arch-s3c2410/entry-macro.S
@@ -20,7 +20,7 @@
#define INTOFFSET (0x14)
#include <asm/hardware.h>
-#include <asm/arch/irqs.h>
+#include <asm/irq.h>
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
diff --git a/include/asm-arm/arch-s3c2410/h1940-latch.h b/include/asm-arm/arch-s3c2410/h1940-latch.h
index c5802411f43d..c3de5ab102eb 100644
--- a/include/asm-arm/arch-s3c2410/h1940-latch.h
+++ b/include/asm-arm/arch-s3c2410/h1940-latch.h
@@ -1,6 +1,6 @@
/* linux/include/asm-arm/arch-s3c2410/h1940-latch.h
*
- * (c) 2005 Simtec Electronics
+ * Copyright (c) 2005 Simtec Electronics
* http://armlinux.simtec.co.uk/
* Ben Dooks <ben@simtec.co.uk>
*
@@ -16,7 +16,7 @@
#ifndef __ASSEMBLY__
-#define H1940_LATCH ((void __iomem *)0xF8000000)
+#define H1940_LATCH ((void __force __iomem *)0xF8000000)
#else
#define H1940_LATCH 0xF8000000
#endif
diff --git a/include/asm-arm/arch-s3c2410/hardware.h b/include/asm-arm/arch-s3c2410/hardware.h
index 871f8af09b8b..6dadf58ff984 100644
--- a/include/asm-arm/arch-s3c2410/hardware.h
+++ b/include/asm-arm/arch-s3c2410/hardware.h
@@ -1,7 +1,7 @@
/* linux/include/asm-arm/arch-s3c2410/hardware.h
*
- * (c) 2003 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
+ * Copyright (c) 2003 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
*
* S3C2410 - hardware
*
@@ -13,6 +13,10 @@
#ifndef __ASM_ARCH_HARDWARE_H
#define __ASM_ARCH_HARDWARE_H
+#ifndef __ASM_HARDWARE_H
+#error "Do not include this directly, instead #include <asm/hardware.h>"
+#endif
+
#ifndef __ASSEMBLY__
/* external functions for GPIO support
diff --git a/include/asm-arm/arch-s3c2410/iic.h b/include/asm-arm/arch-s3c2410/iic.h
index ed3d6c7bf6d7..71211c8b5384 100644
--- a/include/asm-arm/arch-s3c2410/iic.h
+++ b/include/asm-arm/arch-s3c2410/iic.h
@@ -1,6 +1,6 @@
/* linux/include/asm-arm/arch-s3c2410/iic.h
*
- * (c) 2004 Simtec Electronics
+ * Copyright (c) 2004 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* S3C2410 - I2C Controller platfrom_device info
diff --git a/include/asm-arm/arch-s3c2410/irqs.h b/include/asm-arm/arch-s3c2410/irqs.h
index 39a69829d163..4b7cff456c4e 100644
--- a/include/asm-arm/arch-s3c2410/irqs.h
+++ b/include/asm-arm/arch-s3c2410/irqs.h
@@ -12,6 +12,9 @@
#ifndef __ASM_ARCH_IRQS_H
#define __ASM_ARCH_IRQS_H __FILE__
+#ifndef __ASM_ARM_IRQ_H
+#error "Do not include this directly, instead #include <asm/irq.h>"
+#endif
/* we keep the first set of CPU IRQs out of the range of
* the ISA space, so that the PC104 has them to itself
diff --git a/include/asm-arm/arch-s3c2410/leds-gpio.h b/include/asm-arm/arch-s3c2410/leds-gpio.h
index f07ed040622b..800846ebddba 100644
--- a/include/asm-arm/arch-s3c2410/leds-gpio.h
+++ b/include/asm-arm/arch-s3c2410/leds-gpio.h
@@ -1,6 +1,6 @@
/* linux/include/asm-arm/arch-s3c2410/leds-gpio.h
*
- * (c) 2006 Simtec Electronics
+ * Copyright (c) 2006 Simtec Electronics
* http://armlinux.simtec.co.uk/
* Ben Dooks <ben@simtec.co.uk>
*
diff --git a/include/asm-arm/arch-s3c2410/map.h b/include/asm-arm/arch-s3c2410/map.h
index 7895042d176b..4505aefbad17 100644
--- a/include/asm-arm/arch-s3c2410/map.h
+++ b/include/asm-arm/arch-s3c2410/map.h
@@ -1,7 +1,7 @@
/* linux/include/asm-arm/arch-s3c2410/map.h
*
- * (c) 2003 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
+ * Copyright (c) 2003 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
*
* S3C2410 - Memory map definitions
*
@@ -25,7 +25,7 @@
*/
#ifndef __ASSEMBLY__
-#define S3C2410_ADDR(x) ((void __iomem *)0xF0000000 + (x))
+#define S3C2410_ADDR(x) ((void __iomem __force *)0xF0000000 + (x))
#else
#define S3C2410_ADDR(x) (0xF0000000 + (x))
#endif
@@ -47,73 +47,65 @@
#define S3C24XX_SZ_MEMCTRL SZ_1M
/* USB host controller */
-#define S3C24XX_VA_USBHOST S3C2410_ADDR(0x00200000)
#define S3C2400_PA_USBHOST (0x14200000)
#define S3C2410_PA_USBHOST (0x49000000)
#define S3C24XX_SZ_USBHOST SZ_1M
/* DMA controller */
-#define S3C24XX_VA_DMA S3C2410_ADDR(0x00300000)
#define S3C2400_PA_DMA (0x14600000)
#define S3C2410_PA_DMA (0x4B000000)
#define S3C24XX_SZ_DMA SZ_1M
/* Clock and Power management */
-#define S3C24XX_VA_CLKPWR S3C2410_ADDR(0x00400000)
+#define S3C24XX_VA_CLKPWR S3C2410_ADDR(0x00200000)
#define S3C2400_PA_CLKPWR (0x14800000)
#define S3C2410_PA_CLKPWR (0x4C000000)
#define S3C24XX_SZ_CLKPWR SZ_1M
/* LCD controller */
-#define S3C24XX_VA_LCD S3C2410_ADDR(0x00600000)
+#define S3C24XX_VA_LCD S3C2410_ADDR(0x00300000)
#define S3C2400_PA_LCD (0x14A00000)
#define S3C2410_PA_LCD (0x4D000000)
#define S3C24XX_SZ_LCD SZ_1M
/* NAND flash controller */
-#define S3C24XX_VA_NAND S3C2410_ADDR(0x00700000)
#define S3C2410_PA_NAND (0x4E000000)
#define S3C24XX_SZ_NAND SZ_1M
/* MMC controller - available on the S3C2400 */
-#define S3C2400_VA_MMC S3C2400_ADDR(0x00700000)
#define S3C2400_PA_MMC (0x15A00000)
#define S3C2400_SZ_MMC SZ_1M
/* UARTs */
-#define S3C24XX_VA_UART S3C2410_ADDR(0x00800000)
+#define S3C24XX_VA_UART S3C2410_ADDR(0x00400000)
#define S3C2400_PA_UART (0x15000000)
#define S3C2410_PA_UART (0x50000000)
#define S3C24XX_SZ_UART SZ_1M
/* Timers */
-#define S3C24XX_VA_TIMER S3C2410_ADDR(0x00900000)
+#define S3C24XX_VA_TIMER S3C2410_ADDR(0x00500000)
#define S3C2400_PA_TIMER (0x15100000)
#define S3C2410_PA_TIMER (0x51000000)
#define S3C24XX_SZ_TIMER SZ_1M
/* USB Device port */
-#define S3C24XX_VA_USBDEV S3C2410_ADDR(0x00A00000)
+#define S3C24XX_VA_USBDEV S3C2410_ADDR(0x00600000)
#define S3C2400_PA_USBDEV (0x15200140)
#define S3C2410_PA_USBDEV (0x52000000)
#define S3C24XX_SZ_USBDEV SZ_1M
/* Watchdog */
-#define S3C24XX_VA_WATCHDOG S3C2410_ADDR(0x00B00000)
+#define S3C24XX_VA_WATCHDOG S3C2410_ADDR(0x00700000)
#define S3C2400_PA_WATCHDOG (0x15300000)
#define S3C2410_PA_WATCHDOG (0x53000000)
#define S3C24XX_SZ_WATCHDOG SZ_1M
/* IIC hardware controller */
-#define S3C24XX_VA_IIC S3C2410_ADDR(0x00C00000)
#define S3C2400_PA_IIC (0x15400000)
#define S3C2410_PA_IIC (0x54000000)
#define S3C24XX_SZ_IIC SZ_1M
-#define VA_IIC_BASE (S3C24XX_VA_IIC)
-
/* IIS controller */
-#define S3C24XX_VA_IIS S3C2410_ADDR(0x00D00000)
#define S3C2400_PA_IIS (0x15508000)
#define S3C2410_PA_IIS (0x55000000)
#define S3C24XX_SZ_IIS SZ_1M
@@ -134,25 +126,21 @@
#define S3C24XX_SZ_GPIO SZ_1M
/* RTC */
-#define S3C24XX_VA_RTC S3C2410_ADDR(0x00F00000)
#define S3C2400_PA_RTC (0x15700040)
#define S3C2410_PA_RTC (0x57000000)
#define S3C24XX_SZ_RTC SZ_1M
/* ADC */
-#define S3C24XX_VA_ADC S3C2410_ADDR(0x01000000)
#define S3C2400_PA_ADC (0x15800000)
#define S3C2410_PA_ADC (0x58000000)
#define S3C24XX_SZ_ADC SZ_1M
/* SPI */
-#define S3C24XX_VA_SPI S3C2410_ADDR(0x01100000)
#define S3C2400_PA_SPI (0x15900000)
#define S3C2410_PA_SPI (0x59000000)
#define S3C24XX_SZ_SPI SZ_1M
/* SDI */
-#define S3C24XX_VA_SDI S3C2410_ADDR(0x01200000)
#define S3C2410_PA_SDI (0x5A000000)
#define S3C24XX_SZ_SDI SZ_1M
diff --git a/include/asm-arm/arch-s3c2410/nand.h b/include/asm-arm/arch-s3c2410/nand.h
index e350ae2acfc6..8816f7f9cee1 100644
--- a/include/asm-arm/arch-s3c2410/nand.h
+++ b/include/asm-arm/arch-s3c2410/nand.h
@@ -1,7 +1,7 @@
/* linux/include/asm-arm/arch-s3c2410/nand.h
*
- * (c) 2004 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
+ * Copyright (c) 2004 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
*
* S3C2410 - NAND device controller platfrom_device info
*
diff --git a/include/asm-arm/arch-s3c2410/osiris-cpld.h b/include/asm-arm/arch-s3c2410/osiris-cpld.h
index e9d1ae1f354f..3b6498468d62 100644
--- a/include/asm-arm/arch-s3c2410/osiris-cpld.h
+++ b/include/asm-arm/arch-s3c2410/osiris-cpld.h
@@ -1,6 +1,6 @@
/* linux/include/asm-arm/arch-s3c2410/osiris-cpld.h
*
- * (c) 2005 Simtec Electronics
+ * Copyright (c) 2005 Simtec Electronics
* http://www.simtec.co.uk/products/
* Ben Dooks <ben@simtec.co.uk>
*
diff --git a/include/asm-arm/arch-s3c2410/regs-serial.h b/include/asm-arm/arch-s3c2410/regs-serial.h
index 19c77da9c3fe..46f52401d132 100644
--- a/include/asm-arm/arch-s3c2410/regs-serial.h
+++ b/include/asm-arm/arch-s3c2410/regs-serial.h
@@ -197,7 +197,7 @@ struct s3c2410_uartcfg {
unsigned char hwport; /* hardware port number */
unsigned char unused;
unsigned short flags;
- unsigned long uart_flags; /* default uart flags */
+ upf_t uart_flags; /* default uart flags */
unsigned long ucon; /* value of ucon for port */
unsigned long ulcon; /* value of ulcon for port */
diff --git a/include/asm-arm/arch-s3c2410/regs-udc.h b/include/asm-arm/arch-s3c2410/regs-udc.h
index 487861d5b49a..3c8354619b60 100644
--- a/include/asm-arm/arch-s3c2410/regs-udc.h
+++ b/include/asm-arm/arch-s3c2410/regs-udc.h
@@ -11,8 +11,7 @@
#ifndef __ASM_ARCH_REGS_UDC_H
#define __ASM_ARCH_REGS_UDC_H
-
-#define S3C2410_USBDREG(x) ((x) + S3C24XX_VA_USBDEV)
+#define S3C2410_USBDREG(x) (x)
#define S3C2410_UDC_FUNC_ADDR_REG S3C2410_USBDREG(0x0140)
#define S3C2410_UDC_PWR_REG S3C2410_USBDREG(0x0144)
@@ -136,8 +135,8 @@
#define S3C2410_UDC_OCSR2_ISO (1<<6) // R/W
#define S3C2410_UDC_OCSR2_DMAIEN (1<<5) // R/W
-#define S3C2410_UDC_SETIX(x) \
- __raw_writel(S3C2410_UDC_INDEX_ ## x, S3C2410_UDC_INDEX_REG);
+#define S3C2410_UDC_SETIX(base,x) \
+ writel(S3C2410_UDC_INDEX_ ## x, base+S3C2410_UDC_INDEX_REG);
#define S3C2410_UDC_EP0_CSR_OPKRDY (1<<0)
diff --git a/include/asm-arm/arch-s3c2410/system.h b/include/asm-arm/arch-s3c2410/system.h
index 4f72a853a5cf..ecf250db45fb 100644
--- a/include/asm-arm/arch-s3c2410/system.h
+++ b/include/asm-arm/arch-s3c2410/system.h
@@ -1,7 +1,7 @@
/* linux/include/asm-arm/arch-s3c2410/system.h
*
- * (c) 2003 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
+ * Copyright (c) 2003 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
*
* S3C2410 - System function defines and includes
*
diff --git a/include/asm-arm/arch-s3c2410/timex.h b/include/asm-arm/arch-s3c2410/timex.h
index 703c337c5617..c16a99c5a59a 100644
--- a/include/asm-arm/arch-s3c2410/timex.h
+++ b/include/asm-arm/arch-s3c2410/timex.h
@@ -1,7 +1,7 @@
/* linux/include/asm-arm/arch-s3c2410/timex.h
*
- * (c) 2003-2005 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
+ * Copyright (c) 2003-2005 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
*
* S3C2410 - time parameters
*
diff --git a/include/asm-arm/arch-s3c2410/uncompress.h b/include/asm-arm/arch-s3c2410/uncompress.h
index 81b3e91c56ab..dcb2cef38f50 100644
--- a/include/asm-arm/arch-s3c2410/uncompress.h
+++ b/include/asm-arm/arch-s3c2410/uncompress.h
@@ -1,7 +1,7 @@
/* linux/include/asm-arm/arch-s3c2410/uncompress.h
*
- * (c) 2003 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
+ * Copyright (c) 2003 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
*
* S3C2410 - uncompress code
*
@@ -13,6 +13,7 @@
#ifndef __ASM_ARCH_UNCOMPRESS_H
#define __ASM_ARCH_UNCOMPRESS_H
+typedef unsigned int upf_t; /* cannot include linux/serial_core.h */
/* defines for UART registers */
#include "asm/arch/regs-serial.h"
diff --git a/include/asm-arm/arch-s3c2410/usb-control.h b/include/asm-arm/arch-s3c2410/usb-control.h
index 35723569a17a..5bfa376e33dc 100644
--- a/include/asm-arm/arch-s3c2410/usb-control.h
+++ b/include/asm-arm/arch-s3c2410/usb-control.h
@@ -1,7 +1,7 @@
/* linux/include/asm-arm/arch-s3c2410/usb-control.h
*
- * (c) 2004 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
+ * Copyright (c) 2004 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
*
* S3C2410 - usb port information
*
diff --git a/include/asm-arm/arch-s3c2410/vr1000-cpld.h b/include/asm-arm/arch-s3c2410/vr1000-cpld.h
index a341b1e1bd98..0557b0a5ab1d 100644
--- a/include/asm-arm/arch-s3c2410/vr1000-cpld.h
+++ b/include/asm-arm/arch-s3c2410/vr1000-cpld.h
@@ -1,7 +1,7 @@
/* linux/include/asm-arm/arch-s3c2410/vr1000-cpld.h
*
- * (c) 2003 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
+ * Copyright (c) 2003 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
*
* VR1000 - CPLD control constants
*
diff --git a/include/asm-arm/arch-s3c2410/vr1000-irq.h b/include/asm-arm/arch-s3c2410/vr1000-irq.h
index c39a0ffa670d..890937083c61 100644
--- a/include/asm-arm/arch-s3c2410/vr1000-irq.h
+++ b/include/asm-arm/arch-s3c2410/vr1000-irq.h
@@ -1,7 +1,7 @@
/* linux/include/asm-arm/arch-s3c2410/vr1000-irq.h
*
- * (c) 2003,2004 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
+ * Copyright (c) 2003,2004 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
*
* Machine VR1000 - IRQ Number definitions
*
diff --git a/include/asm-arm/arch-s3c2410/vr1000-map.h b/include/asm-arm/arch-s3c2410/vr1000-map.h
index 1fe4db36c834..92a56a724a8c 100644
--- a/include/asm-arm/arch-s3c2410/vr1000-map.h
+++ b/include/asm-arm/arch-s3c2410/vr1000-map.h
@@ -1,7 +1,7 @@
/* linux/include/asm-arm/arch-s3c2410/vr1000-map.h
*
- * (c) 2003-2005 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
+ * Copyright (c) 2003-2005 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
*
* Machine VR1000 - Memory map definitions
*
diff --git a/include/asm-arm/cacheflush.h b/include/asm-arm/cacheflush.h
index f0845646aacb..d51049522cd0 100644
--- a/include/asm-arm/cacheflush.h
+++ b/include/asm-arm/cacheflush.h
@@ -319,6 +319,8 @@ extern void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
unsigned long len, int write);
#endif
+#define flush_cache_dup_mm(mm) flush_cache_mm(mm)
+
/*
* flush_cache_user_range is used when we want to ensure that the
* Harvard caches are synchronised for the user space address range.
@@ -353,6 +355,8 @@ extern void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
*/
extern void flush_dcache_page(struct page *);
+extern void __flush_dcache_page(struct address_space *mapping, struct page *page);
+
#define flush_dcache_mmap_lock(mapping) \
write_lock_irq(&(mapping)->tree_lock)
#define flush_dcache_mmap_unlock(mapping) \
diff --git a/include/asm-arm/cpu-multi32.h b/include/asm-arm/cpu-multi32.h
index 4679f63688e9..715e18a4add1 100644
--- a/include/asm-arm/cpu-multi32.h
+++ b/include/asm-arm/cpu-multi32.h
@@ -50,9 +50,10 @@ extern struct processor {
*/
void (*switch_mm)(unsigned long pgd_phys, struct mm_struct *mm);
/*
- * Set a PTE
+ * Set a possibly extended PTE. Non-extended PTEs should
+ * ignore 'ext'.
*/
- void (*set_pte)(pte_t *ptep, pte_t pte);
+ void (*set_pte_ext)(pte_t *ptep, pte_t pte, unsigned int ext);
} processor;
#define cpu_proc_init() processor._proc_init()
@@ -60,5 +61,5 @@ extern struct processor {
#define cpu_reset(addr) processor.reset(addr)
#define cpu_do_idle() processor._do_idle()
#define cpu_dcache_clean_area(addr,sz) processor.dcache_clean_area(addr,sz)
-#define cpu_set_pte(ptep, pte) processor.set_pte(ptep, pte)
+#define cpu_set_pte_ext(ptep,pte,ext) processor.set_pte_ext(ptep,pte,ext)
#define cpu_do_switch_mm(pgd,mm) processor.switch_mm(pgd,mm)
diff --git a/include/asm-arm/cpu-single.h b/include/asm-arm/cpu-single.h
index 6723e67244fa..0b120ee36091 100644
--- a/include/asm-arm/cpu-single.h
+++ b/include/asm-arm/cpu-single.h
@@ -28,7 +28,7 @@
#define cpu_do_idle __cpu_fn(CPU_NAME,_do_idle)
#define cpu_dcache_clean_area __cpu_fn(CPU_NAME,_dcache_clean_area)
#define cpu_do_switch_mm __cpu_fn(CPU_NAME,_switch_mm)
-#define cpu_set_pte __cpu_fn(CPU_NAME,_set_pte)
+#define cpu_set_pte_ext __cpu_fn(CPU_NAME,_set_pte_ext)
#include <asm/page.h>
@@ -40,5 +40,5 @@ extern void cpu_proc_fin(void);
extern int cpu_do_idle(void);
extern void cpu_dcache_clean_area(void *, int);
extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm);
-extern void cpu_set_pte(pte_t *ptep, pte_t pte);
+extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext);
extern void cpu_reset(unsigned long addr) __attribute__((noreturn));
diff --git a/include/asm-arm/elf.h b/include/asm-arm/elf.h
index 642382d2c9f0..3679a8a8922e 100644
--- a/include/asm-arm/elf.h
+++ b/include/asm-arm/elf.h
@@ -52,6 +52,7 @@ typedef struct user_fp elf_fpregset_t;
#define HWCAP_EDSP 128
#define HWCAP_JAVA 256
#define HWCAP_IWMMXT 512
+#define HWCAP_CRUNCH 1024
#ifdef __KERNEL__
#ifndef __ASSEMBLY__
diff --git a/include/asm-arm/flat.h b/include/asm-arm/flat.h
index 966946478589..16f5375e57b8 100644
--- a/include/asm-arm/flat.h
+++ b/include/asm-arm/flat.h
@@ -5,7 +5,9 @@
#ifndef __ARM_FLAT_H__
#define __ARM_FLAT_H__
-#define flat_stack_align(sp) /* nothing needed */
+/* An odd number of words will be pushed after this alignment, so
+ deliberately misalign the value. */
+#define flat_stack_align(sp) sp = (void *)(((unsigned long)(sp) - 4) | 4)
#define flat_argvp_envp_on_stack() 1
#define flat_old_ram_flag(flags) (flags)
#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
diff --git a/include/asm-arm/irq.h b/include/asm-arm/irq.h
index 283af50a16cb..1b882a255e35 100644
--- a/include/asm-arm/irq.h
+++ b/include/asm-arm/irq.h
@@ -19,7 +19,6 @@
#define NO_IRQ ((unsigned int)(-1))
#endif
-struct irqaction;
/*
* Migration helpers
@@ -37,6 +36,10 @@ struct irqaction;
#define IRQT_HIGH (__IRQT_HIGHLVL)
#define IRQT_PROBE IRQ_TYPE_PROBE
+#ifndef __ASSEMBLY__
+struct irqaction;
extern void migrate_irqs(void);
#endif
+#endif
+
diff --git a/include/asm-arm/pgtable.h b/include/asm-arm/pgtable.h
index 88cd5c784ef0..b8cf2d5ec304 100644
--- a/include/asm-arm/pgtable.h
+++ b/include/asm-arm/pgtable.h
@@ -21,6 +21,7 @@
#include <asm/memory.h>
#include <asm/arch/vmalloc.h>
+#include <asm/pgtable-hwdef.h>
/*
* Just any arbitrary offset to the start of the vmalloc VM area: the
@@ -170,7 +171,6 @@ extern void __pgd_error(const char *file, int line, unsigned long val);
#define L_PTE_EXEC (1 << 6)
#define L_PTE_DIRTY (1 << 7)
#define L_PTE_SHARED (1 << 10) /* shared(v6), coherent(xsc3) */
-#define L_PTE_ASID (1 << 11) /* non-global (use ASID, v6) */
#ifndef __ASSEMBLY__
@@ -228,7 +228,7 @@ extern struct page *empty_zero_page;
#define pfn_pte(pfn,prot) (__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)))
#define pte_none(pte) (!pte_val(pte))
-#define pte_clear(mm,addr,ptep) set_pte_at((mm),(addr),(ptep), __pte(0))
+#define pte_clear(mm,addr,ptep) set_pte_ext(ptep, __pte(0), 0)
#define pte_page(pte) (pfn_to_page(pte_pfn(pte)))
#define pte_offset_kernel(dir,addr) (pmd_page_vaddr(*(dir)) + __pte_index(addr))
#define pte_offset_map(dir,addr) (pmd_page_vaddr(*(dir)) + __pte_index(addr))
@@ -236,8 +236,11 @@ extern struct page *empty_zero_page;
#define pte_unmap(pte) do { } while (0)
#define pte_unmap_nested(pte) do { } while (0)
-#define set_pte(ptep, pte) cpu_set_pte(ptep,pte)
-#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
+#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext)
+
+#define set_pte_at(mm,addr,ptep,pteval) do { \
+ set_pte_ext(ptep, pteval, (addr) >= PAGE_OFFSET ? 0 : PTE_EXT_NG); \
+ } while (0)
/*
* The following only work if pte_present() is true.
diff --git a/include/asm-arm/processor.h b/include/asm-arm/processor.h
index b442e8e2a809..1bbf16182d62 100644
--- a/include/asm-arm/processor.h
+++ b/include/asm-arm/processor.h
@@ -103,14 +103,14 @@ extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
#if __LINUX_ARM_ARCH__ >= 5
#define ARCH_HAS_PREFETCH
-#define prefetch(ptr) \
- ({ \
- __asm__ __volatile__( \
- "pld\t%0" \
- : \
- : "o" (*(char *)(ptr)) \
- : "cc"); \
- })
+static inline void prefetch(const void *ptr)
+{
+ __asm__ __volatile__(
+ "pld\t%0"
+ :
+ : "o" (*(char *)ptr)
+ : "cc");
+}
#define ARCH_HAS_PREFETCHW
#define prefetchw(ptr) prefetch(ptr)
diff --git a/include/asm-arm/system.h b/include/asm-arm/system.h
index f05fbe31576c..aa223fc546af 100644
--- a/include/asm-arm/system.h
+++ b/include/asm-arm/system.h
@@ -73,6 +73,7 @@
#ifndef __ASSEMBLY__
#include <linux/linkage.h>
+#include <linux/irqflags.h>
struct thread_info;
struct task_struct;
@@ -139,23 +140,44 @@ static inline int cpu_is_xsc3(void)
#define cpu_is_xscale() 1
#endif
-#define set_cr(x) \
- __asm__ __volatile__( \
- "mcr p15, 0, %0, c1, c0, 0 @ set CR" \
- : : "r" (x) : "cc")
-
-#define get_cr() \
- ({ \
- unsigned int __val; \
- __asm__ __volatile__( \
- "mrc p15, 0, %0, c1, c0, 0 @ get CR" \
- : "=r" (__val) : : "cc"); \
- __val; \
- })
-
extern unsigned long cr_no_alignment; /* defined in entry-armv.S */
extern unsigned long cr_alignment; /* defined in entry-armv.S */
+static inline unsigned int get_cr(void)
+{
+ unsigned int val;
+ asm("mrc p15, 0, %0, c1, c0, 0 @ get CR" : "=r" (val) : : "cc");
+ return val;
+}
+
+static inline void set_cr(unsigned int val)
+{
+ asm volatile("mcr p15, 0, %0, c1, c0, 0 @ set CR"
+ : : "r" (val) : "cc");
+}
+
+#ifndef CONFIG_SMP
+extern void adjust_cr(unsigned long mask, unsigned long set);
+#endif
+
+#define CPACC_FULL(n) (3 << (n * 2))
+#define CPACC_SVC(n) (1 << (n * 2))
+#define CPACC_DISABLE(n) (0 << (n * 2))
+
+static inline unsigned int get_copro_access(void)
+{
+ unsigned int val;
+ asm("mrc p15, 0, %0, c1, c0, 2 @ get copro access"
+ : "=r" (val) : : "cc");
+ return val;
+}
+
+static inline void set_copro_access(unsigned int val)
+{
+ asm volatile("mcr p15, 0, %0, c1, c0, 2 @ set copro access"
+ : : "r" (val) : "cc");
+}
+
#define UDBG_UNDEFINED (1 << 0)
#define UDBG_SYSCALL (1 << 1)
#define UDBG_BADABORT (1 << 2)
@@ -211,8 +233,6 @@ static inline void sched_cacheflush(void)
{
}
-#include <linux/irqflags.h>
-
#ifdef CONFIG_SMP
#define smp_mb() mb()
diff --git a/include/asm-arm/thread_info.h b/include/asm-arm/thread_info.h
index d9b8bddc8732..5014794f9eb3 100644
--- a/include/asm-arm/thread_info.h
+++ b/include/asm-arm/thread_info.h
@@ -147,6 +147,7 @@ extern void iwmmxt_task_switch(struct thread_info *);
#define TIF_POLLING_NRFLAG 16
#define TIF_USING_IWMMXT 17
#define TIF_MEMDIE 18
+#define TIF_FREEZE 19
#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
@@ -154,6 +155,7 @@ extern void iwmmxt_task_switch(struct thread_info *);
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
#define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT)
+#define _TIF_FREEZE (1 << TIF_FREEZE)
/*
* Change these and you break ASM code in entry-common.S
diff --git a/include/asm-arm/unistd.h b/include/asm-arm/unistd.h
index d44c629d8424..97e7060000cf 100644
--- a/include/asm-arm/unistd.h
+++ b/include/asm-arm/unistd.h
@@ -347,6 +347,31 @@
#define __NR_mbind (__NR_SYSCALL_BASE+319)
#define __NR_get_mempolicy (__NR_SYSCALL_BASE+320)
#define __NR_set_mempolicy (__NR_SYSCALL_BASE+321)
+#define __NR_openat (__NR_SYSCALL_BASE+322)
+#define __NR_mkdirat (__NR_SYSCALL_BASE+323)
+#define __NR_mknodat (__NR_SYSCALL_BASE+324)
+#define __NR_fchownat (__NR_SYSCALL_BASE+325)
+#define __NR_futimesat (__NR_SYSCALL_BASE+326)
+#define __NR_fstatat64 (__NR_SYSCALL_BASE+327)
+#define __NR_unlinkat (__NR_SYSCALL_BASE+328)
+#define __NR_renameat (__NR_SYSCALL_BASE+329)
+#define __NR_linkat (__NR_SYSCALL_BASE+330)
+#define __NR_symlinkat (__NR_SYSCALL_BASE+331)
+#define __NR_readlinkat (__NR_SYSCALL_BASE+332)
+#define __NR_fchmodat (__NR_SYSCALL_BASE+333)
+#define __NR_faccessat (__NR_SYSCALL_BASE+334)
+ /* 335 for pselect6 */
+ /* 336 for ppoll */
+#define __NR_unshare (__NR_SYSCALL_BASE+337)
+#define __NR_set_robust_list (__NR_SYSCALL_BASE+338)
+#define __NR_get_robust_list (__NR_SYSCALL_BASE+339)
+#define __NR_splice (__NR_SYSCALL_BASE+340)
+#define __NR_arm_sync_file_range (__NR_SYSCALL_BASE+341)
+#define __NR_tee (__NR_SYSCALL_BASE+342)
+#define __NR_vmsplice (__NR_SYSCALL_BASE+343)
+#define __NR_move_pages (__NR_SYSCALL_BASE+344)
+#define __NR_getcpu (__NR_SYSCALL_BASE+345)
+ /* 346 for epoll_pwait */
/*
* The following SWIs are ARM private.
diff --git a/include/asm-arm26/cacheflush.h b/include/asm-arm26/cacheflush.h
index 9c1b9c7f2ebd..14ae15b6faab 100644
--- a/include/asm-arm26/cacheflush.h
+++ b/include/asm-arm26/cacheflush.h
@@ -22,6 +22,7 @@
#define flush_cache_all() do { } while (0)
#define flush_cache_mm(mm) do { } while (0)
+#define flush_cache_dup_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_cache_vmap(start, end) do { } while (0)
diff --git a/include/asm-avr32/cacheflush.h b/include/asm-avr32/cacheflush.h
index f1bf1708980e..dfaaa88cd412 100644
--- a/include/asm-avr32/cacheflush.h
+++ b/include/asm-avr32/cacheflush.h
@@ -87,6 +87,7 @@ void invalidate_icache_region(void *start, size_t len);
*/
#define flush_cache_all() do { } while (0)
#define flush_cache_mm(mm) do { } while (0)
+#define flush_cache_dup_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_cache_vmap(start, end) do { } while (0)
diff --git a/include/asm-avr32/pgalloc.h b/include/asm-avr32/pgalloc.h
index 7492cfb92ced..bb82e70cde8d 100644
--- a/include/asm-avr32/pgalloc.h
+++ b/include/asm-avr32/pgalloc.h
@@ -28,7 +28,7 @@ static __inline__ void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
static __inline__ pgd_t *pgd_alloc(struct mm_struct *mm)
{
unsigned int pgd_size = (USER_PTRS_PER_PGD * sizeof(pgd_t));
- pgd_t *pgd = (pgd_t *)kmalloc(pgd_size, GFP_KERNEL);
+ pgd_t *pgd = kmalloc(pgd_size, GFP_KERNEL);
if (pgd)
memset(pgd, 0, pgd_size);
diff --git a/include/asm-cris/cacheflush.h b/include/asm-cris/cacheflush.h
index 72cc71dffe70..01af2de27c5b 100644
--- a/include/asm-cris/cacheflush.h
+++ b/include/asm-cris/cacheflush.h
@@ -9,6 +9,7 @@
*/
#define flush_cache_all() do { } while (0)
#define flush_cache_mm(mm) do { } while (0)
+#define flush_cache_dup_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_page(page) do { } while (0)
diff --git a/include/asm-frv/cacheflush.h b/include/asm-frv/cacheflush.h
index eaa5826bc1c8..02500405a6fb 100644
--- a/include/asm-frv/cacheflush.h
+++ b/include/asm-frv/cacheflush.h
@@ -20,6 +20,7 @@
*/
#define flush_cache_all() do {} while(0)
#define flush_cache_mm(mm) do {} while(0)
+#define flush_cache_dup_mm(mm) do {} while(0)
#define flush_cache_range(mm, start, end) do {} while(0)
#define flush_cache_page(vma, vmaddr, pfn) do {} while(0)
#define flush_cache_vmap(start, end) do {} while(0)
diff --git a/include/asm-frv/thread_info.h b/include/asm-frv/thread_info.h
index d66c48e6ef14..d881f518e6a9 100644
--- a/include/asm-frv/thread_info.h
+++ b/include/asm-frv/thread_info.h
@@ -116,6 +116,7 @@ register struct thread_info *__current_thread_info asm("gr15");
#define TIF_RESTORE_SIGMASK 6 /* restore signal mask in do_signal() */
#define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling TIF_NEED_RESCHED */
#define TIF_MEMDIE 17 /* OOM killer killed process */
+#define TIF_FREEZE 18 /* freezing for suspend */
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
@@ -125,6 +126,7 @@ register struct thread_info *__current_thread_info asm("gr15");
#define _TIF_IRET (1 << TIF_IRET)
#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
+#define _TIF_FREEZE (1 << TIF_FREEZE)
#define _TIF_WORK_MASK 0x0000FFFE /* work to do on interrupt/exception return */
#define _TIF_ALLWORK_MASK 0x0000FFFF /* work to do on any return to u-space */
diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h
index a06eecd48292..14fae1fa87df 100644
--- a/include/asm-generic/bug.h
+++ b/include/asm-generic/bug.h
@@ -35,7 +35,7 @@ struct bug_entry {
#define WARN_ON(condition) ({ \
typeof(condition) __ret_warn_on = (condition); \
if (unlikely(__ret_warn_on)) { \
- printk("WARNING at %s:%d %s()\n", __FILE__, \
+ printk("BUG: at %s:%d %s()\n", __FILE__, \
__LINE__, __FUNCTION__); \
dump_stack(); \
} \
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 7437ccaada77..9fcc8d9fbb14 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -35,6 +35,9 @@
VMLINUX_SYMBOL(__start_pci_fixups_enable) = .; \
*(.pci_fixup_enable) \
VMLINUX_SYMBOL(__end_pci_fixups_enable) = .; \
+ VMLINUX_SYMBOL(__start_pci_fixups_resume) = .; \
+ *(.pci_fixup_resume) \
+ VMLINUX_SYMBOL(__end_pci_fixups_resume) = .; \
} \
\
/* RapidIO route ops */ \
@@ -119,8 +122,6 @@
*(__ksymtab_strings) \
} \
\
- EH_FRAME \
- \
/* Built-in module parameters. */ \
__param : AT(ADDR(__param) - LOAD_OFFSET) { \
VMLINUX_SYMBOL(__start___param) = .; \
@@ -160,26 +161,6 @@
*(.kprobes.text) \
VMLINUX_SYMBOL(__kprobes_text_end) = .;
-#ifdef CONFIG_STACK_UNWIND
-#define EH_FRAME \
- /* Unwind data binary search table */ \
- . = ALIGN(8); \
- .eh_frame_hdr : AT(ADDR(.eh_frame_hdr) - LOAD_OFFSET) { \
- VMLINUX_SYMBOL(__start_unwind_hdr) = .; \
- *(.eh_frame_hdr) \
- VMLINUX_SYMBOL(__end_unwind_hdr) = .; \
- } \
- /* Unwind data */ \
- . = ALIGN(8); \
- .eh_frame : AT(ADDR(.eh_frame) - LOAD_OFFSET) { \
- VMLINUX_SYMBOL(__start_unwind) = .; \
- *(.eh_frame) \
- VMLINUX_SYMBOL(__end_unwind) = .; \
- }
-#else
-#define EH_FRAME
-#endif
-
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to
the beginning of the section so we begin them at 0. */
diff --git a/include/asm-h8300/cacheflush.h b/include/asm-h8300/cacheflush.h
index 1e4d95bb5ec9..71210d141b64 100644
--- a/include/asm-h8300/cacheflush.h
+++ b/include/asm-h8300/cacheflush.h
@@ -12,6 +12,7 @@
#define flush_cache_all()
#define flush_cache_mm(mm)
+#define flush_cache_dup_mm(mm) do { } while (0)
#define flush_cache_range(vma,a,b)
#define flush_cache_page(vma,p,pfn)
#define flush_dcache_page(page)
diff --git a/include/asm-i386/acpi.h b/include/asm-i386/acpi.h
index c80b3a94511a..7cfad93edf10 100644
--- a/include/asm-i386/acpi.h
+++ b/include/asm-i386/acpi.h
@@ -56,30 +56,8 @@
#define ACPI_ENABLE_IRQS() local_irq_enable()
#define ACPI_FLUSH_CPU_CACHE() wbinvd()
-
-static inline int
-__acpi_acquire_global_lock (unsigned int *lock)
-{
- unsigned int old, new, val;
- do {
- old = *lock;
- new = (((old & ~0x3) + 2) + ((old >> 1) & 0x1));
- val = cmpxchg(lock, old, new);
- } while (unlikely (val != old));
- return (new < 3) ? -1 : 0;
-}
-
-static inline int
-__acpi_release_global_lock (unsigned int *lock)
-{
- unsigned int old, new, val;
- do {
- old = *lock;
- new = old & ~0x3;
- val = cmpxchg(lock, old, new);
- } while (unlikely (val != old));
- return old & 0x1;
-}
+int __acpi_acquire_global_lock(unsigned int *lock);
+int __acpi_release_global_lock(unsigned int *lock);
#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \
((Acq) = __acpi_acquire_global_lock((unsigned int *) GLptr))
diff --git a/include/asm-i386/cacheflush.h b/include/asm-i386/cacheflush.h
index 7199f7b326f1..74e03c8f2e51 100644
--- a/include/asm-i386/cacheflush.h
+++ b/include/asm-i386/cacheflush.h
@@ -7,6 +7,7 @@
/* Caches aren't brain-dead on the intel. */
#define flush_cache_all() do { } while (0)
#define flush_cache_mm(mm) do { } while (0)
+#define flush_cache_dup_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_page(page) do { } while (0)
diff --git a/include/asm-i386/e820.h b/include/asm-i386/e820.h
index 395077aba583..c5b8fc6109d6 100644
--- a/include/asm-i386/e820.h
+++ b/include/asm-i386/e820.h
@@ -40,7 +40,7 @@ extern int e820_all_mapped(unsigned long start, unsigned long end,
unsigned type);
extern void find_max_pfn(void);
extern void register_bootmem_low_pages(unsigned long max_low_pfn);
-extern void register_memory(void);
+extern void e820_register_memory(void);
extern void limit_regions(unsigned long long size);
extern void print_memory_map(char *who);
diff --git a/include/asm-i386/thread_info.h b/include/asm-i386/thread_info.h
index 46d32ad92082..4b187bb377b4 100644
--- a/include/asm-i386/thread_info.h
+++ b/include/asm-i386/thread_info.h
@@ -134,6 +134,7 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_MEMDIE 16
#define TIF_DEBUG 17 /* uses debug registers */
#define TIF_IO_BITMAP 18 /* uses I/O bitmap */
+#define TIF_FREEZE 19 /* is freezing for suspend */
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
@@ -147,6 +148,7 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
#define _TIF_DEBUG (1<<TIF_DEBUG)
#define _TIF_IO_BITMAP (1<<TIF_IO_BITMAP)
+#define _TIF_FREEZE (1<<TIF_FREEZE)
/* work to do on interrupt/exception return */
#define _TIF_WORK_MASK \
diff --git a/include/asm-i386/unwind.h b/include/asm-i386/unwind.h
index aa2c931e30db..43c70c3de2f9 100644
--- a/include/asm-i386/unwind.h
+++ b/include/asm-i386/unwind.h
@@ -1,95 +1,6 @@
#ifndef _ASM_I386_UNWIND_H
#define _ASM_I386_UNWIND_H
-/*
- * Copyright (C) 2002-2006 Novell, Inc.
- * Jan Beulich <jbeulich@novell.com>
- * This code is released under version 2 of the GNU GPL.
- */
-
-#ifdef CONFIG_STACK_UNWIND
-
-#include <linux/sched.h>
-#include <asm/fixmap.h>
-#include <asm/ptrace.h>
-#include <asm/uaccess.h>
-
-struct unwind_frame_info
-{
- struct pt_regs regs;
- struct task_struct *task;
- unsigned call_frame:1;
-};
-
-#define UNW_PC(frame) (frame)->regs.eip
-#define UNW_SP(frame) (frame)->regs.esp
-#ifdef CONFIG_FRAME_POINTER
-#define UNW_FP(frame) (frame)->regs.ebp
-#define FRAME_RETADDR_OFFSET 4
-#define FRAME_LINK_OFFSET 0
-#define STACK_BOTTOM(tsk) STACK_LIMIT((tsk)->thread.esp0)
-#define STACK_TOP(tsk) ((tsk)->thread.esp0)
-#else
-#define UNW_FP(frame) ((void)(frame), 0)
-#endif
-#define STACK_LIMIT(ptr) (((ptr) - 1) & ~(THREAD_SIZE - 1))
-
-#define UNW_REGISTER_INFO \
- PTREGS_INFO(eax), \
- PTREGS_INFO(ecx), \
- PTREGS_INFO(edx), \
- PTREGS_INFO(ebx), \
- PTREGS_INFO(esp), \
- PTREGS_INFO(ebp), \
- PTREGS_INFO(esi), \
- PTREGS_INFO(edi), \
- PTREGS_INFO(eip)
-
-#define UNW_DEFAULT_RA(raItem, dataAlign) \
- ((raItem).where == Memory && \
- !((raItem).value * (dataAlign) + 4))
-
-static inline void arch_unw_init_frame_info(struct unwind_frame_info *info,
- /*const*/ struct pt_regs *regs)
-{
- if (user_mode_vm(regs))
- info->regs = *regs;
- else {
- memcpy(&info->regs, regs, offsetof(struct pt_regs, esp));
- info->regs.esp = (unsigned long)&regs->esp;
- info->regs.xss = __KERNEL_DS;
- }
-}
-
-static inline void arch_unw_init_blocked(struct unwind_frame_info *info)
-{
- memset(&info->regs, 0, sizeof(info->regs));
- info->regs.eip = info->task->thread.eip;
- info->regs.xcs = __KERNEL_CS;
- __get_user(info->regs.ebp, (long *)info->task->thread.esp);
- info->regs.esp = info->task->thread.esp;
- info->regs.xss = __KERNEL_DS;
- info->regs.xds = __USER_DS;
- info->regs.xes = __USER_DS;
- info->regs.xgs = __KERNEL_PDA;
-}
-
-extern asmlinkage int arch_unwind_init_running(struct unwind_frame_info *,
- asmlinkage int (*callback)(struct unwind_frame_info *,
- void *arg),
- void *arg);
-
-static inline int arch_unw_user_mode(/*const*/ struct unwind_frame_info *info)
-{
- return user_mode_vm(&info->regs)
- || info->regs.eip < PAGE_OFFSET
- || (info->regs.eip >= __fix_to_virt(FIX_VDSO)
- && info->regs.eip < __fix_to_virt(FIX_VDSO) + PAGE_SIZE)
- || info->regs.esp < PAGE_OFFSET;
-}
-
-#else
-
#define UNW_PC(frame) ((void)(frame), 0)
#define UNW_SP(frame) ((void)(frame), 0)
#define UNW_FP(frame) ((void)(frame), 0)
@@ -99,6 +10,4 @@ static inline int arch_unw_user_mode(const void *info)
return 0;
}
-#endif
-
#endif /* _ASM_I386_UNWIND_H */
diff --git a/include/asm-ia64/cacheflush.h b/include/asm-ia64/cacheflush.h
index f2dacb4245ec..4906916d715b 100644
--- a/include/asm-ia64/cacheflush.h
+++ b/include/asm-ia64/cacheflush.h
@@ -18,6 +18,7 @@
#define flush_cache_all() do { } while (0)
#define flush_cache_mm(mm) do { } while (0)
+#define flush_cache_dup_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_icache_page(vma,page) do { } while (0)
diff --git a/include/asm-ia64/pci.h b/include/asm-ia64/pci.h
index 825eb7d882e6..556f53fa44cb 100644
--- a/include/asm-ia64/pci.h
+++ b/include/asm-ia64/pci.h
@@ -78,9 +78,6 @@ pcibios_penalize_isa_irq (int irq, int active)
#define pci_dac_dma_sync_single_for_cpu(dev,dma_addr,len,dir) do { } while (0)
#define pci_dac_dma_sync_single_for_device(dev,dma_addr,len,dir) do { mb(); } while (0)
-#define sg_dma_len(sg) ((sg)->dma_length)
-#define sg_dma_address(sg) ((sg)->dma_address)
-
#ifdef CONFIG_PCI
static inline void pci_dma_burst_advice(struct pci_dev *pdev,
enum pci_dma_burst_strategy *strat,
diff --git a/include/asm-ia64/scatterlist.h b/include/asm-ia64/scatterlist.h
index 834a189ef189..9dbea8844d5e 100644
--- a/include/asm-ia64/scatterlist.h
+++ b/include/asm-ia64/scatterlist.h
@@ -25,4 +25,7 @@ struct scatterlist {
*/
#define ISA_DMA_THRESHOLD 0xffffffff
+#define sg_dma_len(sg) ((sg)->dma_length)
+#define sg_dma_address(sg) ((sg)->dma_address)
+
#endif /* _ASM_IA64_SCATTERLIST_H */
diff --git a/include/asm-ia64/thread_info.h b/include/asm-ia64/thread_info.h
index 8adcde0934ca..9b505b25544f 100644
--- a/include/asm-ia64/thread_info.h
+++ b/include/asm-ia64/thread_info.h
@@ -88,6 +88,7 @@ struct thread_info {
#define TIF_MEMDIE 17
#define TIF_MCA_INIT 18 /* this task is processing MCA or INIT */
#define TIF_DB_DISABLED 19 /* debug trap disabled for fsyscall */
+#define TIF_FREEZE 20 /* is freezing for suspend */
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
@@ -98,6 +99,7 @@ struct thread_info {
#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
#define _TIF_MCA_INIT (1 << TIF_MCA_INIT)
#define _TIF_DB_DISABLED (1 << TIF_DB_DISABLED)
+#define _TIF_FREEZE (1 << TIF_FREEZE)
/* "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)
diff --git a/include/asm-m32r/cacheflush.h b/include/asm-m32r/cacheflush.h
index 8b261b49149e..56961a9511b2 100644
--- a/include/asm-m32r/cacheflush.h
+++ b/include/asm-m32r/cacheflush.h
@@ -9,6 +9,7 @@ extern void _flush_cache_copyback_all(void);
#if defined(CONFIG_CHIP_M32700) || defined(CONFIG_CHIP_OPSP) || defined(CONFIG_CHIP_M32104)
#define flush_cache_all() do { } while (0)
#define flush_cache_mm(mm) do { } while (0)
+#define flush_cache_dup_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_page(page) do { } while (0)
@@ -29,6 +30,7 @@ extern void smp_flush_cache_all(void);
#elif defined(CONFIG_CHIP_M32102)
#define flush_cache_all() do { } while (0)
#define flush_cache_mm(mm) do { } while (0)
+#define flush_cache_dup_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_page(page) do { } while (0)
@@ -41,6 +43,7 @@ extern void smp_flush_cache_all(void);
#else
#define flush_cache_all() do { } while (0)
#define flush_cache_mm(mm) do { } while (0)
+#define flush_cache_dup_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_page(page) do { } while (0)
diff --git a/include/asm-m68k/cacheflush.h b/include/asm-m68k/cacheflush.h
index 24d3ff449135..16bf375fdbe1 100644
--- a/include/asm-m68k/cacheflush.h
+++ b/include/asm-m68k/cacheflush.h
@@ -89,6 +89,8 @@ static inline void flush_cache_mm(struct mm_struct *mm)
__flush_cache_030();
}
+#define flush_cache_dup_mm(mm) flush_cache_mm(mm)
+
/* flush_cache_range/flush_cache_page must be macros to avoid
a dependency on linux/mm.h, which includes this file... */
static inline void flush_cache_range(struct vm_area_struct *vma,
diff --git a/include/asm-m68k/swim_iop.h b/include/asm-m68k/swim_iop.h
deleted file mode 100644
index f29b67876b01..000000000000
--- a/include/asm-m68k/swim_iop.h
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * SWIM access through the IOP
- * Written by Joshua M. Thompson
- */
-
-/* IOP number and channel number for the SWIM */
-
-#define SWIM_IOP IOP_NUM_ISM
-#define SWIM_CHAN 1
-
-/* Command code: */
-
-#define CMD_INIT 0x01 /* Initialize */
-#define CMD_SHUTDOWN 0x02 /* Shutdown */
-#define CMD_START_POLL 0x03 /* Start insert/eject polling */
-#define CMD_STOP_POLL 0x04 /* Stop insert/eject polling */
-#define CMD_SETHFSTAG 0x05 /* Set HFS tag buffer address */
-#define CMD_STATUS 0x06 /* Status */
-#define CMD_EJECT 0x07 /* Eject */
-#define CMD_FORMAT 0x08 /* Format */
-#define CMD_FORMAT_VERIFY 0x09 /* Format and Verify */
-#define CMD_WRITE 0x0A /* Write */
-#define CMD_READ 0x0B /* Read */
-#define CMD_READ_VERIFY 0x0C /* Read and Verify */
-#define CMD_CACHE_CTRL 0x0D /* Cache control */
-#define CMD_TAGBUFF_CTRL 0x0E /* Tag buffer control */
-#define CMD_GET_ICON 0x0F /* Get Icon */
-
-/* Drive types: */
-
-/* note: apple sez DRV_FDHD is 4, but I get back a type */
-/* of 5 when I do a drive status check on my FDHD */
-
-#define DRV_NONE 0 /* No drive */
-#define DRV_UNKNOWN 1 /* Unspecified drive */
-#define DRV_400K 2 /* 400K */
-#define DRV_800K 3 /* 400K/800K */
-#define DRV_FDHD 5 /* 400K/800K/720K/1440K */
-#define DRV_HD20 7 /* Apple HD20 */
-
-/* Format types: */
-
-#define FMT_HD20 0x0001 /* Apple HD20 */
-#define FMT_400K 0x0002 /* 400K (GCR) */
-#define FMT_800K 0x0004 /* 800K (GCR) */
-#define FMT_720K 0x0008 /* 720K (MFM) */
-#define FMT_1440K 0x0010 /* 1.44M (MFM) */
-
-#define FMD_KIND_400K 1
-#define FMD_KIND_800K 2
-#define FMD_KIND_720K 3
-#define FMD_KIND_1440K 1
-
-/* Icon Flags: */
-
-#define ICON_MEDIA 0x01 /* Have IOP supply media icon */
-#define ICON_DRIVE 0x01 /* Have IOP supply drive icon */
-
-/* Error codes: */
-
-#define gcrOnMFMErr -400 /* GCR (400/800K) on HD media */
-#define verErr -84 /* verify failed */
-#define fmt2Err -83 /* can't get enough sync during format */
-#define fmt1Err -82 /* can't find sector 0 after track format */
-#define sectNFErr -81 /* can't find sector */
-#define seekErr -80 /* drive error during seek */
-#define spdAdjErr -79 /* can't set drive speed */
-#define twoSideErr -78 /* drive is single-sided */
-#define initIWMErr -77 /* error during initialization */
-#define tk0badErr -76 /* track zero is bad */
-#define cantStepErr -75 /* drive error during step */
-#define wrUnderrun -74 /* write underrun occurred */
-#define badDBtSlp -73 /* bad data bitslip marks */
-#define badDCksum -72 /* bad data checksum */
-#define noDtaMkErr -71 /* can't find data mark */
-#define badBtSlpErr -70 /* bad address bitslip marks */
-#define badCksmErr -69 /* bad address-mark checksum */
-#define dataVerErr -68 /* read-verify failed */
-#define noAdrMkErr -67 /* can't find an address mark */
-#define noNybErr -66 /* no nybbles? disk is probably degaussed */
-#define offLinErr -65 /* no disk in drive */
-#define noDriveErr -64 /* drive isn't connected */
-#define nsDrvErr -56 /* no such drive */
-#define paramErr -50 /* bad positioning information */
-#define wPrErr -44 /* write protected */
-#define openErr -23 /* already initialized */
-
-#ifndef __ASSEMBLY__
-
-struct swim_drvstatus {
- __u16 curr_track; /* Current track number */
- __u8 write_prot; /* 0x80 if disk is write protected */
- __u8 disk_in_drive; /* 0x01 or 0x02 if a disk is in the drive */
- __u8 installed; /* 0x01 if drive installed, 0xFF if not */
- __u8 num_sides; /* 0x80 if two-sided format supported */
- __u8 two_sided; /* 0xff if two-sided format diskette */
- __u8 new_interface; /* 0x00 if old 400K drive, 0xFF if newer */
- __u16 errors; /* Disk error count */
- struct { /* 32 bits */
- __u16 reserved;
- __u16 :4;
- __u16 external:1; /* Drive is external */
- __u16 scsi:1; /* Drive is a SCSI drive */
- __u16 fixed:1; /* Drive has fixed media */
- __u16 secondary:1; /* Drive is secondary drive */
- __u8 type; /* Drive type */
- } info;
- __u8 mfm_drive; /* 0xFF if this is an FDHD drive */
- __u8 mfm_disk; /* 0xFF if 720K/1440K (MFM) disk */
- __u8 mfm_format; /* 0x00 if 720K, 0xFF if 1440K */
- __u8 ctlr_type; /* 0x00 if IWM, 0xFF if SWIM */
- __u16 curr_format; /* Current format type */
- __u16 allowed_fmt; /* Allowed format types */
- __u32 num_blocks; /* Number of blocks on disk */
- __u8 icon_flags; /* Icon flags */
- __u8 unusued;
-};
-
-/* Commands issued from the host to the IOP: */
-
-struct swimcmd_init {
- __u8 code; /* CMD_INIT */
- __u8 unusued;
- __u16 error;
- __u8 drives[28]; /* drive type list */
-};
-
-struct swimcmd_startpoll {
- __u8 code; /* CMD_START_POLL */
- __u8 unusued;
- __u16 error;
-};
-
-struct swimcmd_sethfstag {
- __u8 code; /* CMD_SETHFSTAG */
- __u8 unusued;
- __u16 error;
- caddr_t tagbuf; /* HFS tag buffer address */
-};
-
-struct swimcmd_status {
- __u8 code; /* CMD_STATUS */
- __u8 drive_num;
- __u16 error;
- struct swim_drvstatus status;
-};
-
-struct swimcmd_eject {
- __u8 code; /* CMD_EJECT */
- __u8 drive_num;
- __u16 error;
- struct swim_drvstatus status;
-};
-
-struct swimcmd_format {
- __u8 code; /* CMD_FORMAT */
- __u8 drive_num;
- __u16 error;
- union {
- struct {
- __u16 fmt; /* format kind */
- __u8 hdrbyte; /* fmt byte for hdr (0=default) */
- __u8 interleave; /* interleave (0 = default) */
- caddr_t databuf; /* sector data buff (0=default */
- caddr_t tagbuf; /* tag data buffer (0=default) */
- } f;
- struct swim_drvstatus status;
- } p;
-};
-
-struct swimcmd_fmtverify {
- __u8 code; /* CMD_FORMAT_VERIFY */
- __u8 drive_num;
- __u16 error;
-};
-
-struct swimcmd_rw {
- __u8 code; /* CMD_READ, CMD_WRITE or CMD_READ_VERIFY */
- __u8 drive_num;
- __u16 error;
- caddr_t buffer; /* R/W buffer address */
- __u32 first_block; /* Starting block */
- __u32 num_blocks; /* Number of blocks */
- __u8 tag[12]; /* tag data */
-};
-
-struct swimcmd_cachectl {
- __u8 code; /* CMD_CACHE_CTRL */
- __u8 unused;
- __u16 error;
- __u8 enable; /* Nonzero to enable cache */
- __u8 install; /* +1 = install, -1 = remove, 0 = neither */
-};
-
-struct swimcmd_tagbufctl {
- __u8 code; /* CMD_TAGBUFF_CTRL */
- __u8 unused;
- __u16 error;
- caddr_t buf; /* buffer address or 0 to disable */
-};
-
-struct swimcmd_geticon {
- __u8 code; /* CMD_GET_ICON */
- __u8 drive_num;
- __u16 error;
- caddr_t buffer; /* Nuffer address */
- __u16 kind; /* 0 = media icon, 1 = drive icon */
- __u16 unused;
- __u16 max_bytes; /* maximum byte count */
-};
-
-/* Messages from the SWIM IOP to the host CPU: */
-
-struct swimmsg_status {
- __u8 code; /* 1 = insert, 2 = eject, 3 = status changed */
- __u8 drive_num;
- __u16 error;
- struct swim_drvstatus status;
-};
-
-#endif /* __ASSEMBLY__ */
diff --git a/include/asm-m68knommu/cacheflush.h b/include/asm-m68knommu/cacheflush.h
index c3aadf3b0d88..163dcb1a9689 100644
--- a/include/asm-m68knommu/cacheflush.h
+++ b/include/asm-m68knommu/cacheflush.h
@@ -8,6 +8,7 @@
#define flush_cache_all() __flush_cache_all()
#define flush_cache_mm(mm) do { } while (0)
+#define flush_cache_dup_mm(mm) 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()
diff --git a/include/asm-mips/cacheflush.h b/include/asm-mips/cacheflush.h
index e3c9925876a3..0ddada3bb0b6 100644
--- a/include/asm-mips/cacheflush.h
+++ b/include/asm-mips/cacheflush.h
@@ -17,6 +17,7 @@
*
* - flush_cache_all() flushes entire cache
* - flush_cache_mm(mm) flushes the specified mm context's cache lines
+ * - flush_cache_dup mm(mm) handles cache flushing when forking
* - flush_cache_page(mm, vmaddr, pfn) flushes a single page
* - flush_cache_range(vma, start, end) flushes a range of pages
* - flush_icache_range(start, end) flush a range of instructions
@@ -31,6 +32,7 @@
extern void (*flush_cache_all)(void);
extern void (*__flush_cache_all)(void);
extern void (*flush_cache_mm)(struct mm_struct *mm);
+#define flush_cache_dup_mm(mm) do { (void) (mm); } while (0)
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 page, unsigned long pfn);
diff --git a/include/asm-mips/page.h b/include/asm-mips/page.h
index 0dc1a45c27ed..2f9e1a9ec51f 100644
--- a/include/asm-mips/page.h
+++ b/include/asm-mips/page.h
@@ -35,7 +35,6 @@
#ifndef __ASSEMBLY__
#include <linux/pfn.h>
-#include <asm/cpu-features.h>
#include <asm/io.h>
extern void clear_page(void * page);
@@ -61,16 +60,13 @@ static inline void clear_user_page(void *addr, unsigned long vaddr,
flush_data_cache_page((unsigned long)addr);
}
-static inline void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
- struct page *to)
-{
- extern void (*flush_data_cache_page)(unsigned long addr);
+extern void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
+ struct page *to);
+struct vm_area_struct;
+extern void copy_user_highpage(struct page *to, struct page *from,
+ unsigned long vaddr, struct vm_area_struct *vma);
- copy_page(vto, vfrom);
- if (!cpu_has_ic_fills_f_dc ||
- pages_do_alias((unsigned long)vto, vaddr & PAGE_MASK))
- flush_data_cache_page((unsigned long)vto);
-}
+#define __HAVE_ARCH_COPY_USER_HIGHPAGE
/*
* These are used to make use of C type-checking..
diff --git a/include/asm-parisc/cacheflush.h b/include/asm-parisc/cacheflush.h
index 2bc41f2e0271..aedb0512cb04 100644
--- a/include/asm-parisc/cacheflush.h
+++ b/include/asm-parisc/cacheflush.h
@@ -15,6 +15,8 @@
#define flush_cache_mm(mm) flush_cache_all_local()
#endif
+#define flush_cache_dup_mm(mm) flush_cache_mm(mm)
+
#define flush_kernel_dcache_range(start,size) \
flush_kernel_dcache_range_asm((start), (start)+(size));
diff --git a/include/asm-powerpc/cacheflush.h b/include/asm-powerpc/cacheflush.h
index 8a740c88d93d..08e93e789219 100644
--- a/include/asm-powerpc/cacheflush.h
+++ b/include/asm-powerpc/cacheflush.h
@@ -18,6 +18,7 @@
*/
#define flush_cache_all() do { } while (0)
#define flush_cache_mm(mm) do { } while (0)
+#define flush_cache_dup_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_icache_page(vma, page) do { } while (0)
diff --git a/include/asm-powerpc/spu.h b/include/asm-powerpc/spu.h
index fdad4267b447..3d90264e9d36 100644
--- a/include/asm-powerpc/spu.h
+++ b/include/asm-powerpc/spu.h
@@ -161,6 +161,7 @@ struct spu_syscall_block {
extern long spu_sys_callback(struct spu_syscall_block *s);
/* syscalls implemented in spufs */
+struct file;
extern struct spufs_calls {
asmlinkage long (*create_thread)(const char __user *name,
unsigned int flags, mode_t mode);
@@ -232,6 +233,7 @@ void spu_remove_sysdev_attr_group(struct attribute_group *attrs);
* to object-id spufs file from user space and the notifer
* function can assume that spu->ctx is valid.
*/
+struct notifier_block;
int spu_switch_event_register(struct notifier_block * n);
int spu_switch_event_unregister(struct notifier_block * n);
diff --git a/include/asm-powerpc/thread_info.h b/include/asm-powerpc/thread_info.h
index d339e2e88b11..3f32ca8bfec9 100644
--- a/include/asm-powerpc/thread_info.h
+++ b/include/asm-powerpc/thread_info.h
@@ -122,6 +122,7 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_RESTOREALL 12 /* Restore all regs (implies NOERROR) */
#define TIF_NOERROR 14 /* Force successful syscall return */
#define TIF_RESTORE_SIGMASK 15 /* Restore signal mask in do_signal */
+#define TIF_FREEZE 16 /* Freezing for suspend */
/* as above, but as bit values */
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
@@ -138,6 +139,7 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_RESTOREALL (1<<TIF_RESTOREALL)
#define _TIF_NOERROR (1<<TIF_NOERROR)
#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
+#define _TIF_FREEZE (1<<TIF_FREEZE)
#define _TIF_SYSCALL_T_OR_A (_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP)
#define _TIF_USER_WORK_MASK (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING | \
diff --git a/include/asm-s390/cacheflush.h b/include/asm-s390/cacheflush.h
index e399a8ba2ed7..f7cade8083f3 100644
--- a/include/asm-s390/cacheflush.h
+++ b/include/asm-s390/cacheflush.h
@@ -7,6 +7,7 @@
/* Caches aren't brain-dead on the s390. */
#define flush_cache_all() do { } while (0)
#define flush_cache_mm(mm) do { } while (0)
+#define flush_cache_dup_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_page(page) do { } while (0)
diff --git a/include/asm-s390/qdio.h b/include/asm-s390/qdio.h
index 7189c79bc673..127f72e77419 100644
--- a/include/asm-s390/qdio.h
+++ b/include/asm-s390/qdio.h
@@ -34,6 +34,7 @@
#define QDIO_QETH_QFMT 0
#define QDIO_ZFCP_QFMT 1
#define QDIO_IQDIO_QFMT 2
+#define QDIO_IQDIO_QFMT_ASYNCH 3
struct qdio_buffer_element{
unsigned int flags;
diff --git a/include/asm-s390/reset.h b/include/asm-s390/reset.h
index 9b439cf67800..532e65a2aafc 100644
--- a/include/asm-s390/reset.h
+++ b/include/asm-s390/reset.h
@@ -19,5 +19,6 @@ extern void register_reset_call(struct reset_call *reset);
extern void unregister_reset_call(struct reset_call *reset);
extern void s390_reset_system(void);
extern void (*s390_reset_mcck_handler)(void);
+extern void (*s390_reset_pgm_handler)(void);
#endif /* _ASM_S390_RESET_H */
diff --git a/include/asm-sh/cpu-sh2/cacheflush.h b/include/asm-sh/cpu-sh2/cacheflush.h
index f556fa80ea97..2979efb26de3 100644
--- a/include/asm-sh/cpu-sh2/cacheflush.h
+++ b/include/asm-sh/cpu-sh2/cacheflush.h
@@ -15,6 +15,7 @@
*
* - flush_cache_all() flushes entire cache
* - flush_cache_mm(mm) flushes the specified mm context's cache lines
+ * - flush_cache_dup mm(mm) handles cache flushing when forking
* - flush_cache_page(mm, vmaddr, pfn) flushes a single page
* - flush_cache_range(vma, start, end) flushes a range of pages
*
@@ -27,6 +28,7 @@
*/
#define flush_cache_all() do { } while (0)
#define flush_cache_mm(mm) do { } while (0)
+#define flush_cache_dup_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_page(page) do { } while (0)
diff --git a/include/asm-sh/cpu-sh3/cacheflush.h b/include/asm-sh/cpu-sh3/cacheflush.h
index 03fde97a7fd0..f70d8ef76a15 100644
--- a/include/asm-sh/cpu-sh3/cacheflush.h
+++ b/include/asm-sh/cpu-sh3/cacheflush.h
@@ -15,6 +15,7 @@
*
* - flush_cache_all() flushes entire cache
* - flush_cache_mm(mm) flushes the specified mm context's cache lines
+ * - flush_cache_dup mm(mm) handles cache flushing when forking
* - flush_cache_page(mm, vmaddr, pfn) flushes a single page
* - flush_cache_range(vma, start, end) flushes a range of pages
*
@@ -39,6 +40,7 @@
void flush_cache_all(void);
void flush_cache_mm(struct mm_struct *mm);
+#define flush_cache_dup_mm(mm) flush_cache_mm(mm)
void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
unsigned long end);
void flush_cache_page(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn);
@@ -48,6 +50,7 @@ void flush_icache_page(struct vm_area_struct *vma, struct page *page);
#else
#define flush_cache_all() do { } while (0)
#define flush_cache_mm(mm) do { } while (0)
+#define flush_cache_dup_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_page(page) do { } while (0)
diff --git a/include/asm-sh/cpu-sh4/cacheflush.h b/include/asm-sh/cpu-sh4/cacheflush.h
index 515fd574267c..b01a10f31225 100644
--- a/include/asm-sh/cpu-sh4/cacheflush.h
+++ b/include/asm-sh/cpu-sh4/cacheflush.h
@@ -18,6 +18,7 @@
*/
void flush_cache_all(void);
void flush_cache_mm(struct mm_struct *mm);
+#define flush_cache_dup_mm(mm) flush_cache_mm(mm)
void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
unsigned long end);
void flush_cache_page(struct vm_area_struct *vma, unsigned long addr,
diff --git a/include/asm-sh/thread_info.h b/include/asm-sh/thread_info.h
index 0c01dc550819..879f741105db 100644
--- a/include/asm-sh/thread_info.h
+++ b/include/asm-sh/thread_info.h
@@ -106,6 +106,7 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */
#define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */
#define TIF_MEMDIE 18
+#define TIF_FREEZE 19
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
@@ -114,6 +115,7 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
#define _TIF_USEDFPU (1<<TIF_USEDFPU)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
+#define _TIF_FREEZE (1<<TIF_FREEZE)
#define _TIF_WORK_MASK 0x000000FE /* work to do on interrupt/exception return */
#define _TIF_ALLWORK_MASK 0x000000FF /* work to do on any return to u-space */
diff --git a/include/asm-sh64/cacheflush.h b/include/asm-sh64/cacheflush.h
index 55f71aa0aa6b..1e53a47bdc97 100644
--- a/include/asm-sh64/cacheflush.h
+++ b/include/asm-sh64/cacheflush.h
@@ -21,6 +21,8 @@ extern void flush_icache_user_range(struct vm_area_struct *vma,
struct page *page, unsigned long addr,
int len);
+#define flush_cache_dup_mm(mm) flush_cache_mm(mm)
+
#define flush_dcache_mmap_lock(mapping) do { } while (0)
#define flush_dcache_mmap_unlock(mapping) do { } while (0)
diff --git a/include/asm-sh64/pgalloc.h b/include/asm-sh64/pgalloc.h
index b29dd468817e..cb803e56cb64 100644
--- a/include/asm-sh64/pgalloc.h
+++ b/include/asm-sh64/pgalloc.h
@@ -41,7 +41,7 @@ static inline void pgd_init(unsigned long page)
static inline pgd_t *get_pgd_slow(void)
{
unsigned int pgd_size = (USER_PTRS_PER_PGD * sizeof(pgd_t));
- pgd_t *ret = (pgd_t *)kmalloc(pgd_size, GFP_KERNEL);
+ pgd_t *ret = kmalloc(pgd_size, GFP_KERNEL);
return ret;
}
diff --git a/include/asm-sparc/bitops.h b/include/asm-sparc/bitops.h
index 04aa3318f76a..329e696e7751 100644
--- a/include/asm-sparc/bitops.h
+++ b/include/asm-sparc/bitops.h
@@ -14,6 +14,10 @@
#ifdef __KERNEL__
+extern unsigned long ___set_bit(unsigned long *addr, unsigned long mask);
+extern unsigned long ___clear_bit(unsigned long *addr, unsigned long mask);
+extern unsigned long ___change_bit(unsigned long *addr, unsigned long mask);
+
/*
* Set bit 'nr' in 32-bit quantity at address 'addr' where bit '0'
* is in the highest of the four bytes and bit '31' is the high bit
@@ -22,134 +26,62 @@
*/
static inline int test_and_set_bit(unsigned long nr, volatile unsigned long *addr)
{
- register unsigned long mask asm("g2");
- register unsigned long *ADDR asm("g1");
- register int tmp1 asm("g3");
- register int tmp2 asm("g4");
- register int tmp3 asm("g5");
- register int tmp4 asm("g7");
+ unsigned long *ADDR, mask;
ADDR = ((unsigned long *) addr) + (nr >> 5);
mask = 1 << (nr & 31);
- __asm__ __volatile__(
- "mov %%o7, %%g4\n\t"
- "call ___set_bit\n\t"
- " add %%o7, 8, %%o7\n"
- : "=&r" (mask), "=r" (tmp1), "=r" (tmp2), "=r" (tmp3), "=r" (tmp4)
- : "0" (mask), "r" (ADDR)
- : "memory", "cc");
-
- return mask != 0;
+ return ___set_bit(ADDR, mask) != 0;
}
static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
{
- register unsigned long mask asm("g2");
- register unsigned long *ADDR asm("g1");
- register int tmp1 asm("g3");
- register int tmp2 asm("g4");
- register int tmp3 asm("g5");
- register int tmp4 asm("g7");
+ unsigned long *ADDR, mask;
ADDR = ((unsigned long *) addr) + (nr >> 5);
mask = 1 << (nr & 31);
- __asm__ __volatile__(
- "mov %%o7, %%g4\n\t"
- "call ___set_bit\n\t"
- " add %%o7, 8, %%o7\n"
- : "=&r" (mask), "=r" (tmp1), "=r" (tmp2), "=r" (tmp3), "=r" (tmp4)
- : "0" (mask), "r" (ADDR)
- : "memory", "cc");
+ (void) ___set_bit(ADDR, mask);
}
static inline int test_and_clear_bit(unsigned long nr, volatile unsigned long *addr)
{
- register unsigned long mask asm("g2");
- register unsigned long *ADDR asm("g1");
- register int tmp1 asm("g3");
- register int tmp2 asm("g4");
- register int tmp3 asm("g5");
- register int tmp4 asm("g7");
+ unsigned long *ADDR, mask;
ADDR = ((unsigned long *) addr) + (nr >> 5);
mask = 1 << (nr & 31);
- __asm__ __volatile__(
- "mov %%o7, %%g4\n\t"
- "call ___clear_bit\n\t"
- " add %%o7, 8, %%o7\n"
- : "=&r" (mask), "=r" (tmp1), "=r" (tmp2), "=r" (tmp3), "=r" (tmp4)
- : "0" (mask), "r" (ADDR)
- : "memory", "cc");
-
- return mask != 0;
+ return ___clear_bit(ADDR, mask) != 0;
}
static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
{
- register unsigned long mask asm("g2");
- register unsigned long *ADDR asm("g1");
- register int tmp1 asm("g3");
- register int tmp2 asm("g4");
- register int tmp3 asm("g5");
- register int tmp4 asm("g7");
+ unsigned long *ADDR, mask;
ADDR = ((unsigned long *) addr) + (nr >> 5);
mask = 1 << (nr & 31);
- __asm__ __volatile__(
- "mov %%o7, %%g4\n\t"
- "call ___clear_bit\n\t"
- " add %%o7, 8, %%o7\n"
- : "=&r" (mask), "=r" (tmp1), "=r" (tmp2), "=r" (tmp3), "=r" (tmp4)
- : "0" (mask), "r" (ADDR)
- : "memory", "cc");
+ (void) ___clear_bit(ADDR, mask);
}
static inline int test_and_change_bit(unsigned long nr, volatile unsigned long *addr)
{
- register unsigned long mask asm("g2");
- register unsigned long *ADDR asm("g1");
- register int tmp1 asm("g3");
- register int tmp2 asm("g4");
- register int tmp3 asm("g5");
- register int tmp4 asm("g7");
+ unsigned long *ADDR, mask;
ADDR = ((unsigned long *) addr) + (nr >> 5);
mask = 1 << (nr & 31);
- __asm__ __volatile__(
- "mov %%o7, %%g4\n\t"
- "call ___change_bit\n\t"
- " add %%o7, 8, %%o7\n"
- : "=&r" (mask), "=r" (tmp1), "=r" (tmp2), "=r" (tmp3), "=r" (tmp4)
- : "0" (mask), "r" (ADDR)
- : "memory", "cc");
-
- return mask != 0;
+ return ___change_bit(ADDR, mask) != 0;
}
static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
{
- register unsigned long mask asm("g2");
- register unsigned long *ADDR asm("g1");
- register int tmp1 asm("g3");
- register int tmp2 asm("g4");
- register int tmp3 asm("g5");
- register int tmp4 asm("g7");
+ unsigned long *ADDR, mask;
ADDR = ((unsigned long *) addr) + (nr >> 5);
mask = 1 << (nr & 31);
- __asm__ __volatile__(
- "mov %%o7, %%g4\n\t"
- "call ___change_bit\n\t"
- " add %%o7, 8, %%o7\n"
- : "=&r" (mask), "=r" (tmp1), "=r" (tmp2), "=r" (tmp3), "=r" (tmp4)
- : "0" (mask), "r" (ADDR)
- : "memory", "cc");
+ (void) ___change_bit(ADDR, mask);
}
#include <asm-generic/bitops/non-atomic.h>
diff --git a/include/asm-sparc/cacheflush.h b/include/asm-sparc/cacheflush.h
index fc632f811cd8..68ac10910271 100644
--- a/include/asm-sparc/cacheflush.h
+++ b/include/asm-sparc/cacheflush.h
@@ -48,6 +48,7 @@ BTFIXUPDEF_CALL(void, flush_cache_page, struct vm_area_struct *, unsigned long)
#define flush_cache_all() BTFIXUP_CALL(flush_cache_all)()
#define flush_cache_mm(mm) BTFIXUP_CALL(flush_cache_mm)(mm)
+#define flush_cache_dup_mm(mm) BTFIXUP_CALL(flush_cache_mm)(mm)
#define flush_cache_range(vma,start,end) BTFIXUP_CALL(flush_cache_range)(vma,start,end)
#define flush_cache_page(vma,addr,pfn) BTFIXUP_CALL(flush_cache_page)(vma,addr)
#define flush_icache_range(start, end) do { } while (0)
diff --git a/include/asm-sparc/of_device.h b/include/asm-sparc/of_device.h
index 80ea31f6e17f..7cb00c1b09c6 100644
--- a/include/asm-sparc/of_device.h
+++ b/include/asm-sparc/of_device.h
@@ -33,7 +33,7 @@ struct of_device
#define to_of_device(d) container_of(d, struct of_device, dev)
extern void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name);
-extern void of_iounmap(void __iomem *base, unsigned long size);
+extern void of_iounmap(struct resource *res, void __iomem *base, unsigned long size);
extern struct of_device *of_find_device_by_node(struct device_node *);
diff --git a/include/asm-sparc64/cacheflush.h b/include/asm-sparc64/cacheflush.h
index 745d1ab60371..122e4058dd9e 100644
--- a/include/asm-sparc64/cacheflush.h
+++ b/include/asm-sparc64/cacheflush.h
@@ -12,6 +12,7 @@
/* These are the same regardless of whether this is an SMP kernel or not. */
#define flush_cache_mm(__mm) \
do { if ((__mm) == current->mm) flushw_user(); } while(0)
+#define flush_cache_dup_mm(mm) flush_cache_mm(mm)
#define flush_cache_range(vma, start, end) \
flush_cache_mm((vma)->vm_mm)
#define flush_cache_page(vma, page, pfn) \
diff --git a/include/asm-sparc64/hw_irq.h b/include/asm-sparc64/hw_irq.h
index 599b3b073450..8e44a8360829 100644
--- a/include/asm-sparc64/hw_irq.h
+++ b/include/asm-sparc64/hw_irq.h
@@ -1,6 +1,4 @@
#ifndef __ASM_SPARC64_HW_IRQ_H
#define __ASM_SPARC64_HW_IRQ_H
-extern void hw_resend_irq(struct hw_interrupt_type *handler, unsigned int virt_irq);
-
#endif
diff --git a/include/asm-sparc64/of_device.h b/include/asm-sparc64/of_device.h
index a62c7b997d66..60e9173c9acb 100644
--- a/include/asm-sparc64/of_device.h
+++ b/include/asm-sparc64/of_device.h
@@ -34,7 +34,7 @@ struct of_device
#define to_of_device(d) container_of(d, struct of_device, dev)
extern void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name);
-extern void of_iounmap(void __iomem *base, unsigned long size);
+extern void of_iounmap(struct resource *res, void __iomem *base, unsigned long size);
extern struct of_device *of_find_device_by_node(struct device_node *);
diff --git a/include/asm-sparc64/percpu.h b/include/asm-sparc64/percpu.h
index ced8cbde046d..0d3df76aa47f 100644
--- a/include/asm-sparc64/percpu.h
+++ b/include/asm-sparc64/percpu.h
@@ -5,6 +5,16 @@
#ifdef CONFIG_SMP
+#ifdef CONFIG_MODULES
+# define PERCPU_MODULE_RESERVE 8192
+#else
+# define PERCPU_MODULE_RESERVE 0
+#endif
+
+#define PERCPU_ENOUGH_ROOM \
+ (ALIGN(__per_cpu_end - __per_cpu_start, SMP_CACHE_BYTES) + \
+ PERCPU_MODULE_RESERVE)
+
extern void setup_per_cpu_areas(void);
extern unsigned long __per_cpu_base;
diff --git a/include/asm-v850/cacheflush.h b/include/asm-v850/cacheflush.h
index e1a87f82f1a4..9ece05a202ef 100644
--- a/include/asm-v850/cacheflush.h
+++ b/include/asm-v850/cacheflush.h
@@ -24,6 +24,7 @@
systems with MMUs, so we don't need them. */
#define flush_cache_all() ((void)0)
#define flush_cache_mm(mm) ((void)0)
+#define flush_cache_dup_mm(mm) ((void)0)
#define flush_cache_range(vma, start, end) ((void)0)
#define flush_cache_page(vma, vmaddr, pfn) ((void)0)
#define flush_dcache_page(page) ((void)0)
diff --git a/include/asm-x86_64/acpi.h b/include/asm-x86_64/acpi.h
index 9d1916e59c04..6b6fc6f8be7e 100644
--- a/include/asm-x86_64/acpi.h
+++ b/include/asm-x86_64/acpi.h
@@ -54,30 +54,8 @@
#define ACPI_ENABLE_IRQS() local_irq_enable()
#define ACPI_FLUSH_CPU_CACHE() wbinvd()
-
-static inline int
-__acpi_acquire_global_lock (unsigned int *lock)
-{
- unsigned int old, new, val;
- do {
- old = *lock;
- new = (((old & ~0x3) + 2) + ((old >> 1) & 0x1));
- val = cmpxchg(lock, old, new);
- } while (unlikely (val != old));
- return (new < 3) ? -1 : 0;
-}
-
-static inline int
-__acpi_release_global_lock (unsigned int *lock)
-{
- unsigned int old, new, val;
- do {
- old = *lock;
- new = old & ~0x3;
- val = cmpxchg(lock, old, new);
- } while (unlikely (val != old));
- return old & 0x1;
-}
+int __acpi_acquire_global_lock(unsigned int *lock);
+int __acpi_release_global_lock(unsigned int *lock);
#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \
((Acq) = __acpi_acquire_global_lock((unsigned int *) GLptr))
diff --git a/include/asm-x86_64/cacheflush.h b/include/asm-x86_64/cacheflush.h
index d32f7f58752a..ab1cb5c7dc92 100644
--- a/include/asm-x86_64/cacheflush.h
+++ b/include/asm-x86_64/cacheflush.h
@@ -7,6 +7,7 @@
/* Caches aren't brain-dead on the intel. */
#define flush_cache_all() do { } while (0)
#define flush_cache_mm(mm) do { } while (0)
+#define flush_cache_dup_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_page(page) do { } while (0)
diff --git a/include/asm-x86_64/thread_info.h b/include/asm-x86_64/thread_info.h
index 787a08114b48..74a6c74397f7 100644
--- a/include/asm-x86_64/thread_info.h
+++ b/include/asm-x86_64/thread_info.h
@@ -122,6 +122,7 @@ static inline struct thread_info *stack_thread_info(void)
#define TIF_MEMDIE 20
#define TIF_DEBUG 21 /* uses debug registers */
#define TIF_IO_BITMAP 22 /* uses I/O bitmap */
+#define TIF_FREEZE 23 /* is freezing for suspend */
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
@@ -137,6 +138,7 @@ static inline struct thread_info *stack_thread_info(void)
#define _TIF_ABI_PENDING (1<<TIF_ABI_PENDING)
#define _TIF_DEBUG (1<<TIF_DEBUG)
#define _TIF_IO_BITMAP (1<<TIF_IO_BITMAP)
+#define _TIF_FREEZE (1<<TIF_FREEZE)
/* work to do on interrupt/exception return */
#define _TIF_WORK_MASK \
diff --git a/include/asm-x86_64/unwind.h b/include/asm-x86_64/unwind.h
index 2f6349e48717..02710f6a4560 100644
--- a/include/asm-x86_64/unwind.h
+++ b/include/asm-x86_64/unwind.h
@@ -1,100 +1,6 @@
#ifndef _ASM_X86_64_UNWIND_H
#define _ASM_X86_64_UNWIND_H
-/*
- * Copyright (C) 2002-2006 Novell, Inc.
- * Jan Beulich <jbeulich@novell.com>
- * This code is released under version 2 of the GNU GPL.
- */
-
-#ifdef CONFIG_STACK_UNWIND
-
-#include <linux/sched.h>
-#include <asm/ptrace.h>
-#include <asm/uaccess.h>
-#include <asm/vsyscall.h>
-
-struct unwind_frame_info
-{
- struct pt_regs regs;
- struct task_struct *task;
- unsigned call_frame:1;
-};
-
-#define UNW_PC(frame) (frame)->regs.rip
-#define UNW_SP(frame) (frame)->regs.rsp
-#ifdef CONFIG_FRAME_POINTER
-#define UNW_FP(frame) (frame)->regs.rbp
-#define FRAME_RETADDR_OFFSET 8
-#define FRAME_LINK_OFFSET 0
-#define STACK_BOTTOM(tsk) (((tsk)->thread.rsp0 - 1) & ~(THREAD_SIZE - 1))
-#define STACK_TOP(tsk) ((tsk)->thread.rsp0)
-#endif
-/* Might need to account for the special exception and interrupt handling
- stacks here, since normally
- EXCEPTION_STACK_ORDER < THREAD_ORDER < IRQSTACK_ORDER,
- but the construct is needed only for getting across the stack switch to
- the interrupt stack - thus considering the IRQ stack itself is unnecessary,
- and the overhead of comparing against all exception handling stacks seems
- not desirable. */
-#define STACK_LIMIT(ptr) (((ptr) - 1) & ~(THREAD_SIZE - 1))
-
-#define UNW_REGISTER_INFO \
- PTREGS_INFO(rax), \
- PTREGS_INFO(rdx), \
- PTREGS_INFO(rcx), \
- PTREGS_INFO(rbx), \
- PTREGS_INFO(rsi), \
- PTREGS_INFO(rdi), \
- PTREGS_INFO(rbp), \
- PTREGS_INFO(rsp), \
- PTREGS_INFO(r8), \
- PTREGS_INFO(r9), \
- PTREGS_INFO(r10), \
- PTREGS_INFO(r11), \
- PTREGS_INFO(r12), \
- PTREGS_INFO(r13), \
- PTREGS_INFO(r14), \
- PTREGS_INFO(r15), \
- PTREGS_INFO(rip)
-
-#define UNW_DEFAULT_RA(raItem, dataAlign) \
- ((raItem).where == Memory && \
- !((raItem).value * (dataAlign) + 8))
-
-static inline void arch_unw_init_frame_info(struct unwind_frame_info *info,
- /*const*/ struct pt_regs *regs)
-{
- info->regs = *regs;
-}
-
-static inline void arch_unw_init_blocked(struct unwind_frame_info *info)
-{
- extern const char thread_return[];
-
- memset(&info->regs, 0, sizeof(info->regs));
- info->regs.rip = (unsigned long)thread_return;
- info->regs.cs = __KERNEL_CS;
- __get_user(info->regs.rbp, (unsigned long *)info->task->thread.rsp);
- info->regs.rsp = info->task->thread.rsp;
- info->regs.ss = __KERNEL_DS;
-}
-
-extern int arch_unwind_init_running(struct unwind_frame_info *,
- int (*callback)(struct unwind_frame_info *,
- void *arg),
- void *arg);
-
-static inline int arch_unw_user_mode(const struct unwind_frame_info *info)
-{
- return user_mode(&info->regs)
- || (long)info->regs.rip >= 0
- || (info->regs.rip >= VSYSCALL_START && info->regs.rip < VSYSCALL_END)
- || (long)info->regs.rsp >= 0;
-}
-
-#else
-
#define UNW_PC(frame) ((void)(frame), 0UL)
#define UNW_SP(frame) ((void)(frame), 0UL)
@@ -103,6 +9,4 @@ static inline int arch_unw_user_mode(const void *info)
return 0;
}
-#endif
-
#endif /* _ASM_X86_64_UNWIND_H */
diff --git a/include/asm-xtensa/cacheflush.h b/include/asm-xtensa/cacheflush.h
index 337765b629de..22ef901b7845 100644
--- a/include/asm-xtensa/cacheflush.h
+++ b/include/asm-xtensa/cacheflush.h
@@ -75,6 +75,7 @@ extern void __flush_invalidate_dcache_range(unsigned long, unsigned long);
#define flush_cache_all() __flush_invalidate_cache_all();
#define flush_cache_mm(mm) __flush_invalidate_cache_all();
+#define flush_cache_dup_mm(mm) __flush_invalidate_cache_all();
#define flush_cache_vmap(start,end) __flush_invalidate_cache_all();
#define flush_cache_vunmap(start,end) __flush_invalidate_cache_all();
@@ -88,6 +89,7 @@ extern void flush_cache_page(struct vm_area_struct*, unsigned long, unsigned lon
#define flush_cache_all() do { } while (0)
#define flush_cache_mm(mm) do { } while (0)
+#define flush_cache_dup_mm(mm) do { } while (0)
#define flush_cache_vmap(start,end) do { } while (0)
#define flush_cache_vunmap(start,end) do { } while (0)
diff --git a/include/asm-xtensa/termbits.h b/include/asm-xtensa/termbits.h
index c780593ff5f9..057b9a3d8f83 100644
--- a/include/asm-xtensa/termbits.h
+++ b/include/asm-xtensa/termbits.h
@@ -30,6 +30,17 @@ struct termios {
cc_t c_cc[NCCS]; /* control characters */
};
+struct ktermios {
+ tcflag_t c_iflag; /* input mode flags */
+ tcflag_t c_oflag; /* output mode flags */
+ tcflag_t c_cflag; /* control mode flags */
+ tcflag_t c_lflag; /* local mode flags */
+ cc_t c_line; /* line discipline */
+ cc_t c_cc[NCCS]; /* control characters */
+ speed_t c_ispeed; /* input speed */
+ speed_t c_ospeed; /* output speed */
+};
+
/* c_cc characters */
#define VINTR 0
diff --git a/include/asm-xtensa/uaccess.h b/include/asm-xtensa/uaccess.h
index 88a64e1144d5..d6352da05b10 100644
--- a/include/asm-xtensa/uaccess.h
+++ b/include/asm-xtensa/uaccess.h
@@ -23,7 +23,6 @@
#ifdef __ASSEMBLY__
-#define _ASMLANGUAGE
#include <asm/current.h>
#include <asm/asm-offsets.h>
#include <asm/processor.h>
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index a1b04d8a1d01..862e483cce8a 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -119,7 +119,6 @@ header-y += nfs4_mount.h
header-y += nfs_mount.h
header-y += oom.h
header-y += param.h
-header-y += pci_ids.h
header-y += pci_regs.h
header-y += personality.h
header-y += pfkeyv2.h
@@ -138,7 +137,6 @@ header-y += radeonfb.h
header-y += raw.h
header-y += resource.h
header-y += rose.h
-header-y += sctp.h
header-y += smbno.h
header-y += snmp.h
header-y += sockios.h
@@ -162,7 +160,6 @@ header-y += vt.h
header-y += wireless.h
header-y += xattr.h
header-y += x25.h
-header-y += zorro_ids.h
unifdef-y += acct.h
unifdef-y += adb.h
diff --git a/include/linux/aio.h b/include/linux/aio.h
index 3372ec6bf53a..a30ef13c9e62 100644
--- a/include/linux/aio.h
+++ b/include/linux/aio.h
@@ -105,6 +105,7 @@ struct kiocb {
wait_queue_t ki_wait;
loff_t ki_pos;
+ atomic_t ki_bio_count; /* num bio used for this iocb */
void *private;
/* State that we remember to be able to restart/retry */
unsigned short ki_opcode;
diff --git a/include/linux/backlight.h b/include/linux/backlight.h
index 75e91f5b6a04..a5cf1beacb44 100644
--- a/include/linux/backlight.h
+++ b/include/linux/backlight.h
@@ -54,7 +54,7 @@ struct backlight_device {
};
extern struct backlight_device *backlight_device_register(const char *name,
- void *devdata, struct backlight_properties *bp);
+ struct device *dev,void *devdata,struct backlight_properties *bp);
extern void backlight_device_unregister(struct backlight_device *bd);
#define to_backlight_device(obj) container_of(obj, struct backlight_device, class_dev)
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 092dbd0e7658..08daf3272c02 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -309,6 +309,7 @@ extern struct bio *bio_map_kern(struct request_queue *, void *, unsigned int,
gfp_t);
extern void bio_set_pages_dirty(struct bio *bio);
extern void bio_check_pages_dirty(struct bio *bio);
+extern void bio_release_pages(struct bio *bio);
extern struct bio *bio_copy_user(struct request_queue *, unsigned long, unsigned int, int);
extern int bio_uncopy_user(struct bio *);
void zero_fill_bio(struct bio *bio);
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index ea330d7b46c0..36a6eacefe20 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -331,10 +331,6 @@ struct request_pm_state
#include <linux/elevator.h>
-typedef int (merge_request_fn) (request_queue_t *, struct request *,
- struct bio *);
-typedef int (merge_requests_fn) (request_queue_t *, struct request *,
- struct request *);
typedef void (request_fn_proc) (request_queue_t *q);
typedef int (make_request_fn) (request_queue_t *q, struct bio *bio);
typedef int (prep_rq_fn) (request_queue_t *, struct request *);
@@ -376,9 +372,6 @@ struct request_queue
struct request_list rq;
request_fn_proc *request_fn;
- merge_request_fn *back_merge_fn;
- merge_request_fn *front_merge_fn;
- merge_requests_fn *merge_requests_fn;
make_request_fn *make_request_fn;
prep_rq_fn *prep_rq_fn;
unplug_fn *unplug_fn;
@@ -649,6 +642,11 @@ extern int sg_scsi_ioctl(struct file *, struct request_queue *,
struct gendisk *, struct scsi_ioctl_command __user *);
/*
+ * Temporary export, until SCSI gets fixed up.
+ */
+extern int ll_back_merge_fn(request_queue_t *, struct request *, struct bio *);
+
+/*
* A queue has just exitted congestion. Note this in the global counter of
* congested queues, and wake up anyone who was waiting for requests to be
* put back.
@@ -674,7 +672,7 @@ extern void __blk_stop_queue(request_queue_t *q);
extern void blk_run_queue(request_queue_t *);
extern void blk_start_queueing(request_queue_t *);
extern int blk_rq_map_user(request_queue_t *, struct request *, void __user *, unsigned long);
-extern int blk_rq_unmap_user(struct request *);
+extern int blk_rq_unmap_user(struct bio *);
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, unsigned int);
diff --git a/include/linux/coda_linux.h b/include/linux/coda_linux.h
index be512cc98791..4c2632a8d31b 100644
--- a/include/linux/coda_linux.h
+++ b/include/linux/coda_linux.h
@@ -64,7 +64,7 @@ void coda_sysctl_clean(void);
#define CODA_ALLOC(ptr, cast, size) do { \
if (size < PAGE_SIZE) \
- ptr = (cast)kmalloc((unsigned long) size, GFP_KERNEL); \
+ ptr = kmalloc((unsigned long) size, GFP_KERNEL); \
else \
ptr = (cast)vmalloc((unsigned long) size); \
if (!ptr) \
diff --git a/include/linux/connector.h b/include/linux/connector.h
index 3ea1cd58de97..10eb56b2940a 100644
--- a/include/linux/connector.h
+++ b/include/linux/connector.h
@@ -133,7 +133,7 @@ struct cn_callback_data {
struct cn_callback_entry {
struct list_head callback_entry;
struct cn_callback *cb;
- struct delayed_work work;
+ struct work_struct work;
struct cn_queue_dev *pdev;
struct cn_callback_id id;
diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h
index 8821e1f75b44..fd404416f31c 100644
--- a/include/linux/cpuset.h
+++ b/include/linux/cpuset.h
@@ -30,10 +30,19 @@ void cpuset_update_task_memory_state(void);
nodes_subset((nodes), current->mems_allowed)
int cpuset_zonelist_valid_mems_allowed(struct zonelist *zl);
-extern int __cpuset_zone_allowed(struct zone *z, gfp_t gfp_mask);
-static int inline cpuset_zone_allowed(struct zone *z, gfp_t gfp_mask)
+extern int __cpuset_zone_allowed_softwall(struct zone *z, gfp_t gfp_mask);
+extern int __cpuset_zone_allowed_hardwall(struct zone *z, gfp_t gfp_mask);
+
+static int inline cpuset_zone_allowed_softwall(struct zone *z, gfp_t gfp_mask)
+{
+ return number_of_cpusets <= 1 ||
+ __cpuset_zone_allowed_softwall(z, gfp_mask);
+}
+
+static int inline cpuset_zone_allowed_hardwall(struct zone *z, gfp_t gfp_mask)
{
- return number_of_cpusets <= 1 || __cpuset_zone_allowed(z, gfp_mask);
+ return number_of_cpusets <= 1 ||
+ __cpuset_zone_allowed_hardwall(z, gfp_mask);
}
extern int cpuset_excl_nodes_overlap(const struct task_struct *p);
@@ -46,7 +55,7 @@ extern int cpuset_excl_nodes_overlap(const struct task_struct *p);
extern int cpuset_memory_pressure_enabled;
extern void __cpuset_memory_pressure_bump(void);
-extern const struct file_operations proc_cpuset_operations;
+extern struct file_operations proc_cpuset_operations;
extern char *cpuset_task_status_allowed(struct task_struct *task, char *buffer);
extern void cpuset_lock(void);
@@ -94,7 +103,12 @@ static inline int cpuset_zonelist_valid_mems_allowed(struct zonelist *zl)
return 1;
}
-static inline int cpuset_zone_allowed(struct zone *z, gfp_t gfp_mask)
+static inline int cpuset_zone_allowed_softwall(struct zone *z, gfp_t gfp_mask)
+{
+ return 1;
+}
+
+static inline int cpuset_zone_allowed_hardwall(struct zone *z, gfp_t gfp_mask)
{
return 1;
}
diff --git a/include/linux/debug_locks.h b/include/linux/debug_locks.h
index a1c10b0c4cf0..1678a5de7013 100644
--- a/include/linux/debug_locks.h
+++ b/include/linux/debug_locks.h
@@ -24,7 +24,7 @@ extern int debug_locks_off(void);
int __ret = 0; \
\
if (unlikely(c)) { \
- if (debug_locks_silent || debug_locks_off()) \
+ if (debug_locks_off() && !debug_locks_silent) \
WARN_ON(1); \
__ret = 1; \
} \
diff --git a/include/linux/device.h b/include/linux/device.h
index 49ab53ce92dc..f44247fe8135 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -433,6 +433,8 @@ static inline int device_is_registered(struct device *dev)
return dev->is_registered;
}
+void driver_init(void);
+
/*
* High level routines for use by the bus drivers
*/
diff --git a/include/linux/elevator.h b/include/linux/elevator.h
index a24931d24404..e88fcbc77f8f 100644
--- a/include/linux/elevator.h
+++ b/include/linux/elevator.h
@@ -12,6 +12,8 @@ typedef void (elevator_merge_req_fn) (request_queue_t *, struct request *, struc
typedef void (elevator_merged_fn) (request_queue_t *, struct request *, int);
+typedef int (elevator_allow_merge_fn) (request_queue_t *, struct request *, struct bio *);
+
typedef int (elevator_dispatch_fn) (request_queue_t *, int);
typedef void (elevator_add_req_fn) (request_queue_t *, struct request *);
@@ -33,6 +35,7 @@ struct elevator_ops
elevator_merge_fn *elevator_merge_fn;
elevator_merged_fn *elevator_merged_fn;
elevator_merge_req_fn *elevator_merge_req_fn;
+ elevator_allow_merge_fn *elevator_allow_merge_fn;
elevator_dispatch_fn *elevator_dispatch_fn;
elevator_add_req_fn *elevator_add_req_fn;
diff --git a/include/linux/fb.h b/include/linux/fb.h
index 6fe56aaa6685..64177ec9a019 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -929,8 +929,6 @@ extern void fb_bl_default_curve(struct fb_info *fb_info, u8 off, u8 min, u8 max)
#define FB_MODE_IS_FIRST 16
#define FB_MODE_IS_FROM_VAR 32
-extern int fbmon_valid_timings(u_int pixclock, u_int htotal, u_int vtotal,
- const struct fb_info *fb_info);
extern int fbmon_dpms(const struct fb_info *fb_info);
extern int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var,
struct fb_info *info);
diff --git a/include/linux/file.h b/include/linux/file.h
index edca361f2ab4..a59001e9ea58 100644
--- a/include/linux/file.h
+++ b/include/linux/file.h
@@ -80,6 +80,11 @@ extern int expand_files(struct files_struct *, int nr);
extern void free_fdtable_rcu(struct rcu_head *rcu);
extern void __init files_defer_init(void);
+static inline void free_fdtable(struct fdtable *fdt)
+{
+ call_rcu(&fdt->rcu, free_fdtable_rcu);
+}
+
static inline struct file * fcheck_files(struct files_struct *files, unsigned int fd)
{
struct file * file = NULL;
diff --git a/include/linux/freezer.h b/include/linux/freezer.h
index 393063096134..5e75e26d4787 100644
--- a/include/linux/freezer.h
+++ b/include/linux/freezer.h
@@ -16,16 +16,15 @@ static inline int frozen(struct task_struct *p)
*/
static inline int freezing(struct task_struct *p)
{
- return p->flags & PF_FREEZE;
+ return test_tsk_thread_flag(p, TIF_FREEZE);
}
/*
* Request that a process be frozen
- * FIXME: SMP problem. We may not modify other process' flags!
*/
static inline void freeze(struct task_struct *p)
{
- p->flags |= PF_FREEZE;
+ set_tsk_thread_flag(p, TIF_FREEZE);
}
/*
@@ -33,7 +32,7 @@ static inline void freeze(struct task_struct *p)
*/
static inline void do_not_freeze(struct task_struct *p)
{
- p->flags &= ~PF_FREEZE;
+ clear_tsk_thread_flag(p, TIF_FREEZE);
}
/*
@@ -54,7 +53,9 @@ static inline int thaw_process(struct task_struct *p)
*/
static inline void frozen_process(struct task_struct *p)
{
- p->flags = (p->flags & ~PF_FREEZE) | PF_FROZEN;
+ p->flags |= PF_FROZEN;
+ wmb();
+ clear_tsk_thread_flag(p, TIF_FREEZE);
}
extern void refrigerator(void);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index adce6e1d70c2..186da813541e 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -120,6 +120,7 @@ extern int dir_notify_enable;
#define MS_PRIVATE (1<<18) /* change to private */
#define MS_SLAVE (1<<19) /* change to slave */
#define MS_SHARED (1<<20) /* change to shared */
+#define MS_RELATIME (1<<21) /* Update atime relative to mtime/ctime. */
#define MS_ACTIVE (1<<30)
#define MS_NOUSER (1<<31)
diff --git a/include/linux/gameport.h b/include/linux/gameport.h
index 2cdba0c23957..afad95272841 100644
--- a/include/linux/gameport.h
+++ b/include/linux/gameport.h
@@ -105,7 +105,7 @@ static inline void gameport_set_phys(struct gameport *gameport,
static inline struct gameport *gameport_allocate_port(void)
{
- struct gameport *gameport = kcalloc(1, sizeof(struct gameport), GFP_KERNEL);
+ struct gameport *gameport = kzalloc(sizeof(struct gameport), GFP_KERNEL);
return gameport;
}
diff --git a/include/linux/highmem.h b/include/linux/highmem.h
index 3d8768b619e9..ca9a602cffd7 100644
--- a/include/linux/highmem.h
+++ b/include/linux/highmem.h
@@ -96,7 +96,10 @@ static inline void memclear_highpage_flush(struct page *page, unsigned int offse
kunmap_atomic(kaddr, KM_USER0);
}
-static inline void copy_user_highpage(struct page *to, struct page *from, unsigned long vaddr)
+#ifndef __HAVE_ARCH_COPY_USER_HIGHPAGE
+
+static inline void copy_user_highpage(struct page *to, struct page *from,
+ unsigned long vaddr, struct vm_area_struct *vma)
{
char *vfrom, *vto;
@@ -109,6 +112,8 @@ static inline void copy_user_highpage(struct page *to, struct page *from, unsign
smp_wmb();
}
+#endif
+
static inline void copy_highpage(struct page *to, struct page *from)
{
char *vfrom, *vto;
diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h
index 7ae3c3326643..d38778f2fbec 100644
--- a/include/linux/i2c-id.h
+++ b/include/linux/i2c-id.h
@@ -142,7 +142,6 @@
#define I2C_DRIVERID_MTP008 1023
#define I2C_DRIVERID_DS1621 1024
#define I2C_DRIVERID_ADM1024 1025
-#define I2C_DRIVERID_IT87 1026
#define I2C_DRIVERID_CH700X 1027 /* single driver for CH7003-7009 digital pc to tv encoders */
#define I2C_DRIVERID_FSCPOS 1028
#define I2C_DRIVERID_FSCSCY 1029
diff --git a/include/linux/if_fddi.h b/include/linux/if_fddi.h
index e0a150046208..4aba6b0ad41c 100644
--- a/include/linux/if_fddi.h
+++ b/include/linux/if_fddi.h
@@ -103,6 +103,8 @@ struct fddihdr
} __attribute__ ((packed));
#ifdef __KERNEL__
+#include <linux/netdevice.h>
+
/* Define FDDI statistics structure */
struct fddi_statistics {
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index b5315150199e..6383d2d83bb0 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -75,7 +75,6 @@ extern struct nsproxy init_nsproxy;
.pid_ns = &init_pid_ns, \
.count = ATOMIC_INIT(1), \
.nslock = __SPIN_LOCK_UNLOCKED(nsproxy.nslock), \
- .id = 0, \
.uts_ns = &init_uts_ns, \
.mnt_ns = NULL, \
INIT_IPC_NS(ipc_ns) \
diff --git a/include/linux/input.h b/include/linux/input.h
index 4e61158b06a0..bde65c8a3519 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -491,6 +491,21 @@ struct input_absinfo {
#define KEY_DIGITS 0x19d
#define KEY_TEEN 0x19e
#define KEY_TWEN 0x19f
+#define KEY_VIDEOPHONE 0x1a0
+#define KEY_GAMES 0x1a1
+#define KEY_ZOOMIN 0x1a2
+#define KEY_ZOOMOUT 0x1a3
+#define KEY_ZOOMRESET 0x1a4
+#define KEY_WORDPROCESSOR 0x1a5
+#define KEY_EDITOR 0x1a6
+#define KEY_SPREADSHEET 0x1a7
+#define KEY_GRAPHICSEDITOR 0x1a8
+#define KEY_PRESENTATION 0x1a9
+#define KEY_DATABASE 0x1aa
+#define KEY_NEWS 0x1ab
+#define KEY_VOICEMAIL 0x1ac
+#define KEY_ADDRESSBOOK 0x1ad
+#define KEY_MESSENGER 0x1ae
#define KEY_DEL_EOL 0x1c0
#define KEY_DEL_EOS 0x1c1
diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index cf8696d4a138..15228d79c5bc 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -91,6 +91,9 @@ struct resource_list {
#define IORESOURCE_ROM_COPY (1<<2) /* ROM is alloc'd copy, resource field overlaid */
#define IORESOURCE_ROM_BIOS_COPY (1<<3) /* ROM is BIOS copy, resource field overlaid */
+/* PCI control bits. Shares IORESOURCE_BITS with above PCI ROM. */
+#define IORESOURCE_PCI_FIXED (1<<4) /* Do not move resource */
+
/* PC/ISA/whatever - the normal PC address spaces: IO and memory */
extern struct resource ioport_resource;
extern struct resource iomem_resource;
diff --git a/include/linux/kobject.h b/include/linux/kobject.h
index d1c8d28fa92e..76538fcf2c4e 100644
--- a/include/linux/kobject.h
+++ b/include/linux/kobject.h
@@ -265,8 +265,8 @@ extern int __must_check subsys_create_file(struct subsystem * ,
struct subsys_attribute *);
#if defined(CONFIG_HOTPLUG)
-void kobject_uevent(struct kobject *kobj, enum kobject_action action);
-void kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
+int kobject_uevent(struct kobject *kobj, enum kobject_action action);
+int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
char *envp[]);
int add_uevent_var(char **envp, int num_envp, int *cur_index,
@@ -274,11 +274,12 @@ int add_uevent_var(char **envp, int num_envp, int *cur_index,
const char *format, ...)
__attribute__((format (printf, 7, 8)));
#else
-static inline void kobject_uevent(struct kobject *kobj, enum kobject_action action) { }
-static inline void kobject_uevent_env(struct kobject *kobj,
+static inline int kobject_uevent(struct kobject *kobj, enum kobject_action action)
+{ return 0; }
+static inline int kobject_uevent_env(struct kobject *kobj,
enum kobject_action action,
char *envp[])
-{ }
+{ return 0; }
static inline int add_uevent_var(char **envp, int num_envp, int *cur_index,
char *buffer, int buffer_size, int *cur_len,
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 5bb2c3c585c1..28fdce1ac1db 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -11,6 +11,8 @@
#include <asm/types.h>
#include <linux/ioctl.h>
+#define KVM_API_VERSION 1
+
/*
* Architectural interrupt line count, and the size of the bitmap needed
* to hold them.
@@ -209,6 +211,7 @@ struct kvm_dirty_log {
#define KVMIO 0xAE
+#define KVM_GET_API_VERSION _IO(KVMIO, 1)
#define KVM_RUN _IOWR(KVMIO, 2, struct kvm_run)
#define KVM_GET_REGS _IOWR(KVMIO, 3, struct kvm_regs)
#define KVM_SET_REGS _IOW(KVMIO, 4, struct kvm_regs)
diff --git a/include/linux/lockd/bind.h b/include/linux/lockd/bind.h
index aa50d89eacd7..246de1d84a26 100644
--- a/include/linux/lockd/bind.h
+++ b/include/linux/lockd/bind.h
@@ -23,7 +23,7 @@ struct svc_rqst;
* This is the set of functions for lockd->nfsd communication
*/
struct nlmsvc_binding {
- u32 (*fopen)(struct svc_rqst *,
+ __be32 (*fopen)(struct svc_rqst *,
struct nfs_fh *,
struct file **);
void (*fclose)(struct file *);
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
index 0c962b82a9de..ac25b5649c59 100644
--- a/include/linux/lockd/lockd.h
+++ b/include/linux/lockd/lockd.h
@@ -191,7 +191,7 @@ __be32 nlmsvc_cancel_blocked(struct nlm_file *, struct nlm_lock *);
unsigned long nlmsvc_retry_blocked(void);
void nlmsvc_traverse_blocks(struct nlm_host *, struct nlm_file *,
nlm_host_match_fn_t match);
-void nlmsvc_grant_reply(struct nlm_cookie *, u32);
+void nlmsvc_grant_reply(struct nlm_cookie *, __be32);
/*
* File handling for the server personality
diff --git a/include/linux/lockd/sm_inter.h b/include/linux/lockd/sm_inter.h
index fc61d40964da..22a645828f26 100644
--- a/include/linux/lockd/sm_inter.h
+++ b/include/linux/lockd/sm_inter.h
@@ -24,7 +24,7 @@
* Arguments for all calls to statd
*/
struct nsm_args {
- u32 addr; /* remote address */
+ __be32 addr; /* remote address */
u32 prog; /* RPC callback info */
u32 vers;
u32 proc;
diff --git a/include/linux/lockd/xdr.h b/include/linux/lockd/xdr.h
index 29e7d9fc9dad..83a1f9f6237b 100644
--- a/include/linux/lockd/xdr.h
+++ b/include/linux/lockd/xdr.h
@@ -69,7 +69,7 @@ typedef struct nlm_args nlm_args;
*/
struct nlm_res {
struct nlm_cookie cookie;
- u32 status;
+ __be32 status;
struct nlm_lock lock;
};
@@ -80,9 +80,9 @@ struct nlm_reboot {
char * mon;
int len;
u32 state;
- u32 addr;
- u32 vers;
- u32 proto;
+ __be32 addr;
+ __be32 vers;
+ __be32 proto;
};
/*
diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
index 498bfbd3b4e1..ea097dddc44f 100644
--- a/include/linux/lockdep.h
+++ b/include/linux/lockdep.h
@@ -281,15 +281,25 @@ struct lock_class_key { };
#if defined(CONFIG_TRACE_IRQFLAGS) && defined(CONFIG_GENERIC_HARDIRQS)
extern void early_init_irq_lock_class(void);
#else
-# define early_init_irq_lock_class() do { } while (0)
+static inline void early_init_irq_lock_class(void)
+{
+}
#endif
#ifdef CONFIG_TRACE_IRQFLAGS
extern void early_boot_irqs_off(void);
extern void early_boot_irqs_on(void);
+extern void print_irqtrace_events(struct task_struct *curr);
#else
-# define early_boot_irqs_off() do { } while (0)
-# define early_boot_irqs_on() do { } while (0)
+static inline void early_boot_irqs_off(void)
+{
+}
+static inline void early_boot_irqs_on(void)
+{
+}
+static inline void print_irqtrace_events(struct task_struct *curr)
+{
+}
#endif
/*
diff --git a/include/linux/mount.h b/include/linux/mount.h
index e357dc86a4de..1b7e178b0d84 100644
--- a/include/linux/mount.h
+++ b/include/linux/mount.h
@@ -27,6 +27,7 @@ struct mnt_namespace;
#define MNT_NOEXEC 0x04
#define MNT_NOATIME 0x08
#define MNT_NODIRATIME 0x10
+#define MNT_RELATIME 0x20
#define MNT_SHRINKABLE 0x100
diff --git a/include/linux/n_r3964.h b/include/linux/n_r3964.h
index db4f3776978a..de24af79ebd3 100644
--- a/include/linux/n_r3964.h
+++ b/include/linux/n_r3964.h
@@ -116,7 +116,7 @@ struct r3964_message;
struct r3964_client_info {
spinlock_t lock;
- pid_t pid;
+ struct pid *pid;
unsigned int sig_flags;
struct r3964_client_info *next;
diff --git a/include/linux/ncp_mount.h b/include/linux/ncp_mount.h
index f46bddcdbd3b..a2b549eb1eca 100644
--- a/include/linux/ncp_mount.h
+++ b/include/linux/ncp_mount.h
@@ -75,7 +75,7 @@ struct ncp_mount_data_kernel {
unsigned int int_flags; /* internal flags */
#define NCP_IMOUNT_LOGGEDIN_POSSIBLE 0x0001
__kernel_uid32_t mounted_uid; /* Who may umount() this filesystem? */
- __kernel_pid_t wdog_pid; /* Who cares for our watchdog packets? */
+ struct pid *wdog_pid; /* Who cares for our watchdog packets? */
unsigned int ncp_fd; /* The socket to the ncp port */
unsigned int time_out; /* How long should I wait after
sending a NCP request? */
diff --git a/include/linux/net.h b/include/linux/net.h
index 6f0dfeba509a..f28d8a2e2c91 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -19,7 +19,6 @@
#define _LINUX_NET_H
#include <linux/wait.h>
-#include <linux/random.h>
#include <asm/socket.h>
struct poll_table_struct;
@@ -57,6 +56,7 @@ typedef enum {
#ifdef __KERNEL__
#include <linux/stringify.h>
+#include <linux/random.h>
#define SOCK_ASYNC_NOSPACE 0
#define SOCK_ASYNC_WAITDATA 1
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 6be767c76b37..fea0d9db6846 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -906,6 +906,7 @@ static inline void netif_poll_disable(struct net_device *dev)
static inline void netif_poll_enable(struct net_device *dev)
{
+ smp_mb__before_clear_bit();
clear_bit(__LINK_STATE_RX_SCHED, &dev->state);
}
diff --git a/include/linux/netfilter_bridge.h b/include/linux/netfilter_bridge.h
index 6c4613f8ad75..55689f39f77a 100644
--- a/include/linux/netfilter_bridge.h
+++ b/include/linux/netfilter_bridge.h
@@ -68,7 +68,6 @@ struct bridge_skb_cb {
} daddr;
};
-extern int brnf_deferred_hooks;
#else
#define nf_bridge_maybe_copy_header(skb) (0)
#define nf_bridge_pad(skb) (0)
diff --git a/include/linux/netfilter_ipv4.h b/include/linux/netfilter_ipv4.h
index 5821eb5a0a3e..ceae87a4c891 100644
--- a/include/linux/netfilter_ipv4.h
+++ b/include/linux/netfilter_ipv4.h
@@ -57,10 +57,8 @@ enum nf_ip_hook_priorities {
NF_IP_PRI_RAW = -300,
NF_IP_PRI_SELINUX_FIRST = -225,
NF_IP_PRI_CONNTRACK = -200,
- NF_IP_PRI_BRIDGE_SABOTAGE_FORWARD = -175,
NF_IP_PRI_MANGLE = -150,
NF_IP_PRI_NAT_DST = -100,
- NF_IP_PRI_BRIDGE_SABOTAGE_LOCAL_OUT = -50,
NF_IP_PRI_FILTER = 0,
NF_IP_PRI_NAT_SRC = 100,
NF_IP_PRI_SELINUX_LAST = 225,
diff --git a/include/linux/netfilter_ipv6.h b/include/linux/netfilter_ipv6.h
index ab81a6dc94ea..66ca8e3100dc 100644
--- a/include/linux/netfilter_ipv6.h
+++ b/include/linux/netfilter_ipv6.h
@@ -62,10 +62,8 @@ enum nf_ip6_hook_priorities {
NF_IP6_PRI_CONNTRACK_DEFRAG = -400,
NF_IP6_PRI_SELINUX_FIRST = -225,
NF_IP6_PRI_CONNTRACK = -200,
- NF_IP6_PRI_BRIDGE_SABOTAGE_FORWARD = -175,
NF_IP6_PRI_MANGLE = -150,
NF_IP6_PRI_NAT_DST = -100,
- NF_IP6_PRI_BRIDGE_SABOTAGE_LOCAL_OUT = -50,
NF_IP6_PRI_FILTER = 0,
NF_IP6_PRI_NAT_SRC = 100,
NF_IP6_PRI_SELINUX_LAST = 225,
diff --git a/include/linux/nfsd/nfsd.h b/include/linux/nfsd/nfsd.h
index edb54c3171b3..0727774772ba 100644
--- a/include/linux/nfsd/nfsd.h
+++ b/include/linux/nfsd/nfsd.h
@@ -275,12 +275,12 @@ static inline int is_fsid(struct svc_fh *fh, struct knfsd_fh *reffh)
* we might process an operation with side effects, and be unable to
* tell the client that the operation succeeded.
*
- * COMPOUND_SLACK_SPACE - this is the minimum amount of buffer space
+ * COMPOUND_SLACK_SPACE - this is the minimum bytes of buffer space
* needed to encode an "ordinary" _successful_ operation. (GETATTR,
* READ, READDIR, and READLINK have their own buffer checks.) if we
* fall below this level, we fail the next operation with NFS4ERR_RESOURCE.
*
- * COMPOUND_ERR_SLACK_SPACE - this is the minimum amount of buffer space
+ * COMPOUND_ERR_SLACK_SPACE - this is the minimum bytes of buffer space
* needed to encode an operation which has failed with NFS4ERR_RESOURCE.
* care is taken to ensure that we never fall below this level for any
* reason.
diff --git a/include/linux/nfsd/state.h b/include/linux/nfsd/state.h
index c3673f487e84..ab5c236bd9a7 100644
--- a/include/linux/nfsd/state.h
+++ b/include/linux/nfsd/state.h
@@ -273,7 +273,6 @@ struct nfs4_stateid {
((err) != nfserr_stale_stateid) && \
((err) != nfserr_bad_stateid))
-extern __be32 nfsd4_renew(clientid_t *clid);
extern __be32 nfs4_preprocess_stateid_op(struct svc_fh *current_fh,
stateid_t *stateid, int flags, struct file **filp);
extern void nfs4_lock_state(void);
diff --git a/include/linux/nfsd/xdr4.h b/include/linux/nfsd/xdr4.h
index 45ca01b5f844..09799bcee0ac 100644
--- a/include/linux/nfsd/xdr4.h
+++ b/include/linux/nfsd/xdr4.h
@@ -44,6 +44,12 @@
#define NFSD4_MAX_TAGLEN 128
#define XDR_LEN(n) (((n) + 3) & ~3)
+struct nfsd4_compound_state {
+ struct svc_fh current_fh;
+ struct svc_fh save_fh;
+ struct nfs4_stateowner *replay_owner;
+};
+
struct nfsd4_change_info {
u32 atomic;
u32 before_ctime_sec;
@@ -430,35 +436,39 @@ __be32 nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
struct dentry *dentry, __be32 *buffer, int *countp,
u32 *bmval, struct svc_rqst *);
extern __be32 nfsd4_setclientid(struct svc_rqst *rqstp,
+ struct nfsd4_compound_state *,
struct nfsd4_setclientid *setclid);
extern __be32 nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
+ struct nfsd4_compound_state *,
struct nfsd4_setclientid_confirm *setclientid_confirm);
extern __be32 nfsd4_process_open1(struct nfsd4_open *open);
extern __be32 nfsd4_process_open2(struct svc_rqst *rqstp,
struct svc_fh *current_fh, struct nfsd4_open *open);
extern __be32 nfsd4_open_confirm(struct svc_rqst *rqstp,
- struct svc_fh *current_fh, struct nfsd4_open_confirm *oc,
- struct nfs4_stateowner **);
-extern __be32 nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh,
- struct nfsd4_close *close,
- struct nfs4_stateowner **replay_owner);
+ struct nfsd4_compound_state *, struct nfsd4_open_confirm *oc);
+extern __be32 nfsd4_close(struct svc_rqst *rqstp,
+ struct nfsd4_compound_state *,
+ struct nfsd4_close *close);
extern __be32 nfsd4_open_downgrade(struct svc_rqst *rqstp,
- struct svc_fh *current_fh, struct nfsd4_open_downgrade *od,
- struct nfs4_stateowner **replay_owner);
-extern __be32 nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh,
- struct nfsd4_lock *lock,
- struct nfs4_stateowner **replay_owner);
-extern __be32 nfsd4_lockt(struct svc_rqst *rqstp, struct svc_fh *current_fh,
+ struct nfsd4_compound_state *,
+ struct nfsd4_open_downgrade *od);
+extern __be32 nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *,
+ struct nfsd4_lock *lock);
+extern __be32 nfsd4_lockt(struct svc_rqst *rqstp,
+ struct nfsd4_compound_state *,
struct nfsd4_lockt *lockt);
-extern __be32 nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh,
- struct nfsd4_locku *locku,
- struct nfs4_stateowner **replay_owner);
+extern __be32 nfsd4_locku(struct svc_rqst *rqstp,
+ struct nfsd4_compound_state *,
+ struct nfsd4_locku *locku);
extern __be32
nfsd4_release_lockowner(struct svc_rqst *rqstp,
+ struct nfsd4_compound_state *,
struct nfsd4_release_lockowner *rlockowner);
extern void nfsd4_release_compoundargs(struct nfsd4_compoundargs *);
extern __be32 nfsd4_delegreturn(struct svc_rqst *rqstp,
- struct svc_fh *current_fh, struct nfsd4_delegreturn *dr);
+ struct nfsd4_compound_state *, struct nfsd4_delegreturn *dr);
+extern __be32 nfsd4_renew(struct svc_rqst *rqstp,
+ struct nfsd4_compound_state *, clientid_t *clid);
#endif
/*
diff --git a/include/linux/nsproxy.h b/include/linux/nsproxy.h
index fdfb0e44912f..0b9f0dc30d61 100644
--- a/include/linux/nsproxy.h
+++ b/include/linux/nsproxy.h
@@ -24,7 +24,6 @@ struct pid_namespace;
struct nsproxy {
atomic_t count;
spinlock_t nslock;
- unsigned long id;
struct uts_namespace *uts_ns;
struct ipc_namespace *ipc_ns;
struct mnt_namespace *mnt_ns;
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index 4830a3bedfb2..350878a2d848 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -253,15 +253,11 @@ static inline void SetPageUptodate(struct page *page)
struct page; /* forward declaration */
-int test_clear_page_dirty(struct page *page);
+extern void cancel_dirty_page(struct page *page, unsigned int account_size);
+
int test_clear_page_writeback(struct page *page);
int test_set_page_writeback(struct page *page);
-static inline void clear_page_dirty(struct page *page)
-{
- test_clear_page_dirty(page);
-}
-
static inline void set_page_writeback(struct page *page)
{
test_set_page_writeback(page);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 01c707261f9c..f3c617eabd8d 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -20,9 +20,6 @@
/* Include the pci register defines */
#include <linux/pci_regs.h>
-/* Include the ID list */
-#include <linux/pci_ids.h>
-
/*
* The PCI interface treats multi-function devices as independent
* devices. The slot/function address of each device is encoded
@@ -54,6 +51,9 @@
#include <asm/atomic.h>
#include <linux/device.h>
+/* Include the ID list */
+#include <linux/pci_ids.h>
+
/* File state for mmap()s on /proc/bus/pci/X/Y */
enum pci_mmap_state {
pci_mmap_io,
@@ -396,6 +396,21 @@ struct pci_driver {
*/
#define pci_module_init pci_register_driver
+/**
+ * PCI_VDEVICE - macro used to describe a specific pci device in short form
+ * @vend: the vendor name
+ * @dev: the 16 bit PCI Device ID
+ *
+ * This macro is used to create a struct pci_device_id that matches a
+ * specific PCI device. The subvendor, and subdevice fields will be set
+ * to PCI_ANY_ID. The macro allows the next field to follow as the device
+ * private data.
+ */
+
+#define PCI_VDEVICE(vendor, device) \
+ PCI_VENDOR_ID_##vendor, (device), \
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0
+
/* these external functions are only available when PCI support is enabled */
#ifdef CONFIG_PCI
@@ -454,6 +469,8 @@ struct pci_dev *pci_find_slot (unsigned int bus, unsigned int devfn);
int pci_find_capability (struct pci_dev *dev, int cap);
int pci_find_next_capability (struct pci_dev *dev, u8 pos, int cap);
int pci_find_ext_capability (struct pci_dev *dev, int cap);
+int pci_find_ht_capability (struct pci_dev *dev, int ht_cap);
+int pci_find_next_ht_capability (struct pci_dev *dev, int pos, int ht_cap);
struct pci_bus *pci_find_next_bus(const struct pci_bus *from);
struct pci_dev *pci_get_device(unsigned int vendor, unsigned int device,
@@ -468,6 +485,7 @@ struct pci_dev *pci_get_slot (struct pci_bus *bus, unsigned int devfn);
struct pci_dev *pci_get_bus_and_slot (unsigned int bus, unsigned int devfn);
struct pci_dev *pci_get_class (unsigned int class, struct pci_dev *from);
int pci_dev_present(const struct pci_device_id *ids);
+const struct pci_device_id *pci_find_present(const struct pci_device_id *ids);
int pci_bus_read_config_byte (struct pci_bus *bus, unsigned int devfn, int where, u8 *val);
int pci_bus_read_config_word (struct pci_bus *bus, unsigned int devfn, int where, u16 *val);
@@ -681,6 +699,7 @@ static inline struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *
{ return NULL; }
#define pci_dev_present(ids) (0)
+#define pci_find_present(ids) (NULL)
#define pci_dev_put(dev) do { } while (0)
static inline void pci_set_master(struct pci_dev *dev) { }
@@ -783,6 +802,7 @@ enum pci_fixup_pass {
pci_fixup_header, /* After reading configuration header */
pci_fixup_final, /* Final phase of device fixups */
pci_fixup_enable, /* pci_enable_device() time */
+ pci_fixup_resume, /* pci_enable_device() time */
};
/* Anonymous variables would be nice... */
@@ -801,6 +821,9 @@ enum pci_fixup_pass {
#define DECLARE_PCI_FIXUP_ENABLE(vendor, device, hook) \
DECLARE_PCI_FIXUP_SECTION(.pci_fixup_enable, \
vendor##device##hook, vendor, device, hook)
+#define DECLARE_PCI_FIXUP_RESUME(vendor, device, hook) \
+ DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume, \
+ resume##vendor##device##hook, vendor, device, hook)
void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev);
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 51180dba9a98..778e701eff30 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -104,6 +104,10 @@
#define PCI_CLASS_SERIAL_FIBER 0x0c04
#define PCI_CLASS_SERIAL_SMBUS 0x0c05
+#define PCI_BASE_CLASS_WIRELESS 0x0d
+#define PCI_CLASS_WIRELESS_RF_CONTROLLER 0x0d10
+#define PCI_CLASS_WIRELESS_WHCI 0x0d1010
+
#define PCI_BASE_CLASS_INTELLIGENT 0x0e
#define PCI_CLASS_INTELLIGENT_I2O 0x0e00
@@ -2067,6 +2071,10 @@
#define PCI_DEVICE_ID_JMICRON_JMB366 0x2366
#define PCI_DEVICE_ID_JMICRON_JMB368 0x2368
+#define PCI_VENDOR_ID_KORENIX 0x1982
+#define PCI_DEVICE_ID_KORENIX_JETCARDF0 0x1600
+#define PCI_DEVICE_ID_KORENIX_JETCARDF1 0x16ff
+
#define PCI_VENDOR_ID_TEKRAM 0x1de1
#define PCI_DEVICE_ID_TEKRAM_DC290 0xdc29
diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h
index 064b1dc71c22..7a6d34ee5ab1 100644
--- a/include/linux/pci_regs.h
+++ b/include/linux/pci_regs.h
@@ -475,15 +475,32 @@
#define PCI_PWR_CAP 12 /* Capability */
#define PCI_PWR_CAP_BUDGET(x) ((x) & 1) /* Included in system budget */
-/* Hypertransport sub capability types */
+/*
+ * Hypertransport sub capability types
+ *
+ * Unfortunately there are both 3 bit and 5 bit capability types defined
+ * in the HT spec, catering for that is a little messy. You probably don't
+ * want to use these directly, just use pci_find_ht_capability() and it
+ * will do the right thing for you.
+ */
+#define HT_3BIT_CAP_MASK 0xE0
#define HT_CAPTYPE_SLAVE 0x00 /* Slave/Primary link configuration */
#define HT_CAPTYPE_HOST 0x20 /* Host/Secondary link configuration */
+
+#define HT_5BIT_CAP_MASK 0xF8
#define HT_CAPTYPE_IRQ 0x80 /* IRQ Configuration */
#define HT_CAPTYPE_REMAPPING_40 0xA0 /* 40 bit address remapping */
#define HT_CAPTYPE_REMAPPING_64 0xA2 /* 64 bit address remapping */
#define HT_CAPTYPE_UNITID_CLUMP 0x90 /* Unit ID clumping */
#define HT_CAPTYPE_EXTCONF 0x98 /* Extended Configuration Space Access */
#define HT_CAPTYPE_MSI_MAPPING 0xA8 /* MSI Mapping Capability */
+#define HT_MSI_FLAGS 0x02 /* Offset to flags */
+#define HT_MSI_FLAGS_ENABLE 0x1 /* Mapping enable */
+#define HT_MSI_FLAGS_FIXED 0x2 /* Fixed mapping only */
+#define HT_MSI_FIXED_ADDR 0x00000000FEE00000ULL /* Fixed addr */
+#define HT_MSI_ADDR_LO 0x04 /* Offset to low addr bits */
+#define HT_MSI_ADDR_LO_MASK 0xFFF00000 /* Low address bit mask */
+#define HT_MSI_ADDR_HI 0x08 /* Offset to high addr bits */
#define HT_CAPTYPE_DIRECT_ROUTE 0xB0 /* Direct routing configuration */
#define HT_CAPTYPE_VCSET 0xB8 /* Virtual Channel configuration */
#define HT_CAPTYPE_ERROR_RETRY 0xC0 /* Retry on error configuration */
diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h
index ea4f7cd7bfd8..2e19478e9e84 100644
--- a/include/linux/pipe_fs_i.h
+++ b/include/linux/pipe_fs_i.h
@@ -12,7 +12,7 @@
struct pipe_buffer {
struct page *page;
unsigned int offset, len;
- struct pipe_buf_operations *ops;
+ const struct pipe_buf_operations *ops;
unsigned int flags;
};
@@ -41,9 +41,7 @@ struct pipe_buf_operations {
struct pipe_inode_info {
wait_queue_head_t wait;
unsigned int nrbufs, curbuf;
- struct pipe_buffer bufs[PIPE_BUFFERS];
struct page *tmp_page;
- unsigned int start;
unsigned int readers;
unsigned int writers;
unsigned int waiting_writers;
@@ -52,6 +50,7 @@ struct pipe_inode_info {
struct fasync_struct *fasync_readers;
struct fasync_struct *fasync_writers;
struct inode *inode;
+ struct pipe_buffer bufs[PIPE_BUFFERS];
};
/* Differs from PIPE_BUF in that PIPE_SIZE is the length of the actual
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index 20f47b81d3fa..8bbd459eafdc 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -39,7 +39,7 @@ extern struct platform_device *platform_device_register_simple(char *, unsigned
extern struct platform_device *platform_device_alloc(const char *name, unsigned int id);
extern int platform_device_add_resources(struct platform_device *pdev, struct resource *res, unsigned int num);
-extern int platform_device_add_data(struct platform_device *pdev, void *data, size_t size);
+extern int platform_device_add_data(struct platform_device *pdev, const void *data, size_t size);
extern int platform_device_add(struct platform_device *pdev);
extern void platform_device_del(struct platform_device *pdev);
extern void platform_device_put(struct platform_device *pdev);
diff --git a/include/linux/reciprocal_div.h b/include/linux/reciprocal_div.h
new file mode 100644
index 000000000000..f9c90b33285b
--- /dev/null
+++ b/include/linux/reciprocal_div.h
@@ -0,0 +1,32 @@
+#ifndef _LINUX_RECIPROCAL_DIV_H
+#define _LINUX_RECIPROCAL_DIV_H
+
+#include <linux/types.h>
+
+/*
+ * This file describes reciprocical division.
+ *
+ * This optimizes the (A/B) problem, when A and B are two u32
+ * and B is a known value (but not known at compile time)
+ *
+ * The math principle used is :
+ * Let RECIPROCAL_VALUE(B) be (((1LL << 32) + (B - 1))/ B)
+ * Then A / B = (u32)(((u64)(A) * (R)) >> 32)
+ *
+ * This replaces a divide by a multiply (and a shift), and
+ * is generally less expensive in CPU cycles.
+ */
+
+/*
+ * Computes the reciprocal value (R) for the value B of the divisor.
+ * Should not be called before each reciprocal_divide(),
+ * or else the performance is slower than a normal divide.
+ */
+extern u32 reciprocal_value(u32 B);
+
+
+static inline u32 reciprocal_divide(u32 A, u32 R)
+{
+ return (u32)(((u64)A * R) >> 32);
+}
+#endif
diff --git a/include/linux/rmap.h b/include/linux/rmap.h
index 36f850373d2c..bdd277223af0 100644
--- a/include/linux/rmap.h
+++ b/include/linux/rmap.h
@@ -72,7 +72,7 @@ void __anon_vma_link(struct vm_area_struct *);
void page_add_anon_rmap(struct page *, struct vm_area_struct *, unsigned long);
void page_add_new_anon_rmap(struct page *, struct vm_area_struct *, unsigned long);
void page_add_file_rmap(struct page *);
-void page_remove_rmap(struct page *);
+void page_remove_rmap(struct page *, struct vm_area_struct *);
/**
* page_dup_rmap - duplicate pte mapping to a page
diff --git a/include/linux/sched.h b/include/linux/sched.h
index ea92e5c89089..446373535190 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1144,7 +1144,6 @@ static inline void put_task_struct(struct task_struct *t)
#define PF_MEMALLOC 0x00000800 /* Allocating memory */
#define PF_FLUSHER 0x00001000 /* responsible for disk writeback */
#define PF_USED_MATH 0x00002000 /* if unset the fpu must be initialized before use */
-#define PF_FREEZE 0x00004000 /* this task is being frozen for suspend now */
#define PF_NOFREEZE 0x00008000 /* this thread should not be frozen */
#define PF_FROZEN 0x00010000 /* frozen for system suspend */
#define PF_FSTRANS 0x00020000 /* inside a filesystem transaction */
diff --git a/include/linux/sctp.h b/include/linux/sctp.h
index 35108fe7a686..d4f86560bfff 100644
--- a/include/linux/sctp.h
+++ b/include/linux/sctp.h
@@ -180,7 +180,7 @@ typedef enum {
SCTP_PARAM_ERR_CAUSE = __constant_htons(0xc003),
SCTP_PARAM_SET_PRIMARY = __constant_htons(0xc004),
SCTP_PARAM_SUCCESS_REPORT = __constant_htons(0xc005),
- SCTP_PARAM_ADAPTION_LAYER_IND = __constant_htons(0xc006),
+ SCTP_PARAM_ADAPTATION_LAYER_IND = __constant_htons(0xc006),
} sctp_param_t; /* enum */
@@ -281,11 +281,11 @@ typedef struct sctp_ecn_capable_param {
sctp_paramhdr_t param_hdr;
} __attribute__((packed)) sctp_ecn_capable_param_t;
-/* ADDIP Section 3.2.6 Adaption Layer Indication */
-typedef struct sctp_adaption_ind_param {
+/* ADDIP Section 3.2.6 Adaptation Layer Indication */
+typedef struct sctp_adaptation_ind_param {
struct sctp_paramhdr param_hdr;
- __be32 adaption_ind;
-} __attribute__((packed)) sctp_adaption_ind_param_t;
+ __be32 adaptation_ind;
+} __attribute__((packed)) sctp_adaptation_ind_param_t;
/* RFC 2960. Section 3.3.3 Initiation Acknowledgement (INIT ACK) (2):
* The INIT ACK chunk is used to acknowledge the initiation of an SCTP
diff --git a/include/linux/slab.h b/include/linux/slab.h
index 2271886744f8..1ef822e31c77 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -1,7 +1,9 @@
/*
- * linux/include/linux/slab.h
- * Written by Mark Hemment, 1996.
- * (markhe@nextd.demon.co.uk)
+ * Written by Mark Hemment, 1996 (markhe@nextd.demon.co.uk).
+ *
+ * (C) SGI 2006, Christoph Lameter <clameter@sgi.com>
+ * Cleaned up and restructured to ease the addition of alternative
+ * implementations of SLAB allocators.
*/
#ifndef _LINUX_SLAB_H
@@ -10,64 +12,95 @@
#ifdef __KERNEL__
#include <linux/gfp.h>
-#include <linux/init.h>
#include <linux/types.h>
-#include <asm/page.h> /* kmalloc_sizes.h needs PAGE_SIZE */
-#include <asm/cache.h> /* kmalloc_sizes.h needs L1_CACHE_BYTES */
-#include <linux/compiler.h>
-/* kmem_cache_t exists for legacy reasons and is not used by code in mm */
typedef struct kmem_cache kmem_cache_t __deprecated;
-/* flags to pass to kmem_cache_create().
- * The first 3 are only valid when the allocator as been build
- * SLAB_DEBUG_SUPPORT.
+/*
+ * Flags to pass to kmem_cache_create().
+ * The ones marked DEBUG are only valid if CONFIG_SLAB_DEBUG is set.
*/
-#define SLAB_DEBUG_FREE 0x00000100UL /* Peform (expensive) checks on free */
-#define SLAB_DEBUG_INITIAL 0x00000200UL /* Call constructor (as verifier) */
-#define SLAB_RED_ZONE 0x00000400UL /* Red zone objs in a cache */
-#define SLAB_POISON 0x00000800UL /* Poison objects */
-#define SLAB_HWCACHE_ALIGN 0x00002000UL /* align objs on a h/w cache lines */
-#define SLAB_CACHE_DMA 0x00004000UL /* use GFP_DMA memory */
-#define SLAB_MUST_HWCACHE_ALIGN 0x00008000UL /* force alignment */
-#define SLAB_STORE_USER 0x00010000UL /* store the last owner for bug hunting */
-#define SLAB_RECLAIM_ACCOUNT 0x00020000UL /* track pages allocated to indicate
- what is reclaimable later*/
-#define SLAB_PANIC 0x00040000UL /* panic if kmem_cache_create() fails */
-#define SLAB_DESTROY_BY_RCU 0x00080000UL /* defer freeing pages to RCU */
+#define SLAB_DEBUG_FREE 0x00000100UL /* DEBUG: Perform (expensive) checks on free */
+#define SLAB_DEBUG_INITIAL 0x00000200UL /* DEBUG: Call constructor (as verifier) */
+#define SLAB_RED_ZONE 0x00000400UL /* DEBUG: Red zone objs in a cache */
+#define SLAB_POISON 0x00000800UL /* DEBUG: Poison objects */
+#define SLAB_HWCACHE_ALIGN 0x00002000UL /* Align objs on cache lines */
+#define SLAB_CACHE_DMA 0x00004000UL /* Use GFP_DMA memory */
+#define SLAB_MUST_HWCACHE_ALIGN 0x00008000UL /* Force alignment even if debuggin is active */
+#define SLAB_STORE_USER 0x00010000UL /* DEBUG: Store the last owner for bug hunting */
+#define SLAB_RECLAIM_ACCOUNT 0x00020000UL /* Objects are reclaimable */
+#define SLAB_PANIC 0x00040000UL /* Panic if kmem_cache_create() fails */
+#define SLAB_DESTROY_BY_RCU 0x00080000UL /* Defer freeing slabs to RCU */
#define SLAB_MEM_SPREAD 0x00100000UL /* Spread some memory over cpuset */
-/* flags passed to a constructor func */
-#define SLAB_CTOR_CONSTRUCTOR 0x001UL /* if not set, then deconstructor */
-#define SLAB_CTOR_ATOMIC 0x002UL /* tell constructor it can't sleep */
-#define SLAB_CTOR_VERIFY 0x004UL /* tell constructor it's a verify call */
+/* Flags passed to a constructor functions */
+#define SLAB_CTOR_CONSTRUCTOR 0x001UL /* If not set, then deconstructor */
+#define SLAB_CTOR_ATOMIC 0x002UL /* Tell constructor it can't sleep */
+#define SLAB_CTOR_VERIFY 0x004UL /* Tell constructor it's a verify call */
-#ifndef CONFIG_SLOB
-
-/* prototypes */
-extern void __init kmem_cache_init(void);
+/*
+ * struct kmem_cache related prototypes
+ */
+void __init kmem_cache_init(void);
+extern int slab_is_available(void);
-extern struct kmem_cache *kmem_cache_create(const char *, size_t, size_t,
+struct kmem_cache *kmem_cache_create(const char *, size_t, size_t,
unsigned long,
void (*)(void *, struct kmem_cache *, unsigned long),
void (*)(void *, struct kmem_cache *, unsigned long));
-extern void kmem_cache_destroy(struct kmem_cache *);
-extern int kmem_cache_shrink(struct kmem_cache *);
-extern void *kmem_cache_alloc(struct kmem_cache *, gfp_t);
-extern void *kmem_cache_zalloc(struct kmem_cache *, gfp_t);
-extern void kmem_cache_free(struct kmem_cache *, void *);
-extern unsigned int kmem_cache_size(struct kmem_cache *);
-extern const char *kmem_cache_name(struct kmem_cache *);
+void kmem_cache_destroy(struct kmem_cache *);
+int kmem_cache_shrink(struct kmem_cache *);
+void *kmem_cache_alloc(struct kmem_cache *, gfp_t);
+void *kmem_cache_zalloc(struct kmem_cache *, gfp_t);
+void kmem_cache_free(struct kmem_cache *, void *);
+unsigned int kmem_cache_size(struct kmem_cache *);
+const char *kmem_cache_name(struct kmem_cache *);
+int kmem_ptr_validate(struct kmem_cache *cachep, const void *ptr);
+
+#ifdef CONFIG_NUMA
+extern void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node);
+#else
+static inline void *kmem_cache_alloc_node(struct kmem_cache *cachep,
+ gfp_t flags, int node)
+{
+ return kmem_cache_alloc(cachep, flags);
+}
+#endif
+
+/*
+ * Common kmalloc functions provided by all allocators
+ */
+void *__kmalloc(size_t, gfp_t);
+void *__kzalloc(size_t, gfp_t);
+void kfree(const void *);
+unsigned int ksize(const void *);
+
+/**
+ * kcalloc - allocate memory for an array. The memory is set to zero.
+ * @n: number of elements.
+ * @size: element size.
+ * @flags: the type of memory to allocate.
+ */
+static inline void *kcalloc(size_t n, size_t size, gfp_t flags)
+{
+ if (n != 0 && size > ULONG_MAX / n)
+ return NULL;
+ return __kzalloc(n * size, flags);
+}
-/* Size description struct for general caches. */
-struct cache_sizes {
- size_t cs_size;
- struct kmem_cache *cs_cachep;
- struct kmem_cache *cs_dmacachep;
-};
-extern struct cache_sizes malloc_sizes[];
+/*
+ * Allocator specific definitions. These are mainly used to establish optimized
+ * ways to convert kmalloc() calls to kmem_cache_alloc() invocations by selecting
+ * the appropriate general cache at compile time.
+ */
-extern void *__kmalloc(size_t, gfp_t);
+#ifdef CONFIG_SLAB
+#include <linux/slab_def.h>
+#else
+/*
+ * Fallback definitions for an allocator not wanting to provide
+ * its own optimized kmalloc definitions (like SLOB).
+ */
/**
* kmalloc - allocate memory
@@ -116,46 +149,9 @@ extern void *__kmalloc(size_t, gfp_t);
*/
static inline void *kmalloc(size_t size, gfp_t flags)
{
- if (__builtin_constant_p(size)) {
- int i = 0;
-#define CACHE(x) \
- if (size <= x) \
- goto found; \
- else \
- i++;
-#include "kmalloc_sizes.h"
-#undef CACHE
- {
- extern void __you_cannot_kmalloc_that_much(void);
- __you_cannot_kmalloc_that_much();
- }
-found:
- return kmem_cache_alloc((flags & GFP_DMA) ?
- malloc_sizes[i].cs_dmacachep :
- malloc_sizes[i].cs_cachep, flags);
- }
return __kmalloc(size, flags);
}
-/*
- * kmalloc_track_caller is a special version of kmalloc that records the
- * calling function of the routine calling it for slab leak tracking instead
- * of just the calling function (confusing, eh?).
- * It's useful when the call to kmalloc comes from a widely-used standard
- * allocator where we care about the real place the memory allocation
- * request comes from.
- */
-#ifndef CONFIG_DEBUG_SLAB
-#define kmalloc_track_caller(size, flags) \
- __kmalloc(size, flags)
-#else
-extern void *__kmalloc_track_caller(size_t, gfp_t, void*);
-#define kmalloc_track_caller(size, flags) \
- __kmalloc_track_caller(size, flags, __builtin_return_address(0))
-#endif
-
-extern void *__kzalloc(size_t, gfp_t);
-
/**
* kzalloc - allocate memory. The memory is set to zero.
* @size: how many bytes of memory are required.
@@ -163,72 +159,41 @@ extern void *__kzalloc(size_t, gfp_t);
*/
static inline void *kzalloc(size_t size, gfp_t flags)
{
- if (__builtin_constant_p(size)) {
- int i = 0;
-#define CACHE(x) \
- if (size <= x) \
- goto found; \
- else \
- i++;
-#include "kmalloc_sizes.h"
-#undef CACHE
- {
- extern void __you_cannot_kzalloc_that_much(void);
- __you_cannot_kzalloc_that_much();
- }
-found:
- return kmem_cache_zalloc((flags & GFP_DMA) ?
- malloc_sizes[i].cs_dmacachep :
- malloc_sizes[i].cs_cachep, flags);
- }
return __kzalloc(size, flags);
}
+#endif
-/**
- * kcalloc - allocate memory for an array. The memory is set to zero.
- * @n: number of elements.
- * @size: element size.
- * @flags: the type of memory to allocate.
- */
-static inline void *kcalloc(size_t n, size_t size, gfp_t flags)
+#ifndef CONFIG_NUMA
+static inline void *kmalloc_node(size_t size, gfp_t flags, int node)
{
- if (n != 0 && size > ULONG_MAX / n)
- return NULL;
- return kzalloc(n * size, flags);
+ return kmalloc(size, flags);
}
-extern void kfree(const void *);
-extern unsigned int ksize(const void *);
-extern int slab_is_available(void);
-
-#ifdef CONFIG_NUMA
-extern void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node);
-extern void *__kmalloc_node(size_t size, gfp_t flags, int node);
-
-static inline void *kmalloc_node(size_t size, gfp_t flags, int node)
+static inline void *__kmalloc_node(size_t size, gfp_t flags, int node)
{
- if (__builtin_constant_p(size)) {
- int i = 0;
-#define CACHE(x) \
- if (size <= x) \
- goto found; \
- else \
- i++;
-#include "kmalloc_sizes.h"
-#undef CACHE
- {
- extern void __you_cannot_kmalloc_that_much(void);
- __you_cannot_kmalloc_that_much();
- }
-found:
- return kmem_cache_alloc_node((flags & GFP_DMA) ?
- malloc_sizes[i].cs_dmacachep :
- malloc_sizes[i].cs_cachep, flags, node);
- }
- return __kmalloc_node(size, flags, node);
+ return __kmalloc(size, flags);
}
+#endif /* !CONFIG_NUMA */
/*
+ * kmalloc_track_caller is a special version of kmalloc that records the
+ * calling function of the routine calling it for slab leak tracking instead
+ * of just the calling function (confusing, eh?).
+ * It's useful when the call to kmalloc comes from a widely-used standard
+ * allocator where we care about the real place the memory allocation
+ * request comes from.
+ */
+#ifdef CONFIG_DEBUG_SLAB
+extern void *__kmalloc_track_caller(size_t, gfp_t, void*);
+#define kmalloc_track_caller(size, flags) \
+ __kmalloc_track_caller(size, flags, __builtin_return_address(0))
+#else
+#define kmalloc_track_caller(size, flags) \
+ __kmalloc(size, flags)
+#endif /* DEBUG_SLAB */
+
+#ifdef CONFIG_NUMA
+/*
* kmalloc_node_track_caller is a special version of kmalloc_node that
* records the calling function of the routine calling it for slab leak
* tracking instead of just the calling function (confusing, eh?).
@@ -236,70 +201,23 @@ found:
* standard allocator where we care about the real place the memory
* allocation request comes from.
*/
-#ifndef CONFIG_DEBUG_SLAB
-#define kmalloc_node_track_caller(size, flags, node) \
- __kmalloc_node(size, flags, node)
-#else
+#ifdef CONFIG_DEBUG_SLAB
extern void *__kmalloc_node_track_caller(size_t, gfp_t, int, void *);
#define kmalloc_node_track_caller(size, flags, node) \
__kmalloc_node_track_caller(size, flags, node, \
__builtin_return_address(0))
+#else
+#define kmalloc_node_track_caller(size, flags, node) \
+ __kmalloc_node(size, flags, node)
#endif
+
#else /* CONFIG_NUMA */
-static inline void *kmem_cache_alloc_node(struct kmem_cache *cachep,
- gfp_t flags, int node)
-{
- return kmem_cache_alloc(cachep, flags);
-}
-static inline void *kmalloc_node(size_t size, gfp_t flags, int node)
-{
- return kmalloc(size, flags);
-}
#define kmalloc_node_track_caller(size, flags, node) \
kmalloc_track_caller(size, flags)
-#endif
-extern int FASTCALL(kmem_cache_reap(int));
-extern int FASTCALL(kmem_ptr_validate(struct kmem_cache *cachep, void *ptr));
-
-#else /* CONFIG_SLOB */
-
-/* SLOB allocator routines */
-
-void kmem_cache_init(void);
-struct kmem_cache *kmem_cache_create(const char *c, size_t, size_t,
- unsigned long,
- void (*)(void *, struct kmem_cache *, unsigned long),
- void (*)(void *, struct kmem_cache *, unsigned long));
-void kmem_cache_destroy(struct kmem_cache *c);
-void *kmem_cache_alloc(struct kmem_cache *c, gfp_t flags);
-void *kmem_cache_zalloc(struct kmem_cache *, gfp_t);
-void kmem_cache_free(struct kmem_cache *c, void *b);
-const char *kmem_cache_name(struct kmem_cache *);
-void *kmalloc(size_t size, gfp_t flags);
-void *__kzalloc(size_t size, gfp_t flags);
-void kfree(const void *m);
-unsigned int ksize(const void *m);
-unsigned int kmem_cache_size(struct kmem_cache *c);
-
-static inline void *kcalloc(size_t n, size_t size, gfp_t flags)
-{
- return __kzalloc(n * size, flags);
-}
-
-#define kmem_cache_shrink(d) (0)
-#define kmem_cache_reap(a)
-#define kmem_ptr_validate(a, b) (0)
-#define kmem_cache_alloc_node(c, f, n) kmem_cache_alloc(c, f)
-#define kmalloc_node(s, f, n) kmalloc(s, f)
-#define kzalloc(s, f) __kzalloc(s, f)
-#define kmalloc_track_caller kmalloc
-
-#define kmalloc_node_track_caller kmalloc_node
-
-#endif /* CONFIG_SLOB */
+#endif /* DEBUG_SLAB */
#endif /* __KERNEL__ */
-
#endif /* _LINUX_SLAB_H */
+
diff --git a/include/linux/slab_def.h b/include/linux/slab_def.h
new file mode 100644
index 000000000000..4b463e66ddea
--- /dev/null
+++ b/include/linux/slab_def.h
@@ -0,0 +1,100 @@
+#ifndef _LINUX_SLAB_DEF_H
+#define _LINUX_SLAB_DEF_H
+
+/*
+ * Definitions unique to the original Linux SLAB allocator.
+ *
+ * What we provide here is a way to optimize the frequent kmalloc
+ * calls in the kernel by selecting the appropriate general cache
+ * if kmalloc was called with a size that can be established at
+ * compile time.
+ */
+
+#include <linux/init.h>
+#include <asm/page.h> /* kmalloc_sizes.h needs PAGE_SIZE */
+#include <asm/cache.h> /* kmalloc_sizes.h needs L1_CACHE_BYTES */
+#include <linux/compiler.h>
+
+/* Size description struct for general caches. */
+struct cache_sizes {
+ size_t cs_size;
+ struct kmem_cache *cs_cachep;
+ struct kmem_cache *cs_dmacachep;
+};
+extern struct cache_sizes malloc_sizes[];
+
+static inline void *kmalloc(size_t size, gfp_t flags)
+{
+ if (__builtin_constant_p(size)) {
+ int i = 0;
+#define CACHE(x) \
+ if (size <= x) \
+ goto found; \
+ else \
+ i++;
+#include "kmalloc_sizes.h"
+#undef CACHE
+ {
+ extern void __you_cannot_kmalloc_that_much(void);
+ __you_cannot_kmalloc_that_much();
+ }
+found:
+ return kmem_cache_alloc((flags & GFP_DMA) ?
+ malloc_sizes[i].cs_dmacachep :
+ malloc_sizes[i].cs_cachep, flags);
+ }
+ return __kmalloc(size, flags);
+}
+
+static inline void *kzalloc(size_t size, gfp_t flags)
+{
+ if (__builtin_constant_p(size)) {
+ int i = 0;
+#define CACHE(x) \
+ if (size <= x) \
+ goto found; \
+ else \
+ i++;
+#include "kmalloc_sizes.h"
+#undef CACHE
+ {
+ extern void __you_cannot_kzalloc_that_much(void);
+ __you_cannot_kzalloc_that_much();
+ }
+found:
+ return kmem_cache_zalloc((flags & GFP_DMA) ?
+ malloc_sizes[i].cs_dmacachep :
+ malloc_sizes[i].cs_cachep, flags);
+ }
+ return __kzalloc(size, flags);
+}
+
+#ifdef CONFIG_NUMA
+extern void *__kmalloc_node(size_t size, gfp_t flags, int node);
+
+static inline void *kmalloc_node(size_t size, gfp_t flags, int node)
+{
+ if (__builtin_constant_p(size)) {
+ int i = 0;
+#define CACHE(x) \
+ if (size <= x) \
+ goto found; \
+ else \
+ i++;
+#include "kmalloc_sizes.h"
+#undef CACHE
+ {
+ extern void __you_cannot_kmalloc_that_much(void);
+ __you_cannot_kmalloc_that_much();
+ }
+found:
+ return kmem_cache_alloc_node((flags & GFP_DMA) ?
+ malloc_sizes[i].cs_dmacachep :
+ malloc_sizes[i].cs_cachep, flags, node);
+ }
+ return __kmalloc_node(size, flags, node);
+}
+
+#endif /* CONFIG_NUMA */
+
+#endif /* _LINUX_SLAB_DEF_H */
diff --git a/include/linux/smb_fs_sb.h b/include/linux/smb_fs_sb.h
index 5b4ae2cc445c..3aa97aa4277f 100644
--- a/include/linux/smb_fs_sb.h
+++ b/include/linux/smb_fs_sb.h
@@ -55,7 +55,7 @@ struct smb_sb_info {
* generation is incremented.
*/
unsigned int generation;
- pid_t conn_pid;
+ struct pid *conn_pid;
struct smb_conn_opt opt;
wait_queue_head_t conn_wq;
int conn_complete;
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index c8bb68099eb9..176f6e36dbfa 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -289,7 +289,7 @@ extern struct spi_master *spi_busnum_to_master(u16 busnum);
* the data being transferred; that may reduce overhead, when the
* underlying driver uses dma.
*
- * If the transmit buffer is null, undefined data will be shifted out
+ * If the transmit buffer is null, zeroes will be shifted out
* while filling rx_buf. If the receive buffer is null, the data
* shifted in will be discarded. Only "len" bytes shift out (or in).
* It's an error to try to shift out a partial word. (For example, by
diff --git a/include/linux/sysrq.h b/include/linux/sysrq.h
index 9df8833670cb..98a1d8cfb73d 100644
--- a/include/linux/sysrq.h
+++ b/include/linux/sysrq.h
@@ -37,23 +37,37 @@ struct sysrq_key_op {
#ifdef CONFIG_MAGIC_SYSRQ
+extern int sysrq_on(void);
+
+/*
+ * Do not use this one directly:
+ */
+extern int __sysrq_enabled;
+
/* Generic SysRq interface -- you may call it from any device driver, supplying
* ASCII code of the key, pointer to registers and kbd/tty structs (if they
* are available -- else NULL's).
*/
-void handle_sysrq(int, struct tty_struct *);
-void __handle_sysrq(int, struct tty_struct *, int check_mask);
-int register_sysrq_key(int, struct sysrq_key_op *);
-int unregister_sysrq_key(int, struct sysrq_key_op *);
+void handle_sysrq(int key, struct tty_struct *tty);
+void __handle_sysrq(int key, struct tty_struct *tty, int check_mask);
+int register_sysrq_key(int key, struct sysrq_key_op *op);
+int unregister_sysrq_key(int key, struct sysrq_key_op *op);
struct sysrq_key_op *__sysrq_get_key_op(int key);
#else
+static inline int sysrq_on(void)
+{
+ return 0;
+}
static inline int __reterr(void)
{
return -EINVAL;
}
+static inline void handle_sysrq(int key, struct tty_struct *tty)
+{
+}
#define register_sysrq_key(ig,nore) __reterr()
#define unregister_sysrq_key(ig,nore) __reterr()
diff --git a/include/linux/unwind.h b/include/linux/unwind.h
index 749928c161fb..7760860fa170 100644
--- a/include/linux/unwind.h
+++ b/include/linux/unwind.h
@@ -14,63 +14,6 @@
struct module;
-#ifdef CONFIG_STACK_UNWIND
-
-#include <asm/unwind.h>
-
-#ifndef ARCH_UNWIND_SECTION_NAME
-#define ARCH_UNWIND_SECTION_NAME ".eh_frame"
-#endif
-
-/*
- * Initialize unwind support.
- */
-extern void unwind_init(void);
-extern void unwind_setup(void);
-
-#ifdef CONFIG_MODULES
-
-extern void *unwind_add_table(struct module *,
- const void *table_start,
- unsigned long table_size);
-
-extern void unwind_remove_table(void *handle, int init_only);
-
-#endif
-
-extern int unwind_init_frame_info(struct unwind_frame_info *,
- struct task_struct *,
- /*const*/ struct pt_regs *);
-
-/*
- * Prepare to unwind a blocked task.
- */
-extern int unwind_init_blocked(struct unwind_frame_info *,
- struct task_struct *);
-
-/*
- * Prepare to unwind the currently running thread.
- */
-extern int unwind_init_running(struct unwind_frame_info *,
- asmlinkage int (*callback)(struct unwind_frame_info *,
- void *arg),
- void *arg);
-
-/*
- * Unwind to previous to frame. Returns 0 if successful, negative
- * number in case of an error.
- */
-extern int unwind(struct unwind_frame_info *);
-
-/*
- * Unwind until the return pointer is in user-land (or until an error
- * occurs). Returns 0 if successful, negative number in case of
- * error.
- */
-extern int unwind_to_user(struct unwind_frame_info *);
-
-#else
-
struct unwind_frame_info {};
static inline void unwind_init(void) {}
@@ -85,12 +28,12 @@ static inline void *unwind_add_table(struct module *mod,
return NULL;
}
-#endif
-
static inline void unwind_remove_table(void *handle, int init_only)
{
}
+#endif
+
static inline int unwind_init_frame_info(struct unwind_frame_info *info,
struct task_struct *tsk,
const struct pt_regs *regs)
@@ -122,6 +65,4 @@ static inline int unwind_to_user(struct unwind_frame_info *info)
return -ENOSYS;
}
-#endif
-
#endif /* _LINUX_UNWIND_H */
diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h
index c89df55f6e03..5e9803ed17fc 100644
--- a/include/linux/vmstat.h
+++ b/include/linux/vmstat.h
@@ -10,8 +10,9 @@
/*
* Light weight per cpu counter implementation.
*
- * Counters should only be incremented and no critical kernel component
- * should rely on the counter values.
+ * Counters should only be incremented. You need to set EMBEDDED
+ * to disable VM_EVENT_COUNTERS. Things like procps (vmstat,
+ * top, etc) use /proc/vmstat and depend on these counters.
*
* Counters are handled completely inline. On many platforms the code
* generated will simply be the increment of a global address.
@@ -73,7 +74,13 @@ static inline void count_vm_events(enum vm_event_item item, long delta)
}
extern void all_vm_events(unsigned long *);
+#ifdef CONFIG_HOTPLUG
extern void vm_events_fold_cpu(int cpu);
+#else
+static inline void vm_events_fold_cpu(int cpu)
+{
+}
+#endif
#else
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
index edef8d50b26b..2a7b38d87018 100644
--- a/include/linux/workqueue.h
+++ b/include/linux/workqueue.h
@@ -8,16 +8,21 @@
#include <linux/timer.h>
#include <linux/linkage.h>
#include <linux/bitops.h>
+#include <asm/atomic.h>
struct workqueue_struct;
struct work_struct;
typedef void (*work_func_t)(struct work_struct *work);
+/*
+ * The first word is the work queue pointer and the flags rolled into
+ * one
+ */
+#define work_data_bits(work) ((unsigned long *)(&(work)->data))
+
struct work_struct {
- /* the first word is the work queue pointer and the flags rolled into
- * one */
- unsigned long management;
+ atomic_long_t data;
#define WORK_STRUCT_PENDING 0 /* T if work item pending execution */
#define WORK_STRUCT_NOAUTOREL 1 /* F if work item automatically released on exec */
#define WORK_STRUCT_FLAG_MASK (3UL)
@@ -26,6 +31,9 @@ struct work_struct {
work_func_t func;
};
+#define WORK_DATA_INIT(autorelease) \
+ ATOMIC_LONG_INIT((autorelease) << WORK_STRUCT_NOAUTOREL)
+
struct delayed_work {
struct work_struct work;
struct timer_list timer;
@@ -36,13 +44,13 @@ struct execute_work {
};
#define __WORK_INITIALIZER(n, f) { \
- .management = 0, \
+ .data = WORK_DATA_INIT(0), \
.entry = { &(n).entry, &(n).entry }, \
.func = (f), \
}
#define __WORK_INITIALIZER_NAR(n, f) { \
- .management = (1 << WORK_STRUCT_NOAUTOREL), \
+ .data = WORK_DATA_INIT(1), \
.entry = { &(n).entry, &(n).entry }, \
.func = (f), \
}
@@ -82,17 +90,21 @@ struct execute_work {
/*
* initialize all of a work item in one go
+ *
+ * NOTE! No point in using "atomic_long_set()": useing a direct
+ * assignment of the work data initializer allows the compiler
+ * to generate better code.
*/
#define INIT_WORK(_work, _func) \
do { \
- (_work)->management = 0; \
+ (_work)->data = (atomic_long_t) WORK_DATA_INIT(0); \
INIT_LIST_HEAD(&(_work)->entry); \
PREPARE_WORK((_work), (_func)); \
} while (0)
#define INIT_WORK_NAR(_work, _func) \
do { \
- (_work)->management = (1 << WORK_STRUCT_NOAUTOREL); \
+ (_work)->data = (atomic_long_t) WORK_DATA_INIT(1); \
INIT_LIST_HEAD(&(_work)->entry); \
PREPARE_WORK((_work), (_func)); \
} while (0)
@@ -114,15 +126,15 @@ struct execute_work {
* @work: The work item in question
*/
#define work_pending(work) \
- test_bit(WORK_STRUCT_PENDING, &(work)->management)
+ test_bit(WORK_STRUCT_PENDING, work_data_bits(work))
/**
* delayed_work_pending - Find out whether a delayable work item is currently
* pending
* @work: The work item in question
*/
-#define delayed_work_pending(work) \
- test_bit(WORK_STRUCT_PENDING, &(work)->work.management)
+#define delayed_work_pending(w) \
+ work_pending(&(w)->work)
/**
* work_release - Release a work item under execution
@@ -143,7 +155,7 @@ struct execute_work {
* This should also be used to release a delayed work item.
*/
#define work_release(work) \
- clear_bit(WORK_STRUCT_PENDING, &(work)->management)
+ clear_bit(WORK_STRUCT_PENDING, work_data_bits(work))
extern struct workqueue_struct *__create_workqueue(const char *name,
@@ -188,7 +200,7 @@ static inline int cancel_delayed_work(struct delayed_work *work)
ret = del_timer_sync(&work->timer);
if (ret)
- clear_bit(WORK_STRUCT_PENDING, &work->work.management);
+ work_release(&work->work);
return ret;
}
diff --git a/include/media/cx2341x.h b/include/media/cx2341x.h
index d91d88f93c8b..ecad55bf0162 100644
--- a/include/media/cx2341x.h
+++ b/include/media/cx2341x.h
@@ -49,7 +49,7 @@ struct cx2341x_mpeg_params {
enum v4l2_mpeg_audio_mode_extension audio_mode_extension;
enum v4l2_mpeg_audio_emphasis audio_emphasis;
enum v4l2_mpeg_audio_crc audio_crc;
- u8 audio_properties;
+ u16 audio_properties;
/* video */
enum v4l2_mpeg_video_encoding video_encoding;
diff --git a/include/media/ir-common.h b/include/media/ir-common.h
index 2b25f5c95006..4bb0ad810179 100644
--- a/include/media/ir-common.h
+++ b/include/media/ir-common.h
@@ -24,6 +24,7 @@
#define _IR_COMMON
#include <linux/input.h>
+#include <linux/workqueue.h>
#define IR_TYPE_RC5 1
#define IR_TYPE_PD 2 /* Pulse distance encoded IR */
diff --git a/include/net/ax25.h b/include/net/ax25.h
index 14b72d868f03..5ae10dd2e32e 100644
--- a/include/net/ax25.h
+++ b/include/net/ax25.h
@@ -277,7 +277,7 @@ struct sock *ax25_get_socket(ax25_address *, ax25_address *, int);
extern ax25_cb *ax25_find_cb(ax25_address *, ax25_address *, ax25_digi *, struct net_device *);
extern void ax25_send_to_raw(ax25_address *, struct sk_buff *, int);
extern void ax25_destroy_socket(ax25_cb *);
-extern ax25_cb *ax25_create_cb(void);
+extern ax25_cb * __must_check ax25_create_cb(void);
extern void ax25_fillin_cb(ax25_cb *, ax25_dev *);
extern struct sock *ax25_make_new(struct sock *, struct ax25_dev *);
@@ -333,11 +333,25 @@ extern void ax25_ds_t3timer_expiry(ax25_cb *);
extern void ax25_ds_idletimer_expiry(ax25_cb *);
/* ax25_iface.c */
-extern int ax25_protocol_register(unsigned int, int (*)(struct sk_buff *, ax25_cb *));
+
+struct ax25_protocol {
+ struct ax25_protocol *next;
+ unsigned int pid;
+ int (*func)(struct sk_buff *, ax25_cb *);
+};
+
+extern void ax25_register_pid(struct ax25_protocol *ap);
extern void ax25_protocol_release(unsigned int);
-extern int ax25_linkfail_register(void (*)(ax25_cb *, int));
-extern void ax25_linkfail_release(void (*)(ax25_cb *, int));
-extern int ax25_listen_register(ax25_address *, struct net_device *);
+
+struct ax25_linkfail {
+ struct hlist_node lf_node;
+ void (*func)(ax25_cb *, int);
+};
+
+extern void ax25_linkfail_register(struct ax25_linkfail *lf);
+extern void ax25_linkfail_release(struct ax25_linkfail *lf);
+extern int __must_check ax25_listen_register(ax25_address *,
+ struct net_device *);
extern void ax25_listen_release(ax25_address *, struct net_device *);
extern int (*ax25_protocol_function(unsigned int))(struct sk_buff *, ax25_cb *);
extern int ax25_listen_mine(ax25_address *, struct net_device *);
@@ -415,7 +429,7 @@ extern unsigned long ax25_display_timer(struct timer_list *);
/* ax25_uid.c */
extern int ax25_uid_policy;
extern ax25_uid_assoc *ax25_findbyuid(uid_t);
-extern int ax25_uid_ioctl(int, struct sockaddr_ax25 *);
+extern int __must_check ax25_uid_ioctl(int, struct sockaddr_ax25 *);
extern struct file_operations ax25_uid_fops;
extern void ax25_uid_free(void);
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 10a3eec191fd..41456c148842 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -739,13 +739,13 @@ struct sockaddr_hci {
struct hci_filter {
unsigned long type_mask;
unsigned long event_mask[2];
- __u16 opcode;
+ __le16 opcode;
};
struct hci_ufilter {
__u32 type_mask;
__u32 event_mask[2];
- __u16 opcode;
+ __le16 opcode;
};
#define HCI_FLT_TYPE_BITS 31
diff --git a/include/net/ip6_checksum.h b/include/net/ip6_checksum.h
index 68e2b32cf1d6..bc1b0fda2b04 100644
--- a/include/net/ip6_checksum.h
+++ b/include/net/ip6_checksum.h
@@ -87,7 +87,7 @@ static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
carry = (sum < uproto);
sum += carry;
- return csum_fold((__force __wsum)csum);
+ return csum_fold((__force __wsum)sum);
}
#endif
diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
index f9cde44f93b4..7be4f4e3a0f2 100644
--- a/include/net/ip6_fib.h
+++ b/include/net/ip6_fib.h
@@ -50,9 +50,9 @@ struct fib6_node
struct fib6_node *parent;
struct fib6_node *left;
struct fib6_node *right;
-
+#ifdef CONFIG_IPV6_SUBTREES
struct fib6_node *subtree;
-
+#endif
struct rt6_info *leaf;
__u16 fn_bit; /* bit key */
diff --git a/include/net/netfilter/nf_conntrack_compat.h b/include/net/netfilter/nf_conntrack_compat.h
index f1b1482d7200..b9ce5c80d9d5 100644
--- a/include/net/netfilter/nf_conntrack_compat.h
+++ b/include/net/netfilter/nf_conntrack_compat.h
@@ -64,6 +64,16 @@ static inline int nf_ct_get_ctinfo(const struct sk_buff *skb,
return (ct != NULL);
}
+static inline int nf_ct_l3proto_try_module_get(unsigned short l3proto)
+{
+ need_conntrack();
+ return l3proto == PF_INET ? 0 : -1;
+}
+
+static inline void nf_ct_l3proto_module_put(unsigned short l3proto)
+{
+}
+
#else /* CONFIG_IP_NF_CONNTRACK */
#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
diff --git a/include/net/rose.h b/include/net/rose.h
index 012b09ed2401..4c05a88b921b 100644
--- a/include/net/rose.h
+++ b/include/net/rose.h
@@ -188,13 +188,13 @@ extern void rose_kick(struct sock *);
extern void rose_enquiry_response(struct sock *);
/* rose_route.c */
-extern struct rose_neigh *rose_loopback_neigh;
+extern struct rose_neigh rose_loopback_neigh;
extern struct file_operations rose_neigh_fops;
extern struct file_operations rose_nodes_fops;
extern struct file_operations rose_routes_fops;
-extern int rose_add_loopback_neigh(void);
-extern int rose_add_loopback_node(rose_address *);
+extern void rose_add_loopback_neigh(void);
+extern int __must_check rose_add_loopback_node(rose_address *);
extern void rose_del_loopback_node(rose_address *);
extern void rose_rt_device_down(struct net_device *);
extern void rose_link_device_down(struct net_device *);
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index c818f87122af..28af68059521 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -128,8 +128,6 @@ extern int sctp_copy_local_addr_list(struct sctp_bind_addr *,
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);
-int sctp_inetaddr_event(struct notifier_block *this, unsigned long ev,
- void *ptr);
/*
* sctp/socket.c
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index c089f93ba591..31a8e88f1a74 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -201,13 +201,12 @@ extern struct sctp_globals {
struct sctp_bind_hashbucket *port_hashtable;
/* This is the global local address list.
- * We actively maintain this complete list of interfaces on
- * the system by catching routing events.
+ * We actively maintain this complete list of addresses on
+ * the system by catching address add/delete events.
*
* It is a list of sctp_sockaddr_entry.
*/
struct list_head local_addr_list;
- spinlock_t local_addr_lock;
/* Flag to indicate if addip is enabled. */
int addip_enable;
@@ -243,7 +242,6 @@ extern struct sctp_globals {
#define sctp_port_alloc_lock (sctp_globals.port_alloc_lock)
#define sctp_port_hashtable (sctp_globals.port_hashtable)
#define sctp_local_addr_list (sctp_globals.local_addr_list)
-#define sctp_local_addr_lock (sctp_globals.local_addr_lock)
#define sctp_addip_enable (sctp_globals.addip_enable)
#define sctp_prsctp_enable (sctp_globals.prsctp_enable)
@@ -277,6 +275,7 @@ struct sctp_sock {
__u16 default_flags;
__u32 default_context;
__u32 default_timetolive;
+ __u32 default_rcv_context;
/* Heartbeat interval: The endpoint sends out a Heartbeat chunk to
* the destination address every heartbeat interval. This value
@@ -307,7 +306,7 @@ struct sctp_sock {
__u8 disable_fragments;
__u8 pd_mode;
__u8 v4mapped;
- __u32 adaption_ind;
+ __u32 adaptation_ind;
/* Receive to here while partial delivery is in effect. */
struct sk_buff_head pd_lobby;
@@ -389,7 +388,7 @@ struct sctp_cookie {
/* Padding for future use */
__u8 padding;
- __u32 adaption_ind;
+ __u32 adaptation_ind;
/* This is a shim for my peer's INIT packet, followed by
@@ -432,7 +431,7 @@ union sctp_params {
struct sctp_ipv4addr_param *v4;
struct sctp_ipv6addr_param *v6;
union sctp_addr_param *addr;
- struct sctp_adaption_ind_param *aind;
+ struct sctp_adaptation_ind_param *aind;
};
/* RFC 2960. Section 3.3.5 Heartbeat.
@@ -1484,7 +1483,7 @@ struct sctp_association {
__u8 asconf_capable; /* Does peer support ADDIP? */
__u8 prsctp_capable; /* Can peer do PR-SCTP? */
- __u32 adaption_ind; /* Adaption Code point. */
+ __u32 adaptation_ind; /* Adaptation Code point. */
/* This mask is used to disable sending the ASCONF chunk
* with specified parameter to peer.
@@ -1659,6 +1658,9 @@ struct sctp_association {
__u32 default_context;
__u32 default_timetolive;
+ /* Default receive parameters */
+ __u32 default_rcv_context;
+
/* This tracks outbound ssn for a given stream. */
struct sctp_ssnmap *ssnmap;
diff --git a/include/net/sctp/ulpevent.h b/include/net/sctp/ulpevent.h
index 1a4ddc1ec7d2..2923e3d31a08 100644
--- a/include/net/sctp/ulpevent.h
+++ b/include/net/sctp/ulpevent.h
@@ -120,7 +120,7 @@ struct sctp_ulpevent *sctp_ulpevent_make_pdapi(
const struct sctp_association *asoc,
__u32 indication, gfp_t gfp);
-struct sctp_ulpevent *sctp_ulpevent_make_adaption_indication(
+struct sctp_ulpevent *sctp_ulpevent_make_adaptation_indication(
const struct sctp_association *asoc, gfp_t gfp);
struct sctp_ulpevent *sctp_ulpevent_make_rcvmsg(struct sctp_association *asoc,
diff --git a/include/net/sctp/user.h b/include/net/sctp/user.h
index 1b7aae6cdd82..67a30eb2b3a4 100644
--- a/include/net/sctp/user.h
+++ b/include/net/sctp/user.h
@@ -75,8 +75,8 @@ enum sctp_optname {
#define SCTP_SET_PEER_PRIMARY_ADDR SCTP_SET_PEER_PRIMARY_ADDR
SCTP_PRIMARY_ADDR,
#define SCTP_PRIMARY_ADDR SCTP_PRIMARY_ADDR
- SCTP_ADAPTION_LAYER,
-#define SCTP_ADAPTION_LAYER SCTP_ADAPTION_LAYER
+ SCTP_ADAPTATION_LAYER,
+#define SCTP_ADAPTATION_LAYER SCTP_ADAPTATION_LAYER
SCTP_DISABLE_FRAGMENTS,
#define SCTP_DISABLE_FRAGMENTS SCTP_DISABLE_FRAGMENTS
SCTP_PEER_ADDR_PARAMS,
@@ -95,6 +95,8 @@ enum sctp_optname {
#define SCTP_GET_PEER_ADDR_INFO SCTP_GET_PEER_ADDR_INFO
SCTP_DELAYED_ACK_TIME,
#define SCTP_DELAYED_ACK_TIME SCTP_DELAYED_ACK_TIME
+ SCTP_CONTEXT, /* Receive Context */
+#define SCTP_CONTEXT SCTP_CONTEXT
/* Internal Socket Options. Some of the sctp library functions are
* implemented using these socket options.
@@ -329,17 +331,17 @@ struct sctp_shutdown_event {
};
/*
- * 5.3.1.6 SCTP_ADAPTION_INDICATION
+ * 5.3.1.6 SCTP_ADAPTATION_INDICATION
*
- * When a peer sends a Adaption Layer Indication parameter , SCTP
+ * When a peer sends a Adaptation Layer Indication parameter , SCTP
* delivers this notification to inform the application
- * that of the peers requested adaption layer.
+ * that of the peers requested adaptation layer.
*/
-struct sctp_adaption_event {
+struct sctp_adaptation_event {
__u16 sai_type;
__u16 sai_flags;
__u32 sai_length;
- __u32 sai_adaption_ind;
+ __u32 sai_adaptation_ind;
sctp_assoc_t sai_assoc_id;
};
@@ -372,7 +374,7 @@ struct sctp_event_subscribe {
__u8 sctp_peer_error_event;
__u8 sctp_shutdown_event;
__u8 sctp_partial_delivery_event;
- __u8 sctp_adaption_layer_event;
+ __u8 sctp_adaptation_layer_event;
};
/*
@@ -393,7 +395,7 @@ union sctp_notification {
struct sctp_remote_error sn_remote_error;
struct sctp_send_failed sn_send_failed;
struct sctp_shutdown_event sn_shutdown_event;
- struct sctp_adaption_event sn_adaption_event;
+ struct sctp_adaptation_event sn_adaptation_event;
struct sctp_pdapi_event sn_pdapi_event;
};
@@ -410,7 +412,7 @@ enum sctp_sn_type {
SCTP_REMOTE_ERROR,
SCTP_SHUTDOWN_EVENT,
SCTP_PARTIAL_DELIVERY_EVENT,
- SCTP_ADAPTION_INDICATION,
+ SCTP_ADAPTATION_INDICATION,
};
/* Notification error codes used to fill up the error fields in some
@@ -486,13 +488,13 @@ struct sctp_prim {
} __attribute__((packed, aligned(4)));
/*
- * 7.1.11 Set Adaption Layer Indicator (SCTP_ADAPTION_LAYER)
+ * 7.1.11 Set Adaptation Layer Indicator (SCTP_ADAPTATION_LAYER)
*
- * Requests that the local endpoint set the specified Adaption Layer
+ * Requests that the local endpoint set the specified Adaptation Layer
* Indication parameter for all future INIT and INIT-ACK exchanges.
*/
-struct sctp_setadaption {
- __u32 ssb_adaption_ind;
+struct sctp_setadaptation {
+ __u32 ssb_adaptation_ind;
};
/*
diff --git a/include/net/tcp.h b/include/net/tcp.h
index c99774f15eba..b7d8317f22ac 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -242,14 +242,9 @@ extern int tcp_memory_pressure;
static inline int before(__u32 seq1, __u32 seq2)
{
- return (__s32)(seq1-seq2) < 0;
+ return (__s32)(seq2-seq1) > 0;
}
-
-static inline int after(__u32 seq1, __u32 seq2)
-{
- return (__s32)(seq2-seq1) < 0;
-}
-
+#define after(seq2, seq1) before(seq1, seq2)
/* is s2<=s1<=s3 ? */
static inline int between(__u32 seq1, __u32 seq2, __u32 seq3)
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index fd2353fa7e12..0bfa3328d686 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -1456,9 +1456,9 @@ struct ib_mr *ib_get_dma_mr(struct ib_pd *pd, int mr_access_flags);
*/
static inline int ib_dma_mapping_error(struct ib_device *dev, u64 dma_addr)
{
- return dev->dma_ops ?
- dev->dma_ops->mapping_error(dev, dma_addr) :
- dma_mapping_error(dma_addr);
+ if (dev->dma_ops)
+ return dev->dma_ops->mapping_error(dev, dma_addr);
+ return dma_mapping_error(dma_addr);
}
/**
@@ -1472,9 +1472,9 @@ static inline u64 ib_dma_map_single(struct ib_device *dev,
void *cpu_addr, size_t size,
enum dma_data_direction direction)
{
- return dev->dma_ops ?
- dev->dma_ops->map_single(dev, cpu_addr, size, direction) :
- dma_map_single(dev->dma_device, cpu_addr, size, direction);
+ if (dev->dma_ops)
+ return dev->dma_ops->map_single(dev, cpu_addr, size, direction);
+ return dma_map_single(dev->dma_device, cpu_addr, size, direction);
}
/**
@@ -1488,8 +1488,9 @@ static inline void ib_dma_unmap_single(struct ib_device *dev,
u64 addr, size_t size,
enum dma_data_direction direction)
{
- dev->dma_ops ?
- dev->dma_ops->unmap_single(dev, addr, size, direction) :
+ if (dev->dma_ops)
+ dev->dma_ops->unmap_single(dev, addr, size, direction);
+ else
dma_unmap_single(dev->dma_device, addr, size, direction);
}
@@ -1507,9 +1508,9 @@ static inline u64 ib_dma_map_page(struct ib_device *dev,
size_t size,
enum dma_data_direction direction)
{
- return dev->dma_ops ?
- dev->dma_ops->map_page(dev, page, offset, size, direction) :
- dma_map_page(dev->dma_device, page, offset, size, direction);
+ if (dev->dma_ops)
+ return dev->dma_ops->map_page(dev, page, offset, size, direction);
+ return dma_map_page(dev->dma_device, page, offset, size, direction);
}
/**
@@ -1523,8 +1524,9 @@ static inline void ib_dma_unmap_page(struct ib_device *dev,
u64 addr, size_t size,
enum dma_data_direction direction)
{
- dev->dma_ops ?
- dev->dma_ops->unmap_page(dev, addr, size, direction) :
+ if (dev->dma_ops)
+ dev->dma_ops->unmap_page(dev, addr, size, direction);
+ else
dma_unmap_page(dev->dma_device, addr, size, direction);
}
@@ -1539,9 +1541,9 @@ static inline int ib_dma_map_sg(struct ib_device *dev,
struct scatterlist *sg, int nents,
enum dma_data_direction direction)
{
- return dev->dma_ops ?
- dev->dma_ops->map_sg(dev, sg, nents, direction) :
- dma_map_sg(dev->dma_device, sg, nents, direction);
+ if (dev->dma_ops)
+ return dev->dma_ops->map_sg(dev, sg, nents, direction);
+ return dma_map_sg(dev->dma_device, sg, nents, direction);
}
/**
@@ -1555,8 +1557,9 @@ static inline void ib_dma_unmap_sg(struct ib_device *dev,
struct scatterlist *sg, int nents,
enum dma_data_direction direction)
{
- dev->dma_ops ?
- dev->dma_ops->unmap_sg(dev, sg, nents, direction) :
+ if (dev->dma_ops)
+ dev->dma_ops->unmap_sg(dev, sg, nents, direction);
+ else
dma_unmap_sg(dev->dma_device, sg, nents, direction);
}
@@ -1568,8 +1571,9 @@ static inline void ib_dma_unmap_sg(struct ib_device *dev,
static inline u64 ib_sg_dma_address(struct ib_device *dev,
struct scatterlist *sg)
{
- return dev->dma_ops ?
- dev->dma_ops->dma_address(dev, sg) : sg_dma_address(sg);
+ if (dev->dma_ops)
+ return dev->dma_ops->dma_address(dev, sg);
+ return sg_dma_address(sg);
}
/**
@@ -1580,8 +1584,9 @@ static inline u64 ib_sg_dma_address(struct ib_device *dev,
static inline unsigned int ib_sg_dma_len(struct ib_device *dev,
struct scatterlist *sg)
{
- return dev->dma_ops ?
- dev->dma_ops->dma_len(dev, sg) : sg_dma_len(sg);
+ if (dev->dma_ops)
+ return dev->dma_ops->dma_len(dev, sg);
+ return sg_dma_len(sg);
}
/**
@@ -1596,8 +1601,9 @@ static inline void ib_dma_sync_single_for_cpu(struct ib_device *dev,
size_t size,
enum dma_data_direction dir)
{
- dev->dma_ops ?
- dev->dma_ops->sync_single_for_cpu(dev, addr, size, dir) :
+ if (dev->dma_ops)
+ dev->dma_ops->sync_single_for_cpu(dev, addr, size, dir);
+ else
dma_sync_single_for_cpu(dev->dma_device, addr, size, dir);
}
@@ -1613,8 +1619,9 @@ static inline void ib_dma_sync_single_for_device(struct ib_device *dev,
size_t size,
enum dma_data_direction dir)
{
- dev->dma_ops ?
- dev->dma_ops->sync_single_for_device(dev, addr, size, dir) :
+ if (dev->dma_ops)
+ dev->dma_ops->sync_single_for_device(dev, addr, size, dir);
+ else
dma_sync_single_for_device(dev->dma_device, addr, size, dir);
}
@@ -1630,9 +1637,16 @@ static inline void *ib_dma_alloc_coherent(struct ib_device *dev,
u64 *dma_handle,
gfp_t flag)
{
- return dev->dma_ops ?
- dev->dma_ops->alloc_coherent(dev, size, dma_handle, flag) :
- dma_alloc_coherent(dev->dma_device, size, dma_handle, flag);
+ if (dev->dma_ops)
+ return dev->dma_ops->alloc_coherent(dev, size, dma_handle, flag);
+ else {
+ dma_addr_t handle;
+ void *ret;
+
+ ret = dma_alloc_coherent(dev->dma_device, size, &handle, flag);
+ *dma_handle = handle;
+ return ret;
+ }
}
/**
@@ -1646,8 +1660,9 @@ static inline void ib_dma_free_coherent(struct ib_device *dev,
size_t size, void *cpu_addr,
u64 dma_handle)
{
- dev->dma_ops ?
- dev->dma_ops->free_coherent(dev, size, cpu_addr, dma_handle) :
+ if (dev->dma_ops)
+ dev->dma_ops->free_coherent(dev, size, cpu_addr, dma_handle);
+ else
dma_free_coherent(dev->dma_device, size, cpu_addr, dma_handle);
}
diff --git a/include/sound/pcm_oss.h b/include/sound/pcm_oss.h
index c854647b6f3c..1cd4f64cdf31 100644
--- a/include/sound/pcm_oss.h
+++ b/include/sound/pcm_oss.h
@@ -56,6 +56,7 @@ struct snd_pcm_oss_runtime {
size_t mmap_bytes;
char *buffer; /* vmallocated period */
size_t buffer_used; /* used length from period buffer */
+ struct mutex params_lock;
#ifdef CONFIG_SND_PCM_OSS_PLUGINS
struct snd_pcm_plugin *plugin_first;
struct snd_pcm_plugin *plugin_last;
diff --git a/include/sound/version.h b/include/sound/version.h
index 17137f3a3b6f..2949b9b991b5 100644
--- a/include/sound/version.h
+++ b/include/sound/version.h
@@ -1,3 +1,3 @@
/* include/version.h. Generated by alsa/ksync script. */
-#define CONFIG_SND_VERSION "1.0.13"
-#define CONFIG_SND_DATE " (Tue Nov 28 14:07:24 2006 UTC)"
+#define CONFIG_SND_VERSION "1.0.14rc1"
+#define CONFIG_SND_DATE " (Wed Dec 20 08:11:48 2006 UTC)"
diff --git a/include/sound/ymfpci.h b/include/sound/ymfpci.h
index d41cda97e952..f3514ee96bd9 100644
--- a/include/sound/ymfpci.h
+++ b/include/sound/ymfpci.h
@@ -286,7 +286,7 @@ struct snd_ymfpci {
int irq;
unsigned int device_id; /* PCI device ID */
- unsigned int rev; /* PCI revision */
+ unsigned char rev; /* PCI revision */
unsigned long reg_area_phys;
void __iomem *reg_area_virt;
struct resource *res_reg_area;
@@ -345,7 +345,6 @@ struct snd_ymfpci {
struct snd_kcontrol *spdif_pcm_ctl;
int mode_dup4ch;
int rear_opened;
- int rear_swap;
int spdif_opened;
struct {
u16 left;
@@ -378,7 +377,7 @@ int snd_ymfpci_pcm(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm);
int snd_ymfpci_pcm2(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm);
int snd_ymfpci_pcm_spdif(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm);
int snd_ymfpci_pcm_4ch(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm);
-int snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch, int rear_swap);
+int snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch);
int snd_ymfpci_timer(struct snd_ymfpci *chip, int device);
#endif /* __SOUND_YMFPCI_H */
diff --git a/include/video/sstfb.h b/include/video/sstfb.h
index 5dbf5e7e50a8..baa163f770ab 100644
--- a/include/video/sstfb.h
+++ b/include/video/sstfb.h
@@ -119,7 +119,7 @@
#define BACKPORCH 0x0208
#define VIDEODIMENSIONS 0x020c
#define FBIINIT0 0x0210 /* misc+fifo controls */
-# define EN_VGA_PASSTHROUGH BIT(0)
+# define DIS_VGA_PASSTHROUGH BIT(0)
# define FBI_RESET BIT(1)
# define FIFO_RESET BIT(2)
#define FBIINIT1 0x0214 /* PCI + video controls */
@@ -251,7 +251,7 @@
# define DACREG_ICS_CLK1_A 0 /* bit4 */
/* sst default init registers */
-#define FBIINIT0_DEFAULT EN_VGA_PASSTHROUGH
+#define FBIINIT0_DEFAULT DIS_VGA_PASSTHROUGH
#define FBIINIT1_DEFAULT \
( \
@@ -296,6 +296,11 @@
*
*/
+/* ioctl to enable/disable VGA passthrough */
+#define SSTFB_SET_VGAPASS _IOW('F', 0xdd, __u32)
+#define SSTFB_GET_VGAPASS _IOR('F', 0xdd, __u32)
+
+
/* used to know witch clock to set */
enum {
VID_CLOCK=0,
@@ -317,7 +322,7 @@ struct pll_timing {
};
struct dac_switch {
- char * name;
+ const char *name;
int (*detect) (struct fb_info *info);
int (*set_pll) (struct fb_info *info, const struct pll_timing *t, const int clock);
void (*set_vidmod) (struct fb_info *info, const int bpp);
@@ -345,7 +350,7 @@ struct sstfb_par {
struct pci_dev *dev;
int type;
u8 revision;
- int gfx_clock; /* status */
+ u8 vgapass; /* VGA pass through: 1=enabled, 0=disabled */
};
#endif /* _SSTFB_H_ */
diff --git a/init/Kconfig b/init/Kconfig
index f000edb3bb7a..a3f83e2c8250 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -450,7 +450,7 @@ config SHMEM
config SLAB
default y
- bool "Use full SLAB allocator" if EMBEDDED
+ bool "Use full SLAB allocator" if (EMBEDDED && !SMP && !SPARSEMEM)
help
Disabling this replaces the advanced SLAB allocator and
kmalloc support with the drastically simpler SLOB allocator.
@@ -461,10 +461,10 @@ config VM_EVENT_COUNTERS
default y
bool "Enable VM event counters for /proc/vmstat" if EMBEDDED
help
- VM event counters are only needed to for event counts to be
- shown. They have no function for the kernel itself. This
- option allows the disabling of the VM event counters.
- /proc/vmstat will only show page counts.
+ VM event counters are needed for event counts to be shown.
+ This option allows the disabling of the VM event counters
+ on EMBEDDED systems. /proc/vmstat will only show page counts
+ if VM event counters are disabled.
endmenu # General setup
diff --git a/init/Makefile b/init/Makefile
index d6c764d0eabb..9cd871ce5784 100644
--- a/init/Makefile
+++ b/init/Makefile
@@ -18,12 +18,3 @@ clean-files := ../include/linux/compile.h
$(obj)/main.o: include/linux/compile.h
$(obj)/version.o: include/linux/compile.h
-# compile.h changes depending on hostname, generation number, etc,
-# so we regenerate it always.
-# mkcompile_h will make sure to only update the
-# actual file if its content has changed.
-
-include/linux/compile.h: FORCE
- @echo ' CHK $@'
- $(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkcompile_h $@ \
- "$(UTS_MACHINE)" "$(CONFIG_SMP)" "$(CONFIG_PREEMPT)" "$(CC) $(CFLAGS)"
diff --git a/init/main.c b/init/main.c
index e3f0bb20b4dd..2b1cdaab45e6 100644
--- a/init/main.c
+++ b/init/main.c
@@ -53,6 +53,7 @@
#include <linux/utsrelease.h>
#include <linux/pid_namespace.h>
#include <linux/compile.h>
+#include <linux/device.h>
#include <asm/io.h>
#include <asm/bugs.h>
@@ -94,7 +95,6 @@ extern void pidmap_init(void);
extern void prio_tree_init(void);
extern void radix_tree_init(void);
extern void free_initmem(void);
-extern void driver_init(void);
extern void prepare_namespace(void);
#ifdef CONFIG_ACPI
extern void acpi_early_init(void);
diff --git a/ipc/msgutil.c b/ipc/msgutil.c
index 0992616eeed6..c82c215693d7 100644
--- a/ipc/msgutil.c
+++ b/ipc/msgutil.c
@@ -36,7 +36,7 @@ struct msg_msg *load_msg(const void __user *src, int len)
if (alen > DATALEN_MSG)
alen = DATALEN_MSG;
- msg = (struct msg_msg *)kmalloc(sizeof(*msg) + alen, GFP_KERNEL);
+ msg = kmalloc(sizeof(*msg) + alen, GFP_KERNEL);
if (msg == NULL)
return ERR_PTR(-ENOMEM);
@@ -56,7 +56,7 @@ struct msg_msg *load_msg(const void __user *src, int len)
alen = len;
if (alen > DATALEN_SEG)
alen = DATALEN_SEG;
- seg = (struct msg_msgseg *)kmalloc(sizeof(*seg) + alen,
+ seg = kmalloc(sizeof(*seg) + alen,
GFP_KERNEL);
if (seg == NULL) {
err = -ENOMEM;
diff --git a/kernel/Makefile b/kernel/Makefile
index 5e3f3b75563a..14f4d45e0ae9 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -31,7 +31,6 @@ obj-$(CONFIG_PROVE_LOCKING) += spinlock.o
obj-$(CONFIG_UID16) += uid16.o
obj-$(CONFIG_MODULES) += module.o
obj-$(CONFIG_KALLSYMS) += kallsyms.o
-obj-$(CONFIG_STACK_UNWIND) += unwind.o
obj-$(CONFIG_PM) += power/
obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
obj-$(CONFIG_KEXEC) += kexec.o
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index 2e896f8ae29e..9c8c23227c7f 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -800,8 +800,8 @@ static inline int audit_dupe_selinux_field(struct audit_field *df,
/* our own copy of se_str */
se_str = kstrdup(sf->se_str, GFP_KERNEL);
- if (unlikely(IS_ERR(se_str)))
- return -ENOMEM;
+ if (unlikely(!se_str))
+ return -ENOMEM;
df->se_str = se_str;
/* our own (refreshed) copy of se_rule */
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 9124669f4586..241064a32241 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -258,7 +258,7 @@ static cpumask_t frozen_cpus;
int disable_nonboot_cpus(void)
{
- int cpu, first_cpu, error;
+ int cpu, first_cpu, error = 0;
mutex_lock(&cpu_add_remove_lock);
first_cpu = first_cpu(cpu_present_map);
@@ -294,7 +294,7 @@ int disable_nonboot_cpus(void)
/* Make sure the CPUs won't be enabled by someone else */
cpu_hotplug_disabled = 1;
} else {
- printk(KERN_ERR "Non-boot CPUs are not disabled");
+ printk(KERN_ERR "Non-boot CPUs are not disabled\n");
}
out:
mutex_unlock(&cpu_add_remove_lock);
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index 2c3b4431472b..6b05dc69c959 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -2342,32 +2342,48 @@ static const struct cpuset *nearest_exclusive_ancestor(const struct cpuset *cs)
}
/**
- * cpuset_zone_allowed - Can we allocate memory on zone z's memory node?
+ * cpuset_zone_allowed_softwall - Can we allocate on zone z's memory node?
* @z: is this zone on an allowed node?
- * @gfp_mask: memory allocation flags (we use __GFP_HARDWALL)
+ * @gfp_mask: memory allocation flags
*
- * If we're in interrupt, yes, we can always allocate. If zone
+ * If we're in interrupt, yes, we can always allocate. If
+ * __GFP_THISNODE is set, yes, we can always allocate. If zone
* z's node is in our tasks mems_allowed, yes. If it's not a
* __GFP_HARDWALL request and this zone's nodes is in the nearest
* mem_exclusive cpuset ancestor to this tasks cpuset, yes.
* Otherwise, no.
*
+ * If __GFP_HARDWALL is set, cpuset_zone_allowed_softwall()
+ * reduces to cpuset_zone_allowed_hardwall(). Otherwise,
+ * cpuset_zone_allowed_softwall() might sleep, and might allow a zone
+ * from an enclosing cpuset.
+ *
+ * cpuset_zone_allowed_hardwall() only handles the simpler case of
+ * hardwall cpusets, and never sleeps.
+ *
+ * The __GFP_THISNODE placement logic is really handled elsewhere,
+ * by forcibly using a zonelist starting at a specified node, and by
+ * (in get_page_from_freelist()) refusing to consider the zones for
+ * any node on the zonelist except the first. By the time any such
+ * calls get to this routine, we should just shut up and say 'yes'.
+ *
* GFP_USER allocations are marked with the __GFP_HARDWALL bit,
* and do not allow allocations outside the current tasks cpuset.
* GFP_KERNEL allocations are not so marked, so can escape to the
- * nearest mem_exclusive ancestor cpuset.
+ * nearest enclosing mem_exclusive ancestor cpuset.
*
- * Scanning up parent cpusets requires callback_mutex. The __alloc_pages()
- * routine only calls here with __GFP_HARDWALL bit _not_ set if
- * it's a GFP_KERNEL allocation, and all nodes in the current tasks
- * mems_allowed came up empty on the first pass over the zonelist.
- * So only GFP_KERNEL allocations, if all nodes in the cpuset are
- * short of memory, might require taking the callback_mutex mutex.
+ * Scanning up parent cpusets requires callback_mutex. The
+ * __alloc_pages() routine only calls here with __GFP_HARDWALL bit
+ * _not_ set if it's a GFP_KERNEL allocation, and all nodes in the
+ * current tasks mems_allowed came up empty on the first pass over
+ * the zonelist. So only GFP_KERNEL allocations, if all nodes in the
+ * cpuset are short of memory, might require taking the callback_mutex
+ * mutex.
*
* The first call here from mm/page_alloc:get_page_from_freelist()
- * has __GFP_HARDWALL set in gfp_mask, enforcing hardwall cpusets, so
- * no allocation on a node outside the cpuset is allowed (unless in
- * interrupt, of course).
+ * has __GFP_HARDWALL set in gfp_mask, enforcing hardwall cpusets,
+ * so no allocation on a node outside the cpuset is allowed (unless
+ * in interrupt, of course).
*
* The second pass through get_page_from_freelist() doesn't even call
* here for GFP_ATOMIC calls. For those calls, the __alloc_pages()
@@ -2380,12 +2396,12 @@ static const struct cpuset *nearest_exclusive_ancestor(const struct cpuset *cs)
* GFP_USER - only nodes in current tasks mems allowed ok.
*
* Rule:
- * Don't call cpuset_zone_allowed() if you can't sleep, unless you
+ * Don't call cpuset_zone_allowed_softwall if you can't sleep, unless you
* pass in the __GFP_HARDWALL flag set in gfp_flag, which disables
* the code that might scan up ancestor cpusets and sleep.
- **/
+ */
-int __cpuset_zone_allowed(struct zone *z, gfp_t gfp_mask)
+int __cpuset_zone_allowed_softwall(struct zone *z, gfp_t gfp_mask)
{
int node; /* node that zone z is on */
const struct cpuset *cs; /* current cpuset ancestors */
@@ -2415,6 +2431,40 @@ int __cpuset_zone_allowed(struct zone *z, gfp_t gfp_mask)
return allowed;
}
+/*
+ * cpuset_zone_allowed_hardwall - Can we allocate on zone z's memory node?
+ * @z: is this zone on an allowed node?
+ * @gfp_mask: memory allocation flags
+ *
+ * If we're in interrupt, yes, we can always allocate.
+ * If __GFP_THISNODE is set, yes, we can always allocate. If zone
+ * z's node is in our tasks mems_allowed, yes. Otherwise, no.
+ *
+ * The __GFP_THISNODE placement logic is really handled elsewhere,
+ * by forcibly using a zonelist starting at a specified node, and by
+ * (in get_page_from_freelist()) refusing to consider the zones for
+ * any node on the zonelist except the first. By the time any such
+ * calls get to this routine, we should just shut up and say 'yes'.
+ *
+ * Unlike the cpuset_zone_allowed_softwall() variant, above,
+ * this variant requires that the zone be in the current tasks
+ * mems_allowed or that we're in interrupt. It does not scan up the
+ * cpuset hierarchy for the nearest enclosing mem_exclusive cpuset.
+ * It never sleeps.
+ */
+
+int __cpuset_zone_allowed_hardwall(struct zone *z, gfp_t gfp_mask)
+{
+ int node; /* node that zone z is on */
+
+ if (in_interrupt() || (gfp_mask & __GFP_THISNODE))
+ return 1;
+ node = zone_to_nid(z);
+ if (node_isset(node, current->mems_allowed))
+ return 1;
+ return 0;
+}
+
/**
* cpuset_lock - lock out any changes to cpuset structures
*
@@ -2606,7 +2656,7 @@ static int cpuset_open(struct inode *inode, struct file *file)
return single_open(file, proc_cpuset_show, pid);
}
-const struct file_operations proc_cpuset_operations = {
+struct file_operations proc_cpuset_operations = {
.open = cpuset_open,
.read = seq_read,
.llseek = seq_lseek,
diff --git a/kernel/exit.c b/kernel/exit.c
index 122fadb972fc..35401720635b 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -468,7 +468,7 @@ void fastcall put_files_struct(struct files_struct *files)
fdt = files_fdtable(files);
if (fdt != &files->fdtab)
kmem_cache_free(files_cachep, files);
- call_rcu(&fdt->rcu, free_fdtable_rcu);
+ free_fdtable(fdt);
}
}
@@ -597,10 +597,6 @@ choose_new_parent(struct task_struct *p, struct task_struct *reaper)
static void
reparent_thread(struct task_struct *p, struct task_struct *father, int traced)
{
- /* We don't want people slaying init. */
- if (p->exit_signal != -1)
- p->exit_signal = SIGCHLD;
-
if (p->pdeath_signal)
/* We already hold the tasklist_lock here. */
group_send_sig_info(p->pdeath_signal, SEND_SIG_NOINFO, p);
@@ -620,13 +616,7 @@ reparent_thread(struct task_struct *p, struct task_struct *father, int traced)
p->parent = p->real_parent;
add_parent(p);
- /* If we'd notified the old parent about this child's death,
- * also notify the new parent.
- */
- if (p->exit_state == EXIT_ZOMBIE && p->exit_signal != -1 &&
- thread_group_empty(p))
- do_notify_parent(p, p->exit_signal);
- else if (p->state == TASK_TRACED) {
+ if (p->state == TASK_TRACED) {
/*
* If it was at a trace stop, turn it into
* a normal stop since it's no longer being
@@ -636,6 +626,23 @@ reparent_thread(struct task_struct *p, struct task_struct *father, int traced)
}
}
+ /* If this is a threaded reparent there is no need to
+ * notify anyone anything has happened.
+ */
+ if (p->real_parent->group_leader == father->group_leader)
+ return;
+
+ /* We don't want people slaying init. */
+ if (p->exit_signal != -1)
+ p->exit_signal = SIGCHLD;
+
+ /* If we'd notified the old parent about this child's death,
+ * also notify the new parent.
+ */
+ if (!traced && p->exit_state == EXIT_ZOMBIE &&
+ p->exit_signal != -1 && thread_group_empty(p))
+ do_notify_parent(p, p->exit_signal);
+
/*
* process group orphan check
* Case ii: Our child is in a different pgrp
diff --git a/kernel/fork.c b/kernel/fork.c
index d16c566eb645..fc723e595cd5 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -203,7 +203,7 @@ static inline int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
struct mempolicy *pol;
down_write(&oldmm->mmap_sem);
- flush_cache_mm(oldmm);
+ flush_cache_dup_mm(oldmm);
/*
* Not linked in yet - no deadlock potential:
*/
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index ebfd24a41858..d27b25855743 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -517,10 +517,9 @@ __set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
if (!handle)
handle = handle_bad_irq;
-
- if (desc->chip == &no_irq_chip) {
+ else if (desc->chip == &no_irq_chip) {
printk(KERN_WARNING "Trying to install %sinterrupt handler "
- "for IRQ%d\n", is_chained ? "chained " : " ", irq);
+ "for IRQ%d\n", is_chained ? "chained " : "", irq);
/*
* Some ARM implementations install a handler for really dumb
* interrupt hardware without setting an irq_chip. This worked
diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index b02032476dc2..509efd49540f 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -43,13 +43,49 @@
#include "lockdep_internals.h"
/*
- * hash_lock: protects the lockdep hashes and class/list/hash allocators.
+ * lockdep_lock: protects the lockdep graph, the hashes and the
+ * class/list/hash allocators.
*
* This is one of the rare exceptions where it's justified
* to use a raw spinlock - we really dont want the spinlock
- * code to recurse back into the lockdep code.
+ * code to recurse back into the lockdep code...
*/
-static raw_spinlock_t hash_lock = (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED;
+static raw_spinlock_t lockdep_lock = (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED;
+
+static int graph_lock(void)
+{
+ __raw_spin_lock(&lockdep_lock);
+ /*
+ * Make sure that if another CPU detected a bug while
+ * walking the graph we dont change it (while the other
+ * CPU is busy printing out stuff with the graph lock
+ * dropped already)
+ */
+ if (!debug_locks) {
+ __raw_spin_unlock(&lockdep_lock);
+ return 0;
+ }
+ return 1;
+}
+
+static inline int graph_unlock(void)
+{
+ __raw_spin_unlock(&lockdep_lock);
+ return 0;
+}
+
+/*
+ * Turn lock debugging off and return with 0 if it was off already,
+ * and also release the graph lock:
+ */
+static inline int debug_locks_off_graph_unlock(void)
+{
+ int ret = debug_locks_off();
+
+ __raw_spin_unlock(&lockdep_lock);
+
+ return ret;
+}
static int lockdep_initialized;
@@ -57,14 +93,15 @@ unsigned long nr_list_entries;
static struct lock_list list_entries[MAX_LOCKDEP_ENTRIES];
/*
- * Allocate a lockdep entry. (assumes hash_lock held, returns
+ * Allocate a lockdep entry. (assumes the graph_lock held, returns
* with NULL on failure)
*/
static struct lock_list *alloc_list_entry(void)
{
if (nr_list_entries >= MAX_LOCKDEP_ENTRIES) {
- __raw_spin_unlock(&hash_lock);
- debug_locks_off();
+ if (!debug_locks_off_graph_unlock())
+ return NULL;
+
printk("BUG: MAX_LOCKDEP_ENTRIES too low!\n");
printk("turning off the locking correctness validator.\n");
return NULL;
@@ -145,9 +182,7 @@ EXPORT_SYMBOL(lockdep_on);
*/
#define VERBOSE 0
-#ifdef VERBOSE
-# define VERY_VERBOSE 0
-#endif
+#define VERY_VERBOSE 0
#if VERBOSE
# define HARDIRQ_VERBOSE 1
@@ -172,8 +207,8 @@ static int class_filter(struct lock_class *class)
!strcmp(class->name, "&struct->lockfield"))
return 1;
#endif
- /* Allow everything else. 0 would be filter everything else */
- return 1;
+ /* Filter everything else. 1 would be to allow everything else */
+ return 0;
}
#endif
@@ -207,7 +242,7 @@ static int softirq_verbose(struct lock_class *class)
/*
* Stack-trace: tightly packed array of stack backtrace
- * addresses. Protected by the hash_lock.
+ * addresses. Protected by the graph_lock.
*/
unsigned long nr_stack_trace_entries;
static unsigned long stack_trace[MAX_STACK_TRACE_ENTRIES];
@@ -226,18 +261,15 @@ static int save_trace(struct stack_trace *trace)
trace->max_entries = trace->nr_entries;
nr_stack_trace_entries += trace->nr_entries;
- if (DEBUG_LOCKS_WARN_ON(nr_stack_trace_entries > MAX_STACK_TRACE_ENTRIES)) {
- __raw_spin_unlock(&hash_lock);
- return 0;
- }
if (nr_stack_trace_entries == MAX_STACK_TRACE_ENTRIES) {
- __raw_spin_unlock(&hash_lock);
- if (debug_locks_off()) {
- printk("BUG: MAX_STACK_TRACE_ENTRIES too low!\n");
- printk("turning off the locking correctness validator.\n");
- dump_stack();
- }
+ if (!debug_locks_off_graph_unlock())
+ return 0;
+
+ printk("BUG: MAX_STACK_TRACE_ENTRIES too low!\n");
+ printk("turning off the locking correctness validator.\n");
+ dump_stack();
+
return 0;
}
@@ -526,9 +558,7 @@ print_circular_bug_header(struct lock_list *entry, unsigned int depth)
{
struct task_struct *curr = current;
- __raw_spin_unlock(&hash_lock);
- debug_locks_off();
- if (debug_locks_silent)
+ if (!debug_locks_off_graph_unlock() || debug_locks_silent)
return 0;
printk("\n=======================================================\n");
@@ -556,12 +586,10 @@ static noinline int print_circular_bug_tail(void)
if (debug_locks_silent)
return 0;
- /* hash_lock unlocked by the header */
- __raw_spin_lock(&hash_lock);
this.class = check_source->class;
if (!save_trace(&this.trace))
return 0;
- __raw_spin_unlock(&hash_lock);
+
print_circular_bug_entry(&this, 0);
printk("\nother info that might help us debug this:\n\n");
@@ -577,8 +605,10 @@ static noinline int print_circular_bug_tail(void)
static int noinline print_infinite_recursion_bug(void)
{
- __raw_spin_unlock(&hash_lock);
- DEBUG_LOCKS_WARN_ON(1);
+ if (!debug_locks_off_graph_unlock())
+ return 0;
+
+ WARN_ON(1);
return 0;
}
@@ -713,9 +743,7 @@ print_bad_irq_dependency(struct task_struct *curr,
enum lock_usage_bit bit2,
const char *irqclass)
{
- __raw_spin_unlock(&hash_lock);
- debug_locks_off();
- if (debug_locks_silent)
+ if (!debug_locks_off_graph_unlock() || debug_locks_silent)
return 0;
printk("\n======================================================\n");
@@ -796,9 +824,7 @@ static int
print_deadlock_bug(struct task_struct *curr, struct held_lock *prev,
struct held_lock *next)
{
- debug_locks_off();
- __raw_spin_unlock(&hash_lock);
- if (debug_locks_silent)
+ if (!debug_locks_off_graph_unlock() || debug_locks_silent)
return 0;
printk("\n=============================================\n");
@@ -974,14 +1000,14 @@ check_prev_add(struct task_struct *curr, struct held_lock *prev,
* Debugging printouts:
*/
if (verbose(prev->class) || verbose(next->class)) {
- __raw_spin_unlock(&hash_lock);
+ graph_unlock();
printk("\n new dependency: ");
print_lock_name(prev->class);
printk(" => ");
print_lock_name(next->class);
printk("\n");
dump_stack();
- __raw_spin_lock(&hash_lock);
+ return graph_lock();
}
return 1;
}
@@ -1046,8 +1072,10 @@ check_prevs_add(struct task_struct *curr, struct held_lock *next)
}
return 1;
out_bug:
- __raw_spin_unlock(&hash_lock);
- DEBUG_LOCKS_WARN_ON(1);
+ if (!debug_locks_off_graph_unlock())
+ return 0;
+
+ WARN_ON(1);
return 0;
}
@@ -1201,7 +1229,10 @@ register_lock_class(struct lockdep_map *lock, unsigned int subclass, int force)
hash_head = classhashentry(key);
raw_local_irq_save(flags);
- __raw_spin_lock(&hash_lock);
+ if (!graph_lock()) {
+ raw_local_irq_restore(flags);
+ return NULL;
+ }
/*
* We have to do the hash-walk again, to avoid races
* with another CPU:
@@ -1214,9 +1245,12 @@ register_lock_class(struct lockdep_map *lock, unsigned int subclass, int force)
* the hash:
*/
if (nr_lock_classes >= MAX_LOCKDEP_KEYS) {
- __raw_spin_unlock(&hash_lock);
+ if (!debug_locks_off_graph_unlock()) {
+ raw_local_irq_restore(flags);
+ return NULL;
+ }
raw_local_irq_restore(flags);
- debug_locks_off();
+
printk("BUG: MAX_LOCKDEP_KEYS too low!\n");
printk("turning off the locking correctness validator.\n");
return NULL;
@@ -1237,18 +1271,23 @@ register_lock_class(struct lockdep_map *lock, unsigned int subclass, int force)
list_add_tail_rcu(&class->hash_entry, hash_head);
if (verbose(class)) {
- __raw_spin_unlock(&hash_lock);
+ graph_unlock();
raw_local_irq_restore(flags);
+
printk("\nnew class %p: %s", class->key, class->name);
if (class->name_version > 1)
printk("#%d", class->name_version);
printk("\n");
dump_stack();
+
raw_local_irq_save(flags);
- __raw_spin_lock(&hash_lock);
+ if (!graph_lock()) {
+ raw_local_irq_restore(flags);
+ return NULL;
+ }
}
out_unlock_set:
- __raw_spin_unlock(&hash_lock);
+ graph_unlock();
raw_local_irq_restore(flags);
if (!subclass || force)
@@ -1264,7 +1303,7 @@ out_unlock_set:
* add it and return 0 - in this case the new dependency chain is
* validated. If the key is already hashed, return 1.
*/
-static inline int lookup_chain_cache(u64 chain_key)
+static inline int lookup_chain_cache(u64 chain_key, struct lock_class *class)
{
struct list_head *hash_head = chainhashentry(chain_key);
struct lock_chain *chain;
@@ -1278,34 +1317,36 @@ static inline int lookup_chain_cache(u64 chain_key)
if (chain->chain_key == chain_key) {
cache_hit:
debug_atomic_inc(&chain_lookup_hits);
- /*
- * In the debugging case, force redundant checking
- * by returning 1:
- */
-#ifdef CONFIG_DEBUG_LOCKDEP
- __raw_spin_lock(&hash_lock);
- return 1;
-#endif
+ if (very_verbose(class))
+ printk("\nhash chain already cached, key: "
+ "%016Lx tail class: [%p] %s\n",
+ (unsigned long long)chain_key,
+ class->key, class->name);
return 0;
}
}
+ if (very_verbose(class))
+ printk("\nnew hash chain, key: %016Lx tail class: [%p] %s\n",
+ (unsigned long long)chain_key, class->key, class->name);
/*
* Allocate a new chain entry from the static array, and add
* it to the hash:
*/
- __raw_spin_lock(&hash_lock);
+ if (!graph_lock())
+ return 0;
/*
* We have to walk the chain again locked - to avoid duplicates:
*/
list_for_each_entry(chain, hash_head, entry) {
if (chain->chain_key == chain_key) {
- __raw_spin_unlock(&hash_lock);
+ graph_unlock();
goto cache_hit;
}
}
if (unlikely(nr_lock_chains >= MAX_LOCKDEP_CHAINS)) {
- __raw_spin_unlock(&hash_lock);
- debug_locks_off();
+ if (!debug_locks_off_graph_unlock())
+ return 0;
+
printk("BUG: MAX_LOCKDEP_CHAINS too low!\n");
printk("turning off the locking correctness validator.\n");
return 0;
@@ -1381,9 +1422,7 @@ print_irq_inversion_bug(struct task_struct *curr, struct lock_class *other,
struct held_lock *this, int forwards,
const char *irqclass)
{
- __raw_spin_unlock(&hash_lock);
- debug_locks_off();
- if (debug_locks_silent)
+ if (!debug_locks_off_graph_unlock() || debug_locks_silent)
return 0;
printk("\n=========================================================\n");
@@ -1453,7 +1492,7 @@ check_usage_backwards(struct task_struct *curr, struct held_lock *this,
return print_irq_inversion_bug(curr, backwards_match, this, 0, irqclass);
}
-static inline void print_irqtrace_events(struct task_struct *curr)
+void print_irqtrace_events(struct task_struct *curr)
{
printk("irq event stamp: %u\n", curr->irq_events);
printk("hardirqs last enabled at (%u): ", curr->hardirq_enable_event);
@@ -1466,19 +1505,13 @@ static inline void print_irqtrace_events(struct task_struct *curr)
print_ip_sym(curr->softirq_disable_ip);
}
-#else
-static inline void print_irqtrace_events(struct task_struct *curr)
-{
-}
#endif
static int
print_usage_bug(struct task_struct *curr, struct held_lock *this,
enum lock_usage_bit prev_bit, enum lock_usage_bit new_bit)
{
- __raw_spin_unlock(&hash_lock);
- debug_locks_off();
- if (debug_locks_silent)
+ if (!debug_locks_off_graph_unlock() || debug_locks_silent)
return 0;
printk("\n=================================\n");
@@ -1539,12 +1572,13 @@ static int mark_lock(struct task_struct *curr, struct held_lock *this,
if (likely(this->class->usage_mask & new_mask))
return 1;
- __raw_spin_lock(&hash_lock);
+ if (!graph_lock())
+ return 0;
/*
* Make sure we didnt race:
*/
if (unlikely(this->class->usage_mask & new_mask)) {
- __raw_spin_unlock(&hash_lock);
+ graph_unlock();
return 1;
}
@@ -1730,16 +1764,16 @@ static int mark_lock(struct task_struct *curr, struct held_lock *this,
debug_atomic_dec(&nr_unused_locks);
break;
default:
- __raw_spin_unlock(&hash_lock);
- debug_locks_off();
+ if (!debug_locks_off_graph_unlock())
+ return 0;
WARN_ON(1);
return 0;
}
- __raw_spin_unlock(&hash_lock);
+ graph_unlock();
/*
- * We must printk outside of the hash_lock:
+ * We must printk outside of the graph_lock:
*/
if (ret == 2) {
printk("\nmarked lock as {%s}:\n", usage_str[new_bit]);
@@ -2137,9 +2171,9 @@ out_calc_hash:
* We look up the chain_key and do the O(N^2) check and update of
* the dependencies only if this is a new dependency chain.
* (If lookup_chain_cache() returns with 1 it acquires
- * hash_lock for us)
+ * graph_lock for us)
*/
- if (!trylock && (check == 2) && lookup_chain_cache(chain_key)) {
+ if (!trylock && (check == 2) && lookup_chain_cache(chain_key, class)) {
/*
* Check whether last held lock:
*
@@ -2170,7 +2204,7 @@ out_calc_hash:
if (!chain_head && ret != 2)
if (!check_prevs_add(curr, hlock))
return 0;
- __raw_spin_unlock(&hash_lock);
+ graph_unlock();
}
curr->lockdep_depth++;
check_chain_key(curr);
@@ -2433,6 +2467,7 @@ EXPORT_SYMBOL_GPL(lock_release);
void lockdep_reset(void)
{
unsigned long flags;
+ int i;
raw_local_irq_save(flags);
current->curr_chain_key = 0;
@@ -2443,6 +2478,8 @@ void lockdep_reset(void)
nr_softirq_chains = 0;
nr_process_chains = 0;
debug_locks = 1;
+ for (i = 0; i < CHAINHASH_SIZE; i++)
+ INIT_LIST_HEAD(chainhash_table + i);
raw_local_irq_restore(flags);
}
@@ -2479,7 +2516,7 @@ void lockdep_free_key_range(void *start, unsigned long size)
int i;
raw_local_irq_save(flags);
- __raw_spin_lock(&hash_lock);
+ graph_lock();
/*
* Unhash all classes that were created by this module:
@@ -2493,7 +2530,7 @@ void lockdep_free_key_range(void *start, unsigned long size)
zap_class(class);
}
- __raw_spin_unlock(&hash_lock);
+ graph_unlock();
raw_local_irq_restore(flags);
}
@@ -2521,20 +2558,20 @@ void lockdep_reset_lock(struct lockdep_map *lock)
* Debug check: in the end all mapped classes should
* be gone.
*/
- __raw_spin_lock(&hash_lock);
+ graph_lock();
for (i = 0; i < CLASSHASH_SIZE; i++) {
head = classhash_table + i;
if (list_empty(head))
continue;
list_for_each_entry_safe(class, next, head, hash_entry) {
if (unlikely(class == lock->class_cache)) {
- __raw_spin_unlock(&hash_lock);
- DEBUG_LOCKS_WARN_ON(1);
+ if (debug_locks_off_graph_unlock())
+ WARN_ON(1);
goto out_restore;
}
}
}
- __raw_spin_unlock(&hash_lock);
+ graph_unlock();
out_restore:
raw_local_irq_restore(flags);
diff --git a/kernel/module.c b/kernel/module.c
index d9eae45d0145..dbce132b354c 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -824,9 +824,34 @@ static inline void module_unload_init(struct module *mod)
}
#endif /* CONFIG_MODULE_UNLOAD */
+static ssize_t show_initstate(struct module_attribute *mattr,
+ struct module *mod, char *buffer)
+{
+ const char *state = "unknown";
+
+ switch (mod->state) {
+ case MODULE_STATE_LIVE:
+ state = "live";
+ break;
+ case MODULE_STATE_COMING:
+ state = "coming";
+ break;
+ case MODULE_STATE_GOING:
+ state = "going";
+ break;
+ }
+ return sprintf(buffer, "%s\n", state);
+}
+
+static struct module_attribute initstate = {
+ .attr = { .name = "initstate", .mode = 0444, .owner = THIS_MODULE },
+ .show = show_initstate,
+};
+
static struct module_attribute *modinfo_attrs[] = {
&modinfo_version,
&modinfo_srcversion,
+ &initstate,
#ifdef CONFIG_MODULE_UNLOAD
&refcnt,
#endif
@@ -1107,8 +1132,10 @@ static int mod_sysfs_setup(struct module *mod,
goto out;
mod->drivers_dir = kobject_add_dir(&mod->mkobj.kobj, "drivers");
- if (!mod->drivers_dir)
+ if (!mod->drivers_dir) {
+ err = -ENOMEM;
goto out_unreg;
+ }
err = module_param_sysfs_setup(mod, kparam, num_params);
if (err)
diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c
index e2ce748e96af..f5b9ee6f6bbb 100644
--- a/kernel/nsproxy.c
+++ b/kernel/nsproxy.c
@@ -46,10 +46,8 @@ static inline struct nsproxy *clone_namespaces(struct nsproxy *orig)
struct nsproxy *ns;
ns = kmemdup(orig, sizeof(struct nsproxy), GFP_KERNEL);
- if (ns) {
+ if (ns)
atomic_set(&ns->count, 1);
- ns->id = -1;
- }
return ns;
}
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index 710ed084e7c5..ed296225dcd4 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -20,13 +20,14 @@ config PM
sending the processor to sleep and saving power.
config PM_LEGACY
- bool "Legacy Power Management API"
+ bool "Legacy Power Management API (DEPRECATED)"
depends on PM
- default y
+ default n
---help---
- Support for pm_register() and friends.
+ Support for pm_register() and friends. This old API is obsoleted
+ by the driver model.
- If unsure, say Y.
+ If unsure, say N.
config PM_DEBUG
bool "Power Management Debug Support"
diff --git a/kernel/power/disk.c b/kernel/power/disk.c
index 0b00f56c2ad0..88fc5d7ac737 100644
--- a/kernel/power/disk.c
+++ b/kernel/power/disk.c
@@ -60,9 +60,11 @@ static void power_down(suspend_disk_method_t mode)
{
switch(mode) {
case PM_DISK_PLATFORM:
- kernel_shutdown_prepare(SYSTEM_SUSPEND_DISK);
- pm_ops->enter(PM_SUSPEND_DISK);
- break;
+ if (pm_ops && pm_ops->enter) {
+ kernel_shutdown_prepare(SYSTEM_SUSPEND_DISK);
+ pm_ops->enter(PM_SUSPEND_DISK);
+ break;
+ }
case PM_DISK_SHUTDOWN:
kernel_power_off();
break;
diff --git a/kernel/power/main.c b/kernel/power/main.c
index 500eb87f643d..ff3a6182f5f0 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -29,7 +29,7 @@
DEFINE_MUTEX(pm_mutex);
struct pm_ops *pm_ops;
-suspend_disk_method_t pm_disk_mode = PM_DISK_SHUTDOWN;
+suspend_disk_method_t pm_disk_mode = PM_DISK_PLATFORM;
/**
* pm_set_ops - Set the global power method table.
diff --git a/kernel/power/process.c b/kernel/power/process.c
index 99eeb119b06d..6d566bf7085c 100644
--- a/kernel/power/process.c
+++ b/kernel/power/process.c
@@ -28,8 +28,7 @@ static inline int freezeable(struct task_struct * p)
if ((p == current) ||
(p->flags & PF_NOFREEZE) ||
(p->exit_state == EXIT_ZOMBIE) ||
- (p->exit_state == EXIT_DEAD) ||
- (p->state == TASK_STOPPED))
+ (p->exit_state == EXIT_DEAD))
return 0;
return 1;
}
@@ -61,10 +60,16 @@ static inline void freeze_process(struct task_struct *p)
unsigned long flags;
if (!freezing(p)) {
- freeze(p);
- spin_lock_irqsave(&p->sighand->siglock, flags);
- signal_wake_up(p, 0);
- spin_unlock_irqrestore(&p->sighand->siglock, flags);
+ rmb();
+ if (!frozen(p)) {
+ if (p->state == TASK_STOPPED)
+ force_sig_specific(SIGSTOP, p);
+
+ freeze(p);
+ spin_lock_irqsave(&p->sighand->siglock, flags);
+ signal_wake_up(p, p->state == TASK_STOPPED);
+ spin_unlock_irqrestore(&p->sighand->siglock, flags);
+ }
}
}
@@ -103,9 +108,7 @@ static unsigned int try_to_freeze_tasks(int freeze_user_space)
if (frozen(p))
continue;
- if (p->state == TASK_TRACED &&
- (frozen(p->parent) ||
- p->parent->state == TASK_STOPPED)) {
+ if (p->state == TASK_TRACED && frozen(p->parent)) {
cancel_freezing(p);
continue;
}
diff --git a/kernel/printk.c b/kernel/printk.c
index 185bb45eacf7..c770e1a4e882 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -335,7 +335,7 @@ static void __call_console_drivers(unsigned long start, unsigned long end)
static int __read_mostly ignore_loglevel;
-int __init ignore_loglevel_setup(char *str)
+static int __init ignore_loglevel_setup(char *str)
{
ignore_loglevel = 1;
printk(KERN_INFO "debug: ignoring loglevel setting.\n");
diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c
index c52f981ea008..482b11ff65cb 100644
--- a/kernel/rcutorture.c
+++ b/kernel/rcutorture.c
@@ -522,6 +522,7 @@ rcu_torture_writer(void *arg)
VERBOSE_PRINTK_STRING("rcu_torture_writer task started");
set_user_nice(current, 19);
+ current->flags |= PF_NOFREEZE;
do {
schedule_timeout_uninterruptible(1);
@@ -561,6 +562,7 @@ rcu_torture_fakewriter(void *arg)
VERBOSE_PRINTK_STRING("rcu_torture_fakewriter task started");
set_user_nice(current, 19);
+ current->flags |= PF_NOFREEZE;
do {
schedule_timeout_uninterruptible(1 + rcu_random(&rand)%10);
@@ -591,6 +593,7 @@ rcu_torture_reader(void *arg)
VERBOSE_PRINTK_STRING("rcu_torture_reader task started");
set_user_nice(current, 19);
+ current->flags |= PF_NOFREEZE;
do {
idx = cur_ops->readlock();
diff --git a/kernel/relay.c b/kernel/relay.c
index 818e514729cf..284e2e8b4eed 100644
--- a/kernel/relay.c
+++ b/kernel/relay.c
@@ -138,7 +138,7 @@ depopulate:
*/
struct rchan_buf *relay_create_buf(struct rchan *chan)
{
- struct rchan_buf *buf = kcalloc(1, sizeof(struct rchan_buf), GFP_KERNEL);
+ struct rchan_buf *buf = kzalloc(sizeof(struct rchan_buf), GFP_KERNEL);
if (!buf)
return NULL;
@@ -302,7 +302,7 @@ static struct rchan_callbacks default_channel_callbacks = {
/**
* wakeup_readers - wake up readers waiting on a channel
- * @private: the channel buffer
+ * @work: work struct that contains the the channel buffer
*
* This is the work function used to defer reader waking. The
* reason waking is deferred is that calling directly from write
@@ -322,7 +322,7 @@ static void wakeup_readers(struct work_struct *work)
*
* See relay_reset for description of effect.
*/
-static inline void __relay_reset(struct rchan_buf *buf, unsigned int init)
+static void __relay_reset(struct rchan_buf *buf, unsigned int init)
{
size_t i;
@@ -418,7 +418,7 @@ static struct rchan_buf *relay_open_buf(struct rchan *chan,
* The channel buffer and channel buffer data structure are then freed
* automatically when the last reference is given up.
*/
-static inline void relay_close_buf(struct rchan_buf *buf)
+static void relay_close_buf(struct rchan_buf *buf)
{
buf->finalized = 1;
cancel_delayed_work(&buf->wake_readers);
@@ -426,7 +426,7 @@ static inline void relay_close_buf(struct rchan_buf *buf)
kref_put(&buf->kref, relay_remove_buf);
}
-static inline void setup_callbacks(struct rchan *chan,
+static void setup_callbacks(struct rchan *chan,
struct rchan_callbacks *cb)
{
if (!cb) {
@@ -479,7 +479,7 @@ struct rchan *relay_open(const char *base_filename,
if (!(subbuf_size && n_subbufs))
return NULL;
- chan = kcalloc(1, sizeof(struct rchan), GFP_KERNEL);
+ chan = kzalloc(sizeof(struct rchan), GFP_KERNEL);
if (!chan)
return NULL;
@@ -946,11 +946,10 @@ typedef int (*subbuf_actor_t) (size_t read_start,
/*
* relay_file_read_subbufs - read count bytes, bridging subbuf boundaries
*/
-static inline ssize_t relay_file_read_subbufs(struct file *filp,
- loff_t *ppos,
- subbuf_actor_t subbuf_actor,
- read_actor_t actor,
- read_descriptor_t *desc)
+static ssize_t relay_file_read_subbufs(struct file *filp, loff_t *ppos,
+ subbuf_actor_t subbuf_actor,
+ read_actor_t actor,
+ read_descriptor_t *desc)
{
struct rchan_buf *buf = filp->private_data;
size_t read_start, avail;
diff --git a/kernel/sched.c b/kernel/sched.c
index 8a0afb97af71..3df33da0dafc 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -1567,6 +1567,7 @@ int fastcall wake_up_state(struct task_struct *p, unsigned int state)
return try_to_wake_up(p, state, 0);
}
+static void task_running_tick(struct rq *rq, struct task_struct *p);
/*
* Perform scheduler related setup for a newly forked process p.
* p is forked by current.
@@ -1627,7 +1628,7 @@ void fastcall sched_fork(struct task_struct *p, int clone_flags)
* runqueue lock is not a problem.
*/
current->time_slice = 1;
- scheduler_tick();
+ task_running_tick(cpu_rq(cpu), current);
}
local_irq_enable();
put_cpu();
@@ -3429,6 +3430,8 @@ asmlinkage void __sched schedule(void)
"%s/0x%08x/%d\n",
current->comm, preempt_count(), current->pid);
debug_show_held_locks(current);
+ if (irqs_disabled())
+ print_irqtrace_events(current);
dump_stack();
}
profile_hit(SCHED_PROFILING, __builtin_return_address(0));
@@ -4614,15 +4617,6 @@ asmlinkage long sys_sched_yield(void)
return 0;
}
-static inline int __resched_legal(int expected_preempt_count)
-{
- if (unlikely(preempt_count() != expected_preempt_count))
- return 0;
- if (unlikely(system_state != SYSTEM_RUNNING))
- return 0;
- return 1;
-}
-
static void __cond_resched(void)
{
#ifdef CONFIG_DEBUG_SPINLOCK_SLEEP
@@ -4642,7 +4636,8 @@ static void __cond_resched(void)
int __sched cond_resched(void)
{
- if (need_resched() && __resched_legal(0)) {
+ if (need_resched() && !(preempt_count() & PREEMPT_ACTIVE) &&
+ system_state == SYSTEM_RUNNING) {
__cond_resched();
return 1;
}
@@ -4668,7 +4663,7 @@ int cond_resched_lock(spinlock_t *lock)
ret = 1;
spin_lock(lock);
}
- if (need_resched() && __resched_legal(1)) {
+ if (need_resched() && system_state == SYSTEM_RUNNING) {
spin_release(&lock->dep_map, 1, _THIS_IP_);
_raw_spin_unlock(lock);
preempt_enable_no_resched();
@@ -4684,7 +4679,7 @@ int __sched cond_resched_softirq(void)
{
BUG_ON(!in_softirq());
- if (need_resched() && __resched_legal(0)) {
+ if (need_resched() && system_state == SYSTEM_RUNNING) {
raw_local_irq_disable();
_local_bh_enable();
raw_local_irq_enable();
@@ -5605,7 +5600,7 @@ static void cpu_attach_domain(struct sched_domain *sd, int cpu)
}
/* cpus with isolated domains */
-static cpumask_t __cpuinitdata cpu_isolated_map = CPU_MASK_NONE;
+static cpumask_t cpu_isolated_map = CPU_MASK_NONE;
/* Setup the mask of cpus configured for isolated domains */
static int __init isolated_cpu_setup(char *str)
@@ -6977,6 +6972,8 @@ void __might_sleep(char *file, int line)
printk("in_atomic():%d, irqs_disabled():%d\n",
in_atomic(), irqs_disabled());
debug_show_held_locks(current);
+ if (irqs_disabled())
+ print_irqtrace_events(current);
dump_stack();
}
#endif
diff --git a/kernel/signal.c b/kernel/signal.c
index 1921ffdc5e77..5630255d2e2a 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1705,7 +1705,9 @@ finish_stop(int stop_count)
read_unlock(&tasklist_lock);
}
- schedule();
+ do {
+ schedule();
+ } while (try_to_freeze());
/*
* Now we don't run again until continued.
*/
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 130c5ec9ee0b..600b33358ded 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -65,7 +65,6 @@ extern int sysctl_overcommit_memory;
extern int sysctl_overcommit_ratio;
extern int sysctl_panic_on_oom;
extern int max_threads;
-extern int sysrq_enabled;
extern int core_uses_pid;
extern int suid_dumpable;
extern char core_pattern[];
@@ -543,7 +542,7 @@ static ctl_table kern_table[] = {
{
.ctl_name = KERN_SYSRQ,
.procname = "sysrq",
- .data = &sysrq_enabled,
+ .data = &__sysrq_enabled,
.maxlen = sizeof (int),
.mode = 0644,
.proc_handler = &proc_dointvec,
diff --git a/kernel/timer.c b/kernel/timer.c
index 0256ab443d8a..c2a8ccfc2882 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -1146,11 +1146,15 @@ static inline void calc_load(unsigned long ticks)
unsigned long active_tasks; /* fixed-point */
static int count = LOAD_FREQ;
- active_tasks = count_active_tasks();
- for (count -= ticks; count < 0; count += LOAD_FREQ) {
- CALC_LOAD(avenrun[0], EXP_1, active_tasks);
- CALC_LOAD(avenrun[1], EXP_5, active_tasks);
- CALC_LOAD(avenrun[2], EXP_15, active_tasks);
+ count -= ticks;
+ if (unlikely(count < 0)) {
+ active_tasks = count_active_tasks();
+ do {
+ CALC_LOAD(avenrun[0], EXP_1, active_tasks);
+ CALC_LOAD(avenrun[1], EXP_5, active_tasks);
+ CALC_LOAD(avenrun[2], EXP_15, active_tasks);
+ count += LOAD_FREQ;
+ } while (count < 0);
}
}
@@ -1340,11 +1344,10 @@ fastcall signed long __sched schedule_timeout(signed long timeout)
* should never happens anyway). You just have the printk()
* that will tell you if something is gone wrong and where.
*/
- if (timeout < 0)
- {
+ if (timeout < 0) {
printk(KERN_ERR "schedule_timeout: wrong timeout "
- "value %lx from %p\n", timeout,
- __builtin_return_address(0));
+ "value %lx\n", timeout);
+ dump_stack();
current->state = TASK_RUNNING;
goto out;
}
diff --git a/kernel/unwind.c b/kernel/unwind.c
deleted file mode 100644
index 09c261329249..000000000000
--- a/kernel/unwind.c
+++ /dev/null
@@ -1,1305 +0,0 @@
-/*
- * Copyright (C) 2002-2006 Novell, Inc.
- * Jan Beulich <jbeulich@novell.com>
- * This code is released under version 2 of the GNU GPL.
- *
- * A simple API for unwinding kernel stacks. This is used for
- * debugging and error reporting purposes. The kernel doesn't need
- * full-blown stack unwinding with all the bells and whistles, so there
- * is not much point in implementing the full Dwarf2 unwind API.
- */
-
-#include <linux/unwind.h>
-#include <linux/module.h>
-#include <linux/bootmem.h>
-#include <linux/sort.h>
-#include <linux/stop_machine.h>
-#include <linux/uaccess.h>
-#include <asm/sections.h>
-#include <asm/uaccess.h>
-#include <asm/unaligned.h>
-
-extern const char __start_unwind[], __end_unwind[];
-extern const u8 __start_unwind_hdr[], __end_unwind_hdr[];
-
-#define MAX_STACK_DEPTH 8
-
-#define EXTRA_INFO(f) { \
- BUILD_BUG_ON_ZERO(offsetof(struct unwind_frame_info, f) \
- % FIELD_SIZEOF(struct unwind_frame_info, f)) \
- + offsetof(struct unwind_frame_info, f) \
- / FIELD_SIZEOF(struct unwind_frame_info, f), \
- FIELD_SIZEOF(struct unwind_frame_info, f) \
- }
-#define PTREGS_INFO(f) EXTRA_INFO(regs.f)
-
-static const struct {
- unsigned offs:BITS_PER_LONG / 2;
- unsigned width:BITS_PER_LONG / 2;
-} reg_info[] = {
- UNW_REGISTER_INFO
-};
-
-#undef PTREGS_INFO
-#undef EXTRA_INFO
-
-#ifndef REG_INVALID
-#define REG_INVALID(r) (reg_info[r].width == 0)
-#endif
-
-#define DW_CFA_nop 0x00
-#define DW_CFA_set_loc 0x01
-#define DW_CFA_advance_loc1 0x02
-#define DW_CFA_advance_loc2 0x03
-#define DW_CFA_advance_loc4 0x04
-#define DW_CFA_offset_extended 0x05
-#define DW_CFA_restore_extended 0x06
-#define DW_CFA_undefined 0x07
-#define DW_CFA_same_value 0x08
-#define DW_CFA_register 0x09
-#define DW_CFA_remember_state 0x0a
-#define DW_CFA_restore_state 0x0b
-#define DW_CFA_def_cfa 0x0c
-#define DW_CFA_def_cfa_register 0x0d
-#define DW_CFA_def_cfa_offset 0x0e
-#define DW_CFA_def_cfa_expression 0x0f
-#define DW_CFA_expression 0x10
-#define DW_CFA_offset_extended_sf 0x11
-#define DW_CFA_def_cfa_sf 0x12
-#define DW_CFA_def_cfa_offset_sf 0x13
-#define DW_CFA_val_offset 0x14
-#define DW_CFA_val_offset_sf 0x15
-#define DW_CFA_val_expression 0x16
-#define DW_CFA_lo_user 0x1c
-#define DW_CFA_GNU_window_save 0x2d
-#define DW_CFA_GNU_args_size 0x2e
-#define DW_CFA_GNU_negative_offset_extended 0x2f
-#define DW_CFA_hi_user 0x3f
-
-#define DW_EH_PE_FORM 0x07
-#define DW_EH_PE_native 0x00
-#define DW_EH_PE_leb128 0x01
-#define DW_EH_PE_data2 0x02
-#define DW_EH_PE_data4 0x03
-#define DW_EH_PE_data8 0x04
-#define DW_EH_PE_signed 0x08
-#define DW_EH_PE_ADJUST 0x70
-#define DW_EH_PE_abs 0x00
-#define DW_EH_PE_pcrel 0x10
-#define DW_EH_PE_textrel 0x20
-#define DW_EH_PE_datarel 0x30
-#define DW_EH_PE_funcrel 0x40
-#define DW_EH_PE_aligned 0x50
-#define DW_EH_PE_indirect 0x80
-#define DW_EH_PE_omit 0xff
-
-typedef unsigned long uleb128_t;
-typedef signed long sleb128_t;
-#define sleb128abs __builtin_labs
-
-static struct unwind_table {
- struct {
- unsigned long pc;
- unsigned long range;
- } core, init;
- const void *address;
- unsigned long size;
- const unsigned char *header;
- unsigned long hdrsz;
- struct unwind_table *link;
- const char *name;
-} root_table;
-
-struct unwind_item {
- enum item_location {
- Nowhere,
- Memory,
- Register,
- Value
- } where;
- uleb128_t value;
-};
-
-struct unwind_state {
- uleb128_t loc, org;
- const u8 *cieStart, *cieEnd;
- uleb128_t codeAlign;
- sleb128_t dataAlign;
- struct cfa {
- uleb128_t reg, offs;
- } cfa;
- struct unwind_item regs[ARRAY_SIZE(reg_info)];
- unsigned stackDepth:8;
- unsigned version:8;
- const u8 *label;
- const u8 *stack[MAX_STACK_DEPTH];
-};
-
-static const struct cfa badCFA = { ARRAY_SIZE(reg_info), 1 };
-
-static unsigned unwind_debug;
-static int __init unwind_debug_setup(char *s)
-{
- unwind_debug = simple_strtoul(s, NULL, 0);
- return 1;
-}
-__setup("unwind_debug=", unwind_debug_setup);
-#define dprintk(lvl, fmt, args...) \
- ((void)(lvl > unwind_debug \
- || printk(KERN_DEBUG "unwind: " fmt "\n", ##args)))
-
-static struct unwind_table *find_table(unsigned long pc)
-{
- struct unwind_table *table;
-
- for (table = &root_table; table; table = table->link)
- if ((pc >= table->core.pc
- && pc < table->core.pc + table->core.range)
- || (pc >= table->init.pc
- && pc < table->init.pc + table->init.range))
- break;
-
- return table;
-}
-
-static unsigned long read_pointer(const u8 **pLoc,
- const void *end,
- signed ptrType,
- unsigned long text_base,
- unsigned long data_base);
-
-static void init_unwind_table(struct unwind_table *table,
- const char *name,
- const void *core_start,
- unsigned long core_size,
- const void *init_start,
- unsigned long init_size,
- const void *table_start,
- unsigned long table_size,
- const u8 *header_start,
- unsigned long header_size)
-{
- const u8 *ptr = header_start + 4;
- const u8 *end = header_start + header_size;
-
- table->core.pc = (unsigned long)core_start;
- table->core.range = core_size;
- table->init.pc = (unsigned long)init_start;
- table->init.range = init_size;
- table->address = table_start;
- table->size = table_size;
- /* See if the linker provided table looks valid. */
- if (header_size <= 4
- || header_start[0] != 1
- || (void *)read_pointer(&ptr, end, header_start[1], 0, 0)
- != table_start
- || !read_pointer(&ptr, end, header_start[2], 0, 0)
- || !read_pointer(&ptr, end, header_start[3], 0,
- (unsigned long)header_start)
- || !read_pointer(&ptr, end, header_start[3], 0,
- (unsigned long)header_start))
- header_start = NULL;
- table->hdrsz = header_size;
- smp_wmb();
- table->header = header_start;
- table->link = NULL;
- table->name = name;
-}
-
-void __init unwind_init(void)
-{
- init_unwind_table(&root_table, "kernel",
- _text, _end - _text,
- NULL, 0,
- __start_unwind, __end_unwind - __start_unwind,
- __start_unwind_hdr, __end_unwind_hdr - __start_unwind_hdr);
-}
-
-static const u32 bad_cie, not_fde;
-static const u32 *cie_for_fde(const u32 *fde, const struct unwind_table *);
-static signed fde_pointer_type(const u32 *cie);
-
-struct eh_frame_hdr_table_entry {
- unsigned long start, fde;
-};
-
-static int cmp_eh_frame_hdr_table_entries(const void *p1, const void *p2)
-{
- const struct eh_frame_hdr_table_entry *e1 = p1;
- const struct eh_frame_hdr_table_entry *e2 = p2;
-
- return (e1->start > e2->start) - (e1->start < e2->start);
-}
-
-static void swap_eh_frame_hdr_table_entries(void *p1, void *p2, int size)
-{
- struct eh_frame_hdr_table_entry *e1 = p1;
- struct eh_frame_hdr_table_entry *e2 = p2;
- unsigned long v;
-
- v = e1->start;
- e1->start = e2->start;
- e2->start = v;
- v = e1->fde;
- e1->fde = e2->fde;
- e2->fde = v;
-}
-
-static void __init setup_unwind_table(struct unwind_table *table,
- void *(*alloc)(unsigned long))
-{
- const u8 *ptr;
- unsigned long tableSize = table->size, hdrSize;
- unsigned n;
- const u32 *fde;
- struct {
- u8 version;
- u8 eh_frame_ptr_enc;
- u8 fde_count_enc;
- u8 table_enc;
- unsigned long eh_frame_ptr;
- unsigned int fde_count;
- struct eh_frame_hdr_table_entry table[];
- } __attribute__((__packed__)) *header;
-
- if (table->header)
- return;
-
- if (table->hdrsz)
- printk(KERN_WARNING ".eh_frame_hdr for '%s' present but unusable\n",
- table->name);
-
- if (tableSize & (sizeof(*fde) - 1))
- return;
-
- for (fde = table->address, n = 0;
- tableSize > sizeof(*fde) && tableSize - sizeof(*fde) >= *fde;
- tableSize -= sizeof(*fde) + *fde, fde += 1 + *fde / sizeof(*fde)) {
- const u32 *cie = cie_for_fde(fde, table);
- signed ptrType;
-
- if (cie == &not_fde)
- continue;
- if (cie == NULL
- || cie == &bad_cie
- || (ptrType = fde_pointer_type(cie)) < 0)
- return;
- ptr = (const u8 *)(fde + 2);
- if (!read_pointer(&ptr,
- (const u8 *)(fde + 1) + *fde,
- ptrType, 0, 0))
- return;
- ++n;
- }
-
- if (tableSize || !n)
- return;
-
- hdrSize = 4 + sizeof(unsigned long) + sizeof(unsigned int)
- + 2 * n * sizeof(unsigned long);
- dprintk(2, "Binary lookup table size for %s: %lu bytes", table->name, hdrSize);
- header = alloc(hdrSize);
- if (!header)
- return;
- header->version = 1;
- header->eh_frame_ptr_enc = DW_EH_PE_abs|DW_EH_PE_native;
- header->fde_count_enc = DW_EH_PE_abs|DW_EH_PE_data4;
- header->table_enc = DW_EH_PE_abs|DW_EH_PE_native;
- put_unaligned((unsigned long)table->address, &header->eh_frame_ptr);
- BUILD_BUG_ON(offsetof(typeof(*header), fde_count)
- % __alignof(typeof(header->fde_count)));
- header->fde_count = n;
-
- BUILD_BUG_ON(offsetof(typeof(*header), table)
- % __alignof(typeof(*header->table)));
- for (fde = table->address, tableSize = table->size, n = 0;
- tableSize;
- tableSize -= sizeof(*fde) + *fde, fde += 1 + *fde / sizeof(*fde)) {
- const u32 *cie = fde + 1 - fde[1] / sizeof(*fde);
-
- if (!fde[1])
- continue; /* this is a CIE */
- ptr = (const u8 *)(fde + 2);
- header->table[n].start = read_pointer(&ptr,
- (const u8 *)(fde + 1) + *fde,
- fde_pointer_type(cie), 0, 0);
- header->table[n].fde = (unsigned long)fde;
- ++n;
- }
- WARN_ON(n != header->fde_count);
-
- sort(header->table,
- n,
- sizeof(*header->table),
- cmp_eh_frame_hdr_table_entries,
- swap_eh_frame_hdr_table_entries);
-
- table->hdrsz = hdrSize;
- smp_wmb();
- table->header = (const void *)header;
-}
-
-static void *__init balloc(unsigned long sz)
-{
- return __alloc_bootmem_nopanic(sz,
- sizeof(unsigned int),
- __pa(MAX_DMA_ADDRESS));
-}
-
-void __init unwind_setup(void)
-{
- setup_unwind_table(&root_table, balloc);
-}
-
-#ifdef CONFIG_MODULES
-
-static struct unwind_table *last_table;
-
-/* Must be called with module_mutex held. */
-void *unwind_add_table(struct module *module,
- const void *table_start,
- unsigned long table_size)
-{
- struct unwind_table *table;
-
- if (table_size <= 0)
- return NULL;
-
- table = kmalloc(sizeof(*table), GFP_KERNEL);
- if (!table)
- return NULL;
-
- init_unwind_table(table, module->name,
- module->module_core, module->core_size,
- module->module_init, module->init_size,
- table_start, table_size,
- NULL, 0);
-
- if (last_table)
- last_table->link = table;
- else
- root_table.link = table;
- last_table = table;
-
- return table;
-}
-
-struct unlink_table_info
-{
- struct unwind_table *table;
- int init_only;
-};
-
-static int unlink_table(void *arg)
-{
- struct unlink_table_info *info = arg;
- struct unwind_table *table = info->table, *prev;
-
- for (prev = &root_table; prev->link && prev->link != table; prev = prev->link)
- ;
-
- if (prev->link) {
- if (info->init_only) {
- table->init.pc = 0;
- table->init.range = 0;
- info->table = NULL;
- } else {
- prev->link = table->link;
- if (!prev->link)
- last_table = prev;
- }
- } else
- info->table = NULL;
-
- return 0;
-}
-
-/* Must be called with module_mutex held. */
-void unwind_remove_table(void *handle, int init_only)
-{
- struct unwind_table *table = handle;
- struct unlink_table_info info;
-
- if (!table || table == &root_table)
- return;
-
- if (init_only && table == last_table) {
- table->init.pc = 0;
- table->init.range = 0;
- return;
- }
-
- info.table = table;
- info.init_only = init_only;
- stop_machine_run(unlink_table, &info, NR_CPUS);
-
- if (info.table)
- kfree(table);
-}
-
-#endif /* CONFIG_MODULES */
-
-static uleb128_t get_uleb128(const u8 **pcur, const u8 *end)
-{
- const u8 *cur = *pcur;
- uleb128_t value;
- unsigned shift;
-
- for (shift = 0, value = 0; cur < end; shift += 7) {
- if (shift + 7 > 8 * sizeof(value)
- && (*cur & 0x7fU) >= (1U << (8 * sizeof(value) - shift))) {
- cur = end + 1;
- break;
- }
- value |= (uleb128_t)(*cur & 0x7f) << shift;
- if (!(*cur++ & 0x80))
- break;
- }
- *pcur = cur;
-
- return value;
-}
-
-static sleb128_t get_sleb128(const u8 **pcur, const u8 *end)
-{
- const u8 *cur = *pcur;
- sleb128_t value;
- unsigned shift;
-
- for (shift = 0, value = 0; cur < end; shift += 7) {
- if (shift + 7 > 8 * sizeof(value)
- && (*cur & 0x7fU) >= (1U << (8 * sizeof(value) - shift))) {
- cur = end + 1;
- break;
- }
- value |= (sleb128_t)(*cur & 0x7f) << shift;
- if (!(*cur & 0x80)) {
- value |= -(*cur++ & 0x40) << shift;
- break;
- }
- }
- *pcur = cur;
-
- return value;
-}
-
-static const u32 *cie_for_fde(const u32 *fde, const struct unwind_table *table)
-{
- const u32 *cie;
-
- if (!*fde || (*fde & (sizeof(*fde) - 1)))
- return &bad_cie;
- if (!fde[1])
- return &not_fde; /* this is a CIE */
- if ((fde[1] & (sizeof(*fde) - 1))
- || fde[1] > (unsigned long)(fde + 1) - (unsigned long)table->address)
- return NULL; /* this is not a valid FDE */
- cie = fde + 1 - fde[1] / sizeof(*fde);
- if (*cie <= sizeof(*cie) + 4
- || *cie >= fde[1] - sizeof(*fde)
- || (*cie & (sizeof(*cie) - 1))
- || cie[1])
- return NULL; /* this is not a (valid) CIE */
- return cie;
-}
-
-static unsigned long read_pointer(const u8 **pLoc,
- const void *end,
- signed ptrType,
- unsigned long text_base,
- unsigned long data_base)
-{
- unsigned long value = 0;
- union {
- const u8 *p8;
- const u16 *p16u;
- const s16 *p16s;
- const u32 *p32u;
- const s32 *p32s;
- const unsigned long *pul;
- } ptr;
-
- if (ptrType < 0 || ptrType == DW_EH_PE_omit) {
- dprintk(1, "Invalid pointer encoding %02X (%p,%p).", ptrType, *pLoc, end);
- return 0;
- }
- ptr.p8 = *pLoc;
- switch(ptrType & DW_EH_PE_FORM) {
- case DW_EH_PE_data2:
- if (end < (const void *)(ptr.p16u + 1)) {
- dprintk(1, "Data16 overrun (%p,%p).", ptr.p8, end);
- return 0;
- }
- if(ptrType & DW_EH_PE_signed)
- value = get_unaligned(ptr.p16s++);
- else
- value = get_unaligned(ptr.p16u++);
- break;
- case DW_EH_PE_data4:
-#ifdef CONFIG_64BIT
- if (end < (const void *)(ptr.p32u + 1)) {
- dprintk(1, "Data32 overrun (%p,%p).", ptr.p8, end);
- return 0;
- }
- if(ptrType & DW_EH_PE_signed)
- value = get_unaligned(ptr.p32s++);
- else
- value = get_unaligned(ptr.p32u++);
- break;
- case DW_EH_PE_data8:
- BUILD_BUG_ON(sizeof(u64) != sizeof(value));
-#else
- BUILD_BUG_ON(sizeof(u32) != sizeof(value));
-#endif
- case DW_EH_PE_native:
- if (end < (const void *)(ptr.pul + 1)) {
- dprintk(1, "DataUL overrun (%p,%p).", ptr.p8, end);
- return 0;
- }
- value = get_unaligned(ptr.pul++);
- break;
- case DW_EH_PE_leb128:
- BUILD_BUG_ON(sizeof(uleb128_t) > sizeof(value));
- value = ptrType & DW_EH_PE_signed
- ? get_sleb128(&ptr.p8, end)
- : get_uleb128(&ptr.p8, end);
- if ((const void *)ptr.p8 > end) {
- dprintk(1, "DataLEB overrun (%p,%p).", ptr.p8, end);
- return 0;
- }
- break;
- default:
- dprintk(2, "Cannot decode pointer type %02X (%p,%p).",
- ptrType, ptr.p8, end);
- return 0;
- }
- switch(ptrType & DW_EH_PE_ADJUST) {
- case DW_EH_PE_abs:
- break;
- case DW_EH_PE_pcrel:
- value += (unsigned long)*pLoc;
- break;
- case DW_EH_PE_textrel:
- if (likely(text_base)) {
- value += text_base;
- break;
- }
- dprintk(2, "Text-relative encoding %02X (%p,%p), but zero text base.",
- ptrType, *pLoc, end);
- return 0;
- case DW_EH_PE_datarel:
- if (likely(data_base)) {
- value += data_base;
- break;
- }
- dprintk(2, "Data-relative encoding %02X (%p,%p), but zero data base.",
- ptrType, *pLoc, end);
- return 0;
- default:
- dprintk(2, "Cannot adjust pointer type %02X (%p,%p).",
- ptrType, *pLoc, end);
- return 0;
- }
- if ((ptrType & DW_EH_PE_indirect)
- && probe_kernel_address((unsigned long *)value, value)) {
- dprintk(1, "Cannot read indirect value %lx (%p,%p).",
- value, *pLoc, end);
- return 0;
- }
- *pLoc = ptr.p8;
-
- return value;
-}
-
-static signed fde_pointer_type(const u32 *cie)
-{
- const u8 *ptr = (const u8 *)(cie + 2);
- unsigned version = *ptr;
-
- if (version != 1)
- return -1; /* unsupported */
- if (*++ptr) {
- const char *aug;
- const u8 *end = (const u8 *)(cie + 1) + *cie;
- uleb128_t len;
-
- /* check if augmentation size is first (and thus present) */
- if (*ptr != 'z')
- return -1;
- /* check if augmentation string is nul-terminated */
- if ((ptr = memchr(aug = (const void *)ptr, 0, end - ptr)) == NULL)
- return -1;
- ++ptr; /* skip terminator */
- get_uleb128(&ptr, end); /* skip code alignment */
- get_sleb128(&ptr, end); /* skip data alignment */
- /* skip return address column */
- version <= 1 ? (void)++ptr : (void)get_uleb128(&ptr, end);
- len = get_uleb128(&ptr, end); /* augmentation length */
- if (ptr + len < ptr || ptr + len > end)
- return -1;
- end = ptr + len;
- while (*++aug) {
- if (ptr >= end)
- return -1;
- switch(*aug) {
- case 'L':
- ++ptr;
- break;
- case 'P': {
- signed ptrType = *ptr++;
-
- if (!read_pointer(&ptr, end, ptrType, 0, 0)
- || ptr > end)
- return -1;
- }
- break;
- case 'R':
- return *ptr;
- default:
- return -1;
- }
- }
- }
- return DW_EH_PE_native|DW_EH_PE_abs;
-}
-
-static int advance_loc(unsigned long delta, struct unwind_state *state)
-{
- state->loc += delta * state->codeAlign;
-
- return delta > 0;
-}
-
-static void set_rule(uleb128_t reg,
- enum item_location where,
- uleb128_t value,
- struct unwind_state *state)
-{
- if (reg < ARRAY_SIZE(state->regs)) {
- state->regs[reg].where = where;
- state->regs[reg].value = value;
- }
-}
-
-static int processCFI(const u8 *start,
- const u8 *end,
- unsigned long targetLoc,
- signed ptrType,
- struct unwind_state *state)
-{
- union {
- const u8 *p8;
- const u16 *p16;
- const u32 *p32;
- } ptr;
- int result = 1;
-
- if (start != state->cieStart) {
- state->loc = state->org;
- result = processCFI(state->cieStart, state->cieEnd, 0, ptrType, state);
- if (targetLoc == 0 && state->label == NULL)
- return result;
- }
- for (ptr.p8 = start; result && ptr.p8 < end; ) {
- switch(*ptr.p8 >> 6) {
- uleb128_t value;
-
- case 0:
- switch(*ptr.p8++) {
- case DW_CFA_nop:
- break;
- case DW_CFA_set_loc:
- state->loc = read_pointer(&ptr.p8, end, ptrType, 0, 0);
- if (state->loc == 0)
- result = 0;
- break;
- case DW_CFA_advance_loc1:
- result = ptr.p8 < end && advance_loc(*ptr.p8++, state);
- break;
- case DW_CFA_advance_loc2:
- result = ptr.p8 <= end + 2
- && advance_loc(*ptr.p16++, state);
- break;
- case DW_CFA_advance_loc4:
- result = ptr.p8 <= end + 4
- && advance_loc(*ptr.p32++, state);
- break;
- case DW_CFA_offset_extended:
- value = get_uleb128(&ptr.p8, end);
- set_rule(value, Memory, get_uleb128(&ptr.p8, end), state);
- break;
- case DW_CFA_val_offset:
- value = get_uleb128(&ptr.p8, end);
- set_rule(value, Value, get_uleb128(&ptr.p8, end), state);
- break;
- case DW_CFA_offset_extended_sf:
- value = get_uleb128(&ptr.p8, end);
- set_rule(value, Memory, get_sleb128(&ptr.p8, end), state);
- break;
- case DW_CFA_val_offset_sf:
- value = get_uleb128(&ptr.p8, end);
- set_rule(value, Value, get_sleb128(&ptr.p8, end), state);
- break;
- case DW_CFA_restore_extended:
- case DW_CFA_undefined:
- case DW_CFA_same_value:
- set_rule(get_uleb128(&ptr.p8, end), Nowhere, 0, state);
- break;
- case DW_CFA_register:
- value = get_uleb128(&ptr.p8, end);
- set_rule(value,
- Register,
- get_uleb128(&ptr.p8, end), state);
- break;
- case DW_CFA_remember_state:
- if (ptr.p8 == state->label) {
- state->label = NULL;
- return 1;
- }
- if (state->stackDepth >= MAX_STACK_DEPTH) {
- dprintk(1, "State stack overflow (%p,%p).", ptr.p8, end);
- return 0;
- }
- state->stack[state->stackDepth++] = ptr.p8;
- break;
- case DW_CFA_restore_state:
- if (state->stackDepth) {
- const uleb128_t loc = state->loc;
- const u8 *label = state->label;
-
- state->label = state->stack[state->stackDepth - 1];
- memcpy(&state->cfa, &badCFA, sizeof(state->cfa));
- memset(state->regs, 0, sizeof(state->regs));
- state->stackDepth = 0;
- result = processCFI(start, end, 0, ptrType, state);
- state->loc = loc;
- state->label = label;
- } else {
- dprintk(1, "State stack underflow (%p,%p).", ptr.p8, end);
- return 0;
- }
- break;
- case DW_CFA_def_cfa:
- state->cfa.reg = get_uleb128(&ptr.p8, end);
- /*nobreak*/
- case DW_CFA_def_cfa_offset:
- state->cfa.offs = get_uleb128(&ptr.p8, end);
- break;
- case DW_CFA_def_cfa_sf:
- state->cfa.reg = get_uleb128(&ptr.p8, end);
- /*nobreak*/
- case DW_CFA_def_cfa_offset_sf:
- state->cfa.offs = get_sleb128(&ptr.p8, end)
- * state->dataAlign;
- break;
- case DW_CFA_def_cfa_register:
- state->cfa.reg = get_uleb128(&ptr.p8, end);
- break;
- /*todo case DW_CFA_def_cfa_expression: */
- /*todo case DW_CFA_expression: */
- /*todo case DW_CFA_val_expression: */
- case DW_CFA_GNU_args_size:
- get_uleb128(&ptr.p8, end);
- break;
- case DW_CFA_GNU_negative_offset_extended:
- value = get_uleb128(&ptr.p8, end);
- set_rule(value,
- Memory,
- (uleb128_t)0 - get_uleb128(&ptr.p8, end), state);
- break;
- case DW_CFA_GNU_window_save:
- default:
- dprintk(1, "Unrecognized CFI op %02X (%p,%p).", ptr.p8[-1], ptr.p8 - 1, end);
- result = 0;
- break;
- }
- break;
- case 1:
- result = advance_loc(*ptr.p8++ & 0x3f, state);
- break;
- case 2:
- value = *ptr.p8++ & 0x3f;
- set_rule(value, Memory, get_uleb128(&ptr.p8, end), state);
- break;
- case 3:
- set_rule(*ptr.p8++ & 0x3f, Nowhere, 0, state);
- break;
- }
- if (ptr.p8 > end) {
- dprintk(1, "Data overrun (%p,%p).", ptr.p8, end);
- result = 0;
- }
- if (result && targetLoc != 0 && targetLoc < state->loc)
- return 1;
- }
-
- if (result && ptr.p8 < end)
- dprintk(1, "Data underrun (%p,%p).", ptr.p8, end);
-
- return result
- && ptr.p8 == end
- && (targetLoc == 0
- || (/*todo While in theory this should apply, gcc in practice omits
- everything past the function prolog, and hence the location
- never reaches the end of the function.
- targetLoc < state->loc &&*/ state->label == NULL));
-}
-
-/* Unwind to previous to frame. Returns 0 if successful, negative
- * number in case of an error. */
-int unwind(struct unwind_frame_info *frame)
-{
-#define FRAME_REG(r, t) (((t *)frame)[reg_info[r].offs])
- const u32 *fde = NULL, *cie = NULL;
- const u8 *ptr = NULL, *end = NULL;
- unsigned long pc = UNW_PC(frame) - frame->call_frame, sp;
- unsigned long startLoc = 0, endLoc = 0, cfa;
- unsigned i;
- signed ptrType = -1;
- uleb128_t retAddrReg = 0;
- const struct unwind_table *table;
- struct unwind_state state;
-
- if (UNW_PC(frame) == 0)
- return -EINVAL;
- if ((table = find_table(pc)) != NULL
- && !(table->size & (sizeof(*fde) - 1))) {
- const u8 *hdr = table->header;
- unsigned long tableSize;
-
- smp_rmb();
- if (hdr && hdr[0] == 1) {
- switch(hdr[3] & DW_EH_PE_FORM) {
- case DW_EH_PE_native: tableSize = sizeof(unsigned long); break;
- case DW_EH_PE_data2: tableSize = 2; break;
- case DW_EH_PE_data4: tableSize = 4; break;
- case DW_EH_PE_data8: tableSize = 8; break;
- default: tableSize = 0; break;
- }
- ptr = hdr + 4;
- end = hdr + table->hdrsz;
- if (tableSize
- && read_pointer(&ptr, end, hdr[1], 0, 0)
- == (unsigned long)table->address
- && (i = read_pointer(&ptr, end, hdr[2], 0, 0)) > 0
- && i == (end - ptr) / (2 * tableSize)
- && !((end - ptr) % (2 * tableSize))) {
- do {
- const u8 *cur = ptr + (i / 2) * (2 * tableSize);
-
- startLoc = read_pointer(&cur,
- cur + tableSize,
- hdr[3], 0,
- (unsigned long)hdr);
- if (pc < startLoc)
- i /= 2;
- else {
- ptr = cur - tableSize;
- i = (i + 1) / 2;
- }
- } while (startLoc && i > 1);
- if (i == 1
- && (startLoc = read_pointer(&ptr,
- ptr + tableSize,
- hdr[3], 0,
- (unsigned long)hdr)) != 0
- && pc >= startLoc)
- fde = (void *)read_pointer(&ptr,
- ptr + tableSize,
- hdr[3], 0,
- (unsigned long)hdr);
- }
- }
- if(hdr && !fde)
- dprintk(3, "Binary lookup for %lx failed.", pc);
-
- if (fde != NULL) {
- cie = cie_for_fde(fde, table);
- ptr = (const u8 *)(fde + 2);
- if(cie != NULL
- && cie != &bad_cie
- && cie != &not_fde
- && (ptrType = fde_pointer_type(cie)) >= 0
- && read_pointer(&ptr,
- (const u8 *)(fde + 1) + *fde,
- ptrType, 0, 0) == startLoc) {
- if (!(ptrType & DW_EH_PE_indirect))
- ptrType &= DW_EH_PE_FORM|DW_EH_PE_signed;
- endLoc = startLoc
- + read_pointer(&ptr,
- (const u8 *)(fde + 1) + *fde,
- ptrType, 0, 0);
- if(pc >= endLoc)
- fde = NULL;
- } else
- fde = NULL;
- if(!fde)
- dprintk(1, "Binary lookup result for %lx discarded.", pc);
- }
- if (fde == NULL) {
- for (fde = table->address, tableSize = table->size;
- cie = NULL, tableSize > sizeof(*fde)
- && tableSize - sizeof(*fde) >= *fde;
- tableSize -= sizeof(*fde) + *fde,
- fde += 1 + *fde / sizeof(*fde)) {
- cie = cie_for_fde(fde, table);
- if (cie == &bad_cie) {
- cie = NULL;
- break;
- }
- if (cie == NULL
- || cie == &not_fde
- || (ptrType = fde_pointer_type(cie)) < 0)
- continue;
- ptr = (const u8 *)(fde + 2);
- startLoc = read_pointer(&ptr,
- (const u8 *)(fde + 1) + *fde,
- ptrType, 0, 0);
- if (!startLoc)
- continue;
- if (!(ptrType & DW_EH_PE_indirect))
- ptrType &= DW_EH_PE_FORM|DW_EH_PE_signed;
- endLoc = startLoc
- + read_pointer(&ptr,
- (const u8 *)(fde + 1) + *fde,
- ptrType, 0, 0);
- if (pc >= startLoc && pc < endLoc)
- break;
- }
- if(!fde)
- dprintk(3, "Linear lookup for %lx failed.", pc);
- }
- }
- if (cie != NULL) {
- memset(&state, 0, sizeof(state));
- state.cieEnd = ptr; /* keep here temporarily */
- ptr = (const u8 *)(cie + 2);
- end = (const u8 *)(cie + 1) + *cie;
- frame->call_frame = 1;
- if ((state.version = *ptr) != 1)
- cie = NULL; /* unsupported version */
- else if (*++ptr) {
- /* check if augmentation size is first (and thus present) */
- if (*ptr == 'z') {
- while (++ptr < end && *ptr) {
- switch(*ptr) {
- /* check for ignorable (or already handled)
- * nul-terminated augmentation string */
- case 'L':
- case 'P':
- case 'R':
- continue;
- case 'S':
- frame->call_frame = 0;
- continue;
- default:
- break;
- }
- break;
- }
- }
- if (ptr >= end || *ptr)
- cie = NULL;
- }
- if(!cie)
- dprintk(1, "CIE unusable (%p,%p).", ptr, end);
- ++ptr;
- }
- if (cie != NULL) {
- /* get code aligment factor */
- state.codeAlign = get_uleb128(&ptr, end);
- /* get data aligment factor */
- state.dataAlign = get_sleb128(&ptr, end);
- if (state.codeAlign == 0 || state.dataAlign == 0 || ptr >= end)
- cie = NULL;
- else if (UNW_PC(frame) % state.codeAlign
- || UNW_SP(frame) % sleb128abs(state.dataAlign)) {
- dprintk(1, "Input pointer(s) misaligned (%lx,%lx).",
- UNW_PC(frame), UNW_SP(frame));
- return -EPERM;
- } else {
- retAddrReg = state.version <= 1 ? *ptr++ : get_uleb128(&ptr, end);
- /* skip augmentation */
- if (((const char *)(cie + 2))[1] == 'z') {
- uleb128_t augSize = get_uleb128(&ptr, end);
-
- ptr += augSize;
- }
- if (ptr > end
- || retAddrReg >= ARRAY_SIZE(reg_info)
- || REG_INVALID(retAddrReg)
- || reg_info[retAddrReg].width != sizeof(unsigned long))
- cie = NULL;
- }
- if(!cie)
- dprintk(1, "CIE validation failed (%p,%p).", ptr, end);
- }
- if (cie != NULL) {
- state.cieStart = ptr;
- ptr = state.cieEnd;
- state.cieEnd = end;
- end = (const u8 *)(fde + 1) + *fde;
- /* skip augmentation */
- if (((const char *)(cie + 2))[1] == 'z') {
- uleb128_t augSize = get_uleb128(&ptr, end);
-
- if ((ptr += augSize) > end)
- fde = NULL;
- }
- if(!fde)
- dprintk(1, "FDE validation failed (%p,%p).", ptr, end);
- }
- if (cie == NULL || fde == NULL) {
-#ifdef CONFIG_FRAME_POINTER
- unsigned long top, bottom;
-
- if ((UNW_SP(frame) | UNW_FP(frame)) % sizeof(unsigned long))
- return -EPERM;
- top = STACK_TOP(frame->task);
- bottom = STACK_BOTTOM(frame->task);
-# if FRAME_RETADDR_OFFSET < 0
- if (UNW_SP(frame) < top
- && UNW_FP(frame) <= UNW_SP(frame)
- && bottom < UNW_FP(frame)
-# else
- if (UNW_SP(frame) > top
- && UNW_FP(frame) >= UNW_SP(frame)
- && bottom > UNW_FP(frame)
-# endif
- && !((UNW_SP(frame) | UNW_FP(frame))
- & (sizeof(unsigned long) - 1))) {
- unsigned long link;
-
- if (!probe_kernel_address(
- (unsigned long *)(UNW_FP(frame)
- + FRAME_LINK_OFFSET),
- link)
-# if FRAME_RETADDR_OFFSET < 0
- && link > bottom && link < UNW_FP(frame)
-# else
- && link > UNW_FP(frame) && link < bottom
-# endif
- && !(link & (sizeof(link) - 1))
- && !probe_kernel_address(
- (unsigned long *)(UNW_FP(frame)
- + FRAME_RETADDR_OFFSET), UNW_PC(frame))) {
- UNW_SP(frame) = UNW_FP(frame) + FRAME_RETADDR_OFFSET
-# if FRAME_RETADDR_OFFSET < 0
- -
-# else
- +
-# endif
- sizeof(UNW_PC(frame));
- UNW_FP(frame) = link;
- return 0;
- }
- }
-#endif
- return -ENXIO;
- }
- state.org = startLoc;
- memcpy(&state.cfa, &badCFA, sizeof(state.cfa));
- /* process instructions */
- if (!processCFI(ptr, end, pc, ptrType, &state)
- || state.loc > endLoc
- || state.regs[retAddrReg].where == Nowhere
- || state.cfa.reg >= ARRAY_SIZE(reg_info)
- || reg_info[state.cfa.reg].width != sizeof(unsigned long)
- || FRAME_REG(state.cfa.reg, unsigned long) % sizeof(unsigned long)
- || state.cfa.offs % sizeof(unsigned long)) {
- dprintk(1, "Unusable unwind info (%p,%p).", ptr, end);
- return -EIO;
- }
- /* update frame */
-#ifndef CONFIG_AS_CFI_SIGNAL_FRAME
- if(frame->call_frame
- && !UNW_DEFAULT_RA(state.regs[retAddrReg], state.dataAlign))
- frame->call_frame = 0;
-#endif
- cfa = FRAME_REG(state.cfa.reg, unsigned long) + state.cfa.offs;
- startLoc = min((unsigned long)UNW_SP(frame), cfa);
- endLoc = max((unsigned long)UNW_SP(frame), cfa);
- if (STACK_LIMIT(startLoc) != STACK_LIMIT(endLoc)) {
- startLoc = min(STACK_LIMIT(cfa), cfa);
- endLoc = max(STACK_LIMIT(cfa), cfa);
- }
-#ifndef CONFIG_64BIT
-# define CASES CASE(8); CASE(16); CASE(32)
-#else
-# define CASES CASE(8); CASE(16); CASE(32); CASE(64)
-#endif
- pc = UNW_PC(frame);
- sp = UNW_SP(frame);
- for (i = 0; i < ARRAY_SIZE(state.regs); ++i) {
- if (REG_INVALID(i)) {
- if (state.regs[i].where == Nowhere)
- continue;
- dprintk(1, "Cannot restore register %u (%d).",
- i, state.regs[i].where);
- return -EIO;
- }
- switch(state.regs[i].where) {
- default:
- break;
- case Register:
- if (state.regs[i].value >= ARRAY_SIZE(reg_info)
- || REG_INVALID(state.regs[i].value)
- || reg_info[i].width > reg_info[state.regs[i].value].width) {
- dprintk(1, "Cannot restore register %u from register %lu.",
- i, state.regs[i].value);
- return -EIO;
- }
- switch(reg_info[state.regs[i].value].width) {
-#define CASE(n) \
- case sizeof(u##n): \
- state.regs[i].value = FRAME_REG(state.regs[i].value, \
- const u##n); \
- break
- CASES;
-#undef CASE
- default:
- dprintk(1, "Unsupported register size %u (%lu).",
- reg_info[state.regs[i].value].width,
- state.regs[i].value);
- return -EIO;
- }
- break;
- }
- }
- for (i = 0; i < ARRAY_SIZE(state.regs); ++i) {
- if (REG_INVALID(i))
- continue;
- switch(state.regs[i].where) {
- case Nowhere:
- if (reg_info[i].width != sizeof(UNW_SP(frame))
- || &FRAME_REG(i, __typeof__(UNW_SP(frame)))
- != &UNW_SP(frame))
- continue;
- UNW_SP(frame) = cfa;
- break;
- case Register:
- switch(reg_info[i].width) {
-#define CASE(n) case sizeof(u##n): \
- FRAME_REG(i, u##n) = state.regs[i].value; \
- break
- CASES;
-#undef CASE
- default:
- dprintk(1, "Unsupported register size %u (%u).",
- reg_info[i].width, i);
- return -EIO;
- }
- break;
- case Value:
- if (reg_info[i].width != sizeof(unsigned long)) {
- dprintk(1, "Unsupported value size %u (%u).",
- reg_info[i].width, i);
- return -EIO;
- }
- FRAME_REG(i, unsigned long) = cfa + state.regs[i].value
- * state.dataAlign;
- break;
- case Memory: {
- unsigned long addr = cfa + state.regs[i].value
- * state.dataAlign;
-
- if ((state.regs[i].value * state.dataAlign)
- % sizeof(unsigned long)
- || addr < startLoc
- || addr + sizeof(unsigned long) < addr
- || addr + sizeof(unsigned long) > endLoc) {
- dprintk(1, "Bad memory location %lx (%lx).",
- addr, state.regs[i].value);
- return -EIO;
- }
- switch(reg_info[i].width) {
-#define CASE(n) case sizeof(u##n): \
- probe_kernel_address((u##n *)addr, FRAME_REG(i, u##n)); \
- break
- CASES;
-#undef CASE
- default:
- dprintk(1, "Unsupported memory size %u (%u).",
- reg_info[i].width, i);
- return -EIO;
- }
- }
- break;
- }
- }
-
- if (UNW_PC(frame) % state.codeAlign
- || UNW_SP(frame) % sleb128abs(state.dataAlign)) {
- dprintk(1, "Output pointer(s) misaligned (%lx,%lx).",
- UNW_PC(frame), UNW_SP(frame));
- return -EIO;
- }
- if (pc == UNW_PC(frame) && sp == UNW_SP(frame)) {
- dprintk(1, "No progress (%lx,%lx).", pc, sp);
- return -EIO;
- }
-
- return 0;
-#undef CASES
-#undef FRAME_REG
-}
-EXPORT_SYMBOL(unwind);
-
-int unwind_init_frame_info(struct unwind_frame_info *info,
- struct task_struct *tsk,
- /*const*/ struct pt_regs *regs)
-{
- info->task = tsk;
- info->call_frame = 0;
- arch_unw_init_frame_info(info, regs);
-
- return 0;
-}
-EXPORT_SYMBOL(unwind_init_frame_info);
-
-/*
- * Prepare to unwind a blocked task.
- */
-int unwind_init_blocked(struct unwind_frame_info *info,
- struct task_struct *tsk)
-{
- info->task = tsk;
- info->call_frame = 0;
- arch_unw_init_blocked(info);
-
- return 0;
-}
-EXPORT_SYMBOL(unwind_init_blocked);
-
-/*
- * Prepare to unwind the currently running thread.
- */
-int unwind_init_running(struct unwind_frame_info *info,
- asmlinkage int (*callback)(struct unwind_frame_info *,
- void *arg),
- void *arg)
-{
- info->task = current;
- info->call_frame = 0;
-
- return arch_unwind_init_running(info, callback, arg);
-}
-EXPORT_SYMBOL(unwind_init_running);
-
-/*
- * Unwind until the return pointer is in user-land (or until an error
- * occurs). Returns 0 if successful, negative number in case of
- * error.
- */
-int unwind_to_user(struct unwind_frame_info *info)
-{
- while (!arch_unw_user_mode(info)) {
- int err = unwind(info);
-
- if (err < 0)
- return err;
- }
-
- return 0;
-}
-EXPORT_SYMBOL(unwind_to_user);
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index db49886bfae1..a3da07c5af28 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -96,13 +96,13 @@ static inline void set_wq_data(struct work_struct *work, void *wq)
BUG_ON(!work_pending(work));
new = (unsigned long) wq | (1UL << WORK_STRUCT_PENDING);
- new |= work->management & WORK_STRUCT_FLAG_MASK;
- work->management = new;
+ new |= WORK_STRUCT_FLAG_MASK & *work_data_bits(work);
+ atomic_long_set(&work->data, new);
}
static inline void *get_wq_data(struct work_struct *work)
{
- return (void *) (work->management & WORK_STRUCT_WQ_DATA_MASK);
+ return (void *) (atomic_long_read(&work->data) & WORK_STRUCT_WQ_DATA_MASK);
}
static int __run_work(struct cpu_workqueue_struct *cwq, struct work_struct *work)
@@ -133,7 +133,7 @@ static int __run_work(struct cpu_workqueue_struct *cwq, struct work_struct *work
list_del_init(&work->entry);
spin_unlock_irqrestore(&cwq->lock, flags);
- if (!test_bit(WORK_STRUCT_NOAUTOREL, &work->management))
+ if (!test_bit(WORK_STRUCT_NOAUTOREL, work_data_bits(work)))
work_release(work);
f(work);
@@ -206,7 +206,7 @@ int fastcall queue_work(struct workqueue_struct *wq, struct work_struct *work)
{
int ret = 0, cpu = get_cpu();
- if (!test_and_set_bit(WORK_STRUCT_PENDING, &work->management)) {
+ if (!test_and_set_bit(WORK_STRUCT_PENDING, work_data_bits(work))) {
if (unlikely(is_single_threaded(wq)))
cpu = singlethread_cpu;
BUG_ON(!list_empty(&work->entry));
@@ -233,7 +233,7 @@ static void delayed_work_timer_fn(unsigned long __data)
/**
* queue_delayed_work - queue work on a workqueue after delay
* @wq: workqueue to use
- * @work: delayable work to queue
+ * @dwork: delayable work to queue
* @delay: number of jiffies to wait before queueing
*
* Returns 0 if @work was already on a queue, non-zero otherwise.
@@ -248,7 +248,7 @@ int fastcall queue_delayed_work(struct workqueue_struct *wq,
if (delay == 0)
return queue_work(wq, work);
- if (!test_and_set_bit(WORK_STRUCT_PENDING, &work->management)) {
+ if (!test_and_set_bit(WORK_STRUCT_PENDING, work_data_bits(work))) {
BUG_ON(timer_pending(timer));
BUG_ON(!list_empty(&work->entry));
@@ -268,7 +268,7 @@ EXPORT_SYMBOL_GPL(queue_delayed_work);
* queue_delayed_work_on - queue work on specific CPU after delay
* @cpu: CPU number to execute work on
* @wq: workqueue to use
- * @work: work to queue
+ * @dwork: work to queue
* @delay: number of jiffies to wait before queueing
*
* Returns 0 if @work was already on a queue, non-zero otherwise.
@@ -280,7 +280,7 @@ int queue_delayed_work_on(int cpu, struct workqueue_struct *wq,
struct timer_list *timer = &dwork->timer;
struct work_struct *work = &dwork->work;
- if (!test_and_set_bit(WORK_STRUCT_PENDING, &work->management)) {
+ if (!test_and_set_bit(WORK_STRUCT_PENDING, work_data_bits(work))) {
BUG_ON(timer_pending(timer));
BUG_ON(!list_empty(&work->entry));
@@ -321,7 +321,7 @@ static void run_workqueue(struct cpu_workqueue_struct *cwq)
spin_unlock_irqrestore(&cwq->lock, flags);
BUG_ON(get_wq_data(work) != cwq);
- if (!test_bit(WORK_STRUCT_NOAUTOREL, &work->management))
+ if (!test_bit(WORK_STRUCT_NOAUTOREL, work_data_bits(work)))
work_release(work);
f(work);
@@ -637,9 +637,11 @@ int schedule_on_each_cpu(work_func_t func)
mutex_lock(&workqueue_mutex);
for_each_online_cpu(cpu) {
- INIT_WORK(per_cpu_ptr(works, cpu), func);
- __queue_work(per_cpu_ptr(keventd_wq->cpu_wq, cpu),
- per_cpu_ptr(works, cpu));
+ struct work_struct *work = per_cpu_ptr(works, cpu);
+
+ INIT_WORK(work, func);
+ set_bit(WORK_STRUCT_PENDING, work_data_bits(work));
+ __queue_work(per_cpu_ptr(keventd_wq->cpu_wq, cpu), work);
}
mutex_unlock(&workqueue_mutex);
flush_workqueue(keventd_wq);
diff --git a/lib/Kconfig b/lib/Kconfig
index 47b172df3e31..9b03581cdecb 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -101,4 +101,9 @@ config TEXTSEARCH_FSM
config PLIST
boolean
+config IOMAP_COPY
+ boolean
+ depends on !UML
+ default y
+
endmenu
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 818e4589f718..5c2681875b9a 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -354,24 +354,6 @@ config FRAME_POINTER
some architectures or if you use external debuggers.
If you don't debug the kernel, you can say N.
-config UNWIND_INFO
- bool "Compile the kernel with frame unwind information"
- depends on !IA64 && !PARISC && !ARM
- depends on !MODULES || !(MIPS || PPC || SUPERH || V850)
- help
- If you say Y here the resulting kernel image will be slightly larger
- but not slower, and 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 unwind information or frame pointers.
-
-config STACK_UNWIND
- bool "Stack unwind support"
- depends on UNWIND_INFO
- depends on X86
- help
- This enables more precise stack traces, omitting all unrelated
- occurrences of pointers into kernel code from the dump.
-
config FORCED_INLINING
bool "Force gcc to inline functions marked 'inline'"
depends on DEBUG_KERNEL
diff --git a/lib/Makefile b/lib/Makefile
index 2d6106af53cd..77b4bad7d441 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -5,20 +5,21 @@
lib-y := ctype.o string.o vsprintf.o cmdline.o \
bust_spinlocks.o rbtree.o radix-tree.o dump_stack.o \
idr.o div64.o int_sqrt.o bitmap.o extable.o prio_tree.o \
- sha1.o irq_regs.o
+ sha1.o irq_regs.o reciprocal_div.o
lib-$(CONFIG_MMU) += ioremap.o
lib-$(CONFIG_SMP) += cpumask.o
lib-y += kobject.o kref.o kobject_uevent.o klist.o
-obj-y += sort.o parser.o halfmd4.o iomap_copy.o debug_locks.o random32.o
+obj-y += sort.o parser.o halfmd4.o debug_locks.o random32.o
ifeq ($(CONFIG_DEBUG_KOBJECT),y)
CFLAGS_kobject.o += -DDEBUG
CFLAGS_kobject_uevent.o += -DDEBUG
endif
+obj-$(CONFIG_IOMAP_COPY) += iomap_copy.o
obj-$(CONFIG_DEBUG_LOCKING_API_SELFTESTS) += locking-selftest.o
obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock_debug.o
lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o
diff --git a/lib/fault-inject.c b/lib/fault-inject.c
index d143c0faf248..b5a90fc056d3 100644
--- a/lib/fault-inject.c
+++ b/lib/fault-inject.c
@@ -55,37 +55,7 @@ static bool fail_task(struct fault_attr *attr, struct task_struct *task)
#define MAX_STACK_TRACE_DEPTH 32
-#ifdef CONFIG_STACK_UNWIND
-
-static asmlinkage int fail_stacktrace_callback(struct unwind_frame_info *info,
- void *arg)
-{
- int depth;
- struct fault_attr *attr = arg;
- bool found = (attr->require_start == 0 && attr->require_end == ULONG_MAX);
-
- for (depth = 0; depth < attr->stacktrace_depth
- && unwind(info) == 0 && UNW_PC(info); depth++) {
- if (arch_unw_user_mode(info))
- break;
- if (attr->reject_start <= UNW_PC(info) &&
- UNW_PC(info) < attr->reject_end)
- return false;
- if (attr->require_start <= UNW_PC(info) &&
- UNW_PC(info) < attr->require_end)
- found = true;
- }
- return found;
-}
-
-static bool fail_stacktrace(struct fault_attr *attr)
-{
- struct unwind_frame_info info;
-
- return unwind_init_running(&info, fail_stacktrace_callback, attr);
-}
-
-#elif defined(CONFIG_STACKTRACE)
+#if defined(CONFIG_STACKTRACE)
static bool fail_stacktrace(struct fault_attr *attr)
{
diff --git a/lib/ioremap.c b/lib/ioremap.c
index 99fa277f9f7b..a9e4415b02dc 100644
--- a/lib/ioremap.c
+++ b/lib/ioremap.c
@@ -5,7 +5,6 @@
*
* (C) Copyright 1995 1996 Linus Torvalds
*/
-#include <linux/io.h>
#include <linux/vmalloc.h>
#include <linux/mm.h>
diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c
index a1922765ff31..84272ed77f03 100644
--- a/lib/kobject_uevent.c
+++ b/lib/kobject_uevent.c
@@ -63,8 +63,11 @@ static char *action_to_string(enum kobject_action action)
* @action: action that is happening (usually KOBJ_MOVE)
* @kobj: struct kobject that the action is happening to
* @envp_ext: pointer to environmental data
+ *
+ * Returns 0 if kobject_uevent() is completed with success or the
+ * corresponding error when it fails.
*/
-void kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
+int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
char *envp_ext[])
{
char **envp;
@@ -79,14 +82,16 @@ void kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
u64 seq;
char *seq_buff;
int i = 0;
- int retval;
+ int retval = 0;
int j;
pr_debug("%s\n", __FUNCTION__);
action_string = action_to_string(action);
- if (!action_string)
- return;
+ if (!action_string) {
+ pr_debug("kobject attempted to send uevent without action_string!\n");
+ return -EINVAL;
+ }
/* search the kset we belong to */
top_kobj = kobj;
@@ -95,31 +100,39 @@ void kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
top_kobj = top_kobj->parent;
} while (!top_kobj->kset && top_kobj->parent);
}
- if (!top_kobj->kset)
- return;
+ if (!top_kobj->kset) {
+ pr_debug("kobject attempted to send uevent without kset!\n");
+ return -EINVAL;
+ }
kset = top_kobj->kset;
uevent_ops = kset->uevent_ops;
/* skip the event, if the filter returns zero. */
if (uevent_ops && uevent_ops->filter)
- if (!uevent_ops->filter(kset, kobj))
- return;
+ if (!uevent_ops->filter(kset, kobj)) {
+ pr_debug("kobject filter function caused the event to drop!\n");
+ return 0;
+ }
/* environment index */
envp = kzalloc(NUM_ENVP * sizeof (char *), GFP_KERNEL);
if (!envp)
- return;
+ return -ENOMEM;
/* environment values */
buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL);
- if (!buffer)
+ if (!buffer) {
+ retval = -ENOMEM;
goto exit;
+ }
/* complete object path */
devpath = kobject_get_path(kobj, GFP_KERNEL);
- if (!devpath)
+ if (!devpath) {
+ retval = -ENOENT;
goto exit;
+ }
/* originating subsystem */
if (uevent_ops && uevent_ops->name)
@@ -204,7 +217,7 @@ exit:
kfree(devpath);
kfree(buffer);
kfree(envp);
- return;
+ return retval;
}
EXPORT_SYMBOL_GPL(kobject_uevent_env);
@@ -214,10 +227,13 @@ EXPORT_SYMBOL_GPL(kobject_uevent_env);
*
* @action: action that is happening (usually KOBJ_ADD and KOBJ_REMOVE)
* @kobj: struct kobject that the action is happening to
+ *
+ * Returns 0 if kobject_uevent() is completed with success or the
+ * corresponding error when it fails.
*/
-void kobject_uevent(struct kobject *kobj, enum kobject_action action)
+int kobject_uevent(struct kobject *kobj, enum kobject_action action)
{
- kobject_uevent_env(kobj, action, NULL);
+ return kobject_uevent_env(kobj, action, NULL);
}
EXPORT_SYMBOL_GPL(kobject_uevent);
diff --git a/lib/kref.c b/lib/kref.c
index 4a467faf1367..0d07cc31c818 100644
--- a/lib/kref.c
+++ b/lib/kref.c
@@ -52,12 +52,7 @@ int kref_put(struct kref *kref, void (*release)(struct kref *kref))
WARN_ON(release == NULL);
WARN_ON(release == (void (*)(struct kref *))kfree);
- /*
- * if current count is one, we are the last user and can release object
- * right now, avoiding an atomic operation on 'refcount'
- */
- if ((atomic_read(&kref->refcount) == 1) ||
- (atomic_dec_and_test(&kref->refcount))) {
+ if (atomic_dec_and_test(&kref->refcount)) {
release(kref);
return 1;
}
diff --git a/lib/reciprocal_div.c b/lib/reciprocal_div.c
new file mode 100644
index 000000000000..6a3bd48fa2a0
--- /dev/null
+++ b/lib/reciprocal_div.c
@@ -0,0 +1,9 @@
+#include <asm/div64.h>
+#include <linux/reciprocal_div.h>
+
+u32 reciprocal_value(u32 k)
+{
+ u64 val = (1LL << 32) + (k - 1);
+ do_div(val, k);
+ return (u32)val;
+}
diff --git a/mm/filemap_xip.c b/mm/filemap_xip.c
index 8d667617f558..45b3553865cf 100644
--- a/mm/filemap_xip.c
+++ b/mm/filemap_xip.c
@@ -189,7 +189,7 @@ __xip_unmap (struct address_space * mapping,
/* Nuke the page table entry. */
flush_cache_page(vma, address, pte_pfn(*pte));
pteval = ptep_clear_flush(vma, address, pte);
- page_remove_rmap(page);
+ page_remove_rmap(page, vma);
dec_mm_counter(mm, file_rss);
BUG_ON(pte_dirty(pteval));
pte_unmap_unlock(pte, ptl);
diff --git a/mm/fremap.c b/mm/fremap.c
index b77a002c3352..4e3f53dd5fd4 100644
--- a/mm/fremap.c
+++ b/mm/fremap.c
@@ -33,7 +33,7 @@ static int zap_pte(struct mm_struct *mm, struct vm_area_struct *vma,
if (page) {
if (pte_dirty(pte))
set_page_dirty(page);
- page_remove_rmap(page);
+ page_remove_rmap(page, vma);
page_cache_release(page);
}
} else {
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 0ccc7f230252..cb362f761f17 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -44,14 +44,14 @@ static void clear_huge_page(struct page *page, unsigned long addr)
}
static void copy_huge_page(struct page *dst, struct page *src,
- unsigned long addr)
+ unsigned long addr, struct vm_area_struct *vma)
{
int i;
might_sleep();
for (i = 0; i < HPAGE_SIZE/PAGE_SIZE; i++) {
cond_resched();
- copy_user_highpage(dst + i, src + i, addr + i*PAGE_SIZE);
+ copy_user_highpage(dst + i, src + i, addr + i*PAGE_SIZE, vma);
}
}
@@ -73,7 +73,7 @@ static struct page *dequeue_huge_page(struct vm_area_struct *vma,
for (z = zonelist->zones; *z; z++) {
nid = zone_to_nid(*z);
- if (cpuset_zone_allowed(*z, GFP_HIGHUSER) &&
+ if (cpuset_zone_allowed_softwall(*z, GFP_HIGHUSER) &&
!list_empty(&hugepage_freelists[nid]))
break;
}
@@ -442,7 +442,7 @@ static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma,
}
spin_unlock(&mm->page_table_lock);
- copy_huge_page(new_page, old_page, address);
+ copy_huge_page(new_page, old_page, address, vma);
spin_lock(&mm->page_table_lock);
ptep = huge_pte_offset(mm, address & HPAGE_MASK);
diff --git a/mm/memory.c b/mm/memory.c
index bf6100236e62..563792f4f687 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -681,7 +681,7 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb,
mark_page_accessed(page);
file_rss--;
}
- page_remove_rmap(page);
+ page_remove_rmap(page, vma);
tlb_remove_page(tlb, page);
continue;
}
@@ -1441,7 +1441,7 @@ static inline pte_t maybe_mkwrite(pte_t pte, struct vm_area_struct *vma)
return pte;
}
-static inline void cow_user_page(struct page *dst, struct page *src, unsigned long va)
+static inline void cow_user_page(struct page *dst, struct page *src, unsigned long va, struct vm_area_struct *vma)
{
/*
* If the source page was a PFN mapping, we don't have
@@ -1464,9 +1464,9 @@ static inline void cow_user_page(struct page *dst, struct page *src, unsigned lo
kunmap_atomic(kaddr, KM_USER0);
flush_dcache_page(dst);
return;
-
+
}
- copy_user_highpage(dst, src, va);
+ copy_user_highpage(dst, src, va, vma);
}
/*
@@ -1577,7 +1577,7 @@ gotten:
new_page = alloc_page_vma(GFP_HIGHUSER, vma, address);
if (!new_page)
goto oom;
- cow_user_page(new_page, old_page, address);
+ cow_user_page(new_page, old_page, address, vma);
}
/*
@@ -1586,7 +1586,7 @@ gotten:
page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
if (likely(pte_same(*page_table, orig_pte))) {
if (old_page) {
- page_remove_rmap(old_page);
+ page_remove_rmap(old_page, vma);
if (!PageAnon(old_page)) {
dec_mm_counter(mm, file_rss);
inc_mm_counter(mm, anon_rss);
@@ -2200,7 +2200,7 @@ retry:
page = alloc_page_vma(GFP_HIGHUSER, vma, address);
if (!page)
goto oom;
- copy_user_highpage(page, new_page, address);
+ copy_user_highpage(page, new_page, address, vma);
page_cache_release(new_page);
new_page = page;
anon = 1;
diff --git a/mm/mincore.c b/mm/mincore.c
index 72890780c1c9..8aca6f7167bb 100644
--- a/mm/mincore.c
+++ b/mm/mincore.c
@@ -1,7 +1,7 @@
/*
* linux/mm/mincore.c
*
- * Copyright (C) 1994-1999 Linus Torvalds
+ * Copyright (C) 1994-2006 Linus Torvalds
*/
/*
@@ -38,46 +38,51 @@ static unsigned char mincore_page(struct vm_area_struct * vma,
return present;
}
-static long mincore_vma(struct vm_area_struct * vma,
- unsigned long start, unsigned long end, unsigned char __user * vec)
+/*
+ * Do a chunk of "sys_mincore()". We've already checked
+ * all the arguments, we hold the mmap semaphore: we should
+ * just return the amount of info we're asked for.
+ */
+static long do_mincore(unsigned long addr, unsigned char *vec, unsigned long pages)
{
- long error, i, remaining;
- unsigned char * tmp;
-
- error = -ENOMEM;
- if (!vma->vm_file)
- return error;
-
- start = ((start - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
- if (end > vma->vm_end)
- end = vma->vm_end;
- end = ((end - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
+ unsigned long i, nr, pgoff;
+ struct vm_area_struct *vma = find_vma(current->mm, addr);
- error = -EAGAIN;
- tmp = (unsigned char *) __get_free_page(GFP_KERNEL);
- if (!tmp)
- return error;
+ /*
+ * find_vma() didn't find anything above us, or we're
+ * in an unmapped hole in the address space: ENOMEM.
+ */
+ if (!vma || addr < vma->vm_start)
+ return -ENOMEM;
- /* (end - start) is # of pages, and also # of bytes in "vec */
- remaining = (end - start),
+ /*
+ * Ok, got it. But check whether it's a segment we support
+ * mincore() on. Right now, we don't do any anonymous mappings.
+ *
+ * FIXME: This is just stupid. And returning ENOMEM is
+ * stupid too. We should just look at the page tables. But
+ * this is what we've traditionally done, so we'll just
+ * continue doing it.
+ */
+ if (!vma->vm_file)
+ return -ENOMEM;
- error = 0;
- for (i = 0; remaining > 0; remaining -= PAGE_SIZE, i++) {
- int j = 0;
- long thispiece = (remaining < PAGE_SIZE) ?
- remaining : PAGE_SIZE;
+ /*
+ * Calculate how many pages there are left in the vma, and
+ * what the pgoff is for our address.
+ */
+ nr = (vma->vm_end - addr) >> PAGE_SHIFT;
+ if (nr > pages)
+ nr = pages;
- while (j < thispiece)
- tmp[j++] = mincore_page(vma, start++);
+ pgoff = (addr - vma->vm_start) >> PAGE_SHIFT;
+ pgoff += vma->vm_pgoff;
- if (copy_to_user(vec + PAGE_SIZE * i, tmp, thispiece)) {
- error = -EFAULT;
- break;
- }
- }
+ /* And then we just fill the sucker in.. */
+ for (i = 0 ; i < nr; i++, pgoff++)
+ vec[i] = mincore_page(vma, pgoff);
- free_page((unsigned long) tmp);
- return error;
+ return nr;
}
/*
@@ -107,82 +112,50 @@ static long mincore_vma(struct vm_area_struct * vma,
asmlinkage long sys_mincore(unsigned long start, size_t len,
unsigned char __user * vec)
{
- int index = 0;
- unsigned long end, limit;
- struct vm_area_struct * vma;
- size_t max;
- int unmapped_error = 0;
- long error;
-
- /* check the arguments */
- if (start & ~PAGE_CACHE_MASK)
- goto einval;
-
- limit = TASK_SIZE;
- if (start >= limit)
- goto enomem;
-
- if (!len)
- return 0;
-
- max = limit - start;
- len = PAGE_CACHE_ALIGN(len);
- if (len > max || !len)
- goto enomem;
+ long retval;
+ unsigned long pages;
+ unsigned char *tmp;
- end = start + len;
+ /* Check the start address: needs to be page-aligned.. */
+ if (start & ~PAGE_CACHE_MASK)
+ return -EINVAL;
- /* check the output buffer whilst holding the lock */
- error = -EFAULT;
- down_read(&current->mm->mmap_sem);
+ /* ..and we need to be passed a valid user-space range */
+ if (!access_ok(VERIFY_READ, (void __user *) start, len))
+ return -ENOMEM;
- if (!access_ok(VERIFY_WRITE, vec, len >> PAGE_SHIFT))
- goto out;
+ /* This also avoids any overflows on PAGE_CACHE_ALIGN */
+ pages = len >> PAGE_SHIFT;
+ pages += (len & ~PAGE_MASK) != 0;
- /*
- * If the interval [start,end) covers some unmapped address
- * ranges, just ignore them, but return -ENOMEM at the end.
- */
- error = 0;
-
- vma = find_vma(current->mm, start);
- while (vma) {
- /* Here start < vma->vm_end. */
- if (start < vma->vm_start) {
- unmapped_error = -ENOMEM;
- start = vma->vm_start;
- }
+ if (!access_ok(VERIFY_WRITE, vec, pages))
+ return -EFAULT;
- /* Here vma->vm_start <= start < vma->vm_end. */
- if (end <= vma->vm_end) {
- if (start < end) {
- error = mincore_vma(vma, start, end,
- &vec[index]);
- if (error)
- goto out;
- }
- error = unmapped_error;
- goto out;
+ tmp = (void *) __get_free_page(GFP_USER);
+ if (!tmp)
+ return -EAGAIN;
+
+ retval = 0;
+ while (pages) {
+ /*
+ * Do at most PAGE_SIZE entries per iteration, due to
+ * the temporary buffer size.
+ */
+ down_read(&current->mm->mmap_sem);
+ retval = do_mincore(start, tmp, min(pages, PAGE_SIZE));
+ up_read(&current->mm->mmap_sem);
+
+ if (retval <= 0)
+ break;
+ if (copy_to_user(vec, tmp, retval)) {
+ retval = -EFAULT;
+ break;
}
-
- /* Here vma->vm_start <= start < vma->vm_end < end. */
- error = mincore_vma(vma, start, vma->vm_end, &vec[index]);
- if (error)
- goto out;
- index += (vma->vm_end - start) >> PAGE_CACHE_SHIFT;
- start = vma->vm_end;
- vma = vma->vm_next;
+ pages -= retval;
+ vec += retval;
+ start += retval << PAGE_SHIFT;
+ retval = 0;
}
-
- /* we found a hole in the area queried if we arrive here */
- error = -ENOMEM;
-
-out:
- up_read(&current->mm->mmap_sem);
- return error;
-
-einval:
- return -EINVAL;
-enomem:
- return -ENOMEM;
+ free_page((unsigned long) tmp);
+ return retval;
}
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index 223d9ccb7d64..6969cfb33901 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -174,10 +174,15 @@ static inline int constrained_alloc(struct zonelist *zonelist, gfp_t gfp_mask)
{
#ifdef CONFIG_NUMA
struct zone **z;
- nodemask_t nodes = node_online_map;
+ nodemask_t nodes;
+ int node;
+ /* node has memory ? */
+ for_each_online_node(node)
+ if (NODE_DATA(node)->node_present_pages)
+ node_set(node, nodes);
for (z = zonelist->zones; *z; z++)
- if (cpuset_zone_allowed(*z, gfp_mask))
+ if (cpuset_zone_allowed_softwall(*z, gfp_mask))
node_clear(zone_to_nid(*z), nodes);
else
return CONSTRAINT_CPUSET;
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 237107c1b084..1d2fc89ca56d 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -845,38 +845,6 @@ int set_page_dirty_lock(struct page *page)
EXPORT_SYMBOL(set_page_dirty_lock);
/*
- * Clear a page's dirty flag, while caring for dirty memory accounting.
- * Returns true if the page was previously dirty.
- */
-int test_clear_page_dirty(struct page *page)
-{
- struct address_space *mapping = page_mapping(page);
- unsigned long flags;
-
- if (!mapping)
- return TestClearPageDirty(page);
-
- write_lock_irqsave(&mapping->tree_lock, flags);
- if (TestClearPageDirty(page)) {
- radix_tree_tag_clear(&mapping->page_tree,
- page_index(page), PAGECACHE_TAG_DIRTY);
- write_unlock_irqrestore(&mapping->tree_lock, flags);
- /*
- * We can continue to use `mapping' here because the
- * page is locked, which pins the address_space
- */
- if (mapping_cap_account_dirty(mapping)) {
- page_mkclean(page);
- dec_zone_page_state(page, NR_FILE_DIRTY);
- }
- return 1;
- }
- write_unlock_irqrestore(&mapping->tree_lock, flags);
- return 0;
-}
-EXPORT_SYMBOL(test_clear_page_dirty);
-
-/*
* Clear a page's dirty flag, while caring for dirty memory accounting.
* Returns true if the page was previously dirty.
*
@@ -894,17 +862,46 @@ int clear_page_dirty_for_io(struct page *page)
{
struct address_space *mapping = page_mapping(page);
- if (!mapping)
- return TestClearPageDirty(page);
-
- if (TestClearPageDirty(page)) {
- if (mapping_cap_account_dirty(mapping)) {
- page_mkclean(page);
+ if (mapping && mapping_cap_account_dirty(mapping)) {
+ /*
+ * Yes, Virginia, this is indeed insane.
+ *
+ * We use this sequence to make sure that
+ * (a) we account for dirty stats properly
+ * (b) we tell the low-level filesystem to
+ * mark the whole page dirty if it was
+ * dirty in a pagetable. Only to then
+ * (c) clean the page again and return 1 to
+ * cause the writeback.
+ *
+ * This way we avoid all nasty races with the
+ * dirty bit in multiple places and clearing
+ * them concurrently from different threads.
+ *
+ * Note! Normally the "set_page_dirty(page)"
+ * has no effect on the actual dirty bit - since
+ * that will already usually be set. But we
+ * need the side effects, and it can help us
+ * avoid races.
+ *
+ * We basically use the page "master dirty bit"
+ * as a serialization point for all the different
+ * threads doing their things.
+ *
+ * FIXME! We still have a race here: if somebody
+ * adds the page back to the page tables in
+ * between the "page_mkclean()" and the "TestClearPageDirty()",
+ * we might have it mapped without the dirty bit set.
+ */
+ if (page_mkclean(page))
+ set_page_dirty(page);
+ if (TestClearPageDirty(page)) {
dec_zone_page_state(page, NR_FILE_DIRTY);
+ return 1;
}
- return 1;
+ return 0;
}
- return 0;
+ return TestClearPageDirty(page);
}
EXPORT_SYMBOL(clear_page_dirty_for_io);
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index e6b17b2989e0..8c1a116875bc 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1162,7 +1162,7 @@ zonelist_scan:
zone->zone_pgdat != zonelist->zones[0]->zone_pgdat))
break;
if ((alloc_flags & ALLOC_CPUSET) &&
- !cpuset_zone_allowed(zone, gfp_mask))
+ !cpuset_zone_allowed_softwall(zone, gfp_mask))
goto try_next_zone;
if (!(alloc_flags & ALLOC_NO_WATERMARKS)) {
diff --git a/mm/rmap.c b/mm/rmap.c
index d8a842a586db..669acb22b572 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -47,6 +47,7 @@
#include <linux/rmap.h>
#include <linux/rcupdate.h>
#include <linux/module.h>
+#include <linux/kallsyms.h>
#include <asm/tlbflush.h>
@@ -432,7 +433,7 @@ static int page_mkclean_one(struct page *page, struct vm_area_struct *vma)
{
struct mm_struct *mm = vma->vm_mm;
unsigned long address;
- pte_t *pte, entry;
+ pte_t *pte;
spinlock_t *ptl;
int ret = 0;
@@ -444,17 +445,18 @@ static int page_mkclean_one(struct page *page, struct vm_area_struct *vma)
if (!pte)
goto out;
- if (!pte_dirty(*pte) && !pte_write(*pte))
- goto unlock;
+ if (pte_dirty(*pte) || pte_write(*pte)) {
+ pte_t entry;
- entry = ptep_get_and_clear(mm, address, pte);
- entry = pte_mkclean(entry);
- entry = pte_wrprotect(entry);
- ptep_establish(vma, address, pte, entry);
- lazy_mmu_prot_update(entry);
- ret = 1;
+ flush_cache_page(vma, address, pte_pfn(*pte));
+ entry = ptep_clear_flush(vma, address, pte);
+ entry = pte_wrprotect(entry);
+ entry = pte_mkclean(entry);
+ set_pte_at(mm, address, pte, entry);
+ lazy_mmu_prot_update(entry);
+ ret = 1;
+ }
-unlock:
pte_unmap_unlock(pte, ptl);
out:
return ret;
@@ -489,6 +491,8 @@ int page_mkclean(struct page *page)
if (mapping)
ret = page_mkclean_file(mapping, page);
}
+ if (page_test_and_clear_dirty(page))
+ ret = 1;
return ret;
}
@@ -567,14 +571,20 @@ void page_add_file_rmap(struct page *page)
*
* The caller needs to hold the pte lock.
*/
-void page_remove_rmap(struct page *page)
+void page_remove_rmap(struct page *page, struct vm_area_struct *vma)
{
if (atomic_add_negative(-1, &page->_mapcount)) {
if (unlikely(page_mapcount(page) < 0)) {
printk (KERN_EMERG "Eeek! page_mapcount(page) went negative! (%d)\n", page_mapcount(page));
+ printk (KERN_EMERG " page pfn = %lx\n", page_to_pfn(page));
printk (KERN_EMERG " page->flags = %lx\n", page->flags);
printk (KERN_EMERG " page->count = %x\n", page_count(page));
printk (KERN_EMERG " page->mapping = %p\n", page->mapping);
+ print_symbol (KERN_EMERG " vma->vm_ops = %s\n", (unsigned long)vma->vm_ops);
+ if (vma->vm_ops)
+ print_symbol (KERN_EMERG " vma->vm_ops->nopage = %s\n", (unsigned long)vma->vm_ops->nopage);
+ if (vma->vm_file && vma->vm_file->f_op)
+ print_symbol (KERN_EMERG " vma->vm_file->f_op->mmap = %s\n", (unsigned long)vma->vm_file->f_op->mmap);
BUG();
}
@@ -679,7 +689,7 @@ static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
dec_mm_counter(mm, file_rss);
- page_remove_rmap(page);
+ page_remove_rmap(page, vma);
page_cache_release(page);
out_unmap:
@@ -769,7 +779,7 @@ static void try_to_unmap_cluster(unsigned long cursor,
if (pte_dirty(pteval))
set_page_dirty(page);
- page_remove_rmap(page);
+ page_remove_rmap(page, vma);
page_cache_release(page);
dec_mm_counter(mm, file_rss);
(*mapcount)--;
diff --git a/mm/shmem.c b/mm/shmem.c
index 4bb28d218eb5..70da7a0981bf 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -515,7 +515,12 @@ static void shmem_truncate_range(struct inode *inode, loff_t start, loff_t end)
size = SHMEM_NR_DIRECT;
nr_swaps_freed = shmem_free_swp(ptr+idx, ptr+size);
}
- if (!topdir)
+
+ /*
+ * If there are no indirect blocks or we are punching a hole
+ * below indirect blocks, nothing to be done.
+ */
+ if (!topdir || (punch_hole && (limit <= SHMEM_NR_DIRECT)))
goto done2;
BUG_ON(limit <= SHMEM_NR_DIRECT);
diff --git a/mm/slab.c b/mm/slab.c
index 2c655532f5ef..0d4e57431de4 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -109,6 +109,7 @@
#include <linux/mutex.h>
#include <linux/fault-inject.h>
#include <linux/rtmutex.h>
+#include <linux/reciprocal_div.h>
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
@@ -386,6 +387,7 @@ struct kmem_cache {
unsigned int shared;
unsigned int buffer_size;
+ u32 reciprocal_buffer_size;
/* 3) touched by every alloc & free from the backend */
struct kmem_list3 *nodelists[MAX_NUMNODES];
@@ -627,10 +629,17 @@ static inline void *index_to_obj(struct kmem_cache *cache, struct slab *slab,
return slab->s_mem + cache->buffer_size * idx;
}
-static inline unsigned int obj_to_index(struct kmem_cache *cache,
- struct slab *slab, void *obj)
+/*
+ * We want to avoid an expensive divide : (offset / cache->buffer_size)
+ * Using the fact that buffer_size is a constant for a particular cache,
+ * we can replace (offset / cache->buffer_size) by
+ * reciprocal_divide(offset, cache->reciprocal_buffer_size)
+ */
+static inline unsigned int obj_to_index(const struct kmem_cache *cache,
+ const struct slab *slab, void *obj)
{
- return (unsigned)(obj - slab->s_mem) / cache->buffer_size;
+ u32 offset = (obj - slab->s_mem);
+ return reciprocal_divide(offset, cache->reciprocal_buffer_size);
}
/*
@@ -1427,6 +1436,8 @@ void __init kmem_cache_init(void)
cache_cache.buffer_size = ALIGN(cache_cache.buffer_size,
cache_line_size());
+ cache_cache.reciprocal_buffer_size =
+ reciprocal_value(cache_cache.buffer_size);
for (order = 0; order < MAX_ORDER; order++) {
cache_estimate(order, cache_cache.buffer_size,
@@ -2313,6 +2324,7 @@ kmem_cache_create (const char *name, size_t size, size_t align,
if (flags & SLAB_CACHE_DMA)
cachep->gfpflags |= GFP_DMA;
cachep->buffer_size = size;
+ cachep->reciprocal_buffer_size = reciprocal_value(size);
if (flags & CFLGS_OFF_SLAB) {
cachep->slabp_cache = kmem_find_general_cachep(slab_size, 0u);
@@ -3252,6 +3264,7 @@ void *fallback_alloc(struct kmem_cache *cache, gfp_t flags)
struct zone **z;
void *obj = NULL;
int nid;
+ gfp_t local_flags = (flags & GFP_LEVEL_MASK);
retry:
/*
@@ -3261,7 +3274,7 @@ retry:
for (z = zonelist->zones; *z && !obj; z++) {
nid = zone_to_nid(*z);
- if (cpuset_zone_allowed(*z, flags | __GFP_HARDWALL) &&
+ if (cpuset_zone_allowed_hardwall(*z, flags) &&
cache->nodelists[nid] &&
cache->nodelists[nid]->free_objects)
obj = ____cache_alloc_node(cache,
@@ -3275,7 +3288,12 @@ retry:
* We may trigger various forms of reclaim on the allowed
* set and go into memory reserves if necessary.
*/
+ if (local_flags & __GFP_WAIT)
+ local_irq_enable();
+ kmem_flagcheck(cache, flags);
obj = kmem_getpages(cache, flags, -1);
+ if (local_flags & __GFP_WAIT)
+ local_irq_disable();
if (obj) {
/*
* Insert into the appropriate per node queues
@@ -3535,7 +3553,7 @@ EXPORT_SYMBOL(kmem_cache_zalloc);
*
* Currently only used for dentry validation.
*/
-int fastcall kmem_ptr_validate(struct kmem_cache *cachep, void *ptr)
+int kmem_ptr_validate(struct kmem_cache *cachep, const void *ptr)
{
unsigned long addr = (unsigned long)ptr;
unsigned long min_addr = PAGE_OFFSET;
@@ -3569,6 +3587,7 @@ out:
* @cachep: The cache to allocate from.
* @flags: See kmalloc().
* @nodeid: node number of the target node.
+ * @caller: return address of caller, used for debug information
*
* Identical to kmem_cache_alloc but it will allocate memory on the given
* node, which can improve the performance for cpu bound structures.
diff --git a/mm/slob.c b/mm/slob.c
index 542394184a58..5adc29cb58dd 100644
--- a/mm/slob.c
+++ b/mm/slob.c
@@ -60,6 +60,8 @@ static DEFINE_SPINLOCK(slob_lock);
static DEFINE_SPINLOCK(block_lock);
static void slob_free(void *b, int size);
+static void slob_timer_cbk(void);
+
static void *slob_alloc(size_t size, gfp_t gfp, int align)
{
@@ -157,7 +159,7 @@ static int fastcall find_order(int size)
return order;
}
-void *kmalloc(size_t size, gfp_t gfp)
+void *__kmalloc(size_t size, gfp_t gfp)
{
slob_t *m;
bigblock_t *bb;
@@ -186,8 +188,7 @@ void *kmalloc(size_t size, gfp_t gfp)
slob_free(bb, sizeof(bigblock_t));
return 0;
}
-
-EXPORT_SYMBOL(kmalloc);
+EXPORT_SYMBOL(__kmalloc);
void kfree(const void *block)
{
@@ -327,9 +328,25 @@ const char *kmem_cache_name(struct kmem_cache *c)
EXPORT_SYMBOL(kmem_cache_name);
static struct timer_list slob_timer = TIMER_INITIALIZER(
- (void (*)(unsigned long))kmem_cache_init, 0, 0);
+ (void (*)(unsigned long))slob_timer_cbk, 0, 0);
+
+int kmem_cache_shrink(struct kmem_cache *d)
+{
+ return 0;
+}
+EXPORT_SYMBOL(kmem_cache_shrink);
+
+int kmem_ptr_validate(struct kmem_cache *a, const void *b)
+{
+ return 0;
+}
+
+void __init kmem_cache_init(void)
+{
+ slob_timer_cbk();
+}
-void kmem_cache_init(void)
+static void slob_timer_cbk(void)
{
void *p = slob_alloc(PAGE_SIZE, 0, PAGE_SIZE-1);
diff --git a/mm/truncate.c b/mm/truncate.c
index 9bfb8e853860..ecdfdcc50522 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -51,6 +51,26 @@ static inline void truncate_partial_page(struct page *page, unsigned partial)
do_invalidatepage(page, partial);
}
+void cancel_dirty_page(struct page *page, unsigned int account_size)
+{
+ /* If we're cancelling the page, it had better not be mapped any more */
+ if (page_mapped(page)) {
+ static unsigned int warncount;
+
+ WARN_ON(++warncount < 5);
+ }
+
+ if (TestClearPageDirty(page)) {
+ struct address_space *mapping = page->mapping;
+ if (mapping && mapping_cap_account_dirty(mapping)) {
+ dec_zone_page_state(page, NR_FILE_DIRTY);
+ if (account_size)
+ task_io_account_cancelled_write(account_size);
+ }
+ }
+}
+EXPORT_SYMBOL(cancel_dirty_page);
+
/*
* If truncate cannot remove the fs-private metadata from the page, the page
* becomes anonymous. It will be left on the LRU and may even be mapped into
@@ -67,11 +87,11 @@ truncate_complete_page(struct address_space *mapping, struct page *page)
if (page->mapping != mapping)
return;
+ cancel_dirty_page(page, PAGE_CACHE_SIZE);
+
if (PagePrivate(page))
do_invalidatepage(page, 0);
- if (test_clear_page_dirty(page))
- task_io_account_cancelled_write(PAGE_CACHE_SIZE);
ClearPageUptodate(page);
ClearPageMappedToDisk(page);
remove_from_page_cache(page);
@@ -350,7 +370,6 @@ int invalidate_inode_pages2_range(struct address_space *mapping,
for (i = 0; !ret && i < pagevec_count(&pvec); i++) {
struct page *page = pvec.pages[i];
pgoff_t page_index;
- int was_dirty;
lock_page(page);
if (page->mapping != mapping) {
@@ -386,12 +405,8 @@ int invalidate_inode_pages2_range(struct address_space *mapping,
PAGE_CACHE_SIZE, 0);
}
}
- was_dirty = test_clear_page_dirty(page);
- if (!invalidate_complete_page2(mapping, page)) {
- if (was_dirty)
- set_page_dirty(page);
+ if (!invalidate_complete_page2(mapping, page))
ret = -EIO;
- }
unlock_page(page);
}
pagevec_release(&pvec);
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 093f5fe6dd77..40fea4918390 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -692,7 +692,7 @@ static unsigned long shrink_inactive_list(unsigned long max_scan,
__count_vm_events(KSWAPD_STEAL, nr_freed);
} else
__count_zone_vm_events(PGSCAN_DIRECT, zone, nr_scan);
- __count_vm_events(PGACTIVATE, nr_freed);
+ __count_zone_vm_events(PGSTEAL, zone, nr_freed);
if (nr_taken == 0)
goto done;
@@ -984,7 +984,7 @@ static unsigned long shrink_zones(int priority, struct zone **zones,
if (!populated_zone(zone))
continue;
- if (!cpuset_zone_allowed(zone, __GFP_HARDWALL))
+ if (!cpuset_zone_allowed_hardwall(zone, GFP_KERNEL))
continue;
note_zone_scanning_priority(zone, priority);
@@ -1034,7 +1034,7 @@ unsigned long try_to_free_pages(struct zone **zones, gfp_t gfp_mask)
for (i = 0; zones[i] != NULL; i++) {
struct zone *zone = zones[i];
- if (!cpuset_zone_allowed(zone, __GFP_HARDWALL))
+ if (!cpuset_zone_allowed_hardwall(zone, GFP_KERNEL))
continue;
lru_pages += zone->nr_active + zone->nr_inactive;
@@ -1089,7 +1089,7 @@ out:
for (i = 0; zones[i] != 0; i++) {
struct zone *zone = zones[i];
- if (!cpuset_zone_allowed(zone, __GFP_HARDWALL))
+ if (!cpuset_zone_allowed_hardwall(zone, GFP_KERNEL))
continue;
zone->prev_priority = priority;
@@ -1354,7 +1354,7 @@ void wakeup_kswapd(struct zone *zone, int order)
return;
if (pgdat->kswapd_max_order < order)
pgdat->kswapd_max_order = order;
- if (!cpuset_zone_allowed(zone, __GFP_HARDWALL))
+ if (!cpuset_zone_allowed_hardwall(zone, GFP_KERNEL))
return;
if (!waitqueue_active(&pgdat->kswapd_wait))
return;
@@ -1369,8 +1369,8 @@ void wakeup_kswapd(struct zone *zone, int order)
*
* For pass > 3 we also try to shrink the LRU lists that contain a few pages
*/
-static unsigned long shrink_all_zones(unsigned long nr_pages, int pass,
- int prio, struct scan_control *sc)
+static unsigned long shrink_all_zones(unsigned long nr_pages, int prio,
+ int pass, struct scan_control *sc)
{
struct zone *zone;
unsigned long nr_to_scan, ret = 0;
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index 6cabf6d8a751..42233df2b099 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -1088,8 +1088,8 @@ out:
/*
* FIXME: nonblock behaviour looks like it may have a bug.
*/
-static int ax25_connect(struct socket *sock, struct sockaddr *uaddr,
- int addr_len, int flags)
+static int __must_check ax25_connect(struct socket *sock,
+ struct sockaddr *uaddr, int addr_len, int flags)
{
struct sock *sk = sock->sk;
ax25_cb *ax25 = ax25_sk(sk), *ax25t;
diff --git a/net/ax25/ax25_iface.c b/net/ax25/ax25_iface.c
index 07ac0207eb69..aff3e652c2d1 100644
--- a/net/ax25/ax25_iface.c
+++ b/net/ax25/ax25_iface.c
@@ -29,17 +29,10 @@
#include <linux/mm.h>
#include <linux/interrupt.h>
-static struct protocol_struct {
- struct protocol_struct *next;
- unsigned int pid;
- int (*func)(struct sk_buff *, ax25_cb *);
-} *protocol_list = NULL;
+static struct ax25_protocol *protocol_list;
static DEFINE_RWLOCK(protocol_list_lock);
-static struct linkfail_struct {
- struct linkfail_struct *next;
- void (*func)(ax25_cb *, int);
-} *linkfail_list = NULL;
+static HLIST_HEAD(ax25_linkfail_list);
static DEFINE_SPINLOCK(linkfail_lock);
static struct listen_struct {
@@ -49,36 +42,23 @@ static struct listen_struct {
} *listen_list = NULL;
static DEFINE_SPINLOCK(listen_lock);
-int ax25_protocol_register(unsigned int pid,
- int (*func)(struct sk_buff *, ax25_cb *))
+/*
+ * Do not register the internal protocols AX25_P_TEXT, AX25_P_SEGMENT,
+ * AX25_P_IP or AX25_P_ARP ...
+ */
+void ax25_register_pid(struct ax25_protocol *ap)
{
- struct protocol_struct *protocol;
-
- if (pid == AX25_P_TEXT || pid == AX25_P_SEGMENT)
- return 0;
-#ifdef CONFIG_INET
- if (pid == AX25_P_IP || pid == AX25_P_ARP)
- return 0;
-#endif
- if ((protocol = kmalloc(sizeof(*protocol), GFP_ATOMIC)) == NULL)
- return 0;
-
- protocol->pid = pid;
- protocol->func = func;
-
write_lock_bh(&protocol_list_lock);
- protocol->next = protocol_list;
- protocol_list = protocol;
+ ap->next = protocol_list;
+ protocol_list = ap;
write_unlock_bh(&protocol_list_lock);
-
- return 1;
}
-EXPORT_SYMBOL(ax25_protocol_register);
+EXPORT_SYMBOL_GPL(ax25_register_pid);
void ax25_protocol_release(unsigned int pid)
{
- struct protocol_struct *s, *protocol;
+ struct ax25_protocol *s, *protocol;
write_lock_bh(&protocol_list_lock);
protocol = protocol_list;
@@ -110,54 +90,19 @@ void ax25_protocol_release(unsigned int pid)
EXPORT_SYMBOL(ax25_protocol_release);
-int ax25_linkfail_register(void (*func)(ax25_cb *, int))
+void ax25_linkfail_register(struct ax25_linkfail *lf)
{
- struct linkfail_struct *linkfail;
-
- if ((linkfail = kmalloc(sizeof(*linkfail), GFP_ATOMIC)) == NULL)
- return 0;
-
- linkfail->func = func;
-
spin_lock_bh(&linkfail_lock);
- linkfail->next = linkfail_list;
- linkfail_list = linkfail;
+ hlist_add_head(&lf->lf_node, &ax25_linkfail_list);
spin_unlock_bh(&linkfail_lock);
-
- return 1;
}
EXPORT_SYMBOL(ax25_linkfail_register);
-void ax25_linkfail_release(void (*func)(ax25_cb *, int))
+void ax25_linkfail_release(struct ax25_linkfail *lf)
{
- struct linkfail_struct *s, *linkfail;
-
spin_lock_bh(&linkfail_lock);
- linkfail = linkfail_list;
- if (linkfail == NULL) {
- spin_unlock_bh(&linkfail_lock);
- return;
- }
-
- if (linkfail->func == func) {
- linkfail_list = linkfail->next;
- spin_unlock_bh(&linkfail_lock);
- kfree(linkfail);
- return;
- }
-
- while (linkfail != NULL && linkfail->next != NULL) {
- if (linkfail->next->func == func) {
- s = linkfail->next;
- linkfail->next = linkfail->next->next;
- spin_unlock_bh(&linkfail_lock);
- kfree(s);
- return;
- }
-
- linkfail = linkfail->next;
- }
+ hlist_del_init(&lf->lf_node);
spin_unlock_bh(&linkfail_lock);
}
@@ -171,7 +116,7 @@ int ax25_listen_register(ax25_address *callsign, struct net_device *dev)
return 0;
if ((listen = kmalloc(sizeof(*listen), GFP_ATOMIC)) == NULL)
- return 0;
+ return -ENOMEM;
listen->callsign = *callsign;
listen->dev = dev;
@@ -181,7 +126,7 @@ int ax25_listen_register(ax25_address *callsign, struct net_device *dev)
listen_list = listen;
spin_unlock_bh(&listen_lock);
- return 1;
+ return 0;
}
EXPORT_SYMBOL(ax25_listen_register);
@@ -223,7 +168,7 @@ EXPORT_SYMBOL(ax25_listen_release);
int (*ax25_protocol_function(unsigned int pid))(struct sk_buff *, ax25_cb *)
{
int (*res)(struct sk_buff *, ax25_cb *) = NULL;
- struct protocol_struct *protocol;
+ struct ax25_protocol *protocol;
read_lock(&protocol_list_lock);
for (protocol = protocol_list; protocol != NULL; protocol = protocol->next)
@@ -242,7 +187,8 @@ int ax25_listen_mine(ax25_address *callsign, struct net_device *dev)
spin_lock_bh(&listen_lock);
for (listen = listen_list; listen != NULL; listen = listen->next)
- if (ax25cmp(&listen->callsign, callsign) == 0 && (listen->dev == dev || listen->dev == NULL)) {
+ if (ax25cmp(&listen->callsign, callsign) == 0 &&
+ (listen->dev == dev || listen->dev == NULL)) {
spin_unlock_bh(&listen_lock);
return 1;
}
@@ -253,17 +199,18 @@ int ax25_listen_mine(ax25_address *callsign, struct net_device *dev)
void ax25_link_failed(ax25_cb *ax25, int reason)
{
- struct linkfail_struct *linkfail;
+ struct ax25_linkfail *lf;
+ struct hlist_node *node;
spin_lock_bh(&linkfail_lock);
- for (linkfail = linkfail_list; linkfail != NULL; linkfail = linkfail->next)
- (linkfail->func)(ax25, reason);
+ hlist_for_each_entry(lf, node, &ax25_linkfail_list, lf_node)
+ lf->func(ax25, reason);
spin_unlock_bh(&linkfail_lock);
}
int ax25_protocol_is_registered(unsigned int pid)
{
- struct protocol_struct *protocol;
+ struct ax25_protocol *protocol;
int res = 0;
read_lock_bh(&protocol_list_lock);
diff --git a/net/ax25/ax25_route.c b/net/ax25/ax25_route.c
index 8580356ace5c..0a0381622b1c 100644
--- a/net/ax25/ax25_route.c
+++ b/net/ax25/ax25_route.c
@@ -71,7 +71,7 @@ void ax25_rt_device_down(struct net_device *dev)
write_unlock(&ax25_route_lock);
}
-static int ax25_rt_add(struct ax25_routes_struct *route)
+static int __must_check ax25_rt_add(struct ax25_routes_struct *route)
{
ax25_route *ax25_rt;
ax25_dev *ax25_dev;
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 711a085eca5b..dbf98c49dbaa 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -123,10 +123,10 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
if (flt->opcode &&
((evt == HCI_EV_CMD_COMPLETE &&
flt->opcode !=
- get_unaligned((__u16 *)(skb->data + 3))) ||
+ get_unaligned((__le16 *)(skb->data + 3))) ||
(evt == HCI_EV_CMD_STATUS &&
flt->opcode !=
- get_unaligned((__u16 *)(skb->data + 4)))))
+ get_unaligned((__le16 *)(skb->data + 4)))))
continue;
}
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index bd221ad52eaf..ea3337ad0edc 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -61,9 +61,6 @@ static int brnf_filter_vlan_tagged __read_mostly = 1;
#define brnf_filter_vlan_tagged 1
#endif
-int brnf_deferred_hooks;
-EXPORT_SYMBOL_GPL(brnf_deferred_hooks);
-
static __be16 inline vlan_proto(const struct sk_buff *skb)
{
return vlan_eth_hdr(skb)->h_vlan_encapsulated_proto;
@@ -685,110 +682,50 @@ static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff **pskb,
return NF_STOLEN;
}
-/* PF_BRIDGE/LOCAL_OUT ***********************************************/
-static int br_nf_local_out_finish(struct sk_buff *skb)
-{
- if (skb->protocol == htons(ETH_P_8021Q)) {
- skb_push(skb, VLAN_HLEN);
- skb->nh.raw -= VLAN_HLEN;
- }
-
- NF_HOOK_THRESH(PF_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev,
- br_forward_finish, NF_BR_PRI_FIRST + 1);
-
- return 0;
-}
-
-/* This function sees both locally originated IP packets and forwarded
+/* PF_BRIDGE/LOCAL_OUT ***********************************************
+ *
+ * This function sees both locally originated IP packets and forwarded
* IP packets (in both cases the destination device is a bridge
* device). It also sees bridged-and-DNAT'ed packets.
- * To be able to filter on the physical bridge devices (with the physdev
- * module), we steal packets destined to a bridge device away from the
- * PF_INET/FORWARD and PF_INET/OUTPUT hook functions, and give them back later,
- * when we have determined the real output device. This is done in here.
*
* If (nf_bridge->mask & BRNF_BRIDGED_DNAT) then the packet is bridged
* and we fake the PF_BRIDGE/FORWARD hook. The function br_nf_forward()
* will then fake the PF_INET/FORWARD hook. br_nf_local_out() has priority
* NF_BR_PRI_FIRST, so no relevant PF_BRIDGE/INPUT functions have been nor
* will be executed.
- * Otherwise, if nf_bridge->physindev is NULL, the bridge-nf code never touched
- * this packet before, and so the packet was locally originated. We fake
- * the PF_INET/LOCAL_OUT hook.
- * Finally, if nf_bridge->physindev isn't NULL, then the packet was IP routed,
- * so we fake the PF_INET/FORWARD hook. ip_sabotage_out() makes sure
- * even routed packets that didn't arrive on a bridge interface have their
- * nf_bridge->physindev set. */
+ */
static unsigned int br_nf_local_out(unsigned int hook, struct sk_buff **pskb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
- struct net_device *realindev, *realoutdev;
+ struct net_device *realindev;
struct sk_buff *skb = *pskb;
struct nf_bridge_info *nf_bridge;
- int pf;
if (!skb->nf_bridge)
return NF_ACCEPT;
- if (skb->protocol == htons(ETH_P_IP) || IS_VLAN_IP(skb))
- pf = PF_INET;
- else
- pf = PF_INET6;
-
nf_bridge = skb->nf_bridge;
- nf_bridge->physoutdev = skb->dev;
- realindev = nf_bridge->physindev;
+ if (!(nf_bridge->mask & BRNF_BRIDGED_DNAT))
+ return NF_ACCEPT;
/* Bridged, take PF_BRIDGE/FORWARD.
* (see big note in front of br_nf_pre_routing_finish) */
- if (nf_bridge->mask & BRNF_BRIDGED_DNAT) {
- if (nf_bridge->mask & BRNF_PKT_TYPE) {
- skb->pkt_type = PACKET_OTHERHOST;
- nf_bridge->mask ^= BRNF_PKT_TYPE;
- }
- if (skb->protocol == htons(ETH_P_8021Q)) {
- skb_push(skb, VLAN_HLEN);
- skb->nh.raw -= VLAN_HLEN;
- }
+ nf_bridge->physoutdev = skb->dev;
+ realindev = nf_bridge->physindev;
- NF_HOOK(PF_BRIDGE, NF_BR_FORWARD, skb, realindev,
- skb->dev, br_forward_finish);
- goto out;
+ if (nf_bridge->mask & BRNF_PKT_TYPE) {
+ skb->pkt_type = PACKET_OTHERHOST;
+ nf_bridge->mask ^= BRNF_PKT_TYPE;
}
- realoutdev = bridge_parent(skb->dev);
- if (!realoutdev)
- return NF_DROP;
-
-#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
- /* iptables should match -o br0.x */
- if (nf_bridge->netoutdev)
- realoutdev = nf_bridge->netoutdev;
-#endif
if (skb->protocol == htons(ETH_P_8021Q)) {
- skb_pull(skb, VLAN_HLEN);
- (*pskb)->nh.raw += VLAN_HLEN;
- }
- /* IP forwarded traffic has a physindev, locally
- * generated traffic hasn't. */
- if (realindev != NULL) {
- if (!(nf_bridge->mask & BRNF_DONT_TAKE_PARENT)) {
- struct net_device *parent = bridge_parent(realindev);
- if (parent)
- realindev = parent;
- }
-
- NF_HOOK_THRESH(pf, NF_IP_FORWARD, skb, realindev,
- realoutdev, br_nf_local_out_finish,
- NF_IP_PRI_BRIDGE_SABOTAGE_FORWARD + 1);
- } else {
- NF_HOOK_THRESH(pf, NF_IP_LOCAL_OUT, skb, realindev,
- realoutdev, br_nf_local_out_finish,
- NF_IP_PRI_BRIDGE_SABOTAGE_LOCAL_OUT + 1);
+ skb_push(skb, VLAN_HLEN);
+ skb->nh.raw -= VLAN_HLEN;
}
-out:
+ NF_HOOK(PF_BRIDGE, NF_BR_FORWARD, skb, realindev, skb->dev,
+ br_forward_finish);
return NF_STOLEN;
}
@@ -894,69 +831,6 @@ static unsigned int ip_sabotage_in(unsigned int hook, struct sk_buff **pskb,
return NF_ACCEPT;
}
-/* Postpone execution of PF_INET(6)/FORWARD, PF_INET(6)/LOCAL_OUT
- * and PF_INET(6)/POST_ROUTING until we have done the forwarding
- * decision in the bridge code and have determined nf_bridge->physoutdev. */
-static unsigned int ip_sabotage_out(unsigned int hook, struct sk_buff **pskb,
- const struct net_device *in,
- const struct net_device *out,
- int (*okfn)(struct sk_buff *))
-{
- struct sk_buff *skb = *pskb;
-
- if ((out->hard_start_xmit == br_dev_xmit &&
- okfn != br_nf_forward_finish &&
- okfn != br_nf_local_out_finish && okfn != br_nf_dev_queue_xmit)
-#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
- || ((out->priv_flags & IFF_802_1Q_VLAN) &&
- VLAN_DEV_INFO(out)->real_dev->hard_start_xmit == br_dev_xmit)
-#endif
- ) {
- struct nf_bridge_info *nf_bridge;
-
- if (!skb->nf_bridge) {
-#ifdef CONFIG_SYSCTL
- /* This code is executed while in the IP(v6) stack,
- the version should be 4 or 6. We can't use
- skb->protocol because that isn't set on
- PF_INET(6)/LOCAL_OUT. */
- struct iphdr *ip = skb->nh.iph;
-
- if (ip->version == 4 && !brnf_call_iptables)
- return NF_ACCEPT;
- else if (ip->version == 6 && !brnf_call_ip6tables)
- return NF_ACCEPT;
- else if (!brnf_deferred_hooks)
- return NF_ACCEPT;
-#endif
- if (hook == NF_IP_POST_ROUTING)
- return NF_ACCEPT;
- if (!nf_bridge_alloc(skb))
- return NF_DROP;
- }
-
- nf_bridge = skb->nf_bridge;
-
- /* This frame will arrive on PF_BRIDGE/LOCAL_OUT and we
- * will need the indev then. For a brouter, the real indev
- * can be a bridge port, so we make sure br_nf_local_out()
- * doesn't use the bridge parent of the indev by using
- * the BRNF_DONT_TAKE_PARENT mask. */
- if (hook == NF_IP_FORWARD && nf_bridge->physindev == NULL) {
- nf_bridge->mask |= BRNF_DONT_TAKE_PARENT;
- nf_bridge->physindev = (struct net_device *)in;
- }
-#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
- /* the iptables outdev is br0.x, not br0 */
- if (out->priv_flags & IFF_802_1Q_VLAN)
- nf_bridge->netoutdev = (struct net_device *)out;
-#endif
- return NF_STOP;
- }
-
- return NF_ACCEPT;
-}
-
/* For br_nf_local_out we need (prio = NF_BR_PRI_FIRST), to insure that innocent
* PF_BRIDGE/NF_BR_LOCAL_OUT functions don't get bridged traffic as input.
* For br_nf_post_routing, we need (prio = NF_BR_PRI_LAST), because
@@ -1002,36 +876,6 @@ static struct nf_hook_ops br_nf_ops[] = {
.pf = PF_INET6,
.hooknum = NF_IP6_PRE_ROUTING,
.priority = NF_IP6_PRI_FIRST, },
- { .hook = ip_sabotage_out,
- .owner = THIS_MODULE,
- .pf = PF_INET,
- .hooknum = NF_IP_FORWARD,
- .priority = NF_IP_PRI_BRIDGE_SABOTAGE_FORWARD, },
- { .hook = ip_sabotage_out,
- .owner = THIS_MODULE,
- .pf = PF_INET6,
- .hooknum = NF_IP6_FORWARD,
- .priority = NF_IP6_PRI_BRIDGE_SABOTAGE_FORWARD, },
- { .hook = ip_sabotage_out,
- .owner = THIS_MODULE,
- .pf = PF_INET,
- .hooknum = NF_IP_LOCAL_OUT,
- .priority = NF_IP_PRI_BRIDGE_SABOTAGE_LOCAL_OUT, },
- { .hook = ip_sabotage_out,
- .owner = THIS_MODULE,
- .pf = PF_INET6,
- .hooknum = NF_IP6_LOCAL_OUT,
- .priority = NF_IP6_PRI_BRIDGE_SABOTAGE_LOCAL_OUT, },
- { .hook = ip_sabotage_out,
- .owner = THIS_MODULE,
- .pf = PF_INET,
- .hooknum = NF_IP_POST_ROUTING,
- .priority = NF_IP_PRI_FIRST, },
- { .hook = ip_sabotage_out,
- .owner = THIS_MODULE,
- .pf = PF_INET6,
- .hooknum = NF_IP6_POST_ROUTING,
- .priority = NF_IP6_PRI_FIRST, },
};
#ifdef CONFIG_SYSCTL
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index fa6b75372ed7..40402c59506a 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -845,8 +845,8 @@ found:
* Find some p such that f(p) = fval; return 1/p [RFC 3448, 6.3.1].
*/
if (rtt == 0) { /* would result in divide-by-zero */
- DCCP_WARN("RTT==0, returning 1/p = 1\n");
- return 1000000;
+ DCCP_WARN("RTT==0\n");
+ return ~0;
}
dccp_timestamp(sk, &tstamp);
@@ -858,7 +858,7 @@ found:
DCCP_WARN("X_recv==0\n");
if ((x_recv = hcrx->ccid3hcrx_x_recv) == 0) {
DCCP_BUG("stored value of X_recv is zero");
- return 1000000;
+ return ~0;
}
}
diff --git a/net/ieee80211/softmac/ieee80211softmac_assoc.c b/net/ieee80211/softmac/ieee80211softmac_assoc.c
index e3f37fdda65f..a824852909e4 100644
--- a/net/ieee80211/softmac/ieee80211softmac_assoc.c
+++ b/net/ieee80211/softmac/ieee80211softmac_assoc.c
@@ -167,7 +167,7 @@ static void
ieee80211softmac_assoc_notify_scan(struct net_device *dev, int event_type, void *context)
{
struct ieee80211softmac_device *mac = ieee80211_priv(dev);
- ieee80211softmac_assoc_work((void*)mac);
+ ieee80211softmac_assoc_work(&mac->associnfo.work.work);
}
static void
@@ -177,7 +177,7 @@ ieee80211softmac_assoc_notify_auth(struct net_device *dev, int event_type, void
switch (event_type) {
case IEEE80211SOFTMAC_EVENT_AUTHENTICATED:
- ieee80211softmac_assoc_work((void*)mac);
+ ieee80211softmac_assoc_work(&mac->associnfo.work.work);
break;
case IEEE80211SOFTMAC_EVENT_AUTH_FAILED:
case IEEE80211SOFTMAC_EVENT_AUTH_TIMEOUT:
diff --git a/net/ieee80211/softmac/ieee80211softmac_wx.c b/net/ieee80211/softmac/ieee80211softmac_wx.c
index 480d72c7a42c..fa2f7da606a9 100644
--- a/net/ieee80211/softmac/ieee80211softmac_wx.c
+++ b/net/ieee80211/softmac/ieee80211softmac_wx.c
@@ -463,7 +463,7 @@ ieee80211softmac_wx_get_genie(struct net_device *dev,
err = -E2BIG;
}
spin_unlock_irqrestore(&mac->lock, flags);
- mutex_lock(&mac->associnfo.mutex);
+ mutex_unlock(&mac->associnfo.mutex);
return err;
}
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
index 363df9976c9d..f6026d4ac428 100644
--- a/net/ipv4/netfilter/Kconfig
+++ b/net/ipv4/netfilter/Kconfig
@@ -401,7 +401,7 @@ config IP_NF_NAT
# NAT + specific targets: nf_conntrack
config NF_NAT
tristate "Full NAT"
- depends on IP_NF_IPTABLES && NF_CONNTRACK
+ depends on IP_NF_IPTABLES && NF_CONNTRACK_IPV4
help
The Full NAT option allows masquerading, port forwarding and other
forms of full Network Address Port Translation. It is controlled by
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 71b76ade00e1..9aa22398b3dc 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -358,6 +358,7 @@ static int mark_source_chains(struct xt_table_info *newinfo,
for (;;) {
struct arpt_standard_target *t
= (void *)arpt_get_target(e);
+ int visited = e->comefrom & (1 << hook);
if (e->comefrom & (1 << NF_ARP_NUMHOOKS)) {
printk("arptables: loop hook %u pos %u %08X.\n",
@@ -368,11 +369,11 @@ static int mark_source_chains(struct xt_table_info *newinfo,
|= ((1 << hook) | (1 << NF_ARP_NUMHOOKS));
/* Unconditional return/END. */
- if (e->target_offset == sizeof(struct arpt_entry)
+ if ((e->target_offset == sizeof(struct arpt_entry)
&& (strcmp(t->target.u.user.name,
ARPT_STANDARD_TARGET) == 0)
&& t->verdict < 0
- && unconditional(&e->arp)) {
+ && unconditional(&e->arp)) || visited) {
unsigned int oldpos, size;
if (t->verdict < -NF_MAX_VERDICT - 1) {
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 0ff2956d35e5..09696f16aa95 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -384,6 +384,7 @@ mark_source_chains(struct xt_table_info *newinfo,
for (;;) {
struct ipt_standard_target *t
= (void *)ipt_get_target(e);
+ int visited = e->comefrom & (1 << hook);
if (e->comefrom & (1 << NF_IP_NUMHOOKS)) {
printk("iptables: loop hook %u pos %u %08X.\n",
@@ -394,11 +395,11 @@ mark_source_chains(struct xt_table_info *newinfo,
|= ((1 << hook) | (1 << NF_IP_NUMHOOKS));
/* Unconditional return/END. */
- if (e->target_offset == sizeof(struct ipt_entry)
+ if ((e->target_offset == sizeof(struct ipt_entry)
&& (strcmp(t->target.u.user.name,
IPT_STANDARD_TARGET) == 0)
&& t->verdict < 0
- && unconditional(&e->ip)) {
+ && unconditional(&e->ip)) || visited) {
unsigned int oldpos, size;
if (t->verdict < -NF_MAX_VERDICT - 1) {
@@ -484,7 +485,47 @@ cleanup_match(struct ipt_entry_match *m, unsigned int *i)
}
static inline int
-check_match(struct ipt_entry_match *m,
+check_entry(struct ipt_entry *e, const char *name)
+{
+ struct ipt_entry_target *t;
+
+ if (!ip_checkentry(&e->ip)) {
+ duprintf("ip_tables: ip check failed %p %s.\n", e, name);
+ return -EINVAL;
+ }
+
+ if (e->target_offset + sizeof(struct ipt_entry_target) > e->next_offset)
+ return -EINVAL;
+
+ t = ipt_get_target(e);
+ if (e->target_offset + t->u.target_size > e->next_offset)
+ return -EINVAL;
+
+ return 0;
+}
+
+static inline int check_match(struct ipt_entry_match *m, const char *name,
+ const struct ipt_ip *ip, unsigned int hookmask)
+{
+ struct ipt_match *match;
+ int ret;
+
+ match = m->u.kernel.match;
+ ret = xt_check_match(match, AF_INET, m->u.match_size - sizeof(*m),
+ name, hookmask, ip->proto,
+ ip->invflags & IPT_INV_PROTO);
+ if (!ret && m->u.kernel.match->checkentry
+ && !m->u.kernel.match->checkentry(name, ip, match, m->data,
+ hookmask)) {
+ duprintf("ip_tables: check failed for `%s'.\n",
+ m->u.kernel.match->name);
+ ret = -EINVAL;
+ }
+ return ret;
+}
+
+static inline int
+find_check_match(struct ipt_entry_match *m,
const char *name,
const struct ipt_ip *ip,
unsigned int hookmask,
@@ -497,26 +538,15 @@ check_match(struct ipt_entry_match *m,
m->u.user.revision),
"ipt_%s", m->u.user.name);
if (IS_ERR(match) || !match) {
- duprintf("check_match: `%s' not found\n", m->u.user.name);
+ duprintf("find_check_match: `%s' not found\n", m->u.user.name);
return match ? PTR_ERR(match) : -ENOENT;
}
m->u.kernel.match = match;
- ret = xt_check_match(match, AF_INET, m->u.match_size - sizeof(*m),
- name, hookmask, ip->proto,
- ip->invflags & IPT_INV_PROTO);
+ ret = check_match(m, name, ip, hookmask);
if (ret)
goto err;
- if (m->u.kernel.match->checkentry
- && !m->u.kernel.match->checkentry(name, ip, match, m->data,
- hookmask)) {
- duprintf("ip_tables: check failed for `%s'.\n",
- m->u.kernel.match->name);
- ret = -EINVAL;
- goto err;
- }
-
(*i)++;
return 0;
err:
@@ -524,10 +554,29 @@ err:
return ret;
}
-static struct ipt_target ipt_standard_target;
+static inline int check_target(struct ipt_entry *e, const char *name)
+{
+ struct ipt_entry_target *t;
+ struct ipt_target *target;
+ int ret;
+
+ t = ipt_get_target(e);
+ target = t->u.kernel.target;
+ ret = xt_check_target(target, AF_INET, t->u.target_size - sizeof(*t),
+ name, e->comefrom, e->ip.proto,
+ e->ip.invflags & IPT_INV_PROTO);
+ if (!ret && t->u.kernel.target->checkentry
+ && !t->u.kernel.target->checkentry(name, e, target,
+ t->data, e->comefrom)) {
+ duprintf("ip_tables: check failed for `%s'.\n",
+ t->u.kernel.target->name);
+ ret = -EINVAL;
+ }
+ return ret;
+}
static inline int
-check_entry(struct ipt_entry *e, const char *name, unsigned int size,
+find_check_entry(struct ipt_entry *e, const char *name, unsigned int size,
unsigned int *i)
{
struct ipt_entry_target *t;
@@ -535,49 +584,32 @@ check_entry(struct ipt_entry *e, const char *name, unsigned int size,
int ret;
unsigned int j;
- if (!ip_checkentry(&e->ip)) {
- duprintf("ip_tables: ip check failed %p %s.\n", e, name);
- return -EINVAL;
- }
-
- if (e->target_offset + sizeof(struct ipt_entry_target) > e->next_offset)
- return -EINVAL;
+ ret = check_entry(e, name);
+ if (ret)
+ return ret;
j = 0;
- ret = IPT_MATCH_ITERATE(e, check_match, name, &e->ip, e->comefrom, &j);
+ ret = IPT_MATCH_ITERATE(e, find_check_match, name, &e->ip,
+ e->comefrom, &j);
if (ret != 0)
goto cleanup_matches;
t = ipt_get_target(e);
- ret = -EINVAL;
- if (e->target_offset + t->u.target_size > e->next_offset)
- goto cleanup_matches;
target = try_then_request_module(xt_find_target(AF_INET,
t->u.user.name,
t->u.user.revision),
"ipt_%s", t->u.user.name);
if (IS_ERR(target) || !target) {
- duprintf("check_entry: `%s' not found\n", t->u.user.name);
+ duprintf("find_check_entry: `%s' not found\n", t->u.user.name);
ret = target ? PTR_ERR(target) : -ENOENT;
goto cleanup_matches;
}
t->u.kernel.target = target;
- ret = xt_check_target(target, AF_INET, t->u.target_size - sizeof(*t),
- name, e->comefrom, e->ip.proto,
- e->ip.invflags & IPT_INV_PROTO);
+ ret = check_target(e, name);
if (ret)
goto err;
- if (t->u.kernel.target->checkentry
- && !t->u.kernel.target->checkentry(name, e, target, t->data,
- e->comefrom)) {
- duprintf("ip_tables: check failed for `%s'.\n",
- t->u.kernel.target->name);
- ret = -EINVAL;
- goto err;
- }
-
(*i)++;
return 0;
err:
@@ -712,7 +744,7 @@ translate_table(const char *name,
/* Finally, each sanity check must pass */
i = 0;
ret = IPT_ENTRY_ITERATE(entry0, newinfo->size,
- check_entry, name, size, &i);
+ find_check_entry, name, size, &i);
if (ret != 0) {
IPT_ENTRY_ITERATE(entry0, newinfo->size,
@@ -1452,14 +1484,9 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e,
return -EINVAL;
}
- if (!ip_checkentry(&e->ip)) {
- duprintf("ip_tables: ip check failed %p %s.\n", e, name);
- return -EINVAL;
- }
-
- if (e->target_offset + sizeof(struct compat_xt_entry_target) >
- e->next_offset)
- return -EINVAL;
+ ret = check_entry(e, name);
+ if (ret)
+ return ret;
off = 0;
entry_offset = (void *)e - (void *)base;
@@ -1470,15 +1497,13 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e,
goto cleanup_matches;
t = ipt_get_target(e);
- ret = -EINVAL;
- if (e->target_offset + t->u.target_size > e->next_offset)
- goto cleanup_matches;
target = try_then_request_module(xt_find_target(AF_INET,
t->u.user.name,
t->u.user.revision),
"ipt_%s", t->u.user.name);
if (IS_ERR(target) || !target) {
- duprintf("check_entry: `%s' not found\n", t->u.user.name);
+ duprintf("check_compat_entry_size_and_hooks: `%s' not found\n",
+ t->u.user.name);
ret = target ? PTR_ERR(target) : -ENOENT;
goto cleanup_matches;
}
@@ -1555,57 +1580,15 @@ static int compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr,
return ret;
}
-static inline int compat_check_match(struct ipt_entry_match *m, const char *name,
- const struct ipt_ip *ip, unsigned int hookmask)
-{
- struct ipt_match *match;
- int ret;
-
- match = m->u.kernel.match;
- ret = xt_check_match(match, AF_INET, m->u.match_size - sizeof(*m),
- name, hookmask, ip->proto,
- ip->invflags & IPT_INV_PROTO);
- if (!ret && m->u.kernel.match->checkentry
- && !m->u.kernel.match->checkentry(name, ip, match, m->data,
- hookmask)) {
- duprintf("ip_tables: compat: check failed for `%s'.\n",
- m->u.kernel.match->name);
- ret = -EINVAL;
- }
- return ret;
-}
-
-static inline int compat_check_target(struct ipt_entry *e, const char *name)
-{
- struct ipt_entry_target *t;
- struct ipt_target *target;
- int ret;
-
- t = ipt_get_target(e);
- target = t->u.kernel.target;
- ret = xt_check_target(target, AF_INET, t->u.target_size - sizeof(*t),
- name, e->comefrom, e->ip.proto,
- e->ip.invflags & IPT_INV_PROTO);
- if (!ret && t->u.kernel.target->checkentry
- && !t->u.kernel.target->checkentry(name, e, target,
- t->data, e->comefrom)) {
- duprintf("ip_tables: compat: check failed for `%s'.\n",
- t->u.kernel.target->name);
- ret = -EINVAL;
- }
- return ret;
-}
-
static inline int compat_check_entry(struct ipt_entry *e, const char *name)
{
int ret;
- ret = IPT_MATCH_ITERATE(e, compat_check_match, name, &e->ip,
- e->comefrom);
+ ret = IPT_MATCH_ITERATE(e, check_match, name, &e->ip, e->comefrom);
if (ret)
return ret;
- return compat_check_target(e, name);
+ return check_target(e, name);
}
static int
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
index fef56ae61abe..b1c11160b9de 100644
--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
+++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
@@ -447,6 +447,12 @@ checkentry(const char *tablename,
cipinfo->config = config;
}
+ if (nf_ct_l3proto_try_module_get(target->family) < 0) {
+ printk(KERN_WARNING "can't load conntrack support for "
+ "proto=%d\n", target->family);
+ return 0;
+ }
+
return 1;
}
@@ -460,6 +466,8 @@ static void destroy(const struct xt_target *target, void *targinfo)
clusterip_config_entry_put(cipinfo->config);
clusterip_config_put(cipinfo->config);
+
+ nf_ct_l3proto_module_put(target->family);
}
static struct ipt_target clusterip_tgt = {
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 1aaff0a2e098..2daa0dc19d33 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1325,7 +1325,8 @@ void ip_rt_send_redirect(struct sk_buff *skb)
/* Check for load limit; set rate_last to the latest sent
* redirect.
*/
- if (time_after(jiffies,
+ if (rt->u.dst.rate_tokens == 0 ||
+ time_after(jiffies,
(rt->u.dst.rate_last +
(ip_rt_redirect_load << rt->u.dst.rate_tokens)))) {
icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, rt->rt_gateway);
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 090c690627e5..b67e0dd743be 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -2364,8 +2364,9 @@ struct tcp_md5sig_pool *__tcp_get_md5sig_pool(int cpu)
EXPORT_SYMBOL(__tcp_get_md5sig_pool);
-void __tcp_put_md5sig_pool(void) {
- __tcp_free_md5sig_pool(tcp_md5sig_pool);
+void __tcp_put_md5sig_pool(void)
+{
+ tcp_free_md5sig_pool();
}
EXPORT_SYMBOL(__tcp_put_md5sig_pool);
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index a1222d6968c4..bf7a22412bcb 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -928,6 +928,7 @@ int tcp_v4_md5_do_del(struct sock *sk, __be32 addr)
if (tp->md5sig_info->entries4 == 0) {
kfree(tp->md5sig_info->keys4);
tp->md5sig_info->keys4 = NULL;
+ tp->md5sig_info->alloced4 = 0;
} else if (tp->md5sig_info->entries4 != i) {
/* Need to do some manipulation */
memcpy(&tp->md5sig_info->keys4[i],
@@ -1185,7 +1186,7 @@ done_opts:
return 0;
if (hash_expected && !hash_location) {
- LIMIT_NETDEBUG(KERN_INFO "MD5 Hash NOT expected but found "
+ LIMIT_NETDEBUG(KERN_INFO "MD5 Hash expected but NOT found "
"(" NIPQUAD_FMT ", %d)->(" NIPQUAD_FMT ", %d)\n",
NIPQUAD(iph->saddr), ntohs(th->source),
NIPQUAD(iph->daddr), ntohs(th->dest));
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 035915fc9ed3..cfff930f2baf 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -165,11 +165,14 @@ int __udp_lib_get_port(struct sock *sk, unsigned short snum,
goto gotit;
}
size = 0;
- sk_for_each(sk2, node, head)
- if (++size < best_size_so_far) {
- best_size_so_far = size;
- best = result;
- }
+ sk_for_each(sk2, node, head) {
+ if (++size >= best_size_so_far)
+ goto next;
+ }
+ best_size_so_far = size;
+ best = result;
+ next:
+ ;
}
result = best;
for(i = 0; i < (1 << 16) / UDP_HTABLE_SIZE; i++, result += UDP_HTABLE_SIZE) {
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 1eafcfc95e81..352690e2ab82 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -978,12 +978,27 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
break;
case IPV6_UNICAST_HOPS:
- val = np->hop_limit;
- break;
-
case IPV6_MULTICAST_HOPS:
- val = np->mcast_hops;
+ {
+ struct dst_entry *dst;
+
+ if (optname == IPV6_UNICAST_HOPS)
+ val = np->hop_limit;
+ else
+ val = np->mcast_hops;
+
+ dst = sk_dst_get(sk);
+ if (dst) {
+ if (val < 0)
+ val = dst_metric(dst, RTAX_HOPLIMIT);
+ if (val < 0)
+ val = ipv6_get_hoplimit(dst->dev);
+ dst_release(dst);
+ }
+ if (val < 0)
+ val = ipv6_devconf.hop_limit;
break;
+ }
case IPV6_MULTICAST_LOOP:
val = np->mc_loop;
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
index fc3e5eb4bc3f..adcd6131df2a 100644
--- a/net/ipv6/netfilter/Kconfig
+++ b/net/ipv6/netfilter/Kconfig
@@ -7,7 +7,7 @@ menu "IPv6: Netfilter Configuration (EXPERIMENTAL)"
config NF_CONNTRACK_IPV6
tristate "IPv6 connection tracking support (EXPERIMENTAL)"
- depends on EXPERIMENTAL && NF_CONNTRACK
+ depends on INET && IPV6 && EXPERIMENTAL && NF_CONNTRACK
---help---
Connection tracking keeps a record of what packets have passed
through your machine, in order to figure out how they are related
@@ -21,6 +21,7 @@ config NF_CONNTRACK_IPV6
config IP6_NF_QUEUE
tristate "IP6 Userspace queueing via NETLINK (OBSOLETE)"
+ depends on INET && IPV6 && NETFILTER && EXPERIMENTAL
---help---
This option adds a queue handler to the kernel for IPv6
@@ -41,7 +42,7 @@ config IP6_NF_QUEUE
config IP6_NF_IPTABLES
tristate "IP6 tables support (required for filtering)"
- depends on NETFILTER_XTABLES
+ depends on INET && IPV6 && EXPERIMENTAL && NETFILTER_XTABLES
help
ip6tables is a general, extensible packet identification framework.
Currently only the packet filtering and packet mangling subsystem
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 4eec4b3988b8..99502c5da4c4 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -413,6 +413,7 @@ mark_source_chains(struct xt_table_info *newinfo,
unsigned int pos = newinfo->hook_entry[hook];
struct ip6t_entry *e
= (struct ip6t_entry *)(entry0 + pos);
+ int visited = e->comefrom & (1 << hook);
if (!(valid_hooks & (1 << hook)))
continue;
@@ -433,11 +434,11 @@ mark_source_chains(struct xt_table_info *newinfo,
|= ((1 << hook) | (1 << NF_IP6_NUMHOOKS));
/* Unconditional return/END. */
- if (e->target_offset == sizeof(struct ip6t_entry)
+ if ((e->target_offset == sizeof(struct ip6t_entry)
&& (strcmp(t->target.u.user.name,
IP6T_STANDARD_TARGET) == 0)
&& t->verdict < 0
- && unconditional(&e->ipv6)) {
+ && unconditional(&e->ipv6)) || visited) {
unsigned int oldpos, size;
if (t->verdict < -NF_MAX_VERDICT - 1) {
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 9f80518aacbd..8c3d56871b50 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -494,7 +494,7 @@ do { \
goto out; \
pn = fn->parent; \
if (FIB6_SUBTREE(pn) && FIB6_SUBTREE(pn) != fn) \
- fn = fib6_lookup(pn->subtree, NULL, saddr); \
+ fn = fib6_lookup(FIB6_SUBTREE(pn), NULL, saddr); \
else \
fn = pn; \
if (fn->fn_flags & RTN_RTINFO) \
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 3a66878a1829..1b853c34d301 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -1,5 +1,5 @@
menu "Core Netfilter Configuration"
- depends on NET && NETFILTER
+ depends on NET && INET && NETFILTER
config NETFILTER_NETLINK
tristate "Netfilter netlink interface"
diff --git a/net/netfilter/xt_CONNMARK.c b/net/netfilter/xt_CONNMARK.c
index b5548239d412..0534bfa65cce 100644
--- a/net/netfilter/xt_CONNMARK.c
+++ b/net/netfilter/xt_CONNMARK.c
@@ -96,6 +96,11 @@ checkentry(const char *tablename,
{
struct xt_connmark_target_info *matchinfo = targinfo;
+ if (nf_ct_l3proto_try_module_get(target->family) < 0) {
+ printk(KERN_WARNING "can't load conntrack support for "
+ "proto=%d\n", target->family);
+ return 0;
+ }
if (matchinfo->mode == XT_CONNMARK_RESTORE) {
if (strcmp(tablename, "mangle") != 0) {
printk(KERN_WARNING "CONNMARK: restore can only be "
@@ -111,6 +116,12 @@ checkentry(const char *tablename,
return 1;
}
+static void
+destroy(const struct xt_target *target, void *targinfo)
+{
+ nf_ct_l3proto_module_put(target->family);
+}
+
#ifdef CONFIG_COMPAT
struct compat_xt_connmark_target_info {
compat_ulong_t mark, mask;
@@ -147,6 +158,7 @@ static struct xt_target xt_connmark_target[] = {
.name = "CONNMARK",
.family = AF_INET,
.checkentry = checkentry,
+ .destroy = destroy,
.target = target,
.targetsize = sizeof(struct xt_connmark_target_info),
#ifdef CONFIG_COMPAT
@@ -160,6 +172,7 @@ static struct xt_target xt_connmark_target[] = {
.name = "CONNMARK",
.family = AF_INET6,
.checkentry = checkentry,
+ .destroy = destroy,
.target = target,
.targetsize = sizeof(struct xt_connmark_target_info),
.me = THIS_MODULE
@@ -168,7 +181,6 @@ static struct xt_target xt_connmark_target[] = {
static int __init xt_connmark_init(void)
{
- need_conntrack();
return xt_register_targets(xt_connmark_target,
ARRAY_SIZE(xt_connmark_target));
}
diff --git a/net/netfilter/xt_CONNSECMARK.c b/net/netfilter/xt_CONNSECMARK.c
index 467386266674..a3fe3c334b09 100644
--- a/net/netfilter/xt_CONNSECMARK.c
+++ b/net/netfilter/xt_CONNSECMARK.c
@@ -93,6 +93,11 @@ static int checkentry(const char *tablename, const void *entry,
{
struct xt_connsecmark_target_info *info = targinfo;
+ if (nf_ct_l3proto_try_module_get(target->family) < 0) {
+ printk(KERN_WARNING "can't load conntrack support for "
+ "proto=%d\n", target->family);
+ return 0;
+ }
switch (info->mode) {
case CONNSECMARK_SAVE:
case CONNSECMARK_RESTORE:
@@ -106,11 +111,18 @@ static int checkentry(const char *tablename, const void *entry,
return 1;
}
+static void
+destroy(const struct xt_target *target, void *targinfo)
+{
+ nf_ct_l3proto_module_put(target->family);
+}
+
static struct xt_target xt_connsecmark_target[] = {
{
.name = "CONNSECMARK",
.family = AF_INET,
.checkentry = checkentry,
+ .destroy = destroy,
.target = target,
.targetsize = sizeof(struct xt_connsecmark_target_info),
.table = "mangle",
@@ -120,6 +132,7 @@ static struct xt_target xt_connsecmark_target[] = {
.name = "CONNSECMARK",
.family = AF_INET6,
.checkentry = checkentry,
+ .destroy = destroy,
.target = target,
.targetsize = sizeof(struct xt_connsecmark_target_info),
.table = "mangle",
@@ -129,7 +142,6 @@ static struct xt_target xt_connsecmark_target[] = {
static int __init xt_connsecmark_init(void)
{
- need_conntrack();
return xt_register_targets(xt_connsecmark_target,
ARRAY_SIZE(xt_connsecmark_target));
}
diff --git a/net/netfilter/xt_connbytes.c b/net/netfilter/xt_connbytes.c
index dcc497ea8183..d93cb096a675 100644
--- a/net/netfilter/xt_connbytes.c
+++ b/net/netfilter/xt_connbytes.c
@@ -139,15 +139,28 @@ static int check(const char *tablename,
sinfo->direction != XT_CONNBYTES_DIR_BOTH)
return 0;
+ if (nf_ct_l3proto_try_module_get(match->family) < 0) {
+ printk(KERN_WARNING "can't load conntrack support for "
+ "proto=%d\n", match->family);
+ return 0;
+ }
+
return 1;
}
+static void
+destroy(const struct xt_match *match, void *matchinfo)
+{
+ nf_ct_l3proto_module_put(match->family);
+}
+
static struct xt_match xt_connbytes_match[] = {
{
.name = "connbytes",
.family = AF_INET,
.checkentry = check,
.match = match,
+ .destroy = destroy,
.matchsize = sizeof(struct xt_connbytes_info),
.me = THIS_MODULE
},
@@ -156,6 +169,7 @@ static struct xt_match xt_connbytes_match[] = {
.family = AF_INET6,
.checkentry = check,
.match = match,
+ .destroy = destroy,
.matchsize = sizeof(struct xt_connbytes_info),
.me = THIS_MODULE
},
diff --git a/net/netfilter/xt_connmark.c b/net/netfilter/xt_connmark.c
index a8f03057dbde..36c2defff238 100644
--- a/net/netfilter/xt_connmark.c
+++ b/net/netfilter/xt_connmark.c
@@ -63,22 +63,18 @@ checkentry(const char *tablename,
printk(KERN_WARNING "connmark: only support 32bit mark\n");
return 0;
}
-#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
if (nf_ct_l3proto_try_module_get(match->family) < 0) {
- printk(KERN_WARNING "can't load nf_conntrack support for "
+ printk(KERN_WARNING "can't load conntrack support for "
"proto=%d\n", match->family);
return 0;
}
-#endif
return 1;
}
static void
destroy(const struct xt_match *match, void *matchinfo)
{
-#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
nf_ct_l3proto_module_put(match->family);
-#endif
}
#ifdef CONFIG_COMPAT
@@ -140,7 +136,6 @@ static struct xt_match xt_connmark_match[] = {
static int __init xt_connmark_init(void)
{
- need_conntrack();
return xt_register_matches(xt_connmark_match,
ARRAY_SIZE(xt_connmark_match));
}
diff --git a/net/netfilter/xt_conntrack.c b/net/netfilter/xt_conntrack.c
index 0ea501a2fda5..3dc2357b8de8 100644
--- a/net/netfilter/xt_conntrack.c
+++ b/net/netfilter/xt_conntrack.c
@@ -20,6 +20,7 @@
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter/xt_conntrack.h>
+#include <net/netfilter/nf_conntrack_compat.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
@@ -228,21 +229,17 @@ checkentry(const char *tablename,
void *matchinfo,
unsigned int hook_mask)
{
-#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
if (nf_ct_l3proto_try_module_get(match->family) < 0) {
- printk(KERN_WARNING "can't load nf_conntrack support for "
+ printk(KERN_WARNING "can't load conntrack support for "
"proto=%d\n", match->family);
return 0;
}
-#endif
return 1;
}
static void destroy(const struct xt_match *match, void *matchinfo)
{
-#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
nf_ct_l3proto_module_put(match->family);
-#endif
}
static struct xt_match conntrack_match = {
@@ -257,7 +254,6 @@ static struct xt_match conntrack_match = {
static int __init xt_conntrack_init(void)
{
- need_conntrack();
return xt_register_match(&conntrack_match);
}
diff --git a/net/netfilter/xt_helper.c b/net/netfilter/xt_helper.c
index 5d7818b73e3a..04bc32ba7195 100644
--- a/net/netfilter/xt_helper.c
+++ b/net/netfilter/xt_helper.c
@@ -24,6 +24,7 @@
#endif
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter/xt_helper.h>
+#include <net/netfilter/nf_conntrack_compat.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Martin Josefsson <gandalf@netfilter.org>");
@@ -143,13 +144,11 @@ static int check(const char *tablename,
{
struct xt_helper_info *info = matchinfo;
-#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
if (nf_ct_l3proto_try_module_get(match->family) < 0) {
- printk(KERN_WARNING "can't load nf_conntrack support for "
+ printk(KERN_WARNING "can't load conntrack support for "
"proto=%d\n", match->family);
return 0;
}
-#endif
info->name[29] = '\0';
return 1;
}
@@ -157,9 +156,7 @@ static int check(const char *tablename,
static void
destroy(const struct xt_match *match, void *matchinfo)
{
-#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
nf_ct_l3proto_module_put(match->family);
-#endif
}
static struct xt_match xt_helper_match[] = {
@@ -185,7 +182,6 @@ static struct xt_match xt_helper_match[] = {
static int __init xt_helper_init(void)
{
- need_conntrack();
return xt_register_matches(xt_helper_match,
ARRAY_SIZE(xt_helper_match));
}
diff --git a/net/netfilter/xt_physdev.c b/net/netfilter/xt_physdev.c
index fd8f954cded5..b9b3ffc5451d 100644
--- a/net/netfilter/xt_physdev.c
+++ b/net/netfilter/xt_physdev.c
@@ -113,20 +113,16 @@ checkentry(const char *tablename,
if (!(info->bitmask & XT_PHYSDEV_OP_MASK) ||
info->bitmask & ~XT_PHYSDEV_OP_MASK)
return 0;
- if (brnf_deferred_hooks == 0 &&
- info->bitmask & XT_PHYSDEV_OP_OUT &&
+ if (info->bitmask & XT_PHYSDEV_OP_OUT &&
(!(info->bitmask & XT_PHYSDEV_OP_BRIDGED) ||
info->invert & XT_PHYSDEV_OP_BRIDGED) &&
hook_mask & ((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_FORWARD) |
(1 << NF_IP_POST_ROUTING))) {
printk(KERN_WARNING "physdev match: using --physdev-out in the "
"OUTPUT, FORWARD and POSTROUTING chains for non-bridged "
- "traffic is deprecated and breaks other things, it will "
- "be removed in January 2007. See Documentation/"
- "feature-removal-schedule.txt for details. This doesn't "
- "affect you in case you're using it for purely bridged "
- "traffic.\n");
- brnf_deferred_hooks = 1;
+ "traffic is not supported anymore.\n");
+ if (hook_mask & (1 << NF_IP_LOCAL_OUT))
+ return 0;
}
return 1;
}
diff --git a/net/netfilter/xt_state.c b/net/netfilter/xt_state.c
index d9010b16a1f9..df37b912163a 100644
--- a/net/netfilter/xt_state.c
+++ b/net/netfilter/xt_state.c
@@ -50,22 +50,18 @@ static int check(const char *tablename,
void *matchinfo,
unsigned int hook_mask)
{
-#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
if (nf_ct_l3proto_try_module_get(match->family) < 0) {
- printk(KERN_WARNING "can't load nf_conntrack support for "
+ printk(KERN_WARNING "can't load conntrack support for "
"proto=%d\n", match->family);
return 0;
}
-#endif
return 1;
}
static void
destroy(const struct xt_match *match, void *matchinfo)
{
-#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
nf_ct_l3proto_module_put(match->family);
-#endif
}
static struct xt_match xt_state_match[] = {
@@ -91,7 +87,6 @@ static struct xt_match xt_state_match[] = {
static int __init xt_state_init(void)
{
- need_conntrack();
return xt_register_matches(xt_state_match, ARRAY_SIZE(xt_state_match));
}
diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c
index 743b05734a49..4afc75f9e377 100644
--- a/net/netlabel/netlabel_cipso_v4.c
+++ b/net/netlabel/netlabel_cipso_v4.c
@@ -162,6 +162,7 @@ static int netlbl_cipsov4_add_std(struct genl_info *info)
struct nlattr *nla_b;
int nla_a_rem;
int nla_b_rem;
+ u32 iter;
if (!info->attrs[NLBL_CIPSOV4_A_TAGLST] ||
!info->attrs[NLBL_CIPSOV4_A_MLSLVLLST])
@@ -185,20 +186,31 @@ static int netlbl_cipsov4_add_std(struct genl_info *info)
ret_val = netlbl_cipsov4_add_common(info, doi_def);
if (ret_val != 0)
goto add_std_failure;
+ ret_val = -EINVAL;
nla_for_each_nested(nla_a,
info->attrs[NLBL_CIPSOV4_A_MLSLVLLST],
nla_a_rem)
if (nla_a->nla_type == NLBL_CIPSOV4_A_MLSLVL) {
+ if (nla_validate_nested(nla_a,
+ NLBL_CIPSOV4_A_MAX,
+ netlbl_cipsov4_genl_policy) != 0)
+ goto add_std_failure;
nla_for_each_nested(nla_b, nla_a, nla_b_rem)
switch (nla_b->nla_type) {
case NLBL_CIPSOV4_A_MLSLVLLOC:
+ if (nla_get_u32(nla_b) >
+ CIPSO_V4_MAX_LOC_LVLS)
+ goto add_std_failure;
if (nla_get_u32(nla_b) >=
doi_def->map.std->lvl.local_size)
doi_def->map.std->lvl.local_size =
nla_get_u32(nla_b) + 1;
break;
case NLBL_CIPSOV4_A_MLSLVLREM:
+ if (nla_get_u32(nla_b) >
+ CIPSO_V4_MAX_REM_LVLS)
+ goto add_std_failure;
if (nla_get_u32(nla_b) >=
doi_def->map.std->lvl.cipso_size)
doi_def->map.std->lvl.cipso_size =
@@ -206,9 +218,6 @@ static int netlbl_cipsov4_add_std(struct genl_info *info)
break;
}
}
- if (doi_def->map.std->lvl.local_size > CIPSO_V4_MAX_LOC_LVLS ||
- doi_def->map.std->lvl.cipso_size > CIPSO_V4_MAX_REM_LVLS)
- goto add_std_failure;
doi_def->map.std->lvl.local = kcalloc(doi_def->map.std->lvl.local_size,
sizeof(u32),
GFP_KERNEL);
@@ -223,6 +232,10 @@ static int netlbl_cipsov4_add_std(struct genl_info *info)
ret_val = -ENOMEM;
goto add_std_failure;
}
+ for (iter = 0; iter < doi_def->map.std->lvl.local_size; iter++)
+ doi_def->map.std->lvl.local[iter] = CIPSO_V4_INV_LVL;
+ for (iter = 0; iter < doi_def->map.std->lvl.cipso_size; iter++)
+ doi_def->map.std->lvl.cipso[iter] = CIPSO_V4_INV_LVL;
nla_for_each_nested(nla_a,
info->attrs[NLBL_CIPSOV4_A_MLSLVLLST],
nla_a_rem)
@@ -230,11 +243,6 @@ static int netlbl_cipsov4_add_std(struct genl_info *info)
struct nlattr *lvl_loc;
struct nlattr *lvl_rem;
- if (nla_validate_nested(nla_a,
- NLBL_CIPSOV4_A_MAX,
- netlbl_cipsov4_genl_policy) != 0)
- goto add_std_failure;
-
lvl_loc = nla_find_nested(nla_a,
NLBL_CIPSOV4_A_MLSLVLLOC);
lvl_rem = nla_find_nested(nla_a,
@@ -264,12 +272,18 @@ static int netlbl_cipsov4_add_std(struct genl_info *info)
nla_for_each_nested(nla_b, nla_a, nla_b_rem)
switch (nla_b->nla_type) {
case NLBL_CIPSOV4_A_MLSCATLOC:
+ if (nla_get_u32(nla_b) >
+ CIPSO_V4_MAX_LOC_CATS)
+ goto add_std_failure;
if (nla_get_u32(nla_b) >=
doi_def->map.std->cat.local_size)
doi_def->map.std->cat.local_size =
nla_get_u32(nla_b) + 1;
break;
case NLBL_CIPSOV4_A_MLSCATREM:
+ if (nla_get_u32(nla_b) >
+ CIPSO_V4_MAX_REM_CATS)
+ goto add_std_failure;
if (nla_get_u32(nla_b) >=
doi_def->map.std->cat.cipso_size)
doi_def->map.std->cat.cipso_size =
@@ -277,9 +291,6 @@ static int netlbl_cipsov4_add_std(struct genl_info *info)
break;
}
}
- if (doi_def->map.std->cat.local_size > CIPSO_V4_MAX_LOC_CATS ||
- doi_def->map.std->cat.cipso_size > CIPSO_V4_MAX_REM_CATS)
- goto add_std_failure;
doi_def->map.std->cat.local = kcalloc(
doi_def->map.std->cat.local_size,
sizeof(u32),
@@ -296,6 +307,10 @@ static int netlbl_cipsov4_add_std(struct genl_info *info)
ret_val = -ENOMEM;
goto add_std_failure;
}
+ for (iter = 0; iter < doi_def->map.std->cat.local_size; iter++)
+ doi_def->map.std->cat.local[iter] = CIPSO_V4_INV_CAT;
+ for (iter = 0; iter < doi_def->map.std->cat.cipso_size; iter++)
+ doi_def->map.std->cat.cipso[iter] = CIPSO_V4_INV_CAT;
nla_for_each_nested(nla_a,
info->attrs[NLBL_CIPSOV4_A_MLSCATLST],
nla_a_rem)
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
index 1d50f801f181..43bbe2c9e49a 100644
--- a/net/netrom/af_netrom.c
+++ b/net/netrom/af_netrom.c
@@ -1377,6 +1377,15 @@ static struct notifier_block nr_dev_notifier = {
static struct net_device **dev_nr;
+static struct ax25_protocol nr_pid = {
+ .pid = AX25_P_NETROM,
+ .func = nr_route_frame
+};
+
+static struct ax25_linkfail nr_linkfail_notifier = {
+ .func = nr_link_failed,
+};
+
static int __init nr_proto_init(void)
{
int i;
@@ -1424,8 +1433,8 @@ static int __init nr_proto_init(void)
register_netdevice_notifier(&nr_dev_notifier);
- ax25_protocol_register(AX25_P_NETROM, nr_route_frame);
- ax25_linkfail_register(nr_link_failed);
+ ax25_register_pid(&nr_pid);
+ ax25_linkfail_register(&nr_linkfail_notifier);
#ifdef CONFIG_SYSCTL
nr_register_sysctl();
@@ -1474,7 +1483,7 @@ static void __exit nr_exit(void)
nr_unregister_sysctl();
#endif
- ax25_linkfail_release(nr_link_failed);
+ ax25_linkfail_release(&nr_linkfail_notifier);
ax25_protocol_release(AX25_P_NETROM);
unregister_netdevice_notifier(&nr_dev_notifier);
diff --git a/net/netrom/nr_dev.c b/net/netrom/nr_dev.c
index 9b8eb54971ab..4700d5225b78 100644
--- a/net/netrom/nr_dev.c
+++ b/net/netrom/nr_dev.c
@@ -128,25 +128,37 @@ static int nr_header(struct sk_buff *skb, struct net_device *dev, unsigned short
return -37;
}
-static int nr_set_mac_address(struct net_device *dev, void *addr)
+static int __must_check nr_set_mac_address(struct net_device *dev, void *addr)
{
struct sockaddr *sa = addr;
+ int err;
+
+ if (!memcmp(dev->dev_addr, sa->sa_data, dev->addr_len))
+ return 0;
+
+ if (dev->flags & IFF_UP) {
+ err = ax25_listen_register((ax25_address *)sa->sa_data, NULL);
+ if (err)
+ return err;
- if (dev->flags & IFF_UP)
ax25_listen_release((ax25_address *)dev->dev_addr, NULL);
+ }
memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
- if (dev->flags & IFF_UP)
- ax25_listen_register((ax25_address *)dev->dev_addr, NULL);
-
return 0;
}
static int nr_open(struct net_device *dev)
{
+ int err;
+
+ err = ax25_listen_register((ax25_address *)dev->dev_addr, NULL);
+ if (err)
+ return err;
+
netif_start_queue(dev);
- ax25_listen_register((ax25_address *)dev->dev_addr, NULL);
+
return 0;
}
diff --git a/net/netrom/nr_route.c b/net/netrom/nr_route.c
index 0096105bcd47..8f88964099ef 100644
--- a/net/netrom/nr_route.c
+++ b/net/netrom/nr_route.c
@@ -87,8 +87,9 @@ static void nr_remove_neigh(struct nr_neigh *);
* Add a new route to a node, and in the process add the node and the
* neighbour if it is new.
*/
-static int nr_add_node(ax25_address *nr, const char *mnemonic, ax25_address *ax25,
- ax25_digi *ax25_digi, struct net_device *dev, int quality, int obs_count)
+static int __must_check nr_add_node(ax25_address *nr, const char *mnemonic,
+ ax25_address *ax25, ax25_digi *ax25_digi, struct net_device *dev,
+ int quality, int obs_count)
{
struct nr_node *nr_node;
struct nr_neigh *nr_neigh;
@@ -406,7 +407,8 @@ static int nr_del_node(ax25_address *callsign, ax25_address *neighbour, struct n
/*
* Lock a neighbour with a quality.
*/
-static int nr_add_neigh(ax25_address *callsign, ax25_digi *ax25_digi, struct net_device *dev, unsigned int quality)
+static int __must_check nr_add_neigh(ax25_address *callsign,
+ ax25_digi *ax25_digi, struct net_device *dev, unsigned int quality)
{
struct nr_neigh *nr_neigh;
@@ -777,9 +779,13 @@ int nr_route_frame(struct sk_buff *skb, ax25_cb *ax25)
nr_src = (ax25_address *)(skb->data + 0);
nr_dest = (ax25_address *)(skb->data + 7);
- if (ax25 != NULL)
- nr_add_node(nr_src, "", &ax25->dest_addr, ax25->digipeat,
- ax25->ax25_dev->dev, 0, sysctl_netrom_obsolescence_count_initialiser);
+ if (ax25 != NULL) {
+ ret = nr_add_node(nr_src, "", &ax25->dest_addr, ax25->digipeat,
+ ax25->ax25_dev->dev, 0,
+ sysctl_netrom_obsolescence_count_initialiser);
+ if (ret)
+ return ret;
+ }
if ((dev = nr_dev_get(nr_dest)) != NULL) { /* Its for me */
if (ax25 == NULL) /* Its from me */
@@ -844,6 +850,7 @@ int nr_route_frame(struct sk_buff *skb, ax25_cb *ax25)
ret = (nr_neigh->ax25 != NULL);
nr_node_unlock(nr_node);
nr_node_put(nr_node);
+
return ret;
}
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
index 08a542855654..9e279464c9d1 100644
--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -1314,7 +1314,8 @@ static int rose_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
if (copy_from_user(&rose_callsign, argp, sizeof(ax25_address)))
return -EFAULT;
if (ax25cmp(&rose_callsign, &null_ax25_address) != 0)
- ax25_listen_register(&rose_callsign, NULL);
+ return ax25_listen_register(&rose_callsign, NULL);
+
return 0;
case SIOCRSGL2CALL:
@@ -1481,6 +1482,15 @@ static struct notifier_block rose_dev_notifier = {
static struct net_device **dev_rose;
+static struct ax25_protocol rose_pid = {
+ .pid = AX25_P_ROSE,
+ .func = rose_route_frame
+};
+
+static struct ax25_linkfail rose_linkfail_notifier = {
+ .func = rose_link_failed
+};
+
static int __init rose_proto_init(void)
{
int i;
@@ -1530,8 +1540,8 @@ static int __init rose_proto_init(void)
sock_register(&rose_family_ops);
register_netdevice_notifier(&rose_dev_notifier);
- ax25_protocol_register(AX25_P_ROSE, rose_route_frame);
- ax25_linkfail_register(rose_link_failed);
+ ax25_register_pid(&rose_pid);
+ ax25_linkfail_register(&rose_linkfail_notifier);
#ifdef CONFIG_SYSCTL
rose_register_sysctl();
@@ -1579,7 +1589,7 @@ static void __exit rose_exit(void)
rose_rt_free();
ax25_protocol_release(AX25_P_ROSE);
- ax25_linkfail_release(rose_link_failed);
+ ax25_linkfail_release(&rose_linkfail_notifier);
if (ax25cmp(&rose_callsign, &null_ax25_address) != 0)
ax25_listen_release(&rose_callsign, NULL);
diff --git a/net/rose/rose_dev.c b/net/rose/rose_dev.c
index 7c279e2659ec..50824d345fa6 100644
--- a/net/rose/rose_dev.c
+++ b/net/rose/rose_dev.c
@@ -93,20 +93,34 @@ static int rose_rebuild_header(struct sk_buff *skb)
static int rose_set_mac_address(struct net_device *dev, void *addr)
{
struct sockaddr *sa = addr;
+ int err;
- rose_del_loopback_node((rose_address *)dev->dev_addr);
+ if (!memcpy(dev->dev_addr, sa->sa_data, dev->addr_len))
+ return 0;
- memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
+ if (dev->flags & IFF_UP) {
+ err = rose_add_loopback_node((rose_address *)dev->dev_addr);
+ if (err)
+ return err;
+
+ rose_del_loopback_node((rose_address *)dev->dev_addr);
+ }
- rose_add_loopback_node((rose_address *)dev->dev_addr);
+ memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
return 0;
}
static int rose_open(struct net_device *dev)
{
+ int err;
+
+ err = rose_add_loopback_node((rose_address *)dev->dev_addr);
+ if (err)
+ return err;
+
netif_start_queue(dev);
- rose_add_loopback_node((rose_address *)dev->dev_addr);
+
return 0;
}
diff --git a/net/rose/rose_loopback.c b/net/rose/rose_loopback.c
index 103b4d38f88a..3e41bd93ab9f 100644
--- a/net/rose/rose_loopback.c
+++ b/net/rose/rose_loopback.c
@@ -79,7 +79,8 @@ static void rose_loopback_timer(unsigned long param)
skb->h.raw = skb->data;
- if ((sk = rose_find_socket(lci_o, rose_loopback_neigh)) != NULL) {
+ sk = rose_find_socket(lci_o, &rose_loopback_neigh);
+ if (sk) {
if (rose_process_rx_frame(sk, skb) == 0)
kfree_skb(skb);
continue;
@@ -87,7 +88,7 @@ static void rose_loopback_timer(unsigned long param)
if (frametype == ROSE_CALL_REQUEST) {
if ((dev = rose_dev_get(dest)) != NULL) {
- if (rose_rx_call_request(skb, dev, rose_loopback_neigh, lci_o) == 0)
+ if (rose_rx_call_request(skb, dev, &rose_loopback_neigh, lci_o) == 0)
kfree_skb(skb);
} else {
kfree_skb(skb);
diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
index 7252344779a0..8028c0d425dc 100644
--- a/net/rose/rose_route.c
+++ b/net/rose/rose_route.c
@@ -46,13 +46,13 @@ static DEFINE_SPINLOCK(rose_neigh_list_lock);
static struct rose_route *rose_route_list;
static DEFINE_SPINLOCK(rose_route_list_lock);
-struct rose_neigh *rose_loopback_neigh;
+struct rose_neigh rose_loopback_neigh;
/*
* Add a new route to a node, and in the process add the node and the
* neighbour if it is new.
*/
-static int rose_add_node(struct rose_route_struct *rose_route,
+static int __must_check rose_add_node(struct rose_route_struct *rose_route,
struct net_device *dev)
{
struct rose_node *rose_node, *rose_tmpn, *rose_tmpp;
@@ -361,33 +361,30 @@ out:
/*
* Add the loopback neighbour.
*/
-int rose_add_loopback_neigh(void)
+void rose_add_loopback_neigh(void)
{
- if ((rose_loopback_neigh = kmalloc(sizeof(struct rose_neigh), GFP_ATOMIC)) == NULL)
- return -ENOMEM;
+ struct rose_neigh *sn = &rose_loopback_neigh;
- rose_loopback_neigh->callsign = null_ax25_address;
- rose_loopback_neigh->digipeat = NULL;
- rose_loopback_neigh->ax25 = NULL;
- rose_loopback_neigh->dev = NULL;
- rose_loopback_neigh->count = 0;
- rose_loopback_neigh->use = 0;
- rose_loopback_neigh->dce_mode = 1;
- rose_loopback_neigh->loopback = 1;
- rose_loopback_neigh->number = rose_neigh_no++;
- rose_loopback_neigh->restarted = 1;
+ sn->callsign = null_ax25_address;
+ sn->digipeat = NULL;
+ sn->ax25 = NULL;
+ sn->dev = NULL;
+ sn->count = 0;
+ sn->use = 0;
+ sn->dce_mode = 1;
+ sn->loopback = 1;
+ sn->number = rose_neigh_no++;
+ sn->restarted = 1;
- skb_queue_head_init(&rose_loopback_neigh->queue);
+ skb_queue_head_init(&sn->queue);
- init_timer(&rose_loopback_neigh->ftimer);
- init_timer(&rose_loopback_neigh->t0timer);
+ init_timer(&sn->ftimer);
+ init_timer(&sn->t0timer);
spin_lock_bh(&rose_neigh_list_lock);
- rose_loopback_neigh->next = rose_neigh_list;
- rose_neigh_list = rose_loopback_neigh;
+ sn->next = rose_neigh_list;
+ rose_neigh_list = sn;
spin_unlock_bh(&rose_neigh_list_lock);
-
- return 0;
}
/*
@@ -421,13 +418,13 @@ int rose_add_loopback_node(rose_address *address)
rose_node->mask = 10;
rose_node->count = 1;
rose_node->loopback = 1;
- rose_node->neighbour[0] = rose_loopback_neigh;
+ rose_node->neighbour[0] = &rose_loopback_neigh;
/* Insert at the head of list. Address is always mask=10 */
rose_node->next = rose_node_list;
rose_node_list = rose_node;
- rose_loopback_neigh->count++;
+ rose_loopback_neigh.count++;
out:
spin_unlock_bh(&rose_node_list_lock);
@@ -458,7 +455,7 @@ void rose_del_loopback_node(rose_address *address)
rose_remove_node(rose_node);
- rose_loopback_neigh->count--;
+ rose_loopback_neigh.count--;
out:
spin_unlock_bh(&rose_node_list_lock);
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index ad0057db0f91..5db95caed0a3 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -298,6 +298,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
asoc->default_flags = sp->default_flags;
asoc->default_context = sp->default_context;
asoc->default_timetolive = sp->default_timetolive;
+ asoc->default_rcv_context = sp->default_rcv_context;
return asoc;
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index 3c3e560087ca..ef36be073a13 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -78,8 +78,44 @@
#include <asm/uaccess.h>
+/* Event handler for inet6 address addition/deletion events. */
+static int sctp_inet6addr_event(struct notifier_block *this, unsigned long ev,
+ void *ptr)
+{
+ struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr;
+ struct sctp_sockaddr_entry *addr;
+ struct list_head *pos, *temp;
+
+ switch (ev) {
+ case NETDEV_UP:
+ addr = kmalloc(sizeof(struct sctp_sockaddr_entry), GFP_ATOMIC);
+ if (addr) {
+ addr->a.v6.sin6_family = AF_INET6;
+ addr->a.v6.sin6_port = 0;
+ memcpy(&addr->a.v6.sin6_addr, &ifa->addr,
+ sizeof(struct in6_addr));
+ addr->a.v6.sin6_scope_id = ifa->idev->dev->ifindex;
+ list_add_tail(&addr->list, &sctp_local_addr_list);
+ }
+ break;
+ case NETDEV_DOWN:
+ list_for_each_safe(pos, temp, &sctp_local_addr_list) {
+ addr = list_entry(pos, struct sctp_sockaddr_entry, list);
+ if (ipv6_addr_equal(&addr->a.v6.sin6_addr, &ifa->addr)) {
+ list_del(pos);
+ kfree(addr);
+ break;
+ }
+ }
+
+ break;
+ }
+
+ return NOTIFY_DONE;
+}
+
static struct notifier_block sctp_inet6addr_notifier = {
- .notifier_call = sctp_inetaddr_event,
+ .notifier_call = sctp_inet6addr_event,
};
/* ICMP error handler. */
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index f2ba8615895b..225f39b5d595 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -163,7 +163,7 @@ static void sctp_v4_copy_addrlist(struct list_head *addrlist,
/* Extract our IP addresses from the system and stash them in the
* protocol structure.
*/
-static void __sctp_get_local_addr_list(void)
+static void sctp_get_local_addr_list(void)
{
struct net_device *dev;
struct list_head *pos;
@@ -179,17 +179,8 @@ static void __sctp_get_local_addr_list(void)
read_unlock(&dev_base_lock);
}
-static void sctp_get_local_addr_list(void)
-{
- unsigned long flags;
-
- sctp_spin_lock_irqsave(&sctp_local_addr_lock, flags);
- __sctp_get_local_addr_list();
- sctp_spin_unlock_irqrestore(&sctp_local_addr_lock, flags);
-}
-
/* Free the existing local addresses. */
-static void __sctp_free_local_addr_list(void)
+static void sctp_free_local_addr_list(void)
{
struct sctp_sockaddr_entry *addr;
struct list_head *pos, *temp;
@@ -201,27 +192,15 @@ static void __sctp_free_local_addr_list(void)
}
}
-/* Free the existing local addresses. */
-static void sctp_free_local_addr_list(void)
-{
- unsigned long flags;
-
- sctp_spin_lock_irqsave(&sctp_local_addr_lock, flags);
- __sctp_free_local_addr_list();
- sctp_spin_unlock_irqrestore(&sctp_local_addr_lock, flags);
-}
-
/* 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,
gfp_t gfp, int copy_flags)
{
struct sctp_sockaddr_entry *addr;
int error = 0;
- struct list_head *pos;
- unsigned long flags;
+ struct list_head *pos, *temp;
- sctp_spin_lock_irqsave(&sctp_local_addr_lock, flags);
- list_for_each(pos, &sctp_local_addr_list) {
+ list_for_each_safe(pos, temp, &sctp_local_addr_list) {
addr = list_entry(pos, struct sctp_sockaddr_entry, list);
if (sctp_in_scope(&addr->a, scope)) {
/* Now that the address is in scope, check to see if
@@ -242,7 +221,6 @@ int sctp_copy_local_addr_list(struct sctp_bind_addr *bp, sctp_scope_t scope,
}
end_copy:
- sctp_spin_unlock_irqrestore(&sctp_local_addr_lock, flags);
return error;
}
@@ -622,18 +600,36 @@ static void sctp_v4_seq_dump_addr(struct seq_file *seq, union sctp_addr *addr)
seq_printf(seq, "%d.%d.%d.%d ", NIPQUAD(addr->v4.sin_addr));
}
-/* Event handler for inet address addition/deletion events.
- * Basically, whenever there is an event, we re-build our local address list.
- */
-int sctp_inetaddr_event(struct notifier_block *this, unsigned long ev,
- void *ptr)
+/* Event handler for inet address addition/deletion events. */
+static int sctp_inetaddr_event(struct notifier_block *this, unsigned long ev,
+ void *ptr)
{
- unsigned long flags;
+ struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;
+ struct sctp_sockaddr_entry *addr;
+ struct list_head *pos, *temp;
- sctp_spin_lock_irqsave(&sctp_local_addr_lock, flags);
- __sctp_free_local_addr_list();
- __sctp_get_local_addr_list();
- sctp_spin_unlock_irqrestore(&sctp_local_addr_lock, flags);
+ switch (ev) {
+ case NETDEV_UP:
+ addr = kmalloc(sizeof(struct sctp_sockaddr_entry), GFP_ATOMIC);
+ if (addr) {
+ addr->a.v4.sin_family = AF_INET;
+ addr->a.v4.sin_port = 0;
+ addr->a.v4.sin_addr.s_addr = ifa->ifa_local;
+ list_add_tail(&addr->list, &sctp_local_addr_list);
+ }
+ break;
+ case NETDEV_DOWN:
+ list_for_each_safe(pos, temp, &sctp_local_addr_list) {
+ addr = list_entry(pos, struct sctp_sockaddr_entry, list);
+ if (addr->a.v4.sin_addr.s_addr == ifa->ifa_local) {
+ list_del(pos);
+ kfree(addr);
+ break;
+ }
+ }
+
+ break;
+ }
return NOTIFY_DONE;
}
@@ -1172,13 +1168,12 @@ SCTP_STATIC __init int sctp_init(void)
/* Initialize the local address list. */
INIT_LIST_HEAD(&sctp_local_addr_list);
- spin_lock_init(&sctp_local_addr_lock);
+
+ sctp_get_local_addr_list();
/* Register notifier for inet address additions/deletions. */
register_inetaddr_notifier(&sctp_inetaddr_notifier);
- sctp_get_local_addr_list();
-
__unsafe(THIS_MODULE);
status = 0;
out:
@@ -1263,6 +1258,7 @@ module_exit(sctp_exit);
* __stringify doesn't likes enums, so use IPPROTO_SCTP value (132) directly.
*/
MODULE_ALIAS("net-pf-" __stringify(PF_INET) "-proto-132");
+MODULE_ALIAS("net-pf-" __stringify(PF_INET6) "-proto-132");
MODULE_AUTHOR("Linux Kernel SCTP developers <lksctp-developers@lists.sourceforge.net>");
MODULE_DESCRIPTION("Support for the SCTP protocol (RFC2960)");
MODULE_LICENSE("GPL");
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 30927d3a597f..f0bbe36799cf 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -184,7 +184,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
struct sctp_sock *sp;
sctp_supported_addrs_param_t sat;
__be16 types[2];
- sctp_adaption_ind_param_t aiparam;
+ sctp_adaptation_ind_param_t aiparam;
/* RFC 2960 3.3.2 Initiation (INIT) (1)
*
@@ -249,9 +249,9 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
sctp_addto_chunk(retval, sizeof(ecap_param), &ecap_param);
if (sctp_prsctp_enable)
sctp_addto_chunk(retval, sizeof(prsctp_param), &prsctp_param);
- aiparam.param_hdr.type = SCTP_PARAM_ADAPTION_LAYER_IND;
+ aiparam.param_hdr.type = SCTP_PARAM_ADAPTATION_LAYER_IND;
aiparam.param_hdr.length = htons(sizeof(aiparam));
- aiparam.adaption_ind = htonl(sp->adaption_ind);
+ aiparam.adaptation_ind = htonl(sp->adaptation_ind);
sctp_addto_chunk(retval, sizeof(aiparam), &aiparam);
nodata:
kfree(addrs.v);
@@ -269,7 +269,7 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
sctp_cookie_param_t *cookie;
int cookie_len;
size_t chunksize;
- sctp_adaption_ind_param_t aiparam;
+ sctp_adaptation_ind_param_t aiparam;
retval = NULL;
@@ -323,9 +323,9 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
if (asoc->peer.prsctp_capable)
sctp_addto_chunk(retval, sizeof(prsctp_param), &prsctp_param);
- aiparam.param_hdr.type = SCTP_PARAM_ADAPTION_LAYER_IND;
+ aiparam.param_hdr.type = SCTP_PARAM_ADAPTATION_LAYER_IND;
aiparam.param_hdr.length = htons(sizeof(aiparam));
- aiparam.adaption_ind = htonl(sctp_sk(asoc->base.sk)->adaption_ind);
+ aiparam.adaptation_ind = htonl(sctp_sk(asoc->base.sk)->adaptation_ind);
sctp_addto_chunk(retval, sizeof(aiparam), &aiparam);
/* We need to remove the const qualifier at this point. */
@@ -1300,8 +1300,8 @@ static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep,
/* Remember PR-SCTP capability. */
cookie->c.prsctp_capable = asoc->peer.prsctp_capable;
- /* Save adaption indication in the cookie. */
- cookie->c.adaption_ind = asoc->peer.adaption_ind;
+ /* Save adaptation indication in the cookie. */
+ cookie->c.adaptation_ind = asoc->peer.adaptation_ind;
/* Set an expiration time for the cookie. */
do_gettimeofday(&cookie->c.expiration);
@@ -1512,7 +1512,7 @@ no_hmac:
retval->addip_serial = retval->c.initial_tsn;
retval->adv_peer_ack_point = retval->ctsn_ack_point;
retval->peer.prsctp_capable = retval->c.prsctp_capable;
- retval->peer.adaption_ind = retval->c.adaption_ind;
+ retval->peer.adaptation_ind = retval->c.adaptation_ind;
/* The INIT stuff will be done by the side effects. */
return retval;
@@ -1743,7 +1743,7 @@ static int sctp_verify_param(const struct sctp_association *asoc,
case SCTP_PARAM_HEARTBEAT_INFO:
case SCTP_PARAM_UNRECOGNIZED_PARAMETERS:
case SCTP_PARAM_ECN_CAPABLE:
- case SCTP_PARAM_ADAPTION_LAYER_IND:
+ case SCTP_PARAM_ADAPTATION_LAYER_IND:
break;
case SCTP_PARAM_HOST_NAME_ADDRESS:
@@ -2098,8 +2098,8 @@ static int sctp_process_param(struct sctp_association *asoc,
asoc->peer.ecn_capable = 1;
break;
- case SCTP_PARAM_ADAPTION_LAYER_IND:
- asoc->peer.adaption_ind = param.aind->adaption_ind;
+ case SCTP_PARAM_ADAPTATION_LAYER_IND:
+ asoc->peer.adaptation_ind = param.aind->adaptation_ind;
break;
case SCTP_PARAM_FWD_TSN_SUPPORT:
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 27cc444aaf11..aa51d190bfb2 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -688,12 +688,12 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep,
goto nomem_ev;
/* Sockets API Draft Section 5.3.1.6
- * When a peer sends a Adaption Layer Indication parameter , SCTP
+ * When a peer sends a Adaptation Layer Indication parameter , SCTP
* delivers this notification to inform the application that of the
- * peers requested adaption layer.
+ * peers requested adaptation layer.
*/
- if (new_asoc->peer.adaption_ind) {
- ai_ev = sctp_ulpevent_make_adaption_indication(new_asoc,
+ if (new_asoc->peer.adaptation_ind) {
+ ai_ev = sctp_ulpevent_make_adaptation_indication(new_asoc,
GFP_ATOMIC);
if (!ai_ev)
goto nomem_aiev;
@@ -820,12 +820,12 @@ sctp_disposition_t sctp_sf_do_5_1E_ca(const struct sctp_endpoint *ep,
sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev));
/* Sockets API Draft Section 5.3.1.6
- * When a peer sends a Adaption Layer Indication parameter , SCTP
+ * When a peer sends a Adaptation Layer Indication parameter , SCTP
* delivers this notification to inform the application that of the
- * peers requested adaption layer.
+ * peers requested adaptation layer.
*/
- if (asoc->peer.adaption_ind) {
- ev = sctp_ulpevent_make_adaption_indication(asoc, GFP_ATOMIC);
+ if (asoc->peer.adaptation_ind) {
+ ev = sctp_ulpevent_make_adaptation_indication(asoc, GFP_ATOMIC);
if (!ev)
goto nomem;
@@ -1698,12 +1698,12 @@ static sctp_disposition_t sctp_sf_do_dupcook_b(const struct sctp_endpoint *ep,
sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev));
/* Sockets API Draft Section 5.3.1.6
- * When a peer sends a Adaption Layer Indication parameter , SCTP
+ * When a peer sends a Adaptation Layer Indication parameter , SCTP
* delivers this notification to inform the application that of the
- * peers requested adaption layer.
+ * peers requested adaptation layer.
*/
- if (asoc->peer.adaption_ind) {
- ev = sctp_ulpevent_make_adaption_indication(asoc, GFP_ATOMIC);
+ if (asoc->peer.adaptation_ind) {
+ ev = sctp_ulpevent_make_adaptation_indication(asoc, GFP_ATOMIC);
if (!ev)
goto nomem_ev;
@@ -1791,12 +1791,12 @@ static sctp_disposition_t sctp_sf_do_dupcook_d(const struct sctp_endpoint *ep,
goto nomem;
/* Sockets API Draft Section 5.3.1.6
- * When a peer sends a Adaption Layer Indication parameter,
+ * When a peer sends a Adaptation Layer Indication parameter,
* SCTP delivers this notification to inform the application
- * that of the peers requested adaption layer.
+ * that of the peers requested adaptation layer.
*/
- if (asoc->peer.adaption_ind) {
- ai_ev = sctp_ulpevent_make_adaption_indication(asoc,
+ if (asoc->peer.adaptation_ind) {
+ ai_ev = sctp_ulpevent_make_adaptation_indication(asoc,
GFP_ATOMIC);
if (!ai_ev)
goto nomem;
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 1e8132b8c4d9..388d0fb1a377 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -2731,17 +2731,57 @@ static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optva
return err;
}
-static int sctp_setsockopt_adaption_layer(struct sock *sk, char __user *optval,
+static int sctp_setsockopt_adaptation_layer(struct sock *sk, char __user *optval,
int optlen)
{
- struct sctp_setadaption adaption;
+ struct sctp_setadaptation adaptation;
- if (optlen != sizeof(struct sctp_setadaption))
+ if (optlen != sizeof(struct sctp_setadaptation))
return -EINVAL;
- if (copy_from_user(&adaption, optval, optlen))
+ if (copy_from_user(&adaptation, optval, optlen))
return -EFAULT;
- sctp_sk(sk)->adaption_ind = adaption.ssb_adaption_ind;
+ sctp_sk(sk)->adaptation_ind = adaptation.ssb_adaptation_ind;
+
+ return 0;
+}
+
+/*
+ * 7.1.29. Set or Get the default context (SCTP_CONTEXT)
+ *
+ * The context field in the sctp_sndrcvinfo structure is normally only
+ * used when a failed message is retrieved holding the value that was
+ * sent down on the actual send call. This option allows the setting of
+ * a default context on an association basis that will be received on
+ * reading messages from the peer. This is especially helpful in the
+ * one-2-many model for an application to keep some reference to an
+ * internal state machine that is processing messages on the
+ * association. Note that the setting of this value only effects
+ * received messages from the peer and does not effect the value that is
+ * saved with outbound messages.
+ */
+static int sctp_setsockopt_context(struct sock *sk, char __user *optval,
+ int optlen)
+{
+ struct sctp_assoc_value params;
+ struct sctp_sock *sp;
+ struct sctp_association *asoc;
+
+ if (optlen != sizeof(struct sctp_assoc_value))
+ return -EINVAL;
+ if (copy_from_user(&params, optval, optlen))
+ return -EFAULT;
+
+ sp = sctp_sk(sk);
+
+ if (params.assoc_id != 0) {
+ asoc = sctp_id2assoc(sk, params.assoc_id);
+ if (!asoc)
+ return -EINVAL;
+ asoc->default_rcv_context = params.assoc_value;
+ } else {
+ sp->default_rcv_context = params.assoc_value;
+ }
return 0;
}
@@ -2854,8 +2894,11 @@ SCTP_STATIC int sctp_setsockopt(struct sock *sk, int level, int optname,
case SCTP_MAXSEG:
retval = sctp_setsockopt_maxseg(sk, optval, optlen);
break;
- case SCTP_ADAPTION_LAYER:
- retval = sctp_setsockopt_adaption_layer(sk, optval, optlen);
+ case SCTP_ADAPTATION_LAYER:
+ retval = sctp_setsockopt_adaptation_layer(sk, optval, optlen);
+ break;
+ case SCTP_CONTEXT:
+ retval = sctp_setsockopt_context(sk, optval, optlen);
break;
default:
@@ -3016,6 +3059,8 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk)
sp->default_context = 0;
sp->default_timetolive = 0;
+ sp->default_rcv_context = 0;
+
/* Initialize default setup parameters. These parameters
* can be modified with the SCTP_INITMSG socket option or
* overridden by the SCTP_INIT CMSG.
@@ -3078,7 +3123,7 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk)
/* User specified fragmentation limit. */
sp->user_frag = 0;
- sp->adaption_ind = 0;
+ sp->adaptation_ind = 0;
sp->pf = sctp_get_pf_specific(sk->sk_family);
@@ -3821,10 +3866,9 @@ static int sctp_getsockopt_local_addrs_num_old(struct sock *sk, int len,
sctp_assoc_t id;
struct sctp_bind_addr *bp;
struct sctp_association *asoc;
- struct list_head *pos;
+ struct list_head *pos, *temp;
struct sctp_sockaddr_entry *addr;
rwlock_t *addr_lock;
- unsigned long flags;
int cnt = 0;
if (len != sizeof(sctp_assoc_t))
@@ -3859,8 +3903,7 @@ static int sctp_getsockopt_local_addrs_num_old(struct sock *sk, int len,
addr = list_entry(bp->address_list.next,
struct sctp_sockaddr_entry, list);
if (sctp_is_any(&addr->a)) {
- sctp_spin_lock_irqsave(&sctp_local_addr_lock, flags);
- list_for_each(pos, &sctp_local_addr_list) {
+ list_for_each_safe(pos, temp, &sctp_local_addr_list) {
addr = list_entry(pos,
struct sctp_sockaddr_entry,
list);
@@ -3869,8 +3912,6 @@ static int sctp_getsockopt_local_addrs_num_old(struct sock *sk, int len,
continue;
cnt++;
}
- sctp_spin_unlock_irqrestore(&sctp_local_addr_lock,
- flags);
} else {
cnt = 1;
}
@@ -3892,15 +3933,13 @@ done:
static int sctp_copy_laddrs_to_user_old(struct sock *sk, __u16 port, int max_addrs,
void __user *to)
{
- struct list_head *pos;
+ struct list_head *pos, *next;
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) {
+ list_for_each_safe(pos, next, &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))
@@ -3909,16 +3948,13 @@ static int sctp_copy_laddrs_to_user_old(struct sock *sk, __u16 port, int max_add
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 (copy_to_user(to, &temp, addrlen)) {
- sctp_spin_unlock_irqrestore(&sctp_local_addr_lock,
- flags);
+ if (copy_to_user(to, &temp, addrlen))
return -EFAULT;
- }
+
to += addrlen;
cnt ++;
if (cnt >= max_addrs) break;
}
- sctp_spin_unlock_irqrestore(&sctp_local_addr_lock, flags);
return cnt;
}
@@ -3926,15 +3962,13 @@ static int sctp_copy_laddrs_to_user_old(struct sock *sk, __u16 port, int max_add
static int sctp_copy_laddrs_to_user(struct sock *sk, __u16 port,
void __user **to, size_t space_left)
{
- struct list_head *pos;
+ struct list_head *pos, *next;
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) {
+ list_for_each_safe(pos, next, &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))
@@ -3945,16 +3979,13 @@ static int sctp_copy_laddrs_to_user(struct sock *sk, __u16 port,
addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len;
if(space_left<addrlen)
return -ENOMEM;
- if (copy_to_user(*to, &temp, addrlen)) {
- sctp_spin_unlock_irqrestore(&sctp_local_addr_lock,
- flags);
+ if (copy_to_user(*to, &temp, addrlen))
return -EFAULT;
- }
+
*to += addrlen;
cnt ++;
space_left -= addrlen;
}
- sctp_spin_unlock_irqrestore(&sctp_local_addr_lock, flags);
return cnt;
}
@@ -4179,21 +4210,21 @@ static int sctp_getsockopt_primary_addr(struct sock *sk, int len,
}
/*
- * 7.1.11 Set Adaption Layer Indicator (SCTP_ADAPTION_LAYER)
+ * 7.1.11 Set Adaptation Layer Indicator (SCTP_ADAPTATION_LAYER)
*
- * Requests that the local endpoint set the specified Adaption Layer
+ * Requests that the local endpoint set the specified Adaptation Layer
* Indication parameter for all future INIT and INIT-ACK exchanges.
*/
-static int sctp_getsockopt_adaption_layer(struct sock *sk, int len,
+static int sctp_getsockopt_adaptation_layer(struct sock *sk, int len,
char __user *optval, int __user *optlen)
{
- struct sctp_setadaption adaption;
+ struct sctp_setadaptation adaptation;
- if (len != sizeof(struct sctp_setadaption))
+ if (len != sizeof(struct sctp_setadaptation))
return -EINVAL;
- adaption.ssb_adaption_ind = sctp_sk(sk)->adaption_ind;
- if (copy_to_user(optval, &adaption, len))
+ adaptation.ssb_adaptation_ind = sctp_sk(sk)->adaptation_ind;
+ if (copy_to_user(optval, &adaptation, len))
return -EFAULT;
return 0;
@@ -4435,6 +4466,42 @@ static int sctp_getsockopt_mappedv4(struct sock *sk, int len,
}
/*
+ * 7.1.29. Set or Get the default context (SCTP_CONTEXT)
+ * (chapter and verse is quoted at sctp_setsockopt_context())
+ */
+static int sctp_getsockopt_context(struct sock *sk, int len,
+ char __user *optval, int __user *optlen)
+{
+ struct sctp_assoc_value params;
+ struct sctp_sock *sp;
+ struct sctp_association *asoc;
+
+ if (len != sizeof(struct sctp_assoc_value))
+ return -EINVAL;
+
+ if (copy_from_user(&params, optval, len))
+ return -EFAULT;
+
+ sp = sctp_sk(sk);
+
+ if (params.assoc_id != 0) {
+ asoc = sctp_id2assoc(sk, params.assoc_id);
+ if (!asoc)
+ return -EINVAL;
+ params.assoc_value = asoc->default_rcv_context;
+ } else {
+ params.assoc_value = sp->default_rcv_context;
+ }
+
+ if (put_user(len, optlen))
+ return -EFAULT;
+ if (copy_to_user(optval, &params, len))
+ return -EFAULT;
+
+ return 0;
+}
+
+/*
* 7.1.17 Set the maximum fragrmentation size (SCTP_MAXSEG)
*
* This socket option specifies the maximum size to put in any outgoing
@@ -4568,10 +4635,13 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname,
retval = sctp_getsockopt_peer_addr_info(sk, len, optval,
optlen);
break;
- case SCTP_ADAPTION_LAYER:
- retval = sctp_getsockopt_adaption_layer(sk, len, optval,
+ case SCTP_ADAPTATION_LAYER:
+ retval = sctp_getsockopt_adaptation_layer(sk, len, optval,
optlen);
break;
+ case SCTP_CONTEXT:
+ retval = sctp_getsockopt_context(sk, len, optval, optlen);
+ break;
default:
retval = -ENOPROTOOPT;
break;
diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c
index e255a709f1b7..445e07a7ac4b 100644
--- a/net/sctp/ulpevent.c
+++ b/net/sctp/ulpevent.c
@@ -609,31 +609,31 @@ fail:
return NULL;
}
-/* Create and initialize a SCTP_ADAPTION_INDICATION notification.
+/* Create and initialize a SCTP_ADAPTATION_INDICATION notification.
*
* Socket Extensions for SCTP
- * 5.3.1.6 SCTP_ADAPTION_INDICATION
+ * 5.3.1.6 SCTP_ADAPTATION_INDICATION
*/
-struct sctp_ulpevent *sctp_ulpevent_make_adaption_indication(
+struct sctp_ulpevent *sctp_ulpevent_make_adaptation_indication(
const struct sctp_association *asoc, gfp_t gfp)
{
struct sctp_ulpevent *event;
- struct sctp_adaption_event *sai;
+ struct sctp_adaptation_event *sai;
struct sk_buff *skb;
- event = sctp_ulpevent_new(sizeof(struct sctp_adaption_event),
+ event = sctp_ulpevent_new(sizeof(struct sctp_adaptation_event),
MSG_NOTIFICATION, gfp);
if (!event)
goto fail;
skb = sctp_event2skb(event);
- sai = (struct sctp_adaption_event *)
- skb_put(skb, sizeof(struct sctp_adaption_event));
+ sai = (struct sctp_adaptation_event *)
+ skb_put(skb, sizeof(struct sctp_adaptation_event));
- sai->sai_type = SCTP_ADAPTION_INDICATION;
+ sai->sai_type = SCTP_ADAPTATION_INDICATION;
sai->sai_flags = 0;
- sai->sai_length = sizeof(struct sctp_adaption_event);
- sai->sai_adaption_ind = asoc->peer.adaption_ind;
+ sai->sai_length = sizeof(struct sctp_adaptation_event);
+ sai->sai_adaptation_ind = asoc->peer.adaptation_ind;
sctp_ulpevent_set_owner(event, asoc);
sai->sai_assoc_id = sctp_assoc2id(asoc);
@@ -849,8 +849,10 @@ void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event,
*/
sinfo.sinfo_assoc_id = sctp_assoc2id(event->asoc);
+ /* context value that is set via SCTP_CONTEXT socket option. */
+ sinfo.sinfo_context = event->asoc->default_rcv_context;
+
/* These fields are not used while receiving. */
- sinfo.sinfo_context = 0;
sinfo.sinfo_timetolive = 0;
put_cmsg(msghdr, IPPROTO_SCTP, SCTP_SNDRCV,
diff --git a/net/sunrpc/auth_gss/gss_spkm3_mech.c b/net/sunrpc/auth_gss/gss_spkm3_mech.c
index 41465072d0b5..8ef3f1c19435 100644
--- a/net/sunrpc/auth_gss/gss_spkm3_mech.c
+++ b/net/sunrpc/auth_gss/gss_spkm3_mech.c
@@ -228,7 +228,7 @@ static int __init init_spkm3_module(void)
status = gss_mech_register(&gss_spkm3_mech);
if (status)
printk("Failed to register spkm3 gss mechanism!\n");
- return 0;
+ return status;
}
static void __exit cleanup_spkm3_module(void)
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index 700353b330fd..066c64a97fd8 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -804,19 +804,19 @@ unwrap_integ_data(struct xdr_buf *buf, u32 seq, struct gss_ctx *ctx)
integ_len = svc_getnl(&buf->head[0]);
if (integ_len & 3)
- goto out;
+ return stat;
if (integ_len > buf->len)
- goto out;
+ return stat;
if (xdr_buf_subsegment(buf, &integ_buf, 0, integ_len))
BUG();
/* copy out mic... */
if (read_u32_from_xdr_buf(buf, integ_len, &mic.len))
BUG();
if (mic.len > RPC_MAX_AUTH_SIZE)
- goto out;
+ return stat;
mic.data = kmalloc(mic.len, GFP_KERNEL);
if (!mic.data)
- goto out;
+ return stat;
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);
@@ -826,6 +826,7 @@ unwrap_integ_data(struct xdr_buf *buf, u32 seq, struct gss_ctx *ctx)
goto out;
stat = 0;
out:
+ kfree(mic.data);
return stat;
}
@@ -1065,7 +1066,7 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp)
}
switch(cache_check(&rsi_cache, &rsip->h, &rqstp->rq_chandle)) {
case -EAGAIN:
- goto drop;
+ case -ETIMEDOUT:
case -ENOENT:
goto drop;
case 0:
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index 80aff0474572..14274490f92e 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -34,7 +34,7 @@
#define RPCDBG_FACILITY RPCDBG_CACHE
-static void cache_defer_req(struct cache_req *req, struct cache_head *item);
+static int cache_defer_req(struct cache_req *req, struct cache_head *item);
static void cache_revisit_request(struct cache_head *item);
static void cache_init(struct cache_head *h)
@@ -185,6 +185,7 @@ static int cache_make_upcall(struct cache_detail *detail, struct cache_head *h);
*
* Returns 0 if the cache_head can be used, or cache_puts it and returns
* -EAGAIN if upcall is pending,
+ * -ETIMEDOUT if upcall failed and should be retried,
* -ENOENT if cache entry was negative
*/
int cache_check(struct cache_detail *detail,
@@ -236,7 +237,8 @@ int cache_check(struct cache_detail *detail,
}
if (rv == -EAGAIN)
- cache_defer_req(rqstp, h);
+ if (cache_defer_req(rqstp, h) != 0)
+ rv = -ETIMEDOUT;
if (rv)
cache_put(h, detail);
@@ -523,14 +525,21 @@ static LIST_HEAD(cache_defer_list);
static struct list_head cache_defer_hash[DFR_HASHSIZE];
static int cache_defer_cnt;
-static void cache_defer_req(struct cache_req *req, struct cache_head *item)
+static int cache_defer_req(struct cache_req *req, struct cache_head *item)
{
struct cache_deferred_req *dreq;
int hash = DFR_HASH(item);
+ if (cache_defer_cnt >= DFR_MAX) {
+ /* too much in the cache, randomly drop this one,
+ * or continue and drop the oldest below
+ */
+ if (net_random()&1)
+ return -ETIMEDOUT;
+ }
dreq = req->defer(req);
if (dreq == NULL)
- return;
+ return -ETIMEDOUT;
dreq->item = item;
dreq->recv_time = get_seconds();
@@ -546,17 +555,8 @@ static void cache_defer_req(struct cache_req *req, struct cache_head *item)
/* it is in, now maybe clean up */
dreq = NULL;
if (++cache_defer_cnt > DFR_MAX) {
- /* too much in the cache, randomly drop
- * first or last
- */
- if (net_random()&1)
- dreq = list_entry(cache_defer_list.next,
- struct cache_deferred_req,
- recent);
- else
- dreq = list_entry(cache_defer_list.prev,
- struct cache_deferred_req,
- recent);
+ dreq = list_entry(cache_defer_list.prev,
+ struct cache_deferred_req, recent);
list_del(&dreq->recent);
list_del(&dreq->hash);
cache_defer_cnt--;
@@ -571,6 +571,7 @@ static void cache_defer_req(struct cache_req *req, struct cache_head *item)
/* must have just been validated... */
cache_revisit_request(item);
}
+ return 0;
}
static void cache_revisit_request(struct cache_head *item)
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index eb44ec929ca1..f3001f3626f6 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -308,7 +308,7 @@ __svc_create(struct svc_program *prog, unsigned int bufsize, int npools,
serv->sv_nrpools = npools;
serv->sv_pools =
- kcalloc(sizeof(struct svc_pool), serv->sv_nrpools,
+ kcalloc(serv->sv_nrpools, sizeof(struct svc_pool),
GFP_KERNEL);
if (!serv->sv_pools) {
kfree(serv);
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
index a0a953a430c2..0d1e8fb83b93 100644
--- a/net/sunrpc/svcauth_unix.c
+++ b/net/sunrpc/svcauth_unix.c
@@ -53,6 +53,10 @@ struct auth_domain *unix_domain_find(char *name)
return NULL;
kref_init(&new->h.ref);
new->h.name = kstrdup(name, GFP_KERNEL);
+ if (new->h.name == NULL) {
+ kfree(new);
+ return NULL;
+ }
new->h.flavour = &svcauth_unix;
new->addr_changes = 0;
rv = auth_domain_lookup(name, &new->h);
@@ -435,6 +439,7 @@ svcauth_unix_set_client(struct svc_rqst *rqstp)
default:
BUG();
case -EAGAIN:
+ case -ETIMEDOUT:
return SVC_DROP;
case -ENOENT:
return SVC_DENIED;
diff --git a/net/tipc/config.c b/net/tipc/config.c
index 458a2c46cef3..baf55c459c8b 100644
--- a/net/tipc/config.c
+++ b/net/tipc/config.c
@@ -208,7 +208,7 @@ static void cfg_cmd_event(struct tipc_cmd_msg *msg,
if (mng.link_subscriptions > 64)
break;
- sub = (struct subscr_data *)kmalloc(sizeof(*sub),
+ sub = kmalloc(sizeof(*sub),
GFP_ATOMIC);
if (sub == NULL) {
warn("Memory squeeze; dropped remote link subscription\n");
diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c
index 6b381fc0383d..f1cf3402e75c 100644
--- a/net/xfrm/xfrm_algo.c
+++ b/net/xfrm/xfrm_algo.c
@@ -399,7 +399,8 @@ static struct xfrm_algo_desc *xfrm_get_byname(struct xfrm_algo_desc *list,
if (!probe)
break;
- status = crypto_has_alg(name, type, mask | CRYPTO_ALG_ASYNC);
+ status = crypto_has_alg(list[i].name, type,
+ mask | CRYPTO_ALG_ASYNC);
if (!status)
break;
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c
index 4dcb8867b5f4..124b341a18c0 100644
--- a/scripts/kconfig/conf.c
+++ b/scripts/kconfig/conf.c
@@ -600,7 +600,7 @@ int main(int ac, char **av)
input_mode = ask_silent;
valid_stdin = 1;
}
- } else if (sym_change_count) {
+ } else if (conf_get_changed()) {
name = getenv("KCONFIG_NOSILENTUPDATE");
if (name && *name) {
fprintf(stderr, _("\n*** Kernel configuration requires explicit update.\n\n"));
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index 66b15ef02931..664fe29dacef 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -100,7 +100,7 @@ int conf_read_simple(const char *name, int def)
in = zconf_fopen(name);
if (in)
goto load;
- sym_change_count++;
+ sym_add_change_count(1);
if (!sym_defconfig_list)
return 1;
@@ -312,7 +312,7 @@ int conf_read(const char *name)
struct expr *e;
int i, flags;
- sym_change_count = 0;
+ sym_set_change_count(0);
if (conf_read_simple(name, S_DEF_USER))
return 1;
@@ -364,7 +364,7 @@ int conf_read(const char *name)
sym->flags &= flags | ~SYMBOL_DEF_USER;
}
- sym_change_count += conf_warnings || conf_unsaved;
+ sym_add_change_count(conf_warnings || conf_unsaved);
return 0;
}
@@ -432,7 +432,7 @@ int conf_write(const char *name)
use_timestamp ? "# " : "",
use_timestamp ? ctime(&now) : "");
- if (!sym_change_count)
+ if (!conf_get_changed())
sym_clear_all_valid();
menu = rootmenu.list;
@@ -528,7 +528,7 @@ int conf_write(const char *name)
"# configuration written to %s\n"
"#\n"), newname);
- sym_change_count = 0;
+ sym_set_change_count(0);
return 0;
}
@@ -765,3 +765,30 @@ int conf_write_autoconf(void)
return 0;
}
+
+static int sym_change_count;
+static void (*conf_changed_callback)(void);
+
+void sym_set_change_count(int count)
+{
+ int _sym_change_count = sym_change_count;
+ sym_change_count = count;
+ if (conf_changed_callback &&
+ (bool)_sym_change_count != (bool)count)
+ conf_changed_callback();
+}
+
+void sym_add_change_count(int count)
+{
+ sym_set_change_count(count + sym_change_count);
+}
+
+bool conf_get_changed(void)
+{
+ return sym_change_count;
+}
+
+void conf_set_changed_callback(void (*fn)(void))
+{
+ conf_changed_callback = fn;
+}
diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c
index 7b0d3a93d5c0..61d8166166ef 100644
--- a/scripts/kconfig/gconf.c
+++ b/scripts/kconfig/gconf.c
@@ -38,8 +38,6 @@ static gboolean show_all = FALSE;
static gboolean show_debug = FALSE;
static gboolean resizeable = FALSE;
-static gboolean config_changed = FALSE;
-
static char nohelp_text[] =
N_("Sorry, no help available for this option yet.\n");
@@ -50,6 +48,8 @@ GtkWidget *text_w = NULL;
GtkWidget *hpaned = NULL;
GtkWidget *vpaned = NULL;
GtkWidget *back_btn = NULL;
+GtkWidget *save_btn = NULL;
+GtkWidget *save_menu_item = NULL;
GtkTextTag *tag1, *tag2;
GdkColor color;
@@ -75,7 +75,7 @@ static void display_tree_part(void);
static void update_tree(struct menu *src, GtkTreeIter * dst);
static void set_node(GtkTreeIter * node, struct menu *menu, gchar ** row);
static gchar **fill_row(struct menu *menu);
-
+static void conf_changed(void);
/* Helping/Debugging Functions */
@@ -224,6 +224,10 @@ void init_main_window(const gchar * glade_file)
gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget,
show_value);
+ save_btn = glade_xml_get_widget(xml, "button3");
+ save_menu_item = glade_xml_get_widget(xml, "save1");
+ conf_set_changed_callback(conf_changed);
+
style = gtk_widget_get_style(main_wnd);
widget = glade_xml_get_widget(xml, "toolbar1");
@@ -512,14 +516,14 @@ static void text_insert_msg(const char *title, const char *message)
/* Main Windows Callbacks */
-void on_save1_activate(GtkMenuItem * menuitem, gpointer user_data);
+void on_save_activate(GtkMenuItem * menuitem, gpointer user_data);
gboolean on_window1_delete_event(GtkWidget * widget, GdkEvent * event,
gpointer user_data)
{
GtkWidget *dialog, *label;
gint result;
- if (config_changed == FALSE)
+ if (!conf_get_changed())
return FALSE;
dialog = gtk_dialog_new_with_buttons(_("Warning !"),
@@ -543,7 +547,7 @@ gboolean on_window1_delete_event(GtkWidget * widget, GdkEvent * event,
result = gtk_dialog_run(GTK_DIALOG(dialog));
switch (result) {
case GTK_RESPONSE_YES:
- on_save1_activate(NULL, NULL);
+ on_save_activate(NULL, NULL);
return FALSE;
case GTK_RESPONSE_NO:
return FALSE;
@@ -621,12 +625,10 @@ void on_load1_activate(GtkMenuItem * menuitem, gpointer user_data)
}
-void on_save1_activate(GtkMenuItem * menuitem, gpointer user_data)
+void on_save_activate(GtkMenuItem * menuitem, gpointer user_data)
{
if (conf_write(NULL))
text_insert_msg(_("Error"), _("Unable to save configuration !"));
-
- config_changed = FALSE;
}
@@ -819,12 +821,6 @@ void on_load_clicked(GtkButton * button, gpointer user_data)
}
-void on_save_clicked(GtkButton * button, gpointer user_data)
-{
- on_save1_activate(NULL, user_data);
-}
-
-
void on_single_clicked(GtkButton * button, gpointer user_data)
{
view_mode = SINGLE_VIEW;
@@ -899,7 +895,6 @@ static void renderer_edited(GtkCellRendererText * cell,
sym_set_string_value(sym, new_def);
- config_changed = TRUE;
update_tree(&rootmenu, NULL);
gtk_tree_path_free(path);
@@ -930,7 +925,6 @@ static void change_sym_value(struct menu *menu, gint col)
if (!sym_tristate_within_range(sym, newval))
newval = yes;
sym_set_tristate_value(sym, newval);
- config_changed = TRUE;
if (view_mode == FULL_VIEW)
update_tree(&rootmenu, NULL);
else if (view_mode == SPLIT_VIEW) {
@@ -1633,3 +1627,10 @@ int main(int ac, char *av[])
return 0;
}
+
+static void conf_changed(void)
+{
+ bool changed = conf_get_changed();
+ gtk_widget_set_sensitive(save_btn, changed);
+ gtk_widget_set_sensitive(save_menu_item, changed);
+}
diff --git a/scripts/kconfig/gconf.glade b/scripts/kconfig/gconf.glade
index f8744ed64967..803233fdd6dd 100644
--- a/scripts/kconfig/gconf.glade
+++ b/scripts/kconfig/gconf.glade
@@ -70,7 +70,7 @@
<property name="tooltip" translatable="yes">Save the config in .config</property>
<property name="label" translatable="yes">_Save</property>
<property name="use_underline">True</property>
- <signal name="activate" handler="on_save1_activate"/>
+ <signal name="activate" handler="on_save_activate"/>
<accelerator key="S" modifiers="GDK_CONTROL_MASK" signal="activate"/>
<child internal-child="image">
@@ -380,7 +380,7 @@
<property name="visible_horizontal">True</property>
<property name="visible_vertical">True</property>
<property name="is_important">False</property>
- <signal name="clicked" handler="on_save_clicked"/>
+ <signal name="clicked" handler="on_save_activate"/>
</widget>
<packing>
<property name="expand">False</property>
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h
index 2628023a1fe1..9b2706a41548 100644
--- a/scripts/kconfig/lkc.h
+++ b/scripts/kconfig/lkc.h
@@ -65,6 +65,8 @@ char *zconf_curname(void);
/* confdata.c */
char *conf_get_default_confname(void);
+void sym_set_change_count(int count);
+void sym_add_change_count(int count);
/* kconfig_load.c */
void kconfig_load(void);
diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h
index a263746cfa7d..15030770d1ad 100644
--- a/scripts/kconfig/lkc_proto.h
+++ b/scripts/kconfig/lkc_proto.h
@@ -5,6 +5,8 @@ P(conf_read,int,(const char *name));
P(conf_read_simple,int,(const char *name, int));
P(conf_write,int,(const char *name));
P(conf_write_autoconf,int,(void));
+P(conf_get_changed,bool,(void));
+P(conf_set_changed_callback, void,(void (*fn)(void)));
/* menu.c */
P(rootmenu,struct menu,);
@@ -16,7 +18,6 @@ P(menu_get_parent_menu,struct menu *,(struct menu *menu));
/* symbol.c */
P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]);
-P(sym_change_count,int,);
P(sym_lookup,struct symbol *,(const char *name, int isconst));
P(sym_find,struct symbol *,(const char *name));
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
index 08a4c7af93ea..3f9a1321b3e6 100644
--- a/scripts/kconfig/mconf.c
+++ b/scripts/kconfig/mconf.c
@@ -890,14 +890,19 @@ int main(int ac, char **av)
do {
conf(&rootmenu);
dialog_clear();
- res = dialog_yesno(NULL,
- _("Do you wish to save your "
- "new kernel configuration?\n"
- "<ESC><ESC> to continue."),
- 6, 60);
+ if (conf_get_changed())
+ res = dialog_yesno(NULL,
+ _("Do you wish to save your "
+ "new kernel configuration?\n"
+ "<ESC><ESC> to continue."),
+ 6, 60);
+ else
+ res = -1;
} while (res == KEY_ESC);
end_dialog();
- if (res == 0) {
+
+ switch (res) {
+ case 0:
if (conf_write(NULL)) {
fprintf(stderr, _("\n\n"
"Error during writing of the kernel configuration.\n"
@@ -905,11 +910,13 @@ int main(int ac, char **av)
"\n\n"));
return 1;
}
+ case -1:
printf(_("\n\n"
"*** End of Linux kernel configuration.\n"
"*** Execute 'make' to build the kernel or try 'make help'."
"\n\n"));
- } else {
+ break;
+ default:
fprintf(stderr, _("\n\n"
"Your kernel configuration changes were NOT saved."
"\n\n"));
diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc
index f5628c57640b..0b2fcc417f59 100644
--- a/scripts/kconfig/qconf.cc
+++ b/scripts/kconfig/qconf.cc
@@ -38,6 +38,8 @@
static QApplication *configApp;
static ConfigSettings *configSettings;
+QAction *ConfigMainWindow::saveAction;
+
static inline QString qgettext(const char* str)
{
return QString::fromLocal8Bit(gettext(str));
@@ -1306,8 +1308,11 @@ ConfigMainWindow::ConfigMainWindow(void)
connect(quitAction, SIGNAL(activated()), SLOT(close()));
QAction *loadAction = new QAction("Load", QPixmap(xpm_load), "&Load", CTRL+Key_L, this);
connect(loadAction, SIGNAL(activated()), SLOT(loadConfig()));
- QAction *saveAction = new QAction("Save", QPixmap(xpm_save), "&Save", CTRL+Key_S, this);
+ saveAction = new QAction("Save", QPixmap(xpm_save), "&Save", CTRL+Key_S, this);
connect(saveAction, SIGNAL(activated()), SLOT(saveConfig()));
+ conf_set_changed_callback(conf_changed);
+ // Set saveAction's initial state
+ conf_changed();
QAction *saveAsAction = new QAction("Save As...", "Save &As...", 0, this);
connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs()));
QAction *searchAction = new QAction("Search", "&Search", CTRL+Key_F, this);
@@ -1585,7 +1590,7 @@ void ConfigMainWindow::showFullView(void)
*/
void ConfigMainWindow::closeEvent(QCloseEvent* e)
{
- if (!sym_change_count) {
+ if (!conf_get_changed()) {
e->accept();
return;
}
@@ -1658,6 +1663,12 @@ void ConfigMainWindow::saveSettings(void)
configSettings->writeSizes("/split2", split2->sizes());
}
+void ConfigMainWindow::conf_changed(void)
+{
+ if (saveAction)
+ saveAction->setEnabled(conf_get_changed());
+}
+
void fixup_rootmenu(struct menu *menu)
{
struct menu *child;
diff --git a/scripts/kconfig/qconf.h b/scripts/kconfig/qconf.h
index 6a9e3b14c227..6fc1c5f14425 100644
--- a/scripts/kconfig/qconf.h
+++ b/scripts/kconfig/qconf.h
@@ -297,6 +297,9 @@ protected:
class ConfigMainWindow : public QMainWindow {
Q_OBJECT
+
+ static QAction *saveAction;
+ static void conf_changed(void);
public:
ConfigMainWindow(void);
public slots:
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index ee225ced2ce4..8f06c474d800 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -30,7 +30,6 @@ struct symbol symbol_yes = {
.flags = SYMBOL_VALID,
};
-int sym_change_count;
struct symbol *sym_defconfig_list;
struct symbol *modules_sym;
tristate modules_val;
@@ -379,7 +378,7 @@ void sym_clear_all_valid(void)
for_all_symbols(i, sym)
sym->flags &= ~SYMBOL_VALID;
- sym_change_count++;
+ sym_add_change_count(1);
if (modules_sym)
sym_calc_value(modules_sym);
}
diff --git a/scripts/kconfig/zconf.tab.c_shipped b/scripts/kconfig/zconf.tab.c_shipped
index 2fb0a4fc61d0..d777fe85627f 100644
--- a/scripts/kconfig/zconf.tab.c_shipped
+++ b/scripts/kconfig/zconf.tab.c_shipped
@@ -2135,7 +2135,7 @@ void conf_parse(const char *name)
sym_check_deps(sym);
}
- sym_change_count = 1;
+ sym_set_change_count(1);
}
const char *zconf_tokenname(int token)
diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y
index ab44feb3c600..04a5864c03b1 100644
--- a/scripts/kconfig/zconf.y
+++ b/scripts/kconfig/zconf.y
@@ -504,7 +504,7 @@ void conf_parse(const char *name)
sym_check_deps(sym);
}
- sym_change_count = 1;
+ sym_set_change_count(1);
}
const char *zconf_tokenname(int token)
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index df3b272f7ce6..f50a70f550b3 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -1469,6 +1469,7 @@ sub push_parameter($$$) {
my $param = shift;
my $type = shift;
my $file = shift;
+ my $anon = 0;
my $param_name = $param;
$param_name =~ s/\[.*//;
@@ -1484,9 +1485,20 @@ sub push_parameter($$$) {
$param="void";
$parameterdescs{void} = "no arguments";
}
+ elsif ($type eq "" && ($param eq "struct" or $param eq "union"))
+ # handle unnamed (anonymous) union or struct:
+ {
+ $type = $param;
+ $param = "{unnamed_" . $param. "}";
+ $parameterdescs{$param} = "anonymous\n";
+ $anon = 1;
+ }
+
# warn if parameter has no description
- # (but ignore ones starting with # as these are no parameters
- # but inline preprocessor statements
+ # (but ignore ones starting with # as these are not parameters
+ # but inline preprocessor statements);
+ # also ignore unnamed structs/unions;
+ if (!$anon) {
if (!defined $parameterdescs{$param_name} && $param_name !~ /^#/) {
$parameterdescs{$param_name} = $undescribed;
@@ -1500,6 +1512,7 @@ sub push_parameter($$$) {
" No description found for parameter '$param'\n";
++$warnings;
}
+ }
push @parameterlist, $param;
$parametertypes{$param} = $type;
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index ac0a58222992..15ab5d02e80a 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -997,6 +997,7 @@ static int exit_section_ref_ok(const char *name)
"__bug_table", /* used by powerpc for BUG() */
".exitcall.exit",
".eh_frame",
+ ".parainstructions",
".stab",
"__ex_table",
".fixup",
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index bdb7070dd3dc..ee0581557966 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -2660,9 +2660,11 @@ int selinux_netlbl_inode_permission(struct inode *inode, int mask)
rcu_read_unlock();
return 0;
}
- lock_sock(sock->sk);
+ local_bh_disable();
+ bh_lock_sock_nested(sock->sk);
rc = selinux_netlbl_socket_setsid(sock, sksec->sid);
- release_sock(sock->sk);
+ bh_unlock_sock(sock->sk);
+ local_bh_enable();
rcu_read_unlock();
return rc;
diff --git a/sound/aoa/codecs/snd-aoa-codec-onyx.h b/sound/aoa/codecs/snd-aoa-codec-onyx.h
index aeedda773699..ffd20254ff76 100644
--- a/sound/aoa/codecs/snd-aoa-codec-onyx.h
+++ b/sound/aoa/codecs/snd-aoa-codec-onyx.h
@@ -9,7 +9,6 @@
#define __SND_AOA_CODEC_ONYX_H
#include <stddef.h>
#include <linux/i2c.h>
-#include <linux/i2c-dev.h>
#include <asm/pmac_low_i2c.h>
#include <asm/prom.h>
diff --git a/sound/aoa/codecs/snd-aoa-codec-tas.c b/sound/aoa/codecs/snd-aoa-codec-tas.c
index 9de8485ba3f5..2cd81fa07ce1 100644
--- a/sound/aoa/codecs/snd-aoa-codec-tas.c
+++ b/sound/aoa/codecs/snd-aoa-codec-tas.c
@@ -61,7 +61,6 @@
*/
#include <stddef.h>
#include <linux/i2c.h>
-#include <linux/i2c-dev.h>
#include <asm/pmac_low_i2c.h>
#include <asm/prom.h>
#include <linux/delay.h>
diff --git a/sound/core/control.c b/sound/core/control.c
index 48ef0a09a7a7..0c7bcd62e5b2 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -1275,7 +1275,7 @@ static ssize_t snd_ctl_read(struct file *file, char __user *buffer,
schedule();
remove_wait_queue(&ctl->change_sleep, &wait);
if (signal_pending(current))
- return result > 0 ? result : -ERESTARTSYS;
+ return -ERESTARTSYS;
spin_lock_irq(&ctl->read_lock);
}
kev = snd_kctl_event(ctl->events.next);
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
index f4c67042e3ac..3391f2a9b4d1 100644
--- a/sound/core/oss/mixer_oss.c
+++ b/sound/core/oss/mixer_oss.c
@@ -1023,7 +1023,7 @@ static int snd_mixer_oss_build_input(struct snd_mixer_oss *mixer, struct snd_mix
}
up_read(&mixer->card->controls_rwsem);
if (slot.present != 0) {
- pslot = (struct slot *)kmalloc(sizeof(slot), GFP_KERNEL);
+ pslot = kmalloc(sizeof(slot), GFP_KERNEL);
if (! pslot)
return -ENOMEM;
*pslot = slot;
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index e0821eb3d851..786a82e68890 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -810,6 +810,8 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
struct snd_mask sformat_mask;
struct snd_mask mask;
+ if (mutex_lock_interruptible(&runtime->oss.params_lock))
+ return -EINTR;
sw_params = kmalloc(sizeof(*sw_params), GFP_KERNEL);
params = kmalloc(sizeof(*params), GFP_KERNEL);
sparams = kmalloc(sizeof(*sparams), GFP_KERNEL);
@@ -1020,6 +1022,7 @@ failure:
kfree(sw_params);
kfree(params);
kfree(sparams);
+ mutex_unlock(&runtime->oss.params_lock);
return err;
}
@@ -1307,14 +1310,17 @@ static ssize_t snd_pcm_oss_write1(struct snd_pcm_substream *substream, const cha
if ((tmp = snd_pcm_oss_make_ready(substream)) < 0)
return tmp;
+ mutex_lock(&runtime->oss.params_lock);
while (bytes > 0) {
if (bytes < runtime->oss.period_bytes || runtime->oss.buffer_used > 0) {
tmp = bytes;
if (tmp + runtime->oss.buffer_used > runtime->oss.period_bytes)
tmp = runtime->oss.period_bytes - runtime->oss.buffer_used;
if (tmp > 0) {
- if (copy_from_user(runtime->oss.buffer + runtime->oss.buffer_used, buf, tmp))
- return xfer > 0 ? (snd_pcm_sframes_t)xfer : -EFAULT;
+ if (copy_from_user(runtime->oss.buffer + runtime->oss.buffer_used, buf, tmp)) {
+ tmp = -EFAULT;
+ goto err;
+ }
}
runtime->oss.buffer_used += tmp;
buf += tmp;
@@ -1325,22 +1331,24 @@ static ssize_t snd_pcm_oss_write1(struct snd_pcm_substream *substream, const cha
tmp = snd_pcm_oss_write2(substream, runtime->oss.buffer + runtime->oss.period_ptr,
runtime->oss.buffer_used - runtime->oss.period_ptr, 1);
if (tmp <= 0)
- return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
+ goto err;
runtime->oss.bytes += tmp;
runtime->oss.period_ptr += tmp;
runtime->oss.period_ptr %= runtime->oss.period_bytes;
if (runtime->oss.period_ptr == 0 ||
runtime->oss.period_ptr == runtime->oss.buffer_used)
runtime->oss.buffer_used = 0;
- else if ((substream->f_flags & O_NONBLOCK) != 0)
- return xfer > 0 ? xfer : -EAGAIN;
+ else if ((substream->f_flags & O_NONBLOCK) != 0) {
+ tmp = -EAGAIN;
+ goto err;
+ }
}
} else {
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;
+ goto err;
runtime->oss.bytes += tmp;
buf += tmp;
bytes -= tmp;
@@ -1350,7 +1358,12 @@ static ssize_t snd_pcm_oss_write1(struct snd_pcm_substream *substream, const cha
break;
}
}
+ mutex_unlock(&runtime->oss.params_lock);
return xfer;
+
+ err:
+ mutex_unlock(&runtime->oss.params_lock);
+ return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
}
static ssize_t snd_pcm_oss_read2(struct snd_pcm_substream *substream, char *buf, size_t bytes, int in_kernel)
@@ -1397,12 +1410,13 @@ static ssize_t snd_pcm_oss_read1(struct snd_pcm_substream *substream, char __use
if ((tmp = snd_pcm_oss_make_ready(substream)) < 0)
return tmp;
+ mutex_lock(&runtime->oss.params_lock);
while (bytes > 0) {
if (bytes < runtime->oss.period_bytes || runtime->oss.buffer_used > 0) {
if (runtime->oss.buffer_used == 0) {
tmp = snd_pcm_oss_read2(substream, runtime->oss.buffer, runtime->oss.period_bytes, 1);
if (tmp <= 0)
- return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
+ goto err;
runtime->oss.bytes += tmp;
runtime->oss.period_ptr = tmp;
runtime->oss.buffer_used = tmp;
@@ -1410,8 +1424,10 @@ static ssize_t snd_pcm_oss_read1(struct snd_pcm_substream *substream, char __use
tmp = bytes;
if ((size_t) tmp > runtime->oss.buffer_used)
tmp = runtime->oss.buffer_used;
- if (copy_to_user(buf, runtime->oss.buffer + (runtime->oss.period_ptr - runtime->oss.buffer_used), tmp))
- return xfer > 0 ? (snd_pcm_sframes_t)xfer : -EFAULT;
+ if (copy_to_user(buf, runtime->oss.buffer + (runtime->oss.period_ptr - runtime->oss.buffer_used), tmp)) {
+ tmp = -EFAULT;
+ goto err;
+ }
buf += tmp;
bytes -= tmp;
xfer += tmp;
@@ -1420,14 +1436,19 @@ static ssize_t snd_pcm_oss_read1(struct snd_pcm_substream *substream, char __use
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;
+ goto err;
runtime->oss.bytes += tmp;
buf += tmp;
bytes -= tmp;
xfer += tmp;
}
}
+ mutex_unlock(&runtime->oss.params_lock);
return xfer;
+
+ err:
+ mutex_unlock(&runtime->oss.params_lock);
+ return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
}
static int snd_pcm_oss_reset(struct snd_pcm_oss_file *pcm_oss_file)
@@ -1528,6 +1549,7 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file)
return err;
format = snd_pcm_oss_format_from(runtime->oss.format);
width = snd_pcm_format_physical_width(format);
+ mutex_lock(&runtime->oss.params_lock);
if (runtime->oss.buffer_used > 0) {
#ifdef OSS_DEBUG
printk("sync: buffer_used\n");
@@ -1537,8 +1559,10 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file)
runtime->oss.buffer + runtime->oss.buffer_used,
size);
err = snd_pcm_oss_sync1(substream, runtime->oss.period_bytes);
- if (err < 0)
+ if (err < 0) {
+ mutex_unlock(&runtime->oss.params_lock);
return err;
+ }
} else if (runtime->oss.period_ptr > 0) {
#ifdef OSS_DEBUG
printk("sync: period_ptr\n");
@@ -1548,8 +1572,10 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file)
runtime->oss.buffer,
size * 8 / width);
err = snd_pcm_oss_sync1(substream, size);
- if (err < 0)
+ if (err < 0) {
+ mutex_unlock(&runtime->oss.params_lock);
return err;
+ }
}
/*
* The ALSA's period might be a bit large than OSS one.
@@ -1579,6 +1605,7 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file)
snd_pcm_lib_writev(substream, buffers, size);
}
}
+ mutex_unlock(&runtime->oss.params_lock);
/*
* finish sync: drain the buffer
*/
@@ -2172,6 +2199,7 @@ static void snd_pcm_oss_init_substream(struct snd_pcm_substream *substream,
runtime->oss.params = 1;
runtime->oss.trigger = 1;
runtime->oss.rate = 8000;
+ mutex_init(&runtime->oss.params_lock);
switch (SNDRV_MINOR_OSS_DEVICE(minor)) {
case SNDRV_MINOR_OSS_PCM_8:
runtime->oss.format = AFMT_U8;
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 5ac6e19ccb41..8e0189885516 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -640,6 +640,10 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
err = snd_pcm_substream_proc_init(substream);
if (err < 0) {
snd_printk(KERN_ERR "Error in snd_pcm_stream_proc_init\n");
+ if (prev == NULL)
+ pstr->substream = NULL;
+ else
+ prev->next = NULL;
kfree(substream);
return err;
}
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 0bb142a28539..b336797be4fc 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -79,19 +79,17 @@ void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_ufram
runtime->silence_filled -= frames;
if ((snd_pcm_sframes_t)runtime->silence_filled < 0) {
runtime->silence_filled = 0;
- runtime->silence_start = (ofs + frames) - runtime->buffer_size;
+ runtime->silence_start = new_hw_ptr;
} else {
- runtime->silence_start = ofs - runtime->silence_filled;
+ runtime->silence_start = ofs;
}
- if ((snd_pcm_sframes_t)runtime->silence_start < 0)
- runtime->silence_start += runtime->boundary;
}
frames = runtime->buffer_size - runtime->silence_filled;
}
snd_assert(frames <= runtime->buffer_size, return);
if (frames == 0)
return;
- ofs = (runtime->silence_start + runtime->silence_filled) % runtime->buffer_size;
+ ofs = runtime->silence_start % runtime->buffer_size;
while (frames > 0) {
transfer = ofs + frames > runtime->buffer_size ? runtime->buffer_size - ofs : frames;
if (runtime->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED ||
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index 269c467ca9bb..0f055bfcbdac 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -1385,7 +1385,6 @@ static int snd_rawmidi_alloc_substreams(struct snd_rawmidi *rmidi,
struct snd_rawmidi_substream *substream;
int idx;
- INIT_LIST_HEAD(&stream->substreams);
for (idx = 0; idx < count; idx++) {
substream = kzalloc(sizeof(*substream), GFP_KERNEL);
if (substream == NULL) {
@@ -1440,6 +1439,9 @@ int snd_rawmidi_new(struct snd_card *card, char *id, int device,
rmidi->device = device;
mutex_init(&rmidi->open_mutex);
init_waitqueue_head(&rmidi->open_wait);
+ INIT_LIST_HEAD(&rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substreams);
+ INIT_LIST_HEAD(&rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams);
+
if (id != NULL)
strlcpy(rmidi->id, id, sizeof(rmidi->id));
if ((err = snd_rawmidi_alloc_substreams(rmidi,
diff --git a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c
index 4bffe509f719..a3dc5e01e9f2 100644
--- a/sound/core/seq/seq_memory.c
+++ b/sound/core/seq/seq_memory.c
@@ -151,7 +151,7 @@ int snd_seq_expand_var_event(const struct snd_seq_event *event, int count, char
return len;
newlen = len;
if (size_aligned > 0)
- newlen = ((len + size_aligned - 1) / size_aligned) * size_aligned;
+ newlen = roundup(len, size_aligned);
if (count < newlen)
return -EAGAIN;
diff --git a/sound/core/sgbuf.c b/sound/core/sgbuf.c
index c30669f14ac0..cefd228cd2aa 100644
--- a/sound/core/sgbuf.c
+++ b/sound/core/sgbuf.c
@@ -27,7 +27,7 @@
/* table entries are align to 32 */
#define SGBUF_TBL_ALIGN 32
-#define sgbuf_align_table(tbl) ((((tbl) + SGBUF_TBL_ALIGN - 1) / SGBUF_TBL_ALIGN) * SGBUF_TBL_ALIGN)
+#define sgbuf_align_table(tbl) ALIGN((tbl), SGBUF_TBL_ALIGN)
int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab)
{
diff --git a/sound/isa/gus/gus_mem.c b/sound/isa/gus/gus_mem.c
index f50c276caee8..7107753b85b5 100644
--- a/sound/isa/gus/gus_mem.c
+++ b/sound/isa/gus/gus_mem.c
@@ -143,9 +143,8 @@ static int snd_gf1_mem_find(struct snd_gf1_mem * alloc,
struct snd_gf1_mem_block *pblock;
unsigned int ptr1, ptr2;
- align--;
- if (w_16 && align < 1)
- align = 1;
+ if (w_16 && align < 2)
+ align = 2;
block->flags = w_16 ? SNDRV_GF1_MEM_BLOCK_16BIT : 0;
block->owner = SNDRV_GF1_MEM_OWNER_DRIVER;
block->share = 0;
@@ -165,7 +164,7 @@ static int snd_gf1_mem_find(struct snd_gf1_mem * alloc,
if (pblock->next->ptr < boundary)
ptr2 = pblock->next->ptr;
}
- ptr1 = (pblock->ptr + pblock->size + align) & ~align;
+ ptr1 = ALIGN(pblock->ptr + pblock->size, align);
if (ptr1 >= ptr2)
continue;
size1 = ptr2 - ptr1;
diff --git a/sound/isa/sb/sb_common.c b/sound/isa/sb/sb_common.c
index c62a9e3d2ae4..3094f3852167 100644
--- a/sound/isa/sb/sb_common.c
+++ b/sound/isa/sb/sb_common.c
@@ -232,7 +232,7 @@ int snd_sbdsp_create(struct snd_card *card,
chip->port = port;
if (request_irq(irq, irq_handler, hardware == SB_HW_ALS4000 ?
- IRQF_DISABLED | IRQF_SHARED : IRQF_DISABLED,
+ IRQF_SHARED : IRQF_DISABLED,
"SoundBlaster", (void *) chip)) {
snd_printk(KERN_ERR "sb: can't grab irq %d\n", irq);
snd_sbdsp_free(chip);
diff --git a/sound/isa/wavefront/wavefront_synth.c b/sound/isa/wavefront/wavefront_synth.c
index bed329edbdd7..78020d832e04 100644
--- a/sound/isa/wavefront/wavefront_synth.c
+++ b/sound/isa/wavefront/wavefront_synth.c
@@ -1068,7 +1068,7 @@ wavefront_send_sample (snd_wavefront_t *dev,
blocksize = max_blksize;
} else {
/* round to nearest 16-byte value */
- blocksize = ((length-written+7)&~0x7);
+ blocksize = ALIGN(length - written, 8);
}
if (snd_wavefront_cmd (dev, WFC_DOWNLOAD_BLOCK, NULL, NULL)) {
diff --git a/sound/oss/ad1848.c b/sound/oss/ad1848.c
index 0ffa9970bf0f..7cf9913a47b2 100644
--- a/sound/oss/ad1848.c
+++ b/sound/oss/ad1848.c
@@ -1992,7 +1992,7 @@ int ad1848_init (char *name, struct resource *ports, int irq, int dma_playback,
devc->audio_flags |= DMA_DUPLEX;
}
- portc = (ad1848_port_info *) kmalloc(sizeof(ad1848_port_info), GFP_KERNEL);
+ portc = kmalloc(sizeof(ad1848_port_info), GFP_KERNEL);
if(portc==NULL) {
release_region(devc->base, 4);
return -1;
diff --git a/sound/oss/cs4232.c b/sound/oss/cs4232.c
index b6924c7f1484..de40e21bf279 100644
--- a/sound/oss/cs4232.c
+++ b/sound/oss/cs4232.c
@@ -408,7 +408,7 @@ static int __init cs4232_pnp_probe(struct pnp_dev *dev, const struct pnp_device_
{
struct address_info *isapnpcfg;
- isapnpcfg=(struct address_info*)kmalloc(sizeof(*isapnpcfg),GFP_KERNEL);
+ isapnpcfg = kmalloc(sizeof(*isapnpcfg),GFP_KERNEL);
if (!isapnpcfg)
return -ENOMEM;
diff --git a/sound/oss/dmasound/tas3001c.c b/sound/oss/dmasound/tas3001c.c
index f227c9f688cc..2f21a3c00374 100644
--- a/sound/oss/dmasound/tas3001c.c
+++ b/sound/oss/dmasound/tas3001c.c
@@ -50,6 +50,7 @@ struct tas3001c_data_t {
int output_id;
int speaker_id;
struct tas_drce_t drce_state;
+ struct work_struct change;
};
@@ -667,14 +668,13 @@ tas3001c_update_device_parameters(struct tas3001c_data_t *self)
}
static void
-tas3001c_device_change_handler(void *self)
+tas3001c_device_change_handler(struct work_struct *work)
{
- if (self)
- tas3001c_update_device_parameters(self);
+ struct tas3001c_data_t *self;
+ self = container_of(work, struct tas3001c_data_t, change);
+ tas3001c_update_device_parameters(self);
}
-static struct work_struct device_change;
-
static int
tas3001c_output_device_change( struct tas3001c_data_t *self,
int device_id,
@@ -685,7 +685,7 @@ tas3001c_output_device_change( struct tas3001c_data_t *self,
self->output_id=output_id;
self->speaker_id=speaker_id;
- schedule_work(&device_change);
+ schedule_work(&self->change);
return 0;
}
@@ -823,7 +823,7 @@ tas3001c_init(struct i2c_client *client)
tas3001c_write_biquad_shadow(self, i, j,
&tas3001c_eq_unity);
- INIT_WORK(&device_change, tas3001c_device_change_handler, self);
+ INIT_WORK(&self->change, tas3001c_device_change_handler);
return 0;
}
diff --git a/sound/oss/dmasound/tas3004.c b/sound/oss/dmasound/tas3004.c
index 82eaaca2db9a..af34fb39bc29 100644
--- a/sound/oss/dmasound/tas3004.c
+++ b/sound/oss/dmasound/tas3004.c
@@ -48,6 +48,7 @@ struct tas3004_data_t {
int output_id;
int speaker_id;
struct tas_drce_t drce_state;
+ struct work_struct change;
};
#define MAKE_TIME(sec,usec) (((sec)<<12) + (50000+(usec/10)*(1<<12))/100000)
@@ -914,15 +915,13 @@ tas3004_update_device_parameters(struct tas3004_data_t *self)
}
static void
-tas3004_device_change_handler(void *self)
+tas3004_device_change_handler(struct work_struct *work)
{
- if (!self) return;
-
- tas3004_update_device_parameters((struct tas3004_data_t *)self);
+ struct tas3004_data_t *self;
+ self = container_of(work, struct tas3004_data_t, change);
+ tas3004_update_device_parameters(self);
}
-static struct work_struct device_change;
-
static int
tas3004_output_device_change( struct tas3004_data_t *self,
int device_id,
@@ -933,7 +932,7 @@ tas3004_output_device_change( struct tas3004_data_t *self,
self->output_id=output_id;
self->speaker_id=speaker_id;
- schedule_work(&device_change);
+ schedule_work(&self->change);
return 0;
}
@@ -1112,7 +1111,7 @@ tas3004_init(struct i2c_client *client)
tas3004_write_register(self, TAS3004_REG_MCR2, &mcr2, WRITE_SHADOW);
tas3004_write_register(self, TAS3004_REG_DRC, drce_init, WRITE_SHADOW);
- INIT_WORK(&device_change, tas3004_device_change_handler, self);
+ INIT_WORK(&self->change, tas3004_device_change_handler);
return 0;
}
diff --git a/sound/oss/emu10k1/audio.c b/sound/oss/emu10k1/audio.c
index 49f902f35c28..efcf589d7083 100644
--- a/sound/oss/emu10k1/audio.c
+++ b/sound/oss/emu10k1/audio.c
@@ -1139,7 +1139,7 @@ static int emu10k1_audio_open(struct inode *inode, struct file *file)
match:
- wave_dev = (struct emu10k1_wavedevice *) kmalloc(sizeof(struct emu10k1_wavedevice), GFP_KERNEL);
+ wave_dev = kmalloc(sizeof(struct emu10k1_wavedevice), GFP_KERNEL);
if (wave_dev == NULL) {
ERROR();
@@ -1155,7 +1155,7 @@ match:
/* Recording */
struct wiinst *wiinst;
- if ((wiinst = (struct wiinst *) kmalloc(sizeof(struct wiinst), GFP_KERNEL)) == NULL) {
+ if ((wiinst = kmalloc(sizeof(struct wiinst), GFP_KERNEL)) == NULL) {
ERROR();
kfree(wave_dev);
return -ENOMEM;
@@ -1211,7 +1211,7 @@ match:
struct woinst *woinst;
int i;
- if ((woinst = (struct woinst *) kmalloc(sizeof(struct woinst), GFP_KERNEL)) == NULL) {
+ if ((woinst = kmalloc(sizeof(struct woinst), GFP_KERNEL)) == NULL) {
ERROR();
kfree(wave_dev);
return -ENOMEM;
diff --git a/sound/oss/emu10k1/cardmi.c b/sound/oss/emu10k1/cardmi.c
index 0545814cc67d..57674f8c8a2e 100644
--- a/sound/oss/emu10k1/cardmi.c
+++ b/sound/oss/emu10k1/cardmi.c
@@ -157,7 +157,7 @@ int emu10k1_mpuin_add_buffer(struct emu10k1_mpuin *card_mpuin, struct midi_hdr *
midihdr->flags |= MIDIBUF_INQUEUE; /* set */
midihdr->flags &= ~MIDIBUF_DONE; /* clear */
- if ((midiq = (struct midi_queue *) kmalloc(sizeof(struct midi_queue), GFP_ATOMIC)) == NULL) {
+ if ((midiq = kmalloc(sizeof(struct midi_queue), GFP_ATOMIC)) == NULL) {
/* Message lost */
return -1;
}
diff --git a/sound/oss/emu10k1/cardmo.c b/sound/oss/emu10k1/cardmo.c
index 5938d31f9e21..a8cc75db3e45 100644
--- a/sound/oss/emu10k1/cardmo.c
+++ b/sound/oss/emu10k1/cardmo.c
@@ -117,7 +117,7 @@ int emu10k1_mpuout_add_buffer(struct emu10k1_card *card, struct midi_hdr *midihd
midihdr->flags |= MIDIBUF_INQUEUE;
midihdr->flags &= ~MIDIBUF_DONE;
- if ((midiq = (struct midi_queue *) kmalloc(sizeof(struct midi_queue), GFP_KERNEL)) == NULL) {
+ if ((midiq = kmalloc(sizeof(struct midi_queue), GFP_KERNEL)) == NULL) {
/* Message lost */
return -1;
}
diff --git a/sound/oss/emu10k1/midi.c b/sound/oss/emu10k1/midi.c
index 8ac77df86397..cca3dad2bdf4 100644
--- a/sound/oss/emu10k1/midi.c
+++ b/sound/oss/emu10k1/midi.c
@@ -58,7 +58,7 @@ static int midiin_add_buffer(struct emu10k1_mididevice *midi_dev, struct midi_hd
{
struct midi_hdr *midihdr;
- if ((midihdr = (struct midi_hdr *) kmalloc(sizeof(struct midi_hdr), GFP_KERNEL)) == NULL) {
+ if ((midihdr = kmalloc(sizeof(struct midi_hdr), GFP_KERNEL)) == NULL) {
ERROR();
return -EINVAL;
}
@@ -128,7 +128,7 @@ match:
mutex_lock(&card->open_sem);
}
- if ((midi_dev = (struct emu10k1_mididevice *) kmalloc(sizeof(*midi_dev), GFP_KERNEL)) == NULL)
+ if ((midi_dev = kmalloc(sizeof(*midi_dev), GFP_KERNEL)) == NULL)
return -EINVAL;
midi_dev->card = card;
@@ -328,7 +328,7 @@ static ssize_t emu10k1_midi_write(struct file *file, const char __user *buffer,
if (!access_ok(VERIFY_READ, buffer, count))
return -EFAULT;
- if ((midihdr = (struct midi_hdr *) kmalloc(sizeof(struct midi_hdr), GFP_KERNEL)) == NULL)
+ if ((midihdr = kmalloc(sizeof(struct midi_hdr), GFP_KERNEL)) == NULL)
return -EINVAL;
midihdr->bufferlength = count;
@@ -490,7 +490,7 @@ int emu10k1_seq_midi_open(int dev, int mode,
DPF(2, "emu10k1_seq_midi_open()\n");
- if ((midi_dev = (struct emu10k1_mididevice *) kmalloc(sizeof(*midi_dev), GFP_KERNEL)) == NULL)
+ if ((midi_dev = kmalloc(sizeof(*midi_dev), GFP_KERNEL)) == NULL)
return -EINVAL;
midi_dev->card = card;
@@ -540,7 +540,7 @@ int emu10k1_seq_midi_out(int dev, unsigned char midi_byte)
card = midi_devs[dev]->devc;
- if ((midihdr = (struct midi_hdr *) kmalloc(sizeof(struct midi_hdr), GFP_KERNEL)) == NULL)
+ if ((midihdr = kmalloc(sizeof(struct midi_hdr), GFP_KERNEL)) == NULL)
return -EINVAL;
midihdr->bufferlength = 1;
diff --git a/sound/oss/emu10k1/mixer.c b/sound/oss/emu10k1/mixer.c
index cbcaaa34189a..6419796c2ed7 100644
--- a/sound/oss/emu10k1/mixer.c
+++ b/sound/oss/emu10k1/mixer.c
@@ -194,7 +194,7 @@ static int emu10k1_private_mixer(struct emu10k1_card *card, unsigned int cmd, un
case SOUND_MIXER_PRIVATE3:
- ctl = (struct mixer_private_ioctl *) kmalloc(sizeof(struct mixer_private_ioctl), GFP_KERNEL);
+ ctl = kmalloc(sizeof(struct mixer_private_ioctl), GFP_KERNEL);
if (ctl == NULL)
return -ENOMEM;
diff --git a/sound/oss/hal2.c b/sound/oss/hal2.c
index 784bdd707055..d18286ccc14d 100644
--- a/sound/oss/hal2.c
+++ b/sound/oss/hal2.c
@@ -1435,7 +1435,7 @@ static int hal2_init_card(struct hal2_card **phal2, struct hpc3_regs *hpc3)
int ret = 0;
struct hal2_card *hal2;
- hal2 = (struct hal2_card *) kmalloc(sizeof(struct hal2_card), GFP_KERNEL);
+ hal2 = kmalloc(sizeof(struct hal2_card), GFP_KERNEL);
if (!hal2)
return -ENOMEM;
memset(hal2, 0, sizeof(struct hal2_card));
diff --git a/sound/oss/mpu401.c b/sound/oss/mpu401.c
index e96220541971..2796c0ef985f 100644
--- a/sound/oss/mpu401.c
+++ b/sound/oss/mpu401.c
@@ -1023,7 +1023,7 @@ int attach_mpu401(struct address_info *hw_config, struct module *owner)
devc->capabilities |= MPU_CAP_INTLG; /* Supports intelligent mode */
- mpu401_synth_operations[m] = (struct synth_operations *)kmalloc(sizeof(struct synth_operations), GFP_KERNEL);
+ mpu401_synth_operations[m] = kmalloc(sizeof(struct synth_operations), GFP_KERNEL);
if (mpu401_synth_operations[m] == NULL)
{
diff --git a/sound/oss/opl3.c b/sound/oss/opl3.c
index 4799bc77f987..2e8cfa5481f2 100644
--- a/sound/oss/opl3.c
+++ b/sound/oss/opl3.c
@@ -166,7 +166,7 @@ int opl3_detect(int ioaddr, int *osp)
return 0;
}
- devc = (struct opl_devinfo *)kmalloc(sizeof(*devc), GFP_KERNEL);
+ devc = kmalloc(sizeof(*devc), GFP_KERNEL);
if (devc == NULL)
{
diff --git a/sound/oss/sb_common.c b/sound/oss/sb_common.c
index 440537c72604..07cbacf63824 100644
--- a/sound/oss/sb_common.c
+++ b/sound/oss/sb_common.c
@@ -625,7 +625,7 @@ int sb_dsp_detect(struct address_info *hw_config, int pci, int pciio, struct sb_
*/
- detected_devc = (sb_devc *)kmalloc(sizeof(sb_devc), GFP_KERNEL);
+ detected_devc = kmalloc(sizeof(sb_devc), GFP_KERNEL);
if (detected_devc == NULL)
{
printk(KERN_ERR "sb: Can't allocate memory for device information\n");
diff --git a/sound/oss/sb_midi.c b/sound/oss/sb_midi.c
index 2e3bc045caba..8b796704e112 100644
--- a/sound/oss/sb_midi.c
+++ b/sound/oss/sb_midi.c
@@ -173,7 +173,7 @@ void sb_dsp_midi_init(sb_devc * devc, struct module *owner)
return;
}
std_midi_synth.midi_dev = devc->my_mididev = dev;
- midi_devs[dev] = (struct midi_operations *)kmalloc(sizeof(struct midi_operations), GFP_KERNEL);
+ midi_devs[dev] = kmalloc(sizeof(struct midi_operations), GFP_KERNEL);
if (midi_devs[dev] == NULL)
{
printk(KERN_WARNING "Sound Blaster: failed to allocate MIDI memory.\n");
@@ -189,7 +189,7 @@ void sb_dsp_midi_init(sb_devc * devc, struct module *owner)
midi_devs[dev]->devc = devc;
- midi_devs[dev]->converter = (struct synth_operations *)kmalloc(sizeof(struct synth_operations), GFP_KERNEL);
+ midi_devs[dev]->converter = kmalloc(sizeof(struct synth_operations), GFP_KERNEL);
if (midi_devs[dev]->converter == NULL)
{
printk(KERN_WARNING "Sound Blaster: failed to allocate MIDI memory.\n");
diff --git a/sound/oss/sb_mixer.c b/sound/oss/sb_mixer.c
index 238e2cf44b08..fad1a4f25ad6 100644
--- a/sound/oss/sb_mixer.c
+++ b/sound/oss/sb_mixer.c
@@ -734,7 +734,7 @@ int sb_mixer_init(sb_devc * devc, struct module *owner)
if (m == -1)
return 0;
- mixer_devs[m] = (struct mixer_operations *)kmalloc(sizeof(struct mixer_operations), GFP_KERNEL);
+ mixer_devs[m] = kmalloc(sizeof(struct mixer_operations), GFP_KERNEL);
if (mixer_devs[m] == NULL)
{
printk(KERN_ERR "sb_mixer: Can't allocate memory\n");
diff --git a/sound/oss/v_midi.c b/sound/oss/v_midi.c
index d952b2264da1..103940fd5b4f 100644
--- a/sound/oss/v_midi.c
+++ b/sound/oss/v_midi.c
@@ -183,7 +183,7 @@ static void __init attach_v_midi (struct address_info *hw_config)
return;
}
- m=(struct vmidi_memory *)kmalloc(sizeof(struct vmidi_memory), GFP_KERNEL);
+ m = kmalloc(sizeof(struct vmidi_memory), GFP_KERNEL);
if (m == NULL)
{
printk(KERN_WARNING "Loopback MIDI: Failed to allocate memory\n");
diff --git a/sound/oss/waveartist.c b/sound/oss/waveartist.c
index c5bf363d32c2..26a7c6af95bc 100644
--- a/sound/oss/waveartist.c
+++ b/sound/oss/waveartist.c
@@ -1267,7 +1267,7 @@ static int __init waveartist_init(wavnc_info *devc)
conf_printf2(dev_name, devc->hw.io_base, devc->hw.irq,
devc->hw.dma, devc->hw.dma2);
- portc = (wavnc_port_info *)kmalloc(sizeof(wavnc_port_info), GFP_KERNEL);
+ portc = kmalloc(sizeof(wavnc_port_info), GFP_KERNEL);
if (portc == NULL)
goto nomem;
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
index 7abcb10b2754..d2994cb4c8c9 100644
--- a/sound/pci/ac97/ac97_codec.c
+++ b/sound/pci/ac97/ac97_codec.c
@@ -129,9 +129,9 @@ static const struct ac97_codec_id snd_ac97_codec_ids[] = {
{ 0x434d4941, 0xffffffff, "CMI9738", patch_cm9738, NULL },
{ 0x434d4961, 0xffffffff, "CMI9739", patch_cm9739, NULL },
{ 0x434d4969, 0xffffffff, "CMI9780", patch_cm9780, NULL },
-{ 0x434d4978, 0xffffffff, "CMI9761", patch_cm9761, NULL },
-{ 0x434d4982, 0xffffffff, "CMI9761", patch_cm9761, NULL },
-{ 0x434d4983, 0xffffffff, "CMI9761", patch_cm9761, NULL },
+{ 0x434d4978, 0xffffffff, "CMI9761A", patch_cm9761, NULL },
+{ 0x434d4982, 0xffffffff, "CMI9761B", patch_cm9761, NULL },
+{ 0x434d4983, 0xffffffff, "CMI9761A+", patch_cm9761, NULL },
{ 0x43525900, 0xfffffff8, "CS4297", NULL, NULL },
{ 0x43525910, 0xfffffff8, "CS4297A", patch_cirrus_spdif, NULL },
{ 0x43525920, 0xfffffff8, "CS4298", patch_cirrus_spdif, NULL },
@@ -382,7 +382,7 @@ int snd_ac97_update_bits_nolock(struct snd_ac97 *ac97, unsigned short reg,
unsigned short old, new;
old = snd_ac97_read_cache(ac97, reg);
- new = (old & ~mask) | value;
+ new = (old & ~mask) | (value & mask);
change = old != new;
if (change) {
ac97->regs[reg] = new;
@@ -399,7 +399,7 @@ static int snd_ac97_ad18xx_update_pcm_bits(struct snd_ac97 *ac97, int codec, uns
mutex_lock(&ac97->page_mutex);
old = ac97->spec.ad18xx.pcmreg[codec];
- new = (old & ~mask) | value;
+ new = (old & ~mask) | (value & mask);
change = old != new;
if (change) {
mutex_lock(&ac97->reg_mutex);
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index 15be6ba87c82..e813968e0cf8 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -1467,7 +1467,9 @@ static void patch_ad1881_chained(struct snd_ac97 * ac97, int unchained_idx, int
snd_ac97_write_cache(ac97, AC97_AD_CODEC_CFG, 0x0002); // ID1C
ac97->spec.ad18xx.codec_cfg[unchained_idx] = 0x0002;
if (cidx1 >= 0) {
- if (patch_ad1881_chained1(ac97, cidx1, 0x0006)) // SDIE | ID1C
+ if (cidx2 < 0)
+ patch_ad1881_chained1(ac97, cidx1, 0);
+ else if (patch_ad1881_chained1(ac97, cidx1, 0x0006)) // SDIE | ID1C
patch_ad1881_chained1(ac97, cidx2, 0);
else if (patch_ad1881_chained1(ac97, cidx2, 0x0006)) // SDIE | ID1C
patch_ad1881_chained1(ac97, cidx1, 0);
@@ -2261,7 +2263,8 @@ int patch_alc655(struct snd_ac97 * ac97)
else { /* ALC655 */
if (ac97->subsystem_vendor == 0x1462 &&
(ac97->subsystem_device == 0x0131 || /* MSI S270 laptop */
- ac97->subsystem_device == 0x0161)) /* LG K1 Express */
+ ac97->subsystem_device == 0x0161 || /* LG K1 Express */
+ ac97->subsystem_device == 0x0351)) /* MSI L725 laptop */
val &= ~(1 << 1); /* Pin 47 is EAPD (for internal speaker) */
else
val |= (1 << 1); /* Pin 47 is spdif input pin */
diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c
index cbf8331c3d33..98970d401be9 100644
--- a/sound/pci/ad1889.c
+++ b/sound/pci/ad1889.c
@@ -858,7 +858,7 @@ snd_ad1889_free(struct snd_ad1889 *chip)
synchronize_irq(chip->irq);
if (chip->irq >= 0)
- free_irq(chip->irq, (void*)chip);
+ free_irq(chip->irq, chip);
skip_hw:
if (chip->iobase)
@@ -945,7 +945,7 @@ snd_ad1889_create(struct snd_card *card,
spin_lock_init(&chip->lock); /* only now can we call ad1889_free */
if (request_irq(pci->irq, snd_ad1889_interrupt,
- IRQF_DISABLED|IRQF_SHARED, card->driver, (void*)chip)) {
+ IRQF_SHARED, card->driver, chip)) {
printk(KERN_ERR PFX "cannot obtain IRQ %d\n", pci->irq);
snd_ad1889_free(chip);
return -EBUSY;
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
index a7edd56542d4..9327ab2eccb0 100644
--- a/sound/pci/ali5451/ali5451.c
+++ b/sound/pci/ali5451/ali5451.c
@@ -2095,7 +2095,7 @@ static int snd_ali_free(struct snd_ali * codec)
snd_ali_disable_address_interrupt(codec);
if (codec->irq >= 0) {
synchronize_irq(codec->irq);
- free_irq(codec->irq, (void *)codec);
+ free_irq(codec->irq, codec);
}
if (codec->port)
pci_release_regions(codec->pci);
@@ -2192,7 +2192,8 @@ static int __devinit snd_ali_resources(struct snd_ali *codec)
return err;
codec->port = pci_resource_start(codec->pci, 0);
- if (request_irq(codec->pci->irq, snd_ali_card_interrupt, IRQF_DISABLED|IRQF_SHARED, "ALI 5451", (void *)codec)) {
+ if (request_irq(codec->pci->irq, snd_ali_card_interrupt,
+ IRQF_SHARED, "ALI 5451", codec)) {
snd_printk(KERN_ERR "Unable to request irq.\n");
return -EBUSY;
}
diff --git a/sound/pci/als300.c b/sound/pci/als300.c
index 95f70f3cc37e..9f406fbe0d95 100644
--- a/sound/pci/als300.c
+++ b/sound/pci/als300.c
@@ -190,7 +190,7 @@ static int snd_als300_free(struct snd_als300 *chip)
snd_als300_dbgcallenter();
snd_als300_set_irq_flag(chip, IRQ_DISABLE);
if (chip->irq >= 0)
- free_irq(chip->irq, (void *)chip);
+ free_irq(chip->irq, chip);
pci_release_regions(chip->pci);
pci_disable_device(chip->pci);
kfree(chip);
@@ -722,8 +722,8 @@ static int __devinit snd_als300_create(snd_card_t *card,
else
irq_handler = snd_als300_interrupt;
- if (request_irq(pci->irq, irq_handler, IRQF_DISABLED|IRQF_SHARED,
- card->shortname, (void *)chip)) {
+ if (request_irq(pci->irq, irq_handler, IRQF_SHARED,
+ card->shortname, chip)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_als300_free(chip);
return -EBUSY;
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
index e3e99f396711..476c3433073e 100644
--- a/sound/pci/atiixp.c
+++ b/sound/pci/atiixp.c
@@ -1583,7 +1583,7 @@ static int __devinit snd_atiixp_create(struct snd_card *card,
return -EIO;
}
- if (request_irq(pci->irq, snd_atiixp_interrupt, IRQF_DISABLED|IRQF_SHARED,
+ if (request_irq(pci->irq, snd_atiixp_interrupt, IRQF_SHARED,
card->shortname, chip)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_atiixp_free(chip);
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c
index dc54f2c68ed7..cc2e6b9d407e 100644
--- a/sound/pci/atiixp_modem.c
+++ b/sound/pci/atiixp_modem.c
@@ -1256,7 +1256,7 @@ static int __devinit snd_atiixp_create(struct snd_card *card,
return -EIO;
}
- if (request_irq(pci->irq, snd_atiixp_interrupt, IRQF_DISABLED|IRQF_SHARED,
+ if (request_irq(pci->irq, snd_atiixp_interrupt, IRQF_SHARED,
card->shortname, chip)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_atiixp_free(chip);
diff --git a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c
index 6ed5ad59f5b5..238154bb7a25 100644
--- a/sound/pci/au88x0/au88x0.c
+++ b/sound/pci/au88x0/au88x0.c
@@ -198,7 +198,7 @@ snd_vortex_create(struct snd_card *card, struct pci_dev *pci, vortex_t ** rchip)
}
if ((err = request_irq(pci->irq, vortex_interrupt,
- IRQF_DISABLED | IRQF_SHARED, CARD_NAME_SHORT,
+ IRQF_SHARED, CARD_NAME_SHORT,
chip)) != 0) {
printk(KERN_ERR "cannot grab irq\n");
goto irq_out;
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index 2414ee630756..43edd2839b5a 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -1513,7 +1513,7 @@ snd_azf3328_free(struct snd_azf3328 *chip)
__end_hw:
snd_azf3328_free_joystick(chip);
if (chip->irq >= 0)
- free_irq(chip->irq, (void *)chip);
+ free_irq(chip->irq, chip);
pci_release_regions(chip->pci);
pci_disable_device(chip->pci);
@@ -1724,7 +1724,8 @@ snd_azf3328_create(struct snd_card *card,
chip->synth_port = pci_resource_start(pci, 3);
chip->mixer_port = pci_resource_start(pci, 4);
- if (request_irq(pci->irq, snd_azf3328_interrupt, IRQF_DISABLED|IRQF_SHARED, card->shortname, (void *)chip)) {
+ if (request_irq(pci->irq, snd_azf3328_interrupt,
+ IRQF_SHARED, card->shortname, chip)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
err = -EBUSY;
goto out_err;
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
index d33a37086df9..c3f3da211234 100644
--- a/sound/pci/bt87x.c
+++ b/sound/pci/bt87x.c
@@ -699,7 +699,7 @@ static int __devinit snd_bt87x_pcm(struct snd_bt87x *chip, int device, char *nam
SNDRV_DMA_TYPE_DEV_SG,
snd_dma_pci_data(chip->pci),
128 * 1024,
- (255 * 4092 + 1023) & ~1023);
+ ALIGN(255 * 4092, 1024));
}
static int __devinit snd_bt87x_create(struct snd_card *card,
@@ -747,7 +747,7 @@ static int __devinit snd_bt87x_create(struct snd_card *card,
snd_bt87x_writel(chip, REG_INT_MASK, 0);
snd_bt87x_writel(chip, REG_INT_STAT, MY_INTERRUPTS);
- if (request_irq(pci->irq, snd_bt87x_interrupt, IRQF_DISABLED | IRQF_SHARED,
+ if (request_irq(pci->irq, snd_bt87x_interrupt, IRQF_SHARED,
"Bt87x audio", chip)) {
snd_bt87x_free(chip);
snd_printk(KERN_ERR "cannot grab irq\n");
diff --git a/sound/pci/ca0106/ca0106.h b/sound/pci/ca0106/ca0106.h
index 9cb66c59f523..aaac6e5b4767 100644
--- a/sound/pci/ca0106/ca0106.h
+++ b/sound/pci/ca0106/ca0106.h
@@ -590,7 +590,7 @@ struct snd_ca0106 {
struct resource *res_port;
int irq;
- unsigned int revision; /* chip revision */
+ unsigned char revision; /* chip revision */
unsigned int serial; /* serial number */
unsigned short model; /* subsystem id */
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index 6fa4a302f7de..f61f052f6d14 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -154,6 +154,7 @@ MODULE_SUPPORTED_DEVICE("{{Creative,SB CA0106 chip}}");
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
+static uint subsystem[SNDRV_CARDS]; /* Force card subsystem model */
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for the CA0106 soundcard.");
@@ -161,6 +162,8 @@ module_param_array(id, charp, NULL, 0444);
MODULE_PARM_DESC(id, "ID string for the CA0106 soundcard.");
module_param_array(enable, bool, NULL, 0444);
MODULE_PARM_DESC(enable, "Enable the CA0106 soundcard.");
+module_param_array(subsystem, uint, NULL, 0444);
+MODULE_PARM_DESC(subsystem, "Force card subsystem model.");
#include "ca0106.h"
@@ -194,6 +197,17 @@ static struct snd_ca0106_details ca0106_chip_details[] = {
.gpio_type = 1,
.i2c_adc = 1,
.spi_dac = 1 } ,
+ /* New Audigy LS. Has a different DAC. */
+ /* SB0570:
+ * CTRL:CA0106-DAT
+ * ADC: WM8775EDS
+ * DAC: WM8768GEDS
+ */
+ { .serial = 0x10111102,
+ .name = "Audigy SE OEM [SB0570a]",
+ .gpio_type = 1,
+ .i2c_adc = 1,
+ .spi_dac = 1 } ,
/* MSI K8N Diamond Motherboard with onboard SB Live 24bit without AC97 */
/* SB0438
* CTRL:CA0106-DAT
@@ -1046,7 +1060,7 @@ static int snd_ca0106_free(struct snd_ca0106 *chip)
// release the irq
if (chip->irq >= 0)
- free_irq(chip->irq, (void *)chip);
+ free_irq(chip->irq, chip);
pci_disable_device(chip->pci);
kfree(chip);
return 0;
@@ -1223,7 +1237,7 @@ static unsigned int i2c_adc_init[][2] = {
{ 0x15, ADC_MUX_LINEIN }, /* ADC Mixer control */
};
-static int __devinit snd_ca0106_create(struct snd_card *card,
+static int __devinit snd_ca0106_create(int dev, struct snd_card *card,
struct pci_dev *pci,
struct snd_ca0106 **rchip)
{
@@ -1267,8 +1281,7 @@ static int __devinit snd_ca0106_create(struct snd_card *card,
}
if (request_irq(pci->irq, snd_ca0106_interrupt,
- IRQF_DISABLED|IRQF_SHARED, "snd_ca0106",
- (void *)chip)) {
+ IRQF_SHARED, "snd_ca0106", chip)) {
snd_ca0106_free(chip);
printk(KERN_ERR "cannot grab irq\n");
return -EBUSY;
@@ -1283,21 +1296,29 @@ static int __devinit snd_ca0106_create(struct snd_card *card,
pci_set_master(pci);
/* read revision & serial */
- pci_read_config_byte(pci, PCI_REVISION_ID, (char *)&chip->revision);
+ pci_read_config_byte(pci, PCI_REVISION_ID, &chip->revision);
pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &chip->serial);
pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &chip->model);
#if 1
- printk(KERN_INFO "Model %04x Rev %08x Serial %08x\n", chip->model,
+ printk(KERN_INFO "snd-ca0106: Model %04x Rev %08x Serial %08x\n", chip->model,
chip->revision, chip->serial);
#endif
strcpy(card->driver, "CA0106");
strcpy(card->shortname, "CA0106");
for (c = ca0106_chip_details; c->serial; c++) {
- if (c->serial == chip->serial)
+ if (subsystem[dev]) {
+ if (c->serial == subsystem[dev])
+ break;
+ } else if (c->serial == chip->serial)
break;
}
chip->details = c;
+ if (subsystem[dev]) {
+ printk(KERN_INFO "snd-ca0106: Sound card name=%s, subsystem=0x%x. Forced to subsystem=0x%x\n",
+ c->name, chip->serial, subsystem[dev]);
+ }
+
sprintf(card->longname, "%s at 0x%lx irq %i",
c->name, chip->port, chip->irq);
@@ -1540,7 +1561,7 @@ static int __devinit snd_ca0106_probe(struct pci_dev *pci,
if (card == NULL)
return -ENOMEM;
- if ((err = snd_ca0106_create(card, pci, &chip)) < 0) {
+ if ((err = snd_ca0106_create(dev, card, pci, &chip)) < 0) {
snd_card_free(card);
return err;
}
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
index 0093cd1f92db..71c58df4af28 100644
--- a/sound/pci/cmipci.c
+++ b/sound/pci/cmipci.c
@@ -2862,7 +2862,7 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc
cm->iobase = pci_resource_start(pci, 0);
if (request_irq(pci->irq, snd_cmipci_interrupt,
- IRQF_DISABLED|IRQF_SHARED, card->driver, cm)) {
+ IRQF_SHARED, card->driver, cm)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_cmipci_free(cm);
return -EBUSY;
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c
index 0905fa88129d..8e5519de7115 100644
--- a/sound/pci/cs4281.c
+++ b/sound/pci/cs4281.c
@@ -1391,7 +1391,7 @@ static int __devinit snd_cs4281_create(struct snd_card *card,
return -ENOMEM;
}
- if (request_irq(pci->irq, snd_cs4281_interrupt, IRQF_DISABLED|IRQF_SHARED,
+ if (request_irq(pci->irq, snd_cs4281_interrupt, IRQF_SHARED,
"CS4281", chip)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_cs4281_free(chip);
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
index 2807b9756ef0..2ae539b195fd 100644
--- a/sound/pci/cs46xx/cs46xx_lib.c
+++ b/sound/pci/cs46xx/cs46xx_lib.c
@@ -3867,7 +3867,7 @@ int __devinit snd_cs46xx_create(struct snd_card *card,
}
}
- if (request_irq(pci->irq, snd_cs46xx_interrupt, IRQF_DISABLED|IRQF_SHARED,
+ if (request_irq(pci->irq, snd_cs46xx_interrupt, IRQF_SHARED,
"CS46XX", chip)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_cs46xx_free(chip);
diff --git a/sound/pci/cs5535audio/cs5535audio.c b/sound/pci/cs5535audio/cs5535audio.c
index 2441238f2004..b8e75ef9c1e6 100644
--- a/sound/pci/cs5535audio/cs5535audio.c
+++ b/sound/pci/cs5535audio/cs5535audio.c
@@ -320,7 +320,7 @@ static int __devinit snd_cs5535audio_create(struct snd_card *card,
cs5535au->port = pci_resource_start(pci, 0);
if (request_irq(pci->irq, snd_cs5535audio_interrupt,
- IRQF_DISABLED|IRQF_SHARED, "CS5535 Audio", cs5535au)) {
+ IRQF_SHARED, "CS5535 Audio", cs5535au)) {
snd_printk("unable to grab IRQ %d\n", pci->irq);
err = -EBUSY;
goto sndfail;
diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c
index e5e88fe54de0..047e0b5bf15d 100644
--- a/sound/pci/echoaudio/echoaudio.c
+++ b/sound/pci/echoaudio/echoaudio.c
@@ -1872,7 +1872,7 @@ static int snd_echo_free(struct echoaudio *chip)
DE_INIT(("Stopped.\n"));
if (chip->irq >= 0)
- free_irq(chip->irq, (void *)chip);
+ free_irq(chip->irq, chip);
if (chip->dsp_registers)
iounmap(chip->dsp_registers);
@@ -1950,8 +1950,8 @@ static __devinit int snd_echo_create(struct snd_card *card,
chip->dsp_registers = (volatile u32 __iomem *)
ioremap_nocache(chip->dsp_registers_phys, sz);
- if (request_irq(pci->irq, snd_echo_interrupt, IRQF_DISABLED | IRQF_SHARED,
- ECHOCARD_NAME, (void *)chip)) {
+ if (request_irq(pci->irq, snd_echo_interrupt, IRQF_SHARED,
+ ECHOCARD_NAME, chip)) {
snd_echo_free(chip);
snd_printk(KERN_ERR "cannot grab irq\n");
return -EBUSY;
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
index 8bc4ffa6220d..972ec40d8166 100644
--- a/sound/pci/emu10k1/emu10k1_main.c
+++ b/sound/pci/emu10k1/emu10k1_main.c
@@ -759,7 +759,7 @@ static int snd_emu10k1_free(struct snd_emu10k1 *emu)
free_pm_buffer(emu);
#endif
if (emu->irq >= 0)
- free_irq(emu->irq, (void *)emu);
+ free_irq(emu->irq, emu);
if (emu->port)
pci_release_regions(emu->pci);
if (emu->card_capabilities->ca0151_chip) /* P16V */
@@ -1246,7 +1246,8 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
}
emu->port = pci_resource_start(pci, 0);
- if (request_irq(pci->irq, snd_emu10k1_interrupt, IRQF_DISABLED|IRQF_SHARED, "EMU10K1", (void *)emu)) {
+ if (request_irq(pci->irq, snd_emu10k1_interrupt, IRQF_SHARED,
+ "EMU10K1", emu)) {
err = -EBUSY;
goto error;
}
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c
index c46905a11175..2199b42a6019 100644
--- a/sound/pci/emu10k1/emu10k1x.c
+++ b/sound/pci/emu10k1/emu10k1x.c
@@ -235,7 +235,7 @@ struct emu10k1x {
struct resource *res_port;
int irq;
- unsigned int revision; /* chip revision */
+ unsigned char revision; /* chip revision */
unsigned int serial; /* serial number */
unsigned short model; /* subsystem id */
@@ -760,7 +760,7 @@ static int snd_emu10k1x_free(struct emu10k1x *chip)
// release the irq
if (chip->irq >= 0)
- free_irq(chip->irq, (void *)chip);
+ free_irq(chip->irq, chip);
// release the DMA
if (chip->dma_buffer.area) {
@@ -927,8 +927,7 @@ static int __devinit snd_emu10k1x_create(struct snd_card *card,
}
if (request_irq(pci->irq, snd_emu10k1x_interrupt,
- IRQF_DISABLED|IRQF_SHARED, "EMU10K1X",
- (void *)chip)) {
+ IRQF_SHARED, "EMU10K1X", chip)) {
snd_printk(KERN_ERR "emu10k1x: cannot grab irq %d\n", pci->irq);
snd_emu10k1x_free(chip);
return -EBUSY;
@@ -943,7 +942,7 @@ static int __devinit snd_emu10k1x_create(struct snd_card *card,
pci_set_master(pci);
/* read revision & serial */
- pci_read_config_byte(pci, PCI_REVISION_ID, (char *)&chip->revision);
+ pci_read_config_byte(pci, PCI_REVISION_ID, &chip->revision);
pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &chip->serial);
pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &chip->model);
snd_printk(KERN_INFO "Model %04x Rev %08x Serial %08x\n", chip->model,
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c
index d2a811f222c9..a84f6b21024f 100644
--- a/sound/pci/ens1370.c
+++ b/sound/pci/ens1370.c
@@ -2141,7 +2141,7 @@ static int __devinit snd_ensoniq_create(struct snd_card *card,
return err;
}
ensoniq->port = pci_resource_start(pci, 0);
- if (request_irq(pci->irq, snd_audiopci_interrupt, IRQF_DISABLED|IRQF_SHARED,
+ if (request_irq(pci->irq, snd_audiopci_interrupt, IRQF_SHARED,
"Ensoniq AudioPCI", ensoniq)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_ensoniq_free(ensoniq);
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c
index 1a8d36df4b5d..66ac26c5a240 100644
--- a/sound/pci/es1938.c
+++ b/sound/pci/es1938.c
@@ -1508,7 +1508,7 @@ static int es1938_resume(struct pci_dev *pci)
}
if (request_irq(pci->irq, snd_es1938_interrupt,
- IRQF_DISABLED|IRQF_SHARED, "ES1938", chip)) {
+ IRQF_SHARED, "ES1938", chip)) {
printk(KERN_ERR "es1938: unable to grab IRQ %d, "
"disabling device\n", pci->irq);
snd_card_disconnect(card);
@@ -1631,7 +1631,7 @@ static int __devinit snd_es1938_create(struct snd_card *card,
chip->vc_port = pci_resource_start(pci, 2);
chip->mpu_port = pci_resource_start(pci, 3);
chip->game_port = pci_resource_start(pci, 4);
- if (request_irq(pci->irq, snd_es1938_interrupt, IRQF_DISABLED|IRQF_SHARED,
+ if (request_irq(pci->irq, snd_es1938_interrupt, IRQF_SHARED,
"ES1938", chip)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_es1938_free(chip);
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index 092da53e1464..dc84c189b05f 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -1337,7 +1337,7 @@ static struct esm_memory *snd_es1968_new_memory(struct es1968 *chip, int size)
struct esm_memory *buf;
struct list_head *p;
- size = ((size + ESM_MEM_ALIGN - 1) / ESM_MEM_ALIGN) * ESM_MEM_ALIGN;
+ size = ALIGN(size, ESM_MEM_ALIGN);
mutex_lock(&chip->memory_mutex);
list_for_each(p, &chip->buf_list) {
buf = list_entry(p, struct esm_memory, list);
@@ -2462,7 +2462,7 @@ static int snd_es1968_free(struct es1968 *chip)
}
if (chip->irq >= 0)
- free_irq(chip->irq, (void *)chip);
+ free_irq(chip->irq, chip);
snd_es1968_free_gameport(chip);
chip->master_switch = NULL;
chip->master_volume = NULL;
@@ -2552,8 +2552,8 @@ static int __devinit snd_es1968_create(struct snd_card *card,
return err;
}
chip->io_port = pci_resource_start(pci, 0);
- if (request_irq(pci->irq, snd_es1968_interrupt, IRQF_DISABLED|IRQF_SHARED,
- "ESS Maestro", (void*)chip)) {
+ if (request_irq(pci->irq, snd_es1968_interrupt, IRQF_SHARED,
+ "ESS Maestro", chip)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_es1968_free(chip);
return -EBUSY;
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index 77e3d5c18302..b7b361ce3a93 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -1395,7 +1395,7 @@ static int __devinit snd_fm801_create(struct snd_card *card,
}
chip->port = pci_resource_start(pci, 0);
if ((tea575x_tuner & 0x0010) == 0) {
- if (request_irq(pci->irq, snd_fm801_interrupt, IRQF_DISABLED|IRQF_SHARED,
+ if (request_irq(pci->irq, snd_fm801_interrupt, IRQF_SHARED,
"FM801", chip)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", chip->irq);
snd_fm801_free(chip);
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 71482c15a852..18bbc87e376f 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -1367,9 +1367,6 @@ static struct hda_rate_tbl rate_bits[] = {
{ 176400, SNDRV_PCM_RATE_176400, 0x5800 },/* 4 x 44 */
{ 192000, SNDRV_PCM_RATE_192000, 0x1800 }, /* 4 x 48 */
- /* not autodetected value */
- { 9600, SNDRV_PCM_RATE_KNOT, 0x0400 }, /* 1/5 x 48 */
-
{ 0 } /* terminator */
};
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index e35cfd326df2..9fd34f85cad5 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -1380,7 +1380,8 @@ static int __devinit azx_init_stream(struct azx *chip)
static int azx_acquire_irq(struct azx *chip, int do_disconnect)
{
- if (request_irq(chip->pci->irq, azx_interrupt, IRQF_DISABLED|IRQF_SHARED,
+ if (request_irq(chip->pci->irq, azx_interrupt,
+ chip->msi ? 0 : IRQF_SHARED,
"HDA Intel", chip)) {
printk(KERN_ERR "hda-intel: unable to grab IRQ %d, "
"disabling device\n", chip->pci->irq);
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index d737f17695a3..17df4d0fe135 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -45,7 +45,7 @@ static const char *get_wid_type_name(unsigned int wid_value)
if (names[wid_value])
return names[wid_value];
else
- return "UNKOWN Widget";
+ return "UNKNOWN Widget";
}
static void print_amp_caps(struct snd_info_buffer *buffer,
@@ -88,6 +88,48 @@ static void print_amp_vals(struct snd_info_buffer *buffer,
snd_iprintf(buffer, "\n");
}
+static void print_pcm_rates(struct snd_info_buffer *buffer, unsigned int pcm)
+{
+ static unsigned int rates[] = {
+ 8000, 11025, 16000, 22050, 32000, 44100, 48000, 88200,
+ 96000, 176400, 192000, 384000
+ };
+ int i;
+
+ pcm &= AC_SUPPCM_RATES;
+ snd_iprintf(buffer, " rates [0x%x]:", pcm);
+ for (i = 0; i < ARRAY_SIZE(rates); i++)
+ if (pcm & (1 << i))
+ snd_iprintf(buffer, " %d", rates[i]);
+ snd_iprintf(buffer, "\n");
+}
+
+static void print_pcm_bits(struct snd_info_buffer *buffer, unsigned int pcm)
+{
+ static unsigned int bits[] = { 8, 16, 20, 24, 32 };
+ int i;
+
+ pcm = (pcm >> 16) & 0xff;
+ snd_iprintf(buffer, " bits [0x%x]:", pcm);
+ for (i = 0; i < ARRAY_SIZE(bits); i++)
+ if (pcm & (1 << i))
+ snd_iprintf(buffer, " %d", bits[i]);
+ snd_iprintf(buffer, "\n");
+}
+
+static void print_pcm_formats(struct snd_info_buffer *buffer,
+ unsigned int streams)
+{
+ snd_iprintf(buffer, " formats [0x%x]:", streams & 0xf);
+ if (streams & AC_SUPFMT_PCM)
+ snd_iprintf(buffer, " PCM");
+ if (streams & AC_SUPFMT_FLOAT32)
+ snd_iprintf(buffer, " FLOAT");
+ if (streams & AC_SUPFMT_AC3)
+ snd_iprintf(buffer, " AC3");
+ snd_iprintf(buffer, "\n");
+}
+
static void print_pcm_caps(struct snd_info_buffer *buffer,
struct hda_codec *codec, hda_nid_t nid)
{
@@ -97,8 +139,9 @@ static void print_pcm_caps(struct snd_info_buffer *buffer,
snd_iprintf(buffer, "N/A\n");
return;
}
- snd_iprintf(buffer, "rates 0x%03x, bits 0x%02x, types 0x%x\n",
- pcm & AC_SUPPCM_RATES, (pcm >> 16) & 0xff, stream & 0xf);
+ print_pcm_rates(buffer, pcm);
+ print_pcm_bits(buffer, pcm);
+ print_pcm_formats(buffer, stream);
}
static const char *get_jack_location(u32 cfg)
@@ -210,7 +253,7 @@ static void print_codec_info(struct snd_info_entry *entry, struct snd_info_buffe
snd_iprintf(buffer, "Revision Id: 0x%x\n", codec->revision_id);
if (! codec->afg)
return;
- snd_iprintf(buffer, "Default PCM: ");
+ snd_iprintf(buffer, "Default PCM:\n");
print_pcm_caps(buffer, codec, codec->afg);
snd_iprintf(buffer, "Default Amp-In caps: ");
print_amp_caps(buffer, codec, codec->afg, HDA_INPUT);
@@ -278,7 +321,7 @@ static void print_codec_info(struct snd_info_entry *entry, struct snd_info_buffe
if ((wid_type == AC_WID_AUD_OUT || wid_type == AC_WID_AUD_IN) &&
(wid_caps & AC_WCAP_FORMAT_OVRD)) {
- snd_iprintf(buffer, " PCM: ");
+ snd_iprintf(buffer, " PCM:\n");
print_pcm_caps(buffer, codec, nid);
}
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index edd22dec8286..076365bc10e9 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -794,6 +794,8 @@ static struct hda_board_config ad1986a_cfg_tbl[] = {
{ .modelname = "3stack", .config = AD1986A_3STACK },
{ .pci_subvendor = 0x10de, .pci_subdevice = 0xcb84,
.config = AD1986A_3STACK }, /* ASUS A8N-VM CSM */
+ { .pci_subvendor = 0x1043, .pci_subdevice = 0x817f,
+ .config = AD1986A_3STACK }, /* ASUS P5P-L2 */
{ .pci_subvendor = 0x1043, .pci_subdevice = 0x81b3,
.config = AD1986A_3STACK }, /* ASUS P5RD2-VM / P5GPL-X SE */
{ .pci_subvendor = 0x1043, .pci_subdevice = 0x81cb,
@@ -811,7 +813,7 @@ static struct hda_board_config ad1986a_cfg_tbl[] = {
{ .pci_subvendor = 0x144d, .pci_subdevice = 0xc024,
.config = AD1986A_LAPTOP_EAPD }, /* Samsung R65-T2300 Charis */
{ .pci_subvendor = 0x144d, .pci_subdevice = 0xc026,
- .config = AD1986A_LAPTOP_EAPD }, /* Samsung X10-T2300 Culesa */
+ .config = AD1986A_LAPTOP_EAPD }, /* Samsung X11-T2300 Culesa */
{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1153,
.config = AD1986A_LAPTOP_EAPD }, /* ASUS M9 */
{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1213,
@@ -822,6 +824,8 @@ static struct hda_board_config ad1986a_cfg_tbl[] = {
.config = AD1986A_LAPTOP_EAPD }, /* ASUS U5F */
{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1297,
.config = AD1986A_LAPTOP_EAPD }, /* ASUS Z62F */
+ { .pci_subvendor = 0x1043, .pci_subdevice = 0x12b3,
+ .config = AD1986A_LAPTOP_EAPD }, /* ASUS V1j */
{ .pci_subvendor = 0x103c, .pci_subdevice = 0x30af,
.config = AD1986A_LAPTOP_EAPD }, /* HP Compaq Presario B2800 */
{ .pci_subvendor = 0x17aa, .pci_subdevice = 0x2066,
@@ -1640,7 +1644,7 @@ static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol,
int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
spec->num_channel_mode,
&spec->multiout.max_channels);
- if (! err && spec->need_dac_fix)
+ if (err >= 0 && spec->need_dac_fix)
spec->multiout.num_dacs = spec->multiout.max_channels / 2;
return err;
}
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index fb961448db19..4e0c3c1b908b 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -271,7 +271,7 @@ static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
spec->num_channel_mode,
&spec->multiout.max_channels);
- if (! err && spec->need_dac_fix)
+ if (err >= 0 && spec->need_dac_fix)
spec->multiout.num_dacs = spec->multiout.max_channels / 2;
return err;
}
@@ -5070,6 +5070,8 @@ static struct hda_board_config alc883_cfg_tbl[] = {
{ .modelname = "6stack-dig", .config = ALC883_6ST_DIG },
{ .pci_subvendor = 0x1462, .pci_subdevice = 0x6668,
.config = ALC883_6ST_DIG }, /* MSI */
+ { .pci_subvendor = 0x1462, .pci_subdevice = 0x7280,
+ .config = ALC883_6ST_DIG }, /* MSI K9A Platinum (MS-7280) */
{ .pci_subvendor = 0x105b, .pci_subdevice = 0x6668,
.config = ALC883_6ST_DIG }, /* Foxconn */
{ .modelname = "6stack-dig-demo", .config = ALC888_DEMO_BOARD },
@@ -5872,6 +5874,8 @@ static struct hda_board_config alc262_cfg_tbl[] = {
{ .modelname = "hp-bpc", .config = ALC262_HP_BPC },
{ .pci_subvendor = 0x103c, .pci_subdevice = 0x280c,
.config = ALC262_HP_BPC }, /* xw4400 */
+ { .pci_subvendor = 0x103c, .pci_subdevice = 0x2801,
+ .config = ALC262_HP_BPC }, /* q965 */
{ .pci_subvendor = 0x103c, .pci_subdevice = 0x3014,
.config = ALC262_HP_BPC }, /* xw6400 */
{ .pci_subvendor = 0x103c, .pci_subdevice = 0x3015,
diff --git a/sound/pci/hda/patch_si3054.c b/sound/pci/hda/patch_si3054.c
index cc87dff1eb56..ed5e45e35963 100644
--- a/sound/pci/hda/patch_si3054.c
+++ b/sound/pci/hda/patch_si3054.c
@@ -243,7 +243,8 @@ static int si3054_init(struct hda_codec *codec)
if((val&SI3054_MEI_READY) != SI3054_MEI_READY) {
snd_printk(KERN_ERR "si3054: cannot initialize. EXT MID = %04x\n", val);
- return -EACCES;
+ /* let's pray that this is no fatal error */
+ /* return -EACCES; */
}
SET_REG(codec, SI3054_GPIO_POLARITY, 0xffff);
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
index 8a576b78bee5..8ba31cfb9045 100644
--- a/sound/pci/ice1712/ice1712.c
+++ b/sound/pci/ice1712/ice1712.c
@@ -2614,7 +2614,7 @@ static int __devinit snd_ice1712_create(struct snd_card *card,
ice->dmapath_port = pci_resource_start(pci, 2);
ice->profi_port = pci_resource_start(pci, 3);
- if (request_irq(pci->irq, snd_ice1712_interrupt, IRQF_DISABLED|IRQF_SHARED,
+ if (request_irq(pci->irq, snd_ice1712_interrupt, IRQF_SHARED,
"ICE1712", ice)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_ice1712_free(ice);
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index e9cbfdf37059..3e3a102e6c34 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -2253,7 +2253,7 @@ static int __devinit snd_vt1724_create(struct snd_card *card,
ice->profi_port = pci_resource_start(pci, 1);
if (request_irq(pci->irq, snd_vt1724_interrupt,
- IRQF_DISABLED|IRQF_SHARED, "ICE1724", ice)) {
+ IRQF_SHARED, "ICE1724", ice)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_vt1724_free(ice);
return -EIO;
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index 9c1bce7afa86..30aaa6092a84 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -2509,7 +2509,7 @@ static int intel8x0_resume(struct pci_dev *pci)
}
pci_set_master(pci);
if (request_irq(pci->irq, snd_intel8x0_interrupt,
- IRQF_DISABLED|IRQF_SHARED, card->shortname, chip)) {
+ IRQF_SHARED, card->shortname, chip)) {
printk(KERN_ERR "intel8x0: unable to grab IRQ %d, "
"disabling device\n", pci->irq);
snd_card_disconnect(card);
@@ -2887,7 +2887,7 @@ static int __devinit snd_intel8x0_create(struct snd_card *card,
/* request irq after initializaing int_sta_mask, etc */
if (request_irq(pci->irq, snd_intel8x0_interrupt,
- IRQF_DISABLED|IRQF_SHARED, card->shortname, chip)) {
+ IRQF_SHARED, card->shortname, chip)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_intel8x0_free(chip);
return -EBUSY;
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c
index bd467c501123..09dcf923b547 100644
--- a/sound/pci/intel8x0m.c
+++ b/sound/pci/intel8x0m.c
@@ -1071,7 +1071,7 @@ static int intel8x0m_resume(struct pci_dev *pci)
}
pci_set_master(pci);
if (request_irq(pci->irq, snd_intel8x0_interrupt,
- IRQF_DISABLED|IRQF_SHARED, card->shortname, chip)) {
+ IRQF_SHARED, card->shortname, chip)) {
printk(KERN_ERR "intel8x0m: unable to grab IRQ %d, "
"disabling device\n", pci->irq);
snd_card_disconnect(card);
@@ -1205,7 +1205,7 @@ static int __devinit snd_intel8x0m_create(struct snd_card *card,
}
port_inited:
- if (request_irq(pci->irq, snd_intel8x0_interrupt, IRQF_DISABLED|IRQF_SHARED,
+ if (request_irq(pci->irq, snd_intel8x0_interrupt, IRQF_SHARED,
card->shortname, chip)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_intel8x0_free(chip);
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
index fa8cd8cecc21..345eefeedb39 100644
--- a/sound/pci/korg1212/korg1212.c
+++ b/sound/pci/korg1212/korg1212.c
@@ -2233,7 +2233,7 @@ static int __devinit snd_korg1212_create(struct snd_card *card, struct pci_dev *
}
err = request_irq(pci->irq, snd_korg1212_interrupt,
- IRQF_DISABLED|IRQF_SHARED,
+ IRQF_SHARED,
"korg1212", korg1212);
if (err) {
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index 8cab342bbaaf..6efe6d5ade1e 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -2377,7 +2377,7 @@ static int __devinit snd_m3_assp_client_init(struct snd_m3 *chip, struct m3_dma
* shifted list address is aligned.
* list address = (mem address >> 1) >> 7;
*/
- data_bytes = (data_bytes + 255) & ~255;
+ data_bytes = ALIGN(data_bytes, 256);
address = 0x1100 + ((data_bytes/2) * index);
if ((address + (data_bytes/2)) >= 0x1c00) {
@@ -2762,7 +2762,7 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci,
tasklet_init(&chip->hwvol_tq, snd_m3_update_hw_volume, (unsigned long)chip);
- if (request_irq(pci->irq, snd_m3_interrupt, IRQF_DISABLED|IRQF_SHARED,
+ if (request_irq(pci->irq, snd_m3_interrupt, IRQF_SHARED,
card->driver, chip)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_m3_free(chip);
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c
index 216aee5f93e7..21386da3bc86 100644
--- a/sound/pci/mixart/mixart.c
+++ b/sound/pci/mixart/mixart.c
@@ -1066,7 +1066,7 @@ static int snd_mixart_free(struct mixart_mgr *mgr)
/* release irq */
if (mgr->irq >= 0)
- free_irq(mgr->irq, (void *)mgr);
+ free_irq(mgr->irq, mgr);
/* reset board if some firmware was loaded */
if(mgr->dsp_loaded) {
@@ -1319,7 +1319,8 @@ static int __devinit snd_mixart_probe(struct pci_dev *pci,
pci_resource_len(pci, i));
}
- if (request_irq(pci->irq, snd_mixart_interrupt, IRQF_DISABLED|IRQF_SHARED, CARD_NAME, (void *)mgr)) {
+ if (request_irq(pci->irq, snd_mixart_interrupt, IRQF_SHARED,
+ CARD_NAME, mgr)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_mixart_free(mgr);
return -EBUSY;
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c
index 945d21bf187e..879e31a9f9c6 100644
--- a/sound/pci/nm256/nm256.c
+++ b/sound/pci/nm256/nm256.c
@@ -465,7 +465,7 @@ static int snd_nm256_acquire_irq(struct nm256 *chip)
{
mutex_lock(&chip->irq_mutex);
if (chip->irq < 0) {
- if (request_irq(chip->pci->irq, chip->interrupt, IRQF_DISABLED|IRQF_SHARED,
+ if (request_irq(chip->pci->irq, chip->interrupt, IRQF_SHARED,
chip->card->driver, chip)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", chip->pci->irq);
mutex_unlock(&chip->irq_mutex);
diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c
index 533c672ae8f3..d97413484ae9 100644
--- a/sound/pci/pcxhr/pcxhr.c
+++ b/sound/pci/pcxhr/pcxhr.c
@@ -1250,7 +1250,7 @@ static int __devinit pcxhr_probe(struct pci_dev *pci, const struct pci_device_id
mgr->pci = pci;
mgr->irq = -1;
- if (request_irq(pci->irq, pcxhr_interrupt, IRQF_DISABLED|IRQF_SHARED,
+ if (request_irq(pci->irq, pcxhr_interrupt, IRQF_SHARED,
card_name, mgr)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
pcxhr_free(mgr);
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c
index 56e0c01123e7..5e1d5d2b2850 100644
--- a/sound/pci/riptide/riptide.c
+++ b/sound/pci/riptide/riptide.c
@@ -1899,9 +1899,8 @@ snd_riptide_create(struct snd_card *card, struct pci_dev *pci,
hwport = (struct riptideport *)chip->port;
UNSET_AIE(hwport);
- if (request_irq
- (pci->irq, snd_riptide_interrupt, IRQF_DISABLED | IRQF_SHARED,
- "RIPTIDE", chip)) {
+ if (request_irq(pci->irq, snd_riptide_interrupt, IRQF_SHARED,
+ "RIPTIDE", chip)) {
snd_printk(KERN_ERR "Riptide: unable to grab IRQ %d\n",
pci->irq);
snd_riptide_free(chip);
diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c
index dc8d1302e22d..6bb7ac650ec4 100644
--- a/sound/pci/rme32.c
+++ b/sound/pci/rme32.c
@@ -1373,7 +1373,8 @@ static int __devinit snd_rme32_create(struct rme32 * rme32)
return -ENOMEM;
}
- if (request_irq(pci->irq, snd_rme32_interrupt, IRQF_DISABLED | IRQF_SHARED, "RME32", (void *) rme32)) {
+ if (request_irq(pci->irq, snd_rme32_interrupt, IRQF_SHARED,
+ "RME32", rme32)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
return -EBUSY;
}
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c
index 106110a89a4c..e3304b7ccbcb 100644
--- a/sound/pci/rme96.c
+++ b/sound/pci/rme96.c
@@ -1587,7 +1587,8 @@ snd_rme96_create(struct rme96 *rme96)
return -ENOMEM;
}
- if (request_irq(pci->irq, snd_rme96_interrupt, IRQF_DISABLED|IRQF_SHARED, "RME96", (void *)rme96)) {
+ if (request_irq(pci->irq, snd_rme96_interrupt, IRQF_SHARED,
+ "RME96", rme96)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
return -EBUSY;
}
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 694aa057ed49..6383987b460e 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -3516,8 +3516,8 @@ static int __devinit snd_hdsp_initialize_memory(struct hdsp *hdsp)
/* Align to bus-space 64K boundary */
- cb_bus = (hdsp->capture_dma_buf.addr + 0xFFFF) & ~0xFFFFl;
- pb_bus = (hdsp->playback_dma_buf.addr + 0xFFFF) & ~0xFFFFl;
+ cb_bus = ALIGN(hdsp->capture_dma_buf.addr, 0x10000ul);
+ pb_bus = ALIGN(hdsp->playback_dma_buf.addr, 0x10000ul);
/* Tell the card where it is */
@@ -4934,13 +4934,14 @@ static int __devinit snd_hdsp_create(struct snd_card *card,
return -EBUSY;
}
- if (request_irq(pci->irq, snd_hdsp_interrupt, IRQF_DISABLED|IRQF_SHARED, "hdsp", (void *)hdsp)) {
+ if (request_irq(pci->irq, snd_hdsp_interrupt, IRQF_SHARED,
+ "hdsp", hdsp)) {
snd_printk(KERN_ERR "Hammerfall-DSP: unable to use IRQ %d\n", pci->irq);
return -EBUSY;
}
hdsp->irq = pci->irq;
- hdsp->precise_ptr = 1;
+ hdsp->precise_ptr = 0;
hdsp->use_midi_tasklet = 1;
if ((err = snd_hdsp_initialize_memory(hdsp)) < 0)
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index 7055d893855d..0547f6f04bdc 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -3496,8 +3496,7 @@ static int __devinit snd_hdspm_create(struct snd_card *card, struct hdspm * hdsp
hdspm->port + io_extent - 1);
if (request_irq(pci->irq, snd_hdspm_interrupt,
- IRQF_DISABLED | IRQF_SHARED, "hdspm",
- (void *) hdspm)) {
+ IRQF_SHARED, "hdspm", hdspm)) {
snd_printk(KERN_ERR "HDSPM: unable to use IRQ %d\n", pci->irq);
return -EBUSY;
}
diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c
index cf0427b4bfde..cc3bdececce7 100644
--- a/sound/pci/rme9652/rme9652.c
+++ b/sound/pci/rme9652/rme9652.c
@@ -1827,8 +1827,8 @@ static int __devinit snd_rme9652_initialize_memory(struct snd_rme9652 *rme9652)
/* Align to bus-space 64K boundary */
- cb_bus = (rme9652->capture_dma_buf.addr + 0xFFFF) & ~0xFFFFl;
- pb_bus = (rme9652->playback_dma_buf.addr + 0xFFFF) & ~0xFFFFl;
+ cb_bus = ALIGN(rme9652->capture_dma_buf.addr, 0x10000ul);
+ pb_bus = ALIGN(rme9652->playback_dma_buf.addr, 0x10000ul);
/* Tell the card where it is */
@@ -2500,7 +2500,8 @@ static int __devinit snd_rme9652_create(struct snd_card *card,
return -EBUSY;
}
- if (request_irq(pci->irq, snd_rme9652_interrupt, IRQF_DISABLED|IRQF_SHARED, "rme9652", (void *)rme9652)) {
+ if (request_irq(pci->irq, snd_rme9652_interrupt, IRQF_SHARED,
+ "rme9652", rme9652)) {
snd_printk(KERN_ERR "unable to request IRQ %d\n", pci->irq);
return -EBUSY;
}
diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c
index f9b8afabda9c..9f25d93cbec2 100644
--- a/sound/pci/sonicvibes.c
+++ b/sound/pci/sonicvibes.c
@@ -1195,7 +1195,7 @@ static int snd_sonicvibes_free(struct sonicvibes *sonic)
pci_write_config_dword(sonic->pci, 0x40, sonic->dmaa_port);
pci_write_config_dword(sonic->pci, 0x48, sonic->dmac_port);
if (sonic->irq >= 0)
- free_irq(sonic->irq, (void *)sonic);
+ free_irq(sonic->irq, sonic);
release_and_free_resource(sonic->res_dmaa);
release_and_free_resource(sonic->res_dmac);
pci_release_regions(sonic->pci);
@@ -1257,7 +1257,8 @@ static int __devinit snd_sonicvibes_create(struct snd_card *card,
sonic->midi_port = pci_resource_start(pci, 3);
sonic->game_port = pci_resource_start(pci, 4);
- if (request_irq(pci->irq, snd_sonicvibes_interrupt, IRQF_DISABLED|IRQF_SHARED, "S3 SonicVibes", (void *)sonic)) {
+ if (request_irq(pci->irq, snd_sonicvibes_interrupt, IRQF_SHARED,
+ "S3 SonicVibes", sonic)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_sonicvibes_free(sonic);
return -EBUSY;
diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c
index 1fbc4321122f..474f2d451ae8 100644
--- a/sound/pci/trident/trident_main.c
+++ b/sound/pci/trident/trident_main.c
@@ -3380,8 +3380,8 @@ static int __devinit snd_trident_tlb_alloc(struct snd_trident *trident)
snd_printk(KERN_ERR "trident: unable to allocate TLB buffer\n");
return -ENOMEM;
}
- trident->tlb.entries = (unsigned int*)(((unsigned long)trident->tlb.buffer.area + SNDRV_TRIDENT_MAX_PAGES * 4 - 1) & ~(SNDRV_TRIDENT_MAX_PAGES * 4 - 1));
- trident->tlb.entries_dmaaddr = (trident->tlb.buffer.addr + SNDRV_TRIDENT_MAX_PAGES * 4 - 1) & ~(SNDRV_TRIDENT_MAX_PAGES * 4 - 1);
+ trident->tlb.entries = (unsigned int*)ALIGN((unsigned long)trident->tlb.buffer.area, SNDRV_TRIDENT_MAX_PAGES * 4);
+ trident->tlb.entries_dmaaddr = ALIGN(trident->tlb.buffer.addr, SNDRV_TRIDENT_MAX_PAGES * 4);
/* allocate shadow TLB page table (virtual addresses) */
trident->tlb.shadow_entries = vmalloc(SNDRV_TRIDENT_MAX_PAGES*sizeof(unsigned long));
if (trident->tlb.shadow_entries == NULL) {
@@ -3608,7 +3608,7 @@ int __devinit snd_trident_create(struct snd_card *card,
}
trident->port = pci_resource_start(pci, 0);
- if (request_irq(pci->irq, snd_trident_interrupt, IRQF_DISABLED|IRQF_SHARED,
+ if (request_irq(pci->irq, snd_trident_interrupt, IRQF_SHARED,
"Trident Audio", trident)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_trident_free(trident);
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index 92b0736c0fdb..a572b018807f 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -2307,7 +2307,7 @@ static int __devinit snd_via82xx_create(struct snd_card *card,
if (request_irq(pci->irq,
chip_type == TYPE_VIA8233 ?
snd_via8233_interrupt : snd_via686_interrupt,
- IRQF_DISABLED|IRQF_SHARED,
+ IRQF_SHARED,
card->driver, chip)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_via82xx_free(chip);
@@ -2366,7 +2366,7 @@ struct dxs_whitelist {
static int __devinit check_dxs_list(struct pci_dev *pci, int revision)
{
- static struct dxs_whitelist whitelist[] = {
+ static struct dxs_whitelist whitelist[] __devinitdata = {
{ .subvendor = 0x1005, .subdevice = 0x4710, .action = VIA_DXS_ENABLE }, /* Avance Logic Mobo */
{ .subvendor = 0x1019, .subdevice = 0x0996, .action = VIA_DXS_48K },
{ .subvendor = 0x1019, .subdevice = 0x0a81, .action = VIA_DXS_NO_VRA }, /* ECS K7VTA3 v8.0 */
@@ -2427,7 +2427,7 @@ static int __devinit check_dxs_list(struct pci_dev *pci, int revision)
{ .subvendor = 0x4005, .subdevice = 0x4710, .action = VIA_DXS_SRC }, /* MSI K7T266 Pro2 (MS-6380 V2.0) BIOS 3.7 */
{ } /* terminator */
};
- struct dxs_whitelist *w;
+ const struct dxs_whitelist *w;
unsigned short subsystem_vendor;
unsigned short subsystem_device;
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c
index feb27c966256..17d6b847585f 100644
--- a/sound/pci/via82xx_modem.c
+++ b/sound/pci/via82xx_modem.c
@@ -1124,7 +1124,7 @@ static int __devinit snd_via82xx_create(struct snd_card *card,
return err;
}
chip->port = pci_resource_start(pci, 0);
- if (request_irq(pci->irq, snd_via82xx_interrupt, IRQF_DISABLED|IRQF_SHARED,
+ if (request_irq(pci->irq, snd_via82xx_interrupt, IRQF_SHARED,
card->driver, chip)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_via82xx_free(chip);
diff --git a/sound/pci/vx222/vx222.c b/sound/pci/vx222/vx222.c
index af49e8aabf55..89f58ea180b3 100644
--- a/sound/pci/vx222/vx222.c
+++ b/sound/pci/vx222/vx222.c
@@ -169,8 +169,8 @@ static int __devinit snd_vx222_create(struct snd_card *card, struct pci_dev *pci
for (i = 0; i < 2; i++)
vx->port[i] = pci_resource_start(pci, i + 1);
- if (request_irq(pci->irq, snd_vx_irq_handler, IRQF_DISABLED|IRQF_SHARED,
- CARD_NAME, (void *) chip)) {
+ if (request_irq(pci->irq, snd_vx_irq_handler, IRQF_SHARED,
+ CARD_NAME, chip)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_vx222_free(chip);
return -EBUSY;
diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c
index 186453f7abe7..fd9b7b83a884 100644
--- a/sound/pci/ymfpci/ymfpci.c
+++ b/sound/pci/ymfpci/ymfpci.c
@@ -49,7 +49,6 @@ static long mpu_port[SNDRV_CARDS];
static long joystick_port[SNDRV_CARDS];
#endif
static int rear_switch[SNDRV_CARDS];
-static int rear_swap[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = 1 };
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for the Yamaha DS-1 PCI soundcard.");
@@ -67,8 +66,6 @@ MODULE_PARM_DESC(joystick_port, "Joystick port address");
#endif
module_param_array(rear_switch, bool, NULL, 0444);
MODULE_PARM_DESC(rear_switch, "Enable shared rear/line-in switch");
-module_param_array(rear_swap, bool, NULL, 0444);
-MODULE_PARM_DESC(rear_swap, "Swap rear channels (must be enabled for correct IEC958 (S/PDIF)) output");
static struct pci_device_id snd_ymfpci_ids[] = {
{ 0x1073, 0x0004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* YMF724 */
@@ -298,7 +295,7 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci,
snd_card_free(card);
return err;
}
- if ((err = snd_ymfpci_mixer(chip, rear_switch[dev], rear_swap[dev])) < 0) {
+ if ((err = snd_ymfpci_mixer(chip, rear_switch[dev])) < 0) {
snd_card_free(card);
return err;
}
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
index a40c1085fd20..7881944a1957 100644
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -910,7 +910,7 @@ static int snd_ymfpci_playback_open(struct snd_pcm_substream *substream)
ypcm = runtime->private_data;
ypcm->output_front = 1;
ypcm->output_rear = chip->mode_dup4ch ? 1 : 0;
- ypcm->swap_rear = chip->rear_swap;
+ ypcm->swap_rear = 0;
spin_lock_irq(&chip->reg_lock);
if (ypcm->output_rear) {
ymfpci_open_extension(chip);
@@ -936,6 +936,7 @@ static int snd_ymfpci_playback_spdif_open(struct snd_pcm_substream *substream)
ypcm = runtime->private_data;
ypcm->output_front = 0;
ypcm->output_rear = 1;
+ ypcm->swap_rear = 1;
spin_lock_irq(&chip->reg_lock);
snd_ymfpci_writew(chip, YDSXGR_SPDIFOUTCTRL,
snd_ymfpci_readw(chip, YDSXGR_SPDIFOUTCTRL) | 2);
@@ -963,6 +964,7 @@ static int snd_ymfpci_playback_4ch_open(struct snd_pcm_substream *substream)
ypcm = runtime->private_data;
ypcm->output_front = 0;
ypcm->output_rear = 1;
+ ypcm->swap_rear = 0;
spin_lock_irq(&chip->reg_lock);
ymfpci_open_extension(chip);
chip->rear_opened++;
@@ -1755,7 +1757,7 @@ static void snd_ymfpci_mixer_free_ac97(struct snd_ac97 *ac97)
chip->ac97 = NULL;
}
-int __devinit snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch, int rear_swap)
+int __devinit snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch)
{
struct snd_ac97_template ac97;
struct snd_kcontrol *kctl;
@@ -1767,7 +1769,6 @@ int __devinit snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch, int rea
.read = snd_ymfpci_codec_read,
};
- chip->rear_swap = rear_swap;
if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &chip->ac97_bus)) < 0)
return err;
chip->ac97_bus->private_free = snd_ymfpci_mixer_free_ac97_bus;
@@ -2025,10 +2026,10 @@ static int __devinit snd_ymfpci_memalloc(struct snd_ymfpci *chip)
chip->bank_size_effect = snd_ymfpci_readl(chip, YDSXGR_EFFCTRLSIZE) << 2;
chip->work_size = YDSXG_DEFAULT_WORK_SIZE;
- size = ((playback_ctrl_size + 0x00ff) & ~0x00ff) +
- ((chip->bank_size_playback * 2 * YDSXG_PLAYBACK_VOICES + 0x00ff) & ~0x00ff) +
- ((chip->bank_size_capture * 2 * YDSXG_CAPTURE_VOICES + 0x00ff) & ~0x00ff) +
- ((chip->bank_size_effect * 2 * YDSXG_EFFECT_VOICES + 0x00ff) & ~0x00ff) +
+ size = ALIGN(playback_ctrl_size, 0x100) +
+ ALIGN(chip->bank_size_playback * 2 * YDSXG_PLAYBACK_VOICES, 0x100) +
+ ALIGN(chip->bank_size_capture * 2 * YDSXG_CAPTURE_VOICES, 0x100) +
+ ALIGN(chip->bank_size_effect * 2 * YDSXG_EFFECT_VOICES, 0x100) +
chip->work_size;
/* work_ptr must be aligned to 256 bytes, but it's already
covered with the kernel page allocation mechanism */
@@ -2043,8 +2044,8 @@ static int __devinit snd_ymfpci_memalloc(struct snd_ymfpci *chip)
chip->bank_base_playback_addr = ptr_addr;
chip->ctrl_playback = (u32 *)ptr;
chip->ctrl_playback[0] = cpu_to_le32(YDSXG_PLAYBACK_VOICES);
- ptr += (playback_ctrl_size + 0x00ff) & ~0x00ff;
- ptr_addr += (playback_ctrl_size + 0x00ff) & ~0x00ff;
+ ptr += ALIGN(playback_ctrl_size, 0x100);
+ ptr_addr += ALIGN(playback_ctrl_size, 0x100);
for (voice = 0; voice < YDSXG_PLAYBACK_VOICES; voice++) {
chip->voices[voice].number = voice;
chip->voices[voice].bank = (struct snd_ymfpci_playback_bank *)ptr;
@@ -2055,8 +2056,8 @@ static int __devinit snd_ymfpci_memalloc(struct snd_ymfpci *chip)
ptr_addr += chip->bank_size_playback;
}
}
- ptr = (char *)(((unsigned long)ptr + 0x00ff) & ~0x00ff);
- ptr_addr = (ptr_addr + 0x00ff) & ~0x00ff;
+ ptr = (char *)ALIGN((unsigned long)ptr, 0x100);
+ ptr_addr = ALIGN(ptr_addr, 0x100);
chip->bank_base_capture = ptr;
chip->bank_base_capture_addr = ptr_addr;
for (voice = 0; voice < YDSXG_CAPTURE_VOICES; voice++)
@@ -2065,8 +2066,8 @@ static int __devinit snd_ymfpci_memalloc(struct snd_ymfpci *chip)
ptr += chip->bank_size_capture;
ptr_addr += chip->bank_size_capture;
}
- ptr = (char *)(((unsigned long)ptr + 0x00ff) & ~0x00ff);
- ptr_addr = (ptr_addr + 0x00ff) & ~0x00ff;
+ ptr = (char *)ALIGN((unsigned long)ptr, 0x100);
+ ptr_addr = ALIGN(ptr_addr, 0x100);
chip->bank_base_effect = ptr;
chip->bank_base_effect_addr = ptr_addr;
for (voice = 0; voice < YDSXG_EFFECT_VOICES; voice++)
@@ -2075,8 +2076,8 @@ static int __devinit snd_ymfpci_memalloc(struct snd_ymfpci *chip)
ptr += chip->bank_size_effect;
ptr_addr += chip->bank_size_effect;
}
- ptr = (char *)(((unsigned long)ptr + 0x00ff) & ~0x00ff);
- ptr_addr = (ptr_addr + 0x00ff) & ~0x00ff;
+ ptr = (char *)ALIGN((unsigned long)ptr, 0x100);
+ ptr_addr = ALIGN(ptr_addr, 0x100);
chip->work_base = ptr;
chip->work_base_addr = ptr_addr;
@@ -2153,7 +2154,7 @@ static int snd_ymfpci_free(struct snd_ymfpci *chip)
snd_dma_free_pages(&chip->work_ptr);
if (chip->irq >= 0)
- free_irq(chip->irq, (void *)chip);
+ free_irq(chip->irq, chip);
release_and_free_resource(chip->res_reg_area);
pci_write_config_word(chip->pci, 0x40, chip->old_legacy_ctrl);
@@ -2290,7 +2291,7 @@ int __devinit snd_ymfpci_create(struct snd_card *card,
chip->pci = pci;
chip->irq = -1;
chip->device_id = pci->device;
- pci_read_config_byte(pci, PCI_REVISION_ID, (u8 *)&chip->rev);
+ pci_read_config_byte(pci, PCI_REVISION_ID, &chip->rev);
chip->reg_area_phys = pci_resource_start(pci, 0);
chip->reg_area_virt = ioremap_nocache(chip->reg_area_phys, 0x8000);
pci_set_master(pci);
@@ -2300,7 +2301,8 @@ int __devinit snd_ymfpci_create(struct snd_card *card,
snd_ymfpci_free(chip);
return -EBUSY;
}
- if (request_irq(pci->irq, snd_ymfpci_interrupt, IRQF_DISABLED|IRQF_SHARED, "YMFPCI", (void *) chip)) {
+ if (request_irq(pci->irq, snd_ymfpci_interrupt, IRQF_SHARED,
+ "YMFPCI", chip)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_ymfpci_free(chip);
return -EBUSY;
@@ -2322,7 +2324,6 @@ int __devinit snd_ymfpci_create(struct snd_card *card,
return -EIO;
}
- chip->rear_swap = 1;
if ((err = snd_ymfpci_ac3_init(chip)) < 0) {
snd_ymfpci_free(chip);
return err;
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index 67202b9eeb77..3d7f36fb4cf0 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -3577,8 +3577,7 @@ static int __init snd_usb_audio_init(void)
printk(KERN_WARNING "invalid nrpacks value.\n");
return -EINVAL;
}
- usb_register(&usb_audio_driver);
- return 0;
+ return usb_register(&usb_audio_driver);
}