Merge branch 'for-linus' of git://git.kernel.dk/linux-2.6-block
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 20 Dec 2010 17:19:46 +0000 (09:19 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 20 Dec 2010 17:19:46 +0000 (09:19 -0800)
* 'for-linus' of git://git.kernel.dk/linux-2.6-block:
  cciss: fix cciss_revalidate panic
  block: max hardware sectors limit wrapper
  block: Deprecate QUEUE_FLAG_CLUSTER and use queue_limits instead
  blk-throttle: Correct the placement of smp_rmb()
  blk-throttle: Trim/adjust slice_end once a bio has been dispatched
  block: check for proper length of iov entries earlier in blk_rq_map_user_iov()
  drbd: fix for spin_lock_irqsave in endio callback
  drbd: don't recvmsg with zero length

777 files changed:
Documentation/ABI/testing/sysfs-bus-rbd [new file with mode: 0644]
Documentation/ABI/testing/sysfs-platform-asus-laptop
Documentation/ABI/testing/sysfs-platform-eeepc-wmi [new file with mode: 0644]
Documentation/driver-model/interface.txt [deleted file]
Documentation/edac.txt
Documentation/filesystems/Locking
Documentation/filesystems/vfs.txt
Documentation/kernel-parameters.txt
Documentation/networking/ip-sysctl.txt
Documentation/power/runtime_pm.txt
MAINTAINERS
Makefile
arch/arm/Kconfig
arch/arm/boot/Makefile
arch/arm/boot/bootp/init.S
arch/arm/boot/compressed/head.S
arch/arm/common/gic.c
arch/arm/configs/at91rm9200_defconfig [new file with mode: 0644]
arch/arm/configs/at91rm9200dk_defconfig [deleted file]
arch/arm/configs/at91rm9200ek_defconfig [deleted file]
arch/arm/configs/ateb9200_defconfig [deleted file]
arch/arm/configs/carmeva_defconfig [deleted file]
arch/arm/configs/cpuat91_defconfig [deleted file]
arch/arm/configs/csb337_defconfig [deleted file]
arch/arm/configs/csb637_defconfig [deleted file]
arch/arm/configs/ecbat91_defconfig [deleted file]
arch/arm/configs/kafa_defconfig [deleted file]
arch/arm/configs/kb9202_defconfig [deleted file]
arch/arm/configs/onearm_defconfig [deleted file]
arch/arm/configs/picotux200_defconfig [deleted file]
arch/arm/configs/yl9200_defconfig [deleted file]
arch/arm/kernel/entry-armv.S
arch/arm/kernel/head.S
arch/arm/kernel/relocate_kernel.S
arch/arm/mach-at91/Makefile
arch/arm/mach-at91/at91rm9200_devices.c
arch/arm/mach-at91/board-1arm.c
arch/arm/mach-at91/board-dk.c [deleted file]
arch/arm/mach-at91/board-ek.c [deleted file]
arch/arm/mach-at91/board-kafa.c
arch/arm/mach-at91/board-pcontrol-g20.c
arch/arm/mach-at91/board-picotux200.c
arch/arm/mach-at91/board-rm9200dk.c [new file with mode: 0644]
arch/arm/mach-at91/board-rm9200ek.c [new file with mode: 0644]
arch/arm/mach-at91/board-stamp9g20.c
arch/arm/mach-at91/board-yl-9200.c
arch/arm/mach-at91/clock.c
arch/arm/mach-at91/include/mach/board.h
arch/arm/mach-at91/include/mach/stamp9g20.h [new file with mode: 0644]
arch/arm/mach-cns3xxx/pcie.c
arch/arm/mach-mmp/mmp2.c
arch/arm/mach-omap2/board-zoom-peripherals.c
arch/arm/mach-omap2/io.c
arch/arm/mach-omap2/pm-debug.c
arch/arm/mach-omap2/pm24xx.c
arch/arm/mach-omap2/pm34xx.c
arch/arm/mach-omap2/prcm-common.h
arch/arm/mach-omap2/serial.c
arch/arm/mach-pxa/palmtx.c
arch/arm/mach-realview/headsmp.S
arch/arm/mach-s3c2412/Kconfig
arch/arm/mach-s3c2416/Kconfig
arch/arm/mach-s3c2440/Kconfig
arch/arm/mach-s3c2440/s3c2440.c
arch/arm/mach-s3c2440/s3c2442.c
arch/arm/mach-s3c2443/Kconfig
arch/arm/mach-tegra/include/mach/debug-macro.S
arch/arm/mach-vexpress/headsmp.S
arch/arm/mm/cache-v6.S
arch/arm/mm/cache-v7.S
arch/arm/mm/proc-macros.S
arch/arm/mm/proc-v7.S
arch/arm/plat-iop/time.c
arch/arm/plat-omap/counter_32k.c
arch/arm/plat-omap/sram.c
arch/arm/plat-s3c24xx/cpu.c
arch/arm/plat-s3c24xx/gpiolib.c
arch/arm/plat-s3c24xx/include/plat/s3c244x.h
arch/arm/plat-samsung/gpio-config.c
arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
arch/arm/tools/mach-types
arch/arm/vfp/vfphw.S
arch/mips/Kconfig
arch/mips/alchemy/common/platform.c
arch/mips/alchemy/devboards/prom.c
arch/mips/ar7/clock.c
arch/mips/ar7/time.c
arch/mips/bcm47xx/setup.c
arch/mips/include/asm/cpu.h
arch/mips/include/asm/elf.h
arch/mips/include/asm/io.h
arch/mips/include/asm/mach-ar7/ar7.h
arch/mips/include/asm/mach-bcm47xx/nvram.h
arch/mips/jz4740/board-qi_lb60.c
arch/mips/jz4740/platform.c
arch/mips/jz4740/prom.c
arch/mips/kernel/cevt-r4k.c
arch/mips/kernel/cpu-probe.c
arch/mips/kernel/linux32.c
arch/mips/kernel/process.c
arch/mips/kernel/prom.c
arch/mips/kernel/smp-mt.c
arch/mips/kernel/traps.c
arch/mips/kernel/vpe.c
arch/mips/lib/memset.S
arch/mips/loongson/common/env.c
arch/mips/math-emu/cp1emu.c
arch/mips/mm/dma-default.c
arch/mips/mm/sc-mips.c
arch/mips/pmc-sierra/yosemite/py-console.c
arch/mips/sibyte/swarm/setup.c
arch/mn10300/include/asm/syscall.h [new file with mode: 0644]
arch/mn10300/kernel/gdb-io-serial.c
arch/mn10300/kernel/gdb-io-ttysm.c
arch/mn10300/kernel/gdb-stub.c
arch/mn10300/kernel/time.c
arch/parisc/kernel/irq.c
arch/parisc/kernel/signal.c
arch/powerpc/mm/pgtable.c
arch/s390/kernel/vtime.c
arch/sh/Kconfig
arch/sh/boards/mach-ecovec24/setup.c
arch/sh/boards/mach-se/7724/setup.c
arch/sh/include/asm/cacheflush.h
arch/sh/include/asm/unistd_32.h
arch/sh/include/cpu-sh4/cpu/sh7724.h
arch/sh/kernel/cpu/sh4a/clock-sh7724.c
arch/sh/kernel/syscalls_32.S
arch/sh/mm/cache-sh4.c
arch/sh/mm/cache-sh7705.c
arch/sh/mm/cache.c
arch/sh/mm/kmap.c
arch/sparc/include/asm/openprom.h
arch/sparc/include/asm/oplib_32.h
arch/sparc/include/asm/oplib_64.h
arch/sparc/kernel/leon_kernel.c
arch/sparc/prom/Makefile
arch/sparc/prom/console_32.c
arch/sparc/prom/console_64.c
arch/sparc/prom/devops_32.c [deleted file]
arch/sparc/prom/devops_64.c [deleted file]
arch/sparc/prom/misc_64.c
arch/sparc/prom/printf.c
arch/sparc/prom/tree_32.c
arch/sparc/prom/tree_64.c
arch/tile/include/asm/signal.h
arch/tile/kernel/compat_signal.c
arch/tile/kernel/intvec_32.S
arch/tile/kernel/process.c
arch/tile/kernel/signal.c
arch/x86/Kconfig
arch/x86/boot/compressed/misc.c
arch/x86/crypto/ghash-clmulni-intel_glue.c
arch/x86/include/asm/e820.h
arch/x86/include/asm/kvm_host.h
arch/x86/include/asm/pvclock.h
arch/x86/kernel/Makefile
arch/x86/kernel/apic/apic.c
arch/x86/kernel/apic/io_apic.c
arch/x86/kernel/apic/probe_64.c
arch/x86/kernel/cpu/perf_event.c
arch/x86/kernel/head_32.S
arch/x86/kernel/hpet.c
arch/x86/kernel/pvclock.c
arch/x86/kernel/resource.c [new file with mode: 0644]
arch/x86/kernel/setup.c
arch/x86/kernel/xsave.c
arch/x86/kvm/svm.c
arch/x86/kvm/vmx.c
arch/x86/kvm/x86.c
arch/x86/kvm/x86.h
arch/x86/lguest/boot.c
arch/x86/lguest/i386_head.S
arch/x86/pci/i386.c
arch/x86/pci/xen.c
arch/x86/vdso/Makefile
arch/x86/xen/enlighten.c
arch/x86/xen/mmu.c
arch/x86/xen/platform-pci-unplug.c
arch/x86/xen/setup.c
arch/x86/xen/suspend.c
arch/x86/xen/time.c
arch/x86/xen/xen-ops.h
block/bsg.c
drivers/acpi/ac.c
drivers/acpi/apei/erst.c
drivers/acpi/apei/hest.c
drivers/acpi/battery.c
drivers/acpi/ec.c
drivers/acpi/osl.c
drivers/acpi/power.c
drivers/acpi/processor_thermal.c
drivers/acpi/sleep.c
drivers/atm/adummy.c
drivers/atm/ambassador.c
drivers/atm/atmtcp.c
drivers/atm/eni.c
drivers/atm/firestream.c
drivers/atm/fore200e.c
drivers/atm/he.c
drivers/atm/horizon.c
drivers/atm/idt77252.c
drivers/atm/iphase.c
drivers/atm/lanai.c
drivers/atm/nicstar.c
drivers/atm/solos-pci.c
drivers/atm/zatm.c
drivers/block/rbd.c
drivers/block/xen-blkfront.c
drivers/bluetooth/ath3k.c
drivers/bluetooth/btusb.c
drivers/char/agp/intel-gtt.c
drivers/char/tpm/tpm_tis.c
drivers/connector/connector.c
drivers/dma/Makefile
drivers/dma/at_hdmac.c
drivers/dma/fsldma.c
drivers/dma/fsldma.h
drivers/dma/imx-dma.c
drivers/dma/imx-sdma.c
drivers/dma/intel_mid_dma.c
drivers/dma/ioat/Makefile
drivers/dma/pch_dma.c
drivers/dma/ppc4xx/adma.c
drivers/dma/shdma.c
drivers/edac/Makefile
drivers/edac/amd64_edac.c
drivers/edac/edac_core.h
drivers/edac/edac_mc.c
drivers/edac/mce_amd_inj.c
drivers/firewire/net.c
drivers/firewire/ohci.c
drivers/gpio/cs5535-gpio.c
drivers/gpu/drm/drm_crtc.c
drivers/gpu/drm/drm_crtc_helper.c
drivers/gpu/drm/drm_irq.c
drivers/gpu/drm/i915/i915_dma.c
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/i915_suspend.c
drivers/gpu/drm/i915/intel_acpi.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_lvds.c
drivers/gpu/drm/i915/intel_ringbuffer.c
drivers/gpu/drm/i915/intel_sdvo.c
drivers/gpu/drm/radeon/atom.c
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/r600_cs.c
drivers/gpu/drm/radeon/r600_reg.h
drivers/gpu/drm/radeon/radeon_atombios.c
drivers/gpu/drm/radeon/radeon_bios.c
drivers/gpu/drm/radeon/radeon_combios.c
drivers/gpu/drm/radeon/radeon_connectors.c
drivers/gpu/drm/radeon/radeon_device.c
drivers/gpu/drm/radeon/radeon_object.c
drivers/hid/hid-core.c
drivers/hid/hid-egalax.c
drivers/hid/hid-input.c
drivers/hid/hid-tmff.c
drivers/hwmon/adm1026.c
drivers/hwmon/it87.c
drivers/hwmon/ltc4215.c
drivers/i2c/Kconfig
drivers/i2c/algos/Kconfig
drivers/i2c/busses/i2c-intel-mid.c
drivers/idle/intel_idle.c
drivers/infiniband/core/ud_header.c
drivers/infiniband/core/uverbs_cmd.c
drivers/infiniband/core/uverbs_marshall.c
drivers/infiniband/hw/mlx4/main.c
drivers/infiniband/hw/mlx4/qp.c
drivers/input/evdev.c
drivers/input/joystick/turbografx.c
drivers/input/keyboard/Kconfig
drivers/input/keyboard/Makefile
drivers/input/keyboard/gpio_keys_polled.c [new file with mode: 0644]
drivers/input/mouse/synaptics.h
drivers/input/serio/gscps2.c
drivers/input/tablet/wacom_wac.c
drivers/input/touchscreen/usbtouchscreen.c
drivers/isdn/icn/icn.c
drivers/leds/Kconfig
drivers/macintosh/Kconfig
drivers/md/md.c
drivers/md/raid10.c
drivers/media/common/tuners/Kconfig
drivers/media/dvb/frontends/Kconfig
drivers/media/radio/radio-aimslab.c
drivers/media/radio/radio-aztech.c
drivers/media/radio/radio-cadet.c
drivers/media/radio/radio-gemtek-pci.c
drivers/media/radio/radio-gemtek.c
drivers/media/radio/radio-maestro.c
drivers/media/radio/radio-maxiradio.c
drivers/media/radio/radio-miropcm20.c
drivers/media/radio/radio-rtrack2.c
drivers/media/radio/radio-sf16fmi.c
drivers/media/radio/radio-sf16fmr2.c
drivers/media/radio/radio-si4713.c
drivers/media/radio/radio-tea5764.c
drivers/media/radio/radio-terratec.c
drivers/media/radio/radio-timb.c
drivers/media/radio/radio-trust.c
drivers/media/radio/radio-typhoon.c
drivers/media/radio/radio-zoltrix.c
drivers/media/video/Kconfig
drivers/media/video/arv.c
drivers/media/video/au0828/au0828-cards.c
drivers/media/video/bt8xx/bttv-cards.c
drivers/media/video/bw-qcam.c
drivers/media/video/c-qcam.c
drivers/media/video/cafe_ccic.c
drivers/media/video/cx18/cx18-alsa-pcm.c
drivers/media/video/cx18/cx18-i2c.c
drivers/media/video/cx18/cx18-streams.c
drivers/media/video/cx231xx/cx231xx-cards.c
drivers/media/video/cx23885/cx23885-cards.c
drivers/media/video/cx23885/cx23885-video.c
drivers/media/video/cx88/cx88-cards.c
drivers/media/video/cx88/cx88-video.c
drivers/media/video/davinci/vpfe_capture.c
drivers/media/video/davinci/vpif_capture.c
drivers/media/video/davinci/vpif_display.c
drivers/media/video/em28xx/em28xx-cards.c
drivers/media/video/et61x251/et61x251_core.c
drivers/media/video/fsl-viu.c
drivers/media/video/ivtv/ivtv-i2c.c
drivers/media/video/meye.c
drivers/media/video/mxb.c
drivers/media/video/pms.c
drivers/media/video/pvrusb2/pvrusb2-hdw.c
drivers/media/video/s5p-fimc/fimc-capture.c
drivers/media/video/saa7134/saa7134-cards.c
drivers/media/video/saa7134/saa7134-core.c
drivers/media/video/sh_vou.c
drivers/media/video/sn9c102/sn9c102_core.c
drivers/media/video/soc_camera.c
drivers/media/video/usbvision/usbvision-i2c.c
drivers/media/video/uvc/uvc_ctrl.c
drivers/media/video/uvc/uvc_queue.c
drivers/media/video/uvc/uvc_v4l2.c
drivers/media/video/uvc/uvc_video.c
drivers/media/video/uvc/uvcvideo.h
drivers/media/video/v4l2-common.c
drivers/media/video/v4l2-dev.c
drivers/media/video/v4l2-device.c
drivers/media/video/via-camera.c
drivers/media/video/vino.c
drivers/media/video/w9966.c
drivers/media/video/zoran/zoran_card.c
drivers/mtd/maps/pxa2xx-flash.c
drivers/mtd/nand/omap2.c
drivers/mtd/ubi/io.c
drivers/mtd/ubi/scan.c
drivers/net/Kconfig
drivers/net/au1000_eth.c
drivers/net/b44.c
drivers/net/benet/be_cmds.c
drivers/net/bnx2x/bnx2x.h
drivers/net/bnx2x/bnx2x_cmn.c
drivers/net/bnx2x/bnx2x_init_ops.h
drivers/net/bonding/bond_main.c
drivers/net/bonding/bonding.h
drivers/net/caif/caif_shm_u5500.c
drivers/net/caif/caif_shmcore.c
drivers/net/cxgb4/t4_hw.c
drivers/net/cxgb4vf/cxgb4vf_main.c
drivers/net/cxgb4vf/t4vf_hw.c
drivers/net/ehea/ehea_ethtool.c
drivers/net/ehea/ehea_main.c
drivers/net/enic/enic_main.c
drivers/net/ifb.c
drivers/net/ixgbe/ixgbe_main.c
drivers/net/mlx4/fw.c
drivers/net/pch_gbe/pch_gbe_main.c
drivers/net/pch_gbe/pch_gbe_param.c
drivers/net/phy/Kconfig
drivers/net/phy/icplus.c
drivers/net/ppp_generic.c
drivers/net/pppoe.c
drivers/net/qlge/qlge.h
drivers/net/qlge/qlge_main.c
drivers/net/qlge/qlge_mpi.c
drivers/net/r8169.c
drivers/net/sfc/efx.c
drivers/net/sfc/net_driver.h
drivers/net/sfc/nic.c
drivers/net/stmmac/stmmac_main.c
drivers/net/tulip/dmfe.c
drivers/net/ucc_geth.h
drivers/net/usb/hso.c
drivers/net/wan/hd64572.c
drivers/net/wan/x25_asy.c
drivers/net/wireless/ath/ath5k/base.c
drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
drivers/net/wireless/ath/ath9k/ath9k.h
drivers/net/wireless/ath/ath9k/eeprom.c
drivers/net/wireless/ath/ath9k/eeprom.h
drivers/net/wireless/ath/ath9k/eeprom_def.c
drivers/net/wireless/ath/ath9k/hif_usb.c
drivers/net/wireless/ath/ath9k/htc.h
drivers/net/wireless/ath/ath9k/htc_drv_init.c
drivers/net/wireless/ath/ath9k/htc_drv_main.c
drivers/net/wireless/ath/ath9k/hw.c
drivers/net/wireless/ath/ath9k/init.c
drivers/net/wireless/ath/ath9k/mac.c
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/ath/ath9k/recv.c
drivers/net/wireless/ath/ath9k/reg.h
drivers/net/wireless/ath/ath9k/xmit.c
drivers/net/wireless/ath/carl9170/fw.c
drivers/net/wireless/ath/carl9170/main.c
drivers/net/wireless/ath/carl9170/tx.c
drivers/net/wireless/b43/sdio.c
drivers/net/wireless/libertas/if_sdio.c
drivers/net/wireless/libertas/if_spi.c
drivers/net/wireless/libertas/main.c
drivers/net/wireless/orinoco/main.c
drivers/net/wireless/orinoco/orinoco_cs.c
drivers/net/wireless/orinoco/scan.c
drivers/net/wireless/orinoco/scan.h
drivers/net/wireless/orinoco/spectrum_cs.c
drivers/net/wireless/orinoco/wext.c
drivers/net/xen-netfront.c
drivers/parisc/dino.c
drivers/parisc/eisa.c
drivers/parisc/gsc.c
drivers/parisc/iosapic.c
drivers/parisc/led.c
drivers/parisc/superio.c
drivers/pci/bus.c
drivers/pci/dmar.c
drivers/pci/quirks.c
drivers/pcmcia/soc_common.c
drivers/platform/x86/asus-laptop.c
drivers/platform/x86/eeepc-wmi.c
drivers/platform/x86/hp-wmi.c
drivers/platform/x86/ibm_rtl.c
drivers/platform/x86/msi-wmi.c
drivers/platform/x86/thinkpad_acpi.c
drivers/platform/x86/toshiba_acpi.c
drivers/platform/x86/wmi.c
drivers/pnp/pnpacpi/core.c
drivers/regulator/core.c
drivers/regulator/mc13783-regulator.c
drivers/regulator/tps6586x-regulator.c
drivers/regulator/twl-regulator.c
drivers/s390/cio/css.c
drivers/s390/scsi/zfcp_erp.c
drivers/s390/scsi/zfcp_fsf.c
drivers/s390/scsi/zfcp_scsi.c
drivers/scsi/hpsa.c
drivers/scsi/osd/osd_initiator.c
drivers/scsi/pmcraid.c
drivers/scsi/pmcraid.h
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_iocb.c
drivers/scsi/qla2xxx/qla_isr.c
drivers/scsi/qla2xxx/qla_nx.c
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/qla2xxx/qla_version.h
drivers/scsi/scsi_error.c
drivers/scsi/scsi_lib.c
drivers/serial/8250.c
drivers/serial/kgdboc.c
drivers/serial/mfd.c
drivers/spi/atmel_spi.c
drivers/spi/dw_spi.c
drivers/ssb/b43_pci_bridge.c
drivers/staging/asus_oled/asus_oled.c
drivers/staging/batman-adv/hard-interface.c
drivers/staging/batman-adv/soft-interface.c
drivers/staging/brcm80211/README
drivers/staging/brcm80211/TODO
drivers/staging/comedi/drivers/usbdux.c
drivers/staging/easycap/easycap.h
drivers/staging/frontier/tranzport.c
drivers/staging/go7007/go7007-driver.c
drivers/staging/iio/accel/adis16220_core.c
drivers/staging/intel_sst/intel_sst_stream_encoded.c
drivers/staging/line6/control.c
drivers/staging/line6/midi.c
drivers/staging/line6/pcm.c
drivers/staging/line6/pod.c
drivers/staging/line6/toneport.c
drivers/staging/line6/variax.c
drivers/staging/quickstart/quickstart.c
drivers/staging/rt2860/usb_main_dev.c
drivers/staging/rtl8187se/r8185b_init.c
drivers/staging/rtl8712/usb_halinit.c
drivers/staging/samsung-laptop/samsung-laptop.c
drivers/staging/speakup/fakekey.c
drivers/staging/spectra/ffsport.c
drivers/staging/tm6000/tm6000-cards.c
drivers/staging/udlfb/udlfb.c
drivers/staging/winbond/sysdef.h
drivers/staging/zram/zram_sysfs.c
drivers/tty/tty_io.c
drivers/tty/tty_ldisc.c
drivers/uio/uio.c
drivers/uio/uio_cif.c
drivers/uio/uio_netx.c
drivers/usb/atm/usbatm.c
drivers/usb/core/hcd.c
drivers/usb/host/ehci-pci.c
drivers/usb/host/xhci-hub.c
drivers/usb/host/xhci-mem.c
drivers/usb/host/xhci.c
drivers/usb/host/xhci.h
drivers/usb/misc/yurex.c
drivers/usb/musb/musb_core.c
drivers/usb/musb/musb_gadget.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/ftdi_sio_ids.h
drivers/usb/serial/usb-serial.c
drivers/vhost/net.c
drivers/vhost/vhost.c
drivers/video/da8xx-fb.c
drivers/video/fbcmap.c
drivers/video/geode/lxfb.h
drivers/video/geode/lxfb_ops.c
drivers/video/modedb.c
drivers/watchdog/Kconfig
drivers/watchdog/bcm63xx_wdt.c
drivers/watchdog/gef_wdt.c
drivers/watchdog/iTCO_wdt.c
drivers/xen/balloon.c
drivers/xen/events.c
drivers/xen/manage.c
fs/autofs4/root.c
fs/btrfs/compression.c
fs/btrfs/ctree.h
fs/btrfs/disk-io.c
fs/btrfs/export.c
fs/btrfs/extent-tree.c
fs/btrfs/extent_io.c
fs/btrfs/extent_io.h
fs/btrfs/file.c
fs/btrfs/free-space-cache.c
fs/btrfs/inode.c
fs/btrfs/ioctl.c
fs/btrfs/ioctl.h
fs/btrfs/ordered-data.c
fs/btrfs/ordered-data.h
fs/btrfs/orphan.c
fs/btrfs/super.c
fs/btrfs/transaction.c
fs/btrfs/tree-log.c
fs/btrfs/volumes.c
fs/btrfs/volumes.h
fs/ceph/dir.c
fs/ceph/ioctl.h
fs/ceph/locks.c
fs/ceph/mds_client.c
fs/ceph/mds_client.h
fs/cifs/Kconfig
fs/cifs/Makefile
fs/cifs/README
fs/cifs/cifs_fs_sb.h
fs/cifs/cifsacl.c
fs/cifs/cifsacl.h
fs/cifs/cifsfs.c
fs/cifs/cifsglob.h
fs/cifs/cifsproto.h
fs/cifs/cifssmb.c
fs/cifs/connect.c
fs/cifs/dns_resolve.c
fs/cifs/file.c
fs/cifs/fscache.c
fs/cifs/inode.c
fs/cifs/readdir.c
fs/cifs/xattr.c
fs/compat.c
fs/exec.c
fs/ext4/ext4.h
fs/ext4/inode.c
fs/ext4/namei.c
fs/ext4/super.c
fs/fuse/file.c
fs/gfs2/quota.c
fs/namei.c
fs/nfs/dir.c
fs/nfs/file.c
fs/nfs/inode.c
fs/nfs/mount_clnt.c
fs/nfs/nfs4proc.c
fs/nfs/pagelist.c
fs/nfs/read.c
fs/nfs/super.c
fs/nfs/write.c
fs/nfsd/nfs3xdr.c
fs/nfsd/xdr4.h
fs/nilfs2/gcinode.c
fs/nilfs2/ioctl.c
fs/notify/fanotify/fanotify.c
fs/notify/fanotify/fanotify_user.c
fs/notify/inotify/inotify_user.c
fs/ocfs2/cluster/heartbeat.c
fs/ocfs2/dcache.c
fs/ocfs2/dlm/dlmdomain.c
fs/ocfs2/ocfs2.h
fs/ocfs2/stack_user.c
fs/pipe.c
fs/proc/base.c
fs/reiserfs/xattr_acl.c
fs/splice.c
fs/xfs/linux-2.6/xfs_aops.c
fs/xfs/linux-2.6/xfs_buf.c
fs/xfs/xfs_bmap.c
fs/xfs/xfs_bmap.h
fs/xfs/xfs_dfrag.c
fs/xfs/xfs_error.c
fs/xfs/xfs_error.h
fs/xfs/xfs_inode_item.c
fs/xfs/xfs_rename.c
include/acpi/video.h
include/drm/i915_drm.h
include/linux/acpi.h
include/linux/atmdev.h
include/linux/binfmts.h
include/linux/bootmem.h
include/linux/cnt32_to_63.h
include/linux/cpu.h
include/linux/fanotify.h
include/linux/fs.h
include/linux/fsnotify.h
include/linux/fsnotify_backend.h
include/linux/gfp.h
include/linux/gpio_keys.h
include/linux/input.h
include/linux/ioport.h
include/linux/memory_hotplug.h
include/linux/mfd/wm8994/pdata.h
include/linux/nfs_fs.h
include/linux/nfs_page.h
include/linux/node.h
include/linux/pci_ids.h
include/linux/perf_event.h
include/linux/pipe_fs_i.h
include/linux/pm_runtime.h
include/linux/sched.h
include/linux/snmp.h
include/linux/ssb/ssb_driver_gige.h
include/linux/tty.h
include/linux/uio_driver.h
include/linux/usb.h
include/linux/video_output.h
include/linux/vmalloc.h
include/media/v4l2-common.h
include/media/v4l2-device.h
include/net/af_unix.h
include/net/sock.h
include/xen/events.h
include/xen/interface/io/ring.h
include/xen/interface/physdev.h
kernel/exit.c
kernel/fork.c
kernel/irq/proc.c
kernel/perf_event.c
kernel/power/hibernate.c
kernel/power/suspend.c
kernel/power/swap.c
kernel/power/user.c
kernel/printk.c
kernel/resource.c
kernel/sched.c
kernel/timer.c
kernel/trace/trace.c
kernel/workqueue.c
lib/debug_locks.c
mm/filemap.c
mm/hugetlb.c
mm/ksm.c
mm/memory-failure.c
mm/memory_hotplug.c
mm/mempolicy.c
mm/mmap.c
mm/page_alloc.c
mm/slub.c
mm/truncate.c
mm/vmalloc.c
mm/vmscan.c
mm/vmstat.c
net/atm/atm_sysfs.c
net/atm/resources.c
net/atm/resources.h
net/bluetooth/sco.c
net/ceph/Makefile
net/core/filter.c
net/core/timestamping.c
net/dccp/input.c
net/decnet/af_decnet.c
net/econet/af_econet.c
net/ipv4/inet_hashtables.c
net/ipv4/proc.c
net/ipv4/sysctl_net_ipv4.c
net/ipv4/tcp.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_minisocks.c
net/ipv4/tcp_output.c
net/ipv6/addrconf.c
net/ipv6/ip6_tunnel.c
net/ipv6/sit.c
net/l2tp/l2tp_ip.c
net/llc/af_llc.c
net/mac80211/Kconfig
net/mac80211/rx.c
net/mac80211/tx.c
net/sctp/socket.c
net/socket.c
net/sunrpc/svc_xprt.c
net/unix/af_unix.c
net/unix/garbage.c
net/x25/x25_link.c
net/xfrm/xfrm_state.c
scripts/kconfig/expr.h
scripts/kconfig/lkc.h
scripts/kconfig/menu.c
scripts/kconfig/zconf.gperf
scripts/kconfig/zconf.hash.c_shipped
scripts/kconfig/zconf.tab.c_shipped
scripts/kconfig/zconf.y
scripts/recordmcount.h
scripts/tags.sh
sound/core/oss/pcm_oss.c
sound/pci/hda/hda_eld.c
sound/pci/hda/hda_intel.c
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_hdmi.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_sigmatel.c
sound/soc/atmel/sam9g20_wm8731.c
sound/soc/atmel/snd-soc-afeb9260.c
sound/soc/codecs/max98088.c
sound/soc/codecs/stac9766.c
sound/soc/codecs/tlv320aic3x.c
sound/soc/codecs/tpa6130a2.c
sound/soc/codecs/wm8523.c
sound/soc/codecs/wm8580.c
sound/soc/codecs/wm8731.c
sound/soc/codecs/wm8904.c
sound/soc/codecs/wm8955.c
sound/soc/codecs/wm8960.c
sound/soc/codecs/wm8961.c
sound/soc/codecs/wm8962.c
sound/soc/codecs/wm8994.c
sound/soc/codecs/wm_hubs.c
sound/soc/davinci/davinci-vcif.c
sound/soc/ep93xx/simone.c
sound/soc/fsl/efika-audio-fabric.c
sound/soc/fsl/mpc5200_dma.c
sound/soc/fsl/mpc8610_hpcd.c
sound/soc/fsl/p1022_ds.c
sound/soc/fsl/pcm030-audio-fabric.c
sound/soc/imx/imx-ssi.c
sound/soc/imx/phycore-ac97.c
sound/soc/nuc900/nuc900-ac97.c
sound/soc/nuc900/nuc900-audio.h
sound/soc/nuc900/nuc900-pcm.c
sound/soc/omap/Kconfig
sound/soc/omap/omap3pandora.c
sound/soc/omap/osk5912.c
sound/soc/pxa/Kconfig
sound/soc/s3c24xx/smdk_spdif.c
sound/soc/s6000/s6000-i2s.c
sound/soc/s6000/s6000-pcm.c
sound/soc/s6000/s6105-ipcam.c
sound/soc/sh/ssi.c
sound/soc/soc-core.c
sound/soc/soc-dapm.c
tools/perf/builtin-record.c
tools/perf/util/header.c
tools/perf/util/symbol.c
usr/initramfs_data.S

diff --git a/Documentation/ABI/testing/sysfs-bus-rbd b/Documentation/ABI/testing/sysfs-bus-rbd
new file mode 100644 (file)
index 0000000..90a87e2
--- /dev/null
@@ -0,0 +1,83 @@
+What:          /sys/bus/rbd/
+Date:          November 2010
+Contact:       Yehuda Sadeh <yehuda@hq.newdream.net>,
+               Sage Weil <sage@newdream.net>
+Description:
+
+Being used for adding and removing rbd block devices.
+
+Usage: <mon ip addr> <options> <pool name> <rbd image name> [snap name]
+
+ $ echo "192.168.0.1 name=admin rbd foo" > /sys/bus/rbd/add
+
+The snapshot name can be "-" or omitted to map the image read/write. A <dev-id>
+will be assigned for any registered block device. If snapshot is used, it will
+be mapped read-only.
+
+Removal of a device:
+
+  $ echo <dev-id> > /sys/bus/rbd/remove
+
+Entries under /sys/bus/rbd/devices/<dev-id>/
+--------------------------------------------
+
+client_id
+
+       The ceph unique client id that was assigned for this specific session.
+
+major
+
+       The block device major number.
+
+name
+
+       The name of the rbd image.
+
+pool
+
+       The pool where this rbd image resides. The pool-name pair is unique
+       per rados system.
+
+size
+
+       The size (in bytes) of the mapped block device.
+
+refresh
+
+       Writing to this file will reread the image header data and set
+       all relevant datastructures accordingly.
+
+current_snap
+
+       The current snapshot for which the device is mapped.
+
+create_snap
+
+       Create a snapshot:
+
+        $ echo <snap-name> > /sys/bus/rbd/devices/<dev-id>/snap_create
+
+rollback_snap
+
+       Rolls back data to the specified snapshot. This goes over the entire
+       list of rados blocks and sends a rollback command to each.
+
+        $ echo <snap-name> > /sys/bus/rbd/devices/<dev-id>/snap_rollback
+
+snap_*
+
+       A directory per each snapshot
+
+
+Entries under /sys/bus/rbd/devices/<dev-id>/snap_<snap-name>
+-------------------------------------------------------------
+
+id
+
+       The rados internal snapshot id assigned for this snapshot
+
+size
+
+       The size of the image when this snapshot was taken.
+
+
index 1d77539..41ff8ae 100644 (file)
@@ -47,6 +47,20 @@ Date:                January 2007
 KernelVersion: 2.6.20
 Contact:       "Corentin Chary" <corentincj@iksaif.net>
 Description:
-               Control the bluetooth device. 1 means on, 0 means off.
+               Control the wlan device. 1 means on, 0 means off.
                This may control the led, the device or both.
 Users:         Lapsus
+
+What:          /sys/devices/platform/asus_laptop/wimax
+Date:          October 2010
+KernelVersion: 2.6.37
+Contact:       "Corentin Chary" <corentincj@iksaif.net>
+Description:
+               Control the wimax device. 1 means on, 0 means off.
+
+What:          /sys/devices/platform/asus_laptop/wwan
+Date:          October 2010
+KernelVersion: 2.6.37
+Contact:       "Corentin Chary" <corentincj@iksaif.net>
+Description:
+               Control the wwan (3G) device. 1 means on, 0 means off.
diff --git a/Documentation/ABI/testing/sysfs-platform-eeepc-wmi b/Documentation/ABI/testing/sysfs-platform-eeepc-wmi
new file mode 100644 (file)
index 0000000..e4b5fef
--- /dev/null
@@ -0,0 +1,10 @@
+What:          /sys/devices/platform/eeepc-wmi/cpufv
+Date:          Oct 2010
+KernelVersion: 2.6.37
+Contact:       "Corentin Chary" <corentincj@iksaif.net>
+Description:
+               Change CPU clock configuration (write-only).
+               There are three available clock configuration:
+                   * 0 -> Super Performance Mode
+                   * 1 -> High Performance Mode
+                   * 2 -> Power Saving Mode
diff --git a/Documentation/driver-model/interface.txt b/Documentation/driver-model/interface.txt
deleted file mode 100644 (file)
index c66912b..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-
-Device Interfaces
-
-Introduction
-~~~~~~~~~~~~
-
-Device interfaces are the logical interfaces of device classes that correlate
-directly to userspace interfaces, like device nodes. 
-   
-Each device class may have multiple interfaces through which you can 
-access the same device. An input device may support the mouse interface, 
-the 'evdev' interface, and the touchscreen interface. A SCSI disk would 
-support the disk interface, the SCSI generic interface, and possibly a raw 
-device interface. 
-
-Device interfaces are registered with the class they belong to. As devices
-are added to the class, they are added to each interface registered with
-the class. The interface is responsible for determining whether the device
-supports the interface or not. 
-
-
-Programming Interface
-~~~~~~~~~~~~~~~~~~~~~
-
-struct device_interface {
-       char                    * name;
-       rwlock_t                lock;
-       u32                     devnum;
-       struct device_class     * devclass;
-
-       struct list_head        node;
-       struct driver_dir_entry dir;
-
-       int (*add_device)(struct device *);
-       int (*add_device)(struct intf_data *);
-};
-
-int interface_register(struct device_interface *);
-void interface_unregister(struct device_interface *);
-
-
-An interface must specify the device class it belongs to. It is added
-to that class's list of interfaces on registration.
-
-
-Interfaces can be added to a device class at any time. Whenever it is
-added, each device in the class is passed to the interface's
-add_device callback. When an interface is removed, each device is
-removed from the interface.
-
-
-Devices
-~~~~~~~
-Once a device is added to a device class, it is added to each
-interface that is registered with the device class. The class
-is expected to place a class-specific data structure in 
-struct device::class_data. The interface can use that (along with
-other fields of struct device) to determine whether or not the driver
-and/or device support that particular interface.
-
-
-Data
-~~~~
-
-struct intf_data {
-       struct list_head        node;
-       struct device_interface * intf;
-       struct device           * dev;
-       u32                     intf_num;
-};
-
-int interface_add_data(struct interface_data *);
-
-The interface is responsible for allocating and initializing a struct 
-intf_data and calling interface_add_data() to add it to the device's list
-of interfaces it belongs to. This list will be iterated over when the device
-is removed from the class (instead of all possible interfaces for a class).
-This structure should probably be embedded in whatever per-device data 
-structure the interface is allocating anyway.
-   
-Devices are enumerated within the interface. This happens in interface_add_data()
-and the enumerated value is stored in the struct intf_data for that device. 
-
-sysfs
-~~~~~
-Each interface is given a directory in the directory of the device
-class it belongs to:
-
-Interfaces get a directory in the class's directory as well:
-
-   class/
-   `-- input
-       |-- devices
-       |-- drivers
-       |-- mouse
-       `-- evdev
-
-When a device is added to the interface, a symlink is created that points 
-to the device's directory in the physical hierarchy:
-
-   class/
-   `-- input
-       |-- devices
-       |   `-- 1 -> ../../../root/pci0/00:1f.0/usb_bus/00:1f.2-1:0/
-       |-- drivers
-       |   `-- usb:usb_mouse -> ../../../bus/drivers/usb_mouse/
-       |-- mouse
-       |   `-- 1 -> ../../../root/pci0/00:1f.0/usb_bus/00:1f.2-1:0/
-       `-- evdev
-           `-- 1 -> ../../../root/pci0/00:1f.0/usb_bus/00:1f.2-1:0/
-
-
-Future Plans
-~~~~~~~~~~~~
-A device interface is correlated directly with a userspace interface
-for a device, specifically a device node. For instance, a SCSI disk
-exposes at least two interfaces to userspace: the standard SCSI disk
-interface and the SCSI generic interface. It might also export a raw
-device interface. 
-
-Many interfaces have a major number associated with them and each
-device gets a minor number. Or, multiple interfaces might share one
-major number, and each will receive a range of minor numbers (like in
-the case of input devices).
-
-These major and minor numbers could be stored in the interface
-structure. Major and minor allocations could happen when the interface
-is registered with the class, or via a helper function. 
-
index 0b875e8..9ee774d 100644 (file)
@@ -196,7 +196,7 @@ csrow3.
 The representation of the above is reflected in the directory tree
 in EDAC's sysfs interface. Starting in directory
 /sys/devices/system/edac/mc each memory controller will be represented
-by its own 'mcX' directory, where 'X" is the index of the MC.
+by its own 'mcX' directory, where 'X' is the index of the MC.
 
 
        ..../edac/mc/
@@ -207,7 +207,7 @@ by its own 'mcX' directory, where 'X" is the index of the MC.
                   ....
 
 Under each 'mcX' directory each 'csrowX' is again represented by a
-'csrowX', where 'X" is the csrow index:
+'csrowX', where 'X' is the csrow index:
 
 
        .../mc/mc0/
@@ -232,7 +232,7 @@ EDAC control and attribute files.
 
 
 In 'mcX' directories are EDAC control and attribute files for
-this 'X" instance of the memory controllers:
+this 'X' instance of the memory controllers:
 
 
 Counter reset control file:
@@ -343,7 +343,7 @@ Sdram memory scrubbing rate:
 'csrowX' DIRECTORIES
 
 In the 'csrowX' directories are EDAC control and attribute files for
-this 'X" instance of csrow:
+this 'X' instance of csrow:
 
 
 Total Uncorrectable Errors count attribute file:
index a91f308..b6426f1 100644 (file)
@@ -173,12 +173,13 @@ prototypes:
        sector_t (*bmap)(struct address_space *, sector_t);
        int (*invalidatepage) (struct page *, unsigned long);
        int (*releasepage) (struct page *, int);
+       void (*freepage)(struct page *);
        int (*direct_IO)(int, struct kiocb *, const struct iovec *iov,
                        loff_t offset, unsigned long nr_segs);
        int (*launder_page) (struct page *);
 
 locking rules:
-       All except set_page_dirty may block
+       All except set_page_dirty and freepage may block
 
                        BKL     PageLocked(page)        i_mutex
 writepage:             no      yes, unlocks (see below)
@@ -193,6 +194,7 @@ perform_write:              no      n/a                     yes
 bmap:                  no
 invalidatepage:                no      yes
 releasepage:           no      yes
+freepage:              no      yes
 direct_IO:             no
 launder_page:          no      yes
 
@@ -288,6 +290,9 @@ buffers from the page in preparation for freeing it.  It returns zero to
 indicate that the buffers are (or may be) freeable.  If ->releasepage is zero,
 the kernel assumes that the fs has no private interest in the buffers.
 
+       ->freepage() is called when the kernel is done dropping the page
+from the page cache.
+
        ->launder_page() may be called prior to releasing a page if
 it is still found to be dirty. It returns zero if the page was successfully
 cleaned, or an error value if not. Note that in order to prevent the page
index ed7e5ef..20899e0 100644 (file)
@@ -534,6 +534,7 @@ struct address_space_operations {
        sector_t (*bmap)(struct address_space *, sector_t);
        int (*invalidatepage) (struct page *, unsigned long);
        int (*releasepage) (struct page *, int);
+       void (*freepage)(struct page *);
        ssize_t (*direct_IO)(int, struct kiocb *, const struct iovec *iov,
                        loff_t offset, unsigned long nr_segs);
        struct page* (*get_xip_page)(struct address_space *, sector_t,
@@ -660,11 +661,10 @@ struct address_space_operations {
   releasepage: releasepage is called on PagePrivate pages to indicate
         that the page should be freed if possible.  ->releasepage
         should remove any private data from the page and clear the
-        PagePrivate flag.  It may also remove the page from the
-        address_space.  If this fails for some reason, it may indicate
-        failure with a 0 return value.
-       This is used in two distinct though related cases.  The first
-        is when the VM finds a clean page with no active users and
+        PagePrivate flag. If releasepage() fails for some reason, it must
+       indicate failure with a 0 return value.
+       releasepage() is used in two distinct though related cases.  The
+       first is when the VM finds a clean page with no active users and
         wants to make it a free page.  If ->releasepage succeeds, the
         page will be removed from the address_space and become free.
 
@@ -679,6 +679,12 @@ struct address_space_operations {
         need to ensure this.  Possibly it can clear the PageUptodate
         bit if it cannot free private data yet.
 
+  freepage: freepage is called once the page is no longer visible in
+        the page cache in order to allow the cleanup of any private
+       data. Since it may be called by the memory reclaimer, it
+       should not assume that the original address_space mapping still
+       exists, and it should not block.
+
   direct_IO: called by the generic read/write routines to perform
         direct_IO - that is IO requests which bypass the page cache
         and transfer data directly between the storage and the
index cdd2a6e..8b61c93 100644 (file)
@@ -2175,11 +2175,6 @@ and is between 256 and 4096 characters. It is defined in the file
        reset_devices   [KNL] Force drivers to reset the underlying device
                        during initialization.
 
-       resource_alloc_from_bottom
-                       Allocate new resources from the beginning of available
-                       space, not the end.  If you need to use this, please
-                       report a bug.
-
        resume=         [SWSUSP]
                        Specify the partition device for software suspend
 
index fe95105..3c5e465 100644 (file)
@@ -144,6 +144,7 @@ tcp_adv_win_scale - INTEGER
        Count buffering overhead as bytes/2^tcp_adv_win_scale
        (if tcp_adv_win_scale > 0) or bytes-bytes/2^(-tcp_adv_win_scale),
        if it is <= 0.
+       Possible values are [-31, 31], inclusive.
        Default: 2
 
 tcp_allowed_congestion_control - STRING
index 489e9ba..41cc7b3 100644 (file)
@@ -379,8 +379,8 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h:
       zero)
 
   bool pm_runtime_suspended(struct device *dev);
-    - return true if the device's runtime PM status is 'suspended', or false
-      otherwise
+    - return true if the device's runtime PM status is 'suspended' and its
+      'power.disable_depth' field is equal to zero, or false otherwise
 
   void pm_runtime_allow(struct device *dev);
     - set the power.runtime_auto flag for the device and decrease its usage
index b3be8b3..6a58887 100644 (file)
@@ -559,14 +559,14 @@ W:        http://maxim.org.za/at91_26.html
 S:     Maintained
 
 ARM/BCMRING ARM ARCHITECTURE
-M:     Leo Chen <leochen@broadcom.com>
+M:     Jiandong Zheng <jdzheng@broadcom.com>
 M:     Scott Branden <sbranden@broadcom.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 F:     arch/arm/mach-bcmring
 
 ARM/BCMRING MTD NAND DRIVER
-M:     Leo Chen <leochen@broadcom.com>
+M:     Jiandong Zheng <jdzheng@broadcom.com>
 M:     Scott Branden <sbranden@broadcom.com>
 L:     linux-mtd@lists.infradead.org
 S:     Maintained
@@ -815,7 +815,7 @@ F:  drivers/mmc/host/msm_sdcc.c
 F:     drivers/mmc/host/msm_sdcc.h
 F:     drivers/serial/msm_serial.h
 F:     drivers/serial/msm_serial.c
-T:     git git://codeaurora.org/quic/kernel/dwalker/linux-msm.git
+T:     git git://codeaurora.org/quic/kernel/davidb/linux-msm.git
 S:     Maintained
 
 ARM/TOSA MACHINE SUPPORT
@@ -2060,7 +2060,7 @@ F:        Documentation/blockdev/drbd/
 
 DRIVER CORE, KOBJECTS, DEBUGFS AND SYSFS
 M:     Greg Kroah-Hartman <gregkh@suse.de>
-T:     quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6.git
 S:     Supported
 F:     Documentation/kobject.txt
 F:     drivers/base/
@@ -2080,7 +2080,7 @@ F:        include/drm/
 
 INTEL DRM DRIVERS (excluding Poulsbo, Moorestown and derivative chipsets)
 M:     Chris Wilson <chris@chris-wilson.co.uk>
-L:     intel-gfx@lists.freedesktop.org
+L:     intel-gfx@lists.freedesktop.org (subscribers-only)
 L:     dri-devel@lists.freedesktop.org
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/ickle/drm-intel.git
 S:     Supported
@@ -4064,9 +4064,8 @@ F:        drivers/scsi/NCR_D700.*
 
 NETEFFECT IWARP RNIC DRIVER (IW_NES)
 M:     Faisal Latif <faisal.latif@intel.com>
-M:     Chien Tung <chien.tin.tung@intel.com>
 L:     linux-rdma@vger.kernel.org
-W:     http://www.neteffect.com
+W:     http://www.intel.com/Products/Server/Adapters/Server-Cluster/Server-Cluster-overview.htm
 S:     Supported
 F:     drivers/infiniband/hw/nes/
 
@@ -5933,7 +5932,6 @@ F:        include/linux/tty.h
 
 TULIP NETWORK DRIVERS
 M:     Grant Grundler <grundler@parisc-linux.org>
-M:     Kyle McMartin <kyle@mcmartin.ca>
 L:     netdev@vger.kernel.org
 S:     Maintained
 F:     drivers/net/tulip/
@@ -6585,6 +6583,15 @@ F:       include/linux/mfd/wm8400*
 F:     include/sound/wm????.h
 F:     sound/soc/codecs/wm*
 
+WORKQUEUE
+M:     Tejun Heo <tj@kernel.org>
+L:     linux-kernel@vger.kernel.org
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq.git
+S:     Maintained
+F:     include/linux/workqueue.h
+F:     kernel/workqueue.c
+F:     Documentation/workqueue.txt
+
 X.25 NETWORK LAYER
 M:     Andrew Hendry <andrew.hendry@gmail.com>
 L:     linux-x25@vger.kernel.org
index b31d213..5aa4427 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 37
-EXTRAVERSION = -rc3
+EXTRAVERSION = -rc6
 NAME = Flesh-Eating Bats with Fangs
 
 # *DOCUMENTATION*
index db524e7..d56d21c 100644 (file)
@@ -9,7 +9,7 @@ config ARM
        select GENERIC_ATOMIC64 if (!CPU_32v6K || !AEABI)
        select HAVE_OPROFILE if (HAVE_PERF_EVENTS)
        select HAVE_ARCH_KGDB
-       select HAVE_KPROBES if (!XIP_KERNEL)
+       select HAVE_KPROBES if (!XIP_KERNEL && !THUMB2_KERNEL)
        select HAVE_KRETPROBES if (HAVE_KPROBES)
        select HAVE_FUNCTION_TRACER if (!XIP_KERNEL)
        select HAVE_FTRACE_MCOUNT_RECORD if (!XIP_KERNEL)
@@ -1311,7 +1311,7 @@ config HZ
 
 config THUMB2_KERNEL
        bool "Compile the kernel in Thumb-2 mode"
-       depends on CPU_V7 && EXPERIMENTAL
+       depends on CPU_V7 && !CPU_V6 && EXPERIMENTAL
        select AEABI
        select ARM_ASM_UNIFIED
        help
@@ -1759,7 +1759,7 @@ comment "At least one emulation must be selected"
 
 config FPE_NWFPE
        bool "NWFPE math emulation"
-       depends on !AEABI || OABI_COMPAT
+       depends on (!AEABI || OABI_COMPAT) && !THUMB2_KERNEL
        ---help---
          Say Y to include the NWFPE floating point emulator in the kernel.
          This is necessary to run most binaries. Linux does not currently
index 4a590f4..4d26f2c 100644 (file)
@@ -70,12 +70,7 @@ else
 $(obj)/uImage: LOADADDR=$(ZRELADDR)
 endif
 
-ifeq ($(CONFIG_THUMB2_KERNEL),y)
-# Set bit 0 to 1 so that "mov pc, rx" switches to Thumb-2 mode
-$(obj)/uImage: STARTADDR=$(shell echo $(LOADADDR) | sed -e "s/.$$/1/")
-else
 $(obj)/uImage: STARTADDR=$(LOADADDR)
-endif
 
 $(obj)/uImage: $(obj)/zImage FORCE
        $(call if_changed,uimage)
index 8b0de41..78b5080 100644 (file)
@@ -73,6 +73,8 @@ move:         ldmia   r4!, {r7 - r10}         @ move 32-bytes at a time
 
                .size   _start, . - _start
 
+               .align
+
                .type   data,#object
 data:          .word   initrd_start            @ source initrd address
                .word   initrd_phys             @ destination initrd address
index 9be21ba..7193884 100644 (file)
@@ -125,9 +125,13 @@ wait:              mrc     p14, 0, pc, c0, c1, 0
  * sort out different calling conventions
  */
                .align
+               .arm                            @ Always enter in ARM state
 start:
                .type   start,#function
-               .rept   8
+ THUMB(                adr     r12, BSYM(1f)   )
+ THUMB(                bx      r12             )
+ THUMB(                .rept   6               )
+ ARM(          .rept   8               )
                mov     r0, r0
                .endr
 
@@ -135,6 +139,7 @@ start:
                .word   0x016f2818              @ Magic numbers to help the loader
                .word   start                   @ absolute load/run zImage address
                .word   _edata                  @ zImage end address
+ THUMB(                .thumb                  )
 1:             mov     r7, r1                  @ save architecture ID
                mov     r8, r2                  @ save atags pointer
 
@@ -174,7 +179,8 @@ not_angel:
                ldr     sp, [r0, #28]
 #ifdef CONFIG_AUTO_ZRELADDR
                @ determine final kernel image address
-               and     r4, pc, #0xf8000000
+               mov     r4, pc
+               and     r4, r4, #0xf8000000
                add     r4, r4, #TEXT_OFFSET
 #else
                ldr     r4, =zreladdr
@@ -445,7 +451,8 @@ __setup_mmu:        sub     r3, r4, #16384          @ Page directory size
  */
                mov     r1, #0x1e
                orr     r1, r1, #3 << 10
-               mov     r2, pc, lsr #20
+               mov     r2, pc
+               mov     r2, r2, lsr #20
                orr     r1, r1, r2, lsl #20
                add     r0, r3, r2, lsl #2
                str     r1, [r0], #4
index 772f95f..e6388dc 100644 (file)
@@ -146,9 +146,15 @@ static int gic_set_cpu(unsigned int irq, const struct cpumask *mask_val)
        unsigned int shift = (irq % 4) * 8;
        unsigned int cpu = cpumask_first(mask_val);
        u32 val;
+       struct irq_desc *desc;
 
        spin_lock(&irq_controller_lock);
-       irq_desc[irq].node = cpu;
+       desc = irq_to_desc(irq);
+       if (desc == NULL) {
+               spin_unlock(&irq_controller_lock);
+               return -EINVAL;
+       }
+       desc->node = cpu;
        val = readl(reg) & ~(0xff << shift);
        val |= 1 << (cpu + shift);
        writel(val, reg);
@@ -210,7 +216,7 @@ void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)
 void __init gic_dist_init(unsigned int gic_nr, void __iomem *base,
                          unsigned int irq_start)
 {
-       unsigned int max_irq, i;
+       unsigned int gic_irqs, irq_limit, i;
        u32 cpumask = 1 << smp_processor_id();
 
        if (gic_nr >= MAX_GIC_NR)
@@ -226,47 +232,49 @@ void __init gic_dist_init(unsigned int gic_nr, void __iomem *base,
 
        /*
         * Find out how many interrupts are supported.
-        */
-       max_irq = readl(base + GIC_DIST_CTR) & 0x1f;
-       max_irq = (max_irq + 1) * 32;
-
-       /*
         * The GIC only supports up to 1020 interrupt sources.
-        * Limit this to either the architected maximum, or the
-        * platform maximum.
         */
-       if (max_irq > max(1020, NR_IRQS))
-               max_irq = max(1020, NR_IRQS);
+       gic_irqs = readl(base + GIC_DIST_CTR) & 0x1f;
+       gic_irqs = (gic_irqs + 1) * 32;
+       if (gic_irqs > 1020)
+               gic_irqs = 1020;
 
        /*
         * Set all global interrupts to be level triggered, active low.
         */
-       for (i = 32; i < max_irq; i += 16)
+       for (i = 32; i < gic_irqs; i += 16)
                writel(0, base + GIC_DIST_CONFIG + i * 4 / 16);
 
        /*
         * Set all global interrupts to this CPU only.
         */
-       for (i = 32; i < max_irq; i += 4)
+       for (i = 32; i < gic_irqs; i += 4)
                writel(cpumask, base + GIC_DIST_TARGET + i * 4 / 4);
 
        /*
         * Set priority on all global interrupts.
         */
-       for (i = 32; i < max_irq; i += 4)
+       for (i = 32; i < gic_irqs; i += 4)
                writel(0xa0a0a0a0, base + GIC_DIST_PRI + i * 4 / 4);
 
        /*
         * Disable all interrupts.  Leave the PPI and SGIs alone
         * as these enables are banked registers.
         */
-       for (i = 32; i < max_irq; i += 32)
+       for (i = 32; i < gic_irqs; i += 32)
                writel(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i * 4 / 32);
 
+       /*
+        * Limit number of interrupts registered to the platform maximum
+        */
+       irq_limit = gic_data[gic_nr].irq_offset + gic_irqs;
+       if (WARN_ON(irq_limit > NR_IRQS))
+               irq_limit = NR_IRQS;
+
        /*
         * Setup the Linux IRQ subsystem.
         */
-       for (i = irq_start; i < gic_data[gic_nr].irq_offset + max_irq; i++) {
+       for (i = irq_start; i < irq_limit; i++) {
                set_irq_chip(i, &gic_chip);
                set_irq_chip_data(i, &gic_data[gic_nr]);
                set_irq_handler(i, handle_level_irq);
diff --git a/arch/arm/configs/at91rm9200_defconfig b/arch/arm/configs/at91rm9200_defconfig
new file mode 100644 (file)
index 0000000..38cb7c9
--- /dev/null
@@ -0,0 +1,341 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_AT91=y
+CONFIG_MACH_ONEARM=y
+CONFIG_ARCH_AT91RM9200DK=y
+CONFIG_MACH_AT91RM9200EK=y
+CONFIG_MACH_CSB337=y
+CONFIG_MACH_CSB637=y
+CONFIG_MACH_CARMEVA=y
+CONFIG_MACH_ATEB9200=y
+CONFIG_MACH_KB9200=y
+CONFIG_MACH_PICOTUX2XX=y
+CONFIG_MACH_KAFA=y
+CONFIG_MACH_ECBAT91=y
+CONFIG_MACH_YL9200=y
+CONFIG_MACH_CPUAT91=y
+CONFIG_MACH_ECO920=y
+CONFIG_MTD_AT91_DATAFLASH_CARD=y
+CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
+CONFIG_AT91_TIMER_HZ=100
+# CONFIG_ARM_THUMB is not set
+CONFIG_PCCARD=y
+CONFIG_AT91_CF=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_LEDS=y
+CONFIG_LEDS_CPU=y
+CONFIG_ZBOOT_ROM_TEXT=0x10000000
+CONFIG_ZBOOT_ROM_BSS=0x20040000
+CONFIG_KEXEC=y
+CONFIG_FPE_NWFPE=y
+CONFIG_BINFMT_MISC=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_MIP6=m
+CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=m
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_AFS_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PLATRAM=y
+CONFIG_MTD_DATAFLASH=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_ATMEL=y
+CONFIG_MTD_NAND_PLATFORM=y
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_GLUEBI=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_NBD=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_ATMEL_TCLIB=y
+CONFIG_EEPROM_LEGACY=m
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+CONFIG_TUN=m
+CONFIG_PHYLIB=y
+CONFIG_DAVICOM_PHY=y
+CONFIG_SMSC_PHY=y
+CONFIG_MICREL_PHY=y
+CONFIG_NET_ETHERNET=y
+CONFIG_ARM_AT91_ETHER=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_DM9601=m
+CONFIG_USB_NET_GL620A=m
+CONFIG_USB_NET_PLUSB=m
+CONFIG_USB_NET_RNDIS_HOST=m
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_EPSON2888=y
+CONFIG_PPP=y
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=y
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_BSDCOMP=y
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+CONFIG_SLIP_MODE_SLIP6=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
+CONFIG_INPUT_EVDEV=y
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+CONFIG_LEGACY_PTY_COUNT=32
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_GPIO=y
+CONFIG_SPI=y
+CONFIG_SPI_ATMEL=y
+CONFIG_SPI_BITBANG=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_HWMON=m
+CONFIG_SENSORS_ADM1021=m
+CONFIG_SENSORS_ADM1025=m
+CONFIG_SENSORS_ADM1026=m
+CONFIG_SENSORS_ADM1029=m
+CONFIG_SENSORS_ADM1031=m
+CONFIG_SENSORS_ADM9240=m
+CONFIG_SENSORS_DS1621=m
+CONFIG_SENSORS_GL518SM=m
+CONFIG_SENSORS_GL520SM=m
+CONFIG_SENSORS_IT87=m
+CONFIG_SENSORS_LM63=m
+CONFIG_SENSORS_LM73=m
+CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_LM77=m
+CONFIG_SENSORS_LM78=m
+CONFIG_SENSORS_LM80=m
+CONFIG_SENSORS_LM83=m
+CONFIG_SENSORS_LM85=m
+CONFIG_SENSORS_LM87=m
+CONFIG_SENSORS_LM90=m
+CONFIG_SENSORS_LM92=m
+CONFIG_SENSORS_MAX1619=m
+CONFIG_SENSORS_PCF8591=m
+CONFIG_SENSORS_SMSC47B397=m
+CONFIG_SENSORS_W83781D=m
+CONFIG_SENSORS_W83791D=m
+CONFIG_SENSORS_W83792D=m
+CONFIG_SENSORS_W83793=m
+CONFIG_SENSORS_W83L785TS=m
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+CONFIG_AT91RM9200_WATCHDOG=y
+CONFIG_FB=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+CONFIG_FB_S1D13XXX=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_DISPLAY_SUPPORT=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FONTS=y
+CONFIG_FONT_MINI_4x6=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_MON=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+CONFIG_USB_STORAGE=y
+CONFIG_USB_SERIAL=y
+CONFIG_USB_SERIAL_CONSOLE=y
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_FTDI_SIO=y
+CONFIG_USB_SERIAL_KEYSPAN=y
+CONFIG_USB_SERIAL_KEYSPAN_MPR=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19=y
+CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
+CONFIG_USB_SERIAL_MCT_U232=y
+CONFIG_USB_SERIAL_PL2303=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_ETH=m
+CONFIG_USB_MASS_STORAGE=m
+CONFIG_MMC=y
+CONFIG_MMC_AT91=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_GPIO=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_RTC_CLASS=y
+# CONFIG_RTC_HCTOSYS is not set
+CONFIG_RTC_DRV_DS1307=y
+CONFIG_RTC_DRV_PCF8563=y
+CONFIG_RTC_DRV_AT91RM9200=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+CONFIG_REISERFS_FS=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_NTFS_FS=m
+CONFIG_TMPFS=y
+CONFIG_CONFIGFS_FS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_LZO=y
+CONFIG_JFFS2_RUBIN=y
+CONFIG_CRAMFS=y
+CONFIG_MINIX_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=y
+CONFIG_SMB_FS=m
+CONFIG_CIFS=m
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_MAC_PARTITION=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_FTRACE is not set
+CONFIG_CRYPTO_PCBC=y
+CONFIG_CRYPTO_SHA1=y
diff --git a/arch/arm/configs/at91rm9200dk_defconfig b/arch/arm/configs/at91rm9200dk_defconfig
deleted file mode 100644 (file)
index 4438e64..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_AT91=y
-CONFIG_ARCH_AT91RM9200DK=y
-CONFIG_MACH_ECO920=y
-CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_PCCARD=y
-CONFIG_AT91_CF=y
-CONFIG_LEDS=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="mem=32M console=ttyS0,115200 initrd=0x20410000,3145728 root=/dev/ram0 rw"
-CONFIG_FPE_NWFPE=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IPV6 is not set
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_JEDECPROBE=y
-CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_ARM_AT91_ETHER=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_GPIO=y
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-CONFIG_AT91RM9200_WATCHDOG=y
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_USB_HID is not set
-CONFIG_USB=y
-CONFIG_USB_DEBUG=y
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_MON=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_GADGET=y
-CONFIG_MMC=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_AT91RM9200=y
-CONFIG_EXT2_FS=y
-CONFIG_INOTIFY=y
-CONFIG_TMPFS=y
-CONFIG_CRAMFS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_LL=y
diff --git a/arch/arm/configs/at91rm9200ek_defconfig b/arch/arm/configs/at91rm9200ek_defconfig
deleted file mode 100644 (file)
index ccd517c..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_LOCALVERSION_AUTO is not set
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_AT91=y
-CONFIG_MACH_AT91RM9200EK=y
-CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_LEDS=y
-CONFIG_LEDS_CPU=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="mem=32M console=ttyS0,115200 initrd=0x20410000,3145728 root=/dev/ram0 rw"
-CONFIG_FPE_NWFPE=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IPV6 is not set
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_JEDECPROBE=y
-CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_ARM_AT91_ETHER=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_GPIO=y
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-CONFIG_AT91RM9200_WATCHDOG=y
-CONFIG_FB=y
-CONFIG_FB_S1D13XXX=y
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_USB_HID is not set
-CONFIG_USB=y
-CONFIG_USB_DEBUG=y
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_MON=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_GADGET=y
-CONFIG_MMC=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_AT91RM9200=y
-CONFIG_EXT2_FS=y
-CONFIG_INOTIFY=y
-CONFIG_TMPFS=y
-CONFIG_CRAMFS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_LL=y
diff --git a/arch/arm/configs/ateb9200_defconfig b/arch/arm/configs/ateb9200_defconfig
deleted file mode 100644 (file)
index 1b0e9a1..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_EMBEDDED=y
-CONFIG_SLAB=y
-CONFIG_PROFILING=y
-CONFIG_OPROFILE=m
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_ARCH_AT91=y
-CONFIG_MACH_ATEB9200=y
-CONFIG_PCCARD=m
-CONFIG_AT91_CF=m
-CONFIG_PREEMPT=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_FPE_NWFPE=y
-CONFIG_PM=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-# CONFIG_IPV6 is not set
-CONFIG_BRIDGE=m
-CONFIG_VLAN_8021Q=m
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK_RO=y
-CONFIG_BLK_DEV_LOOP=m
-CONFIG_BLK_DEV_NBD=m
-CONFIG_SCSI=m
-CONFIG_BLK_DEV_SD=m
-CONFIG_BLK_DEV_SR=m
-CONFIG_BLK_DEV_SR_VENDOR=y
-CONFIG_CHR_DEV_SG=m
-CONFIG_SCSI_MULTI_LUN=y
-CONFIG_NETDEVICES=y
-CONFIG_DUMMY=m
-CONFIG_TUN=m
-CONFIG_PHYLIB=y
-CONFIG_DAVICOM_PHY=y
-CONFIG_NET_ETHERNET=y
-CONFIG_ARM_AT91_ETHER=y
-CONFIG_USB_USBNET=y
-CONFIG_USB_NET_GL620A=y
-CONFIG_USB_NET_PLUSB=y
-CONFIG_USB_NET_RNDIS_HOST=y
-CONFIG_USB_ALI_M5632=y
-CONFIG_USB_AN2720=y
-CONFIG_USB_EPSON2888=y
-CONFIG_PPP=m
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_BSDCOMP=m
-CONFIG_PPPOE=m
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-CONFIG_I2C=m
-CONFIG_I2C_CHARDEV=m
-CONFIG_I2C_GPIO=m
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_SOUND=y
-CONFIG_USB_HID=m
-CONFIG_HID_PID=y
-CONFIG_USB_HIDDEV=y
-CONFIG_USB=y
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_MON=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_ACM=m
-CONFIG_USB_PRINTER=m
-CONFIG_USB_STORAGE=m
-CONFIG_USB_STORAGE_DATAFAB=m
-CONFIG_USB_STORAGE_FREECOM=m
-CONFIG_USB_STORAGE_USBAT=m
-CONFIG_USB_STORAGE_SDDR09=m
-CONFIG_USB_STORAGE_SDDR55=m
-CONFIG_USB_STORAGE_JUMPSHOT=m
-CONFIG_USB_SERIAL=m
-CONFIG_USB_SERIAL_GENERIC=y
-CONFIG_USB_SERIAL_FTDI_SIO=m
-CONFIG_USB_SERIAL_PL2303=m
-CONFIG_USB_GADGET=m
-CONFIG_USB_ETH=m
-CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
-CONFIG_USB_G_SERIAL=m
-CONFIG_MMC=m
-CONFIG_MMC_DEBUG=y
-CONFIG_RTC_CLASS=y
-# CONFIG_RTC_HCTOSYS is not set
-CONFIG_RTC_DRV_AT91RM9200=y
-CONFIG_EXT2_FS=m
-CONFIG_EXT3_FS=m
-CONFIG_REISERFS_FS=m
-CONFIG_INOTIFY=y
-CONFIG_ISO9660_FS=m
-CONFIG_JOLIET=y
-CONFIG_ZISOFS=y
-CONFIG_UDF_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
-CONFIG_NTFS_FS=m
-CONFIG_NTFS_RW=y
-CONFIG_TMPFS=y
-CONFIG_CRAMFS=y
-CONFIG_NFS_FS=m
-CONFIG_NFS_V3=y
-CONFIG_NFS_V3_ACL=y
-CONFIG_NFS_V4=y
-CONFIG_NFSD=m
-CONFIG_NFSD_V4=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_MAC_PARTITION=y
-CONFIG_BSD_DISKLABEL=y
-CONFIG_MINIX_SUBPARTITION=y
-CONFIG_SOLARIS_X86_PARTITION=y
-CONFIG_UNIXWARE_DISKLABEL=y
-CONFIG_NLS_CODEPAGE_932=m
-CONFIG_NLS_ASCII=m
-CONFIG_NLS_ISO8859_15=m
-CONFIG_NLS_UTF8=m
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_ARC4=m
-CONFIG_CRC16=m
-CONFIG_LIBCRC32C=m
diff --git a/arch/arm/configs/carmeva_defconfig b/arch/arm/configs/carmeva_defconfig
deleted file mode 100644 (file)
index ac64dbd..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_EMBEDDED=y
-# CONFIG_HOTPLUG is not set
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_ARCH_AT91=y
-CONFIG_MACH_CARMEVA=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_FPE_NWFPE=y
-CONFIG_NET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_PNP=y
-# CONFIG_IPV6 is not set
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_ARM_AT91_ETHER=y
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_SERIO=m
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_MMC=m
-CONFIG_MMC_DEBUG=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-# CONFIG_DNOTIFY is not set
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_COMPRESSION_OPTIONS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_NFS_V4=y
-CONFIG_ROOT_NFS=y
-CONFIG_NFSD=y
diff --git a/arch/arm/configs/cpuat91_defconfig b/arch/arm/configs/cpuat91_defconfig
deleted file mode 100644 (file)
index 022aeb5..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_LOCALVERSION_AUTO is not set
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_AT91=y
-CONFIG_MACH_CPUAT91=y
-CONFIG_AT91_TIMER_HZ=100
-# CONFIG_ARM_THUMB is not set
-CONFIG_PREEMPT=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_IPV6 is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_CFI_INTELEXT=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PLATRAM=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_NBD=y
-CONFIG_BLK_DEV_RAM=y
-# CONFIG_MISC_DEVICES is not set
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_SCSI_MULTI_LUN=y
-# CONFIG_SCSI_LOWLEVEL is not set
-CONFIG_NETDEVICES=y
-CONFIG_PHYLIB=y
-CONFIG_NET_ETHERNET=y
-CONFIG_ARM_AT91_ETHER=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
-CONFIG_PPP=y
-CONFIG_PPP_ASYNC=y
-CONFIG_PPP_DEFLATE=y
-CONFIG_PPP_BSDCOMP=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-CONFIG_LEGACY_PTY_COUNT=32
-# CONFIG_HW_RANDOM is not set
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_GPIO=y
-CONFIG_GPIO_SYSFS=y
-# CONFIG_HWMON is not set
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-CONFIG_AT91RM9200_WATCHDOG=y
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_HID_SUPPORT is not set
-CONFIG_USB=y
-# CONFIG_USB_DEVICE_CLASS is not set
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_GADGET=y
-CONFIG_USB_ETH=m
-CONFIG_MMC=y
-CONFIG_MMC_AT91=m
-CONFIG_NEW_LEDS=y
-CONFIG_LEDS_CLASS=y
-CONFIG_LEDS_GPIO=y
-CONFIG_LEDS_TRIGGERS=y
-CONFIG_LEDS_TRIGGER_TIMER=y
-CONFIG_LEDS_TRIGGER_HEARTBEAT=y
-CONFIG_LEDS_TRIGGER_GPIO=y
-CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
-CONFIG_RTC_CLASS=y
-# CONFIG_RTC_HCTOSYS is not set
-CONFIG_RTC_DRV_DS1307=y
-CONFIG_RTC_DRV_PCF8563=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT3_FS=y
-# CONFIG_EXT3_FS_XATTR is not set
-CONFIG_INOTIFY=y
-CONFIG_AUTOFS4_FS=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_SUMMARY=y
-CONFIG_CRAMFS=y
-CONFIG_MINIX_FS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_ROOT_NFS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NLS_UTF8=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
diff --git a/arch/arm/configs/csb337_defconfig b/arch/arm/configs/csb337_defconfig
deleted file mode 100644 (file)
index a24c448..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_ARCH_AT91=y
-CONFIG_MACH_CSB337=y
-CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_PCCARD=y
-CONFIG_AT91_CF=y
-CONFIG_LEDS=y
-CONFIG_LEDS_CPU=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="mem=32M console=ttyS0,38400 initrd=0x20410000,3145728 root=/dev/ram0 rw"
-CONFIG_FPE_NWFPE=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_INET_LRO is not set
-# CONFIG_IPV6 is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_CFI_INTELEXT=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_ATMEL_SSC=y
-CONFIG_SCSI=y
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_ARM_AT91_ETHER=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-# CONFIG_HW_RANDOM is not set
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_GPIO=y
-# CONFIG_HWMON is not set
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-CONFIG_AT91RM9200_WATCHDOG=y
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_USB_HID is not set
-CONFIG_USB=y
-CONFIG_USB_DEBUG=y
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_MON=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_SERIAL=y
-CONFIG_USB_SERIAL_CONSOLE=y
-CONFIG_USB_SERIAL_GENERIC=y
-CONFIG_USB_SERIAL_FTDI_SIO=y
-CONFIG_USB_SERIAL_KEYSPAN=y
-CONFIG_USB_SERIAL_KEYSPAN_MPR=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19=y
-CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
-CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
-CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
-CONFIG_USB_SERIAL_MCT_U232=y
-CONFIG_USB_GADGET=y
-CONFIG_MMC=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_HCTOSYS_DEVICE="rtc1"
-# CONFIG_RTC_INTF_SYSFS is not set
-CONFIG_RTC_DRV_DS1307=y
-CONFIG_RTC_DRV_AT91RM9200=y
-CONFIG_EXT2_FS=y
-CONFIG_INOTIFY=y
-CONFIG_TMPFS=y
-CONFIG_CRAMFS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_NFS_V4=y
-CONFIG_ROOT_NFS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_LL=y
diff --git a/arch/arm/configs/csb637_defconfig b/arch/arm/configs/csb637_defconfig
deleted file mode 100644 (file)
index 98552ad..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_ARCH_AT91=y
-CONFIG_MACH_CSB637=y
-CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_PCCARD=y
-CONFIG_AT91_CF=y
-CONFIG_LEDS=y
-CONFIG_LEDS_CPU=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="mem=32M console=ttyS0,38400 initrd=0x20410000,3145728 root=/dev/ram0 rw"
-CONFIG_FPE_NWFPE=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_INET_LRO is not set
-# CONFIG_IPV6 is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_CFI_INTELEXT=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_SCSI=y
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_ARM_AT91_ETHER=y
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-CONFIG_AT91RM9200_WATCHDOG=y
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_USB_HID is not set
-CONFIG_USB=y
-CONFIG_USB_DEBUG=y
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_MON=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_SERIAL=y
-CONFIG_USB_SERIAL_CONSOLE=y
-CONFIG_USB_SERIAL_GENERIC=y
-CONFIG_USB_SERIAL_FTDI_SIO=y
-CONFIG_USB_SERIAL_KEYSPAN=y
-CONFIG_USB_SERIAL_KEYSPAN_MPR=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19=y
-CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
-CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
-CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
-CONFIG_USB_SERIAL_MCT_U232=y
-CONFIG_NEW_LEDS=y
-CONFIG_LEDS_CLASS=y
-CONFIG_LEDS_GPIO=y
-CONFIG_LEDS_TRIGGERS=y
-CONFIG_LEDS_TRIGGER_HEARTBEAT=y
-CONFIG_EXT2_FS=y
-CONFIG_INOTIFY=y
-CONFIG_TMPFS=y
-CONFIG_CRAMFS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_NFS_V4=y
-CONFIG_ROOT_NFS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_LL=y
diff --git a/arch/arm/configs/ecbat91_defconfig b/arch/arm/configs/ecbat91_defconfig
deleted file mode 100644 (file)
index 6bb6abd..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_AT91=y
-CONFIG_MACH_ECBAT91=y
-CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
-CONFIG_PCCARD=y
-CONFIG_AT91_CF=y
-CONFIG_PREEMPT=y
-CONFIG_LEDS=y
-CONFIG_LEDS_CPU=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="rootfstype=reiserfs root=/dev/mmcblk0p1 console=ttyS0,115200n8 rootdelay=1"
-CONFIG_FPE_NWFPE=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-# CONFIG_IPV6 is not set
-CONFIG_CFG80211=y
-CONFIG_MAC80211=y
-# CONFIG_STANDALONE is not set
-# CONFIG_PREVENT_FIRMWARE_BUILD is not set
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_AFS_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_DATAFLASH=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_SG=y
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_ARM_AT91_ETHER=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
-CONFIG_PPP=y
-CONFIG_PPP_MULTILINK=y
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_ASYNC=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-CONFIG_HW_RANDOM=y
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_SPI=y
-CONFIG_SPI_BITBANG=y
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_USB_HID is not set
-CONFIG_USB=y
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_DEVICE_CLASS is not set
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_PRINTER=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_GADGET=y
-CONFIG_MMC=y
-CONFIG_MMC_DEBUG=y
-CONFIG_MMC_AT91=m
-CONFIG_NEW_LEDS=y
-CONFIG_LEDS_CLASS=y
-CONFIG_RTC_CLASS=y
-# CONFIG_RTC_HCTOSYS is not set
-CONFIG_RTC_DRV_AT91RM9200=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT3_FS=y
-CONFIG_REISERFS_FS=y
-CONFIG_INOTIFY=y
-CONFIG_TMPFS=y
-CONFIG_CONFIGFS_FS=y
-CONFIG_CRAMFS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_NFS_V3_ACL=y
-CONFIG_NFS_V4=y
-CONFIG_ROOT_NFS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_DEBUG_USER=y
-CONFIG_CRYPTO_PCBC=y
-CONFIG_CRYPTO_SHA1=y
diff --git a/arch/arm/configs/kafa_defconfig b/arch/arm/configs/kafa_defconfig
deleted file mode 100644 (file)
index 896dbe0..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_LOCALVERSION_AUTO is not set
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_AT91=y
-CONFIG_MACH_KAFA=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_PREEMPT=y
-CONFIG_LEDS=y
-CONFIG_LEDS_CPU=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="mem=32M console=ttyS0,115200 initrd=0x20800000,10M root=/dev/ram0 rw"
-CONFIG_FPE_NWFPE=y
-CONFIG_BINFMT_MISC=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-# CONFIG_INET_DIAG is not set
-# CONFIG_IPV6 is not set
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK_RO=y
-CONFIG_NETDEVICES=y
-CONFIG_PHYLIB=y
-CONFIG_DAVICOM_PHY=y
-CONFIG_NET_ETHERNET=y
-CONFIG_ARM_AT91_ETHER=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-CONFIG_LEGACY_PTY_COUNT=32
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_GPIO=y
-# CONFIG_HWMON is not set
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-CONFIG_AT91RM9200_WATCHDOG=y
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_RTC_CLASS=y
-# CONFIG_RTC_HCTOSYS is not set
-CONFIG_RTC_DRV_AT91RM9200=y
-CONFIG_EXT3_FS=y
-# CONFIG_EXT3_FS_XATTR is not set
-CONFIG_TMPFS=y
-CONFIG_CRAMFS=y
-CONFIG_NFS_FS=m
-CONFIG_NFS_V3=y
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_DES=y
diff --git a/arch/arm/configs/kb9202_defconfig b/arch/arm/configs/kb9202_defconfig
deleted file mode 100644 (file)
index 9f906a8..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_AUDIT=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_KALLSYMS_EXTRA_PASS=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-CONFIG_ARCH_AT91=y
-CONFIG_MACH_KB9200=y
-CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_PREEMPT=y
-CONFIG_AEABI=y
-CONFIG_ZBOOT_ROM_TEXT=0x10000000
-CONFIG_ZBOOT_ROM_BSS=0x20040000
-CONFIG_CMDLINE="noinitrd root=/dev/mtdblock0 rootfstype=jffs2 mem=64M"
-CONFIG_KEXEC=y
-CONFIG_FPE_NWFPE=y
-CONFIG_BINFMT_MISC=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
-# CONFIG_INET_DIAG is not set
-# CONFIG_IPV6 is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-# CONFIG_FIRMWARE_IN_KERNEL is not set
-CONFIG_MTD=y
-CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_CFI_INTELEXT=y
-CONFIG_MTD_COMPLEX_MAPPINGS=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_ATMEL=y
-CONFIG_MTD_UBI=y
-CONFIG_MTD_UBI_GLUEBI=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=16384
-CONFIG_ATMEL_TCLIB=y
-CONFIG_ATMEL_SSC=y
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_SG=y
-CONFIG_SCSI_MULTI_LUN=y
-CONFIG_SCSI_CONSTANTS=y
-CONFIG_SCSI_LOGGING=y
-CONFIG_SCSI_SPI_ATTRS=m
-# CONFIG_SCSI_LOWLEVEL is not set
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_ARM_AT91_ETHER=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_HW_RANDOM is not set
-# CONFIG_HWMON is not set
-CONFIG_WATCHDOG=y
-CONFIG_AT91RM9200_WATCHDOG=y
-CONFIG_FB=y
-CONFIG_FB_MODE_HELPERS=y
-CONFIG_FB_TILEBLITTING=y
-CONFIG_BACKLIGHT_LCD_SUPPORT=y
-# CONFIG_LCD_CLASS_DEVICE is not set
-CONFIG_BACKLIGHT_CLASS_DEVICE=y
-# CONFIG_BACKLIGHT_GENERIC is not set
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_FONTS=y
-CONFIG_FONT_MINI_4x6=y
-# CONFIG_HID_SUPPORT is not set
-CONFIG_USB=y
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_LIBUSUAL=y
-CONFIG_MMC=y
-CONFIG_MMC_AT91=m
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_AT91RM9200=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT3_FS=y
-# CONFIG_DNOTIFY is not set
-CONFIG_INOTIFY=y
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_CONFIGFS_FS=y
-CONFIG_JFFS2_FS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_ROOT_NFS=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_UTF8=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_FS=y
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_SCHED_DEBUG is not set
-# CONFIG_DEBUG_PREEMPT is not set
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
diff --git a/arch/arm/configs/onearm_defconfig b/arch/arm/configs/onearm_defconfig
deleted file mode 100644 (file)
index 1579857..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_EMBEDDED=y
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_AT91=y
-CONFIG_MACH_ONEARM=y
-CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_PCCARD=y
-CONFIG_AT91_CF=y
-CONFIG_LEDS=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp mem=64M"
-CONFIG_FPE_NWFPE=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IPV6=y
-# 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_IPV6_SIT is not set
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_JEDECPROBE=y
-CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_BLK_DEV_NBD=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_ARM_AT91_ETHER=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-# CONFIG_VT is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-# CONFIG_HW_RANDOM is not set
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-CONFIG_AT91RM9200_WATCHDOG=y
-# CONFIG_USB_HID is not set
-CONFIG_USB=y
-CONFIG_USB_DEBUG=y
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_MON=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_GADGET=y
-CONFIG_MMC=y
-CONFIG_EXT2_FS=y
-CONFIG_INOTIFY=y
-CONFIG_TMPFS=y
-CONFIG_CRAMFS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_NFS_V3_ACL=y
-CONFIG_ROOT_NFS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_LL=y
diff --git a/arch/arm/configs/picotux200_defconfig b/arch/arm/configs/picotux200_defconfig
deleted file mode 100644 (file)
index 4c9afa4..0000000
+++ /dev/null
@@ -1,242 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_IKCONFIG=m
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_EMBEDDED=y
-# CONFIG_KALLSYMS is not set
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_AT91=y
-CONFIG_MACH_PICOTUX2XX=y
-CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
-CONFIG_AEABI=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_KEXEC=y
-CONFIG_FPE_NWFPE=y
-CONFIG_BINFMT_MISC=m
-CONFIG_NET=y
-CONFIG_PACKET=m
-CONFIG_UNIX=y
-CONFIG_XFRM_USER=m
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_NET_IPIP=m
-CONFIG_NET_IPGRE=m
-CONFIG_INET_AH=m
-CONFIG_INET_ESP=m
-CONFIG_INET_IPCOMP=m
-CONFIG_INET_XFRM_MODE_TRANSPORT=m
-CONFIG_INET_XFRM_MODE_TUNNEL=m
-CONFIG_INET_XFRM_MODE_BEET=m
-CONFIG_INET_DIAG=m
-CONFIG_IPV6_PRIVACY=y
-CONFIG_IPV6_ROUTER_PREF=y
-CONFIG_IPV6_ROUTE_INFO=y
-CONFIG_INET6_AH=m
-CONFIG_INET6_ESP=m
-CONFIG_INET6_IPCOMP=m
-CONFIG_IPV6_MIP6=m
-CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
-CONFIG_IPV6_TUNNEL=m
-CONFIG_BRIDGE=m
-CONFIG_VLAN_8021Q=m
-CONFIG_BT=m
-CONFIG_BT_L2CAP=m
-CONFIG_BT_SCO=m
-CONFIG_BT_RFCOMM=m
-CONFIG_BT_RFCOMM_TTY=y
-CONFIG_BT_BNEP=m
-CONFIG_BT_BNEP_MC_FILTER=y
-CONFIG_BT_BNEP_PROTO_FILTER=y
-CONFIG_BT_HIDP=m
-CONFIG_FW_LOADER=m
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_BLK_DEV_LOOP=m
-CONFIG_EEPROM_LEGACY=m
-CONFIG_SCSI=m
-CONFIG_BLK_DEV_SD=m
-CONFIG_BLK_DEV_SR=m
-CONFIG_BLK_DEV_SR_VENDOR=y
-CONFIG_CHR_DEV_SG=m
-CONFIG_NETDEVICES=y
-CONFIG_TUN=m
-CONFIG_NET_ETHERNET=y
-CONFIG_ARM_AT91_ETHER=y
-CONFIG_USB_CATC=m
-CONFIG_USB_KAWETH=m
-CONFIG_USB_PEGASUS=m
-CONFIG_USB_RTL8150=m
-CONFIG_USB_USBNET=m
-CONFIG_USB_NET_DM9601=m
-CONFIG_USB_NET_GL620A=m
-CONFIG_USB_NET_PLUSB=m
-CONFIG_USB_NET_MCS7830=m
-CONFIG_USB_NET_RNDIS_HOST=m
-CONFIG_USB_ALI_M5632=y
-CONFIG_USB_AN2720=y
-CONFIG_USB_EPSON2888=y
-CONFIG_USB_KC2190=y
-CONFIG_PPP=m
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_BSDCOMP=m
-CONFIG_PPP_MPPE=m
-CONFIG_PPPOE=m
-CONFIG_SLIP=m
-CONFIG_SLIP_COMPRESSED=y
-CONFIG_SLIP_SMART=y
-CONFIG_SLIP_MODE_SLIP6=y
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-# CONFIG_VT is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-# CONFIG_LEGACY_PTYS is not set
-CONFIG_I2C=m
-CONFIG_I2C_CHARDEV=m
-CONFIG_I2C_GPIO=m
-CONFIG_HWMON=m
-CONFIG_SENSORS_ADM1021=m
-CONFIG_SENSORS_ADM1025=m
-CONFIG_SENSORS_ADM1026=m
-CONFIG_SENSORS_ADM1029=m
-CONFIG_SENSORS_ADM1031=m
-CONFIG_SENSORS_ADM9240=m
-CONFIG_SENSORS_DS1621=m
-CONFIG_SENSORS_GL518SM=m
-CONFIG_SENSORS_GL520SM=m
-CONFIG_SENSORS_IT87=m
-CONFIG_SENSORS_LM63=m
-CONFIG_SENSORS_LM75=m
-CONFIG_SENSORS_LM77=m
-CONFIG_SENSORS_LM78=m
-CONFIG_SENSORS_LM80=m
-CONFIG_SENSORS_LM83=m
-CONFIG_SENSORS_LM85=m
-CONFIG_SENSORS_LM87=m
-CONFIG_SENSORS_LM90=m
-CONFIG_SENSORS_LM92=m
-CONFIG_SENSORS_MAX1619=m
-CONFIG_SENSORS_PCF8591=m
-CONFIG_SENSORS_SMSC47B397=m
-CONFIG_SENSORS_W83781D=m
-CONFIG_SENSORS_W83791D=m
-CONFIG_SENSORS_W83792D=m
-CONFIG_SENSORS_W83793=m
-CONFIG_SENSORS_W83L785TS=m
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-CONFIG_AT91RM9200_WATCHDOG=m
-CONFIG_HID=m
-CONFIG_USB=m
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_OHCI_HCD=m
-CONFIG_USB_ACM=m
-CONFIG_USB_PRINTER=m
-CONFIG_USB_STORAGE=m
-CONFIG_USB_SERIAL=m
-CONFIG_USB_SERIAL_GENERIC=y
-CONFIG_USB_SERIAL_PL2303=m
-CONFIG_MMC=m
-CONFIG_MMC_AT91=m
-CONFIG_RTC_CLASS=m
-CONFIG_RTC_DRV_AT91RM9200=m
-CONFIG_EXT2_FS=m
-CONFIG_EXT3_FS=m
-# CONFIG_EXT3_FS_XATTR is not set
-CONFIG_INOTIFY=y
-CONFIG_ISO9660_FS=m
-CONFIG_JOLIET=y
-CONFIG_UDF_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
-CONFIG_NTFS_FS=m
-CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_SUMMARY=y
-CONFIG_JFFS2_COMPRESSION_OPTIONS=y
-CONFIG_NFS_FS=m
-CONFIG_SMB_FS=m
-CONFIG_CIFS=m
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_AMIGA_PARTITION=y
-CONFIG_NLS_DEFAULT="utf-8"
-CONFIG_NLS_CODEPAGE_437=m
-CONFIG_NLS_CODEPAGE_737=m
-CONFIG_NLS_CODEPAGE_775=m
-CONFIG_NLS_CODEPAGE_850=m
-CONFIG_NLS_CODEPAGE_852=m
-CONFIG_NLS_CODEPAGE_855=m
-CONFIG_NLS_CODEPAGE_857=m
-CONFIG_NLS_CODEPAGE_860=m
-CONFIG_NLS_CODEPAGE_861=m
-CONFIG_NLS_CODEPAGE_862=m
-CONFIG_NLS_CODEPAGE_863=m
-CONFIG_NLS_CODEPAGE_864=m
-CONFIG_NLS_CODEPAGE_865=m
-CONFIG_NLS_CODEPAGE_866=m
-CONFIG_NLS_CODEPAGE_869=m
-CONFIG_NLS_CODEPAGE_936=m
-CONFIG_NLS_CODEPAGE_950=m
-CONFIG_NLS_CODEPAGE_932=m
-CONFIG_NLS_CODEPAGE_949=m
-CONFIG_NLS_CODEPAGE_874=m
-CONFIG_NLS_ISO8859_8=m
-CONFIG_NLS_CODEPAGE_1250=m
-CONFIG_NLS_CODEPAGE_1251=m
-CONFIG_NLS_ASCII=m
-CONFIG_NLS_ISO8859_1=m
-CONFIG_NLS_ISO8859_2=m
-CONFIG_NLS_ISO8859_3=m
-CONFIG_NLS_ISO8859_4=m
-CONFIG_NLS_ISO8859_5=m
-CONFIG_NLS_ISO8859_6=m
-CONFIG_NLS_ISO8859_7=m
-CONFIG_NLS_ISO8859_9=m
-CONFIG_NLS_ISO8859_13=m
-CONFIG_NLS_ISO8859_14=m
-CONFIG_NLS_ISO8859_15=m
-CONFIG_NLS_KOI8_R=m
-CONFIG_NLS_KOI8_U=m
-CONFIG_NLS_UTF8=m
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_BUGVERBOSE is not set
-CONFIG_DEBUG_LL=y
-CONFIG_CRYPTO_NULL=m
-CONFIG_CRYPTO_TEST=m
-CONFIG_CRYPTO_LRW=m
-CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_XCBC=m
-CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_SHA256=m
-CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_TGR192=m
-CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_CAMELLIA=m
-CONFIG_CRYPTO_CAST5=m
-CONFIG_CRYPTO_CAST6=m
-CONFIG_CRYPTO_FCRYPT=m
-CONFIG_CRYPTO_KHAZAD=m
-CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_TEA=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_LIBCRC32C=m
diff --git a/arch/arm/configs/yl9200_defconfig b/arch/arm/configs/yl9200_defconfig
deleted file mode 100644 (file)
index 30c537f..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_AT91=y
-CONFIG_ARCH_AT91RM9200DK=y
-CONFIG_MACH_YL9200=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="mem=32M console=ttyS0,115200 initrd=0x20410000,3145728 root=/dev/ram0 rw"
-CONFIG_FPE_NWFPE=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
-# CONFIG_INET_DIAG is not set
-# CONFIG_IPV6 is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_MTD=y
-CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_JEDECPROBE=y
-CONFIG_MTD_CFI_INTELEXT=y
-CONFIG_MTD_COMPLEX_MAPPINGS=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PLATRAM=y
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_ATMEL=y
-CONFIG_MTD_NAND_PLATFORM=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=3
-CONFIG_BLK_DEV_RAM_SIZE=8192
-# CONFIG_MISC_DEVICES is not set
-CONFIG_BLK_DEV_SD=y
-CONFIG_ATA=y
-CONFIG_NETDEVICES=y
-CONFIG_PHYLIB=y
-CONFIG_DAVICOM_PHY=y
-CONFIG_NET_ETHERNET=y
-CONFIG_ARM_AT91_ETHER=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
-CONFIG_INPUT_EVDEV=y
-# CONFIG_KEYBOARD_ATKBD is not set
-CONFIG_KEYBOARD_GPIO=y
-CONFIG_INPUT_TOUCHSCREEN=y
-CONFIG_TOUCHSCREEN_ADS7846=y
-# CONFIG_SERIO_SERPORT is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-# CONFIG_HW_RANDOM is not set
-CONFIG_I2C=y
-CONFIG_SPI=y
-CONFIG_SPI_DEBUG=y
-CONFIG_SPI_ATMEL=y
-CONFIG_FB=y
-CONFIG_BACKLIGHT_LCD_SUPPORT=y
-CONFIG_LCD_CLASS_DEVICE=y
-CONFIG_BACKLIGHT_CLASS_DEVICE=y
-CONFIG_DISPLAY_SUPPORT=y
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_LOGO=y
-# CONFIG_LOGO_LINUX_MONO is not set
-# CONFIG_LOGO_LINUX_VGA16 is not set
-CONFIG_USB=y
-CONFIG_USB_DEBUG=y
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_DEVICE_CLASS is not set
-CONFIG_USB_MON=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_GADGET=y
-CONFIG_USB_GADGET_M66592=y
-CONFIG_USB_FILE_STORAGE=m
-CONFIG_MMC=y
-CONFIG_MMC_DEBUG=y
-# CONFIG_MMC_BLOCK_BOUNCE is not set
-CONFIG_MMC_AT91=m
-CONFIG_NEW_LEDS=y
-CONFIG_LEDS_CLASS=y
-CONFIG_LEDS_GPIO=y
-CONFIG_LEDS_TRIGGERS=y
-CONFIG_LEDS_TRIGGER_TIMER=y
-CONFIG_LEDS_TRIGGER_HEARTBEAT=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_AT91RM9200=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT3_FS=y
-CONFIG_REISERFS_FS=y
-CONFIG_INOTIFY=y
-CONFIG_ISO9660_FS=y
-CONFIG_JOLIET=y
-CONFIG_ZISOFS=y
-CONFIG_UDF_FS=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_FS_DEBUG=1
-CONFIG_JFFS2_COMPRESSION_OPTIONS=y
-CONFIG_JFFS2_RUBIN=y
-CONFIG_CRAMFS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_MAC_PARTITION=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ISO8859_1=y
-# CONFIG_ENABLE_MUST_CHECK is not set
-CONFIG_DEBUG_FS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_SLUB_DEBUG_ON=y
-CONFIG_DEBUG_KOBJECT=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_LIST=y
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_ERRORS=y
-CONFIG_DEBUG_LL=y
index c09e357..bb96a7d 100644 (file)
@@ -911,7 +911,7 @@ __kuser_cmpxchg:                            @ 0xffff0fc0
         * A special ghost syscall is used for that (see traps.c).
         */
        stmfd   sp!, {r7, lr}
-       ldr     r7, =1f                 @ it's 20 bits
+       ldr     r7, 1f                  @ it's 20 bits
        swi     __ARM_NR_cmpxchg
        ldmfd   sp!, {r7, pc}
 1:     .word   __ARM_NR_cmpxchg
index dd6b369..6bd82d2 100644 (file)
@@ -85,9 +85,11 @@ ENTRY(stext)
        mrc     p15, 0, r9, c0, c0              @ get processor id
        bl      __lookup_processor_type         @ r5=procinfo r9=cpuid
        movs    r10, r5                         @ invalid processor (r5=0)?
+ THUMB( it     eq )            @ force fixup-able long branch encoding
        beq     __error_p                       @ yes, error 'p'
        bl      __lookup_machine_type           @ r5=machinfo
        movs    r8, r5                          @ invalid machine (r5=0)?
+ THUMB( it     eq )            @ force fixup-able long branch encoding
        beq     __error_a                       @ yes, error 'a'
        bl      __vet_atags
 #ifdef CONFIG_SMP_ON_UP
@@ -262,6 +264,7 @@ __create_page_tables:
        mov     pc, lr
 ENDPROC(__create_page_tables)
        .ltorg
+       .align
 __enable_mmu_loc:
        .long   .
        .long   __enable_mmu
@@ -282,6 +285,7 @@ ENTRY(secondary_startup)
        bl      __lookup_processor_type
        movs    r10, r5                         @ invalid processor?
        moveq   r0, #'p'                        @ yes, error 'p'
+ THUMB( it     eq )            @ force fixup-able long branch encoding
        beq     __error_p
 
        /*
@@ -308,6 +312,8 @@ ENTRY(__secondary_switched)
        b       secondary_start_kernel
 ENDPROC(__secondary_switched)
 
+       .align
+
        .type   __secondary_data, %object
 __secondary_data:
        .long   .
@@ -413,6 +419,7 @@ __fixup_smp_on_up:
        mov     pc, lr
 ENDPROC(__fixup_smp)
 
+       .align
 1:     .word   .
        .word   __smpalt_begin
        .word   __smpalt_end
index fd26f8d..9cf4cbf 100644 (file)
@@ -59,6 +59,8 @@ relocate_new_kernel:
        ldr r2,kexec_boot_atags
        mov pc,lr
 
+       .align
+
        .globl kexec_start_address
 kexec_start_address:
        .long   0x0
index 821eb84..d13add7 100644 (file)
@@ -24,8 +24,8 @@ obj-$(CONFIG_ARCH_AT91X40)    += at91x40.o at91x40_time.o
 
 # AT91RM9200 board-specific support
 obj-$(CONFIG_MACH_ONEARM)      += board-1arm.o
-obj-$(CONFIG_ARCH_AT91RM9200DK)        += board-dk.o
-obj-$(CONFIG_MACH_AT91RM9200EK)        += board-ek.o
+obj-$(CONFIG_ARCH_AT91RM9200DK)        += board-rm9200dk.o
+obj-$(CONFIG_MACH_AT91RM9200EK)        += board-rm9200ek.o
 obj-$(CONFIG_MACH_CSB337)      += board-csb337.o
 obj-$(CONFIG_MACH_CSB637)      += board-csb637.o
 obj-$(CONFIG_MACH_CARMEVA)     += board-carmeva.o
@@ -65,7 +65,7 @@ obj-$(CONFIG_MACH_AT91SAM9G20EK) += board-sam9g20ek.o
 obj-$(CONFIG_MACH_CPU9G20)     += board-cpu9krea.o
 obj-$(CONFIG_MACH_STAMP9G20)   += board-stamp9g20.o
 obj-$(CONFIG_MACH_PORTUXG20)   += board-stamp9g20.o
-obj-$(CONFIG_MACH_PCONTROL_G20)        += board-pcontrol-g20.o
+obj-$(CONFIG_MACH_PCONTROL_G20)        += board-pcontrol-g20.o board-stamp9g20.o
 
 # AT91SAM9260/AT91SAM9G20 board-specific support
 obj-$(CONFIG_MACH_SNAPPER_9260)        += board-snapper9260.o
index 9338825..7b53922 100644 (file)
@@ -1106,51 +1106,6 @@ static inline void configure_usart3_pins(unsigned pins)
 static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART];  /* the UARTs to use */
 struct platform_device *atmel_default_console_device;  /* the serial console device */
 
-void __init __deprecated at91_init_serial(struct at91_uart_config *config)
-{
-       int i;
-
-       /* Fill in list of supported UARTs */
-       for (i = 0; i < config->nr_tty; i++) {
-               switch (config->tty_map[i]) {
-                       case 0:
-                               configure_usart0_pins(ATMEL_UART_CTS | ATMEL_UART_RTS);
-                               at91_uarts[i] = &at91rm9200_uart0_device;
-                               at91_clock_associate("usart0_clk", &at91rm9200_uart0_device.dev, "usart");
-                               break;
-                       case 1:
-                               configure_usart1_pins(ATMEL_UART_CTS | ATMEL_UART_RTS | ATMEL_UART_DSR | ATMEL_UART_DTR | ATMEL_UART_DCD | ATMEL_UART_RI);
-                               at91_uarts[i] = &at91rm9200_uart1_device;
-                               at91_clock_associate("usart1_clk", &at91rm9200_uart1_device.dev, "usart");
-                               break;
-                       case 2:
-                               configure_usart2_pins(0);
-                               at91_uarts[i] = &at91rm9200_uart2_device;
-                               at91_clock_associate("usart2_clk", &at91rm9200_uart2_device.dev, "usart");
-                               break;
-                       case 3:
-                               configure_usart3_pins(0);
-                               at91_uarts[i] = &at91rm9200_uart3_device;
-                               at91_clock_associate("usart3_clk", &at91rm9200_uart3_device.dev, "usart");
-                               break;
-                       case 4:
-                               configure_dbgu_pins();
-                               at91_uarts[i] = &at91rm9200_dbgu_device;
-                               at91_clock_associate("mck", &at91rm9200_dbgu_device.dev, "usart");
-                               break;
-                       default:
-                               continue;
-               }
-               at91_uarts[i]->id = i;          /* update ID number to mapped ID */
-       }
-
-       /* Set serial console device */
-       if (config->console_tty < ATMEL_MAX_UART)
-               atmel_default_console_device = at91_uarts[config->console_tty];
-       if (!atmel_default_console_device)
-               printk(KERN_INFO "AT91: No default serial console defined.\n");
-}
-
 void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
 {
        struct platform_device *pdev;
index 46bdc82..8a3fc84 100644 (file)
 #include "generic.h"
 
 
-/*
- * Serial port configuration.
- *    0 .. 3 = USART0 .. USART3
- *    4      = DBGU
- */
-static struct at91_uart_config __initdata onearm_uart_config = {
-       .console_tty    = 0,                            /* ttyS0 */
-       .nr_tty         = 3,
-       .tty_map        = { 4, 0, 1, -1, -1 },          /* ttyS0, ..., ttyS4 */
-};
-
 static void __init onearm_map_io(void)
 {
        /* Initialize processor: 18.432 MHz crystal */
        at91rm9200_initialize(18432000, AT91RM9200_PQFP);
 
-       /* Setup the serial ports and console */
-       at91_init_serial(&onearm_uart_config);
+       /* DBGU on ttyS0. (Rx & Tx only) */
+       at91_register_uart(0, 0, 0);
+
+       /* USART0 on ttyS1 (Rx, Tx, CTS, RTS) */
+       at91_register_uart(AT91RM9200_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS);
+
+       /* USART1 on ttyS2 (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
+       at91_register_uart(AT91RM9200_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS
+                          | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD
+                          | ATMEL_UART_RI);
+
+       /* set serial console to ttyS0 (ie, DBGU) */
+       at91_set_serial_console(0);
 }
 
 static void __init onearm_init_irq(void)
diff --git a/arch/arm/mach-at91/board-dk.c b/arch/arm/mach-at91/board-dk.c
deleted file mode 100644 (file)
index e14f0e1..0000000
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * linux/arch/arm/mach-at91/board-dk.c
- *
- *  Copyright (C) 2005 SAN People
- *
- *  Epson S1D framebuffer glue code is:
- *     Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/spi/spi.h>
-#include <linux/mtd/physmap.h>
-
-#include <asm/setup.h>
-#include <asm/mach-types.h>
-#include <asm/irq.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/hardware.h>
-#include <mach/board.h>
-#include <mach/gpio.h>
-#include <mach/at91rm9200_mc.h>
-
-#include "generic.h"
-
-
-static void __init dk_map_io(void)
-{
-       /* Initialize processor: 18.432 MHz crystal */
-       at91rm9200_initialize(18432000, AT91RM9200_BGA);
-
-       /* Setup the LEDs */
-       at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2);
-
-       /* DBGU on ttyS0. (Rx & Tx only) */
-       at91_register_uart(0, 0, 0);
-
-       /* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
-       at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
-                          | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD
-                          | ATMEL_UART_RI);
-
-       /* set serial console to ttyS0 (ie, DBGU) */
-       at91_set_serial_console(0);
-}
-
-static void __init dk_init_irq(void)
-{
-       at91rm9200_init_interrupts(NULL);
-}
-
-static struct at91_eth_data __initdata dk_eth_data = {
-       .phy_irq_pin    = AT91_PIN_PC4,
-       .is_rmii        = 1,
-};
-
-static struct at91_usbh_data __initdata dk_usbh_data = {
-       .ports          = 2,
-};
-
-static struct at91_udc_data __initdata dk_udc_data = {
-       .vbus_pin       = AT91_PIN_PD4,
-       .pullup_pin     = AT91_PIN_PD5,
-};
-
-static struct at91_cf_data __initdata dk_cf_data = {
-       .det_pin        = AT91_PIN_PB0,
-       .rst_pin        = AT91_PIN_PC5,
-       // .irq_pin     = ... not connected
-       // .vcc_pin     = ... always powered
-};
-
-static struct at91_mmc_data __initdata dk_mmc_data = {
-       .slot_b         = 0,
-       .wire4          = 1,
-};
-
-static struct spi_board_info dk_spi_devices[] = {
-       {       /* DataFlash chip */
-               .modalias       = "mtd_dataflash",
-               .chip_select    = 0,
-               .max_speed_hz   = 15 * 1000 * 1000,
-       },
-       {       /* UR6HCPS2-SP40 PS2-to-SPI adapter */
-               .modalias       = "ur6hcps2",
-               .chip_select    = 1,
-               .max_speed_hz   = 250 *  1000,
-       },
-       {       /* TLV1504 ADC, 4 channels, 10 bits; one is a temp sensor */
-               .modalias       = "tlv1504",
-               .chip_select    = 2,
-               .max_speed_hz   = 20 * 1000 * 1000,
-       },
-#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
-       {       /* DataFlash card */
-               .modalias       = "mtd_dataflash",
-               .chip_select    = 3,
-               .max_speed_hz   = 15 * 1000 * 1000,
-       }
-#endif
-};
-
-static struct i2c_board_info __initdata dk_i2c_devices[] = {
-       {
-               I2C_BOARD_INFO("ics1523", 0x26),
-       },
-       {
-               I2C_BOARD_INFO("x9429", 0x28),
-       },
-       {
-               I2C_BOARD_INFO("24c1024", 0x50),
-       }
-};
-
-static struct mtd_partition __initdata dk_nand_partition[] = {
-       {
-               .name   = "NAND Partition 1",
-               .offset = 0,
-               .size   = MTDPART_SIZ_FULL,
-       },
-};
-
-static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
-{
-       *num_partitions = ARRAY_SIZE(dk_nand_partition);
-       return dk_nand_partition;
-}
-
-static struct atmel_nand_data __initdata dk_nand_data = {
-       .ale            = 22,
-       .cle            = 21,
-       .det_pin        = AT91_PIN_PB1,
-       .rdy_pin        = AT91_PIN_PC2,
-       // .enable_pin  = ... not there
-       .partition_info = nand_partitions,
-};
-
-#define DK_FLASH_BASE  AT91_CHIPSELECT_0
-#define DK_FLASH_SIZE  SZ_2M
-
-static struct physmap_flash_data dk_flash_data = {
-       .width          = 2,
-};
-
-static struct resource dk_flash_resource = {
-       .start          = DK_FLASH_BASE,
-       .end            = DK_FLASH_BASE + DK_FLASH_SIZE - 1,
-       .flags          = IORESOURCE_MEM,
-};
-
-static struct platform_device dk_flash = {
-       .name           = "physmap-flash",
-       .id             = 0,
-       .dev            = {
-                               .platform_data  = &dk_flash_data,
-                       },
-       .resource       = &dk_flash_resource,
-       .num_resources  = 1,
-};
-
-static struct gpio_led dk_leds[] = {
-       {
-               .name                   = "led0",
-               .gpio                   = AT91_PIN_PB2,
-               .active_low             = 1,
-               .default_trigger        = "heartbeat",
-       }
-};
-
-static void __init dk_board_init(void)
-{
-       /* Serial */
-       at91_add_device_serial();
-       /* Ethernet */
-       at91_add_device_eth(&dk_eth_data);
-       /* USB Host */
-       at91_add_device_usbh(&dk_usbh_data);
-       /* USB Device */
-       at91_add_device_udc(&dk_udc_data);
-       at91_set_multi_drive(dk_udc_data.pullup_pin, 1);        /* pullup_pin is connected to reset */
-       /* Compact Flash */
-       at91_add_device_cf(&dk_cf_data);
-       /* I2C */
-       at91_add_device_i2c(dk_i2c_devices, ARRAY_SIZE(dk_i2c_devices));
-       /* SPI */
-       at91_add_device_spi(dk_spi_devices, ARRAY_SIZE(dk_spi_devices));
-#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
-       /* DataFlash card */
-       at91_set_gpio_output(AT91_PIN_PB7, 0);
-#else
-       /* MMC */
-       at91_set_gpio_output(AT91_PIN_PB7, 1);  /* this MMC card slot can optionally use SPI signaling (CS3). */
-       at91_add_device_mmc(0, &dk_mmc_data);
-#endif
-       /* NAND */
-       at91_add_device_nand(&dk_nand_data);
-       /* NOR Flash */
-       platform_device_register(&dk_flash);
-       /* LEDs */
-       at91_gpio_leds(dk_leds, ARRAY_SIZE(dk_leds));
-       /* VGA */
-//     dk_add_device_video();
-}
-
-MACHINE_START(AT91RM9200DK, "Atmel AT91RM9200-DK")
-       /* Maintainer: SAN People/Atmel */
-       .boot_params    = AT91_SDRAM_BASE + 0x100,
-       .timer          = &at91rm9200_timer,
-       .map_io         = dk_map_io,
-       .init_irq       = dk_init_irq,
-       .init_machine   = dk_board_init,
-MACHINE_END
diff --git a/arch/arm/mach-at91/board-ek.c b/arch/arm/mach-at91/board-ek.c
deleted file mode 100644 (file)
index 56e92c4..0000000
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * linux/arch/arm/mach-at91/board-ek.c
- *
- *  Copyright (C) 2005 SAN People
- *
- *  Epson S1D framebuffer glue code is:
- *     Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/spi/spi.h>
-#include <linux/mtd/physmap.h>
-
-#include <asm/setup.h>
-#include <asm/mach-types.h>
-#include <asm/irq.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/hardware.h>
-#include <mach/board.h>
-#include <mach/gpio.h>
-#include <mach/at91rm9200_mc.h>
-
-#include "generic.h"
-
-
-static void __init ek_map_io(void)
-{
-       /* Initialize processor: 18.432 MHz crystal */
-       at91rm9200_initialize(18432000, AT91RM9200_BGA);
-
-       /* Setup the LEDs */
-       at91_init_leds(AT91_PIN_PB1, AT91_PIN_PB2);
-
-       /* DBGU on ttyS0. (Rx & Tx only) */
-       at91_register_uart(0, 0, 0);
-
-       /* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
-       at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
-                          | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD
-                          | ATMEL_UART_RI);
-
-       /* set serial console to ttyS0 (ie, DBGU) */
-       at91_set_serial_console(0);
-}
-
-static void __init ek_init_irq(void)
-{
-       at91rm9200_init_interrupts(NULL);
-}
-
-static struct at91_eth_data __initdata ek_eth_data = {
-       .phy_irq_pin    = AT91_PIN_PC4,
-       .is_rmii        = 1,
-};
-
-static struct at91_usbh_data __initdata ek_usbh_data = {
-       .ports          = 2,
-};
-
-static struct at91_udc_data __initdata ek_udc_data = {
-       .vbus_pin       = AT91_PIN_PD4,
-       .pullup_pin     = AT91_PIN_PD5,
-};
-
-static struct at91_mmc_data __initdata ek_mmc_data = {
-       .det_pin        = AT91_PIN_PB27,
-       .slot_b         = 0,
-       .wire4          = 1,
-       .wp_pin         = AT91_PIN_PA17,
-};
-
-static struct spi_board_info ek_spi_devices[] = {
-       {       /* DataFlash chip */
-               .modalias       = "mtd_dataflash",
-               .chip_select    = 0,
-               .max_speed_hz   = 15 * 1000 * 1000,
-       },
-#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
-       {       /* DataFlash card */
-               .modalias       = "mtd_dataflash",
-               .chip_select    = 3,
-               .max_speed_hz   = 15 * 1000 * 1000,
-       },
-#endif
-};
-
-static struct i2c_board_info __initdata ek_i2c_devices[] = {
-       {
-               I2C_BOARD_INFO("ics1523", 0x26),
-       },
-       {
-               I2C_BOARD_INFO("dac3550", 0x4d),
-       }
-};
-
-#define EK_FLASH_BASE  AT91_CHIPSELECT_0
-#define EK_FLASH_SIZE  SZ_2M
-
-static struct physmap_flash_data ek_flash_data = {
-       .width          = 2,
-};
-
-static struct resource ek_flash_resource = {
-       .start          = EK_FLASH_BASE,
-       .end            = EK_FLASH_BASE + EK_FLASH_SIZE - 1,
-       .flags          = IORESOURCE_MEM,
-};
-
-static struct platform_device ek_flash = {
-       .name           = "physmap-flash",
-       .id             = 0,
-       .dev            = {
-                               .platform_data  = &ek_flash_data,
-                       },
-       .resource       = &ek_flash_resource,
-       .num_resources  = 1,
-};
-
-static struct gpio_led ek_leds[] = {
-       {       /* "user led 1", DS2 */
-               .name                   = "green",
-               .gpio                   = AT91_PIN_PB0,
-               .active_low             = 1,
-               .default_trigger        = "mmc0",
-       },
-       {       /* "user led 2", DS4 */
-               .name                   = "yellow",
-               .gpio                   = AT91_PIN_PB1,
-               .active_low             = 1,
-               .default_trigger        = "heartbeat",
-       },
-       {       /* "user led 3", DS6 */
-               .name                   = "red",
-               .gpio                   = AT91_PIN_PB2,
-               .active_low             = 1,
-       }
-};
-
-static void __init ek_board_init(void)
-{
-       /* Serial */
-       at91_add_device_serial();
-       /* Ethernet */
-       at91_add_device_eth(&ek_eth_data);
-       /* USB Host */
-       at91_add_device_usbh(&ek_usbh_data);
-       /* USB Device */
-       at91_add_device_udc(&ek_udc_data);
-       at91_set_multi_drive(ek_udc_data.pullup_pin, 1);        /* pullup_pin is connected to reset */
-       /* I2C */
-       at91_add_device_i2c(ek_i2c_devices, ARRAY_SIZE(ek_i2c_devices));
-       /* SPI */
-       at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
-#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
-       /* DataFlash card */
-       at91_set_gpio_output(AT91_PIN_PB22, 0);
-#else
-       /* MMC */
-       at91_set_gpio_output(AT91_PIN_PB22, 1); /* this MMC card slot can optionally use SPI signaling (CS3). */
-       at91_add_device_mmc(0, &ek_mmc_data);
-#endif
-       /* NOR Flash */
-       platform_device_register(&ek_flash);
-       /* LEDs */
-       at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
-       /* VGA */
-//     ek_add_device_video();
-}
-
-MACHINE_START(AT91RM9200EK, "Atmel AT91RM9200-EK")
-       /* Maintainer: SAN People/Atmel */
-       .boot_params    = AT91_SDRAM_BASE + 0x100,
-       .timer          = &at91rm9200_timer,
-       .map_io         = ek_map_io,
-       .init_irq       = ek_init_irq,
-       .init_machine   = ek_board_init,
-MACHINE_END
index c0ce79d..d2e1f4e 100644 (file)
 #include "generic.h"
 
 
-/*
- * Serial port configuration.
- *    0 .. 3 = USART0 .. USART3
- *    4      = DBGU
- */
-static struct at91_uart_config __initdata kafa_uart_config = {
-       .console_tty    = 0,                            /* ttyS0 */
-       .nr_tty         = 2,
-       .tty_map        = { 4, 0, -1, -1, -1 }          /* ttyS0, ..., ttyS4 */
-};
-
 static void __init kafa_map_io(void)
 {
        /* Initialize processor: 18.432 MHz crystal */
@@ -58,8 +47,14 @@ static void __init kafa_map_io(void)
        /* Set up the LEDs */
        at91_init_leds(AT91_PIN_PB4, AT91_PIN_PB4);
 
-       /* Setup the serial ports and console */
-       at91_init_serial(&kafa_uart_config);
+       /* DBGU on ttyS0. (Rx & Tx only) */
+       at91_register_uart(0, 0, 0);
+
+       /* USART0 on ttyS1 (Rx, Tx, CTS, RTS) */
+       at91_register_uart(AT91RM9200_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS);
+
+       /* set serial console to ttyS0 (ie, DBGU) */
+       at91_set_serial_console(0);
 }
 
 static void __init kafa_init_irq(void)
index bba5a56..feb6578 100644 (file)
@@ -31,6 +31,7 @@
 
 #include <mach/board.h>
 #include <mach/at91sam9_smc.h>
+#include <mach/stamp9g20.h>
 
 #include "sam9_smc.h"
 #include "generic.h"
 
 static void __init pcontrol_g20_map_io(void)
 {
-       /* Initialize processor: 18.432 MHz crystal */
-       at91sam9260_initialize(18432000);
-
-       /* DGBU on ttyS0. (Rx, Tx) only TTL -> JTAG connector X7 17,19 ) */
-       at91_register_uart(0, 0, 0);
+       stamp9g20_map_io();
 
        /* USART0 on ttyS1. (Rx, Tx, CTS, RTS) piggyback  A2 */
        at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS
@@ -54,9 +51,6 @@ static void __init pcontrol_g20_map_io(void)
 
        /* USART2 on ttyS3. (Rx, Tx)  9bit-Bus  Multidrop-mode  X4 */
        at91_register_uart(AT91SAM9260_ID_US4, 3, 0);
-
-       /* set serial console to ttyS0 (ie, DBGU) */
-       at91_set_serial_console(0);
 }
 
 
@@ -66,38 +60,6 @@ static void __init init_irq(void)
 }
 
 
-/*
- * NAND flash 512MiB 1,8V 8-bit, sector size 128 KiB
- */
-static struct atmel_nand_data __initdata nand_data = {
-       .ale            = 21,
-       .cle            = 22,
-       .rdy_pin        = AT91_PIN_PC13,
-       .enable_pin     = AT91_PIN_PC14,
-};
-
-/*
- * Bus timings; unit = 7.57ns
- */
-static struct sam9_smc_config __initdata nand_smc_config = {
-       .ncs_read_setup         = 0,
-       .nrd_setup              = 2,
-       .ncs_write_setup        = 0,
-       .nwe_setup              = 2,
-
-       .ncs_read_pulse         = 4,
-       .nrd_pulse              = 4,
-       .ncs_write_pulse        = 4,
-       .nwe_pulse              = 4,
-
-       .read_cycle             = 7,
-       .write_cycle            = 7,
-
-       .mode                   = AT91_SMC_READMODE | AT91_SMC_WRITEMODE
-                       | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8,
-       .tdf_cycles             = 3,
-};
-
 static struct sam9_smc_config __initdata pcontrol_smc_config[2] = { {
        .ncs_read_setup         = 16,
        .nrd_setup              = 18,
@@ -138,14 +100,6 @@ static struct sam9_smc_config __initdata pcontrol_smc_config[2] = { {
        .tdf_cycles             = 1,
 } };
 
-static void __init add_device_nand(void)
-{
-       /* configure chip-select 3 (NAND) */
-       sam9_smc_configure(3, &nand_smc_config);
-       at91_add_device_nand(&nand_data);
-}
-
-
 static void __init add_device_pcontrol(void)
 {
        /* configure chip-select 4 (IO compatible to 8051  X4 ) */
@@ -155,23 +109,6 @@ static void __init add_device_pcontrol(void)
 }
 
 
-/*
- * MCI (SD/MMC)
- * det_pin, wp_pin and vcc_pin are not connected
- */
-#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
-static struct mci_platform_data __initdata mmc_data = {
-       .slot[0] = {
-               .bus_width      = 4,
-       },
-};
-#else
-static struct at91_mmc_data __initdata mmc_data = {
-       .wire4          = 1,
-};
-#endif
-
-
 /*
  * USB Host port
  */
@@ -265,42 +202,13 @@ static struct spi_board_info pcontrol_g20_spi_devices[] = {
 };
 
 
-/*
- * Dallas 1-Wire  DS2431
- */
-static struct w1_gpio_platform_data w1_gpio_pdata = {
-       .pin            = AT91_PIN_PA29,
-       .is_open_drain  = 1,
-};
-
-static struct platform_device w1_device = {
-       .name                   = "w1-gpio",
-       .id                     = -1,
-       .dev.platform_data      = &w1_gpio_pdata,
-};
-
-static void add_wire1(void)
-{
-       at91_set_GPIO_periph(w1_gpio_pdata.pin, 1);
-       at91_set_multi_drive(w1_gpio_pdata.pin, 1);
-       platform_device_register(&w1_device);
-}
-
-
 static void __init pcontrol_g20_board_init(void)
 {
-       at91_add_device_serial();
-       add_device_nand();
-#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
-       at91_add_device_mci(0, &mmc_data);
-#else
-       at91_add_device_mmc(0, &mmc_data);
-#endif
+       stamp9g20_board_init();
        at91_add_device_usbh(&usbh_data);
        at91_add_device_eth(&macb_data);
        at91_add_device_i2c(pcontrol_g20_i2c_devices,
                ARRAY_SIZE(pcontrol_g20_i2c_devices));
-       add_wire1();
        add_device_pcontrol();
        at91_add_device_spi(pcontrol_g20_spi_devices,
                ARRAY_SIZE(pcontrol_g20_spi_devices));
index 9d833bb..55dad3a 100644 (file)
 #include "generic.h"
 
 
-/*
- * Serial port configuration.
- *    0 .. 3 = USART0 .. USART3
- *    4      = DBGU
- */
-static struct at91_uart_config __initdata picotux200_uart_config = {
-       .console_tty    = 0,                            /* ttyS0 */
-       .nr_tty         = 2,
-       .tty_map        = { 4, 1, -1, -1, -1 }          /* ttyS0, ..., ttyS4 */
-};
-
 static void __init picotux200_map_io(void)
 {
        /* Initialize processor: 18.432 MHz crystal */
        at91rm9200_initialize(18432000, AT91RM9200_BGA);
 
-       /* Setup the serial ports and console */
-       at91_init_serial(&picotux200_uart_config);
+       /* DBGU on ttyS0. (Rx & Tx only) */
+       at91_register_uart(0, 0, 0);
+
+       /* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
+       at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
+                         | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD
+                         | ATMEL_UART_RI);
+
+       /* set serial console to ttyS0 (ie, DBGU) */
+       at91_set_serial_console(0);
 }
 
 static void __init picotux200_init_irq(void)
@@ -77,11 +74,6 @@ static struct at91_usbh_data __initdata picotux200_usbh_data = {
        .ports          = 1,
 };
 
-// static struct at91_udc_data __initdata picotux200_udc_data = {
-//     .vbus_pin       = AT91_PIN_PD4,
-//     .pullup_pin     = AT91_PIN_PD5,
-// };
-
 static struct at91_mmc_data __initdata picotux200_mmc_data = {
        .det_pin        = AT91_PIN_PB27,
        .slot_b         = 0,
@@ -89,21 +81,6 @@ static struct at91_mmc_data __initdata picotux200_mmc_data = {
        .wp_pin         = AT91_PIN_PA17,
 };
 
-// static struct spi_board_info picotux200_spi_devices[] = {
-//     {       /* DataFlash chip */
-//             .modalias       = "mtd_dataflash",
-//             .chip_select    = 0,
-//             .max_speed_hz   = 15 * 1000 * 1000,
-//     },
-// #ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
-//     {       /* DataFlash card */
-//             .modalias       = "mtd_dataflash",
-//             .chip_select    = 3,
-//             .max_speed_hz   = 15 * 1000 * 1000,
-//     },
-// #endif
-// };
-
 #define PICOTUX200_FLASH_BASE  AT91_CHIPSELECT_0
 #define PICOTUX200_FLASH_SIZE  SZ_4M
 
@@ -135,21 +112,11 @@ static void __init picotux200_board_init(void)
        at91_add_device_eth(&picotux200_eth_data);
        /* USB Host */
        at91_add_device_usbh(&picotux200_usbh_data);
-       /* USB Device */
-       // at91_add_device_udc(&picotux200_udc_data);
-       // at91_set_multi_drive(picotux200_udc_data.pullup_pin, 1);     /* pullup_pin is connected to reset */
        /* I2C */
        at91_add_device_i2c(NULL, 0);
-       /* SPI */
-       // at91_add_device_spi(picotux200_spi_devices, ARRAY_SIZE(picotux200_spi_devices));
-#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
-       /* DataFlash card */
-       at91_set_gpio_output(AT91_PIN_PB22, 0);
-#else
        /* MMC */
        at91_set_gpio_output(AT91_PIN_PB22, 1); /* this MMC card slot can optionally use SPI signaling (CS3). */
        at91_add_device_mmc(0, &picotux200_mmc_data);
-#endif
        /* NOR Flash */
        platform_device_register(&picotux200_flash);
 }
diff --git a/arch/arm/mach-at91/board-rm9200dk.c b/arch/arm/mach-at91/board-rm9200dk.c
new file mode 100644 (file)
index 0000000..4c1047c
--- /dev/null
@@ -0,0 +1,235 @@
+/*
+ * linux/arch/arm/mach-at91/board-rm9200dk.c
+ *
+ *  Copyright (C) 2005 SAN People
+ *
+ *  Epson S1D framebuffer glue code is:
+ *     Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/mtd/physmap.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/at91rm9200_mc.h>
+
+#include "generic.h"
+
+
+static void __init dk_map_io(void)
+{
+       /* Initialize processor: 18.432 MHz crystal */
+       at91rm9200_initialize(18432000, AT91RM9200_BGA);
+
+       /* Setup the LEDs */
+       at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2);
+
+       /* DBGU on ttyS0. (Rx & Tx only) */
+       at91_register_uart(0, 0, 0);
+
+       /* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
+       at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
+                          | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD
+                          | ATMEL_UART_RI);
+
+       /* set serial console to ttyS0 (ie, DBGU) */
+       at91_set_serial_console(0);
+}
+
+static void __init dk_init_irq(void)
+{
+       at91rm9200_init_interrupts(NULL);
+}
+
+static struct at91_eth_data __initdata dk_eth_data = {
+       .phy_irq_pin    = AT91_PIN_PC4,
+       .is_rmii        = 1,
+};
+
+static struct at91_usbh_data __initdata dk_usbh_data = {
+       .ports          = 2,
+};
+
+static struct at91_udc_data __initdata dk_udc_data = {
+       .vbus_pin       = AT91_PIN_PD4,
+       .pullup_pin     = AT91_PIN_PD5,
+};
+
+static struct at91_cf_data __initdata dk_cf_data = {
+       .det_pin        = AT91_PIN_PB0,
+       .rst_pin        = AT91_PIN_PC5,
+       // .irq_pin     = ... not connected
+       // .vcc_pin     = ... always powered
+};
+
+#ifndef CONFIG_MTD_AT91_DATAFLASH_CARD
+static struct at91_mmc_data __initdata dk_mmc_data = {
+       .slot_b         = 0,
+       .wire4          = 1,
+};
+#endif
+
+static struct spi_board_info dk_spi_devices[] = {
+       {       /* DataFlash chip */
+               .modalias       = "mtd_dataflash",
+               .chip_select    = 0,
+               .max_speed_hz   = 15 * 1000 * 1000,
+       },
+       {       /* UR6HCPS2-SP40 PS2-to-SPI adapter */
+               .modalias       = "ur6hcps2",
+               .chip_select    = 1,
+               .max_speed_hz   = 250 *  1000,
+       },
+       {       /* TLV1504 ADC, 4 channels, 10 bits; one is a temp sensor */
+               .modalias       = "tlv1504",
+               .chip_select    = 2,
+               .max_speed_hz   = 20 * 1000 * 1000,
+       },
+#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
+       {       /* DataFlash card */
+               .modalias       = "mtd_dataflash",
+               .chip_select    = 3,
+               .max_speed_hz   = 15 * 1000 * 1000,
+       }
+#endif
+};
+
+static struct i2c_board_info __initdata dk_i2c_devices[] = {
+       {
+               I2C_BOARD_INFO("ics1523", 0x26),
+       },
+       {
+               I2C_BOARD_INFO("x9429", 0x28),
+       },
+       {
+               I2C_BOARD_INFO("24c1024", 0x50),
+       }
+};
+
+static struct mtd_partition __initdata dk_nand_partition[] = {
+       {
+               .name   = "NAND Partition 1",
+               .offset = 0,
+               .size   = MTDPART_SIZ_FULL,
+       },
+};
+
+static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
+{
+       *num_partitions = ARRAY_SIZE(dk_nand_partition);
+       return dk_nand_partition;
+}
+
+static struct atmel_nand_data __initdata dk_nand_data = {
+       .ale            = 22,
+       .cle            = 21,
+       .det_pin        = AT91_PIN_PB1,
+       .rdy_pin        = AT91_PIN_PC2,
+       // .enable_pin  = ... not there
+       .partition_info = nand_partitions,
+};
+
+#define DK_FLASH_BASE  AT91_CHIPSELECT_0
+#define DK_FLASH_SIZE  SZ_2M
+
+static struct physmap_flash_data dk_flash_data = {
+       .width          = 2,
+};
+
+static struct resource dk_flash_resource = {
+       .start          = DK_FLASH_BASE,
+       .end            = DK_FLASH_BASE + DK_FLASH_SIZE - 1,
+       .flags          = IORESOURCE_MEM,
+};
+
+static struct platform_device dk_flash = {
+       .name           = "physmap-flash",
+       .id             = 0,
+       .dev            = {
+                               .platform_data  = &dk_flash_data,
+                       },
+       .resource       = &dk_flash_resource,
+       .num_resources  = 1,
+};
+
+static struct gpio_led dk_leds[] = {
+       {
+               .name                   = "led0",
+               .gpio                   = AT91_PIN_PB2,
+               .active_low             = 1,
+               .default_trigger        = "heartbeat",
+       }
+};
+
+static void __init dk_board_init(void)
+{
+       /* Serial */
+       at91_add_device_serial();
+       /* Ethernet */
+       at91_add_device_eth(&dk_eth_data);
+       /* USB Host */
+       at91_add_device_usbh(&dk_usbh_data);
+       /* USB Device */
+       at91_add_device_udc(&dk_udc_data);
+       at91_set_multi_drive(dk_udc_data.pullup_pin, 1);        /* pullup_pin is connected to reset */
+       /* Compact Flash */
+       at91_add_device_cf(&dk_cf_data);
+       /* I2C */
+       at91_add_device_i2c(dk_i2c_devices, ARRAY_SIZE(dk_i2c_devices));
+       /* SPI */
+       at91_add_device_spi(dk_spi_devices, ARRAY_SIZE(dk_spi_devices));
+#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
+       /* DataFlash card */
+       at91_set_gpio_output(AT91_PIN_PB7, 0);
+#else
+       /* MMC */
+       at91_set_gpio_output(AT91_PIN_PB7, 1);  /* this MMC card slot can optionally use SPI signaling (CS3). */
+       at91_add_device_mmc(0, &dk_mmc_data);
+#endif
+       /* NAND */
+       at91_add_device_nand(&dk_nand_data);
+       /* NOR Flash */
+       platform_device_register(&dk_flash);
+       /* LEDs */
+       at91_gpio_leds(dk_leds, ARRAY_SIZE(dk_leds));
+       /* VGA */
+//     dk_add_device_video();
+}
+
+MACHINE_START(AT91RM9200DK, "Atmel AT91RM9200-DK")
+       /* Maintainer: SAN People/Atmel */
+       .boot_params    = AT91_SDRAM_BASE + 0x100,
+       .timer          = &at91rm9200_timer,
+       .map_io         = dk_map_io,
+       .init_irq       = dk_init_irq,
+       .init_machine   = dk_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91/board-rm9200ek.c b/arch/arm/mach-at91/board-rm9200ek.c
new file mode 100644 (file)
index 0000000..9df1be8
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+ * linux/arch/arm/mach-at91/board-rm9200ek.c
+ *
+ *  Copyright (C) 2005 SAN People
+ *
+ *  Epson S1D framebuffer glue code is:
+ *     Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/mtd/physmap.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/at91rm9200_mc.h>
+
+#include "generic.h"
+
+
+static void __init ek_map_io(void)
+{
+       /* Initialize processor: 18.432 MHz crystal */
+       at91rm9200_initialize(18432000, AT91RM9200_BGA);
+
+       /* Setup the LEDs */
+       at91_init_leds(AT91_PIN_PB1, AT91_PIN_PB2);
+
+       /* DBGU on ttyS0. (Rx & Tx only) */
+       at91_register_uart(0, 0, 0);
+
+       /* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
+       at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
+                          | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD
+                          | ATMEL_UART_RI);
+
+       /* set serial console to ttyS0 (ie, DBGU) */
+       at91_set_serial_console(0);
+}
+
+static void __init ek_init_irq(void)
+{
+       at91rm9200_init_interrupts(NULL);
+}
+
+static struct at91_eth_data __initdata ek_eth_data = {
+       .phy_irq_pin    = AT91_PIN_PC4,
+       .is_rmii        = 1,
+};
+
+static struct at91_usbh_data __initdata ek_usbh_data = {
+       .ports          = 2,
+};
+
+static struct at91_udc_data __initdata ek_udc_data = {
+       .vbus_pin       = AT91_PIN_PD4,
+       .pullup_pin     = AT91_PIN_PD5,
+};
+
+#ifndef CONFIG_MTD_AT91_DATAFLASH_CARD
+static struct at91_mmc_data __initdata ek_mmc_data = {
+       .det_pin        = AT91_PIN_PB27,
+       .slot_b         = 0,
+       .wire4          = 1,
+       .wp_pin         = AT91_PIN_PA17,
+};
+#endif
+
+static struct spi_board_info ek_spi_devices[] = {
+       {       /* DataFlash chip */
+               .modalias       = "mtd_dataflash",
+               .chip_select    = 0,
+               .max_speed_hz   = 15 * 1000 * 1000,
+       },
+#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
+       {       /* DataFlash card */
+               .modalias       = "mtd_dataflash",
+               .chip_select    = 3,
+               .max_speed_hz   = 15 * 1000 * 1000,
+       },
+#endif
+};
+
+static struct i2c_board_info __initdata ek_i2c_devices[] = {
+       {
+               I2C_BOARD_INFO("ics1523", 0x26),
+       },
+       {
+               I2C_BOARD_INFO("dac3550", 0x4d),
+       }
+};
+
+#define EK_FLASH_BASE  AT91_CHIPSELECT_0
+#define EK_FLASH_SIZE  SZ_2M
+
+static struct physmap_flash_data ek_flash_data = {
+       .width          = 2,
+};
+
+static struct resource ek_flash_resource = {
+       .start          = EK_FLASH_BASE,
+       .end            = EK_FLASH_BASE + EK_FLASH_SIZE - 1,
+       .flags          = IORESOURCE_MEM,
+};
+
+static struct platform_device ek_flash = {
+       .name           = "physmap-flash",
+       .id             = 0,
+       .dev            = {
+                               .platform_data  = &ek_flash_data,
+                       },
+       .resource       = &ek_flash_resource,
+       .num_resources  = 1,
+};
+
+static struct gpio_led ek_leds[] = {
+       {       /* "user led 1", DS2 */
+               .name                   = "green",
+               .gpio                   = AT91_PIN_PB0,
+               .active_low             = 1,
+               .default_trigger        = "mmc0",
+       },
+       {       /* "user led 2", DS4 */
+               .name                   = "yellow",
+               .gpio                   = AT91_PIN_PB1,
+               .active_low             = 1,
+               .default_trigger        = "heartbeat",
+       },
+       {       /* "user led 3", DS6 */
+               .name                   = "red",
+               .gpio                   = AT91_PIN_PB2,
+               .active_low             = 1,
+       }
+};
+
+static void __init ek_board_init(void)
+{
+       /* Serial */
+       at91_add_device_serial();
+       /* Ethernet */
+       at91_add_device_eth(&ek_eth_data);
+       /* USB Host */
+       at91_add_device_usbh(&ek_usbh_data);
+       /* USB Device */
+       at91_add_device_udc(&ek_udc_data);
+       at91_set_multi_drive(ek_udc_data.pullup_pin, 1);        /* pullup_pin is connected to reset */
+       /* I2C */
+       at91_add_device_i2c(ek_i2c_devices, ARRAY_SIZE(ek_i2c_devices));
+       /* SPI */
+       at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
+#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
+       /* DataFlash card */
+       at91_set_gpio_output(AT91_PIN_PB22, 0);
+#else
+       /* MMC */
+       at91_set_gpio_output(AT91_PIN_PB22, 1); /* this MMC card slot can optionally use SPI signaling (CS3). */
+       at91_add_device_mmc(0, &ek_mmc_data);
+#endif
+       /* NOR Flash */
+       platform_device_register(&ek_flash);
+       /* LEDs */
+       at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
+       /* VGA */
+//     ek_add_device_video();
+}
+
+MACHINE_START(AT91RM9200EK, "Atmel AT91RM9200-EK")
+       /* Maintainer: SAN People/Atmel */
+       .boot_params    = AT91_SDRAM_BASE + 0x100,
+       .timer          = &at91rm9200_timer,
+       .map_io         = ek_map_io,
+       .init_irq       = ek_init_irq,
+       .init_machine   = ek_board_init,
+MACHINE_END
index 5206eef..f8902b1 100644 (file)
@@ -32,7 +32,7 @@
 #include "generic.h"
 
 
-static void __init portuxg20_map_io(void)
+void __init stamp9g20_map_io(void)
 {
        /* Initialize processor: 18.432 MHz crystal */
        at91sam9260_initialize(18432000);
@@ -40,6 +40,24 @@ static void __init portuxg20_map_io(void)
        /* DGBU on ttyS0. (Rx & Tx only) */
        at91_register_uart(0, 0, 0);
 
+       /* set serial console to ttyS0 (ie, DBGU) */
+       at91_set_serial_console(0);
+}
+
+static void __init stamp9g20evb_map_io(void)
+{
+       stamp9g20_map_io();
+
+       /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
+       at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
+                                               | ATMEL_UART_DTR | ATMEL_UART_DSR
+                                               | ATMEL_UART_DCD | ATMEL_UART_RI);
+}
+
+static void __init portuxg20_map_io(void)
+{
+       stamp9g20_map_io();
+
        /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
        at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
                                                | ATMEL_UART_DTR | ATMEL_UART_DSR
@@ -56,26 +74,6 @@ static void __init portuxg20_map_io(void)
 
        /* USART5 on ttyS6. (Rx, Tx only) */
        at91_register_uart(AT91SAM9260_ID_US5, 6, 0);
-
-       /* set serial console to ttyS0 (ie, DBGU) */
-       at91_set_serial_console(0);
-}
-
-static void __init stamp9g20_map_io(void)
-{
-       /* Initialize processor: 18.432 MHz crystal */
-       at91sam9260_initialize(18432000);
-
-       /* DGBU on ttyS0. (Rx & Tx only) */
-       at91_register_uart(0, 0, 0);
-
-       /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
-       at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
-                                               | ATMEL_UART_DTR | ATMEL_UART_DSR
-                                               | ATMEL_UART_DCD | ATMEL_UART_RI);
-
-       /* set serial console to ttyS0 (ie, DBGU) */
-       at91_set_serial_console(0);
 }
 
 static void __init init_irq(void)
@@ -156,7 +154,7 @@ static struct at91_udc_data __initdata portuxg20_udc_data = {
        .pullup_pin     = 0,            /* pull-up driven by UDC */
 };
 
-static struct at91_udc_data __initdata stamp9g20_udc_data = {
+static struct at91_udc_data __initdata stamp9g20evb_udc_data = {
        .vbus_pin       = AT91_PIN_PA22,
        .pullup_pin     = 0,            /* pull-up driven by UDC */
 };
@@ -190,7 +188,7 @@ static struct gpio_led portuxg20_leds[] = {
        }
 };
 
-static struct gpio_led stamp9g20_leds[] = {
+static struct gpio_led stamp9g20evb_leds[] = {
        {
                .name                   = "D8",
                .gpio                   = AT91_PIN_PB18,
@@ -250,7 +248,7 @@ void add_w1(void)
 }
 
 
-static void __init generic_board_init(void)
+void __init stamp9g20_board_init(void)
 {
        /* Serial */
        at91_add_device_serial();
@@ -262,34 +260,40 @@ static void __init generic_board_init(void)
 #else
        at91_add_device_mmc(0, &mmc_data);
 #endif
-       /* USB Host */
-       at91_add_device_usbh(&usbh_data);
-       /* Ethernet */
-       at91_add_device_eth(&macb_data);
-       /* I2C */
-       at91_add_device_i2c(NULL, 0);
        /* W1 */
        add_w1();
 }
 
 static void __init portuxg20_board_init(void)
 {
-       generic_board_init();
-       /* SPI */
-       at91_add_device_spi(portuxg20_spi_devices, ARRAY_SIZE(portuxg20_spi_devices));
+       stamp9g20_board_init();
+       /* USB Host */
+       at91_add_device_usbh(&usbh_data);
        /* USB Device */
        at91_add_device_udc(&portuxg20_udc_data);
+       /* Ethernet */
+       at91_add_device_eth(&macb_data);
+       /* I2C */
+       at91_add_device_i2c(NULL, 0);
+       /* SPI */
+       at91_add_device_spi(portuxg20_spi_devices, ARRAY_SIZE(portuxg20_spi_devices));
        /* LEDs */
        at91_gpio_leds(portuxg20_leds, ARRAY_SIZE(portuxg20_leds));
 }
 
-static void __init stamp9g20_board_init(void)
+static void __init stamp9g20evb_board_init(void)
 {
-       generic_board_init();
+       stamp9g20_board_init();
+       /* USB Host */
+       at91_add_device_usbh(&usbh_data);
        /* USB Device */
-       at91_add_device_udc(&stamp9g20_udc_data);
+       at91_add_device_udc(&stamp9g20evb_udc_data);
+       /* Ethernet */
+       at91_add_device_eth(&macb_data);
+       /* I2C */
+       at91_add_device_i2c(NULL, 0);
        /* LEDs */
-       at91_gpio_leds(stamp9g20_leds, ARRAY_SIZE(stamp9g20_leds));
+       at91_gpio_leds(stamp9g20evb_leds, ARRAY_SIZE(stamp9g20evb_leds));
 }
 
 MACHINE_START(PORTUXG20, "taskit PortuxG20")
@@ -305,7 +309,7 @@ MACHINE_START(STAMP9G20, "taskit Stamp9G20")
        /* Maintainer: taskit GmbH */
        .boot_params    = AT91_SDRAM_BASE + 0x100,
        .timer          = &at91sam926x_timer,
-       .map_io         = stamp9g20_map_io,
+       .map_io         = stamp9g20evb_map_io,
        .init_irq       = init_irq,
-       .init_machine   = stamp9g20_board_init,
+       .init_machine   = stamp9g20evb_board_init,
 MACHINE_END
index 89df00a..e0f0080 100644 (file)
@@ -387,7 +387,7 @@ static struct spi_board_info yl9200_spi_devices[] = {
  * EPSON S1D13806 FB (discontinued chip)
  * EPSON S1D13506 FB
  */
-#if defined(CONFIG_FB_S1D135XX) || defined(CONFIG_FB_S1D13XXX_MODULE)
+#if defined(CONFIG_FB_S1D13XXX) || defined(CONFIG_FB_S1D13XXX_MODULE)
 #include <video/s1d13xxxfb.h>
 
 
index 7525cee..9113da6 100644 (file)
@@ -658,7 +658,7 @@ static void __init at91_upll_usbfs_clock_init(unsigned long main_clock)
        /* Now set uhpck values */
        uhpck.parent = &utmi_clk;
        uhpck.pmc_mask = AT91SAM926x_PMC_UHP;
-       uhpck.rate_hz = utmi_clk.parent->rate_hz;
+       uhpck.rate_hz = utmi_clk.rate_hz;
        uhpck.rate_hz /= 1 + ((at91_sys_read(AT91_PMC_USB) & AT91_PMC_OHCIUSBDIV) >> 8);
 }
 
index 58528aa..2b499eb 100644 (file)
@@ -137,13 +137,7 @@ extern void __init at91_add_device_spi(struct spi_board_info *devices, int nr_de
 extern void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins);
 extern void __init at91_set_serial_console(unsigned portnr);
 
-struct at91_uart_config {
-       unsigned short  console_tty;    /* tty number of serial console */
-       unsigned short  nr_tty;         /* number of serial tty's */
-       short           tty_map[];      /* map UART to tty number */
-};
 extern struct platform_device *atmel_default_console_device;
-extern void __init __deprecated at91_init_serial(struct at91_uart_config *config);
 
 struct atmel_uart_data {
        short                   use_dma_tx;     /* use transmit DMA? */
diff --git a/arch/arm/mach-at91/include/mach/stamp9g20.h b/arch/arm/mach-at91/include/mach/stamp9g20.h
new file mode 100644 (file)
index 0000000..6120f9c
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef __MACH_STAMP9G20_H
+#define __MACH_STAMP9G20_H
+
+void stamp9g20_map_io(void);
+void stamp9g20_board_init(void);
+
+#endif
index 38088c3..78defd7 100644 (file)
@@ -369,7 +369,7 @@ static int __init cns3xxx_pcie_init(void)
 {
        int i;
 
-       hook_fault_code(16 + 6, cns3xxx_pcie_abort_handler, SIGBUS,
+       hook_fault_code(16 + 6, cns3xxx_pcie_abort_handler, SIGBUS, 0,
                        "imprecise external abort");
 
        for (i = 0; i < ARRAY_SIZE(cns3xxx_pcie); i++) {
index daf3993..2e3dd08 100644 (file)
@@ -126,7 +126,6 @@ static APBC_CLK(twsi3, MMP2_TWSI3, 0, 26000000);
 static APBC_CLK(twsi4, MMP2_TWSI4, 0, 26000000);
 static APBC_CLK(twsi5, MMP2_TWSI5, 0, 26000000);
 static APBC_CLK(twsi6, MMP2_TWSI6, 0, 26000000);
-static APBC_CLK(rtc, MMP2_RTC, 0, 32768);
 
 static APMU_CLK(nand, NAND, 0xbf, 100000000);
 
index 86c9b21..9db9203 100644 (file)
@@ -216,7 +216,7 @@ static struct omap2_hsmmc_info mmc[] __initdata = {
        {
                .name           = "wl1271",
                .mmc            = 3,
-               .caps           = MMC_CAP_4_BIT_DATA,
+               .caps           = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD,
                .gpio_wp        = -EINVAL,
                .gpio_cd        = -EINVAL,
                .nonremovable   = true,
index 40562dd..a1939b1 100644 (file)
@@ -297,7 +297,7 @@ static int __init _omap2_init_reprogram_sdrc(void)
                return 0;
 
        dpll3_m2_ck = clk_get(NULL, "dpll3_m2_ck");
-       if (!dpll3_m2_ck)
+       if (IS_ERR(dpll3_m2_ck))
                return -EINVAL;
 
        rate = clk_get_rate(dpll3_m2_ck);
index 5e81517..a8afb61 100644 (file)
@@ -161,6 +161,23 @@ void omap2_pm_dump(int mode, int resume, unsigned int us)
                printk(KERN_INFO "%-20s: 0x%08x\n", regs[i].name, regs[i].val);
 }
 
+void omap2_pm_wakeup_on_timer(u32 seconds, u32 milliseconds)
+{
+       u32 tick_rate, cycles;
+
+       if (!seconds && !milliseconds)
+               return;
+
+       tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer_wakeup));
+       cycles = tick_rate * seconds + tick_rate * milliseconds / 1000;
+       omap_dm_timer_stop(gptimer_wakeup);
+       omap_dm_timer_set_load_start(gptimer_wakeup, 0, 0xffffffff - cycles);
+
+       pr_info("PM: Resume timer in %u.%03u secs"
+               " (%d ticks at %d ticks/sec.)\n",
+               seconds, milliseconds, cycles, tick_rate);
+}
+
 #ifdef CONFIG_DEBUG_FS
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
@@ -354,23 +371,6 @@ void pm_dbg_update_time(struct powerdomain *pwrdm, int prev)
        pwrdm->timer = t;
 }
 
-void omap2_pm_wakeup_on_timer(u32 seconds, u32 milliseconds)
-{
-       u32 tick_rate, cycles;
-
-       if (!seconds && !milliseconds)
-               return;
-
-       tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer_wakeup));
-       cycles = tick_rate * seconds + tick_rate * milliseconds / 1000;
-       omap_dm_timer_stop(gptimer_wakeup);
-       omap_dm_timer_set_load_start(gptimer_wakeup, 0, 0xffffffff - cycles);
-
-       pr_info("PM: Resume timer in %u.%03u secs"
-               " (%d ticks at %d ticks/sec.)\n",
-               seconds, milliseconds, cycles, tick_rate);
-}
-
 static int clkdm_dbg_show_counter(struct clockdomain *clkdm, void *user)
 {
        struct seq_file *s = (struct seq_file *)user;
index a40457d..aaeea49 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/irq.h>
 #include <linux/time.h>
 #include <linux/gpio.h>
+#include <linux/console.h>
 
 #include <asm/mach/time.h>
 #include <asm/mach/irq.h>
 #include <plat/powerdomain.h>
 #include <plat/clockdomain.h>
 
+#ifdef CONFIG_SUSPEND
+static suspend_state_t suspend_state = PM_SUSPEND_ON;
+static inline bool is_suspending(void)
+{
+       return (suspend_state != PM_SUSPEND_ON);
+}
+#else
+static inline bool is_suspending(void)
+{
+       return false;
+}
+#endif
+
 static void (*omap2_sram_idle)(void);
 static void (*omap2_sram_suspend)(u32 dllctrl, void __iomem *sdrc_dlla_ctrl,
                                  void __iomem *sdrc_power);
@@ -118,6 +132,11 @@ static void omap2_enter_full_retention(void)
        if (omap_irq_pending())
                goto no_sleep;
 
+       /* Block console output in case it is on one of the OMAP UARTs */
+       if (!is_suspending())
+               if (try_acquire_console_sem())
+                       goto no_sleep;
+
        omap_uart_prepare_idle(0);
        omap_uart_prepare_idle(1);
        omap_uart_prepare_idle(2);
@@ -131,6 +150,9 @@ static void omap2_enter_full_retention(void)
        omap_uart_resume_idle(1);
        omap_uart_resume_idle(0);
 
+       if (!is_suspending())
+               release_console_sem();
+
 no_sleep:
        if (omap2_pm_debug) {
                unsigned long long tmp;
@@ -277,6 +299,12 @@ out:
        local_irq_enable();
 }
 
+static int omap2_pm_begin(suspend_state_t state)
+{
+       suspend_state = state;
+       return 0;
+}
+
 static int omap2_pm_prepare(void)
 {
        /* We cannot sleep in idle until we have resumed */
@@ -326,10 +354,17 @@ static void omap2_pm_finish(void)
        enable_hlt();
 }
 
+static void omap2_pm_end(void)
+{
+       suspend_state = PM_SUSPEND_ON;
+}
+
 static struct platform_suspend_ops omap_pm_ops = {
+       .begin          = omap2_pm_begin,
        .prepare        = omap2_pm_prepare,
        .enter          = omap2_pm_enter,
        .finish         = omap2_pm_finish,
+       .end            = omap2_pm_end,
        .valid          = suspend_valid_only_mem,
 };
 
index 75c0cd1..648b8c5 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
+#include <linux/console.h>
 
 #include <plat/sram.h>
 #include <plat/clockdomain.h>
 #include "sdrc.h"
 #include "control.h"
 
+#ifdef CONFIG_SUSPEND
+static suspend_state_t suspend_state = PM_SUSPEND_ON;
+static inline bool is_suspending(void)
+{
+       return (suspend_state != PM_SUSPEND_ON);
+}
+#else
+static inline bool is_suspending(void)
+{
+       return false;
+}
+#endif
+
 /* Scratchpad offsets */
 #define OMAP343X_TABLE_ADDRESS_OFFSET     0xc4
 #define OMAP343X_TABLE_VALUE_OFFSET       0xc0
@@ -385,6 +399,13 @@ void omap_sram_idle(void)
                omap3_enable_io_chain();
        }
 
+       /* Block console output in case it is on one of the OMAP UARTs */
+       if (!is_suspending())
+               if (per_next_state < PWRDM_POWER_ON ||
+                   core_next_state < PWRDM_POWER_ON)
+                       if (try_acquire_console_sem())
+                               goto console_still_active;
+
        /* PER */
        if (per_next_state < PWRDM_POWER_ON) {
                omap_uart_prepare_idle(2);
@@ -463,6 +484,10 @@ void omap_sram_idle(void)
                omap_uart_resume_idle(3);
        }
 
+       if (!is_suspending())
+               release_console_sem();
+
+console_still_active:
        /* Disable IO-PAD and IO-CHAIN wakeup */
        if (omap3_has_io_wakeup() &&
            (per_next_state < PWRDM_POWER_ON ||
@@ -504,8 +529,6 @@ out:
 }
 
 #ifdef CONFIG_SUSPEND
-static suspend_state_t suspend_state;
-
 static int omap3_pm_prepare(void)
 {
        disable_hlt();
index 298a22a..f81acee 100644 (file)
 #define OMAP24XX_EN_GPT1_MASK                          (1 << 0)
 
 /* PM_WKST_WKUP, CM_IDLEST_WKUP shared bits */
-#define OMAP24XX_ST_GPIOS_SHIFT                                (1 << 2)
-#define OMAP24XX_ST_GPIOS_MASK                         2
-#define OMAP24XX_ST_GPT1_SHIFT                         (1 << 0)
-#define OMAP24XX_ST_GPT1_MASK                          0
+#define OMAP24XX_ST_GPIOS_SHIFT                                2
+#define OMAP24XX_ST_GPIOS_MASK                         (1 << 2)
+#define OMAP24XX_ST_GPT1_SHIFT                         0
+#define OMAP24XX_ST_GPT1_MASK                          (1 << 0)
 
 /* CM_IDLEST_MDM and PM_WKST_MDM shared bits */
-#define OMAP2430_ST_MDM_SHIFT                          (1 << 0)
+#define OMAP2430_ST_MDM_SHIFT                          0
+#define OMAP2430_ST_MDM_MASK                           (1 << 0)
 
 
 /* 3430 register bits shared between CM & PRM registers */
index becf0e3..d17960a 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/slab.h>
 #include <linux/serial_8250.h>
 #include <linux/pm_runtime.h>
+#include <linux/console.h>
 
 #ifdef CONFIG_SERIAL_OMAP
 #include <plat/omap-serial.h>
@@ -406,7 +407,7 @@ void omap_uart_resume_idle(int num)
        struct omap_uart_state *uart;
 
        list_for_each_entry(uart, &uart_list, node) {
-               if (num == uart->num) {
+               if (num == uart->num && uart->can_sleep) {
                        omap_uart_enable_clocks(uart);
 
                        /* Check for IO pad wakeup */
@@ -807,6 +808,8 @@ void __init omap_serial_init_port(int port)
 
        oh->dev_attr = uart;
 
+       acquire_console_sem(); /* in case the earlycon is on the UART */
+
        /*
         * Because of early UART probing, UART did not get idled
         * on init.  Now that omap_device is ready, ensure full idle
@@ -831,6 +834,8 @@ void __init omap_serial_init_port(int port)
        omap_uart_block_sleep(uart);
        uart->timeout = DEFAULT_TIMEOUT;
 
+       release_console_sem();
+
        if ((cpu_is_omap34xx() && uart->padconf) ||
            (uart->wk_en && uart->wk_mask)) {
                device_init_wakeup(&od->pdev.dev, true);
index d2060a1..e5c9932 100644 (file)
@@ -241,7 +241,8 @@ static inline void palmtx_keys_init(void) {}
 /******************************************************************************
  * NAND Flash
  ******************************************************************************/
-#if defined(CONFIG_MTD_NAND_GPIO) || defined(CONFIG_MTD_NAND_GPIO_MODULE)
+#if defined(CONFIG_MTD_NAND_PLATFORM) || \
+       defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
 static void palmtx_nand_cmd_ctl(struct mtd_info *mtd, int cmd,
                                 unsigned int ctrl)
 {
index 4075473..b34be45 100644 (file)
@@ -35,5 +35,6 @@ pen:  ldr     r7, [r6]
         */
        b       secondary_startup
 
+       .align
 1:     .long   .
        .long   pen_release
index cef6a65..fa2e5bf 100644 (file)
@@ -16,7 +16,7 @@ config CPU_S3C2412
 config CPU_S3C2412_ONLY
        bool
        depends on ARCH_S3C2410 && !CPU_S3C2400 && !CPU_S3C2410 && \
-                  !CPU_2416 && !CPU_S3C2440 && !CPU_S3C2442 && \
+                  !CPU_S3C2416 && !CPU_S3C2440 && !CPU_S3C2442 && \
                   !CPU_S3C2443 && CPU_S3C2412
        default y if CPU_S3C2412
 
index 87b9c9f..27b3e7c 100644 (file)
@@ -35,9 +35,12 @@ menu "S3C2416 Machines"
 config MACH_SMDK2416
        bool "SMDK2416"
        select CPU_S3C2416
+       select MACH_SMDK
        select S3C_DEV_FB
        select S3C_DEV_HSMMC
        select S3C_DEV_HSMMC1
+       select S3C_DEV_NAND
+       select S3C_DEV_USB_HOST
        select S3C2416_PM if PM
        help
          Say Y here if you are using an SMDK2416
index ff024a6..a0cb258 100644 (file)
@@ -18,6 +18,7 @@ config CPU_S3C2440
 config CPU_S3C2442
        bool
        select CPU_ARM920T
+       select S3C_GPIO_PULL_DOWN
        select S3C2410_CLOCK
        select S3C2410_GPIO
        select S3C2410_PM if PM
@@ -178,6 +179,9 @@ config MACH_MINI2440
        bool "MINI2440 development board"
        select CPU_S3C2440
        select EEPROM_AT24
+       select NEW_LEDS
+       select LEDS_CLASS
+       select LEDS_TRIGGER
        select LEDS_TRIGGER_BACKLIGHT
        select S3C_DEV_NAND
        select S3C_DEV_USB_HOST
index d50f3ae..f7663f7 100644 (file)
@@ -46,9 +46,6 @@ int __init s3c2440_init(void)
 {
        printk("S3C2440: Initialising architecture\n");
 
-       s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_1up;
-       s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_1up;
-
        /* change irq for watchdog */
 
        s3c_device_wdt.resource[1].start = IRQ_S3C2440_WDT;
@@ -58,3 +55,11 @@ int __init s3c2440_init(void)
 
        return sysdev_register(&s3c2440_sysdev);
 }
+
+void __init s3c2440_map_io(void)
+{
+       s3c244x_map_io();
+
+       s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_1up;
+       s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_1up;
+}
index 188ad1e..ecf8135 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/mutex.h>
+#include <linux/gpio.h>
 #include <linux/clk.h>
 #include <linux/io.h>
 
 
 #include <plat/clock.h>
 #include <plat/cpu.h>
+#include <plat/s3c244x.h>
+
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
 
 /* S3C2442 extended clock support */
 
@@ -163,3 +169,11 @@ int __init s3c2442_init(void)
 
        return sysdev_register(&s3c2442_sysdev);
 }
+
+void __init s3c2442_map_io(void)
+{
+       s3c244x_map_io();
+
+       s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_1down;
+       s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_1down;
+}
index 4fef723..31babec 100644 (file)
@@ -5,6 +5,7 @@
 config CPU_S3C2443
        bool
        depends on ARCH_S3C2410
+       select CPU_ARM920T
        select S3C2443_DMA if S3C2410_DMA
        select CPU_LLSERIAL_S3C2440
        select SAMSUNG_CLKSRC
index 8ea3bff..a0e7c12 100644 (file)
@@ -21,8 +21,8 @@
 #include <mach/io.h>
 
        .macro  addruart, rp, rv
-        ldreq   \rp, =IO_APB_PHYS       @ physical
-        ldrne   \rv, =IO_APB_VIRT        @ virtual
+        ldr     \rp, =IO_APB_PHYS       @ physical
+        ldr     \rv, =IO_APB_VIRT        @ virtual
 #if defined(CONFIG_TEGRA_DEBUG_UART_NONE)
 #error "A debug UART must be selected in the kernel config to use DEBUG_LL"
 #elif defined(CONFIG_TEGRA_DEBUG_UARTA)
index 8a78ff6..7a3f063 100644 (file)
@@ -35,5 +35,6 @@ pen:  ldr     r7, [r6]
         */
        b       secondary_startup
 
+       .align
 1:     .long   .
        .long   pen_release
index 99fa688..c96fa1b 100644 (file)
@@ -203,6 +203,10 @@ ENTRY(v6_flush_kern_dcache_area)
  *     - end     - virtual end address of region
  */
 v6_dma_inv_range:
+#ifdef CONFIG_DMA_CACHE_RWFO
+       ldrb    r2, [r0]                        @ read for ownership
+       strb    r2, [r0]                        @ write for ownership
+#endif
        tst     r0, #D_CACHE_LINE_SIZE - 1
        bic     r0, r0, #D_CACHE_LINE_SIZE - 1
 #ifdef HARVARD_CACHE
@@ -211,6 +215,10 @@ v6_dma_inv_range:
        mcrne   p15, 0, r0, c7, c11, 1          @ clean unified line
 #endif
        tst     r1, #D_CACHE_LINE_SIZE - 1
+#ifdef CONFIG_DMA_CACHE_RWFO
+       ldrneb  r2, [r1, #-1]                   @ read for ownership
+       strneb  r2, [r1, #-1]                   @ write for ownership
+#endif
        bic     r1, r1, #D_CACHE_LINE_SIZE - 1
 #ifdef HARVARD_CACHE
        mcrne   p15, 0, r1, c7, c14, 1          @ clean & invalidate D line
@@ -218,10 +226,6 @@ v6_dma_inv_range:
        mcrne   p15, 0, r1, c7, c15, 1          @ clean & invalidate unified line
 #endif
 1:
-#ifdef CONFIG_DMA_CACHE_RWFO
-       ldr     r2, [r0]                        @ read for ownership
-       str     r2, [r0]                        @ write for ownership
-#endif
 #ifdef HARVARD_CACHE
        mcr     p15, 0, r0, c7, c6, 1           @ invalidate D line
 #else
@@ -229,6 +233,10 @@ v6_dma_inv_range:
 #endif
        add     r0, r0, #D_CACHE_LINE_SIZE
        cmp     r0, r1
+#ifdef CONFIG_DMA_CACHE_RWFO
+       ldrlo   r2, [r0]                        @ read for ownership
+       strlo   r2, [r0]                        @ write for ownership
+#endif
        blo     1b
        mov     r0, #0
        mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer
@@ -263,12 +271,12 @@ v6_dma_clean_range:
  *     - end     - virtual end address of region
  */
 ENTRY(v6_dma_flush_range)
-       bic     r0, r0, #D_CACHE_LINE_SIZE - 1
-1:
 #ifdef CONFIG_DMA_CACHE_RWFO
-       ldr     r2, [r0]                        @ read for ownership
-       str     r2, [r0]                        @ write for ownership
+       ldrb    r2, [r0]                @ read for ownership
+       strb    r2, [r0]                @ write for ownership
 #endif
+       bic     r0, r0, #D_CACHE_LINE_SIZE - 1
+1:
 #ifdef HARVARD_CACHE
        mcr     p15, 0, r0, c7, c14, 1          @ clean & invalidate D line
 #else
@@ -276,6 +284,10 @@ ENTRY(v6_dma_flush_range)
 #endif
        add     r0, r0, #D_CACHE_LINE_SIZE
        cmp     r0, r1
+#ifdef CONFIG_DMA_CACHE_RWFO
+       ldrlob  r2, [r0]                        @ read for ownership
+       strlob  r2, [r0]                        @ write for ownership
+#endif
        blo     1b
        mov     r0, #0
        mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer
index a3ebf7a..6136e68 100644 (file)
@@ -173,15 +173,22 @@ ENTRY(v7_coherent_user_range)
  UNWIND(.fnstart               )
        dcache_line_size r2, r3
        sub     r3, r2, #1
-       bic     r0, r0, r3
+       bic     r12, r0, r3
 1:
- USER( mcr     p15, 0, r0, c7, c11, 1  )       @ clean D line to the point of unification
+ USER( mcr     p15, 0, r12, c7, c11, 1 )       @ clean D line to the point of unification
+       add     r12, r12, r2
+       cmp     r12, r1
+       blo     1b
        dsb
- USER( mcr     p15, 0, r0, c7, c5, 1   )       @ invalidate I line
-       add     r0, r0, r2
+       icache_line_size r2, r3
+       sub     r3, r2, #1
+       bic     r12, r0, r3
 2:
-       cmp     r0, r1
-       blo     1b
+ USER( mcr     p15, 0, r12, c7, c5, 1  )       @ invalidate I line
+       add     r12, r12, r2
+       cmp     r12, r1
+       blo     2b
+3:
        mov     r0, #0
        ALT_SMP(mcr     p15, 0, r0, c7, c1, 6)  @ invalidate BTB Inner Shareable
        ALT_UP(mcr      p15, 0, r0, c7, c5, 6)  @ invalidate BTB
@@ -194,10 +201,10 @@ ENTRY(v7_coherent_user_range)
  * isn't mapped, just try the next page.
  */
 9001:
-       mov     r0, r0, lsr #12
-       mov     r0, r0, lsl #12
-       add     r0, r0, #4096
-       b       2b
+       mov     r12, r12, lsr #12
+       mov     r12, r12, lsl #12
+       add     r12, r12, #4096
+       b       3b
  UNWIND(.fnend         )
 ENDPROC(v7_coherent_kern_range)
 ENDPROC(v7_coherent_user_range)
index 7d63bea..b795afd 100644 (file)
        .endm
 
 /*
- * cache_line_size - get the cache line size from the CSIDR register
- * (available on ARMv7+). It assumes that the CSSR register was configured
- * to access the L1 data cache CSIDR.
+ * dcache_line_size - get the minimum D-cache line size from the CTR register
+ * on ARMv7.
  */
        .macro  dcache_line_size, reg, tmp
-       mrc     p15, 1, \tmp, c0, c0, 0         @ read CSIDR
-       and     \tmp, \tmp, #7                  @ cache line size encoding
-       mov     \reg, #16                       @ size offset
+       mrc     p15, 0, \tmp, c0, c0, 1         @ read ctr
+       lsr     \tmp, \tmp, #16
+       and     \tmp, \tmp, #0xf                @ cache line size encoding
+       mov     \reg, #4                        @ bytes per word
        mov     \reg, \reg, lsl \tmp            @ actual cache line size
        .endm
 
+/*
+ * icache_line_size - get the minimum I-cache line size from the CTR register
+ * on ARMv7.
+ */
+       .macro  icache_line_size, reg, tmp
+       mrc     p15, 0, \tmp, c0, c0, 1         @ read ctr
+       and     \tmp, \tmp, #0xf                @ cache line size encoding
+       mov     \reg, #4                        @ bytes per word
+       mov     \reg, \reg, lsl \tmp            @ actual cache line size
+       .endm
 
 /*
  * Sanity check the PTE configuration for the code below - which makes
index 53cbe22..9b9ff5d 100644 (file)
@@ -381,7 +381,7 @@ __v7_ca9mp_proc_info:
                PMD_SECT_XN | \
                PMD_SECT_AP_WRITE | \
                PMD_SECT_AP_READ
-       b       __v7_ca9mp_setup
+       W(b)    __v7_ca9mp_setup
        .long   cpu_arch_name
        .long   cpu_elf_name
        .long   HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_TLS
@@ -413,7 +413,7 @@ __v7_proc_info:
                PMD_SECT_XN | \
                PMD_SECT_AP_WRITE | \
                PMD_SECT_AP_READ
-       b       __v7_setup
+       W(b)    __v7_setup
        .long   cpu_arch_name
        .long   cpu_elf_name
        .long   HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_TLS
index 85d3e55..558cdfa 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/time.h>
 #include <linux/init.h>
 #include <linux/timex.h>
+#include <linux/sched.h>
 #include <linux/io.h>
 #include <linux/clocksource.h>
 #include <linux/clockchips.h>
@@ -36,7 +37,7 @@
 /*
  * IOP clocksource (free-running timer 1).
  */
-static cycle_t iop_clocksource_read(struct clocksource *unused)
+static cycle_t notrace iop_clocksource_read(struct clocksource *unused)
 {
        return 0xffffffffu - read_tcr1();
 }
index 155fe43..8722a13 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/init.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/err.h>
 
 #include <plat/common.h>
 #include <plat/board.h>
@@ -164,7 +165,7 @@ static int __init omap_init_clocksource_32k(void)
                        return -ENODEV;
 
                sync_32k_ick = clk_get(NULL, "omap_32ksync_ick");
-               if (sync_32k_ick)
+               if (!IS_ERR(sync_32k_ick))
                        clk_enable(sync_32k_ick);
 
                clocksource_32k.mult = clocksource_hz2mult(32768,
index e2c8eeb..74dac41 100644 (file)
@@ -166,7 +166,7 @@ static void __init omap_detect_sram(void)
                     cpu_is_omap1710())
                        omap_sram_size = 0x4000;        /* 16K */
                else if (cpu_is_omap1611())
-                       omap_sram_size = 0x3e800;       /* 250K */
+                       omap_sram_size = SZ_256K;
                else {
                        printk(KERN_ERR "Could not detect SRAM size\n");
                        omap_sram_size = 0x4000;
index 76d0858..4a10c0f 100644 (file)
@@ -88,7 +88,7 @@ static struct cpu_table cpu_ids[] __initdata = {
        {
                .idcode         = 0x32440000,
                .idmask         = 0xffffffff,
-               .map_io         = s3c244x_map_io,
+               .map_io         = s3c2440_map_io,
                .init_clocks    = s3c244x_init_clocks,
                .init_uarts     = s3c244x_init_uarts,
                .init           = s3c2440_init,
@@ -97,7 +97,7 @@ static struct cpu_table cpu_ids[] __initdata = {
        {
                .idcode         = 0x32440001,
                .idmask         = 0xffffffff,
-               .map_io         = s3c244x_map_io,
+               .map_io         = s3c2440_map_io,
                .init_clocks    = s3c244x_init_clocks,
                .init_uarts     = s3c244x_init_uarts,
                .init           = s3c2440_init,
@@ -106,7 +106,7 @@ static struct cpu_table cpu_ids[] __initdata = {
        {
                .idcode         = 0x32440aaa,
                .idmask         = 0xffffffff,
-               .map_io         = s3c244x_map_io,
+               .map_io         = s3c2442_map_io,
                .init_clocks    = s3c244x_init_clocks,
                .init_uarts     = s3c244x_init_uarts,
                .init           = s3c2442_init,
@@ -115,7 +115,7 @@ static struct cpu_table cpu_ids[] __initdata = {
        {
                .idcode         = 0x32440aab,
                .idmask         = 0xffffffff,
-               .map_io         = s3c244x_map_io,
+               .map_io         = s3c2442_map_io,
                .init_clocks    = s3c244x_init_clocks,
                .init_uarts     = s3c244x_init_uarts,
                .init           = s3c2442_init,
index 24c6f5a..243b641 100644 (file)
@@ -82,8 +82,6 @@ static struct s3c_gpio_cfg s3c24xx_gpiocfg_banka = {
 struct s3c_gpio_cfg s3c24xx_gpiocfg_default = {
        .set_config     = s3c_gpio_setcfg_s3c24xx,
        .get_config     = s3c_gpio_getcfg_s3c24xx,
-       .set_pull       = s3c_gpio_setpull_1up,
-       .get_pull       = s3c_gpio_getpull_1up,
 };
 
 struct s3c_gpio_chip s3c24xx_gpios[] = {
index 307248d..89e8d0a 100644 (file)
@@ -21,17 +21,22 @@ extern void s3c244x_init_clocks(int xtal);
 #else
 #define s3c244x_init_clocks NULL
 #define s3c244x_init_uarts NULL
-#define s3c244x_map_io NULL
 #endif
 
 #ifdef CONFIG_CPU_S3C2440
 extern  int s3c2440_init(void);
+
+extern void s3c2440_map_io(void);
 #else
 #define s3c2440_init NULL
+#define s3c2440_map_io NULL
 #endif
 
 #ifdef CONFIG_CPU_S3C2442
 extern  int s3c2442_init(void);
+
+extern void s3c2442_map_io(void);
 #else
 #define s3c2442_init NULL
+#define s3c2442_map_io NULL
 #endif
index b732b77..0aa32f2 100644 (file)
@@ -280,18 +280,17 @@ s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip,
 }
 #endif
 
-#ifdef CONFIG_S3C_GPIO_PULL_UP
-int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip,
-                        unsigned int off, s3c_gpio_pull_t pull)
+#if defined(CONFIG_S3C_GPIO_PULL_UP) || defined(CONFIG_S3C_GPIO_PULL_DOWN)
+static int s3c_gpio_setpull_1(struct s3c_gpio_chip *chip,
+                        unsigned int off, s3c_gpio_pull_t pull,
+                        s3c_gpio_pull_t updown)
 {
        void __iomem *reg = chip->base + 0x08;
        u32 pup = __raw_readl(reg);
 
-       pup = __raw_readl(reg);
-
-       if (pup == S3C_GPIO_PULL_UP)
+       if (pull == updown)
                pup &= ~(1 << off);
-       else if (pup == S3C_GPIO_PULL_NONE)
+       else if (pull == S3C_GPIO_PULL_NONE)
                pup |= (1 << off);
        else
                return -EINVAL;
@@ -300,17 +299,45 @@ int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip,
        return 0;
 }
 
-s3c_gpio_pull_t s3c_gpio_getpull_1up(struct s3c_gpio_chip *chip,
-                                    unsigned int off)
+static s3c_gpio_pull_t s3c_gpio_getpull_1(struct s3c_gpio_chip *chip,
+                                    unsigned int off, s3c_gpio_pull_t updown)
 {
        void __iomem *reg = chip->base + 0x08;
        u32 pup = __raw_readl(reg);
 
        pup &= (1 << off);
-       return pup ? S3C_GPIO_PULL_NONE : S3C_GPIO_PULL_UP;
+       return pup ? S3C_GPIO_PULL_NONE : updown;
+}
+#endif /* CONFIG_S3C_GPIO_PULL_UP || CONFIG_S3C_GPIO_PULL_DOWN */
+
+#ifdef CONFIG_S3C_GPIO_PULL_UP
+s3c_gpio_pull_t s3c_gpio_getpull_1up(struct s3c_gpio_chip *chip,
+                                    unsigned int off)
+{
+       return s3c_gpio_getpull_1(chip, off, S3C_GPIO_PULL_UP);
+}
+
+int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip,
+                        unsigned int off, s3c_gpio_pull_t pull)
+{
+       return s3c_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_UP);
 }
 #endif /* CONFIG_S3C_GPIO_PULL_UP */
 
+#ifdef CONFIG_S3C_GPIO_PULL_DOWN
+s3c_gpio_pull_t s3c_gpio_getpull_1down(struct s3c_gpio_chip *chip,
+                                    unsigned int off)
+{
+       return s3c_gpio_getpull_1(chip, off, S3C_GPIO_PULL_DOWN);
+}
+
+int s3c_gpio_setpull_1down(struct s3c_gpio_chip *chip,
+                        unsigned int off, s3c_gpio_pull_t pull)
+{
+       return s3c_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_DOWN);
+}
+#endif /* CONFIG_S3C_GPIO_PULL_DOWN */
+
 #ifdef CONFIG_S5P_GPIO_DRVSTR
 s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin)
 {
index 8fd65d8..0d2c570 100644 (file)
@@ -209,6 +209,17 @@ extern s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip,
 extern s3c_gpio_pull_t s3c_gpio_getpull_1up(struct s3c_gpio_chip *chip,
                                            unsigned int off);
 
+/**
+ * s3c_gpio_getpull_1down() - Get configuration for choice of down or none
+ * @chip: The gpio chip that the GPIO pin belongs to
+ * @off: The offset to the pin to get the configuration of.
+ *
+ * This helper function reads the state of the pull-down resistor for the
+ * given GPIO in the same case as s3c_gpio_setpull_1down.
+*/
+extern s3c_gpio_pull_t s3c_gpio_getpull_1down(struct s3c_gpio_chip *chip,
+                                           unsigned int off);
+
 /**
  * s3c_gpio_setpull_s3c2443() - Pull configuration for s3c2443.
  * @chip: The gpio chip that is being configured.
index 55590a4..2fea897 100644 (file)
@@ -12,7 +12,7 @@
 #
 #   http://www.arm.linux.org.uk/developer/machines/?action=new
 #
-# Last update: Thu Sep 9 22:43:01 2010
+# Last update: Sun Dec 12 23:24:27 2010
 #
 # machine_is_xxx       CONFIG_xxxx             MACH_TYPE_xxx           number
 #
@@ -2321,7 +2321,7 @@ mx31txtr          MACH_MX31TXTR           MX31TXTR                2332
 u380                   MACH_U380               U380                    2333
 oamp3_hualu            MACH_HUALU_BOARD        HUALU_BOARD             2334
 npcmx50                        MACH_NPCMX50            NPCMX50                 2335
-mx51_lange51           MACH_MX51_LANGE51       MX51_LANGE51            2336
+mx51_efikamx           MACH_MX51_EFIKAMX       MX51_EFIKAMX            2336
 mx51_lange52           MACH_MX51_LANGE52       MX51_LANGE52            2337
 riom                   MACH_RIOM               RIOM                    2338
 comcas                 MACH_COMCAS             COMCAS                  2339
@@ -2355,7 +2355,7 @@ at91sam9263cs             MACH_AT91SAM9263CS      AT91SAM9263CS           2366
 csb732                 MACH_CSB732             CSB732                  2367
 u8500                  MACH_U8500              U8500                   2368
 huqiu                  MACH_HUQIU              HUQIU                   2369
-mx51_kunlun            MACH_MX51_KUNLUN        MX51_KUNLUN             2370
+mx51_efikasb           MACH_MX51_EFIKASB       MX51_EFIKASB            2370
 pmt1g                  MACH_PMT1G              PMT1G                   2371
 htcelf                 MACH_HTCELF             HTCELF                  2372
 armadillo420           MACH_ARMADILLO420       ARMADILLO420            2373
@@ -2971,7 +2971,7 @@ premierwave_en            MACH_PREMIERWAVE_EN     PREMIERWAVE_EN          2985
 wasabi                 MACH_WASABI             WASABI                  2986
 vivow                  MACH_VIVOW              VIVOW                   2987
 mx50_rdp               MACH_MX50_RDP           MX50_RDP                2988
-universal              MACH_UNIVERSAL          UNIVERSAL               2989
+universal_c210         MACH_UNIVERSAL_C210     UNIVERSAL_C210          2989
 real6410               MACH_REAL6410           REAL6410                2990
 spx_sakura             MACH_SPX_SAKURA         SPX_SAKURA              2991
 ij3k_2440              MACH_IJ3K_2440          IJ3K_2440               2992
@@ -3044,3 +3044,178 @@ harvest_desoto          MACH_HARVEST_DESOTO     HARVEST_DESOTO          3059
 msm8x60_qrdc           MACH_MSM8X60_QRDC       MSM8X60_QRDC            3060
 spear900               MACH_SPEAR900           SPEAR900                3061
 pcontrol_g20           MACH_PCONTROL_G20       PCONTROL_G20            3062
+rdstor                 MACH_RDSTOR             RDSTOR                  3063
+usdloader              MACH_USDLOADER          USDLOADER               3064
+tsoploader             MACH_TSOPLOADER         TSOPLOADER              3065
+kronos                 MACH_KRONOS             KRONOS                  3066
+ffcore                 MACH_FFCORE             FFCORE                  3067
+mone                   MACH_MONE               MONE                    3068
+unit2s                 MACH_UNIT2S             UNIT2S                  3069
+acer_a5                        MACH_ACER_A5            ACER_A5                 3070
+etherpro_isp           MACH_ETHERPRO_ISP       ETHERPRO_ISP            3071
+stretchs7000           MACH_STRETCHS7000       STRETCHS7000            3072
+p87_smartsim           MACH_P87_SMARTSIM       P87_SMARTSIM            3073
+tulip                  MACH_TULIP              TULIP                   3074
+sunflower              MACH_SUNFLOWER          SUNFLOWER               3075
+rib                    MACH_RIB                RIB                     3076
+clod                   MACH_CLOD               CLOD                    3077
+rump                   MACH_RUMP               RUMP                    3078
+tenderloin             MACH_TENDERLOIN         TENDERLOIN              3079
+shortloin              MACH_SHORTLOIN          SHORTLOIN               3080
+crespo                 MACH_CRESPO             CRESPO                  3081
+antares                        MACH_ANTARES            ANTARES                 3082
+wb40n                  MACH_WB40N              WB40N                   3083
+herring                        MACH_HERRING            HERRING                 3084
+naxy400                        MACH_NAXY400            NAXY400                 3085
+naxy1200               MACH_NAXY1200           NAXY1200                3086
+vpr200                 MACH_VPR200             VPR200                  3087
+bug20                  MACH_BUG20              BUG20                   3088
+goflexnet              MACH_GOFLEXNET          GOFLEXNET               3089
+torbreck               MACH_TORBRECK           TORBRECK                3090
+saarb_mg1              MACH_SAARB_MG1          SAARB_MG1               3091
+callisto               MACH_CALLISTO           CALLISTO                3092
+multhsu                        MACH_MULTHSU            MULTHSU                 3093
+saluda                 MACH_SALUDA             SALUDA                  3094
+pemp_omap3_apollo      MACH_PEMP_OMAP3_APOLLO  PEMP_OMAP3_APOLLO       3095
+vc0718                 MACH_VC0718             VC0718                  3096
+mvblx                  MACH_MVBLX              MVBLX                   3097
+inhand_apeiron         MACH_INHAND_APEIRON     INHAND_APEIRON          3098
+inhand_fury            MACH_INHAND_FURY        INHAND_FURY             3099
+inhand_siren           MACH_INHAND_SIREN       INHAND_SIREN            3100
+hdnvp                  MACH_HDNVP              HDNVP                   3101
+softwinner             MACH_SOFTWINNER         SOFTWINNER              3102
+prima2_evb             MACH_PRIMA2_EVB         PRIMA2_EVB              3103
+nas6210                        MACH_NAS6210            NAS6210                 3104
+unisdev                        MACH_UNISDEV            UNISDEV                 3105
+sbca11                 MACH_SBCA11             SBCA11                  3106
+saga                   MACH_SAGA               SAGA                    3107
+ns_k330                        MACH_NS_K330            NS_K330                 3108
+tanna                  MACH_TANNA              TANNA                   3109
+imate8502              MACH_IMATE8502          IMATE8502               3110
+aspen                  MACH_ASPEN              ASPEN                   3111
+daintree_cwac          MACH_DAINTREE_CWAC      DAINTREE_CWAC           3112
+zmx25                  MACH_ZMX25              ZMX25                   3113
+maple1                 MACH_MAPLE1             MAPLE1                  3114
+qsd8x72_surf           MACH_QSD8X72_SURF       QSD8X72_SURF            3115
+qsd8x72_ffa            MACH_QSD8X72_FFA        QSD8X72_FFA             3116
+abilene                        MACH_ABILENE            ABILENE                 3117
+eigen_ttr              MACH_EIGEN_TTR          EIGEN_TTR               3118
+iomega_ix2_200         MACH_IOMEGA_IX2_200     IOMEGA_IX2_200          3119
+coretec_vcx7400                MACH_CORETEC_VCX7400    CORETEC_VCX7400         3120
+santiago               MACH_SANTIAGO           SANTIAGO                3121
+mx257sol               MACH_MX257SOL           MX257SOL                3122
+strasbourg             MACH_STRASBOURG         STRASBOURG              3123
+msm8x60_fluid          MACH_MSM8X60_FLUID      MSM8X60_FLUID           3124
+smartqv5               MACH_SMARTQV5           SMARTQV5                3125
+smartqv3               MACH_SMARTQV3           SMARTQV3                3126
+smartqv7               MACH_SMARTQV7           SMARTQV7                3127
+paz00                  MACH_PAZ00              PAZ00                   3128
+acmenetusfoxg20                MACH_ACMENETUSFOXG20    ACMENETUSFOXG20         3129
+htcwillow              MACH_HTCWILLOW          HTCWILLOW               3130
+fwbd_0404              MACH_FWBD_0404          FWBD_0404               3131
+hdgu                   MACH_HDGU               HDGU                    3132
+pyramid                        MACH_PYRAMID            PYRAMID                 3133
+epiphan                        MACH_EPIPHAN            EPIPHAN                 3134
+omap_bender            MACH_OMAP_BENDER        OMAP_BENDER             3135
+gurnard                        MACH_GURNARD            GURNARD                 3136
+gtl_it5100             MACH_GTL_IT5100         GTL_IT5100              3137
+bcm2708                        MACH_BCM2708            BCM2708                 3138
+mx51_ggc               MACH_MX51_GGC           MX51_GGC                3139
+sharespace             MACH_SHARESPACE         SHARESPACE              3140
+haba_knx_explorer      MACH_HABA_KNX_EXPLORER  HABA_KNX_EXPLORER       3141
+simtec_kirkmod         MACH_SIMTEC_KIRKMOD     SIMTEC_KIRKMOD          3142
+crux                   MACH_CRUX               CRUX                    3143
+mx51_bravo             MACH_MX51_BRAVO         MX51_BRAVO              3144
+charon                 MACH_CHARON             CHARON                  3145
+picocom3               MACH_PICOCOM3           PICOCOM3                3146
+picocom4               MACH_PICOCOM4           PICOCOM4                3147
+serrano                        MACH_SERRANO            SERRANO                 3148
+doubleshot             MACH_DOUBLESHOT         DOUBLESHOT              3149
+evsy                   MACH_EVSY               EVSY                    3150
+huashan                        MACH_HUASHAN            HUASHAN                 3151
+lausanne               MACH_LAUSANNE           LAUSANNE                3152
+emerald                        MACH_EMERALD            EMERALD                 3153
+tqma35                 MACH_TQMA35             TQMA35                  3154
+marvel                 MACH_MARVEL             MARVEL                  3155
+manuae                 MACH_MANUAE             MANUAE                  3156
+chacha                 MACH_CHACHA             CHACHA                  3157
+lemon                  MACH_LEMON              LEMON                   3158
+csc                    MACH_CSC                CSC                     3159
+gira_knxip_router      MACH_GIRA_KNXIP_ROUTER  GIRA_KNXIP_ROUTER       3160
+t20                    MACH_T20                T20                     3161
+hdmini                 MACH_HDMINI             HDMINI                  3162
+sciphone_g2            MACH_SCIPHONE_G2        SCIPHONE_G2             3163
+express                        MACH_EXPRESS            EXPRESS                 3164
+express_kt             MACH_EXPRESS_KT         EXPRESS_KT              3165
+maximasp               MACH_MAXIMASP           MAXIMASP                3166
+nitrogen_imx51         MACH_NITROGEN_IMX51     NITROGEN_IMX51          3167
+nitrogen_imx53         MACH_NITROGEN_IMX53     NITROGEN_IMX53          3168
+sunfire                        MACH_SUNFIRE            SUNFIRE                 3169
+arowana                        MACH_AROWANA            AROWANA                 3170
+tegra_daytona          MACH_TEGRA_DAYTONA      TEGRA_DAYTONA           3171
+tegra_swordfish                MACH_TEGRA_SWORDFISH    TEGRA_SWORDFISH         3172
+edison                 MACH_EDISON             EDISON                  3173
+svp8500v1              MACH_SVP8500V1          SVP8500V1               3174
+svp8500v2              MACH_SVP8500V2          SVP8500V2               3175
+svp5500                        MACH_SVP5500            SVP5500                 3176
+b5500                  MACH_B5500              B5500                   3177
+s5500                  MACH_S5500              S5500                   3178
+icon                   MACH_ICON               ICON                    3179
+elephant               MACH_ELEPHANT           ELEPHANT                3180
+msm8x60_fusion         MACH_MSM8X60_FUSION     MSM8X60_FUSION          3181
+shooter                        MACH_SHOOTER            SHOOTER                 3182
+spade_lte              MACH_SPADE_LTE          SPADE_LTE               3183
+philhwani              MACH_PHILHWANI          PHILHWANI               3184
+gsncomm                        MACH_GSNCOMM            GSNCOMM                 3185
+strasbourg_a2          MACH_STRASBOURG_A2      STRASBOURG_A2           3186
+mmm                    MACH_MMM                MMM                     3187
+davinci_dm365_bv       MACH_DAVINCI_DM365_BV   DAVINCI_DM365_BV        3188
+ag5evm                 MACH_AG5EVM             AG5EVM                  3189
+sc575plc               MACH_SC575PLC           SC575PLC                3190
+sc575hmi               MACH_SC575IPC           SC575IPC                3191
+omap3_tdm3730          MACH_OMAP3_TDM3730      OMAP3_TDM3730           3192
+g7                     MACH_G7                 G7                      3193
+top9000_eval           MACH_TOP9000_EVAL       TOP9000_EVAL            3194
+top9000_su             MACH_TOP9000_SU         TOP9000_SU              3195
+utm300                 MACH_UTM300             UTM300                  3196
+tsunagi                        MACH_TSUNAGI            TSUNAGI                 3197
+ts75xx                 MACH_TS75XX             TS75XX                  3198
+msm8x60_fusn_ffa       MACH_MSM8X60_FUSN_FFA   MSM8X60_FUSN_FFA        3199
+ts47xx                 MACH_TS47XX             TS47XX                  3200
+da850_k5               MACH_DA850_K5           DA850_K5                3201
+ax502                  MACH_AX502              AX502                   3202
+igep0032               MACH_IGEP0032           IGEP0032                3203
+antero                 MACH_ANTERO             ANTERO                  3204
+synergy                        MACH_SYNERGY            SYNERGY                 3205
+ics_if_voip            MACH_ICS_IF_VOIP        ICS_IF_VOIP             3206
+wlf_cragg_6410         MACH_WLF_CRAGG_6410     WLF_CRAGG_6410          3207
+punica                 MACH_PUNICA             PUNICA                  3208
+sbc_nt250              MACH_SBC_NT250          SBC_NT250               3209
+mx27_wmultra           MACH_MX27_WMULTRA       MX27_WMULTRA            3210
+mackerel               MACH_MACKEREL           MACKEREL                3211
+fa9x27                 MACH_FA9X27             FA9X27                  3213
+ns2816tb               MACH_NS2816TB           NS2816TB                3214
+ns2816_ntpad           MACH_NS2816_NTPAD       NS2816_NTPAD            3215
+ns2816_ntnb            MACH_NS2816_NTNB        NS2816_NTNB             3216
+kaen                   MACH_KAEN               KAEN                    3217
+nv1000                 MACH_NV1000             NV1000                  3218
+nuc950ts               MACH_NUC950TS           NUC950TS                3219
+nokia_rm680            MACH_NOKIA_RM680        NOKIA_RM680             3220
+ast2200                        MACH_AST2200            AST2200                 3221
+lead                   MACH_LEAD               LEAD                    3222
+unino1                 MACH_UNINO1             UNINO1                  3223
+greeco                 MACH_GREECO             GREECO                  3224
+verdi                  MACH_VERDI              VERDI                   3225
+dm6446_adbox           MACH_DM6446_ADBOX       DM6446_ADBOX            3226
+quad_salsa             MACH_QUAD_SALSA         QUAD_SALSA              3227
+abb_gma_1_1            MACH_ABB_GMA_1_1        ABB_GMA_1_1             3228
+svcid                  MACH_SVCID              SVCID                   3229
+msm8960_sim            MACH_MSM8960_SIM        MSM8960_SIM             3230
+msm8960_rumi3          MACH_MSM8960_RUMI3      MSM8960_RUMI3           3231
+icon_g                 MACH_ICON_G             ICON_G                  3232
+mb3                    MACH_MB3                MB3                     3233
+gsia18s                        MACH_GSIA18S            GSIA18S                 3234
+pivicc                 MACH_PIVICC             PIVICC                  3235
+pcm048                 MACH_PCM048             PCM048                  3236
+dds                    MACH_DDS                DDS                     3237
+chalten_xa1            MACH_CHALTEN_XA1        CHALTEN_XA1             3238
index d66cead..9897dcf 100644 (file)
@@ -206,6 +206,7 @@ ENTRY(vfp_save_state)
        mov     pc, lr
 ENDPROC(vfp_save_state)
 
+       .align
 last_VFP_context_address:
        .word   last_VFP_context
 
index 67a2fa2..0a9b5b8 100644 (file)
@@ -19,6 +19,8 @@ config MIPS
        select GENERIC_ATOMIC64 if !64BIT
        select HAVE_DMA_ATTRS
        select HAVE_DMA_API_DEBUG
+       select HAVE_GENERIC_HARDIRQS
+       select GENERIC_IRQ_PROBE
 
 menu "Machine selection"
 
@@ -1664,6 +1666,28 @@ config PAGE_SIZE_64KB
 
 endchoice
 
+config FORCE_MAX_ZONEORDER
+       int "Maximum zone order"
+       range 13 64 if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_32KB
+       default "13" if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_32KB
+       range 12 64 if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_16KB
+       default "12" if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_16KB
+       range 11 64
+       default "11"
+       help
+         The kernel memory allocator divides physically contiguous memory
+         blocks into "zones", where each zone is a power of two number of
+         pages.  This option selects the largest power of two that the kernel
+         keeps in the memory allocator.  If you need to allocate very large
+         blocks of physically contiguous memory, then you may need to
+         increase this value.
+
+         This config option is actually maximum order plus one. For example,
+         a value of 11 means that the largest free memory block is 2^10 pages.
+
+         The page size is not necessarily 4KB.  Keep this in mind
+         when choosing a value for this option.
+
 config BOARD_SCACHE
        bool
 
@@ -1921,20 +1945,6 @@ config CPU_R4000_WORKAROUNDS
 config CPU_R4400_WORKAROUNDS
        bool
 
-#
-# Use the generic interrupt handling code in kernel/irq/:
-#
-config GENERIC_HARDIRQS
-       bool
-       default y
-
-config GENERIC_IRQ_PROBE
-       bool
-       default y
-
-config IRQ_PER_CPU
-       bool
-
 #
 # - Highmem only makes sense for the 32-bit kernel.
 # - The current highmem code will only work properly on physically indexed
index 3691630..9e7814d 100644 (file)
@@ -27,6 +27,7 @@
 static void alchemy_8250_pm(struct uart_port *port, unsigned int state,
                            unsigned int old_state)
 {
+#ifdef CONFIG_SERIAL_8250
        switch (state) {
        case 0:
                if ((__raw_readl(port->membase + UART_MOD_CNTRL) & 3) != 3) {
@@ -49,6 +50,7 @@ static void alchemy_8250_pm(struct uart_port *port, unsigned int state,
                serial8250_do_pm(port, state, old_state);
                break;
        }
+#endif
 }
 
 #define PORT(_base, _irq)                                      \
index b30df5c..baeb213 100644 (file)
@@ -54,10 +54,9 @@ void __init prom_init(void)
 
        prom_init_cmdline();
        memsize_str = prom_getenv("memsize");
-       if (!memsize_str)
+       if (!memsize_str || strict_strtoul(memsize_str, 0, &memsize))
                memsize = ALCHEMY_BOARD_DEFAULT_MEMSIZE;
-       else
-               strict_strtoul(memsize_str, 0, &memsize);
+
        add_memory_region(0, memsize, BOOT_MEM_RAM);
 }
 
index fc0e715..2ca4ada 100644 (file)
@@ -239,12 +239,12 @@ static void tnetd7300_set_clock(u32 shift, struct tnetd7300_clock *clock,
        calculate(base_clock, frequency, &prediv, &postdiv, &mul);
 
        writel(((prediv - 1) << PREDIV_SHIFT) | (postdiv - 1), &clock->ctrl);
-       msleep(1);
+       mdelay(1);
        writel(4, &clock->pll);
        while (readl(&clock->pll) & PLL_STATUS)
                ;
        writel(((mul - 1) << MUL_SHIFT) | (0xff << 3) | 0x0e, &clock->pll);
-       msleep(75);
+       mdelay(75);
 }
 
 static void __init tnetd7300_init_clocks(void)
@@ -456,7 +456,7 @@ void clk_put(struct clk *clk)
 }
 EXPORT_SYMBOL(clk_put);
 
-int __init ar7_init_clocks(void)
+void __init ar7_init_clocks(void)
 {
        switch (ar7_chip_id()) {
        case AR7_CHIP_7100:
@@ -472,7 +472,4 @@ int __init ar7_init_clocks(void)
        }
        /* adjust vbus clock rate */
        vbus_clk.rate = bus_clk.rate / 2;
-
-       return 0;
 }
-arch_initcall(ar7_init_clocks);
index 5fb8a01..22c9321 100644 (file)
@@ -30,6 +30,9 @@ void __init plat_time_init(void)
 {
        struct clk *cpu_clk;
 
+       /* Initialize ar7 clocks so the CPU clock frequency is correct */
+       ar7_init_clocks();
+
        cpu_clk = clk_get(NULL, "cpu");
        if (IS_ERR(cpu_clk)) {
                printk(KERN_ERR "unable to get cpu clock\n");
index b1aee33..c95f90b 100644 (file)
@@ -32,7 +32,6 @@
 #include <asm/reboot.h>
 #include <asm/time.h>
 #include <bcm47xx.h>
-#include <asm/fw/cfe/cfe_api.h>
 #include <asm/mach-bcm47xx/nvram.h>
 
 struct ssb_bus ssb_bcm47xx;
@@ -57,68 +56,112 @@ static void bcm47xx_machine_halt(void)
                cpu_relax();
 }
 
-static void str2eaddr(char *str, char *dest)
-{
-       int i = 0;
+#define READ_FROM_NVRAM(_outvar, name, buf) \
+       if (nvram_getenv(name, buf, sizeof(buf)) >= 0)\
+               sprom->_outvar = simple_strtoul(buf, NULL, 0);
 
-       if (str == NULL) {
-               memset(dest, 0, 6);
-               return;
+static void bcm47xx_fill_sprom(struct ssb_sprom *sprom)
+{
+       char buf[100];
+       u32 boardflags;
+
+       memset(sprom, 0, sizeof(struct ssb_sprom));
+
+       sprom->revision = 1; /* Fallback: Old hardware does not define this. */
+       READ_FROM_NVRAM(revision, "sromrev", buf);
+       if (nvram_getenv("il0macaddr", buf, sizeof(buf)) >= 0)
+               nvram_parse_macaddr(buf, sprom->il0mac);
+       if (nvram_getenv("et0macaddr", buf, sizeof(buf)) >= 0)
+               nvram_parse_macaddr(buf, sprom->et0mac);
+       if (nvram_getenv("et1macaddr", buf, sizeof(buf)) >= 0)
+               nvram_parse_macaddr(buf, sprom->et1mac);
+       READ_FROM_NVRAM(et0phyaddr, "et0phyaddr", buf);
+       READ_FROM_NVRAM(et1phyaddr, "et1phyaddr", buf);
+       READ_FROM_NVRAM(et0mdcport, "et0mdcport", buf);
+       READ_FROM_NVRAM(et1mdcport, "et1mdcport", buf);
+       READ_FROM_NVRAM(board_rev, "boardrev", buf);
+       READ_FROM_NVRAM(country_code, "ccode", buf);
+       READ_FROM_NVRAM(ant_available_a, "aa5g", buf);
+       READ_FROM_NVRAM(ant_available_bg, "aa2g", buf);
+       READ_FROM_NVRAM(pa0b0, "pa0b0", buf);
+       READ_FROM_NVRAM(pa0b1, "pa0b1", buf);
+       READ_FROM_NVRAM(pa0b2, "pa0b2", buf);
+       READ_FROM_NVRAM(pa1b0, "pa1b0", buf);
+       READ_FROM_NVRAM(pa1b1, "pa1b1", buf);
+       READ_FROM_NVRAM(pa1b2, "pa1b2", buf);
+       READ_FROM_NVRAM(pa1lob0, "pa1lob0", buf);
+       READ_FROM_NVRAM(pa1lob2, "pa1lob1", buf);
+       READ_FROM_NVRAM(pa1lob1, "pa1lob2", buf);
+       READ_FROM_NVRAM(pa1hib0, "pa1hib0", buf);
+       READ_FROM_NVRAM(pa1hib2, "pa1hib1", buf);
+       READ_FROM_NVRAM(pa1hib1, "pa1hib2", buf);
+       READ_FROM_NVRAM(gpio0, "wl0gpio0", buf);
+       READ_FROM_NVRAM(gpio1, "wl0gpio1", buf);
+       READ_FROM_NVRAM(gpio2, "wl0gpio2", buf);
+       READ_FROM_NVRAM(gpio3, "wl0gpio3", buf);
+       READ_FROM_NVRAM(maxpwr_bg, "pa0maxpwr", buf);
+       READ_FROM_NVRAM(maxpwr_al, "pa1lomaxpwr", buf);
+       READ_FROM_NVRAM(maxpwr_a, "pa1maxpwr", buf);
+       READ_FROM_NVRAM(maxpwr_ah, "pa1himaxpwr", buf);
+       READ_FROM_NVRAM(itssi_a, "pa1itssit", buf);
+       READ_FROM_NVRAM(itssi_bg, "pa0itssit", buf);
+       READ_FROM_NVRAM(tri2g, "tri2g", buf);
+       READ_FROM_NVRAM(tri5gl, "tri5gl", buf);
+       READ_FROM_NVRAM(tri5g, "tri5g", buf);
+       READ_FROM_NVRAM(tri5gh, "tri5gh", buf);
+       READ_FROM_NVRAM(rxpo2g, "rxpo2g", buf);
+       READ_FROM_NVRAM(rxpo5g, "rxpo5g", buf);
+       READ_FROM_NVRAM(rssisav2g, "rssisav2g", buf);
+       READ_FROM_NVRAM(rssismc2g, "rssismc2g", buf);
+       READ_FROM_NVRAM(rssismf2g, "rssismf2g", buf);
+       READ_FROM_NVRAM(bxa2g, "bxa2g", buf);
+       READ_FROM_NVRAM(rssisav5g, "rssisav5g", buf);
+       READ_FROM_NVRAM(rssismc5g, "rssismc5g", buf);
+       READ_FROM_NVRAM(rssismf5g, "rssismf5g", buf);
+       READ_FROM_NVRAM(bxa5g, "bxa5g", buf);
+       READ_FROM_NVRAM(cck2gpo, "cck2gpo", buf);
+       READ_FROM_NVRAM(ofdm2gpo, "ofdm2gpo", buf);
+       READ_FROM_NVRAM(ofdm5glpo, "ofdm5glpo", buf);
+       READ_FROM_NVRAM(ofdm5gpo, "ofdm5gpo", buf);
+       READ_FROM_NVRAM(ofdm5ghpo, "ofdm5ghpo", buf);
+
+       if (nvram_getenv("boardflags", buf, sizeof(buf)) >= 0) {
+               boardflags = simple_strtoul(buf, NULL, 0);
+               if (boardflags) {
+                       sprom->boardflags_lo = (boardflags & 0x0000FFFFU);
+                       sprom->boardflags_hi = (boardflags & 0xFFFF0000U) >> 16;
+               }
        }
-
-       for (;;) {
-               dest[i++] = (char) simple_strtoul(str, NULL, 16);
-               str += 2;
-               if (!*str++ || i == 6)
-                       break;
+       if (nvram_getenv("boardflags2", buf, sizeof(buf)) >= 0) {
+               boardflags = simple_strtoul(buf, NULL, 0);
+               if (boardflags) {
+                       sprom->boardflags2_lo = (boardflags & 0x0000FFFFU);
+                       sprom->boardflags2_hi = (boardflags & 0xFFFF0000U) >> 16;
+               }
        }
 }
 
 static int bcm47xx_get_invariants(struct ssb_bus *bus,
                                   struct ssb_init_invariants *iv)
 {
-       char buf[100];
+       char buf[20];
 
        /* Fill boardinfo structure */
        memset(&(iv->boardinfo), 0 , sizeof(struct ssb_boardinfo));
 
-       if (cfe_getenv("boardvendor", buf, sizeof(buf)) >= 0 ||
-           nvram_getenv("boardvendor", buf, sizeof(buf)) >= 0)
-               iv->boardinfo.type = (u16)simple_strtoul(buf, NULL, 0);
-       if (cfe_getenv("boardtype", buf, sizeof(buf)) >= 0 ||
-           nvram_getenv("boardtype", buf, sizeof(buf)) >= 0)
+       if (nvram_getenv("boardvendor", buf, sizeof(buf)) >= 0)
+               iv->boardinfo.vendor = (u16)simple_strtoul(buf, NULL, 0);
+       else
+               iv->boardinfo.vendor = SSB_BOARDVENDOR_BCM;
+       if (nvram_getenv("boardtype", buf, sizeof(buf)) >= 0)
                iv->boardinfo.type = (u16)simple_strtoul(buf, NULL, 0);
-       if (cfe_getenv("boardrev", buf, sizeof(buf)) >= 0 ||
-           nvram_getenv("boardrev", buf, sizeof(buf)) >= 0)
+       if (nvram_getenv("boardrev", buf, sizeof(buf)) >= 0)
                iv->boardinfo.rev = (u16)simple_strtoul(buf, NULL, 0);
 
-       /* Fill sprom structure */
-       memset(&(iv->sprom), 0, sizeof(struct ssb_sprom));
-       iv->sprom.revision = 3;
-
-       if (cfe_getenv("et0macaddr", buf, sizeof(buf)) >= 0 ||
-           nvram_getenv("et0macaddr", buf, sizeof(buf)) >= 0)
-               str2eaddr(buf, iv->sprom.et0mac);
+       bcm47xx_fill_sprom(&iv->sprom);
 
-       if (cfe_getenv("et1macaddr", buf, sizeof(buf)) >= 0 ||
-           nvram_getenv("et1macaddr", buf, sizeof(buf)) >= 0)
-               str2eaddr(buf, iv->sprom.et1mac);
-
-       if (cfe_getenv("et0phyaddr", buf, sizeof(buf)) >= 0 ||
-           nvram_getenv("et0phyaddr", buf, sizeof(buf)) >= 0)
-               iv->sprom.et0phyaddr = simple_strtoul(buf, NULL, 0);
-
-       if (cfe_getenv("et1phyaddr", buf, sizeof(buf)) >= 0 ||
-           nvram_getenv("et1phyaddr", buf, sizeof(buf)) >= 0)
-               iv->sprom.et1phyaddr = simple_strtoul(buf, NULL, 0);
-
-       if (cfe_getenv("et0mdcport", buf, sizeof(buf)) >= 0 ||
-           nvram_getenv("et0mdcport", buf, sizeof(buf)) >= 0)
-               iv->sprom.et0mdcport = simple_strtoul(buf, NULL, 10);
-
-       if (cfe_getenv("et1mdcport", buf, sizeof(buf)) >= 0 ||
-           nvram_getenv("et1mdcport", buf, sizeof(buf)) >= 0)
-               iv->sprom.et1mdcport = simple_strtoul(buf, NULL, 10);
+       if (nvram_getenv("cardbus", buf, sizeof(buf)) >= 0)
+               iv->has_cardbus_slot = !!simple_strtoul(buf, NULL, 10);
 
        return 0;
 }
@@ -126,12 +169,28 @@ static int bcm47xx_get_invariants(struct ssb_bus *bus,
 void __init plat_mem_setup(void)
 {
        int err;
+       char buf[100];
+       struct ssb_mipscore *mcore;
 
        err = ssb_bus_ssbbus_register(&ssb_bcm47xx, SSB_ENUM_BASE,
                                      bcm47xx_get_invariants);
        if (err)
                panic("Failed to initialize SSB bus (err %d)\n", err);
 
+       mcore = &ssb_bcm47xx.mipscore;
+       if (nvram_getenv("kernel_args", buf, sizeof(buf)) >= 0) {
+               if (strstr(buf, "console=ttyS1")) {
+                       struct ssb_serial_port port;
+
+                       printk(KERN_DEBUG "Swapping serial ports!\n");
+                       /* swap serial ports */
+                       memcpy(&port, &mcore->serial_ports[0], sizeof(port));
+                       memcpy(&mcore->serial_ports[0], &mcore->serial_ports[1],
+                              sizeof(port));
+                       memcpy(&mcore->serial_ports[1], &port, sizeof(port));
+               }
+       }
+
        _machine_restart = bcm47xx_machine_restart;
        _machine_halt = bcm47xx_machine_halt;
        pm_power_off = bcm47xx_machine_halt;
index 06d59dc..8687753 100644 (file)
  * These are the PRID's for when 23:16 == PRID_COMP_BROADCOM
  */
 
-#define PRID_IMP_BMIPS4KC      0x4000
-#define PRID_IMP_BMIPS32       0x8000
+#define PRID_IMP_BMIPS32_REV4  0x4000
+#define PRID_IMP_BMIPS32_REV8  0x8000
 #define PRID_IMP_BMIPS3300     0x9000
 #define PRID_IMP_BMIPS3300_ALT 0x9100
 #define PRID_IMP_BMIPS3300_BUG 0x0000
index fd1d39e..455c0ac 100644 (file)
@@ -249,7 +249,8 @@ extern struct mips_abi mips_abi_n32;
 
 #define SET_PERSONALITY(ex)                                            \
 do {                                                                   \
-       set_personality(PER_LINUX);                                     \
+       if (personality(current->personality) != PER_LINUX)             \
+               set_personality(PER_LINUX);                             \
                                                                        \
        current->thread.abi = &mips_abi;                                \
 } while (0)
@@ -296,6 +297,8 @@ do {                                                                        \
 
 #define SET_PERSONALITY(ex)                                            \
 do {                                                                   \
+       unsigned int p;                                                 \
+                                                                       \
        clear_thread_flag(TIF_32BIT_REGS);                              \
        clear_thread_flag(TIF_32BIT_ADDR);                              \
                                                                        \
@@ -304,7 +307,8 @@ do {                                                                        \
        else                                                            \
                current->thread.abi = &mips_abi;                        \
                                                                        \
-       if (current->personality != PER_LINUX32)                        \
+       p = personality(current->personality);                          \
+       if (p != PER_LINUX32 && p != PER_LINUX)                         \
                set_personality(PER_LINUX);                             \
 } while (0)
 
index c98bf51..5b017f2 100644 (file)
@@ -329,10 +329,14 @@ static inline void pfx##write##bwlq(type val,                             \
                        "dsrl32 %L0, %L0, 0"                    "\n\t"  \
                        "dsll32 %M0, %M0, 0"                    "\n\t"  \
                        "or     %L0, %L0, %M0"                  "\n\t"  \
+                       ".set   push"                           "\n\t"  \
+                       ".set   noreorder"                      "\n\t"  \
+                       ".set   nomacro"                        "\n\t"  \
                        "sd     %L0, %2"                        "\n\t"  \
+                       ".set   pop"                            "\n\t"  \
                        ".set   mips0"                          "\n"    \
                        : "=r" (__tmp)                                  \
-                       : "0" (__val), "m" (*__mem));                   \
+                       : "0" (__val), "R" (*__mem));                   \
                if (irq)                                                \
                        local_irq_restore(__flags);                     \
        } else                                                          \
@@ -355,12 +359,16 @@ static inline type pfx##read##bwlq(const volatile void __iomem *mem)      \
                        local_irq_save(__flags);                        \
                __asm__ __volatile__(                                   \
                        ".set   mips3"          "\t\t# __readq" "\n\t"  \
+                       ".set   push"                           "\n\t"  \
+                       ".set   noreorder"                      "\n\t"  \
+                       ".set   nomacro"                        "\n\t"  \
                        "ld     %L0, %1"                        "\n\t"  \
+                       ".set   pop"                            "\n\t"  \
                        "dsra32 %M0, %L0, 0"                    "\n\t"  \
                        "sll    %L0, %L0, 0"                    "\n\t"  \
                        ".set   mips0"                          "\n"    \
                        : "=r" (__val)                                  \
-                       : "m" (*__mem));                                \
+                       : "R" (*__mem));                                \
                if (irq)                                                \
                        local_irq_restore(__flags);                     \
        } else {                                                        \
index 7919d76..07d3fad 100644 (file)
@@ -201,7 +201,6 @@ static inline void ar7_device_off(u32 bit)
 }
 
 int __init ar7_gpio_init(void);
-
-int __init ar7_gpio_init(void);
+void __init ar7_init_clocks(void);
 
 #endif /* __AR7_H__ */
index c58ebd8..9759588 100644 (file)
@@ -12,6 +12,7 @@
 #define __NVRAM_H
 
 #include <linux/types.h>
+#include <linux/kernel.h>
 
 struct nvram_header {
        u32 magic;
@@ -36,4 +37,10 @@ struct nvram_header {
 
 extern int nvram_getenv(char *name, char *val, size_t val_len);
 
+static inline void nvram_parse_macaddr(char *buf, u8 *macaddr)
+{
+       sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &macaddr[0], &macaddr[1],
+              &macaddr[2], &macaddr[3], &macaddr[4], &macaddr[5]);
+}
+
 #endif
index 5742bb4..5c0a357 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 2009 Qi Hardware inc.,
  * Author: Xiangfu Liu <xiangfu@qi-hardware.com>
- * Copyright 2010, Lars-Petrer Clausen <lars@metafoo.de>
+ * Copyright 2010, Lars-Peter Clausen <lars@metafoo.de>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 or later
@@ -235,7 +235,7 @@ static const unsigned int qi_lb60_keypad_rows[] = {
        QI_LB60_GPIO_KEYIN(3),
        QI_LB60_GPIO_KEYIN(4),
        QI_LB60_GPIO_KEYIN(5),
-       QI_LB60_GPIO_KEYIN(7),
+       QI_LB60_GPIO_KEYIN(6),
        QI_LB60_GPIO_KEYIN8,
 };
 
index 95bc2b5..1cc9e54 100644 (file)
@@ -208,7 +208,7 @@ struct platform_device jz4740_i2s_device = {
 
 /* PCM */
 struct platform_device jz4740_pcm_device = {
-       .name           = "jz4740-pcm",
+       .name           = "jz4740-pcm-audio",
        .id             = -1,
 };
 
index cfeac15..4a70407 100644 (file)
@@ -23,7 +23,7 @@
 #include <asm/bootinfo.h>
 #include <asm/mach-jz4740/base.h>
 
-void jz4740_init_cmdline(int argc, char *argv[])
+static __init void jz4740_init_cmdline(int argc, char *argv[])
 {
        unsigned int count = COMMAND_LINE_SIZE - 1;
        int i;
index 2f4d7a9..98c5a97 100644 (file)
@@ -32,7 +32,7 @@ static int mips_next_event(unsigned long delta,
        cnt = read_c0_count();
        cnt += delta;
        write_c0_compare(cnt);
-       res = ((int)(read_c0_count() - cnt) > 0) ? -ETIME : 0;
+       res = ((int)(read_c0_count() - cnt) >= 0) ? -ETIME : 0;
        return res;
 }
 
index 71620e1..68dae7b 100644 (file)
@@ -905,7 +905,8 @@ static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu)
 {
        decode_configs(c);
        switch (c->processor_id & 0xff00) {
-       case PRID_IMP_BMIPS32:
+       case PRID_IMP_BMIPS32_REV4:
+       case PRID_IMP_BMIPS32_REV8:
                c->cputype = CPU_BMIPS32;
                __cpu_name[cpu] = "Broadcom BMIPS32";
                break;
@@ -933,10 +934,6 @@ static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu)
                __cpu_name[cpu] = "Broadcom BMIPS5000";
                c->options |= MIPS_CPU_ULRI;
                break;
-       case PRID_IMP_BMIPS4KC:
-               c->cputype = CPU_4KC;
-               __cpu_name[cpu] = "MIPS 4Kc";
-               break;
        }
 }
 
index 6343b4a..876a75c 100644 (file)
@@ -251,14 +251,15 @@ SYSCALL_DEFINE5(n32_msgrcv, int, msqid, u32, msgp, size_t, msgsz,
 
 SYSCALL_DEFINE1(32_personality, unsigned long, personality)
 {
+       unsigned int p = personality & 0xffffffff;
        int ret;
-       personality &= 0xffffffff;
+
        if (personality(current->personality) == PER_LINUX32 &&
-           personality == PER_LINUX)
-               personality = PER_LINUX32;
-       ret = sys_personality(personality);
-       if (ret == PER_LINUX32)
-               ret = PER_LINUX;
+           personality(p) == PER_LINUX)
+               p = (p & ~PER_MASK) | PER_LINUX32;
+       ret = sys_personality(p);
+       if (ret != -1 && personality(ret) == PER_LINUX32)
+               ret = (ret & ~PER_MASK) | PER_LINUX;
        return ret;
 }
 
index 9996094..ae167df 100644 (file)
@@ -142,7 +142,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
        childregs->regs[7] = 0; /* Clear error flag */
 
        childregs->regs[2] = 0; /* Child gets zero as return value */
-       regs->regs[2] = p->pid;
 
        if (childregs->cp0_status & ST0_CU0) {
                childregs->regs[28] = (unsigned long) ti;
index e000b27..9dbe583 100644 (file)
@@ -100,7 +100,7 @@ void __init device_tree_init(void)
                return;
 
        base = virt_to_phys((void *)initial_boot_params);
-       size = initial_boot_params->totalsize;
+       size = be32_to_cpu(initial_boot_params->totalsize);
 
        /* Before we do anything, lets reserve the dt blob */
        reserve_mem_mach(base, size);
index 43e7cdc..c0e8141 100644 (file)
@@ -153,7 +153,7 @@ static void __cpuinit vsmp_init_secondary(void)
 {
        extern int gic_present;
 
-       /* This is Malta specific: IPI,performance and timer inetrrupts */
+       /* This is Malta specific: IPI,performance and timer interrupts */
        if (gic_present)
                change_c0_status(ST0_IM, STATUSF_IP3 | STATUSF_IP4 |
                                         STATUSF_IP6 | STATUSF_IP7);
index 8e9fbe7..e971043 100644 (file)
@@ -83,7 +83,8 @@ extern asmlinkage void handle_mcheck(void);
 extern asmlinkage void handle_reserved(void);
 
 extern int fpu_emulator_cop1Handler(struct pt_regs *xcp,
-       struct mips_fpu_struct *ctx, int has_fpu);
+                                   struct mips_fpu_struct *ctx, int has_fpu,
+                                   void *__user *fault_addr);
 
 void (*board_be_init)(void);
 int (*board_be_handler)(struct pt_regs *regs, int is_fixup);
@@ -661,12 +662,36 @@ asmlinkage void do_ov(struct pt_regs *regs)
        force_sig_info(SIGFPE, &info, current);
 }
 
+static int process_fpemu_return(int sig, void __user *fault_addr)
+{
+       if (sig == SIGSEGV || sig == SIGBUS) {
+               struct siginfo si = {0};
+               si.si_addr = fault_addr;
+               si.si_signo = sig;
+               if (sig == SIGSEGV) {
+                       if (find_vma(current->mm, (unsigned long)fault_addr))
+                               si.si_code = SEGV_ACCERR;
+                       else
+                               si.si_code = SEGV_MAPERR;
+               } else {
+                       si.si_code = BUS_ADRERR;
+               }
+               force_sig_info(sig, &si, current);
+               return 1;
+       } else if (sig) {
+               force_sig(sig, current);
+               return 1;
+       } else {
+               return 0;
+       }
+}
+
 /*
  * XXX Delayed fp exceptions when doing a lazy ctx switch XXX
  */
 asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
 {
-       siginfo_t info;
+       siginfo_t info = {0};
 
        if (notify_die(DIE_FP, "FP exception", regs, 0, regs_to_trapnr(regs), SIGFPE)
            == NOTIFY_STOP)
@@ -675,6 +700,7 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
 
        if (fcr31 & FPU_CSR_UNI_X) {
                int sig;
+               void __user *fault_addr = NULL;
 
                /*
                 * Unimplemented operation exception.  If we've got the full
@@ -690,7 +716,8 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
                lose_fpu(1);
 
                /* Run the emulator */
-               sig = fpu_emulator_cop1Handler(regs, &current->thread.fpu, 1);
+               sig = fpu_emulator_cop1Handler(regs, &current->thread.fpu, 1,
+                                              &fault_addr);
 
                /*
                 * We can't allow the emulated instruction to leave any of
@@ -702,8 +729,7 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
                own_fpu(1);     /* Using the FPU again.  */
 
                /* If something went wrong, signal */
-               if (sig)
-                       force_sig(sig, current);
+               process_fpemu_return(sig, fault_addr);
 
                return;
        } else if (fcr31 & FPU_CSR_INV_X)
@@ -996,11 +1022,11 @@ asmlinkage void do_cpu(struct pt_regs *regs)
 
                if (!raw_cpu_has_fpu) {
                        int sig;
+                       void __user *fault_addr = NULL;
                        sig = fpu_emulator_cop1Handler(regs,
-                                               &current->thread.fpu, 0);
-                       if (sig)
-                               force_sig(sig, current);
-                       else
+                                                      &current->thread.fpu,
+                                                      0, &fault_addr);
+                       if (!process_fpemu_return(sig, fault_addr))
                                mt_ase_fp_affinity();
                }
 
index 3eb3cde..6a1fdfe 100644 (file)
@@ -1092,6 +1092,10 @@ static int vpe_open(struct inode *inode, struct file *filp)
 
        /* this of-course trashes what was there before... */
        v->pbuffer = vmalloc(P_SIZE);
+       if (!v->pbuffer) {
+               pr_warning("VPE loader: unable to allocate memory\n");
+               return -ENOMEM;
+       }
        v->plen = P_SIZE;
        v->load_addr = NULL;
        v->len = 0;
@@ -1149,10 +1153,9 @@ static int vpe_release(struct inode *inode, struct file *filp)
        if (ret < 0)
                v->shared_ptr = NULL;
 
-       // cleanup any temp buffers
-       if (v->pbuffer)
-               vfree(v->pbuffer);
+       vfree(v->pbuffer);
        v->plen = 0;
+
        return ret;
 }
 
@@ -1169,11 +1172,6 @@ static ssize_t vpe_write(struct file *file, const char __user * buffer,
        if (v == NULL)
                return -ENODEV;
 
-       if (v->pbuffer == NULL) {
-               printk(KERN_ERR "VPE loader: no buffer for program\n");
-               return -ENOMEM;
-       }
-
        if ((count + v->len) > v->plen) {
                printk(KERN_WARNING
                       "VPE loader: elf size too big. Perhaps strip uneeded symbols\n");
index 77dc3b2..606c8a9 100644 (file)
@@ -161,16 +161,16 @@ FEXPORT(__bzero)
 
 .Lfwd_fixup:
        PTR_L           t0, TI_TASK($28)
-       LONG_L          t0, THREAD_BUADDR(t0)
        andi            a2, 0x3f
+       LONG_L          t0, THREAD_BUADDR(t0)
        LONG_ADDU       a2, t1
        jr              ra
         LONG_SUBU      a2, t0
 
 .Lpartial_fixup:
        PTR_L           t0, TI_TASK($28)
-       LONG_L          t0, THREAD_BUADDR(t0)
        andi            a2, LONGMASK
+       LONG_L          t0, THREAD_BUADDR(t0)
        LONG_ADDU       a2, t1
        jr              ra
         LONG_SUBU      a2, t0
index ae4cff9..11b193f 100644 (file)
@@ -29,9 +29,9 @@ unsigned long memsize, highmemsize;
 
 #define parse_even_earlier(res, option, p)                             \
 do {                                                                   \
+       int ret;                                                        \
        if (strncmp(option, (char *)p, strlen(option)) == 0)            \
-                       strict_strtol((char *)p + strlen(option"="),    \
-                                       10, &res);                      \
+               ret = strict_strtol((char *)p + strlen(option"="), 10, &res); \
 } while (0)
 
 void __init prom_init_env(void)
index b2ad1b0..d32cb05 100644 (file)
@@ -64,7 +64,7 @@ static int fpu_emu(struct pt_regs *, struct mips_fpu_struct *,
 
 #if __mips >= 4 && __mips != 32
 static int fpux_emu(struct pt_regs *,
-       struct mips_fpu_struct *, mips_instruction);
+       struct mips_fpu_struct *, mips_instruction, void *__user *);
 #endif
 
 /* Further private data for which no space exists in mips_fpu_struct */
@@ -208,16 +208,23 @@ static inline int cop1_64bit(struct pt_regs *xcp)
  * Two instructions if the instruction is in a branch delay slot.
  */
 
-static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
+static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
+                      void *__user *fault_addr)
 {
        mips_instruction ir;
        unsigned long emulpc, contpc;
        unsigned int cond;
 
-       if (get_user(ir, (mips_instruction __user *) xcp->cp0_epc)) {
+       if (!access_ok(VERIFY_READ, xcp->cp0_epc, sizeof(mips_instruction))) {
                MIPS_FPU_EMU_INC_STATS(errors);
+               *fault_addr = (mips_instruction __user *)xcp->cp0_epc;
                return SIGBUS;
        }
+       if (__get_user(ir, (mips_instruction __user *) xcp->cp0_epc)) {
+               MIPS_FPU_EMU_INC_STATS(errors);
+               *fault_addr = (mips_instruction __user *)xcp->cp0_epc;
+               return SIGSEGV;
+       }
 
        /* XXX NEC Vr54xx bug workaround */
        if ((xcp->cp0_cause & CAUSEF_BD) && !isBranchInstr(&ir))
@@ -245,10 +252,16 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
 #endif
                        return SIGILL;
                }
-               if (get_user(ir, (mips_instruction __user *) emulpc)) {
+               if (!access_ok(VERIFY_READ, emulpc, sizeof(mips_instruction))) {
                        MIPS_FPU_EMU_INC_STATS(errors);
+                       *fault_addr = (mips_instruction __user *)emulpc;
                        return SIGBUS;
                }
+               if (__get_user(ir, (mips_instruction __user *) emulpc)) {
+                       MIPS_FPU_EMU_INC_STATS(errors);
+                       *fault_addr = (mips_instruction __user *)emulpc;
+                       return SIGSEGV;
+               }
                /* __compute_return_epc() will have updated cp0_epc */
                contpc = xcp->cp0_epc;
                /* In order not to confuse ptrace() et al, tweak context */
@@ -269,10 +282,17 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
                u64 val;
 
                MIPS_FPU_EMU_INC_STATS(loads);
-               if (get_user(val, va)) {
+
+               if (!access_ok(VERIFY_READ, va, sizeof(u64))) {
                        MIPS_FPU_EMU_INC_STATS(errors);
+                       *fault_addr = va;
                        return SIGBUS;
                }
+               if (__get_user(val, va)) {
+                       MIPS_FPU_EMU_INC_STATS(errors);
+                       *fault_addr = va;
+                       return SIGSEGV;
+               }
                DITOREG(val, MIPSInst_RT(ir));
                break;
        }
@@ -284,10 +304,16 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
 
                MIPS_FPU_EMU_INC_STATS(stores);
                DIFROMREG(val, MIPSInst_RT(ir));
-               if (put_user(val, va)) {
+               if (!access_ok(VERIFY_WRITE, va, sizeof(u64))) {
                        MIPS_FPU_EMU_INC_STATS(errors);
+                       *fault_addr = va;
                        return SIGBUS;
                }
+               if (__put_user(val, va)) {
+                       MIPS_FPU_EMU_INC_STATS(errors);
+                       *fault_addr = va;
+                       return SIGSEGV;
+               }
                break;
        }
 
@@ -297,10 +323,16 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
                u32 val;
 
                MIPS_FPU_EMU_INC_STATS(loads);
-               if (get_user(val, va)) {
+               if (!access_ok(VERIFY_READ, va, sizeof(u32))) {
                        MIPS_FPU_EMU_INC_STATS(errors);
+                       *fault_addr = va;
                        return SIGBUS;
                }
+               if (__get_user(val, va)) {
+                       MIPS_FPU_EMU_INC_STATS(errors);
+                       *fault_addr = va;
+                       return SIGSEGV;
+               }
                SITOREG(val, MIPSInst_RT(ir));
                break;
        }
@@ -312,10 +344,16 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
 
                MIPS_FPU_EMU_INC_STATS(stores);
                SIFROMREG(val, MIPSInst_RT(ir));
-               if (put_user(val, va)) {
+               if (!access_ok(VERIFY_WRITE, va, sizeof(u32))) {
                        MIPS_FPU_EMU_INC_STATS(errors);
+                       *fault_addr = va;
                        return SIGBUS;
                }
+               if (__put_user(val, va)) {
+                       MIPS_FPU_EMU_INC_STATS(errors);
+                       *fault_addr = va;
+                       return SIGSEGV;
+               }
                break;
        }
 
@@ -440,11 +478,18 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
                                contpc = (xcp->cp0_epc +
                                        (MIPSInst_SIMM(ir) << 2));
 
-                               if (get_user(ir,
-                                   (mips_instruction __user *) xcp->cp0_epc)) {
+                               if (!access_ok(VERIFY_READ, xcp->cp0_epc,
+                                              sizeof(mips_instruction))) {
                                        MIPS_FPU_EMU_INC_STATS(errors);
+                                       *fault_addr = (mips_instruction __user *)xcp->cp0_epc;
                                        return SIGBUS;
                                }
+                               if (__get_user(ir,
+                                   (mips_instruction __user *) xcp->cp0_epc)) {
+                                       MIPS_FPU_EMU_INC_STATS(errors);
+                                       *fault_addr = (mips_instruction __user *)xcp->cp0_epc;
+                                       return SIGSEGV;
+                               }
 
                                switch (MIPSInst_OPCODE(ir)) {
                                case lwc1_op:
@@ -506,9 +551,8 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
 
 #if __mips >= 4 && __mips != 32
        case cop1x_op:{
-               int sig;
-
-               if ((sig = fpux_emu(xcp, ctx, ir)))
+               int sig = fpux_emu(xcp, ctx, ir, fault_addr);
+               if (sig)
                        return sig;
                break;
        }
@@ -604,7 +648,7 @@ DEF3OP(nmadd, dp, ieee754dp_mul, ieee754dp_add, ieee754dp_neg);
 DEF3OP(nmsub, dp, ieee754dp_mul, ieee754dp_sub, ieee754dp_neg);
 
 static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
-       mips_instruction ir)
+       mips_instruction ir, void *__user *fault_addr)
 {
        unsigned rcsr = 0;      /* resulting csr */
 
@@ -624,10 +668,16 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
                                xcp->regs[MIPSInst_FT(ir)]);
 
                        MIPS_FPU_EMU_INC_STATS(loads);
-                       if (get_user(val, va)) {
+                       if (!access_ok(VERIFY_READ, va, sizeof(u32))) {
                                MIPS_FPU_EMU_INC_STATS(errors);
+                               *fault_addr = va;
                                return SIGBUS;
                        }
+                       if (__get_user(val, va)) {
+                               MIPS_FPU_EMU_INC_STATS(errors);
+                               *fault_addr = va;
+                               return SIGSEGV;
+                       }
                        SITOREG(val, MIPSInst_FD(ir));
                        break;
 
@@ -638,10 +688,16 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
                        MIPS_FPU_EMU_INC_STATS(stores);
 
                        SIFROMREG(val, MIPSInst_FS(ir));
-                       if (put_user(val, va)) {
+                       if (!access_ok(VERIFY_WRITE, va, sizeof(u32))) {
                                MIPS_FPU_EMU_INC_STATS(errors);
+                               *fault_addr = va;
                                return SIGBUS;
                        }
+                       if (put_user(val, va)) {
+                               MIPS_FPU_EMU_INC_STATS(errors);
+                               *fault_addr = va;
+                               return SIGSEGV;
+                       }
                        break;
 
                case madd_s_op:
@@ -701,10 +757,16 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
                                xcp->regs[MIPSInst_FT(ir)]);
 
                        MIPS_FPU_EMU_INC_STATS(loads);
-                       if (get_user(val, va)) {
+                       if (!access_ok(VERIFY_READ, va, sizeof(u64))) {
                                MIPS_FPU_EMU_INC_STATS(errors);
+                               *fault_addr = va;
                                return SIGBUS;
                        }
+                       if (__get_user(val, va)) {
+                               MIPS_FPU_EMU_INC_STATS(errors);
+                               *fault_addr = va;
+                               return SIGSEGV;
+                       }
                        DITOREG(val, MIPSInst_FD(ir));
                        break;
 
@@ -714,10 +776,16 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
 
                        MIPS_FPU_EMU_INC_STATS(stores);
                        DIFROMREG(val, MIPSInst_FS(ir));
-                       if (put_user(val, va)) {
+                       if (!access_ok(VERIFY_WRITE, va, sizeof(u64))) {
                                MIPS_FPU_EMU_INC_STATS(errors);
+                               *fault_addr = va;
                                return SIGBUS;
                        }
+                       if (__put_user(val, va)) {
+                               MIPS_FPU_EMU_INC_STATS(errors);
+                               *fault_addr = va;
+                               return SIGSEGV;
+                       }
                        break;
 
                case madd_d_op:
@@ -1242,7 +1310,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
 }
 
 int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
-       int has_fpu)
+       int has_fpu, void *__user *fault_addr)
 {
        unsigned long oldepc, prevepc;
        mips_instruction insn;
@@ -1252,10 +1320,16 @@ int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
        do {
                prevepc = xcp->cp0_epc;
 
-               if (get_user(insn, (mips_instruction __user *) xcp->cp0_epc)) {
+               if (!access_ok(VERIFY_READ, xcp->cp0_epc, sizeof(mips_instruction))) {
                        MIPS_FPU_EMU_INC_STATS(errors);
+                       *fault_addr = (mips_instruction __user *)xcp->cp0_epc;
                        return SIGBUS;
                }
+               if (__get_user(insn, (mips_instruction __user *) xcp->cp0_epc)) {
+                       MIPS_FPU_EMU_INC_STATS(errors);
+                       *fault_addr = (mips_instruction __user *)xcp->cp0_epc;
+                       return SIGSEGV;
+               }
                if (insn == 0)
                        xcp->cp0_epc += 4;      /* skip nops */
                else {
@@ -1267,7 +1341,7 @@ int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
                         */
                        /* convert to ieee library modes */
                        ieee754_csr.rm = ieee_rm[ieee754_csr.rm];
-                       sig = cop1Emulate(xcp, ctx);
+                       sig = cop1Emulate(xcp, ctx, fault_addr);
                        /* revert to mips rounding mode */
                        ieee754_csr.rm = mips_rm[ieee754_csr.rm];
                }
index 4fc1a0f..21ea14e 100644 (file)
@@ -288,7 +288,7 @@ int mips_dma_supported(struct device *dev, u64 mask)
        return plat_dma_supported(dev, mask);
 }
 
-void mips_dma_cache_sync(struct device *dev, void *vaddr, size_t size,
+void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
                         enum dma_data_direction direction)
 {
        BUG_ON(direction == DMA_NONE);
@@ -298,6 +298,8 @@ void mips_dma_cache_sync(struct device *dev, void *vaddr, size_t size,
                __dma_sync((unsigned long)vaddr, size, direction);
 }
 
+EXPORT_SYMBOL(dma_cache_sync);
+
 static struct dma_map_ops mips_default_dma_map_ops = {
        .alloc_coherent = mips_dma_alloc_coherent,
        .free_coherent = mips_dma_free_coherent,
index 505feca..9cca8de 100644 (file)
@@ -68,6 +68,9 @@ static struct bcache_ops mips_sc_ops = {
  */
 static inline int mips_sc_is_activated(struct cpuinfo_mips *c)
 {
+       unsigned int config2 = read_c0_config2();
+       unsigned int tmp;
+
        /* Check the bypass bit (L2B) */
        switch (c->cputype) {
        case CPU_34K:
@@ -83,6 +86,7 @@ static inline int mips_sc_is_activated(struct cpuinfo_mips *c)
                c->scache.linesz = 2 << tmp;
        else
                return 0;
+       return 1;
 }
 
 static inline int __init mips_sc_probe(void)
index b7f1d9c..434d7b1 100644 (file)
@@ -65,11 +65,15 @@ static unsigned char readb_outer_space(unsigned long long phys)
 
        __asm__ __volatile__ (
        "       .set    mips3           \n"
+       "       .set    push            \n"
+       "       .set    noreorder       \n"
+       "       .set    nomacro         \n"
        "       ld      %0, %1          \n"
+       "       .set    pop             \n"
        "       lbu     %0, (%0)        \n"
        "       .set    mips0           \n"
        : "=r" (res)
-       : "m" (vaddr));
+       : "R" (vaddr));
 
        write_c0_status(sr);
        ssnop_4();
@@ -89,11 +93,15 @@ static void writeb_outer_space(unsigned long long phys, unsigned char c)
 
        __asm__ __volatile__ (
        "       .set    mips3           \n"
+       "       .set    push            \n"
+       "       .set    noreorder       \n"
+       "       .set    nomacro         \n"
        "       ld      %0, %1          \n"
+       "       .set    pop             \n"
        "       sb      %2, (%0)        \n"
        "       .set    mips0           \n"
        : "=&r" (tmp)
-       : "m" (vaddr), "r" (c));
+       : "R" (vaddr), "r" (c));
 
        write_c0_status(sr);
        ssnop_4();
index c308989..41707a2 100644 (file)
@@ -82,7 +82,7 @@ int swarm_be_handler(struct pt_regs *regs, int is_fixup)
 enum swarm_rtc_type {
        RTC_NONE,
        RTC_XICOR,
-       RTC_M4LT81
+       RTC_M41T81,
 };
 
 enum swarm_rtc_type swarm_rtc_type;
@@ -96,7 +96,7 @@ void read_persistent_clock(struct timespec *ts)
                sec = xicor_get_time();
                break;
 
-       case RTC_M4LT81:
+       case RTC_M41T81:
                sec = m41t81_get_time();
                break;
 
@@ -115,7 +115,7 @@ int rtc_mips_set_time(unsigned long sec)
        case RTC_XICOR:
                return xicor_set_time(sec);
 
-       case RTC_M4LT81:
+       case RTC_M41T81:
                return m41t81_set_time(sec);
 
        case RTC_NONE:
@@ -141,7 +141,7 @@ void __init plat_mem_setup(void)
        if (xicor_probe())
                swarm_rtc_type = RTC_XICOR;
        if (m41t81_probe())
-               swarm_rtc_type = RTC_M4LT81;
+               swarm_rtc_type = RTC_M41T81;
 
 #ifdef CONFIG_VT
        screen_info = (struct screen_info) {
diff --git a/arch/mn10300/include/asm/syscall.h b/arch/mn10300/include/asm/syscall.h
new file mode 100644 (file)
index 0000000..b44b0bb
--- /dev/null
@@ -0,0 +1,117 @@
+/* Access to user system call parameters and results
+ *
+ * See asm-generic/syscall.h for function descriptions.
+ *
+ * Copyright (C) 2010 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#ifndef _ASM_SYSCALL_H
+#define _ASM_SYSCALL_H
+
+#include <linux/sched.h>
+#include <linux/err.h>
+
+extern const unsigned long sys_call_table[];
+
+static inline int syscall_get_nr(struct task_struct *task, struct pt_regs *regs)
+{
+       return regs->orig_d0;
+}
+
+static inline void syscall_rollback(struct task_struct *task,
+                                   struct pt_regs *regs)
+{
+       regs->d0 = regs->orig_d0;
+}
+
+static inline long syscall_get_error(struct task_struct *task,
+                                    struct pt_regs *regs)
+{
+       unsigned long error = regs->d0;
+       return IS_ERR_VALUE(error) ? error : 0;
+}
+
+static inline long syscall_get_return_value(struct task_struct *task,
+                                           struct pt_regs *regs)
+{
+       return regs->d0;
+}
+
+static inline void syscall_set_return_value(struct task_struct *task,
+                                           struct pt_regs *regs,
+                                           int error, long val)
+{
+       regs->d0 = (long) error ?: val;
+}
+
+static inline void syscall_get_arguments(struct task_struct *task,
+                                        struct pt_regs *regs,
+                                        unsigned int i, unsigned int n,
+                                        unsigned long *args)
+{
+       switch (i) {
+       case 0:
+               if (!n--) break;
+               *args++ = regs->a0;
+       case 1:
+               if (!n--) break;
+               *args++ = regs->d1;
+       case 2:
+               if (!n--) break;
+               *args++ = regs->a3;
+       case 3:
+               if (!n--) break;
+               *args++ = regs->a2;
+       case 4:
+               if (!n--) break;
+               *args++ = regs->d3;
+       case 5:
+               if (!n--) break;
+               *args++ = regs->d2;
+       case 6:
+               if (!n--) break;
+       default:
+               BUG();
+               break;
+       }
+}
+
+static inline void syscall_set_arguments(struct task_struct *task,
+                                        struct pt_regs *regs,
+                                        unsigned int i, unsigned int n,
+                                        const unsigned long *args)
+{
+       switch (i) {
+       case 0:
+               if (!n--) break;
+               regs->a0 = *args++;
+       case 1:
+               if (!n--) break;
+               regs->d1 = *args++;
+       case 2:
+               if (!n--) break;
+               regs->a3 = *args++;
+       case 3:
+               if (!n--) break;
+               regs->a2 = *args++;
+       case 4:
+               if (!n--) break;
+               regs->d3 = *args++;
+       case 5:
+               if (!n--) break;
+               regs->d2 = *args++;
+       case 6:
+               if (!n--) break;
+       default:
+               BUG();
+               break;
+       }
+}
+
+#endif /* _ASM_SYSCALL_H */
index 0d5d63c..f28dc99 100644 (file)
@@ -73,7 +73,8 @@ void gdbstub_io_init(void)
        GDBPORT_SERIAL_IER = UART_IER_RDI | UART_IER_RLSI;
 
        /* permit level 0 IRQs to take place */
-       local_change_intr_mask_level(NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1));
+       arch_local_change_intr_mask_level(
+               NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1));
 }
 
 /*
index 97dfda2..abdeea1 100644 (file)
@@ -87,7 +87,8 @@ void __init gdbstub_io_init(void)
        tmp = *gdbstub_port->_control;
 
        /* permit level 0 IRQs only */
-       local_change_intr_mask_level(NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1));
+       arch_local_change_intr_mask_level(
+               NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1));
 }
 
 /*
index a5fc3f0..b169d99 100644 (file)
@@ -1194,7 +1194,8 @@ static int gdbstub(struct pt_regs *regs, enum exception_code excep)
 
        asm volatile("mov mdr,%0" : "=d"(mdr));
        local_save_flags(epsw);
-       local_change_intr_mask_level(NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1));
+       arch_local_change_intr_mask_level(
+               NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1));
 
        gdbstub_store_fpu();
 
index f860a34..75da468 100644 (file)
@@ -40,21 +40,17 @@ unsigned long long sched_clock(void)
                unsigned long long ll;
                unsigned l[2];
        } tsc64, result;
-       unsigned long tsc, tmp;
+       unsigned long tmp;
        unsigned product[3]; /* 96-bit intermediate value */
 
        /* cnt32_to_63() is not safe with preemption */
        preempt_disable();
 
-       /* read the TSC value
-        */
-       tsc = get_cycles();
-
-       /* expand to 64-bits.
+       /* expand the tsc to 64-bits.
         * - sched_clock() must be called once a minute or better or the
         *   following will go horribly wrong - see cnt32_to_63()
         */
-       tsc64.ll = cnt32_to_63(tsc) & 0x7fffffffffffffffULL;
+       tsc64.ll = cnt32_to_63(get_cycles()) & 0x7fffffffffffffffULL;
 
        preempt_enable();
 
index 5024f64..d7d94b8 100644 (file)
@@ -75,9 +75,6 @@ static void cpu_unmask_irq(unsigned int irq)
        smp_send_all_nop();
 }
 
-void no_ack_irq(unsigned int irq) { }
-void no_end_irq(unsigned int irq) { }
-
 void cpu_ack_irq(unsigned int irq)
 {
        unsigned long mask = EIEM_MASK(irq);
@@ -241,7 +238,7 @@ int cpu_claim_irq(unsigned int irq, struct irq_chip *type, void *data)
 
        /* for iosapic interrupts */
        if (type) {
-               set_irq_chip_and_handler(irq, type, handle_level_irq);
+               set_irq_chip_and_handler(irq, type, handle_percpu_irq);
                set_irq_chip_data(irq, data);
                cpu_unmask_irq(irq);
        }
@@ -392,7 +389,7 @@ static void claim_cpu_irqs(void)
        int i;
        for (i = CPU_IRQ_BASE; i <= CPU_IRQ_MAX; i++) {
                set_irq_chip_and_handler(i, &cpu_interrupt_type,
-                       handle_level_irq);
+                                        handle_percpu_irq);
        }
 
        set_irq_handler(TIMER_IRQ, handle_percpu_irq);
index 35c827e..609a331 100644 (file)
@@ -98,7 +98,6 @@ void
 sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
 {
        struct rt_sigframe __user *frame;
-       struct siginfo si;
        sigset_t set;
        unsigned long usp = (regs->gr[30] & ~(0x01UL));
        unsigned long sigframe_size = PARISC_RT_SIGFRAME_SIZE;
@@ -178,13 +177,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
 
 give_sigsegv:
        DBG(1,"sys_rt_sigreturn: Sending SIGSEGV\n");
-       si.si_signo = SIGSEGV;
-       si.si_errno = 0;
-       si.si_code = SI_KERNEL;
-       si.si_pid = task_pid_vnr(current);
-       si.si_uid = current_uid();
-       si.si_addr = &frame->uc;
-       force_sig_info(SIGSEGV, &si, current);
+       force_sig(SIGSEGV, current);
        return;
 }
 
index 2c7e801..6a3997f 100644 (file)
@@ -92,7 +92,7 @@ static void pte_free_rcu_callback(struct rcu_head *head)
 
 static void pte_free_submit(struct pte_freelist_batch *batch)
 {
-       call_rcu(&batch->rcu, pte_free_rcu_callback);
+       call_rcu_sched(&batch->rcu, pte_free_rcu_callback);
 }
 
 void pgtable_free_tlb(struct mmu_gather *tlb, void *table, unsigned shift)
index 56c8687..7eff9b7 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/kernel_stat.h>
 #include <linux/rcupdate.h>
 #include <linux/posix-timers.h>
+#include <linux/cpu.h>
 
 #include <asm/s390_ext.h>
 #include <asm/timer.h>
@@ -566,6 +567,23 @@ void init_cpu_vtimer(void)
        __ctl_set_bit(0,10);
 }
 
+static int __cpuinit s390_nohz_notify(struct notifier_block *self,
+                                     unsigned long action, void *hcpu)
+{
+       struct s390_idle_data *idle;
+       long cpu = (long) hcpu;
+
+       idle = &per_cpu(s390_idle, cpu);
+       switch (action) {
+       case CPU_DYING:
+       case CPU_DYING_FROZEN:
+               idle->nohz_delay = 0;
+       default:
+               break;
+       }
+       return NOTIFY_OK;
+}
+
 void __init vtime_init(void)
 {
        /* request the cpu timer external interrupt */
@@ -574,5 +592,6 @@ void __init vtime_init(void)
 
        /* Enable cpu timer interrupts on the boot cpu. */
        init_cpu_vtimer();
+       cpu_notifier(s390_nohz_notify, 0);
 }
 
index 7f217b3..2e9d78d 100644 (file)
@@ -22,7 +22,8 @@ config SUPERH
        select HAVE_SPARSE_IRQ
        select RTC_LIB
        select GENERIC_ATOMIC64
-       select GENERIC_HARDIRQS_NO_DEPRECATED
+       # Support the deprecated APIs until MFD and GPIOLIB catch up.
+       select GENERIC_HARDIRQS_NO_DEPRECATED if !MFD_SUPPORT && !GPIOLIB
        help
          The SuperH is a RISC processor targeted for use in embedded systems
          and consumer electronics; it was also used in the Sega Dreamcast
index 2eaeb9e..f48c492 100644 (file)
@@ -720,32 +720,6 @@ static struct platform_device camera_devices[] = {
 };
 
 /* FSI */
-/*
- * FSI-B use external clock which came from da7210.
- * So, we should change parent of fsi
- */
-#define FCLKBCR                0xa415000c
-static void fsimck_init(struct clk *clk)
-{
-       u32 status = __raw_readl(clk->enable_reg);
-
-       /* use external clock */
-       status &= ~0x000000ff;
-       status |= 0x00000080;
-
-       __raw_writel(status, clk->enable_reg);
-}
-
-static struct clk_ops fsimck_clk_ops = {
-       .init = fsimck_init,
-};
-
-static struct clk fsimckb_clk = {
-       .ops            = &fsimck_clk_ops,
-       .enable_reg     = (void __iomem *)FCLKBCR,
-       .rate           = 0, /* unknown */
-};
-
 static struct sh_fsi_platform_info fsi_info = {
        .portb_flags = SH_FSI_BRS_INV |
                       SH_FSI_OUT_SLAVE_MODE |
@@ -1264,10 +1238,10 @@ static int __init arch_setup(void)
        /* change parent of FSI B */
        clk = clk_get(NULL, "fsib_clk");
        if (!IS_ERR(clk)) {
-               clk_register(&fsimckb_clk);
-               clk_set_parent(clk, &fsimckb_clk);
-               clk_set_rate(clk, 11000);
-               clk_set_rate(&fsimckb_clk, 11000);
+               /* 48kHz dummy clock was used to make sure 1/1 divide */
+               clk_set_rate(&sh7724_fsimckb_clk, 48000);
+               clk_set_parent(clk, &sh7724_fsimckb_clk);
+               clk_set_rate(clk, 48000);
                clk_put(clk);
        }
 
index c31d228..527a0cd 100644 (file)
@@ -283,31 +283,6 @@ static struct platform_device ceu1_device = {
 };
 
 /* FSI */
-/*
- * FSI-A use external clock which came from ak464x.
- * So, we should change parent of fsi
- */
-#define FCLKACR                0xa4150008
-static void fsimck_init(struct clk *clk)
-{
-       u32 status = __raw_readl(clk->enable_reg);
-
-       /* use external clock */
-       status &= ~0x000000ff;
-       status |= 0x00000080;
-       __raw_writel(status, clk->enable_reg);
-}
-
-static struct clk_ops fsimck_clk_ops = {
-       .init = fsimck_init,
-};
-
-static struct clk fsimcka_clk = {
-       .ops            = &fsimck_clk_ops,
-       .enable_reg     = (void __iomem *)FCLKACR,
-       .rate           = 0, /* unknown */
-};
-
 /* change J20, J21, J22 pin to 1-2 connection to use slave mode */
 static struct sh_fsi_platform_info fsi_info = {
        .porta_flags = SH_FSI_BRS_INV |
@@ -852,37 +827,29 @@ static int __init devices_setup(void)
        gpio_request(GPIO_FN_KEYOUT0,     NULL);
 
        /* enable FSI */
-       gpio_request(GPIO_FN_FSIMCKB,    NULL);
        gpio_request(GPIO_FN_FSIMCKA,    NULL);
+       gpio_request(GPIO_FN_FSIIASD,    NULL);
        gpio_request(GPIO_FN_FSIOASD,    NULL);
        gpio_request(GPIO_FN_FSIIABCK,   NULL);
        gpio_request(GPIO_FN_FSIIALRCK,  NULL);
        gpio_request(GPIO_FN_FSIOABCK,   NULL);
        gpio_request(GPIO_FN_FSIOALRCK,  NULL);
        gpio_request(GPIO_FN_CLKAUDIOAO, NULL);
-       gpio_request(GPIO_FN_FSIIBSD,    NULL);
-       gpio_request(GPIO_FN_FSIOBSD,    NULL);
-       gpio_request(GPIO_FN_FSIIBBCK,   NULL);
-       gpio_request(GPIO_FN_FSIIBLRCK,  NULL);
-       gpio_request(GPIO_FN_FSIOBBCK,   NULL);
-       gpio_request(GPIO_FN_FSIOBLRCK,  NULL);
-       gpio_request(GPIO_FN_CLKAUDIOBO, NULL);
-       gpio_request(GPIO_FN_FSIIASD,    NULL);
 
        /* set SPU2 clock to 83.4 MHz */
        clk = clk_get(NULL, "spu_clk");
-       if (clk) {
+       if (!IS_ERR(clk)) {
                clk_set_rate(clk, clk_round_rate(clk, 83333333));
                clk_put(clk);
        }
 
        /* change parent of FSI A */
        clk = clk_get(NULL, "fsia_clk");
-       if (clk) {
-               clk_register(&fsimcka_clk);
-               clk_set_parent(clk, &fsimcka_clk);
-               clk_set_rate(clk, 11000);
-               clk_set_rate(&fsimcka_clk, 11000);
+       if (!IS_ERR(clk)) {
+               /* 48kHz dummy clock was used to make sure 1/1 divide */
+               clk_set_rate(&sh7724_fsimcka_clk, 48000);
+               clk_set_parent(clk, &sh7724_fsimcka_clk);
+               clk_set_rate(clk, 48000);
                clk_put(clk);
        }
 
index 1f4e562..82e1eab 100644 (file)
@@ -96,7 +96,7 @@ void kmap_coherent_init(void);
 void *kmap_coherent(struct page *page, unsigned long addr);
 void kunmap_coherent(void *kvaddr);
 
-#define PG_dcache_dirty        PG_arch_1
+#define PG_dcache_clean        PG_arch_1
 
 void cpu_cache_init(void);
 
index 903cd61..d6741fc 100644 (file)
 #define __NR_sendmsg           355
 #define __NR_recvmsg           356
 #define __NR_recvmmsg          357
+#define __NR_accept4           358
 
-#define NR_syscalls 358
+#define NR_syscalls 359
 
 #ifdef __KERNEL__
 
index 4c27b68..7eb4359 100644 (file)
@@ -303,4 +303,7 @@ enum {
        SHDMA_SLAVE_SDHI1_RX,
 };
 
+extern struct clk sh7724_fsimcka_clk;
+extern struct clk sh7724_fsimckb_clk;
+
 #endif /* __ASM_SH7724_H__ */
index 0fe2e93..271c0b3 100644 (file)
@@ -111,12 +111,21 @@ static struct clk div3_clk = {
        .parent         = &pll_clk,
 };
 
+/* External input clock (pin name: FSIMCKA/FSIMCKB ) */
+struct clk sh7724_fsimcka_clk = {
+};
+
+struct clk sh7724_fsimckb_clk = {
+};
+
 static struct clk *main_clks[] = {
        &r_clk,
        &extal_clk,
        &fll_clk,
        &pll_clk,
        &div3_clk,
+       &sh7724_fsimcka_clk,
+       &sh7724_fsimckb_clk,
 };
 
 static void div4_kick(struct clk *clk)
@@ -154,16 +163,38 @@ struct clk div4_clks[DIV4_NR] = {
        [DIV4_M1] = DIV4(FRQCRB, 4, 0x2f7c, CLK_ENABLE_ON_INIT),
 };
 
-enum { DIV6_V, DIV6_FA, DIV6_FB, DIV6_I, DIV6_S, DIV6_NR };
+enum { DIV6_V, DIV6_I, DIV6_S, DIV6_NR };
 
 static struct clk div6_clks[DIV6_NR] = {
        [DIV6_V] = SH_CLK_DIV6(&div3_clk, VCLKCR, 0),
-       [DIV6_FA] = SH_CLK_DIV6(&div3_clk, FCLKACR, 0),
-       [DIV6_FB] = SH_CLK_DIV6(&div3_clk, FCLKBCR, 0),
        [DIV6_I] = SH_CLK_DIV6(&div3_clk, IRDACLKCR, 0),
        [DIV6_S] = SH_CLK_DIV6(&div3_clk, SPUCLKCR, CLK_ENABLE_ON_INIT),
 };
 
+enum { DIV6_FA, DIV6_FB, DIV6_REPARENT_NR };
+
+/* Indices are important - they are the actual src selecting values */
+static struct clk *fclkacr_parent[] = {
+       [0] = &div3_clk,
+       [1] = NULL,
+       [2] = &sh7724_fsimcka_clk,
+       [3] = NULL,
+};
+
+static struct clk *fclkbcr_parent[] = {
+       [0] = &div3_clk,
+       [1] = NULL,
+       [2] = &sh7724_fsimckb_clk,
+       [3] = NULL,
+};
+
+static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = {
+       [DIV6_FA] = SH_CLK_DIV6_EXT(&div3_clk, FCLKACR, 0,
+                                     fclkacr_parent, ARRAY_SIZE(fclkacr_parent), 6, 2),
+       [DIV6_FB] = SH_CLK_DIV6_EXT(&div3_clk, FCLKBCR, 0,
+                                     fclkbcr_parent, ARRAY_SIZE(fclkbcr_parent), 6, 2),
+};
+
 static struct clk mstp_clks[HWBLK_NR] = {
        SH_HWBLK_CLK(HWBLK_TLB, &div4_clks[DIV4_I], CLK_ENABLE_ON_INIT),
        SH_HWBLK_CLK(HWBLK_IC, &div4_clks[DIV4_I], CLK_ENABLE_ON_INIT),
@@ -240,8 +271,8 @@ static struct clk_lookup lookups[] = {
 
        /* DIV6 clocks */
        CLKDEV_CON_ID("video_clk", &div6_clks[DIV6_V]),
-       CLKDEV_CON_ID("fsia_clk", &div6_clks[DIV6_FA]),
-       CLKDEV_CON_ID("fsib_clk", &div6_clks[DIV6_FB]),
+       CLKDEV_CON_ID("fsia_clk", &div6_reparent_clks[DIV6_FA]),
+       CLKDEV_CON_ID("fsib_clk", &div6_reparent_clks[DIV6_FB]),
        CLKDEV_CON_ID("irda_clk", &div6_clks[DIV6_I]),
        CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_S]),
 
@@ -375,6 +406,9 @@ int __init arch_clk_init(void)
        if (!ret)
                ret = sh_clk_div6_register(div6_clks, DIV6_NR);
 
+       if (!ret)
+               ret = sh_clk_div6_reparent_register(div6_reparent_clks, DIV6_REPARENT_NR);
+
        if (!ret)
                ret = sh_hwblk_clk_register(mstp_clks, HWBLK_NR);
 
index e872e81..6fc347e 100644 (file)
@@ -375,3 +375,4 @@ ENTRY(sys_call_table)
        .long sys_sendmsg               /* 355 */
        .long sys_recvmsg
        .long sys_recvmmsg
+       .long sys_accept4
index 2cfae81..92eb986 100644 (file)
@@ -114,7 +114,7 @@ static void sh4_flush_dcache_page(void *arg)
        struct address_space *mapping = page_mapping(page);
 
        if (mapping && !mapping_mapped(mapping))
-               set_bit(PG_dcache_dirty, &page->flags);
+               clear_bit(PG_dcache_clean, &page->flags);
        else
 #endif
                flush_cache_one(CACHE_OC_ADDRESS_ARRAY |
@@ -239,7 +239,7 @@ static void sh4_flush_cache_page(void *args)
                 * another ASID than the current one.
                 */
                map_coherent = (current_cpu_data.dcache.n_aliases &&
-                       !test_bit(PG_dcache_dirty, &page->flags) &&
+                       test_bit(PG_dcache_clean, &page->flags) &&
                        page_mapped(page));
                if (map_coherent)
                        vaddr = kmap_coherent(page, address);
index f498da1..7729cca 100644 (file)
@@ -139,7 +139,7 @@ static void sh7705_flush_dcache_page(void *arg)
        struct address_space *mapping = page_mapping(page);
 
        if (mapping && !mapping_mapped(mapping))
-               set_bit(PG_dcache_dirty, &page->flags);
+               clear_bit(PG_dcache_clean, &page->flags);
        else
                __flush_dcache_page(__pa(page_address(page)));
 }
index ba401d1..88d3dc3 100644 (file)
@@ -60,14 +60,14 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
                       unsigned long len)
 {
        if (boot_cpu_data.dcache.n_aliases && page_mapped(page) &&
-           !test_bit(PG_dcache_dirty, &page->flags)) {
+           test_bit(PG_dcache_clean, &page->flags)) {
                void *vto = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
                memcpy(vto, src, len);
                kunmap_coherent(vto);
        } else {
                memcpy(dst, src, len);
                if (boot_cpu_data.dcache.n_aliases)
-                       set_bit(PG_dcache_dirty, &page->flags);
+                       clear_bit(PG_dcache_clean, &page->flags);
        }
 
        if (vma->vm_flags & VM_EXEC)
@@ -79,14 +79,14 @@ void copy_from_user_page(struct vm_area_struct *vma, struct page *page,
                         unsigned long len)
 {
        if (boot_cpu_data.dcache.n_aliases && page_mapped(page) &&
-           !test_bit(PG_dcache_dirty, &page->flags)) {
+           test_bit(PG_dcache_clean, &page->flags)) {
                void *vfrom = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
                memcpy(dst, vfrom, len);
                kunmap_coherent(vfrom);
        } else {
                memcpy(dst, src, len);
                if (boot_cpu_data.dcache.n_aliases)
-                       set_bit(PG_dcache_dirty, &page->flags);
+                       clear_bit(PG_dcache_clean, &page->flags);
        }
 }
 
@@ -98,7 +98,7 @@ void copy_user_highpage(struct page *to, struct page *from,
        vto = kmap_atomic(to, KM_USER1);
 
        if (boot_cpu_data.dcache.n_aliases && page_mapped(from) &&
-           !test_bit(PG_dcache_dirty, &from->flags)) {
+           test_bit(PG_dcache_clean, &from->flags)) {
                vfrom = kmap_coherent(from, vaddr);
                copy_page(vto, vfrom);
                kunmap_coherent(vfrom);
@@ -141,7 +141,7 @@ void __update_cache(struct vm_area_struct *vma,
 
        page = pfn_to_page(pfn);
        if (pfn_valid(pfn)) {
-               int dirty = test_and_clear_bit(PG_dcache_dirty, &page->flags);
+               int dirty = !test_and_set_bit(PG_dcache_clean, &page->flags);
                if (dirty)
                        __flush_purge_region(page_address(page), PAGE_SIZE);
        }
@@ -153,7 +153,7 @@ void __flush_anon_page(struct page *page, unsigned long vmaddr)
 
        if (pages_do_alias(addr, vmaddr)) {
                if (boot_cpu_data.dcache.n_aliases && page_mapped(page) &&
-                   !test_bit(PG_dcache_dirty, &page->flags)) {
+                   test_bit(PG_dcache_clean, &page->flags)) {
                        void *kaddr;
 
                        kaddr = kmap_coherent(page, vmaddr);
index 15d74ea..ec29e14 100644 (file)
@@ -34,7 +34,7 @@ void *kmap_coherent(struct page *page, unsigned long addr)
        enum fixed_addresses idx;
        unsigned long vaddr;
 
-       BUG_ON(test_bit(PG_dcache_dirty, &page->flags));
+       BUG_ON(!test_bit(PG_dcache_clean, &page->flags));
 
        pagefault_disable();
 
index 81cd434..47eaafa 100644 (file)
@@ -39,7 +39,7 @@ struct linux_dev_v2_funcs {
        int (*v2_dev_open)(char *devpath);
        void (*v2_dev_close)(int d);
        int (*v2_dev_read)(int d, char *buf, int nbytes);
-       int (*v2_dev_write)(int d, char *buf, int nbytes);
+       int (*v2_dev_write)(int d, const char *buf, int nbytes);
        int (*v2_dev_seek)(int d, int hi, int lo);
 
        /* Never issued (multistage load support) */
index 51296a6..9e5c640 100644 (file)
@@ -60,25 +60,6 @@ extern char *prom_getbootargs(void);
 extern char *prom_mapio(char *virt_hint, int io_space, unsigned int phys_addr, unsigned int num_bytes);
 extern void prom_unmapio(char *virt_addr, unsigned int num_bytes);
 
-/* Device operations. */
-
-/* Open the device described by the passed string.  Note, that the format
- * of the string is different on V0 vs. V2->higher proms.  The caller must
- * know what he/she is doing!  Returns the device descriptor, an int.
- */
-extern int prom_devopen(char *device_string);
-
-/* Close a previously opened device described by the passed integer
- * descriptor.
- */
-extern int prom_devclose(int device_handle);
-
-/* Do a seek operation on the device described by the passed integer
- * descriptor.
- */
-extern void prom_seek(int device_handle, unsigned int seek_hival,
-                     unsigned int seek_lowval);
-
 /* Miscellaneous routines, don't really fit in any category per se. */
 
 /* Reboot the machine with the command line passed. */
@@ -121,19 +102,8 @@ extern int prom_getrev(void);
 /* Get the prom firmware revision. */
 extern int prom_getprev(void);
 
-/* Character operations to/from the console.... */
-
-/* Non-blocking get character from console. */
-extern int prom_nbgetchar(void);
-
-/* Non-blocking put character to console. */
-extern int prom_nbputchar(char character);
-
-/* Blocking get character from console. */
-extern char prom_getchar(void);
-
-/* Blocking put character to console. */
-extern void prom_putchar(char character);
+/* Write a buffer of characters to the console. */
+extern void prom_console_write_buf(const char *buf, int len);
 
 /* Prom's internal routines, don't use in kernel/boot code. */
 extern void prom_printf(const char *fmt, ...);
@@ -238,7 +208,6 @@ extern int prom_node_has_property(phandle node, char *property);
 extern int prom_setprop(phandle node, const char *prop_name, char *prop_value,
                        int value_size);
 
-extern phandle prom_pathtoinode(char *path);
 extern phandle prom_inst2pkg(int);
 
 /* Dorking with Bus ranges... */
index c9cc078..8cd0df3 100644 (file)
@@ -67,27 +67,6 @@ extern void prom_init(void *cif_handler, void *cif_stack);
 /* Boot argument acquisition, returns the boot command line string. */
 extern char *prom_getbootargs(void);
 
-/* Device utilities. */
-
-/* Device operations. */
-
-/* Open the device described by the passed string.  Note, that the format
- * of the string is different on V0 vs. V2->higher proms.  The caller must
- * know what he/she is doing!  Returns the device descriptor, an int.
- */
-extern int prom_devopen(const char *device_string);
-
-/* Close a previously opened device described by the passed integer
- * descriptor.
- */
-extern int prom_devclose(int device_handle);
-
-/* Do a seek operation on the device described by the passed integer
- * descriptor.
- */
-extern void prom_seek(int device_handle, unsigned int seek_hival,
-                     unsigned int seek_lowval);
-
 /* Miscellaneous routines, don't really fit in any category per se. */
 
 /* Reboot the machine with the command line passed. */
@@ -109,33 +88,14 @@ extern void prom_halt(void) __attribute__ ((noreturn));
 /* Halt and power-off the machine. */
 extern void prom_halt_power_off(void) __attribute__ ((noreturn));
 
-/* Set the PROM 'sync' callback function to the passed function pointer.
- * When the user gives the 'sync' command at the prom prompt while the
- * kernel is still active, the prom will call this routine.
- *
- */
-typedef int (*callback_func_t)(long *cmd);
-extern void prom_setcallback(callback_func_t func_ptr);
-
 /* Acquire the IDPROM of the root node in the prom device tree.  This
  * gets passed a buffer where you would like it stuffed.  The return value
  * is the format type of this idprom or 0xff on error.
  */
 extern unsigned char prom_get_idprom(char *idp_buffer, int idpbuf_size);
 
-/* Character operations to/from the console.... */
-
-/* Non-blocking get character from console. */
-extern int prom_nbgetchar(void);
-
-/* Non-blocking put character to console. */
-extern int prom_nbputchar(char character);
-
-/* Blocking get character from console. */
-extern char prom_getchar(void);
-
-/* Blocking put character to console. */
-extern void prom_putchar(char character);
+/* Write a buffer of characters to the console. */
+extern void prom_console_write_buf(const char *buf, int len);
 
 /* Prom's internal routines, don't use in kernel/boot code. */
 extern void prom_printf(const char *fmt, ...);
@@ -279,9 +239,7 @@ extern phandle prom_finddevice(const char *name);
 extern int prom_setprop(phandle node, const char *prop_name, char *prop_value,
                        int value_size);
 
-extern phandle prom_pathtoinode(const char *path);
 extern phandle prom_inst2pkg(int);
-extern int prom_service_exists(const char *service_name);
 extern void prom_sun4v_guest_soft_state(void);
 
 extern int prom_ihandle2path(int handle, char *buffer, int bufsize);
index 2d51527..f01c426 100644 (file)
@@ -114,7 +114,7 @@ void __init leon_init_timers(irq_handler_t counter_fn)
        if (leon3_gptimer_regs && leon3_irqctrl_regs) {
                LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].val, 0);
                LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].rld,
-                                     (((1000000 / 100) - 1)));
+                                     (((1000000 / HZ) - 1)));
                LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].ctrl, 0);
 
 #ifdef CONFIG_SMP
@@ -128,7 +128,7 @@ void __init leon_init_timers(irq_handler_t counter_fn)
                }
 
                LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].val, 0);
-               LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].rld, (((1000000/100) - 1)));
+               LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].rld, (((1000000/HZ) - 1)));
                LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].ctrl, 0);
 # endif
 
index 1b8c073..816c0fa 100644 (file)
@@ -6,7 +6,6 @@ ccflags := -Werror
 
 lib-y                 := bootstr_$(BITS).o
 lib-$(CONFIG_SPARC32) += devmap.o
-lib-y                 += devops_$(BITS).o
 lib-y                 += init_$(BITS).o
 lib-$(CONFIG_SPARC32) += memory.o
 lib-y                 += misc_$(BITS).o
index 5340264..4886310 100644 (file)
 
 extern void restore_current(void);
 
-/* Non blocking get character from console input device, returns -1
- * if no input was taken.  This can be used for polling.
- */
-int
-prom_nbgetchar(void)
-{
-       static char inc;
-       int i = -1;
-       unsigned long flags;
-
-       spin_lock_irqsave(&prom_lock, flags);
-       switch(prom_vers) {
-       case PROM_V0:
-               i = (*(romvec->pv_nbgetchar))();
-               break;
-       case PROM_V2:
-       case PROM_V3:
-               if( (*(romvec->pv_v2devops).v2_dev_read)(*romvec->pv_v2bootargs.fd_stdin , &inc, 0x1) == 1) {
-                       i = inc;
-               } else {
-                       i = -1;
-               }
-               break;
-       default:
-               i = -1;
-               break;
-       };
-       restore_current();
-       spin_unlock_irqrestore(&prom_lock, flags);
-       return i; /* Ugh, we could spin forever on unsupported proms ;( */
-}
-
 /* Non blocking put character to console device, returns -1 if
  * unsuccessful.
  */
-int
-prom_nbputchar(char c)
+static int prom_nbputchar(const char *buf)
 {
-       static char outc;
        unsigned long flags;
        int i = -1;
 
        spin_lock_irqsave(&prom_lock, flags);
        switch(prom_vers) {
        case PROM_V0:
-               i = (*(romvec->pv_nbputchar))(c);
+               i = (*(romvec->pv_nbputchar))(*buf);
                break;
        case PROM_V2:
        case PROM_V3:
-               outc = c;
-               if( (*(romvec->pv_v2devops).v2_dev_write)(*romvec->pv_v2bootargs.fd_stdout, &outc, 0x1) == 1)
+               if ((*(romvec->pv_v2devops).v2_dev_write)(*romvec->pv_v2bootargs.fd_stdout,
+                                                         buf, 0x1) == 1)
                        i = 0;
-               else
-                       i = -1;
                break;
        default:
-               i = -1;
                break;
        };
        restore_current();
@@ -80,18 +43,14 @@ prom_nbputchar(char c)
        return i; /* Ugh, we could spin forever on unsupported proms ;( */
 }
 
-/* Blocking version of get character routine above. */
-char
-prom_getchar(void)
+void prom_console_write_buf(const char *buf, int len)
 {
-       int character;
-       while((character = prom_nbgetchar()) == -1) ;
-       return (char) character;
+       while (len) {
+               int n = prom_nbputchar(buf);
+               if (n)
+                       continue;
+               len--;
+               buf++;
+       }
 }
 
-/* Blocking version of put character routine above. */
-void
-prom_putchar(char c)
-{
-       while(prom_nbputchar(c) == -1) ;
-}
index 10322dc..ed39e75 100644 (file)
 
 extern int prom_stdin, prom_stdout;
 
-/* Non blocking get character from console input device, returns -1
- * if no input was taken.  This can be used for polling.
- */
-inline int
-prom_nbgetchar(void)
-{
-       unsigned long args[7];
-       char inc;
-
-       args[0] = (unsigned long) "read";
-       args[1] = 3;
-       args[2] = 1;
-       args[3] = (unsigned int) prom_stdin;
-       args[4] = (unsigned long) &inc;
-       args[5] = 1;
-       args[6] = (unsigned long) -1;
-
-       p1275_cmd_direct(args);
-
-       if (args[6] == 1)
-               return inc;
-       return -1;
-}
-
-/* Non blocking put character to console device, returns -1 if
- * unsuccessful.
- */
-inline int
-prom_nbputchar(char c)
+static int __prom_console_write_buf(const char *buf, int len)
 {
        unsigned long args[7];
-       char outc;
-       
-       outc = c;
+       int ret;
 
        args[0] = (unsigned long) "write";
        args[1] = 3;
        args[2] = 1;
        args[3] = (unsigned int) prom_stdout;
-       args[4] = (unsigned long) &outc;
-       args[5] = 1;
+       args[4] = (unsigned long) buf;
+       args[5] = (unsigned int) len;
        args[6] = (unsigned long) -1;
 
        p1275_cmd_direct(args);
 
-       if (args[6] == 1)
-               return 0;
-       else
+       ret = (int) args[6];
+       if (ret < 0)
                return -1;
+       return ret;
 }
 
-/* Blocking version of get character routine above. */
-char
-prom_getchar(void)
-{
-       int character;
-       while((character = prom_nbgetchar()) == -1) ;
-       return (char) character;
-}
-
-/* Blocking version of put character routine above. */
-void
-prom_putchar(char c)
+void prom_console_write_buf(const char *buf, int len)
 {
-       prom_nbputchar(c);
-}
-
-void
-prom_puts(const char *s, int len)
-{
-       unsigned long args[7];
-
-       args[0] = (unsigned long) "write";
-       args[1] = 3;
-       args[2] = 1;
-       args[3] = (unsigned int) prom_stdout;
-       args[4] = (unsigned long) s;
-       args[5] = len;
-       args[6] = (unsigned long) -1;
-
-       p1275_cmd_direct(args);
+       while (len) {
+               int n = __prom_console_write_buf(buf, len);
+               if (n < 0)
+                       continue;
+               len -= n;
+               buf += len;
+       }
 }
diff --git a/arch/sparc/prom/devops_32.c b/arch/sparc/prom/devops_32.c
deleted file mode 100644 (file)
index 9c5d468..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * devops.c:  Device operations using the PROM.
- *
- * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
- */
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-
-#include <asm/openprom.h>
-#include <asm/oplib.h>
-
-extern void restore_current(void);
-
-/* Open the device described by the string 'dstr'.  Returns the handle
- * to that device used for subsequent operations on that device.
- * Returns -1 on failure.
- */
-int
-prom_devopen(char *dstr)
-{
-       int handle;
-       unsigned long flags;
-       spin_lock_irqsave(&prom_lock, flags);
-       switch(prom_vers) {
-       case PROM_V0:
-               handle = (*(romvec->pv_v0devops.v0_devopen))(dstr);
-               if(handle == 0) handle = -1;
-               break;
-       case PROM_V2:
-       case PROM_V3:
-               handle = (*(romvec->pv_v2devops.v2_dev_open))(dstr);
-               break;
-       default:
-               handle = -1;
-               break;
-       };
-       restore_current();
-       spin_unlock_irqrestore(&prom_lock, flags);
-
-       return handle;
-}
-
-/* Close the device described by device handle 'dhandle'. */
-int
-prom_devclose(int dhandle)
-{
-       unsigned long flags;
-       spin_lock_irqsave(&prom_lock, flags);
-       switch(prom_vers) {
-       case PROM_V0:
-               (*(romvec->pv_v0devops.v0_devclose))(dhandle);
-               break;
-       case PROM_V2:
-       case PROM_V3:
-               (*(romvec->pv_v2devops.v2_dev_close))(dhandle);
-               break;
-       default:
-               break;
-       };
-       restore_current();
-       spin_unlock_irqrestore(&prom_lock, flags);
-       return 0;
-}
-
-/* Seek to specified location described by 'seekhi' and 'seeklo'
- * for device 'dhandle'.
- */
-void
-prom_seek(int dhandle, unsigned int seekhi, unsigned int seeklo)
-{
-       unsigned long flags;
-       spin_lock_irqsave(&prom_lock, flags);
-       switch(prom_vers) {
-       case PROM_V0:
-               (*(romvec->pv_v0devops.v0_seekdev))(dhandle, seekhi, seeklo);
-               break;
-       case PROM_V2:
-       case PROM_V3:
-               (*(romvec->pv_v2devops.v2_dev_seek))(dhandle, seekhi, seeklo);
-               break;
-       default:
-               break;
-       };
-       restore_current();
-       spin_unlock_irqrestore(&prom_lock, flags);
-}
diff --git a/arch/sparc/prom/devops_64.c b/arch/sparc/prom/devops_64.c
deleted file mode 100644 (file)
index a017119..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * devops.c:  Device operations using the PROM.
- *
- * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
- * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- */
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-
-#include <asm/openprom.h>
-#include <asm/oplib.h>
-
-/* Open the device described by the string 'dstr'.  Returns the handle
- * to that device used for subsequent operations on that device.
- * Returns 0 on failure.
- */
-int
-prom_devopen(const char *dstr)
-{
-       unsigned long args[5];
-
-       args[0] = (unsigned long) "open";
-       args[1] = 1;
-       args[2] = 1;
-       args[3] = (unsigned long) dstr;
-       args[4] = (unsigned long) -1;
-
-       p1275_cmd_direct(args);
-
-       return (int) args[4];
-}
-
-/* Close the device described by device handle 'dhandle'. */
-int
-prom_devclose(int dhandle)
-{
-       unsigned long args[4];
-
-       args[0] = (unsigned long) "close";
-       args[1] = 1;
-       args[2] = 0;
-       args[3] = (unsigned int) dhandle;
-
-       p1275_cmd_direct(args);
-
-       return 0;
-}
-
-/* Seek to specified location described by 'seekhi' and 'seeklo'
- * for device 'dhandle'.
- */
-void
-prom_seek(int dhandle, unsigned int seekhi, unsigned int seeklo)
-{
-       unsigned long args[7];
-
-       args[0] = (unsigned long) "seek";
-       args[1] = 3;
-       args[2] = 1;
-       args[3] = (unsigned int) dhandle;
-       args[4] = seekhi;
-       args[5] = seeklo;
-       args[6] = (unsigned long) -1;
-
-       p1275_cmd_direct(args);
-}
index d24bc44..e4f31d4 100644 (file)
@@ -18,7 +18,7 @@
 #include <asm/system.h>
 #include <asm/ldc.h>
 
-int prom_service_exists(const char *service_name)
+static int prom_service_exists(const char *service_name)
 {
        unsigned long args[5];
 
@@ -150,20 +150,6 @@ void prom_halt_power_off(void)
        prom_halt();
 }
 
-/* Set prom sync handler to call function 'funcp'. */
-void prom_setcallback(callback_func_t funcp)
-{
-       unsigned long args[5];
-       if (!funcp)
-               return;
-       args[0] = (unsigned long) "set-callback";
-       args[1] = 1;
-       args[2] = 1;
-       args[3] = (unsigned long) funcp;
-       args[4] = (unsigned long) -1;
-       p1275_cmd_direct(args);
-}
-
 /* Get the idprom and stuff it into buffer 'idbuf'.  Returns the
  * format type.  'num_bytes' is the number of bytes that your idbuf
  * has space for.  Returns 0xff on error.
index ca86926..d9682f0 100644 (file)
 
 #include <linux/kernel.h>
 #include <linux/compiler.h>
+#include <linux/spinlock.h>
 
 #include <asm/openprom.h>
 #include <asm/oplib.h>
 
+#define CONSOLE_WRITE_BUF_SIZE 1024
+
 static char ppbuf[1024];
+static char console_write_buf[CONSOLE_WRITE_BUF_SIZE];
+static DEFINE_RAW_SPINLOCK(console_write_lock);
 
 void notrace prom_write(const char *buf, unsigned int n)
 {
-       char ch;
+       unsigned int dest_len;
+       unsigned long flags;
+       char *dest;
+
+       dest = console_write_buf;
+       raw_spin_lock_irqsave(&console_write_lock, flags);
 
-       while (n != 0) {
-               --n;
-               if ((ch = *buf++) == '\n')
-                       prom_putchar('\r');
-               prom_putchar(ch);
+       dest_len = 0;
+       while (n-- != 0) {
+               char ch = *buf++;
+               if (ch == '\n') {
+                       *dest++ = '\r';
+                       dest_len++;
+               }
+               *dest++ = ch;
+               dest_len++;
+               if (dest_len >= CONSOLE_WRITE_BUF_SIZE - 1) {
+                       prom_console_write_buf(console_write_buf, dest_len);
+                       dest = console_write_buf;
+                       dest_len = 0;
+               }
        }
+       if (dest_len)
+               prom_console_write_buf(console_write_buf, dest_len);
+
+       raw_spin_unlock_irqrestore(&console_write_lock, flags);
 }
 
 void notrace prom_printf(const char *fmt, ...)
index 63e08e1..535e2e6 100644 (file)
@@ -342,19 +342,3 @@ phandle prom_inst2pkg(int inst)
        if (node == -1) return 0;
        return node;
 }
-
-/* Return 'node' assigned to a particular prom 'path'
- * FIXME: Should work for v0 as well
- */
-phandle prom_pathtoinode(char *path)
-{
-       phandle node;
-       int inst;
-       
-       inst = prom_devopen (path);
-       if (inst == -1) return 0;
-       node = prom_inst2pkg (inst);
-       prom_devclose (inst);
-       if (node == -1) return 0;
-       return node;
-}
index 691be68..d936600 100644 (file)
@@ -374,24 +374,6 @@ inline phandle prom_inst2pkg(int inst)
        return node;
 }
 
-/* Return 'node' assigned to a particular prom 'path'
- * FIXME: Should work for v0 as well
- */
-phandle prom_pathtoinode(const char *path)
-{
-       phandle node;
-       int inst;
-
-       inst = prom_devopen (path);
-       if (inst == 0)
-               return 0;
-       node = prom_inst2pkg(inst);
-       prom_devclose(inst);
-       if (node == -1)
-               return 0;
-       return node;
-}
-
 int prom_ihandle2path(int handle, char *buffer, int bufsize)
 {
        unsigned long args[7];
index c1ee1d6..81d92a4 100644 (file)
@@ -25,7 +25,7 @@
 
 #if defined(__KERNEL__) && !defined(__ASSEMBLY__)
 struct pt_regs;
-int restore_sigcontext(struct pt_regs *, struct sigcontext __user *, long *);
+int restore_sigcontext(struct pt_regs *, struct sigcontext __user *);
 int setup_sigcontext(struct sigcontext __user *, struct pt_regs *);
 void do_signal(struct pt_regs *regs);
 #endif
index 543d6a3..dbb0dfc 100644 (file)
@@ -290,12 +290,12 @@ long compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr,
        return ret;
 }
 
+/* The assembly shim for this function arranges to ignore the return value. */
 long compat_sys_rt_sigreturn(struct pt_regs *regs)
 {
        struct compat_rt_sigframe __user *frame =
                (struct compat_rt_sigframe __user *) compat_ptr(regs->sp);
        sigset_t set;
-       long r0;
 
        if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
                goto badframe;
@@ -308,13 +308,13 @@ long compat_sys_rt_sigreturn(struct pt_regs *regs)
        recalc_sigpending();
        spin_unlock_irq(&current->sighand->siglock);
 
-       if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0))
+       if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
                goto badframe;
 
        if (compat_sys_sigaltstack(&frame->uc.uc_stack, NULL, regs) != 0)
                goto badframe;
 
-       return r0;
+       return 0;
 
 badframe:
        force_sig(SIGSEGV, current);
index f582162..5eed4a0 100644 (file)
@@ -1342,8 +1342,8 @@ handle_syscall:
        lw      r20, r20
 
        /* Jump to syscall handler. */
-       jalr    r20; .Lhandle_syscall_link:
-       FEEDBACK_REENTER(handle_syscall)
+       jalr    r20
+.Lhandle_syscall_link: /* value of "lr" after "jalr r20" above */
 
        /*
         * Write our r0 onto the stack so it gets restored instead
@@ -1352,6 +1352,9 @@ handle_syscall:
        PTREGS_PTR(r29, PTREGS_OFFSET_REG(0))
        sw      r29, r0
 
+.Lsyscall_sigreturn_skip:
+       FEEDBACK_REENTER(handle_syscall)
+
        /* Do syscall trace again, if requested. */
        lw      r30, r31
        andi    r30, r30, _TIF_SYSCALL_TRACE
@@ -1536,9 +1539,24 @@ STD_ENTRY_LOCAL(bad_intr)
        };                                              \
        STD_ENDPROC(_##x)
 
+/*
+ * Special-case sigreturn to not write r0 to the stack on return.
+ * This is technically more efficient, but it also avoids difficulties
+ * in the 64-bit OS when handling 32-bit compat code, since we must not
+ * sign-extend r0 for the sigreturn return-value case.
+ */
+#define PTREGS_SYSCALL_SIGRETURN(x, reg)                \
+       STD_ENTRY(_##x);                                \
+       addli   lr, lr, .Lsyscall_sigreturn_skip - .Lhandle_syscall_link; \
+       {                                               \
+        PTREGS_PTR(reg, PTREGS_OFFSET_BASE);           \
+        j      x                                       \
+       };                                              \
+       STD_ENDPROC(_##x)
+
 PTREGS_SYSCALL(sys_execve, r3)
 PTREGS_SYSCALL(sys_sigaltstack, r2)
-PTREGS_SYSCALL(sys_rt_sigreturn, r0)
+PTREGS_SYSCALL_SIGRETURN(sys_rt_sigreturn, r0)
 PTREGS_SYSCALL(sys_cmpxchg_badaddr, r1)
 
 /* Save additional callee-saves to pt_regs, put address in r4 and jump. */
index 8430f45..e90eb53 100644 (file)
@@ -211,6 +211,13 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
        childregs->regs[0] = 0;         /* return value is zero */
        childregs->sp = sp;  /* override with new user stack pointer */
 
+       /*
+        * If CLONE_SETTLS is set, set "tp" in the new task to "r4",
+        * which is passed in as arg #5 to sys_clone().
+        */
+       if (clone_flags & CLONE_SETTLS)
+               childregs->tp = regs->regs[4];
+
        /*
         * Copy the callee-saved registers from the passed pt_regs struct
         * into the context-switch callee-saved registers area.
@@ -539,6 +546,7 @@ struct task_struct *__sched _switch_to(struct task_struct *prev,
        return __switch_to(prev, next, next_current_ksp0(next));
 }
 
+/* Note there is an implicit fifth argument if (clone_flags & CLONE_SETTLS). */
 SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp,
                void __user *, parent_tidptr, void __user *, child_tidptr,
                struct pt_regs *, regs)
index 757407e..1260321 100644 (file)
@@ -52,7 +52,7 @@ SYSCALL_DEFINE3(sigaltstack, const stack_t __user *, uss,
  */
 
 int restore_sigcontext(struct pt_regs *regs,
-                      struct sigcontext __user *sc, long *pr0)
+                      struct sigcontext __user *sc)
 {
        int err = 0;
        int i;
@@ -75,17 +75,15 @@ int restore_sigcontext(struct pt_regs *regs,
 
        regs->faultnum = INT_SWINT_1_SIGRETURN;
 
-       err |= __get_user(*pr0, &sc->gregs[0]);
        return err;
 }
 
-/* sigreturn() returns long since it restores r0 in the interrupted code. */
+/* The assembly shim for this function arranges to ignore the return value. */
 SYSCALL_DEFINE1(rt_sigreturn, struct pt_regs *, regs)
 {
        struct rt_sigframe __user *frame =
                (struct rt_sigframe __user *)(regs->sp);
        sigset_t set;
-       long r0;
 
        if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
                goto badframe;
@@ -98,13 +96,13 @@ SYSCALL_DEFINE1(rt_sigreturn, struct pt_regs *, regs)
        recalc_sigpending();
        spin_unlock_irq(&current->sighand->siglock);
 
-       if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0))
+       if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
                goto badframe;
 
        if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->sp) == -EFAULT)
                goto badframe;
 
-       return r0;
+       return 0;
 
 badframe:
        force_sig(SIGSEGV, current);
index e832768..e330da2 100644 (file)
@@ -21,7 +21,7 @@ config X86
        select HAVE_UNSTABLE_SCHED_CLOCK
        select HAVE_IDE
        select HAVE_OPROFILE
-       select HAVE_PERF_EVENTS if (!M386 && !M486)
+       select HAVE_PERF_EVENTS
        select HAVE_IRQ_WORK
        select HAVE_IOREMAP_PROT
        select HAVE_KPROBES
index 23f315c..325c052 100644 (file)
@@ -355,7 +355,7 @@ asmlinkage void decompress_kernel(void *rmode, memptr heap,
        if (heap > 0x3fffffffffffUL)
                error("Destination address too large");
 #else
-       if (heap > ((-__PAGE_OFFSET-(512<<20)-1) & 0x7fffffff))
+       if (heap > ((-__PAGE_OFFSET-(128<<20)-1) & 0x7fffffff))
                error("Destination address too large");
 #endif
 #ifndef CONFIG_RELOCATABLE
index cbcc8d8..7a6e68e 100644 (file)
@@ -10,6 +10,7 @@
  * by the Free Software Foundation.
  */
 
+#include <linux/err.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
index 5be1542..e99d55d 100644 (file)
@@ -72,6 +72,9 @@ struct e820map {
 #define BIOS_BEGIN             0x000a0000
 #define BIOS_END               0x00100000
 
+#define BIOS_ROM_BASE          0xffe00000
+#define BIOS_ROM_END           0xffffffff
+
 #ifdef __KERNEL__
 /* see comment in arch/x86/kernel/e820.c */
 extern struct e820map e820;
index 9e6fe39..f702f82 100644 (file)
@@ -79,7 +79,7 @@
 #define KVM_NUM_MMU_PAGES (1 << KVM_MMU_HASH_SHIFT)
 #define KVM_MIN_FREE_MMU_PAGES 5
 #define KVM_REFILL_PAGES 25
-#define KVM_MAX_CPUID_ENTRIES 40
+#define KVM_MAX_CPUID_ENTRIES 80
 #define KVM_NR_FIXED_MTRR_REGION 88
 #define KVM_NR_VAR_MTRR 8
 
index 7f7e577..31d84ac 100644 (file)
@@ -11,6 +11,7 @@ unsigned long pvclock_tsc_khz(struct pvclock_vcpu_time_info *src);
 void pvclock_read_wallclock(struct pvclock_wall_clock *wall,
                            struct pvclock_vcpu_time_info *vcpu,
                            struct timespec *ts);
+void pvclock_resume(void);
 
 /*
  * Scale a 64-bit delta by scaling and multiplying by a 32-bit fraction,
index 9e13763..1e99475 100644 (file)
@@ -45,6 +45,7 @@ obj-y                 += pci-dma.o quirks.o i8237.o topology.o kdebugfs.o
 obj-y                  += alternative.o i8253.o pci-nommu.o hw_breakpoint.o
 obj-y                  += tsc.o io_delay.o rtc.o
 obj-y                  += pci-iommu_table.o
+obj-y                  += resource.o
 
 obj-$(CONFIG_X86_TRAMPOLINE)   += trampoline.o
 obj-y                          += process.o
index 3f838d5..7821813 100644 (file)
@@ -1389,6 +1389,14 @@ void __cpuinit end_local_APIC_setup(void)
 
        setup_apic_nmi_watchdog(NULL);
        apic_pm_activate();
+
+       /*
+        * Now that local APIC setup is completed for BP, configure the fault
+        * handling for interrupt remapping.
+        */
+       if (!smp_processor_id() && intr_remapping_enabled)
+               enable_drhd_fault_handling();
+
 }
 
 #ifdef CONFIG_X86_X2APIC
index 7cc0a72..fadcd74 100644 (file)
@@ -2430,13 +2430,12 @@ static void ack_apic_level(struct irq_data *data)
 {
        struct irq_cfg *cfg = data->chip_data;
        int i, do_unmask_irq = 0, irq = data->irq;
-       struct irq_desc *desc = irq_to_desc(irq);
        unsigned long v;
 
        irq_complete_move(cfg);
 #ifdef CONFIG_GENERIC_PENDING_IRQ
        /* If we are moving the irq we need to mask it */
-       if (unlikely(desc->status & IRQ_MOVE_PENDING)) {
+       if (unlikely(irq_to_desc(irq)->status & IRQ_MOVE_PENDING)) {
                do_unmask_irq = 1;
                mask_ioapic(cfg);
        }
@@ -3413,6 +3412,7 @@ dmar_msi_set_affinity(struct irq_data *data, const struct cpumask *mask,
        msg.data |= MSI_DATA_VECTOR(cfg->vector);
        msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
        msg.address_lo |= MSI_ADDR_DEST_ID(dest);
+       msg.address_hi = MSI_ADDR_BASE_HI | MSI_ADDR_EXT_DEST_ID(dest);
 
        dmar_msi_write(irq, &msg);
 
index f9e4e6a..d8c4a6f 100644 (file)
@@ -79,13 +79,6 @@ void __init default_setup_apic_routing(void)
                /* need to update phys_pkg_id */
                apic->phys_pkg_id = apicid_phys_pkg_id;
        }
-
-       /*
-        * Now that apic routing model is selected, configure the
-        * fault handling for intr remapping.
-        */
-       if (intr_remapping_enabled)
-               enable_drhd_fault_handling();
 }
 
 /* Same for both flat and physical. */
index ed63101..6d75b91 100644 (file)
@@ -381,6 +381,20 @@ static void release_pmc_hardware(void) {}
 
 #endif
 
+static bool check_hw_exists(void)
+{
+       u64 val, val_new = 0;
+       int ret = 0;
+
+       val = 0xabcdUL;
+       ret |= checking_wrmsrl(x86_pmu.perfctr, val);
+       ret |= rdmsrl_safe(x86_pmu.perfctr, &val_new);
+       if (ret || val != val_new)
+               return false;
+
+       return true;
+}
+
 static void reserve_ds_buffers(void);
 static void release_ds_buffers(void);
 
@@ -1372,6 +1386,12 @@ void __init init_hw_perf_events(void)
 
        pmu_check_apic();
 
+       /* sanity check that the hardware exists or is emulated */
+       if (!check_hw_exists()) {
+               pr_cont("Broken PMU hardware detected, software events only.\n");
+               return;
+       }
+
        pr_cont("%s PMU driver.\n", x86_pmu.name);
 
        if (x86_pmu.quirks)
index bcece91..c0dbd9a 100644 (file)
 #define PAGE_TABLE_SIZE(pages) ((pages) / PTRS_PER_PGD)
 #endif
 
+/* Number of possible pages in the lowmem region */
+LOWMEM_PAGES = (((1<<32) - __PAGE_OFFSET) >> PAGE_SHIFT)
+       
 /* Enough space to fit pagetables for the low memory linear map */
-MAPPING_BEYOND_END = \
-       PAGE_TABLE_SIZE(((1<<32) - __PAGE_OFFSET) >> PAGE_SHIFT) << PAGE_SHIFT
+MAPPING_BEYOND_END = PAGE_TABLE_SIZE(LOWMEM_PAGES) << PAGE_SHIFT
 
 /*
  * Worst-case size of the kernel mapping we need to make:
- * the worst-case size of the kernel itself, plus the extra we need
- * to map for the linear map.
+ * a relocatable kernel can live anywhere in lowmem, so we need to be able
+ * to map all of lowmem.
  */
-KERNEL_PAGES = (KERNEL_IMAGE_SIZE + MAPPING_BEYOND_END)>>PAGE_SHIFT
+KERNEL_PAGES = LOWMEM_PAGES
 
 INIT_MAP_SIZE = PAGE_TABLE_SIZE(KERNEL_PAGES) * PAGE_SIZE_asm
 RESERVE_BRK(pagetables, INIT_MAP_SIZE)
@@ -620,13 +622,13 @@ ENTRY(initial_code)
 __PAGE_ALIGNED_BSS
        .align PAGE_SIZE_asm
 #ifdef CONFIG_X86_PAE
-initial_pg_pmd:
+ENTRY(initial_pg_pmd)
        .fill 1024*KPMDS,4,0
 #else
 ENTRY(initial_page_table)
        .fill 1024,4,0
 #endif
-initial_pg_fixmap:
+ENTRY(initial_pg_fixmap)
        .fill 1024,4,0
 ENTRY(empty_zero_page)
        .fill 4096,1,0
index ae03cab..4ff5968 100644 (file)
@@ -27,6 +27,9 @@
 #define HPET_DEV_FSB_CAP               0x1000
 #define HPET_DEV_PERI_CAP              0x2000
 
+#define HPET_MIN_CYCLES                        128
+#define HPET_MIN_PROG_DELTA            (HPET_MIN_CYCLES + (HPET_MIN_CYCLES >> 1))
+
 #define EVT_TO_HPET_DEV(evt) container_of(evt, struct hpet_dev, evt)
 
 /*
@@ -299,8 +302,9 @@ static void hpet_legacy_clockevent_register(void)
        /* Calculate the min / max delta */
        hpet_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF,
                                                           &hpet_clockevent);
-       /* 5 usec minimum reprogramming delta. */
-       hpet_clockevent.min_delta_ns = 5000;
+       /* Setup minimum reprogramming delta. */
+       hpet_clockevent.min_delta_ns = clockevent_delta2ns(HPET_MIN_PROG_DELTA,
+                                                          &hpet_clockevent);
 
        /*
         * Start hpet with the boot cpu mask and make it
@@ -393,22 +397,24 @@ static int hpet_next_event(unsigned long delta,
         * the wraparound into account) nor a simple count down event
         * mode. Further the write to the comparator register is
         * delayed internally up to two HPET clock cycles in certain
-        * chipsets (ATI, ICH9,10). We worked around that by reading
-        * back the compare register, but that required another
-        * workaround for ICH9,10 chips where the first readout after
-        * write can return the old stale value. We already have a
-        * minimum delta of 5us enforced, but a NMI or SMI hitting
+        * chipsets (ATI, ICH9,10). Some newer AMD chipsets have even
+        * longer delays. We worked around that by reading back the
+        * compare register, but that required another workaround for
+        * ICH9,10 chips where the first readout after write can
+        * return the old stale value. We already had a minimum
+        * programming delta of 5us enforced, but a NMI or SMI hitting
         * between the counter readout and the comparator write can
         * move us behind that point easily. Now instead of reading
         * the compare register back several times, we make the ETIME
         * decision based on the following: Return ETIME if the
-        * counter value after the write is less than 8 HPET cycles
+        * counter value after the write is less than HPET_MIN_CYCLES
         * away from the event or if the counter is already ahead of
-        * the event.
+        * the event. The minimum programming delta for the generic
+        * clockevents code is set to 1.5 * HPET_MIN_CYCLES.
         */
        res = (s32)(cnt - hpet_readl(HPET_COUNTER));
 
-       return res < 8 ? -ETIME : 0;
+       return res < HPET_MIN_CYCLES ? -ETIME : 0;
 }
 
 static void hpet_legacy_set_mode(enum clock_event_mode mode,
index 008b91e..42eb330 100644 (file)
@@ -83,6 +83,11 @@ unsigned long pvclock_tsc_khz(struct pvclock_vcpu_time_info *src)
 
 static atomic64_t last_value = ATOMIC64_INIT(0);
 
+void pvclock_resume(void)
+{
+       atomic64_set(&last_value, 0);
+}
+
 cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src)
 {
        struct pvclock_shadow_time shadow;
diff --git a/arch/x86/kernel/resource.c b/arch/x86/kernel/resource.c
new file mode 100644 (file)
index 0000000..2a26819
--- /dev/null
@@ -0,0 +1,48 @@
+#include <linux/ioport.h>
+#include <asm/e820.h>
+
+static void resource_clip(struct resource *res, resource_size_t start,
+                         resource_size_t end)
+{
+       resource_size_t low = 0, high = 0;
+
+       if (res->end < start || res->start > end)
+               return;         /* no conflict */
+
+       if (res->start < start)
+               low = start - res->start;
+
+       if (res->end > end)
+               high = res->end - end;
+
+       /* Keep the area above or below the conflict, whichever is larger */
+       if (low > high)
+               res->end = start - 1;
+       else
+               res->start = end + 1;
+}
+
+static void remove_e820_regions(struct resource *avail)
+{
+       int i;
+       struct e820entry *entry;
+
+       for (i = 0; i < e820.nr_map; i++) {
+               entry = &e820.map[i];
+
+               resource_clip(avail, entry->addr,
+                             entry->addr + entry->size - 1);
+       }
+}
+
+void arch_remove_reservations(struct resource *avail)
+{
+       /* Trim out BIOS areas (low 1MB and high 2MB) and E820 regions */
+       if (avail->flags & IORESOURCE_MEM) {
+               if (avail->start < BIOS_END)
+                       avail->start = BIOS_END;
+               resource_clip(avail, BIOS_ROM_BASE, BIOS_ROM_END);
+
+               remove_e820_regions(avail);
+       }
+}
index 21c6746..85268f8 100644 (file)
@@ -769,7 +769,6 @@ void __init setup_arch(char **cmdline_p)
 
        x86_init.oem.arch_setup();
 
-       resource_alloc_from_bottom = 0;
        iomem_resource.end = (1ULL << boot_cpu_data.x86_phys_bits) - 1;
        setup_memory_map();
        parse_setup_data();
index 9c253bd..5471285 100644 (file)
@@ -394,7 +394,8 @@ static void __init setup_xstate_init(void)
         * Setup init_xstate_buf to represent the init state of
         * all the features managed by the xsave
         */
-       init_xstate_buf = alloc_bootmem(xstate_size);
+       init_xstate_buf = alloc_bootmem_align(xstate_size,
+                                             __alignof__(struct xsave_struct));
        init_xstate_buf->i387.mxcsr = MXCSR_DEFAULT;
 
        clts();
index 1ca1229..b81a9b7 100644 (file)
@@ -3494,6 +3494,10 @@ static void svm_cpuid_update(struct kvm_vcpu *vcpu)
 static void svm_set_supported_cpuid(u32 func, struct kvm_cpuid_entry2 *entry)
 {
        switch (func) {
+       case 0x00000001:
+               /* Mask out xsave bit as long as it is not supported by SVM */
+               entry->ecx &= ~(bit(X86_FEATURE_XSAVE));
+               break;
        case 0x80000001:
                if (nested)
                        entry->ecx |= (1 << 2); /* Set SVM bit */
index ff21fdd..81fcbe9 100644 (file)
@@ -4227,11 +4227,6 @@ static int vmx_get_lpage_level(void)
                return PT_PDPE_LEVEL;
 }
 
-static inline u32 bit(int bitno)
-{
-       return 1 << (bitno & 31);
-}
-
 static void vmx_cpuid_update(struct kvm_vcpu *vcpu)
 {
        struct kvm_cpuid_entry2 *best;
index cdac9e5..b989e1f 100644 (file)
@@ -155,11 +155,6 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
 
 u64 __read_mostly host_xcr0;
 
-static inline u32 bit(int bitno)
-{
-       return 1 << (bitno & 31);
-}
-
 static void kvm_on_user_return(struct user_return_notifier *urn)
 {
        unsigned slot;
@@ -4569,9 +4564,11 @@ static void kvm_timer_init(void)
 #ifdef CONFIG_CPU_FREQ
                struct cpufreq_policy policy;
                memset(&policy, 0, sizeof(policy));
-               cpufreq_get_policy(&policy, get_cpu());
+               cpu = get_cpu();
+               cpufreq_get_policy(&policy, cpu);
                if (policy.cpuinfo.max_freq)
                        max_tsc_khz = policy.cpuinfo.max_freq;
+               put_cpu();
 #endif
                cpufreq_register_notifier(&kvmclock_cpufreq_notifier_block,
                                          CPUFREQ_TRANSITION_NOTIFIER);
@@ -5522,6 +5519,8 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
 
        mmu_reset_needed |= kvm_read_cr4(vcpu) != sregs->cr4;
        kvm_x86_ops->set_cr4(vcpu, sregs->cr4);
+       if (sregs->cr4 & X86_CR4_OSXSAVE)
+               update_cpuid(vcpu);
        if (!is_long_mode(vcpu) && is_pae(vcpu)) {
                load_pdptrs(vcpu, vcpu->arch.walk_mmu, vcpu->arch.cr3);
                mmu_reset_needed = 1;
index 2cea414..c600da8 100644 (file)
@@ -70,6 +70,11 @@ static inline int is_paging(struct kvm_vcpu *vcpu)
        return kvm_read_cr0_bits(vcpu, X86_CR0_PG);
 }
 
+static inline u32 bit(int bitno)
+{
+       return 1 << (bitno & 31);
+}
+
 void kvm_before_handle_nmi(struct kvm_vcpu *vcpu);
 void kvm_after_handle_nmi(struct kvm_vcpu *vcpu);
 int kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq);
index 73b1e1a..4996cf5 100644 (file)
@@ -531,7 +531,10 @@ static void lguest_write_cr3(unsigned long cr3)
 {
        lguest_data.pgdir = cr3;
        lazy_hcall1(LHCALL_NEW_PGTABLE, cr3);
-       cr3_changed = true;
+
+       /* These two page tables are simple, linear, and used during boot */
+       if (cr3 != __pa(swapper_pg_dir) && cr3 != __pa(initial_page_table))
+               cr3_changed = true;
 }
 
 static unsigned long lguest_read_cr3(void)
@@ -703,9 +706,9 @@ static void lguest_set_pmd(pmd_t *pmdp, pmd_t pmdval)
  * to forget all of them.  Fortunately, this is very rare.
  *
  * ... except in early boot when the kernel sets up the initial pagetables,
- * which makes booting astonishingly slow: 1.83 seconds!  So we don't even tell
- * the Host anything changed until we've done the first page table switch,
- * which brings boot back to 0.25 seconds.
+ * which makes booting astonishingly slow: 48 seconds!  So we don't even tell
+ * the Host anything changed until we've done the first real page table switch,
+ * which brings boot back to 4.3 seconds.
  */
 static void lguest_set_pte(pte_t *ptep, pte_t pteval)
 {
@@ -1002,7 +1005,7 @@ static void lguest_time_init(void)
        clockevents_register_device(&lguest_clockevent);
 
        /* Finally, we unblock the timer interrupt. */
-       enable_lguest_irq(0);
+       clear_bit(0, lguest_data.blocked_interrupts);
 }
 
 /*
@@ -1349,9 +1352,6 @@ __init void lguest_init(void)
         */
        switch_to_new_gdt(0);
 
-       /* We actually boot with all memory mapped, but let's say 128MB. */
-       max_pfn_mapped = (128*1024*1024) >> PAGE_SHIFT;
-
        /*
         * The Host<->Guest Switcher lives at the top of our address space, and
         * the Host told us how big it is when we made LGUEST_INIT hypercall:
index 4f420c2..e7d5382 100644 (file)
@@ -4,6 +4,7 @@
 #include <asm/asm-offsets.h>
 #include <asm/thread_info.h>
 #include <asm/processor-flags.h>
+#include <asm/pgtable.h>
 
 /*G:020
  * Our story starts with the kernel booting into startup_32 in
@@ -37,9 +38,113 @@ ENTRY(lguest_entry)
        /* Set up the initial stack so we can run C code. */
        movl $(init_thread_union+THREAD_SIZE),%esp
 
+       call init_pagetables
+
        /* Jumps are relative: we're running __PAGE_OFFSET too low. */
        jmp lguest_init+__PAGE_OFFSET
 
+/*
+ * Initialize page tables.  This creates a PDE and a set of page
+ * tables, which are located immediately beyond __brk_base.  The variable
+ * _brk_end is set up to point to the first "safe" location.
+ * Mappings are created both at virtual address 0 (identity mapping)
+ * and PAGE_OFFSET for up to _end.
+ *
+ * FIXME: This code is taken verbatim from arch/x86/kernel/head_32.S: they
+ * don't have a stack at this point, so we can't just use call and ret.
+ */
+init_pagetables:
+#if PTRS_PER_PMD > 1
+#define PAGE_TABLE_SIZE(pages) (((pages) / PTRS_PER_PMD) + PTRS_PER_PGD)
+#else
+#define PAGE_TABLE_SIZE(pages) ((pages) / PTRS_PER_PGD)
+#endif
+#define pa(X) ((X) - __PAGE_OFFSET)
+
+/* Enough space to fit pagetables for the low memory linear map */
+MAPPING_BEYOND_END = \
+       PAGE_TABLE_SIZE(((1<<32) - __PAGE_OFFSET) >> PAGE_SHIFT) << PAGE_SHIFT
+#ifdef CONFIG_X86_PAE
+
+       /*
+        * In PAE mode initial_page_table is statically defined to contain
+        * enough entries to cover the VMSPLIT option (that is the top 1, 2 or 3
+        * entries). The identity mapping is handled by pointing two PGD entries
+        * to the first kernel PMD.
+        *
+        * Note the upper half of each PMD or PTE are always zero at this stage.
+        */
+
+#define KPMDS (((-__PAGE_OFFSET) >> 30) & 3) /* Number of kernel PMDs */
+
+       xorl %ebx,%ebx                          /* %ebx is kept at zero */
+
+       movl $pa(__brk_base), %edi
+       movl $pa(initial_pg_pmd), %edx
+       movl $PTE_IDENT_ATTR, %eax
+10:
+       leal PDE_IDENT_ATTR(%edi),%ecx          /* Create PMD entry */
+       movl %ecx,(%edx)                        /* Store PMD entry */
+                                               /* Upper half already zero */
+       addl $8,%edx
+       movl $512,%ecx
+11:
+       stosl
+       xchgl %eax,%ebx
+       stosl
+       xchgl %eax,%ebx
+       addl $0x1000,%eax
+       loop 11b
+
+       /*
+        * End condition: we must map up to the end + MAPPING_BEYOND_END.
+        */
+       movl $pa(_end) + MAPPING_BEYOND_END + PTE_IDENT_ATTR, %ebp
+       cmpl %ebp,%eax
+       jb 10b
+1:
+       addl $__PAGE_OFFSET, %edi
+       movl %edi, pa(_brk_end)
+       shrl $12, %eax
+       movl %eax, pa(max_pfn_mapped)
+
+       /* Do early initialization of the fixmap area */
+       movl $pa(initial_pg_fixmap)+PDE_IDENT_ATTR,%eax
+       movl %eax,pa(initial_pg_pmd+0x1000*KPMDS-8)
+#else  /* Not PAE */
+
+page_pde_offset = (__PAGE_OFFSET >> 20);
+
+       movl $pa(__brk_base), %edi
+       movl $pa(initial_page_table), %edx
+       movl $PTE_IDENT_ATTR, %eax
+10:
+       leal PDE_IDENT_ATTR(%edi),%ecx          /* Create PDE entry */
+       movl %ecx,(%edx)                        /* Store identity PDE entry */
+       movl %ecx,page_pde_offset(%edx)         /* Store kernel PDE entry */
+       addl $4,%edx
+       movl $1024, %ecx
+11:
+       stosl
+       addl $0x1000,%eax
+       loop 11b
+       /*
+        * End condition: we must map up to the end + MAPPING_BEYOND_END.
+        */
+       movl $pa(_end) + MAPPING_BEYOND_END + PTE_IDENT_ATTR, %ebp
+       cmpl %ebp,%eax
+       jb 10b
+       addl $__PAGE_OFFSET, %edi
+       movl %edi, pa(_brk_end)
+       shrl $12, %eax
+       movl %eax, pa(max_pfn_mapped)
+
+       /* Do early initialization of the fixmap area */
+       movl $pa(initial_pg_fixmap)+PDE_IDENT_ATTR,%eax
+       movl %eax,pa(initial_page_table+0xffc)
+#endif
+       ret
+
 /*G:055
  * We create a macro which puts the assembler code between lgstart_ and lgend_
  * markers.  These templates are put in the .text section: they can't be
index c4bb261..b1805b7 100644 (file)
@@ -65,21 +65,13 @@ pcibios_align_resource(void *data, const struct resource *res,
                        resource_size_t size, resource_size_t align)
 {
        struct pci_dev *dev = data;
-       resource_size_t start = round_down(res->end - size + 1, align);
+       resource_size_t start = res->start;
 
        if (res->flags & IORESOURCE_IO) {
-
-               /*
-                * If we're avoiding ISA aliases, the largest contiguous I/O
-                * port space is 256 bytes.  Clearing bits 9 and 10 preserves
-                * all 256-byte and smaller alignments, so the result will
-                * still be correctly aligned.
-                */
-               if (!skip_isa_ioresource_align(dev))
-                       start &= ~0x300;
-       } else if (res->flags & IORESOURCE_MEM) {
-               if (start < BIOS_END)
-                       start = res->end;       /* fail; no space */
+               if (skip_isa_ioresource_align(dev))
+                       return start;
+               if (start & 0x300)
+                       start = (start + 0x3ff) & ~0x3ff;
        }
        return start;
 }
index d7b5109..25cd4a0 100644 (file)
@@ -70,6 +70,9 @@ static int acpi_register_gsi_xen_hvm(struct device *dev, u32 gsi,
 struct xen_pci_frontend_ops *xen_pci_frontend;
 EXPORT_SYMBOL_GPL(xen_pci_frontend);
 
+#define XEN_PIRQ_MSI_DATA  (MSI_DATA_TRIGGER_EDGE | \
+               MSI_DATA_LEVEL_ASSERT | (3 << 8) | MSI_DATA_VECTOR(0))
+
 static void xen_msi_compose_msg(struct pci_dev *pdev, unsigned int pirq,
                struct msi_msg *msg)
 {
@@ -83,12 +86,7 @@ static void xen_msi_compose_msg(struct pci_dev *pdev, unsigned int pirq,
                MSI_ADDR_REDIRECTION_CPU |
                MSI_ADDR_DEST_ID(pirq);
 
-       msg->data =
-               MSI_DATA_TRIGGER_EDGE |
-               MSI_DATA_LEVEL_ASSERT |
-               /* delivery mode reserved */
-               (3 << 8) |
-               MSI_DATA_VECTOR(0);
+       msg->data = XEN_PIRQ_MSI_DATA;
 }
 
 static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
@@ -98,8 +96,23 @@ static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
        struct msi_msg msg;
 
        list_for_each_entry(msidesc, &dev->msi_list, list) {
+               __read_msi_msg(msidesc, &msg);
+               pirq = MSI_ADDR_EXT_DEST_ID(msg.address_hi) |
+                       ((msg.address_lo >> MSI_ADDR_DEST_ID_SHIFT) & 0xff);
+               if (xen_irq_from_pirq(pirq) >= 0 && msg.data == XEN_PIRQ_MSI_DATA) {
+                       xen_allocate_pirq_msi((type == PCI_CAP_ID_MSIX) ?
+                                       "msi-x" : "msi", &irq, &pirq, XEN_ALLOC_IRQ);
+                       if (irq < 0)
+                               goto error;
+                       ret = set_irq_msi(irq, msidesc);
+                       if (ret < 0)
+                               goto error_while;
+                       printk(KERN_DEBUG "xen: msi already setup: msi --> irq=%d"
+                                       " pirq=%d\n", irq, pirq);
+                       return 0;
+               }
                xen_allocate_pirq_msi((type == PCI_CAP_ID_MSIX) ?
-                               "msi-x" : "msi", &irq, &pirq);
+                               "msi-x" : "msi", &irq, &pirq, (XEN_ALLOC_IRQ | XEN_ALLOC_PIRQ));
                if (irq < 0 || pirq < 0)
                        goto error;
                printk(KERN_DEBUG "xen: msi --> irq=%d, pirq=%d\n", irq, pirq);
index 4a2afa1..b6552b1 100644 (file)
@@ -25,7 +25,7 @@ targets += vdso.so vdso.so.dbg vdso.lds $(vobjs-y)
 
 export CPPFLAGS_vdso.lds += -P -C
 
-VDSO_LDFLAGS_vdso.lds = -m elf_x86_64 -Wl,-soname=linux-vdso.so.1 \
+VDSO_LDFLAGS_vdso.lds = -m64 -Wl,-soname=linux-vdso.so.1 \
                        -Wl,-z,max-page-size=4096 -Wl,-z,common-page-size=4096
 
 $(obj)/vdso.o: $(src)/vdso.S $(obj)/vdso.so
@@ -69,7 +69,7 @@ vdso32.so-$(VDSO32-y)         += sysenter
 vdso32-images                  = $(vdso32.so-y:%=vdso32-%.so)
 
 CPPFLAGS_vdso32.lds = $(CPPFLAGS_vdso.lds)
-VDSO_LDFLAGS_vdso32.lds = -m elf_i386 -Wl,-soname=linux-gate.so.1
+VDSO_LDFLAGS_vdso32.lds = -m32 -Wl,-soname=linux-gate.so.1
 
 # This makes sure the $(obj) subdirectory exists even though vdso32/
 # is not a kbuild sub-make subdirectory.
index 02c710b..44dcad4 100644 (file)
@@ -1021,10 +1021,6 @@ static void xen_reboot(int reason)
 {
        struct sched_shutdown r = { .reason = reason };
 
-#ifdef CONFIG_SMP
-       stop_other_cpus();
-#endif
-
        if (HYPERVISOR_sched_op(SCHEDOP_shutdown, &r))
                BUG();
 }
index a1feff9..44924e5 100644 (file)
@@ -2415,8 +2415,6 @@ void __init xen_init_mmu_ops(void)
        x86_init.paging.pagetable_setup_done = xen_pagetable_setup_done;
        pv_mmu_ops = xen_mmu_ops;
 
-       vmap_lazy_unmap = false;
-
        memset(dummy_mapping, 0xff, PAGE_SIZE);
 }
 
index 0f45638..25c52f9 100644 (file)
@@ -68,7 +68,7 @@ static int __init check_platform_magic(void)
        return 0;
 }
 
-void __init xen_unplug_emulated_devices(void)
+void xen_unplug_emulated_devices(void)
 {
        int r;
 
index 01afd8a..b5a7f92 100644 (file)
@@ -181,24 +181,21 @@ char * __init xen_memory_setup(void)
        for (i = 0; i < memmap.nr_entries; i++) {
                unsigned long long end = map[i].addr + map[i].size;
 
-               if (map[i].type == E820_RAM) {
-                       if (map[i].addr < mem_end && end > mem_end) {
-                               /* Truncate region to max_mem. */
-                               u64 delta = end - mem_end;
+               if (map[i].type == E820_RAM && end > mem_end) {
+                       /* RAM off the end - may be partially included */
+                       u64 delta = min(map[i].size, end - mem_end);
 
-                               map[i].size -= delta;
-                               extra_pages += PFN_DOWN(delta);
+                       map[i].size -= delta;
+                       end -= delta;
 
-                               end = mem_end;
-                       }
+                       extra_pages += PFN_DOWN(delta);
                }
 
-               if (end > xen_extra_mem_start)
+               if (map[i].size > 0 && end > xen_extra_mem_start)
                        xen_extra_mem_start = end;
 
-               /* If region is non-RAM or below mem_end, add what remains */
-               if ((map[i].type != E820_RAM || map[i].addr < mem_end) &&
-                   map[i].size > 0)
+               /* Add region if any remains */
+               if (map[i].size > 0)
                        e820_add_region(map[i].addr, map[i].size, map[i].type);
        }
 
@@ -252,20 +249,6 @@ char * __init xen_memory_setup(void)
        return "Xen";
 }
 
-static void xen_idle(void)
-{
-       local_irq_disable();
-
-       if (need_resched())
-               local_irq_enable();
-       else {
-               current_thread_info()->status &= ~TS_POLLING;
-               smp_mb__after_clear_bit();
-               safe_halt();
-               current_thread_info()->status |= TS_POLLING;
-       }
-}
-
 /*
  * Set the bit indicating "nosegneg" library variants should be used.
  * We only need to bother in pure 32-bit mode; compat 32-bit processes
@@ -362,7 +345,11 @@ void __init xen_arch_setup(void)
               MAX_GUEST_CMDLINE > COMMAND_LINE_SIZE ?
               COMMAND_LINE_SIZE : MAX_GUEST_CMDLINE);
 
-       pm_idle = xen_idle;
+       /* Set up idle, making sure it calls safe_halt() pvop */
+#ifdef CONFIG_X86_32
+       boot_cpu_data.hlt_works_ok = 1;
+#endif
+       pm_idle = default_idle;
 
        fiddle_vdso();
 }
index 1d789d5..9bbd63a 100644 (file)
@@ -31,6 +31,7 @@ void xen_hvm_post_suspend(int suspend_cancelled)
        int cpu;
        xen_hvm_init_shared_info();
        xen_callback_vector();
+       xen_unplug_emulated_devices();
        if (xen_feature(XENFEAT_hvm_safe_pvclock)) {
                for_each_online_cpu(cpu) {
                        xen_setup_runstate_info(cpu);
index b2bb5aa..5da5e53 100644 (file)
@@ -426,6 +426,8 @@ void xen_timer_resume(void)
 {
        int cpu;
 
+       pvclock_resume();
+
        if (xen_clockevent != &xen_vcpuop_clockevent)
                return;
 
index 6404474..9d41bf9 100644 (file)
@@ -43,7 +43,7 @@ void xen_vcpu_restore(void);
 
 void xen_callback_vector(void);
 void xen_hvm_init_shared_info(void);
-void __init xen_unplug_emulated_devices(void);
+void xen_unplug_emulated_devices(void);
 
 void __init xen_build_dynamic_phys_to_machine(void);
 
index f20d6a7..0c8b64a 100644 (file)
@@ -250,6 +250,14 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm,
        int ret, rw;
        unsigned int dxfer_len;
        void *dxferp = NULL;
+       struct bsg_class_device *bcd = &q->bsg_dev;
+
+       /* if the LLD has been removed then the bsg_unregister_queue will
+        * eventually be called and the class_dev was freed, so we can no
+        * longer use this request_queue. Return no such address.
+        */
+       if (!bcd->class_dev)
+               return ERR_PTR(-ENXIO);
 
        dprintk("map hdr %llx/%u %llx/%u\n", (unsigned long long) hdr->dout_xferp,
                hdr->dout_xfer_len, (unsigned long long) hdr->din_xferp,
index ba9afea..25d3aae 100644 (file)
@@ -100,24 +100,7 @@ static const struct file_operations acpi_ac_fops = {
        .release = single_release,
 };
 #endif
-static int get_ac_property(struct power_supply *psy,
-                          enum power_supply_property psp,
-                          union power_supply_propval *val)
-{
-       struct acpi_ac *ac = to_acpi_ac(psy);
-       switch (psp) {
-       case POWER_SUPPLY_PROP_ONLINE:
-               val->intval = ac->state;
-               break;
-       default:
-               return -EINVAL;
-       }
-       return 0;
-}
 
-static enum power_supply_property ac_props[] = {
-       POWER_SUPPLY_PROP_ONLINE,
-};
 /* --------------------------------------------------------------------------
                                AC Adapter Management
    -------------------------------------------------------------------------- */
@@ -140,6 +123,35 @@ static int acpi_ac_get_state(struct acpi_ac *ac)
        return 0;
 }
 
+/* --------------------------------------------------------------------------
+                            sysfs I/F
+   -------------------------------------------------------------------------- */
+static int get_ac_property(struct power_supply *psy,
+                          enum power_supply_property psp,
+                          union power_supply_propval *val)
+{
+       struct acpi_ac *ac = to_acpi_ac(psy);
+
+       if (!ac)
+               return -ENODEV;
+
+       if (acpi_ac_get_state(ac))
+               return -ENODEV;
+
+       switch (psp) {
+       case POWER_SUPPLY_PROP_ONLINE:
+               val->intval = ac->state;
+               break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static enum power_supply_property ac_props[] = {
+       POWER_SUPPLY_PROP_ONLINE,
+};
+
 #ifdef CONFIG_ACPI_PROCFS_POWER
 /* --------------------------------------------------------------------------
                               FS Interface (/proc)
index 1211c03..5850d32 100644 (file)
@@ -86,7 +86,7 @@ static struct erst_erange {
  * It is used to provide exclusive accessing for ERST Error Log
  * Address Range too.
  */
-static DEFINE_SPINLOCK(erst_lock);
+static DEFINE_RAW_SPINLOCK(erst_lock);
 
 static inline int erst_errno(int command_status)
 {
@@ -421,9 +421,9 @@ ssize_t erst_get_record_count(void)
        if (erst_disable)
                return -ENODEV;
 
-       spin_lock_irqsave(&erst_lock, flags);
+       raw_spin_lock_irqsave(&erst_lock, flags);
        count = __erst_get_record_count();
-       spin_unlock_irqrestore(&erst_lock, flags);
+       raw_spin_unlock_irqrestore(&erst_lock, flags);
 
        return count;
 }
@@ -456,9 +456,9 @@ int erst_get_next_record_id(u64 *record_id)
        if (erst_disable)
                return -ENODEV;
 
-       spin_lock_irqsave(&erst_lock, flags);
+       raw_spin_lock_irqsave(&erst_lock, flags);
        rc = __erst_get_next_record_id(record_id);
-       spin_unlock_irqrestore(&erst_lock, flags);
+       raw_spin_unlock_irqrestore(&erst_lock, flags);
 
        return rc;
 }
@@ -624,17 +624,17 @@ int erst_write(const struct cper_record_header *record)
                return -EINVAL;
 
        if (erst_erange.attr & ERST_RANGE_NVRAM) {
-               if (!spin_trylock_irqsave(&erst_lock, flags))
+               if (!raw_spin_trylock_irqsave(&erst_lock, flags))
                        return -EBUSY;
                rc = __erst_write_to_nvram(record);
-               spin_unlock_irqrestore(&erst_lock, flags);
+               raw_spin_unlock_irqrestore(&erst_lock, flags);
                return rc;
        }
 
        if (record->record_length > erst_erange.size)
                return -EINVAL;
 
-       if (!spin_trylock_irqsave(&erst_lock, flags))
+       if (!raw_spin_trylock_irqsave(&erst_lock, flags))
                return -EBUSY;
        memcpy(erst_erange.vaddr, record, record->record_length);
        rcd_erange = erst_erange.vaddr;
@@ -642,7 +642,7 @@ int erst_write(const struct cper_record_header *record)
        memcpy(&rcd_erange->persistence_information, "ER", 2);
 
        rc = __erst_write_to_storage(0);
-       spin_unlock_irqrestore(&erst_lock, flags);
+       raw_spin_unlock_irqrestore(&erst_lock, flags);
 
        return rc;
 }
@@ -696,9 +696,9 @@ ssize_t erst_read(u64 record_id, struct cper_record_header *record,
        if (erst_disable)
                return -ENODEV;
 
-       spin_lock_irqsave(&erst_lock, flags);
+       raw_spin_lock_irqsave(&erst_lock, flags);
        len = __erst_read(record_id, record, buflen);
-       spin_unlock_irqrestore(&erst_lock, flags);
+       raw_spin_unlock_irqrestore(&erst_lock, flags);
        return len;
 }
 EXPORT_SYMBOL_GPL(erst_read);
@@ -719,20 +719,20 @@ ssize_t erst_read_next(struct cper_record_header *record, size_t buflen)
        if (erst_disable)
                return -ENODEV;
 
-       spin_lock_irqsave(&erst_lock, flags);
+       raw_spin_lock_irqsave(&erst_lock, flags);
        rc = __erst_get_next_record_id(&record_id);
        if (rc) {
-               spin_unlock_irqrestore(&erst_lock, flags);
+               raw_spin_unlock_irqrestore(&erst_lock, flags);
                return rc;
        }
        /* no more record */
        if (record_id == APEI_ERST_INVALID_RECORD_ID) {
-               spin_unlock_irqrestore(&erst_lock, flags);
+               raw_spin_unlock_irqrestore(&erst_lock, flags);
                return 0;
        }
 
        len = __erst_read(record_id, record, buflen);
-       spin_unlock_irqrestore(&erst_lock, flags);
+       raw_spin_unlock_irqrestore(&erst_lock, flags);
 
        return len;
 }
@@ -746,12 +746,12 @@ int erst_clear(u64 record_id)
        if (erst_disable)
                return -ENODEV;
 
-       spin_lock_irqsave(&erst_lock, flags);
+       raw_spin_lock_irqsave(&erst_lock, flags);
        if (erst_erange.attr & ERST_RANGE_NVRAM)
                rc = __erst_clear_from_nvram(record_id);
        else
                rc = __erst_clear_from_storage(record_id);
-       spin_unlock_irqrestore(&erst_lock, flags);
+       raw_spin_unlock_irqrestore(&erst_lock, flags);
 
        return rc;
 }
index 1a3508a..daa7bc6 100644 (file)
@@ -46,9 +46,9 @@ EXPORT_SYMBOL_GPL(hest_disable);
 
 /* HEST table parsing */
 
-static struct acpi_table_hest *hest_tab;
+static struct acpi_table_hest *__read_mostly hest_tab;
 
-static int hest_esrc_len_tab[ACPI_HEST_TYPE_RESERVED] = {
+static const int hest_esrc_len_tab[ACPI_HEST_TYPE_RESERVED] = {
        [ACPI_HEST_TYPE_IA32_CHECK] = -1,       /* need further calculation */
        [ACPI_HEST_TYPE_IA32_CORRECTED_CHECK] = -1,
        [ACPI_HEST_TYPE_IA32_NMI] = sizeof(struct acpi_hest_ia_nmi),
@@ -126,7 +126,7 @@ struct ghes_arr {
        unsigned int count;
 };
 
-static int hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data)
+static int __init hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data)
 {
        int *count = data;
 
@@ -135,7 +135,7 @@ static int hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data)
        return 0;
 }
 
-static int hest_parse_ghes(struct acpi_hest_header *hest_hdr, void *data)
+static int __init hest_parse_ghes(struct acpi_hest_header *hest_hdr, void *data)
 {
        struct platform_device *ghes_dev;
        struct ghes_arr *ghes_arr = data;
@@ -165,7 +165,7 @@ err:
        return rc;
 }
 
-static int hest_ghes_dev_register(unsigned int ghes_count)
+static int __init hest_ghes_dev_register(unsigned int ghes_count)
 {
        int rc, i;
        struct ghes_arr ghes_arr;
index 95649d3..9fb9d5a 100644 (file)
@@ -130,6 +130,8 @@ struct acpi_battery {
        unsigned long flags;
 };
 
+static int acpi_battery_update(struct acpi_battery *battery);
+
 #define to_acpi_battery(x) container_of(x, struct acpi_battery, bat);
 
 inline int acpi_battery_present(struct acpi_battery *battery)
@@ -184,6 +186,9 @@ static int acpi_battery_get_property(struct power_supply *psy,
        int ret = 0;
        struct acpi_battery *battery = to_acpi_battery(psy);
 
+       if (acpi_battery_update(battery))
+               return -ENODEV;
+
        if (acpi_battery_present(battery)) {
                /* run battery update only if it is present */
                acpi_battery_get_state(battery);
index 372ff80..302b31e 100644 (file)
@@ -934,6 +934,9 @@ static struct dmi_system_id __initdata ec_dmi_table[] = {
        ec_flag_msi, "MSI hardware", {
        DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-Star")}, NULL},
        {
+       ec_flag_msi, "MSI hardware", {
+       DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-STAR")}, NULL},
+       {
        ec_validate_ecdt, "ASUS hardware", {
        DMI_MATCH(DMI_BIOS_VENDOR, "ASUS") }, NULL},
        {},
index 966fedd..055d7b7 100644 (file)
@@ -110,9 +110,6 @@ struct acpi_ioremap {
 static LIST_HEAD(acpi_ioremaps);
 static DEFINE_SPINLOCK(acpi_ioremap_lock);
 
-#define        OSI_STRING_LENGTH_MAX 64        /* arbitrary */
-static char osi_setup_string[OSI_STRING_LENGTH_MAX];
-
 static void __init acpi_osi_setup_late(void);
 
 /*
@@ -152,8 +149,7 @@ static struct osi_linux {
        unsigned int    enable:1;
        unsigned int    dmi:1;
        unsigned int    cmdline:1;
-       unsigned int    known:1;
-} osi_linux = { 0, 0, 0, 0};
+} osi_linux = {0, 0, 0};
 
 static u32 acpi_osi_handler(acpi_string interface, u32 supported)
 {
@@ -1055,13 +1051,53 @@ static int __init acpi_os_name_setup(char *str)
 
 __setup("acpi_os_name=", acpi_os_name_setup);
 
+#define        OSI_STRING_LENGTH_MAX 64        /* arbitrary */
+#define        OSI_STRING_ENTRIES_MAX 16       /* arbitrary */
+
+struct osi_setup_entry {
+       char string[OSI_STRING_LENGTH_MAX];
+       bool enable;
+};
+
+static struct osi_setup_entry __initdata osi_setup_entries[OSI_STRING_ENTRIES_MAX];
+
+void __init acpi_osi_setup(char *str)
+{
+       struct osi_setup_entry *osi;
+       bool enable = true;
+       int i;
+
+       if (!acpi_gbl_create_osi_method)
+               return;
+
+       if (str == NULL || *str == '\0') {
+               printk(KERN_INFO PREFIX "_OSI method disabled\n");
+               acpi_gbl_create_osi_method = FALSE;
+               return;
+       }
+
+       if (*str == '!') {
+               str++;
+               enable = false;
+       }
+
+       for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) {
+               osi = &osi_setup_entries[i];
+               if (!strcmp(osi->string, str)) {
+                       osi->enable = enable;
+                       break;
+               } else if (osi->string[0] == '\0') {
+                       osi->enable = enable;
+                       strncpy(osi->string, str, OSI_STRING_LENGTH_MAX);
+                       break;
+               }
+       }
+}
+
 static void __init set_osi_linux(unsigned int enable)
 {
-       if (osi_linux.enable != enable) {
+       if (osi_linux.enable != enable)
                osi_linux.enable = enable;
-               printk(KERN_NOTICE PREFIX "%sed _OSI(Linux)\n",
-                       enable ? "Add": "Delet");
-       }
 
        if (osi_linux.enable)
                acpi_osi_setup("Linux");
@@ -1073,7 +1109,8 @@ static void __init set_osi_linux(unsigned int enable)
 
 static void __init acpi_cmdline_osi_linux(unsigned int enable)
 {
-       osi_linux.cmdline = 1;  /* cmdline set the default */
+       osi_linux.cmdline = 1;  /* cmdline set the default and override DMI */
+       osi_linux.dmi = 0;
        set_osi_linux(enable);
 
        return;
@@ -1081,15 +1118,12 @@ static void __init acpi_cmdline_osi_linux(unsigned int enable)
 
 void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d)
 {
-       osi_linux.dmi = 1;      /* DMI knows that this box asks OSI(Linux) */
-
        printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident);
 
        if (enable == -1)
                return;
 
-       osi_linux.known = 1;    /* DMI knows which OSI(Linux) default needed */
-
+       osi_linux.dmi = 1;      /* DMI knows that this box asks OSI(Linux) */
        set_osi_linux(enable);
 
        return;
@@ -1104,37 +1138,44 @@ void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d)
  */
 static void __init acpi_osi_setup_late(void)
 {
-       char *str = osi_setup_string;
+       struct osi_setup_entry *osi;
+       char *str;
+       int i;
+       acpi_status status;
 
-       if (*str == '\0')
-               return;
+       for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) {
+               osi = &osi_setup_entries[i];
+               str = osi->string;
 
-       if (!strcmp("!Linux", str)) {
-               acpi_cmdline_osi_linux(0);      /* !enable */
-       } else if (*str == '!') {
-               if (acpi_remove_interface(++str) == AE_OK)
-                       printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str);
-       } else if (!strcmp("Linux", str)) {
-               acpi_cmdline_osi_linux(1);      /* enable */
-       } else {
-               if (acpi_install_interface(str) == AE_OK)
-                       printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str);
+               if (*str == '\0')
+                       break;
+               if (osi->enable) {
+                       status = acpi_install_interface(str);
+
+                       if (ACPI_SUCCESS(status))
+                               printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str);
+               } else {
+                       status = acpi_remove_interface(str);
+
+                       if (ACPI_SUCCESS(status))
+                               printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str);
+               }
        }
 }
 
-int __init acpi_osi_setup(char *str)
+static int __init osi_setup(char *str)
 {
-       if (str == NULL || *str == '\0') {
-               printk(KERN_INFO PREFIX "_OSI method disabled\n");
-               acpi_gbl_create_osi_method = FALSE;
-       } else {
-               strncpy(osi_setup_string, str, OSI_STRING_LENGTH_MAX);
-       }
+       if (str && !strcmp("Linux", str))
+               acpi_cmdline_osi_linux(1);
+       else if (str && !strcmp("!Linux", str))
+               acpi_cmdline_osi_linux(0);
+       else
+               acpi_osi_setup(str);
 
        return 1;
 }
 
-__setup("acpi_osi=", acpi_osi_setup);
+__setup("acpi_osi=", osi_setup);
 
 /* enable serialization to combat AE_ALREADY_EXISTS errors */
 static int __init acpi_serialize_setup(char *str)
@@ -1530,7 +1571,7 @@ acpi_status __init acpi_os_initialize(void)
        return AE_OK;
 }
 
-acpi_status acpi_os_initialize1(void)
+acpi_status __init acpi_os_initialize1(void)
 {
        kacpid_wq = create_workqueue("kacpid");
        kacpi_notify_wq = create_workqueue("kacpi_notify");
index 67dedee..4c9c2fb 100644 (file)
@@ -213,11 +213,13 @@ static int acpi_power_on(acpi_handle handle)
                                  resource->name));
        } else {
                result = __acpi_power_on(resource);
+               if (result)
+                       resource->ref_count--;
        }
 
        mutex_unlock(&resource->resource_lock);
 
-       return 0;
+       return result;
 }
 
 static int acpi_power_off_device(acpi_handle handle)
@@ -465,10 +467,12 @@ int acpi_power_transition(struct acpi_device *device, int state)
        struct acpi_handle_list *tl = NULL;     /* Target Resources */
        int i = 0;
 
-
        if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3))
                return -EINVAL;
 
+       if (device->power.state == state)
+               return 0;
+
        if ((device->power.state < ACPI_STATE_D0)
            || (device->power.state > ACPI_STATE_D3))
                return -ENODEV;
@@ -488,10 +492,6 @@ int acpi_power_transition(struct acpi_device *device, int state)
                        goto end;
        }
 
-       if (device->power.state == state) {
-               goto end;
-       }
-
        /*
         * Then we dereference all power resources used in the current list.
         */
index fde49b9..79cb653 100644 (file)
@@ -156,15 +156,6 @@ static int cpufreq_set_cur_state(unsigned int cpu, int state)
        return 0;
 }
 
-static int acpi_thermal_cpufreq_increase(unsigned int cpu)
-{
-       return -ENODEV;
-}
-static int acpi_thermal_cpufreq_decrease(unsigned int cpu)
-{
-       return -ENODEV;
-}
-
 #endif
 
 int acpi_processor_get_limit_info(struct acpi_processor *pr)
index 721d93b..febb153 100644 (file)
@@ -27,8 +27,6 @@
 
 static u8 sleep_states[ACPI_S_STATE_COUNT];
 
-static u32 acpi_target_sleep_state = ACPI_STATE_S0;
-
 static void acpi_sleep_tts_switch(u32 acpi_state)
 {
        union acpi_object in_arg = { ACPI_TYPE_INTEGER };
@@ -81,6 +79,8 @@ static int acpi_sleep_prepare(u32 acpi_state)
 }
 
 #ifdef CONFIG_ACPI_SLEEP
+static u32 acpi_target_sleep_state = ACPI_STATE_S0;
+
 /*
  * The ACPI specification wants us to save NVS memory regions during hibernation
  * and to restore them during the subsequent resume.  Windows does that also for
@@ -427,6 +427,14 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
                DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB1Z1E"),
                },
        },
+       {
+       .callback = init_nvs_nosave,
+       .ident = "Sony Vaio VGN-NW130D",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+               DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NW130D"),
+               },
+       },
        {},
 };
 #endif /* CONFIG_SUSPEND */
index 46b9476..f9b983a 100644 (file)
@@ -154,7 +154,7 @@ static int __init adummy_init(void)
                err = -ENOMEM;
                goto out;
        }
-       atm_dev = atm_dev_register(DEV_LABEL, &adummy_ops, -1, NULL);
+       atm_dev = atm_dev_register(DEV_LABEL, NULL, &adummy_ops, -1, NULL);
        if (!atm_dev) {
                printk(KERN_ERR DEV_LABEL ": atm_dev_register() failed\n");
                err = -ENODEV;
index a33896a..ffe9b65 100644 (file)
@@ -2244,7 +2244,8 @@ static int __devinit amb_probe(struct pci_dev *pci_dev, const struct pci_device_
                goto out_reset;
        }
 
-       dev->atm_dev = atm_dev_register (DEV_LABEL, &amb_ops, -1, NULL);
+       dev->atm_dev = atm_dev_register (DEV_LABEL, &pci_dev->dev, &amb_ops, -1,
+                                        NULL);
        if (!dev->atm_dev) {
                PRINTD (DBG_ERR, "failed to register Madge ATM adapter");
                err = -EINVAL;
index b910181..2b464b6 100644 (file)
@@ -366,7 +366,7 @@ static int atmtcp_create(int itf,int persist,struct atm_dev **result)
        if (!dev_data)
                return -ENOMEM;
 
-       dev = atm_dev_register(DEV_LABEL,&atmtcp_v_dev_ops,itf,NULL);
+       dev = atm_dev_register(DEV_LABEL,NULL,&atmtcp_v_dev_ops,itf,NULL);
        if (!dev) {
                kfree(dev_data);
                return itf == -1 ? -ENOMEM : -EBUSY;
index 97c5898..c495fae 100644 (file)
@@ -2244,7 +2244,7 @@ static int __devinit eni_init_one(struct pci_dev *pci_dev,
                    &zeroes);
                if (!cpu_zeroes) goto out1;
        }
-       dev = atm_dev_register(DEV_LABEL,&ops,-1,NULL);
+       dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &ops, -1, NULL);
        if (!dev) goto out2;
        pci_set_drvdata(pci_dev, dev);
        eni_dev->pci_dev = pci_dev;
index 5d86bb8..7d912ba 100644 (file)
@@ -1911,7 +1911,7 @@ static int __devinit firestream_init_one (struct pci_dev *pci_dev,
                    fs_dev, sizeof (struct fs_dev));
        if (!fs_dev)
                goto err_out;
-       atm_dev = atm_dev_register("fs", &ops, -1, NULL);
+       atm_dev = atm_dev_register("fs", &pci_dev->dev, &ops, -1, NULL);
        if (!atm_dev)
                goto err_out_free_fs_dev;
   
index c8fc69c..962c309 100644 (file)
@@ -2567,14 +2567,14 @@ release:
 
 
 static int __devinit
-fore200e_register(struct fore200e* fore200e)
+fore200e_register(struct fore200e* fore200e, struct device *parent)
 {
     struct atm_dev* atm_dev;
 
     DPRINTK(2, "device %s being registered\n", fore200e->name);
 
-    atm_dev = atm_dev_register(fore200e->bus->proc_name, &fore200e_ops, -1,
-      NULL); 
+    atm_dev = atm_dev_register(fore200e->bus->proc_name, parent, &fore200e_ops,
+                               -1, NULL);
     if (atm_dev == NULL) {
        printk(FORE200E "unable to register device %s\n", fore200e->name);
        return -ENODEV;
@@ -2594,9 +2594,9 @@ fore200e_register(struct fore200e* fore200e)
 
 
 static int __devinit
-fore200e_init(struct fore200e* fore200e)
+fore200e_init(struct fore200e* fore200e, struct device *parent)
 {
-    if (fore200e_register(fore200e) < 0)
+    if (fore200e_register(fore200e, parent) < 0)
        return -ENODEV;
     
     if (fore200e->bus->configure(fore200e) < 0)
@@ -2662,7 +2662,7 @@ static int __devinit fore200e_sba_probe(struct platform_device *op,
 
        sprintf(fore200e->name, "%s-%d", bus->model_name, index);
 
-       err = fore200e_init(fore200e);
+       err = fore200e_init(fore200e, &op->dev);
        if (err < 0) {
                fore200e_shutdown(fore200e);
                kfree(fore200e);
@@ -2740,7 +2740,7 @@ fore200e_pca_detect(struct pci_dev *pci_dev, const struct pci_device_id *pci_ent
 
     sprintf(fore200e->name, "%s-%d", bus->model_name, index);
 
-    err = fore200e_init(fore200e);
+    err = fore200e_init(fore200e, &pci_dev->dev);
     if (err < 0) {
        fore200e_shutdown(fore200e);
        goto out_free;
index 801e8b6..6cf59bf 100644 (file)
@@ -366,7 +366,7 @@ he_init_one(struct pci_dev *pci_dev, const struct pci_device_id *pci_ent)
                goto init_one_failure;
        }
 
-       atm_dev = atm_dev_register(DEV_LABEL, &he_ops, -1, NULL);
+       atm_dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &he_ops, -1, NULL);
        if (!atm_dev) {
                err = -ENODEV;
                goto init_one_failure;
index a957904..24761e1 100644 (file)
@@ -2733,7 +2733,8 @@ static int __devinit hrz_probe(struct pci_dev *pci_dev, const struct pci_device_
        PRINTD(DBG_INFO, "found Madge ATM adapter (hrz) at: IO %x, IRQ %u, MEM %p",
               iobase, irq, membase);
 
-       dev->atm_dev = atm_dev_register(DEV_LABEL, &hrz_ops, -1, NULL);
+       dev->atm_dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &hrz_ops, -1,
+                                       NULL);
        if (!(dev->atm_dev)) {
                PRINTD(DBG_ERR, "failed to register Madge ATM adapter");
                err = -EINVAL;
index bce5732..bfb7fee 100644 (file)
@@ -3698,7 +3698,8 @@ idt77252_init_one(struct pci_dev *pcidev, const struct pci_device_id *id)
                goto err_out_iounmap;
        }
 
-       dev = atm_dev_register("idt77252", &idt77252_ops, -1, NULL);
+       dev = atm_dev_register("idt77252", &pcidev->dev, &idt77252_ops, -1,
+                              NULL);
        if (!dev) {
                printk("%s: can't register atm device\n", card->name);
                err = -EIO;
index 9309d47..7292540 100644 (file)
@@ -3172,7 +3172,7 @@ static int __devinit ia_init_one(struct pci_dev *pdev,
                ret = -ENODEV;
                goto err_out_free_iadev;
        }
-       dev = atm_dev_register(DEV_LABEL, &ops, -1, NULL);
+       dev = atm_dev_register(DEV_LABEL, &pdev->dev, &ops, -1, NULL);
        if (!dev) {
                ret = -ENOMEM;
                goto err_out_disable_dev;
index cbe15a8..a395c9a 100644 (file)
@@ -2591,7 +2591,7 @@ static int __devinit lanai_init_one(struct pci_dev *pci,
                return -ENOMEM;
        }
 
-       atmdev = atm_dev_register(DEV_LABEL, &ops, -1, NULL);
+       atmdev = atm_dev_register(DEV_LABEL, &pci->dev, &ops, -1, NULL);
        if (atmdev == NULL) {
                printk(KERN_ERR DEV_LABEL
                    ": couldn't register atm device!\n");
index 2f3516b..6b313ee 100644 (file)
@@ -771,7 +771,8 @@ static int __devinit ns_init_card(int i, struct pci_dev *pcidev)
        }
 
        /* Register device */
-       card->atmdev = atm_dev_register("nicstar", &atm_ops, -1, NULL);
+       card->atmdev = atm_dev_register("nicstar", &card->pcidev->dev, &atm_ops,
+                                       -1, NULL);
        if (card->atmdev == NULL) {
                printk("nicstar%d: can't register device.\n", i);
                error = 17;
index 2e08c99..73fb1c4 100644 (file)
@@ -166,7 +166,7 @@ static irqreturn_t solos_irq(int irq, void *dev_id);
 static struct atm_vcc* find_vcc(struct atm_dev *dev, short vpi, int vci);
 static int list_vccs(int vci);
 static void release_vccs(struct atm_dev *dev);
-static int atm_init(struct solos_card *);
+static int atm_init(struct solos_card *, struct device *);
 static void atm_remove(struct solos_card *);
 static int send_command(struct solos_card *card, int dev, const char *buf, size_t size);
 static void solos_bh(unsigned long);
@@ -1210,7 +1210,7 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id)
        if (db_firmware_upgrade)
                flash_upgrade(card, 3);
 
-       err = atm_init(card);
+       err = atm_init(card, &dev->dev);
        if (err)
                goto out_free_irq;
 
@@ -1233,7 +1233,7 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id)
        return err;
 }
 
-static int atm_init(struct solos_card *card)
+static int atm_init(struct solos_card *card, struct device *parent)
 {
        int i;
 
@@ -1244,7 +1244,7 @@ static int atm_init(struct solos_card *card)
                skb_queue_head_init(&card->tx_queue[i]);
                skb_queue_head_init(&card->cli_queue[i]);
 
-               card->atmdev[i] = atm_dev_register("solos-pci", &fpga_ops, -1, NULL);
+               card->atmdev[i] = atm_dev_register("solos-pci", parent, &fpga_ops, -1, NULL);
                if (!card->atmdev[i]) {
                        dev_err(&card->dev->dev, "Could not register ATM device %d\n", i);
                        atm_remove(card);
index 4e885d2..6249179 100644 (file)
@@ -1597,7 +1597,7 @@ static int __devinit zatm_init_one(struct pci_dev *pci_dev,
                goto out;
        }
 
-       dev = atm_dev_register(DEV_LABEL, &ops, -1, NULL);
+       dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &ops, -1, NULL);
        if (!dev)
                goto out_free;
 
index 6ec9d53..008d4a0 100644 (file)
 
 
 
-   Instructions for use
-   --------------------
+   For usage instructions, please refer to:
 
-   1) Map a Linux block device to an existing rbd image.
-
-      Usage: <mon ip addr> <options> <pool name> <rbd image name> [snap name]
-
-      $ echo "192.168.0.1 name=admin rbd foo" > /sys/class/rbd/add
-
-      The snapshot name can be "-" or omitted to map the image read/write.
-
-   2) List all active blkdev<->object mappings.
-
-      In this example, we have performed step #1 twice, creating two blkdevs,
-      mapped to two separate rados objects in the rados rbd pool
-
-      $ cat /sys/class/rbd/list
-      #id     major   client_name     pool    name    snap    KB
-      0       254     client4143      rbd     foo     -      1024000
-
-      The columns, in order, are:
-      - blkdev unique id
-      - blkdev assigned major
-      - rados client id
-      - rados pool name
-      - rados block device name
-      - mapped snapshot ("-" if none)
-      - device size in KB
-
-
-   3) Create a snapshot.
-
-      Usage: <blkdev id> <snapname>
-
-      $ echo "0 mysnap" > /sys/class/rbd/snap_create
-
-
-   4) Listing a snapshot.
-
-      $ cat /sys/class/rbd/snaps_list
-      #id     snap    KB
-      0       -       1024000 (*)
-      0       foo     1024000
-
-      The columns, in order, are:
-      - blkdev unique id
-      - snapshot name, '-' means none (active read/write version)
-      - size of device at time of snapshot
-      - the (*) indicates this is the active version
-
-   5) Rollback to snapshot.
-
-      Usage: <blkdev id> <snapname>
-
-      $ echo "0 mysnap" > /sys/class/rbd/snap_rollback
-
-
-   6) Mapping an image using snapshot.
-
-      A snapshot mapping is read-only. This is being done by passing
-      snap=<snapname> to the options when adding a device.
-
-      $ echo "192.168.0.1 name=admin,snap=mysnap rbd foo" > /sys/class/rbd/add
-
-
-   7) Remove an active blkdev<->rbd image mapping.
-
-      In this example, we remove the mapping with blkdev unique id 1.
-
-      $ echo 1 > /sys/class/rbd/remove
-
-
-   NOTE:  The actual creation and deletion of rados objects is outside the scope
-   of this driver.
+                 Documentation/ABI/testing/sysfs-bus-rbd
 
  */
 
@@ -163,6 +92,14 @@ struct rbd_request {
        u64                     len;
 };
 
+struct rbd_snap {
+       struct  device          dev;
+       const char              *name;
+       size_t                  size;
+       struct list_head        node;
+       u64                     id;
+};
+
 /*
  * a single device
  */
@@ -193,21 +130,60 @@ struct rbd_device {
        int read_only;
 
        struct list_head        node;
+
+       /* list of snapshots */
+       struct list_head        snaps;
+
+       /* sysfs related */
+       struct device           dev;
+};
+
+static struct bus_type rbd_bus_type = {
+       .name           = "rbd",
 };
 
 static spinlock_t node_lock;      /* protects client get/put */
 
-static struct class *class_rbd;          /* /sys/class/rbd */
 static DEFINE_MUTEX(ctl_mutex);          /* Serialize open/close/setup/teardown */
 static LIST_HEAD(rbd_dev_list);    /* devices */
 static LIST_HEAD(rbd_client_list);      /* clients */
 
+static int __rbd_init_snaps_header(struct rbd_device *rbd_dev);
+static void rbd_dev_release(struct device *dev);
+static ssize_t rbd_snap_rollback(struct device *dev,
+                                struct device_attribute *attr,
+                                const char *buf,
+                                size_t size);
+static ssize_t rbd_snap_add(struct device *dev,
+                           struct device_attribute *attr,
+                           const char *buf,
+                           size_t count);
+static void __rbd_remove_snap_dev(struct rbd_device *rbd_dev,
+                                 struct rbd_snap *snap);;
+
+
+static struct rbd_device *dev_to_rbd(struct device *dev)
+{
+       return container_of(dev, struct rbd_device, dev);
+}
+
+static struct device *rbd_get_dev(struct rbd_device *rbd_dev)
+{
+       return get_device(&rbd_dev->dev);
+}
+
+static void rbd_put_dev(struct rbd_device *rbd_dev)
+{
+       put_device(&rbd_dev->dev);
+}
 
 static int rbd_open(struct block_device *bdev, fmode_t mode)
 {
        struct gendisk *disk = bdev->bd_disk;
        struct rbd_device *rbd_dev = disk->private_data;
 
+       rbd_get_dev(rbd_dev);
+
        set_device_ro(bdev, rbd_dev->read_only);
 
        if ((mode & FMODE_WRITE) && rbd_dev->read_only)
@@ -216,9 +192,19 @@ static int rbd_open(struct block_device *bdev, fmode_t mode)
        return 0;
 }
 
+static int rbd_release(struct gendisk *disk, fmode_t mode)
+{
+       struct rbd_device *rbd_dev = disk->private_data;
+
+       rbd_put_dev(rbd_dev);
+
+       return 0;
+}
+
 static const struct block_device_operations rbd_bd_ops = {
        .owner                  = THIS_MODULE,
        .open                   = rbd_open,
+       .release                = rbd_release,
 };
 
 /*
@@ -361,7 +347,6 @@ static int rbd_header_from_disk(struct rbd_image_header *header,
        int ret = -ENOMEM;
 
        init_rwsem(&header->snap_rwsem);
-
        header->snap_names_len = le64_to_cpu(ondisk->snap_names_len);
        header->snapc = kmalloc(sizeof(struct ceph_snap_context) +
                                snap_count *
@@ -1256,10 +1241,20 @@ bad:
        return -ERANGE;
 }
 
+static void __rbd_remove_all_snaps(struct rbd_device *rbd_dev)
+{
+       struct rbd_snap *snap;
+
+       while (!list_empty(&rbd_dev->snaps)) {
+               snap = list_first_entry(&rbd_dev->snaps, struct rbd_snap, node);
+               __rbd_remove_snap_dev(rbd_dev, snap);
+       }
+}
+
 /*
  * only read the first part of the ondisk header, without the snaps info
  */
-static int rbd_update_snaps(struct rbd_device *rbd_dev)
+static int __rbd_update_snaps(struct rbd_device *rbd_dev)
 {
        int ret;
        struct rbd_image_header h;
@@ -1280,12 +1275,15 @@ static int rbd_update_snaps(struct rbd_device *rbd_dev)
        rbd_dev->header.total_snaps = h.total_snaps;
        rbd_dev->header.snapc = h.snapc;
        rbd_dev->header.snap_names = h.snap_names;
+       rbd_dev->header.snap_names_len = h.snap_names_len;
        rbd_dev->header.snap_sizes = h.snap_sizes;
        rbd_dev->header.snapc->seq = snap_seq;
 
+       ret = __rbd_init_snaps_header(rbd_dev);
+
        up_write(&rbd_dev->header.snap_rwsem);
 
-       return 0;
+       return ret;
 }
 
 static int rbd_init_disk(struct rbd_device *rbd_dev)
@@ -1300,6 +1298,11 @@ static int rbd_init_disk(struct rbd_device *rbd_dev)
        if (rc)
                return rc;
 
+       /* no need to lock here, as rbd_dev is not registered yet */
+       rc = __rbd_init_snaps_header(rbd_dev);
+       if (rc)
+               return rc;
+
        rc = rbd_header_set_snap(rbd_dev, rbd_dev->snap_name, &total_size);
        if (rc)
                return rc;
@@ -1343,54 +1346,360 @@ out:
        return rc;
 }
 
-/********************************************************************
- * /sys/class/rbd/
- *                   add       map rados objects to blkdev
- *                   remove    unmap rados objects
- *                   list      show mappings
- *******************************************************************/
+/*
+  sysfs
+*/
+
+static ssize_t rbd_size_show(struct device *dev,
+                            struct device_attribute *attr, char *buf)
+{
+       struct rbd_device *rbd_dev = dev_to_rbd(dev);
+
+       return sprintf(buf, "%llu\n", (unsigned long long)rbd_dev->header.image_size);
+}
+
+static ssize_t rbd_major_show(struct device *dev,
+                             struct device_attribute *attr, char *buf)
+{
+       struct rbd_device *rbd_dev = dev_to_rbd(dev);
 
-static void class_rbd_release(struct class *cls)
+       return sprintf(buf, "%d\n", rbd_dev->major);
+}
+
+static ssize_t rbd_client_id_show(struct device *dev,
+                                 struct device_attribute *attr, char *buf)
 {
-       kfree(cls);
+       struct rbd_device *rbd_dev = dev_to_rbd(dev);
+
+       return sprintf(buf, "client%lld\n", ceph_client_id(rbd_dev->client));
 }
 
-static ssize_t class_rbd_list(struct class *c,
-                             struct class_attribute *attr,
-                             char *data)
+static ssize_t rbd_pool_show(struct device *dev,
+                            struct device_attribute *attr, char *buf)
 {
-       int n = 0;
-       struct list_head *tmp;
-       int max = PAGE_SIZE;
+       struct rbd_device *rbd_dev = dev_to_rbd(dev);
+
+       return sprintf(buf, "%s\n", rbd_dev->pool_name);
+}
+
+static ssize_t rbd_name_show(struct device *dev,
+                            struct device_attribute *attr, char *buf)
+{
+       struct rbd_device *rbd_dev = dev_to_rbd(dev);
+
+       return sprintf(buf, "%s\n", rbd_dev->obj);
+}
+
+static ssize_t rbd_snap_show(struct device *dev,
+                            struct device_attribute *attr,
+                            char *buf)
+{
+       struct rbd_device *rbd_dev = dev_to_rbd(dev);
+
+       return sprintf(buf, "%s\n", rbd_dev->snap_name);
+}
+
+static ssize_t rbd_image_refresh(struct device *dev,
+                                struct device_attribute *attr,
+                                const char *buf,
+                                size_t size)
+{
+       struct rbd_device *rbd_dev = dev_to_rbd(dev);
+       int rc;
+       int ret = size;
 
        mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
 
-       n += snprintf(data, max,
-                     "#id\tmajor\tclient_name\tpool\tname\tsnap\tKB\n");
+       rc = __rbd_update_snaps(rbd_dev);
+       if (rc < 0)
+               ret = rc;
 
-       list_for_each(tmp, &rbd_dev_list) {
-               struct rbd_device *rbd_dev;
+       mutex_unlock(&ctl_mutex);
+       return ret;
+}
 
-               rbd_dev = list_entry(tmp, struct rbd_device, node);
-               n += snprintf(data+n, max-n,
-                             "%d\t%d\tclient%lld\t%s\t%s\t%s\t%lld\n",
-                             rbd_dev->id,
-                             rbd_dev->major,
-                             ceph_client_id(rbd_dev->client),
-                             rbd_dev->pool_name,
-                             rbd_dev->obj, rbd_dev->snap_name,
-                             rbd_dev->header.image_size >> 10);
-               if (n == max)
+static DEVICE_ATTR(size, S_IRUGO, rbd_size_show, NULL);
+static DEVICE_ATTR(major, S_IRUGO, rbd_major_show, NULL);
+static DEVICE_ATTR(client_id, S_IRUGO, rbd_client_id_show, NULL);
+static DEVICE_ATTR(pool, S_IRUGO, rbd_pool_show, NULL);
+static DEVICE_ATTR(name, S_IRUGO, rbd_name_show, NULL);
+static DEVICE_ATTR(refresh, S_IWUSR, NULL, rbd_image_refresh);
+static DEVICE_ATTR(current_snap, S_IRUGO, rbd_snap_show, NULL);
+static DEVICE_ATTR(create_snap, S_IWUSR, NULL, rbd_snap_add);
+static DEVICE_ATTR(rollback_snap, S_IWUSR, NULL, rbd_snap_rollback);
+
+static struct attribute *rbd_attrs[] = {
+       &dev_attr_size.attr,
+       &dev_attr_major.attr,
+       &dev_attr_client_id.attr,
+       &dev_attr_pool.attr,
+       &dev_attr_name.attr,
+       &dev_attr_current_snap.attr,
+       &dev_attr_refresh.attr,
+       &dev_attr_create_snap.attr,
+       &dev_attr_rollback_snap.attr,
+       NULL
+};
+
+static struct attribute_group rbd_attr_group = {
+       .attrs = rbd_attrs,
+};
+
+static const struct attribute_group *rbd_attr_groups[] = {
+       &rbd_attr_group,
+       NULL
+};
+
+static void rbd_sysfs_dev_release(struct device *dev)
+{
+}
+
+static struct device_type rbd_device_type = {
+       .name           = "rbd",
+       .groups         = rbd_attr_groups,
+       .release        = rbd_sysfs_dev_release,
+};
+
+
+/*
+  sysfs - snapshots
+*/
+
+static ssize_t rbd_snap_size_show(struct device *dev,
+                                 struct device_attribute *attr,
+                                 char *buf)
+{
+       struct rbd_snap *snap = container_of(dev, struct rbd_snap, dev);
+
+       return sprintf(buf, "%lld\n", (long long)snap->size);
+}
+
+static ssize_t rbd_snap_id_show(struct device *dev,
+                               struct device_attribute *attr,
+                               char *buf)
+{
+       struct rbd_snap *snap = container_of(dev, struct rbd_snap, dev);
+
+       return sprintf(buf, "%lld\n", (long long)snap->id);
+}
+
+static DEVICE_ATTR(snap_size, S_IRUGO, rbd_snap_size_show, NULL);
+static DEVICE_ATTR(snap_id, S_IRUGO, rbd_snap_id_show, NULL);
+
+static struct attribute *rbd_snap_attrs[] = {
+       &dev_attr_snap_size.attr,
+       &dev_attr_snap_id.attr,
+       NULL,
+};
+
+static struct attribute_group rbd_snap_attr_group = {
+       .attrs = rbd_snap_attrs,
+};
+
+static void rbd_snap_dev_release(struct device *dev)
+{
+       struct rbd_snap *snap = container_of(dev, struct rbd_snap, dev);
+       kfree(snap->name);
+       kfree(snap);
+}
+
+static const struct attribute_group *rbd_snap_attr_groups[] = {
+       &rbd_snap_attr_group,
+       NULL
+};
+
+static struct device_type rbd_snap_device_type = {
+       .groups         = rbd_snap_attr_groups,
+       .release        = rbd_snap_dev_release,
+};
+
+static void __rbd_remove_snap_dev(struct rbd_device *rbd_dev,
+                                 struct rbd_snap *snap)
+{
+       list_del(&snap->node);
+       device_unregister(&snap->dev);
+}
+
+static int rbd_register_snap_dev(struct rbd_device *rbd_dev,
+                                 struct rbd_snap *snap,
+                                 struct device *parent)
+{
+       struct device *dev = &snap->dev;
+       int ret;
+
+       dev->type = &rbd_snap_device_type;
+       dev->parent = parent;
+       dev->release = rbd_snap_dev_release;
+       dev_set_name(dev, "snap_%s", snap->name);
+       ret = device_register(dev);
+
+       return ret;
+}
+
+static int __rbd_add_snap_dev(struct rbd_device *rbd_dev,
+                             int i, const char *name,
+                             struct rbd_snap **snapp)
+{
+       int ret;
+       struct rbd_snap *snap = kzalloc(sizeof(*snap), GFP_KERNEL);
+       if (!snap)
+               return -ENOMEM;
+       snap->name = kstrdup(name, GFP_KERNEL);
+       snap->size = rbd_dev->header.snap_sizes[i];
+       snap->id = rbd_dev->header.snapc->snaps[i];
+       if (device_is_registered(&rbd_dev->dev)) {
+               ret = rbd_register_snap_dev(rbd_dev, snap,
+                                            &rbd_dev->dev);
+               if (ret < 0)
+                       goto err;
+       }
+       *snapp = snap;
+       return 0;
+err:
+       kfree(snap->name);
+       kfree(snap);
+       return ret;
+}
+
+/*
+ * search for the previous snap in a null delimited string list
+ */
+const char *rbd_prev_snap_name(const char *name, const char *start)
+{
+       if (name < start + 2)
+               return NULL;
+
+       name -= 2;
+       while (*name) {
+               if (name == start)
+                       return start;
+               name--;
+       }
+       return name + 1;
+}
+
+/*
+ * compare the old list of snapshots that we have to what's in the header
+ * and update it accordingly. Note that the header holds the snapshots
+ * in a reverse order (from newest to oldest) and we need to go from
+ * older to new so that we don't get a duplicate snap name when
+ * doing the process (e.g., removed snapshot and recreated a new
+ * one with the same name.
+ */
+static int __rbd_init_snaps_header(struct rbd_device *rbd_dev)
+{
+       const char *name, *first_name;
+       int i = rbd_dev->header.total_snaps;
+       struct rbd_snap *snap, *old_snap = NULL;
+       int ret;
+       struct list_head *p, *n;
+
+       first_name = rbd_dev->header.snap_names;
+       name = first_name + rbd_dev->header.snap_names_len;
+
+       list_for_each_prev_safe(p, n, &rbd_dev->snaps) {
+               u64 cur_id;
+
+               old_snap = list_entry(p, struct rbd_snap, node);
+
+               if (i)
+                       cur_id = rbd_dev->header.snapc->snaps[i - 1];
+
+               if (!i || old_snap->id < cur_id) {
+                       /* old_snap->id was skipped, thus was removed */
+                       __rbd_remove_snap_dev(rbd_dev, old_snap);
+                       continue;
+               }
+               if (old_snap->id == cur_id) {
+                       /* we have this snapshot already */
+                       i--;
+                       name = rbd_prev_snap_name(name, first_name);
+                       continue;
+               }
+               for (; i > 0;
+                    i--, name = rbd_prev_snap_name(name, first_name)) {
+                       if (!name) {
+                               WARN_ON(1);
+                               return -EINVAL;
+                       }
+                       cur_id = rbd_dev->header.snapc->snaps[i];
+                       /* snapshot removal? handle it above */
+                       if (cur_id >= old_snap->id)
+                               break;
+                       /* a new snapshot */
+                       ret = __rbd_add_snap_dev(rbd_dev, i - 1, name, &snap);
+                       if (ret < 0)
+                               return ret;
+
+                       /* note that we add it backward so using n and not p */
+                       list_add(&snap->node, n);
+                       p = &snap->node;
+               }
+       }
+       /* we're done going over the old snap list, just add what's left */
+       for (; i > 0; i--) {
+               name = rbd_prev_snap_name(name, first_name);
+               if (!name) {
+                       WARN_ON(1);
+                       return -EINVAL;
+               }
+               ret = __rbd_add_snap_dev(rbd_dev, i - 1, name, &snap);
+               if (ret < 0)
+                       return ret;
+               list_add(&snap->node, &rbd_dev->snaps);
+       }
+
+       return 0;
+}
+
+
+static void rbd_root_dev_release(struct device *dev)
+{
+}
+
+static struct device rbd_root_dev = {
+       .init_name =    "rbd",
+       .release =      rbd_root_dev_release,
+};
+
+static int rbd_bus_add_dev(struct rbd_device *rbd_dev)
+{
+       int ret = -ENOMEM;
+       struct device *dev;
+       struct rbd_snap *snap;
+
+       mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
+       dev = &rbd_dev->dev;
+
+       dev->bus = &rbd_bus_type;
+       dev->type = &rbd_device_type;
+       dev->parent = &rbd_root_dev;
+       dev->release = rbd_dev_release;
+       dev_set_name(dev, "%d", rbd_dev->id);
+       ret = device_register(dev);
+       if (ret < 0)
+               goto done_free;
+
+       list_for_each_entry(snap, &rbd_dev->snaps, node) {
+               ret = rbd_register_snap_dev(rbd_dev, snap,
+                                            &rbd_dev->dev);
+               if (ret < 0)
                        break;
        }
 
        mutex_unlock(&ctl_mutex);
-       return n;
+       return 0;
+done_free:
+       mutex_unlock(&ctl_mutex);
+       return ret;
 }
 
-static ssize_t class_rbd_add(struct class *c,
-                            struct class_attribute *attr,
-                            const char *buf, size_t count)
+static void rbd_bus_del_dev(struct rbd_device *rbd_dev)
+{
+       device_unregister(&rbd_dev->dev);
+}
+
+static ssize_t rbd_add(struct bus_type *bus, const char *buf, size_t count)
 {
        struct ceph_osd_client *osdc;
        struct rbd_device *rbd_dev;
@@ -1419,6 +1728,7 @@ static ssize_t class_rbd_add(struct class *c,
        /* static rbd_device initialization */
        spin_lock_init(&rbd_dev->lock);
        INIT_LIST_HEAD(&rbd_dev->node);
+       INIT_LIST_HEAD(&rbd_dev->snaps);
 
        /* generate unique id: find highest unique id, add one */
        mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
@@ -1478,6 +1788,9 @@ static ssize_t class_rbd_add(struct class *c,
        }
        rbd_dev->major = irc;
 
+       rc = rbd_bus_add_dev(rbd_dev);
+       if (rc)
+               goto err_out_disk;
        /* set up and announce blkdev mapping */
        rc = rbd_init_disk(rbd_dev);
        if (rc)
@@ -1487,6 +1800,8 @@ static ssize_t class_rbd_add(struct class *c,
 
 err_out_blkdev:
        unregister_blkdev(rbd_dev->major, rbd_dev->name);
+err_out_disk:
+       rbd_free_disk(rbd_dev);
 err_out_client:
        rbd_put_client(rbd_dev);
        mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
@@ -1518,35 +1833,10 @@ static struct rbd_device *__rbd_get_dev(unsigned long id)
        return NULL;
 }
 
-static ssize_t class_rbd_remove(struct class *c,
-                               struct class_attribute *attr,
-                               const char *buf,
-                               size_t count)
+static void rbd_dev_release(struct device *dev)
 {
-       struct rbd_device *rbd_dev = NULL;
-       int target_id, rc;
-       unsigned long ul;
-
-       rc = strict_strtoul(buf, 10, &ul);
-       if (rc)
-               return rc;
-
-       /* convert to int; abort if we lost anything in the conversion */
-       target_id = (int) ul;
-       if (target_id != ul)
-               return -EINVAL;
-
-       /* remove object from list immediately */
-       mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
-
-       rbd_dev = __rbd_get_dev(target_id);
-       if (rbd_dev)
-               list_del_init(&rbd_dev->node);
-
-       mutex_unlock(&ctl_mutex);
-
-       if (!rbd_dev)
-               return -ENOENT;
+       struct rbd_device *rbd_dev =
+                       container_of(dev, struct rbd_device, dev);
 
        rbd_put_client(rbd_dev);
 
@@ -1557,67 +1847,11 @@ static ssize_t class_rbd_remove(struct class *c,
 
        /* release module ref */
        module_put(THIS_MODULE);
-
-       return count;
 }
 
-static ssize_t class_rbd_snaps_list(struct class *c,
-                             struct class_attribute *attr,
-                             char *data)
-{
-       struct rbd_device *rbd_dev = NULL;
-       struct list_head *tmp;
-       struct rbd_image_header *header;
-       int i, n = 0, max = PAGE_SIZE;
-       int ret;
-
-       mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
-
-       n += snprintf(data, max, "#id\tsnap\tKB\n");
-
-       list_for_each(tmp, &rbd_dev_list) {
-               char *names, *p;
-               struct ceph_snap_context *snapc;
-
-               rbd_dev = list_entry(tmp, struct rbd_device, node);
-               header = &rbd_dev->header;
-
-               down_read(&header->snap_rwsem);
-
-               names = header->snap_names;
-               snapc = header->snapc;
-
-               n += snprintf(data + n, max - n, "%d\t%s\t%lld%s\n",
-                             rbd_dev->id, RBD_SNAP_HEAD_NAME,
-                             header->image_size >> 10,
-                             (!rbd_dev->cur_snap ? " (*)" : ""));
-               if (n == max)
-                       break;
-
-               p = names;
-               for (i = 0; i < header->total_snaps; i++, p += strlen(p) + 1) {
-                       n += snprintf(data + n, max - n, "%d\t%s\t%lld%s\n",
-                             rbd_dev->id, p, header->snap_sizes[i] >> 10,
-                             (rbd_dev->cur_snap &&
-                              (snap_index(header, i) == rbd_dev->cur_snap) ?
-                              " (*)" : ""));
-                       if (n == max)
-                               break;
-               }
-
-               up_read(&header->snap_rwsem);
-       }
-
-
-       ret = n;
-       mutex_unlock(&ctl_mutex);
-       return ret;
-}
-
-static ssize_t class_rbd_snaps_refresh(struct class *c,
-                               struct class_attribute *attr,
-                               const char *buf,
-                               size_t count)
+static ssize_t rbd_remove(struct bus_type *bus,
+                         const char *buf,
+                         size_t count)
 {
        struct rbd_device *rbd_dev = NULL;
        int target_id, rc;
@@ -1641,95 +1875,70 @@ static ssize_t class_rbd_snaps_refresh(struct class *c,
                goto done;
        }
 
-       rc = rbd_update_snaps(rbd_dev);
-       if (rc < 0)
-               ret = rc;
+       list_del_init(&rbd_dev->node);
+
+       __rbd_remove_all_snaps(rbd_dev);
+       rbd_bus_del_dev(rbd_dev);
 
 done:
        mutex_unlock(&ctl_mutex);
        return ret;
 }
 
-static ssize_t class_rbd_snap_create(struct class *c,
-                               struct class_attribute *attr,
-                               const char *buf,
-                               size_t count)
+static ssize_t rbd_snap_add(struct device *dev,
+                           struct device_attribute *attr,
+                           const char *buf,
+                           size_t count)
 {
-       struct rbd_device *rbd_dev = NULL;
-       int target_id, ret;
-       char *name;
-
-       name = kmalloc(RBD_MAX_SNAP_NAME_LEN + 1, GFP_KERNEL);
+       struct rbd_device *rbd_dev = dev_to_rbd(dev);
+       int ret;
+       char *name = kmalloc(count + 1, GFP_KERNEL);
        if (!name)
                return -ENOMEM;
 
-       /* parse snaps add command */
-       if (sscanf(buf, "%d "
-                  "%" __stringify(RBD_MAX_SNAP_NAME_LEN) "s",
-                  &target_id,
-                  name) != 2) {
-               ret = -EINVAL;
-               goto done;
-       }
+       snprintf(name, count, "%s", buf);
 
        mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
 
-       rbd_dev = __rbd_get_dev(target_id);
-       if (!rbd_dev) {
-               ret = -ENOENT;
-               goto done_unlock;
-       }
-
        ret = rbd_header_add_snap(rbd_dev,
                                  name, GFP_KERNEL);
        if (ret < 0)
                goto done_unlock;
 
-       ret = rbd_update_snaps(rbd_dev);
+       ret = __rbd_update_snaps(rbd_dev);
        if (ret < 0)
                goto done_unlock;
 
        ret = count;
 done_unlock:
        mutex_unlock(&ctl_mutex);
-done:
        kfree(name);
        return ret;
 }
 
-static ssize_t class_rbd_rollback(struct class *c,
-                               struct class_attribute *attr,
-                               const char *buf,
-                               size_t count)
+static ssize_t rbd_snap_rollback(struct device *dev,
+                                struct device_attribute *attr,
+                                const char *buf,
+                                size_t count)
 {
-       struct rbd_device *rbd_dev = NULL;
-       int target_id, ret;
+       struct rbd_device *rbd_dev = dev_to_rbd(dev);
+       int ret;
        u64 snapid;
-       char snap_name[RBD_MAX_SNAP_NAME_LEN];
        u64 cur_ofs;
-       char *seg_name;
+       char *seg_name = NULL;
+       char *snap_name = kmalloc(count + 1, GFP_KERNEL);
+       ret = -ENOMEM;
+       if (!snap_name)
+               return ret;
 
        /* parse snaps add command */
-       if (sscanf(buf, "%d "
-                  "%" __stringify(RBD_MAX_SNAP_NAME_LEN) "s",
-                  &target_id,
-                  snap_name) != 2) {
-               return -EINVAL;
-       }
-
-       ret = -ENOMEM;
+       snprintf(snap_name, count, "%s", buf);
        seg_name = kmalloc(RBD_MAX_SEG_NAME_LEN + 1, GFP_NOIO);
        if (!seg_name)
-               return ret;
+               goto done;
 
        mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
 
-       rbd_dev = __rbd_get_dev(target_id);
-       if (!rbd_dev) {
-               ret = -ENOENT;
-               goto done_unlock;
-       }
-
        ret = snap_by_name(&rbd_dev->header, snap_name, &snapid, NULL);
        if (ret < 0)
                goto done_unlock;
@@ -1750,7 +1959,7 @@ static ssize_t class_rbd_rollback(struct class *c,
                                   seg_name, ret);
        }
 
-       ret = rbd_update_snaps(rbd_dev);
+       ret = __rbd_update_snaps(rbd_dev);
        if (ret < 0)
                goto done_unlock;
 
@@ -1758,57 +1967,42 @@ static ssize_t class_rbd_rollback(struct class *c,
 
 done_unlock:
        mutex_unlock(&ctl_mutex);
+done:
        kfree(seg_name);
+       kfree(snap_name);
 
        return ret;
 }
 
-static struct class_attribute class_rbd_attrs[] = {
-       __ATTR(add,             0200, NULL, class_rbd_add),
-       __ATTR(remove,          0200, NULL, class_rbd_remove),
-       __ATTR(list,            0444, class_rbd_list, NULL),
-       __ATTR(snaps_refresh,   0200, NULL, class_rbd_snaps_refresh),
-       __ATTR(snap_create,     0200, NULL, class_rbd_snap_create),
-       __ATTR(snaps_list,      0444, class_rbd_snaps_list, NULL),
-       __ATTR(snap_rollback,   0200, NULL, class_rbd_rollback),
+static struct bus_attribute rbd_bus_attrs[] = {
+       __ATTR(add, S_IWUSR, NULL, rbd_add),
+       __ATTR(remove, S_IWUSR, NULL, rbd_remove),
        __ATTR_NULL
 };
 
 /*
  * create control files in sysfs
- * /sys/class/rbd/...
+ * /sys/bus/rbd/...
  */
 static int rbd_sysfs_init(void)
 {
-       int ret = -ENOMEM;
+       int ret;
 
-       class_rbd = kzalloc(sizeof(*class_rbd), GFP_KERNEL);
-       if (!class_rbd)
-               goto out;
+       rbd_bus_type.bus_attrs = rbd_bus_attrs;
 
-       class_rbd->name = DRV_NAME;
-       class_rbd->owner = THIS_MODULE;
-       class_rbd->class_release = class_rbd_release;
-       class_rbd->class_attrs = class_rbd_attrs;
+       ret = bus_register(&rbd_bus_type);
+        if (ret < 0)
+               return ret;
 
-       ret = class_register(class_rbd);
-       if (ret)
-               goto out_class;
-       return 0;
+       ret = device_register(&rbd_root_dev);
 
-out_class:
-       kfree(class_rbd);
-       class_rbd = NULL;
-       pr_err(DRV_NAME ": failed to create class rbd\n");
-out:
        return ret;
 }
 
 static void rbd_sysfs_cleanup(void)
 {
-       if (class_rbd)
-               class_destroy(class_rbd);
-       class_rbd = NULL;
+       device_unregister(&rbd_root_dev);
+       bus_unregister(&rbd_bus_type);
 }
 
 int __init rbd_init(void)
index 4f9e22f..657873e 100644 (file)
@@ -72,7 +72,7 @@ struct blk_shadow {
 static DEFINE_MUTEX(blkfront_mutex);
 static const struct block_device_operations xlvbd_block_fops;
 
-#define BLK_RING_SIZE __RING_SIZE((struct blkif_sring *)0, PAGE_SIZE)
+#define BLK_RING_SIZE __CONST_RING_SIZE(blkif, PAGE_SIZE)
 
 /*
  * We have one of these per vbd, whether ide, scsi or 'other'.  They
index 128cae4..949ed09 100644 (file)
 static struct usb_device_id ath3k_table[] = {
        /* Atheros AR3011 */
        { USB_DEVICE(0x0CF3, 0x3000) },
+
+       /* Atheros AR3011 with sflash firmware*/
+       { USB_DEVICE(0x0CF3, 0x3002) },
+
        { }     /* Terminating entry */
 };
 
index ab3894f..1da773f 100644 (file)
@@ -99,6 +99,9 @@ static struct usb_device_id blacklist_table[] = {
        /* Broadcom BCM2033 without firmware */
        { USB_DEVICE(0x0a5c, 0x2033), .driver_info = BTUSB_IGNORE },
 
+       /* Atheros 3011 with sflash firmware */
+       { USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE },
+
        /* Broadcom BCM2035 */
        { USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU },
        { USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_WRONG_SCO_MTU },
@@ -239,7 +242,8 @@ static void btusb_intr_complete(struct urb *urb)
 
        err = usb_submit_urb(urb, GFP_ATOMIC);
        if (err < 0) {
-               BT_ERR("%s urb %p failed to resubmit (%d)",
+               if (err != -EPERM)
+                       BT_ERR("%s urb %p failed to resubmit (%d)",
                                                hdev->name, urb, -err);
                usb_unanchor_urb(urb);
        }
@@ -323,7 +327,8 @@ static void btusb_bulk_complete(struct urb *urb)
 
        err = usb_submit_urb(urb, GFP_ATOMIC);
        if (err < 0) {
-               BT_ERR("%s urb %p failed to resubmit (%d)",
+               if (err != -EPERM)
+                       BT_ERR("%s urb %p failed to resubmit (%d)",
                                                hdev->name, urb, -err);
                usb_unanchor_urb(urb);
        }
@@ -412,7 +417,8 @@ static void btusb_isoc_complete(struct urb *urb)
 
        err = usb_submit_urb(urb, GFP_ATOMIC);
        if (err < 0) {
-               BT_ERR("%s urb %p failed to resubmit (%d)",
+               if (err != -EPERM)
+                       BT_ERR("%s urb %p failed to resubmit (%d)",
                                                hdev->name, urb, -err);
                usb_unanchor_urb(urb);
        }
index 9272c38..16a2847 100644 (file)
@@ -812,8 +812,10 @@ static int intel_fake_agp_fetch_size(void)
 
 static void i830_cleanup(void)
 {
-       kunmap(intel_private.i8xx_page);
-       intel_private.i8xx_flush_page = NULL;
+       if (intel_private.i8xx_flush_page) {
+               kunmap(intel_private.i8xx_flush_page);
+               intel_private.i8xx_flush_page = NULL;
+       }
 
        __free_page(intel_private.i8xx_page);
        intel_private.i8xx_page = NULL;
index 1030f84..c17a305 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/wait.h>
+#include <linux/acpi.h>
 #include "tpm.h"
 
 #define TPM_HEADER_SIZE 10
@@ -78,6 +79,26 @@ enum tis_defaults {
 static LIST_HEAD(tis_chips);
 static DEFINE_SPINLOCK(tis_lock);
 
+#ifdef CONFIG_ACPI
+static int is_itpm(struct pnp_dev *dev)
+{
+       struct acpi_device *acpi = pnp_acpi_device(dev);
+       struct acpi_hardware_id *id;
+
+       list_for_each_entry(id, &acpi->pnp.ids, list) {
+               if (!strcmp("INTC0102", id->id))
+                       return 1;
+       }
+
+       return 0;
+}
+#else
+static int is_itpm(struct pnp_dev *dev)
+{
+       return 0;
+}
+#endif
+
 static int check_locality(struct tpm_chip *chip, int l)
 {
        if ((ioread8(chip->vendor.iobase + TPM_ACCESS(l)) &
@@ -472,6 +493,9 @@ static int tpm_tis_init(struct device *dev, resource_size_t start,
                 "1.2 TPM (device-id 0x%X, rev-id %d)\n",
                 vendor >> 16, ioread8(chip->vendor.iobase + TPM_RID(0)));
 
+       if (is_itpm(to_pnp_dev(dev)))
+               itpm = 1;
+
        if (itpm)
                dev_info(dev, "Intel iTPM workaround enabled\n");
 
index e16c3fa..05117f1 100644 (file)
@@ -36,6 +36,7 @@
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>");
 MODULE_DESCRIPTION("Generic userspace <-> kernelspace connector.");
+MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_CONNECTOR);
 
 static struct cn_dev cdev;
 
index a8a84f4..64b21f5 100644 (file)
@@ -1,8 +1,8 @@
 ifeq ($(CONFIG_DMADEVICES_DEBUG),y)
-       EXTRA_CFLAGS    += -DDEBUG
+       ccflags-y       += -DDEBUG
 endif
 ifeq ($(CONFIG_DMADEVICES_VDEBUG),y)
-       EXTRA_CFLAGS    += -DVERBOSE_DEBUG
+       ccflags-y       += -DVERBOSE_DEBUG
 endif
 
 obj-$(CONFIG_DMA_ENGINE) += dmaengine.o
index a0f3e6a..ea0ee81 100644 (file)
@@ -722,7 +722,7 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
                        desc->lli.daddr = mem;
                        desc->lli.ctrla = ctrla
                                        | ATC_DST_WIDTH(mem_width)
-                                       | len >> mem_width;
+                                       | len >> reg_width;
                        desc->lli.ctrlb = ctrlb;
 
                        if (!first) {
index 286c3ac..e5e172d 100644 (file)
@@ -50,9 +50,11 @@ static void dma_init(struct fsldma_chan *chan)
                 * EIE - Error interrupt enable
                 * EOSIE - End of segments interrupt enable (basic mode)
                 * EOLNIE - End of links interrupt enable
+                * BWC - Bandwidth sharing among channels
                 */
-               DMA_OUT(chan, &chan->regs->mr, FSL_DMA_MR_EIE
-                               | FSL_DMA_MR_EOLNIE | FSL_DMA_MR_EOSIE, 32);
+               DMA_OUT(chan, &chan->regs->mr, FSL_DMA_MR_BWC
+                               | FSL_DMA_MR_EIE | FSL_DMA_MR_EOLNIE
+                               | FSL_DMA_MR_EOSIE, 32);
                break;
        case FSL_DMA_IP_83XX:
                /* Set the channel to below modes:
index cb4d6ff..ba9f403 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved.
+ * Copyright (C) 2007-2010 Freescale Semiconductor, Inc. All rights reserved.
  *
  * Author:
  *   Zhang Wei <wei.zhang@freescale.com>, Jul 2007
 #define FSL_DMA_MR_DAHE                0x00002000
 #define FSL_DMA_MR_SAHE                0x00001000
 
+/*
+ * Bandwidth/pause control determines how many bytes a given
+ * channel is allowed to transfer before the DMA engine pauses
+ * the current channel and switches to the next channel
+ */
+#define FSL_DMA_MR_BWC         0x08000000
+
 /* Special MR definition for MPC8349 */
 #define FSL_DMA_MR_EOTIE       0x00000080
 #define FSL_DMA_MR_PRC_RM      0x00000800
index f629e49..e53d438 100644 (file)
@@ -379,7 +379,7 @@ static int __init imxdma_probe(struct platform_device *pdev)
        return 0;
 
 err_init:
-       while (i-- >= 0) {
+       while (--i >= 0) {
                struct imxdma_channel *imxdmac = &imxdma->channel[i];
                imx_dma_free(imxdmac->imxdma_channel);
        }
index 0834323..d0602dd 100644 (file)
@@ -951,7 +951,7 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg(
                struct sdma_buffer_descriptor *bd = &sdmac->bd[i];
                int param;
 
-               bd->buffer_addr = sgl->dma_address;
+               bd->buffer_addr = sg->dma_address;
 
                count = sg->length;
 
@@ -1385,7 +1385,7 @@ static int __init sdma_module_init(void)
 {
        return platform_driver_probe(&sdma_driver, sdma_probe);
 }
-subsys_initcall(sdma_module_init);
+module_init(sdma_module_init);
 
 MODULE_AUTHOR("Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>");
 MODULE_DESCRIPTION("i.MX SDMA driver");
index 338bc4e..3109bd9 100644 (file)
@@ -1075,7 +1075,6 @@ static int mid_setup_dma(struct pci_dev *pdev)
        if (NULL == dma->dma_pool) {
                pr_err("ERR_MDMA:pci_pool_create failed\n");
                err = -ENOMEM;
-               kfree(dma);
                goto err_dma_pool;
        }
 
@@ -1186,7 +1185,6 @@ err_engine:
        free_irq(pdev->irq, dma);
 err_irq:
        pci_pool_destroy(dma->dma_pool);
-       kfree(dma);
 err_dma_pool:
        pr_err("ERR_MDMA:setup_dma failed: %d\n", err);
        return err;
@@ -1413,7 +1411,7 @@ static const struct dev_pm_ops intel_mid_dma_pm = {
        .runtime_idle = dma_runtime_idle,
 };
 
-static struct pci_driver intel_mid_dma_pci = {
+static struct pci_driver intel_mid_dma_pci_driver = {
        .name           =       "Intel MID DMA",
        .id_table       =       intel_mid_dma_ids,
        .probe          =       intel_mid_dma_probe,
@@ -1431,13 +1429,13 @@ static int __init intel_mid_dma_init(void)
 {
        pr_debug("INFO_MDMA: LNW DMA Driver Version %s\n",
                        INTEL_MID_DMA_DRIVER_VERSION);
-       return pci_register_driver(&intel_mid_dma_pci);
+       return pci_register_driver(&intel_mid_dma_pci_driver);
 }
 fs_initcall(intel_mid_dma_init);
 
 static void __exit intel_mid_dma_exit(void)
 {
-       pci_unregister_driver(&intel_mid_dma_pci);
+       pci_unregister_driver(&intel_mid_dma_pci_driver);
 }
 module_exit(intel_mid_dma_exit);
 
index 8997d3f..0ff7270 100644 (file)
@@ -1,2 +1,2 @@
 obj-$(CONFIG_INTEL_IOATDMA) += ioatdma.o
-ioatdma-objs := pci.o dma.o dma_v2.o dma_v3.o dca.o
+ioatdma-y := pci.o dma.o dma_v2.o dma_v3.o dca.o
index 92b6790..c064c89 100644 (file)
@@ -259,11 +259,6 @@ static void pdc_dostart(struct pch_dma_chan *pd_chan, struct pch_dma_desc* desc)
                return;
        }
 
-       channel_writel(pd_chan, DEV_ADDR, desc->regs.dev_addr);
-       channel_writel(pd_chan, MEM_ADDR, desc->regs.mem_addr);
-       channel_writel(pd_chan, SIZE, desc->regs.size);
-       channel_writel(pd_chan, NEXT, desc->regs.next);
-
        dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> dev_addr: %x\n",
                pd_chan->chan.chan_id, desc->regs.dev_addr);
        dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> mem_addr: %x\n",
@@ -273,10 +268,16 @@ static void pdc_dostart(struct pch_dma_chan *pd_chan, struct pch_dma_desc* desc)
        dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> next: %x\n",
                pd_chan->chan.chan_id, desc->regs.next);
 
-       if (list_empty(&desc->tx_list))
+       if (list_empty(&desc->tx_list)) {
+               channel_writel(pd_chan, DEV_ADDR, desc->regs.dev_addr);
+               channel_writel(pd_chan, MEM_ADDR, desc->regs.mem_addr);
+               channel_writel(pd_chan, SIZE, desc->regs.size);
+               channel_writel(pd_chan, NEXT, desc->regs.next);
                pdc_set_mode(&pd_chan->chan, DMA_CTL0_ONESHOT);
-       else
+       } else {
+               channel_writel(pd_chan, NEXT, desc->txd.phys);
                pdc_set_mode(&pd_chan->chan, DMA_CTL0_SG);
+       }
 
        val = dma_readl(pd, CTL2);
        val |= 1 << (DMA_CTL2_START_SHIFT_BITS + pd_chan->chan.chan_id);
index 0d58a4a..cef5845 100644 (file)
@@ -4449,9 +4449,8 @@ static int __devinit ppc440spe_adma_probe(struct platform_device *ofdev,
 
        if (!request_mem_region(res.start, resource_size(&res),
                                dev_driver_string(&ofdev->dev))) {
-               dev_err(&ofdev->dev, "failed to request memory region "
-                       "(0x%016llx-0x%016llx)\n",
-                       (u64)res.start, (u64)res.end);
+               dev_err(&ofdev->dev, "failed to request memory region %pR\n",
+                       &res);
                initcode = PPC_ADMA_INIT_MEMREG;
                ret = -EBUSY;
                goto out;
index eb6b54d..85ffd5e 100644 (file)
@@ -1213,3 +1213,4 @@ module_exit(sh_dmae_exit);
 MODULE_AUTHOR("Nobuhiro Iwamatsu <iwamatsu.nobuhiro@renesas.com>");
 MODULE_DESCRIPTION("Renesas SH DMA Engine driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:sh-dma-engine");
index b378139..ba2898b 100644 (file)
@@ -10,16 +10,16 @@ obj-$(CONFIG_EDAC)                  := edac_stub.o
 obj-$(CONFIG_EDAC_MM_EDAC)             += edac_core.o
 obj-$(CONFIG_EDAC_MCE)                 += edac_mce.o
 
-edac_core-objs := edac_mc.o edac_device.o edac_mc_sysfs.o edac_pci_sysfs.o
-edac_core-objs += edac_module.o edac_device_sysfs.o
+edac_core-y    := edac_mc.o edac_device.o edac_mc_sysfs.o edac_pci_sysfs.o
+edac_core-y    += edac_module.o edac_device_sysfs.o
 
 ifdef CONFIG_PCI
-edac_core-objs += edac_pci.o edac_pci_sysfs.o
+edac_core-y    += edac_pci.o edac_pci_sysfs.o
 endif
 
 obj-$(CONFIG_EDAC_MCE_INJ)             += mce_amd_inj.o
 
-edac_mce_amd-objs                      := mce_amd.o
+edac_mce_amd-y                         := mce_amd.o
 obj-$(CONFIG_EDAC_DECODE_MCE)          += edac_mce_amd.o
 
 obj-$(CONFIG_EDAC_AMD76X)              += amd76x_edac.o
index 8521401..eca9ba1 100644 (file)
@@ -1572,7 +1572,7 @@ static int f10_match_to_this_node(struct amd64_pvt *pvt, int dram_range,
        debugf1("   HoleOffset=0x%x  HoleValid=0x%x IntlvSel=0x%x\n",
                        hole_off, hole_valid, intlv_sel);
 
-       if (intlv_en ||
+       if (intlv_en &&
            (intlv_sel != ((sys_addr >> 12) & intlv_en)))
                return -EINVAL;
 
index d7ca43a..251440c 100644 (file)
 #define MC_PROC_NAME_MAX_LEN   7
 
 #if PAGE_SHIFT < 20
-#define PAGES_TO_MiB( pages )  ( ( pages ) >> ( 20 - PAGE_SHIFT ) )
-#define MiB_TO_PAGES(mb)       ((mb) >> (20 - PAGE_SHIFT))
+#define PAGES_TO_MiB(pages)    ((pages) >> (20 - PAGE_SHIFT))
+#define MiB_TO_PAGES(mb)       ((mb) << (20 - PAGE_SHIFT))
 #else                          /* PAGE_SHIFT > 20 */
-#define PAGES_TO_MiB( pages )  ( ( pages ) << ( PAGE_SHIFT - 20 ) )
+#define PAGES_TO_MiB(pages)    ((pages) << (PAGE_SHIFT - 20))
 #define MiB_TO_PAGES(mb)       ((mb) >> (PAGE_SHIFT - 20))
 #endif
 
index ba6586a..795ea69 100644 (file)
@@ -586,14 +586,16 @@ struct mem_ctl_info *edac_mc_del_mc(struct device *dev)
                return NULL;
        }
 
-       /* marking MCI offline */
-       mci->op_state = OP_OFFLINE;
-
        del_mc_from_global_list(mci);
        mutex_unlock(&mem_ctls_mutex);
 
-       /* flush workq processes and remove sysfs */
+       /* flush workq processes */
        edac_mc_workq_teardown(mci);
+
+       /* marking MCI offline */
+       mci->op_state = OP_OFFLINE;
+
+       /* remove from sysfs */
        edac_remove_sysfs_mci_device(mci);
 
        edac_printk(KERN_INFO, EDAC_MC,
index 8d0688f..39faded 100644 (file)
@@ -139,7 +139,7 @@ static int __init edac_init_mce_inject(void)
        return 0;
 
 err_sysfs_create:
-       while (i-- >= 0)
+       while (--i >= 0)
                sysfs_remove_file(mce_kobj, &sysfs_attrs[i]->attr);
 
        kobject_del(mce_kobj);
index 18fdd97..1a467a9 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <linux/bug.h>
+#include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/firewire.h>
 #include <linux/firewire-constants.h>
 #include <asm/unaligned.h>
 #include <net/arp.h>
 
-#define FWNET_MAX_FRAGMENTS    25      /* arbitrary limit */
-#define FWNET_ISO_PAGE_COUNT   (PAGE_SIZE < 16 * 1024 ? 4 : 2)
+/* rx limits */
+#define FWNET_MAX_FRAGMENTS            30 /* arbitrary, > TX queue depth */
+#define FWNET_ISO_PAGE_COUNT           (PAGE_SIZE < 16*1024 ? 4 : 2)
+
+/* tx limits */
+#define FWNET_MAX_QUEUED_DATAGRAMS     20 /* < 64 = number of tlabels */
+#define FWNET_MIN_QUEUED_DATAGRAMS     10 /* should keep AT DMA busy enough */
+#define FWNET_TX_QUEUE_LEN             FWNET_MAX_QUEUED_DATAGRAMS /* ? */
 
 #define IEEE1394_BROADCAST_CHANNEL     31
 #define IEEE1394_ALL_NODES             (0xffc0 | 0x003f)
@@ -169,15 +176,8 @@ struct fwnet_device {
        struct fw_address_handler handler;
        u64 local_fifo;
 
-       /* List of packets to be sent */
-       struct list_head packet_list;
-       /*
-        * List of packets that were broadcasted.  When we get an ISO interrupt
-        * one of them has been sent
-        */
-       struct list_head broadcasted_list;
-       /* List of packets that have been sent but not yet acked */
-       struct list_head sent_list;
+       /* Number of tx datagrams that have been queued but not yet acked */
+       int queued_datagrams;
 
        struct list_head peer_list;
        struct fw_card *card;
@@ -195,7 +195,7 @@ struct fwnet_peer {
        unsigned pdg_size;        /* pd_list size */
 
        u16 datagram_label;       /* outgoing datagram label */
-       unsigned max_payload;     /* includes RFC2374_FRAG_HDR_SIZE overhead */
+       u16 max_payload;          /* includes RFC2374_FRAG_HDR_SIZE overhead */
        int node_id;
        int generation;
        unsigned speed;
@@ -203,22 +203,18 @@ struct fwnet_peer {
 
 /* This is our task struct. It's used for the packet complete callback.  */
 struct fwnet_packet_task {
-       /*
-        * ptask can actually be on dev->packet_list, dev->broadcasted_list,
-        * or dev->sent_list depending on its current state.
-        */
-       struct list_head pt_link;
        struct fw_transaction transaction;
        struct rfc2734_header hdr;
        struct sk_buff *skb;
        struct fwnet_device *dev;
 
        int outstanding_pkts;
-       unsigned max_payload;
        u64 fifo_addr;
        u16 dest_node;
+       u16 max_payload;
        u8 generation;
        u8 speed;
+       u8 enqueued;
 };
 
 /*
@@ -650,8 +646,6 @@ static int fwnet_finish_incoming_packet(struct net_device *net,
                net->stats.rx_packets++;
                net->stats.rx_bytes += skb->len;
        }
-       if (netif_queue_stopped(net))
-               netif_wake_queue(net);
 
        return 0;
 
@@ -660,8 +654,6 @@ static int fwnet_finish_incoming_packet(struct net_device *net,
        net->stats.rx_dropped++;
 
        dev_kfree_skb_any(skb);
-       if (netif_queue_stopped(net))
-               netif_wake_queue(net);
 
        return -ENOENT;
 }
@@ -793,15 +785,10 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len,
         * Datagram is not complete, we're done for the
         * moment.
         */
-       spin_unlock_irqrestore(&dev->lock, flags);
-
-       return 0;
+       retval = 0;
  fail:
        spin_unlock_irqrestore(&dev->lock, flags);
 
-       if (netif_queue_stopped(net))
-               netif_wake_queue(net);
-
        return retval;
 }
 
@@ -901,11 +888,19 @@ static void fwnet_free_ptask(struct fwnet_packet_task *ptask)
        kmem_cache_free(fwnet_packet_task_cache, ptask);
 }
 
+/* Caller must hold dev->lock. */
+static void dec_queued_datagrams(struct fwnet_device *dev)
+{
+       if (--dev->queued_datagrams == FWNET_MIN_QUEUED_DATAGRAMS)
+               netif_wake_queue(dev->netdev);
+}
+
 static int fwnet_send_packet(struct fwnet_packet_task *ptask);
 
 static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask)
 {
        struct fwnet_device *dev = ptask->dev;
+       struct sk_buff *skb = ptask->skb;
        unsigned long flags;
        bool free;
 
@@ -914,10 +909,14 @@ static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask)
        ptask->outstanding_pkts--;
 
        /* Check whether we or the networking TX soft-IRQ is last user. */
-       free = (ptask->outstanding_pkts == 0 && !list_empty(&ptask->pt_link));
+       free = (ptask->outstanding_pkts == 0 && ptask->enqueued);
+       if (free)
+               dec_queued_datagrams(dev);
 
-       if (ptask->outstanding_pkts == 0)
-               list_del(&ptask->pt_link);
+       if (ptask->outstanding_pkts == 0) {
+               dev->netdev->stats.tx_packets++;
+               dev->netdev->stats.tx_bytes += skb->len;
+       }
 
        spin_unlock_irqrestore(&dev->lock, flags);
 
@@ -926,7 +925,6 @@ static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask)
                u16 fg_off;
                u16 datagram_label;
                u16 lf;
-               struct sk_buff *skb;
 
                /* Update the ptask to point to the next fragment and send it */
                lf = fwnet_get_hdr_lf(&ptask->hdr);
@@ -953,7 +951,7 @@ static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask)
                        datagram_label = fwnet_get_hdr_dgl(&ptask->hdr);
                        break;
                }
-               skb = ptask->skb;
+
                skb_pull(skb, ptask->max_payload);
                if (ptask->outstanding_pkts > 1) {
                        fwnet_make_sf_hdr(&ptask->hdr, RFC2374_HDR_INTFRAG,
@@ -970,6 +968,31 @@ static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask)
                fwnet_free_ptask(ptask);
 }
 
+static void fwnet_transmit_packet_failed(struct fwnet_packet_task *ptask)
+{
+       struct fwnet_device *dev = ptask->dev;
+       unsigned long flags;
+       bool free;
+
+       spin_lock_irqsave(&dev->lock, flags);
+
+       /* One fragment failed; don't try to send remaining fragments. */
+       ptask->outstanding_pkts = 0;
+
+       /* Check whether we or the networking TX soft-IRQ is last user. */
+       free = ptask->enqueued;
+       if (free)
+               dec_queued_datagrams(dev);
+
+       dev->netdev->stats.tx_dropped++;
+       dev->netdev->stats.tx_errors++;
+
+       spin_unlock_irqrestore(&dev->lock, flags);
+
+       if (free)
+               fwnet_free_ptask(ptask);
+}
+
 static void fwnet_write_complete(struct fw_card *card, int rcode,
                                 void *payload, size_t length, void *data)
 {
@@ -977,11 +1000,12 @@ static void fwnet_write_complete(struct fw_card *card, int rcode,
 
        ptask = data;
 
-       if (rcode == RCODE_COMPLETE)
+       if (rcode == RCODE_COMPLETE) {
                fwnet_transmit_packet_done(ptask);
-       else
+       } else {
                fw_error("fwnet_write_complete: failed: %x\n", rcode);
-               /* ??? error recovery */
+               fwnet_transmit_packet_failed(ptask);
+       }
 }
 
 static int fwnet_send_packet(struct fwnet_packet_task *ptask)
@@ -1039,9 +1063,11 @@ static int fwnet_send_packet(struct fwnet_packet_task *ptask)
                spin_lock_irqsave(&dev->lock, flags);
 
                /* If the AT tasklet already ran, we may be last user. */
-               free = (ptask->outstanding_pkts == 0 && list_empty(&ptask->pt_link));
+               free = (ptask->outstanding_pkts == 0 && !ptask->enqueued);
                if (!free)
-                       list_add_tail(&ptask->pt_link, &dev->broadcasted_list);
+                       ptask->enqueued = true;
+               else
+                       dec_queued_datagrams(dev);
 
                spin_unlock_irqrestore(&dev->lock, flags);
 
@@ -1056,9 +1082,11 @@ static int fwnet_send_packet(struct fwnet_packet_task *ptask)
        spin_lock_irqsave(&dev->lock, flags);
 
        /* If the AT tasklet already ran, we may be last user. */
-       free = (ptask->outstanding_pkts == 0 && list_empty(&ptask->pt_link));
+       free = (ptask->outstanding_pkts == 0 && !ptask->enqueued);
        if (!free)
-               list_add_tail(&ptask->pt_link, &dev->sent_list);
+               ptask->enqueued = true;
+       else
+               dec_queued_datagrams(dev);
 
        spin_unlock_irqrestore(&dev->lock, flags);
 
@@ -1224,6 +1252,15 @@ static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net)
        struct fwnet_peer *peer;
        unsigned long flags;
 
+       spin_lock_irqsave(&dev->lock, flags);
+
+       /* Can this happen? */
+       if (netif_queue_stopped(dev->netdev)) {
+               spin_unlock_irqrestore(&dev->lock, flags);
+
+               return NETDEV_TX_BUSY;
+       }
+
        ptask = kmem_cache_alloc(fwnet_packet_task_cache, GFP_ATOMIC);
        if (ptask == NULL)
                goto fail;
@@ -1242,9 +1279,6 @@ static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net)
        proto = hdr_buf.h_proto;
        dg_size = skb->len;
 
-       /* serialize access to peer, including peer->datagram_label */
-       spin_lock_irqsave(&dev->lock, flags);
-
        /*
         * Set the transmission type for the packet.  ARP packets and IP
         * broadcast packets are sent via GASP.
@@ -1266,7 +1300,7 @@ static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net)
 
                peer = fwnet_peer_find_by_guid(dev, be64_to_cpu(guid));
                if (!peer || peer->fifo == FWNET_NO_FIFO_ADDR)
-                       goto fail_unlock;
+                       goto fail;
 
                generation         = peer->generation;
                dest_node          = peer->node_id;
@@ -1320,18 +1354,21 @@ static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net)
                max_payload += RFC2374_FRAG_HDR_SIZE;
        }
 
+       if (++dev->queued_datagrams == FWNET_MAX_QUEUED_DATAGRAMS)
+               netif_stop_queue(dev->netdev);
+
        spin_unlock_irqrestore(&dev->lock, flags);
 
        ptask->max_payload = max_payload;
-       INIT_LIST_HEAD(&ptask->pt_link);
+       ptask->enqueued    = 0;
 
        fwnet_send_packet(ptask);
 
        return NETDEV_TX_OK;
 
- fail_unlock:
-       spin_unlock_irqrestore(&dev->lock, flags);
  fail:
+       spin_unlock_irqrestore(&dev->lock, flags);
+
        if (ptask)
                kmem_cache_free(fwnet_packet_task_cache, ptask);
 
@@ -1377,7 +1414,7 @@ static void fwnet_init_dev(struct net_device *net)
        net->addr_len           = FWNET_ALEN;
        net->hard_header_len    = FWNET_HLEN;
        net->type               = ARPHRD_IEEE1394;
-       net->tx_queue_len       = 10;
+       net->tx_queue_len       = FWNET_TX_QUEUE_LEN;
 }
 
 /* caller must hold fwnet_device_mutex */
@@ -1457,14 +1494,9 @@ static int fwnet_probe(struct device *_dev)
        dev->broadcast_rcv_context = NULL;
        dev->broadcast_xmt_max_payload = 0;
        dev->broadcast_xmt_datagramlabel = 0;
-
        dev->local_fifo = FWNET_NO_FIFO_ADDR;
-
-       INIT_LIST_HEAD(&dev->packet_list);
-       INIT_LIST_HEAD(&dev->broadcasted_list);
-       INIT_LIST_HEAD(&dev->sent_list);
+       dev->queued_datagrams = 0;
        INIT_LIST_HEAD(&dev->peer_list);
-
        dev->card = card;
        dev->netdev = net;
 
@@ -1522,7 +1554,7 @@ static int fwnet_remove(struct device *_dev)
        struct fwnet_peer *peer = dev_get_drvdata(_dev);
        struct fwnet_device *dev = peer->dev;
        struct net_device *net;
-       struct fwnet_packet_task *ptask, *pt_next;
+       int i;
 
        mutex_lock(&fwnet_device_mutex);
 
@@ -1540,21 +1572,9 @@ static int fwnet_remove(struct device *_dev)
                                              dev->card);
                        fw_iso_context_destroy(dev->broadcast_rcv_context);
                }
-               list_for_each_entry_safe(ptask, pt_next,
-                                        &dev->packet_list, pt_link) {
-                       dev_kfree_skb_any(ptask->skb);
-                       kmem_cache_free(fwnet_packet_task_cache, ptask);
-               }
-               list_for_each_entry_safe(ptask, pt_next,
-                                        &dev->broadcasted_list, pt_link) {
-                       dev_kfree_skb_any(ptask->skb);
-                       kmem_cache_free(fwnet_packet_task_cache, ptask);
-               }
-               list_for_each_entry_safe(ptask, pt_next,
-                                        &dev->sent_list, pt_link) {
-                       dev_kfree_skb_any(ptask->skb);
-                       kmem_cache_free(fwnet_packet_task_cache, ptask);
-               }
+               for (i = 0; dev->queued_datagrams && i < 5; i++)
+                       ssleep(1);
+               WARN_ON(dev->queued_datagrams);
                list_del(&dev->dev_link);
 
                free_netdev(net);
index 84eb607..e3c8b60 100644 (file)
@@ -242,6 +242,7 @@ static inline struct fw_ohci *fw_ohci(struct fw_card *card)
 
 static char ohci_driver_name[] = KBUILD_MODNAME;
 
+#define PCI_DEVICE_ID_AGERE_FW643      0x5901
 #define PCI_DEVICE_ID_JMICRON_JMB38X_FW        0x2380
 #define PCI_DEVICE_ID_TI_TSB12LV22     0x8009
 
@@ -253,18 +254,34 @@ static char ohci_driver_name[] = KBUILD_MODNAME;
 
 /* In case of multiple matches in ohci_quirks[], only the first one is used. */
 static const struct {
-       unsigned short vendor, device, flags;
+       unsigned short vendor, device, revision, flags;
 } ohci_quirks[] = {
-       {PCI_VENDOR_ID_TI,      PCI_DEVICE_ID_TI_TSB12LV22, QUIRK_CYCLE_TIMER |
-                                                           QUIRK_RESET_PACKET |
-                                                           QUIRK_NO_1394A},
-       {PCI_VENDOR_ID_TI,      PCI_ANY_ID,     QUIRK_RESET_PACKET},
-       {PCI_VENDOR_ID_AL,      PCI_ANY_ID,     QUIRK_CYCLE_TIMER},
-       {PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB38X_FW, QUIRK_NO_MSI},
-       {PCI_VENDOR_ID_NEC,     PCI_ANY_ID,     QUIRK_CYCLE_TIMER},
-       {PCI_VENDOR_ID_VIA,     PCI_ANY_ID,     QUIRK_CYCLE_TIMER},
-       {PCI_VENDOR_ID_RICOH,   PCI_ANY_ID,     QUIRK_CYCLE_TIMER},
-       {PCI_VENDOR_ID_APPLE,   PCI_DEVICE_ID_APPLE_UNI_N_FW, QUIRK_BE_HEADERS},
+       {PCI_VENDOR_ID_AL, PCI_ANY_ID, PCI_ANY_ID,
+               QUIRK_CYCLE_TIMER},
+
+       {PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_FW, PCI_ANY_ID,
+               QUIRK_BE_HEADERS},
+
+       {PCI_VENDOR_ID_ATT, PCI_DEVICE_ID_AGERE_FW643, 6,
+               QUIRK_NO_MSI},
+
+       {PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB38X_FW, PCI_ANY_ID,
+               QUIRK_NO_MSI},
+
+       {PCI_VENDOR_ID_NEC, PCI_ANY_ID, PCI_ANY_ID,
+               QUIRK_CYCLE_TIMER},
+
+       {PCI_VENDOR_ID_RICOH, PCI_ANY_ID, PCI_ANY_ID,
+               QUIRK_CYCLE_TIMER},
+
+       {PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_TSB12LV22, PCI_ANY_ID,
+               QUIRK_CYCLE_TIMER | QUIRK_RESET_PACKET | QUIRK_NO_1394A},
+
+       {PCI_VENDOR_ID_TI, PCI_ANY_ID, PCI_ANY_ID,
+               QUIRK_RESET_PACKET},
+
+       {PCI_VENDOR_ID_VIA, PCI_ANY_ID, PCI_ANY_ID,
+               QUIRK_CYCLE_TIMER | QUIRK_NO_MSI},
 };
 
 /* This overrides anything that was found in ohci_quirks[]. */
@@ -2927,9 +2944,11 @@ static int __devinit pci_probe(struct pci_dev *dev,
        }
 
        for (i = 0; i < ARRAY_SIZE(ohci_quirks); i++)
-               if (ohci_quirks[i].vendor == dev->vendor &&
-                   (ohci_quirks[i].device == dev->device ||
-                    ohci_quirks[i].device == (unsigned short)PCI_ANY_ID)) {
+               if ((ohci_quirks[i].vendor == dev->vendor) &&
+                   (ohci_quirks[i].device == (unsigned short)PCI_ANY_ID ||
+                    ohci_quirks[i].device == dev->device) &&
+                   (ohci_quirks[i].revision == (unsigned short)PCI_ANY_ID ||
+                    ohci_quirks[i].revision >= dev->revision)) {
                        ohci->quirks = ohci_quirks[i].flags;
                        break;
                }
index e23c068..599f6c9 100644 (file)
@@ -56,6 +56,18 @@ static struct cs5535_gpio_chip {
  * registers, see include/linux/cs5535.h.
  */
 
+static void errata_outl(u32 val, unsigned long addr)
+{
+       /*
+        * According to the CS5536 errata (#36), after suspend
+        * a write to the high bank GPIO register will clear all
+        * non-selected bits; the recommended workaround is a
+        * read-modify-write operation.
+        */
+       val |= inl(addr);
+       outl(val, addr);
+}
+
 static void __cs5535_gpio_set(struct cs5535_gpio_chip *chip, unsigned offset,
                unsigned int reg)
 {
@@ -64,7 +76,7 @@ static void __cs5535_gpio_set(struct cs5535_gpio_chip *chip, unsigned offset,
                outl(1 << offset, chip->base + reg);
        else
                /* high bank register */
-               outl(1 << (offset - 16), chip->base + 0x80 + reg);
+               errata_outl(1 << (offset - 16), chip->base + 0x80 + reg);
 }
 
 void cs5535_gpio_set(unsigned offset, unsigned int reg)
@@ -86,7 +98,7 @@ static void __cs5535_gpio_clear(struct cs5535_gpio_chip *chip, unsigned offset,
                outl(1 << (offset + 16), chip->base + reg);
        else
                /* high bank register */
-               outl(1 << offset, chip->base + 0x80 + reg);
+               errata_outl(1 << offset, chip->base + 0x80 + reg);
 }
 
 void cs5535_gpio_clear(unsigned offset, unsigned int reg)
index 6985cb1..2baa670 100644 (file)
@@ -156,12 +156,12 @@ static struct drm_conn_prop_enum_list drm_connector_enum_list[] =
        { DRM_MODE_CONNECTOR_SVIDEO, "SVIDEO", 0 },
        { DRM_MODE_CONNECTOR_LVDS, "LVDS", 0 },
        { DRM_MODE_CONNECTOR_Component, "Component", 0 },
-       { DRM_MODE_CONNECTOR_9PinDIN, "9-pin DIN", 0 },
-       { DRM_MODE_CONNECTOR_DisplayPort, "DisplayPort", 0 },
-       { DRM_MODE_CONNECTOR_HDMIA, "HDMI Type A", 0 },
-       { DRM_MODE_CONNECTOR_HDMIB, "HDMI Type B", 0 },
+       { DRM_MODE_CONNECTOR_9PinDIN, "DIN", 0 },
+       { DRM_MODE_CONNECTOR_DisplayPort, "DP", 0 },
+       { DRM_MODE_CONNECTOR_HDMIA, "HDMI-A", 0 },
+       { DRM_MODE_CONNECTOR_HDMIB, "HDMI-B", 0 },
        { DRM_MODE_CONNECTOR_TV, "TV", 0 },
-       { DRM_MODE_CONNECTOR_eDP, "Embedded DisplayPort", 0 },
+       { DRM_MODE_CONNECTOR_eDP, "eDP", 0 },
 };
 
 static struct drm_prop_enum_list drm_encoder_enum_list[] =
index f7af91c..bede10a 100644 (file)
@@ -241,7 +241,7 @@ void drm_helper_disable_unused_functions(struct drm_device *dev)
        }
 
        list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
-               if (!drm_helper_encoder_in_use(encoder)) {
+               if (encoder->crtc && !drm_helper_encoder_in_use(encoder)) {
                        drm_encoder_disable(encoder);
                        /* disconnector encoder from any connector */
                        encoder->crtc = NULL;
@@ -471,6 +471,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
        int count = 0, ro, fail = 0;
        struct drm_crtc_helper_funcs *crtc_funcs;
        int ret = 0;
+       int i;
 
        DRM_DEBUG_KMS("\n");
 
@@ -666,6 +667,12 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
                if (ret != 0)
                        goto fail;
        }
+       DRM_DEBUG_KMS("Setting connector DPMS state to on\n");
+       for (i = 0; i < set->num_connectors; i++) {
+               DRM_DEBUG_KMS("\t[CONNECTOR:%d:%s] set DPMS on\n", set->connectors[i]->base.id,
+                             drm_get_connector_name(set->connectors[i]));
+               set->connectors[i]->dpms = DRM_MODE_DPMS_ON;
+       }
 
        kfree(save_connectors);
        kfree(save_encoders);
@@ -841,7 +848,7 @@ static void output_poll_execute(struct work_struct *work)
        struct delayed_work *delayed_work = to_delayed_work(work);
        struct drm_device *dev = container_of(delayed_work, struct drm_device, mode_config.output_poll_work);
        struct drm_connector *connector;
-       enum drm_connector_status old_status, status;
+       enum drm_connector_status old_status;
        bool repoll = false, changed = false;
 
        if (!drm_kms_helper_poll)
@@ -866,8 +873,9 @@ static void output_poll_execute(struct work_struct *work)
                    !(connector->polled & DRM_CONNECTOR_POLL_HPD))
                        continue;
 
-               status = connector->funcs->detect(connector, false);
-               if (old_status != status)
+               connector->status = connector->funcs->detect(connector, false);
+               DRM_DEBUG_KMS("connector status updated to %d\n", connector->status);
+               if (old_status != connector->status)
                        changed = true;
        }
 
index 9d3a503..16d5155 100644 (file)
@@ -585,10 +585,13 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe,
        struct timeval now;
        unsigned long flags;
        unsigned int seq;
+       int ret;
 
        e = kzalloc(sizeof *e, GFP_KERNEL);
-       if (e == NULL)
-               return -ENOMEM;
+       if (e == NULL) {
+               ret = -ENOMEM;
+               goto err_put;
+       }
 
        e->pipe = pipe;
        e->base.pid = current->pid;
@@ -603,9 +606,8 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe,
        spin_lock_irqsave(&dev->event_lock, flags);
 
        if (file_priv->event_space < sizeof e->event) {
-               spin_unlock_irqrestore(&dev->event_lock, flags);
-               kfree(e);
-               return -ENOMEM;
+               ret = -EBUSY;
+               goto err_unlock;
        }
 
        file_priv->event_space -= sizeof e->event;
@@ -626,7 +628,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe,
        if ((seq - vblwait->request.sequence) <= (1 << 23)) {
                e->event.tv_sec = now.tv_sec;
                e->event.tv_usec = now.tv_usec;
-               drm_vblank_put(dev, e->pipe);
+               drm_vblank_put(dev, pipe);
                list_add_tail(&e->base.link, &e->base.file_priv->event_list);
                wake_up_interruptible(&e->base.file_priv->event_wait);
                trace_drm_vblank_event_delivered(current->pid, pipe,
@@ -638,6 +640,13 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe,
        spin_unlock_irqrestore(&dev->event_lock, flags);
 
        return 0;
+
+err_unlock:
+       spin_unlock_irqrestore(&dev->event_lock, flags);
+       kfree(e);
+err_put:
+       drm_vblank_put(dev, pipe);
+       return ret;
 }
 
 /**
index 7a26f4d..e680081 100644 (file)
@@ -767,6 +767,9 @@ static int i915_getparam(struct drm_device *dev, void *data,
        case I915_PARAM_HAS_BLT:
                value = HAS_BLT(dev);
                break;
+       case I915_PARAM_HAS_COHERENT_RINGS:
+               value = 1;
+               break;
        default:
                DRM_DEBUG_DRIVER("Unknown parameter %d\n",
                                 param->param);
index 17b1cba..275ec6e 100644 (file)
@@ -38,8 +38,7 @@
 
 static uint32_t i915_gem_get_gtt_alignment(struct drm_gem_object *obj);
 
-static int i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj,
-                                                 bool pipelined);
+static int i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj);
 static void i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj);
 static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj);
 static int i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj,
@@ -2594,7 +2593,7 @@ i915_gem_object_put_fence_reg(struct drm_gem_object *obj,
        if (reg->gpu) {
                int ret;
 
-               ret = i915_gem_object_flush_gpu_write_domain(obj, true);
+               ret = i915_gem_object_flush_gpu_write_domain(obj);
                if (ret)
                        return ret;
 
@@ -2742,8 +2741,7 @@ i915_gem_clflush_object(struct drm_gem_object *obj)
 
 /** Flushes any GPU write domain for the object if it's dirty. */
 static int
-i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj,
-                                      bool pipelined)
+i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
        uint32_t old_write_domain;
@@ -2762,10 +2760,7 @@ i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj,
                                            obj->read_domains,
                                            old_write_domain);
 
-       if (pipelined)
-               return 0;
-
-       return i915_gem_object_wait_rendering(obj, true);
+       return 0;
 }
 
 /** Flushes the GTT write domain for the object if it's dirty. */
@@ -2826,18 +2821,15 @@ i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write)
        if (obj_priv->gtt_space == NULL)
                return -EINVAL;
 
-       ret = i915_gem_object_flush_gpu_write_domain(obj, false);
+       ret = i915_gem_object_flush_gpu_write_domain(obj);
        if (ret != 0)
                return ret;
+       ret = i915_gem_object_wait_rendering(obj, true);
+       if (ret)
+               return ret;
 
        i915_gem_object_flush_cpu_write_domain(obj);
 
-       if (write) {
-               ret = i915_gem_object_wait_rendering(obj, true);
-               if (ret)
-                       return ret;
-       }
-
        old_write_domain = obj->write_domain;
        old_read_domains = obj->read_domains;
 
@@ -2875,7 +2867,7 @@ i915_gem_object_set_to_display_plane(struct drm_gem_object *obj,
        if (obj_priv->gtt_space == NULL)
                return -EINVAL;
 
-       ret = i915_gem_object_flush_gpu_write_domain(obj, true);
+       ret = i915_gem_object_flush_gpu_write_domain(obj);
        if (ret)
                return ret;
 
@@ -2924,9 +2916,12 @@ i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, int write)
        uint32_t old_write_domain, old_read_domains;
        int ret;
 
-       ret = i915_gem_object_flush_gpu_write_domain(obj, false);
+       ret = i915_gem_object_flush_gpu_write_domain(obj);
        if (ret != 0)
                return ret;
+       ret = i915_gem_object_wait_rendering(obj, true);
+       if (ret)
+               return ret;
 
        i915_gem_object_flush_gtt_write_domain(obj);
 
@@ -2935,12 +2930,6 @@ i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, int write)
         */
        i915_gem_object_set_to_full_cpu_read_domain(obj);
 
-       if (write) {
-               ret = i915_gem_object_wait_rendering(obj, true);
-               if (ret)
-                       return ret;
-       }
-
        old_write_domain = obj->write_domain;
        old_read_domains = obj->read_domains;
 
@@ -3205,9 +3194,13 @@ i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj,
        if (offset == 0 && size == obj->size)
                return i915_gem_object_set_to_cpu_domain(obj, 0);
 
-       ret = i915_gem_object_flush_gpu_write_domain(obj, false);
+       ret = i915_gem_object_flush_gpu_write_domain(obj);
        if (ret != 0)
                return ret;
+       ret = i915_gem_object_wait_rendering(obj, true);
+       if (ret)
+               return ret;
+
        i915_gem_object_flush_gtt_write_domain(obj);
 
        /* If we're already fully in the CPU read domain, we're done. */
@@ -3254,192 +3247,230 @@ i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj,
        return 0;
 }
 
-/**
- * Pin an object to the GTT and evaluate the relocations landing in it.
- */
 static int
-i915_gem_execbuffer_relocate(struct drm_i915_gem_object *obj,
-                            struct drm_file *file_priv,
-                            struct drm_i915_gem_exec_object2 *entry)
+i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj,
+                                  struct drm_file *file_priv,
+                                  struct drm_i915_gem_exec_object2 *entry,
+                                  struct drm_i915_gem_relocation_entry *reloc)
 {
        struct drm_device *dev = obj->base.dev;
-       drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_gem_relocation_entry __user *user_relocs;
-       struct drm_gem_object *target_obj = NULL;
-       uint32_t target_handle = 0;
-       int i, ret = 0;
+       struct drm_gem_object *target_obj;
+       uint32_t target_offset;
+       int ret = -EINVAL;
 
-       user_relocs = (void __user *)(uintptr_t)entry->relocs_ptr;
-       for (i = 0; i < entry->relocation_count; i++) {
-               struct drm_i915_gem_relocation_entry reloc;
-               uint32_t target_offset;
+       target_obj = drm_gem_object_lookup(dev, file_priv,
+                                          reloc->target_handle);
+       if (target_obj == NULL)
+               return -ENOENT;
 
-               if (__copy_from_user_inatomic(&reloc,
-                                             user_relocs+i,
-                                             sizeof(reloc))) {
-                       ret = -EFAULT;
-                       break;
-               }
+       target_offset = to_intel_bo(target_obj)->gtt_offset;
 
-               if (reloc.target_handle != target_handle) {
-                       drm_gem_object_unreference(target_obj);
+#if WATCH_RELOC
+       DRM_INFO("%s: obj %p offset %08x target %d "
+                "read %08x write %08x gtt %08x "
+                "presumed %08x delta %08x\n",
+                __func__,
+                obj,
+                (int) reloc->offset,
+                (int) reloc->target_handle,
+                (int) reloc->read_domains,
+                (int) reloc->write_domain,
+                (int) target_offset,
+                (int) reloc->presumed_offset,
+                reloc->delta);
+#endif
 
-                       target_obj = drm_gem_object_lookup(dev, file_priv,
-                                                          reloc.target_handle);
-                       if (target_obj == NULL) {
-                               ret = -ENOENT;
-                               break;
-                       }
+       /* The target buffer should have appeared before us in the
+        * exec_object list, so it should have a GTT space bound by now.
+        */
+       if (target_offset == 0) {
+               DRM_ERROR("No GTT space found for object %d\n",
+                         reloc->target_handle);
+               goto err;
+       }
 
-                       target_handle = reloc.target_handle;
-               }
-               target_offset = to_intel_bo(target_obj)->gtt_offset;
+       /* Validate that the target is in a valid r/w GPU domain */
+       if (reloc->write_domain & (reloc->write_domain - 1)) {
+               DRM_ERROR("reloc with multiple write domains: "
+                         "obj %p target %d offset %d "
+                         "read %08x write %08x",
+                         obj, reloc->target_handle,
+                         (int) reloc->offset,
+                         reloc->read_domains,
+                         reloc->write_domain);
+               goto err;
+       }
+       if (reloc->write_domain & I915_GEM_DOMAIN_CPU ||
+           reloc->read_domains & I915_GEM_DOMAIN_CPU) {
+               DRM_ERROR("reloc with read/write CPU domains: "
+                         "obj %p target %d offset %d "
+                         "read %08x write %08x",
+                         obj, reloc->target_handle,
+                         (int) reloc->offset,
+                         reloc->read_domains,
+                         reloc->write_domain);
+               goto err;
+       }
+       if (reloc->write_domain && target_obj->pending_write_domain &&
+           reloc->write_domain != target_obj->pending_write_domain) {
+               DRM_ERROR("Write domain conflict: "
+                         "obj %p target %d offset %d "
+                         "new %08x old %08x\n",
+                         obj, reloc->target_handle,
+                         (int) reloc->offset,
+                         reloc->write_domain,
+                         target_obj->pending_write_domain);
+               goto err;
+       }
 
-#if WATCH_RELOC
-               DRM_INFO("%s: obj %p offset %08x target %d "
-                        "read %08x write %08x gtt %08x "
-                        "presumed %08x delta %08x\n",
-                        __func__,
-                        obj,
-                        (int) reloc.offset,
-                        (int) reloc.target_handle,
-                        (int) reloc.read_domains,
-                        (int) reloc.write_domain,
-                        (int) target_offset,
-                        (int) reloc.presumed_offset,
-                        reloc.delta);
-#endif
+       target_obj->pending_read_domains |= reloc->read_domains;
+       target_obj->pending_write_domain |= reloc->write_domain;
 
-               /* The target buffer should have appeared before us in the
-                * exec_object list, so it should have a GTT space bound by now.
-                */
-               if (target_offset == 0) {
-                       DRM_ERROR("No GTT space found for object %d\n",
-                                 reloc.target_handle);
-                       ret = -EINVAL;
-                       break;
-               }
+       /* If the relocation already has the right value in it, no
+        * more work needs to be done.
+        */
+       if (target_offset == reloc->presumed_offset)
+               goto out;
 
-               /* Validate that the target is in a valid r/w GPU domain */
-               if (reloc.write_domain & (reloc.write_domain - 1)) {
-                       DRM_ERROR("reloc with multiple write domains: "
-                                 "obj %p target %d offset %d "
-                                 "read %08x write %08x",
-                                 obj, reloc.target_handle,
-                                 (int) reloc.offset,
-                                 reloc.read_domains,
-                                 reloc.write_domain);
-                       ret = -EINVAL;
-                       break;
-               }
-               if (reloc.write_domain & I915_GEM_DOMAIN_CPU ||
-                   reloc.read_domains & I915_GEM_DOMAIN_CPU) {
-                       DRM_ERROR("reloc with read/write CPU domains: "
-                                 "obj %p target %d offset %d "
-                                 "read %08x write %08x",
-                                 obj, reloc.target_handle,
-                                 (int) reloc.offset,
-                                 reloc.read_domains,
-                                 reloc.write_domain);
-                       ret = -EINVAL;
-                       break;
-               }
-               if (reloc.write_domain && target_obj->pending_write_domain &&
-                   reloc.write_domain != target_obj->pending_write_domain) {
-                       DRM_ERROR("Write domain conflict: "
-                                 "obj %p target %d offset %d "
-                                 "new %08x old %08x\n",
-                                 obj, reloc.target_handle,
-                                 (int) reloc.offset,
-                                 reloc.write_domain,
-                                 target_obj->pending_write_domain);
-                       ret = -EINVAL;
-                       break;
-               }
+       /* Check that the relocation address is valid... */
+       if (reloc->offset > obj->base.size - 4) {
+               DRM_ERROR("Relocation beyond object bounds: "
+                         "obj %p target %d offset %d size %d.\n",
+                         obj, reloc->target_handle,
+                         (int) reloc->offset,
+                         (int) obj->base.size);
+               goto err;
+       }
+       if (reloc->offset & 3) {
+               DRM_ERROR("Relocation not 4-byte aligned: "
+                         "obj %p target %d offset %d.\n",
+                         obj, reloc->target_handle,
+                         (int) reloc->offset);
+               goto err;
+       }
 
-               target_obj->pending_read_domains |= reloc.read_domains;
-               target_obj->pending_write_domain |= reloc.write_domain;
+       /* and points to somewhere within the target object. */
+       if (reloc->delta >= target_obj->size) {
+               DRM_ERROR("Relocation beyond target object bounds: "
+                         "obj %p target %d delta %d size %d.\n",
+                         obj, reloc->target_handle,
+                         (int) reloc->delta,
+                         (int) target_obj->size);
+               goto err;
+       }
 
-               /* If the relocation already has the right value in it, no
-                * more work needs to be done.
-                */
-               if (target_offset == reloc.presumed_offset)
-                       continue;
+       reloc->delta += target_offset;
+       if (obj->base.write_domain == I915_GEM_DOMAIN_CPU) {
+               uint32_t page_offset = reloc->offset & ~PAGE_MASK;
+               char *vaddr;
 
-               /* Check that the relocation address is valid... */
-               if (reloc.offset > obj->base.size - 4) {
-                       DRM_ERROR("Relocation beyond object bounds: "
-                                 "obj %p target %d offset %d size %d.\n",
-                                 obj, reloc.target_handle,
-                                 (int) reloc.offset, (int) obj->base.size);
-                       ret = -EINVAL;
-                       break;
-               }
-               if (reloc.offset & 3) {
-                       DRM_ERROR("Relocation not 4-byte aligned: "
-                                 "obj %p target %d offset %d.\n",
-                                 obj, reloc.target_handle,
-                                 (int) reloc.offset);
-                       ret = -EINVAL;
-                       break;
-               }
+               vaddr = kmap_atomic(obj->pages[reloc->offset >> PAGE_SHIFT]);
+               *(uint32_t *)(vaddr + page_offset) = reloc->delta;
+               kunmap_atomic(vaddr);
+       } else {
+               struct drm_i915_private *dev_priv = dev->dev_private;
+               uint32_t __iomem *reloc_entry;
+               void __iomem *reloc_page;
 
-               /* and points to somewhere within the target object. */
-               if (reloc.delta >= target_obj->size) {
-                       DRM_ERROR("Relocation beyond target object bounds: "
-                                 "obj %p target %d delta %d size %d.\n",
-                                 obj, reloc.target_handle,
-                                 (int) reloc.delta, (int) target_obj->size);
-                       ret = -EINVAL;
-                       break;
-               }
+               ret = i915_gem_object_set_to_gtt_domain(&obj->base, 1);
+               if (ret)
+                       goto err;
 
-               reloc.delta += target_offset;
-               if (obj->base.write_domain == I915_GEM_DOMAIN_CPU) {
-                       uint32_t page_offset = reloc.offset & ~PAGE_MASK;
-                       char *vaddr;
+               /* Map the page containing the relocation we're going to perform.  */
+               reloc->offset += obj->gtt_offset;
+               reloc_page = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping,
+                                                     reloc->offset & PAGE_MASK);
+               reloc_entry = (uint32_t __iomem *)
+                       (reloc_page + (reloc->offset & ~PAGE_MASK));
+               iowrite32(reloc->delta, reloc_entry);
+               io_mapping_unmap_atomic(reloc_page);
+       }
 
-                       vaddr = kmap_atomic(obj->pages[reloc.offset >> PAGE_SHIFT]);
-                       *(uint32_t *)(vaddr + page_offset) = reloc.delta;
-                       kunmap_atomic(vaddr);
-               } else {
-                       uint32_t __iomem *reloc_entry;
-                       void __iomem *reloc_page;
+       /* and update the user's relocation entry */
+       reloc->presumed_offset = target_offset;
 
-                       ret = i915_gem_object_set_to_gtt_domain(&obj->base, 1);
-                       if (ret)
-                               break;
+out:
+       ret = 0;
+err:
+       drm_gem_object_unreference(target_obj);
+       return ret;
+}
 
-                       /* Map the page containing the relocation we're going to perform.  */
-                       reloc.offset += obj->gtt_offset;
-                       reloc_page = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping,
-                                                             reloc.offset & PAGE_MASK);
-                       reloc_entry = (uint32_t __iomem *)
-                               (reloc_page + (reloc.offset & ~PAGE_MASK));
-                       iowrite32(reloc.delta, reloc_entry);
-                       io_mapping_unmap_atomic(reloc_page);
-               }
+static int
+i915_gem_execbuffer_relocate_object(struct drm_i915_gem_object *obj,
+                                   struct drm_file *file_priv,
+                                   struct drm_i915_gem_exec_object2 *entry)
+{
+       struct drm_i915_gem_relocation_entry __user *user_relocs;
+       int i, ret;
+
+       user_relocs = (void __user *)(uintptr_t)entry->relocs_ptr;
+       for (i = 0; i < entry->relocation_count; i++) {
+               struct drm_i915_gem_relocation_entry reloc;
+
+               if (__copy_from_user_inatomic(&reloc,
+                                             user_relocs+i,
+                                             sizeof(reloc)))
+                       return -EFAULT;
+
+               ret = i915_gem_execbuffer_relocate_entry(obj, file_priv, entry, &reloc);
+               if (ret)
+                       return ret;
 
-               /* and update the user's relocation entry */
-               reloc.presumed_offset = target_offset;
                if (__copy_to_user_inatomic(&user_relocs[i].presumed_offset,
-                                             &reloc.presumed_offset,
-                                             sizeof(reloc.presumed_offset))) {
-                   ret = -EFAULT;
-                   break;
-               }
+                                           &reloc.presumed_offset,
+                                           sizeof(reloc.presumed_offset)))
+                       return -EFAULT;
        }
 
-       drm_gem_object_unreference(target_obj);
-       return ret;
+       return 0;
+}
+
+static int
+i915_gem_execbuffer_relocate_object_slow(struct drm_i915_gem_object *obj,
+                                        struct drm_file *file_priv,
+                                        struct drm_i915_gem_exec_object2 *entry,
+                                        struct drm_i915_gem_relocation_entry *relocs)
+{
+       int i, ret;
+
+       for (i = 0; i < entry->relocation_count; i++) {
+               ret = i915_gem_execbuffer_relocate_entry(obj, file_priv, entry, &relocs[i]);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
 }
 
 static int
-i915_gem_execbuffer_pin(struct drm_device *dev,
-                       struct drm_file *file,
-                       struct drm_gem_object **object_list,
-                       struct drm_i915_gem_exec_object2 *exec_list,
-                       int count)
+i915_gem_execbuffer_relocate(struct drm_device *dev,
+                            struct drm_file *file,
+                            struct drm_gem_object **object_list,
+                            struct drm_i915_gem_exec_object2 *exec_list,
+                            int count)
+{
+       int i, ret;
+
+       for (i = 0; i < count; i++) {
+               struct drm_i915_gem_object *obj = to_intel_bo(object_list[i]);
+               obj->base.pending_read_domains = 0;
+               obj->base.pending_write_domain = 0;
+               ret = i915_gem_execbuffer_relocate_object(obj, file,
+                                                         &exec_list[i]);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
+
+static int
+i915_gem_execbuffer_reserve(struct drm_device *dev,
+                           struct drm_file *file,
+                           struct drm_gem_object **object_list,
+                           struct drm_i915_gem_exec_object2 *exec_list,
+                           int count)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        int ret, i, retry;
@@ -3501,6 +3532,87 @@ i915_gem_execbuffer_pin(struct drm_device *dev,
        return 0;
 }
 
+static int
+i915_gem_execbuffer_relocate_slow(struct drm_device *dev,
+                                 struct drm_file *file,
+                                 struct drm_gem_object **object_list,
+                                 struct drm_i915_gem_exec_object2 *exec_list,
+                                 int count)
+{
+       struct drm_i915_gem_relocation_entry *reloc;
+       int i, total, ret;
+
+       for (i = 0; i < count; i++) {
+               struct drm_i915_gem_object *obj = to_intel_bo(object_list[i]);
+               obj->in_execbuffer = false;
+       }
+
+       mutex_unlock(&dev->struct_mutex);
+
+       total = 0;
+       for (i = 0; i < count; i++)
+               total += exec_list[i].relocation_count;
+
+       reloc = drm_malloc_ab(total, sizeof(*reloc));
+       if (reloc == NULL) {
+               mutex_lock(&dev->struct_mutex);
+               return -ENOMEM;
+       }
+
+       total = 0;
+       for (i = 0; i < count; i++) {
+               struct drm_i915_gem_relocation_entry __user *user_relocs;
+
+               user_relocs = (void __user *)(uintptr_t)exec_list[i].relocs_ptr;
+
+               if (copy_from_user(reloc+total, user_relocs,
+                                  exec_list[i].relocation_count *
+                                  sizeof(*reloc))) {
+                       ret = -EFAULT;
+                       mutex_lock(&dev->struct_mutex);
+                       goto err;
+               }
+
+               total += exec_list[i].relocation_count;
+       }
+
+       ret = i915_mutex_lock_interruptible(dev);
+       if (ret) {
+               mutex_lock(&dev->struct_mutex);
+               goto err;
+       }
+
+       ret = i915_gem_execbuffer_reserve(dev, file,
+                                         object_list, exec_list,
+                                         count);
+       if (ret)
+               goto err;
+
+       total = 0;
+       for (i = 0; i < count; i++) {
+               struct drm_i915_gem_object *obj = to_intel_bo(object_list[i]);
+               obj->base.pending_read_domains = 0;
+               obj->base.pending_write_domain = 0;
+               ret = i915_gem_execbuffer_relocate_object_slow(obj, file,
+                                                              &exec_list[i],
+                                                              reloc + total);
+               if (ret)
+                       goto err;
+
+               total += exec_list[i].relocation_count;
+       }
+
+       /* Leave the user relocations as are, this is the painfully slow path,
+        * and we want to avoid the complication of dropping the lock whilst
+        * having buffers reserved in the aperture and so causing spurious
+        * ENOSPC for random operations.
+        */
+
+err:
+       drm_free_large(reloc);
+       return ret;
+}
+
 static int
 i915_gem_execbuffer_move_to_gpu(struct drm_device *dev,
                                struct drm_file *file,
@@ -3630,8 +3742,15 @@ validate_exec_list(struct drm_i915_gem_exec_object2 *exec,
 
        for (i = 0; i < count; i++) {
                char __user *ptr = (char __user *)(uintptr_t)exec[i].relocs_ptr;
-               size_t length = exec[i].relocation_count * sizeof(struct drm_i915_gem_relocation_entry);
+               int length; /* limited by fault_in_pages_readable() */
+
+               /* First check for malicious input causing overflow */
+               if (exec[i].relocation_count >
+                   INT_MAX / sizeof(struct drm_i915_gem_relocation_entry))
+                       return -EINVAL;
 
+               length = exec[i].relocation_count *
+                       sizeof(struct drm_i915_gem_relocation_entry);
                if (!access_ok(VERIFY_READ, ptr, length))
                        return -EFAULT;
 
@@ -3774,18 +3893,24 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
        }
 
        /* Move the objects en-masse into the GTT, evicting if necessary. */
-       ret = i915_gem_execbuffer_pin(dev, file,
-                                     object_list, exec_list,
-                                     args->buffer_count);
+       ret = i915_gem_execbuffer_reserve(dev, file,
+                                         object_list, exec_list,
+                                         args->buffer_count);
        if (ret)
                goto err;
 
        /* The objects are in their final locations, apply the relocations. */
-       for (i = 0; i < args->buffer_count; i++) {
-               struct drm_i915_gem_object *obj = to_intel_bo(object_list[i]);
-               obj->base.pending_read_domains = 0;
-               obj->base.pending_write_domain = 0;
-               ret = i915_gem_execbuffer_relocate(obj, file, &exec_list[i]);
+       ret = i915_gem_execbuffer_relocate(dev, file,
+                                          object_list, exec_list,
+                                          args->buffer_count);
+       if (ret) {
+               if (ret == -EFAULT) {
+                       ret = i915_gem_execbuffer_relocate_slow(dev, file,
+                                                               object_list,
+                                                               exec_list,
+                                                               args->buffer_count);
+                       BUG_ON(!mutex_is_locked(&dev->struct_mutex));
+               }
                if (ret)
                        goto err;
        }
@@ -4249,10 +4374,20 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data,
                 * use this buffer rather sooner than later, so issuing the required
                 * flush earlier is beneficial.
                 */
-               if (obj->write_domain & I915_GEM_GPU_DOMAINS)
+               if (obj->write_domain & I915_GEM_GPU_DOMAINS) {
                        i915_gem_flush_ring(dev, file_priv,
                                            obj_priv->ring,
                                            0, obj->write_domain);
+               } else if (obj_priv->ring->outstanding_lazy_request) {
+                       /* This ring is not being cleared by active usage,
+                        * so emit a request to do so.
+                        */
+                       u32 seqno = i915_add_request(dev,
+                                                    NULL, NULL,
+                                                    obj_priv->ring);
+                       if (seqno == 0)
+                               ret = -ENOMEM;
+               }
 
                /* Update the active list for the hardware's current position.
                 * Otherwise this only updates on a delayed timer or when irqs
index 25ed911..878fc76 100644 (file)
 #define  TRANS_DP_10BPC                (1<<9)
 #define  TRANS_DP_6BPC         (2<<9)
 #define  TRANS_DP_12BPC                (3<<9)
+#define  TRANS_DP_BPC_MASK     (3<<9)
 #define  TRANS_DP_VSYNC_ACTIVE_HIGH    (1<<4)
 #define  TRANS_DP_VSYNC_ACTIVE_LOW     0
 #define  TRANS_DP_HSYNC_ACTIVE_HIGH    (1<<3)
index 454c064..42729d2 100644 (file)
@@ -239,6 +239,16 @@ static void i915_save_modeset_reg(struct drm_device *dev)
        if (drm_core_check_feature(dev, DRIVER_MODESET))
                return;
 
+       /* Cursor state */
+       dev_priv->saveCURACNTR = I915_READ(CURACNTR);
+       dev_priv->saveCURAPOS = I915_READ(CURAPOS);
+       dev_priv->saveCURABASE = I915_READ(CURABASE);
+       dev_priv->saveCURBCNTR = I915_READ(CURBCNTR);
+       dev_priv->saveCURBPOS = I915_READ(CURBPOS);
+       dev_priv->saveCURBBASE = I915_READ(CURBBASE);
+       if (IS_GEN2(dev))
+               dev_priv->saveCURSIZE = I915_READ(CURSIZE);
+
        if (HAS_PCH_SPLIT(dev)) {
                dev_priv->savePCH_DREF_CONTROL = I915_READ(PCH_DREF_CONTROL);
                dev_priv->saveDISP_ARB_CTL = I915_READ(DISP_ARB_CTL);
@@ -529,6 +539,16 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
        I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR);
        I915_WRITE(DSPBADDR, I915_READ(DSPBADDR));
 
+       /* Cursor state */
+       I915_WRITE(CURAPOS, dev_priv->saveCURAPOS);
+       I915_WRITE(CURACNTR, dev_priv->saveCURACNTR);
+       I915_WRITE(CURABASE, dev_priv->saveCURABASE);
+       I915_WRITE(CURBPOS, dev_priv->saveCURBPOS);
+       I915_WRITE(CURBCNTR, dev_priv->saveCURBCNTR);
+       I915_WRITE(CURBBASE, dev_priv->saveCURBBASE);
+       if (IS_GEN2(dev))
+               I915_WRITE(CURSIZE, dev_priv->saveCURSIZE);
+
        return;
 }
 
@@ -543,16 +563,6 @@ void i915_save_display(struct drm_device *dev)
        /* Don't save them in KMS mode */
        i915_save_modeset_reg(dev);
 
-       /* Cursor state */
-       dev_priv->saveCURACNTR = I915_READ(CURACNTR);
-       dev_priv->saveCURAPOS = I915_READ(CURAPOS);
-       dev_priv->saveCURABASE = I915_READ(CURABASE);
-       dev_priv->saveCURBCNTR = I915_READ(CURBCNTR);
-       dev_priv->saveCURBPOS = I915_READ(CURBPOS);
-       dev_priv->saveCURBBASE = I915_READ(CURBBASE);
-       if (IS_GEN2(dev))
-               dev_priv->saveCURSIZE = I915_READ(CURSIZE);
-
        /* CRT state */
        if (HAS_PCH_SPLIT(dev)) {
                dev_priv->saveADPA = I915_READ(PCH_ADPA);
@@ -657,16 +667,6 @@ void i915_restore_display(struct drm_device *dev)
        /* Don't restore them in KMS mode */
        i915_restore_modeset_reg(dev);
 
-       /* Cursor state */
-       I915_WRITE(CURAPOS, dev_priv->saveCURAPOS);
-       I915_WRITE(CURACNTR, dev_priv->saveCURACNTR);
-       I915_WRITE(CURABASE, dev_priv->saveCURABASE);
-       I915_WRITE(CURBPOS, dev_priv->saveCURBPOS);
-       I915_WRITE(CURBCNTR, dev_priv->saveCURBCNTR);
-       I915_WRITE(CURBBASE, dev_priv->saveCURBBASE);
-       if (IS_GEN2(dev))
-               I915_WRITE(CURSIZE, dev_priv->saveCURSIZE);
-
        /* CRT state */
        if (HAS_PCH_SPLIT(dev))
                I915_WRITE(PCH_ADPA, dev_priv->saveADPA);
index 65c88f9..2cb8e0b 100644 (file)
@@ -190,37 +190,6 @@ out:
        kfree(output.pointer);
 }
 
-static int intel_dsm_switchto(enum vga_switcheroo_client_id id)
-{
-       return 0;
-}
-
-static int intel_dsm_power_state(enum vga_switcheroo_client_id id,
-                                enum vga_switcheroo_state state)
-{
-       return 0;
-}
-
-static int intel_dsm_init(void)
-{
-       return 0;
-}
-
-static int intel_dsm_get_client_id(struct pci_dev *pdev)
-{
-       if (intel_dsm_priv.dhandle == DEVICE_ACPI_HANDLE(&pdev->dev))
-               return VGA_SWITCHEROO_IGD;
-       else
-               return VGA_SWITCHEROO_DIS;
-}
-
-static struct vga_switcheroo_handler intel_dsm_handler = {
-       .switchto = intel_dsm_switchto,
-       .power_state = intel_dsm_power_state,
-       .init = intel_dsm_init,
-       .get_client_id = intel_dsm_get_client_id,
-};
-
 static bool intel_dsm_pci_probe(struct pci_dev *pdev)
 {
        acpi_handle dhandle, intel_handle;
@@ -276,11 +245,8 @@ void intel_register_dsm_handler(void)
 {
        if (!intel_dsm_detect())
                return;
-
-       vga_switcheroo_register_handler(&intel_dsm_handler);
 }
 
 void intel_unregister_dsm_handler(void)
 {
-       vga_switcheroo_unregister_handler();
 }
index bee24b1..d9b7092 100644 (file)
@@ -2120,9 +2120,11 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
                reg = TRANS_DP_CTL(pipe);
                temp = I915_READ(reg);
                temp &= ~(TRANS_DP_PORT_SEL_MASK |
-                         TRANS_DP_SYNC_MASK);
+                         TRANS_DP_SYNC_MASK |
+                         TRANS_DP_BPC_MASK);
                temp |= (TRANS_DP_OUTPUT_ENABLE |
                         TRANS_DP_ENH_FRAMING);
+               temp |= TRANS_DP_8BPC;
 
                if (crtc->mode.flags & DRM_MODE_FLAG_PHSYNC)
                        temp |= TRANS_DP_HSYNC_ACTIVE_HIGH;
@@ -2712,27 +2714,19 @@ fdi_reduce_ratio(u32 *num, u32 *den)
        }
 }
 
-#define DATA_N 0x800000
-#define LINK_N 0x80000
-
 static void
 ironlake_compute_m_n(int bits_per_pixel, int nlanes, int pixel_clock,
                     int link_clock, struct fdi_m_n *m_n)
 {
-       u64 temp;
-
        m_n->tu = 64; /* default size */
 
-       temp = (u64) DATA_N * pixel_clock;
-       temp = div_u64(temp, link_clock);
-       m_n->gmch_m = div_u64(temp * bits_per_pixel, nlanes);
-       m_n->gmch_m >>= 3; /* convert to bytes_per_pixel */
-       m_n->gmch_n = DATA_N;
+       /* BUG_ON(pixel_clock > INT_MAX / 36); */
+       m_n->gmch_m = bits_per_pixel * pixel_clock;
+       m_n->gmch_n = link_clock * nlanes * 8;
        fdi_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n);
 
-       temp = (u64) LINK_N * pixel_clock;
-       m_n->link_m = div_u64(temp, link_clock);
-       m_n->link_n = LINK_N;
+       m_n->link_m = pixel_clock;
+       m_n->link_n = link_clock;
        fdi_reduce_ratio(&m_n->link_m, &m_n->link_n);
 }
 
@@ -3716,6 +3710,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
 
        /* FDI link */
        if (HAS_PCH_SPLIT(dev)) {
+               int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode);
                int lane = 0, link_bw, bpp;
                /* CPU eDP doesn't require FDI link, so just set DP M/N
                   according to current link config */
@@ -3799,6 +3794,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
 
                intel_crtc->fdi_lanes = lane;
 
+               if (pixel_multiplier > 1)
+                       link_bw *= pixel_multiplier;
                ironlake_compute_m_n(bpp, lane, target_clock, link_bw, &m_n);
        }
 
@@ -5236,6 +5233,55 @@ static const struct drm_crtc_funcs intel_crtc_funcs = {
        .page_flip = intel_crtc_page_flip,
 };
 
+static void intel_sanitize_modesetting(struct drm_device *dev,
+                                      int pipe, int plane)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       u32 reg, val;
+
+       if (HAS_PCH_SPLIT(dev))
+               return;
+
+       /* Who knows what state these registers were left in by the BIOS or
+        * grub?
+        *
+        * If we leave the registers in a conflicting state (e.g. with the
+        * display plane reading from the other pipe than the one we intend
+        * to use) then when we attempt to teardown the active mode, we will
+        * not disable the pipes and planes in the correct order -- leaving
+        * a plane reading from a disabled pipe and possibly leading to
+        * undefined behaviour.
+        */
+
+       reg = DSPCNTR(plane);
+       val = I915_READ(reg);
+
+       if ((val & DISPLAY_PLANE_ENABLE) == 0)
+               return;
+       if (!!(val & DISPPLANE_SEL_PIPE_MASK) == pipe)
+               return;
+
+       /* This display plane is active and attached to the other CPU pipe. */
+       pipe = !pipe;
+
+       /* Disable the plane and wait for it to stop reading from the pipe. */
+       I915_WRITE(reg, val & ~DISPLAY_PLANE_ENABLE);
+       intel_flush_display_plane(dev, plane);
+
+       if (IS_GEN2(dev))
+               intel_wait_for_vblank(dev, pipe);
+
+       if (pipe == 0 && (dev_priv->quirks & QUIRK_PIPEA_FORCE))
+               return;
+
+       /* Switch off the pipe. */
+       reg = PIPECONF(pipe);
+       val = I915_READ(reg);
+       if (val & PIPECONF_ENABLE) {
+               I915_WRITE(reg, val & ~PIPECONF_ENABLE);
+               intel_wait_for_pipe_off(dev, pipe);
+       }
+}
 
 static void intel_crtc_init(struct drm_device *dev, int pipe)
 {
@@ -5287,6 +5333,8 @@ static void intel_crtc_init(struct drm_device *dev, int pipe)
 
        setup_timer(&intel_crtc->idle_timer, intel_crtc_idle_timer,
                    (unsigned long)intel_crtc);
+
+       intel_sanitize_modesetting(dev, intel_crtc->pipe, intel_crtc->plane);
 }
 
 int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
@@ -5336,9 +5384,14 @@ static void intel_setup_outputs(struct drm_device *dev)
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_encoder *encoder;
        bool dpd_is_edp = false;
+       bool has_lvds = false;
 
        if (IS_MOBILE(dev) && !IS_I830(dev))
-               intel_lvds_init(dev);
+               has_lvds = intel_lvds_init(dev);
+       if (!has_lvds && !HAS_PCH_SPLIT(dev)) {
+               /* disable the panel fitter on everything but LVDS */
+               I915_WRITE(PFIT_CONTROL, 0);
+       }
 
        if (HAS_PCH_SPLIT(dev)) {
                dpd_is_edp = intel_dpd_is_edp(dev);
index c8e0055..df648cb 100644 (file)
@@ -584,17 +584,6 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
                mode->clock = dev_priv->panel_fixed_mode->clock;
        }
 
-       /* Just use VBT values for eDP */
-       if (is_edp(intel_dp)) {
-               intel_dp->lane_count = dev_priv->edp.lanes;
-               intel_dp->link_bw = dev_priv->edp.rate;
-               adjusted_mode->clock = intel_dp_link_clock(intel_dp->link_bw);
-               DRM_DEBUG_KMS("eDP link bw %02x lane count %d clock %d\n",
-                             intel_dp->link_bw, intel_dp->lane_count,
-                             adjusted_mode->clock);
-               return true;
-       }
-
        for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) {
                for (clock = 0; clock <= max_clock; clock++) {
                        int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count);
@@ -613,6 +602,19 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
                }
        }
 
+       if (is_edp(intel_dp)) {
+               /* okay we failed just pick the highest */
+               intel_dp->lane_count = max_lane_count;
+               intel_dp->link_bw = bws[max_clock];
+               adjusted_mode->clock = intel_dp_link_clock(intel_dp->link_bw);
+               DRM_DEBUG_KMS("Force picking display port link bw %02x lane "
+                             "count %d clock %d\n",
+                             intel_dp->link_bw, intel_dp->lane_count,
+                             adjusted_mode->clock);
+
+               return true;
+       }
+
        return false;
 }
 
@@ -1087,21 +1089,11 @@ intel_get_adjust_train(struct intel_dp *intel_dp)
 }
 
 static uint32_t
-intel_dp_signal_levels(struct intel_dp *intel_dp)
+intel_dp_signal_levels(uint8_t train_set, int lane_count)
 {
-       struct drm_device *dev = intel_dp->base.base.dev;
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       uint32_t signal_levels = 0;
-       u8 train_set = intel_dp->train_set[0];
-       u32 vswing = train_set & DP_TRAIN_VOLTAGE_SWING_MASK;
-       u32 preemphasis = train_set & DP_TRAIN_PRE_EMPHASIS_MASK;
+       uint32_t        signal_levels = 0;
 
-       if (is_edp(intel_dp)) {
-               vswing = dev_priv->edp.vswing;
-               preemphasis = dev_priv->edp.preemphasis;
-       }
-
-       switch (vswing) {
+       switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
        case DP_TRAIN_VOLTAGE_SWING_400:
        default:
                signal_levels |= DP_VOLTAGE_0_4;
@@ -1116,7 +1108,7 @@ intel_dp_signal_levels(struct intel_dp *intel_dp)
                signal_levels |= DP_VOLTAGE_1_2;
                break;
        }
-       switch (preemphasis) {
+       switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) {
        case DP_TRAIN_PRE_EMPHASIS_0:
        default:
                signal_levels |= DP_PRE_EMPHASIS_0;
@@ -1202,18 +1194,6 @@ intel_channel_eq_ok(struct intel_dp *intel_dp)
        return true;
 }
 
-static bool
-intel_dp_aux_handshake_required(struct intel_dp *intel_dp)
-{
-       struct drm_device *dev = intel_dp->base.base.dev;
-       struct drm_i915_private *dev_priv = dev->dev_private;
-
-       if (is_edp(intel_dp) && dev_priv->no_aux_handshake)
-               return false;
-
-       return true;
-}
-
 static bool
 intel_dp_set_link_train(struct intel_dp *intel_dp,
                        uint32_t dp_reg_value,
@@ -1226,9 +1206,6 @@ intel_dp_set_link_train(struct intel_dp *intel_dp,
        I915_WRITE(intel_dp->output_reg, dp_reg_value);
        POSTING_READ(intel_dp->output_reg);
 
-       if (!intel_dp_aux_handshake_required(intel_dp))
-               return true;
-
        intel_dp_aux_native_write_1(intel_dp,
                                    DP_TRAINING_PATTERN_SET,
                                    dp_train_pat);
@@ -1261,11 +1238,10 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
        POSTING_READ(intel_dp->output_reg);
        intel_wait_for_vblank(dev, intel_crtc->pipe);
 
-       if (intel_dp_aux_handshake_required(intel_dp))
-               /* Write the link configuration data */
-               intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET,
-                                         intel_dp->link_configuration,
-                                         DP_LINK_CONFIGURATION_SIZE);
+       /* Write the link configuration data */
+       intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET,
+                                 intel_dp->link_configuration,
+                                 DP_LINK_CONFIGURATION_SIZE);
 
        DP |= DP_PORT_EN;
        if (HAS_PCH_CPT(dev) && !is_edp(intel_dp))
@@ -1283,7 +1259,7 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
                        signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]);
                        DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels;
                } else {
-                       signal_levels = intel_dp_signal_levels(intel_dp);
+                       signal_levels = intel_dp_signal_levels(intel_dp->train_set[0], intel_dp->lane_count);
                        DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;
                }
 
@@ -1297,37 +1273,33 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
                        break;
                /* Set training pattern 1 */
 
-               udelay(500);
-               if (intel_dp_aux_handshake_required(intel_dp)) {
+               udelay(100);
+               if (!intel_dp_get_link_status(intel_dp))
+                       break;
+
+               if (intel_clock_recovery_ok(intel_dp->link_status, intel_dp->lane_count)) {
+                       clock_recovery = true;
                        break;
-               } else {
-                       if (!intel_dp_get_link_status(intel_dp))
-                               break;
+               }
 
-                       if (intel_clock_recovery_ok(intel_dp->link_status, intel_dp->lane_count)) {
-                               clock_recovery = true;
+               /* Check to see if we've tried the max voltage */
+               for (i = 0; i < intel_dp->lane_count; i++)
+                       if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
                                break;
-                       }
+               if (i == intel_dp->lane_count)
+                       break;
 
-                       /* Check to see if we've tried the max voltage */
-                       for (i = 0; i < intel_dp->lane_count; i++)
-                               if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
-                                       break;
-                       if (i == intel_dp->lane_count)
+               /* Check to see if we've tried the same voltage 5 times */
+               if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) {
+                       ++tries;
+                       if (tries == 5)
                                break;
+               } else
+                       tries = 0;
+               voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
 
-                       /* Check to see if we've tried the same voltage 5 times */
-                       if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) {
-                               ++tries;
-                               if (tries == 5)
-                                       break;
-                       } else
-                               tries = 0;
-                       voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
-
-                       /* Compute new intel_dp->train_set as requested by target */
-                       intel_get_adjust_train(intel_dp);
-               }
+               /* Compute new intel_dp->train_set as requested by target */
+               intel_get_adjust_train(intel_dp);
        }
 
        intel_dp->DP = DP;
@@ -1354,7 +1326,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
                        signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]);
                        DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels;
                } else {
-                       signal_levels = intel_dp_signal_levels(intel_dp);
+                       signal_levels = intel_dp_signal_levels(intel_dp->train_set[0], intel_dp->lane_count);
                        DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;
                }
 
@@ -1368,28 +1340,24 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
                                             DP_TRAINING_PATTERN_2))
                        break;
 
-               udelay(500);
-
-               if (!intel_dp_aux_handshake_required(intel_dp)) {
+               udelay(400);
+               if (!intel_dp_get_link_status(intel_dp))
                        break;
-               } else {
-                       if (!intel_dp_get_link_status(intel_dp))
-                               break;
 
-                       if (intel_channel_eq_ok(intel_dp)) {
-                               channel_eq = true;
-                               break;
-                       }
+               if (intel_channel_eq_ok(intel_dp)) {
+                       channel_eq = true;
+                       break;
+               }
 
-                       /* Try 5 times */
-                       if (tries > 5)
-                               break;
+               /* Try 5 times */
+               if (tries > 5)
+                       break;
 
-                       /* Compute new intel_dp->train_set as requested by target */
-                       intel_get_adjust_train(intel_dp);
-                       ++tries;
-               }
+               /* Compute new intel_dp->train_set as requested by target */
+               intel_get_adjust_train(intel_dp);
+               ++tries;
        }
+
        if (HAS_PCH_CPT(dev) && !is_edp(intel_dp))
                reg = DP | DP_LINK_TRAIN_OFF_CPT;
        else
@@ -1408,6 +1376,9 @@ intel_dp_link_down(struct intel_dp *intel_dp)
        struct drm_i915_private *dev_priv = dev->dev_private;
        uint32_t DP = intel_dp->DP;
 
+       if ((I915_READ(intel_dp->output_reg) & DP_PORT_EN) == 0)
+               return;
+
        DRM_DEBUG_KMS("\n");
 
        if (is_edp(intel_dp)) {
@@ -1430,6 +1401,28 @@ intel_dp_link_down(struct intel_dp *intel_dp)
 
        if (is_edp(intel_dp))
                DP |= DP_LINK_TRAIN_OFF;
+
+       if (!HAS_PCH_CPT(dev) &&
+           I915_READ(intel_dp->output_reg) & DP_PIPEB_SELECT) {
+               struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.base.crtc);
+               /* Hardware workaround: leaving our transcoder select
+                * set to transcoder B while it's off will prevent the
+                * corresponding HDMI output on transcoder A.
+                *
+                * Combine this with another hardware workaround:
+                * transcoder select bit can only be cleared while the
+                * port is enabled.
+                */
+               DP &= ~DP_PIPEB_SELECT;
+               I915_WRITE(intel_dp->output_reg, DP);
+
+               /* Changes to enable or select take place the vblank
+                * after being written.
+                */
+               intel_wait_for_vblank(intel_dp->base.base.dev,
+                                     intel_crtc->pipe);
+       }
+
        I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN);
        POSTING_READ(intel_dp->output_reg);
 }
index 21551fe..e52c612 100644 (file)
@@ -237,7 +237,7 @@ extern bool intel_sdvo_init(struct drm_device *dev, int output_device);
 extern void intel_dvo_init(struct drm_device *dev);
 extern void intel_tv_init(struct drm_device *dev);
 extern void intel_mark_busy(struct drm_device *dev, struct drm_gem_object *obj);
-extern void intel_lvds_init(struct drm_device *dev);
+extern bool intel_lvds_init(struct drm_device *dev);
 extern void intel_dp_init(struct drm_device *dev, int dp_reg);
 void
 intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
index 4324a32..25bcedf 100644 (file)
@@ -68,7 +68,7 @@ static struct intel_lvds *intel_attached_lvds(struct drm_connector *connector)
 /**
  * Sets the power state for the panel.
  */
-static void intel_lvds_set_power(struct intel_lvds *intel_lvds, bool on)
+static void intel_lvds_enable(struct intel_lvds *intel_lvds)
 {
        struct drm_device *dev = intel_lvds->base.base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
@@ -82,26 +82,61 @@ static void intel_lvds_set_power(struct intel_lvds *intel_lvds, bool on)
                lvds_reg = LVDS;
        }
 
-       if (on) {
-               I915_WRITE(lvds_reg, I915_READ(lvds_reg) | LVDS_PORT_EN);
-               I915_WRITE(ctl_reg, I915_READ(ctl_reg) | POWER_TARGET_ON);
-               intel_panel_set_backlight(dev, dev_priv->backlight_level);
-       } else {
-               dev_priv->backlight_level = intel_panel_get_backlight(dev);
-
-               intel_panel_set_backlight(dev, 0);
-               I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON);
+       I915_WRITE(lvds_reg, I915_READ(lvds_reg) | LVDS_PORT_EN);
 
-               if (intel_lvds->pfit_control) {
-                       if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000))
-                               DRM_ERROR("timed out waiting for panel to power off\n");
-                       I915_WRITE(PFIT_CONTROL, 0);
-                       intel_lvds->pfit_control = 0;
+       if (intel_lvds->pfit_dirty) {
+               /*
+                * Enable automatic panel scaling so that non-native modes
+                * fill the screen.  The panel fitter should only be
+                * adjusted whilst the pipe is disabled, according to
+                * register description and PRM.
+                */
+               DRM_DEBUG_KMS("applying panel-fitter: %x, %x\n",
+                             intel_lvds->pfit_control,
+                             intel_lvds->pfit_pgm_ratios);
+               if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000)) {
+                       DRM_ERROR("timed out waiting for panel to power off\n");
+               } else {
+                       I915_WRITE(PFIT_PGM_RATIOS, intel_lvds->pfit_pgm_ratios);
+                       I915_WRITE(PFIT_CONTROL, intel_lvds->pfit_control);
                        intel_lvds->pfit_dirty = false;
                }
+       }
+
+       I915_WRITE(ctl_reg, I915_READ(ctl_reg) | POWER_TARGET_ON);
+       POSTING_READ(lvds_reg);
+
+       intel_panel_set_backlight(dev, dev_priv->backlight_level);
+}
+
+static void intel_lvds_disable(struct intel_lvds *intel_lvds)
+{
+       struct drm_device *dev = intel_lvds->base.base.dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       u32 ctl_reg, lvds_reg;
+
+       if (HAS_PCH_SPLIT(dev)) {
+               ctl_reg = PCH_PP_CONTROL;
+               lvds_reg = PCH_LVDS;
+       } else {
+               ctl_reg = PP_CONTROL;
+               lvds_reg = LVDS;
+       }
+
+       dev_priv->backlight_level = intel_panel_get_backlight(dev);
+       intel_panel_set_backlight(dev, 0);
+
+       I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON);
+
+       if (intel_lvds->pfit_control) {
+               if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000))
+                       DRM_ERROR("timed out waiting for panel to power off\n");
 
-               I915_WRITE(lvds_reg, I915_READ(lvds_reg) & ~LVDS_PORT_EN);
+               I915_WRITE(PFIT_CONTROL, 0);
+               intel_lvds->pfit_dirty = true;
        }
+
+       I915_WRITE(lvds_reg, I915_READ(lvds_reg) & ~LVDS_PORT_EN);
        POSTING_READ(lvds_reg);
 }
 
@@ -110,9 +145,9 @@ static void intel_lvds_dpms(struct drm_encoder *encoder, int mode)
        struct intel_lvds *intel_lvds = to_intel_lvds(encoder);
 
        if (mode == DRM_MODE_DPMS_ON)
-               intel_lvds_set_power(intel_lvds, true);
+               intel_lvds_enable(intel_lvds);
        else
-               intel_lvds_set_power(intel_lvds, false);
+               intel_lvds_disable(intel_lvds);
 
        /* XXX: We never power down the LVDS pairs. */
 }
@@ -411,43 +446,18 @@ static void intel_lvds_commit(struct drm_encoder *encoder)
        /* Always do a full power on as we do not know what state
         * we were left in.
         */
-       intel_lvds_set_power(intel_lvds, true);
+       intel_lvds_enable(intel_lvds);
 }
 
 static void intel_lvds_mode_set(struct drm_encoder *encoder,
                                struct drm_display_mode *mode,
                                struct drm_display_mode *adjusted_mode)
 {
-       struct drm_device *dev = encoder->dev;
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_lvds *intel_lvds = to_intel_lvds(encoder);
-
        /*
         * The LVDS pin pair will already have been turned on in the
         * intel_crtc_mode_set since it has a large impact on the DPLL
         * settings.
         */
-
-       if (HAS_PCH_SPLIT(dev))
-               return;
-
-       if (!intel_lvds->pfit_dirty)
-               return;
-
-       /*
-        * Enable automatic panel scaling so that non-native modes fill the
-        * screen.  Should be enabled before the pipe is enabled, according to
-        * register description and PRM.
-        */
-       DRM_DEBUG_KMS("applying panel-fitter: %x, %x\n",
-                     intel_lvds->pfit_control,
-                     intel_lvds->pfit_pgm_ratios);
-       if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000))
-               DRM_ERROR("timed out waiting for panel to power off\n");
-
-       I915_WRITE(PFIT_PGM_RATIOS, intel_lvds->pfit_pgm_ratios);
-       I915_WRITE(PFIT_CONTROL, intel_lvds->pfit_control);
-       intel_lvds->pfit_dirty = false;
 }
 
 /**
@@ -837,7 +847,7 @@ static bool intel_lvds_ddc_probe(struct drm_device *dev, u8 pin)
  * Create the connector, register the LVDS DDC bus, and try to figure out what
  * modes we can display on the LVDS panel (if present).
  */
-void intel_lvds_init(struct drm_device *dev)
+bool intel_lvds_init(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_lvds *intel_lvds;
@@ -853,37 +863,37 @@ void intel_lvds_init(struct drm_device *dev)
 
        /* Skip init on machines we know falsely report LVDS */
        if (dmi_check_system(intel_no_lvds))
-               return;
+               return false;
 
        pin = GMBUS_PORT_PANEL;
        if (!lvds_is_present_in_vbt(dev, &pin)) {
                DRM_DEBUG_KMS("LVDS is not present in VBT\n");
-               return;
+               return false;
        }
 
        if (HAS_PCH_SPLIT(dev)) {
                if ((I915_READ(PCH_LVDS) & LVDS_DETECTED) == 0)
-                       return;
+                       return false;
                if (dev_priv->edp.support) {
                        DRM_DEBUG_KMS("disable LVDS for eDP support\n");
-                       return;
+                       return false;
                }
        }
 
        if (!intel_lvds_ddc_probe(dev, pin)) {
                DRM_DEBUG_KMS("LVDS did not respond to DDC probe\n");
-               return;
+               return false;
        }
 
        intel_lvds = kzalloc(sizeof(struct intel_lvds), GFP_KERNEL);
        if (!intel_lvds) {
-               return;
+               return false;
        }
 
        intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
        if (!intel_connector) {
                kfree(intel_lvds);
-               return;
+               return false;
        }
 
        if (!HAS_PCH_SPLIT(dev)) {
@@ -1026,7 +1036,7 @@ out:
        /* keep the LVDS connector */
        dev_priv->int_lvds_connector = connector;
        drm_sysfs_connector_add(connector);
-       return;
+       return true;
 
 failed:
        DRM_DEBUG_KMS("No LVDS modes found, disabling.\n");
@@ -1034,4 +1044,5 @@ failed:
        drm_encoder_cleanup(encoder);
        kfree(intel_lvds);
        kfree(intel_connector);
+       return false;
 }
index b83306f..89a65be 100644 (file)
@@ -156,23 +156,25 @@ static int init_ring_common(struct drm_device *dev,
 
        /* G45 ring initialization fails to reset head to zero */
        if (head != 0) {
-               DRM_ERROR("%s head not reset to zero "
-                               "ctl %08x head %08x tail %08x start %08x\n",
-                               ring->name,
-                               I915_READ_CTL(ring),
-                               I915_READ_HEAD(ring),
-                               I915_READ_TAIL(ring),
-                               I915_READ_START(ring));
+               DRM_DEBUG_KMS("%s head not reset to zero "
+                             "ctl %08x head %08x tail %08x start %08x\n",
+                             ring->name,
+                             I915_READ_CTL(ring),
+                             I915_READ_HEAD(ring),
+                             I915_READ_TAIL(ring),
+                             I915_READ_START(ring));
 
                I915_WRITE_HEAD(ring, 0);
 
-               DRM_ERROR("%s head forced to zero "
-                               "ctl %08x head %08x tail %08x start %08x\n",
-                               ring->name,
-                               I915_READ_CTL(ring),
-                               I915_READ_HEAD(ring),
-                               I915_READ_TAIL(ring),
-                               I915_READ_START(ring));
+               if (I915_READ_HEAD(ring) & HEAD_ADDR) {
+                       DRM_ERROR("failed to set %s head to zero "
+                                 "ctl %08x head %08x tail %08x start %08x\n",
+                                 ring->name,
+                                 I915_READ_CTL(ring),
+                                 I915_READ_HEAD(ring),
+                                 I915_READ_TAIL(ring),
+                                 I915_READ_START(ring));
+               }
        }
 
        I915_WRITE_CTL(ring,
index de158b7..d97e6cb 100644 (file)
@@ -107,7 +107,8 @@ struct intel_sdvo {
         * This is set if we treat the device as HDMI, instead of DVI.
         */
        bool is_hdmi;
-       bool has_audio;
+       bool has_hdmi_monitor;
+       bool has_hdmi_audio;
 
        /**
         * This is set if we detect output of sdvo device as LVDS and
@@ -1023,7 +1024,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
        if (!intel_sdvo_set_target_input(intel_sdvo))
                return;
 
-       if (intel_sdvo->is_hdmi &&
+       if (intel_sdvo->has_hdmi_monitor &&
            !intel_sdvo_set_avi_infoframe(intel_sdvo))
                return;
 
@@ -1063,7 +1064,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
        }
        if (intel_crtc->pipe == 1)
                sdvox |= SDVO_PIPE_B_SELECT;
-       if (intel_sdvo->has_audio)
+       if (intel_sdvo->has_hdmi_audio)
                sdvox |= SDVO_AUDIO_ENABLE;
 
        if (INTEL_INFO(dev)->gen >= 4) {
@@ -1295,55 +1296,14 @@ intel_sdvo_get_edid(struct drm_connector *connector)
        return drm_get_edid(connector, &sdvo->ddc);
 }
 
-static struct drm_connector *
-intel_find_analog_connector(struct drm_device *dev)
-{
-       struct drm_connector *connector;
-       struct intel_sdvo *encoder;
-
-       list_for_each_entry(encoder,
-                           &dev->mode_config.encoder_list,
-                           base.base.head) {
-               if (encoder->base.type == INTEL_OUTPUT_ANALOG) {
-                       list_for_each_entry(connector,
-                                           &dev->mode_config.connector_list,
-                                           head) {
-                               if (&encoder->base ==
-                                   intel_attached_encoder(connector))
-                                       return connector;
-                       }
-               }
-       }
-
-       return NULL;
-}
-
-static int
-intel_analog_is_connected(struct drm_device *dev)
-{
-       struct drm_connector *analog_connector;
-
-       analog_connector = intel_find_analog_connector(dev);
-       if (!analog_connector)
-               return false;
-
-       if (analog_connector->funcs->detect(analog_connector, false) ==
-                       connector_status_disconnected)
-               return false;
-
-       return true;
-}
-
 /* Mac mini hack -- use the same DDC as the analog connector */
 static struct edid *
 intel_sdvo_get_analog_edid(struct drm_connector *connector)
 {
        struct drm_i915_private *dev_priv = connector->dev->dev_private;
 
-       if (!intel_analog_is_connected(connector->dev))
-               return NULL;
-
-       return drm_get_edid(connector, &dev_priv->gmbus[dev_priv->crt_ddc_pin].adapter);
+       return drm_get_edid(connector,
+                           &dev_priv->gmbus[dev_priv->crt_ddc_pin].adapter);
 }
 
 enum drm_connector_status
@@ -1388,8 +1348,10 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector)
                /* DDC bus is shared, match EDID to connector type */
                if (edid->input & DRM_EDID_INPUT_DIGITAL) {
                        status = connector_status_connected;
-                       intel_sdvo->is_hdmi = drm_detect_hdmi_monitor(edid);
-                       intel_sdvo->has_audio = drm_detect_monitor_audio(edid);
+                       if (intel_sdvo->is_hdmi) {
+                               intel_sdvo->has_hdmi_monitor = drm_detect_hdmi_monitor(edid);
+                               intel_sdvo->has_hdmi_audio = drm_detect_monitor_audio(edid);
+                       }
                }
                connector->display_info.raw_edid = NULL;
                kfree(edid);
@@ -1398,7 +1360,7 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector)
        if (status == connector_status_connected) {
                struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector);
                if (intel_sdvo_connector->force_audio)
-                       intel_sdvo->has_audio = intel_sdvo_connector->force_audio > 0;
+                       intel_sdvo->has_hdmi_audio = intel_sdvo_connector->force_audio > 0;
        }
 
        return status;
@@ -1415,10 +1377,12 @@ intel_sdvo_detect(struct drm_connector *connector, bool force)
        if (!intel_sdvo_write_cmd(intel_sdvo,
                                  SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0))
                return connector_status_unknown;
-       if (intel_sdvo->is_tv) {
-               /* add 30ms delay when the output type is SDVO-TV */
+
+       /* add 30ms delay when the output type might be TV */
+       if (intel_sdvo->caps.output_flags &
+           (SDVO_OUTPUT_SVID0 | SDVO_OUTPUT_CVBS0))
                mdelay(30);
-       }
+
        if (!intel_sdvo_read_response(intel_sdvo, &response, 2))
                return connector_status_unknown;
 
@@ -1472,8 +1436,10 @@ static void intel_sdvo_get_ddc_modes(struct drm_connector *connector)
                edid = intel_sdvo_get_analog_edid(connector);
 
        if (edid != NULL) {
-               drm_mode_connector_update_edid_property(connector, edid);
-               drm_add_edid_modes(connector, edid);
+               if (edid->input & DRM_EDID_INPUT_DIGITAL) {
+                       drm_mode_connector_update_edid_property(connector, edid);
+                       drm_add_edid_modes(connector, edid);
+               }
                connector->display_info.raw_edid = NULL;
                kfree(edid);
        }
@@ -1713,12 +1679,12 @@ intel_sdvo_set_property(struct drm_connector *connector,
 
                intel_sdvo_connector->force_audio = val;
 
-               if (val > 0 && intel_sdvo->has_audio)
+               if (val > 0 && intel_sdvo->has_hdmi_audio)
                        return 0;
-               if (val < 0 && !intel_sdvo->has_audio)
+               if (val < 0 && !intel_sdvo->has_hdmi_audio)
                        return 0;
 
-               intel_sdvo->has_audio = val > 0;
+               intel_sdvo->has_hdmi_audio = val > 0;
                goto done;
        }
 
@@ -2070,6 +2036,8 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
                intel_sdvo_set_colorimetry(intel_sdvo,
                                           SDVO_COLORIMETRY_RGB256);
                connector->connector_type = DRM_MODE_CONNECTOR_HDMIA;
+
+               intel_sdvo_add_hdmi_properties(intel_sdvo_connector);
                intel_sdvo->is_hdmi = true;
        }
        intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
@@ -2077,8 +2045,6 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
 
        intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo);
 
-       intel_sdvo_add_hdmi_properties(intel_sdvo_connector);
-
        return true;
 }
 
index 8e421f6..05efb5b 100644 (file)
@@ -112,6 +112,7 @@ static uint32_t atom_iio_execute(struct atom_context *ctx, int base,
                        base += 3;
                        break;
                case ATOM_IIO_WRITE:
+                       (void)ctx->card->ioreg_read(ctx->card, CU16(base + 1));
                        ctx->card->ioreg_write(ctx->card, CU16(base + 1), temp);
                        base += 3;
                        break;
index a355259..4d7a2e1 100644 (file)
@@ -878,12 +878,15 @@ void r600_pcie_gart_tlb_flush(struct radeon_device *rdev)
        u32 tmp;
 
        /* flush hdp cache so updates hit vram */
-       if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740)) {
+       if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) &&
+           !(rdev->flags & RADEON_IS_AGP)) {
                void __iomem *ptr = (void *)rdev->gart.table.vram.ptr;
                u32 tmp;
 
                /* r7xx hw bug.  write to HDP_DEBUG1 followed by fb read
                 * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL
+                * This seems to cause problems on some AGP cards. Just use the old
+                * method for them.
                 */
                WREG32(HDP_DEBUG1, 0);
                tmp = readl((void __iomem *)ptr);
@@ -1195,8 +1198,10 @@ void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc)
                                mc->vram_end, mc->real_vram_size >> 20);
        } else {
                u64 base = 0;
-               if (rdev->flags & RADEON_IS_IGP)
-                       base = (RREG32(MC_VM_FB_LOCATION) & 0xFFFF) << 24;
+               if (rdev->flags & RADEON_IS_IGP) {
+                       base = RREG32(MC_VM_FB_LOCATION) & 0xFFFF;
+                       base <<= 24;
+               }
                radeon_vram_location(rdev, &rdev->mc, base);
                rdev->mc.gtt_base_align = 0;
                radeon_gtt_location(rdev, mc);
@@ -3483,10 +3488,12 @@ int r600_debugfs_mc_info_init(struct radeon_device *rdev)
 void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo)
 {
        /* r7xx hw bug.  write to HDP_DEBUG1 followed by fb read
-        * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL
+        * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL.
+        * This seems to cause problems on some AGP cards. Just use the old
+        * method for them.
         */
        if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) &&
-           rdev->vram_scratch.ptr) {
+           rdev->vram_scratch.ptr && !(rdev->flags & RADEON_IS_AGP)) {
                void __iomem *ptr = (void *)rdev->vram_scratch.ptr;
                u32 tmp;
 
index 9bebac1..0f90fc3 100644 (file)
@@ -315,7 +315,7 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
                if (array_mode == V_0280A0_ARRAY_LINEAR_GENERAL) {
                        /* the initial DDX does bad things with the CB size occasionally */
                        /* it rounds up height too far for slice tile max but the BO is smaller */
-                       tmp = (height - 7) * pitch * bpe;
+                       tmp = (height - 7) * 8 * bpe;
                        if ((tmp + track->cb_color_bo_offset[i]) > radeon_bo_size(track->cb_color_bo[i])) {
                                dev_warn(p->dev, "%s offset[%d] %d %d %lu too big\n", __func__, i, track->cb_color_bo_offset[i], tmp, radeon_bo_size(track->cb_color_bo[i]));
                                return -EINVAL;
index d84612a..33cda01 100644 (file)
@@ -86,6 +86,7 @@
 #define R600_HDP_NONSURFACE_BASE                                0x2c04
 
 #define R600_BUS_CNTL                                           0x5420
+#       define R600_BIOS_ROM_DIS                                (1 << 1)
 #define R600_CONFIG_CNTL                                        0x5424
 #define R600_CONFIG_MEMSIZE                                     0x5428
 #define R600_CONFIG_F0_BASE                                     0x542C
index 87ead09..bc5a2c3 100644 (file)
@@ -98,6 +98,14 @@ static inline struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_dev
                                }
                        }
 
+                       /* some DCE3 boards have bad data for this entry */
+                       if (ASIC_IS_DCE3(rdev)) {
+                               if ((i == 4) &&
+                                   (gpio->usClkMaskRegisterIndex == 0x1fda) &&
+                                   (gpio->sucI2cId.ucAccess == 0x94))
+                                       gpio->sucI2cId.ucAccess = 0x14;
+                       }
+
                        if (gpio->sucI2cId.ucAccess == id) {
                                i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4;
                                i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4;
@@ -174,6 +182,14 @@ void radeon_atombios_i2c_init(struct radeon_device *rdev)
                                }
                        }
 
+                       /* some DCE3 boards have bad data for this entry */
+                       if (ASIC_IS_DCE3(rdev)) {
+                               if ((i == 4) &&
+                                   (gpio->usClkMaskRegisterIndex == 0x1fda) &&
+                                   (gpio->sucI2cId.ucAccess == 0x94))
+                                       gpio->sucI2cId.ucAccess = 0x14;
+                       }
+
                        i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4;
                        i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4;
                        i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4;
index 654787e..8f2c7b5 100644 (file)
@@ -130,6 +130,7 @@ static bool radeon_atrm_get_bios(struct radeon_device *rdev)
        }
        return true;
 }
+
 static bool r700_read_disabled_bios(struct radeon_device *rdev)
 {
        uint32_t viph_control;
@@ -143,7 +144,7 @@ static bool r700_read_disabled_bios(struct radeon_device *rdev)
        bool r;
 
        viph_control = RREG32(RADEON_VIPH_CONTROL);
-       bus_cntl = RREG32(RADEON_BUS_CNTL);
+       bus_cntl = RREG32(R600_BUS_CNTL);
        d1vga_control = RREG32(AVIVO_D1VGA_CONTROL);
        d2vga_control = RREG32(AVIVO_D2VGA_CONTROL);
        vga_render_control = RREG32(AVIVO_VGA_RENDER_CONTROL);
@@ -152,7 +153,7 @@ static bool r700_read_disabled_bios(struct radeon_device *rdev)
        /* disable VIP */
        WREG32(RADEON_VIPH_CONTROL, (viph_control & ~RADEON_VIPH_EN));
        /* enable the rom */
-       WREG32(RADEON_BUS_CNTL, (bus_cntl & ~RADEON_BUS_BIOS_DIS_ROM));
+       WREG32(R600_BUS_CNTL, (bus_cntl & ~R600_BIOS_ROM_DIS));
        /* Disable VGA mode */
        WREG32(AVIVO_D1VGA_CONTROL,
               (d1vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE |
@@ -191,7 +192,7 @@ static bool r700_read_disabled_bios(struct radeon_device *rdev)
                        cg_spll_status = RREG32(R600_CG_SPLL_STATUS);
        }
        WREG32(RADEON_VIPH_CONTROL, viph_control);
-       WREG32(RADEON_BUS_CNTL, bus_cntl);
+       WREG32(R600_BUS_CNTL, bus_cntl);
        WREG32(AVIVO_D1VGA_CONTROL, d1vga_control);
        WREG32(AVIVO_D2VGA_CONTROL, d2vga_control);
        WREG32(AVIVO_VGA_RENDER_CONTROL, vga_render_control);
@@ -216,7 +217,7 @@ static bool r600_read_disabled_bios(struct radeon_device *rdev)
        bool r;
 
        viph_control = RREG32(RADEON_VIPH_CONTROL);
-       bus_cntl = RREG32(RADEON_BUS_CNTL);
+       bus_cntl = RREG32(R600_BUS_CNTL);
        d1vga_control = RREG32(AVIVO_D1VGA_CONTROL);
        d2vga_control = RREG32(AVIVO_D2VGA_CONTROL);
        vga_render_control = RREG32(AVIVO_VGA_RENDER_CONTROL);
@@ -231,7 +232,7 @@ static bool r600_read_disabled_bios(struct radeon_device *rdev)
        /* disable VIP */
        WREG32(RADEON_VIPH_CONTROL, (viph_control & ~RADEON_VIPH_EN));
        /* enable the rom */
-       WREG32(RADEON_BUS_CNTL, (bus_cntl & ~RADEON_BUS_BIOS_DIS_ROM));
+       WREG32(R600_BUS_CNTL, (bus_cntl & ~R600_BIOS_ROM_DIS));
        /* Disable VGA mode */
        WREG32(AVIVO_D1VGA_CONTROL,
               (d1vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE |
@@ -262,7 +263,7 @@ static bool r600_read_disabled_bios(struct radeon_device *rdev)
 
        /* restore regs */
        WREG32(RADEON_VIPH_CONTROL, viph_control);
-       WREG32(RADEON_BUS_CNTL, bus_cntl);
+       WREG32(R600_BUS_CNTL, bus_cntl);
        WREG32(AVIVO_D1VGA_CONTROL, d1vga_control);
        WREG32(AVIVO_D2VGA_CONTROL, d2vga_control);
        WREG32(AVIVO_VGA_RENDER_CONTROL, vga_render_control);
index 3bddea5..137b807 100644 (file)
@@ -729,7 +729,7 @@ void radeon_combios_i2c_init(struct radeon_device *rdev)
                                        clk = RBIOS8(offset + 3 + (i * 5) + 3);
                                        data = RBIOS8(offset + 3 + (i * 5) + 4);
                                        i2c = combios_setup_i2c_bus(rdev, DDC_MONID,
-                                                                   clk, data);
+                                                                   (1 << clk), (1 << data));
                                        rdev->i2c_bus[4] = radeon_i2c_create(dev, &i2c, "GPIOPAD_MASK");
                                        break;
                                }
index 3bef9f6..8afaf7a 100644 (file)
@@ -1175,6 +1175,8 @@ radeon_add_atom_connector(struct drm_device *dev,
                /* no HPD on analog connectors */
                radeon_connector->hpd.hpd = RADEON_HPD_NONE;
                connector->polled = DRM_CONNECTOR_POLL_CONNECT;
+               connector->interlace_allowed = true;
+               connector->doublescan_allowed = true;
                break;
        case DRM_MODE_CONNECTOR_DVIA:
                drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
@@ -1190,6 +1192,8 @@ radeon_add_atom_connector(struct drm_device *dev,
                                              1);
                /* no HPD on analog connectors */
                radeon_connector->hpd.hpd = RADEON_HPD_NONE;
+               connector->interlace_allowed = true;
+               connector->doublescan_allowed = true;
                break;
        case DRM_MODE_CONNECTOR_DVII:
        case DRM_MODE_CONNECTOR_DVID:
@@ -1226,6 +1230,11 @@ radeon_add_atom_connector(struct drm_device *dev,
                                                      rdev->mode_info.load_detect_property,
                                                      1);
                }
+               connector->interlace_allowed = true;
+               if (connector_type == DRM_MODE_CONNECTOR_DVII)
+                       connector->doublescan_allowed = true;
+               else
+                       connector->doublescan_allowed = false;
                break;
        case DRM_MODE_CONNECTOR_HDMIA:
        case DRM_MODE_CONNECTOR_HDMIB:
@@ -1256,6 +1265,11 @@ radeon_add_atom_connector(struct drm_device *dev,
                                                      0);
                }
                subpixel_order = SubPixelHorizontalRGB;
+               connector->interlace_allowed = true;
+               if (connector_type == DRM_MODE_CONNECTOR_HDMIB)
+                       connector->doublescan_allowed = true;
+               else
+                       connector->doublescan_allowed = false;
                break;
        case DRM_MODE_CONNECTOR_DisplayPort:
        case DRM_MODE_CONNECTOR_eDP:
@@ -1293,6 +1307,9 @@ radeon_add_atom_connector(struct drm_device *dev,
                                                      rdev->mode_info.underscan_vborder_property,
                                                      0);
                }
+               connector->interlace_allowed = true;
+               /* in theory with a DP to VGA converter... */
+               connector->doublescan_allowed = false;
                break;
        case DRM_MODE_CONNECTOR_SVIDEO:
        case DRM_MODE_CONNECTOR_Composite:
@@ -1308,6 +1325,8 @@ radeon_add_atom_connector(struct drm_device *dev,
                                              radeon_atombios_get_tv_info(rdev));
                /* no HPD on analog connectors */
                radeon_connector->hpd.hpd = RADEON_HPD_NONE;
+               connector->interlace_allowed = false;
+               connector->doublescan_allowed = false;
                break;
        case DRM_MODE_CONNECTOR_LVDS:
                radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL);
@@ -1326,6 +1345,8 @@ radeon_add_atom_connector(struct drm_device *dev,
                                              dev->mode_config.scaling_mode_property,
                                              DRM_MODE_SCALE_FULLSCREEN);
                subpixel_order = SubPixelHorizontalRGB;
+               connector->interlace_allowed = false;
+               connector->doublescan_allowed = false;
                break;
        }
 
@@ -1403,6 +1424,8 @@ radeon_add_legacy_connector(struct drm_device *dev,
                /* no HPD on analog connectors */
                radeon_connector->hpd.hpd = RADEON_HPD_NONE;
                connector->polled = DRM_CONNECTOR_POLL_CONNECT;
+               connector->interlace_allowed = true;
+               connector->doublescan_allowed = true;
                break;
        case DRM_MODE_CONNECTOR_DVIA:
                drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
@@ -1418,6 +1441,8 @@ radeon_add_legacy_connector(struct drm_device *dev,
                                              1);
                /* no HPD on analog connectors */
                radeon_connector->hpd.hpd = RADEON_HPD_NONE;
+               connector->interlace_allowed = true;
+               connector->doublescan_allowed = true;
                break;
        case DRM_MODE_CONNECTOR_DVII:
        case DRM_MODE_CONNECTOR_DVID:
@@ -1435,6 +1460,11 @@ radeon_add_legacy_connector(struct drm_device *dev,
                                                      1);
                }
                subpixel_order = SubPixelHorizontalRGB;
+               connector->interlace_allowed = true;
+               if (connector_type == DRM_MODE_CONNECTOR_DVII)
+                       connector->doublescan_allowed = true;
+               else
+                       connector->doublescan_allowed = false;
                break;
        case DRM_MODE_CONNECTOR_SVIDEO:
        case DRM_MODE_CONNECTOR_Composite:
@@ -1457,6 +1487,8 @@ radeon_add_legacy_connector(struct drm_device *dev,
                                              radeon_combios_get_tv_info(rdev));
                /* no HPD on analog connectors */
                radeon_connector->hpd.hpd = RADEON_HPD_NONE;
+               connector->interlace_allowed = false;
+               connector->doublescan_allowed = false;
                break;
        case DRM_MODE_CONNECTOR_LVDS:
                drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type);
@@ -1470,6 +1502,8 @@ radeon_add_legacy_connector(struct drm_device *dev,
                                              dev->mode_config.scaling_mode_property,
                                              DRM_MODE_SCALE_FULLSCREEN);
                subpixel_order = SubPixelHorizontalRGB;
+               connector->interlace_allowed = false;
+               connector->doublescan_allowed = false;
                break;
        }
 
index d8ac184..e12e793 100644 (file)
@@ -286,7 +286,7 @@ void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64
                mc->mc_vram_size = mc->aper_size;
        }
        mc->vram_end = mc->vram_start + mc->mc_vram_size - 1;
-       dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n",
+       dev_info(rdev->dev, "VRAM: %lluM 0x%016llX - 0x%016llX (%lluM used)\n",
                        mc->mc_vram_size >> 20, mc->vram_start,
                        mc->vram_end, mc->real_vram_size >> 20);
 }
@@ -323,7 +323,7 @@ void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc)
                mc->gtt_start = (mc->vram_end + 1 + mc->gtt_base_align) & ~mc->gtt_base_align;
        }
        mc->gtt_end = mc->gtt_start + mc->gtt_size - 1;
-       dev_info(rdev->dev, "GTT: %lluM 0x%08llX - 0x%08llX\n",
+       dev_info(rdev->dev, "GTT: %lluM 0x%016llX - 0x%016llX\n",
                        mc->gtt_size >> 20, mc->gtt_start, mc->gtt_end);
 }
 
index 1d06774..a598d00 100644 (file)
@@ -69,7 +69,7 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain)
        u32 c = 0;
 
        rbo->placement.fpfn = 0;
-       rbo->placement.lpfn = rbo->rdev->mc.active_vram_size >> PAGE_SHIFT;
+       rbo->placement.lpfn = 0;
        rbo->placement.placement = rbo->placements;
        rbo->placement.busy_placement = rbo->placements;
        if (domain & RADEON_GEM_DOMAIN_VRAM)
@@ -91,7 +91,8 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj,
 {
        struct radeon_bo *bo;
        enum ttm_bo_type type;
-       int page_align = roundup(byte_align, PAGE_SIZE) >> PAGE_SHIFT;
+       unsigned long page_align = roundup(byte_align, PAGE_SIZE) >> PAGE_SHIFT;
+       unsigned long max_size = 0;
        int r;
 
        if (unlikely(rdev->mman.bdev.dev_mapping == NULL)) {
@@ -104,6 +105,14 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj,
        }
        *bo_ptr = NULL;
 
+       /* maximun bo size is the minimun btw visible vram and gtt size */
+       max_size = min(rdev->mc.visible_vram_size, rdev->mc.gtt_size);
+       if ((page_align << PAGE_SHIFT) >= max_size) {
+               printk(KERN_WARNING "%s:%d alloc size %ldM bigger than %ldMb limit\n",
+                       __func__, __LINE__, page_align  >> (20 - PAGE_SHIFT), max_size >> 20);
+               return -ENOMEM;
+       }
+
 retry:
        bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL);
        if (bo == NULL)
index 515345b..88cb04e 100644 (file)
@@ -1386,6 +1386,7 @@ static const struct hid_device_id hid_blacklist[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) },
        { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb653) },
        { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb65a) },
        { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) },
        { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, USB_DEVICE_ID_TOPSEED2_RF_COMBO) },
        { HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) },
index 54b017a..5a1b52e 100644 (file)
@@ -221,7 +221,7 @@ static int egalax_probe(struct hid_device *hdev, const struct hid_device_id *id)
        struct egalax_data *td;
        struct hid_report *report;
 
-       td = kmalloc(sizeof(struct egalax_data), GFP_KERNEL);
+       td = kzalloc(sizeof(struct egalax_data), GFP_KERNEL);
        if (!td) {
                dev_err(&hdev->dev, "cannot allocate eGalax data\n");
                return -ENOMEM;
index bb0b365..d8d372b 100644 (file)
@@ -174,7 +174,7 @@ static int hidinput_setkeycode(struct input_dev *dev,
 
                clear_bit(*old_keycode, dev->keybit);
                set_bit(usage->code, dev->keybit);
-               dbg_hid(KERN_DEBUG "Assigned keycode %d to HID usage code %x\n",
+               dbg_hid("Assigned keycode %d to HID usage code %x\n",
                        usage->code, usage->hid);
 
                /*
@@ -203,8 +203,8 @@ static int hidinput_setkeycode(struct input_dev *dev,
  *
  * as seen in the HID specification v1.11 6.2.2.7 Global Items.
  *
- * Only exponent 1 length units are processed. Centimeters are converted to
- * inches. Degrees are converted to radians.
+ * Only exponent 1 length units are processed. Centimeters and inches are
+ * converted to millimeters. Degrees are converted to radians.
  */
 static __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code)
 {
@@ -225,13 +225,16 @@ static __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code)
         */
        if (code == ABS_X || code == ABS_Y || code == ABS_Z) {
                if (field->unit == 0x11) {              /* If centimeters */
-                       /* Convert to inches */
-                       prev = logical_extents;
-                       logical_extents *= 254;
-                       if (logical_extents < prev)
+                       /* Convert to millimeters */
+                       unit_exponent += 1;
+               } else if (field->unit == 0x13) {       /* If inches */
+                       /* Convert to millimeters */
+                       prev = physical_extents;
+                       physical_extents *= 254;
+                       if (physical_extents < prev)
                                return 0;
-                       unit_exponent += 2;
-               } else if (field->unit != 0x13) {       /* If not inches */
+                       unit_exponent -= 1;
+               } else {
                        return 0;
                }
        } else if (code == ABS_RX || code == ABS_RY || code == ABS_RZ) {
index 15434c8..25be4e1 100644 (file)
@@ -256,6 +256,8 @@ static const struct hid_device_id tm_devices[] = {
                .driver_data = (unsigned long)ff_joystick },
        { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654),   /* FGT Force Feedback Wheel */
                .driver_data = (unsigned long)ff_joystick },
+       { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb65a),   /* F430 Force Feedback Wheel */
+               .driver_data = (unsigned long)ff_joystick },
        { }
 };
 MODULE_DEVICE_TABLE(hid, tm_devices);
index 4bf969c..be0fdd5 100644 (file)
@@ -916,27 +916,27 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
        int nr = sensor_attr->index;
        struct i2c_client *client = to_i2c_client(dev);
        struct adm1026_data *data = i2c_get_clientdata(client);
-       int val, orig_div, new_div, shift;
+       int val, orig_div, new_div;
 
        val = simple_strtol(buf, NULL, 10);
        new_div = DIV_TO_REG(val);
-       if (new_div == 0) {
-               return -EINVAL;
-       }
+
        mutex_lock(&data->update_lock);
        orig_div = data->fan_div[nr];
        data->fan_div[nr] = DIV_FROM_REG(new_div);
 
        if (nr < 4) { /* 0 <= nr < 4 */
-               shift = 2 * nr;
                adm1026_write_value(client, ADM1026_REG_FAN_DIV_0_3,
-                       ((DIV_TO_REG(orig_div) & (~(0x03 << shift))) |
-                       (new_div << shift)));
+                                   (DIV_TO_REG(data->fan_div[0]) << 0) |
+                                   (DIV_TO_REG(data->fan_div[1]) << 2) |
+                                   (DIV_TO_REG(data->fan_div[2]) << 4) |
+                                   (DIV_TO_REG(data->fan_div[3]) << 6));
        } else { /* 3 < nr < 8 */
-               shift = 2 * (nr - 4);
                adm1026_write_value(client, ADM1026_REG_FAN_DIV_4_7,
-                       ((DIV_TO_REG(orig_div) & (~(0x03 << (2 * shift)))) |
-                       (new_div << shift)));
+                                   (DIV_TO_REG(data->fan_div[4]) << 0) |
+                                   (DIV_TO_REG(data->fan_div[5]) << 2) |
+                                   (DIV_TO_REG(data->fan_div[6]) << 4) |
+                                   (DIV_TO_REG(data->fan_div[7]) << 6));
        }
 
        if (data->fan_div[nr] != orig_div) {
index 14a5d98..a428a92 100644 (file)
@@ -187,6 +187,7 @@ static const u8 IT87_REG_FANX_MIN[] = { 0x1b, 0x1c, 0x1d, 0x85, 0x87 };
 #define IT87_REG_FAN_MAIN_CTRL 0x13
 #define IT87_REG_FAN_CTL       0x14
 #define IT87_REG_PWM(nr)       (0x15 + (nr))
+#define IT87_REG_PWM_DUTY(nr)  (0x63 + (nr) * 8)
 
 #define IT87_REG_VIN(nr)       (0x20 + (nr))
 #define IT87_REG_TEMP(nr)      (0x29 + (nr))
@@ -251,12 +252,16 @@ struct it87_data {
        u8 fan_main_ctrl;       /* Register value */
        u8 fan_ctl;             /* Register value */
 
-       /* The following 3 arrays correspond to the same registers. The
-        * meaning of bits 6-0 depends on the value of bit 7, and we want
-        * to preserve settings on mode changes, so we have to track all
-        * values separately. */
+       /* The following 3 arrays correspond to the same registers up to
+        * the IT8720F. The meaning of bits 6-0 depends on the value of bit
+        * 7, and we want to preserve settings on mode changes, so we have
+        * to track all values separately.
+        * Starting with the IT8721F, the manual PWM duty cycles are stored
+        * in separate registers (8-bit values), so the separate tracking
+        * is no longer needed, but it is still done to keep the driver
+        * simple. */
        u8 pwm_ctrl[3];         /* Register value */
-       u8 pwm_duty[3];         /* Manual PWM value set by user (bit 6-0) */
+       u8 pwm_duty[3];         /* Manual PWM value set by user */
        u8 pwm_temp_map[3];     /* PWM to temp. chan. mapping (bits 1-0) */
 
        /* Automatic fan speed control registers */
@@ -832,7 +837,9 @@ static ssize_t set_pwm_enable(struct device *dev,
                                 data->fan_main_ctrl);
        } else {
                if (val == 1)                           /* Manual mode */
-                       data->pwm_ctrl[nr] = data->pwm_duty[nr];
+                       data->pwm_ctrl[nr] = data->type == it8721 ?
+                                            data->pwm_temp_map[nr] :
+                                            data->pwm_duty[nr];
                else                                    /* Automatic mode */
                        data->pwm_ctrl[nr] = 0x80 | data->pwm_temp_map[nr];
                it87_write_value(data, IT87_REG_PWM(nr), data->pwm_ctrl[nr]);
@@ -858,12 +865,25 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
                return -EINVAL;
 
        mutex_lock(&data->update_lock);
-       data->pwm_duty[nr] = pwm_to_reg(data, val);
-       /* If we are in manual mode, write the duty cycle immediately;
-        * otherwise, just store it for later use. */
-       if (!(data->pwm_ctrl[nr] & 0x80)) {
-               data->pwm_ctrl[nr] = data->pwm_duty[nr];
-               it87_write_value(data, IT87_REG_PWM(nr), data->pwm_ctrl[nr]);
+       if (data->type == it8721) {
+               /* If we are in automatic mode, the PWM duty cycle register
+                * is read-only so we can't write the value */
+               if (data->pwm_ctrl[nr] & 0x80) {
+                       mutex_unlock(&data->update_lock);
+                       return -EBUSY;
+               }
+               data->pwm_duty[nr] = pwm_to_reg(data, val);
+               it87_write_value(data, IT87_REG_PWM_DUTY(nr),
+                                data->pwm_duty[nr]);
+       } else {
+               data->pwm_duty[nr] = pwm_to_reg(data, val);
+               /* If we are in manual mode, write the duty cycle immediately;
+                * otherwise, just store it for later use. */
+               if (!(data->pwm_ctrl[nr] & 0x80)) {
+                       data->pwm_ctrl[nr] = data->pwm_duty[nr];
+                       it87_write_value(data, IT87_REG_PWM(nr),
+                                        data->pwm_ctrl[nr]);
+               }
        }
        mutex_unlock(&data->update_lock);
        return count;
@@ -1958,7 +1978,10 @@ static void __devinit it87_init_device(struct platform_device *pdev)
         *   channels to use when later setting to automatic mode later.
         *   Use a 1:1 mapping by default (we are clueless.)
         * In both cases, the value can (and should) be changed by the user
-        * prior to switching to a different mode. */
+        * prior to switching to a different mode.
+        * Note that this is no longer needed for the IT8721F and later, as
+        * these have separate registers for the temperature mapping and the
+        * manual duty cycle. */
        for (i = 0; i < 3; i++) {
                data->pwm_temp_map[i] = i;
                data->pwm_duty[i] = 0x7f;       /* Full speed */
@@ -2034,10 +2057,16 @@ static void __devinit it87_init_device(struct platform_device *pdev)
 static void it87_update_pwm_ctrl(struct it87_data *data, int nr)
 {
        data->pwm_ctrl[nr] = it87_read_value(data, IT87_REG_PWM(nr));
-       if (data->pwm_ctrl[nr] & 0x80)  /* Automatic mode */
+       if (data->type == it8721) {
                data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03;
-       else                            /* Manual mode */
-               data->pwm_duty[nr] = data->pwm_ctrl[nr] & 0x7f;
+               data->pwm_duty[nr] = it87_read_value(data,
+                                                    IT87_REG_PWM_DUTY(nr));
+       } else {
+               if (data->pwm_ctrl[nr] & 0x80)  /* Automatic mode */
+                       data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03;
+               else                            /* Manual mode */
+                       data->pwm_duty[nr] = data->pwm_ctrl[nr] & 0x7f;
+       }
 
        if (has_old_autopwm(data)) {
                int i;
index 00d975e..c7e6d8e 100644 (file)
@@ -205,7 +205,6 @@ LTC4215_ALARM(curr1_max_alarm,      (1 << 2),       LTC4215_STATUS);
 
 /* Power (virtual) */
 LTC4215_POWER(power1_input);
-LTC4215_ALARM(power1_alarm,    (1 << 3),       LTC4215_STATUS);
 
 /* Input Voltage */
 LTC4215_VOLTAGE(in1_input,                     LTC4215_ADIN);
@@ -214,6 +213,7 @@ LTC4215_ALARM(in1_min_alarm,        (1 << 1),       LTC4215_STATUS);
 
 /* Output Voltage */
 LTC4215_VOLTAGE(in2_input,                     LTC4215_SOURCE);
+LTC4215_ALARM(in2_min_alarm,   (1 << 3),       LTC4215_STATUS);
 
 /* Finally, construct an array of pointers to members of the above objects,
  * as required for sysfs_create_group()
@@ -223,13 +223,13 @@ static struct attribute *ltc4215_attributes[] = {
        &sensor_dev_attr_curr1_max_alarm.dev_attr.attr,
 
        &sensor_dev_attr_power1_input.dev_attr.attr,
-       &sensor_dev_attr_power1_alarm.dev_attr.attr,
 
        &sensor_dev_attr_in1_input.dev_attr.attr,
        &sensor_dev_attr_in1_max_alarm.dev_attr.attr,
        &sensor_dev_attr_in1_min_alarm.dev_attr.attr,
 
        &sensor_dev_attr_in2_input.dev_attr.attr,
+       &sensor_dev_attr_in2_min_alarm.dev_attr.attr,
 
        NULL,
 };
index b923074..30f06e9 100644 (file)
@@ -75,8 +75,7 @@ config I2C_HELPER_AUTO
          In doubt, say Y.
 
 config I2C_SMBUS
-       tristate
-       prompt "SMBus-specific protocols" if !I2C_HELPER_AUTO
+       tristate "SMBus-specific protocols" if !I2C_HELPER_AUTO
        help
          Say Y here if you want support for SMBus extensions to the I2C
          specification. At the moment, the only supported extension is
index 3998dd6..f1cfe7e 100644 (file)
@@ -3,7 +3,7 @@
 #
 
 menu "I2C Algorithms"
-       depends on !I2C_HELPER_AUTO
+       visible if !I2C_HELPER_AUTO
 
 config I2C_ALGOBIT
        tristate "I2C bit-banging interfaces"
@@ -15,15 +15,3 @@ config I2C_ALGOPCA
        tristate "I2C PCA 9564 interfaces"
 
 endmenu
-
-# In automatic configuration mode, we still have to define the
-# symbols to avoid unmet dependencies.
-
-if I2C_HELPER_AUTO
-config I2C_ALGOBIT
-       tristate
-config I2C_ALGOPCF
-       tristate
-config I2C_ALGOPCA
-       tristate
-endif
index 80f70d3..c714927 100644 (file)
@@ -999,7 +999,7 @@ static int __devinit intel_mid_i2c_probe(struct pci_dev *dev,
 
        /* Initialize struct members */
        snprintf(mrst->adap.name, sizeof(mrst->adap.name),
-               "MRST/Medfield I2C at %lx", start);
+               "Intel MID I2C at %lx", start);
        mrst->adap.owner = THIS_MODULE;
        mrst->adap.algo = &intel_mid_i2c_algorithm;
        mrst->adap.dev.parent = &dev->dev;
index 41665d2..c131d58 100644 (file)
@@ -273,8 +273,6 @@ static int intel_idle_probe(void)
 
        pr_debug(PREFIX "MWAIT substates: 0x%x\n", mwait_substates);
 
-       if (boot_cpu_has(X86_FEATURE_ARAT))     /* Always Reliable APIC Timer */
-               lapic_timer_reliable_states = 0xFFFFFFFF;
 
        if (boot_cpu_data.x86 != 6)     /* family 6 */
                return -ENODEV;
@@ -286,8 +284,6 @@ static int intel_idle_probe(void)
        case 0x1F:      /* Core i7 and i5 Processor - Nehalem */
        case 0x2E:      /* Nehalem-EX Xeon */
        case 0x2F:      /* Westmere-EX Xeon */
-               lapic_timer_reliable_states = (1 << 1);  /* C1 */
-
        case 0x25:      /* Westmere */
        case 0x2C:      /* Westmere */
                cpuidle_state_table = nehalem_cstates;
@@ -295,7 +291,6 @@ static int intel_idle_probe(void)
 
        case 0x1C:      /* 28 - Atom Processor */
        case 0x26:      /* 38 - Lincroft Atom Processor */
-               lapic_timer_reliable_states = (1 << 1); /* C1 */
                cpuidle_state_table = atom_cstates;
                break;
 
@@ -303,10 +298,6 @@ static int intel_idle_probe(void)
        case 0x2D:      /* SNB Xeon */
                cpuidle_state_table = snb_cstates;
                break;
-#ifdef FUTURE_USE
-       case 0x17:      /* 23 - Core 2 Duo */
-               lapic_timer_reliable_states = (1 << 2) | (1 << 1); /* C2, C1 */
-#endif
 
        default:
                pr_debug(PREFIX "does not run on family %d model %d\n",
@@ -314,6 +305,9 @@ static int intel_idle_probe(void)
                return -ENODEV;
        }
 
+       if (boot_cpu_has(X86_FEATURE_ARAT))     /* Always Reliable APIC Timer */
+               lapic_timer_reliable_states = 0xFFFFFFFF;
+
        pr_debug(PREFIX "v" INTEL_IDLE_VERSION
                " model 0x%X\n", boot_cpu_data.x86_model);
 
index bb7e192..9b737ff 100644 (file)
@@ -277,36 +277,6 @@ void ib_ud_header_init(int                     payload_bytes,
 }
 EXPORT_SYMBOL(ib_ud_header_init);
 
-/**
- * ib_lrh_header_pack - Pack LRH header struct into wire format
- * @lrh:unpacked LRH header struct
- * @buf:Buffer to pack into
- *
- * ib_lrh_header_pack() packs the LRH header structure @lrh into
- * wire format in the buffer @buf.
- */
-int ib_lrh_header_pack(struct ib_unpacked_lrh *lrh, void *buf)
-{
-       ib_pack(lrh_table, ARRAY_SIZE(lrh_table), lrh, buf);
-       return 0;
-}
-EXPORT_SYMBOL(ib_lrh_header_pack);
-
-/**
- * ib_lrh_header_unpack - Unpack LRH structure from wire format
- * @lrh:unpacked LRH header struct
- * @buf:Buffer to pack into
- *
- * ib_lrh_header_unpack() unpacks the LRH header structure from
- * wire format (in buf) into @lrh.
- */
-int ib_lrh_header_unpack(void *buf, struct ib_unpacked_lrh *lrh)
-{
-       ib_unpack(lrh_table, ARRAY_SIZE(lrh_table), buf, lrh);
-       return 0;
-}
-EXPORT_SYMBOL(ib_lrh_header_unpack);
-
 /**
  * ib_ud_header_pack - Pack UD header struct into wire format
  * @header:UD header struct
index b342248..c426992 100644 (file)
@@ -893,68 +893,81 @@ out:
        return ret ? ret : in_len;
 }
 
+static int copy_wc_to_user(void __user *dest, struct ib_wc *wc)
+{
+       struct ib_uverbs_wc tmp;
+
+       tmp.wr_id               = wc->wr_id;
+       tmp.status              = wc->status;
+       tmp.opcode              = wc->opcode;
+       tmp.vendor_err          = wc->vendor_err;
+       tmp.byte_len            = wc->byte_len;
+       tmp.ex.imm_data         = (__u32 __force) wc->ex.imm_data;
+       tmp.qp_num              = wc->qp->qp_num;
+       tmp.src_qp              = wc->src_qp;
+       tmp.wc_flags            = wc->wc_flags;
+       tmp.pkey_index          = wc->pkey_index;
+       tmp.slid                = wc->slid;
+       tmp.sl                  = wc->sl;
+       tmp.dlid_path_bits      = wc->dlid_path_bits;
+       tmp.port_num            = wc->port_num;
+       tmp.reserved            = 0;
+
+       if (copy_to_user(dest, &tmp, sizeof tmp))
+               return -EFAULT;
+
+       return 0;
+}
+
 ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file,
                          const char __user *buf, int in_len,
                          int out_len)
 {
        struct ib_uverbs_poll_cq       cmd;
-       struct ib_uverbs_poll_cq_resp *resp;
+       struct ib_uverbs_poll_cq_resp  resp;
+       u8 __user                     *header_ptr;
+       u8 __user                     *data_ptr;
        struct ib_cq                  *cq;
-       struct ib_wc                  *wc;
-       int                            ret = 0;
-       int                            i;
-       int                            rsize;
+       struct ib_wc                   wc;
+       int                            ret;
 
        if (copy_from_user(&cmd, buf, sizeof cmd))
                return -EFAULT;
 
-       wc = kmalloc(cmd.ne * sizeof *wc, GFP_KERNEL);
-       if (!wc)
-               return -ENOMEM;
-
-       rsize = sizeof *resp + cmd.ne * sizeof(struct ib_uverbs_wc);
-       resp = kmalloc(rsize, GFP_KERNEL);
-       if (!resp) {
-               ret = -ENOMEM;
-               goto out_wc;
-       }
-
        cq = idr_read_cq(cmd.cq_handle, file->ucontext, 0);
-       if (!cq) {
-               ret = -EINVAL;
-               goto out;
-       }
+       if (!cq)
+               return -EINVAL;
 
-       resp->count = ib_poll_cq(cq, cmd.ne, wc);
+       /* we copy a struct ib_uverbs_poll_cq_resp to user space */
+       header_ptr = (void __user *)(unsigned long) cmd.response;
+       data_ptr = header_ptr + sizeof resp;
 
-       put_cq_read(cq);
+       memset(&resp, 0, sizeof resp);
+       while (resp.count < cmd.ne) {
+               ret = ib_poll_cq(cq, 1, &wc);
+               if (ret < 0)
+                       goto out_put;
+               if (!ret)
+                       break;
+
+               ret = copy_wc_to_user(data_ptr, &wc);
+               if (ret)
+                       goto out_put;
 
-       for (i = 0; i < resp->count; i++) {
-               resp->wc[i].wr_id          = wc[i].wr_id;
-               resp->wc[i].status         = wc[i].status;
-               resp->wc[i].opcode         = wc[i].opcode;
-               resp->wc[i].vendor_err     = wc[i].vendor_err;
-               resp->wc[i].byte_len       = wc[i].byte_len;
-               resp->wc[i].ex.imm_data    = (__u32 __force) wc[i].ex.imm_data;
-               resp->wc[i].qp_num         = wc[i].qp->qp_num;
-               resp->wc[i].src_qp         = wc[i].src_qp;
-               resp->wc[i].wc_flags       = wc[i].wc_flags;
-               resp->wc[i].pkey_index     = wc[i].pkey_index;
-               resp->wc[i].slid           = wc[i].slid;
-               resp->wc[i].sl             = wc[i].sl;
-               resp->wc[i].dlid_path_bits = wc[i].dlid_path_bits;
-               resp->wc[i].port_num       = wc[i].port_num;
+               data_ptr += sizeof(struct ib_uverbs_wc);
+               ++resp.count;
        }
 
-       if (copy_to_user((void __user *) (unsigned long) cmd.response, resp, rsize))
+       if (copy_to_user(header_ptr, &resp, sizeof resp)) {
                ret = -EFAULT;
+               goto out_put;
+       }
 
-out:
-       kfree(resp);
+       ret = in_len;
 
-out_wc:
-       kfree(wc);
-       return ret ? ret : in_len;
+out_put:
+       put_cq_read(cq);
+       return ret;
 }
 
 ssize_t ib_uverbs_req_notify_cq(struct ib_uverbs_file *file,
index 5440da0..1b1146f 100644 (file)
@@ -40,18 +40,21 @@ void ib_copy_ah_attr_to_user(struct ib_uverbs_ah_attr *dst,
        dst->grh.sgid_index        = src->grh.sgid_index;
        dst->grh.hop_limit         = src->grh.hop_limit;
        dst->grh.traffic_class     = src->grh.traffic_class;
+       memset(&dst->grh.reserved, 0, sizeof(dst->grh.reserved));
        dst->dlid                  = src->dlid;
        dst->sl                    = src->sl;
        dst->src_path_bits         = src->src_path_bits;
        dst->static_rate           = src->static_rate;
        dst->is_global             = src->ah_flags & IB_AH_GRH ? 1 : 0;
        dst->port_num              = src->port_num;
+       dst->reserved              = 0;
 }
 EXPORT_SYMBOL(ib_copy_ah_attr_to_user);
 
 void ib_copy_qp_attr_to_user(struct ib_uverbs_qp_attr *dst,
                             struct ib_qp_attr *src)
 {
+       dst->qp_state           = src->qp_state;
        dst->cur_qp_state       = src->cur_qp_state;
        dst->path_mtu           = src->path_mtu;
        dst->path_mig_state     = src->path_mig_state;
@@ -83,6 +86,7 @@ void ib_copy_qp_attr_to_user(struct ib_uverbs_qp_attr *dst,
        dst->rnr_retry          = src->rnr_retry;
        dst->alt_port_num       = src->alt_port_num;
        dst->alt_timeout        = src->alt_timeout;
+       memset(dst->reserved, 0, sizeof(dst->reserved));
 }
 EXPORT_SYMBOL(ib_copy_qp_attr_to_user);
 
index bf3e20c..30e09ca 100644 (file)
@@ -219,7 +219,7 @@ static int eth_link_query_port(struct ib_device *ibdev, u8 port,
        struct net_device *ndev;
        enum ib_mtu tmp;
 
-       props->active_width     = IB_WIDTH_4X;
+       props->active_width     = IB_WIDTH_1X;
        props->active_speed     = 4;
        props->port_cap_flags   = IB_PORT_CM_SUP;
        props->gid_tbl_len      = to_mdev(ibdev)->dev->caps.gid_table_len[port];
@@ -242,7 +242,7 @@ static int eth_link_query_port(struct ib_device *ibdev, u8 port,
        tmp = iboe_get_mtu(ndev->mtu);
        props->active_mtu = tmp ? min(props->max_mtu, tmp) : IB_MTU_256;
 
-       props->state            = netif_running(ndev) &&  netif_oper_up(ndev) ?
+       props->state            = (netif_running(ndev) && netif_carrier_ok(ndev)) ?
                                        IB_PORT_ACTIVE : IB_PORT_DOWN;
        props->phys_state       = state_to_phys_state(props->state);
 
index 9a7794a..2001f20 100644 (file)
@@ -1816,6 +1816,11 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
                ctrl->fence_size = (wr->send_flags & IB_SEND_FENCE ?
                                    MLX4_WQE_CTRL_FENCE : 0) | size;
 
+               if (be16_to_cpu(vlan) < 0x1000) {
+                       ctrl->ins_vlan = 1 << 6;
+                       ctrl->vlan_tag = vlan;
+               }
+
                /*
                 * Make sure descriptor is fully written before
                 * setting ownership bit (because HW can start
@@ -1831,11 +1836,6 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
                ctrl->owner_opcode = mlx4_ib_opcode[wr->opcode] |
                        (ind & qp->sq.wqe_cnt ? cpu_to_be32(1 << 31) : 0) | blh;
 
-               if (be16_to_cpu(vlan) < 0x1000) {
-                       ctrl->ins_vlan = 1 << 6;
-                       ctrl->vlan_tag = vlan;
-               }
-
                stamp = ind + qp->sq_spare_wqes;
                ind += DIV_ROUND_UP(size * 16, 1U << qp->sq.wqe_shift);
 
index e3f7fc6..68f09a8 100644 (file)
@@ -534,76 +534,73 @@ static int handle_eviocgbit(struct input_dev *dev,
 }
 #undef OLD_KEY_MAX
 
-static int evdev_handle_get_keycode(struct input_dev *dev,
-                                   void __user *p, size_t size)
+static int evdev_handle_get_keycode(struct input_dev *dev, void __user *p)
 {
-       struct input_keymap_entry ke;
+       struct input_keymap_entry ke = {
+               .len    = sizeof(unsigned int),
+               .flags  = 0,
+       };
+       int __user *ip = (int __user *)p;
        int error;
 
-       memset(&ke, 0, sizeof(ke));
-
-       if (size == sizeof(unsigned int[2])) {
-               /* legacy case */
-               int __user *ip = (int __user *)p;
+       /* legacy case */
+       if (copy_from_user(ke.scancode, p, sizeof(unsigned int)))
+               return -EFAULT;
 
-               if (copy_from_user(ke.scancode, p, sizeof(unsigned int)))
-                       return -EFAULT;
+       error = input_get_keycode(dev, &ke);
+       if (error)
+               return error;
 
-               ke.len = sizeof(unsigned int);
-               ke.flags = 0;
+       if (put_user(ke.keycode, ip + 1))
+               return -EFAULT;
 
-               error = input_get_keycode(dev, &ke);
-               if (error)
-                       return error;
+       return 0;
+}
 
-               if (put_user(ke.keycode, ip + 1))
-                       return -EFAULT;
+static int evdev_handle_get_keycode_v2(struct input_dev *dev, void __user *p)
+{
+       struct input_keymap_entry ke;
+       int error;
 
-       } else {
-               size = min(size, sizeof(ke));
+       if (copy_from_user(&ke, p, sizeof(ke)))
+               return -EFAULT;
 
-               if (copy_from_user(&ke, p, size))
-                       return -EFAULT;
+       error = input_get_keycode(dev, &ke);
+       if (error)
+               return error;
 
-               error = input_get_keycode(dev, &ke);
-               if (error)
-                       return error;
+       if (copy_to_user(p, &ke, sizeof(ke)))
+               return -EFAULT;
 
-               if (copy_to_user(p, &ke, size))
-                       return -EFAULT;
-       }
        return 0;
 }
 
-static int evdev_handle_set_keycode(struct input_dev *dev,
-                                   void __user *p, size_t size)
+static int evdev_handle_set_keycode(struct input_dev *dev, void __user *p)
 {
-       struct input_keymap_entry ke;
-
-       memset(&ke, 0, sizeof(ke));
+       struct input_keymap_entry ke = {
+               .len    = sizeof(unsigned int),
+               .flags  = 0,
+       };
+       int __user *ip = (int __user *)p;
 
-       if (size == sizeof(unsigned int[2])) {
-               /* legacy case */
-               int __user *ip = (int __user *)p;
+       if (copy_from_user(ke.scancode, p, sizeof(unsigned int)))
+               return -EFAULT;
 
-               if (copy_from_user(ke.scancode, p, sizeof(unsigned int)))
-                       return -EFAULT;
+       if (get_user(ke.keycode, ip + 1))
+               return -EFAULT;
 
-               if (get_user(ke.keycode, ip + 1))
-                       return -EFAULT;
+       return input_set_keycode(dev, &ke);
+}
 
-               ke.len = sizeof(unsigned int);
-               ke.flags = 0;
+static int evdev_handle_set_keycode_v2(struct input_dev *dev, void __user *p)
+{
+       struct input_keymap_entry ke;
 
-       } else {
-               size = min(size, sizeof(ke));
+       if (copy_from_user(&ke, p, sizeof(ke)))
+               return -EFAULT;
 
-               if (copy_from_user(&ke, p, size))
-                       return -EFAULT;
-
-               if (ke.len > sizeof(ke.scancode))
-                       return -EINVAL;
-       }
+       if (ke.len > sizeof(ke.scancode))
+               return -EINVAL;
 
        return input_set_keycode(dev, &ke);
 }
@@ -669,6 +666,18 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
                        return evdev_grab(evdev, client);
                else
                        return evdev_ungrab(evdev, client);
+
+       case EVIOCGKEYCODE:
+               return evdev_handle_get_keycode(dev, p);
+
+       case EVIOCSKEYCODE:
+               return evdev_handle_set_keycode(dev, p);
+
+       case EVIOCGKEYCODE_V2:
+               return evdev_handle_get_keycode_v2(dev, p);
+
+       case EVIOCSKEYCODE_V2:
+               return evdev_handle_set_keycode_v2(dev, p);
        }
 
        size = _IOC_SIZE(cmd);
@@ -708,12 +717,6 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
                        return -EFAULT;
 
                return error;
-
-       case EVIOC_MASK_SIZE(EVIOCGKEYCODE):
-               return evdev_handle_get_keycode(dev, p, size);
-
-       case EVIOC_MASK_SIZE(EVIOCSKEYCODE):
-               return evdev_handle_set_keycode(dev, p, size);
        }
 
        /* Multi-number variable-length handlers */
index d53b9e9..27b6a3c 100644 (file)
@@ -245,6 +245,7 @@ static struct tgfx __init *tgfx_probe(int parport, int *n_buttons, int n_devs)
                goto err_free_tgfx;
         }
 
+       parport_put_port(pp);
        return tgfx;
 
  err_free_dev:
index b8c51b9..3a87f3b 100644 (file)
@@ -179,6 +179,22 @@ config KEYBOARD_GPIO
          To compile this driver as a module, choose M here: the
          module will be called gpio_keys.
 
+config KEYBOARD_GPIO_POLLED
+       tristate "Polled GPIO buttons"
+       depends on GENERIC_GPIO
+       select INPUT_POLLDEV
+       help
+         This driver implements support for buttons connected
+         to GPIO pins that are not capable of generating interrupts.
+
+         Say Y here if your device has buttons connected
+         directly to such GPIO pins.  Your board-specific
+         setup logic must also provide a platform device,
+         with configuration data saying which GPIOs are used.
+
+         To compile this driver as a module, choose M here: the
+         module will be called gpio_keys_polled.
+
 config KEYBOARD_TCA6416
        tristate "TCA6416 Keypad Support"
        depends on I2C
index a34452e..622de73 100644 (file)
@@ -14,6 +14,7 @@ obj-$(CONFIG_KEYBOARD_BFIN)           += bf54x-keys.o
 obj-$(CONFIG_KEYBOARD_DAVINCI)         += davinci_keyscan.o
 obj-$(CONFIG_KEYBOARD_EP93XX)          += ep93xx_keypad.o
 obj-$(CONFIG_KEYBOARD_GPIO)            += gpio_keys.o
+obj-$(CONFIG_KEYBOARD_GPIO_POLLED)     += gpio_keys_polled.o
 obj-$(CONFIG_KEYBOARD_TCA6416)         += tca6416-keypad.o
 obj-$(CONFIG_KEYBOARD_HIL)             += hil_kbd.o
 obj-$(CONFIG_KEYBOARD_HIL_OLD)         += hilkbd.o
diff --git a/drivers/input/keyboard/gpio_keys_polled.c b/drivers/input/keyboard/gpio_keys_polled.c
new file mode 100644 (file)
index 0000000..4c17aff
--- /dev/null
@@ -0,0 +1,261 @@
+/*
+ *  Driver for buttons on GPIO lines not capable of generating interrupts
+ *
+ *  Copyright (C) 2007-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2010 Nuno Goncalves <nunojpg@gmail.com>
+ *
+ *  This file was based on: /drivers/input/misc/cobalt_btns.c
+ *     Copyright (C) 2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
+ *
+ *  also was based on: /drivers/input/keyboard/gpio_keys.c
+ *     Copyright 2005 Phil Blundell
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/input-polldev.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+
+#define DRV_NAME       "gpio-keys-polled"
+
+struct gpio_keys_button_data {
+       int last_state;
+       int count;
+       int threshold;
+       int can_sleep;
+};
+
+struct gpio_keys_polled_dev {
+       struct input_polled_dev *poll_dev;
+       struct device *dev;
+       struct gpio_keys_platform_data *pdata;
+       struct gpio_keys_button_data data[0];
+};
+
+static void gpio_keys_polled_check_state(struct input_dev *input,
+                                        struct gpio_keys_button *button,
+                                        struct gpio_keys_button_data *bdata)
+{
+       int state;
+
+       if (bdata->can_sleep)
+               state = !!gpio_get_value_cansleep(button->gpio);
+       else
+               state = !!gpio_get_value(button->gpio);
+
+       if (state != bdata->last_state) {
+               unsigned int type = button->type ?: EV_KEY;
+
+               input_event(input, type, button->code,
+                           !!(state ^ button->active_low));
+               input_sync(input);
+               bdata->count = 0;
+               bdata->last_state = state;
+       }
+}
+
+static void gpio_keys_polled_poll(struct input_polled_dev *dev)
+{
+       struct gpio_keys_polled_dev *bdev = dev->private;
+       struct gpio_keys_platform_data *pdata = bdev->pdata;
+       struct input_dev *input = dev->input;
+       int i;
+
+       for (i = 0; i < bdev->pdata->nbuttons; i++) {
+               struct gpio_keys_button_data *bdata = &bdev->data[i];
+
+               if (bdata->count < bdata->threshold)
+                       bdata->count++;
+               else
+                       gpio_keys_polled_check_state(input, &pdata->buttons[i],
+                                                    bdata);
+       }
+}
+
+static void gpio_keys_polled_open(struct input_polled_dev *dev)
+{
+       struct gpio_keys_polled_dev *bdev = dev->private;
+       struct gpio_keys_platform_data *pdata = bdev->pdata;
+
+       if (pdata->enable)
+               pdata->enable(bdev->dev);
+}
+
+static void gpio_keys_polled_close(struct input_polled_dev *dev)
+{
+       struct gpio_keys_polled_dev *bdev = dev->private;
+       struct gpio_keys_platform_data *pdata = bdev->pdata;
+
+       if (pdata->disable)
+               pdata->disable(bdev->dev);
+}
+
+static int __devinit gpio_keys_polled_probe(struct platform_device *pdev)
+{
+       struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
+       struct device *dev = &pdev->dev;
+       struct gpio_keys_polled_dev *bdev;
+       struct input_polled_dev *poll_dev;
+       struct input_dev *input;
+       int error;
+       int i;
+
+       if (!pdata || !pdata->poll_interval)
+               return -EINVAL;
+
+       bdev = kzalloc(sizeof(struct gpio_keys_polled_dev) +
+                      pdata->nbuttons * sizeof(struct gpio_keys_button_data),
+                      GFP_KERNEL);
+       if (!bdev) {
+               dev_err(dev, "no memory for private data\n");
+               return -ENOMEM;
+       }
+
+       poll_dev = input_allocate_polled_device();
+       if (!poll_dev) {
+               dev_err(dev, "no memory for polled device\n");
+               error = -ENOMEM;
+               goto err_free_bdev;
+       }
+
+       poll_dev->private = bdev;
+       poll_dev->poll = gpio_keys_polled_poll;
+       poll_dev->poll_interval = pdata->poll_interval;
+       poll_dev->open = gpio_keys_polled_open;
+       poll_dev->close = gpio_keys_polled_close;
+
+       input = poll_dev->input;
+
+       input->evbit[0] = BIT(EV_KEY);
+       input->name = pdev->name;
+       input->phys = DRV_NAME"/input0";
+       input->dev.parent = &pdev->dev;
+
+       input->id.bustype = BUS_HOST;
+       input->id.vendor = 0x0001;
+       input->id.product = 0x0001;
+       input->id.version = 0x0100;
+
+       for (i = 0; i < pdata->nbuttons; i++) {
+               struct gpio_keys_button *button = &pdata->buttons[i];
+               struct gpio_keys_button_data *bdata = &bdev->data[i];
+               unsigned int gpio = button->gpio;
+               unsigned int type = button->type ?: EV_KEY;
+
+               if (button->wakeup) {
+                       dev_err(dev, DRV_NAME " does not support wakeup\n");
+                       error = -EINVAL;
+                       goto err_free_gpio;
+               }
+
+               error = gpio_request(gpio,
+                                    button->desc ? button->desc : DRV_NAME);
+               if (error) {
+                       dev_err(dev, "unable to claim gpio %u, err=%d\n",
+                               gpio, error);
+                       goto err_free_gpio;
+               }
+
+               error = gpio_direction_input(gpio);
+               if (error) {
+                       dev_err(dev,
+                               "unable to set direction on gpio %u, err=%d\n",
+                               gpio, error);
+                       goto err_free_gpio;
+               }
+
+               bdata->can_sleep = gpio_cansleep(gpio);
+               bdata->last_state = -1;
+               bdata->threshold = DIV_ROUND_UP(button->debounce_interval,
+                                               pdata->poll_interval);
+
+               input_set_capability(input, type, button->code);
+       }
+
+       bdev->poll_dev = poll_dev;
+       bdev->dev = dev;
+       bdev->pdata = pdata;
+       platform_set_drvdata(pdev, bdev);
+
+       error = input_register_polled_device(poll_dev);
+       if (error) {
+               dev_err(dev, "unable to register polled device, err=%d\n",
+                       error);
+               goto err_free_gpio;
+       }
+
+       /* report initial state of the buttons */
+       for (i = 0; i < pdata->nbuttons; i++)
+               gpio_keys_polled_check_state(input, &pdata->buttons[i],
+                                        &bdev->data[i]);
+
+       return 0;
+
+err_free_gpio:
+       while (--i >= 0)
+               gpio_free(pdata->buttons[i].gpio);
+
+       input_free_polled_device(poll_dev);
+
+err_free_bdev:
+       kfree(bdev);
+
+       platform_set_drvdata(pdev, NULL);
+       return error;
+}
+
+static int __devexit gpio_keys_polled_remove(struct platform_device *pdev)
+{
+       struct gpio_keys_polled_dev *bdev = platform_get_drvdata(pdev);
+       struct gpio_keys_platform_data *pdata = bdev->pdata;
+       int i;
+
+       input_unregister_polled_device(bdev->poll_dev);
+
+       for (i = 0; i < pdata->nbuttons; i++)
+               gpio_free(pdata->buttons[i].gpio);
+
+       input_free_polled_device(bdev->poll_dev);
+
+       kfree(bdev);
+       platform_set_drvdata(pdev, NULL);
+
+       return 0;
+}
+
+static struct platform_driver gpio_keys_polled_driver = {
+       .probe  = gpio_keys_polled_probe,
+       .remove = __devexit_p(gpio_keys_polled_remove),
+       .driver = {
+               .name   = DRV_NAME,
+               .owner  = THIS_MODULE,
+       },
+};
+
+static int __init gpio_keys_polled_init(void)
+{
+       return platform_driver_register(&gpio_keys_polled_driver);
+}
+
+static void __exit gpio_keys_polled_exit(void)
+{
+       platform_driver_unregister(&gpio_keys_polled_driver);
+}
+
+module_init(gpio_keys_polled_init);
+module_exit(gpio_keys_polled_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
+MODULE_DESCRIPTION("Polled GPIO Buttons driver");
+MODULE_ALIAS("platform:" DRV_NAME);
index 613a365..0aefaa8 100644 (file)
@@ -51,7 +51,8 @@
 #define SYN_EXT_CAP_REQUESTS(c)                (((c) & 0x700000) >> 20)
 #define SYN_CAP_MULTI_BUTTON_NO(ec)    (((ec) & 0x00f000) >> 12)
 #define SYN_CAP_PRODUCT_ID(ec)         (((ec) & 0xff0000) >> 16)
-#define SYN_CAP_CLICKPAD(ex0c)         ((ex0c) & 0x100100)
+#define SYN_CAP_CLICKPAD(ex0c)         ((ex0c) & 0x100000) /* 1-button ClickPad */
+#define SYN_CAP_CLICKPAD2BTN(ex0c)     ((ex0c) & 0x000100) /* 2-button ClickPad */
 #define SYN_CAP_MAX_DIMENSIONS(ex0c)   ((ex0c) & 0x020000)
 
 /* synaptics modes query bits */
index 3c287dd..4225f5d 100644 (file)
@@ -358,7 +358,7 @@ static int __devinit gscps2_probe(struct parisc_device *dev)
        gscps2_reset(ps2port);
        ps2port->id = readb(ps2port->addr + GSC_ID) & 0x0f;
 
-       snprintf(serio->name, sizeof(serio->name), "GSC PS/2 %s",
+       snprintf(serio->name, sizeof(serio->name), "gsc-ps2-%s",
                 (ps2port->id == GSC_ID_KEYBOARD) ? "keyboard" : "mouse");
        strlcpy(serio->phys, dev_name(&dev->dev), sizeof(serio->phys));
        serio->id.type          = SERIO_8042;
index b3252ef..435b0af 100644 (file)
@@ -1436,6 +1436,14 @@ static struct wacom_features wacom_features_0xD2 =
        { "Wacom Bamboo Craft",   WACOM_PKGLEN_BBFUN,     14720,  9200, 1023, 63, BAMBOO_PT };
 static struct wacom_features wacom_features_0xD3 =
        { "Wacom Bamboo 2FG 6x8", WACOM_PKGLEN_BBFUN,     21648, 13530, 1023, 63, BAMBOO_PT };
+static const struct wacom_features wacom_features_0xD4 =
+       { "Wacom Bamboo Pen",     WACOM_PKGLEN_BBFUN,     14720,  9200,  255, 63, BAMBOO_PT };
+static struct wacom_features wacom_features_0xD8 =
+       { "Wacom Bamboo Comic 2FG", WACOM_PKGLEN_BBFUN,   21648, 13530, 1023, 63, BAMBOO_PT };
+static struct wacom_features wacom_features_0xDA =
+       { "Wacom Bamboo 2FG 4x5 SE", WACOM_PKGLEN_BBFUN,  14720,  9200, 1023, 63, BAMBOO_PT };
+static struct wacom_features wacom_features_0xDB =
+       { "Wacom Bamboo 2FG 6x8 SE", WACOM_PKGLEN_BBFUN,  21648, 13530, 1023, 63, BAMBOO_PT };
 
 #define USB_DEVICE_WACOM(prod)                                 \
        USB_DEVICE(USB_VENDOR_ID_WACOM, prod),                  \
@@ -1504,6 +1512,10 @@ const struct usb_device_id wacom_ids[] = {
        { USB_DEVICE_WACOM(0xD1) },
        { USB_DEVICE_WACOM(0xD2) },
        { USB_DEVICE_WACOM(0xD3) },
+       { USB_DEVICE_WACOM(0xD4) },
+       { USB_DEVICE_WACOM(0xD8) },
+       { USB_DEVICE_WACOM(0xDA) },
+       { USB_DEVICE_WACOM(0xDB) },
        { USB_DEVICE_WACOM(0xF0) },
        { USB_DEVICE_WACOM(0xCC) },
        { USB_DEVICE_WACOM(0x90) },
index f45f80f..73fd664 100644 (file)
@@ -178,6 +178,7 @@ static const struct usb_device_id usbtouch_devices[] = {
 
 #ifdef CONFIG_TOUCHSCREEN_USB_ITM
        {USB_DEVICE(0x0403, 0xf9e9), .driver_info = DEVTYPE_ITM},
+       {USB_DEVICE(0x16e3, 0xf9e9), .driver_info = DEVTYPE_ITM},
 #endif
 
 #ifdef CONFIG_TOUCHSCREEN_USB_ETURBO
index 2e847a9..f2b5bab 100644 (file)
@@ -1627,7 +1627,7 @@ __setup("icn=", icn_setup);
 static int __init icn_init(void)
 {
        char *p;
-       char rev[10];
+       char rev[20];
 
        memset(&dev, 0, sizeof(icn_dev));
        dev.memaddr = (membase & 0x0ffc000);
@@ -1637,9 +1637,10 @@ static int __init icn_init(void)
        spin_lock_init(&dev.devlock);
 
        if ((p = strchr(revision, ':'))) {
-               strcpy(rev, p + 1);
+               strncpy(rev, p + 1, 20);
                p = strchr(rev, '$');
-               *p = 0;
+               if (p)
+                       *p = 0;
        } else
                strcpy(rev, " ??? ");
        printk(KERN_NOTICE "ICN-ISDN-driver Rev%smem=0x%08lx\n", rev,
index 77b8fd2..6f190f4 100644 (file)
@@ -7,20 +7,20 @@ menuconfig NEW_LEDS
          This is not related to standard keyboard LEDs which are controlled
          via the input system.
 
-if NEW_LEDS
-
 config LEDS_CLASS
        bool "LED Class Support"
+       depends on NEW_LEDS
        help
          This option enables the led sysfs class in /sys/class/leds.  You'll
          need this to do anything useful with LEDs.  If unsure, say N.
 
-if LEDS_CLASS
+if NEW_LEDS
 
 comment "LED drivers"
 
 config LEDS_88PM860X
        tristate "LED Support for Marvell 88PM860x PMIC"
+       depends on LEDS_CLASS
        depends on MFD_88PM860X
        help
          This option enables support for on-chip LED drivers found on Marvell
@@ -28,6 +28,7 @@ config LEDS_88PM860X
 
 config LEDS_ATMEL_PWM
        tristate "LED Support using Atmel PWM outputs"
+       depends on LEDS_CLASS
        depends on ATMEL_PWM
        help
          This option enables support for LEDs driven using outputs
@@ -35,6 +36,7 @@ config LEDS_ATMEL_PWM
 
 config LEDS_LOCOMO
        tristate "LED Support for Locomo device"
+       depends on LEDS_CLASS
        depends on SHARP_LOCOMO
        help
          This option enables support for the LEDs on Sharp Locomo.
@@ -42,6 +44,7 @@ config LEDS_LOCOMO
 
 config LEDS_MIKROTIK_RB532
        tristate "LED Support for Mikrotik Routerboard 532"
+       depends on LEDS_CLASS
        depends on MIKROTIK_RB532
        help
          This option enables support for the so called "User LED" of
@@ -49,6 +52,7 @@ config LEDS_MIKROTIK_RB532
 
 config LEDS_S3C24XX
        tristate "LED Support for Samsung S3C24XX GPIO LEDs"
+       depends on LEDS_CLASS
        depends on ARCH_S3C2410
        help
          This option enables support for LEDs connected to GPIO lines
@@ -56,12 +60,14 @@ config LEDS_S3C24XX
 
 config LEDS_AMS_DELTA
        tristate "LED Support for the Amstrad Delta (E3)"
+       depends on LEDS_CLASS
        depends on MACH_AMS_DELTA
        help
          This option enables support for the LEDs on Amstrad Delta (E3).
 
 config LEDS_NET48XX
        tristate "LED Support for Soekris net48xx series Error LED"
+       depends on LEDS_CLASS
        depends on SCx200_GPIO
        help
          This option enables support for the Soekris net4801 and net4826 error
@@ -79,18 +85,21 @@ config LEDS_NET5501
 
 config LEDS_FSG
        tristate "LED Support for the Freecom FSG-3"
+       depends on LEDS_CLASS
        depends on MACH_FSG
        help
          This option enables support for the LEDs on the Freecom FSG-3.
 
 config LEDS_WRAP
        tristate "LED Support for the WRAP series LEDs"
+       depends on LEDS_CLASS
        depends on SCx200_GPIO
        help
          This option enables support for the PCEngines WRAP programmable LEDs.
 
 config LEDS_ALIX2
        tristate "LED Support for ALIX.2 and ALIX.3 series"
+       depends on LEDS_CLASS
        depends on X86 && !GPIO_CS5535 && !CS5535_GPIO
        help
          This option enables support for the PCEngines ALIX.2 and ALIX.3 LEDs.
@@ -98,12 +107,14 @@ config LEDS_ALIX2
 
 config LEDS_H1940
        tristate "LED Support for iPAQ H1940 device"
+       depends on LEDS_CLASS
        depends on ARCH_H1940
        help
          This option enables support for the LEDs on the h1940.
 
 config LEDS_COBALT_QUBE
        tristate "LED Support for the Cobalt Qube series front LED"
+       depends on LEDS_CLASS
        depends on MIPS_COBALT
        help
          This option enables support for the front LED on Cobalt Qube series
@@ -117,6 +128,7 @@ config LEDS_COBALT_RAQ
 
 config LEDS_SUNFIRE
        tristate "LED support for SunFire servers."
+       depends on LEDS_CLASS
        depends on SPARC64
        select LEDS_TRIGGERS
        help
@@ -125,6 +137,7 @@ config LEDS_SUNFIRE
 
 config LEDS_HP6XX
        tristate "LED Support for the HP Jornada 6xx"
+       depends on LEDS_CLASS
        depends on SH_HP6XX
        help
          This option enables LED support for the handheld
@@ -132,6 +145,7 @@ config LEDS_HP6XX
 
 config LEDS_PCA9532
        tristate "LED driver for PCA9532 dimmer"
+       depends on LEDS_CLASS
        depends on I2C && INPUT && EXPERIMENTAL
        help
          This option enables support for NXP pca9532
@@ -140,6 +154,7 @@ config LEDS_PCA9532
 
 config LEDS_GPIO
        tristate "LED Support for GPIO connected LEDs"
+       depends on LEDS_CLASS
        depends on GENERIC_GPIO
        help
          This option enables support for the LEDs connected to GPIO
@@ -167,6 +182,7 @@ config LEDS_GPIO_OF
 
 config LEDS_LP3944
        tristate "LED Support for N.S. LP3944 (Fun Light) I2C chip"
+       depends on LEDS_CLASS
        depends on I2C
        help
          This option enables support for LEDs connected to the National
@@ -196,6 +212,7 @@ config LEDS_LP5523
 
 config LEDS_CLEVO_MAIL
        tristate "Mail LED on Clevo notebook"
+       depends on LEDS_CLASS
        depends on X86 && SERIO_I8042 && DMI
        help
          This driver makes the mail LED accessible from userspace
@@ -226,6 +243,7 @@ config LEDS_CLEVO_MAIL
 
 config LEDS_PCA955X
        tristate "LED Support for PCA955x I2C chips"
+       depends on LEDS_CLASS
        depends on I2C
        help
          This option enables support for LEDs connected to PCA955x
@@ -234,6 +252,7 @@ config LEDS_PCA955X
 
 config LEDS_WM831X_STATUS
        tristate "LED support for status LEDs on WM831x PMICs"
+       depends on LEDS_CLASS
        depends on MFD_WM831X
        help
          This option enables support for the status LEDs of the WM831x
@@ -241,6 +260,7 @@ config LEDS_WM831X_STATUS
 
 config LEDS_WM8350
        tristate "LED Support for WM8350 AudioPlus PMIC"
+       depends on LEDS_CLASS
        depends on MFD_WM8350
        help
          This option enables support for LEDs driven by the Wolfson
@@ -248,6 +268,7 @@ config LEDS_WM8350
 
 config LEDS_DA903X
        tristate "LED Support for DA9030/DA9034 PMIC"
+       depends on LEDS_CLASS
        depends on PMIC_DA903X
        help
          This option enables support for on-chip LED drivers found
@@ -255,6 +276,7 @@ config LEDS_DA903X
 
 config LEDS_DAC124S085
        tristate "LED Support for DAC124S085 SPI DAC"
+       depends on LEDS_CLASS
        depends on SPI
        help
          This option enables support for DAC124S085 SPI DAC from NatSemi,
@@ -262,18 +284,21 @@ config LEDS_DAC124S085
 
 config LEDS_PWM
        tristate "PWM driven LED Support"
+       depends on LEDS_CLASS
        depends on HAVE_PWM
        help
          This option enables support for pwm driven LEDs
 
 config LEDS_REGULATOR
        tristate "REGULATOR driven LED support"
+       depends on LEDS_CLASS
        depends on REGULATOR
        help
          This option enables support for regulator driven LEDs.
 
 config LEDS_BD2802
        tristate "LED driver for BD2802 RGB LED"
+       depends on LEDS_CLASS
        depends on I2C
        help
          This option enables support for BD2802GU RGB LED driver chips
@@ -281,6 +306,7 @@ config LEDS_BD2802
 
 config LEDS_INTEL_SS4200
        tristate "LED driver for Intel NAS SS4200 series"
+       depends on LEDS_CLASS
        depends on PCI && DMI
        help
          This option enables support for the Intel SS4200 series of
@@ -290,6 +316,7 @@ config LEDS_INTEL_SS4200
 
 config LEDS_LT3593
        tristate "LED driver for LT3593 controllers"
+       depends on LEDS_CLASS
        depends on GENERIC_GPIO
        help
          This option enables support for LEDs driven by a Linear Technology
@@ -298,6 +325,7 @@ config LEDS_LT3593
 
 config LEDS_ADP5520
        tristate "LED Support for ADP5520/ADP5501 PMIC"
+       depends on LEDS_CLASS
        depends on PMIC_ADP5520
        help
          This option enables support for on-chip LED drivers found
@@ -308,6 +336,7 @@ config LEDS_ADP5520
 
 config LEDS_DELL_NETBOOKS
        tristate "External LED on Dell Business Netbooks"
+       depends on LEDS_CLASS
        depends on X86 && ACPI_WMI
        help
          This adds support for the Latitude 2100 and similar
@@ -315,6 +344,7 @@ config LEDS_DELL_NETBOOKS
 
 config LEDS_MC13783
        tristate "LED Support for MC13783 PMIC"
+       depends on LEDS_CLASS
        depends on MFD_MC13783
        help
          This option enable support for on-chip LED drivers found
@@ -322,6 +352,7 @@ config LEDS_MC13783
 
 config LEDS_NS2
        tristate "LED support for Network Space v2 GPIO LEDs"
+       depends on LEDS_CLASS
        depends on MACH_NETSPACE_V2 || MACH_INETSPACE_V2 || MACH_NETSPACE_MAX_V2 || D2NET_V2
        default y
        help
@@ -340,17 +371,17 @@ config LEDS_NETXBIG
 
 config LEDS_TRIGGERS
        bool "LED Trigger support"
+       depends on LEDS_CLASS
        help
          This option enables trigger support for the leds class.
          These triggers allow kernel events to drive the LEDs and can
          be configured via sysfs. If unsure, say Y.
 
-if LEDS_TRIGGERS
-
 comment "LED Triggers"
 
 config LEDS_TRIGGER_TIMER
        tristate "LED Timer Trigger"
+       depends on LEDS_TRIGGERS
        help
          This allows LEDs to be controlled by a programmable timer
          via sysfs. Some LED hardware can be programmed to start
@@ -362,12 +393,14 @@ config LEDS_TRIGGER_TIMER
 config LEDS_TRIGGER_IDE_DISK
        bool "LED IDE Disk Trigger"
        depends on IDE_GD_ATA
+       depends on LEDS_TRIGGERS
        help
          This allows LEDs to be controlled by IDE disk activity.
          If unsure, say Y.
 
 config LEDS_TRIGGER_HEARTBEAT
        tristate "LED Heartbeat Trigger"
+       depends on LEDS_TRIGGERS
        help
          This allows LEDs to be controlled by a CPU load average.
          The flash frequency is a hyperbolic function of the 1-minute
@@ -376,6 +409,7 @@ config LEDS_TRIGGER_HEARTBEAT
 
 config LEDS_TRIGGER_BACKLIGHT
        tristate "LED backlight Trigger"
+       depends on LEDS_TRIGGERS
        help
          This allows LEDs to be controlled as a backlight device: they
          turn off and on when the display is blanked and unblanked.
@@ -384,6 +418,7 @@ config LEDS_TRIGGER_BACKLIGHT
 
 config LEDS_TRIGGER_GPIO
        tristate "LED GPIO Trigger"
+       depends on LEDS_TRIGGERS
        depends on GPIOLIB
        help
          This allows LEDs to be controlled by gpio events. It's good
@@ -396,6 +431,7 @@ config LEDS_TRIGGER_GPIO
 
 config LEDS_TRIGGER_DEFAULT_ON
        tristate "LED Default ON Trigger"
+       depends on LEDS_TRIGGERS
        help
          This allows LEDs to be initialised in the ON state.
          If unsure, say Y.
@@ -403,8 +439,4 @@ config LEDS_TRIGGER_DEFAULT_ON
 comment "iptables trigger is under Netfilter config (LED target)"
        depends on LEDS_TRIGGERS
 
-endif # LEDS_TRIGGERS
-
-endif # LEDS_CLASS
-
 endif # NEW_LEDS
index 3d7355f..fa51af1 100644 (file)
@@ -102,6 +102,7 @@ config ADB_PMU_LED
 config ADB_PMU_LED_IDE
        bool "Use front LED as IDE LED by default"
        depends on ADB_PMU_LED
+       depends on LEDS_CLASS
        select LEDS_TRIGGERS
        select LEDS_TRIGGER_IDE_DISK
        help
index 52694d2..175c424 100644 (file)
@@ -371,10 +371,15 @@ static void md_end_flush(struct bio *bio, int err)
        bio_put(bio);
 }
 
-static void submit_flushes(mddev_t *mddev)
+static void md_submit_flush_data(struct work_struct *ws);
+
+static void submit_flushes(struct work_struct *ws)
 {
+       mddev_t *mddev = container_of(ws, mddev_t, flush_work);
        mdk_rdev_t *rdev;
 
+       INIT_WORK(&mddev->flush_work, md_submit_flush_data);
+       atomic_set(&mddev->flush_pending, 1);
        rcu_read_lock();
        list_for_each_entry_rcu(rdev, &mddev->disks, same_set)
                if (rdev->raid_disk >= 0 &&
@@ -397,6 +402,8 @@ static void submit_flushes(mddev_t *mddev)
                        rdev_dec_pending(rdev, mddev);
                }
        rcu_read_unlock();
+       if (atomic_dec_and_test(&mddev->flush_pending))
+               queue_work(md_wq, &mddev->flush_work);
 }
 
 static void md_submit_flush_data(struct work_struct *ws)
@@ -404,8 +411,6 @@ static void md_submit_flush_data(struct work_struct *ws)
        mddev_t *mddev = container_of(ws, mddev_t, flush_work);
        struct bio *bio = mddev->flush_bio;
 
-       atomic_set(&mddev->flush_pending, 1);
-
        if (bio->bi_size == 0)
                /* an empty barrier - all done */
                bio_endio(bio, 0);
@@ -414,10 +419,9 @@ static void md_submit_flush_data(struct work_struct *ws)
                if (mddev->pers->make_request(mddev, bio))
                        generic_make_request(bio);
        }
-       if (atomic_dec_and_test(&mddev->flush_pending)) {
-               mddev->flush_bio = NULL;
-               wake_up(&mddev->sb_wait);
-       }
+
+       mddev->flush_bio = NULL;
+       wake_up(&mddev->sb_wait);
 }
 
 void md_flush_request(mddev_t *mddev, struct bio *bio)
@@ -429,13 +433,8 @@ void md_flush_request(mddev_t *mddev, struct bio *bio)
        mddev->flush_bio = bio;
        spin_unlock_irq(&mddev->write_lock);
 
-       atomic_set(&mddev->flush_pending, 1);
-       INIT_WORK(&mddev->flush_work, md_submit_flush_data);
-
-       submit_flushes(mddev);
-
-       if (atomic_dec_and_test(&mddev->flush_pending))
-               queue_work(md_wq, &mddev->flush_work);
+       INIT_WORK(&mddev->flush_work, submit_flushes);
+       queue_work(md_wq, &mddev->flush_work);
 }
 EXPORT_SYMBOL(md_flush_request);
 
@@ -5157,7 +5156,7 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
                                PTR_ERR(rdev));
                        return PTR_ERR(rdev);
                }
-               /* set save_raid_disk if appropriate */
+               /* set saved_raid_disk if appropriate */
                if (!mddev->persistent) {
                        if (info->state & (1<<MD_DISK_SYNC)  &&
                            info->raid_disk < mddev->raid_disks)
@@ -5167,7 +5166,10 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
                } else
                        super_types[mddev->major_version].
                                validate_super(mddev, rdev);
-               rdev->saved_raid_disk = rdev->raid_disk;
+               if (test_bit(In_sync, &rdev->flags))
+                       rdev->saved_raid_disk = rdev->raid_disk;
+               else
+                       rdev->saved_raid_disk = -1;
 
                clear_bit(In_sync, &rdev->flags); /* just to be sure */
                if (info->state & (1<<MD_DISK_WRITEMOSTLY))
@@ -6039,9 +6041,8 @@ static int md_thread(void * arg)
                         || kthread_should_stop(),
                         thread->timeout);
 
-               clear_bit(THREAD_WAKEUP, &thread->flags);
-
-               thread->run(thread->mddev);
+               if (test_and_clear_bit(THREAD_WAKEUP, &thread->flags))
+                       thread->run(thread->mddev);
        }
 
        return 0;
index c67aa54..0641674 100644 (file)
@@ -2397,13 +2397,13 @@ static int run(mddev_t *mddev)
        return 0;
 
 out_free_conf:
+       md_unregister_thread(mddev->thread);
        if (conf->r10bio_pool)
                mempool_destroy(conf->r10bio_pool);
        safe_put_page(conf->tmppage);
        kfree(conf->mirrors);
        kfree(conf);
        mddev->private = NULL;
-       md_unregister_thread(mddev->thread);
 out:
        return -EIO;
 }
index 2385e6c..78b0895 100644 (file)
@@ -31,7 +31,7 @@ config MEDIA_TUNER
        select MEDIA_TUNER_TDA9887 if !MEDIA_TUNER_CUSTOMISE
        select MEDIA_TUNER_MC44S803 if !MEDIA_TUNER_CUSTOMISE
 
-menuconfig MEDIA_TUNER_CUSTOMISE
+config MEDIA_TUNER_CUSTOMISE
        bool "Customize analog and hybrid tuner modules to build"
        depends on MEDIA_TUNER
        default y if EMBEDDED
@@ -44,7 +44,8 @@ menuconfig MEDIA_TUNER_CUSTOMISE
 
          If unsure say N.
 
-if MEDIA_TUNER_CUSTOMISE
+menu "Customize TV tuners"
+       visible if MEDIA_TUNER_CUSTOMISE
 
 config MEDIA_TUNER_SIMPLE
        tristate "Simple tuner support"
@@ -185,5 +186,4 @@ config MEDIA_TUNER_TDA18218
        default m if MEDIA_TUNER_CUSTOMISE
        help
          NXP TDA18218 silicon tuner driver.
-
-endif # MEDIA_TUNER_CUSTOMISE
+endmenu
index e9062b0..96b2701 100644 (file)
@@ -12,9 +12,8 @@ config DVB_FE_CUSTOMISE
 
          If unsure say N.
 
-if DVB_FE_CUSTOMISE
-
 menu "Customise DVB Frontends"
+       visible if DVB_FE_CUSTOMISE
 
 comment "Multistandard (satellite) frontends"
        depends on DVB_CORE
@@ -619,5 +618,3 @@ config DVB_DUMMY_FE
        tristate "Dummy frontend driver"
        default n
 endmenu
-
-endif
index 5bf4985..05e832f 100644 (file)
@@ -361,7 +361,7 @@ static int vidioc_s_audio(struct file *file, void *priv,
 
 static const struct v4l2_file_operations rtrack_fops = {
        .owner          = THIS_MODULE,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
 };
 
 static const struct v4l2_ioctl_ops rtrack_ioctl_ops = {
@@ -412,13 +412,6 @@ static int __init rtrack_init(void)
        rt->vdev.release = video_device_release_empty;
        video_set_drvdata(&rt->vdev, rt);
 
-       if (video_register_device(&rt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
-               v4l2_device_unregister(&rt->v4l2_dev);
-               release_region(rt->io, 2);
-               return -EINVAL;
-       }
-       v4l2_info(v4l2_dev, "AIMSlab RadioTrack/RadioReveal card driver.\n");
-
        /* Set up the I/O locking */
 
        mutex_init(&rt->lock);
@@ -430,6 +423,13 @@ static int __init rtrack_init(void)
        sleep_delay(2000000);   /* make sure it's totally down  */
        outb(0xc0, rt->io);             /* steady volume, mute card     */
 
+       if (video_register_device(&rt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+               v4l2_device_unregister(&rt->v4l2_dev);
+               release_region(rt->io, 2);
+               return -EINVAL;
+       }
+       v4l2_info(v4l2_dev, "AIMSlab RadioTrack/RadioReveal card driver.\n");
+
        return 0;
 }
 
index c223113..dd8a6ab 100644 (file)
@@ -324,7 +324,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
 
 static const struct v4l2_file_operations aztech_fops = {
        .owner          = THIS_MODULE,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
 };
 
 static const struct v4l2_ioctl_ops aztech_ioctl_ops = {
@@ -375,6 +375,8 @@ static int __init aztech_init(void)
        az->vdev.ioctl_ops = &aztech_ioctl_ops;
        az->vdev.release = video_device_release_empty;
        video_set_drvdata(&az->vdev, az);
+       /* mute card - prevents noisy bootups */
+       outb(0, az->io);
 
        if (video_register_device(&az->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
                v4l2_device_unregister(v4l2_dev);
@@ -383,8 +385,6 @@ static int __init aztech_init(void)
        }
 
        v4l2_info(v4l2_dev, "Aztech radio card driver v1.00/19990224 rkroll@exploits.org\n");
-       /* mute card - prevents noisy bootups */
-       outb(0, az->io);
        return 0;
 }
 
index b701ea6..bc9ad08 100644 (file)
@@ -328,11 +328,10 @@ static ssize_t cadet_read(struct file *file, char __user *data, size_t count, lo
        unsigned char readbuf[RDS_BUFFER];
        int i = 0;
 
+       mutex_lock(&dev->lock);
        if (dev->rdsstat == 0) {
-               mutex_lock(&dev->lock);
                dev->rdsstat = 1;
                outb(0x80, dev->io);        /* Select RDS fifo */
-               mutex_unlock(&dev->lock);
                init_timer(&dev->readtimer);
                dev->readtimer.function = cadet_handler;
                dev->readtimer.data = (unsigned long)dev;
@@ -340,12 +339,15 @@ static ssize_t cadet_read(struct file *file, char __user *data, size_t count, lo
                add_timer(&dev->readtimer);
        }
        if (dev->rdsin == dev->rdsout) {
+               mutex_unlock(&dev->lock);
                if (file->f_flags & O_NONBLOCK)
                        return -EWOULDBLOCK;
                interruptible_sleep_on(&dev->read_queue);
+               mutex_lock(&dev->lock);
        }
        while (i < count && dev->rdsin != dev->rdsout)
                readbuf[i++] = dev->rdsbuf[dev->rdsout++];
+       mutex_unlock(&dev->lock);
 
        if (copy_to_user(data, readbuf, i))
                return -EFAULT;
@@ -525,9 +527,11 @@ static int cadet_open(struct file *file)
 {
        struct cadet *dev = video_drvdata(file);
 
+       mutex_lock(&dev->lock);
        dev->users++;
        if (1 == dev->users)
                init_waitqueue_head(&dev->read_queue);
+       mutex_unlock(&dev->lock);
        return 0;
 }
 
@@ -535,11 +539,13 @@ static int cadet_release(struct file *file)
 {
        struct cadet *dev = video_drvdata(file);
 
+       mutex_lock(&dev->lock);
        dev->users--;
        if (0 == dev->users) {
                del_timer_sync(&dev->readtimer);
                dev->rdsstat = 0;
        }
+       mutex_unlock(&dev->lock);
        return 0;
 }
 
@@ -559,7 +565,7 @@ static const struct v4l2_file_operations cadet_fops = {
        .open           = cadet_open,
        .release        = cadet_release,
        .read           = cadet_read,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
        .poll           = cadet_poll,
 };
 
index 7903967..28fa85b 100644 (file)
@@ -361,7 +361,7 @@ MODULE_DEVICE_TABLE(pci, gemtek_pci_id);
 
 static const struct v4l2_file_operations gemtek_pci_fops = {
        .owner          = THIS_MODULE,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
 };
 
 static const struct v4l2_ioctl_ops gemtek_pci_ioctl_ops = {
@@ -422,11 +422,11 @@ static int __devinit gemtek_pci_probe(struct pci_dev *pdev, const struct pci_dev
        card->vdev.release = video_device_release_empty;
        video_set_drvdata(&card->vdev, card);
 
+       gemtek_pci_mute(card);
+
        if (video_register_device(&card->vdev, VFL_TYPE_RADIO, nr_radio) < 0)
                goto err_video;
 
-       gemtek_pci_mute(card);
-
        v4l2_info(v4l2_dev, "Gemtek PCI Radio (rev. %d) found at 0x%04x-0x%04x.\n",
                pdev->revision, card->iobase, card->iobase + card->length - 1);
 
index 73985f6..2599364 100644 (file)
@@ -378,7 +378,7 @@ static int gemtek_probe(struct gemtek *gt)
 
 static const struct v4l2_file_operations gemtek_fops = {
        .owner          = THIS_MODULE,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
 };
 
 static int vidioc_querycap(struct file *file, void *priv,
@@ -577,12 +577,6 @@ static int __init gemtek_init(void)
        gt->vdev.release = video_device_release_empty;
        video_set_drvdata(&gt->vdev, gt);
 
-       if (video_register_device(&gt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
-               v4l2_device_unregister(v4l2_dev);
-               release_region(gt->io, 1);
-               return -EBUSY;
-       }
-
        /* Set defaults */
        gt->lastfreq = GEMTEK_LOWFREQ;
        gt->bu2614data = 0;
@@ -590,6 +584,12 @@ static int __init gemtek_init(void)
        if (initmute)
                gemtek_mute(gt);
 
+       if (video_register_device(&gt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+               v4l2_device_unregister(v4l2_dev);
+               release_region(gt->io, 1);
+               return -EBUSY;
+       }
+
        return 0;
 }
 
index 08f1051..6af61bf 100644 (file)
@@ -299,7 +299,7 @@ static int vidioc_s_audio(struct file *file, void *priv,
 
 static const struct v4l2_file_operations maestro_fops = {
        .owner          = THIS_MODULE,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
 };
 
 static const struct v4l2_ioctl_ops maestro_ioctl_ops = {
@@ -383,22 +383,20 @@ static int __devinit maestro_probe(struct pci_dev *pdev,
        dev->vdev.release = video_device_release_empty;
        video_set_drvdata(&dev->vdev, dev);
 
+       if (!radio_power_on(dev)) {
+               retval = -EIO;
+               goto errfr1;
+       }
+
        retval = video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr);
        if (retval) {
                v4l2_err(v4l2_dev, "can't register video device!\n");
                goto errfr1;
        }
 
-       if (!radio_power_on(dev)) {
-               retval = -EIO;
-               goto errunr;
-       }
-
        v4l2_info(v4l2_dev, "version " DRIVER_VERSION "\n");
 
        return 0;
-errunr:
-       video_unregister_device(&dev->vdev);
 errfr1:
        v4l2_device_unregister(v4l2_dev);
 errfr:
index 255d40d..6459a22 100644 (file)
@@ -346,7 +346,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
 
 static const struct v4l2_file_operations maxiradio_fops = {
        .owner          = THIS_MODULE,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
 };
 
 static const struct v4l2_ioctl_ops maxiradio_ioctl_ops = {
index 4ff8854..3fb76e3 100644 (file)
@@ -33,6 +33,7 @@ struct pcm20 {
        unsigned long freq;
        int muted;
        struct snd_miro_aci *aci;
+       struct mutex lock;
 };
 
 static struct pcm20 pcm20_card = {
@@ -72,7 +73,7 @@ static int pcm20_setfreq(struct pcm20 *dev, unsigned long freq)
 
 static const struct v4l2_file_operations pcm20_fops = {
        .owner          = THIS_MODULE,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
 };
 
 static int vidioc_querycap(struct file *file, void *priv,
@@ -229,7 +230,7 @@ static int __init pcm20_init(void)
                return -ENODEV;
        }
        strlcpy(v4l2_dev->name, "miropcm20", sizeof(v4l2_dev->name));
-
+       mutex_init(&dev->lock);
 
        res = v4l2_device_register(NULL, v4l2_dev);
        if (res < 0) {
@@ -242,6 +243,7 @@ static int __init pcm20_init(void)
        dev->vdev.fops = &pcm20_fops;
        dev->vdev.ioctl_ops = &pcm20_ioctl_ops;
        dev->vdev.release = video_device_release_empty;
+       dev->vdev.lock = &dev->lock;
        video_set_drvdata(&dev->vdev, dev);
 
        if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0)
index a79296a..8d6ea59 100644 (file)
@@ -266,7 +266,7 @@ static int vidioc_s_audio(struct file *file, void *priv,
 
 static const struct v4l2_file_operations rtrack2_fops = {
        .owner          = THIS_MODULE,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
 };
 
 static const struct v4l2_ioctl_ops rtrack2_ioctl_ops = {
@@ -315,6 +315,10 @@ static int __init rtrack2_init(void)
        dev->vdev.release = video_device_release_empty;
        video_set_drvdata(&dev->vdev, dev);
 
+       /* mute card - prevents noisy bootups */
+       outb(1, dev->io);
+       dev->muted = 1;
+
        mutex_init(&dev->lock);
        if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
                v4l2_device_unregister(v4l2_dev);
@@ -324,10 +328,6 @@ static int __init rtrack2_init(void)
 
        v4l2_info(v4l2_dev, "AIMSlab Radiotrack II card driver.\n");
 
-       /* mute card - prevents noisy bootups */
-       outb(1, dev->io);
-       dev->muted = 1;
-
        return 0;
 }
 
index 985359d..b5a5f89 100644 (file)
@@ -260,7 +260,7 @@ static int vidioc_s_audio(struct file *file, void *priv,
 
 static const struct v4l2_file_operations fmi_fops = {
        .owner          = THIS_MODULE,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
 };
 
 static const struct v4l2_ioctl_ops fmi_ioctl_ops = {
@@ -382,6 +382,9 @@ static int __init fmi_init(void)
 
        mutex_init(&fmi->lock);
 
+       /* mute card - prevents noisy bootups */
+       fmi_mute(fmi);
+
        if (video_register_device(&fmi->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
                v4l2_device_unregister(v4l2_dev);
                release_region(fmi->io, 2);
@@ -391,8 +394,6 @@ static int __init fmi_init(void)
        }
 
        v4l2_info(v4l2_dev, "card driver at 0x%x\n", fmi->io);
-       /* mute card - prevents noisy bootups */
-       fmi_mute(fmi);
        return 0;
 }
 
index 52c7bbb..dc3f04c 100644 (file)
@@ -376,7 +376,7 @@ static int vidioc_s_audio(struct file *file, void *priv,
 
 static const struct v4l2_file_operations fmr2_fops = {
        .owner          = THIS_MODULE,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
 };
 
 static const struct v4l2_ioctl_ops fmr2_ioctl_ops = {
@@ -424,6 +424,10 @@ static int __init fmr2_init(void)
        fmr2->vdev.release = video_device_release_empty;
        video_set_drvdata(&fmr2->vdev, fmr2);
 
+       /* mute card - prevents noisy bootups */
+       fmr2_mute(fmr2->io);
+       fmr2_product_info(fmr2);
+
        if (video_register_device(&fmr2->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
                v4l2_device_unregister(v4l2_dev);
                release_region(fmr2->io, 2);
@@ -431,11 +435,6 @@ static int __init fmr2_init(void)
        }
 
        v4l2_info(v4l2_dev, "SF16FMR2 radio card driver at 0x%x.\n", fmr2->io);
-       /* mute card - prevents noisy bootups */
-       mutex_lock(&fmr2->lock);
-       fmr2_mute(fmr2->io);
-       fmr2_product_info(fmr2);
-       mutex_unlock(&fmr2->lock);
        debug_print((KERN_DEBUG "card_type %d\n", fmr2->card_type));
        return 0;
 }
index 6a43578..726d367 100644 (file)
@@ -53,7 +53,8 @@ struct radio_si4713_device {
 /* radio_si4713_fops - file operations interface */
 static const struct v4l2_file_operations radio_si4713_fops = {
        .owner          = THIS_MODULE,
-       .ioctl          = video_ioctl2,
+       /* Note: locking is done at the subdev level in the i2c driver. */
+       .unlocked_ioctl = video_ioctl2,
 };
 
 /* Video4Linux Interface */
@@ -291,7 +292,7 @@ static int radio_si4713_pdriver_probe(struct platform_device *pdev)
                goto unregister_v4l2_dev;
        }
 
-       sd = v4l2_i2c_new_subdev_board(&rsdev->v4l2_dev, adapter, NULL,
+       sd = v4l2_i2c_new_subdev_board(&rsdev->v4l2_dev, adapter,
                                        pdata->subdev_board_info, NULL);
        if (!sd) {
                dev_err(&pdev->dev, "Cannot get v4l2 subdevice\n");
index 789d2ec..0e71d81 100644 (file)
@@ -142,7 +142,6 @@ struct tea5764_device {
        struct video_device             *videodev;
        struct tea5764_regs             regs;
        struct mutex                    mutex;
-       int                             users;
 };
 
 /* I2C code related */
@@ -458,41 +457,10 @@ static int vidioc_s_audio(struct file *file, void *priv,
        return 0;
 }
 
-static int tea5764_open(struct file *file)
-{
-       /* Currently we support only one device */
-       struct tea5764_device *radio = video_drvdata(file);
-
-       mutex_lock(&radio->mutex);
-       /* Only exclusive access */
-       if (radio->users) {
-               mutex_unlock(&radio->mutex);
-               return -EBUSY;
-       }
-       radio->users++;
-       mutex_unlock(&radio->mutex);
-       file->private_data = radio;
-       return 0;
-}
-
-static int tea5764_close(struct file *file)
-{
-       struct tea5764_device *radio = video_drvdata(file);
-
-       if (!radio)
-               return -ENODEV;
-       mutex_lock(&radio->mutex);
-       radio->users--;
-       mutex_unlock(&radio->mutex);
-       return 0;
-}
-
 /* File system interface */
 static const struct v4l2_file_operations tea5764_fops = {
        .owner          = THIS_MODULE,
-       .open           = tea5764_open,
-       .release        = tea5764_close,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
 };
 
 static const struct v4l2_ioctl_ops tea5764_ioctl_ops = {
@@ -527,7 +495,7 @@ static int __devinit tea5764_i2c_probe(struct i2c_client *client,
        int ret;
 
        PDEBUG("probe");
-       radio = kmalloc(sizeof(struct tea5764_device), GFP_KERNEL);
+       radio = kzalloc(sizeof(struct tea5764_device), GFP_KERNEL);
        if (!radio)
                return -ENOMEM;
 
@@ -555,12 +523,7 @@ static int __devinit tea5764_i2c_probe(struct i2c_client *client,
 
        i2c_set_clientdata(client, radio);
        video_set_drvdata(radio->videodev, radio);
-
-       ret = video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr);
-       if (ret < 0) {
-               PWARN("Could not register video device!");
-               goto errrel;
-       }
+       radio->videodev->lock = &radio->mutex;
 
        /* initialize and power off the chip */
        tea5764_i2c_read(radio);
@@ -568,6 +531,12 @@ static int __devinit tea5764_i2c_probe(struct i2c_client *client,
        tea5764_mute(radio, 1);
        tea5764_power_down(radio);
 
+       ret = video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr);
+       if (ret < 0) {
+               PWARN("Could not register video device!");
+               goto errrel;
+       }
+
        PINFO("registered.");
        return 0;
 errrel:
index fc1c860..a326639 100644 (file)
@@ -338,7 +338,7 @@ static int vidioc_s_audio(struct file *file, void *priv,
 
 static const struct v4l2_file_operations terratec_fops = {
        .owner          = THIS_MODULE,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
 };
 
 static const struct v4l2_ioctl_ops terratec_ioctl_ops = {
@@ -389,6 +389,9 @@ static int __init terratec_init(void)
 
        mutex_init(&tt->lock);
 
+       /* mute card - prevents noisy bootups */
+       tt_write_vol(tt, 0);
+
        if (video_register_device(&tt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
                v4l2_device_unregister(&tt->v4l2_dev);
                release_region(tt->io, 2);
@@ -396,9 +399,6 @@ static int __init terratec_init(void)
        }
 
        v4l2_info(v4l2_dev, "TERRATEC ActivRadio Standalone card driver.\n");
-
-       /* mute card - prevents noisy bootups */
-       tt_write_vol(tt, 0);
        return 0;
 }
 
index b8bb3ef..a185610 100644 (file)
@@ -34,6 +34,7 @@ struct timbradio {
        struct v4l2_subdev      *sd_dsp;
        struct video_device     video_dev;
        struct v4l2_device      v4l2_dev;
+       struct mutex            lock;
 };
 
 
@@ -142,7 +143,7 @@ static const struct v4l2_ioctl_ops timbradio_ioctl_ops = {
 
 static const struct v4l2_file_operations timbradio_fops = {
        .owner          = THIS_MODULE,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
 };
 
 static int __devinit timbradio_probe(struct platform_device *pdev)
@@ -164,6 +165,7 @@ static int __devinit timbradio_probe(struct platform_device *pdev)
        }
 
        tr->pdata = *pdata;
+       mutex_init(&tr->lock);
 
        strlcpy(tr->video_dev.name, "Timberdale Radio",
                sizeof(tr->video_dev.name));
@@ -171,6 +173,7 @@ static int __devinit timbradio_probe(struct platform_device *pdev)
        tr->video_dev.ioctl_ops = &timbradio_ioctl_ops;
        tr->video_dev.release = video_device_release_empty;
        tr->video_dev.minor = -1;
+       tr->video_dev.lock = &tr->lock;
 
        strlcpy(tr->v4l2_dev.name, DRIVER_NAME, sizeof(tr->v4l2_dev.name));
        err = v4l2_device_register(NULL, &tr->v4l2_dev);
index 9d6dcf8..22fa9cc 100644 (file)
@@ -344,7 +344,7 @@ static int vidioc_s_audio(struct file *file, void *priv,
 
 static const struct v4l2_file_operations trust_fops = {
        .owner          = THIS_MODULE,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
 };
 
 static const struct v4l2_ioctl_ops trust_ioctl_ops = {
@@ -396,14 +396,6 @@ static int __init trust_init(void)
        tr->vdev.release = video_device_release_empty;
        video_set_drvdata(&tr->vdev, tr);
 
-       if (video_register_device(&tr->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
-               v4l2_device_unregister(v4l2_dev);
-               release_region(tr->io, 2);
-               return -EINVAL;
-       }
-
-       v4l2_info(v4l2_dev, "Trust FM Radio card driver v1.0.\n");
-
        write_i2c(tr, 2, TDA7318_ADDR, 0x80);   /* speaker att. LF = 0 dB */
        write_i2c(tr, 2, TDA7318_ADDR, 0xa0);   /* speaker att. RF = 0 dB */
        write_i2c(tr, 2, TDA7318_ADDR, 0xc0);   /* speaker att. LR = 0 dB */
@@ -418,6 +410,14 @@ static int __init trust_init(void)
        /* mute card - prevents noisy bootups */
        tr_setmute(tr, 1);
 
+       if (video_register_device(&tr->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+               v4l2_device_unregister(v4l2_dev);
+               release_region(tr->io, 2);
+               return -EINVAL;
+       }
+
+       v4l2_info(v4l2_dev, "Trust FM Radio card driver v1.0.\n");
+
        return 0;
 }
 
index b1f6305..8dbbf08 100644 (file)
@@ -317,7 +317,7 @@ static int vidioc_log_status(struct file *file, void *priv)
 
 static const struct v4l2_file_operations typhoon_fops = {
        .owner          = THIS_MODULE,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
 };
 
 static const struct v4l2_ioctl_ops typhoon_ioctl_ops = {
@@ -344,18 +344,18 @@ static int __init typhoon_init(void)
 
        strlcpy(v4l2_dev->name, "typhoon", sizeof(v4l2_dev->name));
        dev->io = io;
-       dev->curfreq = dev->mutefreq = mutefreq;
 
        if (dev->io == -1) {
                v4l2_err(v4l2_dev, "You must set an I/O address with io=0x316 or io=0x336\n");
                return -EINVAL;
        }
 
-       if (dev->mutefreq < 87000 || dev->mutefreq > 108500) {
+       if (mutefreq < 87000 || mutefreq > 108500) {
                v4l2_err(v4l2_dev, "You must set a frequency (in kHz) used when muting the card,\n");
                v4l2_err(v4l2_dev, "e.g. with \"mutefreq=87500\" (87000 <= mutefreq <= 108500)\n");
                return -EINVAL;
        }
+       dev->curfreq = dev->mutefreq = mutefreq << 4;
 
        mutex_init(&dev->lock);
        if (!request_region(dev->io, 8, "typhoon")) {
@@ -378,17 +378,17 @@ static int __init typhoon_init(void)
        dev->vdev.ioctl_ops = &typhoon_ioctl_ops;
        dev->vdev.release = video_device_release_empty;
        video_set_drvdata(&dev->vdev, dev);
+
+       /* mute card - prevents noisy bootups */
+       typhoon_mute(dev);
+
        if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
                v4l2_device_unregister(&dev->v4l2_dev);
                release_region(dev->io, 8);
                return -EINVAL;
        }
        v4l2_info(v4l2_dev, "port 0x%x.\n", dev->io);
-       v4l2_info(v4l2_dev, "mute frequency is %lu kHz.\n", dev->mutefreq);
-       dev->mutefreq <<= 4;
-
-       /* mute card - prevents noisy bootups */
-       typhoon_mute(dev);
+       v4l2_info(v4l2_dev, "mute frequency is %lu kHz.\n", mutefreq);
 
        return 0;
 }
index f31eab9..af99c5b 100644 (file)
@@ -377,7 +377,7 @@ static int vidioc_s_audio(struct file *file, void *priv,
 static const struct v4l2_file_operations zoltrix_fops =
 {
        .owner          = THIS_MODULE,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
 };
 
 static const struct v4l2_ioctl_ops zoltrix_ioctl_ops = {
@@ -424,20 +424,6 @@ static int __init zoltrix_init(void)
                return res;
        }
 
-       strlcpy(zol->vdev.name, v4l2_dev->name, sizeof(zol->vdev.name));
-       zol->vdev.v4l2_dev = v4l2_dev;
-       zol->vdev.fops = &zoltrix_fops;
-       zol->vdev.ioctl_ops = &zoltrix_ioctl_ops;
-       zol->vdev.release = video_device_release_empty;
-       video_set_drvdata(&zol->vdev, zol);
-
-       if (video_register_device(&zol->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
-               v4l2_device_unregister(v4l2_dev);
-               release_region(zol->io, 2);
-               return -EINVAL;
-       }
-       v4l2_info(v4l2_dev, "Zoltrix Radio Plus card driver.\n");
-
        mutex_init(&zol->lock);
 
        /* mute card - prevents noisy bootups */
@@ -452,6 +438,20 @@ static int __init zoltrix_init(void)
        zol->curvol = 0;
        zol->stereo = 1;
 
+       strlcpy(zol->vdev.name, v4l2_dev->name, sizeof(zol->vdev.name));
+       zol->vdev.v4l2_dev = v4l2_dev;
+       zol->vdev.fops = &zoltrix_fops;
+       zol->vdev.ioctl_ops = &zoltrix_ioctl_ops;
+       zol->vdev.release = video_device_release_empty;
+       video_set_drvdata(&zol->vdev, zol);
+
+       if (video_register_device(&zol->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+               v4l2_device_unregister(v4l2_dev);
+               release_region(zol->io, 2);
+               return -EINVAL;
+       }
+       v4l2_info(v4l2_dev, "Zoltrix Radio Plus card driver.\n");
+
        return 0;
 }
 
index ac16e81..6830d28 100644 (file)
@@ -112,7 +112,7 @@ config VIDEO_IR_I2C
 #
 
 menu "Encoders/decoders and other helper chips"
-       depends on !VIDEO_HELPER_CHIPS_AUTO
+       visible if !VIDEO_HELPER_CHIPS_AUTO
 
 comment "Audio decoders"
 
index 31e7a12..f989f28 100644 (file)
@@ -712,7 +712,7 @@ static int ar_initialize(struct ar *ar)
 static const struct v4l2_file_operations ar_fops = {
        .owner          = THIS_MODULE,
        .read           = ar_read,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
 };
 
 static const struct v4l2_ioctl_ops ar_ioctl_ops = {
index 0453816..01be89f 100644 (file)
@@ -212,7 +212,7 @@ void au0828_card_setup(struct au0828_dev *dev)
                   be abstracted out if we ever need to support a different
                   demod) */
                sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
-                               NULL, "au8522", 0x8e >> 1, NULL);
+                               "au8522", 0x8e >> 1, NULL);
                if (sd == NULL)
                        printk(KERN_ERR "analog subdev registration failed\n");
        }
@@ -221,7 +221,7 @@ void au0828_card_setup(struct au0828_dev *dev)
        if (dev->board.tuner_type != TUNER_ABSENT) {
                /* Load the tuner module, which does the attach */
                sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
-                               NULL, "tuner", dev->board.tuner_addr, NULL);
+                               "tuner", dev->board.tuner_addr, NULL);
                if (sd == NULL)
                        printk(KERN_ERR "tuner subdev registration fail\n");
 
index 87d8b00..49efcf6 100644 (file)
@@ -3529,7 +3529,7 @@ void __devinit bttv_init_card2(struct bttv *btv)
                struct v4l2_subdev *sd;
 
                sd = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
-                       &btv->c.i2c_adap, NULL, "saa6588", 0, addrs);
+                       &btv->c.i2c_adap, "saa6588", 0, addrs);
                btv->has_saa6588 = (sd != NULL);
        }
 
@@ -3554,7 +3554,7 @@ void __devinit bttv_init_card2(struct bttv *btv)
                };
 
                btv->sd_msp34xx = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
-                       &btv->c.i2c_adap, NULL, "msp3400", 0, addrs);
+                       &btv->c.i2c_adap, "msp3400", 0, addrs);
                if (btv->sd_msp34xx)
                        return;
                goto no_audio;
@@ -3568,7 +3568,7 @@ void __devinit bttv_init_card2(struct bttv *btv)
                };
 
                if (v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
-                               &btv->c.i2c_adap, NULL, "tda7432", 0, addrs))
+                               &btv->c.i2c_adap, "tda7432", 0, addrs))
                        return;
                goto no_audio;
        }
@@ -3576,7 +3576,7 @@ void __devinit bttv_init_card2(struct bttv *btv)
        case 3: {
                /* The user specified that we should probe for tvaudio */
                btv->sd_tvaudio = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
-                       &btv->c.i2c_adap, NULL, "tvaudio", 0, tvaudio_addrs());
+                       &btv->c.i2c_adap, "tvaudio", 0, tvaudio_addrs());
                if (btv->sd_tvaudio)
                        return;
                goto no_audio;
@@ -3596,11 +3596,11 @@ void __devinit bttv_init_card2(struct bttv *btv)
           found is really something else (e.g. a tea6300). */
        if (!bttv_tvcards[btv->c.type].no_msp34xx) {
                btv->sd_msp34xx = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
-                       &btv->c.i2c_adap, NULL, "msp3400",
+                       &btv->c.i2c_adap, "msp3400",
                        0, I2C_ADDRS(I2C_ADDR_MSP3400 >> 1));
        } else if (bttv_tvcards[btv->c.type].msp34xx_alt) {
                btv->sd_msp34xx = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
-                       &btv->c.i2c_adap, NULL, "msp3400",
+                       &btv->c.i2c_adap, "msp3400",
                        0, I2C_ADDRS(I2C_ADDR_MSP3400_ALT >> 1));
        }
 
@@ -3616,13 +3616,13 @@ void __devinit bttv_init_card2(struct bttv *btv)
                };
 
                if (v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
-                               &btv->c.i2c_adap, NULL, "tda7432", 0, addrs))
+                               &btv->c.i2c_adap, "tda7432", 0, addrs))
                        return;
        }
 
        /* Now see if we can find one of the tvaudio devices. */
        btv->sd_tvaudio = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
-               &btv->c.i2c_adap, NULL, "tvaudio", 0, tvaudio_addrs());
+               &btv->c.i2c_adap, "tvaudio", 0, tvaudio_addrs());
        if (btv->sd_tvaudio)
                return;
 
@@ -3646,13 +3646,13 @@ void __devinit bttv_init_tuner(struct bttv *btv)
                /* Load tuner module before issuing tuner config call! */
                if (bttv_tvcards[btv->c.type].has_radio)
                        v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
-                               &btv->c.i2c_adap, NULL, "tuner",
+                               &btv->c.i2c_adap, "tuner",
                                0, v4l2_i2c_tuner_addrs(ADDRS_RADIO));
                v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
-                               &btv->c.i2c_adap, NULL, "tuner",
+                               &btv->c.i2c_adap, "tuner",
                                0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
                v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
-                               &btv->c.i2c_adap, NULL, "tuner",
+                               &btv->c.i2c_adap, "tuner",
                                0, v4l2_i2c_tuner_addrs(ADDRS_TV_WITH_DEMOD));
 
                tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV;
index 935e0c9..c119350 100644 (file)
@@ -860,7 +860,7 @@ static ssize_t qcam_read(struct file *file, char __user *buf,
 
 static const struct v4l2_file_operations qcam_fops = {
        .owner          = THIS_MODULE,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
        .read           = qcam_read,
 };
 
index 6e4b196..24fc009 100644 (file)
@@ -718,7 +718,7 @@ static ssize_t qcam_read(struct file *file, char __user *buf,
 
 static const struct v4l2_file_operations qcam_fops = {
        .owner          = THIS_MODULE,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
        .read           = qcam_read,
 };
 
index 7bc3667..0dfff50 100644 (file)
@@ -1775,7 +1775,7 @@ static const struct v4l2_file_operations cafe_v4l_fops = {
        .read = cafe_v4l_read,
        .poll = cafe_v4l_poll,
        .mmap = cafe_v4l_mmap,
-       .ioctl = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
 };
 
 static const struct v4l2_ioctl_ops cafe_v4l_ioctl_ops = {
@@ -2066,8 +2066,7 @@ static int cafe_pci_probe(struct pci_dev *pdev,
 
        cam->sensor_addr = 0x42;
        cam->sensor = v4l2_i2c_new_subdev_cfg(&cam->v4l2_dev, &cam->i2c_adapter,
-                       "ov7670", "ov7670", 0, &sensor_cfg, cam->sensor_addr,
-                       NULL);
+                       "ov7670", 0, &sensor_cfg, cam->sensor_addr, NULL);
        if (cam->sensor == NULL) {
                ret = -ENODEV;
                goto out_smbus;
index 8f55692..82d195b 100644 (file)
@@ -218,7 +218,13 @@ static int snd_cx18_pcm_capture_close(struct snd_pcm_substream *substream)
 static int snd_cx18_pcm_ioctl(struct snd_pcm_substream *substream,
                     unsigned int cmd, void *arg)
 {
-       return snd_pcm_lib_ioctl(substream, cmd, arg);
+       struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
+       int ret;
+
+       snd_cx18_lock(cxsc);
+       ret = snd_pcm_lib_ioctl(substream, cmd, arg);
+       snd_cx18_unlock(cxsc);
+       return ret;
 }
 
 
index a09caf8..e71a026 100644 (file)
@@ -122,15 +122,15 @@ int cx18_i2c_register(struct cx18 *cx, unsigned idx)
        if (hw == CX18_HW_TUNER) {
                /* special tuner group handling */
                sd = v4l2_i2c_new_subdev(&cx->v4l2_dev,
-                               adap, NULL, type, 0, cx->card_i2c->radio);
+                               adap, type, 0, cx->card_i2c->radio);
                if (sd != NULL)
                        sd->grp_id = hw;
                sd = v4l2_i2c_new_subdev(&cx->v4l2_dev,
-                               adap, NULL, type, 0, cx->card_i2c->demod);
+                               adap, type, 0, cx->card_i2c->demod);
                if (sd != NULL)
                        sd->grp_id = hw;
                sd = v4l2_i2c_new_subdev(&cx->v4l2_dev,
-                               adap, NULL, type, 0, cx->card_i2c->tv);
+                               adap, type, 0, cx->card_i2c->tv);
                if (sd != NULL)
                        sd->grp_id = hw;
                return sd != NULL ? 0 : -1;
@@ -144,7 +144,7 @@ int cx18_i2c_register(struct cx18 *cx, unsigned idx)
                return -1;
 
        /* It's an I2C device other than an analog tuner or IR chip */
-       sd = v4l2_i2c_new_subdev(&cx->v4l2_dev, adap, NULL, type, hw_addrs[idx],
+       sd = v4l2_i2c_new_subdev(&cx->v4l2_dev, adap, type, hw_addrs[idx],
                                 NULL);
        if (sd != NULL)
                sd->grp_id = hw;
index 9045f1e..ab461e2 100644 (file)
@@ -41,7 +41,7 @@ static struct v4l2_file_operations cx18_v4l2_enc_fops = {
        .read = cx18_v4l2_read,
        .open = cx18_v4l2_open,
        /* FIXME change to video_ioctl2 if serialization lock can be removed */
-       .ioctl = cx18_v4l2_ioctl,
+       .unlocked_ioctl = cx18_v4l2_ioctl,
        .release = cx18_v4l2_close,
        .poll = cx18_v4l2_enc_poll,
 };
index 56c2d81..2c78d18 100644 (file)
@@ -560,7 +560,7 @@ void cx231xx_card_setup(struct cx231xx *dev)
        if (dev->board.decoder == CX231XX_AVDECODER) {
                dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev,
                                        &dev->i2c_bus[0].i2c_adap,
-                                       NULL, "cx25840", 0x88 >> 1, NULL);
+                                       "cx25840", 0x88 >> 1, NULL);
                if (dev->sd_cx25840 == NULL)
                        cx231xx_info("cx25840 subdev registration failure\n");
                cx25840_call(dev, core, load_fw);
@@ -571,7 +571,7 @@ void cx231xx_card_setup(struct cx231xx *dev)
        if (dev->board.tuner_type != TUNER_ABSENT) {
                dev->sd_tuner = v4l2_i2c_new_subdev(&dev->v4l2_dev,
                                                    &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap,
-                                                   NULL, "tuner",
+                                                   "tuner",
                                                    dev->tuner_addr, NULL);
                if (dev->sd_tuner == NULL)
                        cx231xx_info("tuner subdev registration failure\n");
index db05400..8861309 100644 (file)
@@ -1247,7 +1247,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
        case CX23885_BOARD_LEADTEK_WINFAST_PXTV1200:
                dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev,
                                &dev->i2c_bus[2].i2c_adap,
-                               NULL, "cx25840", 0x88 >> 1, NULL);
+                               "cx25840", 0x88 >> 1, NULL);
                if (dev->sd_cx25840) {
                        dev->sd_cx25840->grp_id = CX23885_HW_AV_CORE;
                        v4l2_subdev_call(dev->sd_cx25840, core, load_fw);
index 3cc9f46..8b2fb8a 100644 (file)
@@ -1507,10 +1507,10 @@ int cx23885_video_register(struct cx23885_dev *dev)
                if (dev->tuner_addr)
                        sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
                                &dev->i2c_bus[1].i2c_adap,
-                               NULL, "tuner", dev->tuner_addr, NULL);
+                               "tuner", dev->tuner_addr, NULL);
                else
                        sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
-                               &dev->i2c_bus[1].i2c_adap, NULL,
+                               &dev->i2c_bus[1].i2c_adap,
                                "tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_TV));
                if (sd) {
                        struct tuner_setup tun_setup;
index b26fcba..9b9e169 100644 (file)
@@ -3515,19 +3515,18 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr)
                   later code configures a tea5767.
                 */
                v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap,
-                               NULL, "tuner",
-                               0, v4l2_i2c_tuner_addrs(ADDRS_RADIO));
+                               "tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_RADIO));
                if (has_demod)
                        v4l2_i2c_new_subdev(&core->v4l2_dev,
-                               &core->i2c_adap, NULL, "tuner",
+                               &core->i2c_adap, "tuner",
                                0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
                if (core->board.tuner_addr == ADDR_UNSET) {
                        v4l2_i2c_new_subdev(&core->v4l2_dev,
-                               &core->i2c_adap, NULL, "tuner",
+                               &core->i2c_adap, "tuner",
                                0, has_demod ? tv_addrs + 4 : tv_addrs);
                } else {
                        v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap,
-                               NULL, "tuner", core->board.tuner_addr, NULL);
+                               "tuner", core->board.tuner_addr, NULL);
                }
        }
 
index 88b5119..62cea95 100644 (file)
@@ -1895,14 +1895,13 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
 
        if (core->board.audio_chip == V4L2_IDENT_WM8775)
                v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap,
-                               NULL, "wm8775", 0x36 >> 1, NULL);
+                               "wm8775", 0x36 >> 1, NULL);
 
        if (core->board.audio_chip == V4L2_IDENT_TVAUDIO) {
                /* This probes for a tda9874 as is used on some
                   Pixelview Ultra boards. */
-               v4l2_i2c_new_subdev(&core->v4l2_dev,
-                               &core->i2c_adap,
-                               NULL, "tvaudio", 0, I2C_ADDRS(0xb0 >> 1));
+               v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap,
+                               "tvaudio", 0, I2C_ADDRS(0xb0 >> 1));
        }
 
        switch (core->boardnr) {
index d8e38cc..7333a9b 100644 (file)
@@ -1986,7 +1986,6 @@ static __init int vpfe_probe(struct platform_device *pdev)
                vpfe_dev->sd[i] =
                        v4l2_i2c_new_subdev_board(&vpfe_dev->v4l2_dev,
                                                  i2c_adap,
-                                                 NULL,
                                                  &sdinfo->board_info,
                                                  NULL);
                if (vpfe_dev->sd[i]) {
index 6ac6acd..193abab 100644 (file)
@@ -2013,7 +2013,6 @@ static __init int vpif_probe(struct platform_device *pdev)
                vpif_obj.sd[i] =
                        v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev,
                                                  i2c_adap,
-                                                 NULL,
                                                  &subdevdata->board_info,
                                                  NULL);
 
index 685f6a6..412c65d 100644 (file)
@@ -1553,7 +1553,7 @@ static __init int vpif_probe(struct platform_device *pdev)
 
        for (i = 0; i < subdev_count; i++) {
                vpif_obj.sd[i] = v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev,
-                                               i2c_adap, NULL,
+                                               i2c_adap,
                                                &subdevdata[i].board_info,
                                                NULL);
                if (!vpif_obj.sd[i]) {
index 5485923..f7e9168 100644 (file)
@@ -2554,39 +2554,39 @@ void em28xx_card_setup(struct em28xx *dev)
        /* request some modules */
        if (dev->board.has_msp34xx)
                v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
-                       NULL, "msp3400", 0, msp3400_addrs);
+                       "msp3400", 0, msp3400_addrs);
 
        if (dev->board.decoder == EM28XX_SAA711X)
                v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
-                       NULL, "saa7115_auto", 0, saa711x_addrs);
+                       "saa7115_auto", 0, saa711x_addrs);
 
        if (dev->board.decoder == EM28XX_TVP5150)
                v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
-                       NULL, "tvp5150", 0, tvp5150_addrs);
+                       "tvp5150", 0, tvp5150_addrs);
 
        if (dev->em28xx_sensor == EM28XX_MT9V011) {
                struct v4l2_subdev *sd;
 
                sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
-                        &dev->i2c_adap, NULL, "mt9v011", 0, mt9v011_addrs);
+                        &dev->i2c_adap, "mt9v011", 0, mt9v011_addrs);
                v4l2_subdev_call(sd, core, s_config, 0, &dev->sensor_xtal);
        }
 
 
        if (dev->board.adecoder == EM28XX_TVAUDIO)
                v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
-                       NULL, "tvaudio", dev->board.tvaudio_addr, NULL);
+                       "tvaudio", dev->board.tvaudio_addr, NULL);
 
        if (dev->board.tuner_type != TUNER_ABSENT) {
                int has_demod = (dev->tda9887_conf & TDA9887_PRESENT);
 
                if (dev->board.radio.type)
                        v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
-                               NULL, "tuner", dev->board.radio_addr, NULL);
+                               "tuner", dev->board.radio_addr, NULL);
 
                if (has_demod)
                        v4l2_i2c_new_subdev(&dev->v4l2_dev,
-                               &dev->i2c_adap, NULL, "tuner",
+                               &dev->i2c_adap, "tuner",
                                0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
                if (dev->tuner_addr == 0) {
                        enum v4l2_i2c_tuner_type type =
@@ -2594,14 +2594,14 @@ void em28xx_card_setup(struct em28xx *dev)
                        struct v4l2_subdev *sd;
 
                        sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
-                               &dev->i2c_adap, NULL, "tuner",
+                               &dev->i2c_adap, "tuner",
                                0, v4l2_i2c_tuner_addrs(type));
 
                        if (sd)
                                dev->tuner_addr = v4l2_i2c_subdev_addr(sd);
                } else {
                        v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
-                               NULL, "tuner", dev->tuner_addr, NULL);
+                               "tuner", dev->tuner_addr, NULL);
                }
        }
 
index a5cfc76..bb16409 100644 (file)
@@ -2530,7 +2530,7 @@ static const struct v4l2_file_operations et61x251_fops = {
        .owner = THIS_MODULE,
        .open =    et61x251_open,
        .release = et61x251_release,
-       .ioctl =   et61x251_ioctl,
+       .unlocked_ioctl =   et61x251_ioctl,
        .read =    et61x251_read,
        .poll =    et61x251_poll,
        .mmap =    et61x251_mmap,
index 9a075d8..b8faff2 100644 (file)
@@ -1486,7 +1486,7 @@ static int __devinit viu_of_probe(struct platform_device *op,
 
        ad = i2c_get_adapter(0);
        viu_dev->decoder = v4l2_i2c_new_subdev(&viu_dev->v4l2_dev, ad,
-                       NULL, "saa7113", VIU_VIDEO_DECODER_ADDR, NULL);
+                       "saa7113", VIU_VIDEO_DECODER_ADDR, NULL);
 
        viu_dev->vidq.timeout.function = viu_vid_timeout;
        viu_dev->vidq.timeout.data     = (unsigned long)viu_dev;
index 9e8039a..665191c 100644 (file)
@@ -239,19 +239,16 @@ int ivtv_i2c_register(struct ivtv *itv, unsigned idx)
                return -1;
        if (hw == IVTV_HW_TUNER) {
                /* special tuner handling */
-               sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
-                               adap, NULL, type,
-                               0, itv->card_i2c->radio);
+               sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, adap, type, 0,
+                               itv->card_i2c->radio);
                if (sd)
                        sd->grp_id = 1 << idx;
-               sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
-                               adap, NULL, type,
-                               0, itv->card_i2c->demod);
+               sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, adap, type, 0,
+                               itv->card_i2c->demod);
                if (sd)
                        sd->grp_id = 1 << idx;
-               sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
-                               adap, NULL, type,
-                               0, itv->card_i2c->tv);
+               sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, adap, type, 0,
+                               itv->card_i2c->tv);
                if (sd)
                        sd->grp_id = 1 << idx;
                return sd ? 0 : -1;
@@ -267,17 +264,16 @@ int ivtv_i2c_register(struct ivtv *itv, unsigned idx)
        /* It's an I2C device other than an analog tuner or IR chip */
        if (hw == IVTV_HW_UPD64031A || hw == IVTV_HW_UPD6408X) {
                sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
-                               adap, NULL, type, 0, I2C_ADDRS(hw_addrs[idx]));
+                               adap, type, 0, I2C_ADDRS(hw_addrs[idx]));
        } else if (hw == IVTV_HW_CX25840) {
                struct cx25840_platform_data pdata;
 
                pdata.pvr150_workaround = itv->pvr150_workaround;
                sd = v4l2_i2c_new_subdev_cfg(&itv->v4l2_dev,
-                               adap, NULL, type, 0, &pdata, hw_addrs[idx],
-                               NULL);
+                               adap, type, 0, &pdata, hw_addrs[idx], NULL);
        } else {
                sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
-                               adap, NULL, type, hw_addrs[idx], NULL);
+                               adap, type, hw_addrs[idx], NULL);
        }
        if (sd)
                sd->grp_id = 1 << idx;
index 2be23bc..48d2c24 100644 (file)
@@ -1659,7 +1659,7 @@ static const struct v4l2_file_operations meye_fops = {
        .open           = meye_open,
        .release        = meye_release,
        .mmap           = meye_mmap,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
        .poll           = meye_poll,
 };
 
@@ -1831,12 +1831,6 @@ static int __devinit meye_probe(struct pci_dev *pcidev,
        msleep(1);
        mchip_set(MCHIP_MM_INTA, MCHIP_MM_INTA_HIC_1_MASK);
 
-       if (video_register_device(meye.vdev, VFL_TYPE_GRABBER,
-                                 video_nr) < 0) {
-               v4l2_err(v4l2_dev, "video_register_device failed\n");
-               goto outvideoreg;
-       }
-
        mutex_init(&meye.lock);
        init_waitqueue_head(&meye.proc_list);
        meye.brightness = 32 << 10;
@@ -1858,6 +1852,12 @@ static int __devinit meye_probe(struct pci_dev *pcidev,
        sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAPICTURE, 0);
        sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAAGC, 48);
 
+       if (video_register_device(meye.vdev, VFL_TYPE_GRABBER,
+                                 video_nr) < 0) {
+               v4l2_err(v4l2_dev, "video_register_device failed\n");
+               goto outvideoreg;
+       }
+
        v4l2_info(v4l2_dev, "Motion Eye Camera Driver v%s.\n",
               MEYE_DRIVER_VERSION);
        v4l2_info(v4l2_dev, "mchip KL5A72002 rev. %d, base %lx, irq %d\n",
index 94ba698..4e8fd96 100644 (file)
@@ -185,17 +185,17 @@ static int mxb_probe(struct saa7146_dev *dev)
        }
 
        mxb->saa7111a = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
-                       NULL, "saa7111", I2C_SAA7111A, NULL);
+                       "saa7111", I2C_SAA7111A, NULL);
        mxb->tea6420_1 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
-                       NULL, "tea6420", I2C_TEA6420_1, NULL);
+                       "tea6420", I2C_TEA6420_1, NULL);
        mxb->tea6420_2 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
-                       NULL, "tea6420", I2C_TEA6420_2, NULL);
+                       "tea6420", I2C_TEA6420_2, NULL);
        mxb->tea6415c = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
-                       NULL, "tea6415c", I2C_TEA6415C, NULL);
+                       "tea6415c", I2C_TEA6415C, NULL);
        mxb->tda9840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
-                       NULL, "tda9840", I2C_TDA9840, NULL);
+                       "tda9840", I2C_TDA9840, NULL);
        mxb->tuner = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
-                       NULL, "tuner", I2C_TUNER, NULL);
+                       "tuner", I2C_TUNER, NULL);
 
        /* check if all devices are present */
        if (!mxb->tea6420_1 || !mxb->tea6420_2 || !mxb->tea6415c ||
index 7129b50..7551907 100644 (file)
@@ -932,7 +932,7 @@ static ssize_t pms_read(struct file *file, char __user *buf,
 
 static const struct v4l2_file_operations pms_fops = {
        .owner          = THIS_MODULE,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
        .read           = pms_read,
 };
 
index bef2027..66ad516 100644 (file)
@@ -2088,16 +2088,14 @@ static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw,
                           " Setting up with specified i2c address 0x%x",
                           mid, i2caddr[0]);
                sd = v4l2_i2c_new_subdev(&hdw->v4l2_dev, &hdw->i2c_adap,
-                                        NULL, fname,
-                                        i2caddr[0], NULL);
+                                        fname, i2caddr[0], NULL);
        } else {
                pvr2_trace(PVR2_TRACE_INIT,
                           "Module ID %u:"
                           " Setting up with address probe list",
                           mid);
                sd = v4l2_i2c_new_subdev(&hdw->v4l2_dev, &hdw->i2c_adap,
-                                               NULL, fname,
-                                               0, i2caddr);
+                                        fname, 0, i2caddr);
        }
 
        if (!sd) {
index e8f13d3..1b93207 100644 (file)
@@ -44,7 +44,7 @@ static struct v4l2_subdev *fimc_subdev_register(struct fimc_dev *fimc,
                return ERR_PTR(-ENOMEM);
 
        sd = v4l2_i2c_new_subdev_board(&vid_cap->v4l2_dev, i2c_adap,
-                                      MODULE_NAME, isp_info->board_info, NULL);
+                                      isp_info->board_info, NULL);
        if (!sd) {
                v4l2_err(&vid_cap->v4l2_dev, "failed to acquire subdev\n");
                return NULL;
index 0911cb5..1d4d0a4 100644 (file)
@@ -7551,22 +7551,22 @@ int saa7134_board_init2(struct saa7134_dev *dev)
                   so we do not need to probe for a radio tuner device. */
                if (dev->radio_type != UNSET)
                        v4l2_i2c_new_subdev(&dev->v4l2_dev,
-                               &dev->i2c_adap, NULL, "tuner",
+                               &dev->i2c_adap, "tuner",
                                dev->radio_addr, NULL);
                if (has_demod)
                        v4l2_i2c_new_subdev(&dev->v4l2_dev,
-                               &dev->i2c_adap, NULL, "tuner",
+                               &dev->i2c_adap, "tuner",
                                0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
                if (dev->tuner_addr == ADDR_UNSET) {
                        enum v4l2_i2c_tuner_type type =
                                has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;
 
                        v4l2_i2c_new_subdev(&dev->v4l2_dev,
-                               &dev->i2c_adap, NULL, "tuner",
+                               &dev->i2c_adap, "tuner",
                                0, v4l2_i2c_tuner_addrs(type));
                } else {
                        v4l2_i2c_new_subdev(&dev->v4l2_dev,
-                               &dev->i2c_adap, NULL, "tuner",
+                               &dev->i2c_adap, "tuner",
                                dev->tuner_addr, NULL);
                }
        }
index 764d7d2..756a278 100644 (file)
@@ -991,7 +991,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
        if (card_is_empress(dev)) {
                struct v4l2_subdev *sd =
                        v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
-                               NULL, "saa6752hs",
+                               "saa6752hs",
                                saa7134_boards[dev->board].empress_addr, NULL);
 
                if (sd)
@@ -1002,7 +1002,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
                struct v4l2_subdev *sd;
 
                sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
-                               &dev->i2c_adap, NULL, "saa6588",
+                               &dev->i2c_adap, "saa6588",
                                0, I2C_ADDRS(saa7134_boards[dev->board].rds_addr));
                if (sd) {
                        printk(KERN_INFO "%s: found RDS decoder\n", dev->name);
index 0f49061..07cf0c6 100644 (file)
@@ -75,6 +75,7 @@ struct sh_vou_device {
        int pix_idx;
        struct videobuf_buffer *active;
        enum sh_vou_status status;
+       struct mutex fop_lock;
 };
 
 struct sh_vou_file {
@@ -235,7 +236,7 @@ static void free_buffer(struct videobuf_queue *vq, struct videobuf_buffer *vb)
        vb->state = VIDEOBUF_NEEDS_INIT;
 }
 
-/* Locking: caller holds vq->vb_lock mutex */
+/* Locking: caller holds fop_lock mutex */
 static int sh_vou_buf_setup(struct videobuf_queue *vq, unsigned int *count,
                            unsigned int *size)
 {
@@ -257,7 +258,7 @@ static int sh_vou_buf_setup(struct videobuf_queue *vq, unsigned int *count,
        return 0;
 }
 
-/* Locking: caller holds vq->vb_lock mutex */
+/* Locking: caller holds fop_lock mutex */
 static int sh_vou_buf_prepare(struct videobuf_queue *vq,
                              struct videobuf_buffer *vb,
                              enum v4l2_field field)
@@ -306,7 +307,7 @@ static int sh_vou_buf_prepare(struct videobuf_queue *vq,
        return 0;
 }
 
-/* Locking: caller holds vq->vb_lock mutex and vq->irqlock spinlock */
+/* Locking: caller holds fop_lock mutex and vq->irqlock spinlock */
 static void sh_vou_buf_queue(struct videobuf_queue *vq,
                             struct videobuf_buffer *vb)
 {
@@ -1190,7 +1191,7 @@ static int sh_vou_open(struct file *file)
                                       V4L2_BUF_TYPE_VIDEO_OUTPUT,
                                       V4L2_FIELD_NONE,
                                       sizeof(struct videobuf_buffer), vdev,
-                                      NULL);
+                                      &vou_dev->fop_lock);
 
        return 0;
 }
@@ -1292,7 +1293,7 @@ static const struct v4l2_file_operations sh_vou_fops = {
        .owner          = THIS_MODULE,
        .open           = sh_vou_open,
        .release        = sh_vou_release,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
        .mmap           = sh_vou_mmap,
        .poll           = sh_vou_poll,
 };
@@ -1331,6 +1332,7 @@ static int __devinit sh_vou_probe(struct platform_device *pdev)
 
        INIT_LIST_HEAD(&vou_dev->queue);
        spin_lock_init(&vou_dev->lock);
+       mutex_init(&vou_dev->fop_lock);
        atomic_set(&vou_dev->use_count, 0);
        vou_dev->pdata = vou_pdata;
        vou_dev->status = SH_VOU_IDLE;
@@ -1388,6 +1390,7 @@ static int __devinit sh_vou_probe(struct platform_device *pdev)
                vdev->tvnorms |= V4L2_STD_PAL;
        vdev->v4l2_dev = &vou_dev->v4l2_dev;
        vdev->release = video_device_release;
+       vdev->lock = &vou_dev->fop_lock;
 
        vou_dev->vdev = vdev;
        video_set_drvdata(vdev, vou_dev);
@@ -1406,7 +1409,7 @@ static int __devinit sh_vou_probe(struct platform_device *pdev)
                goto ereset;
 
        subdev = v4l2_i2c_new_subdev_board(&vou_dev->v4l2_dev, i2c_adap,
-                       NULL, vou_pdata->board_info, NULL);
+                       vou_pdata->board_info, NULL);
        if (!subdev) {
                ret = -ENOMEM;
                goto ei2cnd;
index 28e19da..f49fbfb 100644 (file)
@@ -3238,7 +3238,7 @@ static const struct v4l2_file_operations sn9c102_fops = {
        .owner = THIS_MODULE,
        .open = sn9c102_open,
        .release = sn9c102_release,
-       .ioctl = sn9c102_ioctl,
+       .unlocked_ioctl = sn9c102_ioctl,
        .read = sn9c102_read,
        .poll = sn9c102_poll,
        .mmap = sn9c102_mmap,
index 43848a7..335120c 100644 (file)
@@ -896,7 +896,7 @@ static int soc_camera_init_i2c(struct soc_camera_device *icd,
        icl->board_info->platform_data = icd;
 
        subdev = v4l2_i2c_new_subdev_board(&ici->v4l2_dev, adap,
-                               NULL, icl->board_info, NULL);
+                               icl->board_info, NULL);
        if (!subdev)
                goto ei2cnd;
 
index e3bbae2..81dd53b 100644 (file)
@@ -251,7 +251,7 @@ int usbvision_i2c_register(struct usb_usbvision *usbvision)
                   hit-and-miss. */
                mdelay(10);
                v4l2_i2c_new_subdev(&usbvision->v4l2_dev,
-                               &usbvision->i2c_adap, NULL,
+                               &usbvision->i2c_adap,
                                "saa7115_auto", 0, saa711x_addrs);
                break;
        }
@@ -261,14 +261,14 @@ int usbvision_i2c_register(struct usb_usbvision *usbvision)
                struct tuner_setup tun_setup;
 
                sd = v4l2_i2c_new_subdev(&usbvision->v4l2_dev,
-                               &usbvision->i2c_adap, NULL,
+                               &usbvision->i2c_adap,
                                "tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
                /* depending on whether we found a demod or not, select
                   the tuner type. */
                type = sd ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;
 
                sd = v4l2_i2c_new_subdev(&usbvision->v4l2_dev,
-                               &usbvision->i2c_adap, NULL,
+                               &usbvision->i2c_adap,
                                "tuner", 0, v4l2_i2c_tuner_addrs(type));
 
                if (sd == NULL)
index f169f77..59f8a9a 100644 (file)
@@ -785,7 +785,7 @@ static void __uvc_find_control(struct uvc_entity *entity, __u32 v4l2_id,
        }
 }
 
-struct uvc_control *uvc_find_control(struct uvc_video_chain *chain,
+static struct uvc_control *uvc_find_control(struct uvc_video_chain *chain,
        __u32 v4l2_id, struct uvc_control_mapping **mapping)
 {
        struct uvc_control *ctrl = NULL;
@@ -944,6 +944,52 @@ done:
        return ret;
 }
 
+/*
+ * Mapping V4L2 controls to UVC controls can be straighforward if done well.
+ * Most of the UVC controls exist in V4L2, and can be mapped directly. Some
+ * must be grouped (for instance the Red Balance, Blue Balance and Do White
+ * Balance V4L2 controls use the White Balance Component UVC control) or
+ * otherwise translated. The approach we take here is to use a translation
+ * table for the controls that can be mapped directly, and handle the others
+ * manually.
+ */
+int uvc_query_v4l2_menu(struct uvc_video_chain *chain,
+       struct v4l2_querymenu *query_menu)
+{
+       struct uvc_menu_info *menu_info;
+       struct uvc_control_mapping *mapping;
+       struct uvc_control *ctrl;
+       u32 index = query_menu->index;
+       u32 id = query_menu->id;
+       int ret;
+
+       memset(query_menu, 0, sizeof(*query_menu));
+       query_menu->id = id;
+       query_menu->index = index;
+
+       ret = mutex_lock_interruptible(&chain->ctrl_mutex);
+       if (ret < 0)
+               return -ERESTARTSYS;
+
+       ctrl = uvc_find_control(chain, query_menu->id, &mapping);
+       if (ctrl == NULL || mapping->v4l2_type != V4L2_CTRL_TYPE_MENU) {
+               ret = -EINVAL;
+               goto done;
+       }
+
+       if (query_menu->index >= mapping->menu_count) {
+               ret = -EINVAL;
+               goto done;
+       }
+
+       menu_info = &mapping->menu_info[query_menu->index];
+       strlcpy(query_menu->name, menu_info->name, sizeof query_menu->name);
+
+done:
+       mutex_unlock(&chain->ctrl_mutex);
+       return ret;
+}
+
 
 /* --------------------------------------------------------------------------
  * Control transactions
index ed6d544..f14581b 100644 (file)
@@ -89,6 +89,39 @@ void uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type,
        queue->type = type;
 }
 
+/*
+ * Free the video buffers.
+ *
+ * This function must be called with the queue lock held.
+ */
+static int __uvc_free_buffers(struct uvc_video_queue *queue)
+{
+       unsigned int i;
+
+       for (i = 0; i < queue->count; ++i) {
+               if (queue->buffer[i].vma_use_count != 0)
+                       return -EBUSY;
+       }
+
+       if (queue->count) {
+               vfree(queue->mem);
+               queue->count = 0;
+       }
+
+       return 0;
+}
+
+int uvc_free_buffers(struct uvc_video_queue *queue)
+{
+       int ret;
+
+       mutex_lock(&queue->mutex);
+       ret = __uvc_free_buffers(queue);
+       mutex_unlock(&queue->mutex);
+
+       return ret;
+}
+
 /*
  * Allocate the video buffers.
  *
@@ -110,7 +143,7 @@ int uvc_alloc_buffers(struct uvc_video_queue *queue, unsigned int nbuffers,
 
        mutex_lock(&queue->mutex);
 
-       if ((ret = uvc_free_buffers(queue)) < 0)
+       if ((ret = __uvc_free_buffers(queue)) < 0)
                goto done;
 
        /* Bail out if no buffers should be allocated. */
@@ -151,28 +184,6 @@ done:
        return ret;
 }
 
-/*
- * Free the video buffers.
- *
- * This function must be called with the queue lock held.
- */
-int uvc_free_buffers(struct uvc_video_queue *queue)
-{
-       unsigned int i;
-
-       for (i = 0; i < queue->count; ++i) {
-               if (queue->buffer[i].vma_use_count != 0)
-                       return -EBUSY;
-       }
-
-       if (queue->count) {
-               vfree(queue->mem);
-               queue->count = 0;
-       }
-
-       return 0;
-}
-
 /*
  * Check if buffers have been allocated.
  */
@@ -368,6 +379,82 @@ done:
        return ret;
 }
 
+/*
+ * VMA operations.
+ */
+static void uvc_vm_open(struct vm_area_struct *vma)
+{
+       struct uvc_buffer *buffer = vma->vm_private_data;
+       buffer->vma_use_count++;
+}
+
+static void uvc_vm_close(struct vm_area_struct *vma)
+{
+       struct uvc_buffer *buffer = vma->vm_private_data;
+       buffer->vma_use_count--;
+}
+
+static const struct vm_operations_struct uvc_vm_ops = {
+       .open           = uvc_vm_open,
+       .close          = uvc_vm_close,
+};
+
+/*
+ * Memory-map a video buffer.
+ *
+ * This function implements video buffers memory mapping and is intended to be
+ * used by the device mmap handler.
+ */
+int uvc_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma)
+{
+       struct uvc_buffer *uninitialized_var(buffer);
+       struct page *page;
+       unsigned long addr, start, size;
+       unsigned int i;
+       int ret = 0;
+
+       start = vma->vm_start;
+       size = vma->vm_end - vma->vm_start;
+
+       mutex_lock(&queue->mutex);
+
+       for (i = 0; i < queue->count; ++i) {
+               buffer = &queue->buffer[i];
+               if ((buffer->buf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff)
+                       break;
+       }
+
+       if (i == queue->count || size != queue->buf_size) {
+               ret = -EINVAL;
+               goto done;
+       }
+
+       /*
+        * VM_IO marks the area as being an mmaped region for I/O to a
+        * device. It also prevents the region from being core dumped.
+        */
+       vma->vm_flags |= VM_IO;
+
+       addr = (unsigned long)queue->mem + buffer->buf.m.offset;
+       while (size > 0) {
+               page = vmalloc_to_page((void *)addr);
+               if ((ret = vm_insert_page(vma, start, page)) < 0)
+                       goto done;
+
+               start += PAGE_SIZE;
+               addr += PAGE_SIZE;
+               size -= PAGE_SIZE;
+       }
+
+       vma->vm_ops = &uvc_vm_ops;
+       vma->vm_private_data = buffer;
+       uvc_vm_open(vma);
+
+done:
+       mutex_unlock(&queue->mutex);
+       return ret;
+}
+
 /*
  * Poll the video queue.
  *
index 6d15de9..8cf61e8 100644 (file)
@@ -100,40 +100,6 @@ done:
  * V4L2 interface
  */
 
-/*
- * Mapping V4L2 controls to UVC controls can be straighforward if done well.
- * Most of the UVC controls exist in V4L2, and can be mapped directly. Some
- * must be grouped (for instance the Red Balance, Blue Balance and Do White
- * Balance V4L2 controls use the White Balance Component UVC control) or
- * otherwise translated. The approach we take here is to use a translation
- * table for the controls that can be mapped directly, and handle the others
- * manually.
- */
-static int uvc_v4l2_query_menu(struct uvc_video_chain *chain,
-       struct v4l2_querymenu *query_menu)
-{
-       struct uvc_menu_info *menu_info;
-       struct uvc_control_mapping *mapping;
-       struct uvc_control *ctrl;
-       u32 index = query_menu->index;
-       u32 id = query_menu->id;
-
-       ctrl = uvc_find_control(chain, query_menu->id, &mapping);
-       if (ctrl == NULL || mapping->v4l2_type != V4L2_CTRL_TYPE_MENU)
-               return -EINVAL;
-
-       if (query_menu->index >= mapping->menu_count)
-               return -EINVAL;
-
-       memset(query_menu, 0, sizeof(*query_menu));
-       query_menu->id = id;
-       query_menu->index = index;
-
-       menu_info = &mapping->menu_info[query_menu->index];
-       strlcpy(query_menu->name, menu_info->name, sizeof query_menu->name);
-       return 0;
-}
-
 /*
  * Find the frame interval closest to the requested frame interval for the
  * given frame format and size. This should be done by the device as part of
@@ -260,12 +226,14 @@ static int uvc_v4l2_try_format(struct uvc_streaming *stream,
         * developers test their webcams with the Linux driver as well as with
         * the Windows driver).
         */
+       mutex_lock(&stream->mutex);
        if (stream->dev->quirks & UVC_QUIRK_PROBE_EXTRAFIELDS)
                probe->dwMaxVideoFrameSize =
                        stream->ctrl.dwMaxVideoFrameSize;
 
        /* Probe the device. */
        ret = uvc_probe_video(stream, probe);
+       mutex_unlock(&stream->mutex);
        if (ret < 0)
                goto done;
 
@@ -289,14 +257,21 @@ done:
 static int uvc_v4l2_get_format(struct uvc_streaming *stream,
        struct v4l2_format *fmt)
 {
-       struct uvc_format *format = stream->cur_format;
-       struct uvc_frame *frame = stream->cur_frame;
+       struct uvc_format *format;
+       struct uvc_frame *frame;
+       int ret = 0;
 
        if (fmt->type != stream->type)
                return -EINVAL;
 
-       if (format == NULL || frame == NULL)
-               return -EINVAL;
+       mutex_lock(&stream->mutex);
+       format = stream->cur_format;
+       frame = stream->cur_frame;
+
+       if (format == NULL || frame == NULL) {
+               ret = -EINVAL;
+               goto done;
+       }
 
        fmt->fmt.pix.pixelformat = format->fcc;
        fmt->fmt.pix.width = frame->wWidth;
@@ -307,7 +282,9 @@ static int uvc_v4l2_get_format(struct uvc_streaming *stream,
        fmt->fmt.pix.colorspace = format->colorspace;
        fmt->fmt.pix.priv = 0;
 
-       return 0;
+done:
+       mutex_unlock(&stream->mutex);
+       return ret;
 }
 
 static int uvc_v4l2_set_format(struct uvc_streaming *stream,
@@ -321,18 +298,24 @@ static int uvc_v4l2_set_format(struct uvc_streaming *stream,
        if (fmt->type != stream->type)
                return -EINVAL;
 
-       if (uvc_queue_allocated(&stream->queue))
-               return -EBUSY;
-
        ret = uvc_v4l2_try_format(stream, fmt, &probe, &format, &frame);
        if (ret < 0)
                return ret;
 
+       mutex_lock(&stream->mutex);
+
+       if (uvc_queue_allocated(&stream->queue)) {
+               ret = -EBUSY;
+               goto done;
+       }
+
        memcpy(&stream->ctrl, &probe, sizeof probe);
        stream->cur_format = format;
        stream->cur_frame = frame;
 
-       return 0;
+done:
+       mutex_unlock(&stream->mutex);
+       return ret;
 }
 
 static int uvc_v4l2_get_streamparm(struct uvc_streaming *stream,
@@ -343,7 +326,10 @@ static int uvc_v4l2_get_streamparm(struct uvc_streaming *stream,
        if (parm->type != stream->type)
                return -EINVAL;
 
+       mutex_lock(&stream->mutex);
        numerator = stream->ctrl.dwFrameInterval;
+       mutex_unlock(&stream->mutex);
+
        denominator = 10000000;
        uvc_simplify_fraction(&numerator, &denominator, 8, 333);
 
@@ -370,7 +356,6 @@ static int uvc_v4l2_get_streamparm(struct uvc_streaming *stream,
 static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream,
                struct v4l2_streamparm *parm)
 {
-       struct uvc_frame *frame = stream->cur_frame;
        struct uvc_streaming_control probe;
        struct v4l2_fract timeperframe;
        uint32_t interval;
@@ -379,28 +364,36 @@ static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream,
        if (parm->type != stream->type)
                return -EINVAL;
 
-       if (uvc_queue_streaming(&stream->queue))
-               return -EBUSY;
-
        if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
                timeperframe = parm->parm.capture.timeperframe;
        else
                timeperframe = parm->parm.output.timeperframe;
 
-       memcpy(&probe, &stream->ctrl, sizeof probe);
        interval = uvc_fraction_to_interval(timeperframe.numerator,
                timeperframe.denominator);
-
        uvc_trace(UVC_TRACE_FORMAT, "Setting frame interval to %u/%u (%u).\n",
                timeperframe.numerator, timeperframe.denominator, interval);
-       probe.dwFrameInterval = uvc_try_frame_interval(frame, interval);
+
+       mutex_lock(&stream->mutex);
+
+       if (uvc_queue_streaming(&stream->queue)) {
+               mutex_unlock(&stream->mutex);
+               return -EBUSY;
+       }
+
+       memcpy(&probe, &stream->ctrl, sizeof probe);
+       probe.dwFrameInterval =
+               uvc_try_frame_interval(stream->cur_frame, interval);
 
        /* Probe the device with the new settings. */
        ret = uvc_probe_video(stream, &probe);
-       if (ret < 0)
+       if (ret < 0) {
+               mutex_unlock(&stream->mutex);
                return ret;
+       }
 
        memcpy(&stream->ctrl, &probe, sizeof probe);
+       mutex_unlock(&stream->mutex);
 
        /* Return the actual frame period. */
        timeperframe.numerator = probe.dwFrameInterval;
@@ -528,11 +521,9 @@ static int uvc_v4l2_release(struct file *file)
        if (uvc_has_privileges(handle)) {
                uvc_video_enable(stream, 0);
 
-               mutex_lock(&stream->queue.mutex);
                if (uvc_free_buffers(&stream->queue) < 0)
                        uvc_printk(KERN_ERR, "uvc_v4l2_release: Unable to "
                                        "free buffers.\n");
-               mutex_unlock(&stream->queue.mutex);
        }
 
        /* Release the file handle. */
@@ -624,7 +615,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
        }
 
        case VIDIOC_QUERYMENU:
-               return uvc_v4l2_query_menu(chain, arg);
+               return uvc_query_v4l2_menu(chain, arg);
 
        case VIDIOC_G_EXT_CTRLS:
        {
@@ -905,15 +896,17 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
        case VIDIOC_CROPCAP:
        {
                struct v4l2_cropcap *ccap = arg;
-               struct uvc_frame *frame = stream->cur_frame;
 
                if (ccap->type != stream->type)
                        return -EINVAL;
 
                ccap->bounds.left = 0;
                ccap->bounds.top = 0;
-               ccap->bounds.width = frame->wWidth;
-               ccap->bounds.height = frame->wHeight;
+
+               mutex_lock(&stream->mutex);
+               ccap->bounds.width = stream->cur_frame->wWidth;
+               ccap->bounds.height = stream->cur_frame->wHeight;
+               mutex_unlock(&stream->mutex);
 
                ccap->defrect = ccap->bounds;
 
@@ -930,8 +923,6 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
        case VIDIOC_REQBUFS:
        {
                struct v4l2_requestbuffers *rb = arg;
-               unsigned int bufsize =
-                       stream->ctrl.dwMaxVideoFrameSize;
 
                if (rb->type != stream->type ||
                    rb->memory != V4L2_MEMORY_MMAP)
@@ -940,7 +931,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
                if ((ret = uvc_acquire_privileges(handle)) < 0)
                        return ret;
 
-               ret = uvc_alloc_buffers(&stream->queue, rb->count, bufsize);
+               mutex_lock(&stream->mutex);
+               ret = uvc_alloc_buffers(&stream->queue, rb->count,
+                                       stream->ctrl.dwMaxVideoFrameSize);
+               mutex_unlock(&stream->mutex);
                if (ret < 0)
                        return ret;
 
@@ -988,7 +982,9 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
                if (!uvc_has_privileges(handle))
                        return -EBUSY;
 
+               mutex_lock(&stream->mutex);
                ret = uvc_video_enable(stream, 1);
+               mutex_unlock(&stream->mutex);
                if (ret < 0)
                        return ret;
                break;
@@ -1068,79 +1064,14 @@ static ssize_t uvc_v4l2_read(struct file *file, char __user *data,
        return -EINVAL;
 }
 
-/*
- * VMA operations.
- */
-static void uvc_vm_open(struct vm_area_struct *vma)
-{
-       struct uvc_buffer *buffer = vma->vm_private_data;
-       buffer->vma_use_count++;
-}
-
-static void uvc_vm_close(struct vm_area_struct *vma)
-{
-       struct uvc_buffer *buffer = vma->vm_private_data;
-       buffer->vma_use_count--;
-}
-
-static const struct vm_operations_struct uvc_vm_ops = {
-       .open           = uvc_vm_open,
-       .close          = uvc_vm_close,
-};
-
 static int uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
 {
        struct uvc_fh *handle = file->private_data;
        struct uvc_streaming *stream = handle->stream;
-       struct uvc_video_queue *queue = &stream->queue;
-       struct uvc_buffer *uninitialized_var(buffer);
-       struct page *page;
-       unsigned long addr, start, size;
-       unsigned int i;
-       int ret = 0;
 
        uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_mmap\n");
 
-       start = vma->vm_start;
-       size = vma->vm_end - vma->vm_start;
-
-       mutex_lock(&queue->mutex);
-
-       for (i = 0; i < queue->count; ++i) {
-               buffer = &queue->buffer[i];
-               if ((buffer->buf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff)
-                       break;
-       }
-
-       if (i == queue->count || size != queue->buf_size) {
-               ret = -EINVAL;
-               goto done;
-       }
-
-       /*
-        * VM_IO marks the area as being an mmaped region for I/O to a
-        * device. It also prevents the region from being core dumped.
-        */
-       vma->vm_flags |= VM_IO;
-
-       addr = (unsigned long)queue->mem + buffer->buf.m.offset;
-       while (size > 0) {
-               page = vmalloc_to_page((void *)addr);
-               if ((ret = vm_insert_page(vma, start, page)) < 0)
-                       goto done;
-
-               start += PAGE_SIZE;
-               addr += PAGE_SIZE;
-               size -= PAGE_SIZE;
-       }
-
-       vma->vm_ops = &uvc_vm_ops;
-       vma->vm_private_data = buffer;
-       uvc_vm_open(vma);
-
-done:
-       mutex_unlock(&queue->mutex);
-       return ret;
+       return uvc_queue_mmap(&stream->queue, vma);
 }
 
 static unsigned int uvc_v4l2_poll(struct file *file, poll_table *wait)
@@ -1157,7 +1088,7 @@ const struct v4l2_file_operations uvc_fops = {
        .owner          = THIS_MODULE,
        .open           = uvc_v4l2_open,
        .release        = uvc_v4l2_release,
-       .ioctl          = uvc_v4l2_ioctl,
+       .unlocked_ioctl = uvc_v4l2_ioctl,
        .read           = uvc_v4l2_read,
        .mmap           = uvc_v4l2_mmap,
        .poll           = uvc_v4l2_poll,
index 5555f01..5673d67 100644 (file)
@@ -293,8 +293,6 @@ int uvc_probe_video(struct uvc_streaming *stream,
        unsigned int i;
        int ret;
 
-       mutex_lock(&stream->mutex);
-
        /* Perform probing. The device should adjust the requested values
         * according to its capabilities. However, some devices, namely the
         * first generation UVC Logitech webcams, don't implement the Video
@@ -346,7 +344,6 @@ int uvc_probe_video(struct uvc_streaming *stream,
        }
 
 done:
-       mutex_unlock(&stream->mutex);
        return ret;
 }
 
index d97cf6d..45f01e7 100644 (file)
@@ -436,7 +436,9 @@ struct uvc_streaming {
        struct uvc_streaming_control ctrl;
        struct uvc_format *cur_format;
        struct uvc_frame *cur_frame;
-
+       /* Protect access to ctrl, cur_format, cur_frame and hardware video
+        * probe control.
+        */
        struct mutex mutex;
 
        unsigned int frozen : 1;
@@ -574,6 +576,8 @@ extern int uvc_queue_enable(struct uvc_video_queue *queue, int enable);
 extern void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect);
 extern struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue,
                struct uvc_buffer *buf);
+extern int uvc_queue_mmap(struct uvc_video_queue *queue,
+               struct vm_area_struct *vma);
 extern unsigned int uvc_queue_poll(struct uvc_video_queue *queue,
                struct file *file, poll_table *wait);
 extern int uvc_queue_allocated(struct uvc_video_queue *queue);
@@ -606,10 +610,10 @@ extern int uvc_status_suspend(struct uvc_device *dev);
 extern int uvc_status_resume(struct uvc_device *dev);
 
 /* Controls */
-extern struct uvc_control *uvc_find_control(struct uvc_video_chain *chain,
-               __u32 v4l2_id, struct uvc_control_mapping **mapping);
 extern int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
                struct v4l2_queryctrl *v4l2_ctrl);
+extern int uvc_query_v4l2_menu(struct uvc_video_chain *chain,
+               struct v4l2_querymenu *query_menu);
 
 extern int uvc_ctrl_add_mapping(struct uvc_video_chain *chain,
                const struct uvc_control_mapping *mapping);
index 9294282..b5eb1f3 100644 (file)
@@ -368,18 +368,15 @@ EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_init);
 
 /* Load an i2c sub-device. */
 struct v4l2_subdev *v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev,
-               struct i2c_adapter *adapter, const char *module_name,
-               struct i2c_board_info *info, const unsigned short *probe_addrs)
+               struct i2c_adapter *adapter, struct i2c_board_info *info,
+               const unsigned short *probe_addrs)
 {
        struct v4l2_subdev *sd = NULL;
        struct i2c_client *client;
 
        BUG_ON(!v4l2_dev);
 
-       if (module_name)
-               request_module(module_name);
-       else
-               request_module(I2C_MODULE_PREFIX "%s", info->type);
+       request_module(I2C_MODULE_PREFIX "%s", info->type);
 
        /* Create the i2c client */
        if (info->addr == 0 && probe_addrs)
@@ -432,8 +429,7 @@ error:
 EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev_board);
 
 struct v4l2_subdev *v4l2_i2c_new_subdev_cfg(struct v4l2_device *v4l2_dev,
-               struct i2c_adapter *adapter,
-               const char *module_name, const char *client_type,
+               struct i2c_adapter *adapter, const char *client_type,
                int irq, void *platform_data,
                u8 addr, const unsigned short *probe_addrs)
 {
@@ -447,8 +443,7 @@ struct v4l2_subdev *v4l2_i2c_new_subdev_cfg(struct v4l2_device *v4l2_dev,
        info.irq = irq;
        info.platform_data = platform_data;
 
-       return v4l2_i2c_new_subdev_board(v4l2_dev, adapter, module_name,
-                       &info, probe_addrs);
+       return v4l2_i2c_new_subdev_board(v4l2_dev, adapter, &info, probe_addrs);
 }
 EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev_cfg);
 
index 03f7f46..359e232 100644 (file)
@@ -186,12 +186,12 @@ static ssize_t v4l2_read(struct file *filp, char __user *buf,
                size_t sz, loff_t *off)
 {
        struct video_device *vdev = video_devdata(filp);
-       int ret = -EIO;
+       int ret = -ENODEV;
 
        if (!vdev->fops->read)
                return -EINVAL;
-       if (vdev->lock)
-               mutex_lock(vdev->lock);
+       if (vdev->lock && mutex_lock_interruptible(vdev->lock))
+               return -ERESTARTSYS;
        if (video_is_registered(vdev))
                ret = vdev->fops->read(filp, buf, sz, off);
        if (vdev->lock)
@@ -203,12 +203,12 @@ static ssize_t v4l2_write(struct file *filp, const char __user *buf,
                size_t sz, loff_t *off)
 {
        struct video_device *vdev = video_devdata(filp);
-       int ret = -EIO;
+       int ret = -ENODEV;
 
        if (!vdev->fops->write)
                return -EINVAL;
-       if (vdev->lock)
-               mutex_lock(vdev->lock);
+       if (vdev->lock && mutex_lock_interruptible(vdev->lock))
+               return -ERESTARTSYS;
        if (video_is_registered(vdev))
                ret = vdev->fops->write(filp, buf, sz, off);
        if (vdev->lock)
@@ -219,10 +219,10 @@ static ssize_t v4l2_write(struct file *filp, const char __user *buf,
 static unsigned int v4l2_poll(struct file *filp, struct poll_table_struct *poll)
 {
        struct video_device *vdev = video_devdata(filp);
-       int ret = DEFAULT_POLLMASK;
+       int ret = POLLERR | POLLHUP;
 
        if (!vdev->fops->poll)
-               return ret;
+               return DEFAULT_POLLMASK;
        if (vdev->lock)
                mutex_lock(vdev->lock);
        if (video_is_registered(vdev))
@@ -238,20 +238,45 @@ static long v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
        int ret = -ENODEV;
 
        if (vdev->fops->unlocked_ioctl) {
-               if (vdev->lock)
-                       mutex_lock(vdev->lock);
+               if (vdev->lock && mutex_lock_interruptible(vdev->lock))
+                       return -ERESTARTSYS;
                if (video_is_registered(vdev))
                        ret = vdev->fops->unlocked_ioctl(filp, cmd, arg);
                if (vdev->lock)
                        mutex_unlock(vdev->lock);
        } else if (vdev->fops->ioctl) {
-               /* TODO: convert all drivers to unlocked_ioctl */
+               /* This code path is a replacement for the BKL. It is a major
+                * hack but it will have to do for those drivers that are not
+                * yet converted to use unlocked_ioctl.
+                *
+                * There are two options: if the driver implements struct
+                * v4l2_device, then the lock defined there is used to
+                * serialize the ioctls. Otherwise the v4l2 core lock defined
+                * below is used. This lock is really bad since it serializes
+                * completely independent devices.
+                *
+                * Both variants suffer from the same problem: if the driver
+                * sleeps, then it blocks all ioctls since the lock is still
+                * held. This is very common for VIDIOC_DQBUF since that
+                * normally waits for a frame to arrive. As a result any other
+                * ioctl calls will proceed very, very slowly since each call
+                * will have to wait for the VIDIOC_QBUF to finish. Things that
+                * should take 0.01s may now take 10-20 seconds.
+                *
+                * The workaround is to *not* take the lock for VIDIOC_DQBUF.
+                * This actually works OK for videobuf-based drivers, since
+                * videobuf will take its own internal lock.
+                */
                static DEFINE_MUTEX(v4l2_ioctl_mutex);
+               struct mutex *m = vdev->v4l2_dev ?
+                       &vdev->v4l2_dev->ioctl_lock : &v4l2_ioctl_mutex;
 
-               mutex_lock(&v4l2_ioctl_mutex);
+               if (cmd != VIDIOC_DQBUF && mutex_lock_interruptible(m))
+                       return -ERESTARTSYS;
                if (video_is_registered(vdev))
                        ret = vdev->fops->ioctl(filp, cmd, arg);
-               mutex_unlock(&v4l2_ioctl_mutex);
+               if (cmd != VIDIOC_DQBUF)
+                       mutex_unlock(m);
        } else
                ret = -ENOTTY;
 
@@ -265,8 +290,8 @@ static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm)
 
        if (!vdev->fops->mmap)
                return ret;
-       if (vdev->lock)
-               mutex_lock(vdev->lock);
+       if (vdev->lock && mutex_lock_interruptible(vdev->lock))
+               return -ERESTARTSYS;
        if (video_is_registered(vdev))
                ret = vdev->fops->mmap(filp, vm);
        if (vdev->lock)
@@ -284,7 +309,7 @@ static int v4l2_open(struct inode *inode, struct file *filp)
        mutex_lock(&videodev_lock);
        vdev = video_devdata(filp);
        /* return ENODEV if the video device has already been removed. */
-       if (vdev == NULL) {
+       if (vdev == NULL || !video_is_registered(vdev)) {
                mutex_unlock(&videodev_lock);
                return -ENODEV;
        }
@@ -292,8 +317,10 @@ static int v4l2_open(struct inode *inode, struct file *filp)
        video_get(vdev);
        mutex_unlock(&videodev_lock);
        if (vdev->fops->open) {
-               if (vdev->lock)
-                       mutex_lock(vdev->lock);
+               if (vdev->lock && mutex_lock_interruptible(vdev->lock)) {
+                       ret = -ERESTARTSYS;
+                       goto err;
+               }
                if (video_is_registered(vdev))
                        ret = vdev->fops->open(filp);
                else
@@ -302,6 +329,7 @@ static int v4l2_open(struct inode *inode, struct file *filp)
                        mutex_unlock(vdev->lock);
        }
 
+err:
        /* decrease the refcount in case of an error */
        if (ret)
                video_put(vdev);
@@ -596,7 +624,12 @@ void video_unregister_device(struct video_device *vdev)
        if (!vdev || !video_is_registered(vdev))
                return;
 
+       mutex_lock(&videodev_lock);
+       /* This must be in a critical section to prevent a race with v4l2_open.
+        * Once this bit has been cleared video_get may never be called again.
+        */
        clear_bit(V4L2_FL_REGISTERED, &vdev->flags);
+       mutex_unlock(&videodev_lock);
        device_unregister(&vdev->dev);
 }
 EXPORT_SYMBOL(video_unregister_device);
index 0b08f96..7fe6f92 100644 (file)
@@ -35,6 +35,7 @@ int v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev)
 
        INIT_LIST_HEAD(&v4l2_dev->subdevs);
        spin_lock_init(&v4l2_dev->lock);
+       mutex_init(&v4l2_dev->ioctl_lock);
        v4l2_dev->dev = dev;
        if (dev == NULL) {
                /* If dev == NULL, then name must be filled in by the caller */
index 02a21bc..9eda7cc 100644 (file)
@@ -1360,7 +1360,7 @@ static __devinit int viacam_probe(struct platform_device *pdev)
         */
        sensor_adapter = viafb_find_i2c_adapter(VIA_PORT_31);
        cam->sensor = v4l2_i2c_new_subdev(&cam->v4l2_dev, sensor_adapter,
-                       "ov7670", "ov7670", 0x42 >> 1, NULL);
+                       "ov7670", 0x42 >> 1, NULL);
        if (cam->sensor == NULL) {
                dev_err(&pdev->dev, "Unable to find the sensor!\n");
                ret = -ENODEV;
index e5e005d..7e7eec4 100644 (file)
@@ -4334,10 +4334,10 @@ static int __init vino_module_init(void)
 
        vino_drvdata->decoder =
                v4l2_i2c_new_subdev(&vino_drvdata->v4l2_dev, &vino_i2c_adapter,
-                              NULL, "saa7191", 0, I2C_ADDRS(0x45));
+                              "saa7191", 0, I2C_ADDRS(0x45));
        vino_drvdata->camera =
                v4l2_i2c_new_subdev(&vino_drvdata->v4l2_dev, &vino_i2c_adapter,
-                              NULL, "indycam", 0, I2C_ADDRS(0x2b));
+                              "indycam", 0, I2C_ADDRS(0x2b));
 
        dprintk("init complete!\n");
 
index 635420d..019ee20 100644 (file)
@@ -815,7 +815,7 @@ out:
 
 static const struct v4l2_file_operations w9966_fops = {
        .owner          = THIS_MODULE,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
        .read           = w9966_v4l_read,
 };
 
index 7e6d624..e520abf 100644 (file)
@@ -1343,13 +1343,12 @@ static int __devinit zoran_probe(struct pci_dev *pdev,
        }
 
        zr->decoder = v4l2_i2c_new_subdev(&zr->v4l2_dev,
-               &zr->i2c_adapter, NULL, zr->card.i2c_decoder,
+               &zr->i2c_adapter, zr->card.i2c_decoder,
                0, zr->card.addrs_decoder);
 
        if (zr->card.i2c_encoder)
                zr->encoder = v4l2_i2c_new_subdev(&zr->v4l2_dev,
-                       &zr->i2c_adapter,
-                       NULL, zr->card.i2c_encoder,
+                       &zr->i2c_adapter, zr->card.i2c_encoder,
                        0, zr->card.addrs_encoder);
 
        dprintk(2,
index dd90880..d8ae634 100644 (file)
@@ -51,7 +51,7 @@ struct pxa2xx_flash_info {
 static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
 
 
-static int __init pxa2xx_flash_probe(struct platform_device *pdev)
+static int __devinit pxa2xx_flash_probe(struct platform_device *pdev)
 {
        struct flash_platform_data *flash = pdev->dev.platform_data;
        struct pxa2xx_flash_info *info;
index cd41c58..15682ec 100644 (file)
@@ -7,7 +7,6 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-#define CONFIG_MTD_NAND_OMAP_HWECC
 
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
index c2960ac..811775a 100644 (file)
@@ -482,10 +482,17 @@ static int nor_erase_prepare(struct ubi_device *ubi, int pnum)
        uint32_t data = 0;
        struct ubi_vid_hdr vid_hdr;
 
-       addr = (loff_t)pnum * ubi->peb_size + ubi->vid_hdr_aloffset;
+       /*
+        * It is important to first invalidate the EC header, and then the VID
+        * header. Otherwise a power cut may lead to valid EC header and
+        * invalid VID header, in which case UBI will treat this PEB as
+        * corrupted and will try to preserve it, and print scary warnings (see
+        * the header comment in scan.c for more information).
+        */
+       addr = (loff_t)pnum * ubi->peb_size;
        err = ubi->mtd->write(ubi->mtd, addr, 4, &written, (void *)&data);
        if (!err) {
-               addr -= ubi->vid_hdr_aloffset;
+               addr += ubi->vid_hdr_aloffset;
                err = ubi->mtd->write(ubi->mtd, addr, 4, &written,
                                      (void *)&data);
                if (!err)
@@ -494,18 +501,24 @@ static int nor_erase_prepare(struct ubi_device *ubi, int pnum)
 
        /*
         * We failed to write to the media. This was observed with Spansion
-        * S29GL512N NOR flash. Most probably the eraseblock erasure was
-        * interrupted at a very inappropriate moment, so it became unwritable.
-        * In this case we probably anyway have garbage in this PEB.
+        * S29GL512N NOR flash. Most probably the previously eraseblock erasure
+        * was interrupted at a very inappropriate moment, so it became
+        * unwritable. In this case we probably anyway have garbage in this
+        * PEB.
         */
        err1 = ubi_io_read_vid_hdr(ubi, pnum, &vid_hdr, 0);
-       if (err1 == UBI_IO_BAD_HDR_EBADMSG || err1 == UBI_IO_BAD_HDR)
-               /*
-                * The VID header is corrupted, so we can safely erase this
-                * PEB and not afraid that it will be treated as a valid PEB in
-                * case of an unclean reboot.
-                */
-               return 0;
+       if (err1 == UBI_IO_BAD_HDR_EBADMSG || err1 == UBI_IO_BAD_HDR) {
+               struct ubi_ec_hdr ec_hdr;
+
+               err1 = ubi_io_read_ec_hdr(ubi, pnum, &ec_hdr, 0);
+               if (err1 == UBI_IO_BAD_HDR_EBADMSG || err1 == UBI_IO_BAD_HDR)
+                       /*
+                        * Both VID and EC headers are corrupted, so we can
+                        * safely erase this PEB and not afraid that it will be
+                        * treated as a valid PEB in case of an unclean reboot.
+                        */
+                       return 0;
+       }
 
        /*
         * The PEB contains a valid VID header, but we cannot invalidate it.
index 204345b..79ca304 100644 (file)
@@ -953,6 +953,10 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si,
                         * impossible to distinguish it from a PEB which just
                         * contains garbage because of a power cut during erase
                         * operation. So we just schedule this PEB for erasure.
+                        *
+                        * Besides, in case of NOR flash, we deliberatly
+                        * corrupt both headers because NOR flash erasure is
+                        * slow and can start from the end.
                         */
                        err = 0;
                else
index 43db398..4f1755b 100644 (file)
@@ -2543,10 +2543,10 @@ config PCH_GBE
        depends on PCI
        select MII
        ---help---
-         This is a gigabit ethernet driver for Topcliff PCH.
-         Topcliff PCH is the platform controller hub that is used in Intel's
+         This is a gigabit ethernet driver for EG20T PCH.
+         EG20T PCH is the platform controller hub that is used in Intel's
          general embedded platform.
-         Topcliff PCH has Gigabit Ethernet interface.
+         EG20T PCH has Gigabit Ethernet interface.
          Using this interface, it is able to access system devices connected
          to Gigabit Ethernet.
          This driver enables Gigabit Ethernet function.
index 43489f8..53eff9b 100644 (file)
@@ -155,10 +155,10 @@ static void au1000_enable_mac(struct net_device *dev, int force_reset)
        spin_lock_irqsave(&aup->lock, flags);
 
        if (force_reset || (!aup->mac_enabled)) {
-               writel(MAC_EN_CLOCK_ENABLE, &aup->enable);
+               writel(MAC_EN_CLOCK_ENABLE, aup->enable);
                au_sync_delay(2);
                writel((MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2
-                               | MAC_EN_CLOCK_ENABLE), &aup->enable);
+                               | MAC_EN_CLOCK_ENABLE), aup->enable);
                au_sync_delay(2);
 
                aup->mac_enabled = 1;
@@ -503,9 +503,9 @@ static void au1000_reset_mac_unlocked(struct net_device *dev)
 
        au1000_hard_stop(dev);
 
-       writel(MAC_EN_CLOCK_ENABLE, &aup->enable);
+       writel(MAC_EN_CLOCK_ENABLE, aup->enable);
        au_sync_delay(2);
-       writel(0, &aup->enable);
+       writel(0, aup->enable);
        au_sync_delay(2);
 
        aup->tx_full = 0;
@@ -1119,7 +1119,7 @@ static int __devinit au1000_probe(struct platform_device *pdev)
        /* set a random MAC now in case platform_data doesn't provide one */
        random_ether_addr(dev->dev_addr);
 
-       writel(0, &aup->enable);
+       writel(0, aup->enable);
        aup->mac_enabled = 0;
 
        pd = pdev->dev.platform_data;
index c6e8631..2e2b762 100644 (file)
@@ -381,11 +381,11 @@ static void b44_set_flow_ctrl(struct b44 *bp, u32 local, u32 remote)
        __b44_set_flow_ctrl(bp, pause_enab);
 }
 
-#ifdef SSB_DRIVER_MIPS
-extern char *nvram_get(char *name);
+#ifdef CONFIG_BCM47XX
+#include <asm/mach-bcm47xx/nvram.h>
 static void b44_wap54g10_workaround(struct b44 *bp)
 {
-       const char *str;
+       char buf[20];
        u32 val;
        int err;
 
@@ -394,10 +394,9 @@ static void b44_wap54g10_workaround(struct b44 *bp)
         * see https://dev.openwrt.org/ticket/146
         * check and reset bit "isolate"
         */
-       str = nvram_get("boardnum");
-       if (!str)
+       if (nvram_getenv("boardnum", buf, sizeof(buf)) < 0)
                return;
-       if (simple_strtoul(str, NULL, 0) == 2) {
+       if (simple_strtoul(buf, NULL, 0) == 2) {
                err = __b44_readphy(bp, 0, MII_BMCR, &val);
                if (err)
                        goto error;
index 36eca1c..e4465d2 100644 (file)
@@ -1235,7 +1235,7 @@ int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id,
 
                i = 0;
                netdev_for_each_mc_addr(ha, netdev)
-                       memcpy(req->mac[i].byte, ha->addr, ETH_ALEN);
+                       memcpy(req->mac[i++].byte, ha->addr, ETH_ALEN);
        } else {
                req->promiscuous = 1;
        }
index 863e73a..d255428 100644 (file)
@@ -20,8 +20,8 @@
  * (you will need to reboot afterwards) */
 /* #define BNX2X_STOP_ON_ERROR */
 
-#define DRV_MODULE_VERSION      "1.60.00-4"
-#define DRV_MODULE_RELDATE      "2010/11/01"
+#define DRV_MODULE_VERSION      "1.60.01-0"
+#define DRV_MODULE_RELDATE      "2010/11/12"
 #define BNX2X_BC_VER            0x040200
 
 #define BNX2X_MULTI_QUEUE
index 94d5f59..0af361e 100644 (file)
@@ -1782,15 +1782,15 @@ exit_lbl:
 }
 #endif
 
-static inline void bnx2x_set_pbd_gso_e2(struct sk_buff *skb,
-                                    struct eth_tx_parse_bd_e2 *pbd,
-                                    u32 xmit_type)
+static inline void bnx2x_set_pbd_gso_e2(struct sk_buff *skb, u32 *parsing_data,
+                                       u32 xmit_type)
 {
-       pbd->parsing_data |= cpu_to_le16(skb_shinfo(skb)->gso_size) <<
-               ETH_TX_PARSE_BD_E2_LSO_MSS_SHIFT;
+       *parsing_data |= (skb_shinfo(skb)->gso_size <<
+                             ETH_TX_PARSE_BD_E2_LSO_MSS_SHIFT) &
+                             ETH_TX_PARSE_BD_E2_LSO_MSS;
        if ((xmit_type & XMIT_GSO_V6) &&
            (ipv6_hdr(skb)->nexthdr == NEXTHDR_IPV6))
-               pbd->parsing_data |= ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR;
+               *parsing_data |= ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR;
 }
 
 /**
@@ -1835,15 +1835,15 @@ static inline void bnx2x_set_pbd_gso(struct sk_buff *skb,
  * @return header len
  */
 static inline  u8 bnx2x_set_pbd_csum_e2(struct bnx2x *bp, struct sk_buff *skb,
-       struct eth_tx_parse_bd_e2 *pbd,
-       u32 xmit_type)
+       u32 *parsing_data, u32 xmit_type)
 {
-       pbd->parsing_data |= cpu_to_le16(tcp_hdrlen(skb)/4) <<
-               ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT;
+       *parsing_data |= ((tcp_hdrlen(skb)/4) <<
+               ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT) &
+               ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW;
 
-       pbd->parsing_data |= cpu_to_le16(((unsigned char *)tcp_hdr(skb) -
-                                         skb->data) / 2) <<
-               ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W_SHIFT;
+       *parsing_data |= ((((u8 *)tcp_hdr(skb) - skb->data) / 2) <<
+               ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W_SHIFT) &
+               ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W;
 
        return skb_transport_header(skb) + tcp_hdrlen(skb) - skb->data;
 }
@@ -1912,6 +1912,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
        struct eth_tx_bd *tx_data_bd, *total_pkt_bd = NULL;
        struct eth_tx_parse_bd_e1x *pbd_e1x = NULL;
        struct eth_tx_parse_bd_e2 *pbd_e2 = NULL;
+       u32 pbd_e2_parsing_data = 0;
        u16 pkt_prod, bd_prod;
        int nbd, fp_index;
        dma_addr_t mapping;
@@ -2033,8 +2034,9 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
                memset(pbd_e2, 0, sizeof(struct eth_tx_parse_bd_e2));
                /* Set PBD in checksum offload case */
                if (xmit_type & XMIT_CSUM)
-                       hlen = bnx2x_set_pbd_csum_e2(bp,
-                                                    skb, pbd_e2, xmit_type);
+                       hlen = bnx2x_set_pbd_csum_e2(bp, skb,
+                                                    &pbd_e2_parsing_data,
+                                                    xmit_type);
        } else {
                pbd_e1x = &fp->tx_desc_ring[bd_prod].parse_bd_e1x;
                memset(pbd_e1x, 0, sizeof(struct eth_tx_parse_bd_e1x));
@@ -2076,10 +2078,18 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
                        bd_prod = bnx2x_tx_split(bp, fp, tx_buf, &tx_start_bd,
                                                 hlen, bd_prod, ++nbd);
                if (CHIP_IS_E2(bp))
-                       bnx2x_set_pbd_gso_e2(skb, pbd_e2, xmit_type);
+                       bnx2x_set_pbd_gso_e2(skb, &pbd_e2_parsing_data,
+                                            xmit_type);
                else
                        bnx2x_set_pbd_gso(skb, pbd_e1x, xmit_type);
        }
+
+       /* Set the PBD's parsing_data field if not zero
+        * (for the chips newer than 57711).
+        */
+       if (pbd_e2_parsing_data)
+               pbd_e2->parsing_data = cpu_to_le32(pbd_e2_parsing_data);
+
        tx_data_bd = (struct eth_tx_bd *)tx_start_bd;
 
        /* Handle fragmented skb */
index a306b0e..66df29f 100644 (file)
@@ -838,7 +838,7 @@ static void bnx2x_qm_init_ptr_table(struct bnx2x *bp, int qm_cid_count,
 /****************************************************************************
 * SRC initializations
 ****************************************************************************/
-
+#ifdef BCM_CNIC
 /* called during init func stage */
 static void bnx2x_src_init_t2(struct bnx2x *bp, struct src_ent *t2,
                              dma_addr_t t2_mapping, int src_cid_count)
@@ -862,5 +862,5 @@ static void bnx2x_src_init_t2(struct bnx2x *bp, struct src_ent *t2,
                    U64_HI((u64)t2_mapping +
                           (src_cid_count-1) * sizeof(struct src_ent)));
 }
-
+#endif
 #endif /* BNX2X_INIT_OPS_H */
index 71a1697..d0ea760 100644 (file)
@@ -171,7 +171,7 @@ MODULE_PARM_DESC(resend_igmp, "Number of IGMP membership reports to send on link
 /*----------------------------- Global variables ----------------------------*/
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
-cpumask_var_t netpoll_block_tx;
+atomic_t netpoll_block_tx = ATOMIC_INIT(0);
 #endif
 
 static const char * const version =
@@ -1576,7 +1576,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
 
        /* If this is the first slave, then we need to set the master's hardware
         * address to be the same as the slave's. */
-       if (bond->slave_cnt == 0)
+       if (is_zero_ether_addr(bond->dev->dev_addr))
                memcpy(bond->dev->dev_addr, slave_dev->dev_addr,
                       slave_dev->addr_len);
 
@@ -5299,13 +5299,6 @@ static int __init bonding_init(void)
        if (res)
                goto out;
 
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       if (!alloc_cpumask_var(&netpoll_block_tx, GFP_KERNEL)) {
-               res = -ENOMEM;
-               goto out;
-       }
-#endif
-
        res = register_pernet_subsys(&bond_net_ops);
        if (res)
                goto out;
@@ -5334,9 +5327,6 @@ err:
        rtnl_link_unregister(&bond_link_ops);
 err_link:
        unregister_pernet_subsys(&bond_net_ops);
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       free_cpumask_var(netpoll_block_tx);
-#endif
        goto out;
 
 }
@@ -5353,7 +5343,10 @@ static void __exit bonding_exit(void)
        unregister_pernet_subsys(&bond_net_ops);
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
-       free_cpumask_var(netpoll_block_tx);
+       /*
+        * Make sure we don't have an imbalance on our netpoll blocking
+        */
+       WARN_ON(atomic_read(&netpoll_block_tx));
 #endif
 }
 
index 4eedb12..c2f0813 100644 (file)
 
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
-extern cpumask_var_t netpoll_block_tx;
+extern atomic_t netpoll_block_tx;
 
 static inline void block_netpoll_tx(void)
 {
-       preempt_disable();
-       BUG_ON(cpumask_test_and_set_cpu(smp_processor_id(),
-                                       netpoll_block_tx));
+       atomic_inc(&netpoll_block_tx);
 }
 
 static inline void unblock_netpoll_tx(void)
 {
-       BUG_ON(!cpumask_test_and_clear_cpu(smp_processor_id(),
-                                          netpoll_block_tx));
-       preempt_enable();
+       atomic_dec(&netpoll_block_tx);
 }
 
 static inline int is_netpoll_tx_blocked(struct net_device *dev)
 {
        if (unlikely(dev->priv_flags & IFF_IN_NETPOLL))
-               return cpumask_test_cpu(smp_processor_id(), netpoll_block_tx);
+               return atomic_read(&netpoll_block_tx);
        return 0;
 }
 #else
index 1cd90da..32b1c6f 100644 (file)
@@ -5,7 +5,7 @@
  * License terms: GNU General Public License (GPL) version 2
  */
 
-#define pr_fmt(fmt) KBUILD_MODNAME ":" __func__ "():" fmt
+#define pr_fmt(fmt) KBUILD_MODNAME ":" fmt
 
 #include <linux/version.h>
 #include <linux/init.h>
index 19f9c06..8051116 100644 (file)
@@ -6,7 +6,7 @@
  * License terms: GNU General Public License (GPL) version 2
  */
 
-#define pr_fmt(fmt) KBUILD_MODNAME ":" __func__ "():" fmt
+#define pr_fmt(fmt) KBUILD_MODNAME ":" fmt
 
 #include <linux/spinlock.h>
 #include <linux/sched.h>
index bb813d9..e97521c 100644 (file)
@@ -2408,7 +2408,7 @@ int t4_alloc_mac_filt(struct adapter *adap, unsigned int mbox,
                if (index < NEXACT_MAC)
                        ret++;
                else if (hash)
-                       *hash |= (1 << hash_mac_addr(addr[i]));
+                       *hash |= (1ULL << hash_mac_addr(addr[i]));
        }
        return ret;
 }
index c3449bb..6bf464a 100644 (file)
@@ -816,40 +816,48 @@ static struct net_device_stats *cxgb4vf_get_stats(struct net_device *dev)
 }
 
 /*
- * Collect up to maxaddrs worth of a netdevice's unicast addresses into an
- * array of addrss pointers and return the number collected.
+ * Collect up to maxaddrs worth of a netdevice's unicast addresses, starting
+ * at a specified offset within the list, into an array of addrss pointers and
+ * return the number collected.
  */
-static inline int collect_netdev_uc_list_addrs(const struct net_device *dev,
-                                              const u8 **addr,
-                                              unsigned int maxaddrs)
+static inline unsigned int collect_netdev_uc_list_addrs(const struct net_device *dev,
+                                                       const u8 **addr,
+                                                       unsigned int offset,
+                                                       unsigned int maxaddrs)
 {
+       unsigned int index = 0;
        unsigned int naddr = 0;
        const struct netdev_hw_addr *ha;
 
-       for_each_dev_addr(dev, ha) {
-               addr[naddr++] = ha->addr;
-               if (naddr >= maxaddrs)
-                       break;
-       }
+       for_each_dev_addr(dev, ha)
+               if (index++ >= offset) {
+                       addr[naddr++] = ha->addr;
+                       if (naddr >= maxaddrs)
+                               break;
+               }
        return naddr;
 }
 
 /*
- * Collect up to maxaddrs worth of a netdevice's multicast addresses into an
- * array of addrss pointers and return the number collected.
+ * Collect up to maxaddrs worth of a netdevice's multicast addresses, starting
+ * at a specified offset within the list, into an array of addrss pointers and
+ * return the number collected.
  */
-static inline int collect_netdev_mc_list_addrs(const struct net_device *dev,
-                                              const u8 **addr,
-                                              unsigned int maxaddrs)
+static inline unsigned int collect_netdev_mc_list_addrs(const struct net_device *dev,
+                                                       const u8 **addr,
+                                                       unsigned int offset,
+                                                       unsigned int maxaddrs)
 {
+       unsigned int index = 0;
        unsigned int naddr = 0;
        const struct netdev_hw_addr *ha;
 
-       netdev_for_each_mc_addr(ha, dev) {
-               addr[naddr++] = ha->addr;
-               if (naddr >= maxaddrs)
-                       break;
-       }
+       netdev_for_each_mc_addr(ha, dev)
+               if (index++ >= offset) {
+                       addr[naddr++] = ha->addr;
+                       if (naddr >= maxaddrs)
+                               break;
+               }
        return naddr;
 }
 
@@ -862,16 +870,20 @@ static int set_addr_filters(const struct net_device *dev, bool sleep)
        u64 mhash = 0;
        u64 uhash = 0;
        bool free = true;
-       u16 filt_idx[7];
+       unsigned int offset, naddr;
        const u8 *addr[7];
-       int ret, naddr = 0;
+       int ret;
        const struct port_info *pi = netdev_priv(dev);
 
        /* first do the secondary unicast addresses */
-       naddr = collect_netdev_uc_list_addrs(dev, addr, ARRAY_SIZE(addr));
-       if (naddr > 0) {
+       for (offset = 0; ; offset += naddr) {
+               naddr = collect_netdev_uc_list_addrs(dev, addr, offset,
+                                                    ARRAY_SIZE(addr));
+               if (naddr == 0)
+                       break;
+
                ret = t4vf_alloc_mac_filt(pi->adapter, pi->viid, free,
-                                         naddr, addr, filt_idx, &uhash, sleep);
+                                         naddr, addr, NULL, &uhash, sleep);
                if (ret < 0)
                        return ret;
 
@@ -879,12 +891,17 @@ static int set_addr_filters(const struct net_device *dev, bool sleep)
        }
 
        /* next set up the multicast addresses */
-       naddr = collect_netdev_mc_list_addrs(dev, addr, ARRAY_SIZE(addr));
-       if (naddr > 0) {
+       for (offset = 0; ; offset += naddr) {
+               naddr = collect_netdev_mc_list_addrs(dev, addr, offset,
+                                                    ARRAY_SIZE(addr));
+               if (naddr == 0)
+                       break;
+
                ret = t4vf_alloc_mac_filt(pi->adapter, pi->viid, free,
-                                         naddr, addr, filt_idx, &mhash, sleep);
+                                         naddr, addr, NULL, &mhash, sleep);
                if (ret < 0)
                        return ret;
+               free = false;
        }
 
        return t4vf_set_addr_hash(pi->adapter, pi->viid, uhash != 0,
@@ -2252,6 +2269,7 @@ static void __devinit cfg_queues(struct adapter *adapter)
 {
        struct sge *s = &adapter->sge;
        int q10g, n10g, qidx, pidx, qs;
+       size_t iqe_size;
 
        /*
         * We should not be called till we know how many Queue Sets we can
@@ -2295,6 +2313,13 @@ static void __devinit cfg_queues(struct adapter *adapter)
        }
        s->ethqsets = qidx;
 
+       /*
+        * The Ingress Queue Entry Size for our various Response Queues needs
+        * to be big enough to accommodate the largest message we can receive
+        * from the chip/firmware; which is 64 bytes ...
+        */
+       iqe_size = 64;
+
        /*
         * Set up default Queue Set parameters ...  Start off with the
         * shortest interrupt holdoff timer.
@@ -2303,7 +2328,7 @@ static void __devinit cfg_queues(struct adapter *adapter)
                struct sge_eth_rxq *rxq = &s->ethrxq[qs];
                struct sge_eth_txq *txq = &s->ethtxq[qs];
 
-               init_rspq(&rxq->rspq, 0, 0, 1024, L1_CACHE_BYTES);
+               init_rspq(&rxq->rspq, 0, 0, 1024, iqe_size);
                rxq->fl.size = 72;
                txq->q.size = 1024;
        }
@@ -2312,8 +2337,7 @@ static void __devinit cfg_queues(struct adapter *adapter)
         * The firmware event queue is used for link state changes and
         * notifications of TX DMA completions.
         */
-       init_rspq(&s->fw_evtq, SGE_TIMER_RSTRT_CNTR, 0, 512,
-                 L1_CACHE_BYTES);
+       init_rspq(&s->fw_evtq, SGE_TIMER_RSTRT_CNTR, 0, 512, iqe_size);
 
        /*
         * The forwarded interrupt queue is used when we're in MSI interrupt
@@ -2329,7 +2353,7 @@ static void __devinit cfg_queues(struct adapter *adapter)
         * any time ...
         */
        init_rspq(&s->intrq, SGE_TIMER_RSTRT_CNTR, 0, MSIX_ENTRIES + 1,
-                 L1_CACHE_BYTES);
+                 iqe_size);
 }
 
 /*
index e306c20..19520af 100644 (file)
@@ -1014,48 +1014,72 @@ int t4vf_alloc_mac_filt(struct adapter *adapter, unsigned int viid, bool free,
                        unsigned int naddr, const u8 **addr, u16 *idx,
                        u64 *hash, bool sleep_ok)
 {
-       int i, ret;
+       int offset, ret = 0;
+       unsigned nfilters = 0;
+       unsigned int rem = naddr;
        struct fw_vi_mac_cmd cmd, rpl;
-       struct fw_vi_mac_exact *p;
-       size_t len16;
 
-       if (naddr > ARRAY_SIZE(cmd.u.exact))
+       if (naddr > FW_CLS_TCAM_NUM_ENTRIES)
                return -EINVAL;
-       len16 = DIV_ROUND_UP(offsetof(struct fw_vi_mac_cmd,
-                                     u.exact[naddr]), 16);
 
-       memset(&cmd, 0, sizeof(cmd));
-       cmd.op_to_viid = cpu_to_be32(FW_CMD_OP(FW_VI_MAC_CMD) |
-                                    FW_CMD_REQUEST |
-                                    FW_CMD_WRITE |
-                                    (free ? FW_CMD_EXEC : 0) |
-                                    FW_VI_MAC_CMD_VIID(viid));
-       cmd.freemacs_to_len16 = cpu_to_be32(FW_VI_MAC_CMD_FREEMACS(free) |
-                                           FW_CMD_LEN16(len16));
+       for (offset = 0; offset < naddr; /**/) {
+               unsigned int fw_naddr = (rem < ARRAY_SIZE(cmd.u.exact)
+                                        ? rem
+                                        : ARRAY_SIZE(cmd.u.exact));
+               size_t len16 = DIV_ROUND_UP(offsetof(struct fw_vi_mac_cmd,
+                                                    u.exact[fw_naddr]), 16);
+               struct fw_vi_mac_exact *p;
+               int i;
 
-       for (i = 0, p = cmd.u.exact; i < naddr; i++, p++) {
-               p->valid_to_idx =
-                       cpu_to_be16(FW_VI_MAC_CMD_VALID |
-                                   FW_VI_MAC_CMD_IDX(FW_VI_MAC_ADD_MAC));
-               memcpy(p->macaddr, addr[i], sizeof(p->macaddr));
-       }
+               memset(&cmd, 0, sizeof(cmd));
+               cmd.op_to_viid = cpu_to_be32(FW_CMD_OP(FW_VI_MAC_CMD) |
+                                            FW_CMD_REQUEST |
+                                            FW_CMD_WRITE |
+                                            (free ? FW_CMD_EXEC : 0) |
+                                            FW_VI_MAC_CMD_VIID(viid));
+               cmd.freemacs_to_len16 =
+                       cpu_to_be32(FW_VI_MAC_CMD_FREEMACS(free) |
+                                   FW_CMD_LEN16(len16));
+
+               for (i = 0, p = cmd.u.exact; i < fw_naddr; i++, p++) {
+                       p->valid_to_idx = cpu_to_be16(
+                               FW_VI_MAC_CMD_VALID |
+                               FW_VI_MAC_CMD_IDX(FW_VI_MAC_ADD_MAC));
+                       memcpy(p->macaddr, addr[offset+i], sizeof(p->macaddr));
+               }
+
+
+               ret = t4vf_wr_mbox_core(adapter, &cmd, sizeof(cmd), &rpl,
+                                       sleep_ok);
+               if (ret && ret != -ENOMEM)
+                       break;
 
-       ret = t4vf_wr_mbox_core(adapter, &cmd, sizeof(cmd), &rpl, sleep_ok);
-       if (ret)
-               return ret;
-
-       for (i = 0, p = rpl.u.exact; i < naddr; i++, p++) {
-               u16 index = FW_VI_MAC_CMD_IDX_GET(be16_to_cpu(p->valid_to_idx));
-
-               if (idx)
-                       idx[i] = (index >= FW_CLS_TCAM_NUM_ENTRIES
-                                 ? 0xffff
-                                 : index);
-               if (index < FW_CLS_TCAM_NUM_ENTRIES)
-                       ret++;
-               else if (hash)
-                       *hash |= (1 << hash_mac_addr(addr[i]));
+               for (i = 0, p = rpl.u.exact; i < fw_naddr; i++, p++) {
+                       u16 index = FW_VI_MAC_CMD_IDX_GET(
+                               be16_to_cpu(p->valid_to_idx));
+
+                       if (idx)
+                               idx[offset+i] =
+                                       (index >= FW_CLS_TCAM_NUM_ENTRIES
+                                        ? 0xffff
+                                        : index);
+                       if (index < FW_CLS_TCAM_NUM_ENTRIES)
+                               nfilters++;
+                       else if (hash)
+                               *hash |= (1ULL << hash_mac_addr(addr[offset+i]));
+               }
+
+               free = false;
+               offset += fw_naddr;
+               rem -= fw_naddr;
        }
+
+       /*
+        * If there were no errors or we merely ran out of room in our MAC
+        * address arena, return the number of filters actually written.
+        */
+       if (ret == 0 || ret == -ENOMEM)
+               ret = nfilters;
        return ret;
 }
 
index 75b099c..1f37ee6 100644 (file)
@@ -261,6 +261,13 @@ static void ehea_get_ethtool_stats(struct net_device *dev,
 
 }
 
+static int ehea_set_flags(struct net_device *dev, u32 data)
+{
+       return ethtool_op_set_flags(dev, data, ETH_FLAG_LRO
+                                       | ETH_FLAG_TXVLAN
+                                       | ETH_FLAG_RXVLAN);
+}
+
 const struct ethtool_ops ehea_ethtool_ops = {
        .get_settings = ehea_get_settings,
        .get_drvinfo = ehea_get_drvinfo,
@@ -273,6 +280,8 @@ const struct ethtool_ops ehea_ethtool_ops = {
        .get_ethtool_stats = ehea_get_ethtool_stats,
        .get_rx_csum = ehea_get_rx_csum,
        .set_settings = ehea_set_settings,
+       .get_flags = ethtool_op_get_flags,
+       .set_flags = ehea_set_flags,
        .nway_reset = ehea_nway_reset,          /* Restart autonegotiation */
 };
 
index 182b2a7..b95f087 100644 (file)
@@ -400,6 +400,7 @@ static void ehea_refill_rq1(struct ehea_port_res *pr, int index, int nr_of_wqes)
                        skb_arr_rq1[index] = netdev_alloc_skb(dev,
                                                              EHEA_L_PKT_SIZE);
                        if (!skb_arr_rq1[index]) {
+                               ehea_info("Unable to allocate enough skb in the array\n");
                                pr->rq1_skba.os_skbs = fill_wqes - i;
                                break;
                        }
@@ -422,13 +423,20 @@ static void ehea_init_fill_rq1(struct ehea_port_res *pr, int nr_rq1a)
        struct net_device *dev = pr->port->netdev;
        int i;
 
-       for (i = 0; i < pr->rq1_skba.len; i++) {
+       if (nr_rq1a > pr->rq1_skba.len) {
+               ehea_error("NR_RQ1A bigger than skb array len\n");
+               return;
+       }
+
+       for (i = 0; i < nr_rq1a; i++) {
                skb_arr_rq1[i] = netdev_alloc_skb(dev, EHEA_L_PKT_SIZE);
-               if (!skb_arr_rq1[i])
+               if (!skb_arr_rq1[i]) {
+                       ehea_info("No enough memory to allocate skb array\n");
                        break;
+               }
        }
        /* Ring doorbell */
-       ehea_update_rq1a(pr->qp, nr_rq1a);
+       ehea_update_rq1a(pr->qp, i);
 }
 
 static int ehea_refill_rq_def(struct ehea_port_res *pr,
@@ -675,7 +683,7 @@ static void ehea_proc_skb(struct ehea_port_res *pr, struct ehea_cqe *cqe,
        int vlan_extracted = ((cqe->status & EHEA_CQE_VLAN_TAG_XTRACT) &&
                              pr->port->vgrp);
 
-       if (use_lro) {
+       if (skb->dev->features & NETIF_F_LRO) {
                if (vlan_extracted)
                        lro_vlan_hwaccel_receive_skb(&pr->lro_mgr, skb,
                                                     pr->port->vgrp,
@@ -735,8 +743,10 @@ static int ehea_proc_rwqes(struct net_device *dev,
 
                                        skb = netdev_alloc_skb(dev,
                                                               EHEA_L_PKT_SIZE);
-                                       if (!skb)
+                                       if (!skb) {
+                                               ehea_info("Not enough memory to allocate skb\n");
                                                break;
+                                       }
                                }
                                skb_copy_to_linear_data(skb, ((char *)cqe) + 64,
                                                 cqe->num_bytes_transfered - 4);
@@ -777,7 +787,7 @@ static int ehea_proc_rwqes(struct net_device *dev,
                }
                cqe = ehea_poll_rq1(qp, &wqe_index);
        }
-       if (use_lro)
+       if (dev->features & NETIF_F_LRO)
                lro_flush_all(&pr->lro_mgr);
 
        pr->rx_packets += processed;
@@ -3268,6 +3278,9 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter,
                      | NETIF_F_LLTX;
        dev->watchdog_timeo = EHEA_WATCH_DOG_TIMEOUT;
 
+       if (use_lro)
+               dev->features |= NETIF_F_LRO;
+
        INIT_WORK(&port->reset_task, ehea_reset_port);
 
        ret = register_netdev(dev);
index a466ef9..aa28b27 100644 (file)
@@ -1962,7 +1962,8 @@ static void enic_poll_controller(struct net_device *netdev)
        case VNIC_DEV_INTR_MODE_MSIX:
                for (i = 0; i < enic->rq_count; i++) {
                        intr = enic_msix_rq_intr(enic, i);
-                       enic_isr_msix_rq(enic->msix_entry[intr].vector, enic);
+                       enic_isr_msix_rq(enic->msix_entry[intr].vector,
+                               &enic->napi[i]);
                }
                intr = enic_msix_wq_intr(enic, i);
                enic_isr_msix_wq(enic->msix_entry[intr].vector, enic);
index ab9f675..fe337bd 100644 (file)
@@ -104,6 +104,8 @@ static void ri_tasklet(unsigned long dev)
                        rcu_read_unlock();
                        dev_kfree_skb(skb);
                        stats->tx_dropped++;
+                       if (skb_queue_len(&dp->tq) != 0)
+                               goto resched;
                        break;
                }
                rcu_read_unlock();
index fbad4d8..eee0b29 100644 (file)
@@ -4771,6 +4771,9 @@ void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter)
                adapter->rx_ring[i] = NULL;
        }
 
+       adapter->num_tx_queues = 0;
+       adapter->num_rx_queues = 0;
+
        ixgbe_free_q_vectors(adapter);
        ixgbe_reset_interrupt_capability(adapter);
 }
index b68eee2..7a7e18b 100644 (file)
@@ -289,6 +289,10 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
                MLX4_GET(field, outbox, QUERY_DEV_CAP_LOG_BF_REG_SZ_OFFSET);
                dev_cap->bf_reg_size = 1 << (field & 0x1f);
                MLX4_GET(field, outbox, QUERY_DEV_CAP_LOG_MAX_BF_REGS_PER_PAGE_OFFSET);
+               if ((1 << (field & 0x3f)) > (PAGE_SIZE / dev_cap->bf_reg_size)) {
+                       mlx4_warn(dev, "firmware bug: log2 # of blue flame regs is invalid (%d), forcing 3\n", field & 0x1f);
+                       field = 3;
+               }
                dev_cap->bf_regs_per_page = 1 << (field & 0x3f);
                mlx4_dbg(dev, "BlueFlame available (reg size %d, regs/page %d)\n",
                         dev_cap->bf_reg_size, dev_cap->bf_regs_per_page);
index 472056b..03a1d28 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 1999 - 2010 Intel Corporation.
- * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.
+ * Copyright (C) 2010 OKI SEMICONDUCTOR CO., LTD.
  *
  * This code was derived from the Intel e1000e Linux driver.
  *
@@ -2464,8 +2464,8 @@ static void __exit pch_gbe_exit_module(void)
 module_init(pch_gbe_init_module);
 module_exit(pch_gbe_exit_module);
 
-MODULE_DESCRIPTION("OKI semiconductor PCH Gigabit ethernet Driver");
-MODULE_AUTHOR("OKI semiconductor, <masa-korg@dsn.okisemi.com>");
+MODULE_DESCRIPTION("EG20T PCH Gigabit ethernet Driver");
+MODULE_AUTHOR("OKI SEMICONDUCTOR, <toshiharu-linux@dsn.okisemi.com>");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
 MODULE_DEVICE_TABLE(pci, pch_gbe_pcidev_id);
index 2510146..ef0996a 100644 (file)
@@ -434,8 +434,8 @@ void pch_gbe_check_options(struct pch_gbe_adapter *adapter)
                        .err  = "using default of "
                                __MODULE_STRING(PCH_GBE_DEFAULT_TXD),
                        .def  = PCH_GBE_DEFAULT_TXD,
-                       .arg  = { .r = { .min = PCH_GBE_MIN_TXD } },
-                       .arg  = { .r = { .max = PCH_GBE_MAX_TXD } }
+                       .arg  = { .r = { .min = PCH_GBE_MIN_TXD,
+                                        .max = PCH_GBE_MAX_TXD } }
                };
                struct pch_gbe_tx_ring *tx_ring = adapter->tx_ring;
                tx_ring->count = TxDescriptors;
@@ -450,8 +450,8 @@ void pch_gbe_check_options(struct pch_gbe_adapter *adapter)
                        .err  = "using default of "
                                __MODULE_STRING(PCH_GBE_DEFAULT_RXD),
                        .def  = PCH_GBE_DEFAULT_RXD,
-                       .arg  = { .r = { .min = PCH_GBE_MIN_RXD } },
-                       .arg  = { .r = { .max = PCH_GBE_MAX_RXD } }
+                       .arg  = { .r = { .min = PCH_GBE_MIN_RXD,
+                                        .max = PCH_GBE_MAX_RXD } }
                };
                struct pch_gbe_rx_ring *rx_ring = adapter->rx_ring;
                rx_ring->count = RxDescriptors;
index cb3d13e..35fda5a 100644 (file)
@@ -64,7 +64,7 @@ config BCM63XX_PHY
 config ICPLUS_PHY
        tristate "Drivers for ICPlus PHYs"
        ---help---
-         Currently supports the IP175C PHY.
+         Currently supports the IP175C and IP1001 PHYs.
 
 config REALTEK_PHY
        tristate "Drivers for Realtek PHYs"
index c1d2d25..9a09e24 100644 (file)
@@ -30,7 +30,7 @@
 #include <asm/irq.h>
 #include <asm/uaccess.h>
 
-MODULE_DESCRIPTION("ICPlus IP175C PHY driver");
+MODULE_DESCRIPTION("ICPlus IP175C/IC1001 PHY drivers");
 MODULE_AUTHOR("Michael Barkowski");
 MODULE_LICENSE("GPL");
 
@@ -89,6 +89,33 @@ static int ip175c_config_init(struct phy_device *phydev)
        return 0;
 }
 
+static int ip1001_config_init(struct phy_device *phydev)
+{
+       int err, value;
+
+       /* Software Reset PHY */
+       value = phy_read(phydev, MII_BMCR);
+       value |= BMCR_RESET;
+       err = phy_write(phydev, MII_BMCR, value);
+       if (err < 0)
+               return err;
+
+       do {
+               value = phy_read(phydev, MII_BMCR);
+       } while (value & BMCR_RESET);
+
+       /* Additional delay (2ns) used to adjust RX clock phase
+        * at GMII/ RGMII interface */
+       value = phy_read(phydev, 16);
+       value |= 0x3;
+
+       err = phy_write(phydev, 16, value);
+       if (err < 0)
+               return err;
+
+       return err;
+}
+
 static int ip175c_read_status(struct phy_device *phydev)
 {
        if (phydev->addr == 4) /* WAN port */
@@ -121,21 +148,43 @@ static struct phy_driver ip175c_driver = {
        .driver         = { .owner = THIS_MODULE,},
 };
 
-static int __init ip175c_init(void)
+static struct phy_driver ip1001_driver = {
+       .phy_id         = 0x02430d90,
+       .name           = "ICPlus IP1001",
+       .phy_id_mask    = 0x0ffffff0,
+       .features       = PHY_GBIT_FEATURES | SUPPORTED_Pause |
+                         SUPPORTED_Asym_Pause,
+       .config_init    = &ip1001_config_init,
+       .config_aneg    = &genphy_config_aneg,
+       .read_status    = &genphy_read_status,
+       .suspend        = genphy_suspend,
+       .resume         = genphy_resume,
+       .driver         = { .owner = THIS_MODULE,},
+};
+
+static int __init icplus_init(void)
 {
+       int ret = 0;
+
+       ret = phy_driver_register(&ip1001_driver);
+       if (ret < 0)
+               return -ENODEV;
+
        return phy_driver_register(&ip175c_driver);
 }
 
-static void __exit ip175c_exit(void)
+static void __exit icplus_exit(void)
 {
+       phy_driver_unregister(&ip1001_driver);
        phy_driver_unregister(&ip175c_driver);
 }
 
-module_init(ip175c_init);
-module_exit(ip175c_exit);
+module_init(icplus_init);
+module_exit(icplus_exit);
 
 static struct mdio_device_id __maybe_unused icplus_tbl[] = {
        { 0x02430d80, 0x0ffffff0 },
+       { 0x02430d90, 0x0ffffff0 },
        { }
 };
 
index 09cf56d..3965997 100644 (file)
@@ -2584,16 +2584,16 @@ ppp_create_interface(struct net *net, int unit, int *retp)
         */
        dev_net_set(dev, net);
 
-       ret = -EEXIST;
        mutex_lock(&pn->all_ppp_mutex);
 
        if (unit < 0) {
                unit = unit_get(&pn->units_idr, ppp);
                if (unit < 0) {
-                       *retp = unit;
+                       ret = unit;
                        goto out2;
                }
        } else {
+               ret = -EEXIST;
                if (unit_find(&pn->units_idr, unit))
                        goto out2; /* unit already exists */
                /*
@@ -2668,10 +2668,10 @@ static void ppp_shutdown_interface(struct ppp *ppp)
                ppp->closing = 1;
                ppp_unlock(ppp);
                unregister_netdev(ppp->dev);
+               unit_put(&pn->units_idr, ppp->file.index);
        } else
                ppp_unlock(ppp);
 
-       unit_put(&pn->units_idr, ppp->file.index);
        ppp->file.dead = 1;
        ppp->owner = NULL;
        wake_up_interruptible(&ppp->file.rwait);
@@ -2859,8 +2859,7 @@ static void __exit ppp_cleanup(void)
  * by holding all_ppp_mutex
  */
 
-/* associate pointer with specified number */
-static int unit_set(struct idr *p, void *ptr, int n)
+static int __unit_alloc(struct idr *p, void *ptr, int n)
 {
        int unit, err;
 
@@ -2871,10 +2870,24 @@ again:
        }
 
        err = idr_get_new_above(p, ptr, n, &unit);
-       if (err == -EAGAIN)
-               goto again;
+       if (err < 0) {
+               if (err == -EAGAIN)
+                       goto again;
+               return err;
+       }
+
+       return unit;
+}
+
+/* associate pointer with specified number */
+static int unit_set(struct idr *p, void *ptr, int n)
+{
+       int unit;
 
-       if (unit != n) {
+       unit = __unit_alloc(p, ptr, n);
+       if (unit < 0)
+               return unit;
+       else if (unit != n) {
                idr_remove(p, unit);
                return -EINVAL;
        }
@@ -2885,19 +2898,7 @@ again:
 /* get new free unit number and associate pointer with it */
 static int unit_get(struct idr *p, void *ptr)
 {
-       int unit, err;
-
-again:
-       if (!idr_pre_get(p, GFP_KERNEL)) {
-               printk(KERN_ERR "PPP: No free memory for idr\n");
-               return -ENOMEM;
-       }
-
-       err = idr_get_new_above(p, ptr, 0, &unit);
-       if (err == -EAGAIN)
-               goto again;
-
-       return unit;
+       return __unit_alloc(p, ptr, 0);
 }
 
 /* put unit number back to a pool */
index d72fb05..78c0e3c 100644 (file)
@@ -948,7 +948,7 @@ static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb)
 
 abort:
        kfree_skb(skb);
-       return 0;
+       return 1;
 }
 
 /************************************************************************
index 2282139..9787dff 100644 (file)
@@ -2083,6 +2083,7 @@ struct ql_adapter {
        u32 mailbox_in;
        u32 mailbox_out;
        struct mbox_params idc_mbc;
+       struct mutex    mpi_mutex;
 
        int tx_ring_size;
        int rx_ring_size;
index 528eaef..2555b1d 100644 (file)
@@ -4629,6 +4629,7 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
        INIT_DELAYED_WORK(&qdev->mpi_idc_work, ql_mpi_idc_work);
        INIT_DELAYED_WORK(&qdev->mpi_core_to_log, ql_mpi_core_to_log);
        init_completion(&qdev->ide_completion);
+       mutex_init(&qdev->mpi_mutex);
 
        if (!cards_found) {
                dev_info(&pdev->dev, "%s\n", DRV_STRING);
index 0e7c7c7..a2e919b 100644 (file)
@@ -534,6 +534,7 @@ static int ql_mailbox_command(struct ql_adapter *qdev, struct mbox_params *mbcp)
        int status;
        unsigned long count;
 
+       mutex_lock(&qdev->mpi_mutex);
 
        /* Begin polled mode for MPI */
        ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16));
@@ -603,6 +604,7 @@ done:
 end:
        /* End polled mode for MPI */
        ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16) | INTR_MASK_PI);
+       mutex_unlock(&qdev->mpi_mutex);
        return status;
 }
 
@@ -1099,9 +1101,7 @@ int ql_wait_fifo_empty(struct ql_adapter *qdev)
 static int ql_set_port_cfg(struct ql_adapter *qdev)
 {
        int status;
-       rtnl_lock();
        status = ql_mb_set_port_cfg(qdev);
-       rtnl_unlock();
        if (status)
                return status;
        status = ql_idc_wait(qdev);
@@ -1122,9 +1122,7 @@ void ql_mpi_port_cfg_work(struct work_struct *work)
            container_of(work, struct ql_adapter, mpi_port_cfg_work.work);
        int status;
 
-       rtnl_lock();
        status = ql_mb_get_port_cfg(qdev);
-       rtnl_unlock();
        if (status) {
                netif_err(qdev, drv, qdev->ndev,
                          "Bug: Failed to get port config data.\n");
@@ -1167,7 +1165,6 @@ void ql_mpi_idc_work(struct work_struct *work)
        u32 aen;
        int timeout;
 
-       rtnl_lock();
        aen = mbcp->mbox_out[1] >> 16;
        timeout = (mbcp->mbox_out[1] >> 8) & 0xf;
 
@@ -1231,7 +1228,6 @@ void ql_mpi_idc_work(struct work_struct *work)
                }
                break;
        }
-       rtnl_unlock();
 }
 
 void ql_mpi_work(struct work_struct *work)
@@ -1242,7 +1238,7 @@ void ql_mpi_work(struct work_struct *work)
        struct mbox_params *mbcp = &mbc;
        int err = 0;
 
-       rtnl_lock();
+       mutex_lock(&qdev->mpi_mutex);
        /* Begin polled mode for MPI */
        ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16));
 
@@ -1259,7 +1255,7 @@ void ql_mpi_work(struct work_struct *work)
 
        /* End polled mode for MPI */
        ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16) | INTR_MASK_PI);
-       rtnl_unlock();
+       mutex_unlock(&qdev->mpi_mutex);
        ql_enable_completion_interrupt(qdev, 0);
 }
 
index 7d33ef4..53b13de 100644 (file)
@@ -744,26 +744,36 @@ static void rtl8169_xmii_reset_enable(void __iomem *ioaddr)
        mdio_write(ioaddr, MII_BMCR, val & 0xffff);
 }
 
-static void rtl8169_check_link_status(struct net_device *dev,
+static void __rtl8169_check_link_status(struct net_device *dev,
                                      struct rtl8169_private *tp,
-                                     void __iomem *ioaddr)
+                                     void __iomem *ioaddr,
+                                     bool pm)
 {
        unsigned long flags;
 
        spin_lock_irqsave(&tp->lock, flags);
        if (tp->link_ok(ioaddr)) {
                /* This is to cancel a scheduled suspend if there's one. */
-               pm_request_resume(&tp->pci_dev->dev);
+               if (pm)
+                       pm_request_resume(&tp->pci_dev->dev);
                netif_carrier_on(dev);
                netif_info(tp, ifup, dev, "link up\n");
        } else {
                netif_carrier_off(dev);
                netif_info(tp, ifdown, dev, "link down\n");
-               pm_schedule_suspend(&tp->pci_dev->dev, 100);
+               if (pm)
+                       pm_schedule_suspend(&tp->pci_dev->dev, 100);
        }
        spin_unlock_irqrestore(&tp->lock, flags);
 }
 
+static void rtl8169_check_link_status(struct net_device *dev,
+                                     struct rtl8169_private *tp,
+                                     void __iomem *ioaddr)
+{
+       __rtl8169_check_link_status(dev, tp, ioaddr, false);
+}
+
 #define WAKE_ANY (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST)
 
 static u32 __rtl8169_get_wol(struct rtl8169_private *tp)
@@ -4600,7 +4610,7 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
                }
 
                if (status & LinkChg)
-                       rtl8169_check_link_status(dev, tp, ioaddr);
+                       __rtl8169_check_link_status(dev, tp, ioaddr, true);
 
                /* We need to see the lastest version of tp->intr_mask to
                 * avoid ignoring an MSI interrupt and having to wait for
@@ -4890,11 +4900,7 @@ static int rtl8169_runtime_idle(struct device *device)
        struct net_device *dev = pci_get_drvdata(pdev);
        struct rtl8169_private *tp = netdev_priv(dev);
 
-       if (!tp->TxDescArray)
-               return 0;
-
-       rtl8169_check_link_status(dev, tp, tp->mmio_addr);
-       return -EBUSY;
+       return tp->TxDescArray ? -EBUSY : 0;
 }
 
 static const struct dev_pm_ops rtl8169_pm_ops = {
index 05df20e..fb83cdd 100644 (file)
@@ -197,7 +197,9 @@ MODULE_PARM_DESC(debug, "Bitmapped debugging message enable value");
 
 static void efx_remove_channels(struct efx_nic *efx);
 static void efx_remove_port(struct efx_nic *efx);
+static void efx_init_napi(struct efx_nic *efx);
 static void efx_fini_napi(struct efx_nic *efx);
+static void efx_fini_napi_channel(struct efx_channel *channel);
 static void efx_fini_struct(struct efx_nic *efx);
 static void efx_start_all(struct efx_nic *efx);
 static void efx_stop_all(struct efx_nic *efx);
@@ -335,8 +337,10 @@ void efx_process_channel_now(struct efx_channel *channel)
 
        /* Disable interrupts and wait for ISRs to complete */
        efx_nic_disable_interrupts(efx);
-       if (efx->legacy_irq)
+       if (efx->legacy_irq) {
                synchronize_irq(efx->legacy_irq);
+               efx->legacy_irq_enabled = false;
+       }
        if (channel->irq)
                synchronize_irq(channel->irq);
 
@@ -351,6 +355,8 @@ void efx_process_channel_now(struct efx_channel *channel)
        efx_channel_processed(channel);
 
        napi_enable(&channel->napi_str);
+       if (efx->legacy_irq)
+               efx->legacy_irq_enabled = true;
        efx_nic_enable_interrupts(efx);
 }
 
@@ -426,6 +432,7 @@ efx_alloc_channel(struct efx_nic *efx, int i, struct efx_channel *old_channel)
 
                *channel = *old_channel;
 
+               channel->napi_dev = NULL;
                memset(&channel->eventq, 0, sizeof(channel->eventq));
 
                rx_queue = &channel->rx_queue;
@@ -736,9 +743,13 @@ efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries)
        if (rc)
                goto rollback;
 
+       efx_init_napi(efx);
+
        /* Destroy old channels */
-       for (i = 0; i < efx->n_channels; i++)
+       for (i = 0; i < efx->n_channels; i++) {
+               efx_fini_napi_channel(other_channel[i]);
                efx_remove_channel(other_channel[i]);
+       }
 out:
        /* Free unused channel structures */
        for (i = 0; i < efx->n_channels; i++)
@@ -1400,6 +1411,8 @@ static void efx_start_all(struct efx_nic *efx)
                efx_start_channel(channel);
        }
 
+       if (efx->legacy_irq)
+               efx->legacy_irq_enabled = true;
        efx_nic_enable_interrupts(efx);
 
        /* Switch to event based MCDI completions after enabling interrupts.
@@ -1460,8 +1473,10 @@ static void efx_stop_all(struct efx_nic *efx)
 
        /* Disable interrupts and wait for ISR to complete */
        efx_nic_disable_interrupts(efx);
-       if (efx->legacy_irq)
+       if (efx->legacy_irq) {
                synchronize_irq(efx->legacy_irq);
+               efx->legacy_irq_enabled = false;
+       }
        efx_for_each_channel(channel, efx) {
                if (channel->irq)
                        synchronize_irq(channel->irq);
@@ -1593,7 +1608,7 @@ static int efx_ioctl(struct net_device *net_dev, struct ifreq *ifr, int cmd)
  *
  **************************************************************************/
 
-static int efx_init_napi(struct efx_nic *efx)
+static void efx_init_napi(struct efx_nic *efx)
 {
        struct efx_channel *channel;
 
@@ -1602,18 +1617,21 @@ static int efx_init_napi(struct efx_nic *efx)
                netif_napi_add(channel->napi_dev, &channel->napi_str,
                               efx_poll, napi_weight);
        }
-       return 0;
+}
+
+static void efx_fini_napi_channel(struct efx_channel *channel)
+{
+       if (channel->napi_dev)
+               netif_napi_del(&channel->napi_str);
+       channel->napi_dev = NULL;
 }
 
 static void efx_fini_napi(struct efx_nic *efx)
 {
        struct efx_channel *channel;
 
-       efx_for_each_channel(channel, efx) {
-               if (channel->napi_dev)
-                       netif_napi_del(&channel->napi_str);
-               channel->napi_dev = NULL;
-       }
+       efx_for_each_channel(channel, efx)
+               efx_fini_napi_channel(channel);
 }
 
 /**************************************************************************
@@ -2335,9 +2353,7 @@ static int efx_pci_probe_main(struct efx_nic *efx)
        if (rc)
                goto fail1;
 
-       rc = efx_init_napi(efx);
-       if (rc)
-               goto fail2;
+       efx_init_napi(efx);
 
        rc = efx->type->init(efx);
        if (rc) {
@@ -2368,7 +2384,6 @@ static int efx_pci_probe_main(struct efx_nic *efx)
        efx->type->fini(efx);
  fail3:
        efx_fini_napi(efx);
- fail2:
        efx_remove_all(efx);
  fail1:
        return rc;
index 0a7e26d..b137c88 100644 (file)
@@ -621,6 +621,7 @@ struct efx_filter_state;
  * @pci_dev: The PCI device
  * @type: Controller type attributes
  * @legacy_irq: IRQ number
+ * @legacy_irq_enabled: Are IRQs enabled on NIC (INT_EN_KER register)?
  * @workqueue: Workqueue for port reconfigures and the HW monitor.
  *     Work items do not hold and must not acquire RTNL.
  * @workqueue_name: Name of workqueue
@@ -709,6 +710,7 @@ struct efx_nic {
        struct pci_dev *pci_dev;
        const struct efx_nic_type *type;
        int legacy_irq;
+       bool legacy_irq_enabled;
        struct workqueue_struct *workqueue;
        char workqueue_name[16];
        struct work_struct reset_work;
index 41c36b9..67cb0c9 100644 (file)
@@ -1418,6 +1418,12 @@ static irqreturn_t efx_legacy_interrupt(int irq, void *dev_id)
        u32 queues;
        int syserr;
 
+       /* Could this be ours?  If interrupts are disabled then the
+        * channel state may not be valid.
+        */
+       if (!efx->legacy_irq_enabled)
+               return result;
+
        /* Read the ISR which also ACKs the interrupts */
        efx_readd(efx, &reg, FR_BZ_INT_ISR0);
        queues = EFX_EXTRACT_DWORD(reg, 0, 31);
index 06bc603..2114837 100644 (file)
@@ -1509,6 +1509,8 @@ static int stmmac_probe(struct net_device *dev)
                pr_warning("\tno valid MAC address;"
                        "please, use ifconfig or nwhwconfig!\n");
 
+       spin_lock_init(&priv->lock);
+
        ret = register_netdev(dev);
        if (ret) {
                pr_err("%s: ERROR %i registering the device\n",
@@ -1520,8 +1522,6 @@ static int stmmac_probe(struct net_device *dev)
            dev->name, (dev->features & NETIF_F_SG) ? "on" : "off",
            (dev->features & NETIF_F_HW_CSUM) ? "on" : "off");
 
-       spin_lock_init(&priv->lock);
-
        return ret;
 }
 
index a9f7d5d..7064e03 100644 (file)
@@ -688,9 +688,6 @@ static netdev_tx_t dmfe_start_xmit(struct sk_buff *skb,
 
        DMFE_DBUG(0, "dmfe_start_xmit", 0);
 
-       /* Resource flag check */
-       netif_stop_queue(dev);
-
        /* Too large packet check */
        if (skb->len > MAX_PACKET_SIZE) {
                pr_err("big packet = %d\n", (u16)skb->len);
@@ -698,6 +695,9 @@ static netdev_tx_t dmfe_start_xmit(struct sk_buff *skb,
                return NETDEV_TX_OK;
        }
 
+       /* Resource flag check */
+       netif_stop_queue(dev);
+
        spin_lock_irqsave(&db->lock, flags);
 
        /* No Tx resource check, it never happen nromally */
index 05a9558..055b87a 100644 (file)
@@ -899,7 +899,8 @@ struct ucc_geth_hardware_statistics {
 #define UCC_GETH_UTFS_INIT                      512    /* Tx virtual FIFO size
                                                         */
 #define UCC_GETH_UTFET_INIT                     256    /* 1/2 utfs */
-#define UCC_GETH_UTFTT_INIT                     512
+#define UCC_GETH_UTFTT_INIT                     256    /* 1/2 utfs
+                                                          due to errata */
 /* Gigabit Ethernet (1000 Mbps) */
 #define UCC_GETH_URFS_GIGA_INIT                 4096/*2048*/   /* Rx virtual
                                                                   FIFO size */
index b154a94..812edf8 100644 (file)
@@ -958,10 +958,6 @@ static void packetizeRx(struct hso_net *odev, unsigned char *ip_pkt,
                                /* Packet is complete. Inject into stack. */
                                /* We have IP packet here */
                                odev->skb_rx_buf->protocol = cpu_to_be16(ETH_P_IP);
-                               /* don't check it */
-                               odev->skb_rx_buf->ip_summed =
-                                       CHECKSUM_UNNECESSARY;
-
                                skb_reset_mac_header(odev->skb_rx_buf);
 
                                /* Ship it off to the kernel */
@@ -2994,12 +2990,14 @@ static int hso_probe(struct usb_interface *interface,
 
        case HSO_INTF_BULK:
                /* It's a regular bulk interface */
-               if (((port_spec & HSO_PORT_MASK) == HSO_PORT_NETWORK) &&
-                   !disable_net)
-                       hso_dev = hso_create_net_device(interface, port_spec);
-               else
+               if ((port_spec & HSO_PORT_MASK) == HSO_PORT_NETWORK) {
+                       if (!disable_net)
+                               hso_dev =
+                                   hso_create_net_device(interface, port_spec);
+               } else {
                        hso_dev =
                            hso_create_bulk_serial_device(interface, port_spec);
+               }
                if (!hso_dev)
                        goto exit;
                break;
index ea476cb..e305274 100644 (file)
@@ -293,6 +293,7 @@ static inline void sca_tx_done(port_t *port)
        struct net_device *dev = port->netdev;
        card_t* card = port->card;
        u8 stat;
+       unsigned count = 0;
 
        spin_lock(&port->lock);
 
@@ -316,10 +317,12 @@ static inline void sca_tx_done(port_t *port)
                        dev->stats.tx_bytes += readw(&desc->len);
                }
                writeb(0, &desc->stat); /* Free descriptor */
+               count++;
                port->txlast = (port->txlast + 1) % card->tx_ring_buffers;
        }
 
-       netif_wake_queue(dev);
+       if (count)
+               netif_wake_queue(dev);
        spin_unlock(&port->lock);
 }
 
index d81ad83..24297b2 100644 (file)
@@ -498,7 +498,6 @@ norbuff:
 static int x25_asy_close(struct net_device *dev)
 {
        struct x25_asy *sl = netdev_priv(dev);
-       int err;
 
        spin_lock(&sl->lock);
        if (sl->tty)
@@ -507,10 +506,6 @@ static int x25_asy_close(struct net_device *dev)
        netif_stop_queue(dev);
        sl->rcount = 0;
        sl->xleft  = 0;
-       err = lapb_unregister(dev);
-       if (err != LAPB_OK)
-               printk(KERN_ERR "x25_asy_close: lapb_unregister error -%d\n",
-                       err);
        spin_unlock(&sl->lock);
        return 0;
 }
@@ -582,7 +577,7 @@ static int x25_asy_open_tty(struct tty_struct *tty)
        if (err)
                return err;
        /* Done.  We have linked the TTY line to a channel. */
-       return sl->dev->base_addr;
+       return 0;
 }
 
 
@@ -595,6 +590,7 @@ static int x25_asy_open_tty(struct tty_struct *tty)
 static void x25_asy_close_tty(struct tty_struct *tty)
 {
        struct x25_asy *sl = tty->disc_data;
+       int err;
 
        /* First make sure we're connected. */
        if (!sl || sl->magic != X25_ASY_MAGIC)
@@ -605,6 +601,11 @@ static void x25_asy_close_tty(struct tty_struct *tty)
                dev_close(sl->dev);
        rtnl_unlock();
 
+       err = lapb_unregister(sl->dev);
+       if (err != LAPB_OK)
+               printk(KERN_ERR "x25_asy_close: lapb_unregister error -%d\n",
+                       err);
+
        tty->disc_data = NULL;
        sl->tty = NULL;
        x25_asy_free(sl);
index 8251946..42ed923 100644 (file)
@@ -1917,7 +1917,8 @@ ath5k_beacon_send(struct ath5k_softc *sc)
                sc->bmisscount = 0;
        }
 
-       if (sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs > 1) {
+       if ((sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs > 1) ||
+                       sc->opmode == NL80211_IFTYPE_MESH_POINT) {
                u64 tsf = ath5k_hw_get_tsf64(ah);
                u32 tsftu = TSF_TO_TU(tsf);
                int slot = ((tsftu % sc->bintval) * ATH_BCBUF) / sc->bintval;
@@ -1949,8 +1950,9 @@ ath5k_beacon_send(struct ath5k_softc *sc)
                /* NB: hw still stops DMA, so proceed */
        }
 
-       /* refresh the beacon for AP mode */
-       if (sc->opmode == NL80211_IFTYPE_AP)
+       /* refresh the beacon for AP or MESH mode */
+       if (sc->opmode == NL80211_IFTYPE_AP ||
+                       sc->opmode == NL80211_IFTYPE_MESH_POINT)
                ath5k_beacon_update(sc->hw, vif);
 
        ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr);
@@ -2851,7 +2853,8 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
 
        /* Assign the vap/adhoc to a beacon xmit slot. */
        if ((avf->opmode == NL80211_IFTYPE_AP) ||
-           (avf->opmode == NL80211_IFTYPE_ADHOC)) {
+           (avf->opmode == NL80211_IFTYPE_ADHOC) ||
+           (avf->opmode == NL80211_IFTYPE_MESH_POINT)) {
                int slot;
 
                WARN_ON(list_empty(&sc->bcbuf));
@@ -2870,7 +2873,7 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
                sc->bslot[avf->bslot] = vif;
                if (avf->opmode == NL80211_IFTYPE_AP)
                        sc->num_ap_vifs++;
-               else
+               else if (avf->opmode == NL80211_IFTYPE_ADHOC)
                        sc->num_adhoc_vifs++;
        }
 
index c418235..a7b82f0 100644 (file)
@@ -55,6 +55,8 @@
 #define SUB_NUM_CTL_MODES_AT_5G_40 2    /* excluding HT40, EXT-OFDM */
 #define SUB_NUM_CTL_MODES_AT_2G_40 3    /* excluding HT40, EXT-OFDM, EXT-CCK */
 
+#define CTL(_tpower, _flag) ((_tpower) | ((_flag) << 6))
+
 static const struct ar9300_eeprom ar9300_default = {
        .eepromVersion = 2,
        .templateVersion = 2,
@@ -290,20 +292,21 @@ static const struct ar9300_eeprom ar9300_default = {
                }
         },
        .ctlPowerData_2G = {
-                { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
-                { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
-                { { {60, 1}, {60, 0}, {60, 0}, {60, 1} } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+                { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
 
-                { { {60, 1}, {60, 0}, {0, 0}, {0, 0} } },
-                { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
-                { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
+                { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
 
-                { { {60, 0}, {60, 1}, {60, 1}, {60, 0} } },
-                { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
-                { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
 
-                { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
-                { { {60, 0}, {60, 1}, {60, 1}, {60, 1} } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
         },
        .modalHeader5G = {
                /* 4 idle,t1,t2,b (4 bits per setting) */
@@ -568,56 +571,56 @@ static const struct ar9300_eeprom ar9300_default = {
        .ctlPowerData_5G = {
                {
                        {
-                               {60, 1}, {60, 1}, {60, 1}, {60, 1},
-                               {60, 1}, {60, 1}, {60, 1}, {60, 0},
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
                        }
                },
                {
                        {
-                               {60, 1}, {60, 1}, {60, 1}, {60, 1},
-                               {60, 1}, {60, 1}, {60, 1}, {60, 0},
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
                        }
                },
                {
                        {
-                               {60, 0}, {60, 1}, {60, 0}, {60, 1},
-                               {60, 1}, {60, 1}, {60, 1}, {60, 1},
+                               CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
                        }
                },
                {
                        {
-                               {60, 0}, {60, 1}, {60, 1}, {60, 0},
-                               {60, 1}, {60, 0}, {60, 0}, {60, 0},
+                               CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+                               CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
                        }
                },
                {
                        {
-                               {60, 1}, {60, 1}, {60, 1}, {60, 0},
-                               {60, 0}, {60, 0}, {60, 0}, {60, 0},
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+                               CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
                        }
                },
                {
                        {
-                               {60, 1}, {60, 1}, {60, 1}, {60, 1},
-                               {60, 1}, {60, 0}, {60, 0}, {60, 0},
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
                        }
                },
                {
                        {
-                               {60, 1}, {60, 1}, {60, 1}, {60, 1},
-                               {60, 1}, {60, 1}, {60, 1}, {60, 1},
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
                        }
                },
                {
                        {
-                               {60, 1}, {60, 1}, {60, 0}, {60, 1},
-                               {60, 1}, {60, 1}, {60, 1}, {60, 0},
+                               CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
                        }
                },
                {
                        {
-                               {60, 1}, {60, 0}, {60, 1}, {60, 1},
-                               {60, 1}, {60, 1}, {60, 0}, {60, 1},
+                               CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
                        }
                },
         }
@@ -1827,9 +1830,9 @@ static u16 ar9003_hw_get_direct_edge_power(struct ar9300_eeprom *eep,
        struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G;
 
        if (is2GHz)
-               return ctl_2g[idx].ctlEdges[edge].tPower;
+               return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge]);
        else
-               return ctl_5g[idx].ctlEdges[edge].tPower;
+               return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge]);
 }
 
 static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep,
@@ -1847,12 +1850,12 @@ static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep,
 
        if (is2GHz) {
                if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 1) < freq &&
-                   ctl_2g[idx].ctlEdges[edge - 1].flag)
-                       return ctl_2g[idx].ctlEdges[edge - 1].tPower;
+                   CTL_EDGE_FLAGS(ctl_2g[idx].ctlEdges[edge - 1]))
+                       return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge - 1]);
        } else {
                if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 0) < freq &&
-                   ctl_5g[idx].ctlEdges[edge - 1].flag)
-                       return ctl_5g[idx].ctlEdges[edge - 1].tPower;
+                   CTL_EDGE_FLAGS(ctl_5g[idx].ctlEdges[edge - 1]))
+                       return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge - 1]);
        }
 
        return AR9300_MAX_RATE_POWER;
index 3c533bb..655b303 100644 (file)
@@ -261,17 +261,12 @@ struct cal_tgt_pow_ht {
        u8 tPow2x[14];
 } __packed;
 
-struct cal_ctl_edge_pwr {
-       u8 tPower:6,
-          flag:2;
-} __packed;
-
 struct cal_ctl_data_2g {
-       struct cal_ctl_edge_pwr ctlEdges[AR9300_NUM_BAND_EDGES_2G];
+       u8 ctlEdges[AR9300_NUM_BAND_EDGES_2G];
 } __packed;
 
 struct cal_ctl_data_5g {
-       struct cal_ctl_edge_pwr ctlEdges[AR9300_NUM_BAND_EDGES_5G];
+       u8 ctlEdges[AR9300_NUM_BAND_EDGES_5G];
 } __packed;
 
 struct ar9300_eeprom {
index 170d44a..0963071 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/device.h>
 #include <linux/leds.h>
 #include <linux/completion.h>
+#include <linux/pm_qos_params.h>
 
 #include "debug.h"
 #include "common.h"
@@ -328,7 +329,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp);
 struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype);
 void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq);
 int ath_tx_setup(struct ath_softc *sc, int haltype);
-void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx);
+bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx);
 void ath_draintxq(struct ath_softc *sc,
                     struct ath_txq *txq, bool retry_tx);
 void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an);
@@ -646,6 +647,8 @@ struct ath_softc {
        struct ath_descdma txsdma;
 
        struct ath_ant_comb ant_comb;
+
+       struct pm_qos_request_list pm_qos_req;
 };
 
 struct ath_wiphy {
@@ -675,7 +678,6 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz)
 }
 
 extern struct ieee80211_ops ath9k_ops;
-extern struct pm_qos_request_list ath9k_pm_qos_req;
 extern int modparam_nohwcrypt;
 extern int led_blink;
 
index 1266333..2bbf94d 100644 (file)
@@ -240,16 +240,16 @@ u16 ath9k_hw_get_max_edge_power(u16 freq, struct cal_ctl_edges *pRdEdgesPower,
        for (i = 0; (i < num_band_edges) &&
                     (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
                if (freq == ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel, is2GHz)) {
-                       twiceMaxEdgePower = pRdEdgesPower[i].tPower;
+                       twiceMaxEdgePower = CTL_EDGE_TPOWER(pRdEdgesPower[i].ctl);
                        break;
                } else if ((i > 0) &&
                           (freq < ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel,
                                                      is2GHz))) {
                        if (ath9k_hw_fbin2freq(pRdEdgesPower[i - 1].bChannel,
                                               is2GHz) < freq &&
-                           pRdEdgesPower[i - 1].flag) {
+                           CTL_EDGE_FLAGS(pRdEdgesPower[i - 1].ctl)) {
                                twiceMaxEdgePower =
-                                       pRdEdgesPower[i - 1].tPower;
+                                       CTL_EDGE_TPOWER(pRdEdgesPower[i - 1].ctl);
                        }
                        break;
                }
index dacb45e..dd59f09 100644 (file)
 
 #define AR9287_CHECKSUM_LOCATION (AR9287_EEP_START_LOC + 1)
 
+#define CTL_EDGE_TPOWER(_ctl) ((_ctl) & 0x3f)
+#define CTL_EDGE_FLAGS(_ctl) (((_ctl) >> 6) & 0x03)
+
+#define LNA_CTL_BUF_MODE       BIT(0)
+#define LNA_CTL_ISEL_LO                BIT(1)
+#define LNA_CTL_ISEL_HI                BIT(2)
+#define LNA_CTL_BUF_IN         BIT(3)
+#define LNA_CTL_FEM_BAND       BIT(4)
+#define LNA_CTL_LOCAL_BIAS     BIT(5)
+#define LNA_CTL_FORCE_XPA      BIT(6)
+#define LNA_CTL_USE_ANT1       BIT(7)
+
 enum eeprom_param {
        EEP_NFTHRESH_5,
        EEP_NFTHRESH_2,
@@ -378,10 +390,7 @@ struct modal_eep_header {
        u8 xatten2Margin[AR5416_MAX_CHAINS];
        u8 ob_ch1;
        u8 db_ch1;
-       u8 useAnt1:1,
-           force_xpaon:1,
-           local_bias:1,
-           femBandSelectUsed:1, xlnabufin:1, xlnaisel:2, xlnabufmode:1;
+       u8 lna_ctl;
        u8 miscBits;
        u16 xpaBiasLvlFreq[3];
        u8 futureModal[6];
@@ -535,18 +544,10 @@ struct cal_target_power_ht {
        u8 tPow2x[8];
 } __packed;
 
-
-#ifdef __BIG_ENDIAN_BITFIELD
-struct cal_ctl_edges {
-       u8 bChannel;
-       u8 flag:2, tPower:6;
-} __packed;
-#else
 struct cal_ctl_edges {
        u8 bChannel;
-       u8 tPower:6, flag:2;
+       u8 ctl;
 } __packed;
-#endif
 
 struct cal_data_op_loop_ar9287 {
        u8 pwrPdg[2][5];
index 76b4d65..a3ccb1b 100644 (file)
@@ -451,9 +451,10 @@ static void ath9k_hw_def_set_board_values(struct ath_hw *ah,
                ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
                                          AR_AN_TOP2_LOCALBIAS,
                                          AR_AN_TOP2_LOCALBIAS_S,
-                                         pModal->local_bias);
+                                         !!(pModal->lna_ctl &
+                                            LNA_CTL_LOCAL_BIAS));
                REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG,
-                             pModal->force_xpaon);
+                             !!(pModal->lna_ctl & LNA_CTL_FORCE_XPA));
        }
 
        REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
@@ -1062,15 +1063,19 @@ static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
        case 1:
                break;
        case 2:
-               scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
+               if (scaledPower > REDUCE_SCALED_POWER_BY_TWO_CHAIN)
+                       scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
+               else
+                       scaledPower = 0;
                break;
        case 3:
-               scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
+               if (scaledPower > REDUCE_SCALED_POWER_BY_THREE_CHAIN)
+                       scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
+               else
+                       scaledPower = 0;
                break;
        }
 
-       scaledPower = max((u16)0, scaledPower);
-
        if (IS_CHAN_2GHZ(chan)) {
                numCtlModes = ARRAY_SIZE(ctlModesFor11g) -
                        SUB_NUM_CTL_MODES_AT_2G_40;
@@ -1428,9 +1433,9 @@ static u8 ath9k_hw_def_get_num_ant_config(struct ath_hw *ah,
 
        num_ant_config = 1;
 
-       if (pBase->version >= 0x0E0D)
-               if (pModal->useAnt1)
-                       num_ant_config += 1;
+       if (pBase->version >= 0x0E0D &&
+           (pModal->lna_ctl & LNA_CTL_USE_ANT1))
+               num_ant_config += 1;
 
        return num_ant_config;
 }
index dfb6560..0de3c3d 100644 (file)
@@ -1024,6 +1024,13 @@ static int ath9k_hif_usb_suspend(struct usb_interface *interface,
        struct hif_device_usb *hif_dev =
                (struct hif_device_usb *) usb_get_intfdata(interface);
 
+       /*
+        * The device has to be set to FULLSLEEP mode in case no
+        * interface is up.
+        */
+       if (!(hif_dev->flags & HIF_USB_START))
+               ath9k_htc_suspend(hif_dev->htc_handle);
+
        ath9k_hif_usb_dealloc_urbs(hif_dev);
 
        return 0;
index 75ecf6a..c3b561d 100644 (file)
@@ -455,6 +455,8 @@ u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv);
 void ath9k_htc_ps_wakeup(struct ath9k_htc_priv *priv);
 void ath9k_htc_ps_restore(struct ath9k_htc_priv *priv);
 void ath9k_ps_work(struct work_struct *work);
+bool ath9k_htc_setpower(struct ath9k_htc_priv *priv,
+                       enum ath9k_power_mode mode);
 
 void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv);
 void ath9k_init_leds(struct ath9k_htc_priv *priv);
@@ -464,6 +466,7 @@ int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
                           u16 devid, char *product);
 void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug);
 #ifdef CONFIG_PM
+void ath9k_htc_suspend(struct htc_target *htc_handle);
 int ath9k_htc_resume(struct htc_target *htc_handle);
 #endif
 #ifdef CONFIG_ATH9K_HTC_DEBUGFS
index 7c8a38d..8776f49 100644 (file)
@@ -891,6 +891,12 @@ void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug)
 }
 
 #ifdef CONFIG_PM
+
+void ath9k_htc_suspend(struct htc_target *htc_handle)
+{
+       ath9k_htc_setpower(htc_handle->drv_priv, ATH9K_PM_FULL_SLEEP);
+}
+
 int ath9k_htc_resume(struct htc_target *htc_handle)
 {
        int ret;
index 9a3be8d..51977ca 100644 (file)
@@ -63,8 +63,8 @@ static enum htc_phymode ath9k_htc_get_curmode(struct ath9k_htc_priv *priv,
        return mode;
 }
 
-static bool ath9k_htc_setpower(struct ath9k_htc_priv *priv,
-                              enum ath9k_power_mode mode)
+bool ath9k_htc_setpower(struct ath9k_htc_priv *priv,
+                       enum ath9k_power_mode mode)
 {
        bool ret;
 
index 6ebc68b..c7fbe25 100644 (file)
@@ -2044,7 +2044,8 @@ u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio)
                val = REG_READ(ah, AR7010_GPIO_IN);
                return (MS(val, AR7010_GPIO_IN_VAL) & AR_GPIO_BIT(gpio)) == 0;
        } else if (AR_SREV_9300_20_OR_LATER(ah))
-               return MS_REG_READ(AR9300, gpio) != 0;
+               return (MS(REG_READ(ah, AR_GPIO_IN), AR9300_GPIO_IN_VAL) &
+                       AR_GPIO_BIT(gpio)) != 0;
        else if (AR_SREV_9271(ah))
                return MS_REG_READ(AR9271, gpio) != 0;
        else if (AR_SREV_9287_11_OR_LATER(ah))
index 92bc5c5..14b8ab3 100644 (file)
@@ -15,7 +15,6 @@
  */
 
 #include <linux/slab.h>
-#include <linux/pm_qos_params.h>
 
 #include "ath9k.h"
 
@@ -180,8 +179,6 @@ static const struct ath_ops ath9k_common_ops = {
        .write = ath9k_iowrite32,
 };
 
-struct pm_qos_request_list ath9k_pm_qos_req;
-
 /**************************/
 /*     Initialization     */
 /**************************/
@@ -664,6 +661,8 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
                hw->flags |= IEEE80211_HW_MFP_CAPABLE;
 
        hw->wiphy->interface_modes =
+               BIT(NL80211_IFTYPE_P2P_GO) |
+               BIT(NL80211_IFTYPE_P2P_CLIENT) |
                BIT(NL80211_IFTYPE_AP) |
                BIT(NL80211_IFTYPE_WDS) |
                BIT(NL80211_IFTYPE_STATION) |
@@ -759,7 +758,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
        ath_init_leds(sc);
        ath_start_rfkill_poll(sc);
 
-       pm_qos_add_request(&ath9k_pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
+       pm_qos_add_request(&sc->pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
                           PM_QOS_DEFAULT_VALUE);
 
        return 0;
@@ -830,7 +829,7 @@ void ath9k_deinit_device(struct ath_softc *sc)
        }
 
        ieee80211_unregister_hw(hw);
-       pm_qos_remove_request(&ath9k_pm_qos_req);
+       pm_qos_remove_request(&sc->pm_qos_req);
        ath_rx_cleanup(sc);
        ath_tx_cleanup(sc);
        ath9k_deinit_softc(sc);
index 8c13479..c996963 100644 (file)
@@ -703,8 +703,7 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
                        rs->rs_phyerr = phyerr;
                } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
                        rs->rs_status |= ATH9K_RXERR_DECRYPT;
-               else if ((ads.ds_rxstatus8 & AR_MichaelErr) &&
-                        rs->rs_keyix != ATH9K_RXKEYIX_INVALID)
+               else if (ads.ds_rxstatus8 & AR_MichaelErr)
                        rs->rs_status |= ATH9K_RXERR_MIC;
                else if (ads.ds_rxstatus8 & AR_KeyMiss)
                        rs->rs_status |= ATH9K_RXERR_DECRYPT;
index 25d3ef4..c0c3464 100644 (file)
@@ -15,7 +15,6 @@
  */
 
 #include <linux/nl80211.h>
-#include <linux/pm_qos_params.h>
 #include "ath9k.h"
 #include "btcoex.h"
 
@@ -245,11 +244,12 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
         * the relevant bits of the h/w.
         */
        ath9k_hw_set_interrupts(ah, 0);
-       ath_drain_all_txq(sc, false);
+       stopped = ath_drain_all_txq(sc, false);
 
        spin_lock_bh(&sc->rx.pcu_lock);
 
-       stopped = ath_stoprecv(sc);
+       if (!ath_stoprecv(sc))
+               stopped = false;
 
        /* XXX: do not flush receive queue here. We don't want
         * to flush data frames already in queue because of
@@ -1244,7 +1244,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
                        ath9k_btcoex_timer_resume(sc);
        }
 
-       pm_qos_update_request(&ath9k_pm_qos_req, 55);
+       pm_qos_update_request(&sc->pm_qos_req, 55);
 
 mutex_unlock:
        mutex_unlock(&sc->mutex);
@@ -1423,7 +1423,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
 
        sc->sc_flags |= SC_OP_INVALID;
 
-       pm_qos_update_request(&ath9k_pm_qos_req, PM_QOS_DEFAULT_VALUE);
+       pm_qos_update_request(&sc->pm_qos_req, PM_QOS_DEFAULT_VALUE);
 
        mutex_unlock(&sc->mutex);
 
@@ -1520,7 +1520,6 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
        struct ath_softc *sc = aphy->sc;
        struct ath_common *common = ath9k_hw_common(sc->sc_ah);
        struct ath_vif *avp = (void *)vif->drv_priv;
-       int i;
 
        ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n");
 
@@ -1534,21 +1533,24 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
        if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) ||
            (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) ||
            (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) {
+               /* Disable SWBA interrupt */
+               sc->sc_ah->imask &= ~ATH9K_INT_SWBA;
                ath9k_ps_wakeup(sc);
+               ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask);
                ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
                ath9k_ps_restore(sc);
+               tasklet_kill(&sc->bcon_tasklet);
        }
 
        ath_beacon_return(sc, avp);
        sc->sc_flags &= ~SC_OP_BEACONS;
 
-       for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) {
-               if (sc->beacon.bslot[i] == vif) {
-                       printk(KERN_DEBUG "%s: vif had allocated beacon "
-                              "slot\n", __func__);
-                       sc->beacon.bslot[i] = NULL;
-                       sc->beacon.bslot_aphy[i] = NULL;
-               }
+       if (sc->nbcnvifs) {
+               /* Re-enable SWBA interrupt */
+               sc->sc_ah->imask |= ATH9K_INT_SWBA;
+               ath9k_ps_wakeup(sc);
+               ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask);
+               ath9k_ps_restore(sc);
        }
 
        sc->nvifs--;
index c76ea53..fdc2ec5 100644 (file)
@@ -518,7 +518,7 @@ bool ath_stoprecv(struct ath_softc *sc)
        bool stopped;
 
        spin_lock_bh(&sc->rx.rxbuflock);
-       ath9k_hw_stoppcurecv(ah);
+       ath9k_hw_abortpcurecv(ah);
        ath9k_hw_setrxfilter(ah, 0);
        stopped = ath9k_hw_stopdmarecv(ah);
 
@@ -838,6 +838,10 @@ static bool ath9k_rx_accept(struct ath_common *common,
                            struct ath_rx_status *rx_stats,
                            bool *decrypt_error)
 {
+#define is_mc_or_valid_tkip_keyix ((is_mc ||                   \
+               (rx_stats->rs_keyix != ATH9K_RXKEYIX_INVALID && \
+               test_bit(rx_stats->rs_keyix, common->tkip_keymap))))
+
        struct ath_hw *ah = common->ah;
        __le16 fc;
        u8 rx_status_len = ah->caps.rx_status_len;
@@ -879,15 +883,18 @@ static bool ath9k_rx_accept(struct ath_common *common,
                if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) {
                        *decrypt_error = true;
                } else if (rx_stats->rs_status & ATH9K_RXERR_MIC) {
+                       bool is_mc;
                        /*
                         * The MIC error bit is only valid if the frame
                         * is not a control frame or fragment, and it was
                         * decrypted using a valid TKIP key.
                         */
+                       is_mc = !!is_multicast_ether_addr(hdr->addr1);
+
                        if (!ieee80211_is_ctl(fc) &&
                            !ieee80211_has_morefrags(fc) &&
                            !(le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) &&
-                           test_bit(rx_stats->rs_keyix, common->tkip_keymap))
+                           is_mc_or_valid_tkip_keyix)
                                rxs->flag |= RX_FLAG_MMIC_ERROR;
                        else
                                rx_stats->rs_status &= ~ATH9K_RXERR_MIC;
index dddf579..2c6a22f 100644 (file)
@@ -984,11 +984,13 @@ enum {
 #define AR9287_GPIO_IN_VAL_S                     11
 #define AR9271_GPIO_IN_VAL                       0xFFFF0000
 #define AR9271_GPIO_IN_VAL_S                     16
-#define AR9300_GPIO_IN_VAL                       0x0001FFFF
-#define AR9300_GPIO_IN_VAL_S                     0
 #define AR7010_GPIO_IN_VAL                       0x0000FFFF
 #define AR7010_GPIO_IN_VAL_S                     0
 
+#define AR_GPIO_IN                              0x404c
+#define AR9300_GPIO_IN_VAL                       0x0001FFFF
+#define AR9300_GPIO_IN_VAL_S                     0
+
 #define AR_GPIO_OE_OUT                           (AR_SREV_9300_20_OR_LATER(ah) ? 0x4050 : 0x404c)
 #define AR_GPIO_OE_OUT_DRV                       0x3
 #define AR_GPIO_OE_OUT_DRV_NO                    0x0
index f2ade24..aff0478 100644 (file)
@@ -1120,7 +1120,7 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
        }
 }
 
-void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
+bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
 {
        struct ath_hw *ah = sc->sc_ah;
        struct ath_common *common = ath9k_hw_common(sc->sc_ah);
@@ -1128,7 +1128,7 @@ void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
        int i, npend = 0;
 
        if (sc->sc_flags & SC_OP_INVALID)
-               return;
+               return true;
 
        /* Stop beacon queue */
        ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
@@ -1142,25 +1142,15 @@ void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
                }
        }
 
-       if (npend) {
-               int r;
-
-               ath_print(common, ATH_DBG_FATAL,
-                         "Failed to stop TX DMA. Resetting hardware!\n");
-
-               spin_lock_bh(&sc->sc_resetlock);
-               r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false);
-               if (r)
-                       ath_print(common, ATH_DBG_FATAL,
-                                 "Unable to reset hardware; reset status %d\n",
-                                 r);
-               spin_unlock_bh(&sc->sc_resetlock);
-       }
+       if (npend)
+               ath_print(common, ATH_DBG_FATAL, "Failed to stop TX DMA!\n");
 
        for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
                if (ATH_TXQ_SETUP(sc, i))
                        ath_draintxq(sc, &sc->tx.txq[i], retry_tx);
        }
+
+       return !npend;
 }
 
 void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq)
index ae6c006..546b4e4 100644 (file)
@@ -291,7 +291,8 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len)
 
                if (SUPP(CARL9170FW_WLANTX_CAB)) {
                        ar->hw->wiphy->interface_modes |=
-                               BIT(NL80211_IFTYPE_AP);
+                               BIT(NL80211_IFTYPE_AP) |
+                               BIT(NL80211_IFTYPE_P2P_GO);
                }
        }
 
index 980ae70..dc7b30b 100644 (file)
@@ -647,7 +647,7 @@ init:
        }
 
 unlock:
-       if (err && (vif_id != -1)) {
+       if (err && (vif_id >= 0)) {
                vif_priv->active = false;
                bitmap_release_region(&ar->vif_bitmap, vif_id, 0);
                ar->vifs--;
@@ -1631,7 +1631,8 @@ void *carl9170_alloc(size_t priv_size)
         * supports these modes. The code which will add the
         * additional interface_modes is in fw.c.
         */
-       hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
+       hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
+                                    BIT(NL80211_IFTYPE_P2P_CLIENT);
 
        hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS |
                     IEEE80211_HW_REPORTS_TX_ACK_STATUS |
index b575c86..7e6506a 100644 (file)
@@ -810,7 +810,7 @@ static int carl9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb)
 
        mac_tmp = cpu_to_le16(AR9170_TX_MAC_HW_DURATION |
                              AR9170_TX_MAC_BACKOFF);
-       mac_tmp |= cpu_to_le16((hw_queue << AR9170_TX_MAC_QOS_S) &&
+       mac_tmp |= cpu_to_le16((hw_queue << AR9170_TX_MAC_QOS_S) &
                               AR9170_TX_MAC_QOS);
 
        no_ack = !!(info->flags & IEEE80211_TX_CTL_NO_ACK);
index 9a55338..09e2dfd 100644 (file)
@@ -163,6 +163,7 @@ static int b43_sdio_probe(struct sdio_func *func,
 err_free_ssb:
        kfree(sdio);
 err_disable_func:
+       sdio_claim_host(func);
        sdio_disable_func(func);
 err_release_host:
        sdio_release_host(func);
index e5685dc..b4de0ca 100644 (file)
@@ -1170,7 +1170,6 @@ static void if_sdio_remove(struct sdio_func *func)
        lbs_deb_sdio("call remove card\n");
        lbs_stop_card(card->priv);
        lbs_remove_card(card->priv);
-       card->priv->surpriseremoved = 1;
 
        flush_workqueue(card->workqueue);
        destroy_workqueue(card->workqueue);
index 79bcb4e..ecd4d04 100644 (file)
@@ -1055,7 +1055,6 @@ static int __devexit libertas_spi_remove(struct spi_device *spi)
        lbs_stop_card(priv);
        lbs_remove_card(priv); /* will call free_netdev */
 
-       priv->surpriseremoved = 1;
        free_irq(spi->irq, card);
        if_spi_terminate_spi_thread(card);
        if (card->pdata->teardown)
index 46b88b1..fcd1bbf 100644 (file)
@@ -915,8 +915,6 @@ void lbs_remove_card(struct lbs_private *priv)
 
        lbs_free_adapter(priv);
        lbs_cfg_free(priv);
-
-       priv->dev = NULL;
        free_netdev(dev);
 
        lbs_deb_leave(LBS_DEB_MAIN);
index e8e2d0f..f3d396e 100644 (file)
@@ -1392,10 +1392,9 @@ static void orinoco_process_scan_results(struct work_struct *work)
                                orinoco_add_hostscan_results(priv, buf, len);
 
                        kfree(buf);
-               } else if (priv->scan_request) {
+               } else {
                        /* Either abort or complete the scan */
-                       cfg80211_scan_done(priv->scan_request, (len < 0));
-                       priv->scan_request = NULL;
+                       orinoco_scan_done(priv, (len < 0));
                }
 
                spin_lock_irqsave(&priv->scan_lock, flags);
@@ -1684,6 +1683,8 @@ static int __orinoco_down(struct orinoco_private *priv)
                hermes_write_regn(hw, EVACK, 0xffff);
        }
 
+       orinoco_scan_done(priv, true);
+
        /* firmware will have to reassociate */
        netif_carrier_off(dev);
        priv->last_linkstatus = 0xffff;
@@ -1762,10 +1763,7 @@ void orinoco_reset(struct work_struct *work)
        orinoco_unlock(priv, &flags);
 
        /* Scanning support: Notify scan cancellation */
-       if (priv->scan_request) {
-               cfg80211_scan_done(priv->scan_request, 1);
-               priv->scan_request = NULL;
-       }
+       orinoco_scan_done(priv, true);
 
        if (priv->hard_reset) {
                err = (*priv->hard_reset)(priv);
@@ -1813,6 +1811,12 @@ static int __orinoco_commit(struct orinoco_private *priv)
        struct net_device *dev = priv->ndev;
        int err = 0;
 
+       /* If we've called commit, we are reconfiguring or bringing the
+        * interface up. Maintaining countermeasures across this would
+        * be confusing, so note that we've disabled them. The port will
+        * be enabled later in orinoco_commit or __orinoco_up. */
+       priv->tkip_cm_active = 0;
+
        err = orinoco_hw_program_rids(priv);
 
        /* FIXME: what about netif_tx_lock */
index 71b3d68..32954c4 100644 (file)
@@ -151,20 +151,20 @@ orinoco_cs_config(struct pcmcia_device *link)
                goto failed;
        }
 
-       ret = pcmcia_request_irq(link, orinoco_interrupt);
-       if (ret)
-               goto failed;
-
-       /* We initialize the hermes structure before completing PCMCIA
-        * configuration just in case the interrupt handler gets
-        * called. */
        mem = ioport_map(link->resource[0]->start,
                        resource_size(link->resource[0]));
        if (!mem)
                goto failed;
 
+       /* We initialize the hermes structure before completing PCMCIA
+        * configuration just in case the interrupt handler gets
+        * called. */
        hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
 
+       ret = pcmcia_request_irq(link, orinoco_interrupt);
+       if (ret)
+               goto failed;
+
        ret = pcmcia_enable_device(link);
        if (ret)
                goto failed;
index 4300d9d..86cb54c 100644 (file)
@@ -229,3 +229,11 @@ void orinoco_add_hostscan_results(struct orinoco_private *priv,
                priv->scan_request = NULL;
        }
 }
+
+void orinoco_scan_done(struct orinoco_private *priv, bool abort)
+{
+       if (priv->scan_request) {
+               cfg80211_scan_done(priv->scan_request, abort);
+               priv->scan_request = NULL;
+       }
+}
index 2dc4e04..27281fb 100644 (file)
@@ -16,5 +16,6 @@ void orinoco_add_extscan_result(struct orinoco_private *priv,
 void orinoco_add_hostscan_results(struct orinoco_private *dev,
                                  unsigned char *buf,
                                  size_t len);
+void orinoco_scan_done(struct orinoco_private *priv, bool abort);
 
 #endif /* _ORINOCO_SCAN_H_ */
index fb859a5..db34c28 100644 (file)
@@ -214,21 +214,21 @@ spectrum_cs_config(struct pcmcia_device *link)
                goto failed;
        }
 
-       ret = pcmcia_request_irq(link, orinoco_interrupt);
-       if (ret)
-               goto failed;
-
-       /* We initialize the hermes structure before completing PCMCIA
-        * configuration just in case the interrupt handler gets
-        * called. */
        mem = ioport_map(link->resource[0]->start,
                        resource_size(link->resource[0]));
        if (!mem)
                goto failed;
 
+       /* We initialize the hermes structure before completing PCMCIA
+        * configuration just in case the interrupt handler gets
+        * called. */
        hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
        hw->eeprom_pda = true;
 
+       ret = pcmcia_request_irq(link, orinoco_interrupt);
+       if (ret)
+               goto failed;
+
        ret = pcmcia_enable_device(link);
        if (ret)
                goto failed;
index 93505f9..e5afabe 100644 (file)
@@ -911,10 +911,10 @@ static int orinoco_ioctl_set_auth(struct net_device *dev,
                 */
                if (param->value) {
                        priv->tkip_cm_active = 1;
-                       ret = hermes_enable_port(hw, 0);
+                       ret = hermes_disable_port(hw, 0);
                } else {
                        priv->tkip_cm_active = 0;
-                       ret = hermes_disable_port(hw, 0);
+                       ret = hermes_enable_port(hw, 0);
                }
                break;
 
index 458bb57..cdbeec9 100644 (file)
@@ -66,8 +66,8 @@ struct netfront_cb {
 
 #define GRANT_INVALID_REF      0
 
-#define NET_TX_RING_SIZE __RING_SIZE((struct xen_netif_tx_sring *)0, PAGE_SIZE)
-#define NET_RX_RING_SIZE __RING_SIZE((struct xen_netif_rx_sring *)0, PAGE_SIZE)
+#define NET_TX_RING_SIZE __CONST_RING_SIZE(xen_netif_tx, PAGE_SIZE)
+#define NET_RX_RING_SIZE __CONST_RING_SIZE(xen_netif_rx, PAGE_SIZE)
 #define TX_MAX_TARGET min_t(int, NET_RX_RING_SIZE, 256)
 
 struct netfront_info {
index d9f5148..9383063 100644 (file)
@@ -349,7 +349,6 @@ static struct irq_chip dino_interrupt_type = {
        .name   = "GSC-PCI",
        .unmask = dino_unmask_irq,
        .mask   = dino_mask_irq,
-       .ack    = no_ack_irq,
 };
 
 
index 1211974..e860038 100644 (file)
@@ -186,7 +186,6 @@ static struct irq_chip eisa_interrupt_type = {
        .name   =       "EISA",
        .unmask =       eisa_unmask_irq,
        .mask   =       eisa_mask_irq,
-       .ack    =       no_ack_irq,
 };
 
 static irqreturn_t eisa_irq(int wax_irq, void *intr_dev)
@@ -340,7 +339,7 @@ static int __init eisa_probe(struct parisc_device *dev)
        setup_irq(2, &irq2_action);
        for (i = 0; i < 16; i++) {
                set_irq_chip_and_handler(i, &eisa_interrupt_type,
-                       handle_level_irq);
+                                        handle_simple_irq);
        }
        
        EISA_bus = 1;
index e605298..772b193 100644 (file)
@@ -143,7 +143,6 @@ static struct irq_chip gsc_asic_interrupt_type = {
        .name   =       "GSC-ASIC",
        .unmask =       gsc_asic_unmask_irq,
        .mask   =       gsc_asic_mask_irq,
-       .ack    =       no_ack_irq,
 };
 
 int gsc_assign_irq(struct irq_chip *type, void *data)
@@ -153,7 +152,7 @@ int gsc_assign_irq(struct irq_chip *type, void *data)
        if (irq > GSC_IRQ_MAX)
                return NO_IRQ;
 
-       set_irq_chip_and_handler(irq, type, handle_level_irq);
+       set_irq_chip_and_handler(irq, type, handle_simple_irq);
        set_irq_chip_data(irq, data);
 
        return irq++;
index a3120a0..0327894 100644 (file)
@@ -669,6 +669,13 @@ printk("\n");
        DBG(KERN_DEBUG "enable_irq(%d): eoi(%p, 0x%x)\n", irq,
                        vi->eoi_addr, vi->eoi_data);
        iosapic_eoi(vi->eoi_addr, vi->eoi_data);
+}
+
+static void iosapic_eoi_irq(unsigned int irq)
+{
+       struct vector_info *vi = get_irq_chip_data(irq);
+
+       iosapic_eoi(vi->eoi_addr, vi->eoi_data);
        cpu_eoi_irq(irq);
 }
 
@@ -705,6 +712,7 @@ static struct irq_chip iosapic_interrupt_type = {
        .unmask =       iosapic_unmask_irq,
        .mask   =       iosapic_mask_irq,
        .ack    =       cpu_ack_irq,
+       .eoi    =       iosapic_eoi_irq,
 #ifdef CONFIG_SMP
        .set_affinity = iosapic_set_affinity_irq,
 #endif
index 2350e8a..f2f501e 100644 (file)
@@ -64,6 +64,7 @@ static unsigned int led_diskio    __read_mostly = 1;
 static unsigned int led_lanrxtx   __read_mostly = 1;
 static char lcd_text[32]          __read_mostly;
 static char lcd_text_default[32]  __read_mostly;
+static int  lcd_no_led_support    __read_mostly = 0; /* KittyHawk doesn't support LED on its LCD */
 
 
 static struct workqueue_struct *led_wq;
@@ -115,7 +116,7 @@ lcd_info __attribute__((aligned(8))) __read_mostly =
        .lcd_width =            16,
        .lcd_cmd_reg_addr =     KITTYHAWK_LCD_CMD,
        .lcd_data_reg_addr =    KITTYHAWK_LCD_DATA,
-       .min_cmd_delay =        40,
+       .min_cmd_delay =        80,
        .reset_cmd1 =           0x80,
        .reset_cmd2 =           0xc0,
 };
@@ -135,6 +136,9 @@ static int start_task(void)
        /* Display the default text now */
        if (led_type == LED_HASLCD) lcd_print( lcd_text_default );
 
+       /* KittyHawk has no LED support on its LCD */
+       if (lcd_no_led_support) return 0;
+
        /* Create the work queue and queue the LED task */
        led_wq = create_singlethread_workqueue("led_wq");       
        queue_delayed_work(led_wq, &led_task, 0);
@@ -248,9 +252,13 @@ static int __init led_create_procfs(void)
 
        proc_pdc_root = proc_mkdir("pdc", 0);
        if (!proc_pdc_root) return -1;
-       ent = proc_create_data("led", S_IRUGO|S_IWUSR, proc_pdc_root,
-                               &led_proc_fops, (void *)LED_NOLCD); /* LED */
-       if (!ent) return -1;
+
+       if (!lcd_no_led_support)
+       {
+               ent = proc_create_data("led", S_IRUGO|S_IWUSR, proc_pdc_root,
+                                       &led_proc_fops, (void *)LED_NOLCD); /* LED */
+               if (!ent) return -1;
+       }
 
        if (led_type == LED_HASLCD)
        {
@@ -692,6 +700,7 @@ int __init led_init(void)
        case 0x58B:             /* KittyHawk DC2 100 (K200) */
                printk(KERN_INFO "%s: KittyHawk-Machine (hversion 0x%x) found, "
                                "LED detection skipped.\n", __FILE__, CPU_HVERSION);
+               lcd_no_led_support = 1;
                goto found;     /* use the preinitialized values of lcd_info */
        }
 
index 0846daf..2824153 100644 (file)
@@ -323,7 +323,6 @@ static struct irq_chip superio_interrupt_type = {
        .name   =       SUPERIO,
        .unmask =       superio_unmask_irq,
        .mask   =       superio_mask_irq,
-       .ack =          no_ack_irq,
 };
 
 #ifdef DEBUG_SUPERIO_INIT
@@ -354,7 +353,7 @@ int superio_fixup_irq(struct pci_dev *pcidev)
 #endif
 
        for (i = 0; i < 16; i++) {
-               set_irq_chip_and_handler(i, &superio_interrupt_type, handle_level_irq);
+               set_irq_chip_and_handler(i, &superio_interrupt_type, handle_simple_irq);
        }
 
        /*
index 003170e..69546e9 100644 (file)
@@ -64,77 +64,6 @@ void pci_bus_remove_resources(struct pci_bus *bus)
        }
 }
 
-static bool pci_bus_resource_better(struct resource *res1, bool pos1,
-                                   struct resource *res2, bool pos2)
-{
-       /* If exactly one is positive decode, always prefer that one */
-       if (pos1 != pos2)
-               return pos1 ? true : false;
-
-       /* Prefer the one that contains the highest address */
-       if (res1->end != res2->end)
-               return (res1->end > res2->end) ? true : false;
-
-       /* Otherwise, prefer the one with highest "center of gravity" */
-       if (res1->start != res2->start)
-               return (res1->start > res2->start) ? true : false;
-
-       /* Otherwise, choose one arbitrarily (but consistently) */
-       return (res1 > res2) ? true : false;
-}
-
-static bool pci_bus_resource_positive(struct pci_bus *bus, struct resource *res)
-{
-       struct pci_bus_resource *bus_res;
-
-       /*
-        * This relies on the fact that pci_bus.resource[] refers to P2P or
-        * CardBus bridge base/limit registers, which are always positively
-        * decoded.  The pci_bus.resources list contains host bridge or
-        * subtractively decoded resources.
-        */
-       list_for_each_entry(bus_res, &bus->resources, list) {
-               if (bus_res->res == res)
-                       return (bus_res->flags & PCI_SUBTRACTIVE_DECODE) ?
-                               false : true;
-       }
-       return true;
-}
-
-/*
- * Find the next-best bus resource after the cursor "res".  If the cursor is
- * NULL, return the best resource.  "Best" means that we prefer positive
- * decode regions over subtractive decode, then those at higher addresses.
- */
-static struct resource *pci_bus_find_resource_prev(struct pci_bus *bus,
-                                                  unsigned int type,
-                                                  struct resource *res)
-{
-       bool res_pos, r_pos, prev_pos = false;
-       struct resource *r, *prev = NULL;
-       int i;
-
-       res_pos = pci_bus_resource_positive(bus, res);
-       pci_bus_for_each_resource(bus, r, i) {
-               if (!r)
-                       continue;
-
-               if ((r->flags & IORESOURCE_TYPE_BITS) != type)
-                       continue;
-
-               r_pos = pci_bus_resource_positive(bus, r);
-               if (!res || pci_bus_resource_better(res, res_pos, r, r_pos)) {
-                       if (!prev || pci_bus_resource_better(r, r_pos,
-                                                            prev, prev_pos)) {
-                               prev = r;
-                               prev_pos = r_pos;
-                       }
-               }
-       }
-
-       return prev;
-}
-
 /**
  * pci_bus_alloc_resource - allocate a resource from a parent bus
  * @bus: PCI bus
@@ -160,10 +89,9 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
                                          resource_size_t),
                void *alignf_data)
 {
-       int ret = -ENOMEM;
+       int i, ret = -ENOMEM;
        struct resource *r;
        resource_size_t max = -1;
-       unsigned int type = res->flags & IORESOURCE_TYPE_BITS;
 
        type_mask |= IORESOURCE_IO | IORESOURCE_MEM;
 
@@ -171,9 +99,10 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
        if (!(res->flags & IORESOURCE_MEM_64))
                max = PCIBIOS_MAX_MEM_32;
 
-       /* Look for space at highest addresses first */
-       r = pci_bus_find_resource_prev(bus, type, NULL);
-       for ( ; r; r = pci_bus_find_resource_prev(bus, type, r)) {
+       pci_bus_for_each_resource(bus, r, i) {
+               if (!r)
+                       continue;
+
                /* type_mask must match */
                if ((res->flags ^ r->flags) & type_mask)
                        continue;
index 0157708..09933eb 100644 (file)
@@ -1417,6 +1417,11 @@ int __init enable_drhd_fault_handling(void)
                               (unsigned long long)drhd->reg_base_addr, ret);
                        return -1;
                }
+
+               /*
+                * Clear any previous faults.
+                */
+               dmar_fault(iommu->irq, iommu);
        }
 
        return 0;
index 6f9350c..53a786f 100644 (file)
@@ -2329,6 +2329,9 @@ static void __devinit nvbridge_check_legacy_irq_routing(struct pci_dev *dev)
 {
        u32 cfg;
 
+       if (!pci_find_capability(dev, PCI_CAP_ID_HT))
+               return;
+
        pci_read_config_dword(dev, 0x74, &cfg);
 
        if (cfg & ((1 << 2) | (1 << 15))) {
@@ -2764,6 +2767,29 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_m
 DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832);
 #endif /*CONFIG_MMC_RICOH_MMC*/
 
+#if defined(CONFIG_DMAR) || defined(CONFIG_INTR_REMAP)
+#define VTUNCERRMSK_REG        0x1ac
+#define VTD_MSK_SPEC_ERRORS    (1 << 31)
+/*
+ * This is a quirk for masking vt-d spec defined errors to platform error
+ * handling logic. With out this, platforms using Intel 7500, 5500 chipsets
+ * (and the derivative chipsets like X58 etc) seem to generate NMI/SMI (based
+ * on the RAS config settings of the platform) when a vt-d fault happens.
+ * The resulting SMI caused the system to hang.
+ *
+ * VT-d spec related errors are already handled by the VT-d OS code, so no
+ * need to report the same error through other channels.
+ */
+static void vtd_mask_spec_errors(struct pci_dev *dev)
+{
+       u32 word;
+
+       pci_read_config_dword(dev, VTUNCERRMSK_REG, &word);
+       pci_write_config_dword(dev, VTUNCERRMSK_REG, word | VTD_MSK_SPEC_ERRORS);
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x342e, vtd_mask_spec_errors);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x3c28, vtd_mask_spec_errors);
+#endif
 
 static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f,
                          struct pci_fixup *end)
index 3753fd0..2fe8cb8 100644 (file)
@@ -70,6 +70,7 @@ void soc_pcmcia_debug(struct soc_pcmcia_socket *skt, const char *func,
                va_end(args);
        }
 }
+EXPORT_SYMBOL(soc_pcmcia_debug);
 
 #endif
 
index 60a5a5c..d235f44 100644 (file)
@@ -81,6 +81,8 @@ MODULE_PARM_DESC(wapf, "WAPF value");
 
 static int wlan_status = 1;
 static int bluetooth_status = 1;
+static int wimax_status = -1;
+static int wwan_status = -1;
 
 module_param(wlan_status, int, 0444);
 MODULE_PARM_DESC(wlan_status, "Set the wireless status on boot "
@@ -92,6 +94,16 @@ MODULE_PARM_DESC(bluetooth_status, "Set the wireless status on boot "
                 "(0 = disabled, 1 = enabled, -1 = don't do anything). "
                 "default is 1");
 
+module_param(wimax_status, int, 0444);
+MODULE_PARM_DESC(wimax_status, "Set the wireless status on boot "
+                "(0 = disabled, 1 = enabled, -1 = don't do anything). "
+                "default is 1");
+
+module_param(wwan_status, int, 0444);
+MODULE_PARM_DESC(wwan_status, "Set the wireless status on boot "
+                "(0 = disabled, 1 = enabled, -1 = don't do anything). "
+                "default is 1");
+
 /*
  * Some events we use, same for all Asus
  */
@@ -114,6 +126,8 @@ MODULE_PARM_DESC(bluetooth_status, "Set the wireless status on boot "
  */
 #define WL_RSTS                0x01    /* internal Wifi */
 #define BT_RSTS                0x02    /* internal Bluetooth */
+#define WM_RSTS                0x08    /* internal wimax */
+#define WW_RSTS                0x20    /* internal wwan */
 
 /* LED */
 #define METHOD_MLED            "MLED"
@@ -132,6 +146,11 @@ MODULE_PARM_DESC(bluetooth_status, "Set the wireless status on boot "
  */
 #define METHOD_WLAN            "WLED"
 #define METHOD_BLUETOOTH       "BLED"
+
+/* WWAN and WIMAX */
+#define METHOD_WWAN            "GSMC"
+#define METHOD_WIMAX           "WMXC"
+
 #define METHOD_WL_STATUS       "RSTS"
 
 /* Brightness */
@@ -882,6 +901,64 @@ static ssize_t store_bluetooth(struct device *dev,
        return sysfs_acpi_set(asus, buf, count, METHOD_BLUETOOTH);
 }
 
+/*
+ * Wimax
+ */
+static int asus_wimax_set(struct asus_laptop *asus, int status)
+{
+       if (write_acpi_int(asus->handle, METHOD_WIMAX, !!status)) {
+               pr_warning("Error setting wimax status to %d", status);
+               return -EIO;
+       }
+       return 0;
+}
+
+static ssize_t show_wimax(struct device *dev,
+                             struct device_attribute *attr, char *buf)
+{
+       struct asus_laptop *asus = dev_get_drvdata(dev);
+
+       return sprintf(buf, "%d\n", asus_wireless_status(asus, WM_RSTS));
+}
+
+static ssize_t store_wimax(struct device *dev,
+                              struct device_attribute *attr, const char *buf,
+                              size_t count)
+{
+       struct asus_laptop *asus = dev_get_drvdata(dev);
+
+       return sysfs_acpi_set(asus, buf, count, METHOD_WIMAX);
+}
+
+/*
+ * Wwan
+ */
+static int asus_wwan_set(struct asus_laptop *asus, int status)
+{
+       if (write_acpi_int(asus->handle, METHOD_WWAN, !!status)) {
+               pr_warning("Error setting wwan status to %d", status);
+               return -EIO;
+       }
+       return 0;
+}
+
+static ssize_t show_wwan(struct device *dev,
+                             struct device_attribute *attr, char *buf)
+{
+       struct asus_laptop *asus = dev_get_drvdata(dev);
+
+       return sprintf(buf, "%d\n", asus_wireless_status(asus, WW_RSTS));
+}
+
+static ssize_t store_wwan(struct device *dev,
+                              struct device_attribute *attr, const char *buf,
+                              size_t count)
+{
+       struct asus_laptop *asus = dev_get_drvdata(dev);
+
+       return sysfs_acpi_set(asus, buf, count, METHOD_WWAN);
+}
+
 /*
  * Display
  */
@@ -1202,6 +1279,8 @@ static DEVICE_ATTR(infos, S_IRUGO, show_infos, NULL);
 static DEVICE_ATTR(wlan, S_IRUGO | S_IWUSR, show_wlan, store_wlan);
 static DEVICE_ATTR(bluetooth, S_IRUGO | S_IWUSR,
                   show_bluetooth, store_bluetooth);
+static DEVICE_ATTR(wimax, S_IRUGO | S_IWUSR, show_wimax, store_wimax);
+static DEVICE_ATTR(wwan, S_IRUGO | S_IWUSR, show_wwan, store_wwan);
 static DEVICE_ATTR(display, S_IRUGO | S_IWUSR, show_disp, store_disp);
 static DEVICE_ATTR(ledd, S_IRUGO | S_IWUSR, show_ledd, store_ledd);
 static DEVICE_ATTR(ls_level, S_IRUGO | S_IWUSR, show_lslvl, store_lslvl);
@@ -1212,6 +1291,8 @@ static struct attribute *asus_attributes[] = {
        &dev_attr_infos.attr,
        &dev_attr_wlan.attr,
        &dev_attr_bluetooth.attr,
+       &dev_attr_wimax.attr,
+       &dev_attr_wwan.attr,
        &dev_attr_display.attr,
        &dev_attr_ledd.attr,
        &dev_attr_ls_level.attr,
@@ -1239,6 +1320,13 @@ static mode_t asus_sysfs_is_visible(struct kobject *kobj,
        } else if (attr == &dev_attr_display.attr) {
                supported = !acpi_check_handle(handle, METHOD_SWITCH_DISPLAY, NULL);
 
+       } else if (attr == &dev_attr_wimax.attr) {
+               supported =
+                       !acpi_check_handle(asus->handle, METHOD_WIMAX, NULL);
+
+       } else if (attr == &dev_attr_wwan.attr) {
+               supported = !acpi_check_handle(asus->handle, METHOD_WWAN, NULL);
+
        } else if (attr == &dev_attr_ledd.attr) {
                supported = !acpi_check_handle(handle, METHOD_LEDD, NULL);
 
@@ -1397,7 +1485,8 @@ static int asus_laptop_get_info(struct asus_laptop *asus)
 
        /*
         * The HWRS method return informations about the hardware.
-        * 0x80 bit is for WLAN, 0x100 for Bluetooth.
+        * 0x80 bit is for WLAN, 0x100 for Bluetooth,
+        * 0x40 for WWAN, 0x10 for WIMAX.
         * The significance of others is yet to be found.
         */
        status =
@@ -1440,6 +1529,12 @@ static int __devinit asus_acpi_init(struct asus_laptop *asus)
        if (wlan_status >= 0)
                asus_wlan_set(asus, !!wlan_status);
 
+       if (wimax_status >= 0)
+               asus_wimax_set(asus, !!wimax_status);
+
+       if (wwan_status >= 0)
+               asus_wwan_set(asus, !!wwan_status);
+
        /* Keyboard Backlight is on by default */
        if (!acpi_check_handle(asus->handle, METHOD_KBD_LIGHT_SET, NULL))
                asus_kled_set(asus, 1);
index 462ceab..0d50fbb 100644 (file)
@@ -298,8 +298,8 @@ static void eeepc_wmi_notify(u32 value, void *context)
        kfree(obj);
 }
 
-static int store_cpufv(struct device *dev, struct device_attribute *attr,
-                      const char *buf, size_t count)
+static ssize_t store_cpufv(struct device *dev, struct device_attribute *attr,
+                          const char *buf, size_t count)
 {
        int value;
        struct acpi_buffer input = { (acpi_size)sizeof(value), &value };
index 1dac659..9e05af9 100644 (file)
@@ -172,6 +172,8 @@ static int hp_wmi_perform_query(int query, int write, u32 *buffer,
        bios_return = *((struct bios_return *)obj->buffer.pointer);
 
        memcpy(buffer, &bios_return.value, sizeof(bios_return.value));
+
+       kfree(obj);
        return 0;
 }
 
index 3c2c6b9..94a114a 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/io.h>
 #include <linux/sysdev.h>
 #include <linux/dmi.h>
+#include <linux/efi.h>
 #include <linux/mutex.h>
 #include <asm/bios_ebda.h>
 
@@ -220,32 +221,13 @@ static void rtl_teardown_sysfs(void) {
        sysdev_class_unregister(&class_rtl);
 }
 
-static int dmi_check_cb(const struct dmi_system_id *id)
-{
-       RTL_DEBUG("found IBM server '%s'\n", id->ident);
-       return 0;
-}
-
-#define ibm_dmi_entry(NAME, TYPE)                  \
-{                                                  \
-       .ident = NAME,                             \
-       .matches = {                               \
-               DMI_MATCH(DMI_SYS_VENDOR, "IBM"),  \
-               DMI_MATCH(DMI_PRODUCT_NAME, TYPE), \
-       },                                         \
-       .callback = dmi_check_cb                   \
-}
 
 static struct dmi_system_id __initdata ibm_rtl_dmi_table[] = {
-       ibm_dmi_entry("BladeCenter LS21", "7971"),
-       ibm_dmi_entry("BladeCenter LS22", "7901"),
-       ibm_dmi_entry("BladeCenter HS21 XM", "7995"),
-       ibm_dmi_entry("BladeCenter HS22", "7870"),
-       ibm_dmi_entry("BladeCenter HS22V", "7871"),
-       ibm_dmi_entry("System x3550 M2", "7946"),
-       ibm_dmi_entry("System x3650 M2", "7947"),
-       ibm_dmi_entry("System x3550 M3", "7944"),
-       ibm_dmi_entry("System x3650 M3", "7945"),
+       {                                                  \
+               .matches = {                               \
+                       DMI_MATCH(DMI_SYS_VENDOR, "IBM"),  \
+               },                                         \
+       },
        { }
 };
 
@@ -257,7 +239,7 @@ static int __init ibm_rtl_init(void) {
        if (force)
                pr_warning("ibm-rtl: module loaded by force\n");
        /* first ensure that we are running on IBM HW */
-       else if (!dmi_check_system(ibm_rtl_dmi_table))
+       else if (efi_enabled || !dmi_check_system(ibm_rtl_dmi_table))
                return -ENODEV;
 
        /* Get the address for the Extended BIOS Data Area */
@@ -302,7 +284,7 @@ static int __init ibm_rtl_init(void) {
                        RTL_DEBUG("rtl_cmd_width = %u, rtl_cmd_type = %u\n",
                              rtl_cmd_width, rtl_cmd_type);
                        addr = ioread32(&rtl_table->cmd_port_address);
-                       RTL_DEBUG("addr = %#llx\n", addr);
+                       RTL_DEBUG("addr = %#llx\n", (unsigned long long)addr);
                        plen = rtl_cmd_width/sizeof(char);
                        rtl_cmd_addr = rtl_port_map(addr, plen);
                        RTL_DEBUG("rtl_cmd_addr = %#llx\n", (u64)rtl_cmd_addr);
index 42a5469..35278ad 100644 (file)
@@ -43,16 +43,18 @@ MODULE_ALIAS("wmi:B6F3EEF2-3D2F-49DC-9DE3-85BCE18C62F2");
 
 #define dprintk(msg...) pr_debug(DRV_PFX msg)
 
-#define KEYCODE_BASE 0xD0
-#define MSI_WMI_BRIGHTNESSUP   KEYCODE_BASE
-#define MSI_WMI_BRIGHTNESSDOWN (KEYCODE_BASE + 1)
-#define MSI_WMI_VOLUMEUP       (KEYCODE_BASE + 2)
-#define MSI_WMI_VOLUMEDOWN     (KEYCODE_BASE + 3)
+#define SCANCODE_BASE 0xD0
+#define MSI_WMI_BRIGHTNESSUP   SCANCODE_BASE
+#define MSI_WMI_BRIGHTNESSDOWN (SCANCODE_BASE + 1)
+#define MSI_WMI_VOLUMEUP       (SCANCODE_BASE + 2)
+#define MSI_WMI_VOLUMEDOWN     (SCANCODE_BASE + 3)
+#define MSI_WMI_MUTE           (SCANCODE_BASE + 4)
 static struct key_entry msi_wmi_keymap[] = {
        { KE_KEY, MSI_WMI_BRIGHTNESSUP,   {KEY_BRIGHTNESSUP} },
        { KE_KEY, MSI_WMI_BRIGHTNESSDOWN, {KEY_BRIGHTNESSDOWN} },
        { KE_KEY, MSI_WMI_VOLUMEUP,       {KEY_VOLUMEUP} },
        { KE_KEY, MSI_WMI_VOLUMEDOWN,     {KEY_VOLUMEDOWN} },
+       { KE_KEY, MSI_WMI_MUTE,           {KEY_MUTE} },
        { KE_END, 0}
 };
 static ktime_t last_pressed[ARRAY_SIZE(msi_wmi_keymap) - 1];
@@ -169,7 +171,7 @@ static void msi_wmi_notify(u32 value, void *context)
                        ktime_t diff;
                        cur = ktime_get_real();
                        diff = ktime_sub(cur, last_pressed[key->code -
-                                       KEYCODE_BASE]);
+                                       SCANCODE_BASE]);
                        /* Ignore event if the same event happened in a 50 ms
                           timeframe -> Key press may result in 10-20 GPEs */
                        if (ktime_to_us(diff) < 1000 * 50) {
@@ -178,7 +180,7 @@ static void msi_wmi_notify(u32 value, void *context)
                                         key->code, ktime_to_us(diff));
                                return;
                        }
-                       last_pressed[key->code - KEYCODE_BASE] = cur;
+                       last_pressed[key->code - SCANCODE_BASE] = cur;
 
                        if (key->type == KE_KEY &&
                        /* Brightness is served via acpi video driver */
index 2d61186..e8c2199 100644 (file)
@@ -8497,7 +8497,6 @@ static void ibm_exit(struct ibm_struct *ibm)
                                           ibm->acpi->type,
                                           dispatch_acpi_notify);
                ibm->flags.acpi_notify_installed = 0;
-               ibm->flags.acpi_notify_installed = 0;
        }
 
        if (ibm->flags.proc_created) {
index 06f304f..4276da7 100644 (file)
@@ -135,6 +135,7 @@ static const struct key_entry toshiba_acpi_keymap[] __initconst = {
        { KE_KEY, 0x141, { KEY_BRIGHTNESSUP } },
        { KE_KEY, 0x142, { KEY_WLAN } },
        { KE_KEY, 0x143, { KEY_PROG1 } },
+       { KE_KEY, 0x17f, { KEY_FN } },
        { KE_KEY, 0xb05, { KEY_PROG2 } },
        { KE_KEY, 0xb06, { KEY_WWW } },
        { KE_KEY, 0xb07, { KEY_MAIL } },
index 104b77c..aecd9a9 100644 (file)
@@ -755,7 +755,7 @@ static bool guid_already_parsed(const char *guid_string)
        struct wmi_block *wblock;
 
        list_for_each_entry(wblock, &wmi_block_list, list)
-               if (strncmp(wblock->gblock.guid, guid_string, 16) == 0)
+               if (memcmp(wblock->gblock.guid, guid_string, 16) == 0)
                        return true;
 
        return false;
index 2d73dfc..57313f4 100644 (file)
@@ -180,7 +180,7 @@ struct pnp_protocol pnpacpi_protocol = {
 };
 EXPORT_SYMBOL(pnpacpi_protocol);
 
-static char *pnpacpi_get_id(struct acpi_device *device)
+static char *__init pnpacpi_get_id(struct acpi_device *device)
 {
        struct acpi_hardware_id *id;
 
index f1d10c9..ba521f0 100644 (file)
@@ -911,7 +911,7 @@ out:
 }
 
 /**
- * set_consumer_device_supply: Bind a regulator to a symbolic supply
+ * set_consumer_device_supply - Bind a regulator to a symbolic supply
  * @rdev:         regulator source
  * @consumer_dev: device the supply applies to
  * @consumer_dev_name: dev_name() string for device supply applies to
@@ -1052,7 +1052,6 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
                        printk(KERN_WARNING
                               "%s: could not add device link %s err %d\n",
                               __func__, dev->kobj.name, err);
-                       device_remove_file(dev, &regulator->dev_attr);
                        goto link_name_err;
                }
        }
@@ -1268,13 +1267,17 @@ static int _regulator_enable(struct regulator_dev *rdev)
 {
        int ret, delay;
 
-       /* do we need to enable the supply regulator first */
-       if (rdev->supply) {
-               ret = _regulator_enable(rdev->supply);
-               if (ret < 0) {
-                       printk(KERN_ERR "%s: failed to enable %s: %d\n",
-                              __func__, rdev_get_name(rdev), ret);
-                       return ret;
+       if (rdev->use_count == 0) {
+               /* do we need to enable the supply regulator first */
+               if (rdev->supply) {
+                       mutex_lock(&rdev->supply->mutex);
+                       ret = _regulator_enable(rdev->supply);
+                       mutex_unlock(&rdev->supply->mutex);
+                       if (ret < 0) {
+                               printk(KERN_ERR "%s: failed to enable %s: %d\n",
+                                      __func__, rdev_get_name(rdev), ret);
+                               return ret;
+                       }
                }
        }
 
@@ -1313,10 +1316,12 @@ static int _regulator_enable(struct regulator_dev *rdev)
                        if (ret < 0)
                                return ret;
 
-                       if (delay >= 1000)
+                       if (delay >= 1000) {
                                mdelay(delay / 1000);
-                       else if (delay)
+                               udelay(delay % 1000);
+                       } else if (delay) {
                                udelay(delay);
+                       }
 
                } else if (ret < 0) {
                        printk(KERN_ERR "%s: is_enabled() failed for %s: %d\n",
@@ -1359,6 +1364,7 @@ static int _regulator_disable(struct regulator_dev *rdev,
                struct regulator_dev **supply_rdev_ptr)
 {
        int ret = 0;
+       *supply_rdev_ptr = NULL;
 
        if (WARN(rdev->use_count <= 0,
                        "unbalanced disables for %s\n",
@@ -2346,6 +2352,7 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
        if (init_data->supply_regulator && init_data->supply_regulator_dev) {
                dev_err(dev,
                        "Supply regulator specified by both name and dev\n");
+               ret = -EINVAL;
                goto scrub;
        }
 
@@ -2364,6 +2371,7 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
                if (!found) {
                        dev_err(dev, "Failed to find supply %s\n",
                                init_data->supply_regulator);
+                       ret = -ENODEV;
                        goto scrub;
                }
 
index 4597d50..ecd99f5 100644 (file)
@@ -465,8 +465,8 @@ static struct regulator_ops mc13783_fixed_regulator_ops = {
        .get_voltage = mc13783_fixed_regulator_get_voltage,
 };
 
-int mc13783_powermisc_rmw(struct mc13783_regulator_priv *priv, u32 mask,
-                                                                       u32 val)
+static int mc13783_powermisc_rmw(struct mc13783_regulator_priv *priv, u32 mask,
+                                u32 val)
 {
        struct mc13783 *mc13783 = priv->mc13783;
        int ret;
index 51237fb..6d20b04 100644 (file)
@@ -231,8 +231,7 @@ static int tps6586x_dvm_voltages[] = {
 };
 
 #define TPS6586X_REGULATOR(_id, vdata, _ops, vreg, shift, nbits,       \
-                          ereg0, ebit0, ereg1, ebit1, goreg, gobit)    \
-{                                                                      \
+                          ereg0, ebit0, ereg1, ebit1)                  \
        .desc   = {                                                     \
                .name   = "REG-" #_id,                                  \
                .ops    = &tps6586x_regulator_##_ops,                   \
@@ -248,18 +247,26 @@ static int tps6586x_dvm_voltages[] = {
        .enable_bit[0]  = (ebit0),                                      \
        .enable_reg[1]  = TPS6586X_SUPPLY##ereg1,                       \
        .enable_bit[1]  = (ebit1),                                      \
-       .voltages       = tps6586x_##vdata##_voltages,                  \
-}
+       .voltages       = tps6586x_##vdata##_voltages,
+
+#define TPS6586X_REGULATOR_DVM_GOREG(goreg, gobit)                     \
+       .go_reg = TPS6586X_##goreg,                                     \
+       .go_bit = (gobit),
 
 #define TPS6586X_LDO(_id, vdata, vreg, shift, nbits,                   \
                     ereg0, ebit0, ereg1, ebit1)                        \
+{                                                                      \
        TPS6586X_REGULATOR(_id, vdata, ldo_ops, vreg, shift, nbits,     \
-                          ereg0, ebit0, ereg1, ebit1, 0, 0)
+                          ereg0, ebit0, ereg1, ebit1)                  \
+}
 
 #define TPS6586X_DVM(_id, vdata, vreg, shift, nbits,                   \
                     ereg0, ebit0, ereg1, ebit1, goreg, gobit)          \
+{                                                                      \
        TPS6586X_REGULATOR(_id, vdata, dvm_ops, vreg, shift, nbits,     \
-                          ereg0, ebit0, ereg1, ebit1, goreg, gobit)
+                          ereg0, ebit0, ereg1, ebit1)                  \
+       TPS6586X_REGULATOR_DVM_GOREG(goreg, gobit)                      \
+}
 
 static struct tps6586x_regulator tps6586x_regulator[] = {
        TPS6586X_LDO(LDO_0, ldo, SUPPLYV1, 5, 3, ENC, 0, END, 0),
@@ -267,11 +274,11 @@ static struct tps6586x_regulator tps6586x_regulator[] = {
        TPS6586X_LDO(LDO_5, ldo, SUPPLYV6, 0, 3, ENE, 6, ENE, 6),
        TPS6586X_LDO(LDO_6, ldo, SUPPLYV3, 0, 3, ENC, 4, END, 4),
        TPS6586X_LDO(LDO_7, ldo, SUPPLYV3, 3, 3, ENC, 5, END, 5),
-       TPS6586X_LDO(LDO_8, ldo, SUPPLYV1, 5, 3, ENC, 6, END, 6),
+       TPS6586X_LDO(LDO_8, ldo, SUPPLYV2, 5, 3, ENC, 6, END, 6),
        TPS6586X_LDO(LDO_9, ldo, SUPPLYV6, 3, 3, ENE, 7, ENE, 7),
-       TPS6586X_LDO(LDO_RTC, ldo, SUPPLYV4, 3, 3, ENE, 7, ENE, 7),
+       TPS6586X_LDO(LDO_RTC, ldo, SUPPLYV4, 3, 3, V4, 7, V4, 7),
        TPS6586X_LDO(LDO_1, dvm, SUPPLYV1, 0, 5, ENC, 1, END, 1),
-       TPS6586X_LDO(SM_2, sm2, SUPPLYV2, 0, 5, ENC, 1, END, 1),
+       TPS6586X_LDO(SM_2, sm2, SUPPLYV2, 0, 5, ENC, 7, END, 7),
 
        TPS6586X_DVM(LDO_2, dvm, LDO2BV1, 0, 5, ENA, 3, ENB, 3, VCC2, 6),
        TPS6586X_DVM(LDO_4, ldo4, LDO4V1, 0, 5, ENC, 3, END, 3, VCC1, 6),
@@ -290,6 +297,10 @@ static inline int tps6586x_regulator_preinit(struct device *parent,
        uint8_t val1, val2;
        int ret;
 
+       if (ri->enable_reg[0] == ri->enable_reg[1] &&
+           ri->enable_bit[0] == ri->enable_bit[1])
+                       return 0;
+
        ret = tps6586x_read(parent, ri->enable_reg[0], &val1);
        if (ret)
                return ret;
@@ -298,14 +309,14 @@ static inline int tps6586x_regulator_preinit(struct device *parent,
        if (ret)
                return ret;
 
-       if (!(val2 & ri->enable_bit[1]))
+       if (!(val2 & (1 << ri->enable_bit[1])))
                return 0;
 
        /*
         * The regulator is on, but it's enabled with the bit we don't
         * want to use, so we switch the enable bits
         */
-       if (!(val1 & ri->enable_bit[0])) {
+       if (!(val1 & (1 << ri->enable_bit[0]))) {
                ret = tps6586x_set_bits(parent, ri->enable_reg[0],
                                        1 << ri->enable_bit[0]);
                if (ret)
index 7e5892e..a57262a 100644 (file)
@@ -219,12 +219,12 @@ static int twlreg_set_mode(struct regulator_dev *rdev, unsigned mode)
                return -EACCES;
 
        status = twl_i2c_write_u8(TWL_MODULE_PM_MASTER,
-                       message >> 8, 0x15 /* PB_WORD_MSB */ );
-       if (status >= 0)
+                       message >> 8, TWL4030_PM_MASTER_PB_WORD_MSB);
+       if (status < 0)
                return status;
 
        return twl_i2c_write_u8(TWL_MODULE_PM_MASTER,
-                       message, 0x16 /* PB_WORD_LSB */ );
+                       message & 0xff, TWL4030_PM_MASTER_PB_WORD_LSB);
 }
 
 /*----------------------------------------------------------------------*/
index a5050e2..825951b 100644 (file)
@@ -635,7 +635,7 @@ static void css_process_crw(struct crw *crw0, struct crw *crw1, int overflow)
        init_subchannel_id(&mchk_schid);
        mchk_schid.sch_no = crw0->rsid;
        if (crw1)
-               mchk_schid.ssid = (crw1->rsid >> 8) & 3;
+               mchk_schid.ssid = (crw1->rsid >> 4) & 3;
 
        /*
         * Since we are always presented with IPI in the CRW, we have to
index d37c733..0bcd580 100644 (file)
@@ -156,6 +156,8 @@ static int zfcp_erp_required_act(int want, struct zfcp_adapter *adapter,
                if (!(a_status & ZFCP_STATUS_COMMON_RUNNING) ||
                      a_status & ZFCP_STATUS_COMMON_ERP_FAILED)
                        return 0;
+               if (p_status & ZFCP_STATUS_COMMON_NOESC)
+                       return need;
                if (!(a_status & ZFCP_STATUS_COMMON_UNBLOCKED))
                        need = ZFCP_ERP_ACTION_REOPEN_ADAPTER;
                /* fall through */
@@ -188,6 +190,9 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status,
                atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE,
                                &zfcp_sdev->status);
                erp_action = &zfcp_sdev->erp_action;
+               memset(erp_action, 0, sizeof(struct zfcp_erp_action));
+               erp_action->port = port;
+               erp_action->sdev = sdev;
                if (!(atomic_read(&zfcp_sdev->status) &
                      ZFCP_STATUS_COMMON_RUNNING))
                        act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY;
@@ -200,6 +205,8 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status,
                zfcp_erp_action_dismiss_port(port);
                atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status);
                erp_action = &port->erp_action;
+               memset(erp_action, 0, sizeof(struct zfcp_erp_action));
+               erp_action->port = port;
                if (!(atomic_read(&port->status) & ZFCP_STATUS_COMMON_RUNNING))
                        act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY;
                break;
@@ -209,6 +216,7 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status,
                zfcp_erp_action_dismiss_adapter(adapter);
                atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status);
                erp_action = &adapter->erp_action;
+               memset(erp_action, 0, sizeof(struct zfcp_erp_action));
                if (!(atomic_read(&adapter->status) &
                      ZFCP_STATUS_COMMON_RUNNING))
                        act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY;
@@ -218,10 +226,7 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status,
                return NULL;
        }
 
-       memset(erp_action, 0, sizeof(struct zfcp_erp_action));
        erp_action->adapter = adapter;
-       erp_action->port = port;
-       erp_action->sdev = sdev;
        erp_action->action = need;
        erp_action->status = act_status;
 
index be03174..2eb7dd5 100644 (file)
@@ -851,7 +851,7 @@ struct zfcp_fsf_req *zfcp_fsf_abort_fcp_cmnd(struct scsi_cmnd *scmnd)
 
        zfcp_qdio_set_sbale_last(qdio, &req->qdio_req);
 
-       req->data = zfcp_sdev;
+       req->data = sdev;
        req->handler = zfcp_fsf_abort_fcp_command_handler;
        req->qtcb->header.lun_handle = zfcp_sdev->lun_handle;
        req->qtcb->header.port_handle = zfcp_sdev->port->handle;
@@ -2069,8 +2069,6 @@ static void zfcp_fsf_fcp_cmnd_handler(struct zfcp_fsf_req *req)
        struct fcp_resp_with_ext *fcp_rsp;
        unsigned long flags;
 
-       zfcp_fsf_fcp_handler_common(req);
-
        read_lock_irqsave(&req->adapter->abort_lock, flags);
 
        scpnt = req->data;
@@ -2079,6 +2077,8 @@ static void zfcp_fsf_fcp_cmnd_handler(struct zfcp_fsf_req *req)
                return;
        }
 
+       zfcp_fsf_fcp_handler_common(req);
+
        if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ERROR)) {
                set_host_byte(scpnt, DID_TRANSPORT_DISRUPTED);
                goto skip_fsfstatus;
@@ -2170,12 +2170,13 @@ int zfcp_fsf_fcp_cmnd(struct scsi_cmnd *scsi_cmnd)
        struct zfcp_adapter *adapter = zfcp_sdev->port->adapter;
        struct zfcp_qdio *qdio = adapter->qdio;
        struct fsf_qtcb_bottom_io *io;
+       unsigned long flags;
 
        if (unlikely(!(atomic_read(&zfcp_sdev->status) &
                       ZFCP_STATUS_COMMON_UNBLOCKED)))
                return -EBUSY;
 
-       spin_lock(&qdio->req_q_lock);
+       spin_lock_irqsave(&qdio->req_q_lock, flags);
        if (atomic_read(&qdio->req_q_free) <= 0) {
                atomic_inc(&qdio->req_q_full);
                goto out;
@@ -2239,7 +2240,7 @@ failed_scsi_cmnd:
        zfcp_fsf_req_free(req);
        scsi_cmnd->host_scribble = NULL;
 out:
-       spin_unlock(&qdio->req_q_lock);
+       spin_unlock_irqrestore(&qdio->req_q_lock, flags);
        return retval;
 }
 
index 6bd2dbc..63529ed 100644 (file)
@@ -76,8 +76,8 @@ static void zfcp_scsi_command_fail(struct scsi_cmnd *scpnt, int result)
        scpnt->scsi_done(scpnt);
 }
 
-static int zfcp_scsi_queuecommand_lck(struct scsi_cmnd *scpnt,
-                                 void (*done) (struct scsi_cmnd *))
+static
+int zfcp_scsi_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scpnt)
 {
        struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scpnt->device);
        struct zfcp_adapter *adapter = zfcp_sdev->port->adapter;
@@ -87,7 +87,6 @@ static int zfcp_scsi_queuecommand_lck(struct scsi_cmnd *scpnt,
        /* reset the status for this request */
        scpnt->result = 0;
        scpnt->host_scribble = NULL;
-       scpnt->scsi_done = done;
 
        scsi_result = fc_remote_port_chkready(rport);
        if (unlikely(scsi_result)) {
@@ -127,8 +126,6 @@ static int zfcp_scsi_queuecommand_lck(struct scsi_cmnd *scpnt,
        return ret;
 }
 
-static DEF_SCSI_QCMD(zfcp_scsi_queuecommand)
-
 static int zfcp_scsi_slave_alloc(struct scsi_device *sdev)
 {
        struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
index b2fb2b2..a6dea08 100644 (file)
@@ -90,11 +90,7 @@ static const struct pci_device_id hpsa_pci_device_id[] = {
        {PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x3252},
        {PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x3253},
        {PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x3254},
-#define PCI_DEVICE_ID_HP_CISSF 0x333f
-       {PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSF,     0x103C, 0x333F},
-       {PCI_VENDOR_ID_HP,     PCI_ANY_ID,             PCI_ANY_ID, PCI_ANY_ID,
-               PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0},
-       {PCI_VENDOR_ID_COMPAQ,     PCI_ANY_ID,             PCI_ANY_ID, PCI_ANY_ID,
+       {PCI_VENDOR_ID_HP,     PCI_ANY_ID,      PCI_ANY_ID, PCI_ANY_ID,
                PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0},
        {0,}
 };
@@ -113,8 +109,6 @@ static struct board_type products[] = {
        {0x3249103C, "Smart Array P812", &SA5_access},
        {0x324a103C, "Smart Array P712m", &SA5_access},
        {0x324b103C, "Smart Array P711m", &SA5_access},
-       {0x3233103C, "StorageWorks P1210m", &SA5_access},
-       {0x333F103C, "StorageWorks P1210m", &SA5_access},
        {0x3250103C, "Smart Array", &SA5_access},
        {0x3250113C, "Smart Array", &SA5_access},
        {0x3250123C, "Smart Array", &SA5_access},
index 0433ea6..b37c8a3 100644 (file)
@@ -951,8 +951,8 @@ static int _osd_req_finalize_cdb_cont(struct osd_request *or, const u8 *cap_key)
        /* create a bio for continuation segment */
        bio = bio_map_kern(req_q, or->cdb_cont.buff, or->cdb_cont.total_bytes,
                           GFP_KERNEL);
-       if (unlikely(!bio))
-               return -ENOMEM;
+       if (IS_ERR(bio))
+               return PTR_ERR(bio);
 
        bio->bi_rw |= REQ_WRITE;
 
index 5e76a62..300d59f 100644 (file)
@@ -62,6 +62,7 @@
 static unsigned int pmcraid_debug_log;
 static unsigned int pmcraid_disable_aen;
 static unsigned int pmcraid_log_level = IOASC_LOG_LEVEL_MUST;
+static unsigned int pmcraid_enable_msix;
 
 /*
  * Data structures to support multiple adapters by the LLD.
@@ -4691,7 +4692,8 @@ pmcraid_register_interrupt_handler(struct pmcraid_instance *pinstance)
        int rc;
        struct pci_dev *pdev = pinstance->pdev;
 
-       if (pci_find_capability(pdev, PCI_CAP_ID_MSIX)) {
+       if ((pmcraid_enable_msix) &&
+               (pci_find_capability(pdev, PCI_CAP_ID_MSIX))) {
                int num_hrrq = PMCRAID_NUM_MSIX_VECTORS;
                struct msix_entry entries[PMCRAID_NUM_MSIX_VECTORS];
                int i;
index 1134279..4db210d 100644 (file)
@@ -42,7 +42,7 @@
  */
 #define PMCRAID_DRIVER_NAME            "PMC MaxRAID"
 #define PMCRAID_DEVFILE                        "pmcsas"
-#define PMCRAID_DRIVER_VERSION         "2.0.3"
+#define PMCRAID_DRIVER_VERSION         "1.0.3"
 #define PMCRAID_DRIVER_DATE            __DATE__
 
 #define PMCRAID_FW_VERSION_1           0x002
@@ -333,11 +333,9 @@ struct pmcraid_config_table_entry {
        __u8  lun[PMCRAID_LUN_LEN];
 } __attribute__((packed, aligned(4)));
 
-/* extended configuration table sizes are of 64 bytes in size */
-#define PMCRAID_CFGTE_EXT_SIZE 32
+/* extended configuration table sizes are also of 32 bytes in size */
 struct pmcraid_config_table_entry_ext {
        struct pmcraid_config_table_entry cfgte;
-       __u8  cfgte_ext[PMCRAID_CFGTE_EXT_SIZE];
 };
 
 /* resource types (config_table_entry.resource_type values) */
index 3a22eff..9ce539d 100644 (file)
@@ -2409,7 +2409,6 @@ struct qla_hw_data {
                uint32_t        enable_target_reset     :1;
                uint32_t        enable_lip_full_login   :1;
                uint32_t        enable_led_scheme       :1;
-               uint32_t        inta_enabled            :1;
                uint32_t        msi_enabled             :1;
                uint32_t        msix_enabled            :1;
                uint32_t        disable_serdes          :1;
index 5f94430..4c1ba62 100644 (file)
@@ -1061,6 +1061,7 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt,
                fcp_cmnd->additional_cdb_len |= 2;
 
        int_to_scsilun(sp->cmd->device->lun, &fcp_cmnd->lun);
+       host_to_fcp_swap((uint8_t *)&fcp_cmnd->lun, sizeof(fcp_cmnd->lun));
        memcpy(fcp_cmnd->cdb, cmd->cmnd, cmd->cmd_len);
        cmd_pkt->fcp_cmnd_dseg_len = cpu_to_le16(fcp_cmnd_len);
        cmd_pkt->fcp_cmnd_dseg_address[0] = cpu_to_le32(
index 1f06ddd..7f77898 100644 (file)
@@ -2491,14 +2491,15 @@ skip_msix:
 skip_msi:
 
        ret = request_irq(ha->pdev->irq, ha->isp_ops->intr_handler,
-           IRQF_SHARED, QLA2XXX_DRIVER_NAME, rsp);
+           ha->flags.msi_enabled ? 0 : IRQF_SHARED,
+           QLA2XXX_DRIVER_NAME, rsp);
        if (ret) {
                qla_printk(KERN_WARNING, ha,
                    "Failed to reserve interrupt %d already in use.\n",
                    ha->pdev->irq);
                goto fail;
        }
-       ha->flags.inta_enabled = 1;
+
 clear_risc_ints:
 
        /*
index 8d9edfb..ae2acac 100644 (file)
@@ -2749,6 +2749,7 @@ sufficient_dsds:
                        goto queuing_error_fcp_cmnd;
 
                int_to_scsilun(sp->cmd->device->lun, &cmd_pkt->lun);
+               host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun));
 
                /* build FCP_CMND IU */
                memset(ctx->fcp_cmnd, 0, sizeof(struct fcp_cmnd));
index 1644eab..2c0876c 100644 (file)
@@ -829,7 +829,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
 {
        scsi_qla_host_t *vha = shost_priv(cmd->device->host);
        srb_t *sp;
-       int ret;
+       int ret = SUCCESS;
        unsigned int id, lun;
        unsigned long flags;
        int wait = 0;
@@ -2064,6 +2064,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
                ha->init_cb_size = sizeof(struct mid_init_cb_81xx);
                ha->gid_list_info_size = 8;
                ha->optrom_size = OPTROM_SIZE_82XX;
+               ha->nvram_npiv_size = QLA_MAX_VPORTS_QLA25XX;
                ha->isp_ops = &qla82xx_isp_ops;
                ha->flash_conf_off = FARX_ACCESS_FLASH_CONF;
                ha->flash_data_off = FARX_ACCESS_FLASH_DATA;
index 8edbccb..cf0075a 100644 (file)
@@ -7,9 +7,9 @@
 /*
  * Driver version
  */
-#define QLA2XXX_VERSION      "8.03.04-k0"
+#define QLA2XXX_VERSION      "8.03.05-k0"
 
 #define QLA_DRIVER_MAJOR_VER   8
 #define QLA_DRIVER_MINOR_VER   3
-#define QLA_DRIVER_PATCH_VER   4
+#define QLA_DRIVER_PATCH_VER   5
 #define QLA_DRIVER_BETA_VER    0
index 824b8fc..30ac116 100644 (file)
@@ -615,7 +615,7 @@ static int scsi_try_bus_device_reset(struct scsi_cmnd *scmd)
        return rtn;
 }
 
-static int __scsi_try_to_abort_cmd(struct scsi_cmnd *scmd)
+static int scsi_try_to_abort_cmd(struct scsi_cmnd *scmd)
 {
        if (!scmd->device->host->hostt->eh_abort_handler)
                return FAILED;
@@ -623,31 +623,9 @@ static int __scsi_try_to_abort_cmd(struct scsi_cmnd *scmd)
        return scmd->device->host->hostt->eh_abort_handler(scmd);
 }
 
-/**
- * scsi_try_to_abort_cmd - Ask host to abort a running command.
- * @scmd:      SCSI cmd to abort from Lower Level.
- *
- * Notes:
- *    This function will not return until the user's completion function
- *    has been called.  there is no timeout on this operation.  if the
- *    author of the low-level driver wishes this operation to be timed,
- *    they can provide this facility themselves.  helper functions in
- *    scsi_error.c can be supplied to make this easier to do.
- */
-static int scsi_try_to_abort_cmd(struct scsi_cmnd *scmd)
-{
-       /*
-        * scsi_done was called just after the command timed out and before
-        * we had a chance to process it. (db)
-        */
-       if (scmd->serial_number == 0)
-               return SUCCESS;
-       return __scsi_try_to_abort_cmd(scmd);
-}
-
 static void scsi_abort_eh_cmnd(struct scsi_cmnd *scmd)
 {
-       if (__scsi_try_to_abort_cmd(scmd) != SUCCESS)
+       if (scsi_try_to_abort_cmd(scmd) != SUCCESS)
                if (scsi_try_bus_device_reset(scmd) != SUCCESS)
                        if (scsi_try_target_reset(scmd) != SUCCESS)
                                if (scsi_try_bus_reset(scmd) != SUCCESS)
index 9d7ba07..4a38422 100644 (file)
@@ -1403,11 +1403,6 @@ static void scsi_softirq_done(struct request *rq)
 
        INIT_LIST_HEAD(&cmd->eh_entry);
 
-       /*
-        * Set the serial numbers back to zero
-        */
-       cmd->serial_number = 0;
-
        atomic_inc(&cmd->device->iodone_cnt);
        if (cmd->result)
                atomic_inc(&cmd->device->ioerr_cnt);
index 4d8e14b..09a5508 100644 (file)
@@ -2872,7 +2872,7 @@ static struct console serial8250_console = {
        .device         = uart_console_device,
        .setup          = serial8250_console_setup,
        .early_setup    = serial8250_console_early_setup,
-       .flags          = CON_PRINTBUFFER,
+       .flags          = CON_PRINTBUFFER | CON_ANYTIME,
        .index          = -1,
        .data           = &serial8250_reg,
 };
index 3374618..25a8bc5 100644 (file)
@@ -90,7 +90,8 @@ static DECLARE_WORK(kgdboc_restore_input_work, kgdboc_restore_input_helper);
 
 static void kgdboc_restore_input(void)
 {
-       schedule_work(&kgdboc_restore_input_work);
+       if (likely(system_state == SYSTEM_RUNNING))
+               schedule_work(&kgdboc_restore_input_work);
 }
 
 static int kgdboc_register_kbd(char **cptr)
index 5fc699e..d40010a 100644 (file)
@@ -900,8 +900,7 @@ serial_hsu_set_termios(struct uart_port *port, struct ktermios *termios,
        unsigned char cval, fcr = 0;
        unsigned long flags;
        unsigned int baud, quot;
-       u32 mul = 0x3600;
-       u32 ps = 0x10;
+       u32 ps, mul;
 
        switch (termios->c_cflag & CSIZE) {
        case CS5:
@@ -943,31 +942,24 @@ serial_hsu_set_termios(struct uart_port *port, struct ktermios *termios,
        baud = uart_get_baud_rate(port, termios, old, 0, 4000000);
 
        quot = 1;
+       ps = 0x10;
+       mul = 0x3600;
        switch (baud) {
        case 3500000:
                mul = 0x3345;
                ps = 0xC;
                break;
-       case 3000000:
-               mul = 0x2EE0;
-               break;
-       case 2500000:
-               mul = 0x2710;
-               break;
-       case 2000000:
-               mul = 0x1F40;
-               break;
        case 1843200:
                mul = 0x2400;
                break;
+       case 3000000:
+       case 2500000:
+       case 2000000:
        case 1500000:
-               mul = 0x1770;
-               break;
        case 1000000:
-               mul = 0xFA0;
-               break;
        case 500000:
-               mul = 0x7D0;
+               /* mul/ps/quot = 0x9C4/0x10/0x1 will make a 500000 bps */
+               mul = baud / 500000 * 0x9C4;
                break;
        default:
                /* Use uart_get_divisor to get quot for other baud rates */
index 154529a..a067046 100644 (file)
@@ -352,8 +352,12 @@ atmel_spi_dma_map_xfer(struct atmel_spi *as, struct spi_transfer *xfer)
 
        xfer->tx_dma = xfer->rx_dma = INVALID_DMA_ADDRESS;
        if (xfer->tx_buf) {
+               /* tx_buf is a const void* where we need a void * for the dma
+                * mapping */
+               void *nonconst_tx = (void *)xfer->tx_buf;
+
                xfer->tx_dma = dma_map_single(dev,
-                               (void *) xfer->tx_buf, xfer->len,
+                               nonconst_tx, xfer->len,
                                DMA_TO_DEVICE);
                if (dma_mapping_error(dev, xfer->tx_dma))
                        return -ENOMEM;
index 9043931..0838c79 100644 (file)
@@ -413,6 +413,11 @@ static void poll_transfer(struct dw_spi *dws)
 {
        while (dws->write(dws))
                dws->read(dws);
+       /*
+        * There is a possibility that the last word of a transaction
+        * will be lost if data is not ready. Re-read to solve this issue.
+        */
+       dws->read(dws);
 
        transfer_complete(dws);
 }
index ef9c6a0..744d3f6 100644 (file)
@@ -24,6 +24,7 @@ static const struct pci_device_id b43_pci_bridge_tbl[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4312) },
        { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4315) },
        { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4318) },
+       { PCI_DEVICE(PCI_VENDOR_ID_BCM_GVC,  0x4318) },
        { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4319) },
        { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4320) },
        { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4321) },
index 8c95d8c..016c6f7 100644 (file)
@@ -620,13 +620,13 @@ static ssize_t class_set_picture(struct device *device,
 
 #define ASUS_OLED_DEVICE_ATTR(_file)           dev_attr_asus_oled_##_file
 
-static DEVICE_ATTR(asus_oled_enabled, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(asus_oled_enabled, S_IWUSR | S_IRUGO,
                   get_enabled, set_enabled);
-static DEVICE_ATTR(asus_oled_picture, S_IWUGO , NULL, set_picture);
+static DEVICE_ATTR(asus_oled_picture, S_IWUSR , NULL, set_picture);
 
-static DEVICE_ATTR(enabled, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(enabled, S_IWUSR | S_IRUGO,
                   class_get_enabled, class_set_enabled);
-static DEVICE_ATTR(picture, S_IWUGO, NULL, class_set_picture);
+static DEVICE_ATTR(picture, S_IWUSR, NULL, class_set_picture);
 
 static int asus_oled_probe(struct usb_interface *interface,
                           const struct usb_device_id *id)
index b68a7e5..d85de82 100644 (file)
@@ -463,9 +463,6 @@ static void hardif_remove_interface(struct batman_if *batman_if)
                return;
 
        batman_if->if_status = IF_TO_BE_REMOVED;
-
-       /* caller must take if_list_lock */
-       list_del_rcu(&batman_if->list);
        synchronize_rcu();
        sysfs_del_hardif(&batman_if->hardif_obj);
        hardif_put(batman_if);
@@ -474,13 +471,21 @@ static void hardif_remove_interface(struct batman_if *batman_if)
 void hardif_remove_interfaces(void)
 {
        struct batman_if *batman_if, *batman_if_tmp;
+       struct list_head if_queue;
+
+       INIT_LIST_HEAD(&if_queue);
 
-       rtnl_lock();
        spin_lock(&if_list_lock);
        list_for_each_entry_safe(batman_if, batman_if_tmp, &if_list, list) {
-               hardif_remove_interface(batman_if);
+               list_del_rcu(&batman_if->list);
+               list_add_tail(&batman_if->list, &if_queue);
        }
        spin_unlock(&if_list_lock);
+
+       rtnl_lock();
+       list_for_each_entry_safe(batman_if, batman_if_tmp, &if_queue, list) {
+               hardif_remove_interface(batman_if);
+       }
        rtnl_unlock();
 }
 
@@ -507,8 +512,10 @@ static int hard_if_event(struct notifier_block *this,
                break;
        case NETDEV_UNREGISTER:
                spin_lock(&if_list_lock);
-               hardif_remove_interface(batman_if);
+               list_del_rcu(&batman_if->list);
                spin_unlock(&if_list_lock);
+
+               hardif_remove_interface(batman_if);
                break;
        case NETDEV_CHANGEMTU:
                if (batman_if->soft_iface)
index 3904db9..0e99618 100644 (file)
@@ -194,14 +194,15 @@ void interface_rx(struct net_device *soft_iface,
        struct bat_priv *priv = netdev_priv(soft_iface);
 
        /* check if enough space is available for pulling, and pull */
-       if (!pskb_may_pull(skb, hdr_size)) {
-               kfree_skb(skb);
-               return;
-       }
+       if (!pskb_may_pull(skb, hdr_size))
+               goto dropped;
+
        skb_pull_rcsum(skb, hdr_size);
 /*     skb_set_mac_header(skb, -sizeof(struct ethhdr));*/
 
        /* skb->dev & skb->pkt_type are set here */
+       if (unlikely(!pskb_may_pull(skb, ETH_HLEN)))
+               goto dropped;
        skb->protocol = eth_type_trans(skb, soft_iface);
 
        /* should not be neccesary anymore as we use skb_pull_rcsum()
@@ -216,6 +217,11 @@ void interface_rx(struct net_device *soft_iface,
        soft_iface->last_rx = jiffies;
 
        netif_rx(skb);
+       return;
+
+dropped:
+       kfree_skb(skb);
+       return;
 }
 
 #ifdef HAVE_NET_DEVICE_OPS
index c8f1cf1..a27bb0b 100644 (file)
@@ -88,7 +88,9 @@ with the driver.
 
 Contact Info:
 =============
-Brett Rudley   brudley@broadcom.com
-Henry Ptasinski henryp@broadcom.com
-Dowan Kim      dowan@broadcom.com
+Brett Rudley           brudley@broadcom.com
+Henry Ptasinski                henryp@broadcom.com
+Dowan Kim                      dowan@broadcom.com
+Roland Vossen          rvossen@broadcom.com
+Arend van Spriel       arend@broadcom.com
 
index dbf9041..24ebadb 100644 (file)
@@ -46,4 +46,6 @@ Contact
 Brett Rudley <brudley@broadcom.com>
 Henry Ptasinski <henryp@broadcom.com>
 Dowan Kim <dowan@broadcom.com>
+Roland Vossen <rvossen@broadcom.com>
+Arend van Spriel <arend@broadcom.com>
 
index 1f177a6..de784ff 100644 (file)
@@ -2295,8 +2295,8 @@ static void tidy_up(struct usbduxsub *usbduxsub_tmp)
        usbduxsub_tmp->inBuffer = NULL;
        kfree(usbduxsub_tmp->insnBuffer);
        usbduxsub_tmp->insnBuffer = NULL;
-       kfree(usbduxsub_tmp->inBuffer);
-       usbduxsub_tmp->inBuffer = NULL;
+       kfree(usbduxsub_tmp->outBuffer);
+       usbduxsub_tmp->outBuffer = NULL;
        kfree(usbduxsub_tmp->dac_commands);
        usbduxsub_tmp->dac_commands = NULL;
        kfree(usbduxsub_tmp->dux_commands);
index 25961c2..884263b 100644 (file)
@@ -75,6 +75,7 @@
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/slab.h>
+#include <linux/smp_lock.h>
 #include <linux/module.h>
 #include <linux/kref.h>
 #include <linux/usb.h>
index a145a15..8894ab1 100644 (file)
@@ -204,7 +204,7 @@ static void usb_tranzport_abort_transfers(struct usb_tranzport *dev)
                t->value = temp;        \
                return count;   \
        }       \
-       static DEVICE_ATTR(value, S_IWUGO | S_IRUGO, show_##value, set_##value);
+       static DEVICE_ATTR(value, S_IWUSR | S_IRUGO, show_##value, set_##value);
 
 show_int(enable);
 show_int(offline);
index b3f42f3..48d4e48 100644 (file)
@@ -199,7 +199,7 @@ static int init_i2c_module(struct i2c_adapter *adapter, const char *type,
        struct go7007 *go = i2c_get_adapdata(adapter);
        struct v4l2_device *v4l2_dev = &go->v4l2_dev;
 
-       if (v4l2_i2c_new_subdev(v4l2_dev, adapter, NULL, type, addr, NULL))
+       if (v4l2_i2c_new_subdev(v4l2_dev, adapter, type, addr, NULL))
                return 0;
 
        printk(KERN_INFO "go7007: probing for module i2c:%s failed\n", type);
index c86d149..1c1e98a 100644 (file)
@@ -507,7 +507,7 @@ static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL,
                adis16220_write_reset, 0);
 
 #define IIO_DEV_ATTR_CAPTURE(_store)                           \
-       IIO_DEVICE_ATTR(capture, S_IWUGO, NULL, _store, 0)
+       IIO_DEVICE_ATTR(capture, S_IWUSR, NULL, _store, 0)
 
 static IIO_DEV_ATTR_CAPTURE(adis16220_write_capture);
 
index fbae39f..5c45560 100644 (file)
@@ -1269,7 +1269,7 @@ finish:
        dbufs->output_bytes_produced = total_output;
        str_info->status = str_info->prev;
        str_info->prev = STREAM_DECODE;
-       str_info->decode_ibuf = NULL;
        kfree(str_info->decode_ibuf);
+       str_info->decode_ibuf = NULL;
        return retval;
 }
index 040e25c..67e23b6 100644 (file)
@@ -266,210 +266,210 @@ VARIAX_PARAM_R(float, mix2);
 VARIAX_PARAM_R(float, mix1);
 VARIAX_PARAM_R(int, pickup_wiring);
 
-static DEVICE_ATTR(tweak, S_IWUGO | S_IRUGO, pod_get_tweak, pod_set_tweak);
-static DEVICE_ATTR(wah_position, S_IWUGO | S_IRUGO, pod_get_wah_position,
+static DEVICE_ATTR(tweak, S_IWUSR | S_IRUGO, pod_get_tweak, pod_set_tweak);
+static DEVICE_ATTR(wah_position, S_IWUSR | S_IRUGO, pod_get_wah_position,
                   pod_set_wah_position);
-static DEVICE_ATTR(compression_gain, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(compression_gain, S_IWUSR | S_IRUGO,
                   pod_get_compression_gain, pod_set_compression_gain);
-static DEVICE_ATTR(vol_pedal_position, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(vol_pedal_position, S_IWUSR | S_IRUGO,
                   pod_get_vol_pedal_position, pod_set_vol_pedal_position);
-static DEVICE_ATTR(compression_threshold, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(compression_threshold, S_IWUSR | S_IRUGO,
                   pod_get_compression_threshold,
                   pod_set_compression_threshold);
-static DEVICE_ATTR(pan, S_IWUGO | S_IRUGO, pod_get_pan, pod_set_pan);
-static DEVICE_ATTR(amp_model_setup, S_IWUGO | S_IRUGO, pod_get_amp_model_setup,
+static DEVICE_ATTR(pan, S_IWUSR | S_IRUGO, pod_get_pan, pod_set_pan);
+static DEVICE_ATTR(amp_model_setup, S_IWUSR | S_IRUGO, pod_get_amp_model_setup,
                   pod_set_amp_model_setup);
-static DEVICE_ATTR(amp_model, S_IWUGO | S_IRUGO, pod_get_amp_model,
+static DEVICE_ATTR(amp_model, S_IWUSR | S_IRUGO, pod_get_amp_model,
                   pod_set_amp_model);
-static DEVICE_ATTR(drive, S_IWUGO | S_IRUGO, pod_get_drive, pod_set_drive);
-static DEVICE_ATTR(bass, S_IWUGO | S_IRUGO, pod_get_bass, pod_set_bass);
-static DEVICE_ATTR(mid, S_IWUGO | S_IRUGO, pod_get_mid, pod_set_mid);
-static DEVICE_ATTR(lowmid, S_IWUGO | S_IRUGO, pod_get_lowmid, pod_set_lowmid);
-static DEVICE_ATTR(treble, S_IWUGO | S_IRUGO, pod_get_treble, pod_set_treble);
-static DEVICE_ATTR(highmid, S_IWUGO | S_IRUGO, pod_get_highmid,
+static DEVICE_ATTR(drive, S_IWUSR | S_IRUGO, pod_get_drive, pod_set_drive);
+static DEVICE_ATTR(bass, S_IWUSR | S_IRUGO, pod_get_bass, pod_set_bass);
+static DEVICE_ATTR(mid, S_IWUSR | S_IRUGO, pod_get_mid, pod_set_mid);
+static DEVICE_ATTR(lowmid, S_IWUSR | S_IRUGO, pod_get_lowmid, pod_set_lowmid);
+static DEVICE_ATTR(treble, S_IWUSR | S_IRUGO, pod_get_treble, pod_set_treble);
+static DEVICE_ATTR(highmid, S_IWUSR | S_IRUGO, pod_get_highmid,
                   pod_set_highmid);
-static DEVICE_ATTR(chan_vol, S_IWUGO | S_IRUGO, pod_get_chan_vol,
+static DEVICE_ATTR(chan_vol, S_IWUSR | S_IRUGO, pod_get_chan_vol,
                   pod_set_chan_vol);
-static DEVICE_ATTR(reverb_mix, S_IWUGO | S_IRUGO, pod_get_reverb_mix,
+static DEVICE_ATTR(reverb_mix, S_IWUSR | S_IRUGO, pod_get_reverb_mix,
                   pod_set_reverb_mix);
-static DEVICE_ATTR(effect_setup, S_IWUGO | S_IRUGO, pod_get_effect_setup,
+static DEVICE_ATTR(effect_setup, S_IWUSR | S_IRUGO, pod_get_effect_setup,
                   pod_set_effect_setup);
-static DEVICE_ATTR(band_1_frequency, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(band_1_frequency, S_IWUSR | S_IRUGO,
                   pod_get_band_1_frequency, pod_set_band_1_frequency);
-static DEVICE_ATTR(presence, S_IWUGO | S_IRUGO, pod_get_presence,
+static DEVICE_ATTR(presence, S_IWUSR | S_IRUGO, pod_get_presence,
                   pod_set_presence);
-static DEVICE_ATTR2(treble__bass, treble, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR2(treble__bass, treble, S_IWUSR | S_IRUGO,
                    pod_get_treble__bass, pod_set_treble__bass);
-static DEVICE_ATTR(noise_gate_enable, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(noise_gate_enable, S_IWUSR | S_IRUGO,
                   pod_get_noise_gate_enable, pod_set_noise_gate_enable);
-static DEVICE_ATTR(gate_threshold, S_IWUGO | S_IRUGO, pod_get_gate_threshold,
+static DEVICE_ATTR(gate_threshold, S_IWUSR | S_IRUGO, pod_get_gate_threshold,
                   pod_set_gate_threshold);
-static DEVICE_ATTR(gate_decay_time, S_IWUGO | S_IRUGO, pod_get_gate_decay_time,
+static DEVICE_ATTR(gate_decay_time, S_IWUSR | S_IRUGO, pod_get_gate_decay_time,
                   pod_set_gate_decay_time);
-static DEVICE_ATTR(stomp_enable, S_IWUGO | S_IRUGO, pod_get_stomp_enable,
+static DEVICE_ATTR(stomp_enable, S_IWUSR | S_IRUGO, pod_get_stomp_enable,
                   pod_set_stomp_enable);
-static DEVICE_ATTR(comp_enable, S_IWUGO | S_IRUGO, pod_get_comp_enable,
+static DEVICE_ATTR(comp_enable, S_IWUSR | S_IRUGO, pod_get_comp_enable,
                   pod_set_comp_enable);
-static DEVICE_ATTR(stomp_time, S_IWUGO | S_IRUGO, pod_get_stomp_time,
+static DEVICE_ATTR(stomp_time, S_IWUSR | S_IRUGO, pod_get_stomp_time,
                   pod_set_stomp_time);
-static DEVICE_ATTR(delay_enable, S_IWUGO | S_IRUGO, pod_get_delay_enable,
+static DEVICE_ATTR(delay_enable, S_IWUSR | S_IRUGO, pod_get_delay_enable,
                   pod_set_delay_enable);
-static DEVICE_ATTR(mod_param_1, S_IWUGO | S_IRUGO, pod_get_mod_param_1,
+static DEVICE_ATTR(mod_param_1, S_IWUSR | S_IRUGO, pod_get_mod_param_1,
                   pod_set_mod_param_1);
-static DEVICE_ATTR(delay_param_1, S_IWUGO | S_IRUGO, pod_get_delay_param_1,
+static DEVICE_ATTR(delay_param_1, S_IWUSR | S_IRUGO, pod_get_delay_param_1,
                   pod_set_delay_param_1);
-static DEVICE_ATTR(delay_param_1_note_value, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(delay_param_1_note_value, S_IWUSR | S_IRUGO,
                   pod_get_delay_param_1_note_value,
                   pod_set_delay_param_1_note_value);
-static DEVICE_ATTR2(band_2_frequency__bass, band_2_frequency, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR2(band_2_frequency__bass, band_2_frequency, S_IWUSR | S_IRUGO,
                    pod_get_band_2_frequency__bass,
                    pod_set_band_2_frequency__bass);
-static DEVICE_ATTR(delay_param_2, S_IWUGO | S_IRUGO, pod_get_delay_param_2,
+static DEVICE_ATTR(delay_param_2, S_IWUSR | S_IRUGO, pod_get_delay_param_2,
                   pod_set_delay_param_2);
-static DEVICE_ATTR(delay_volume_mix, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(delay_volume_mix, S_IWUSR | S_IRUGO,
                   pod_get_delay_volume_mix, pod_set_delay_volume_mix);
-static DEVICE_ATTR(delay_param_3, S_IWUGO | S_IRUGO, pod_get_delay_param_3,
+static DEVICE_ATTR(delay_param_3, S_IWUSR | S_IRUGO, pod_get_delay_param_3,
                   pod_set_delay_param_3);
-static DEVICE_ATTR(reverb_enable, S_IWUGO | S_IRUGO, pod_get_reverb_enable,
+static DEVICE_ATTR(reverb_enable, S_IWUSR | S_IRUGO, pod_get_reverb_enable,
                   pod_set_reverb_enable);
-static DEVICE_ATTR(reverb_type, S_IWUGO | S_IRUGO, pod_get_reverb_type,
+static DEVICE_ATTR(reverb_type, S_IWUSR | S_IRUGO, pod_get_reverb_type,
                   pod_set_reverb_type);
-static DEVICE_ATTR(reverb_decay, S_IWUGO | S_IRUGO, pod_get_reverb_decay,
+static DEVICE_ATTR(reverb_decay, S_IWUSR | S_IRUGO, pod_get_reverb_decay,
                   pod_set_reverb_decay);
-static DEVICE_ATTR(reverb_tone, S_IWUGO | S_IRUGO, pod_get_reverb_tone,
+static DEVICE_ATTR(reverb_tone, S_IWUSR | S_IRUGO, pod_get_reverb_tone,
                   pod_set_reverb_tone);
-static DEVICE_ATTR(reverb_pre_delay, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(reverb_pre_delay, S_IWUSR | S_IRUGO,
                   pod_get_reverb_pre_delay, pod_set_reverb_pre_delay);
-static DEVICE_ATTR(reverb_pre_post, S_IWUGO | S_IRUGO, pod_get_reverb_pre_post,
+static DEVICE_ATTR(reverb_pre_post, S_IWUSR | S_IRUGO, pod_get_reverb_pre_post,
                   pod_set_reverb_pre_post);
-static DEVICE_ATTR(band_2_frequency, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(band_2_frequency, S_IWUSR | S_IRUGO,
                   pod_get_band_2_frequency, pod_set_band_2_frequency);
-static DEVICE_ATTR2(band_3_frequency__bass, band_3_frequency, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR2(band_3_frequency__bass, band_3_frequency, S_IWUSR | S_IRUGO,
                    pod_get_band_3_frequency__bass,
                    pod_set_band_3_frequency__bass);
-static DEVICE_ATTR(wah_enable, S_IWUGO | S_IRUGO, pod_get_wah_enable,
+static DEVICE_ATTR(wah_enable, S_IWUSR | S_IRUGO, pod_get_wah_enable,
                   pod_set_wah_enable);
-static DEVICE_ATTR(modulation_lo_cut, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(modulation_lo_cut, S_IWUSR | S_IRUGO,
                   pod_get_modulation_lo_cut, pod_set_modulation_lo_cut);
-static DEVICE_ATTR(delay_reverb_lo_cut, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(delay_reverb_lo_cut, S_IWUSR | S_IRUGO,
                   pod_get_delay_reverb_lo_cut, pod_set_delay_reverb_lo_cut);
-static DEVICE_ATTR(volume_pedal_minimum, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(volume_pedal_minimum, S_IWUSR | S_IRUGO,
                   pod_get_volume_pedal_minimum, pod_set_volume_pedal_minimum);
-static DEVICE_ATTR(eq_pre_post, S_IWUGO | S_IRUGO, pod_get_eq_pre_post,
+static DEVICE_ATTR(eq_pre_post, S_IWUSR | S_IRUGO, pod_get_eq_pre_post,
                   pod_set_eq_pre_post);
-static DEVICE_ATTR(volume_pre_post, S_IWUGO | S_IRUGO, pod_get_volume_pre_post,
+static DEVICE_ATTR(volume_pre_post, S_IWUSR | S_IRUGO, pod_get_volume_pre_post,
                   pod_set_volume_pre_post);
-static DEVICE_ATTR(di_model, S_IWUGO | S_IRUGO, pod_get_di_model,
+static DEVICE_ATTR(di_model, S_IWUSR | S_IRUGO, pod_get_di_model,
                   pod_set_di_model);
-static DEVICE_ATTR(di_delay, S_IWUGO | S_IRUGO, pod_get_di_delay,
+static DEVICE_ATTR(di_delay, S_IWUSR | S_IRUGO, pod_get_di_delay,
                   pod_set_di_delay);
-static DEVICE_ATTR(mod_enable, S_IWUGO | S_IRUGO, pod_get_mod_enable,
+static DEVICE_ATTR(mod_enable, S_IWUSR | S_IRUGO, pod_get_mod_enable,
                   pod_set_mod_enable);
-static DEVICE_ATTR(mod_param_1_note_value, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(mod_param_1_note_value, S_IWUSR | S_IRUGO,
                   pod_get_mod_param_1_note_value,
                   pod_set_mod_param_1_note_value);
-static DEVICE_ATTR(mod_param_2, S_IWUGO | S_IRUGO, pod_get_mod_param_2,
+static DEVICE_ATTR(mod_param_2, S_IWUSR | S_IRUGO, pod_get_mod_param_2,
                   pod_set_mod_param_2);
-static DEVICE_ATTR(mod_param_3, S_IWUGO | S_IRUGO, pod_get_mod_param_3,
+static DEVICE_ATTR(mod_param_3, S_IWUSR | S_IRUGO, pod_get_mod_param_3,
                   pod_set_mod_param_3);
-static DEVICE_ATTR(mod_param_4, S_IWUGO | S_IRUGO, pod_get_mod_param_4,
+static DEVICE_ATTR(mod_param_4, S_IWUSR | S_IRUGO, pod_get_mod_param_4,
                   pod_set_mod_param_4);
-static DEVICE_ATTR(mod_param_5, S_IWUGO | S_IRUGO, pod_get_mod_param_5,
+static DEVICE_ATTR(mod_param_5, S_IWUSR | S_IRUGO, pod_get_mod_param_5,
                   pod_set_mod_param_5);
-static DEVICE_ATTR(mod_volume_mix, S_IWUGO | S_IRUGO, pod_get_mod_volume_mix,
+static DEVICE_ATTR(mod_volume_mix, S_IWUSR | S_IRUGO, pod_get_mod_volume_mix,
                   pod_set_mod_volume_mix);
-static DEVICE_ATTR(mod_pre_post, S_IWUGO | S_IRUGO, pod_get_mod_pre_post,
+static DEVICE_ATTR(mod_pre_post, S_IWUSR | S_IRUGO, pod_get_mod_pre_post,
                   pod_set_mod_pre_post);
-static DEVICE_ATTR(modulation_model, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(modulation_model, S_IWUSR | S_IRUGO,
                   pod_get_modulation_model, pod_set_modulation_model);
-static DEVICE_ATTR(band_3_frequency, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(band_3_frequency, S_IWUSR | S_IRUGO,
                   pod_get_band_3_frequency, pod_set_band_3_frequency);
-static DEVICE_ATTR2(band_4_frequency__bass, band_4_frequency, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR2(band_4_frequency__bass, band_4_frequency, S_IWUSR | S_IRUGO,
                    pod_get_band_4_frequency__bass,
                    pod_set_band_4_frequency__bass);
-static DEVICE_ATTR(mod_param_1_double_precision, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(mod_param_1_double_precision, S_IWUSR | S_IRUGO,
                   pod_get_mod_param_1_double_precision,
                   pod_set_mod_param_1_double_precision);
-static DEVICE_ATTR(delay_param_1_double_precision, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(delay_param_1_double_precision, S_IWUSR | S_IRUGO,
                   pod_get_delay_param_1_double_precision,
                   pod_set_delay_param_1_double_precision);
-static DEVICE_ATTR(eq_enable, S_IWUGO | S_IRUGO, pod_get_eq_enable,
+static DEVICE_ATTR(eq_enable, S_IWUSR | S_IRUGO, pod_get_eq_enable,
                   pod_set_eq_enable);
-static DEVICE_ATTR(tap, S_IWUGO | S_IRUGO, pod_get_tap, pod_set_tap);
-static DEVICE_ATTR(volume_tweak_pedal_assign, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(tap, S_IWUSR | S_IRUGO, pod_get_tap, pod_set_tap);
+static DEVICE_ATTR(volume_tweak_pedal_assign, S_IWUSR | S_IRUGO,
                   pod_get_volume_tweak_pedal_assign,
                   pod_set_volume_tweak_pedal_assign);
-static DEVICE_ATTR(band_5_frequency, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(band_5_frequency, S_IWUSR | S_IRUGO,
                   pod_get_band_5_frequency, pod_set_band_5_frequency);
-static DEVICE_ATTR(tuner, S_IWUGO | S_IRUGO, pod_get_tuner, pod_set_tuner);
-static DEVICE_ATTR(mic_selection, S_IWUGO | S_IRUGO, pod_get_mic_selection,
+static DEVICE_ATTR(tuner, S_IWUSR | S_IRUGO, pod_get_tuner, pod_set_tuner);
+static DEVICE_ATTR(mic_selection, S_IWUSR | S_IRUGO, pod_get_mic_selection,
                   pod_set_mic_selection);
-static DEVICE_ATTR(cabinet_model, S_IWUGO | S_IRUGO, pod_get_cabinet_model,
+static DEVICE_ATTR(cabinet_model, S_IWUSR | S_IRUGO, pod_get_cabinet_model,
                   pod_set_cabinet_model);
-static DEVICE_ATTR(stomp_model, S_IWUGO | S_IRUGO, pod_get_stomp_model,
+static DEVICE_ATTR(stomp_model, S_IWUSR | S_IRUGO, pod_get_stomp_model,
                   pod_set_stomp_model);
-static DEVICE_ATTR(roomlevel, S_IWUGO | S_IRUGO, pod_get_roomlevel,
+static DEVICE_ATTR(roomlevel, S_IWUSR | S_IRUGO, pod_get_roomlevel,
                   pod_set_roomlevel);
-static DEVICE_ATTR(band_4_frequency, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(band_4_frequency, S_IWUSR | S_IRUGO,
                   pod_get_band_4_frequency, pod_set_band_4_frequency);
-static DEVICE_ATTR(band_6_frequency, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(band_6_frequency, S_IWUSR | S_IRUGO,
                   pod_get_band_6_frequency, pod_set_band_6_frequency);
-static DEVICE_ATTR(stomp_param_1_note_value, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(stomp_param_1_note_value, S_IWUSR | S_IRUGO,
                   pod_get_stomp_param_1_note_value,
                   pod_set_stomp_param_1_note_value);
-static DEVICE_ATTR(stomp_param_2, S_IWUGO | S_IRUGO, pod_get_stomp_param_2,
+static DEVICE_ATTR(stomp_param_2, S_IWUSR | S_IRUGO, pod_get_stomp_param_2,
                   pod_set_stomp_param_2);
-static DEVICE_ATTR(stomp_param_3, S_IWUGO | S_IRUGO, pod_get_stomp_param_3,
+static DEVICE_ATTR(stomp_param_3, S_IWUSR | S_IRUGO, pod_get_stomp_param_3,
                   pod_set_stomp_param_3);
-static DEVICE_ATTR(stomp_param_4, S_IWUGO | S_IRUGO, pod_get_stomp_param_4,
+static DEVICE_ATTR(stomp_param_4, S_IWUSR | S_IRUGO, pod_get_stomp_param_4,
                   pod_set_stomp_param_4);
-static DEVICE_ATTR(stomp_param_5, S_IWUGO | S_IRUGO, pod_get_stomp_param_5,
+static DEVICE_ATTR(stomp_param_5, S_IWUSR | S_IRUGO, pod_get_stomp_param_5,
                   pod_set_stomp_param_5);
-static DEVICE_ATTR(stomp_param_6, S_IWUGO | S_IRUGO, pod_get_stomp_param_6,
+static DEVICE_ATTR(stomp_param_6, S_IWUSR | S_IRUGO, pod_get_stomp_param_6,
                   pod_set_stomp_param_6);
-static DEVICE_ATTR(amp_switch_select, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(amp_switch_select, S_IWUSR | S_IRUGO,
                   pod_get_amp_switch_select, pod_set_amp_switch_select);
-static DEVICE_ATTR(delay_param_4, S_IWUGO | S_IRUGO, pod_get_delay_param_4,
+static DEVICE_ATTR(delay_param_4, S_IWUSR | S_IRUGO, pod_get_delay_param_4,
                   pod_set_delay_param_4);
-static DEVICE_ATTR(delay_param_5, S_IWUGO | S_IRUGO, pod_get_delay_param_5,
+static DEVICE_ATTR(delay_param_5, S_IWUSR | S_IRUGO, pod_get_delay_param_5,
                   pod_set_delay_param_5);
-static DEVICE_ATTR(delay_pre_post, S_IWUGO | S_IRUGO, pod_get_delay_pre_post,
+static DEVICE_ATTR(delay_pre_post, S_IWUSR | S_IRUGO, pod_get_delay_pre_post,
                   pod_set_delay_pre_post);
-static DEVICE_ATTR(delay_model, S_IWUGO | S_IRUGO, pod_get_delay_model,
+static DEVICE_ATTR(delay_model, S_IWUSR | S_IRUGO, pod_get_delay_model,
                   pod_set_delay_model);
-static DEVICE_ATTR(delay_verb_model, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(delay_verb_model, S_IWUSR | S_IRUGO,
                   pod_get_delay_verb_model, pod_set_delay_verb_model);
-static DEVICE_ATTR(tempo_msb, S_IWUGO | S_IRUGO, pod_get_tempo_msb,
+static DEVICE_ATTR(tempo_msb, S_IWUSR | S_IRUGO, pod_get_tempo_msb,
                   pod_set_tempo_msb);
-static DEVICE_ATTR(tempo_lsb, S_IWUGO | S_IRUGO, pod_get_tempo_lsb,
+static DEVICE_ATTR(tempo_lsb, S_IWUSR | S_IRUGO, pod_get_tempo_lsb,
                   pod_set_tempo_lsb);
-static DEVICE_ATTR(wah_model, S_IWUGO | S_IRUGO, pod_get_wah_model,
+static DEVICE_ATTR(wah_model, S_IWUSR | S_IRUGO, pod_get_wah_model,
                   pod_set_wah_model);
-static DEVICE_ATTR(bypass_volume, S_IWUGO | S_IRUGO, pod_get_bypass_volume,
+static DEVICE_ATTR(bypass_volume, S_IWUSR | S_IRUGO, pod_get_bypass_volume,
                   pod_set_bypass_volume);
-static DEVICE_ATTR(fx_loop_on_off, S_IWUGO | S_IRUGO, pod_get_fx_loop_on_off,
+static DEVICE_ATTR(fx_loop_on_off, S_IWUSR | S_IRUGO, pod_get_fx_loop_on_off,
                   pod_set_fx_loop_on_off);
-static DEVICE_ATTR(tweak_param_select, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(tweak_param_select, S_IWUSR | S_IRUGO,
                   pod_get_tweak_param_select, pod_set_tweak_param_select);
-static DEVICE_ATTR(amp1_engage, S_IWUGO | S_IRUGO, pod_get_amp1_engage,
+static DEVICE_ATTR(amp1_engage, S_IWUSR | S_IRUGO, pod_get_amp1_engage,
                   pod_set_amp1_engage);
-static DEVICE_ATTR(band_1_gain, S_IWUGO | S_IRUGO, pod_get_band_1_gain,
+static DEVICE_ATTR(band_1_gain, S_IWUSR | S_IRUGO, pod_get_band_1_gain,
                   pod_set_band_1_gain);
-static DEVICE_ATTR2(band_2_gain__bass, band_2_gain, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR2(band_2_gain__bass, band_2_gain, S_IWUSR | S_IRUGO,
                    pod_get_band_2_gain__bass, pod_set_band_2_gain__bass);
-static DEVICE_ATTR(band_2_gain, S_IWUGO | S_IRUGO, pod_get_band_2_gain,
+static DEVICE_ATTR(band_2_gain, S_IWUSR | S_IRUGO, pod_get_band_2_gain,
                   pod_set_band_2_gain);
-static DEVICE_ATTR2(band_3_gain__bass, band_3_gain, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR2(band_3_gain__bass, band_3_gain, S_IWUSR | S_IRUGO,
                    pod_get_band_3_gain__bass, pod_set_band_3_gain__bass);
-static DEVICE_ATTR(band_3_gain, S_IWUGO | S_IRUGO, pod_get_band_3_gain,
+static DEVICE_ATTR(band_3_gain, S_IWUSR | S_IRUGO, pod_get_band_3_gain,
                   pod_set_band_3_gain);
-static DEVICE_ATTR2(band_4_gain__bass, band_4_gain, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR2(band_4_gain__bass, band_4_gain, S_IWUSR | S_IRUGO,
                    pod_get_band_4_gain__bass, pod_set_band_4_gain__bass);
-static DEVICE_ATTR2(band_5_gain__bass, band_5_gain, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR2(band_5_gain__bass, band_5_gain, S_IWUSR | S_IRUGO,
                    pod_get_band_5_gain__bass, pod_set_band_5_gain__bass);
-static DEVICE_ATTR(band_4_gain, S_IWUGO | S_IRUGO, pod_get_band_4_gain,
+static DEVICE_ATTR(band_4_gain, S_IWUSR | S_IRUGO, pod_get_band_4_gain,
                   pod_set_band_4_gain);
-static DEVICE_ATTR2(band_6_gain__bass, band_6_gain, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR2(band_6_gain__bass, band_6_gain, S_IWUSR | S_IRUGO,
                    pod_get_band_6_gain__bass, pod_set_band_6_gain__bass);
 static DEVICE_ATTR(body, S_IRUGO, variax_get_body, line6_nop_write);
 static DEVICE_ATTR(pickup1_enable, S_IRUGO, variax_get_pickup1_enable,
index 4304dfe..ab67e88 100644 (file)
@@ -350,9 +350,9 @@ static ssize_t midi_set_midi_mask_receive(struct device *dev,
        return count;
 }
 
-static DEVICE_ATTR(midi_mask_transmit, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(midi_mask_transmit, S_IWUSR | S_IRUGO,
                   midi_get_midi_mask_transmit, midi_set_midi_mask_transmit);
-static DEVICE_ATTR(midi_mask_receive, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(midi_mask_receive, S_IWUSR | S_IRUGO,
                   midi_get_midi_mask_receive, midi_set_midi_mask_receive);
 
 /* MIDI device destructor */
index e54770e..b9c55f9 100644 (file)
@@ -79,9 +79,9 @@ static ssize_t pcm_set_impulse_period(struct device *dev,
        return count;
 }
 
-static DEVICE_ATTR(impulse_volume, S_IWUGO | S_IRUGO, pcm_get_impulse_volume,
+static DEVICE_ATTR(impulse_volume, S_IWUSR | S_IRUGO, pcm_get_impulse_volume,
                   pcm_set_impulse_volume);
-static DEVICE_ATTR(impulse_period, S_IWUGO | S_IRUGO, pcm_get_impulse_period,
+static DEVICE_ATTR(impulse_period, S_IWUSR | S_IRUGO, pcm_get_impulse_period,
                   pcm_set_impulse_period);
 
 #endif
index 22e2ced..d9b3021 100644 (file)
@@ -1051,48 +1051,48 @@ POD_GET_SYSTEM_PARAM(tuner_pitch, 1);
 #undef GET_SYSTEM_PARAM
 
 /* POD special files: */
-static DEVICE_ATTR(channel, S_IWUGO | S_IRUGO, pod_get_channel,
+static DEVICE_ATTR(channel, S_IWUSR | S_IRUGO, pod_get_channel,
                   pod_set_channel);
 static DEVICE_ATTR(clip, S_IRUGO, pod_wait_for_clip, line6_nop_write);
 static DEVICE_ATTR(device_id, S_IRUGO, pod_get_device_id, line6_nop_write);
 static DEVICE_ATTR(dirty, S_IRUGO, pod_get_dirty, line6_nop_write);
-static DEVICE_ATTR(dump, S_IWUGO | S_IRUGO, pod_get_dump, pod_set_dump);
-static DEVICE_ATTR(dump_buf, S_IWUGO | S_IRUGO, pod_get_dump_buf,
+static DEVICE_ATTR(dump, S_IWUSR | S_IRUGO, pod_get_dump, pod_set_dump);
+static DEVICE_ATTR(dump_buf, S_IWUSR | S_IRUGO, pod_get_dump_buf,
                   pod_set_dump_buf);
-static DEVICE_ATTR(finish, S_IWUGO, line6_nop_read, pod_set_finish);
+static DEVICE_ATTR(finish, S_IWUSR, line6_nop_read, pod_set_finish);
 static DEVICE_ATTR(firmware_version, S_IRUGO, pod_get_firmware_version,
                   line6_nop_write);
-static DEVICE_ATTR(midi_postprocess, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(midi_postprocess, S_IWUSR | S_IRUGO,
                   pod_get_midi_postprocess, pod_set_midi_postprocess);
-static DEVICE_ATTR(monitor_level, S_IWUGO | S_IRUGO, pod_get_monitor_level,
+static DEVICE_ATTR(monitor_level, S_IWUSR | S_IRUGO, pod_get_monitor_level,
                   pod_set_monitor_level);
 static DEVICE_ATTR(name, S_IRUGO, pod_get_name, line6_nop_write);
 static DEVICE_ATTR(name_buf, S_IRUGO, pod_get_name_buf, line6_nop_write);
-static DEVICE_ATTR(retrieve_amp_setup, S_IWUGO, line6_nop_read,
+static DEVICE_ATTR(retrieve_amp_setup, S_IWUSR, line6_nop_read,
                   pod_set_retrieve_amp_setup);
-static DEVICE_ATTR(retrieve_channel, S_IWUGO, line6_nop_read,
+static DEVICE_ATTR(retrieve_channel, S_IWUSR, line6_nop_read,
                   pod_set_retrieve_channel);
-static DEVICE_ATTR(retrieve_effects_setup, S_IWUGO, line6_nop_read,
+static DEVICE_ATTR(retrieve_effects_setup, S_IWUSR, line6_nop_read,
                   pod_set_retrieve_effects_setup);
-static DEVICE_ATTR(routing, S_IWUGO | S_IRUGO, pod_get_routing,
+static DEVICE_ATTR(routing, S_IWUSR | S_IRUGO, pod_get_routing,
                   pod_set_routing);
 static DEVICE_ATTR(serial_number, S_IRUGO, pod_get_serial_number,
                   line6_nop_write);
-static DEVICE_ATTR(store_amp_setup, S_IWUGO, line6_nop_read,
+static DEVICE_ATTR(store_amp_setup, S_IWUSR, line6_nop_read,
                   pod_set_store_amp_setup);
-static DEVICE_ATTR(store_channel, S_IWUGO, line6_nop_read,
+static DEVICE_ATTR(store_channel, S_IWUSR, line6_nop_read,
                   pod_set_store_channel);
-static DEVICE_ATTR(store_effects_setup, S_IWUGO, line6_nop_read,
+static DEVICE_ATTR(store_effects_setup, S_IWUSR, line6_nop_read,
                   pod_set_store_effects_setup);
-static DEVICE_ATTR(tuner_freq, S_IWUGO | S_IRUGO, pod_get_tuner_freq,
+static DEVICE_ATTR(tuner_freq, S_IWUSR | S_IRUGO, pod_get_tuner_freq,
                   pod_set_tuner_freq);
-static DEVICE_ATTR(tuner_mute, S_IWUGO | S_IRUGO, pod_get_tuner_mute,
+static DEVICE_ATTR(tuner_mute, S_IWUSR | S_IRUGO, pod_get_tuner_mute,
                   pod_set_tuner_mute);
 static DEVICE_ATTR(tuner_note, S_IRUGO, pod_get_tuner_note, line6_nop_write);
 static DEVICE_ATTR(tuner_pitch, S_IRUGO, pod_get_tuner_pitch, line6_nop_write);
 
 #ifdef CONFIG_LINE6_USB_RAW
-static DEVICE_ATTR(raw, S_IWUGO, line6_nop_read, line6_set_raw);
+static DEVICE_ATTR(raw, S_IWUSR, line6_nop_read, line6_set_raw);
 #endif
 
 /* control info callback */
index 6a10b0f..879e699 100644 (file)
@@ -154,9 +154,9 @@ static ssize_t toneport_set_led_green(struct device *dev,
        return count;
 }
 
-static DEVICE_ATTR(led_red, S_IWUGO | S_IRUGO, line6_nop_read,
+static DEVICE_ATTR(led_red, S_IWUSR | S_IRUGO, line6_nop_read,
                   toneport_set_led_red);
-static DEVICE_ATTR(led_green, S_IWUGO | S_IRUGO, line6_nop_read,
+static DEVICE_ATTR(led_green, S_IWUSR | S_IRUGO, line6_nop_read,
                   toneport_set_led_green);
 
 static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2)
index 894eee7..81241cd 100644 (file)
@@ -549,21 +549,21 @@ static ssize_t variax_set_raw2(struct device *dev,
 #endif
 
 /* Variax workbench special files: */
-static DEVICE_ATTR(model, S_IWUGO | S_IRUGO, variax_get_model,
+static DEVICE_ATTR(model, S_IWUSR | S_IRUGO, variax_get_model,
                   variax_set_model);
-static DEVICE_ATTR(volume, S_IWUGO | S_IRUGO, variax_get_volume,
+static DEVICE_ATTR(volume, S_IWUSR | S_IRUGO, variax_get_volume,
                   variax_set_volume);
-static DEVICE_ATTR(tone, S_IWUGO | S_IRUGO, variax_get_tone, variax_set_tone);
+static DEVICE_ATTR(tone, S_IWUSR | S_IRUGO, variax_get_tone, variax_set_tone);
 static DEVICE_ATTR(name, S_IRUGO, variax_get_name, line6_nop_write);
 static DEVICE_ATTR(bank, S_IRUGO, variax_get_bank, line6_nop_write);
 static DEVICE_ATTR(dump, S_IRUGO, variax_get_dump, line6_nop_write);
-static DEVICE_ATTR(active, S_IWUGO | S_IRUGO, variax_get_active,
+static DEVICE_ATTR(active, S_IWUSR | S_IRUGO, variax_get_active,
                   variax_set_active);
 static DEVICE_ATTR(guitar, S_IRUGO, variax_get_guitar, line6_nop_write);
 
 #ifdef CONFIG_LINE6_USB_RAW
-static DEVICE_ATTR(raw, S_IWUGO, line6_nop_read, line6_set_raw);
-static DEVICE_ATTR(raw2, S_IWUGO, line6_nop_read, variax_set_raw2);
+static DEVICE_ATTR(raw, S_IWUSR, line6_nop_read, line6_set_raw);
+static DEVICE_ATTR(raw2, S_IWUSR, line6_nop_read, variax_set_raw2);
 #endif
 
 /*
index d746715..d83bec8 100644 (file)
@@ -355,7 +355,6 @@ static int quickstart_acpi_remove(struct acpi_device *device, int type)
 static void quickstart_exit(void)
 {
        input_unregister_device(quickstart_input);
-       input_free_device(quickstart_input);
 
        device_remove_file(&pf_device->dev, &dev_attr_pressed_button);
        device_remove_file(&pf_device->dev, &dev_attr_buttons);
@@ -375,6 +374,7 @@ static int __init quickstart_init_input(void)
 {
        struct quickstart_btn **ptr = &quickstart_data.btn_lst;
        int count;
+       int ret;
 
        quickstart_input = input_allocate_device();
 
@@ -391,7 +391,13 @@ static int __init quickstart_init_input(void)
                ptr = &((*ptr)->next);
        }
 
-       return input_register_device(quickstart_input);
+       ret = input_register_device(quickstart_input);
+       if (ret) {
+               input_free_device(quickstart_input);
+               return ret;
+       }
+
+       return 0;
 }
 
 static int __init quickstart_init(void)
index ddacfc6..cd15daa 100644 (file)
@@ -182,6 +182,7 @@ struct usb_device_id rtusb_usb_id[] = {
        {USB_DEVICE(0x2001, 0x3C09)},   /* D-Link */
        {USB_DEVICE(0x2001, 0x3C0A)},   /* D-Link 3072 */
        {USB_DEVICE(0x2019, 0xED14)},   /* Planex Communications, Inc. */
+       {USB_DEVICE(0x0411, 0x015D)},   /* Buffalo Airstation WLI-UC-GN */
        {}                      /* Terminating entry */
 };
 
index 46000d7..3bdf9b3 100644 (file)
@@ -264,8 +264,12 @@ HwHSSIThreeWire(
 
                        udelay(10);
                }
-               if (TryCnt == TC_3W_POLL_MAX_TRY_CNT)
-                       panic("HwThreeWire(): CmdReg: %#X RE|WE bits are not clear!!\n", u1bTmp);
+               if (TryCnt == TC_3W_POLL_MAX_TRY_CNT) {
+                       printk(KERN_ERR "rtl8187se: HwThreeWire(): CmdReg:"
+                              " %#X RE|WE bits are not clear!!\n", u1bTmp);
+                       dump_stack();
+                       return 0;
+               }
 
                /* RTL8187S HSSI Read/Write Function */
                u1bTmp = read_nic_byte(dev, RF_SW_CONFIG);
@@ -298,13 +302,23 @@ HwHSSIThreeWire(
                                int idx;
                                int ByteCnt = nDataBufBitCnt / 8;
                                                                /* printk("%d\n",nDataBufBitCnt); */
-                               if ((nDataBufBitCnt % 8) != 0)
-                               panic("HwThreeWire(): nDataBufBitCnt(%d) should be multiple of 8!!!\n",
-                               nDataBufBitCnt);
+                               if ((nDataBufBitCnt % 8) != 0) {
+                                       printk(KERN_ERR "rtl8187se: "
+                                              "HwThreeWire(): nDataBufBitCnt(%d)"
+                                              " should be multiple of 8!!!\n",
+                                              nDataBufBitCnt);
+                                       dump_stack();
+                                       nDataBufBitCnt += 8;
+                                       nDataBufBitCnt &= ~7;
+                               }
 
-                              if (nDataBufBitCnt > 64)
-                               panic("HwThreeWire(): nDataBufBitCnt(%d) should <= 64!!!\n",
-                               nDataBufBitCnt);
+                              if (nDataBufBitCnt > 64) {
+                                       printk(KERN_ERR "rtl8187se: HwThreeWire():"
+                                              " nDataBufBitCnt(%d) should <= 64!!!\n",
+                                              nDataBufBitCnt);
+                                       dump_stack();
+                                       nDataBufBitCnt = 64;
+                               }
 
                                for (idx = 0; idx < ByteCnt; idx++)
                                        write_nic_byte(dev, (SW_3W_DB0+idx), *(pDataBuf+idx));
index f6569dc..0e9483b 100644 (file)
@@ -37,7 +37,7 @@ u8 r8712_usb_hal_bus_init(struct _adapter *padapter)
 {
        u8 val8 = 0;
        u8 ret = _SUCCESS;
-       u8 PollingCnt = 20;
+       int PollingCnt = 20;
        struct registry_priv *pregistrypriv = &padapter->registrypriv;
 
        if (pregistrypriv->chip_version == RTL8712_FPGA) {
index eb44b60..ac2bf11 100644 (file)
@@ -356,7 +356,7 @@ static ssize_t set_silent_state(struct device *dev,
        }
        return count;
 }
-static DEVICE_ATTR(silent, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(silent, S_IWUSR | S_IRUGO,
                   get_silent_state, set_silent_state);
 
 
index adb93f2..65b2311 100644 (file)
@@ -62,7 +62,6 @@ void speakup_remove_virtual_keyboard(void)
 {
        if (virt_keyboard != NULL) {
                input_unregister_device(virt_keyboard);
-               input_free_device(virt_keyboard);
                virt_keyboard = NULL;
        }
 }
index c7932da..63a9d0a 100644 (file)
@@ -656,7 +656,7 @@ static int SBD_setup_device(struct spectra_nand_dev *dev, int which)
        /* Here we force report 512 byte hardware sector size to Kernel */
        blk_queue_logical_block_size(dev->queue, 512);
 
-       blk_queue_ordered(dev->queue, QUEUE_ORDERED_DRAIN_FLUSH);
+       blk_queue_flush(dev->queue, REQ_FLUSH);
 
        dev->thread = kthread_run(spectra_trans_thread, dev, "nand_thd");
        if (IS_ERR(dev->thread)) {
index 664e603..b143258 100644 (file)
@@ -545,7 +545,7 @@ static void tm6000_config_tuner(struct tm6000_core *dev)
 
        /* Load tuner module */
        v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
-               NULL, "tuner", dev->tuner_addr, NULL);
+               "tuner", dev->tuner_addr, NULL);
 
        memset(&tun_setup, 0, sizeof(tun_setup));
        tun_setup.type = dev->tuner_type;
@@ -683,7 +683,7 @@ static int tm6000_init_dev(struct tm6000_core *dev)
 
        if (dev->caps.has_tda9874)
                v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
-                       NULL, "tvaudio", I2C_ADDR_TDA9874, NULL);
+                       "tvaudio", I2C_ADDR_TDA9874, NULL);
 
        /* register and initialize V4L2 */
        rc = tm6000_v4l2_register(dev);
index fed2510..b7ac160 100644 (file)
@@ -1441,7 +1441,7 @@ static struct device_attribute fb_device_attrs[] = {
        __ATTR_RO(metrics_bytes_identical),
        __ATTR_RO(metrics_bytes_sent),
        __ATTR_RO(metrics_cpu_kcycles_used),
-       __ATTR(metrics_reset, S_IWUGO, NULL, metrics_reset_store),
+       __ATTR(metrics_reset, S_IWUSR, NULL, metrics_reset_store),
 };
 
 /*
index 9195adf..d0d71f6 100644 (file)
@@ -2,6 +2,9 @@
 
 #ifndef SYS_DEF_H
 #define SYS_DEF_H
+
+#include <linux/delay.h>
+
 #define WB_LINUX
 #define WB_LINUX_WPA_PSK
 
index 6c574a9..6b3cf00 100644 (file)
@@ -189,10 +189,10 @@ static ssize_t mem_used_total_show(struct device *dev,
        return sprintf(buf, "%llu\n", val);
 }
 
-static DEVICE_ATTR(disksize, S_IRUGO | S_IWUGO,
+static DEVICE_ATTR(disksize, S_IRUGO | S_IWUSR,
                disksize_show, disksize_store);
 static DEVICE_ATTR(initstate, S_IRUGO, initstate_show, NULL);
-static DEVICE_ATTR(reset, S_IWUGO, NULL, reset_store);
+static DEVICE_ATTR(reset, S_IWUSR, NULL, reset_store);
 static DEVICE_ATTR(num_reads, S_IRUGO, num_reads_show, NULL);
 static DEVICE_ATTR(num_writes, S_IRUGO, num_writes_show, NULL);
 static DEVICE_ATTR(invalid_io, S_IRUGO, invalid_io_show, NULL);
index c05c5af..35480dd 100644 (file)
@@ -559,6 +559,9 @@ void __tty_hangup(struct tty_struct *tty)
 
        tty_lock();
 
+       /* some functions below drop BTM, so we need this bit */
+       set_bit(TTY_HUPPING, &tty->flags);
+
        /* inuse_filps is protected by the single tty lock,
           this really needs to change if we want to flush the
           workqueue with the lock held */
@@ -578,6 +581,10 @@ void __tty_hangup(struct tty_struct *tty)
        }
        spin_unlock(&tty_files_lock);
 
+       /*
+        * it drops BTM and thus races with reopen
+        * we protect the race by TTY_HUPPING
+        */
        tty_ldisc_hangup(tty);
 
        read_lock(&tasklist_lock);
@@ -615,7 +622,6 @@ void __tty_hangup(struct tty_struct *tty)
        tty->session = NULL;
        tty->pgrp = NULL;
        tty->ctrl_status = 0;
-       set_bit(TTY_HUPPED, &tty->flags);
        spin_unlock_irqrestore(&tty->ctrl_lock, flags);
 
        /* Account for the p->signal references we killed */
@@ -641,6 +647,7 @@ void __tty_hangup(struct tty_struct *tty)
         * can't yet guarantee all that.
         */
        set_bit(TTY_HUPPED, &tty->flags);
+       clear_bit(TTY_HUPPING, &tty->flags);
        tty_ldisc_enable(tty);
 
        tty_unlock();
@@ -1310,7 +1317,9 @@ static int tty_reopen(struct tty_struct *tty)
 {
        struct tty_driver *driver = tty->driver;
 
-       if (test_bit(TTY_CLOSING, &tty->flags))
+       if (test_bit(TTY_CLOSING, &tty->flags) ||
+                       test_bit(TTY_HUPPING, &tty->flags) ||
+                       test_bit(TTY_LDISC_CHANGING, &tty->flags))
                return -EIO;
 
        if (driver->type == TTY_DRIVER_TYPE_PTY &&
index d8e96b0..4214d58 100644 (file)
@@ -454,6 +454,8 @@ static int tty_ldisc_open(struct tty_struct *tty, struct tty_ldisc *ld)
                 /* BTM here locks versus a hangup event */
                WARN_ON(!tty_locked());
                ret = ld->ops->open(tty);
+               if (ret)
+                       clear_bit(TTY_LDISC_OPEN, &tty->flags);
                return ret;
        }
        return 0;
index a858d2b..51fe179 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright(C) 2005, Benedikt Spranger <b.spranger@linutronix.de>
  * Copyright(C) 2005, Thomas Gleixner <tglx@linutronix.de>
- * Copyright(C) 2006, Hans J. Koch <hjk@linutronix.de>
+ * Copyright(C) 2006, Hans J. Koch <hjk@hansjkoch.de>
  * Copyright(C) 2006, Greg Kroah-Hartman <greg@kroah.com>
  *
  * Userspace IO
index a8ea2f1..a84a451 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * UIO Hilscher CIF card driver
  *
- * (C) 2007 Hans J. Koch <hjk@linutronix.de>
+ * (C) 2007 Hans J. Koch <hjk@hansjkoch.de>
  * Original code (C) 2005 Benedikt Spranger <b.spranger@linutronix.de>
  *
  * Licensed under GPL version 2 only.
index 5a18e9f..5ffdb48 100644 (file)
@@ -2,7 +2,7 @@
  * UIO driver for Hilscher NetX based fieldbus cards (cifX, comX).
  * See http://www.hilscher.com for details.
  *
- * (C) 2007 Hans J. Koch <hjk@linutronix.de>
+ * (C) 2007 Hans J. Koch <hjk@hansjkoch.de>
  * (C) 2008 Manuel Traut <manut@linutronix.de>
  *
  * Licensed under GPL version 2 only.
index 05bf5a2..989e16e 100644 (file)
@@ -951,7 +951,9 @@ static int usbatm_atm_init(struct usbatm_data *instance)
         * condition: callbacks we register can be executed at once, before we have
         * initialized the struct atm_dev.  To protect against this, all callbacks
         * abort if atm_dev->dev_data is NULL. */
-       atm_dev = atm_dev_register(instance->driver_name, &usbatm_atm_devops, -1, NULL);
+       atm_dev = atm_dev_register(instance->driver_name,
+                                  &instance->usb_intf->dev, &usbatm_atm_devops,
+                                  -1, NULL);
        if (!atm_dev) {
                usb_err(instance, "%s: failed to register ATM device!\n", __func__);
                return -1;
@@ -966,14 +968,6 @@ static int usbatm_atm_init(struct usbatm_data *instance)
        /* temp init ATM device, set to 128kbit */
        atm_dev->link_rate = 128 * 1000 / 424;
 
-       ret = sysfs_create_link(&atm_dev->class_dev.kobj,
-                               &instance->usb_intf->dev.kobj, "device");
-       if (ret) {
-               atm_err(instance, "%s: sysfs_create_link failed: %d\n",
-                                       __func__, ret);
-               goto fail_sysfs;
-       }
-
        if (instance->driver->atm_start && ((ret = instance->driver->atm_start(instance, atm_dev)) < 0)) {
                atm_err(instance, "%s: atm_start failed: %d!\n", __func__, ret);
                goto fail;
@@ -992,8 +986,6 @@ static int usbatm_atm_init(struct usbatm_data *instance)
        return 0;
 
  fail:
-       sysfs_remove_link(&atm_dev->class_dev.kobj, "device");
- fail_sysfs:
        instance->atm_dev = NULL;
        atm_dev_deregister(atm_dev); /* usbatm_atm_dev_close will eventually be called */
        return ret;
@@ -1329,7 +1321,6 @@ void usbatm_usb_disconnect(struct usb_interface *intf)
 
        /* ATM finalize */
        if (instance->atm_dev) {
-               sysfs_remove_link(&instance->atm_dev->class_dev.kobj, "device");
                atm_dev_deregister(instance->atm_dev);
                instance->atm_dev = NULL;
        }
index 61800f7..ced846a 100644 (file)
@@ -1330,6 +1330,8 @@ static int map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
         */
 
        if (usb_endpoint_xfer_control(&urb->ep->desc)) {
+               if (hcd->self.uses_pio_for_control)
+                       return ret;
                if (hcd->self.uses_dma) {
                        urb->setup_dma = dma_map_single(
                                        hcd->self.controller,
index 01bb72b..655f3c9 100644 (file)
@@ -161,6 +161,18 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
                        if (pdev->revision < 0xa4)
                                ehci->no_selective_suspend = 1;
                        break;
+
+               /* MCP89 chips on the MacBookAir3,1 give EPROTO when
+                * fetching device descriptors unless LPM is disabled.
+                * There are also intermittent problems enumerating
+                * devices with PPCD enabled.
+                */
+               case 0x0d9d:
+                       ehci_info(ehci, "disable lpm/ppcd for nvidia mcp89");
+                       ehci->has_lpm = 0;
+                       ehci->has_ppcd = 0;
+                       ehci->command &= ~CMD_PPCEE;
+                       break;
                }
                break;
        case PCI_VENDOR_ID_VIA:
index fef5a1f..5d963e3 100644 (file)
@@ -229,6 +229,13 @@ void xhci_ring_device(struct xhci_hcd *xhci, int slot_id)
 static void xhci_disable_port(struct xhci_hcd *xhci, u16 wIndex,
                u32 __iomem *addr, u32 port_status)
 {
+       /* Don't allow the USB core to disable SuperSpeed ports. */
+       if (xhci->port_array[wIndex] == 0x03) {
+               xhci_dbg(xhci, "Ignoring request to disable "
+                               "SuperSpeed port.\n");
+               return;
+       }
+
        /* Write 1 to disable the port */
        xhci_writel(xhci, port_status | PORT_PE, addr);
        port_status = xhci_readl(xhci, addr);
index d178761..0fae58e 100644 (file)
@@ -1443,6 +1443,13 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
        xhci->dcbaa = NULL;
 
        scratchpad_free(xhci);
+
+       xhci->num_usb2_ports = 0;
+       xhci->num_usb3_ports = 0;
+       kfree(xhci->usb2_ports);
+       kfree(xhci->usb3_ports);
+       kfree(xhci->port_array);
+
        xhci->page_size = 0;
        xhci->page_shift = 0;
        xhci->bus_suspended = 0;
@@ -1627,6 +1634,161 @@ static void xhci_set_hc_event_deq(struct xhci_hcd *xhci)
                        &xhci->ir_set->erst_dequeue);
 }
 
+static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports,
+               u32 __iomem *addr, u8 major_revision)
+{
+       u32 temp, port_offset, port_count;
+       int i;
+
+       if (major_revision > 0x03) {
+               xhci_warn(xhci, "Ignoring unknown port speed, "
+                               "Ext Cap %p, revision = 0x%x\n",
+                               addr, major_revision);
+               /* Ignoring port protocol we can't understand. FIXME */
+               return;
+       }
+
+       /* Port offset and count in the third dword, see section 7.2 */
+       temp = xhci_readl(xhci, addr + 2);
+       port_offset = XHCI_EXT_PORT_OFF(temp);
+       port_count = XHCI_EXT_PORT_COUNT(temp);
+       xhci_dbg(xhci, "Ext Cap %p, port offset = %u, "
+                       "count = %u, revision = 0x%x\n",
+                       addr, port_offset, port_count, major_revision);
+       /* Port count includes the current port offset */
+       if (port_offset == 0 || (port_offset + port_count - 1) > num_ports)
+               /* WTF? "Valid values are â€˜1’ to MaxPorts" */
+               return;
+       port_offset--;
+       for (i = port_offset; i < (port_offset + port_count); i++) {
+               /* Duplicate entry.  Ignore the port if the revisions differ. */
+               if (xhci->port_array[i] != 0) {
+                       xhci_warn(xhci, "Duplicate port entry, Ext Cap %p,"
+                                       " port %u\n", addr, i);
+                       xhci_warn(xhci, "Port was marked as USB %u, "
+                                       "duplicated as USB %u\n",
+                                       xhci->port_array[i], major_revision);
+                       /* Only adjust the roothub port counts if we haven't
+                        * found a similar duplicate.
+                        */
+                       if (xhci->port_array[i] != major_revision &&
+                               xhci->port_array[i] != (u8) -1) {
+                               if (xhci->port_array[i] == 0x03)
+                                       xhci->num_usb3_ports--;
+                               else
+                                       xhci->num_usb2_ports--;
+                               xhci->port_array[i] = (u8) -1;
+                       }
+                       /* FIXME: Should we disable the port? */
+               }
+               xhci->port_array[i] = major_revision;
+               if (major_revision == 0x03)
+                       xhci->num_usb3_ports++;
+               else
+                       xhci->num_usb2_ports++;
+       }
+       /* FIXME: Should we disable ports not in the Extended Capabilities? */
+}
+
+/*
+ * Scan the Extended Capabilities for the "Supported Protocol Capabilities" that
+ * specify what speeds each port is supposed to be.  We can't count on the port
+ * speed bits in the PORTSC register being correct until a device is connected,
+ * but we need to set up the two fake roothubs with the correct number of USB
+ * 3.0 and USB 2.0 ports at host controller initialization time.
+ */
+static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags)
+{
+       u32 __iomem *addr;
+       u32 offset;
+       unsigned int num_ports;
+       int i, port_index;
+
+       addr = &xhci->cap_regs->hcc_params;
+       offset = XHCI_HCC_EXT_CAPS(xhci_readl(xhci, addr));
+       if (offset == 0) {
+               xhci_err(xhci, "No Extended Capability registers, "
+                               "unable to set up roothub.\n");
+               return -ENODEV;
+       }
+
+       num_ports = HCS_MAX_PORTS(xhci->hcs_params1);
+       xhci->port_array = kzalloc(sizeof(*xhci->port_array)*num_ports, flags);
+       if (!xhci->port_array)
+               return -ENOMEM;
+
+       /*
+        * For whatever reason, the first capability offset is from the
+        * capability register base, not from the HCCPARAMS register.
+        * See section 5.3.6 for offset calculation.
+        */
+       addr = &xhci->cap_regs->hc_capbase + offset;
+       while (1) {
+               u32 cap_id;
+
+               cap_id = xhci_readl(xhci, addr);
+               if (XHCI_EXT_CAPS_ID(cap_id) == XHCI_EXT_CAPS_PROTOCOL)
+                       xhci_add_in_port(xhci, num_ports, addr,
+                                       (u8) XHCI_EXT_PORT_MAJOR(cap_id));
+               offset = XHCI_EXT_CAPS_NEXT(cap_id);
+               if (!offset || (xhci->num_usb2_ports + xhci->num_usb3_ports)
+                               == num_ports)
+                       break;
+               /*
+                * Once you're into the Extended Capabilities, the offset is
+                * always relative to the register holding the offset.
+                */
+               addr += offset;
+       }
+
+       if (xhci->num_usb2_ports == 0 && xhci->num_usb3_ports == 0) {
+               xhci_warn(xhci, "No ports on the roothubs?\n");
+               return -ENODEV;
+       }
+       xhci_dbg(xhci, "Found %u USB 2.0 ports and %u USB 3.0 ports.\n",
+                       xhci->num_usb2_ports, xhci->num_usb3_ports);
+       /*
+        * Note we could have all USB 3.0 ports, or all USB 2.0 ports.
+        * Not sure how the USB core will handle a hub with no ports...
+        */
+       if (xhci->num_usb2_ports) {
+               xhci->usb2_ports = kmalloc(sizeof(*xhci->usb2_ports)*
+                               xhci->num_usb2_ports, flags);
+               if (!xhci->usb2_ports)
+                       return -ENOMEM;
+
+               port_index = 0;
+               for (i = 0; i < num_ports; i++)
+                       if (xhci->port_array[i] != 0x03) {
+                               xhci->usb2_ports[port_index] =
+                                       &xhci->op_regs->port_status_base +
+                                       NUM_PORT_REGS*i;
+                               xhci_dbg(xhci, "USB 2.0 port at index %u, "
+                                               "addr = %p\n", i,
+                                               xhci->usb2_ports[port_index]);
+                               port_index++;
+                       }
+       }
+       if (xhci->num_usb3_ports) {
+               xhci->usb3_ports = kmalloc(sizeof(*xhci->usb3_ports)*
+                               xhci->num_usb3_ports, flags);
+               if (!xhci->usb3_ports)
+                       return -ENOMEM;
+
+               port_index = 0;
+               for (i = 0; i < num_ports; i++)
+                       if (xhci->port_array[i] == 0x03) {
+                               xhci->usb3_ports[port_index] =
+                                       &xhci->op_regs->port_status_base +
+                                       NUM_PORT_REGS*i;
+                               xhci_dbg(xhci, "USB 3.0 port at index %u, "
+                                               "addr = %p\n", i,
+                                               xhci->usb3_ports[port_index]);
+                               port_index++;
+                       }
+       }
+       return 0;
+}
 
 int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
 {
@@ -1809,6 +1971,8 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
 
        if (scratchpad_alloc(xhci, flags))
                goto fail;
+       if (xhci_setup_port_arrays(xhci, flags))
+               goto fail;
 
        return 0;
 
index 06fca08..45e4a31 100644 (file)
@@ -1549,6 +1549,15 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci,
                cmd_completion = command->completion;
                cmd_status = &command->status;
                command->command_trb = xhci->cmd_ring->enqueue;
+
+               /* Enqueue pointer can be left pointing to the link TRB,
+                * we must handle that
+                */
+               if ((command->command_trb->link.control & TRB_TYPE_BITMASK)
+                               == TRB_TYPE(TRB_LINK))
+                       command->command_trb =
+                               xhci->cmd_ring->enq_seg->next->trbs;
+
                list_add_tail(&command->cmd_list, &virt_dev->cmd_list);
        } else {
                in_ctx = virt_dev->in_ctx;
@@ -2272,6 +2281,15 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev)
        /* Attempt to submit the Reset Device command to the command ring */
        spin_lock_irqsave(&xhci->lock, flags);
        reset_device_cmd->command_trb = xhci->cmd_ring->enqueue;
+
+       /* Enqueue pointer can be left pointing to the link TRB,
+        * we must handle that
+        */
+       if ((reset_device_cmd->command_trb->link.control & TRB_TYPE_BITMASK)
+                       == TRB_TYPE(TRB_LINK))
+               reset_device_cmd->command_trb =
+                       xhci->cmd_ring->enq_seg->next->trbs;
+
        list_add_tail(&reset_device_cmd->cmd_list, &virt_dev->cmd_list);
        ret = xhci_queue_reset_device(xhci, slot_id);
        if (ret) {
index 85e6564..170c367 100644 (file)
@@ -453,6 +453,24 @@ struct xhci_doorbell_array {
 #define STREAM_ID_TO_DB(p)     (((p) & 0xffff) << 16)
 
 
+/**
+ * struct xhci_protocol_caps
+ * @revision:          major revision, minor revision, capability ID,
+ *                     and next capability pointer.
+ * @name_string:       Four ASCII characters to say which spec this xHC
+ *                     follows, typically "USB ".
+ * @port_info:         Port offset, count, and protocol-defined information.
+ */
+struct xhci_protocol_caps {
+       u32     revision;
+       u32     name_string;
+       u32     port_info;
+};
+
+#define        XHCI_EXT_PORT_MAJOR(x)  (((x) >> 24) & 0xff)
+#define        XHCI_EXT_PORT_OFF(x)    ((x) & 0xff)
+#define        XHCI_EXT_PORT_COUNT(x)  (((x) >> 8) & 0xff)
+
 /**
  * struct xhci_container_ctx
  * @type: Type of context.  Used to calculated offsets to contained contexts.
@@ -1240,6 +1258,14 @@ struct xhci_hcd {
        u32                     suspended_ports[8];     /* which ports are
                                                           suspended */
        unsigned long           resume_done[MAX_HC_PORTS];
+       /* Is each xHCI roothub port a USB 3.0, USB 2.0, or USB 1.1 port? */
+       u8                      *port_array;
+       /* Array of pointers to USB 3.0 PORTSC registers */
+       u32 __iomem             **usb3_ports;
+       unsigned int            num_usb3_ports;
+       /* Array of pointers to USB 2.0 PORTSC registers */
+       u32 __iomem             **usb2_ports;
+       unsigned int            num_usb2_ports;
 };
 
 /* For testing purposes */
index 719c618..ac5bfd6 100644 (file)
@@ -536,6 +536,7 @@ static const struct file_operations yurex_fops = {
        .open =         yurex_open,
        .release =      yurex_release,
        .fasync =       yurex_fasync,
+       .llseek =       default_llseek,
 };
 
 
index e6669fc..99beebc 100644 (file)
@@ -2116,12 +2116,15 @@ bad_config:
         * Otherwise, wait till the gadget driver hooks up.
         */
        if (!is_otg_enabled(musb) && is_host_enabled(musb)) {
+               struct usb_hcd  *hcd = musb_to_hcd(musb);
+
                MUSB_HST_MODE(musb);
                musb->xceiv->default_a = 1;
                musb->xceiv->state = OTG_STATE_A_IDLE;
 
                status = usb_add_hcd(musb_to_hcd(musb), -1, 0);
 
+               hcd->self.uses_pio_for_control = 1;
                DBG(1, "%s mode, status %d, devctl %02x %c\n",
                        "HOST", status,
                        musb_readb(musb->mregs, MUSB_DEVCTL),
index 36cfd06..9d6ade8 100644 (file)
 
 /* ----------------------------------------------------------------------- */
 
+/* Maps the buffer to dma  */
+
+static inline void map_dma_buffer(struct musb_request *request,
+                               struct musb *musb)
+{
+       if (request->request.dma == DMA_ADDR_INVALID) {
+               request->request.dma = dma_map_single(
+                               musb->controller,
+                               request->request.buf,
+                               request->request.length,
+                               request->tx
+                                       ? DMA_TO_DEVICE
+                                       : DMA_FROM_DEVICE);
+               request->mapped = 1;
+       } else {
+               dma_sync_single_for_device(musb->controller,
+                       request->request.dma,
+                       request->request.length,
+                       request->tx
+                               ? DMA_TO_DEVICE
+                               : DMA_FROM_DEVICE);
+               request->mapped = 0;
+       }
+}
+
+/* Unmap the buffer from dma and maps it back to cpu */
+static inline void unmap_dma_buffer(struct musb_request *request,
+                               struct musb *musb)
+{
+       if (request->request.dma == DMA_ADDR_INVALID) {
+               DBG(20, "not unmapping a never mapped buffer\n");
+               return;
+       }
+       if (request->mapped) {
+               dma_unmap_single(musb->controller,
+                       request->request.dma,
+                       request->request.length,
+                       request->tx
+                               ? DMA_TO_DEVICE
+                               : DMA_FROM_DEVICE);
+               request->request.dma = DMA_ADDR_INVALID;
+               request->mapped = 0;
+       } else {
+               dma_sync_single_for_cpu(musb->controller,
+                       request->request.dma,
+                       request->request.length,
+                       request->tx
+                               ? DMA_TO_DEVICE
+                               : DMA_FROM_DEVICE);
+
+       }
+}
+
 /*
  * Immediately complete a request.
  *
@@ -119,24 +172,8 @@ __acquires(ep->musb->lock)
 
        ep->busy = 1;
        spin_unlock(&musb->lock);
-       if (is_dma_capable()) {
-               if (req->mapped) {
-                       dma_unmap_single(musb->controller,
-                                       req->request.dma,
-                                       req->request.length,
-                                       req->tx
-                                               ? DMA_TO_DEVICE
-                                               : DMA_FROM_DEVICE);
-                       req->request.dma = DMA_ADDR_INVALID;
-                       req->mapped = 0;
-               } else if (req->request.dma != DMA_ADDR_INVALID)
-                       dma_sync_single_for_cpu(musb->controller,
-                                       req->request.dma,
-                                       req->request.length,
-                                       req->tx
-                                               ? DMA_TO_DEVICE
-                                               : DMA_FROM_DEVICE);
-       }
+       if (is_dma_capable() && ep->dma)
+               unmap_dma_buffer(req, musb);
        if (request->status == 0)
                DBG(5, "%s done request %p,  %d/%d\n",
                                ep->end_point.name, request,
@@ -395,6 +432,13 @@ static void txstate(struct musb *musb, struct musb_request *req)
 #endif
 
        if (!use_dma) {
+               /*
+                * Unmap the dma buffer back to cpu if dma channel
+                * programming fails
+                */
+               if (is_dma_capable() && musb_ep->dma)
+                       unmap_dma_buffer(req, musb);
+
                musb_write_fifo(musb_ep->hw_ep, fifo_count,
                                (u8 *) (request->buf + request->actual));
                request->actual += fifo_count;
@@ -713,6 +757,21 @@ static void rxstate(struct musb *musb, struct musb_request *req)
                                        return;
                        }
 #endif
+                       /*
+                        * Unmap the dma buffer back to cpu if dma channel
+                        * programming fails. This buffer is mapped if the
+                        * channel allocation is successful
+                        */
+                        if (is_dma_capable() && musb_ep->dma) {
+                               unmap_dma_buffer(req, musb);
+
+                               /*
+                                * Clear DMAENAB and AUTOCLEAR for the
+                                * PIO mode transfer
+                                */
+                               csr &= ~(MUSB_RXCSR_DMAENAB | MUSB_RXCSR_AUTOCLEAR);
+                               musb_writew(epio, MUSB_RXCSR, csr);
+                       }
 
                        musb_read_fifo(musb_ep->hw_ep, fifo_count, (u8 *)
                                        (request->buf + request->actual));
@@ -837,7 +896,9 @@ void musb_g_rx(struct musb *musb, u8 epnum)
                if (!request)
                        return;
        }
+#if defined(CONFIG_USB_INVENTRA_DMA) || defined(CONFIG_USB_TUSB_OMAP_DMA)
 exit:
+#endif
        /* Analyze request */
        rxstate(musb, to_musb_request(request));
 }
@@ -1150,26 +1211,9 @@ static int musb_gadget_queue(struct usb_ep *ep, struct usb_request *req,
        request->epnum = musb_ep->current_epnum;
        request->tx = musb_ep->is_in;
 
-       if (is_dma_capable() && musb_ep->dma) {
-               if (request->request.dma == DMA_ADDR_INVALID) {
-                       request->request.dma = dma_map_single(
-                                       musb->controller,
-                                       request->request.buf,
-                                       request->request.length,
-                                       request->tx
-                                               ? DMA_TO_DEVICE
-                                               : DMA_FROM_DEVICE);
-                       request->mapped = 1;
-               } else {
-                       dma_sync_single_for_device(musb->controller,
-                                       request->request.dma,
-                                       request->request.length,
-                                       request->tx
-                                               ? DMA_TO_DEVICE
-                                               : DMA_FROM_DEVICE);
-                       request->mapped = 0;
-               }
-       } else
+       if (is_dma_capable() && musb_ep->dma)
+               map_dma_buffer(request, musb);
+       else
                request->mapped = 0;
 
        spin_lock_irqsave(&musb->lock, lockflags);
@@ -1789,6 +1833,8 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
                spin_unlock_irqrestore(&musb->lock, flags);
 
                if (is_otg_enabled(musb)) {
+                       struct usb_hcd  *hcd = musb_to_hcd(musb);
+
                        DBG(3, "OTG startup...\n");
 
                        /* REVISIT:  funcall to other code, which also
@@ -1803,6 +1849,8 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
                                musb->gadget_driver = NULL;
                                musb->g.dev.driver = NULL;
                                spin_unlock_irqrestore(&musb->lock, flags);
+                       } else {
+                               hcd->self.uses_pio_for_control = 1;
                        }
                }
        }
index 76f8b35..6a50965 100644 (file)
@@ -201,6 +201,7 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(FTDI_VID, FTDI_MTXORB_5_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_R2000KU_TRUE_RNG) },
+       { USB_DEVICE(FTDI_VID, FTDI_VARDAAN_PID) },
        { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0100_PID) },
        { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0101_PID) },
        { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0102_PID) },
@@ -696,6 +697,7 @@ static struct usb_device_id id_table_combined [] = {
                .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk },
        { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) },
        { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_SERIAL_VX7_PID) },
+       { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_CT29B_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_PHI_FISCO_PID) },
        { USB_DEVICE(TML_VID, TML_USB_SERIAL_PID) },
index 263f625..1286f1e 100644 (file)
 /* Lenz LI-USB Computer Interface. */
 #define FTDI_LENZ_LIUSB_PID    0xD780
 
+/* Vardaan Enterprises Serial Interface VEUSB422R3 */
+#define FTDI_VARDAAN_PID       0xF070
+
 /*
  * Xsens Technologies BV products (http://www.xsens.com).
  */
  */
 #define RTSYSTEMS_VID                  0x2100  /* Vendor ID */
 #define RTSYSTEMS_SERIAL_VX7_PID       0x9e52  /* Serial converter for VX-7 Radios using FT232RL */
+#define RTSYSTEMS_CT29B_PID            0x9e54  /* CT29B Radio Cable */
 
 /*
  * Bayer Ascensia Contour blood glucose meter USB-converter cable.
index 861223f..6954de5 100644 (file)
@@ -51,6 +51,7 @@ static struct usb_driver usb_serial_driver = {
        .suspend =      usb_serial_suspend,
        .resume =       usb_serial_resume,
        .no_dynamic_id =        1,
+       .supports_autosuspend = 1,
 };
 
 /* There is no MODULE_DEVICE_TABLE for usbserial.c.  Instead
@@ -1343,6 +1344,8 @@ int usb_serial_register(struct usb_serial_driver *driver)
                return -ENODEV;
 
        fixup_generic(driver);
+       if (driver->usb_driver)
+               driver->usb_driver->supports_autosuspend = 1;
 
        if (!driver->description)
                driver->description = driver->driver.name;
index 4b4da5b..f442668 100644 (file)
@@ -129,8 +129,9 @@ static void handle_tx(struct vhost_net *net)
        size_t hdr_size;
        struct socket *sock;
 
-       sock = rcu_dereference_check(vq->private_data,
-                                    lockdep_is_held(&vq->mutex));
+       /* TODO: check that we are running from vhost_worker?
+        * Not sure it's worth it, it's straight-forward enough. */
+       sock = rcu_dereference_check(vq->private_data, 1);
        if (!sock)
                return;
 
index 94701ff..159c77a 100644 (file)
@@ -884,6 +884,7 @@ static int log_write(void __user *log_base,
        int r;
        if (!write_length)
                return 0;
+       write_length += write_address % VHOST_PAGE_SIZE;
        write_address /= VHOST_PAGE_SIZE;
        for (;;) {
                u64 base = (u64)(unsigned long)log_base;
@@ -897,7 +898,7 @@ static int log_write(void __user *log_base,
                if (write_length <= VHOST_PAGE_SIZE)
                        break;
                write_length -= VHOST_PAGE_SIZE;
-               write_address += VHOST_PAGE_SIZE;
+               write_address += 1;
        }
        return r;
 }
index cad7d45..c265aed 100644 (file)
@@ -1029,10 +1029,6 @@ static int __init fb_probe(struct platform_device *device)
                goto err_release_pl_mem;
        }
 
-       ret = request_irq(par->irq, lcdc_irq_handler, 0, DRIVER_NAME, par);
-       if (ret)
-               goto err_release_pl_mem;
-
        /* Initialize par */
        da8xx_fb_info->var.bits_per_pixel = lcd_cfg->bpp;
 
@@ -1060,7 +1056,7 @@ static int __init fb_probe(struct platform_device *device)
 
        ret = fb_alloc_cmap(&da8xx_fb_info->cmap, PALETTE_SIZE, 0);
        if (ret)
-               goto err_free_irq;
+               goto err_release_pl_mem;
        da8xx_fb_info->cmap.len = par->palette_sz;
 
        /* initialize var_screeninfo */
@@ -1088,8 +1084,13 @@ static int __init fb_probe(struct platform_device *device)
                goto err_cpu_freq;
        }
 #endif
+
+       ret = request_irq(par->irq, lcdc_irq_handler, 0, DRIVER_NAME, par);
+       if (ret)
+               goto irq_freq;
        return 0;
 
+irq_freq:
 #ifdef CONFIG_CPU_FREQ
 err_cpu_freq:
        unregister_framebuffer(da8xx_fb_info);
@@ -1098,9 +1099,6 @@ err_cpu_freq:
 err_dealloc_cmap:
        fb_dealloc_cmap(&da8xx_fb_info->cmap);
 
-err_free_irq:
-       free_irq(par->irq, par);
-
 err_release_pl_mem:
        dma_free_coherent(NULL, PALETTE_SIZE, par->v_palette_base,
                          par->p_palette_base);
index affdf3e..5c3960d 100644 (file)
@@ -80,6 +80,7 @@ static const struct fb_cmap default_16_colors = {
  *     @cmap: frame buffer colormap structure
  *     @len: length of @cmap
  *     @transp: boolean, 1 if there is transparency, 0 otherwise
+ *     @flags: flags for kmalloc memory allocation
  *
  *     Allocates memory for a colormap @cmap.  @len is the
  *     number of entries in the palette.
index e4c4d89..be8ccb4 100644 (file)
@@ -22,6 +22,7 @@
 #define DC_HFILT_COUNT 0x100
 #define DC_VFILT_COUNT 0x100
 #define VP_COEFF_SIZE  0x1000
+#define VP_PAL_COUNT   0x100
 
 #define OUTPUT_CRT   0x01
 #define OUTPUT_PANEL 0x02
@@ -48,7 +49,8 @@ struct lxfb_par {
        uint64_t vp[VP_REG_COUNT];
        uint64_t fp[FP_REG_COUNT];
 
-       uint32_t pal[DC_PAL_COUNT];
+       uint32_t dc_pal[DC_PAL_COUNT];
+       uint32_t vp_pal[VP_PAL_COUNT];
        uint32_t hcoeff[DC_HFILT_COUNT * 2];
        uint32_t vcoeff[DC_VFILT_COUNT];
        uint32_t vp_coeff[VP_COEFF_SIZE / 4];
index 85ec7f6..79e9abc 100644 (file)
@@ -610,10 +610,15 @@ static void lx_save_regs(struct lxfb_par *par)
        memcpy(par->vp, par->vp_regs, sizeof(par->vp));
        memcpy(par->fp, par->vp_regs + VP_FP_START, sizeof(par->fp));
 
-       /* save the palette */
+       /* save the display controller palette */
        write_dc(par, DC_PAL_ADDRESS, 0);
-       for (i = 0; i < ARRAY_SIZE(par->pal); i++)
-               par->pal[i] = read_dc(par, DC_PAL_DATA);
+       for (i = 0; i < ARRAY_SIZE(par->dc_pal); i++)
+               par->dc_pal[i] = read_dc(par, DC_PAL_DATA);
+
+       /* save the video processor palette */
+       write_vp(par, VP_PAR, 0);
+       for (i = 0; i < ARRAY_SIZE(par->vp_pal); i++)
+               par->vp_pal[i] = read_vp(par, VP_PDR);
 
        /* save the horizontal filter coefficients */
        filt = par->dc[DC_IRQ_FILT_CTL] | DC_IRQ_FILT_CTL_H_FILT_SEL;
@@ -706,8 +711,8 @@ static void lx_restore_display_ctlr(struct lxfb_par *par)
 
        /* restore the palette */
        write_dc(par, DC_PAL_ADDRESS, 0);
-       for (i = 0; i < ARRAY_SIZE(par->pal); i++)
-               write_dc(par, DC_PAL_DATA, par->pal[i]);
+       for (i = 0; i < ARRAY_SIZE(par->dc_pal); i++)
+               write_dc(par, DC_PAL_DATA, par->dc_pal[i]);
 
        /* restore the horizontal filter coefficients */
        filt = par->dc[DC_IRQ_FILT_CTL] | DC_IRQ_FILT_CTL_H_FILT_SEL;
@@ -751,6 +756,11 @@ static void lx_restore_video_proc(struct lxfb_par *par)
                }
        }
 
+       /* restore video processor palette */
+       write_vp(par, VP_PAR, 0);
+       for (i = 0; i < ARRAY_SIZE(par->vp_pal); i++)
+               write_vp(par, VP_PDR, par->vp_pal[i]);
+
        /* restore video coeff ram */
        memcpy(par->vp_regs + VP_VCR, par->vp_coeff, sizeof(par->vp_coeff));
 }
index 0a4dbdc..de450c1 100644 (file)
@@ -855,6 +855,7 @@ const struct fb_videomode *fb_find_nearest_mode(const struct fb_videomode *mode,
                        abs(cmode->yres - mode->yres);
                if (diff > d) {
                        diff = d;
+                       diff_refresh = abs(cmode->refresh - mode->refresh);
                        best = cmode;
                } else if (diff == d) {
                        d = abs(cmode->refresh - mode->refresh);
index 4a29104..a5ad77e 100644 (file)
@@ -558,6 +558,9 @@ config IT8712F_WDT
          This is the driver for the built-in watchdog timer on the IT8712F
          Super I/0 chipset used on many motherboards.
 
+         If the driver does not work, then make sure that the game port in
+         the BIOS is enabled.
+
          To compile this driver as a module, choose M here: the
          module will be called it8712f_wdt.
 
index a1debc8..3c5045a 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/miscdevice.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
-#include <linux/reboot.h>
 #include <linux/types.h>
 #include <linux/uaccess.h>
 #include <linux/watchdog.h>
@@ -220,14 +219,6 @@ static long bcm63xx_wdt_ioctl(struct file *file, unsigned int cmd,
        }
 }
 
-static int bcm63xx_wdt_notify_sys(struct notifier_block *this,
-                               unsigned long code, void *unused)
-{
-       if (code == SYS_DOWN || code == SYS_HALT)
-               bcm63xx_wdt_pause();
-       return NOTIFY_DONE;
-}
-
 static const struct file_operations bcm63xx_wdt_fops = {
        .owner          = THIS_MODULE,
        .llseek         = no_llseek,
@@ -243,12 +234,8 @@ static struct miscdevice bcm63xx_wdt_miscdev = {
        .fops   = &bcm63xx_wdt_fops,
 };
 
-static struct notifier_block bcm63xx_wdt_notifier = {
-       .notifier_call = bcm63xx_wdt_notify_sys,
-};
 
-
-static int bcm63xx_wdt_probe(struct platform_device *pdev)
+static int __devinit bcm63xx_wdt_probe(struct platform_device *pdev)
 {
        int ret;
        struct resource *r;
@@ -280,16 +267,10 @@ static int bcm63xx_wdt_probe(struct platform_device *pdev)
                        wdt_time);
        }
 
-       ret = register_reboot_notifier(&bcm63xx_wdt_notifier);
-       if (ret) {
-               dev_err(&pdev->dev, "failed to register reboot_notifier\n");
-               goto unregister_timer;
-       }
-
        ret = misc_register(&bcm63xx_wdt_miscdev);
        if (ret < 0) {
                dev_err(&pdev->dev, "failed to register watchdog device\n");
-               goto unregister_reboot_notifier;
+               goto unregister_timer;
        }
 
        dev_info(&pdev->dev, " started, timer margin: %d sec\n",
@@ -297,8 +278,6 @@ static int bcm63xx_wdt_probe(struct platform_device *pdev)
 
        return 0;
 
-unregister_reboot_notifier:
-       unregister_reboot_notifier(&bcm63xx_wdt_notifier);
 unregister_timer:
        bcm63xx_timer_unregister(TIMER_WDT_ID);
 unmap:
@@ -306,25 +285,28 @@ unmap:
        return ret;
 }
 
-static int bcm63xx_wdt_remove(struct platform_device *pdev)
+static int __devexit bcm63xx_wdt_remove(struct platform_device *pdev)
 {
        if (!nowayout)
                bcm63xx_wdt_pause();
 
        misc_deregister(&bcm63xx_wdt_miscdev);
-
-       iounmap(bcm63xx_wdt_device.regs);
-
-       unregister_reboot_notifier(&bcm63xx_wdt_notifier);
        bcm63xx_timer_unregister(TIMER_WDT_ID);
-
+       iounmap(bcm63xx_wdt_device.regs);
        return 0;
 }
 
+static void bcm63xx_wdt_shutdown(struct platform_device *pdev)
+{
+       bcm63xx_wdt_pause();
+}
+
 static struct platform_driver bcm63xx_wdt = {
        .probe  = bcm63xx_wdt_probe,
-       .remove = bcm63xx_wdt_remove,
+       .remove = __devexit_p(bcm63xx_wdt_remove),
+       .shutdown = bcm63xx_wdt_shutdown,
        .driver = {
+               .owner = THIS_MODULE,
                .name = "bcm63xx-wdt",
        }
 };
index 9c21d19..f6bd6f1 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/module.h>
 #include <linux/miscdevice.h>
 #include <linux/watchdog.h>
+#include <linux/fs.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
 #include <linux/io.h>
index f7e90fe..b8838d2 100644 (file)
@@ -32,6 +32,7 @@
  *     document number 322169-001, 322170-003: 5 Series, 3400 Series (PCH)
  *     document number 320066-003, 320257-008: EP80597 (IICH)
  *     document number TBD                   : Cougar Point (CPT)
+ *     document number TBD                   : Patsburg (PBG)
  */
 
 /*
@@ -146,7 +147,8 @@ enum iTCO_chipsets {
        TCO_CPT29,      /* Cougar Point */
        TCO_CPT30,      /* Cougar Point */
        TCO_CPT31,      /* Cougar Point */
-       TCO_PBG,        /* Patsburg */
+       TCO_PBG1,       /* Patsburg */
+       TCO_PBG2,       /* Patsburg */
 };
 
 static struct {
@@ -235,6 +237,7 @@ static struct {
        {"Cougar Point", 2},
        {"Cougar Point", 2},
        {"Patsburg", 2},
+       {"Patsburg", 2},
        {NULL, 0}
 };
 
@@ -350,7 +353,8 @@ static struct pci_device_id iTCO_wdt_pci_tbl[] = {
        { ITCO_PCI_DEVICE(0x1c5d,                               TCO_CPT29)},
        { ITCO_PCI_DEVICE(0x1c5e,                               TCO_CPT30)},
        { ITCO_PCI_DEVICE(0x1c5f,                               TCO_CPT31)},
-       { ITCO_PCI_DEVICE(0x1d40,                               TCO_PBG)},
+       { ITCO_PCI_DEVICE(0x1d40,                               TCO_PBG1)},
+       { ITCO_PCI_DEVICE(0x1d41,                               TCO_PBG2)},
        { 0, },                 /* End of list */
 };
 MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl);
index 2b17ad5..43f9f02 100644 (file)
@@ -412,8 +412,16 @@ static int __init balloon_init(void)
 
        register_balloon(&balloon_sysdev);
 
-       /* Initialise the balloon with excess memory space. */
-       extra_pfn_end = min(e820_end_of_ram_pfn(),
+       /*
+        * Initialise the balloon with excess memory space.  We need
+        * to make sure we don't add memory which doesn't exist or
+        * logically exist.  The E820 map can be trimmed to be smaller
+        * than the amount of physical memory due to the mem= command
+        * line parameter.  And if this is a 32-bit non-HIGHMEM kernel
+        * on a system with memory which requires highmem to access,
+        * don't try to use it.
+        */
+       extra_pfn_end = min(min(max_pfn, e820_end_of_ram_pfn()),
                            (unsigned long)PFN_DOWN(xen_extra_mem_start + xen_extra_mem_size));
        for (pfn = PFN_UP(xen_extra_mem_start);
             pfn < extra_pfn_end;
index 2811bb9..31af0ac 100644 (file)
@@ -105,7 +105,6 @@ struct irq_info
 
 static struct irq_info *irq_info;
 static int *pirq_to_irq;
-static int nr_pirqs;
 
 static int *evtchn_to_irq;
 struct cpu_evtchn_s {
@@ -385,12 +384,17 @@ static int get_nr_hw_irqs(void)
        return ret;
 }
 
-/* callers of this function should make sure that PHYSDEVOP_get_nr_pirqs
- * succeeded otherwise nr_pirqs won't hold the right value */
-static int find_unbound_pirq(void)
+static int find_unbound_pirq(int type)
 {
-       int i;
-       for (i = nr_pirqs-1; i >= 0; i--) {
+       int rc, i;
+       struct physdev_get_free_pirq op_get_free_pirq;
+       op_get_free_pirq.type = type;
+
+       rc = HYPERVISOR_physdev_op(PHYSDEVOP_get_free_pirq, &op_get_free_pirq);
+       if (!rc)
+               return op_get_free_pirq.pirq;
+
+       for (i = 0; i < nr_irqs; i++) {
                if (pirq_to_irq[i] < 0)
                        return i;
        }
@@ -423,7 +427,7 @@ static int find_unbound_irq(void)
        if (irq == start)
                goto no_irqs;
 
-       res = irq_alloc_desc_at(irq, 0);
+       res = irq_alloc_desc_at(irq, -1);
 
        if (WARN_ON(res != irq))
                return -1;
@@ -611,10 +615,10 @@ int xen_map_pirq_gsi(unsigned pirq, unsigned gsi, int shareable, char *name)
 
        spin_lock(&irq_mapping_update_lock);
 
-       if ((pirq > nr_pirqs) || (gsi > nr_irqs)) {
+       if ((pirq > nr_irqs) || (gsi > nr_irqs)) {
                printk(KERN_WARNING "xen_map_pirq_gsi: %s %s is incorrect!\n",
-                       pirq > nr_pirqs ? "nr_pirqs" :"",
-                       gsi > nr_irqs ? "nr_irqs" : "");
+                       pirq > nr_irqs ? "pirq" :"",
+                       gsi > nr_irqs ? "gsi" : "");
                goto out;
        }
 
@@ -630,7 +634,7 @@ int xen_map_pirq_gsi(unsigned pirq, unsigned gsi, int shareable, char *name)
        if (identity_mapped_irq(gsi) || (!xen_initial_domain() &&
                                xen_pv_domain())) {
                irq = gsi;
-               irq_alloc_desc_at(irq, 0);
+               irq_alloc_desc_at(irq, -1);
        } else
                irq = find_unbound_irq();
 
@@ -664,17 +668,21 @@ out:
 #include <linux/msi.h>
 #include "../pci/msi.h"
 
-void xen_allocate_pirq_msi(char *name, int *irq, int *pirq)
+void xen_allocate_pirq_msi(char *name, int *irq, int *pirq, int alloc)
 {
        spin_lock(&irq_mapping_update_lock);
 
-       *irq = find_unbound_irq();
-       if (*irq == -1)
-               goto out;
+       if (alloc & XEN_ALLOC_IRQ) {
+               *irq = find_unbound_irq();
+               if (*irq == -1)
+                       goto out;
+       }
 
-       *pirq = find_unbound_pirq();
-       if (*pirq == -1)
-               goto out;
+       if (alloc & XEN_ALLOC_PIRQ) {
+               *pirq = find_unbound_pirq(MAP_PIRQ_TYPE_MSI);
+               if (*pirq == -1)
+                       goto out;
+       }
 
        set_irq_chip_and_handler_name(*irq, &xen_pirq_chip,
                                      handle_level_irq, name);
@@ -762,6 +770,7 @@ int xen_destroy_irq(int irq)
                        printk(KERN_WARNING "unmap irq failed %d\n", rc);
                        goto out;
                }
+               pirq_to_irq[info->u.pirq.pirq] = -1;
        }
        irq_info[irq] = mk_unbound_info();
 
@@ -782,6 +791,11 @@ int xen_gsi_from_irq(unsigned irq)
        return gsi_from_irq(irq);
 }
 
+int xen_irq_from_pirq(unsigned pirq)
+{
+       return pirq_to_irq[pirq];
+}
+
 int bind_evtchn_to_irq(unsigned int evtchn)
 {
        int irq;
@@ -1279,6 +1293,42 @@ static int retrigger_dynirq(unsigned int irq)
        return ret;
 }
 
+static void restore_cpu_pirqs(void)
+{
+       int pirq, rc, irq, gsi;
+       struct physdev_map_pirq map_irq;
+
+       for (pirq = 0; pirq < nr_irqs; pirq++) {
+               irq = pirq_to_irq[pirq];
+               if (irq == -1)
+                       continue;
+
+               /* save/restore of PT devices doesn't work, so at this point the
+                * only devices present are GSI based emulated devices */
+               gsi = gsi_from_irq(irq);
+               if (!gsi)
+                       continue;
+
+               map_irq.domid = DOMID_SELF;
+               map_irq.type = MAP_PIRQ_TYPE_GSI;
+               map_irq.index = gsi;
+               map_irq.pirq = pirq;
+
+               rc = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, &map_irq);
+               if (rc) {
+                       printk(KERN_WARNING "xen map irq failed gsi=%d irq=%d pirq=%d rc=%d\n",
+                                       gsi, irq, pirq, rc);
+                       irq_info[irq] = mk_unbound_info();
+                       pirq_to_irq[pirq] = -1;
+                       continue;
+               }
+
+               printk(KERN_DEBUG "xen: --> irq=%d, pirq=%d\n", irq, map_irq.pirq);
+
+               startup_pirq(irq);
+       }
+}
+
 static void restore_cpu_virqs(unsigned int cpu)
 {
        struct evtchn_bind_virq bind_virq;
@@ -1422,6 +1472,8 @@ void xen_irq_resume(void)
 
                unmask_evtchn(evtchn);
        }
+
+       restore_cpu_pirqs();
 }
 
 static struct irq_chip xen_dynamic_chip __read_mostly = {
@@ -1506,26 +1558,17 @@ void xen_callback_vector(void) {}
 
 void __init xen_init_IRQ(void)
 {
-       int i, rc;
-       struct physdev_nr_pirqs op_nr_pirqs;
+       int i;
 
        cpu_evtchn_mask_p = kcalloc(nr_cpu_ids, sizeof(struct cpu_evtchn_s),
                                    GFP_KERNEL);
        irq_info = kcalloc(nr_irqs, sizeof(*irq_info), GFP_KERNEL);
 
-       rc = HYPERVISOR_physdev_op(PHYSDEVOP_get_nr_pirqs, &op_nr_pirqs);
-       if (rc < 0) {
-               nr_pirqs = nr_irqs;
-               if (rc != -ENOSYS)
-                       printk(KERN_WARNING "PHYSDEVOP_get_nr_pirqs returned rc=%d\n", rc);
-       } else {
-               if (xen_pv_domain() && !xen_initial_domain())
-                       nr_pirqs = max((int)op_nr_pirqs.nr_pirqs, nr_irqs);
-               else
-                       nr_pirqs = op_nr_pirqs.nr_pirqs;
-       }
-       pirq_to_irq = kcalloc(nr_pirqs, sizeof(*pirq_to_irq), GFP_KERNEL);
-       for (i = 0; i < nr_pirqs; i++)
+       /* We are using nr_irqs as the maximum number of pirq available but
+        * that number is actually chosen by Xen and we don't know exactly
+        * what it is. Be careful choosing high pirq numbers. */
+       pirq_to_irq = kcalloc(nr_irqs, sizeof(*pirq_to_irq), GFP_KERNEL);
+       for (i = 0; i < nr_irqs; i++)
                pirq_to_irq[i] = -1;
 
        evtchn_to_irq = kcalloc(NR_EVENT_CHANNELS, sizeof(*evtchn_to_irq),
index ef9c7db..db8c4c4 100644 (file)
@@ -49,6 +49,7 @@ static int xen_hvm_suspend(void *data)
 
        if (!*cancelled) {
                xen_irq_resume();
+               xen_console_resume();
                xen_timer_resume();
        }
 
index d5c1401..d34896c 100644 (file)
@@ -980,19 +980,11 @@ static int autofs4_root_ioctl_unlocked(struct inode *inode, struct file *filp,
        }
 }
 
-static DEFINE_MUTEX(autofs4_ioctl_mutex);
-
 static long autofs4_root_ioctl(struct file *filp,
                               unsigned int cmd, unsigned long arg)
 {
-       long ret;
        struct inode *inode = filp->f_dentry->d_inode;
-
-       mutex_lock(&autofs4_ioctl_mutex);
-       ret = autofs4_root_ioctl_unlocked(inode, filp, cmd, arg);
-       mutex_unlock(&autofs4_ioctl_mutex);
-
-       return ret;
+       return autofs4_root_ioctl_unlocked(inode, filp, cmd, arg);
 }
 
 #ifdef CONFIG_COMPAT
@@ -1002,13 +994,11 @@ static long autofs4_root_compat_ioctl(struct file *filp,
        struct inode *inode = filp->f_path.dentry->d_inode;
        int ret;
 
-       mutex_lock(&autofs4_ioctl_mutex);
        if (cmd == AUTOFS_IOC_READY || cmd == AUTOFS_IOC_FAIL)
                ret = autofs4_root_ioctl_unlocked(inode, filp, cmd, arg);
        else
                ret = autofs4_root_ioctl_unlocked(inode, filp, cmd,
                        (unsigned long)compat_ptr(arg));
-       mutex_unlock(&autofs4_ioctl_mutex);
 
        return ret;
 }
index 7845d1f..b50bc4b 100644 (file)
@@ -91,23 +91,10 @@ static inline int compressed_bio_size(struct btrfs_root *root,
 static struct bio *compressed_bio_alloc(struct block_device *bdev,
                                        u64 first_byte, gfp_t gfp_flags)
 {
-       struct bio *bio;
        int nr_vecs;
 
        nr_vecs = bio_get_nr_vecs(bdev);
-       bio = bio_alloc(gfp_flags, nr_vecs);
-
-       if (bio == NULL && (current->flags & PF_MEMALLOC)) {
-               while (!bio && (nr_vecs /= 2))
-                       bio = bio_alloc(gfp_flags, nr_vecs);
-       }
-
-       if (bio) {
-               bio->bi_size = 0;
-               bio->bi_bdev = bdev;
-               bio->bi_sector = first_byte >> 9;
-       }
-       return bio;
+       return btrfs_bio_alloc(bdev, first_byte >> 9, nr_vecs, gfp_flags);
 }
 
 static int check_compressed_csum(struct inode *inode,
index 8db9234..af52f6d 100644 (file)
@@ -808,9 +808,9 @@ struct btrfs_block_group_cache {
        int extents_thresh;
        int free_extents;
        int total_bitmaps;
-       int ro:1;
-       int dirty:1;
-       int iref:1;
+       unsigned int ro:1;
+       unsigned int dirty:1;
+       unsigned int iref:1;
 
        int disk_cache_state;
 
index fb827d0..51d2e4d 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/freezer.h>
 #include <linux/crc32c.h>
 #include <linux/slab.h>
+#include <linux/migrate.h>
 #include "compat.h"
 #include "ctree.h"
 #include "disk-io.h"
@@ -355,6 +356,8 @@ static int csum_dirty_buffer(struct btrfs_root *root, struct page *page)
        ret = btree_read_extent_buffer_pages(root, eb, start + PAGE_CACHE_SIZE,
                                             btrfs_header_generation(eb));
        BUG_ON(ret);
+       WARN_ON(!btrfs_header_flag(eb, BTRFS_HEADER_FLAG_WRITTEN));
+
        found_start = btrfs_header_bytenr(eb);
        if (found_start != start) {
                WARN_ON(1);
@@ -693,6 +696,27 @@ static int btree_submit_bio_hook(struct inode *inode, int rw, struct bio *bio,
                                   __btree_submit_bio_done);
 }
 
+#ifdef CONFIG_MIGRATION
+static int btree_migratepage(struct address_space *mapping,
+                       struct page *newpage, struct page *page)
+{
+       /*
+        * we can't safely write a btree page from here,
+        * we haven't done the locking hook
+        */
+       if (PageDirty(page))
+               return -EAGAIN;
+       /*
+        * Buffers may be managed in a filesystem specific way.
+        * We must have no buffers or drop them.
+        */
+       if (page_has_private(page) &&
+           !try_to_release_page(page, GFP_KERNEL))
+               return -EAGAIN;
+       return migrate_page(mapping, newpage, page);
+}
+#endif
+
 static int btree_writepage(struct page *page, struct writeback_control *wbc)
 {
        struct extent_io_tree *tree;
@@ -707,8 +731,7 @@ static int btree_writepage(struct page *page, struct writeback_control *wbc)
        }
 
        redirty_page_for_writepage(wbc, page);
-       eb = btrfs_find_tree_block(root, page_offset(page),
-                                     PAGE_CACHE_SIZE);
+       eb = btrfs_find_tree_block(root, page_offset(page), PAGE_CACHE_SIZE);
        WARN_ON(!eb);
 
        was_dirty = test_and_set_bit(EXTENT_BUFFER_DIRTY, &eb->bflags);
@@ -799,6 +822,9 @@ static const struct address_space_operations btree_aops = {
        .releasepage    = btree_releasepage,
        .invalidatepage = btree_invalidatepage,
        .sync_page      = block_sync_page,
+#ifdef CONFIG_MIGRATION
+       .migratepage    = btree_migratepage,
+#endif
 };
 
 int readahead_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize,
@@ -981,7 +1007,10 @@ static int find_and_setup_root(struct btrfs_root *tree_root,
        blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item));
        root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item),
                                     blocksize, generation);
-       BUG_ON(!root->node);
+       if (!root->node || !btrfs_buffer_uptodate(root->node, generation)) {
+               free_extent_buffer(root->node);
+               return -EIO;
+       }
        root->commit_root = btrfs_root_node(root);
        return 0;
 }
@@ -1538,10 +1567,8 @@ struct btrfs_root *open_ctree(struct super_block *sb,
                                                 GFP_NOFS);
        struct btrfs_root *csum_root = kzalloc(sizeof(struct btrfs_root),
                                                 GFP_NOFS);
-       struct btrfs_root *tree_root = kzalloc(sizeof(struct btrfs_root),
-                                              GFP_NOFS);
-       struct btrfs_fs_info *fs_info = kzalloc(sizeof(*fs_info),
-                                               GFP_NOFS);
+       struct btrfs_root *tree_root = btrfs_sb(sb);
+       struct btrfs_fs_info *fs_info = tree_root->fs_info;
        struct btrfs_root *chunk_root = kzalloc(sizeof(struct btrfs_root),
                                                GFP_NOFS);
        struct btrfs_root *dev_root = kzalloc(sizeof(struct btrfs_root),
index 951ef09..659f532 100644 (file)
@@ -166,7 +166,7 @@ static struct dentry *btrfs_fh_to_dentry(struct super_block *sb, struct fid *fh,
 static struct dentry *btrfs_get_parent(struct dentry *child)
 {
        struct inode *dir = child->d_inode;
-       static struct dentry *dentry;
+       struct dentry *dentry;
        struct btrfs_root *root = BTRFS_I(dir)->root;
        struct btrfs_path *path;
        struct extent_buffer *leaf;
@@ -232,9 +232,85 @@ fail:
        return ERR_PTR(ret);
 }
 
+static int btrfs_get_name(struct dentry *parent, char *name,
+                         struct dentry *child)
+{
+       struct inode *inode = child->d_inode;
+       struct inode *dir = parent->d_inode;
+       struct btrfs_path *path;
+       struct btrfs_root *root = BTRFS_I(dir)->root;
+       struct btrfs_inode_ref *iref;
+       struct btrfs_root_ref *rref;
+       struct extent_buffer *leaf;
+       unsigned long name_ptr;
+       struct btrfs_key key;
+       int name_len;
+       int ret;
+
+       if (!dir || !inode)
+               return -EINVAL;
+
+       if (!S_ISDIR(dir->i_mode))
+               return -EINVAL;
+
+       path = btrfs_alloc_path();
+       if (!path)
+               return -ENOMEM;
+       path->leave_spinning = 1;
+
+       if (inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) {
+               key.objectid = BTRFS_I(inode)->root->root_key.objectid;
+               key.type = BTRFS_ROOT_BACKREF_KEY;
+               key.offset = (u64)-1;
+               root = root->fs_info->tree_root;
+       } else {
+               key.objectid = inode->i_ino;
+               key.offset = dir->i_ino;
+               key.type = BTRFS_INODE_REF_KEY;
+       }
+
+       ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
+       if (ret < 0) {
+               btrfs_free_path(path);
+               return ret;
+       } else if (ret > 0) {
+               if (inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) {
+                       path->slots[0]--;
+               } else {
+                       btrfs_free_path(path);
+                       return -ENOENT;
+               }
+       }
+       leaf = path->nodes[0];
+
+       if (inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) {
+              rref = btrfs_item_ptr(leaf, path->slots[0],
+                                    struct btrfs_root_ref);
+              name_ptr = (unsigned long)(rref + 1);
+              name_len = btrfs_root_ref_name_len(leaf, rref);
+       } else {
+               iref = btrfs_item_ptr(leaf, path->slots[0],
+                                     struct btrfs_inode_ref);
+               name_ptr = (unsigned long)(iref + 1);
+               name_len = btrfs_inode_ref_name_len(leaf, iref);
+       }
+
+       read_extent_buffer(leaf, name, name_ptr, name_len);
+       btrfs_free_path(path);
+
+       /*
+        * have to add the null termination to make sure that reconnect_path
+        * gets the right len for strlen
+        */
+       name[name_len] = '\0';
+
+       return 0;
+}
+
 const struct export_operations btrfs_export_ops = {
        .encode_fh      = btrfs_encode_fh,
        .fh_to_dentry   = btrfs_fh_to_dentry,
        .fh_to_parent   = btrfs_fh_to_parent,
        .get_parent     = btrfs_get_parent,
+       .get_name       = btrfs_get_name,
 };
index 0c097f3..227e581 100644 (file)
@@ -429,6 +429,7 @@ err:
 
 static int cache_block_group(struct btrfs_block_group_cache *cache,
                             struct btrfs_trans_handle *trans,
+                            struct btrfs_root *root,
                             int load_cache_only)
 {
        struct btrfs_fs_info *fs_info = cache->fs_info;
@@ -442,9 +443,12 @@ static int cache_block_group(struct btrfs_block_group_cache *cache,
 
        /*
         * We can't do the read from on-disk cache during a commit since we need
-        * to have the normal tree locking.
+        * to have the normal tree locking.  Also if we are currently trying to
+        * allocate blocks for the tree root we can't do the fast caching since
+        * we likely hold important locks.
         */
-       if (!trans->transaction->in_commit) {
+       if (!trans->transaction->in_commit &&
+           (root && root != root->fs_info->tree_root)) {
                spin_lock(&cache->lock);
                if (cache->cached != BTRFS_CACHE_NO) {
                        spin_unlock(&cache->lock);
@@ -2741,6 +2745,7 @@ static int cache_save_setup(struct btrfs_block_group_cache *block_group,
        struct btrfs_root *root = block_group->fs_info->tree_root;
        struct inode *inode = NULL;
        u64 alloc_hint = 0;
+       int dcs = BTRFS_DC_ERROR;
        int num_pages = 0;
        int retries = 0;
        int ret = 0;
@@ -2795,6 +2800,8 @@ again:
 
        spin_lock(&block_group->lock);
        if (block_group->cached != BTRFS_CACHE_FINISHED) {
+               /* We're not cached, don't bother trying to write stuff out */
+               dcs = BTRFS_DC_WRITTEN;
                spin_unlock(&block_group->lock);
                goto out_put;
        }
@@ -2821,6 +2828,8 @@ again:
        ret = btrfs_prealloc_file_range_trans(inode, trans, 0, 0, num_pages,
                                              num_pages, num_pages,
                                              &alloc_hint);
+       if (!ret)
+               dcs = BTRFS_DC_SETUP;
        btrfs_free_reserved_data_space(inode, num_pages);
 out_put:
        iput(inode);
@@ -2828,10 +2837,7 @@ out_free:
        btrfs_release_path(root, path);
 out:
        spin_lock(&block_group->lock);
-       if (ret)
-               block_group->disk_cache_state = BTRFS_DC_ERROR;
-       else
-               block_group->disk_cache_state = BTRFS_DC_SETUP;
+       block_group->disk_cache_state = dcs;
        spin_unlock(&block_group->lock);
 
        return ret;
@@ -3037,7 +3043,13 @@ static void set_avail_alloc_bits(struct btrfs_fs_info *fs_info, u64 flags)
 
 u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags)
 {
-       u64 num_devices = root->fs_info->fs_devices->rw_devices;
+       /*
+        * we add in the count of missing devices because we want
+        * to make sure that any RAID levels on a degraded FS
+        * continue to be honored.
+        */
+       u64 num_devices = root->fs_info->fs_devices->rw_devices +
+               root->fs_info->fs_devices->missing_devices;
 
        if (num_devices == 1)
                flags &= ~(BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_RAID0);
@@ -3412,7 +3424,7 @@ again:
         * our reservation.
         */
        if (unused <= space_info->total_bytes) {
-               unused -= space_info->total_bytes;
+               unused = space_info->total_bytes - unused;
                if (unused >= num_bytes) {
                        if (!reserved)
                                space_info->bytes_reserved += orig_bytes;
@@ -4080,7 +4092,7 @@ static int update_block_group(struct btrfs_trans_handle *trans,
                 * space back to the block group, otherwise we will leak space.
                 */
                if (!alloc && cache->cached == BTRFS_CACHE_NO)
-                       cache_block_group(cache, trans, 1);
+                       cache_block_group(cache, trans, NULL, 1);
 
                byte_in_group = bytenr - cache->key.objectid;
                WARN_ON(byte_in_group > cache->key.offset);
@@ -4930,11 +4942,31 @@ search:
                btrfs_get_block_group(block_group);
                search_start = block_group->key.objectid;
 
+               /*
+                * this can happen if we end up cycling through all the
+                * raid types, but we want to make sure we only allocate
+                * for the proper type.
+                */
+               if (!block_group_bits(block_group, data)) {
+                   u64 extra = BTRFS_BLOCK_GROUP_DUP |
+                               BTRFS_BLOCK_GROUP_RAID1 |
+                               BTRFS_BLOCK_GROUP_RAID10;
+
+                       /*
+                        * if they asked for extra copies and this block group
+                        * doesn't provide them, bail.  This does allow us to
+                        * fill raid0 from raid1.
+                        */
+                       if ((data & extra) && !(block_group->flags & extra))
+                               goto loop;
+               }
+
 have_block_group:
                if (unlikely(block_group->cached == BTRFS_CACHE_NO)) {
                        u64 free_percent;
 
-                       ret = cache_block_group(block_group, trans, 1);
+                       ret = cache_block_group(block_group, trans,
+                                               orig_root, 1);
                        if (block_group->cached == BTRFS_CACHE_FINISHED)
                                goto have_block_group;
 
@@ -4958,7 +4990,8 @@ have_block_group:
                        if (loop > LOOP_CACHING_NOWAIT ||
                            (loop > LOOP_FIND_IDEAL &&
                             atomic_read(&space_info->caching_threads) < 2)) {
-                               ret = cache_block_group(block_group, trans, 0);
+                               ret = cache_block_group(block_group, trans,
+                                                       orig_root, 0);
                                BUG_ON(ret);
                        }
                        found_uncached_bg = true;
@@ -5515,7 +5548,7 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans,
        u64 num_bytes = ins->offset;
 
        block_group = btrfs_lookup_block_group(root->fs_info, ins->objectid);
-       cache_block_group(block_group, trans, 0);
+       cache_block_group(block_group, trans, NULL, 0);
        caching_ctl = get_caching_control(block_group);
 
        if (!caching_ctl) {
@@ -6300,9 +6333,13 @@ int btrfs_drop_snapshot(struct btrfs_root *root,
                                           NULL, NULL);
                BUG_ON(ret < 0);
                if (ret > 0) {
-                       ret = btrfs_del_orphan_item(trans, tree_root,
-                                                   root->root_key.objectid);
-                       BUG_ON(ret);
+                       /* if we fail to delete the orphan item this time
+                        * around, it'll get picked up the next time.
+                        *
+                        * The most common failure here is just -ENOENT.
+                        */
+                       btrfs_del_orphan_item(trans, tree_root,
+                                             root->root_key.objectid);
                }
        }
 
@@ -7878,7 +7915,14 @@ static u64 update_block_group_flags(struct btrfs_root *root, u64 flags)
        u64 stripped = BTRFS_BLOCK_GROUP_RAID0 |
                BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_RAID10;
 
-       num_devices = root->fs_info->fs_devices->rw_devices;
+       /*
+        * we add in the count of missing devices because we want
+        * to make sure that any RAID levels on a degraded FS
+        * continue to be honored.
+        */
+       num_devices = root->fs_info->fs_devices->rw_devices +
+               root->fs_info->fs_devices->missing_devices;
+
        if (num_devices == 1) {
                stripped |= BTRFS_BLOCK_GROUP_DUP;
                stripped = flags & ~stripped;
@@ -8247,7 +8291,6 @@ int btrfs_read_block_groups(struct btrfs_root *root)
                        break;
                if (ret != 0)
                        goto error;
-
                leaf = path->nodes[0];
                btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
                cache = kzalloc(sizeof(*cache), GFP_NOFS);
index eac10e3..3e86b9f 100644 (file)
@@ -1828,9 +1828,9 @@ static void end_bio_extent_preparewrite(struct bio *bio, int err)
        bio_put(bio);
 }
 
-static struct bio *
-extent_bio_alloc(struct block_device *bdev, u64 first_sector, int nr_vecs,
-                gfp_t gfp_flags)
+struct bio *
+btrfs_bio_alloc(struct block_device *bdev, u64 first_sector, int nr_vecs,
+               gfp_t gfp_flags)
 {
        struct bio *bio;
 
@@ -1919,7 +1919,7 @@ static int submit_extent_page(int rw, struct extent_io_tree *tree,
        else
                nr = bio_get_nr_vecs(bdev);
 
-       bio = extent_bio_alloc(bdev, sector, nr, GFP_NOFS | __GFP_HIGH);
+       bio = btrfs_bio_alloc(bdev, sector, nr, GFP_NOFS | __GFP_HIGH);
 
        bio_add_page(bio, page, page_size, offset);
        bio->bi_end_io = end_io_func;
@@ -2901,21 +2901,53 @@ out:
 int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
                __u64 start, __u64 len, get_extent_t *get_extent)
 {
-       int ret;
+       int ret = 0;
        u64 off = start;
        u64 max = start + len;
        u32 flags = 0;
+       u32 found_type;
+       u64 last;
        u64 disko = 0;
+       struct btrfs_key found_key;
        struct extent_map *em = NULL;
        struct extent_state *cached_state = NULL;
+       struct btrfs_path *path;
+       struct btrfs_file_extent_item *item;
        int end = 0;
        u64 em_start = 0, em_len = 0;
        unsigned long emflags;
-       ret = 0;
+       int hole = 0;
 
        if (len == 0)
                return -EINVAL;
 
+       path = btrfs_alloc_path();
+       if (!path)
+               return -ENOMEM;
+       path->leave_spinning = 1;
+
+       ret = btrfs_lookup_file_extent(NULL, BTRFS_I(inode)->root,
+                                      path, inode->i_ino, -1, 0);
+       if (ret < 0) {
+               btrfs_free_path(path);
+               return ret;
+       }
+       WARN_ON(!ret);
+       path->slots[0]--;
+       item = btrfs_item_ptr(path->nodes[0], path->slots[0],
+                             struct btrfs_file_extent_item);
+       btrfs_item_key_to_cpu(path->nodes[0], &found_key, path->slots[0]);
+       found_type = btrfs_key_type(&found_key);
+
+       /* No extents, just return */
+       if (found_key.objectid != inode->i_ino ||
+           found_type != BTRFS_EXTENT_DATA_KEY) {
+               btrfs_free_path(path);
+               return 0;
+       }
+       last = found_key.offset;
+       btrfs_free_path(path);
+
        lock_extent_bits(&BTRFS_I(inode)->io_tree, start, start + len, 0,
                         &cached_state, GFP_NOFS);
        em = get_extent(inode, NULL, 0, off, max - off, 0);
@@ -2925,11 +2957,18 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
                ret = PTR_ERR(em);
                goto out;
        }
+
        while (!end) {
+               hole = 0;
                off = em->start + em->len;
                if (off >= max)
                        end = 1;
 
+               if (em->block_start == EXTENT_MAP_HOLE) {
+                       hole = 1;
+                       goto next;
+               }
+
                em_start = em->start;
                em_len = em->len;
 
@@ -2939,8 +2978,6 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
                if (em->block_start == EXTENT_MAP_LAST_BYTE) {
                        end = 1;
                        flags |= FIEMAP_EXTENT_LAST;
-               } else if (em->block_start == EXTENT_MAP_HOLE) {
-                       flags |= FIEMAP_EXTENT_UNWRITTEN;
                } else if (em->block_start == EXTENT_MAP_INLINE) {
                        flags |= (FIEMAP_EXTENT_DATA_INLINE |
                                  FIEMAP_EXTENT_NOT_ALIGNED);
@@ -2953,10 +2990,10 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
                if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags))
                        flags |= FIEMAP_EXTENT_ENCODED;
 
+next:
                emflags = em->flags;
                free_extent_map(em);
                em = NULL;
-
                if (!end) {
                        em = get_extent(inode, NULL, 0, off, max - off, 0);
                        if (!em)
@@ -2967,15 +3004,23 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
                        }
                        emflags = em->flags;
                }
+
                if (test_bit(EXTENT_FLAG_VACANCY, &emflags)) {
                        flags |= FIEMAP_EXTENT_LAST;
                        end = 1;
                }
 
-               ret = fiemap_fill_next_extent(fieinfo, em_start, disko,
-                                       em_len, flags);
-               if (ret)
-                       goto out_free;
+               if (em_start == last) {
+                       flags |= FIEMAP_EXTENT_LAST;
+                       end = 1;
+               }
+
+               if (!hole) {
+                       ret = fiemap_fill_next_extent(fieinfo, em_start, disko,
+                                               em_len, flags);
+                       if (ret)
+                               goto out_free;
+               }
        }
 out_free:
        free_extent_map(em);
@@ -3836,8 +3881,10 @@ int try_release_extent_buffer(struct extent_io_tree *tree, struct page *page)
 
        spin_lock(&tree->buffer_lock);
        eb = radix_tree_lookup(&tree->buffer, start >> PAGE_CACHE_SHIFT);
-       if (!eb)
-               goto out;
+       if (!eb) {
+               spin_unlock(&tree->buffer_lock);
+               return ret;
+       }
 
        if (test_bit(EXTENT_BUFFER_DIRTY, &eb->bflags)) {
                ret = 0;
index 1c6d4f3..4183c81 100644 (file)
@@ -310,4 +310,7 @@ int extent_clear_unlock_delalloc(struct inode *inode,
                                struct extent_io_tree *tree,
                                u64 start, u64 end, struct page *locked_page,
                                unsigned long op);
+struct bio *
+btrfs_bio_alloc(struct block_device *bdev, u64 first_sector, int nr_vecs,
+               gfp_t gfp_flags);
 #endif
index e354c33..66836d8 100644 (file)
@@ -48,30 +48,34 @@ static noinline int btrfs_copy_from_user(loff_t pos, int num_pages,
                                         struct page **prepared_pages,
                                         struct iov_iter *i)
 {
-       size_t copied;
+       size_t copied = 0;
        int pg = 0;
        int offset = pos & (PAGE_CACHE_SIZE - 1);
+       int total_copied = 0;
 
        while (write_bytes > 0) {
                size_t count = min_t(size_t,
                                     PAGE_CACHE_SIZE - offset, write_bytes);
                struct page *page = prepared_pages[pg];
-again:
-               if (unlikely(iov_iter_fault_in_readable(i, count)))
-                       return -EFAULT;
-
-               /* Copy data from userspace to the current page */
-               copied = iov_iter_copy_from_user(page, i, offset, count);
+               /*
+                * Copy data from userspace to the current page
+                *
+                * Disable pagefault to avoid recursive lock since
+                * the pages are already locked
+                */
+               pagefault_disable();
+               copied = iov_iter_copy_from_user_atomic(page, i, offset, count);
+               pagefault_enable();
 
                /* Flush processor's dcache for this page */
                flush_dcache_page(page);
                iov_iter_advance(i, copied);
                write_bytes -= copied;
+               total_copied += copied;
 
+               /* Return to btrfs_file_aio_write to fault page */
                if (unlikely(copied == 0)) {
-                       count = min_t(size_t, PAGE_CACHE_SIZE - offset,
-                                     iov_iter_single_seg_count(i));
-                       goto again;
+                       break;
                }
 
                if (unlikely(copied < PAGE_CACHE_SIZE - offset)) {
@@ -81,7 +85,7 @@ again:
                        offset = 0;
                }
        }
-       return 0;
+       return total_copied;
 }
 
 /*
@@ -854,6 +858,8 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
        unsigned long last_index;
        int will_write;
        int buffered = 0;
+       int copied = 0;
+       int dirty_pages = 0;
 
        will_write = ((file->f_flags & O_DSYNC) || IS_SYNC(inode) ||
                      (file->f_flags & O_DIRECT));
@@ -970,7 +976,17 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
                WARN_ON(num_pages > nrptrs);
                memset(pages, 0, sizeof(struct page *) * nrptrs);
 
-               ret = btrfs_delalloc_reserve_space(inode, write_bytes);
+               /*
+                * Fault pages before locking them in prepare_pages
+                * to avoid recursive lock
+                */
+               if (unlikely(iov_iter_fault_in_readable(&i, write_bytes))) {
+                       ret = -EFAULT;
+                       goto out;
+               }
+
+               ret = btrfs_delalloc_reserve_space(inode,
+                                       num_pages << PAGE_CACHE_SHIFT);
                if (ret)
                        goto out;
 
@@ -978,37 +994,49 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
                                    pos, first_index, last_index,
                                    write_bytes);
                if (ret) {
-                       btrfs_delalloc_release_space(inode, write_bytes);
+                       btrfs_delalloc_release_space(inode,
+                                       num_pages << PAGE_CACHE_SHIFT);
                        goto out;
                }
 
-               ret = btrfs_copy_from_user(pos, num_pages,
+               copied = btrfs_copy_from_user(pos, num_pages,
                                           write_bytes, pages, &i);
-               if (ret == 0) {
+               dirty_pages = (copied + PAGE_CACHE_SIZE - 1) >>
+                                       PAGE_CACHE_SHIFT;
+
+               if (num_pages > dirty_pages) {
+                       if (copied > 0)
+                               atomic_inc(
+                                       &BTRFS_I(inode)->outstanding_extents);
+                       btrfs_delalloc_release_space(inode,
+                                       (num_pages - dirty_pages) <<
+                                       PAGE_CACHE_SHIFT);
+               }
+
+               if (copied > 0) {
                        dirty_and_release_pages(NULL, root, file, pages,
-                                               num_pages, pos, write_bytes);
+                                               dirty_pages, pos, copied);
                }
 
                btrfs_drop_pages(pages, num_pages);
-               if (ret) {
-                       btrfs_delalloc_release_space(inode, write_bytes);
-                       goto out;
-               }
 
-               if (will_write) {
-                       filemap_fdatawrite_range(inode->i_mapping, pos,
-                                                pos + write_bytes - 1);
-               } else {
-                       balance_dirty_pages_ratelimited_nr(inode->i_mapping,
-                                                          num_pages);
-                       if (num_pages <
-                           (root->leafsize >> PAGE_CACHE_SHIFT) + 1)
-                               btrfs_btree_balance_dirty(root, 1);
-                       btrfs_throttle(root);
+               if (copied > 0) {
+                       if (will_write) {
+                               filemap_fdatawrite_range(inode->i_mapping, pos,
+                                                        pos + copied - 1);
+                       } else {
+                               balance_dirty_pages_ratelimited_nr(
+                                                       inode->i_mapping,
+                                                       dirty_pages);
+                               if (dirty_pages <
+                               (root->leafsize >> PAGE_CACHE_SHIFT) + 1)
+                                       btrfs_btree_balance_dirty(root, 1);
+                               btrfs_throttle(root);
+                       }
                }
 
-               pos += write_bytes;
-               num_written += write_bytes;
+               pos += copied;
+               num_written += copied;
 
                cond_resched();
        }
@@ -1047,8 +1075,14 @@ out:
 
                if ((file->f_flags & O_DSYNC) || IS_SYNC(inode)) {
                        trans = btrfs_start_transaction(root, 0);
+                       if (IS_ERR(trans)) {
+                               num_written = PTR_ERR(trans);
+                               goto done;
+                       }
+                       mutex_lock(&inode->i_mutex);
                        ret = btrfs_log_dentry_safe(trans, root,
                                                    file->f_dentry);
+                       mutex_unlock(&inode->i_mutex);
                        if (ret == 0) {
                                ret = btrfs_sync_log(trans, root);
                                if (ret == 0)
@@ -1067,6 +1101,7 @@ out:
                             (start_pos + num_written - 1) >> PAGE_CACHE_SHIFT);
                }
        }
+done:
        current->backing_dev_info = NULL;
        return num_written ? num_written : err;
 }
index 22ee0dc..60d6842 100644 (file)
@@ -290,7 +290,7 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info,
                       (unsigned long long)BTRFS_I(inode)->generation,
                       (unsigned long long)generation,
                       (unsigned long long)block_group->key.objectid);
-               goto out;
+               goto free_cache;
        }
 
        if (!num_entries)
@@ -524,6 +524,12 @@ int btrfs_write_out_cache(struct btrfs_root *root,
                return 0;
        }
 
+       node = rb_first(&block_group->free_space_offset);
+       if (!node) {
+               iput(inode);
+               return 0;
+       }
+
        last_index = (i_size_read(inode) - 1) >> PAGE_CACHE_SHIFT;
        filemap_write_and_wait(inode->i_mapping);
        btrfs_wait_ordered_range(inode, inode->i_size &
@@ -543,10 +549,6 @@ int btrfs_write_out_cache(struct btrfs_root *root,
         */
        first_page_offset = (sizeof(u32) * num_checksums) + sizeof(u64);
 
-       node = rb_first(&block_group->free_space_offset);
-       if (!node)
-               goto out_free;
-
        /*
         * Lock all pages first so we can lock the extent safely.
         *
index 558cac2..72f31ec 100644 (file)
@@ -495,7 +495,7 @@ again:
                add_async_extent(async_cow, start, num_bytes,
                                 total_compressed, pages, nr_pages_ret);
 
-               if (start + num_bytes < end && start + num_bytes < actual_end) {
+               if (start + num_bytes < end) {
                        start += num_bytes;
                        pages = NULL;
                        cond_resched();
@@ -4501,6 +4501,7 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
        BTRFS_I(inode)->index_cnt = 2;
        BTRFS_I(inode)->root = root;
        BTRFS_I(inode)->generation = trans->transid;
+       inode->i_generation = BTRFS_I(inode)->generation;
        btrfs_set_inode_space_info(root, inode);
 
        if (mode & S_IFDIR)
@@ -4622,12 +4623,12 @@ int btrfs_add_link(struct btrfs_trans_handle *trans,
 }
 
 static int btrfs_add_nondir(struct btrfs_trans_handle *trans,
-                           struct dentry *dentry, struct inode *inode,
-                           int backref, u64 index)
+                           struct inode *dir, struct dentry *dentry,
+                           struct inode *inode, int backref, u64 index)
 {
-       int err = btrfs_add_link(trans, dentry->d_parent->d_inode,
-                                inode, dentry->d_name.name,
-                                dentry->d_name.len, backref, index);
+       int err = btrfs_add_link(trans, dir, inode,
+                                dentry->d_name.name, dentry->d_name.len,
+                                backref, index);
        if (!err) {
                d_instantiate(dentry, inode);
                return 0;
@@ -4668,8 +4669,7 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry,
        btrfs_set_trans_block_group(trans, dir);
 
        inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name,
-                               dentry->d_name.len,
-                               dentry->d_parent->d_inode->i_ino, objectid,
+                               dentry->d_name.len, dir->i_ino, objectid,
                                BTRFS_I(dir)->block_group, mode, &index);
        err = PTR_ERR(inode);
        if (IS_ERR(inode))
@@ -4682,7 +4682,7 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry,
        }
 
        btrfs_set_trans_block_group(trans, inode);
-       err = btrfs_add_nondir(trans, dentry, inode, 0, index);
+       err = btrfs_add_nondir(trans, dir, dentry, inode, 0, index);
        if (err)
                drop_inode = 1;
        else {
@@ -4730,10 +4730,8 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
        btrfs_set_trans_block_group(trans, dir);
 
        inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name,
-                               dentry->d_name.len,
-                               dentry->d_parent->d_inode->i_ino,
-                               objectid, BTRFS_I(dir)->block_group, mode,
-                               &index);
+                               dentry->d_name.len, dir->i_ino, objectid,
+                               BTRFS_I(dir)->block_group, mode, &index);
        err = PTR_ERR(inode);
        if (IS_ERR(inode))
                goto out_unlock;
@@ -4745,7 +4743,7 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
        }
 
        btrfs_set_trans_block_group(trans, inode);
-       err = btrfs_add_nondir(trans, dentry, inode, 0, index);
+       err = btrfs_add_nondir(trans, dir, dentry, inode, 0, index);
        if (err)
                drop_inode = 1;
        else {
@@ -4787,6 +4785,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
                return -EPERM;
 
        btrfs_inc_nlink(inode);
+       inode->i_ctime = CURRENT_TIME;
 
        err = btrfs_set_inode_index(dir, &index);
        if (err)
@@ -4805,15 +4804,17 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
        btrfs_set_trans_block_group(trans, dir);
        ihold(inode);
 
-       err = btrfs_add_nondir(trans, dentry, inode, 1, index);
+       err = btrfs_add_nondir(trans, dir, dentry, inode, 1, index);
 
        if (err) {
                drop_inode = 1;
        } else {
+               struct dentry *parent = dget_parent(dentry);
                btrfs_update_inode_block_group(trans, dir);
                err = btrfs_update_inode(trans, root, inode);
                BUG_ON(err);
-               btrfs_log_new_name(trans, inode, NULL, dentry->d_parent);
+               btrfs_log_new_name(trans, inode, NULL, parent);
+               dput(parent);
        }
 
        nr = trans->blocks_used;
@@ -4853,8 +4854,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
        btrfs_set_trans_block_group(trans, dir);
 
        inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name,
-                               dentry->d_name.len,
-                               dentry->d_parent->d_inode->i_ino, objectid,
+                               dentry->d_name.len, dir->i_ino, objectid,
                                BTRFS_I(dir)->block_group, S_IFDIR | mode,
                                &index);
        if (IS_ERR(inode)) {
@@ -4877,9 +4877,8 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
        if (err)
                goto out_fail;
 
-       err = btrfs_add_link(trans, dentry->d_parent->d_inode,
-                                inode, dentry->d_name.name,
-                                dentry->d_name.len, 0, index);
+       err = btrfs_add_link(trans, dir, inode, dentry->d_name.name,
+                            dentry->d_name.len, 0, index);
        if (err)
                goto out_fail;
 
@@ -5535,13 +5534,21 @@ struct btrfs_dio_private {
        u64 bytes;
        u32 *csums;
        void *private;
+
+       /* number of bios pending for this dio */
+       atomic_t pending_bios;
+
+       /* IO errors */
+       int errors;
+
+       struct bio *orig_bio;
 };
 
 static void btrfs_endio_direct_read(struct bio *bio, int err)
 {
+       struct btrfs_dio_private *dip = bio->bi_private;
        struct bio_vec *bvec_end = bio->bi_io_vec + bio->bi_vcnt - 1;
        struct bio_vec *bvec = bio->bi_io_vec;
-       struct btrfs_dio_private *dip = bio->bi_private;
        struct inode *inode = dip->inode;
        struct btrfs_root *root = BTRFS_I(inode)->root;
        u64 start;
@@ -5595,15 +5602,18 @@ static void btrfs_endio_direct_write(struct bio *bio, int err)
        struct btrfs_trans_handle *trans;
        struct btrfs_ordered_extent *ordered = NULL;
        struct extent_state *cached_state = NULL;
+       u64 ordered_offset = dip->logical_offset;
+       u64 ordered_bytes = dip->bytes;
        int ret;
 
        if (err)
                goto out_done;
-
-       ret = btrfs_dec_test_ordered_pending(inode, &ordered,
-                                            dip->logical_offset, dip->bytes);
+again:
+       ret = btrfs_dec_test_first_ordered_pending(inode, &ordered,
+                                                  &ordered_offset,
+                                                  ordered_bytes);
        if (!ret)
-               goto out_done;
+               goto out_test;
 
        BUG_ON(!ordered);
 
@@ -5663,8 +5673,20 @@ out_unlock:
 out:
        btrfs_delalloc_release_metadata(inode, ordered->len);
        btrfs_end_transaction(trans, root);
+       ordered_offset = ordered->file_offset + ordered->len;
        btrfs_put_ordered_extent(ordered);
        btrfs_put_ordered_extent(ordered);
+
+out_test:
+       /*
+        * our bio might span multiple ordered extents.  If we haven't
+        * completed the accounting for the whole dio, go back and try again
+        */
+       if (ordered_offset < dip->logical_offset + dip->bytes) {
+               ordered_bytes = dip->logical_offset + dip->bytes -
+                       ordered_offset;
+               goto again;
+       }
 out_done:
        bio->bi_private = dip->private;
 
@@ -5684,6 +5706,176 @@ static int __btrfs_submit_bio_start_direct_io(struct inode *inode, int rw,
        return 0;
 }
 
+static void btrfs_end_dio_bio(struct bio *bio, int err)
+{
+       struct btrfs_dio_private *dip = bio->bi_private;
+
+       if (err) {
+               printk(KERN_ERR "btrfs direct IO failed ino %lu rw %lu "
+                     "sector %#Lx len %u err no %d\n",
+                     dip->inode->i_ino, bio->bi_rw,
+                     (unsigned long long)bio->bi_sector, bio->bi_size, err);
+               dip->errors = 1;
+
+               /*
+                * before atomic variable goto zero, we must make sure
+                * dip->errors is perceived to be set.
+                */
+               smp_mb__before_atomic_dec();
+       }
+
+       /* if there are more bios still pending for this dio, just exit */
+       if (!atomic_dec_and_test(&dip->pending_bios))
+               goto out;
+
+       if (dip->errors)
+               bio_io_error(dip->orig_bio);
+       else {
+               set_bit(BIO_UPTODATE, &dip->orig_bio->bi_flags);
+               bio_endio(dip->orig_bio, 0);
+       }
+out:
+       bio_put(bio);
+}
+
+static struct bio *btrfs_dio_bio_alloc(struct block_device *bdev,
+                                      u64 first_sector, gfp_t gfp_flags)
+{
+       int nr_vecs = bio_get_nr_vecs(bdev);
+       return btrfs_bio_alloc(bdev, first_sector, nr_vecs, gfp_flags);
+}
+
+static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode,
+                                        int rw, u64 file_offset, int skip_sum,
+                                        u32 *csums)
+{
+       int write = rw & REQ_WRITE;
+       struct btrfs_root *root = BTRFS_I(inode)->root;
+       int ret;
+
+       bio_get(bio);
+       ret = btrfs_bio_wq_end_io(root->fs_info, bio, 0);
+       if (ret)
+               goto err;
+
+       if (write && !skip_sum) {
+               ret = btrfs_wq_submit_bio(root->fs_info,
+                                  inode, rw, bio, 0, 0,
+                                  file_offset,
+                                  __btrfs_submit_bio_start_direct_io,
+                                  __btrfs_submit_bio_done);
+               goto err;
+       } else if (!skip_sum)
+               btrfs_lookup_bio_sums_dio(root, inode, bio,
+                                         file_offset, csums);
+
+       ret = btrfs_map_bio(root, rw, bio, 0, 1);
+err:
+       bio_put(bio);
+       return ret;
+}
+
+static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip,
+                                   int skip_sum)
+{
+       struct inode *inode = dip->inode;
+       struct btrfs_root *root = BTRFS_I(inode)->root;
+       struct btrfs_mapping_tree *map_tree = &root->fs_info->mapping_tree;
+       struct bio *bio;
+       struct bio *orig_bio = dip->orig_bio;
+       struct bio_vec *bvec = orig_bio->bi_io_vec;
+       u64 start_sector = orig_bio->bi_sector;
+       u64 file_offset = dip->logical_offset;
+       u64 submit_len = 0;
+       u64 map_length;
+       int nr_pages = 0;
+       u32 *csums = dip->csums;
+       int ret = 0;
+
+       bio = btrfs_dio_bio_alloc(orig_bio->bi_bdev, start_sector, GFP_NOFS);
+       if (!bio)
+               return -ENOMEM;
+       bio->bi_private = dip;
+       bio->bi_end_io = btrfs_end_dio_bio;
+       atomic_inc(&dip->pending_bios);
+
+       map_length = orig_bio->bi_size;
+       ret = btrfs_map_block(map_tree, READ, start_sector << 9,
+                             &map_length, NULL, 0);
+       if (ret) {
+               bio_put(bio);
+               return -EIO;
+       }
+
+       while (bvec <= (orig_bio->bi_io_vec + orig_bio->bi_vcnt - 1)) {
+               if (unlikely(map_length < submit_len + bvec->bv_len ||
+                   bio_add_page(bio, bvec->bv_page, bvec->bv_len,
+                                bvec->bv_offset) < bvec->bv_len)) {
+                       /*
+                        * inc the count before we submit the bio so
+                        * we know the end IO handler won't happen before
+                        * we inc the count. Otherwise, the dip might get freed
+                        * before we're done setting it up
+                        */
+                       atomic_inc(&dip->pending_bios);
+                       ret = __btrfs_submit_dio_bio(bio, inode, rw,
+                                                    file_offset, skip_sum,
+                                                    csums);
+                       if (ret) {
+                               bio_put(bio);
+                               atomic_dec(&dip->pending_bios);
+                               goto out_err;
+                       }
+
+                       if (!skip_sum)
+                               csums = csums + nr_pages;
+                       start_sector += submit_len >> 9;
+                       file_offset += submit_len;
+
+                       submit_len = 0;
+                       nr_pages = 0;
+
+                       bio = btrfs_dio_bio_alloc(orig_bio->bi_bdev,
+                                                 start_sector, GFP_NOFS);
+                       if (!bio)
+                               goto out_err;
+                       bio->bi_private = dip;
+                       bio->bi_end_io = btrfs_end_dio_bio;
+
+                       map_length = orig_bio->bi_size;
+                       ret = btrfs_map_block(map_tree, READ, start_sector << 9,
+                                             &map_length, NULL, 0);
+                       if (ret) {
+                               bio_put(bio);
+                               goto out_err;
+                       }
+               } else {
+                       submit_len += bvec->bv_len;
+                       nr_pages ++;
+                       bvec++;
+               }
+       }
+
+       ret = __btrfs_submit_dio_bio(bio, inode, rw, file_offset, skip_sum,
+                                    csums);
+       if (!ret)
+               return 0;
+
+       bio_put(bio);
+out_err:
+       dip->errors = 1;
+       /*
+        * before atomic variable goto zero, we must
+        * make sure dip->errors is perceived to be set.
+        */
+       smp_mb__before_atomic_dec();
+       if (atomic_dec_and_test(&dip->pending_bios))
+               bio_io_error(dip->orig_bio);
+
+       /* bio_end_io() will handle error, so we needn't return it */
+       return 0;
+}
+
 static void btrfs_submit_direct(int rw, struct bio *bio, struct inode *inode,
                                loff_t file_offset)
 {
@@ -5723,36 +5915,18 @@ static void btrfs_submit_direct(int rw, struct bio *bio, struct inode *inode,
 
        dip->disk_bytenr = (u64)bio->bi_sector << 9;
        bio->bi_private = dip;
+       dip->errors = 0;
+       dip->orig_bio = bio;
+       atomic_set(&dip->pending_bios, 0);
 
        if (write)
                bio->bi_end_io = btrfs_endio_direct_write;
        else
                bio->bi_end_io = btrfs_endio_direct_read;
 
-       ret = btrfs_bio_wq_end_io(root->fs_info, bio, 0);
-       if (ret)
-               goto out_err;
-
-       if (write && !skip_sum) {
-               ret = btrfs_wq_submit_bio(BTRFS_I(inode)->root->fs_info,
-                                  inode, rw, bio, 0, 0,
-                                  dip->logical_offset,
-                                  __btrfs_submit_bio_start_direct_io,
-                                  __btrfs_submit_bio_done);
-               if (ret)
-                       goto out_err;
+       ret = btrfs_submit_direct_hook(rw, dip, skip_sum);
+       if (!ret)
                return;
-       } else if (!skip_sum)
-               btrfs_lookup_bio_sums_dio(root, inode, bio,
-                                         dip->logical_offset, dip->csums);
-
-       ret = btrfs_map_bio(root, rw, bio, 0, 1);
-       if (ret)
-               goto out_err;
-       return;
-out_err:
-       kfree(dip->csums);
-       kfree(dip);
 free_ordered:
        /*
         * If this is a write, we need to clean up the reserved space and kill
@@ -5760,8 +5934,7 @@ free_ordered:
         */
        if (write) {
                struct btrfs_ordered_extent *ordered;
-               ordered = btrfs_lookup_ordered_extent(inode,
-                                                     dip->logical_offset);
+               ordered = btrfs_lookup_ordered_extent(inode, file_offset);
                if (!test_bit(BTRFS_ORDERED_PREALLOC, &ordered->flags) &&
                    !test_bit(BTRFS_ORDERED_NOCOW, &ordered->flags))
                        btrfs_free_reserved_extent(root, ordered->start,
@@ -6607,8 +6780,9 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
        BUG_ON(ret);
 
        if (old_inode->i_ino != BTRFS_FIRST_FREE_OBJECTID) {
-               btrfs_log_new_name(trans, old_inode, old_dir,
-                                  new_dentry->d_parent);
+               struct dentry *parent = dget_parent(new_dentry);
+               btrfs_log_new_name(trans, old_inode, old_dir, parent);
+               dput(parent);
                btrfs_end_log_trans(root);
        }
 out_fail:
@@ -6758,8 +6932,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
        btrfs_set_trans_block_group(trans, dir);
 
        inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name,
-                               dentry->d_name.len,
-                               dentry->d_parent->d_inode->i_ino, objectid,
+                               dentry->d_name.len, dir->i_ino, objectid,
                                BTRFS_I(dir)->block_group, S_IFLNK|S_IRWXUGO,
                                &index);
        err = PTR_ERR(inode);
@@ -6773,7 +6946,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
        }
 
        btrfs_set_trans_block_group(trans, inode);
-       err = btrfs_add_nondir(trans, dentry, inode, 0, index);
+       err = btrfs_add_nondir(trans, dir, dentry, inode, 0, index);
        if (err)
                drop_inode = 1;
        else {
@@ -6844,6 +7017,7 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode,
        struct btrfs_root *root = BTRFS_I(inode)->root;
        struct btrfs_key ins;
        u64 cur_offset = start;
+       u64 i_size;
        int ret = 0;
        bool own_trans = true;
 
@@ -6885,11 +7059,11 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode,
                    (actual_len > inode->i_size) &&
                    (cur_offset > inode->i_size)) {
                        if (cur_offset > actual_len)
-                               i_size_write(inode, actual_len);
+                               i_size = actual_len;
                        else
-                               i_size_write(inode, cur_offset);
-                       i_size_write(inode, cur_offset);
-                       btrfs_ordered_update_i_size(inode, cur_offset, NULL);
+                               i_size = cur_offset;
+                       i_size_write(inode, i_size);
+                       btrfs_ordered_update_i_size(inode, i_size, NULL);
                }
 
                ret = btrfs_update_inode(trans, root, inode);
@@ -6943,6 +7117,10 @@ static long btrfs_fallocate(struct inode *inode, int mode,
        btrfs_wait_ordered_range(inode, alloc_start, alloc_end - alloc_start);
 
        mutex_lock(&inode->i_mutex);
+       ret = inode_newsize_ok(inode, alloc_end);
+       if (ret)
+               goto out;
+
        if (alloc_start > inode->i_size) {
                ret = btrfs_cont_expand(inode, alloc_start);
                if (ret)
@@ -7139,6 +7317,7 @@ static const struct inode_operations btrfs_symlink_inode_operations = {
        .readlink       = generic_readlink,
        .follow_link    = page_follow_link_light,
        .put_link       = page_put_link,
+       .getattr        = btrfs_getattr,
        .permission     = btrfs_permission,
        .setxattr       = btrfs_setxattr,
        .getxattr       = btrfs_getxattr,
index 463d91b..f87552a 100644 (file)
@@ -233,7 +233,8 @@ static noinline int create_subvol(struct btrfs_root *root,
        struct btrfs_inode_item *inode_item;
        struct extent_buffer *leaf;
        struct btrfs_root *new_root;
-       struct inode *dir = dentry->d_parent->d_inode;
+       struct dentry *parent = dget_parent(dentry);
+       struct inode *dir;
        int ret;
        int err;
        u64 objectid;
@@ -242,8 +243,13 @@ static noinline int create_subvol(struct btrfs_root *root,
 
        ret = btrfs_find_free_objectid(NULL, root->fs_info->tree_root,
                                       0, &objectid);
-       if (ret)
+       if (ret) {
+               dput(parent);
                return ret;
+       }
+
+       dir = parent->d_inode;
+
        /*
         * 1 - inode item
         * 2 - refs
@@ -251,8 +257,10 @@ static noinline int create_subvol(struct btrfs_root *root,
         * 2 - dir items
         */
        trans = btrfs_start_transaction(root, 6);
-       if (IS_ERR(trans))
+       if (IS_ERR(trans)) {
+               dput(parent);
                return PTR_ERR(trans);
+       }
 
        leaf = btrfs_alloc_free_block(trans, root, root->leafsize,
                                      0, objectid, NULL, 0, 0, 0);
@@ -339,6 +347,7 @@ static noinline int create_subvol(struct btrfs_root *root,
 
        d_instantiate(dentry, btrfs_lookup_dentry(dir, dentry));
 fail:
+       dput(parent);
        if (async_transid) {
                *async_transid = trans->transid;
                err = btrfs_commit_transaction_async(trans, root, 1);
@@ -354,6 +363,7 @@ static int create_snapshot(struct btrfs_root *root, struct dentry *dentry,
                           char *name, int namelen, u64 *async_transid)
 {
        struct inode *inode;
+       struct dentry *parent;
        struct btrfs_pending_snapshot *pending_snapshot;
        struct btrfs_trans_handle *trans;
        int ret;
@@ -396,7 +406,9 @@ static int create_snapshot(struct btrfs_root *root, struct dentry *dentry,
 
        btrfs_orphan_cleanup(pending_snapshot->snap);
 
-       inode = btrfs_lookup_dentry(dentry->d_parent->d_inode, dentry);
+       parent = dget_parent(dentry);
+       inode = btrfs_lookup_dentry(parent->d_inode, dentry);
+       dput(parent);
        if (IS_ERR(inode)) {
                ret = PTR_ERR(inode);
                goto fail;
@@ -935,23 +947,42 @@ out:
 
 static noinline int btrfs_ioctl_snap_create(struct file *file,
                                            void __user *arg, int subvol,
-                                           int async)
+                                           int v2)
 {
        struct btrfs_ioctl_vol_args *vol_args = NULL;
-       struct btrfs_ioctl_async_vol_args *async_vol_args = NULL;
+       struct btrfs_ioctl_vol_args_v2 *vol_args_v2 = NULL;
        char *name;
        u64 fd;
-       u64 transid = 0;
        int ret;
 
-       if (async) {
-               async_vol_args = memdup_user(arg, sizeof(*async_vol_args));
-               if (IS_ERR(async_vol_args))
-                       return PTR_ERR(async_vol_args);
+       if (v2) {
+               u64 transid = 0;
+               u64 *ptr = NULL;
+
+               vol_args_v2 = memdup_user(arg, sizeof(*vol_args_v2));
+               if (IS_ERR(vol_args_v2))
+                       return PTR_ERR(vol_args_v2);
+
+               if (vol_args_v2->flags & ~BTRFS_SUBVOL_CREATE_ASYNC) {
+                       ret = -EINVAL;
+                       goto out;
+               }
+
+               name = vol_args_v2->name;
+               fd = vol_args_v2->fd;
+               vol_args_v2->name[BTRFS_SUBVOL_NAME_MAX] = '\0';
+
+               if (vol_args_v2->flags & BTRFS_SUBVOL_CREATE_ASYNC)
+                       ptr = &transid;
+
+               ret = btrfs_ioctl_snap_create_transid(file, name, fd,
+                                                     subvol, ptr);
 
-               name = async_vol_args->name;
-               fd = async_vol_args->fd;
-               async_vol_args->name[BTRFS_SNAPSHOT_NAME_MAX] = '\0';
+               if (ret == 0 && ptr &&
+                   copy_to_user(arg +
+                                offsetof(struct btrfs_ioctl_vol_args_v2,
+                                         transid), ptr, sizeof(*ptr)))
+                       ret = -EFAULT;
        } else {
                vol_args = memdup_user(arg, sizeof(*vol_args));
                if (IS_ERR(vol_args))
@@ -959,20 +990,13 @@ static noinline int btrfs_ioctl_snap_create(struct file *file,
                name = vol_args->name;
                fd = vol_args->fd;
                vol_args->name[BTRFS_PATH_NAME_MAX] = '\0';
-       }
-
-       ret = btrfs_ioctl_snap_create_transid(file, name, fd,
-                                             subvol, &transid);
 
-       if (!ret && async) {
-               if (copy_to_user(arg +
-                               offsetof(struct btrfs_ioctl_async_vol_args,
-                               transid), &transid, sizeof(transid)))
-                       return -EFAULT;
+               ret = btrfs_ioctl_snap_create_transid(file, name, fd,
+                                                     subvol, NULL);
        }
-
+out:
        kfree(vol_args);
-       kfree(async_vol_args);
+       kfree(vol_args_v2);
 
        return ret;
 }
@@ -1669,12 +1693,11 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
                olen = len = src->i_size - off;
        /* if we extend to eof, continue to block boundary */
        if (off + len == src->i_size)
-               len = ((src->i_size + bs-1) & ~(bs-1))
-                       - off;
+               len = ALIGN(src->i_size, bs) - off;
 
        /* verify the end result is block aligned */
-       if ((off & (bs-1)) ||
-           ((off + len) & (bs-1)))
+       if (!IS_ALIGNED(off, bs) || !IS_ALIGNED(off + len, bs) ||
+           !IS_ALIGNED(destoff, bs))
                goto out_unlock;
 
        /* do any pending delalloc/csum calc on src, one way or
@@ -1874,8 +1897,8 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
                         * but shouldn't round up the file size
                         */
                        endoff = new_key.offset + datal;
-                       if (endoff > off+olen)
-                               endoff = off+olen;
+                       if (endoff > destoff+olen)
+                               endoff = destoff+olen;
                        if (endoff > inode->i_size)
                                btrfs_i_size_write(inode, endoff);
 
@@ -2235,7 +2258,7 @@ long btrfs_ioctl(struct file *file, unsigned int
                return btrfs_ioctl_getversion(file, argp);
        case BTRFS_IOC_SNAP_CREATE:
                return btrfs_ioctl_snap_create(file, argp, 0, 0);
-       case BTRFS_IOC_SNAP_CREATE_ASYNC:
+       case BTRFS_IOC_SNAP_CREATE_V2:
                return btrfs_ioctl_snap_create(file, argp, 0, 1);
        case BTRFS_IOC_SUBVOL_CREATE:
                return btrfs_ioctl_snap_create(file, argp, 1, 0);
index 17c99eb..c344d12 100644 (file)
@@ -30,11 +30,15 @@ struct btrfs_ioctl_vol_args {
        char name[BTRFS_PATH_NAME_MAX + 1];
 };
 
-#define BTRFS_SNAPSHOT_NAME_MAX 4079
-struct btrfs_ioctl_async_vol_args {
+#define BTRFS_SUBVOL_CREATE_ASYNC      (1ULL << 0)
+
+#define BTRFS_SUBVOL_NAME_MAX 4039
+struct btrfs_ioctl_vol_args_v2 {
        __s64 fd;
        __u64 transid;
-       char name[BTRFS_SNAPSHOT_NAME_MAX + 1];
+       __u64 flags;
+       __u64 unused[4];
+       char name[BTRFS_SUBVOL_NAME_MAX + 1];
 };
 
 #define BTRFS_INO_LOOKUP_PATH_MAX 4080
@@ -187,6 +191,6 @@ struct btrfs_ioctl_space_args {
                                    struct btrfs_ioctl_space_args)
 #define BTRFS_IOC_START_SYNC _IOR(BTRFS_IOCTL_MAGIC, 24, __u64)
 #define BTRFS_IOC_WAIT_SYNC  _IOW(BTRFS_IOCTL_MAGIC, 22, __u64)
-#define BTRFS_IOC_SNAP_CREATE_ASYNC _IOW(BTRFS_IOCTL_MAGIC, 23, \
-                                  struct btrfs_ioctl_async_vol_args)
+#define BTRFS_IOC_SNAP_CREATE_V2 _IOW(BTRFS_IOCTL_MAGIC, 23, \
+                                  struct btrfs_ioctl_vol_args_v2)
 #endif
index f4621f6..ae7737e 100644 (file)
@@ -248,6 +248,73 @@ int btrfs_add_ordered_sum(struct inode *inode,
        return 0;
 }
 
+/*
+ * this is used to account for finished IO across a given range
+ * of the file.  The IO may span ordered extents.  If
+ * a given ordered_extent is completely done, 1 is returned, otherwise
+ * 0.
+ *
+ * test_and_set_bit on a flag in the struct btrfs_ordered_extent is used
+ * to make sure this function only returns 1 once for a given ordered extent.
+ *
+ * file_offset is updated to one byte past the range that is recorded as
+ * complete.  This allows you to walk forward in the file.
+ */
+int btrfs_dec_test_first_ordered_pending(struct inode *inode,
+                                  struct btrfs_ordered_extent **cached,
+                                  u64 *file_offset, u64 io_size)
+{
+       struct btrfs_ordered_inode_tree *tree;
+       struct rb_node *node;
+       struct btrfs_ordered_extent *entry = NULL;
+       int ret;
+       u64 dec_end;
+       u64 dec_start;
+       u64 to_dec;
+
+       tree = &BTRFS_I(inode)->ordered_tree;
+       spin_lock(&tree->lock);
+       node = tree_search(tree, *file_offset);
+       if (!node) {
+               ret = 1;
+               goto out;
+       }
+
+       entry = rb_entry(node, struct btrfs_ordered_extent, rb_node);
+       if (!offset_in_entry(entry, *file_offset)) {
+               ret = 1;
+               goto out;
+       }
+
+       dec_start = max(*file_offset, entry->file_offset);
+       dec_end = min(*file_offset + io_size, entry->file_offset +
+                     entry->len);
+       *file_offset = dec_end;
+       if (dec_start > dec_end) {
+               printk(KERN_CRIT "bad ordering dec_start %llu end %llu\n",
+                      (unsigned long long)dec_start,
+                      (unsigned long long)dec_end);
+       }
+       to_dec = dec_end - dec_start;
+       if (to_dec > entry->bytes_left) {
+               printk(KERN_CRIT "bad ordered accounting left %llu size %llu\n",
+                      (unsigned long long)entry->bytes_left,
+                      (unsigned long long)to_dec);
+       }
+       entry->bytes_left -= to_dec;
+       if (entry->bytes_left == 0)
+               ret = test_and_set_bit(BTRFS_ORDERED_IO_DONE, &entry->flags);
+       else
+               ret = 1;
+out:
+       if (!ret && cached && entry) {
+               *cached = entry;
+               atomic_inc(&entry->refs);
+       }
+       spin_unlock(&tree->lock);
+       return ret == 0;
+}
+
 /*
  * this is used to account for finished IO across a given range
  * of the file.  The IO should not span ordered extents.  If
index 8ac3654..61dca83 100644 (file)
@@ -141,6 +141,9 @@ int btrfs_remove_ordered_extent(struct inode *inode,
 int btrfs_dec_test_ordered_pending(struct inode *inode,
                                   struct btrfs_ordered_extent **cached,
                                   u64 file_offset, u64 io_size);
+int btrfs_dec_test_first_ordered_pending(struct inode *inode,
+                                  struct btrfs_ordered_extent **cached,
+                                  u64 *file_offset, u64 io_size);
 int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset,
                             u64 start, u64 len, u64 disk_len, int type);
 int btrfs_add_ordered_extent_dio(struct inode *inode, u64 file_offset,
index 79cba5f..f8be250 100644 (file)
@@ -56,8 +56,12 @@ int btrfs_del_orphan_item(struct btrfs_trans_handle *trans,
                return -ENOMEM;
 
        ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
-       if (ret)
+       if (ret < 0)
                goto out;
+       if (ret) {
+               ret = -ENOENT;
+               goto out;
+       }
 
        ret = btrfs_del_item(trans, root, path);
 
index 8299a25..883c6fa 100644 (file)
@@ -244,6 +244,7 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
                case Opt_space_cache:
                        printk(KERN_INFO "btrfs: enabling disk space caching\n");
                        btrfs_set_opt(info->mount_opt, SPACE_CACHE);
+                       break;
                case Opt_clear_cache:
                        printk(KERN_INFO "btrfs: force clearing of disk cache\n");
                        btrfs_set_opt(info->mount_opt, CLEAR_CACHE);
@@ -562,12 +563,26 @@ static int btrfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
 
 static int btrfs_test_super(struct super_block *s, void *data)
 {
-       struct btrfs_fs_devices *test_fs_devices = data;
+       struct btrfs_root *test_root = data;
        struct btrfs_root *root = btrfs_sb(s);
 
-       return root->fs_info->fs_devices == test_fs_devices;
+       /*
+        * If this super block is going away, return false as it
+        * can't match as an existing super block.
+        */
+       if (!atomic_read(&s->s_active))
+               return 0;
+       return root->fs_info->fs_devices == test_root->fs_info->fs_devices;
+}
+
+static int btrfs_set_super(struct super_block *s, void *data)
+{
+       s->s_fs_info = data;
+
+       return set_anon_super(s, data);
 }
 
+
 /*
  * Find a superblock for the given device / mount point.
  *
@@ -581,6 +596,8 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
        struct super_block *s;
        struct dentry *root;
        struct btrfs_fs_devices *fs_devices = NULL;
+       struct btrfs_root *tree_root = NULL;
+       struct btrfs_fs_info *fs_info = NULL;
        fmode_t mode = FMODE_READ;
        char *subvol_name = NULL;
        u64 subvol_objectid = 0;
@@ -608,8 +625,24 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
                goto error_close_devices;
        }
 
+       /*
+        * Setup a dummy root and fs_info for test/set super.  This is because
+        * we don't actually fill this stuff out until open_ctree, but we need
+        * it for searching for existing supers, so this lets us do that and
+        * then open_ctree will properly initialize everything later.
+        */
+       fs_info = kzalloc(sizeof(struct btrfs_fs_info), GFP_NOFS);
+       tree_root = kzalloc(sizeof(struct btrfs_root), GFP_NOFS);
+       if (!fs_info || !tree_root) {
+               error = -ENOMEM;
+               goto error_close_devices;
+       }
+       fs_info->tree_root = tree_root;
+       fs_info->fs_devices = fs_devices;
+       tree_root->fs_info = fs_info;
+
        bdev = fs_devices->latest_bdev;
-       s = sget(fs_type, btrfs_test_super, set_anon_super, fs_devices);
+       s = sget(fs_type, btrfs_test_super, btrfs_set_super, tree_root);
        if (IS_ERR(s))
                goto error_s;
 
@@ -652,9 +685,9 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
                mutex_unlock(&root->d_inode->i_mutex);
 
                if (IS_ERR(new_root)) {
+                       dput(root);
                        deactivate_locked_super(s);
                        error = PTR_ERR(new_root);
-                       dput(root);
                        goto error_free_subvol_name;
                }
                if (!new_root->d_inode) {
@@ -675,6 +708,8 @@ error_s:
        error = PTR_ERR(s);
 error_close_devices:
        btrfs_close_devices(fs_devices);
+       kfree(fs_info);
+       kfree(tree_root);
 error_free_subvol_name:
        kfree(subvol_name);
        return ERR_PTR(error);
index 1fffbc0..f50e931 100644 (file)
@@ -902,6 +902,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
        struct btrfs_root *root = pending->root;
        struct btrfs_root *parent_root;
        struct inode *parent_inode;
+       struct dentry *parent;
        struct dentry *dentry;
        struct extent_buffer *tmp;
        struct extent_buffer *old;
@@ -941,7 +942,8 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
        trans->block_rsv = &pending->block_rsv;
 
        dentry = pending->dentry;
-       parent_inode = dentry->d_parent->d_inode;
+       parent = dget_parent(dentry);
+       parent_inode = parent->d_inode;
        parent_root = BTRFS_I(parent_inode)->root;
        record_root_in_trans(trans, parent_root);
 
@@ -989,6 +991,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
                                 parent_inode->i_ino, index,
                                 dentry->d_name.name, dentry->d_name.len);
        BUG_ON(ret);
+       dput(parent);
 
        key.offset = (u64)-1;
        pending->snap = btrfs_read_fs_root_no_name(root->fs_info, &key);
index a29f193..054744a 100644 (file)
@@ -2869,6 +2869,7 @@ static noinline int check_parent_dirs_for_sync(struct btrfs_trans_handle *trans,
 {
        int ret = 0;
        struct btrfs_root *root;
+       struct dentry *old_parent = NULL;
 
        /*
         * for regular files, if its inode is already on disk, we don't
@@ -2910,10 +2911,13 @@ static noinline int check_parent_dirs_for_sync(struct btrfs_trans_handle *trans,
                if (IS_ROOT(parent))
                        break;
 
-               parent = parent->d_parent;
+               parent = dget_parent(parent);
+               dput(old_parent);
+               old_parent = parent;
                inode = parent->d_inode;
 
        }
+       dput(old_parent);
 out:
        return ret;
 }
@@ -2945,6 +2949,7 @@ int btrfs_log_inode_parent(struct btrfs_trans_handle *trans,
 {
        int inode_only = exists_only ? LOG_INODE_EXISTS : LOG_INODE_ALL;
        struct super_block *sb;
+       struct dentry *old_parent = NULL;
        int ret = 0;
        u64 last_committed = root->fs_info->last_trans_committed;
 
@@ -3016,10 +3021,13 @@ int btrfs_log_inode_parent(struct btrfs_trans_handle *trans,
                if (IS_ROOT(parent))
                        break;
 
-               parent = parent->d_parent;
+               parent = dget_parent(parent);
+               dput(old_parent);
+               old_parent = parent;
        }
        ret = 0;
 end_trans:
+       dput(old_parent);
        if (ret < 0) {
                BUG_ON(ret != -ENOSPC);
                root->fs_info->last_trans_log_full_commit = trans->transid;
@@ -3039,8 +3047,13 @@ end_no_trans:
 int btrfs_log_dentry_safe(struct btrfs_trans_handle *trans,
                          struct btrfs_root *root, struct dentry *dentry)
 {
-       return btrfs_log_inode_parent(trans, root, dentry->d_inode,
-                                     dentry->d_parent, 0);
+       struct dentry *parent = dget_parent(dentry);
+       int ret;
+
+       ret = btrfs_log_inode_parent(trans, root, dentry->d_inode, parent, 0);
+       dput(parent);
+
+       return ret;
 }
 
 /*
index cc04dc1..6b98845 100644 (file)
@@ -412,12 +412,16 @@ static noinline int device_list_add(const char *path,
 
                device->fs_devices = fs_devices;
                fs_devices->num_devices++;
-       } else if (strcmp(device->name, path)) {
+       } else if (!device->name || strcmp(device->name, path)) {
                name = kstrdup(path, GFP_NOFS);
                if (!name)
                        return -ENOMEM;
                kfree(device->name);
                device->name = name;
+               if (device->missing) {
+                       fs_devices->missing_devices--;
+                       device->missing = 0;
+               }
        }
 
        if (found_transid > fs_devices->latest_trans) {
@@ -1236,6 +1240,9 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
 
        device->fs_devices->num_devices--;
 
+       if (device->missing)
+               root->fs_info->fs_devices->missing_devices--;
+
        next_device = list_entry(root->fs_info->fs_devices->devices.next,
                                 struct btrfs_device, dev_list);
        if (device->bdev == root->fs_info->sb->s_bdev)
@@ -3080,7 +3087,9 @@ static struct btrfs_device *add_missing_dev(struct btrfs_root *root,
        device->devid = devid;
        device->work.func = pending_bios_fn;
        device->fs_devices = fs_devices;
+       device->missing = 1;
        fs_devices->num_devices++;
+       fs_devices->missing_devices++;
        spin_lock_init(&device->io_lock);
        INIT_LIST_HEAD(&device->dev_alloc_list);
        memcpy(device->uuid, dev_uuid, BTRFS_UUID_SIZE);
@@ -3278,6 +3287,15 @@ static int read_one_dev(struct btrfs_root *root,
                        device = add_missing_dev(root, devid, dev_uuid);
                        if (!device)
                                return -ENOMEM;
+               } else if (!device->missing) {
+                       /*
+                        * this happens when a device that was properly setup
+                        * in the device info lists suddenly goes bad.
+                        * device->bdev is NULL, and so we have to set
+                        * device->missing to one here
+                        */
+                       root->fs_info->fs_devices->missing_devices++;
+                       device->missing = 1;
                }
        }
 
index 2b638b6..2740db4 100644 (file)
@@ -44,6 +44,7 @@ struct btrfs_device {
 
        int writeable;
        int in_fs_metadata;
+       int missing;
 
        spinlock_t io_lock;
 
@@ -93,6 +94,7 @@ struct btrfs_fs_devices {
        u64 num_devices;
        u64 open_devices;
        u64 rw_devices;
+       u64 missing_devices;
        u64 total_rw_bytes;
        struct block_device *latest_bdev;
 
index 7d447af..158c700 100644 (file)
@@ -114,8 +114,8 @@ static int __dcache_readdir(struct file *filp,
        spin_lock(&dcache_lock);
 
        /* start at beginning? */
-       if (filp->f_pos == 2 || (last &&
-                                filp->f_pos < ceph_dentry(last)->offset)) {
+       if (filp->f_pos == 2 || last == NULL ||
+           filp->f_pos < ceph_dentry(last)->offset) {
                if (list_empty(&parent->d_subdirs))
                        goto out_unlock;
                p = parent->d_subdirs.prev;
index a6ce54e..52e8fd7 100644 (file)
@@ -4,7 +4,7 @@
 #include <linux/ioctl.h>
 #include <linux/types.h>
 
-#define CEPH_IOCTL_MAGIC 0x98
+#define CEPH_IOCTL_MAGIC 0x97
 
 /* just use u64 to align sanely on all archs */
 struct ceph_ioctl_layout {
index 40abde9..476b329 100644 (file)
  * Implement fcntl and flock locking functions.
  */
 static int ceph_lock_message(u8 lock_type, u16 operation, struct file *file,
-                            u64 pid, u64 pid_ns,
-                            int cmd, u64 start, u64 length, u8 wait)
+                            int cmd, u8 wait, struct file_lock *fl)
 {
        struct inode *inode = file->f_dentry->d_inode;
        struct ceph_mds_client *mdsc =
                ceph_sb_to_client(inode->i_sb)->mdsc;
        struct ceph_mds_request *req;
        int err;
+       u64 length = 0;
 
        req = ceph_mdsc_create_request(mdsc, operation, USE_AUTH_MDS);
        if (IS_ERR(req))
                return PTR_ERR(req);
        req->r_inode = igrab(inode);
 
+       /* mds requires start and length rather than start and end */
+       if (LLONG_MAX == fl->fl_end)
+               length = 0;
+       else
+               length = fl->fl_end - fl->fl_start + 1;
+
        dout("ceph_lock_message: rule: %d, op: %d, pid: %llu, start: %llu, "
             "length: %llu, wait: %d, type`: %d", (int)lock_type,
-            (int)operation, pid, start, length, wait, cmd);
+            (int)operation, (u64)fl->fl_pid, fl->fl_start,
+            length, wait, fl->fl_type);
+
 
        req->r_args.filelock_change.rule = lock_type;
        req->r_args.filelock_change.type = cmd;
-       req->r_args.filelock_change.pid = cpu_to_le64(pid);
+       req->r_args.filelock_change.pid = cpu_to_le64((u64)fl->fl_pid);
        /* This should be adjusted, but I'm not sure if
           namespaces actually get id numbers*/
        req->r_args.filelock_change.pid_namespace =
-               cpu_to_le64((u64)pid_ns);
-       req->r_args.filelock_change.start = cpu_to_le64(start);
+               cpu_to_le64((u64)(unsigned long)fl->fl_nspid);
+       req->r_args.filelock_change.start = cpu_to_le64(fl->fl_start);
        req->r_args.filelock_change.length = cpu_to_le64(length);
        req->r_args.filelock_change.wait = wait;
 
        err = ceph_mdsc_do_request(mdsc, inode, req);
+
+       if ( operation == CEPH_MDS_OP_GETFILELOCK){
+               fl->fl_pid = le64_to_cpu(req->r_reply_info.filelock_reply->pid);
+               if (CEPH_LOCK_SHARED == req->r_reply_info.filelock_reply->type)
+                       fl->fl_type = F_RDLCK;
+               else if (CEPH_LOCK_EXCL == req->r_reply_info.filelock_reply->type)
+                       fl->fl_type = F_WRLCK;
+               else
+                       fl->fl_type = F_UNLCK;
+
+               fl->fl_start = le64_to_cpu(req->r_reply_info.filelock_reply->start);
+               length = le64_to_cpu(req->r_reply_info.filelock_reply->start) +
+                                                le64_to_cpu(req->r_reply_info.filelock_reply->length);
+               if (length >= 1)
+                       fl->fl_end = length -1;
+               else
+                       fl->fl_end = 0;
+
+       }
        ceph_mdsc_put_request(req);
        dout("ceph_lock_message: rule: %d, op: %d, pid: %llu, start: %llu, "
-            "length: %llu, wait: %d, type`: %d err code %d", (int)lock_type,
-            (int)operation, pid, start, length, wait, cmd, err);
+            "length: %llu, wait: %d, type`: %d, err code %d", (int)lock_type,
+            (int)operation, (u64)fl->fl_pid, fl->fl_start,
+            length, wait, fl->fl_type, err);
        return err;
 }
 
@@ -54,7 +82,6 @@ static int ceph_lock_message(u8 lock_type, u16 operation, struct file *file,
  */
 int ceph_lock(struct file *file, int cmd, struct file_lock *fl)
 {
-       u64 length;
        u8 lock_cmd;
        int err;
        u8 wait = 0;
@@ -76,29 +103,20 @@ int ceph_lock(struct file *file, int cmd, struct file_lock *fl)
        else
                lock_cmd = CEPH_LOCK_UNLOCK;
 
-       if (LLONG_MAX == fl->fl_end)
-               length = 0;
-       else
-               length = fl->fl_end - fl->fl_start + 1;
-
-       err = ceph_lock_message(CEPH_LOCK_FCNTL, op, file,
-                               (u64)fl->fl_pid,
-                               (u64)(unsigned long)fl->fl_nspid,
-                               lock_cmd, fl->fl_start,
-                               length, wait);
+       err = ceph_lock_message(CEPH_LOCK_FCNTL, op, file, lock_cmd, wait, fl);
        if (!err) {
-               dout("mds locked, locking locally");
-               err = posix_lock_file(file, fl, NULL);
-               if (err && (CEPH_MDS_OP_SETFILELOCK == op)) {
-                       /* undo! This should only happen if the kernel detects
-                        * local deadlock. */
-                       ceph_lock_message(CEPH_LOCK_FCNTL, op, file,
-                                         (u64)fl->fl_pid,
-                                         (u64)(unsigned long)fl->fl_nspid,
-                                         CEPH_LOCK_UNLOCK, fl->fl_start,
-                                         length, 0);
-                       dout("got %d on posix_lock_file, undid lock", err);
+               if ( op != CEPH_MDS_OP_GETFILELOCK ){
+                       dout("mds locked, locking locally");
+                       err = posix_lock_file(file, fl, NULL);
+                       if (err && (CEPH_MDS_OP_SETFILELOCK == op)) {
+                               /* undo! This should only happen if the kernel detects
+                                * local deadlock. */
+                               ceph_lock_message(CEPH_LOCK_FCNTL, op, file,
+                                                 CEPH_LOCK_UNLOCK, 0, fl);
+                               dout("got %d on posix_lock_file, undid lock", err);
+                       }
                }
+
        } else {
                dout("mds returned error code %d", err);
        }
@@ -107,7 +125,6 @@ int ceph_lock(struct file *file, int cmd, struct file_lock *fl)
 
 int ceph_flock(struct file *file, int cmd, struct file_lock *fl)
 {
-       u64 length;
        u8 lock_cmd;
        int err;
        u8 wait = 1;
@@ -127,26 +144,15 @@ int ceph_flock(struct file *file, int cmd, struct file_lock *fl)
                lock_cmd = CEPH_LOCK_EXCL;
        else
                lock_cmd = CEPH_LOCK_UNLOCK;
-       /* mds requires start and length rather than start and end */
-       if (LLONG_MAX == fl->fl_end)
-               length = 0;
-       else
-               length = fl->fl_end - fl->fl_start + 1;
 
        err = ceph_lock_message(CEPH_LOCK_FLOCK, CEPH_MDS_OP_SETFILELOCK,
-                               file, (u64)fl->fl_pid,
-                               (u64)(unsigned long)fl->fl_nspid,
-                               lock_cmd, fl->fl_start,
-                               length, wait);
+                               file, lock_cmd, wait, fl);
        if (!err) {
                err = flock_lock_file_wait(file, fl);
                if (err) {
                        ceph_lock_message(CEPH_LOCK_FLOCK,
                                          CEPH_MDS_OP_SETFILELOCK,
-                                         file, (u64)fl->fl_pid,
-                                         (u64)(unsigned long)fl->fl_nspid,
-                                         CEPH_LOCK_UNLOCK, fl->fl_start,
-                                         length, 0);
+                                         file, CEPH_LOCK_UNLOCK, 0, fl);
                        dout("got %d on flock_lock_file_wait, undid lock", err);
                }
        } else {
index 098b185..38800ea 100644 (file)
@@ -201,6 +201,38 @@ out_bad:
        return err;
 }
 
+/*
+ * parse fcntl F_GETLK results
+ */
+static int parse_reply_info_filelock(void **p, void *end,
+                struct ceph_mds_reply_info_parsed *info)
+{
+       if (*p + sizeof(*info->filelock_reply) > end)
+               goto bad;
+
+       info->filelock_reply = *p;
+       *p += sizeof(*info->filelock_reply);
+
+       if (unlikely(*p != end))
+               goto bad;
+       return 0;
+
+bad:
+       return -EIO;
+}
+
+/*
+ * parse extra results
+ */
+static int parse_reply_info_extra(void **p, void *end,
+                struct ceph_mds_reply_info_parsed *info)
+{
+       if (info->head->op == CEPH_MDS_OP_GETFILELOCK)
+               return parse_reply_info_filelock(p, end, info);
+       else
+               return parse_reply_info_dir(p, end, info);
+}
+
 /*
  * parse entire mds reply
  */
@@ -223,10 +255,10 @@ static int parse_reply_info(struct ceph_msg *msg,
                        goto out_bad;
        }
 
-       /* dir content */
+       /* extra */
        ceph_decode_32_safe(&p, end, len, bad);
        if (len > 0) {
-               err = parse_reply_info_dir(&p, p+len, info);
+               err = parse_reply_info_extra(&p, p+len, info);
                if (err < 0)
                        goto out_bad;
        }
@@ -2074,7 +2106,7 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg)
 
        mutex_lock(&session->s_mutex);
        if (err < 0) {
-               pr_err("mdsc_handle_reply got corrupt reply mds%d\n", mds);
+               pr_err("mdsc_handle_reply got corrupt reply mds%d(tid:%lld)\n", mds, tid);
                ceph_msg_dump(msg);
                goto out_err;
        }
@@ -2094,7 +2126,8 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg)
        mutex_lock(&req->r_fill_mutex);
        err = ceph_fill_trace(mdsc->fsc->sb, req, req->r_session);
        if (err == 0) {
-               if (result == 0 && rinfo->dir_nr)
+               if (result == 0 && req->r_op != CEPH_MDS_OP_GETFILELOCK &&
+                   rinfo->dir_nr)
                        ceph_readdir_prepopulate(req, req->r_session);
                ceph_unreserve_caps(mdsc, &req->r_caps_reservation);
        }
index 9341fd4..aabe563 100644 (file)
@@ -42,26 +42,37 @@ struct ceph_mds_reply_info_in {
 };
 
 /*
- * parsed info about an mds reply, including information about the
- * target inode and/or its parent directory and dentry, and directory
- * contents (for readdir results).
+ * parsed info about an mds reply, including information about
+ * either: 1) the target inode and/or its parent directory and dentry,
+ * and directory contents (for readdir results), or
+ * 2) the file range lock info (for fcntl F_GETLK results).
  */
 struct ceph_mds_reply_info_parsed {
        struct ceph_mds_reply_head    *head;
 
+       /* trace */
        struct ceph_mds_reply_info_in diri, targeti;
        struct ceph_mds_reply_dirfrag *dirfrag;
        char                          *dname;
        u32                           dname_len;
        struct ceph_mds_reply_lease   *dlease;
 
-       struct ceph_mds_reply_dirfrag *dir_dir;
-       int                           dir_nr;
-       char                          **dir_dname;
-       u32                           *dir_dname_len;
-       struct ceph_mds_reply_lease   **dir_dlease;
-       struct ceph_mds_reply_info_in *dir_in;
-       u8                            dir_complete, dir_end;
+       /* extra */
+       union {
+               /* for fcntl F_GETLK results */
+               struct ceph_filelock *filelock_reply;
+
+               /* for readdir results */
+               struct {
+                       struct ceph_mds_reply_dirfrag *dir_dir;
+                       int                           dir_nr;
+                       char                          **dir_dname;
+                       u32                           *dir_dname_len;
+                       struct ceph_mds_reply_lease   **dir_dlease;
+                       struct ceph_mds_reply_info_in *dir_in;
+                       u8                            dir_complete, dir_end;
+               };
+       };
 
        /* encoded blob describing snapshot contexts for certain
           operations (e.g., open) */
index 0ed2139..ee45648 100644 (file)
@@ -4,6 +4,7 @@ config CIFS
        select NLS
        select CRYPTO
        select CRYPTO_MD5
+       select CRYPTO_HMAC
        select CRYPTO_ARC4
        help
          This is the client VFS module for the Common Internet File System
@@ -143,6 +144,13 @@ config CIFS_FSCACHE
            to be cached locally on disk through the general filesystem cache
            manager. If unsure, say N.
 
+config CIFS_ACL
+         bool "Provide CIFS ACL support (EXPERIMENTAL)"
+         depends on EXPERIMENTAL && CIFS_XATTR
+         help
+           Allows to fetch CIFS/NTFS ACL from the server.  The DACL blob
+           is handed over to the application/caller.
+
 config CIFS_EXPERIMENTAL
          bool "CIFS Experimental Features (EXPERIMENTAL)"
          depends on CIFS && EXPERIMENTAL
index adefa60..43b19dd 100644 (file)
@@ -6,7 +6,9 @@ obj-$(CONFIG_CIFS) += cifs.o
 cifs-y := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o \
          link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o \
          md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o \
-         readdir.o ioctl.o sess.o export.o cifsacl.o
+         readdir.o ioctl.o sess.o export.o
+
+cifs-$(CONFIG_CIFS_ACL) += cifsacl.o
 
 cifs-$(CONFIG_CIFS_UPCALL) += cifs_spnego.o
 
index ee68d10..46af99a 100644 (file)
@@ -337,6 +337,15 @@ A partial list of the supported mount options follows:
   wsize                default write size (default 57344)
                maximum wsize currently allowed by CIFS is 57344 (fourteen
                4096 byte pages)
+  actimeo=n    attribute cache timeout in seconds (default 1 second).
+               After this timeout, the cifs client requests fresh attribute
+               information from the server. This option allows to tune the
+               attribute cache timeout to suit the workload needs. Shorter
+               timeouts mean better the cache coherency, but increased number
+               of calls to the server. Longer timeouts mean reduced number
+               of calls to the server at the expense of less stricter cache
+               coherency checks (i.e. incorrect attribute cache for a short
+               period of time).
   rw           mount the network share read-write (note that the
                server may still consider the share read-only)
   ro           mount network share read-only
index e9a393c..7852cd6 100644 (file)
@@ -48,6 +48,7 @@ struct cifs_sb_info {
        struct nls_table *local_nls;
        unsigned int rsize;
        unsigned int wsize;
+       unsigned long actimeo; /* attribute cache timeout (jiffies) */
        atomic_t active;
        uid_t   mnt_uid;
        gid_t   mnt_gid;
index c9b4792..a437ec3 100644 (file)
@@ -30,8 +30,6 @@
 #include "cifs_debug.h"
 
 
-#ifdef CONFIG_CIFS_EXPERIMENTAL
-
 static struct cifs_wksid wksidarr[NUM_WK_SIDS] = {
        {{1, 0, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0} }, "null user"},
        {{1, 1, {0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 0} }, "nobody"},
@@ -560,7 +558,7 @@ static struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
        struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
 
        if (IS_ERR(tlink))
-               return NULL;
+               return ERR_CAST(tlink);
 
        xid = GetXid();
        rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), fid, &pntsd, pacllen);
@@ -568,7 +566,9 @@ static struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
 
        cifs_put_tlink(tlink);
 
-       cFYI(1, "GetCIFSACL rc = %d ACL len %d", rc, *pacllen);
+       cFYI(1, "%s: rc = %d ACL len %d", __func__, rc, *pacllen);
+       if (rc)
+               return ERR_PTR(rc);
        return pntsd;
 }
 
@@ -583,7 +583,7 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
        struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
 
        if (IS_ERR(tlink))
-               return NULL;
+               return ERR_CAST(tlink);
 
        tcon = tlink_tcon(tlink);
        xid = GetXid();
@@ -591,23 +591,22 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
        rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, READ_CONTROL, 0,
                         &fid, &oplock, NULL, cifs_sb->local_nls,
                         cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
-       if (rc) {
-               cERROR(1, "Unable to open file to get ACL");
-               goto out;
+       if (!rc) {
+               rc = CIFSSMBGetCIFSACL(xid, tcon, fid, &pntsd, pacllen);
+               CIFSSMBClose(xid, tcon, fid);
        }
 
-       rc = CIFSSMBGetCIFSACL(xid, tcon, fid, &pntsd, pacllen);
-       cFYI(1, "GetCIFSACL rc = %d ACL len %d", rc, *pacllen);
-
-       CIFSSMBClose(xid, tcon, fid);
- out:
        cifs_put_tlink(tlink);
        FreeXid(xid);
+
+       cFYI(1, "%s: rc = %d ACL len %d", __func__, rc, *pacllen);
+       if (rc)
+               return ERR_PTR(rc);
        return pntsd;
 }
 
 /* Retrieve an ACL from the server */
-static struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
+struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
                                      struct inode *inode, const char *path,
                                      u32 *pacllen)
 {
@@ -695,7 +694,7 @@ static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
 }
 
 /* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */
-void
+int
 cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
                  struct inode *inode, const char *path, const __u16 *pfid)
 {
@@ -711,17 +710,21 @@ cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
                pntsd = get_cifs_acl(cifs_sb, inode, path, &acllen);
 
        /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
-       if (pntsd)
+       if (IS_ERR(pntsd)) {
+               rc = PTR_ERR(pntsd);
+               cERROR(1, "%s: error %d getting sec desc", __func__, rc);
+       } else {
                rc = parse_sec_desc(pntsd, acllen, fattr);
-       if (rc)
-               cFYI(1, "parse sec desc failed rc = %d", rc);
+               kfree(pntsd);
+               if (rc)
+                       cERROR(1, "parse sec desc failed rc = %d", rc);
+       }
 
-       kfree(pntsd);
-       return;
+       return rc;
 }
 
 /* Convert mode bits to an ACL so we can update the ACL on the server */
-int mode_to_acl(struct inode *inode, const char *path, __u64 nmode)
+int mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode)
 {
        int rc = 0;
        __u32 secdesclen = 0;
@@ -736,7 +739,10 @@ int mode_to_acl(struct inode *inode, const char *path, __u64 nmode)
        /* Add three ACEs for owner, group, everyone getting rid of
           other ACEs as chmod disables ACEs and set the security descriptor */
 
-       if (pntsd) {
+       if (IS_ERR(pntsd)) {
+               rc = PTR_ERR(pntsd);
+               cERROR(1, "%s: error %d getting sec desc", __func__, rc);
+       } else {
                /* allocate memory for the smb header,
                   set security descriptor request security descriptor
                   parameters, and secuirty descriptor itself */
@@ -766,4 +772,3 @@ int mode_to_acl(struct inode *inode, const char *path, __u64 nmode)
 
        return rc;
 }
-#endif /* CONFIG_CIFS_EXPERIMENTAL */
index 6c8096c..c4ae7d0 100644 (file)
@@ -74,11 +74,7 @@ struct cifs_wksid {
        char sidname[SIDNAMELENGTH];
 } __attribute__((packed));
 
-#ifdef CONFIG_CIFS_EXPERIMENTAL
-
 extern int match_sid(struct cifs_sid *);
 extern int compare_sids(const struct cifs_sid *, const struct cifs_sid *);
 
-#endif /*  CONFIG_CIFS_EXPERIMENTAL */
-
 #endif /* _CIFSACL_H */
index 9c37897..3936aa7 100644 (file)
@@ -458,9 +458,13 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m)
                seq_printf(s, ",acl");
        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
                seq_printf(s, ",mfsymlinks");
+       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_FSCACHE)
+               seq_printf(s, ",fsc");
 
        seq_printf(s, ",rsize=%d", cifs_sb->rsize);
        seq_printf(s, ",wsize=%d", cifs_sb->wsize);
+       /* convert actimeo and display it in seconds */
+               seq_printf(s, ",actimeo=%lu", cifs_sb->actimeo / HZ);
 
        return 0;
 }
@@ -933,7 +937,6 @@ init_cifs(void)
        GlobalCurrentXid = 0;
        GlobalTotalActiveXid = 0;
        GlobalMaxActiveXid = 0;
-       memset(Local_System_Name, 0, 15);
        spin_lock_init(&cifs_tcp_ses_lock);
        spin_lock_init(&cifs_file_list_lock);
        spin_lock_init(&GlobalMid_Lock);
index b577bf0..7136c0c 100644 (file)
 
 #define CIFS_MIN_RCV_POOL 4
 
+/*
+ * default attribute cache timeout (jiffies)
+ */
+#define CIFS_DEF_ACTIMEO (1 * HZ)
+
+/*
+ * max attribute cache timeout (jiffies) - 2^30
+ */
+#define CIFS_MAX_ACTIMEO (1 << 30)
+
 /*
  * MAX_REQ is the maximum number of requests that WE will send
  * on one socket concurrently. It also matches the most common
@@ -746,8 +756,6 @@ GLOBAL_EXTERN unsigned int GlobalTotalActiveXid; /* prot by GlobalMid_Sem */
 GLOBAL_EXTERN unsigned int GlobalMaxActiveXid; /* prot by GlobalMid_Sem */
 GLOBAL_EXTERN spinlock_t GlobalMid_Lock;  /* protects above & list operations */
                                          /* on midQ entries */
-GLOBAL_EXTERN char Local_System_Name[15];
-
 /*
  *  Global counters, updated atomically
  */
index 7ed69b6..e6d1481 100644 (file)
@@ -54,7 +54,8 @@ do {                                                          \
             __func__, curr_xid, (int)rc);                      \
 } while (0)
 extern char *build_path_from_dentry(struct dentry *);
-extern char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb);
+extern char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb,
+                                       struct cifsTconInfo *tcon);
 extern char *build_wildcard_path_from_dentry(struct dentry *direntry);
 extern char *cifs_compose_mount_options(const char *sb_mountdata,
                const char *fullpath, const struct dfs_info3_param *ref,
@@ -79,9 +80,7 @@ extern bool is_valid_oplock_break(struct smb_hdr *smb,
                                  struct TCP_Server_Info *);
 extern bool is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof);
 extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, bool);
-#ifdef CONFIG_CIFS_EXPERIMENTAL
 extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *, bool);
-#endif
 extern unsigned int smbCalcSize(struct smb_hdr *ptr);
 extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr);
 extern int decode_negTokenInit(unsigned char *security_blob, int length,
@@ -130,10 +129,12 @@ extern int cifs_get_file_info_unix(struct file *filp);
 extern int cifs_get_inode_info_unix(struct inode **pinode,
                        const unsigned char *search_path,
                        struct super_block *sb, int xid);
-extern void cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb,
+extern int cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb,
                              struct cifs_fattr *fattr, struct inode *inode,
                              const char *path, const __u16 *pfid);
-extern int mode_to_acl(struct inode *inode, const char *path, __u64);
+extern int mode_to_cifs_acl(struct inode *inode, const char *path, __u64);
+extern struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *, struct inode *,
+                                       const char *, u32 *);
 
 extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *,
                        const char *);
index 2f2632b..67acfb3 100644 (file)
@@ -2478,95 +2478,6 @@ querySymLinkRetry:
 }
 
 #ifdef CONFIG_CIFS_EXPERIMENTAL
-/* Initialize NT TRANSACT SMB into small smb request buffer.
-   This assumes that all NT TRANSACTS that we init here have
-   total parm and data under about 400 bytes (to fit in small cifs
-   buffer size), which is the case so far, it easily fits. NB:
-       Setup words themselves and ByteCount
-       MaxSetupCount (size of returned setup area) and
-       MaxParameterCount (returned parms size) must be set by caller */
-static int
-smb_init_nttransact(const __u16 sub_command, const int setup_count,
-                  const int parm_len, struct cifsTconInfo *tcon,
-                  void **ret_buf)
-{
-       int rc;
-       __u32 temp_offset;
-       struct smb_com_ntransact_req *pSMB;
-
-       rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
-                               (void **)&pSMB);
-       if (rc)
-               return rc;
-       *ret_buf = (void *)pSMB;
-       pSMB->Reserved = 0;
-       pSMB->TotalParameterCount = cpu_to_le32(parm_len);
-       pSMB->TotalDataCount  = 0;
-       pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf -
-                                         MAX_CIFS_HDR_SIZE) & 0xFFFFFF00);
-       pSMB->ParameterCount = pSMB->TotalParameterCount;
-       pSMB->DataCount  = pSMB->TotalDataCount;
-       temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
-                       (setup_count * 2) - 4 /* for rfc1001 length itself */;
-       pSMB->ParameterOffset = cpu_to_le32(temp_offset);
-       pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
-       pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
-       pSMB->SubCommand = cpu_to_le16(sub_command);
-       return 0;
-}
-
-static int
-validate_ntransact(char *buf, char **ppparm, char **ppdata,
-                  __u32 *pparmlen, __u32 *pdatalen)
-{
-       char *end_of_smb;
-       __u32 data_count, data_offset, parm_count, parm_offset;
-       struct smb_com_ntransact_rsp *pSMBr;
-
-       *pdatalen = 0;
-       *pparmlen = 0;
-
-       if (buf == NULL)
-               return -EINVAL;
-
-       pSMBr = (struct smb_com_ntransact_rsp *)buf;
-
-       /* ByteCount was converted from little endian in SendReceive */
-       end_of_smb = 2 /* sizeof byte count */ + pSMBr->ByteCount +
-                       (char *)&pSMBr->ByteCount;
-
-       data_offset = le32_to_cpu(pSMBr->DataOffset);
-       data_count = le32_to_cpu(pSMBr->DataCount);
-       parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
-       parm_count = le32_to_cpu(pSMBr->ParameterCount);
-
-       *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
-       *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
-
-       /* should we also check that parm and data areas do not overlap? */
-       if (*ppparm > end_of_smb) {
-               cFYI(1, "parms start after end of smb");
-               return -EINVAL;
-       } else if (parm_count + *ppparm > end_of_smb) {
-               cFYI(1, "parm end after end of smb");
-               return -EINVAL;
-       } else if (*ppdata > end_of_smb) {
-               cFYI(1, "data starts after end of smb");
-               return -EINVAL;
-       } else if (data_count + *ppdata > end_of_smb) {
-               cFYI(1, "data %p + count %d (%p) past smb end %p start %p",
-                       *ppdata, data_count, (data_count + *ppdata),
-                       end_of_smb, pSMBr);
-               return -EINVAL;
-       } else if (parm_count + data_count > pSMBr->ByteCount) {
-               cFYI(1, "parm count and data count larger than SMB");
-               return -EINVAL;
-       }
-       *pdatalen = data_count;
-       *pparmlen = parm_count;
-       return 0;
-}
-
 int
 CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
                        const unsigned char *searchName,
@@ -3056,7 +2967,97 @@ GetExtAttrOut:
 
 #endif /* CONFIG_POSIX */
 
-#ifdef CONFIG_CIFS_EXPERIMENTAL
+#ifdef CONFIG_CIFS_ACL
+/*
+ * Initialize NT TRANSACT SMB into small smb request buffer.  This assumes that
+ * all NT TRANSACTS that we init here have total parm and data under about 400
+ * bytes (to fit in small cifs buffer size), which is the case so far, it
+ * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
+ * returned setup area) and MaxParameterCount (returned parms size) must be set
+ * by caller
+ */
+static int
+smb_init_nttransact(const __u16 sub_command, const int setup_count,
+                  const int parm_len, struct cifsTconInfo *tcon,
+                  void **ret_buf)
+{
+       int rc;
+       __u32 temp_offset;
+       struct smb_com_ntransact_req *pSMB;
+
+       rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
+                               (void **)&pSMB);
+       if (rc)
+               return rc;
+       *ret_buf = (void *)pSMB;
+       pSMB->Reserved = 0;
+       pSMB->TotalParameterCount = cpu_to_le32(parm_len);
+       pSMB->TotalDataCount  = 0;
+       pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf -
+                                         MAX_CIFS_HDR_SIZE) & 0xFFFFFF00);
+       pSMB->ParameterCount = pSMB->TotalParameterCount;
+       pSMB->DataCount  = pSMB->TotalDataCount;
+       temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
+                       (setup_count * 2) - 4 /* for rfc1001 length itself */;
+       pSMB->ParameterOffset = cpu_to_le32(temp_offset);
+       pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
+       pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
+       pSMB->SubCommand = cpu_to_le16(sub_command);
+       return 0;
+}
+
+static int
+validate_ntransact(char *buf, char **ppparm, char **ppdata,
+                  __u32 *pparmlen, __u32 *pdatalen)
+{
+       char *end_of_smb;
+       __u32 data_count, data_offset, parm_count, parm_offset;
+       struct smb_com_ntransact_rsp *pSMBr;
+
+       *pdatalen = 0;
+       *pparmlen = 0;
+
+       if (buf == NULL)
+               return -EINVAL;
+
+       pSMBr = (struct smb_com_ntransact_rsp *)buf;
+
+       /* ByteCount was converted from little endian in SendReceive */
+       end_of_smb = 2 /* sizeof byte count */ + pSMBr->ByteCount +
+                       (char *)&pSMBr->ByteCount;
+
+       data_offset = le32_to_cpu(pSMBr->DataOffset);
+       data_count = le32_to_cpu(pSMBr->DataCount);
+       parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
+       parm_count = le32_to_cpu(pSMBr->ParameterCount);
+
+       *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
+       *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
+
+       /* should we also check that parm and data areas do not overlap? */
+       if (*ppparm > end_of_smb) {
+               cFYI(1, "parms start after end of smb");
+               return -EINVAL;
+       } else if (parm_count + *ppparm > end_of_smb) {
+               cFYI(1, "parm end after end of smb");
+               return -EINVAL;
+       } else if (*ppdata > end_of_smb) {
+               cFYI(1, "data starts after end of smb");
+               return -EINVAL;
+       } else if (data_count + *ppdata > end_of_smb) {
+               cFYI(1, "data %p + count %d (%p) past smb end %p start %p",
+                       *ppdata, data_count, (data_count + *ppdata),
+                       end_of_smb, pSMBr);
+               return -EINVAL;
+       } else if (parm_count + data_count > pSMBr->ByteCount) {
+               cFYI(1, "parm count and data count larger than SMB");
+               return -EINVAL;
+       }
+       *pdatalen = data_count;
+       *pparmlen = parm_count;
+       return 0;
+}
+
 /* Get Security Descriptor (by handle) from remote server for a file or dir */
 int
 CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
@@ -3214,7 +3215,7 @@ setCifsAclRetry:
        return (rc);
 }
 
-#endif /* CONFIG_CIFS_EXPERIMENTAL */
+#endif /* CONFIG_CIFS_ACL */
 
 /* Legacy Query Path Information call for lookup to old servers such
    as Win9x/WinME */
index 251a17c..cc1a860 100644 (file)
@@ -105,6 +105,7 @@ struct smb_vol {
        unsigned int wsize;
        bool sockopt_tcp_nodelay:1;
        unsigned short int port;
+       unsigned long actimeo; /* attribute cache timeout (jiffies) */
        char *prepath;
        struct sockaddr_storage srcaddr; /* allow binding to a local IP */
        struct nls_table *local_nls;
@@ -806,23 +807,20 @@ cifs_parse_mount_options(char *options, const char *devname,
        short int override_gid = -1;
        bool uid_specified = false;
        bool gid_specified = false;
+       char *nodename = utsname()->nodename;
 
        separator[0] = ',';
        separator[1] = 0;
 
-       if (Local_System_Name[0] != 0)
-               memcpy(vol->source_rfc1001_name, Local_System_Name, 15);
-       else {
-               char *nodename = utsname()->nodename;
-               int n = strnlen(nodename, 15);
-               memset(vol->source_rfc1001_name, 0x20, 15);
-               for (i = 0; i < n; i++) {
-                       /* does not have to be perfect mapping since field is
-                       informational, only used for servers that do not support
-                       port 445 and it can be overridden at mount time */
-                       vol->source_rfc1001_name[i] = toupper(nodename[i]);
-               }
-       }
+       /*
+        * does not have to be perfect mapping since field is
+        * informational, only used for servers that do not support
+        * port 445 and it can be overridden at mount time
+        */
+       memset(vol->source_rfc1001_name, 0x20, 15);
+       for (i = 0; i < strnlen(nodename, 15); i++)
+               vol->source_rfc1001_name[i] = toupper(nodename[i]);
+
        vol->source_rfc1001_name[15] = 0;
        /* null target name indicates to use *SMBSERVR default called name
           if we end up sending RFC1001 session initialize */
@@ -840,6 +838,8 @@ cifs_parse_mount_options(char *options, const char *devname,
        /* default to using server inode numbers where available */
        vol->server_ino = 1;
 
+       vol->actimeo = CIFS_DEF_ACTIMEO;
+
        if (!options)
                return 1;
 
@@ -1214,6 +1214,16 @@ cifs_parse_mount_options(char *options, const char *devname,
                                        printk(KERN_WARNING "CIFS: server net"
                                        "biosname longer than 15 truncated.\n");
                        }
+               } else if (strnicmp(data, "actimeo", 7) == 0) {
+                       if (value && *value) {
+                               vol->actimeo = HZ * simple_strtoul(value,
+                                                                  &value, 0);
+                               if (vol->actimeo > CIFS_MAX_ACTIMEO) {
+                                       cERROR(1, "CIFS: attribute cache"
+                                                       "timeout too large");
+                                       return 1;
+                               }
+                       }
                } else if (strnicmp(data, "credentials", 4) == 0) {
                        /* ignore */
                } else if (strnicmp(data, "version", 3) == 0) {
@@ -1352,6 +1362,11 @@ cifs_parse_mount_options(char *options, const char *devname,
                                "supported. Instead set "
                                "/proc/fs/cifs/LookupCacheEnabled to 0\n");
                } else if (strnicmp(data, "fsc", 3) == 0) {
+#ifndef CONFIG_CIFS_FSCACHE
+                       cERROR(1, "FS-Cache support needs CONFIG_CIFS_FSCACHE"
+                                 "kernel config option set");
+                       return 1;
+#endif
                        vol->fsc = true;
                } else if (strnicmp(data, "mfsymlinks", 10) == 0) {
                        vol->mfsymlinks = true;
@@ -2566,6 +2581,8 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
        cFYI(1, "file mode: 0x%x  dir mode: 0x%x",
                cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode);
 
+       cifs_sb->actimeo = pvolume_info->actimeo;
+
        if (pvolume_info->noperm)
                cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
        if (pvolume_info->setuids)
@@ -2816,13 +2833,13 @@ remote_path_check:
        /* check if a whole path (including prepath) is not remote */
        if (!rc && cifs_sb->prepathlen && tcon) {
                /* build_path_to_root works only when we have a valid tcon */
-               full_path = cifs_build_path_to_root(cifs_sb);
+               full_path = cifs_build_path_to_root(cifs_sb, tcon);
                if (full_path == NULL) {
                        rc = -ENOMEM;
                        goto mount_fail_check;
                }
                rc = is_path_accessible(xid, tcon, cifs_sb, full_path);
-               if (rc != -EREMOTE) {
+               if (rc != 0 && rc != -EREMOTE) {
                        kfree(full_path);
                        goto mount_fail_check;
                }
index 0eb8702..548f062 100644 (file)
@@ -66,7 +66,7 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr)
        /* Search for server name delimiter */
        sep = memchr(hostname, '\\', len);
        if (sep)
-               len = sep - unc;
+               len = sep - hostname;
        else
                cFYI(1, "%s: probably server name is whole unc: %s",
                     __func__, unc);
index 06c3e83..5a28660 100644 (file)
@@ -1108,7 +1108,6 @@ static ssize_t cifs_write(struct cifsFileInfo *open_file,
        return total_written;
 }
 
-#ifdef CONFIG_CIFS_EXPERIMENTAL
 struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode,
                                        bool fsuid_only)
 {
@@ -1142,7 +1141,6 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode,
        spin_unlock(&cifs_file_list_lock);
        return NULL;
 }
-#endif
 
 struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode,
                                        bool fsuid_only)
@@ -2271,8 +2269,10 @@ void cifs_oplock_break_get(struct cifsFileInfo *cfile)
 
 void cifs_oplock_break_put(struct cifsFileInfo *cfile)
 {
+       struct super_block *sb = cfile->dentry->d_sb;
+
        cifsFileInfo_put(cfile);
-       cifs_sb_deactive(cfile->dentry->d_sb);
+       cifs_sb_deactive(sb);
 }
 
 const struct address_space_operations cifs_addr_ops = {
index a2ad94e..297a43d 100644 (file)
@@ -2,7 +2,7 @@
  *   fs/cifs/fscache.c - CIFS filesystem cache interface
  *
  *   Copyright (c) 2010 Novell, Inc.
- *   Author(s): Suresh Jayaraman (sjayaraman@suse.de>
+ *   Author(s): Suresh Jayaraman <sjayaraman@suse.de>
  *
  *   This library is free software; you can redistribute it and/or modify
  *   it under the terms of the GNU Lesser General Public License as published
@@ -67,10 +67,12 @@ static void cifs_fscache_enable_inode_cookie(struct inode *inode)
        if (cifsi->fscache)
                return;
 
-       cifsi->fscache = fscache_acquire_cookie(tcon->fscache,
+       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_FSCACHE) {
+               cifsi->fscache = fscache_acquire_cookie(tcon->fscache,
                                &cifs_fscache_inode_object_def, cifsi);
-       cFYI(1, "CIFS: got FH cookie (0x%p/0x%p)", tcon->fscache,
+               cFYI(1, "CIFS: got FH cookie (0x%p/0x%p)", tcon->fscache,
                                cifsi->fscache);
+       }
 }
 
 void cifs_fscache_release_inode_cookie(struct inode *inode)
@@ -101,10 +103,8 @@ void cifs_fscache_set_inode_cookie(struct inode *inode, struct file *filp)
 {
        if ((filp->f_flags & O_ACCMODE) != O_RDONLY)
                cifs_fscache_disable_inode_cookie(inode);
-       else {
+       else
                cifs_fscache_enable_inode_cookie(inode);
-               cFYI(1, "CIFS: fscache inode cookie set");
-       }
 }
 
 void cifs_fscache_reset_inode_cookie(struct inode *inode)
index ef3a55b..589f3e3 100644 (file)
@@ -686,13 +686,18 @@ int cifs_get_inode_info(struct inode **pinode,
                        cFYI(1, "cifs_sfu_type failed: %d", tmprc);
        }
 
-#ifdef CONFIG_CIFS_EXPERIMENTAL
+#ifdef CONFIG_CIFS_ACL
        /* fill in 0777 bits from ACL */
        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
-               cFYI(1, "Getting mode bits from ACL");
-               cifs_acl_to_fattr(cifs_sb, &fattr, *pinode, full_path, pfid);
+               rc = cifs_acl_to_fattr(cifs_sb, &fattr, *pinode, full_path,
+                                               pfid);
+               if (rc) {
+                       cFYI(1, "%s: Getting ACL failed with error: %d",
+                               __func__, rc);
+                       goto cgii_exit;
+               }
        }
-#endif
+#endif /* CONFIG_CIFS_ACL */
 
        /* fill in remaining high mode bits e.g. SUID, VTX */
        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)
@@ -723,12 +728,12 @@ static const struct inode_operations cifs_ipc_inode_ops = {
        .lookup = cifs_lookup,
 };
 
-char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb)
+char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb,
+                               struct cifsTconInfo *tcon)
 {
        int pplen = cifs_sb->prepathlen;
        int dfsplen;
        char *full_path = NULL;
-       struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
 
        /* if no prefix path, simply set path to the root of share to "" */
        if (pplen == 0) {
@@ -870,7 +875,7 @@ struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino)
        char *full_path;
        struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
 
-       full_path = cifs_build_path_to_root(cifs_sb);
+       full_path = cifs_build_path_to_root(cifs_sb, tcon);
        if (full_path == NULL)
                return ERR_PTR(-ENOMEM);
 
@@ -881,8 +886,10 @@ struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino)
                rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
                                                xid, NULL);
 
-       if (!inode)
-               return ERR_PTR(rc);
+       if (!inode) {
+               inode = ERR_PTR(rc);
+               goto out;
+       }
 
 #ifdef CONFIG_CIFS_FSCACHE
        /* populate tcon->resource_id */
@@ -898,13 +905,11 @@ struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino)
                inode->i_uid = cifs_sb->mnt_uid;
                inode->i_gid = cifs_sb->mnt_gid;
        } else if (rc) {
-               kfree(full_path);
-               _FreeXid(xid);
                iget_failed(inode);
-               return ERR_PTR(rc);
+               inode = ERR_PTR(rc);
        }
 
-
+out:
        kfree(full_path);
        /* can not call macro FreeXid here since in a void func
         * TODO: This is no longer true
@@ -1648,6 +1653,7 @@ static bool
 cifs_inode_needs_reval(struct inode *inode)
 {
        struct cifsInodeInfo *cifs_i = CIFS_I(inode);
+       struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
 
        if (cifs_i->clientCanCacheRead)
                return false;
@@ -1658,19 +1664,21 @@ cifs_inode_needs_reval(struct inode *inode)
        if (cifs_i->time == 0)
                return true;
 
-       /* FIXME: the actimeo should be tunable */
-       if (time_after_eq(jiffies, cifs_i->time + HZ))
+       if (!time_in_range(jiffies, cifs_i->time,
+                               cifs_i->time + cifs_sb->actimeo))
                return true;
 
        /* hardlinked files w/ noserverino get "special" treatment */
-       if (!(CIFS_SB(inode->i_sb)->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) &&
+       if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) &&
            S_ISREG(inode->i_mode) && inode->i_nlink != 1)
                return true;
 
        return false;
 }
 
-/* check invalid_mapping flag and zap the cache if it's set */
+/*
+ * Zap the cache. Called when invalid_mapping flag is set.
+ */
 static void
 cifs_invalidate_mapping(struct inode *inode)
 {
@@ -2114,11 +2122,16 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
 
        if (attrs->ia_valid & ATTR_MODE) {
                rc = 0;
-#ifdef CONFIG_CIFS_EXPERIMENTAL
-               if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL)
-                       rc = mode_to_acl(inode, full_path, mode);
-               else
-#endif
+#ifdef CONFIG_CIFS_ACL
+               if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
+                       rc = mode_to_cifs_acl(inode, full_path, mode);
+                       if (rc) {
+                               cFYI(1, "%s: Setting ACL failed with error: %d",
+                                       __func__, rc);
+                               goto cifs_setattr_exit;
+                       }
+               } else
+#endif /* CONFIG_CIFS_ACL */
                if (((mode & S_IWUGO) == 0) &&
                    (cifsInode->cifsAttrs & ATTR_READONLY) == 0) {
 
index ef7bb7b..a73eb9f 100644 (file)
@@ -226,26 +226,29 @@ static int initiate_cifs_search(const int xid, struct file *file)
        char *full_path = NULL;
        struct cifsFileInfo *cifsFile;
        struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
-       struct tcon_link *tlink;
+       struct tcon_link *tlink = NULL;
        struct cifsTconInfo *pTcon;
 
-       tlink = cifs_sb_tlink(cifs_sb);
-       if (IS_ERR(tlink))
-               return PTR_ERR(tlink);
-       pTcon = tlink_tcon(tlink);
-
-       if (file->private_data == NULL)
-               file->private_data =
-                       kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL);
        if (file->private_data == NULL) {
-               rc = -ENOMEM;
-               goto error_exit;
+               tlink = cifs_sb_tlink(cifs_sb);
+               if (IS_ERR(tlink))
+                       return PTR_ERR(tlink);
+
+               cifsFile = kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL);
+               if (cifsFile == NULL) {
+                       rc = -ENOMEM;
+                       goto error_exit;
+               }
+               file->private_data = cifsFile;
+               cifsFile->tlink = cifs_get_tlink(tlink);
+               pTcon = tlink_tcon(tlink);
+       } else {
+               cifsFile = file->private_data;
+               pTcon = tlink_tcon(cifsFile->tlink);
        }
 
-       cifsFile = file->private_data;
        cifsFile->invalidHandle = true;
        cifsFile->srch_inf.endOfSearch = false;
-       cifsFile->tlink = cifs_get_tlink(tlink);
 
        full_path = build_path_from_dentry(file->f_path.dentry);
        if (full_path == NULL) {
@@ -756,18 +759,6 @@ static int cifs_filldir(char *pfindEntry, struct file *file, filldir_t filldir,
        rc = filldir(direntry, qstring.name, qstring.len, file->f_pos,
                     ino, fattr.cf_dtype);
 
-       /*
-        * we can not return filldir errors to the caller since they are
-        * "normal" when the stat blocksize is too small - we return remapped
-        * error instead
-        *
-        * FIXME: This looks bogus. filldir returns -EOVERFLOW in the above
-        * case already. Why should we be clobbering other errors from it?
-        */
-       if (rc) {
-               cFYI(1, "filldir rc = %d", rc);
-               rc = -EOVERFLOW;
-       }
        dput(tmp_dentry);
        return rc;
 }
index a264b74..eae2a14 100644 (file)
 
 #define MAX_EA_VALUE_SIZE 65535
 #define CIFS_XATTR_DOS_ATTRIB "user.DosAttrib"
+#define CIFS_XATTR_CIFS_ACL "system.cifs_acl"
 #define CIFS_XATTR_USER_PREFIX "user."
 #define CIFS_XATTR_SYSTEM_PREFIX "system."
 #define CIFS_XATTR_OS2_PREFIX "os2."
-#define CIFS_XATTR_SECURITY_PREFIX ".security"
+#define CIFS_XATTR_SECURITY_PREFIX "security."
 #define CIFS_XATTR_TRUSTED_PREFIX "trusted."
 #define XATTR_TRUSTED_PREFIX_LEN  8
 #define XATTR_SECURITY_PREFIX_LEN 9
@@ -277,29 +278,8 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
                                cifs_sb->local_nls,
                                cifs_sb->mnt_cifs_flags &
                                        CIFS_MOUNT_MAP_SPECIAL_CHR);
-#ifdef CONFIG_CIFS_EXPERIMENTAL
-               else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
-                       __u16 fid;
-                       int oplock = 0;
-                       struct cifs_ntsd *pacl = NULL;
-                       __u32 buflen = 0;
-                       if (experimEnabled)
-                               rc = CIFSSMBOpen(xid, pTcon, full_path,
-                                       FILE_OPEN, GENERIC_READ, 0, &fid,
-                                       &oplock, NULL, cifs_sb->local_nls,
-                                       cifs_sb->mnt_cifs_flags &
-                                       CIFS_MOUNT_MAP_SPECIAL_CHR);
-                       /* else rc is EOPNOTSUPP from above */
-
-                       if (rc == 0) {
-                               rc = CIFSSMBGetCIFSACL(xid, pTcon, fid, &pacl,
-                                                     &buflen);
-                               CIFSSMBClose(xid, pTcon, fid);
-                       }
-               }
-#endif /* EXPERIMENTAL */
 #else
-               cFYI(1, "query POSIX ACL not supported yet");
+               cFYI(1, "Query POSIX ACL not supported yet");
 #endif /* CONFIG_CIFS_POSIX */
        } else if (strncmp(ea_name, POSIX_ACL_XATTR_DEFAULT,
                          strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) {
@@ -311,8 +291,33 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
                                cifs_sb->mnt_cifs_flags &
                                        CIFS_MOUNT_MAP_SPECIAL_CHR);
 #else
-               cFYI(1, "query POSIX default ACL not supported yet");
-#endif
+               cFYI(1, "Query POSIX default ACL not supported yet");
+#endif /* CONFIG_CIFS_POSIX */
+       } else if (strncmp(ea_name, CIFS_XATTR_CIFS_ACL,
+                               strlen(CIFS_XATTR_CIFS_ACL)) == 0) {
+#ifdef CONFIG_CIFS_ACL
+                       u32 acllen;
+                       struct cifs_ntsd *pacl;
+
+                       pacl = get_cifs_acl(cifs_sb, direntry->d_inode,
+                                               full_path, &acllen);
+                       if (IS_ERR(pacl)) {
+                               rc = PTR_ERR(pacl);
+                               cERROR(1, "%s: error %zd getting sec desc",
+                                               __func__, rc);
+                       } else {
+                               if (ea_value) {
+                                       if (acllen > buf_size)
+                                               acllen = -ERANGE;
+                                       else
+                                               memcpy(ea_value, pacl, acllen);
+                               }
+                               rc = acllen;
+                               kfree(pacl);
+                       }
+#else
+               cFYI(1, "Query CIFS ACL not supported yet");
+#endif /* CONFIG_CIFS_ACL */
        } else if (strncmp(ea_name,
                  CIFS_XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) == 0) {
                cFYI(1, "Trusted xattr namespace not supported yet");
index c580c32..eb1740a 100644 (file)
@@ -1350,6 +1350,10 @@ static int compat_count(compat_uptr_t __user *argv, int max)
                        argv++;
                        if (i++ >= max)
                                return -E2BIG;
+
+                       if (fatal_signal_pending(current))
+                               return -ERESTARTNOHAND;
+                       cond_resched();
                }
        }
        return i;
@@ -1391,6 +1395,12 @@ static int compat_copy_strings(int argc, compat_uptr_t __user *argv,
                while (len > 0) {
                        int offset, bytes_to_copy;
 
+                       if (fatal_signal_pending(current)) {
+                               ret = -ERESTARTNOHAND;
+                               goto out;
+                       }
+                       cond_resched();
+
                        offset = pos % PAGE_SIZE;
                        if (offset == 0)
                                offset = PAGE_SIZE;
@@ -1407,18 +1417,8 @@ static int compat_copy_strings(int argc, compat_uptr_t __user *argv,
                        if (!kmapped_page || kpos != (pos & PAGE_MASK)) {
                                struct page *page;
 
-#ifdef CONFIG_STACK_GROWSUP
-                               ret = expand_stack_downwards(bprm->vma, pos);
-                               if (ret < 0) {
-                                       /* We've exceed the stack rlimit. */
-                                       ret = -E2BIG;
-                                       goto out;
-                               }
-#endif
-                               ret = get_user_pages(current, bprm->mm, pos,
-                                                    1, 1, 1, &page, NULL);
-                               if (ret <= 0) {
-                                       /* We've exceed the stack rlimit. */
+                               page = get_arg_page(bprm, pos, 1);
+                               if (!page) {
                                        ret = -E2BIG;
                                        goto out;
                                }
@@ -1539,8 +1539,10 @@ int compat_do_execve(char * filename,
        return retval;
 
 out:
-       if (bprm->mm)
+       if (bprm->mm) {
+               acct_arg_size(bprm, 0);
                mmput(bprm->mm);
+       }
 
 out_file:
        if (bprm->file) {
index 99d33a1..c62efcb 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -164,7 +164,26 @@ out:
 
 #ifdef CONFIG_MMU
 
-static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
+void acct_arg_size(struct linux_binprm *bprm, unsigned long pages)
+{
+       struct mm_struct *mm = current->mm;
+       long diff = (long)(pages - bprm->vma_pages);
+
+       if (!mm || !diff)
+               return;
+
+       bprm->vma_pages = pages;
+
+#ifdef SPLIT_RSS_COUNTING
+       add_mm_counter(mm, MM_ANONPAGES, diff);
+#else
+       spin_lock(&mm->page_table_lock);
+       add_mm_counter(mm, MM_ANONPAGES, diff);
+       spin_unlock(&mm->page_table_lock);
+#endif
+}
+
+struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
                int write)
 {
        struct page *page;
@@ -186,6 +205,8 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
                unsigned long size = bprm->vma->vm_end - bprm->vma->vm_start;
                struct rlimit *rlim;
 
+               acct_arg_size(bprm, size / PAGE_SIZE);
+
                /*
                 * We've historically supported up to 32 pages (ARG_MAX)
                 * of argument strings even with small stacks
@@ -254,6 +275,11 @@ static int __bprm_mm_init(struct linux_binprm *bprm)
        vma->vm_flags = VM_STACK_FLAGS | VM_STACK_INCOMPLETE_SETUP;
        vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
        INIT_LIST_HEAD(&vma->anon_vma_chain);
+
+       err = security_file_mmap(NULL, 0, 0, 0, vma->vm_start, 1);
+       if (err)
+               goto err;
+
        err = insert_vm_struct(mm, vma);
        if (err)
                goto err;
@@ -276,7 +302,11 @@ static bool valid_arg_len(struct linux_binprm *bprm, long len)
 
 #else
 
-static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
+void acct_arg_size(struct linux_binprm *bprm, unsigned long pages)
+{
+}
+
+struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
                int write)
 {
        struct page *page;
@@ -1003,6 +1033,7 @@ int flush_old_exec(struct linux_binprm * bprm)
        /*
         * Release all of the old mmap stuff
         */
+       acct_arg_size(bprm, 0);
        retval = exec_mmap(bprm->mm);
        if (retval)
                goto out;
@@ -1426,8 +1457,10 @@ int do_execve(const char * filename,
        return retval;
 
 out:
-       if (bprm->mm)
-               mmput (bprm->mm);
+       if (bprm->mm) {
+               acct_arg_size(bprm, 0);
+               mmput(bprm->mm);
+       }
 
 out_file:
        if (bprm->file) {
index 6a5edea..94ce3d7 100644 (file)
@@ -910,6 +910,7 @@ struct ext4_inode_info {
 #define EXT4_MOUNT_JOURNAL_CHECKSUM    0x800000 /* Journal checksums */
 #define EXT4_MOUNT_JOURNAL_ASYNC_COMMIT        0x1000000 /* Journal Async Commit */
 #define EXT4_MOUNT_I_VERSION            0x2000000 /* i_version support */
+#define EXT4_MOUNT_MBLK_IO_SUBMIT      0x4000000 /* multi-block io submits */
 #define EXT4_MOUNT_DELALLOC            0x8000000 /* Delalloc support */
 #define EXT4_MOUNT_DATA_ERR_ABORT      0x10000000 /* Abort on file data write */
 #define EXT4_MOUNT_BLOCK_VALIDITY      0x20000000 /* Block validity checking */
index bdbe699..e659597 100644 (file)
@@ -2125,9 +2125,12 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd,
                         */
                        if (unlikely(journal_data && PageChecked(page)))
                                err = __ext4_journalled_writepage(page, len);
-                       else
+                       else if (test_opt(inode->i_sb, MBLK_IO_SUBMIT))
                                err = ext4_bio_write_page(&io_submit, page,
                                                          len, mpd->wbc);
+                       else
+                               err = block_write_full_page(page,
+                                       noalloc_get_block_write, mpd->wbc);
 
                        if (!err)
                                mpd->pages_written++;
index 92203b8..dc40e75 100644 (file)
@@ -872,7 +872,7 @@ static struct buffer_head * ext4_find_entry (struct inode *dir,
        if (namelen > EXT4_NAME_LEN)
                return NULL;
        if ((namelen <= 2) && (name[0] == '.') &&
-           (name[1] == '.' || name[1] == '0')) {
+           (name[1] == '.' || name[1] == '\0')) {
                /*
                 * "." or ".." will only be in the first block
                 * NFS may look up ".."; "." should be handled by the VFS
index e32195d..fb15c9c 100644 (file)
@@ -1026,6 +1026,8 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs)
            !(def_mount_opts & EXT4_DEFM_NODELALLOC))
                seq_puts(seq, ",nodelalloc");
 
+       if (test_opt(sb, MBLK_IO_SUBMIT))
+               seq_puts(seq, ",mblk_io_submit");
        if (sbi->s_stripe)
                seq_printf(seq, ",stripe=%lu", sbi->s_stripe);
        /*
@@ -1239,8 +1241,8 @@ enum {
        Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_jqfmt_vfsv1, Opt_quota,
        Opt_noquota, Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err,
        Opt_resize, Opt_usrquota, Opt_grpquota, Opt_i_version,
-       Opt_stripe, Opt_delalloc, Opt_nodelalloc,
-       Opt_block_validity, Opt_noblock_validity,
+       Opt_stripe, Opt_delalloc, Opt_nodelalloc, Opt_mblk_io_submit,
+       Opt_nomblk_io_submit, Opt_block_validity, Opt_noblock_validity,
        Opt_inode_readahead_blks, Opt_journal_ioprio,
        Opt_dioread_nolock, Opt_dioread_lock,
        Opt_discard, Opt_nodiscard,
@@ -1304,6 +1306,8 @@ static const match_table_t tokens = {
        {Opt_resize, "resize"},
        {Opt_delalloc, "delalloc"},
        {Opt_nodelalloc, "nodelalloc"},
+       {Opt_mblk_io_submit, "mblk_io_submit"},
+       {Opt_nomblk_io_submit, "nomblk_io_submit"},
        {Opt_block_validity, "block_validity"},
        {Opt_noblock_validity, "noblock_validity"},
        {Opt_inode_readahead_blks, "inode_readahead_blks=%u"},
@@ -1725,6 +1729,12 @@ set_qf_format:
                case Opt_nodelalloc:
                        clear_opt(sbi->s_mount_opt, DELALLOC);
                        break;
+               case Opt_mblk_io_submit:
+                       set_opt(sbi->s_mount_opt, MBLK_IO_SUBMIT);
+                       break;
+               case Opt_nomblk_io_submit:
+                       clear_opt(sbi->s_mount_opt, MBLK_IO_SUBMIT);
+                       break;
                case Opt_stripe:
                        if (match_int(&args[0], &option))
                                return 0;
index 9242d29..8b984a2 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/module.h>
+#include <linux/compat.h>
 
 static const struct file_operations fuse_direct_io_file_operations;
 
@@ -1627,6 +1628,58 @@ static int fuse_ioctl_copy_user(struct page **pages, struct iovec *iov,
        return 0;
 }
 
+/*
+ * CUSE servers compiled on 32bit broke on 64bit kernels because the
+ * ABI was defined to be 'struct iovec' which is different on 32bit
+ * and 64bit.  Fortunately we can determine which structure the server
+ * used from the size of the reply.
+ */
+static int fuse_copy_ioctl_iovec(struct iovec *dst, void *src,
+                                size_t transferred, unsigned count,
+                                bool is_compat)
+{
+#ifdef CONFIG_COMPAT
+       if (count * sizeof(struct compat_iovec) == transferred) {
+               struct compat_iovec *ciov = src;
+               unsigned i;
+
+               /*
+                * With this interface a 32bit server cannot support
+                * non-compat (i.e. ones coming from 64bit apps) ioctl
+                * requests
+                */
+               if (!is_compat)
+                       return -EINVAL;
+
+               for (i = 0; i < count; i++) {
+                       dst[i].iov_base = compat_ptr(ciov[i].iov_base);
+                       dst[i].iov_len = ciov[i].iov_len;
+               }
+               return 0;
+       }
+#endif
+
+       if (count * sizeof(struct iovec) != transferred)
+               return -EIO;
+
+       memcpy(dst, src, transferred);
+       return 0;
+}
+
+/* Make sure iov_length() won't overflow */
+static int fuse_verify_ioctl_iov(struct iovec *iov, size_t count)
+{
+       size_t n;
+       u32 max = FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT;
+
+       for (n = 0; n < count; n++) {
+               if (iov->iov_len > (size_t) max)
+                       return -ENOMEM;
+               max -= iov->iov_len;
+       }
+       return 0;
+}
+
 /*
  * For ioctls, there is no generic way to determine how much memory
  * needs to be read and/or written.  Furthermore, ioctls are allowed
@@ -1808,18 +1861,25 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
                    in_iovs + out_iovs > FUSE_IOCTL_MAX_IOV)
                        goto out;
 
-               err = -EIO;
-               if ((in_iovs + out_iovs) * sizeof(struct iovec) != transferred)
-                       goto out;
-
-               /* okay, copy in iovs and retry */
                vaddr = kmap_atomic(pages[0], KM_USER0);
-               memcpy(page_address(iov_page), vaddr, transferred);
+               err = fuse_copy_ioctl_iovec(page_address(iov_page), vaddr,
+                                           transferred, in_iovs + out_iovs,
+                                           (flags & FUSE_IOCTL_COMPAT) != 0);
                kunmap_atomic(vaddr, KM_USER0);
+               if (err)
+                       goto out;
 
                in_iov = page_address(iov_page);
                out_iov = in_iov + in_iovs;
 
+               err = fuse_verify_ioctl_iov(in_iov, in_iovs);
+               if (err)
+                       goto out;
+
+               err = fuse_verify_ioctl_iov(out_iov, out_iovs);
+               if (err)
+                       goto out;
+
                goto retry;
        }
 
index 58a9b99..f606baf 100644 (file)
@@ -631,6 +631,7 @@ static int gfs2_adjust_quota(struct gfs2_inode *ip, loff_t loc,
                             struct fs_disk_quota *fdq)
 {
        struct inode *inode = &ip->i_inode;
+       struct gfs2_sbd *sdp = GFS2_SB(inode);
        struct address_space *mapping = inode->i_mapping;
        unsigned long index = loc >> PAGE_CACHE_SHIFT;
        unsigned offset = loc & (PAGE_CACHE_SIZE - 1);
@@ -658,11 +659,11 @@ static int gfs2_adjust_quota(struct gfs2_inode *ip, loff_t loc,
        qd->qd_qb.qb_value = qp->qu_value;
        if (fdq) {
                if (fdq->d_fieldmask & FS_DQ_BSOFT) {
-                       qp->qu_warn = cpu_to_be64(fdq->d_blk_softlimit);
+                       qp->qu_warn = cpu_to_be64(fdq->d_blk_softlimit >> sdp->sd_fsb2bb_shift);
                        qd->qd_qb.qb_warn = qp->qu_warn;
                }
                if (fdq->d_fieldmask & FS_DQ_BHARD) {
-                       qp->qu_limit = cpu_to_be64(fdq->d_blk_hardlimit);
+                       qp->qu_limit = cpu_to_be64(fdq->d_blk_hardlimit >> sdp->sd_fsb2bb_shift);
                        qd->qd_qb.qb_limit = qp->qu_limit;
                }
        }
@@ -1497,9 +1498,9 @@ static int gfs2_get_dqblk(struct super_block *sb, int type, qid_t id,
        fdq->d_version = FS_DQUOT_VERSION;
        fdq->d_flags = (type == QUOTA_USER) ? FS_USER_QUOTA : FS_GROUP_QUOTA;
        fdq->d_id = id;
-       fdq->d_blk_hardlimit = be64_to_cpu(qlvb->qb_limit);
-       fdq->d_blk_softlimit = be64_to_cpu(qlvb->qb_warn);
-       fdq->d_bcount = be64_to_cpu(qlvb->qb_value);
+       fdq->d_blk_hardlimit = be64_to_cpu(qlvb->qb_limit) << sdp->sd_fsb2bb_shift;
+       fdq->d_blk_softlimit = be64_to_cpu(qlvb->qb_warn) << sdp->sd_fsb2bb_shift;
+       fdq->d_bcount = be64_to_cpu(qlvb->qb_value) << sdp->sd_fsb2bb_shift;
 
        gfs2_glock_dq_uninit(&q_gh);
 out:
@@ -1566,10 +1567,10 @@ static int gfs2_set_dqblk(struct super_block *sb, int type, qid_t id,
 
        /* If nothing has changed, this is a no-op */
        if ((fdq->d_fieldmask & FS_DQ_BSOFT) &&
-           (fdq->d_blk_softlimit == be64_to_cpu(qd->qd_qb.qb_warn)))
+           ((fdq->d_blk_softlimit >> sdp->sd_fsb2bb_shift) == be64_to_cpu(qd->qd_qb.qb_warn)))
                fdq->d_fieldmask ^= FS_DQ_BSOFT;
        if ((fdq->d_fieldmask & FS_DQ_BHARD) &&
-           (fdq->d_blk_hardlimit == be64_to_cpu(qd->qd_qb.qb_limit)))
+           ((fdq->d_blk_hardlimit >> sdp->sd_fsb2bb_shift) == be64_to_cpu(qd->qd_qb.qb_limit)))
                fdq->d_fieldmask ^= FS_DQ_BHARD;
        if (fdq->d_fieldmask == 0)
                goto out_i;
index 5362af9..4ff7ca5 100644 (file)
@@ -1748,6 +1748,9 @@ struct file *do_filp_open(int dfd, const char *pathname,
        if (!(open_flag & O_CREAT))
                mode = 0;
 
+       /* Must never be set by userspace */
+       open_flag &= ~FMODE_NONOTIFY;
+
        /*
         * O_SYNC is implemented as __O_SYNC|O_DSYNC.  As many places only
         * check for O_DSYNC if the need any syncing at all we enforce it's
index 8ea4a41..996dd89 100644 (file)
@@ -57,7 +57,7 @@ static int nfs_rename(struct inode *, struct dentry *,
                      struct inode *, struct dentry *);
 static int nfs_fsync_dir(struct file *, int);
 static loff_t nfs_llseek_dir(struct file *, loff_t, int);
-static int nfs_readdir_clear_array(struct page*, gfp_t);
+static void nfs_readdir_clear_array(struct page*);
 
 const struct file_operations nfs_dir_operations = {
        .llseek         = nfs_llseek_dir,
@@ -83,8 +83,8 @@ const struct inode_operations nfs_dir_inode_operations = {
        .setattr        = nfs_setattr,
 };
 
-const struct address_space_operations nfs_dir_addr_space_ops = {
-       .releasepage = nfs_readdir_clear_array,
+const struct address_space_operations nfs_dir_aops = {
+       .freepage = nfs_readdir_clear_array,
 };
 
 #ifdef CONFIG_NFS_V3
@@ -178,6 +178,7 @@ typedef struct {
        struct page     *page;
        unsigned long   page_index;
        u64             *dir_cookie;
+       u64             last_cookie;
        loff_t          current_index;
        decode_dirent_t decode;
 
@@ -213,17 +214,15 @@ void nfs_readdir_release_array(struct page *page)
  * we are freeing strings created by nfs_add_to_readdir_array()
  */
 static
-int nfs_readdir_clear_array(struct page *page, gfp_t mask)
+void nfs_readdir_clear_array(struct page *page)
 {
-       struct nfs_cache_array *array = nfs_readdir_get_array(page);
+       struct nfs_cache_array *array;
        int i;
 
-       if (IS_ERR(array))
-               return PTR_ERR(array);
+       array = kmap_atomic(page, KM_USER0);
        for (i = 0; i < array->size; i++)
                kfree(array->array[i].string.name);
-       nfs_readdir_release_array(page);
-       return 0;
+       kunmap_atomic(array, KM_USER0);
 }
 
 /*
@@ -272,7 +271,7 @@ int nfs_readdir_add_to_array(struct nfs_entry *entry, struct page *page)
                goto out;
        array->last_cookie = entry->cookie;
        array->size++;
-       if (entry->eof == 1)
+       if (entry->eof != 0)
                array->eof_index = array->size;
 out:
        nfs_readdir_release_array(page);
@@ -312,15 +311,14 @@ int nfs_readdir_search_for_cookie(struct nfs_cache_array *array, nfs_readdir_des
        for (i = 0; i < array->size; i++) {
                if (array->array[i].cookie == *desc->dir_cookie) {
                        desc->cache_entry_index = i;
-                       status = 0;
-                       goto out;
+                       return 0;
                }
        }
-       if (i == array->eof_index) {
-               desc->eof = 1;
+       if (array->eof_index >= 0) {
                status = -EBADCOOKIE;
+               if (*desc->dir_cookie == array->last_cookie)
+                       desc->eof = 1;
        }
-out:
        return status;
 }
 
@@ -328,10 +326,7 @@ static
 int nfs_readdir_search_array(nfs_readdir_descriptor_t *desc)
 {
        struct nfs_cache_array *array;
-       int status = -EBADCOOKIE;
-
-       if (desc->dir_cookie == NULL)
-               goto out;
+       int status;
 
        array = nfs_readdir_get_array(desc->page);
        if (IS_ERR(array)) {
@@ -344,6 +339,10 @@ int nfs_readdir_search_array(nfs_readdir_descriptor_t *desc)
        else
                status = nfs_readdir_search_for_cookie(array, desc);
 
+       if (status == -EAGAIN) {
+               desc->last_cookie = array->last_cookie;
+               desc->page_index++;
+       }
        nfs_readdir_release_array(desc->page);
 out:
        return status;
@@ -395,13 +394,9 @@ int xdr_decode(nfs_readdir_descriptor_t *desc, struct nfs_entry *entry, struct x
 static
 int nfs_same_file(struct dentry *dentry, struct nfs_entry *entry)
 {
-       struct nfs_inode *node;
        if (dentry->d_inode == NULL)
                goto different;
-       node = NFS_I(dentry->d_inode);
-       if (node->fh.size != entry->fh->size)
-               goto different;
-       if (strncmp(node->fh.data, entry->fh->data, node->fh.size) != 0)
+       if (nfs_compare_fh(entry->fh, NFS_FH(dentry->d_inode)) != 0)
                goto different;
        return 1;
 different:
@@ -494,7 +489,7 @@ int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *en
 
                count++;
 
-               if (desc->plus == 1)
+               if (desc->plus != 0)
                        nfs_prime_dcache(desc->file->f_path.dentry, entry);
 
                status = nfs_readdir_add_to_array(entry, page);
@@ -502,7 +497,7 @@ int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *en
                        break;
        } while (!entry->eof);
 
-       if (count == 0 || (status == -EBADCOOKIE && entry->eof == 1)) {
+       if (count == 0 || (status == -EBADCOOKIE && entry->eof != 0)) {
                array = nfs_readdir_get_array(page);
                if (!IS_ERR(array)) {
                        array->eof_index = array->size;
@@ -567,7 +562,7 @@ int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page,
        unsigned int array_size = ARRAY_SIZE(pages);
 
        entry.prev_cookie = 0;
-       entry.cookie = *desc->dir_cookie;
+       entry.cookie = desc->last_cookie;
        entry.eof = 0;
        entry.fh = nfs_alloc_fhandle();
        entry.fattr = nfs_alloc_fattr();
@@ -640,6 +635,8 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page* page)
 static
 void cache_page_release(nfs_readdir_descriptor_t *desc)
 {
+       if (!desc->page->mapping)
+               nfs_readdir_clear_array(desc->page);
        page_cache_release(desc->page);
        desc->page = NULL;
 }
@@ -664,9 +661,8 @@ int find_cache_page(nfs_readdir_descriptor_t *desc)
                return PTR_ERR(desc->page);
 
        res = nfs_readdir_search_array(desc);
-       if (res == 0)
-               return 0;
-       cache_page_release(desc);
+       if (res != 0)
+               cache_page_release(desc);
        return res;
 }
 
@@ -676,22 +672,16 @@ int readdir_search_pagecache(nfs_readdir_descriptor_t *desc)
 {
        int res;
 
-       if (desc->page_index == 0)
+       if (desc->page_index == 0) {
                desc->current_index = 0;
-       while (1) {
-               res = find_cache_page(desc);
-               if (res != -EAGAIN)
-                       break;
-               desc->page_index++;
+               desc->last_cookie = 0;
        }
+       do {
+               res = find_cache_page(desc);
+       } while (res == -EAGAIN);
        return res;
 }
 
-static inline unsigned int dt_type(struct inode *inode)
-{
-       return (inode->i_mode >> 12) & 15;
-}
-
 /*
  * Once we've found the start of the dirent within a page: fill 'er up...
  */
@@ -721,13 +711,12 @@ int nfs_do_filldir(nfs_readdir_descriptor_t *desc, void *dirent,
                        break;
                }
                file->f_pos++;
-               desc->cache_entry_index = i;
                if (i < (array->size-1))
                        *desc->dir_cookie = array->array[i+1].cookie;
                else
                        *desc->dir_cookie = array->last_cookie;
        }
-       if (i == array->eof_index)
+       if (array->eof_index >= 0)
                desc->eof = 1;
 
        nfs_readdir_release_array(desc->page);
@@ -768,6 +757,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
        }
 
        desc->page_index = 0;
+       desc->last_cookie = *desc->dir_cookie;
        desc->page = page;
 
        status = nfs_readdir_xdr_to_array(desc, page, inode);
@@ -795,7 +785,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
        struct inode    *inode = dentry->d_inode;
        nfs_readdir_descriptor_t my_desc,
                        *desc = &my_desc;
-       int res = -ENOMEM;
+       int res;
 
        dfprintk(FILE, "NFS: readdir(%s/%s) starting at cookie %llu\n",
                        dentry->d_parent->d_name.name, dentry->d_name.name,
@@ -820,7 +810,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
        if (res < 0)
                goto out;
 
-       while (desc->eof != 1) {
+       do {
                res = readdir_search_pagecache(desc);
 
                if (res == -EBADCOOKIE) {
@@ -848,7 +838,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
                res = nfs_do_filldir(desc, dirent, filldir);
                if (res < 0)
                        break;
-       }
+       } while (!desc->eof);
 out:
        nfs_unblock_sillyrename(dentry);
        if (res > 0)
index 60677f9..7bf029e 100644 (file)
@@ -693,6 +693,7 @@ do_getlk(struct file *filp, int cmd, struct file_lock *fl, int is_local)
 {
        struct inode *inode = filp->f_mapping->host;
        int status = 0;
+       unsigned int saved_type = fl->fl_type;
 
        /* Try local locking first */
        posix_test_lock(filp, fl);
@@ -700,6 +701,7 @@ do_getlk(struct file *filp, int cmd, struct file_lock *fl, int is_local)
                /* found a conflict */
                goto out;
        }
+       fl->fl_type = saved_type;
 
        if (nfs_have_delegation(inode, FMODE_READ))
                goto out_noconflict;
index 314f571..e67e31c 100644 (file)
@@ -289,6 +289,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
                } else if (S_ISDIR(inode->i_mode)) {
                        inode->i_op = NFS_SB(sb)->nfs_client->rpc_ops->dir_inode_ops;
                        inode->i_fop = &nfs_dir_operations;
+                       inode->i_data.a_ops = &nfs_dir_aops;
                        if (nfs_server_capable(inode, NFS_CAP_READDIRPLUS))
                                set_bit(NFS_INO_ADVISE_RDPLUS, &NFS_I(inode)->flags);
                        /* Deal with crossing mountpoints */
index eceafe7..4f981f1 100644 (file)
@@ -505,13 +505,13 @@ static struct rpc_procinfo mnt3_procedures[] = {
 
 static struct rpc_version mnt_version1 = {
        .number         = 1,
-       .nrprocs        = 2,
+       .nrprocs        = ARRAY_SIZE(mnt_procedures),
        .procs          = mnt_procedures,
 };
 
 static struct rpc_version mnt_version3 = {
        .number         = 3,
-       .nrprocs        = 2,
+       .nrprocs        = ARRAY_SIZE(mnt3_procedures),
        .procs          = mnt3_procedures,
 };
 
index 6a653ff..4435e5e 100644 (file)
@@ -3361,6 +3361,8 @@ static ssize_t nfs4_proc_get_acl(struct inode *inode, void *buf, size_t buflen)
        ret = nfs_revalidate_inode(server, inode);
        if (ret < 0)
                return ret;
+       if (NFS_I(inode)->cache_validity & NFS_INO_INVALID_ACL)
+               nfs_zap_acl_cache(inode);
        ret = nfs4_read_cached_acl(inode, buf, buflen);
        if (ret != -ENOENT)
                return ret;
@@ -3389,6 +3391,13 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl
        nfs_inode_return_delegation(inode);
        buf_to_pages(buf, buflen, arg.acl_pages, &arg.acl_pgbase);
        ret = nfs4_call_sync(server, &msg, &arg, &res, 1);
+       /*
+        * Acl update can result in inode attribute update.
+        * so mark the attribute cache invalid.
+        */
+       spin_lock(&inode->i_lock);
+       NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATTR;
+       spin_unlock(&inode->i_lock);
        nfs_access_zap_cache(inode);
        nfs_zap_acl_cache(inode);
        return ret;
index 137b549..b68536c 100644 (file)
@@ -115,7 +115,7 @@ int nfs_set_page_tag_locked(struct nfs_page *req)
 {
        if (!nfs_lock_request_dontget(req))
                return 0;
-       if (req->wb_page != NULL)
+       if (test_bit(PG_MAPPED, &req->wb_flags))
                radix_tree_tag_set(&NFS_I(req->wb_context->path.dentry->d_inode)->nfs_page_tree, req->wb_index, NFS_PAGE_TAG_LOCKED);
        return 1;
 }
@@ -125,7 +125,7 @@ int nfs_set_page_tag_locked(struct nfs_page *req)
  */
 void nfs_clear_page_tag_locked(struct nfs_page *req)
 {
-       if (req->wb_page != NULL) {
+       if (test_bit(PG_MAPPED, &req->wb_flags)) {
                struct inode *inode = req->wb_context->path.dentry->d_inode;
                struct nfs_inode *nfsi = NFS_I(inode);
 
index e4b62c6..aedcaa7 100644 (file)
@@ -152,7 +152,6 @@ static void nfs_readpage_release(struct nfs_page *req)
                        (long long)NFS_FILEID(req->wb_context->path.dentry->d_inode),
                        req->wb_bytes,
                        (long long)req_offset(req));
-       nfs_clear_request(req);
        nfs_release_request(req);
 }
 
index 3c04504..4100630 100644 (file)
@@ -1069,12 +1069,10 @@ static int nfs_parse_mount_options(char *raw,
                        mnt->flags |= NFS_MOUNT_VER3;
                        mnt->version = 3;
                        break;
-#ifdef CONFIG_NFS_V4
                case Opt_v4:
                        mnt->flags &= ~NFS_MOUNT_VER3;
                        mnt->version = 4;
                        break;
-#endif
                case Opt_udp:
                        mnt->flags &= ~NFS_MOUNT_TCP;
                        mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP;
@@ -1286,12 +1284,10 @@ static int nfs_parse_mount_options(char *raw,
                                mnt->flags |= NFS_MOUNT_VER3;
                                mnt->version = 3;
                                break;
-#ifdef CONFIG_NFS_V4
                        case NFS4_VERSION:
                                mnt->flags &= ~NFS_MOUNT_VER3;
                                mnt->version = 4;
                                break;
-#endif
                        default:
                                goto out_invalid_value;
                        }
index 4c14c17..10d648e 100644 (file)
@@ -390,6 +390,7 @@ static int nfs_inode_add_request(struct inode *inode, struct nfs_page *req)
                if (nfs_have_delegation(inode, FMODE_WRITE))
                        nfsi->change_attr++;
        }
+       set_bit(PG_MAPPED, &req->wb_flags);
        SetPagePrivate(req->wb_page);
        set_page_private(req->wb_page, (unsigned long)req);
        nfsi->npages++;
@@ -415,6 +416,7 @@ static void nfs_inode_remove_request(struct nfs_page *req)
        spin_lock(&inode->i_lock);
        set_page_private(req->wb_page, 0);
        ClearPagePrivate(req->wb_page);
+       clear_bit(PG_MAPPED, &req->wb_flags);
        radix_tree_delete(&nfsi->nfs_page_tree, req->wb_index);
        nfsi->npages--;
        if (!nfsi->npages) {
@@ -422,7 +424,6 @@ static void nfs_inode_remove_request(struct nfs_page *req)
                iput(inode);
        } else
                spin_unlock(&inode->i_lock);
-       nfs_clear_request(req);
        nfs_release_request(req);
 }
 
index 2a533a0..7e84a85 100644 (file)
@@ -260,9 +260,11 @@ void fill_post_wcc(struct svc_fh *fhp)
        err = vfs_getattr(fhp->fh_export->ex_path.mnt, fhp->fh_dentry,
                        &fhp->fh_post_attr);
        fhp->fh_post_change = fhp->fh_dentry->d_inode->i_version;
-       if (err)
+       if (err) {
                fhp->fh_post_saved = 0;
-       else
+               /* Grab the ctime anyway - set_change_info might use it */
+               fhp->fh_post_attr.ctime = fhp->fh_dentry->d_inode->i_ctime;
+       } else
                fhp->fh_post_saved = 1;
 }
 
index 4d476ff..60fce3d 100644 (file)
@@ -484,18 +484,17 @@ static inline bool nfsd4_not_cached(struct nfsd4_compoundres *resp)
 static inline void
 set_change_info(struct nfsd4_change_info *cinfo, struct svc_fh *fhp)
 {
-       BUG_ON(!fhp->fh_pre_saved || !fhp->fh_post_saved);
-       cinfo->atomic = 1;
+       BUG_ON(!fhp->fh_pre_saved);
+       cinfo->atomic = fhp->fh_post_saved;
        cinfo->change_supported = IS_I_VERSION(fhp->fh_dentry->d_inode);
-       if (cinfo->change_supported) {
-               cinfo->before_change = fhp->fh_pre_change;
-               cinfo->after_change = fhp->fh_post_change;
-       } else {
-               cinfo->before_ctime_sec = fhp->fh_pre_ctime.tv_sec;
-               cinfo->before_ctime_nsec = fhp->fh_pre_ctime.tv_nsec;
-               cinfo->after_ctime_sec = fhp->fh_post_attr.ctime.tv_sec;
-               cinfo->after_ctime_nsec = fhp->fh_post_attr.ctime.tv_nsec;
-       }
+
+       cinfo->before_change = fhp->fh_pre_change;
+       cinfo->after_change = fhp->fh_post_change;
+       cinfo->before_ctime_sec = fhp->fh_pre_ctime.tv_sec;
+       cinfo->before_ctime_nsec = fhp->fh_pre_ctime.tv_nsec;
+       cinfo->after_ctime_sec = fhp->fh_post_attr.ctime.tv_sec;
+       cinfo->after_ctime_nsec = fhp->fh_post_attr.ctime.tv_nsec;
+
 }
 
 int nfs4svc_encode_voidres(struct svc_rqst *, __be32 *, void *);
index 33ad25d..caf9a6a 100644 (file)
@@ -176,7 +176,6 @@ int nilfs_gccache_wait_and_mark_dirty(struct buffer_head *bh)
 int nilfs_init_gcinode(struct inode *inode)
 {
        struct nilfs_inode_info *ii = NILFS_I(inode);
-       struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs;
 
        inode->i_mode = S_IFREG;
        mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS);
@@ -186,14 +185,6 @@ int nilfs_init_gcinode(struct inode *inode)
        ii->i_flags = 0;
        nilfs_bmap_init_gc(ii->i_bmap);
 
-       /*
-        * Add the inode to GC inode list. Garbage Collection
-        * is serialized and no two processes manipulate the
-        * list simultaneously.
-        */
-       igrab(inode);
-       list_add(&NILFS_I(inode)->i_dirty, &nilfs->ns_gc_inodes);
-
        return 0;
 }
 
index e00d945..b185e93 100644 (file)
@@ -337,6 +337,7 @@ static int nilfs_ioctl_move_blocks(struct super_block *sb,
                                   struct nilfs_argv *argv, void *buf)
 {
        size_t nmembs = argv->v_nmembs;
+       struct the_nilfs *nilfs = NILFS_SB(sb)->s_nilfs;
        struct inode *inode;
        struct nilfs_vdesc *vdesc;
        struct buffer_head *bh, *n;
@@ -353,6 +354,17 @@ static int nilfs_ioctl_move_blocks(struct super_block *sb,
                        ret = PTR_ERR(inode);
                        goto failed;
                }
+               if (list_empty(&NILFS_I(inode)->i_dirty)) {
+                       /*
+                        * Add the inode to GC inode list. Garbage Collection
+                        * is serialized and no two processes manipulate the
+                        * list simultaneously.
+                        */
+                       igrab(inode);
+                       list_add(&NILFS_I(inode)->i_dirty,
+                                &nilfs->ns_gc_inodes);
+               }
+
                do {
                        ret = nilfs_ioctl_move_inode_block(inode, vdesc,
                                                           &buffers);
index b04f88e..f35794b 100644 (file)
@@ -92,7 +92,11 @@ static int fanotify_get_response_from_access(struct fsnotify_group *group,
 
        pr_debug("%s: group=%p event=%p\n", __func__, group, event);
 
-       wait_event(group->fanotify_data.access_waitq, event->response);
+       wait_event(group->fanotify_data.access_waitq, event->response ||
+                               atomic_read(&group->fanotify_data.bypass_perm));
+
+       if (!event->response) /* bypass_perm set */
+               return 0;
 
        /* userspace responded, convert to something usable */
        spin_lock(&event->lock);
index 0632248..8b61220 100644 (file)
@@ -106,20 +106,29 @@ static int create_fd(struct fsnotify_group *group, struct fsnotify_event *event)
        return client_fd;
 }
 
-static ssize_t fill_event_metadata(struct fsnotify_group *group,
+static int fill_event_metadata(struct fsnotify_group *group,
                                   struct fanotify_event_metadata *metadata,
                                   struct fsnotify_event *event)
 {
+       int ret = 0;
+
        pr_debug("%s: group=%p metadata=%p event=%p\n", __func__,
                 group, metadata, event);
 
        metadata->event_len = FAN_EVENT_METADATA_LEN;
+       metadata->metadata_len = FAN_EVENT_METADATA_LEN;
        metadata->vers = FANOTIFY_METADATA_VERSION;
        metadata->mask = event->mask & FAN_ALL_OUTGOING_EVENTS;
        metadata->pid = pid_vnr(event->tgid);
-       metadata->fd = create_fd(group, event);
+       if (unlikely(event->mask & FAN_Q_OVERFLOW))
+               metadata->fd = FAN_NOFD;
+       else {
+               metadata->fd = create_fd(group, event);
+               if (metadata->fd < 0)
+                       ret = metadata->fd;
+       }
 
-       return metadata->fd;
+       return ret;
 }
 
 #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
@@ -200,7 +209,7 @@ static int prepare_for_access_response(struct fsnotify_group *group,
 
        mutex_lock(&group->fanotify_data.access_mutex);
 
-       if (group->fanotify_data.bypass_perm) {
+       if (atomic_read(&group->fanotify_data.bypass_perm)) {
                mutex_unlock(&group->fanotify_data.access_mutex);
                kmem_cache_free(fanotify_response_event_cache, re);
                event->response = FAN_ALLOW;
@@ -257,24 +266,34 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
 
        pr_debug("%s: group=%p event=%p\n", __func__, group, event);
 
-       fd = fill_event_metadata(group, &fanotify_event_metadata, event);
-       if (fd < 0)
-               return fd;
+       ret = fill_event_metadata(group, &fanotify_event_metadata, event);
+       if (ret < 0)
+               goto out;
 
+       fd = fanotify_event_metadata.fd;
        ret = prepare_for_access_response(group, event, fd);
        if (ret)
                goto out_close_fd;
 
        ret = -EFAULT;
-       if (copy_to_user(buf, &fanotify_event_metadata, FAN_EVENT_METADATA_LEN))
+       if (copy_to_user(buf, &fanotify_event_metadata,
+                        fanotify_event_metadata.event_len))
                goto out_kill_access_response;
 
-       return FAN_EVENT_METADATA_LEN;
+       return fanotify_event_metadata.event_len;
 
 out_kill_access_response:
        remove_access_response(group, event, fd);
 out_close_fd:
-       sys_close(fd);
+       if (fd != FAN_NOFD)
+               sys_close(fd);
+out:
+#ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
+       if (event->mask & FAN_ALL_PERM_EVENTS) {
+               event->response = FAN_DENY;
+               wake_up(&group->fanotify_data.access_waitq);
+       }
+#endif
        return ret;
 }
 
@@ -382,7 +401,7 @@ static int fanotify_release(struct inode *ignored, struct file *file)
 
        mutex_lock(&group->fanotify_data.access_mutex);
 
-       group->fanotify_data.bypass_perm = true;
+       atomic_inc(&group->fanotify_data.bypass_perm);
 
        list_for_each_entry_safe(re, lre, &group->fanotify_data.access_list, list) {
                pr_debug("%s: found group=%p re=%p event=%p\n", __func__, group,
@@ -586,11 +605,10 @@ static int fanotify_add_vfsmount_mark(struct fsnotify_group *group,
 {
        struct fsnotify_mark *fsn_mark;
        __u32 added;
+       int ret = 0;
 
        fsn_mark = fsnotify_find_vfsmount_mark(group, mnt);
        if (!fsn_mark) {
-               int ret;
-
                if (atomic_read(&group->num_marks) > group->fanotify_data.max_marks)
                        return -ENOSPC;
 
@@ -600,17 +618,16 @@ static int fanotify_add_vfsmount_mark(struct fsnotify_group *group,
 
                fsnotify_init_mark(fsn_mark, fanotify_free_mark);
                ret = fsnotify_add_mark(fsn_mark, group, NULL, mnt, 0);
-               if (ret) {
-                       fanotify_free_mark(fsn_mark);
-                       return ret;
-               }
+               if (ret)
+                       goto err;
        }
        added = fanotify_mark_add_to_mask(fsn_mark, mask, flags);
-       fsnotify_put_mark(fsn_mark);
+
        if (added & ~mnt->mnt_fsnotify_mask)
                fsnotify_recalc_vfsmount_mask(mnt);
-
-       return 0;
+err:
+       fsnotify_put_mark(fsn_mark);
+       return ret;
 }
 
 static int fanotify_add_inode_mark(struct fsnotify_group *group,
@@ -619,6 +636,7 @@ static int fanotify_add_inode_mark(struct fsnotify_group *group,
 {
        struct fsnotify_mark *fsn_mark;
        __u32 added;
+       int ret = 0;
 
        pr_debug("%s: group=%p inode=%p\n", __func__, group, inode);
 
@@ -634,8 +652,6 @@ static int fanotify_add_inode_mark(struct fsnotify_group *group,
 
        fsn_mark = fsnotify_find_inode_mark(group, inode);
        if (!fsn_mark) {
-               int ret;
-
                if (atomic_read(&group->num_marks) > group->fanotify_data.max_marks)
                        return -ENOSPC;
 
@@ -645,16 +661,16 @@ static int fanotify_add_inode_mark(struct fsnotify_group *group,
 
                fsnotify_init_mark(fsn_mark, fanotify_free_mark);
                ret = fsnotify_add_mark(fsn_mark, group, inode, NULL, 0);
-               if (ret) {
-                       fanotify_free_mark(fsn_mark);
-                       return ret;
-               }
+               if (ret)
+                       goto err;
        }
        added = fanotify_mark_add_to_mask(fsn_mark, mask, flags);
-       fsnotify_put_mark(fsn_mark);
+
        if (added & ~inode->i_fsnotify_mask)
                fsnotify_recalc_inode_mask(inode);
-       return 0;
+err:
+       fsnotify_put_mark(fsn_mark);
+       return ret;
 }
 
 /* fanotify syscalls */
@@ -687,8 +703,10 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
 
        /* fsnotify_alloc_group takes a ref.  Dropped in fanotify_release */
        group = fsnotify_alloc_group(&fanotify_fsnotify_ops);
-       if (IS_ERR(group))
+       if (IS_ERR(group)) {
+               free_uid(user);
                return PTR_ERR(group);
+       }
 
        group->fanotify_data.user = user;
        atomic_inc(&user->fanotify_listeners);
@@ -698,6 +716,7 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
        mutex_init(&group->fanotify_data.access_mutex);
        init_waitqueue_head(&group->fanotify_data.access_waitq);
        INIT_LIST_HEAD(&group->fanotify_data.access_list);
+       atomic_set(&group->fanotify_data.bypass_perm, 0);
 #endif
        switch (flags & FAN_ALL_CLASS_BITS) {
        case FAN_CLASS_NOTIF:
@@ -764,8 +783,10 @@ SYSCALL_DEFINE(fanotify_mark)(int fanotify_fd, unsigned int flags,
        if (flags & ~FAN_ALL_MARK_FLAGS)
                return -EINVAL;
        switch (flags & (FAN_MARK_ADD | FAN_MARK_REMOVE | FAN_MARK_FLUSH)) {
-       case FAN_MARK_ADD:
+       case FAN_MARK_ADD:              /* fallthrough */
        case FAN_MARK_REMOVE:
+               if (!mask)
+                       return -EINVAL;
        case FAN_MARK_FLUSH:
                break;
        default:
index 444c305..4cd5d5d 100644 (file)
@@ -752,6 +752,7 @@ SYSCALL_DEFINE1(inotify_init1, int, flags)
        if (ret >= 0)
                return ret;
 
+       fsnotify_put_group(group);
        atomic_dec(&user->inotify_devs);
 out_free_uid:
        free_uid(user);
index 52c7557..9f26ac9 100644 (file)
@@ -1964,8 +1964,10 @@ static struct config_item *o2hb_heartbeat_group_make_item(struct config_group *g
        if (reg == NULL)
                return ERR_PTR(-ENOMEM);
 
-       if (strlen(name) > O2HB_MAX_REGION_NAME_LEN)
-               return ERR_PTR(-ENAMETOOLONG);
+       if (strlen(name) > O2HB_MAX_REGION_NAME_LEN) {
+               ret = -ENAMETOOLONG;
+               goto free;
+       }
 
        spin_lock(&o2hb_live_lock);
        reg->hr_region_num = 0;
@@ -1974,7 +1976,8 @@ static struct config_item *o2hb_heartbeat_group_make_item(struct config_group *g
                                                         O2NM_MAX_REGIONS);
                if (reg->hr_region_num >= O2NM_MAX_REGIONS) {
                        spin_unlock(&o2hb_live_lock);
-                       return ERR_PTR(-EFBIG);
+                       ret = -EFBIG;
+                       goto free;
                }
                set_bit(reg->hr_region_num, o2hb_region_bitmap);
        }
@@ -1986,10 +1989,13 @@ static struct config_item *o2hb_heartbeat_group_make_item(struct config_group *g
        ret = o2hb_debug_region_init(reg, o2hb_debug_dir);
        if (ret) {
                config_item_put(&reg->hr_item);
-               return ERR_PTR(ret);
+               goto free;
        }
 
        return &reg->hr_item;
+free:
+       kfree(reg);
+       return ERR_PTR(ret);
 }
 
 static void o2hb_heartbeat_group_drop_item(struct config_group *group,
index edaded4..895532a 100644 (file)
@@ -476,7 +476,6 @@ static void ocfs2_dentry_iput(struct dentry *dentry, struct inode *inode)
 
 out:
        iput(inode);
-       ocfs2_dentry_attach_gen(dentry);
 }
 
 /*
index 58a93b9..cc2aaa9 100644 (file)
@@ -959,7 +959,7 @@ static int dlm_match_regions(struct dlm_ctxt *dlm,
                r += O2HB_MAX_REGION_NAME_LEN;
        }
 
-       local = kmalloc(sizeof(qr->qr_regions), GFP_KERNEL);
+       local = kmalloc(sizeof(qr->qr_regions), GFP_ATOMIC);
        if (!local) {
                status = -ENOMEM;
                goto bail;
index 1efea36..70dd3b1 100644 (file)
@@ -159,9 +159,9 @@ struct ocfs2_lock_res {
        char                     l_name[OCFS2_LOCK_ID_MAX_LEN];
        unsigned int             l_ro_holders;
        unsigned int             l_ex_holders;
-       char                     l_level;
-       char                     l_requested;
-       char                     l_blocking;
+       signed char              l_level;
+       signed char              l_requested;
+       signed char              l_blocking;
 
        /* Data packed - type enum ocfs2_lock_type */
        unsigned char            l_type;
index 252e7c8..a5ebe42 100644 (file)
@@ -190,7 +190,7 @@ static struct ocfs2_live_connection *ocfs2_connection_find(const char *name)
                        return c;
        }
 
-       return c;
+       return NULL;
 }
 
 /*
index a8012a9..04629f3 100644 (file)
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -1199,12 +1199,24 @@ int pipe_proc_fn(struct ctl_table *table, int write, void __user *buf,
        return ret;
 }
 
+/*
+ * After the inode slimming patch, i_pipe/i_bdev/i_cdev share the same
+ * location, so checking ->i_pipe is not enough to verify that this is a
+ * pipe.
+ */
+struct pipe_inode_info *get_pipe_info(struct file *file)
+{
+       struct inode *i = file->f_path.dentry->d_inode;
+
+       return S_ISFIFO(i->i_mode) ? i->i_pipe : NULL;
+}
+
 long pipe_fcntl(struct file *file, unsigned int cmd, unsigned long arg)
 {
        struct pipe_inode_info *pipe;
        long ret;
 
-       pipe = file->f_path.dentry->d_inode->i_pipe;
+       pipe = get_pipe_info(file);
        if (!pipe)
                return -EBADF;
 
index f3d02ca..1828451 100644 (file)
@@ -1574,7 +1574,7 @@ static int do_proc_readlink(struct path *path, char __user *buffer, int buflen)
        if (!tmp)
                return -ENOMEM;
 
-       pathname = d_path_with_unreachable(path, tmp, PAGE_SIZE);
+       pathname = d_path(path, tmp, PAGE_SIZE);
        len = PTR_ERR(pathname);
        if (IS_ERR(pathname))
                goto out;
index 536d697..90d2fcb 100644 (file)
@@ -472,7 +472,9 @@ int reiserfs_acl_chmod(struct inode *inode)
                struct reiserfs_transaction_handle th;
                size_t size = reiserfs_xattr_nblocks(inode,
                                             reiserfs_acl_size(clone->a_count));
-               reiserfs_write_lock(inode->i_sb);
+               int depth;
+
+               depth = reiserfs_write_lock_once(inode->i_sb);
                error = journal_begin(&th, inode->i_sb, size * 2);
                if (!error) {
                        int error2;
@@ -482,7 +484,7 @@ int reiserfs_acl_chmod(struct inode *inode)
                        if (error2)
                                error = error2;
                }
-               reiserfs_write_unlock(inode->i_sb);
+               reiserfs_write_unlock_once(inode->i_sb, depth);
        }
        posix_acl_release(clone);
        return error;
index 8f1dfae..ce2f025 100644 (file)
@@ -1311,18 +1311,6 @@ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
 static int splice_pipe_to_pipe(struct pipe_inode_info *ipipe,
                               struct pipe_inode_info *opipe,
                               size_t len, unsigned int flags);
-/*
- * After the inode slimming patch, i_pipe/i_bdev/i_cdev share the same
- * location, so checking ->i_pipe is not enough to verify that this is a
- * pipe.
- */
-static inline struct pipe_inode_info *pipe_info(struct inode *inode)
-{
-       if (S_ISFIFO(inode->i_mode))
-               return inode->i_pipe;
-
-       return NULL;
-}
 
 /*
  * Determine where to splice to/from.
@@ -1336,8 +1324,8 @@ static long do_splice(struct file *in, loff_t __user *off_in,
        loff_t offset, *off;
        long ret;
 
-       ipipe = pipe_info(in->f_path.dentry->d_inode);
-       opipe = pipe_info(out->f_path.dentry->d_inode);
+       ipipe = get_pipe_info(in);
+       opipe = get_pipe_info(out);
 
        if (ipipe && opipe) {
                if (off_in || off_out)
@@ -1555,7 +1543,7 @@ static long vmsplice_to_user(struct file *file, const struct iovec __user *iov,
        int error;
        long ret;
 
-       pipe = pipe_info(file->f_path.dentry->d_inode);
+       pipe = get_pipe_info(file);
        if (!pipe)
                return -EBADF;
 
@@ -1642,7 +1630,7 @@ static long vmsplice_to_pipe(struct file *file, const struct iovec __user *iov,
        };
        long ret;
 
-       pipe = pipe_info(file->f_path.dentry->d_inode);
+       pipe = get_pipe_info(file);
        if (!pipe)
                return -EBADF;
 
@@ -2022,8 +2010,8 @@ static int link_pipe(struct pipe_inode_info *ipipe,
 static long do_tee(struct file *in, struct file *out, size_t len,
                   unsigned int flags)
 {
-       struct pipe_inode_info *ipipe = pipe_info(in->f_path.dentry->d_inode);
-       struct pipe_inode_info *opipe = pipe_info(out->f_path.dentry->d_inode);
+       struct pipe_inode_info *ipipe = get_pipe_info(in);
+       struct pipe_inode_info *opipe = get_pipe_info(out);
        int ret = -EINVAL;
 
        /*
index 7d287af..691f612 100644 (file)
@@ -934,7 +934,6 @@ xfs_aops_discard_page(
        struct xfs_inode        *ip = XFS_I(inode);
        struct buffer_head      *bh, *head;
        loff_t                  offset = page_offset(page);
-       ssize_t                 len = 1 << inode->i_blkbits;
 
        if (!xfs_is_delayed_page(page, IO_DELAY))
                goto out_invalidate;
@@ -949,58 +948,14 @@ xfs_aops_discard_page(
        xfs_ilock(ip, XFS_ILOCK_EXCL);
        bh = head = page_buffers(page);
        do {
-               int             done;
-               xfs_fileoff_t   offset_fsb;
-               xfs_bmbt_irec_t imap;
-               int             nimaps = 1;
                int             error;
-               xfs_fsblock_t   firstblock;
-               xfs_bmap_free_t flist;
+               xfs_fileoff_t   start_fsb;
 
                if (!buffer_delay(bh))
                        goto next_buffer;
 
-               offset_fsb = XFS_B_TO_FSBT(ip->i_mount, offset);
-
-               /*
-                * Map the range first and check that it is a delalloc extent
-                * before trying to unmap the range. Otherwise we will be
-                * trying to remove a real extent (which requires a
-                * transaction) or a hole, which is probably a bad idea...
-                */
-               error = xfs_bmapi(NULL, ip, offset_fsb, 1,
-                               XFS_BMAPI_ENTIRE,  NULL, 0, &imap,
-                               &nimaps, NULL);
-
-               if (error) {
-                       /* something screwed, just bail */
-                       if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) {
-                               xfs_fs_cmn_err(CE_ALERT, ip->i_mount,
-                               "page discard failed delalloc mapping lookup.");
-                       }
-                       break;
-               }
-               if (!nimaps) {
-                       /* nothing there */
-                       goto next_buffer;
-               }
-               if (imap.br_startblock != DELAYSTARTBLOCK) {
-                       /* been converted, ignore */
-                       goto next_buffer;
-               }
-               WARN_ON(imap.br_blockcount == 0);
-
-               /*
-                * Note: while we initialise the firstblock/flist pair, they
-                * should never be used because blocks should never be
-                * allocated or freed for a delalloc extent and hence we need
-                * don't cancel or finish them after the xfs_bunmapi() call.
-                */
-               xfs_bmap_init(&flist, &firstblock);
-               error = xfs_bunmapi(NULL, ip, offset_fsb, 1, 0, 1, &firstblock,
-                                       &flist, &done);
-
-               ASSERT(!flist.xbf_count && !flist.xbf_first);
+               start_fsb = XFS_B_TO_FSBT(ip->i_mount, offset);
+               error = xfs_bmap_punch_delalloc_range(ip, start_fsb, 1);
                if (error) {
                        /* something screwed, just bail */
                        if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) {
@@ -1010,7 +965,7 @@ xfs_aops_discard_page(
                        break;
                }
 next_buffer:
-               offset += len;
+               offset += 1 << inode->i_blkbits;
 
        } while ((bh = bh->b_this_page) != head);
 
@@ -1505,11 +1460,42 @@ xfs_vm_write_failed(
        struct inode            *inode = mapping->host;
 
        if (to > inode->i_size) {
-               struct iattr    ia = {
-                       .ia_valid       = ATTR_SIZE | ATTR_FORCE,
-                       .ia_size        = inode->i_size,
-               };
-               xfs_setattr(XFS_I(inode), &ia, XFS_ATTR_NOLOCK);
+               /*
+                * punch out the delalloc blocks we have already allocated. We
+                * don't call xfs_setattr() to do this as we may be in the
+                * middle of a multi-iovec write and so the vfs inode->i_size
+                * will not match the xfs ip->i_size and so it will zero too
+                * much. Hence we jus truncate the page cache to zero what is
+                * necessary and punch the delalloc blocks directly.
+                */
+               struct xfs_inode        *ip = XFS_I(inode);
+               xfs_fileoff_t           start_fsb;
+               xfs_fileoff_t           end_fsb;
+               int                     error;
+
+               truncate_pagecache(inode, to, inode->i_size);
+
+               /*
+                * Check if there are any blocks that are outside of i_size
+                * that need to be trimmed back.
+                */
+               start_fsb = XFS_B_TO_FSB(ip->i_mount, inode->i_size) + 1;
+               end_fsb = XFS_B_TO_FSB(ip->i_mount, to);
+               if (end_fsb <= start_fsb)
+                       return;
+
+               xfs_ilock(ip, XFS_ILOCK_EXCL);
+               error = xfs_bmap_punch_delalloc_range(ip, start_fsb,
+                                                       end_fsb - start_fsb);
+               if (error) {
+                       /* something screwed, just bail */
+                       if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) {
+                               xfs_fs_cmn_err(CE_ALERT, ip->i_mount,
+                       "xfs_vm_write_failed: unable to clean up ino %lld",
+                                               ip->i_ino);
+                       }
+               }
+               xfs_iunlock(ip, XFS_ILOCK_EXCL);
        }
 }
 
index aa1d353..4c5deb6 100644 (file)
@@ -488,29 +488,16 @@ found:
        spin_unlock(&pag->pag_buf_lock);
        xfs_perag_put(pag);
 
-       /* Attempt to get the semaphore without sleeping,
-        * if this does not work then we need to drop the
-        * spinlock and do a hard attempt on the semaphore.
-        */
-       if (down_trylock(&bp->b_sema)) {
+       if (xfs_buf_cond_lock(bp)) {
+               /* failed, so wait for the lock if requested. */
                if (!(flags & XBF_TRYLOCK)) {
-                       /* wait for buffer ownership */
                        xfs_buf_lock(bp);
                        XFS_STATS_INC(xb_get_locked_waited);
                } else {
-                       /* We asked for a trylock and failed, no need
-                        * to look at file offset and length here, we
-                        * know that this buffer at least overlaps our
-                        * buffer and is locked, therefore our buffer
-                        * either does not exist, or is this buffer.
-                        */
                        xfs_buf_rele(bp);
                        XFS_STATS_INC(xb_busy_locked);
                        return NULL;
                }
-       } else {
-               /* trylock worked */
-               XB_SET_OWNER(bp);
        }
 
        if (bp->b_flags & XBF_STALE) {
@@ -876,10 +863,18 @@ xfs_buf_rele(
  */
 
 /*
- *     Locks a buffer object, if it is not already locked.
- *     Note that this in no way locks the underlying pages, so it is only
- *     useful for synchronizing concurrent use of buffer objects, not for
- *     synchronizing independent access to the underlying pages.
+ *     Locks a buffer object, if it is not already locked.  Note that this in
+ *     no way locks the underlying pages, so it is only useful for
+ *     synchronizing concurrent use of buffer objects, not for synchronizing
+ *     independent access to the underlying pages.
+ *
+ *     If we come across a stale, pinned, locked buffer, we know that we are
+ *     being asked to lock a buffer that has been reallocated. Because it is
+ *     pinned, we know that the log has not been pushed to disk and hence it
+ *     will still be locked.  Rather than continuing to have trylock attempts
+ *     fail until someone else pushes the log, push it ourselves before
+ *     returning.  This means that the xfsaild will not get stuck trying
+ *     to push on stale inode buffers.
  */
 int
 xfs_buf_cond_lock(
@@ -890,6 +885,8 @@ xfs_buf_cond_lock(
        locked = down_trylock(&bp->b_sema) == 0;
        if (locked)
                XB_SET_OWNER(bp);
+       else if (atomic_read(&bp->b_pin_count) && (bp->b_flags & XBF_STALE))
+               xfs_log_force(bp->b_target->bt_mount, 0);
 
        trace_xfs_buf_cond_lock(bp, _RET_IP_);
        return locked ? 0 : -EBUSY;
index 8abd12e..4111cd3 100644 (file)
@@ -5471,8 +5471,13 @@ xfs_getbmap(
                        if (error)
                                goto out_unlock_iolock;
                }
-
-               ASSERT(ip->i_delayed_blks == 0);
+               /*
+                * even after flushing the inode, there can still be delalloc
+                * blocks on the inode beyond EOF due to speculative
+                * preallocation. These are not removed until the release
+                * function is called or the inode is inactivated. Hence we
+                * cannot assert here that ip->i_delayed_blks == 0.
+                */
        }
 
        lock = xfs_ilock_map_shared(ip);
@@ -6070,3 +6075,79 @@ xfs_bmap_disk_count_leaves(
                *count += xfs_bmbt_disk_get_blockcount(frp);
        }
 }
+
+/*
+ * dead simple method of punching delalyed allocation blocks from a range in
+ * the inode. Walks a block at a time so will be slow, but is only executed in
+ * rare error cases so the overhead is not critical. This will alays punch out
+ * both the start and end blocks, even if the ranges only partially overlap
+ * them, so it is up to the caller to ensure that partial blocks are not
+ * passed in.
+ */
+int
+xfs_bmap_punch_delalloc_range(
+       struct xfs_inode        *ip,
+       xfs_fileoff_t           start_fsb,
+       xfs_fileoff_t           length)
+{
+       xfs_fileoff_t           remaining = length;
+       int                     error = 0;
+
+       ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
+
+       do {
+               int             done;
+               xfs_bmbt_irec_t imap;
+               int             nimaps = 1;
+               xfs_fsblock_t   firstblock;
+               xfs_bmap_free_t flist;
+
+               /*
+                * Map the range first and check that it is a delalloc extent
+                * before trying to unmap the range. Otherwise we will be
+                * trying to remove a real extent (which requires a
+                * transaction) or a hole, which is probably a bad idea...
+                */
+               error = xfs_bmapi(NULL, ip, start_fsb, 1,
+                               XFS_BMAPI_ENTIRE,  NULL, 0, &imap,
+                               &nimaps, NULL);
+
+               if (error) {
+                       /* something screwed, just bail */
+                       if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) {
+                               xfs_fs_cmn_err(CE_ALERT, ip->i_mount,
+                       "Failed delalloc mapping lookup ino %lld fsb %lld.",
+                                               ip->i_ino, start_fsb);
+                       }
+                       break;
+               }
+               if (!nimaps) {
+                       /* nothing there */
+                       goto next_block;
+               }
+               if (imap.br_startblock != DELAYSTARTBLOCK) {
+                       /* been converted, ignore */
+                       goto next_block;
+               }
+               WARN_ON(imap.br_blockcount == 0);
+
+               /*
+                * Note: while we initialise the firstblock/flist pair, they
+                * should never be used because blocks should never be
+                * allocated or freed for a delalloc extent and hence we need
+                * don't cancel or finish them after the xfs_bunmapi() call.
+                */
+               xfs_bmap_init(&flist, &firstblock);
+               error = xfs_bunmapi(NULL, ip, start_fsb, 1, 0, 1, &firstblock,
+                                       &flist, &done);
+               if (error)
+                       break;
+
+               ASSERT(!flist.xbf_count && !flist.xbf_first);
+next_block:
+               start_fsb++;
+               remaining--;
+       } while(remaining > 0);
+
+       return error;
+}
index 71ec9b6..3651191 100644 (file)
@@ -394,6 +394,11 @@ xfs_bmap_count_blocks(
        int                     whichfork,
        int                     *count);
 
+int
+xfs_bmap_punch_delalloc_range(
+       struct xfs_inode        *ip,
+       xfs_fileoff_t           start_fsb,
+       xfs_fileoff_t           length);
 #endif /* __KERNEL__ */
 
 #endif /* __XFS_BMAP_H__ */
index 3b9582c..e60490b 100644 (file)
@@ -377,6 +377,19 @@ xfs_swap_extents(
        ip->i_d.di_format = tip->i_d.di_format;
        tip->i_d.di_format = tmp;
 
+       /*
+        * The extents in the source inode could still contain speculative
+        * preallocation beyond EOF (e.g. the file is open but not modified
+        * while defrag is in progress). In that case, we need to copy over the
+        * number of delalloc blocks the data fork in the source inode is
+        * tracking beyond EOF so that when the fork is truncated away when the
+        * temporary inode is unlinked we don't underrun the i_delayed_blks
+        * counter on that inode.
+        */
+       ASSERT(tip->i_delayed_blks == 0);
+       tip->i_delayed_blks = ip->i_delayed_blks;
+       ip->i_delayed_blks = 0;
+
        ilf_fields = XFS_ILOG_CORE;
 
        switch(ip->i_d.di_format) {
index ed99902..c78cc6a 100644 (file)
@@ -58,6 +58,7 @@ xfs_error_trap(int e)
 int    xfs_etest[XFS_NUM_INJECT_ERROR];
 int64_t        xfs_etest_fsid[XFS_NUM_INJECT_ERROR];
 char * xfs_etest_fsname[XFS_NUM_INJECT_ERROR];
+int    xfs_error_test_active;
 
 int
 xfs_error_test(int error_tag, int *fsidp, char *expression,
@@ -108,6 +109,7 @@ xfs_errortag_add(int error_tag, xfs_mount_t *mp)
                        len = strlen(mp->m_fsname);
                        xfs_etest_fsname[i] = kmem_alloc(len + 1, KM_SLEEP);
                        strcpy(xfs_etest_fsname[i], mp->m_fsname);
+                       xfs_error_test_active++;
                        return 0;
                }
        }
@@ -137,6 +139,7 @@ xfs_errortag_clearall(xfs_mount_t *mp, int loud)
                        xfs_etest_fsid[i] = 0LL;
                        kmem_free(xfs_etest_fsname[i]);
                        xfs_etest_fsname[i] = NULL;
+                       xfs_error_test_active--;
                }
        }
 
index c2c1a07..f338847 100644 (file)
@@ -127,13 +127,14 @@ extern void xfs_corruption_error(const char *tag, int level,
 #define        XFS_RANDOM_BMAPIFORMAT                          XFS_RANDOM_DEFAULT
 
 #ifdef DEBUG
+extern int xfs_error_test_active;
 extern int xfs_error_test(int, int *, char *, int, char *, unsigned long);
 
 #define        XFS_NUM_INJECT_ERROR                            10
 #define XFS_TEST_ERROR(expr, mp, tag, rf)              \
-       ((expr) || \
+       ((expr) || (xfs_error_test_active && \
         xfs_error_test((tag), (mp)->m_fixedfsid, "expr", __LINE__, __FILE__, \
-                       (rf)))
+                       (rf))))
 
 extern int xfs_errortag_add(int error_tag, xfs_mount_t *mp);
 extern int xfs_errortag_clearall(xfs_mount_t *mp, int loud);
index c7ac020..7c8d30c 100644 (file)
@@ -657,18 +657,37 @@ xfs_inode_item_unlock(
 }
 
 /*
- * This is called to find out where the oldest active copy of the
- * inode log item in the on disk log resides now that the last log
- * write of it completed at the given lsn.  Since we always re-log
- * all dirty data in an inode, the latest copy in the on disk log
- * is the only one that matters.  Therefore, simply return the
- * given lsn.
+ * This is called to find out where the oldest active copy of the inode log
+ * item in the on disk log resides now that the last log write of it completed
+ * at the given lsn.  Since we always re-log all dirty data in an inode, the
+ * latest copy in the on disk log is the only one that matters.  Therefore,
+ * simply return the given lsn.
+ *
+ * If the inode has been marked stale because the cluster is being freed, we
+ * don't want to (re-)insert this inode into the AIL. There is a race condition
+ * where the cluster buffer may be unpinned before the inode is inserted into
+ * the AIL during transaction committed processing. If the buffer is unpinned
+ * before the inode item has been committed and inserted, then it is possible
+ * for the buffer to be written and IO completions before the inode is inserted
+ * into the AIL. In that case, we'd be inserting a clean, stale inode into the
+ * AIL which will never get removed. It will, however, get reclaimed which
+ * triggers an assert in xfs_inode_free() complaining about freein an inode
+ * still in the AIL.
+ *
+ * To avoid this, return a lower LSN than the one passed in so that the
+ * transaction committed code will not move the inode forward in the AIL but
+ * will still unpin it properly.
  */
 STATIC xfs_lsn_t
 xfs_inode_item_committed(
        struct xfs_log_item     *lip,
        xfs_lsn_t               lsn)
 {
+       struct xfs_inode_log_item *iip = INODE_ITEM(lip);
+       struct xfs_inode        *ip = iip->ili_inode;
+
+       if (xfs_iflags_test(ip, XFS_ISTALE))
+               return lsn - 1;
        return lsn;
 }
 
index d2af0a8..77a5989 100644 (file)
@@ -297,6 +297,7 @@ xfs_rename(
         * it and some incremental backup programs won't work without it.
         */
        xfs_trans_ichgtime(tp, src_ip, XFS_ICHGTIME_CHG);
+       xfs_trans_log_inode(tp, src_ip, XFS_ILOG_CORE);
 
        /*
         * Adjust the link count on src_dp.  This is necessary when
index 551793c..0e98e67 100644 (file)
@@ -1,6 +1,10 @@
 #ifndef __ACPI_VIDEO_H
 #define __ACPI_VIDEO_H
 
+#include <linux/errno.h> /* for ENODEV */
+
+struct acpi_device;
+
 #define ACPI_VIDEO_DISPLAY_CRT  1
 #define ACPI_VIDEO_DISPLAY_TV   2
 #define ACPI_VIDEO_DISPLAY_DVI  3
@@ -26,4 +30,3 @@ static inline int acpi_video_get_edid(struct acpi_device *device, int type,
 #endif
 
 #endif
-
index 8c641be..a2776e2 100644 (file)
@@ -287,6 +287,8 @@ typedef struct drm_i915_irq_wait {
 #define I915_PARAM_HAS_EXECBUF2          9
 #define I915_PARAM_HAS_BSD              10
 #define I915_PARAM_HAS_BLT              11
+#define I915_PARAM_HAS_RELAXED_FENCING  12
+#define I915_PARAM_HAS_COHERENT_RINGS   13
 
 typedef struct drm_i915_getparam {
        int param;
index 050a7bc..67c91b4 100644 (file)
@@ -219,7 +219,7 @@ static inline int acpi_video_display_switch_support(void)
 
 extern int acpi_blacklisted(void);
 extern void acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d);
-extern int acpi_osi_setup(char *str);
+extern void acpi_osi_setup(char *str);
 
 #ifdef CONFIG_ACPI_NUMA
 int acpi_get_pxm(acpi_handle handle);
index a8e4e83..475f8c4 100644 (file)
@@ -427,8 +427,10 @@ extern rwlock_t vcc_sklist_lock;
 
 #define ATM_SKB(skb) (((struct atm_skb_data *) (skb)->cb))
 
-struct atm_dev *atm_dev_register(const char *type,const struct atmdev_ops *ops,
-    int number,unsigned long *flags); /* number == -1: pick first available */
+struct atm_dev *atm_dev_register(const char *type, struct device *parent,
+                                const struct atmdev_ops *ops,
+                                int number, /* -1 == pick first available */
+                                unsigned long *flags);
 struct atm_dev *atm_dev_lookup(int number);
 void atm_dev_deregister(struct atm_dev *dev);
 
index a065612..64a7114 100644 (file)
@@ -29,6 +29,7 @@ struct linux_binprm{
        char buf[BINPRM_BUF_SIZE];
 #ifdef CONFIG_MMU
        struct vm_area_struct *vma;
+       unsigned long vma_pages;
 #else
 # define MAX_ARG_PAGES 32
        struct page *page[MAX_ARG_PAGES];
@@ -59,6 +60,10 @@ struct linux_binprm{
        unsigned long loader, exec;
 };
 
+extern void acct_arg_size(struct linux_binprm *bprm, unsigned long pages);
+extern struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
+                                       int write);
+
 #define BINPRM_FLAGS_ENFORCE_NONDUMP_BIT 0
 #define BINPRM_FLAGS_ENFORCE_NONDUMP (1 << BINPRM_FLAGS_ENFORCE_NONDUMP_BIT)
 
index 266ab92..499dfe9 100644 (file)
@@ -105,6 +105,8 @@ extern void *__alloc_bootmem_low_node(pg_data_t *pgdat,
 
 #define alloc_bootmem(x) \
        __alloc_bootmem(x, SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS))
+#define alloc_bootmem_align(x, align) \
+       __alloc_bootmem(x, align, __pa(MAX_DMA_ADDRESS))
 #define alloc_bootmem_nopanic(x) \
        __alloc_bootmem_nopanic(x, SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS))
 #define alloc_bootmem_pages(x) \
index 7605fdd..e3d8bf2 100644 (file)
@@ -61,13 +61,31 @@ union cnt32_to_63 {
  *
  * 2) this code must not be preempted for a duration longer than the
  *    32-bit counter half period minus the longest period between two
- *    calls to this code.
+ *    calls to this code;
  *
  * Those requirements ensure proper update to the state bit in memory.
  * This is usually not a problem in practice, but if it is then a kernel
  * timer should be scheduled to manage for this code to be executed often
  * enough.
  *
+ * And finally:
+ *
+ * 3) the cnt_lo argument must be seen as a globally incrementing value,
+ *    meaning that it should be a direct reference to the counter data which
+ *    can be evaluated according to a specific ordering within the macro,
+ *    and not the result of a previous evaluation stored in a variable.
+ *
+ * For example, this is wrong:
+ *
+ *     u32 partial = get_hw_count();
+ *     u64 full = cnt32_to_63(partial);
+ *     return full;
+ *
+ * This is fine:
+ *
+ *     u64 full = cnt32_to_63(get_hw_count());
+ *     return full;
+ *
  * Note that the top bit (bit 63) in the returned value should be considered
  * as garbage.  It is not cleared here because callers are likely to use a
  * multiplier on the returned value which can get rid of the top bit
index 4823af6..5f09323 100644 (file)
  *
  * CPUs are exported via sysfs in the class/cpu/devices/
  * directory. 
- *
- * Per-cpu interfaces can be implemented using a struct device_interface. 
- * See the following for how to do this: 
- * - drivers/base/intf.c 
- * - Documentation/driver-model/interface.txt
  */
 #ifndef _LINUX_CPU_H_
 #define _LINUX_CPU_H_
index 0f01214..6c6133f 100644 (file)
                                 FAN_ALL_PERM_EVENTS |\
                                 FAN_Q_OVERFLOW)
 
-#define FANOTIFY_METADATA_VERSION      2
+#define FANOTIFY_METADATA_VERSION      3
 
 struct fanotify_event_metadata {
        __u32 event_len;
-       __u32 vers;
+       __u8 vers;
+       __u8 reserved;
+       __u16 metadata_len;
        __aligned_u64 mask;
        __s32 fd;
        __s32 pid;
@@ -96,11 +98,13 @@ struct fanotify_event_metadata {
 struct fanotify_response {
        __s32 fd;
        __u32 response;
-} __attribute__ ((packed));
+};
 
 /* Legit userspace responses to a _PERM event */
 #define FAN_ALLOW      0x01
 #define FAN_DENY       0x02
+/* No fd set in event */
+#define FAN_NOFD       -1
 
 /* Helper functions to deal with fanotify_event_metadata buffers */
 #define FAN_EVENT_METADATA_LEN (sizeof(struct fanotify_event_metadata))
index c9e06cc..090f0ea 100644 (file)
@@ -602,6 +602,7 @@ struct address_space_operations {
        sector_t (*bmap)(struct address_space *, sector_t);
        void (*invalidatepage) (struct page *, unsigned long);
        int (*releasepage) (struct page *, gfp_t);
+       void (*freepage)(struct page *);
        ssize_t (*direct_IO)(int, struct kiocb *, const struct iovec *iov,
                        loff_t offset, unsigned long nr_segs);
        int (*get_xip_mem)(struct address_space *, pgoff_t, int,
index 5c185fa..b10bcde 100644 (file)
@@ -235,9 +235,6 @@ static inline void fsnotify_open(struct file *file)
        if (S_ISDIR(inode->i_mode))
                mask |= FS_ISDIR;
 
-       /* FMODE_NONOTIFY must never be set from user */
-       file->f_mode &= ~FMODE_NONOTIFY;
-
        fsnotify_parent(path, NULL, mask);
        fsnotify(inode, mask, path, FSNOTIFY_EVENT_PATH, NULL, 0);
 }
index 0a68f92..7380763 100644 (file)
@@ -166,7 +166,7 @@ struct fsnotify_group {
                        struct mutex access_mutex;
                        struct list_head access_list;
                        wait_queue_head_t access_waitq;
-                       bool bypass_perm; /* protected by access_mutex */
+                       atomic_t bypass_perm;
 #endif /* CONFIG_FANOTIFY_ACCESS_PERMISSIONS */
                        int f_flags;
                        unsigned int max_marks;
index e8713d5..f54adfc 100644 (file)
@@ -360,7 +360,7 @@ void drain_local_pages(void *dummy);
 
 extern gfp_t gfp_allowed_mask;
 
-extern void set_gfp_allowed_mask(gfp_t mask);
-extern gfp_t clear_gfp_allowed_mask(gfp_t mask);
+extern void pm_restrict_gfp_mask(void);
+extern void pm_restore_gfp_mask(void);
 
 #endif /* __LINUX_GFP_H */
index ce73a30..dd1a56f 100644 (file)
@@ -16,6 +16,8 @@ struct gpio_keys_button {
 struct gpio_keys_platform_data {
        struct gpio_keys_button *buttons;
        int nbuttons;
+       unsigned int poll_interval;     /* polling interval in msecs -
+                                          for polling driver only */
        unsigned int rep:1;             /* enable input subsystem auto repeat */
        int (*enable)(struct device *dev);
        void (*disable)(struct device *dev);
index 6ef4446..9777668 100644 (file)
@@ -47,6 +47,25 @@ struct input_id {
        __u16 version;
 };
 
+/**
+ * struct input_absinfo - used by EVIOCGABS/EVIOCSABS ioctls
+ * @value: latest reported value for the axis.
+ * @minimum: specifies minimum value for the axis.
+ * @maximum: specifies maximum value for the axis.
+ * @fuzz: specifies fuzz value that is used to filter noise from
+ *     the event stream.
+ * @flat: values that are within this value will be discarded by
+ *     joydev interface and reported as 0 instead.
+ * @resolution: specifies resolution for the values reported for
+ *     the axis.
+ *
+ * Note that input core does not clamp reported values to the
+ * [minimum, maximum] limits, such task is left to userspace.
+ *
+ * Resolution for main axes (ABS_X, ABS_Y, ABS_Z) is reported in
+ * units per millimeter (units/mm), resolution for rotational axes
+ * (ABS_RX, ABS_RY, ABS_RZ) is reported in units per radian.
+ */
 struct input_absinfo {
        __s32 value;
        __s32 minimum;
@@ -85,8 +104,10 @@ struct input_keymap_entry {
 #define EVIOCGREP              _IOR('E', 0x03, unsigned int[2])        /* get repeat settings */
 #define EVIOCSREP              _IOW('E', 0x03, unsigned int[2])        /* set repeat settings */
 
-#define EVIOCGKEYCODE          _IOR('E', 0x04, struct input_keymap_entry)      /* get keycode */
-#define EVIOCSKEYCODE          _IOW('E', 0x04, struct input_keymap_entry)      /* set keycode */
+#define EVIOCGKEYCODE          _IOR('E', 0x04, unsigned int[2])        /* get keycode */
+#define EVIOCGKEYCODE_V2       _IOR('E', 0x04, struct input_keymap_entry)
+#define EVIOCSKEYCODE          _IOW('E', 0x04, unsigned int[2])        /* set keycode */
+#define EVIOCSKEYCODE_V2       _IOW('E', 0x04, struct input_keymap_entry)
 
 #define EVIOCGNAME(len)                _IOC(_IOC_READ, 'E', 0x06, len)         /* get device name */
 #define EVIOCGPHYS(len)                _IOC(_IOC_READ, 'E', 0x07, len)         /* get physical location */
@@ -624,6 +645,10 @@ struct input_keymap_entry {
 #define KEY_CAMERA_FOCUS       0x210
 #define KEY_WPS_BUTTON         0x211   /* WiFi Protected Setup key */
 
+#define KEY_TOUCHPAD_TOGGLE    0x212   /* Request switch touchpad on or off */
+#define KEY_TOUCHPAD_ON                0x213
+#define KEY_TOUCHPAD_OFF       0x214
+
 #define BTN_TRIGGER_HAPPY              0x2c0
 #define BTN_TRIGGER_HAPPY1             0x2c0
 #define BTN_TRIGGER_HAPPY2             0x2c1
@@ -1130,7 +1155,7 @@ struct input_mt_slot {
  *     of tracked contacts
  * @mtsize: number of MT slots the device uses
  * @slot: MT slot currently being transmitted
- * @absinfo: array of &struct absinfo elements holding information
+ * @absinfo: array of &struct input_absinfo elements holding information
  *     about absolute axes (current value, min, max, flat, fuzz,
  *     resolution)
  * @key: reflects current state of device's keys/buttons
index d377ea8..e9bb22c 100644 (file)
@@ -112,7 +112,6 @@ struct resource_list {
 /* PC/ISA/whatever - the normal PC address spaces: IO and memory */
 extern struct resource ioport_resource;
 extern struct resource iomem_resource;
-extern int resource_alloc_from_bottom;
 
 extern struct resource *request_resource_conflict(struct resource *root, struct resource *new);
 extern int request_resource(struct resource *root, struct resource *new);
@@ -124,6 +123,7 @@ extern void reserve_region_with_split(struct resource *root,
 extern struct resource *insert_resource_conflict(struct resource *parent, struct resource *new);
 extern int insert_resource(struct resource *parent, struct resource *new);
 extern void insert_resource_expand_to_fit(struct resource *root, struct resource *new);
+extern void arch_remove_reservations(struct resource *avail);
 extern int allocate_resource(struct resource *root, struct resource *new,
                             resource_size_t size, resource_size_t min,
                             resource_size_t max, resource_size_t align,
index 4307231..31c237a 100644 (file)
@@ -161,6 +161,9 @@ extern void register_page_bootmem_info_node(struct pglist_data *pgdat);
 extern void put_page_bootmem(struct page *page);
 #endif
 
+void lock_memory_hotplug(void);
+void unlock_memory_hotplug(void);
+
 #else /* ! CONFIG_MEMORY_HOTPLUG */
 /*
  * Stub functions for when hotplug is off
@@ -192,6 +195,9 @@ static inline void register_page_bootmem_info_node(struct pglist_data *pgdat)
 {
 }
 
+static inline void lock_memory_hotplug(void) {}
+static inline void unlock_memory_hotplug(void) {}
+
 #endif /* ! CONFIG_MEMORY_HOTPLUG */
 
 #ifdef CONFIG_MEMORY_HOTREMOVE
index 5c51f36..add8a1b 100644 (file)
@@ -29,7 +29,7 @@ struct wm8994_ldo_pdata {
 #define WM8994_CONFIGURE_GPIO 0x8000
 
 #define WM8994_DRC_REGS 5
-#define WM8994_EQ_REGS  19
+#define WM8994_EQ_REGS  20
 
 /**
  * DRC configurations are specified with a label and a set of register
index c66fdb7..29d504d 100644 (file)
@@ -401,6 +401,7 @@ extern const struct inode_operations nfs3_file_inode_operations;
 #endif /* CONFIG_NFS_V3 */
 extern const struct file_operations nfs_file_operations;
 extern const struct address_space_operations nfs_file_aops;
+extern const struct address_space_operations nfs_dir_aops;
 
 static inline struct nfs_open_context *nfs_file_open_context(struct file *filp)
 {
index f8b60e7..d55cee7 100644 (file)
@@ -29,6 +29,7 @@
  */
 enum {
        PG_BUSY = 0,
+       PG_MAPPED,
        PG_CLEAN,
        PG_NEED_COMMIT,
        PG_NEED_RESCHED,
index 06292da..1466945 100644 (file)
  *
  * Nodes are exported via driverfs in the class/node/devices/
  * directory. 
- *
- * Per-node interfaces can be implemented using a struct device_interface. 
- * See the following for how to do this: 
- * - drivers/base/intf.c 
- * - Documentation/driver-model/interface.txt
  */
 #ifndef _LINUX_NODE_H_
 #define _LINUX_NODE_H_
index d369b53..cb845c1 100644 (file)
 #define PCI_DEVICE_ID_AFAVLAB_P030     0x2182
 #define PCI_SUBDEVICE_ID_AFAVLAB_P061          0x2150
 
+#define PCI_VENDOR_ID_BCM_GVC          0x14a4
 #define PCI_VENDOR_ID_BROADCOM         0x14e4
 #define PCI_DEVICE_ID_TIGON3_5752      0x1600
 #define PCI_DEVICE_ID_TIGON3_5752M     0x1601
index 40150f3..4f1279e 100644 (file)
@@ -850,6 +850,7 @@ struct perf_event_context {
        int                             nr_active;
        int                             is_active;
        int                             nr_stat;
+       int                             rotate_disable;
        atomic_t                        refcount;
        struct task_struct              *task;
 
@@ -886,6 +887,7 @@ struct perf_cpu_context {
        int                             exclusive;
        struct list_head                rotation_list;
        int                             jiffies_interval;
+       struct pmu                      *active_pmu;
 };
 
 struct perf_output_handle {
@@ -908,20 +910,6 @@ extern int perf_num_counters(void);
 extern const char *perf_pmu_name(void);
 extern void __perf_event_task_sched_in(struct task_struct *task);
 extern void __perf_event_task_sched_out(struct task_struct *task, struct task_struct *next);
-
-extern atomic_t perf_task_events;
-
-static inline void perf_event_task_sched_in(struct task_struct *task)
-{
-       COND_STMT(&perf_task_events, __perf_event_task_sched_in(task));
-}
-
-static inline
-void perf_event_task_sched_out(struct task_struct *task, struct task_struct *next)
-{
-       COND_STMT(&perf_task_events, __perf_event_task_sched_out(task, next));
-}
-
 extern int perf_event_init_task(struct task_struct *child);
 extern void perf_event_exit_task(struct task_struct *child);
 extern void perf_event_free_task(struct task_struct *task);
@@ -1030,6 +1018,21 @@ have_event:
        __perf_sw_event(event_id, nr, nmi, regs, addr);
 }
 
+extern atomic_t perf_task_events;
+
+static inline void perf_event_task_sched_in(struct task_struct *task)
+{
+       COND_STMT(&perf_task_events, __perf_event_task_sched_in(task));
+}
+
+static inline
+void perf_event_task_sched_out(struct task_struct *task, struct task_struct *next)
+{
+       perf_sw_event(PERF_COUNT_SW_CONTEXT_SWITCHES, 1, 1, NULL, 0);
+
+       COND_STMT(&perf_task_events, __perf_event_task_sched_out(task, next));
+}
+
 extern void perf_event_mmap(struct vm_area_struct *vma);
 extern struct perf_guest_info_callbacks *perf_guest_cbs;
 extern int perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *callbacks);
index 4457969..bb27d7e 100644 (file)
@@ -160,5 +160,6 @@ void generic_pipe_buf_release(struct pipe_inode_info *, struct pipe_buffer *);
 
 /* for F_SETPIPE_SZ and F_GETPIPE_SZ */
 long pipe_fcntl(struct file *, unsigned int, unsigned long arg);
+struct pipe_inode_info *get_pipe_info(struct file *file);
 
 #endif
index 3ec2358..d19f1cc 100644 (file)
@@ -77,7 +77,8 @@ static inline void device_set_run_wake(struct device *dev, bool enable)
 
 static inline bool pm_runtime_suspended(struct device *dev)
 {
-       return dev->power.runtime_status == RPM_SUSPENDED;
+       return dev->power.runtime_status == RPM_SUSPENDED
+               && !dev->power.disable_depth;
 }
 
 static inline void pm_runtime_mark_last_busy(struct device *dev)
index 2c79e92..2238745 100644 (file)
@@ -143,7 +143,7 @@ extern unsigned long nr_iowait_cpu(int cpu);
 extern unsigned long this_cpu_load(void);
 
 
-extern void calc_global_load(void);
+extern void calc_global_load(unsigned long ticks);
 
 extern unsigned long get_parent_ip(unsigned long addr);
 
index ebb0c80..12b2b18 100644 (file)
@@ -230,6 +230,7 @@ enum
        LINUX_MIB_TCPMINTTLDROP, /* RFC 5082 */
        LINUX_MIB_TCPDEFERACCEPTDROP,
        LINUX_MIB_IPRPFILTER, /* IP Reverse Path Filter (rp_filter) */
+       LINUX_MIB_TCPTIMEWAITOVERFLOW,          /* TCPTimeWaitOverflow */
        __LINUX_MIB_MAX
 };
 
index 942e387..eba52a1 100644 (file)
@@ -96,16 +96,21 @@ static inline bool ssb_gige_must_flush_posted_writes(struct pci_dev *pdev)
        return 0;
 }
 
-extern char * nvram_get(const char *name);
+#ifdef CONFIG_BCM47XX
+#include <asm/mach-bcm47xx/nvram.h>
 /* Get the device MAC address */
 static inline void ssb_gige_get_macaddr(struct pci_dev *pdev, u8 *macaddr)
 {
-#ifdef CONFIG_BCM47XX
-       char *res = nvram_get("et0macaddr");
-       if (res)
-               memcpy(macaddr, res, 6);
-#endif
+       char buf[20];
+       if (nvram_getenv("et0macaddr", buf, sizeof(buf)) < 0)
+               return;
+       nvram_parse_macaddr(buf, macaddr);
 }
+#else
+static inline void ssb_gige_get_macaddr(struct pci_dev *pdev, u8 *macaddr)
+{
+}
+#endif
 
 extern int ssb_gige_pcibios_plat_dev_init(struct ssb_device *sdev,
                                          struct pci_dev *pdev);
index 032d79f..54e4eaa 100644 (file)
@@ -366,6 +366,7 @@ struct tty_file_private {
 #define TTY_HUPPED             18      /* Post driver->hangup() */
 #define TTY_FLUSHING           19      /* Flushing to ldisc in progress */
 #define TTY_FLUSHPENDING       20      /* Queued buffer flush pending */
+#define TTY_HUPPING            21      /* ->hangup() in progress */
 
 #define TTY_WRITE_FLUSH(tty) tty_write_flush((tty))
 
index d6188e5..665517c 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright(C) 2005, Benedikt Spranger <b.spranger@linutronix.de>
  * Copyright(C) 2005, Thomas Gleixner <tglx@linutronix.de>
- * Copyright(C) 2006, Hans J. Koch <hjk@linutronix.de>
+ * Copyright(C) 2006, Hans J. Koch <hjk@hansjkoch.de>
  * Copyright(C) 2006, Greg Kroah-Hartman <greg@kroah.com>
  *
  * Userspace IO driver.
index 24300d8..a28eb25 100644 (file)
@@ -313,6 +313,10 @@ struct usb_bus {
        int busnum;                     /* Bus number (in order of reg) */
        const char *bus_name;           /* stable id (PCI slot_name etc) */
        u8 uses_dma;                    /* Does the host controller use DMA? */
+       u8 uses_pio_for_control;        /*
+                                        * Does the host controller use PIO
+                                        * for control transfers?
+                                        */
        u8 otg_port;                    /* 0, or number of OTG/HNP port */
        unsigned is_b_host:1;           /* true during some HNP roleswitches */
        unsigned b_hnp_enable:1;        /* OTG: did A-Host enable HNP? */
index 2fb46bc..ed5cdeb 100644 (file)
@@ -23,6 +23,7 @@
 #ifndef _LINUX_VIDEO_OUTPUT_H
 #define _LINUX_VIDEO_OUTPUT_H
 #include <linux/device.h>
+#include <linux/err.h>
 struct output_device;
 struct output_properties {
        int (*set_state)(struct output_device *);
@@ -34,9 +35,23 @@ struct output_device {
        struct device dev;
 };
 #define to_output_device(obj) container_of(obj, struct output_device, dev)
+#if    defined(CONFIG_VIDEO_OUTPUT_CONTROL) || defined(CONFIG_VIDEO_OUTPUT_CONTROL_MODULE)
 struct output_device *video_output_register(const char *name,
        struct device *dev,
        void *devdata,
        struct output_properties *op);
 void video_output_unregister(struct output_device *dev);
+#else
+static struct output_device *video_output_register(const char *name,
+        struct device *dev,
+        void *devdata,
+        struct output_properties *op)
+{
+       return ERR_PTR(-ENODEV);
+}
+static void video_output_unregister(struct output_device *dev)
+{
+       return;
+}
+#endif
 #endif
index a03dcf6..44b54f6 100644 (file)
@@ -7,8 +7,6 @@
 
 struct vm_area_struct;         /* vma defining user mapping in mm_types.h */
 
-extern bool vmap_lazy_unmap;
-
 /* bits in flags of vmalloc's vm_struct below */
 #define VM_IOREMAP     0x00000001      /* ioremap() and friends */
 #define VM_ALLOC       0x00000002      /* vmalloc() */
index 41dd480..239125a 100644 (file)
@@ -137,31 +137,27 @@ struct v4l2_subdev_ops;
 
 
 /* Load an i2c module and return an initialized v4l2_subdev struct.
-   Only call request_module if module_name != NULL.
    The client_type argument is the name of the chip that's on the adapter. */
 struct v4l2_subdev *v4l2_i2c_new_subdev_cfg(struct v4l2_device *v4l2_dev,
-               struct i2c_adapter *adapter,
-               const char *module_name, const char *client_type,
+               struct i2c_adapter *adapter, const char *client_type,
                int irq, void *platform_data,
                u8 addr, const unsigned short *probe_addrs);
 
 /* Load an i2c module and return an initialized v4l2_subdev struct.
-   Only call request_module if module_name != NULL.
    The client_type argument is the name of the chip that's on the adapter. */
 static inline struct v4l2_subdev *v4l2_i2c_new_subdev(struct v4l2_device *v4l2_dev,
-               struct i2c_adapter *adapter,
-               const char *module_name, const char *client_type,
+               struct i2c_adapter *adapter, const char *client_type,
                u8 addr, const unsigned short *probe_addrs)
 {
-       return v4l2_i2c_new_subdev_cfg(v4l2_dev, adapter, module_name,
-                               client_type, 0, NULL, addr, probe_addrs);
+       return v4l2_i2c_new_subdev_cfg(v4l2_dev, adapter, client_type, 0, NULL,
+                                      addr, probe_addrs);
 }
 
 struct i2c_board_info;
 
 struct v4l2_subdev *v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev,
-               struct i2c_adapter *adapter, const char *module_name,
-               struct i2c_board_info *info, const unsigned short *probe_addrs);
+               struct i2c_adapter *adapter, struct i2c_board_info *info,
+               const unsigned short *probe_addrs);
 
 /* Initialize an v4l2_subdev with data from an i2c_client struct */
 void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client,
index 6648036..b16f307 100644 (file)
@@ -51,6 +51,8 @@ struct v4l2_device {
                        unsigned int notification, void *arg);
        /* The control handler. May be NULL. */
        struct v4l2_ctrl_handler *ctrl_handler;
+       /* BKL replacement mutex. Temporary solution only. */
+       struct mutex ioctl_lock;
 };
 
 /* Initialize v4l2_dev and make dev->driver_data point to v4l2_dev.
index 90c9e28..18e5c3f 100644 (file)
@@ -10,6 +10,7 @@ extern void unix_inflight(struct file *fp);
 extern void unix_notinflight(struct file *fp);
 extern void unix_gc(void);
 extern void wait_for_unix_gc(void);
+extern struct sock *unix_get_socket(struct file *filp);
 
 #define UNIX_HASH_SIZE 256
 
@@ -56,6 +57,7 @@ struct unix_sock {
        spinlock_t              lock;
        unsigned int            gc_candidate : 1;
        unsigned int            gc_maybe_cycle : 1;
+       unsigned char           recursion_level;
        struct socket_wq        peer_wq;
 };
 #define unix_sk(__sk) ((struct unix_sock *)__sk)
index a6338d0..659d968 100644 (file)
@@ -1155,6 +1155,8 @@ extern void sk_common_release(struct sock *sk);
 /* Initialise core socket variables */
 extern void sock_init_data(struct socket *sock, struct sock *sk);
 
+extern void sk_filter_release_rcu(struct rcu_head *rcu);
+
 /**
  *     sk_filter_release - release a socket filter
  *     @fp: filter to remove
@@ -1165,7 +1167,7 @@ extern void sock_init_data(struct socket *sock, struct sock *sk);
 static inline void sk_filter_release(struct sk_filter *fp)
 {
        if (atomic_dec_and_test(&fp->refcnt))
-               kfree(fp);
+               call_rcu_bh(&fp->rcu, sk_filter_release_rcu);
 }
 
 static inline void sk_filter_uncharge(struct sock *sk, struct sk_filter *fp)
index 646dd17..00f53dd 100644 (file)
@@ -76,7 +76,9 @@ int xen_map_pirq_gsi(unsigned pirq, unsigned gsi, int shareable, char *name);
 
 #ifdef CONFIG_PCI_MSI
 /* Allocate an irq and a pirq to be used with MSIs. */
-void xen_allocate_pirq_msi(char *name, int *irq, int *pirq);
+#define XEN_ALLOC_PIRQ (1 << 0)
+#define XEN_ALLOC_IRQ  (1 << 1)
+void xen_allocate_pirq_msi(char *name, int *irq, int *pirq, int alloc_mask);
 int xen_create_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int type);
 #endif
 
@@ -89,4 +91,7 @@ int xen_vector_from_irq(unsigned pirq);
 /* Return gsi allocated to pirq */
 int xen_gsi_from_irq(unsigned pirq);
 
+/* Return irq from pirq */
+int xen_irq_from_pirq(unsigned pirq);
+
 #endif /* _XEN_EVENTS_H */
index e8cbf43..75271b9 100644 (file)
@@ -24,8 +24,15 @@ typedef unsigned int RING_IDX;
  * A ring contains as many entries as will fit, rounded down to the nearest
  * power of two (so we can mask with (size-1) to loop around).
  */
-#define __RING_SIZE(_s, _sz) \
-    (__RD32(((_sz) - (long)&(_s)->ring + (long)(_s)) / sizeof((_s)->ring[0])))
+#define __CONST_RING_SIZE(_s, _sz)                             \
+       (__RD32(((_sz) - offsetof(struct _s##_sring, ring)) /   \
+               sizeof(((struct _s##_sring *)0)->ring[0])))
+
+/*
+ * The same for passing in an actual pointer instead of a name tag.
+ */
+#define __RING_SIZE(_s, _sz)                                           \
+       (__RD32(((_sz) - (long)&(_s)->ring + (long)(_s)) / sizeof((_s)->ring[0])))
 
 /*
  * Macros to make the correct C datatypes for a new kind of ring.
index 2b2c66c..534cac8 100644 (file)
@@ -188,6 +188,16 @@ struct physdev_nr_pirqs {
     uint32_t nr_pirqs;
 };
 
+/* type is MAP_PIRQ_TYPE_GSI or MAP_PIRQ_TYPE_MSI
+ * the hypercall returns a free pirq */
+#define PHYSDEVOP_get_free_pirq    23
+struct physdev_get_free_pirq {
+    /* IN */ 
+    int type;
+    /* OUT */
+    uint32_t pirq;
+};
+
 /*
  * Notify that some PIRQ-bound event channels have been unmasked.
  * ** This command is obsolete since interface version 0x00030202 and is **
index 21aa7b3..676149a 100644 (file)
@@ -914,6 +914,15 @@ NORET_TYPE void do_exit(long code)
        if (unlikely(!tsk->pid))
                panic("Attempted to kill the idle task!");
 
+       /*
+        * If do_exit is called because this processes oopsed, it's possible
+        * that get_fs() was left as KERNEL_DS, so reset it to USER_DS before
+        * continuing. Amongst other possible reasons, this is to prevent
+        * mm_release()->clear_child_tid() from writing to a user-controlled
+        * kernel address.
+        */
+       set_fs(USER_DS);
+
        tracehook_report_exit(&code);
 
        validate_creds_for_do_exit(tsk);
index 3b159c5..5447dc7 100644 (file)
@@ -273,6 +273,7 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
 
        setup_thread_stack(tsk, orig);
        clear_user_return_notifier(tsk);
+       clear_tsk_need_resched(tsk);
        stackend = end_of_stack(tsk);
        *stackend = STACK_END_MAGIC;    /* for overflow detection */
 
index 01b1d3a..6c8a2a9 100644 (file)
@@ -214,7 +214,7 @@ static int irq_spurious_proc_show(struct seq_file *m, void *v)
 
 static int irq_spurious_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, irq_spurious_proc_show, NULL);
+       return single_open(file, irq_spurious_proc_show, PDE(inode)->data);
 }
 
 static const struct file_operations irq_spurious_proc_fops = {
index 671f6c8..2870fee 100644 (file)
@@ -1287,8 +1287,6 @@ void __perf_event_task_sched_out(struct task_struct *task,
 {
        int ctxn;
 
-       perf_sw_event(PERF_COUNT_SW_CONTEXT_SWITCHES, 1, 1, NULL, 0);
-
        for_each_task_context_nr(ctxn)
                perf_event_context_sched_out(task, ctxn, next);
 }
@@ -1622,8 +1620,12 @@ static void rotate_ctx(struct perf_event_context *ctx)
 {
        raw_spin_lock(&ctx->lock);
 
-       /* Rotate the first entry last of non-pinned groups */
-       list_rotate_left(&ctx->flexible_groups);
+       /*
+        * Rotate the first entry last of non-pinned groups. Rotation might be
+        * disabled by the inheritance code.
+        */
+       if (!ctx->rotate_disable)
+               list_rotate_left(&ctx->flexible_groups);
 
        raw_spin_unlock(&ctx->lock);
 }
@@ -3822,6 +3824,8 @@ static void perf_event_task_event(struct perf_task_event *task_event)
        rcu_read_lock();
        list_for_each_entry_rcu(pmu, &pmus, entry) {
                cpuctx = get_cpu_ptr(pmu->pmu_cpu_context);
+               if (cpuctx->active_pmu != pmu)
+                       goto next;
                perf_event_task_ctx(&cpuctx->ctx, task_event);
 
                ctx = task_event->task_ctx;
@@ -3957,6 +3961,8 @@ static void perf_event_comm_event(struct perf_comm_event *comm_event)
        rcu_read_lock();
        list_for_each_entry_rcu(pmu, &pmus, entry) {
                cpuctx = get_cpu_ptr(pmu->pmu_cpu_context);
+               if (cpuctx->active_pmu != pmu)
+                       goto next;
                perf_event_comm_ctx(&cpuctx->ctx, comm_event);
 
                ctxn = pmu->task_ctx_nr;
@@ -4142,6 +4148,8 @@ got_name:
        rcu_read_lock();
        list_for_each_entry_rcu(pmu, &pmus, entry) {
                cpuctx = get_cpu_ptr(pmu->pmu_cpu_context);
+               if (cpuctx->active_pmu != pmu)
+                       goto next;
                perf_event_mmap_ctx(&cpuctx->ctx, mmap_event,
                                        vma->vm_flags & VM_EXEC);
 
@@ -4711,7 +4719,7 @@ static int perf_swevent_init(struct perf_event *event)
                break;
        }
 
-       if (event_id > PERF_COUNT_SW_MAX)
+       if (event_id >= PERF_COUNT_SW_MAX)
                return -ENOENT;
 
        if (!event->parent) {
@@ -5143,20 +5151,36 @@ static void *find_pmu_context(int ctxn)
        return NULL;
 }
 
-static void free_pmu_context(void * __percpu cpu_context)
+static void update_pmu_context(struct pmu *pmu, struct pmu *old_pmu)
 {
-       struct pmu *pmu;
+       int cpu;
+
+       for_each_possible_cpu(cpu) {
+               struct perf_cpu_context *cpuctx;
+
+               cpuctx = per_cpu_ptr(pmu->pmu_cpu_context, cpu);
+
+               if (cpuctx->active_pmu == old_pmu)
+                       cpuctx->active_pmu = pmu;
+       }
+}
+
+static void free_pmu_context(struct pmu *pmu)
+{
+       struct pmu *i;
 
        mutex_lock(&pmus_lock);
        /*
         * Like a real lame refcount.
         */
-       list_for_each_entry(pmu, &pmus, entry) {
-               if (pmu->pmu_cpu_context == cpu_context)
+       list_for_each_entry(i, &pmus, entry) {
+               if (i->pmu_cpu_context == pmu->pmu_cpu_context) {
+                       update_pmu_context(i, pmu);
                        goto out;
+               }
        }
 
-       free_percpu(cpu_context);
+       free_percpu(pmu->pmu_cpu_context);
 out:
        mutex_unlock(&pmus_lock);
 }
@@ -5188,6 +5212,7 @@ int perf_pmu_register(struct pmu *pmu)
                cpuctx->ctx.pmu = pmu;
                cpuctx->jiffies_interval = 1;
                INIT_LIST_HEAD(&cpuctx->rotation_list);
+               cpuctx->active_pmu = pmu;
        }
 
 got_cpu_context:
@@ -5239,7 +5264,7 @@ void perf_pmu_unregister(struct pmu *pmu)
        synchronize_rcu();
 
        free_percpu(pmu->pmu_disable_count);
-       free_pmu_context(pmu->pmu_cpu_context);
+       free_pmu_context(pmu);
 }
 
 struct pmu *perf_init_event(struct perf_event *event)
@@ -6162,6 +6187,7 @@ int perf_event_init_context(struct task_struct *child, int ctxn)
        struct perf_event *event;
        struct task_struct *parent = current;
        int inherited_all = 1;
+       unsigned long flags;
        int ret = 0;
 
        child->perf_event_ctxp[ctxn] = NULL;
@@ -6202,6 +6228,15 @@ int perf_event_init_context(struct task_struct *child, int ctxn)
                        break;
        }
 
+       /*
+        * We can't hold ctx->lock when iterating the ->flexible_group list due
+        * to allocations, but we need to prevent rotation because
+        * rotate_ctx() will change the list from interrupt context.
+        */
+       raw_spin_lock_irqsave(&parent_ctx->lock, flags);
+       parent_ctx->rotate_disable = 1;
+       raw_spin_unlock_irqrestore(&parent_ctx->lock, flags);
+
        list_for_each_entry(event, &parent_ctx->flexible_groups, group_entry) {
                ret = inherit_task_group(event, parent, parent_ctx,
                                         child, ctxn, &inherited_all);
@@ -6209,6 +6244,10 @@ int perf_event_init_context(struct task_struct *child, int ctxn)
                        break;
        }
 
+       raw_spin_lock_irqsave(&parent_ctx->lock, flags);
+       parent_ctx->rotate_disable = 0;
+       raw_spin_unlock_irqrestore(&parent_ctx->lock, flags);
+
        child_ctx = child->perf_event_ctxp[ctxn];
 
        if (child_ctx && inherited_all) {
index 657272e..048d0b5 100644 (file)
@@ -327,7 +327,6 @@ static int create_image(int platform_mode)
 int hibernation_snapshot(int platform_mode)
 {
        int error;
-       gfp_t saved_mask;
 
        error = platform_begin(platform_mode);
        if (error)
@@ -339,7 +338,7 @@ int hibernation_snapshot(int platform_mode)
                goto Close;
 
        suspend_console();
-       saved_mask = clear_gfp_allowed_mask(GFP_IOFS);
+       pm_restrict_gfp_mask();
        error = dpm_suspend_start(PMSG_FREEZE);
        if (error)
                goto Recover_platform;
@@ -348,7 +347,10 @@ int hibernation_snapshot(int platform_mode)
                goto Recover_platform;
 
        error = create_image(platform_mode);
-       /* Control returns here after successful restore */
+       /*
+        * Control returns here (1) after the image has been created or the
+        * image creation has failed and (2) after a successful restore.
+        */
 
  Resume_devices:
        /* We may need to release the preallocated image pages here. */
@@ -357,7 +359,10 @@ int hibernation_snapshot(int platform_mode)
 
        dpm_resume_end(in_suspend ?
                (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE);
-       set_gfp_allowed_mask(saved_mask);
+
+       if (error || !in_suspend)
+               pm_restore_gfp_mask();
+
        resume_console();
  Close:
        platform_end(platform_mode);
@@ -452,17 +457,16 @@ static int resume_target_kernel(bool platform_mode)
 int hibernation_restore(int platform_mode)
 {
        int error;
-       gfp_t saved_mask;
 
        pm_prepare_console();
        suspend_console();
-       saved_mask = clear_gfp_allowed_mask(GFP_IOFS);
+       pm_restrict_gfp_mask();
        error = dpm_suspend_start(PMSG_QUIESCE);
        if (!error) {
                error = resume_target_kernel(platform_mode);
                dpm_resume_end(PMSG_RECOVER);
        }
-       set_gfp_allowed_mask(saved_mask);
+       pm_restore_gfp_mask();
        resume_console();
        pm_restore_console();
        return error;
@@ -476,7 +480,6 @@ int hibernation_restore(int platform_mode)
 int hibernation_platform_enter(void)
 {
        int error;
-       gfp_t saved_mask;
 
        if (!hibernation_ops)
                return -ENOSYS;
@@ -492,7 +495,6 @@ int hibernation_platform_enter(void)
 
        entering_platform_hibernation = true;
        suspend_console();
-       saved_mask = clear_gfp_allowed_mask(GFP_IOFS);
        error = dpm_suspend_start(PMSG_HIBERNATE);
        if (error) {
                if (hibernation_ops->recover)
@@ -536,7 +538,6 @@ int hibernation_platform_enter(void)
  Resume_devices:
        entering_platform_hibernation = false;
        dpm_resume_end(PMSG_RESTORE);
-       set_gfp_allowed_mask(saved_mask);
        resume_console();
 
  Close:
@@ -646,6 +647,7 @@ int hibernate(void)
                swsusp_free();
                if (!error)
                        power_down();
+               pm_restore_gfp_mask();
        } else {
                pr_debug("PM: Image restored successfully.\n");
        }
index 7335952..ecf7705 100644 (file)
@@ -197,7 +197,6 @@ static int suspend_enter(suspend_state_t state)
 int suspend_devices_and_enter(suspend_state_t state)
 {
        int error;
-       gfp_t saved_mask;
 
        if (!suspend_ops)
                return -ENOSYS;
@@ -208,7 +207,7 @@ int suspend_devices_and_enter(suspend_state_t state)
                        goto Close;
        }
        suspend_console();
-       saved_mask = clear_gfp_allowed_mask(GFP_IOFS);
+       pm_restrict_gfp_mask();
        suspend_test_start();
        error = dpm_suspend_start(PMSG_SUSPEND);
        if (error) {
@@ -225,7 +224,7 @@ int suspend_devices_and_enter(suspend_state_t state)
        suspend_test_start();
        dpm_resume_end(PMSG_RESUME);
        suspend_test_finish("resume devices");
-       set_gfp_allowed_mask(saved_mask);
+       pm_restore_gfp_mask();
        resume_console();
  Close:
        if (suspend_ops->end)
index a0e4a86..8c7e483 100644 (file)
@@ -6,6 +6,7 @@
  *
  * Copyright (C) 1998,2001-2005 Pavel Machek <pavel@ucw.cz>
  * Copyright (C) 2006 Rafael J. Wysocki <rjw@sisk.pl>
+ * Copyright (C) 2010 Bojan Smojver <bojan@rexursive.com>
  *
  * This file is released under the GPLv2.
  *
@@ -29,7 +30,7 @@
 
 #include "power.h"
 
-#define HIBERNATE_SIG  "LINHIB0001"
+#define HIBERNATE_SIG  "S1SUSPEND"
 
 /*
  *     The swap map is a data structure used for keeping track of each page
@@ -753,30 +754,43 @@ static int load_image_lzo(struct swap_map_handle *handle,
 {
        unsigned int m;
        int error = 0;
+       struct bio *bio;
        struct timeval start;
        struct timeval stop;
        unsigned nr_pages;
-       size_t off, unc_len, cmp_len;
-       unsigned char *unc, *cmp, *page;
+       size_t i, off, unc_len, cmp_len;
+       unsigned char *unc, *cmp, *page[LZO_CMP_PAGES];
 
-       page = (void *)__get_free_page(__GFP_WAIT | __GFP_HIGH);
-       if (!page) {
-               printk(KERN_ERR "PM: Failed to allocate LZO page\n");
-               return -ENOMEM;
+       for (i = 0; i < LZO_CMP_PAGES; i++) {
+               page[i] = (void *)__get_free_page(__GFP_WAIT | __GFP_HIGH);
+               if (!page[i]) {
+                       printk(KERN_ERR "PM: Failed to allocate LZO page\n");
+
+                       while (i)
+                               free_page((unsigned long)page[--i]);
+
+                       return -ENOMEM;
+               }
        }
 
        unc = vmalloc(LZO_UNC_SIZE);
        if (!unc) {
                printk(KERN_ERR "PM: Failed to allocate LZO uncompressed\n");
-               free_page((unsigned long)page);
+
+               for (i = 0; i < LZO_CMP_PAGES; i++)
+                       free_page((unsigned long)page[i]);
+
                return -ENOMEM;
        }
 
        cmp = vmalloc(LZO_CMP_SIZE);
        if (!cmp) {
                printk(KERN_ERR "PM: Failed to allocate LZO compressed\n");
+
                vfree(unc);
-               free_page((unsigned long)page);
+               for (i = 0; i < LZO_CMP_PAGES; i++)
+                       free_page((unsigned long)page[i]);
+
                return -ENOMEM;
        }
 
@@ -787,6 +801,7 @@ static int load_image_lzo(struct swap_map_handle *handle,
        if (!m)
                m = 1;
        nr_pages = 0;
+       bio = NULL;
        do_gettimeofday(&start);
 
        error = snapshot_write_next(snapshot);
@@ -794,11 +809,11 @@ static int load_image_lzo(struct swap_map_handle *handle,
                goto out_finish;
 
        for (;;) {
-               error = swap_read_page(handle, page, NULL); /* sync */
+               error = swap_read_page(handle, page[0], NULL); /* sync */
                if (error)
                        break;
 
-               cmp_len = *(size_t *)page;
+               cmp_len = *(size_t *)page[0];
                if (unlikely(!cmp_len ||
                             cmp_len > lzo1x_worst_compress(LZO_UNC_SIZE))) {
                        printk(KERN_ERR "PM: Invalid LZO compressed length\n");
@@ -806,13 +821,20 @@ static int load_image_lzo(struct swap_map_handle *handle,
                        break;
                }
 
-               memcpy(cmp, page, PAGE_SIZE);
-               for (off = PAGE_SIZE; off < LZO_HEADER + cmp_len; off += PAGE_SIZE) {
-                       error = swap_read_page(handle, page, NULL); /* sync */
+               for (off = PAGE_SIZE, i = 1;
+                    off < LZO_HEADER + cmp_len; off += PAGE_SIZE, i++) {
+                       error = swap_read_page(handle, page[i], &bio);
                        if (error)
                                goto out_finish;
+               }
 
-                       memcpy(cmp + off, page, PAGE_SIZE);
+               error = hib_wait_on_bio_chain(&bio); /* need all data now */
+               if (error)
+                       goto out_finish;
+
+               for (off = 0, i = 0;
+                    off < LZO_HEADER + cmp_len; off += PAGE_SIZE, i++) {
+                       memcpy(cmp + off, page[i], PAGE_SIZE);
                }
 
                unc_len = LZO_UNC_SIZE;
@@ -857,7 +879,8 @@ out_finish:
 
        vfree(cmp);
        vfree(unc);
-       free_page((unsigned long)page);
+       for (i = 0; i < LZO_CMP_PAGES; i++)
+               free_page((unsigned long)page[i]);
 
        return error;
 }
index e819e17..c36c3b9 100644 (file)
@@ -137,7 +137,7 @@ static int snapshot_release(struct inode *inode, struct file *filp)
        free_all_swap_pages(data->swap);
        if (data->frozen)
                thaw_processes();
-       pm_notifier_call_chain(data->mode == O_WRONLY ?
+       pm_notifier_call_chain(data->mode == O_RDONLY ?
                        PM_POST_HIBERNATION : PM_POST_RESTORE);
        atomic_inc(&snapshot_device_available);
 
@@ -263,6 +263,7 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
        case SNAPSHOT_UNFREEZE:
                if (!data->frozen || data->ready)
                        break;
+               pm_restore_gfp_mask();
                thaw_processes();
                usermodehelper_enable();
                data->frozen = 0;
@@ -275,6 +276,7 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
                        error = -EPERM;
                        break;
                }
+               pm_restore_gfp_mask();
                error = hibernation_snapshot(data->platform_support);
                if (!error)
                        error = put_user(in_suspend, (int __user *)arg);
index 9a2264f..a23315d 100644 (file)
@@ -1082,13 +1082,15 @@ void printk_tick(void)
 
 int printk_needs_cpu(int cpu)
 {
+       if (unlikely(cpu_is_offline(cpu)))
+               printk_tick();
        return per_cpu(printk_pending, cpu);
 }
 
 void wake_up_klogd(void)
 {
        if (waitqueue_active(&log_wait))
-               __raw_get_cpu_var(printk_pending) = 1;
+               this_cpu_write(printk_pending, 1);
 }
 
 /**
index 9fad33e..798e2fa 100644 (file)
@@ -40,23 +40,6 @@ EXPORT_SYMBOL(iomem_resource);
 
 static DEFINE_RWLOCK(resource_lock);
 
-/*
- * By default, we allocate free space bottom-up.  The architecture can request
- * top-down by clearing this flag.  The user can override the architecture's
- * choice with the "resource_alloc_from_bottom" kernel boot option, but that
- * should only be a debugging tool.
- */
-int resource_alloc_from_bottom = 1;
-
-static __init int setup_alloc_from_bottom(char *s)
-{
-       printk(KERN_INFO
-              "resource: allocating from bottom-up; please report a bug\n");
-       resource_alloc_from_bottom = 1;
-       return 0;
-}
-early_param("resource_alloc_from_bottom", setup_alloc_from_bottom);
-
 static void *r_next(struct seq_file *m, void *v, loff_t *pos)
 {
        struct resource *p = v;
@@ -374,6 +357,10 @@ int __weak page_is_ram(unsigned long pfn)
        return walk_system_ram_range(pfn, 1, NULL, __is_ram) == 1;
 }
 
+void __weak arch_remove_reservations(struct resource *avail)
+{
+}
+
 static resource_size_t simple_align_resource(void *data,
                                             const struct resource *avail,
                                             resource_size_t size,
@@ -396,75 +383,8 @@ static bool resource_contains(struct resource *res1, struct resource *res2)
        return res1->start <= res2->start && res1->end >= res2->end;
 }
 
-/*
- * Find the resource before "child" in the sibling list of "root" children.
- */
-static struct resource *find_sibling_prev(struct resource *root, struct resource *child)
-{
-       struct resource *this;
-
-       for (this = root->child; this; this = this->sibling)
-               if (this->sibling == child)
-                       return this;
-
-       return NULL;
-}
-
 /*
  * Find empty slot in the resource tree given range and alignment.
- * This version allocates from the end of the root resource first.
- */
-static int find_resource_from_top(struct resource *root, struct resource *new,
-                                 resource_size_t size, resource_size_t min,
-                                 resource_size_t max, resource_size_t align,
-                                 resource_size_t (*alignf)(void *,
-                                                  const struct resource *,
-                                                  resource_size_t,
-                                                  resource_size_t),
-                                 void *alignf_data)
-{
-       struct resource *this;
-       struct resource tmp, avail, alloc;
-
-       tmp.start = root->end;
-       tmp.end = root->end;
-
-       this = find_sibling_prev(root, NULL);
-       for (;;) {
-               if (this) {
-                       if (this->end < root->end)
-                               tmp.start = this->end + 1;
-               } else
-                       tmp.start = root->start;
-
-               resource_clip(&tmp, min, max);
-
-               /* Check for overflow after ALIGN() */
-               avail = *new;
-               avail.start = ALIGN(tmp.start, align);
-               avail.end = tmp.end;
-               if (avail.start >= tmp.start) {
-                       alloc.start = alignf(alignf_data, &avail, size, align);
-                       alloc.end = alloc.start + size - 1;
-                       if (resource_contains(&avail, &alloc)) {
-                               new->start = alloc.start;
-                               new->end = alloc.end;
-                               return 0;
-                       }
-               }
-
-               if (!this || this->start == root->start)
-                       break;
-
-               tmp.end = this->start - 1;
-               this = find_sibling_prev(root, this);
-       }
-       return -EBUSY;
-}
-
-/*
- * Find empty slot in the resource tree given range and alignment.
- * This version allocates from the beginning of the root resource first.
  */
 static int find_resource(struct resource *root, struct resource *new,
                         resource_size_t size, resource_size_t min,
@@ -478,23 +398,24 @@ static int find_resource(struct resource *root, struct resource *new,
        struct resource *this = root->child;
        struct resource tmp = *new, avail, alloc;
 
+       tmp.flags = new->flags;
        tmp.start = root->start;
        /*
-        * Skip past an allocated resource that starts at 0, since the
-        * assignment of this->start - 1 to tmp->end below would cause an
-        * underflow.
+        * Skip past an allocated resource that starts at 0, since the assignment
+        * of this->start - 1 to tmp->end below would cause an underflow.
         */
        if (this && this->start == 0) {
                tmp.start = this->end + 1;
                this = this->sibling;
        }
-       for (;;) {
+       for(;;) {
                if (this)
                        tmp.end = this->start - 1;
                else
                        tmp.end = root->end;
 
                resource_clip(&tmp, min, max);
+               arch_remove_reservations(&tmp);
 
                /* Check for overflow after ALIGN() */
                avail = *new;
@@ -509,10 +430,8 @@ static int find_resource(struct resource *root, struct resource *new,
                                return 0;
                        }
                }
-
                if (!this)
                        break;
-
                tmp.start = this->end + 1;
                this = this->sibling;
        }
@@ -545,10 +464,7 @@ int allocate_resource(struct resource *root, struct resource *new,
                alignf = simple_align_resource;
 
        write_lock(&resource_lock);
-       if (resource_alloc_from_bottom)
-               err = find_resource(root, new, size, min, max, align, alignf, alignf_data);
-       else
-               err = find_resource_from_top(root, new, size, min, max, align, alignf, alignf_data);
+       err = find_resource(root, new, size, min, max, align, alignf, alignf_data);
        if (err >= 0 && __request_resource(root, new))
                err = -EBUSY;
        write_unlock(&resource_lock);
index dc91a4d..297d1a0 100644 (file)
@@ -636,22 +636,18 @@ static inline struct task_group *task_group(struct task_struct *p)
 
 #endif /* CONFIG_CGROUP_SCHED */
 
-static u64 irq_time_cpu(int cpu);
-static void sched_irq_time_avg_update(struct rq *rq, u64 irq_time);
+static void update_rq_clock_task(struct rq *rq, s64 delta);
 
-inline void update_rq_clock(struct rq *rq)
+static void update_rq_clock(struct rq *rq)
 {
-       if (!rq->skip_clock_update) {
-               int cpu = cpu_of(rq);
-               u64 irq_time;
+       s64 delta;
 
-               rq->clock = sched_clock_cpu(cpu);
-               irq_time = irq_time_cpu(cpu);
-               if (rq->clock - irq_time > rq->clock_task)
-                       rq->clock_task = rq->clock - irq_time;
+       if (rq->skip_clock_update)
+               return;
 
-               sched_irq_time_avg_update(rq, irq_time);
-       }
+       delta = sched_clock_cpu(cpu_of(rq)) - rq->clock;
+       rq->clock += delta;
+       update_rq_clock_task(rq, delta);
 }
 
 /*
@@ -1924,10 +1920,9 @@ static void deactivate_task(struct rq *rq, struct task_struct *p, int flags)
  * They are read and saved off onto struct rq in update_rq_clock().
  * This may result in other CPU reading this CPU's irq time and can
  * race with irq/account_system_vtime on this CPU. We would either get old
- * or new value (or semi updated value on 32 bit) with a side effect of
- * accounting a slice of irq time to wrong task when irq is in progress
- * while we read rq->clock. That is a worthy compromise in place of having
- * locks on each irq in account_system_time.
+ * or new value with a side effect of accounting a slice of irq time to wrong
+ * task when irq is in progress while we read rq->clock. That is a worthy
+ * compromise in place of having locks on each irq in account_system_time.
  */
 static DEFINE_PER_CPU(u64, cpu_hardirq_time);
 static DEFINE_PER_CPU(u64, cpu_softirq_time);
@@ -1945,19 +1940,58 @@ void disable_sched_clock_irqtime(void)
        sched_clock_irqtime = 0;
 }
 
-static u64 irq_time_cpu(int cpu)
+#ifndef CONFIG_64BIT
+static DEFINE_PER_CPU(seqcount_t, irq_time_seq);
+
+static inline void irq_time_write_begin(void)
 {
-       if (!sched_clock_irqtime)
-               return 0;
+       __this_cpu_inc(irq_time_seq.sequence);
+       smp_wmb();
+}
+
+static inline void irq_time_write_end(void)
+{
+       smp_wmb();
+       __this_cpu_inc(irq_time_seq.sequence);
+}
+
+static inline u64 irq_time_read(int cpu)
+{
+       u64 irq_time;
+       unsigned seq;
 
+       do {
+               seq = read_seqcount_begin(&per_cpu(irq_time_seq, cpu));
+               irq_time = per_cpu(cpu_softirq_time, cpu) +
+                          per_cpu(cpu_hardirq_time, cpu);
+       } while (read_seqcount_retry(&per_cpu(irq_time_seq, cpu), seq));
+
+       return irq_time;
+}
+#else /* CONFIG_64BIT */
+static inline void irq_time_write_begin(void)
+{
+}
+
+static inline void irq_time_write_end(void)
+{
+}
+
+static inline u64 irq_time_read(int cpu)
+{
        return per_cpu(cpu_softirq_time, cpu) + per_cpu(cpu_hardirq_time, cpu);
 }
+#endif /* CONFIG_64BIT */
 
+/*
+ * Called before incrementing preempt_count on {soft,}irq_enter
+ * and before decrementing preempt_count on {soft,}irq_exit.
+ */
 void account_system_vtime(struct task_struct *curr)
 {
        unsigned long flags;
+       s64 delta;
        int cpu;
-       u64 now, delta;
 
        if (!sched_clock_irqtime)
                return;
@@ -1965,9 +1999,10 @@ void account_system_vtime(struct task_struct *curr)
        local_irq_save(flags);
 
        cpu = smp_processor_id();
-       now = sched_clock_cpu(cpu);
-       delta = now - per_cpu(irq_start_time, cpu);
-       per_cpu(irq_start_time, cpu) = now;
+       delta = sched_clock_cpu(cpu) - __this_cpu_read(irq_start_time);
+       __this_cpu_add(irq_start_time, delta);
+
+       irq_time_write_begin();
        /*
         * We do not account for softirq time from ksoftirqd here.
         * We want to continue accounting softirq time to ksoftirqd thread
@@ -1975,33 +2010,55 @@ void account_system_vtime(struct task_struct *curr)
         * that do not consume any time, but still wants to run.
         */
        if (hardirq_count())
-               per_cpu(cpu_hardirq_time, cpu) += delta;
+               __this_cpu_add(cpu_hardirq_time, delta);
        else if (in_serving_softirq() && !(curr->flags & PF_KSOFTIRQD))
-               per_cpu(cpu_softirq_time, cpu) += delta;
+               __this_cpu_add(cpu_softirq_time, delta);
 
+       irq_time_write_end();
        local_irq_restore(flags);
 }
 EXPORT_SYMBOL_GPL(account_system_vtime);
 
-static void sched_irq_time_avg_update(struct rq *rq, u64 curr_irq_time)
+static void update_rq_clock_task(struct rq *rq, s64 delta)
 {
-       if (sched_clock_irqtime && sched_feat(NONIRQ_POWER)) {
-               u64 delta_irq = curr_irq_time - rq->prev_irq_time;
-               rq->prev_irq_time = curr_irq_time;
-               sched_rt_avg_update(rq, delta_irq);
-       }
+       s64 irq_delta;
+
+       irq_delta = irq_time_read(cpu_of(rq)) - rq->prev_irq_time;
+
+       /*
+        * Since irq_time is only updated on {soft,}irq_exit, we might run into
+        * this case when a previous update_rq_clock() happened inside a
+        * {soft,}irq region.
+        *
+        * When this happens, we stop ->clock_task and only update the
+        * prev_irq_time stamp to account for the part that fit, so that a next
+        * update will consume the rest. This ensures ->clock_task is
+        * monotonic.
+        *
+        * It does however cause some slight miss-attribution of {soft,}irq
+        * time, a more accurate solution would be to update the irq_time using
+        * the current rq->clock timestamp, except that would require using
+        * atomic ops.
+        */
+       if (irq_delta > delta)
+               irq_delta = delta;
+
+       rq->prev_irq_time += irq_delta;
+       delta -= irq_delta;
+       rq->clock_task += delta;
+
+       if (irq_delta && sched_feat(NONIRQ_POWER))
+               sched_rt_avg_update(rq, irq_delta);
 }
 
-#else
+#else /* CONFIG_IRQ_TIME_ACCOUNTING */
 
-static u64 irq_time_cpu(int cpu)
+static void update_rq_clock_task(struct rq *rq, s64 delta)
 {
-       return 0;
+       rq->clock_task += delta;
 }
 
-static void sched_irq_time_avg_update(struct rq *rq, u64 curr_irq_time) { }
-
-#endif
+#endif /* CONFIG_IRQ_TIME_ACCOUNTING */
 
 #include "sched_idletask.c"
 #include "sched_fair.c"
@@ -2129,7 +2186,7 @@ static void check_preempt_curr(struct rq *rq, struct task_struct *p, int flags)
         * A queue event has occurred, and we're going to schedule.  In
         * this case, we can save a useless back to back clock update.
         */
-       if (test_tsk_need_resched(rq->curr))
+       if (rq->curr->se.on_rq && test_tsk_need_resched(rq->curr))
                rq->skip_clock_update = 1;
 }
 
@@ -3119,6 +3176,15 @@ static long calc_load_fold_active(struct rq *this_rq)
        return delta;
 }
 
+static unsigned long
+calc_load(unsigned long load, unsigned long exp, unsigned long active)
+{
+       load *= exp;
+       load += active * (FIXED_1 - exp);
+       load += 1UL << (FSHIFT - 1);
+       return load >> FSHIFT;
+}
+
 #ifdef CONFIG_NO_HZ
 /*
  * For NO_HZ we delay the active fold to the next LOAD_FREQ update.
@@ -3148,6 +3214,128 @@ static long calc_load_fold_idle(void)
 
        return delta;
 }
+
+/**
+ * fixed_power_int - compute: x^n, in O(log n) time
+ *
+ * @x:         base of the power
+ * @frac_bits: fractional bits of @x
+ * @n:         power to raise @x to.
+ *
+ * By exploiting the relation between the definition of the natural power
+ * function: x^n := x*x*...*x (x multiplied by itself for n times), and
+ * the binary encoding of numbers used by computers: n := \Sum n_i * 2^i,
+ * (where: n_i \elem {0, 1}, the binary vector representing n),
+ * we find: x^n := x^(\Sum n_i * 2^i) := \Prod x^(n_i * 2^i), which is
+ * of course trivially computable in O(log_2 n), the length of our binary
+ * vector.
+ */
+static unsigned long
+fixed_power_int(unsigned long x, unsigned int frac_bits, unsigned int n)
+{
+       unsigned long result = 1UL << frac_bits;
+
+       if (n) for (;;) {
+               if (n & 1) {
+                       result *= x;
+                       result += 1UL << (frac_bits - 1);
+                       result >>= frac_bits;
+               }
+               n >>= 1;
+               if (!n)
+                       break;
+               x *= x;
+               x += 1UL << (frac_bits - 1);
+               x >>= frac_bits;
+       }
+
+       return result;
+}
+
+/*
+ * a1 = a0 * e + a * (1 - e)
+ *
+ * a2 = a1 * e + a * (1 - e)
+ *    = (a0 * e + a * (1 - e)) * e + a * (1 - e)
+ *    = a0 * e^2 + a * (1 - e) * (1 + e)
+ *
+ * a3 = a2 * e + a * (1 - e)
+ *    = (a0 * e^2 + a * (1 - e) * (1 + e)) * e + a * (1 - e)
+ *    = a0 * e^3 + a * (1 - e) * (1 + e + e^2)
+ *
+ *  ...
+ *
+ * an = a0 * e^n + a * (1 - e) * (1 + e + ... + e^n-1) [1]
+ *    = a0 * e^n + a * (1 - e) * (1 - e^n)/(1 - e)
+ *    = a0 * e^n + a * (1 - e^n)
+ *
+ * [1] application of the geometric series:
+ *
+ *              n         1 - x^(n+1)
+ *     S_n := \Sum x^i = -------------
+ *             i=0          1 - x
+ */
+static unsigned long
+calc_load_n(unsigned long load, unsigned long exp,
+           unsigned long active, unsigned int n)
+{
+
+       return calc_load(load, fixed_power_int(exp, FSHIFT, n), active);
+}
+
+/*
+ * NO_HZ can leave us missing all per-cpu ticks calling
+ * calc_load_account_active(), but since an idle CPU folds its delta into
+ * calc_load_tasks_idle per calc_load_account_idle(), all we need to do is fold
+ * in the pending idle delta if our idle period crossed a load cycle boundary.
+ *
+ * Once we've updated the global active value, we need to apply the exponential
+ * weights adjusted to the number of cycles missed.
+ */
+static void calc_global_nohz(unsigned long ticks)
+{
+       long delta, active, n;
+
+       if (time_before(jiffies, calc_load_update))
+               return;
+
+       /*
+        * If we crossed a calc_load_update boundary, make sure to fold
+        * any pending idle changes, the respective CPUs might have
+        * missed the tick driven calc_load_account_active() update
+        * due to NO_HZ.
+        */
+       delta = calc_load_fold_idle();
+       if (delta)
+               atomic_long_add(delta, &calc_load_tasks);
+
+       /*
+        * If we were idle for multiple load cycles, apply them.
+        */
+       if (ticks >= LOAD_FREQ) {
+               n = ticks / LOAD_FREQ;
+
+               active = atomic_long_read(&calc_load_tasks);
+               active = active > 0 ? active * FIXED_1 : 0;
+
+               avenrun[0] = calc_load_n(avenrun[0], EXP_1, active, n);
+               avenrun[1] = calc_load_n(avenrun[1], EXP_5, active, n);
+               avenrun[2] = calc_load_n(avenrun[2], EXP_15, active, n);
+
+               calc_load_update += n * LOAD_FREQ;
+       }
+
+       /*
+        * Its possible the remainder of the above division also crosses
+        * a LOAD_FREQ period, the regular check in calc_global_load()
+        * which comes after this will take care of that.
+        *
+        * Consider us being 11 ticks before a cycle completion, and us
+        * sleeping for 4*LOAD_FREQ + 22 ticks, then the above code will
+        * age us 4 cycles, and the test in calc_global_load() will
+        * pick up the final one.
+        */
+}
 #else
 static void calc_load_account_idle(struct rq *this_rq)
 {
@@ -3157,6 +3345,10 @@ static inline long calc_load_fold_idle(void)
 {
        return 0;
 }
+
+static void calc_global_nohz(unsigned long ticks)
+{
+}
 #endif
 
 /**
@@ -3174,24 +3366,17 @@ void get_avenrun(unsigned long *loads, unsigned long offset, int shift)
        loads[2] = (avenrun[2] + offset) << shift;
 }
 
-static unsigned long
-calc_load(unsigned long load, unsigned long exp, unsigned long active)
-{
-       load *= exp;
-       load += active * (FIXED_1 - exp);
-       return load >> FSHIFT;
-}
-
 /*
  * calc_load - update the avenrun load estimates 10 ticks after the
  * CPUs have updated calc_load_tasks.
  */
-void calc_global_load(void)
+void calc_global_load(unsigned long ticks)
 {
-       unsigned long upd = calc_load_update + 10;
        long active;
 
-       if (time_before(jiffies, upd))
+       calc_global_nohz(ticks);
+
+       if (time_before(jiffies, calc_load_update + 10))
                return;
 
        active = atomic_long_read(&calc_load_tasks);
@@ -3845,7 +4030,6 @@ static void put_prev_task(struct rq *rq, struct task_struct *prev)
 {
        if (prev->se.on_rq)
                update_rq_clock(rq);
-       rq->skip_clock_update = 0;
        prev->sched_class->put_prev_task(rq, prev);
 }
 
@@ -3903,7 +4087,6 @@ need_resched_nonpreemptible:
                hrtick_clear(rq);
 
        raw_spin_lock_irq(&rq->lock);
-       clear_tsk_need_resched(prev);
 
        switch_count = &prev->nivcsw;
        if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) {
@@ -3935,6 +4118,8 @@ need_resched_nonpreemptible:
 
        put_prev_task(rq, prev);
        next = pick_next_task(rq);
+       clear_tsk_need_resched(prev);
+       rq->skip_clock_update = 0;
 
        if (likely(prev != next)) {
                sched_info_switch(prev, next);
index 68a9ae7..353b922 100644 (file)
@@ -1252,6 +1252,12 @@ unsigned long get_next_timer_interrupt(unsigned long now)
        struct tvec_base *base = __get_cpu_var(tvec_bases);
        unsigned long expires;
 
+       /*
+        * Pretend that there is no timer pending if the cpu is offline.
+        * Possible pending timers will be migrated later to an active cpu.
+        */
+       if (cpu_is_offline(smp_processor_id()))
+               return now + NEXT_TIMER_MAX_DELTA;
        spin_lock(&base->lock);
        if (time_before_eq(base->next_timer, base->timer_jiffies))
                base->next_timer = __next_timer_interrupt(base);
@@ -1319,7 +1325,7 @@ void do_timer(unsigned long ticks)
 {
        jiffies_64 += ticks;
        update_wall_time();
-       calc_global_load();
+       calc_global_load(ticks);
 }
 
 #ifdef __ARCH_WANT_SYS_ALARM
index c380612..f8cf959 100644 (file)
@@ -2338,11 +2338,19 @@ tracing_write_stub(struct file *filp, const char __user *ubuf,
        return count;
 }
 
+static loff_t tracing_seek(struct file *file, loff_t offset, int origin)
+{
+       if (file->f_mode & FMODE_READ)
+               return seq_lseek(file, offset, origin);
+       else
+               return 0;
+}
+
 static const struct file_operations tracing_fops = {
        .open           = tracing_open,
        .read           = seq_read,
        .write          = tracing_write_stub,
-       .llseek         = seq_lseek,
+       .llseek         = tracing_seek,
        .release        = tracing_release,
 };
 
index 90db1bd..e785b0f 100644 (file)
@@ -661,7 +661,7 @@ void wq_worker_waking_up(struct task_struct *task, unsigned int cpu)
 {
        struct worker *worker = kthread_data(task);
 
-       if (likely(!(worker->flags & WORKER_NOT_RUNNING)))
+       if (!(worker->flags & WORKER_NOT_RUNNING))
                atomic_inc(get_gcwq_nr_running(cpu));
 }
 
@@ -687,7 +687,7 @@ struct task_struct *wq_worker_sleeping(struct task_struct *task,
        struct global_cwq *gcwq = get_gcwq(cpu);
        atomic_t *nr_running = get_gcwq_nr_running(cpu);
 
-       if (unlikely(worker->flags & WORKER_NOT_RUNNING))
+       if (worker->flags & WORKER_NOT_RUNNING)
                return NULL;
 
        /* this can only happen on the local cpu */
@@ -3692,7 +3692,8 @@ static int __init init_workqueues(void)
        system_nrt_wq = alloc_workqueue("events_nrt", WQ_NON_REENTRANT, 0);
        system_unbound_wq = alloc_workqueue("events_unbound", WQ_UNBOUND,
                                            WQ_UNBOUND_MAX_ACTIVE);
-       BUG_ON(!system_wq || !system_long_wq || !system_nrt_wq);
+       BUG_ON(!system_wq || !system_long_wq || !system_nrt_wq ||
+              !system_unbound_wq);
        return 0;
 }
 early_initcall(init_workqueues);
index 5bf0020..b1c1773 100644 (file)
@@ -8,7 +8,6 @@
  *
  *  Copyright (C) 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
  */
-#include <linux/kernel.h>
 #include <linux/rwsem.h>
 #include <linux/mutex.h>
 #include <linux/module.h>
@@ -39,7 +38,6 @@ int debug_locks_off(void)
 {
        if (__debug_locks_off()) {
                if (!debug_locks_silent) {
-                       oops_in_progress = 1;
                        console_verbose();
                        return 1;
                }
index ea89840..6b9aee2 100644 (file)
@@ -143,13 +143,18 @@ void __remove_from_page_cache(struct page *page)
 void remove_from_page_cache(struct page *page)
 {
        struct address_space *mapping = page->mapping;
+       void (*freepage)(struct page *);
 
        BUG_ON(!PageLocked(page));
 
+       freepage = mapping->a_ops->freepage;
        spin_lock_irq(&mapping->tree_lock);
        __remove_from_page_cache(page);
        spin_unlock_irq(&mapping->tree_lock);
        mem_cgroup_uncharge_cache_page(page);
+
+       if (freepage)
+               freepage(page);
 }
 EXPORT_SYMBOL(remove_from_page_cache);
 
index c4a3558..8585524 100644 (file)
@@ -2738,7 +2738,8 @@ out_page_table_lock:
                unlock_page(pagecache_page);
                put_page(pagecache_page);
        }
-       unlock_page(page);
+       if (page != pagecache_page)
+               unlock_page(page);
 
 out_mutex:
        mutex_unlock(&hugetlb_instantiation_mutex);
index 65ab5c7..43bc893 100644 (file)
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -1724,8 +1724,13 @@ static int ksm_memory_callback(struct notifier_block *self,
                /*
                 * Keep it very simple for now: just lock out ksmd and
                 * MADV_UNMERGEABLE while any memory is going offline.
+                * mutex_lock_nested() is necessary because lockdep was alarmed
+                * that here we take ksm_thread_mutex inside notifier chain
+                * mutex, and later take notifier chain mutex inside
+                * ksm_thread_mutex to unlock it.   But that's safe because both
+                * are inside mem_hotplug_mutex.
                 */
-               mutex_lock(&ksm_thread_mutex);
+               mutex_lock_nested(&ksm_thread_mutex, SINGLE_DEPTH_NESTING);
                break;
 
        case MEM_OFFLINE:
index 1243241..46ab2c0 100644 (file)
@@ -51,6 +51,7 @@
 #include <linux/slab.h>
 #include <linux/swapops.h>
 #include <linux/hugetlb.h>
+#include <linux/memory_hotplug.h>
 #include "internal.h"
 
 int sysctl_memory_failure_early_kill __read_mostly = 0;
@@ -1230,11 +1231,10 @@ static int get_any_page(struct page *p, unsigned long pfn, int flags)
                return 1;
 
        /*
-        * The lock_system_sleep prevents a race with memory hotplug,
-        * because the isolation assumes there's only a single user.
+        * The lock_memory_hotplug prevents a race with memory hotplug.
         * This is a big hammer, a better would be nicer.
         */
-       lock_system_sleep();
+       lock_memory_hotplug();
 
        /*
         * Isolate the page, so that it doesn't get reallocated if it
@@ -1264,7 +1264,7 @@ static int get_any_page(struct page *p, unsigned long pfn, int flags)
                ret = 1;
        }
        unset_migratetype_isolate(p);
-       unlock_system_sleep();
+       unlock_memory_hotplug();
        return ret;
 }
 
index 9260314..2c6523a 100644 (file)
 
 #include "internal.h"
 
+DEFINE_MUTEX(mem_hotplug_mutex);
+
+void lock_memory_hotplug(void)
+{
+       mutex_lock(&mem_hotplug_mutex);
+
+       /* for exclusive hibernation if CONFIG_HIBERNATION=y */
+       lock_system_sleep();
+}
+
+void unlock_memory_hotplug(void)
+{
+       unlock_system_sleep();
+       mutex_unlock(&mem_hotplug_mutex);
+}
+
+
 /* add this memory to iomem resource */
 static struct resource *register_memory_resource(u64 start, u64 size)
 {
@@ -493,7 +510,7 @@ int mem_online_node(int nid)
        pg_data_t       *pgdat;
        int     ret;
 
-       lock_system_sleep();
+       lock_memory_hotplug();
        pgdat = hotadd_new_pgdat(nid, 0);
        if (pgdat) {
                ret = -ENOMEM;
@@ -504,7 +521,7 @@ int mem_online_node(int nid)
        BUG_ON(ret);
 
 out:
-       unlock_system_sleep();
+       unlock_memory_hotplug();
        return ret;
 }
 
@@ -516,7 +533,7 @@ int __ref add_memory(int nid, u64 start, u64 size)
        struct resource *res;
        int ret;
 
-       lock_system_sleep();
+       lock_memory_hotplug();
 
        res = register_memory_resource(start, size);
        ret = -EEXIST;
@@ -563,7 +580,7 @@ error:
                release_memory_resource(res);
 
 out:
-       unlock_system_sleep();
+       unlock_memory_hotplug();
        return ret;
 }
 EXPORT_SYMBOL_GPL(add_memory);
@@ -791,7 +808,7 @@ static int offline_pages(unsigned long start_pfn,
        if (!test_pages_in_a_zone(start_pfn, end_pfn))
                return -EINVAL;
 
-       lock_system_sleep();
+       lock_memory_hotplug();
 
        zone = page_zone(pfn_to_page(start_pfn));
        node = zone_to_nid(zone);
@@ -880,7 +897,7 @@ repeat:
        writeback_set_ratelimit();
 
        memory_notify(MEM_OFFLINE, &arg);
-       unlock_system_sleep();
+       unlock_memory_hotplug();
        return 0;
 
 failed_removal:
@@ -891,7 +908,7 @@ failed_removal:
        undo_isolate_page_range(start_pfn, end_pfn);
 
 out:
-       unlock_system_sleep();
+       unlock_memory_hotplug();
        return ret;
 }
 
index 4a57f13..11ff260 100644 (file)
@@ -1307,15 +1307,18 @@ SYSCALL_DEFINE4(migrate_pages, pid_t, pid, unsigned long, maxnode,
                goto out;
 
        /* Find the mm_struct */
+       rcu_read_lock();
        read_lock(&tasklist_lock);
        task = pid ? find_task_by_vpid(pid) : current;
        if (!task) {
                read_unlock(&tasklist_lock);
+               rcu_read_unlock();
                err = -ESRCH;
                goto out;
        }
        mm = get_task_mm(task);
        read_unlock(&tasklist_lock);
+       rcu_read_unlock();
 
        err = -EINVAL;
        if (!mm)
index b179abb..50a4aa0 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -2462,6 +2462,7 @@ int install_special_mapping(struct mm_struct *mm,
                            unsigned long addr, unsigned long len,
                            unsigned long vm_flags, struct page **pages)
 {
+       int ret;
        struct vm_area_struct *vma;
 
        vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
@@ -2479,16 +2480,23 @@ int install_special_mapping(struct mm_struct *mm,
        vma->vm_ops = &special_mapping_vmops;
        vma->vm_private_data = pages;
 
-       if (unlikely(insert_vm_struct(mm, vma))) {
-               kmem_cache_free(vm_area_cachep, vma);
-               return -ENOMEM;
-       }
+       ret = security_file_mmap(NULL, 0, 0, 0, vma->vm_start, 1);
+       if (ret)
+               goto out;
+
+       ret = insert_vm_struct(mm, vma);
+       if (ret)
+               goto out;
 
        mm->total_vm += len >> PAGE_SHIFT;
 
        perf_event_mmap(vma);
 
        return 0;
+
+out:
+       kmem_cache_free(vm_area_cachep, vma);
+       return ret;
 }
 
 static DEFINE_MUTEX(mm_all_locks_mutex);
index e409270..ff7e158 100644 (file)
@@ -104,19 +104,24 @@ gfp_t gfp_allowed_mask __read_mostly = GFP_BOOT_MASK;
  * only be modified with pm_mutex held, unless the suspend/hibernate code is
  * guaranteed not to run in parallel with that modification).
  */
-void set_gfp_allowed_mask(gfp_t mask)
+
+static gfp_t saved_gfp_mask;
+
+void pm_restore_gfp_mask(void)
 {
        WARN_ON(!mutex_is_locked(&pm_mutex));
-       gfp_allowed_mask = mask;
+       if (saved_gfp_mask) {
+               gfp_allowed_mask = saved_gfp_mask;
+               saved_gfp_mask = 0;
+       }
 }
 
-gfp_t clear_gfp_allowed_mask(gfp_t mask)
+void pm_restrict_gfp_mask(void)
 {
-       gfp_t ret = gfp_allowed_mask;
-
        WARN_ON(!mutex_is_locked(&pm_mutex));
-       gfp_allowed_mask &= ~mask;
-       return ret;
+       WARN_ON(saved_gfp_mask);
+       saved_gfp_mask = gfp_allowed_mask;
+       gfp_allowed_mask &= ~GFP_IOFS;
 }
 #endif /* CONFIG_PM_SLEEP */
 
index 981fb73..bec0e35 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -3401,13 +3401,13 @@ static int validate_slab(struct kmem_cache *s, struct page *page,
 
        for_each_free_object(p, s, page->freelist) {
                set_bit(slab_index(p, s, addr), map);
-               if (!check_object(s, page, p, 0))
+               if (!check_object(s, page, p, SLUB_RED_INACTIVE))
                        return 0;
        }
 
        for_each_object(p, s, addr, page->objects)
                if (!test_bit(slab_index(p, s, addr), map))
-                       if (!check_object(s, page, p, 1))
+                       if (!check_object(s, page, p, SLUB_RED_ACTIVE))
                                return 0;
        return 1;
 }
index ba887bf..3c2d5dd 100644 (file)
@@ -390,6 +390,10 @@ invalidate_complete_page2(struct address_space *mapping, struct page *page)
        __remove_from_page_cache(page);
        spin_unlock_irq(&mapping->tree_lock);
        mem_cgroup_uncharge_cache_page(page);
+
+       if (mapping->a_ops->freepage)
+               mapping->a_ops->freepage(page);
+
        page_cache_release(page);       /* pagecache ref */
        return 1;
 failed:
index a3d66b3..eb5cc7d 100644 (file)
@@ -31,8 +31,6 @@
 #include <asm/tlbflush.h>
 #include <asm/shmparam.h>
 
-bool vmap_lazy_unmap __read_mostly = true;
-
 /*** Page table manipulation functions ***/
 
 static void vunmap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end)
@@ -503,9 +501,6 @@ static unsigned long lazy_max_pages(void)
 {
        unsigned int log;
 
-       if (!vmap_lazy_unmap)
-               return 0;
-
        log = fls(num_online_cpus());
 
        return log * (32UL * 1024 * 1024 / PAGE_SIZE);
@@ -566,7 +561,6 @@ static void __purge_vmap_area_lazy(unsigned long *start, unsigned long *end,
                        if (va->va_end > *end)
                                *end = va->va_end;
                        nr += (va->va_end - va->va_start) >> PAGE_SHIFT;
-                       unmap_vmap_area(va);
                        list_add_tail(&va->purge_list, &valist);
                        va->flags |= VM_LAZY_FREEING;
                        va->flags &= ~VM_LAZY_FREE;
@@ -611,10 +605,11 @@ static void purge_vmap_area_lazy(void)
 }
 
 /*
- * Free and unmap a vmap area, caller ensuring flush_cache_vunmap had been
- * called for the correct range previously.
+ * Free a vmap area, caller ensuring that the area has been unmapped
+ * and flush_cache_vunmap had been called for the correct range
+ * previously.
  */
-static void free_unmap_vmap_area_noflush(struct vmap_area *va)
+static void free_vmap_area_noflush(struct vmap_area *va)
 {
        va->flags |= VM_LAZY_FREE;
        atomic_add((va->va_end - va->va_start) >> PAGE_SHIFT, &vmap_lazy_nr);
@@ -622,6 +617,16 @@ static void free_unmap_vmap_area_noflush(struct vmap_area *va)
                try_purge_vmap_area_lazy();
 }
 
+/*
+ * Free and unmap a vmap area, caller ensuring flush_cache_vunmap had been
+ * called for the correct range previously.
+ */
+static void free_unmap_vmap_area_noflush(struct vmap_area *va)
+{
+       unmap_vmap_area(va);
+       free_vmap_area_noflush(va);
+}
+
 /*
  * Free and unmap a vmap area
  */
@@ -798,7 +803,7 @@ static void free_vmap_block(struct vmap_block *vb)
        spin_unlock(&vmap_block_tree_lock);
        BUG_ON(tmp != vb);
 
-       free_unmap_vmap_area_noflush(vb->va);
+       free_vmap_area_noflush(vb->va);
        call_rcu(&vb->rcu_head, rcu_free_vb);
 }
 
@@ -936,6 +941,8 @@ static void vb_free(const void *addr, unsigned long size)
        rcu_read_unlock();
        BUG_ON(!vb);
 
+       vunmap_page_range((unsigned long)addr, (unsigned long)addr + size);
+
        spin_lock(&vb->lock);
        BUG_ON(bitmap_allocate_region(vb->dirty_map, offset >> PAGE_SHIFT, order));
 
@@ -988,7 +995,6 @@ void vm_unmap_aliases(void)
 
                                s = vb->va->va_start + (i << PAGE_SHIFT);
                                e = vb->va->va_start + (j << PAGE_SHIFT);
-                               vunmap_page_range(s, e);
                                flush = 1;
 
                                if (s < start)
index d31d7ce..9ca587c 100644 (file)
@@ -494,9 +494,16 @@ static int __remove_mapping(struct address_space *mapping, struct page *page)
                spin_unlock_irq(&mapping->tree_lock);
                swapcache_free(swap, page);
        } else {
+               void (*freepage)(struct page *);
+
+               freepage = mapping->a_ops->freepage;
+
                __remove_from_page_cache(page);
                spin_unlock_irq(&mapping->tree_lock);
                mem_cgroup_uncharge_cache_page(page);
+
+               if (freepage != NULL)
+                       freepage(page);
        }
 
        return 1;
index 42eac4d..8f62f17 100644 (file)
@@ -750,8 +750,6 @@ static const char * const vmstat_text[] = {
        "nr_shmem",
        "nr_dirtied",
        "nr_written",
-       "nr_dirty_threshold",
-       "nr_dirty_background_threshold",
 
 #ifdef CONFIG_NUMA
        "numa_hit",
@@ -761,6 +759,8 @@ static const char * const vmstat_text[] = {
        "numa_local",
        "numa_other",
 #endif
+       "nr_dirty_threshold",
+       "nr_dirty_background_threshold",
 
 #ifdef CONFIG_VM_EVENT_COUNTERS
        "pgpgin",
index 799c631..f7fa67c 100644 (file)
@@ -143,12 +143,13 @@ static struct class atm_class = {
        .dev_uevent             = atm_uevent,
 };
 
-int atm_register_sysfs(struct atm_dev *adev)
+int atm_register_sysfs(struct atm_dev *adev, struct device *parent)
 {
        struct device *cdev = &adev->class_dev;
        int i, j, err;
 
        cdev->class = &atm_class;
+       cdev->parent = parent;
        dev_set_drvdata(cdev, adev);
 
        dev_set_name(cdev, "%s%d", adev->type, adev->number);
index d29e582..23f45ce 100644 (file)
@@ -74,8 +74,9 @@ struct atm_dev *atm_dev_lookup(int number)
 }
 EXPORT_SYMBOL(atm_dev_lookup);
 
-struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops,
-                                int number, unsigned long *flags)
+struct atm_dev *atm_dev_register(const char *type, struct device *parent,
+                                const struct atmdev_ops *ops, int number,
+                                unsigned long *flags)
 {
        struct atm_dev *dev, *inuse;
 
@@ -115,7 +116,7 @@ struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops,
                goto out_fail;
        }
 
-       if (atm_register_sysfs(dev) < 0) {
+       if (atm_register_sysfs(dev, parent) < 0) {
                pr_err("atm_register_sysfs failed for dev %s\n", type);
                atm_proc_dev_deregister(dev);
                goto out_fail;
index 126fb18..521431e 100644 (file)
@@ -42,6 +42,6 @@ static inline void atm_proc_dev_deregister(struct atm_dev *dev)
 
 #endif /* CONFIG_PROC_FS */
 
-int atm_register_sysfs(struct atm_dev *adev);
+int atm_register_sysfs(struct atm_dev *adev, struct device *parent);
 void atm_unregister_sysfs(struct atm_dev *adev);
 #endif
index d0927d1..66b9e5c 100644 (file)
@@ -882,7 +882,7 @@ static int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type)
        int lm = 0;
 
        if (type != SCO_LINK && type != ESCO_LINK)
-               return 0;
+               return -EINVAL;
 
        BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
 
@@ -908,7 +908,7 @@ static int sco_connect_cfm(struct hci_conn *hcon, __u8 status)
        BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
 
        if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK)
-               return 0;
+               return -EINVAL;
 
        if (!status) {
                struct sco_conn *conn;
@@ -927,7 +927,7 @@ static int sco_disconn_cfm(struct hci_conn *hcon, __u8 reason)
        BT_DBG("hcon %p reason %d", hcon, reason);
 
        if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK)
-               return 0;
+               return -EINVAL;
 
        sco_conn_del(hcon, bt_err(reason));
 
index aab1cab..5f19415 100644 (file)
@@ -1,9 +1,6 @@
 #
 # Makefile for CEPH filesystem.
 #
-
-ifneq ($(KERNELRELEASE),)
-
 obj-$(CONFIG_CEPH_LIB) += libceph.o
 
 libceph-objs := ceph_common.o messenger.o msgpool.o buffer.o pagelist.o \
@@ -16,22 +13,3 @@ libceph-objs := ceph_common.o messenger.o msgpool.o buffer.o pagelist.o \
        ceph_fs.o ceph_strings.o ceph_hash.o \
        pagevec.o
 
-else
-#Otherwise we were called directly from the command
-# line; invoke the kernel build system.
-
-KERNELDIR ?= /lib/modules/$(shell uname -r)/build
-PWD := $(shell pwd)
-
-default: all
-
-all:
-       $(MAKE) -C $(KERNELDIR) M=$(PWD) CONFIG_CEPH_LIB=m modules
-
-modules_install:
-       $(MAKE) -C $(KERNELDIR) M=$(PWD) CONFIG_CEPH_LIB=m modules_install
-
-clean:
-       $(MAKE) -C $(KERNELDIR) M=$(PWD) clean
-
-endif
index c1ee800..ae21a0d 100644 (file)
@@ -589,23 +589,16 @@ int sk_chk_filter(struct sock_filter *filter, int flen)
 EXPORT_SYMBOL(sk_chk_filter);
 
 /**
- *     sk_filter_rcu_release - Release a socket filter by rcu_head
+ *     sk_filter_release_rcu - Release a socket filter by rcu_head
  *     @rcu: rcu_head that contains the sk_filter to free
  */
-static void sk_filter_rcu_release(struct rcu_head *rcu)
+void sk_filter_release_rcu(struct rcu_head *rcu)
 {
        struct sk_filter *fp = container_of(rcu, struct sk_filter, rcu);
 
-       sk_filter_release(fp);
-}
-
-static void sk_filter_delayed_uncharge(struct sock *sk, struct sk_filter *fp)
-{
-       unsigned int size = sk_filter_len(fp);
-
-       atomic_sub(size, &sk->sk_omem_alloc);
-       call_rcu_bh(&fp->rcu, sk_filter_rcu_release);
+       kfree(fp);
 }
+EXPORT_SYMBOL(sk_filter_release_rcu);
 
 /**
  *     sk_attach_filter - attach a socket filter
@@ -649,7 +642,7 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk)
        rcu_assign_pointer(sk->sk_filter, fp);
 
        if (old_fp)
-               sk_filter_delayed_uncharge(sk, old_fp);
+               sk_filter_uncharge(sk, old_fp);
        return 0;
 }
 EXPORT_SYMBOL_GPL(sk_attach_filter);
@@ -663,7 +656,7 @@ int sk_detach_filter(struct sock *sk)
                                           sock_owned_by_user(sk));
        if (filter) {
                rcu_assign_pointer(sk->sk_filter, NULL);
-               sk_filter_delayed_uncharge(sk, filter);
+               sk_filter_uncharge(sk, filter);
                ret = 0;
        }
        return ret;
index 0ae6c22..c19bb4e 100644 (file)
@@ -96,11 +96,13 @@ bool skb_defer_rx_timestamp(struct sk_buff *skb)
        struct phy_device *phydev;
        unsigned int type;
 
-       skb_push(skb, ETH_HLEN);
+       if (skb_headroom(skb) < ETH_HLEN)
+               return false;
+       __skb_push(skb, ETH_HLEN);
 
        type = classify(skb);
 
-       skb_pull(skb, ETH_HLEN);
+       __skb_pull(skb, ETH_HLEN);
 
        switch (type) {
        case PTP_CLASS_V1_IPV4:
index 2659853..e424a09 100644 (file)
@@ -239,7 +239,8 @@ static int dccp_check_seqno(struct sock *sk, struct sk_buff *skb)
                dccp_update_gsr(sk, seqno);
 
                if (dh->dccph_type != DCCP_PKT_SYNC &&
-                   (ackno != DCCP_PKT_WITHOUT_ACK_SEQ))
+                   ackno != DCCP_PKT_WITHOUT_ACK_SEQ &&
+                   after48(ackno, dp->dccps_gar))
                        dp->dccps_gar = ackno;
        } else {
                unsigned long now = jiffies;
index a76b78d..6f97268 100644 (file)
@@ -1556,6 +1556,8 @@ static int __dn_getsockopt(struct socket *sock, int level,int optname, char __us
                        if (r_len > sizeof(struct linkinfo_dn))
                                r_len = sizeof(struct linkinfo_dn);
 
+                       memset(&link, 0, sizeof(link));
+
                        switch(sock->state) {
                                case SS_CONNECTING:
                                        link.idn_linkstate = LL_CONNECTING;
index f8c1ae4..15dcc1a 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/skbuff.h>
 #include <linux/udp.h>
 #include <linux/slab.h>
+#include <linux/vmalloc.h>
 #include <net/sock.h>
 #include <net/inet_common.h>
 #include <linux/stat.h>
@@ -276,12 +277,12 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
 #endif
 #ifdef CONFIG_ECONET_AUNUDP
        struct msghdr udpmsg;
-       struct iovec iov[msg->msg_iovlen+1];
+       struct iovec iov[2];
        struct aunhdr ah;
        struct sockaddr_in udpdest;
        __kernel_size_t size;
-       int i;
        mm_segment_t oldfs;
+       char *userbuf;
 #endif
 
        /*
@@ -297,23 +298,14 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
 
        mutex_lock(&econet_mutex);
 
-       if (saddr == NULL) {
-               struct econet_sock *eo = ec_sk(sk);
-
-               addr.station = eo->station;
-               addr.net     = eo->net;
-               port         = eo->port;
-               cb           = eo->cb;
-       } else {
-               if (msg->msg_namelen < sizeof(struct sockaddr_ec)) {
-                       mutex_unlock(&econet_mutex);
-                       return -EINVAL;
-               }
-               addr.station = saddr->addr.station;
-               addr.net = saddr->addr.net;
-               port = saddr->port;
-               cb = saddr->cb;
-       }
+        if (saddr == NULL || msg->msg_namelen < sizeof(struct sockaddr_ec)) {
+                mutex_unlock(&econet_mutex);
+                return -EINVAL;
+        }
+        addr.station = saddr->addr.station;
+        addr.net = saddr->addr.net;
+        port = saddr->port;
+        cb = saddr->cb;
 
        /* Look for a device with the right network number. */
        dev = net2dev_map[addr.net];
@@ -328,17 +320,17 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
                }
        }
 
-       if (len + 15 > dev->mtu) {
-               mutex_unlock(&econet_mutex);
-               return -EMSGSIZE;
-       }
-
        if (dev->type == ARPHRD_ECONET) {
                /* Real hardware Econet.  We're not worthy etc. */
 #ifdef CONFIG_ECONET_NATIVE
                unsigned short proto = 0;
                int res;
 
+               if (len + 15 > dev->mtu) {
+                       mutex_unlock(&econet_mutex);
+                       return -EMSGSIZE;
+               }
+
                dev_hold(dev);
 
                skb = sock_alloc_send_skb(sk, len+LL_ALLOCATED_SPACE(dev),
@@ -351,7 +343,6 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
 
                eb = (struct ec_cb *)&skb->cb;
 
-               /* BUG: saddr may be NULL */
                eb->cookie = saddr->cookie;
                eb->sec = *saddr;
                eb->sent = ec_tx_done;
@@ -415,6 +406,11 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
                return -ENETDOWN;               /* No socket - can't send */
        }
 
+       if (len > 32768) {
+               err = -E2BIG;
+               goto error;
+       }
+
        /* Make up a UDP datagram and hand it off to some higher intellect. */
 
        memset(&udpdest, 0, sizeof(udpdest));
@@ -446,36 +442,26 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
 
        /* tack our header on the front of the iovec */
        size = sizeof(struct aunhdr);
-       /*
-        * XXX: that is b0rken.  We can't mix userland and kernel pointers
-        * in iovec, since on a lot of platforms copy_from_user() will
-        * *not* work with the kernel and userland ones at the same time,
-        * regardless of what we do with set_fs().  And we are talking about
-        * econet-over-ethernet here, so "it's only ARM anyway" doesn't
-        * apply.  Any suggestions on fixing that code?         -- AV
-        */
        iov[0].iov_base = (void *)&ah;
        iov[0].iov_len = size;
-       for (i = 0; i < msg->msg_iovlen; i++) {
-               void __user *base = msg->msg_iov[i].iov_base;
-               size_t iov_len = msg->msg_iov[i].iov_len;
-               /* Check it now since we switch to KERNEL_DS later. */
-               if (!access_ok(VERIFY_READ, base, iov_len)) {
-                       mutex_unlock(&econet_mutex);
-                       return -EFAULT;
-               }
-               iov[i+1].iov_base = base;
-               iov[i+1].iov_len = iov_len;
-               size += iov_len;
+
+       userbuf = vmalloc(len);
+       if (userbuf == NULL) {
+               err = -ENOMEM;
+               goto error;
        }
 
+       iov[1].iov_base = userbuf;
+       iov[1].iov_len = len;
+       err = memcpy_fromiovec(userbuf, msg->msg_iov, len);
+       if (err)
+               goto error_free_buf;
+
        /* Get a skbuff (no data, just holds our cb information) */
        if ((skb = sock_alloc_send_skb(sk, 0,
                                       msg->msg_flags & MSG_DONTWAIT,
-                                      &err)) == NULL) {
-               mutex_unlock(&econet_mutex);
-               return err;
-       }
+                                      &err)) == NULL)
+               goto error_free_buf;
 
        eb = (struct ec_cb *)&skb->cb;
 
@@ -491,7 +477,7 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
        udpmsg.msg_name = (void *)&udpdest;
        udpmsg.msg_namelen = sizeof(udpdest);
        udpmsg.msg_iov = &iov[0];
-       udpmsg.msg_iovlen = msg->msg_iovlen + 1;
+       udpmsg.msg_iovlen = 2;
        udpmsg.msg_control = NULL;
        udpmsg.msg_controllen = 0;
        udpmsg.msg_flags=0;
@@ -499,9 +485,13 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
        oldfs = get_fs(); set_fs(KERNEL_DS);    /* More privs :-) */
        err = sock_sendmsg(udpsock, &udpmsg, size);
        set_fs(oldfs);
+
+error_free_buf:
+       vfree(userbuf);
 #else
        err = -EPROTOTYPE;
 #endif
+       error:
        mutex_unlock(&econet_mutex);
 
        return err;
@@ -671,6 +661,11 @@ static int ec_dev_ioctl(struct socket *sock, unsigned int cmd, void __user *arg)
        err = 0;
        switch (cmd) {
        case SIOCSIFADDR:
+               if (!capable(CAP_NET_ADMIN)) {
+                       err = -EPERM;
+                       break;
+               }
+
                edev = dev->ec_ptr;
                if (edev == NULL) {
                        /* Magic up a new one. */
@@ -856,9 +851,13 @@ static void aun_incoming(struct sk_buff *skb, struct aunhdr *ah, size_t len)
 {
        struct iphdr *ip = ip_hdr(skb);
        unsigned char stn = ntohl(ip->saddr) & 0xff;
+       struct dst_entry *dst = skb_dst(skb);
+       struct ec_device *edev = NULL;
        struct sock *sk = NULL;
        struct sk_buff *newskb;
-       struct ec_device *edev = skb->dev->ec_ptr;
+
+       if (dst)
+               edev = dst->dev->ec_ptr;
 
        if (! edev)
                goto bad;
index 1b344f3..3c0369a 100644 (file)
@@ -133,8 +133,7 @@ int __inet_inherit_port(struct sock *sk, struct sock *child)
                        }
                }
        }
-       sk_add_bind_node(child, &tb->owners);
-       inet_csk(child)->icsk_bind_hash = tb;
+       inet_bind_hash(child, tb, port);
        spin_unlock(&head->lock);
 
        return 0;
index 1b48eb1..b14ec7d 100644 (file)
@@ -253,6 +253,7 @@ static const struct snmp_mib snmp4_net_list[] = {
        SNMP_MIB_ITEM("TCPMinTTLDrop", LINUX_MIB_TCPMINTTLDROP),
        SNMP_MIB_ITEM("TCPDeferAcceptDrop", LINUX_MIB_TCPDEFERACCEPTDROP),
        SNMP_MIB_ITEM("IPReversePathFilter", LINUX_MIB_IPRPFILTER),
+       SNMP_MIB_ITEM("TCPTimeWaitOverflow", LINUX_MIB_TCPTIMEWAITOVERFLOW),
        SNMP_MIB_SENTINEL
 };
 
index e91911d..1b4ec21 100644 (file)
@@ -26,6 +26,8 @@ static int zero;
 static int tcp_retr1_max = 255;
 static int ip_local_port_range_min[] = { 1, 1 };
 static int ip_local_port_range_max[] = { 65535, 65535 };
+static int tcp_adv_win_scale_min = -31;
+static int tcp_adv_win_scale_max = 31;
 
 /* Update system visible IP port range */
 static void set_local_port_range(int range[2])
@@ -426,7 +428,9 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_tcp_adv_win_scale,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = proc_dointvec
+               .proc_handler   = proc_dointvec_minmax,
+               .extra1         = &tcp_adv_win_scale_min,
+               .extra2         = &tcp_adv_win_scale_max,
        },
        {
                .procname       = "tcp_tw_reuse",
index 0814199..f15c36a 100644 (file)
@@ -2246,7 +2246,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level,
                /* Values greater than interface MTU won't take effect. However
                 * at the point when this call is done we typically don't yet
                 * know which interface is going to be used */
-               if (val < 64 || val > MAX_TCP_WINDOW) {
+               if (val < TCP_MIN_MSS || val > MAX_TCP_WINDOW) {
                        err = -EINVAL;
                        break;
                }
index 69ccbc1..e13da6d 100644 (file)
@@ -2043,7 +2043,9 @@ get_req:
        }
 get_sk:
        sk_nulls_for_each_from(sk, node) {
-               if (sk->sk_family == st->family && net_eq(sock_net(sk), net)) {
+               if (!net_eq(sock_net(sk), net))
+                       continue;
+               if (sk->sk_family == st->family) {
                        cur = sk;
                        goto out;
                }
index 43cf901..a66735f 100644 (file)
@@ -347,7 +347,7 @@ void tcp_time_wait(struct sock *sk, int state, int timeo)
                 * socket up.  We've got bigger problems than
                 * non-graceful socket closings.
                 */
-               LIMIT_NETDEBUG(KERN_INFO "TCP: time wait bucket table overflow\n");
+               NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPTIMEWAITOVERFLOW);
        }
 
        tcp_update_metrics(sk);
index 05b1ecf..61c2463 100644 (file)
@@ -231,11 +231,10 @@ void tcp_select_initial_window(int __space, __u32 mss,
                /* when initializing use the value from init_rcv_wnd
                 * rather than the default from above
                 */
-               if (init_rcv_wnd &&
-                   (*rcv_wnd > init_rcv_wnd * mss))
-                       *rcv_wnd = init_rcv_wnd * mss;
-               else if (*rcv_wnd > init_cwnd * mss)
-                       *rcv_wnd = init_cwnd * mss;
+               if (init_rcv_wnd)
+                       *rcv_wnd = min(*rcv_wnd, init_rcv_wnd * mss);
+               else
+                       *rcv_wnd = min(*rcv_wnd, init_cwnd * mss);
        }
 
        /* Set the clamp no higher than max representable value */
@@ -386,27 +385,30 @@ struct tcp_out_options {
  */
 static u8 tcp_cookie_size_check(u8 desired)
 {
-       if (desired > 0) {
+       int cookie_size;
+
+       if (desired > 0)
                /* previously specified */
                return desired;
-       }
-       if (sysctl_tcp_cookie_size <= 0) {
+
+       cookie_size = ACCESS_ONCE(sysctl_tcp_cookie_size);
+       if (cookie_size <= 0)
                /* no default specified */
                return 0;
-       }
-       if (sysctl_tcp_cookie_size <= TCP_COOKIE_MIN) {
+
+       if (cookie_size <= TCP_COOKIE_MIN)
                /* value too small, specify minimum */
                return TCP_COOKIE_MIN;
-       }
-       if (sysctl_tcp_cookie_size >= TCP_COOKIE_MAX) {
+
+       if (cookie_size >= TCP_COOKIE_MAX)
                /* value too large, specify maximum */
                return TCP_COOKIE_MAX;
-       }
-       if (0x1 & sysctl_tcp_cookie_size) {
+
+       if (cookie_size & 1)
                /* 8-bit multiple, illegal, fix it */
-               return (u8)(sysctl_tcp_cookie_size + 0x1);
-       }
-       return (u8)sysctl_tcp_cookie_size;
+               cookie_size++;
+
+       return (u8)cookie_size;
 }
 
 /* Write previously computed TCP options to the packet.
@@ -1513,6 +1515,7 @@ static int tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb)
        struct tcp_sock *tp = tcp_sk(sk);
        const struct inet_connection_sock *icsk = inet_csk(sk);
        u32 send_win, cong_win, limit, in_flight;
+       int win_divisor;
 
        if (TCP_SKB_CB(skb)->flags & TCPHDR_FIN)
                goto send_now;
@@ -1544,13 +1547,14 @@ static int tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb)
        if ((skb != tcp_write_queue_tail(sk)) && (limit >= skb->len))
                goto send_now;
 
-       if (sysctl_tcp_tso_win_divisor) {
+       win_divisor = ACCESS_ONCE(sysctl_tcp_tso_win_divisor);
+       if (win_divisor) {
                u32 chunk = min(tp->snd_wnd, tp->snd_cwnd * tp->mss_cache);
 
                /* If at least some fraction of a window is available,
                 * just use it.
                 */
-               chunk /= sysctl_tcp_tso_win_divisor;
+               chunk /= win_divisor;
                if (limit >= chunk)
                        goto send_now;
        } else {
index 23cc8e1..93b7a93 100644 (file)
@@ -4021,11 +4021,11 @@ void inet6_ifinfo_notify(int event, struct inet6_dev *idev)
                kfree_skb(skb);
                goto errout;
        }
-       rtnl_notify(skb, net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
+       rtnl_notify(skb, net, 0, RTNLGRP_IPV6_IFINFO, NULL, GFP_ATOMIC);
        return;
 errout:
        if (err < 0)
-               rtnl_set_sk_err(net, RTNLGRP_IPV6_IFADDR, err);
+               rtnl_set_sk_err(net, RTNLGRP_IPV6_IFINFO, err);
 }
 
 static inline size_t inet6_prefix_nlmsg_size(void)
index 2a59610..70e891a 100644 (file)
@@ -1175,6 +1175,8 @@ static void ip6_tnl_link_config(struct ip6_tnl *t)
                                sizeof (struct ipv6hdr);
 
                        dev->mtu = rt->rt6i_dev->mtu - sizeof (struct ipv6hdr);
+                       if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
+                               dev->mtu-=8;
 
                        if (dev->mtu < IPV6_MIN_MTU)
                                dev->mtu = IPV6_MIN_MTU;
@@ -1363,12 +1365,17 @@ static const struct net_device_ops ip6_tnl_netdev_ops = {
 
 static void ip6_tnl_dev_setup(struct net_device *dev)
 {
+       struct ip6_tnl *t;
+
        dev->netdev_ops = &ip6_tnl_netdev_ops;
        dev->destructor = ip6_dev_free;
 
        dev->type = ARPHRD_TUNNEL6;
        dev->hard_header_len = LL_MAX_HEADER + sizeof (struct ipv6hdr);
        dev->mtu = ETH_DATA_LEN - sizeof (struct ipv6hdr);
+       t = netdev_priv(dev);
+       if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
+               dev->mtu-=8;
        dev->flags |= IFF_NOARP;
        dev->addr_len = sizeof(struct in6_addr);
        dev->features |= NETIF_F_NETNS_LOCAL;
index d6bfaec..8c4d00c 100644 (file)
@@ -606,8 +606,9 @@ static int ipip6_rcv(struct sk_buff *skb)
                return 0;
        }
 
-       icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
+       /* no tunnel matched,  let upstream know, ipsec may handle it */
        rcu_read_unlock();
+       return 1;
 out:
        kfree_skb(skb);
        return 0;
index 0bf6a59..522e219 100644 (file)
@@ -674,4 +674,8 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("James Chapman <jchapman@katalix.com>");
 MODULE_DESCRIPTION("L2TP over IP");
 MODULE_VERSION("1.0");
-MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET, SOCK_DGRAM, IPPROTO_L2TP);
+
+/* Use the value of SOCK_DGRAM (2) directory, because __stringify does't like
+ * enums
+ */
+MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET, 2, IPPROTO_L2TP);
index 5826129..e35dbe5 100644 (file)
@@ -317,8 +317,9 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen)
                goto out;
        rc = -ENODEV;
        rtnl_lock();
+       rcu_read_lock();
        if (sk->sk_bound_dev_if) {
-               llc->dev = dev_get_by_index(&init_net, sk->sk_bound_dev_if);
+               llc->dev = dev_get_by_index_rcu(&init_net, sk->sk_bound_dev_if);
                if (llc->dev) {
                        if (!addr->sllc_arphrd)
                                addr->sllc_arphrd = llc->dev->type;
@@ -329,13 +330,13 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen)
                            !llc_mac_match(addr->sllc_mac,
                                           llc->dev->dev_addr)) {
                                rc = -EINVAL;
-                               dev_put(llc->dev);
                                llc->dev = NULL;
                        }
                }
        } else
                llc->dev = dev_getbyhwaddr(&init_net, addr->sllc_arphrd,
                                           addr->sllc_mac);
+       rcu_read_unlock();
        rtnl_unlock();
        if (!llc->dev)
                goto out;
index 4d6f865..8e8ea9c 100644 (file)
@@ -92,7 +92,7 @@ config MAC80211_MESH
 config MAC80211_LEDS
        bool "Enable LED triggers"
        depends on MAC80211
-       select NEW_LEDS
+       depends on LEDS_CLASS
        select LEDS_TRIGGERS
        ---help---
          This option enables a few LED triggers for different
index 902b03e..54fb4a0 100644 (file)
@@ -2247,6 +2247,10 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
                break;
        case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
        case cpu_to_le16(IEEE80211_STYPE_DISASSOC):
+               if (is_multicast_ether_addr(mgmt->da) &&
+                   !is_broadcast_ether_addr(mgmt->da))
+                       return RX_DROP_MONITOR;
+
                /* process only for station */
                if (sdata->vif.type != NL80211_IFTYPE_STATION)
                        return RX_DROP_MONITOR;
@@ -2741,6 +2745,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
 
                        if (ieee80211_prepare_and_rx_handle(&rx, skb, true))
                                return;
+                       goto out;
                }
        }
 
@@ -2780,6 +2785,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
                        return;
        }
 
+ out:
        dev_kfree_skb(skb);
 }
 
index 96c5943..7a637b8 100644 (file)
@@ -1587,7 +1587,12 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
                                                list) {
                                if (!ieee80211_sdata_running(tmp_sdata))
                                        continue;
-                               if (tmp_sdata->vif.type != NL80211_IFTYPE_AP)
+                               if (tmp_sdata->vif.type ==
+                                   NL80211_IFTYPE_MONITOR ||
+                                   tmp_sdata->vif.type ==
+                                   NL80211_IFTYPE_AP_VLAN ||
+                                       tmp_sdata->vif.type ==
+                                   NL80211_IFTYPE_WDS)
                                        continue;
                                if (compare_ether_addr(tmp_sdata->vif.addr,
                                                       hdr->addr2) == 0) {
@@ -1732,15 +1737,13 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
        int nh_pos, h_pos;
        struct sta_info *sta = NULL;
        u32 sta_flags = 0;
+       struct sk_buff *tmp_skb;
 
        if (unlikely(skb->len < ETH_HLEN)) {
                ret = NETDEV_TX_OK;
                goto fail;
        }
 
-       nh_pos = skb_network_header(skb) - skb->data;
-       h_pos = skb_transport_header(skb) - skb->data;
-
        /* convert Ethernet header to proper 802.11 header (based on
         * operation mode) */
        ethertype = (skb->data[12] << 8) | skb->data[13];
@@ -1913,6 +1916,20 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
                goto fail;
        }
 
+       /*
+        * If the skb is shared we need to obtain our own copy.
+        */
+       if (skb_shared(skb)) {
+               tmp_skb = skb;
+               skb = skb_copy(skb, GFP_ATOMIC);
+               kfree_skb(tmp_skb);
+
+               if (!skb) {
+                       ret = NETDEV_TX_OK;
+                       goto fail;
+               }
+       }
+
        hdr.frame_control = fc;
        hdr.duration_id = 0;
        hdr.seq_ctrl = 0;
@@ -1931,6 +1948,9 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
                encaps_len = 0;
        }
 
+       nh_pos = skb_network_header(skb) - skb->data;
+       h_pos = skb_transport_header(skb) - skb->data;
+
        skb_pull(skb, skip_header_bytes);
        nh_pos -= skip_header_bytes;
        h_pos -= skip_header_bytes;
index 6bd5543..0b9ee34 100644 (file)
@@ -2932,6 +2932,7 @@ static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optva
        struct sctp_association *asoc = NULL;
        struct sctp_setpeerprim prim;
        struct sctp_chunk       *chunk;
+       struct sctp_af          *af;
        int                     err;
 
        sp = sctp_sk(sk);
@@ -2959,6 +2960,13 @@ static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optva
        if (!sctp_state(asoc, ESTABLISHED))
                return -ENOTCONN;
 
+       af = sctp_get_af_specific(prim.sspp_addr.ss_family);
+       if (!af)
+               return -EINVAL;
+
+       if (!af->addr_valid((union sctp_addr *)&prim.sspp_addr, sp, NULL))
+               return -EADDRNOTAVAIL;
+
        if (!sctp_assoc_lookup_laddr(asoc, (union sctp_addr *)&prim.sspp_addr))
                return -EADDRNOTAVAIL;
 
index 3ca2fd9..088fb3f 100644 (file)
@@ -732,6 +732,21 @@ static int sock_recvmsg_nosec(struct socket *sock, struct msghdr *msg,
        return ret;
 }
 
+/**
+ * kernel_recvmsg - Receive a message from a socket (kernel space)
+ * @sock:       The socket to receive the message from
+ * @msg:        Received message
+ * @vec:        Input s/g array for message data
+ * @num:        Size of input s/g array
+ * @size:       Number of bytes to read
+ * @flags:      Message flags (MSG_DONTWAIT, etc...)
+ *
+ * On return the msg structure contains the scatter/gather array passed in the
+ * vec argument. The array is modified so that it consists of the unfilled
+ * portion of the original array.
+ *
+ * The returned value is the total number of bytes received, or an error.
+ */
 int kernel_recvmsg(struct socket *sock, struct msghdr *msg,
                   struct kvec *vec, size_t num, size_t size, int flags)
 {
index ea2ff78..3f2c555 100644 (file)
@@ -212,6 +212,7 @@ int svc_create_xprt(struct svc_serv *serv, const char *xprt_name,
        spin_lock(&svc_xprt_class_lock);
        list_for_each_entry(xcl, &svc_xprt_class_list, xcl_list) {
                struct svc_xprt *newxprt;
+               unsigned short newport;
 
                if (strcmp(xprt_name, xcl->xcl_name))
                        continue;
@@ -230,8 +231,9 @@ int svc_create_xprt(struct svc_serv *serv, const char *xprt_name,
                spin_lock_bh(&serv->sv_lock);
                list_add(&newxprt->xpt_list, &serv->sv_permsocks);
                spin_unlock_bh(&serv->sv_lock);
+               newport = svc_xprt_local_port(newxprt);
                clear_bit(XPT_BUSY, &newxprt->xpt_flags);
-               return svc_xprt_local_port(newxprt);
+               return newport;
        }
  err:
        spin_unlock(&svc_xprt_class_lock);
@@ -425,8 +427,13 @@ void svc_xprt_received(struct svc_xprt *xprt)
 {
        BUG_ON(!test_bit(XPT_BUSY, &xprt->xpt_flags));
        xprt->xpt_pool = NULL;
+       /* As soon as we clear busy, the xprt could be closed and
+        * 'put', so we need a reference to call svc_xprt_enqueue with:
+        */
+       svc_xprt_get(xprt);
        clear_bit(XPT_BUSY, &xprt->xpt_flags);
        svc_xprt_enqueue(xprt);
+       svc_xprt_put(xprt);
 }
 EXPORT_SYMBOL_GPL(svc_xprt_received);
 
index 3c95304..2268e67 100644 (file)
@@ -1343,9 +1343,25 @@ static void unix_destruct_scm(struct sk_buff *skb)
        sock_wfree(skb);
 }
 
+#define MAX_RECURSION_LEVEL 4
+
 static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
 {
        int i;
+       unsigned char max_level = 0;
+       int unix_sock_count = 0;
+
+       for (i = scm->fp->count - 1; i >= 0; i--) {
+               struct sock *sk = unix_get_socket(scm->fp->fp[i]);
+
+               if (sk) {
+                       unix_sock_count++;
+                       max_level = max(max_level,
+                                       unix_sk(sk)->recursion_level);
+               }
+       }
+       if (unlikely(max_level > MAX_RECURSION_LEVEL))
+               return -ETOOMANYREFS;
 
        /*
         * Need to duplicate file references for the sake of garbage
@@ -1356,9 +1372,11 @@ static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
        if (!UNIXCB(skb).fp)
                return -ENOMEM;
 
-       for (i = scm->fp->count-1; i >= 0; i--)
-               unix_inflight(scm->fp->fp[i]);
-       return 0;
+       if (unix_sock_count) {
+               for (i = scm->fp->count - 1; i >= 0; i--)
+                       unix_inflight(scm->fp->fp[i]);
+       }
+       return max_level;
 }
 
 static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool send_fds)
@@ -1393,6 +1411,7 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
        struct sk_buff *skb;
        long timeo;
        struct scm_cookie tmp_scm;
+       int max_level;
 
        if (NULL == siocb->scm)
                siocb->scm = &tmp_scm;
@@ -1431,8 +1450,9 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
                goto out;
 
        err = unix_scm_to_skb(siocb->scm, skb, true);
-       if (err)
+       if (err < 0)
                goto out_free;
+       max_level = err + 1;
        unix_get_secdata(siocb->scm, skb);
 
        skb_reset_transport_header(skb);
@@ -1514,6 +1534,8 @@ restart:
        if (sock_flag(other, SOCK_RCVTSTAMP))
                __net_timestamp(skb);
        skb_queue_tail(&other->sk_receive_queue, skb);
+       if (max_level > unix_sk(other)->recursion_level)
+               unix_sk(other)->recursion_level = max_level;
        unix_state_unlock(other);
        other->sk_data_ready(other, len);
        sock_put(other);
@@ -1544,6 +1566,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
        int sent = 0;
        struct scm_cookie tmp_scm;
        bool fds_sent = false;
+       int max_level;
 
        if (NULL == siocb->scm)
                siocb->scm = &tmp_scm;
@@ -1607,10 +1630,11 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
 
                /* Only send the fds in the first buffer */
                err = unix_scm_to_skb(siocb->scm, skb, !fds_sent);
-               if (err) {
+               if (err < 0) {
                        kfree_skb(skb);
                        goto out_err;
                }
+               max_level = err + 1;
                fds_sent = true;
 
                err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size);
@@ -1626,6 +1650,8 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
                        goto pipe_err_free;
 
                skb_queue_tail(&other->sk_receive_queue, skb);
+               if (max_level > unix_sk(other)->recursion_level)
+                       unix_sk(other)->recursion_level = max_level;
                unix_state_unlock(other);
                other->sk_data_ready(other, size);
                sent += size;
@@ -1845,6 +1871,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
                unix_state_lock(sk);
                skb = skb_dequeue(&sk->sk_receive_queue);
                if (skb == NULL) {
+                       unix_sk(sk)->recursion_level = 0;
                        if (copied >= target)
                                goto unlock;
 
index c8df6fd..f89f83b 100644 (file)
@@ -96,7 +96,7 @@ static DECLARE_WAIT_QUEUE_HEAD(unix_gc_wait);
 unsigned int unix_tot_inflight;
 
 
-static struct sock *unix_get_socket(struct file *filp)
+struct sock *unix_get_socket(struct file *filp)
 {
        struct sock *u_sock = NULL;
        struct inode *inode = filp->f_path.dentry->d_inode;
@@ -259,9 +259,16 @@ static void inc_inflight_move_tail(struct unix_sock *u)
 }
 
 static bool gc_in_progress = false;
+#define UNIX_INFLIGHT_TRIGGER_GC 16000
 
 void wait_for_unix_gc(void)
 {
+       /*
+        * If number of inflight sockets is insane,
+        * force a garbage collect right now.
+        */
+       if (unix_tot_inflight > UNIX_INFLIGHT_TRIGGER_GC && !gc_in_progress)
+               unix_gc();
        wait_event(unix_gc_wait, gc_in_progress == false);
 }
 
index 73e7b95..b25c646 100644 (file)
@@ -394,6 +394,7 @@ void __exit x25_link_free(void)
        list_for_each_safe(entry, tmp, &x25_neigh_list) {
                nb = list_entry(entry, struct x25_neigh, node);
                __x25_remove_neigh(nb);
+               dev_put(nb->dev);
        }
        write_unlock_bh(&x25_neigh_list_lock);
 }
index eb96ce5..220ebc0 100644 (file)
@@ -1268,7 +1268,7 @@ struct xfrm_state * xfrm_state_migrate(struct xfrm_state *x,
 
        return xc;
 error:
-       kfree(xc);
+       xfrm_state_put(xc);
        return NULL;
 }
 EXPORT_SYMBOL(xfrm_state_migrate);
index 184eb6a..e57826c 100644 (file)
@@ -164,6 +164,7 @@ struct menu {
        struct menu *list;
        struct symbol *sym;
        struct property *prompt;
+       struct expr *visibility;
        struct expr *dep;
        unsigned int flags;
        char *help;
index 753cdbd..3f7240d 100644 (file)
@@ -107,6 +107,7 @@ void menu_end_menu(void);
 void menu_add_entry(struct symbol *sym);
 void menu_end_entry(void);
 void menu_add_dep(struct expr *dep);
+void menu_add_visibility(struct expr *dep);
 struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep);
 struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep);
 void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep);
index 7e83aef..b9d9aa1 100644 (file)
@@ -152,6 +152,12 @@ struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr
        return menu_add_prop(type, prompt, NULL, dep);
 }
 
+void menu_add_visibility(struct expr *expr)
+{
+       current_entry->visibility = expr_alloc_and(current_entry->visibility,
+           expr);
+}
+
 void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep)
 {
        menu_add_prop(type, NULL, expr, dep);
@@ -410,6 +416,11 @@ bool menu_is_visible(struct menu *menu)
        if (!menu->prompt)
                return false;
 
+       if (menu->visibility) {
+               if (expr_calc_value(menu->visibility) == no)
+                       return no;
+       }
+
        sym = menu->sym;
        if (sym) {
                sym_calc_value(sym);
index d8bc742..c9e690e 100644 (file)
@@ -38,6 +38,7 @@ hex,          T_TYPE,         TF_COMMAND, S_HEX
 string,                T_TYPE,         TF_COMMAND, S_STRING
 select,                T_SELECT,       TF_COMMAND
 range,         T_RANGE,        TF_COMMAND
+visible,       T_VISIBLE,      TF_COMMAND
 option,                T_OPTION,       TF_COMMAND
 on,            T_ON,           TF_PARAM
 modules,       T_OPT_MODULES,  TF_OPTION
index c1748fa..4055d5d 100644 (file)
@@ -32,7 +32,7 @@
 struct kconf_id;
 
 static struct kconf_id *kconf_id_lookup(register const char *str, register unsigned int len);
-/* maximum key range = 47, duplicates = 0 */
+/* maximum key range = 50, duplicates = 0 */
 
 #ifdef __GNUC__
 __inline
@@ -46,32 +46,32 @@ kconf_id_hash (register const char *str, register unsigned int len)
 {
   static unsigned char asso_values[] =
     {
-      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      49, 49, 49, 49, 49, 49, 49, 49, 11,  5,
-       0,  0,  5, 49,  5, 20, 49, 49,  5, 20,
-       5,  0, 30, 49,  0, 15,  0, 10,  0, 49,
-      25, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      49, 49, 49, 49, 49, 49
+      52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+      52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+      52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+      52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+      52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+      52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+      52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+      52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+      52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+      52, 52, 52, 52, 52, 52, 52, 52, 40,  5,
+       0,  0,  5, 52,  0, 20, 52, 52, 10, 20,
+       5,  0, 35, 52,  0, 30,  0, 15,  0, 52,
+      15, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+      52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+      52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+      52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+      52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+      52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+      52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+      52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+      52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+      52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+      52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+      52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+      52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+      52, 52, 52, 52, 52, 52
     };
   register int hval = len;
 
@@ -102,25 +102,26 @@ struct kconf_id_strings_t
     char kconf_id_strings_str12[sizeof("default")];
     char kconf_id_strings_str13[sizeof("def_bool")];
     char kconf_id_strings_str14[sizeof("help")];
-    char kconf_id_strings_str15[sizeof("bool")];
     char kconf_id_strings_str16[sizeof("config")];
     char kconf_id_strings_str17[sizeof("def_tristate")];
-    char kconf_id_strings_str18[sizeof("boolean")];
+    char kconf_id_strings_str18[sizeof("hex")];
     char kconf_id_strings_str19[sizeof("defconfig_list")];
-    char kconf_id_strings_str21[sizeof("string")];
     char kconf_id_strings_str22[sizeof("if")];
     char kconf_id_strings_str23[sizeof("int")];
-    char kconf_id_strings_str26[sizeof("select")];
     char kconf_id_strings_str27[sizeof("modules")];
     char kconf_id_strings_str28[sizeof("tristate")];
     char kconf_id_strings_str29[sizeof("menu")];
-    char kconf_id_strings_str31[sizeof("source")];
     char kconf_id_strings_str32[sizeof("comment")];
-    char kconf_id_strings_str33[sizeof("hex")];
     char kconf_id_strings_str35[sizeof("menuconfig")];
-    char kconf_id_strings_str36[sizeof("prompt")];
-    char kconf_id_strings_str37[sizeof("depends")];
+    char kconf_id_strings_str36[sizeof("string")];
+    char kconf_id_strings_str37[sizeof("visible")];
+    char kconf_id_strings_str41[sizeof("prompt")];
+    char kconf_id_strings_str42[sizeof("depends")];
+    char kconf_id_strings_str44[sizeof("bool")];
+    char kconf_id_strings_str46[sizeof("select")];
+    char kconf_id_strings_str47[sizeof("boolean")];
     char kconf_id_strings_str48[sizeof("mainmenu")];
+    char kconf_id_strings_str51[sizeof("source")];
   };
 static struct kconf_id_strings_t kconf_id_strings_contents =
   {
@@ -136,25 +137,26 @@ static struct kconf_id_strings_t kconf_id_strings_contents =
     "default",
     "def_bool",
     "help",
-    "bool",
     "config",
     "def_tristate",
-    "boolean",
+    "hex",
     "defconfig_list",
-    "string",
     "if",
     "int",
-    "select",
     "modules",
     "tristate",
     "menu",
-    "source",
     "comment",
-    "hex",
     "menuconfig",
+    "string",
+    "visible",
     "prompt",
     "depends",
-    "mainmenu"
+    "bool",
+    "select",
+    "boolean",
+    "mainmenu",
+    "source"
   };
 #define kconf_id_strings ((const char *) &kconf_id_strings_contents)
 #ifdef __GNUC__
@@ -168,11 +170,11 @@ kconf_id_lookup (register const char *str, register unsigned int len)
 {
   enum
     {
-      TOTAL_KEYWORDS = 31,
+      TOTAL_KEYWORDS = 32,
       MIN_WORD_LENGTH = 2,
       MAX_WORD_LENGTH = 14,
       MIN_HASH_VALUE = 2,
-      MAX_HASH_VALUE = 48
+      MAX_HASH_VALUE = 51
     };
 
   static struct kconf_id wordlist[] =
@@ -191,31 +193,35 @@ kconf_id_lookup (register const char *str, register unsigned int len)
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str12,   T_DEFAULT,      TF_COMMAND, S_UNKNOWN},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str13,   T_DEFAULT,      TF_COMMAND, S_BOOLEAN},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str14,           T_HELP,         TF_COMMAND},
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str15,           T_TYPE,         TF_COMMAND, S_BOOLEAN},
+      {-1},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str16,           T_CONFIG,       TF_COMMAND},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str17,   T_DEFAULT,      TF_COMMAND, S_TRISTATE},
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str18,   T_TYPE,         TF_COMMAND, S_BOOLEAN},
+      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str18,           T_TYPE,         TF_COMMAND, S_HEX},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str19,   T_OPT_DEFCONFIG_LIST,TF_OPTION},
-      {-1},
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str21,           T_TYPE,         TF_COMMAND, S_STRING},
+      {-1}, {-1},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str22,           T_IF,           TF_COMMAND|TF_PARAM},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str23,           T_TYPE,         TF_COMMAND, S_INT},
-      {-1}, {-1},
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str26,           T_SELECT,       TF_COMMAND},
+      {-1}, {-1}, {-1},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str27,   T_OPT_MODULES,  TF_OPTION},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str28,   T_TYPE,         TF_COMMAND, S_TRISTATE},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str29,           T_MENU,         TF_COMMAND},
-      {-1},
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str31,           T_SOURCE,       TF_COMMAND},
+      {-1}, {-1},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str32,   T_COMMENT,      TF_COMMAND},
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str33,           T_TYPE,         TF_COMMAND, S_HEX},
-      {-1},
+      {-1}, {-1},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str35,   T_MENUCONFIG,   TF_COMMAND},
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str36,           T_PROMPT,       TF_COMMAND},
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str37,   T_DEPENDS,      TF_COMMAND},
-      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str36,           T_TYPE,         TF_COMMAND, S_STRING},
+      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str37,   T_VISIBLE,      TF_COMMAND},
+      {-1}, {-1}, {-1},
+      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str41,           T_PROMPT,       TF_COMMAND},
+      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str42,   T_DEPENDS,      TF_COMMAND},
       {-1},
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str48,   T_MAINMENU,     TF_COMMAND}
+      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str44,           T_TYPE,         TF_COMMAND, S_BOOLEAN},
+      {-1},
+      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str46,           T_SELECT,       TF_COMMAND},
+      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str47,   T_TYPE,         TF_COMMAND, S_BOOLEAN},
+      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str48,   T_MAINMENU,     TF_COMMAND},
+      {-1}, {-1},
+      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str51,           T_SOURCE,       TF_COMMAND}
     };
 
   if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
index 699d4b2..4c5495e 100644 (file)
@@ -160,18 +160,19 @@ static struct menu *current_menu, *current_entry;
      T_DEFAULT = 275,
      T_SELECT = 276,
      T_RANGE = 277,
-     T_OPTION = 278,
-     T_ON = 279,
-     T_WORD = 280,
-     T_WORD_QUOTE = 281,
-     T_UNEQUAL = 282,
-     T_CLOSE_PAREN = 283,
-     T_OPEN_PAREN = 284,
-     T_EOL = 285,
-     T_OR = 286,
-     T_AND = 287,
-     T_EQUAL = 288,
-     T_NOT = 289
+     T_VISIBLE = 278,
+     T_OPTION = 279,
+     T_ON = 280,
+     T_WORD = 281,
+     T_WORD_QUOTE = 282,
+     T_UNEQUAL = 283,
+     T_CLOSE_PAREN = 284,
+     T_OPEN_PAREN = 285,
+     T_EOL = 286,
+     T_OR = 287,
+     T_AND = 288,
+     T_EQUAL = 289,
+     T_NOT = 290
    };
 #endif
 
@@ -419,20 +420,20 @@ union yyalloc
 /* YYFINAL -- State number of the termination state.  */
 #define YYFINAL  11
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   277
+#define YYLAST   290
 
 /* YYNTOKENS -- Number of terminals.  */
-#define YYNTOKENS  35
+#define YYNTOKENS  36
 /* YYNNTS -- Number of nonterminals.  */
-#define YYNNTS  48
+#define YYNNTS  50
 /* YYNRULES -- Number of rules.  */
-#define YYNRULES  113
+#define YYNRULES  118
 /* YYNRULES -- Number of states.  */
-#define YYNSTATES  185
+#define YYNSTATES  191
 
 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
 #define YYUNDEFTOK  2
-#define YYMAXUTOK   289
+#define YYMAXUTOK   290
 
 #define YYTRANSLATE(YYX)                                               \
   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -468,7 +469,8 @@ static const yytype_uint8 yytranslate[] =
        2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
        5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
       15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
-      25,    26,    27,    28,    29,    30,    31,    32,    33,    34
+      25,    26,    27,    28,    29,    30,    31,    32,    33,    34,
+      35
 };
 
 #if YYDEBUG
@@ -478,72 +480,73 @@ static const yytype_uint16 yyprhs[] =
 {
        0,     0,     3,     6,     8,    11,    13,    14,    17,    20,
       23,    26,    31,    36,    40,    42,    44,    46,    48,    50,
-      52,    54,    56,    58,    60,    62,    64,    66,    70,    73,
-      77,    80,    84,    87,    88,    91,    94,    97,   100,   103,
-     106,   110,   115,   120,   125,   131,   135,   136,   140,   141,
-     144,   148,   151,   153,   157,   158,   161,   164,   167,   170,
-     173,   178,   182,   185,   190,   191,   194,   198,   200,   204,
-     205,   208,   211,   214,   218,   222,   225,   227,   231,   232,
-     235,   238,   241,   245,   249,   252,   255,   258,   259,   262,
-     265,   268,   273,   274,   277,   279,   281,   284,   287,   290,
-     292,   295,   296,   299,   301,   305,   309,   313,   316,   320,
-     324,   326,   328,   329
+      52,    54,    56,    58,    60,    62,    64,    66,    68,    72,
+      75,    79,    82,    86,    89,    90,    93,    96,    99,   102,
+     105,   108,   112,   117,   122,   127,   133,   137,   138,   142,
+     143,   146,   150,   153,   155,   159,   160,   163,   166,   169,
+     172,   175,   180,   184,   187,   192,   193,   196,   200,   202,
+     206,   207,   210,   213,   216,   220,   224,   228,   230,   234,
+     235,   238,   241,   244,   248,   252,   255,   258,   261,   262,
+     265,   268,   271,   276,   277,   280,   283,   286,   287,   290,
+     292,   294,   297,   300,   303,   305,   308,   309,   312,   314,
+     318,   322,   326,   329,   333,   337,   339,   341,   342
 };
 
 /* YYRHS -- A `-1'-separated list of the rules' RHS.  */
 static const yytype_int8 yyrhs[] =
 {
-      36,     0,    -1,    78,    37,    -1,    37,    -1,    62,    38,
-      -1,    38,    -1,    -1,    38,    40,    -1,    38,    54,    -1,
-      38,    66,    -1,    38,    77,    -1,    38,    25,     1,    30,
-      -1,    38,    39,     1,    30,    -1,    38,     1,    30,    -1,
+      37,     0,    -1,    81,    38,    -1,    38,    -1,    63,    39,
+      -1,    39,    -1,    -1,    39,    41,    -1,    39,    55,    -1,
+      39,    67,    -1,    39,    80,    -1,    39,    26,     1,    31,
+      -1,    39,    40,     1,    31,    -1,    39,     1,    31,    -1,
       16,    -1,    18,    -1,    19,    -1,    21,    -1,    17,    -1,
-      22,    -1,    20,    -1,    30,    -1,    60,    -1,    70,    -1,
-      43,    -1,    45,    -1,    68,    -1,    25,     1,    30,    -1,
-       1,    30,    -1,    10,    25,    30,    -1,    42,    46,    -1,
-      11,    25,    30,    -1,    44,    46,    -1,    -1,    46,    47,
-      -1,    46,    48,    -1,    46,    74,    -1,    46,    72,    -1,
-      46,    41,    -1,    46,    30,    -1,    19,    75,    30,    -1,
-      18,    76,    79,    30,    -1,    20,    80,    79,    30,    -1,
-      21,    25,    79,    30,    -1,    22,    81,    81,    79,    30,
-      -1,    23,    49,    30,    -1,    -1,    49,    25,    50,    -1,
-      -1,    33,    76,    -1,     7,    82,    30,    -1,    51,    55,
-      -1,    77,    -1,    52,    57,    53,    -1,    -1,    55,    56,
-      -1,    55,    74,    -1,    55,    72,    -1,    55,    30,    -1,
-      55,    41,    -1,    18,    76,    79,    30,    -1,    19,    75,
-      30,    -1,    17,    30,    -1,    20,    25,    79,    30,    -1,
-      -1,    57,    40,    -1,    14,    80,    78,    -1,    77,    -1,
-      58,    61,    59,    -1,    -1,    61,    40,    -1,    61,    66,
-      -1,    61,    54,    -1,     3,    76,    78,    -1,     4,    76,
-      30,    -1,    63,    73,    -1,    77,    -1,    64,    67,    65,
-      -1,    -1,    67,    40,    -1,    67,    66,    -1,    67,    54,
-      -1,     6,    76,    30,    -1,     9,    76,    30,    -1,    69,
-      73,    -1,    12,    30,    -1,    71,    13,    -1,    -1,    73,
-      74,    -1,    73,    30,    -1,    73,    41,    -1,    16,    24,
-      80,    30,    -1,    -1,    76,    79,    -1,    25,    -1,    26,
-      -1,     5,    30,    -1,     8,    30,    -1,    15,    30,    -1,
-      30,    -1,    78,    30,    -1,    -1,    14,    80,    -1,    81,
-      -1,    81,    33,    81,    -1,    81,    27,    81,    -1,    29,
-      80,    28,    -1,    34,    80,    -1,    80,    31,    80,    -1,
-      80,    32,    80,    -1,    25,    -1,    26,    -1,    -1,    25,
-      -1
+      22,    -1,    20,    -1,    23,    -1,    31,    -1,    61,    -1,
+      71,    -1,    44,    -1,    46,    -1,    69,    -1,    26,     1,
+      31,    -1,     1,    31,    -1,    10,    26,    31,    -1,    43,
+      47,    -1,    11,    26,    31,    -1,    45,    47,    -1,    -1,
+      47,    48,    -1,    47,    49,    -1,    47,    75,    -1,    47,
+      73,    -1,    47,    42,    -1,    47,    31,    -1,    19,    78,
+      31,    -1,    18,    79,    82,    31,    -1,    20,    83,    82,
+      31,    -1,    21,    26,    82,    31,    -1,    22,    84,    84,
+      82,    31,    -1,    24,    50,    31,    -1,    -1,    50,    26,
+      51,    -1,    -1,    34,    79,    -1,     7,    85,    31,    -1,
+      52,    56,    -1,    80,    -1,    53,    58,    54,    -1,    -1,
+      56,    57,    -1,    56,    75,    -1,    56,    73,    -1,    56,
+      31,    -1,    56,    42,    -1,    18,    79,    82,    31,    -1,
+      19,    78,    31,    -1,    17,    31,    -1,    20,    26,    82,
+      31,    -1,    -1,    58,    41,    -1,    14,    83,    81,    -1,
+      80,    -1,    59,    62,    60,    -1,    -1,    62,    41,    -1,
+      62,    67,    -1,    62,    55,    -1,     3,    79,    81,    -1,
+       4,    79,    31,    -1,    64,    76,    74,    -1,    80,    -1,
+      65,    68,    66,    -1,    -1,    68,    41,    -1,    68,    67,
+      -1,    68,    55,    -1,     6,    79,    31,    -1,     9,    79,
+      31,    -1,    70,    74,    -1,    12,    31,    -1,    72,    13,
+      -1,    -1,    74,    75,    -1,    74,    31,    -1,    74,    42,
+      -1,    16,    25,    83,    31,    -1,    -1,    76,    77,    -1,
+      76,    31,    -1,    23,    82,    -1,    -1,    79,    82,    -1,
+      26,    -1,    27,    -1,     5,    31,    -1,     8,    31,    -1,
+      15,    31,    -1,    31,    -1,    81,    31,    -1,    -1,    14,
+      83,    -1,    84,    -1,    84,    34,    84,    -1,    84,    28,
+      84,    -1,    30,    83,    29,    -1,    35,    83,    -1,    83,
+      32,    83,    -1,    83,    33,    83,    -1,    26,    -1,    27,
+      -1,    -1,    26,    -1
 };
 
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
-       0,   107,   107,   107,   109,   109,   111,   113,   114,   115,
-     116,   117,   118,   122,   126,   126,   126,   126,   126,   126,
-     126,   130,   131,   132,   133,   134,   135,   139,   140,   146,
-     154,   160,   168,   178,   180,   181,   182,   183,   184,   185,
-     188,   196,   202,   212,   218,   224,   227,   229,   240,   241,
-     246,   255,   260,   268,   271,   273,   274,   275,   276,   277,
-     280,   286,   297,   303,   313,   315,   320,   328,   336,   339,
-     341,   342,   343,   348,   355,   362,   367,   375,   378,   380,
-     381,   382,   385,   393,   400,   407,   413,   420,   422,   423,
-     424,   427,   435,   437,   442,   443,   446,   447,   448,   452,
-     453,   456,   457,   460,   461,   462,   463,   464,   465,   466,
-     469,   470,   473,   474
+       0,   108,   108,   108,   110,   110,   112,   114,   115,   116,
+     117,   118,   119,   123,   127,   127,   127,   127,   127,   127,
+     127,   127,   131,   132,   133,   134,   135,   136,   140,   141,
+     147,   155,   161,   169,   179,   181,   182,   183,   184,   185,
+     186,   189,   197,   203,   213,   219,   225,   228,   230,   241,
+     242,   247,   256,   261,   269,   272,   274,   275,   276,   277,
+     278,   281,   287,   298,   304,   314,   316,   321,   329,   337,
+     340,   342,   343,   344,   349,   356,   363,   368,   376,   379,
+     381,   382,   383,   386,   394,   401,   408,   414,   421,   423,
+     424,   425,   428,   436,   438,   439,   442,   449,   451,   456,
+     457,   460,   461,   462,   466,   467,   470,   471,   474,   475,
+     476,   477,   478,   479,   480,   483,   484,   487,   488
 };
 #endif
 
@@ -556,7 +559,7 @@ static const char *const yytname[] =
   "T_SOURCE", "T_CHOICE", "T_ENDCHOICE", "T_COMMENT", "T_CONFIG",
   "T_MENUCONFIG", "T_HELP", "T_HELPTEXT", "T_IF", "T_ENDIF", "T_DEPENDS",
   "T_OPTIONAL", "T_PROMPT", "T_TYPE", "T_DEFAULT", "T_SELECT", "T_RANGE",
-  "T_OPTION", "T_ON", "T_WORD", "T_WORD_QUOTE", "T_UNEQUAL",
+  "T_VISIBLE", "T_OPTION", "T_ON", "T_WORD", "T_WORD_QUOTE", "T_UNEQUAL",
   "T_CLOSE_PAREN", "T_OPEN_PAREN", "T_EOL", "T_OR", "T_AND", "T_EQUAL",
   "T_NOT", "$accept", "input", "start", "stmt_list", "option_name",
   "common_stmt", "option_error", "config_entry_start", "config_stmt",
@@ -567,8 +570,8 @@ static const char *const yytname[] =
   "if_entry", "if_end", "if_stmt", "if_block", "mainmenu_stmt", "menu",
   "menu_entry", "menu_end", "menu_stmt", "menu_block", "source_stmt",
   "comment", "comment_stmt", "help_start", "help", "depends_list",
-  "depends", "prompt_stmt_opt", "prompt", "end", "nl", "if_expr", "expr",
-  "symbol", "word_opt", 0
+  "depends", "visibility_list", "visible", "prompt_stmt_opt", "prompt",
+  "end", "nl", "if_expr", "expr", "symbol", "word_opt", 0
 };
 #endif
 
@@ -580,25 +583,25 @@ static const yytype_uint16 yytoknum[] =
        0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
      265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
      275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
-     285,   286,   287,   288,   289
+     285,   286,   287,   288,   289,   290
 };
 # endif
 
 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
 static const yytype_uint8 yyr1[] =
 {
-       0,    35,    36,    36,    37,    37,    38,    38,    38,    38,
-      38,    38,    38,    38,    39,    39,    39,    39,    39,    39,
-      39,    40,    40,    40,    40,    40,    40,    41,    41,    42,
-      43,    44,    45,    46,    46,    46,    46,    46,    46,    46,
-      47,    47,    47,    47,    47,    48,    49,    49,    50,    50,
-      51,    52,    53,    54,    55,    55,    55,    55,    55,    55,
-      56,    56,    56,    56,    57,    57,    58,    59,    60,    61,
-      61,    61,    61,    62,    63,    64,    65,    66,    67,    67,
-      67,    67,    68,    69,    70,    71,    72,    73,    73,    73,
-      73,    74,    75,    75,    76,    76,    77,    77,    77,    78,
-      78,    79,    79,    80,    80,    80,    80,    80,    80,    80,
-      81,    81,    82,    82
+       0,    36,    37,    37,    38,    38,    39,    39,    39,    39,
+      39,    39,    39,    39,    40,    40,    40,    40,    40,    40,
+      40,    40,    41,    41,    41,    41,    41,    41,    42,    42,
+      43,    44,    45,    46,    47,    47,    47,    47,    47,    47,
+      47,    48,    48,    48,    48,    48,    49,    50,    50,    51,
+      51,    52,    53,    54,    55,    56,    56,    56,    56,    56,
+      56,    57,    57,    57,    57,    58,    58,    59,    60,    61,
+      62,    62,    62,    62,    63,    64,    65,    66,    67,    68,
+      68,    68,    68,    69,    70,    71,    72,    73,    74,    74,
+      74,    74,    75,    76,    76,    76,    77,    78,    78,    79,
+      79,    80,    80,    80,    81,    81,    82,    82,    83,    83,
+      83,    83,    83,    83,    83,    84,    84,    85,    85
 };
 
 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
@@ -606,16 +609,16 @@ static const yytype_uint8 yyr2[] =
 {
        0,     2,     2,     1,     2,     1,     0,     2,     2,     2,
        2,     4,     4,     3,     1,     1,     1,     1,     1,     1,
-       1,     1,     1,     1,     1,     1,     1,     3,     2,     3,
-       2,     3,     2,     0,     2,     2,     2,     2,     2,     2,
-       3,     4,     4,     4,     5,     3,     0,     3,     0,     2,
-       3,     2,     1,     3,     0,     2,     2,     2,     2,     2,
-       4,     3,     2,     4,     0,     2,     3,     1,     3,     0,
-       2,     2,     2,     3,     3,     2,     1,     3,     0,     2,
-       2,     2,     3,     3,     2,     2,     2,     0,     2,     2,
-       2,     4,     0,     2,     1,     1,     2,     2,     2,     1,
-       2,     0,     2,     1,     3,     3,     3,     2,     3,     3,
-       1,     1,     0,     1
+       1,     1,     1,     1,     1,     1,     1,     1,     3,     2,
+       3,     2,     3,     2,     0,     2,     2,     2,     2,     2,
+       2,     3,     4,     4,     4,     5,     3,     0,     3,     0,
+       2,     3,     2,     1,     3,     0,     2,     2,     2,     2,
+       2,     4,     3,     2,     4,     0,     2,     3,     1,     3,
+       0,     2,     2,     2,     3,     3,     3,     1,     3,     0,
+       2,     2,     2,     3,     3,     2,     2,     2,     0,     2,
+       2,     2,     4,     0,     2,     2,     2,     0,     2,     1,
+       1,     2,     2,     2,     1,     2,     0,     2,     1,     3,
+       3,     3,     2,     3,     3,     1,     1,     0,     1
 };
 
 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
@@ -623,165 +626,172 @@ static const yytype_uint8 yyr2[] =
    means the default is an error.  */
 static const yytype_uint8 yydefact[] =
 {
-       6,     0,    99,     0,     3,     0,     6,     6,    94,    95,
-       0,     1,     0,     0,     0,     0,   112,     0,     0,     0,
+       6,     0,   104,     0,     3,     0,     6,     6,    99,   100,
+       0,     1,     0,     0,     0,     0,   117,     0,     0,     0,
        0,     0,     0,    14,    18,    15,    16,    20,    17,    19,
-       0,    21,     0,     7,    33,    24,    33,    25,    54,    64,
-       8,    69,    22,    87,    78,     9,    26,    87,    23,    10,
-       0,   100,     2,    73,    13,     0,    96,     0,   113,     0,
-      97,     0,     0,     0,   110,   111,     0,     0,     0,   103,
-      98,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,    74,    82,    50,    83,    29,    31,     0,   107,     0,
-       0,    66,     0,     0,    11,    12,     0,     0,     0,     0,
-      92,     0,     0,     0,    46,     0,    39,    38,    34,    35,
-       0,    37,    36,     0,     0,    92,     0,    58,    59,    55,
-      57,    56,    65,    53,    52,    70,    72,    68,    71,    67,
-      89,    90,    88,    79,    81,    77,    80,    76,   106,   108,
-     109,   105,   104,    28,    85,     0,   101,     0,   101,   101,
-     101,     0,     0,     0,    86,    62,   101,     0,   101,     0,
-       0,     0,    40,    93,     0,     0,   101,    48,    45,    27,
-       0,    61,     0,    91,   102,    41,    42,    43,     0,     0,
-      47,    60,    63,    44,    49
+      21,     0,    22,     0,     7,    34,    25,    34,    26,    55,
+      65,     8,    70,    23,    93,    79,     9,    27,    88,    24,
+      10,     0,   105,     2,    74,    13,     0,   101,     0,   118,
+       0,   102,     0,     0,     0,   115,   116,     0,     0,     0,
+     108,   103,     0,     0,     0,     0,     0,     0,     0,    88,
+       0,     0,    75,    83,    51,    84,    30,    32,     0,   112,
+       0,     0,    67,     0,     0,    11,    12,     0,     0,     0,
+       0,    97,     0,     0,     0,    47,     0,    40,    39,    35,
+      36,     0,    38,    37,     0,     0,    97,     0,    59,    60,
+      56,    58,    57,    66,    54,    53,    71,    73,    69,    72,
+      68,   106,    95,     0,    94,    80,    82,    78,    81,    77,
+      90,    91,    89,   111,   113,   114,   110,   109,    29,    86,
+       0,   106,     0,   106,   106,   106,     0,     0,     0,    87,
+      63,   106,     0,   106,     0,    96,     0,     0,    41,    98,
+       0,     0,   106,    49,    46,    28,     0,    62,     0,   107,
+      92,    42,    43,    44,     0,     0,    48,    61,    64,    45,
+      50
 };
 
 /* YYDEFGOTO[NTERM-NUM].  */
 static const yytype_int16 yydefgoto[] =
 {
-      -1,     3,     4,     5,    32,    33,   107,    34,    35,    36,
-      37,    73,   108,   109,   152,   180,    38,    39,   123,    40,
-      75,   119,    76,    41,   127,    42,    77,     6,    43,    44,
-     135,    45,    79,    46,    47,    48,   110,   111,    78,   112,
-     147,   148,    49,     7,   161,    68,    69,    59
+      -1,     3,     4,     5,    33,    34,   108,    35,    36,    37,
+      38,    74,   109,   110,   157,   186,    39,    40,   124,    41,
+      76,   120,    77,    42,   128,    43,    78,     6,    44,    45,
+     137,    46,    80,    47,    48,    49,   111,   112,    81,   113,
+      79,   134,   152,   153,    50,     7,   165,    69,    70,    60
 };
 
 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
    STATE-NUM.  */
-#define YYPACT_NINF -89
+#define YYPACT_NINF -90
 static const yytype_int16 yypact[] =
 {
-       3,     4,   -89,    20,   -89,   100,   -89,     7,   -89,   -89,
-      -8,   -89,    17,     4,    28,     4,    37,    36,     4,    68,
-      87,   -18,    69,   -89,   -89,   -89,   -89,   -89,   -89,   -89,
-     128,   -89,   138,   -89,   -89,   -89,   -89,   -89,   -89,   -89,
-     -89,   -89,   -89,   -89,   -89,   -89,   -89,   -89,   -89,   -89,
-     127,   -89,   -89,   110,   -89,   126,   -89,   136,   -89,   137,
-     -89,   147,   150,   152,   -89,   -89,   -18,   -18,   171,   -14,
-     -89,   153,   157,    34,    67,   180,   233,   220,   207,   220,
-     154,   -89,   -89,   -89,   -89,   -89,   -89,     0,   -89,   -18,
-     -18,   110,    44,    44,   -89,   -89,   163,   174,   182,     4,
-       4,   -18,   194,    44,   -89,   219,   -89,   -89,   -89,   -89,
-     223,   -89,   -89,   203,     4,     4,   215,   -89,   -89,   -89,
-     -89,   -89,   -89,   -89,   -89,   -89,   -89,   -89,   -89,   -89,
-     -89,   -89,   -89,   -89,   -89,   -89,   -89,   -89,   -89,   213,
-     -89,   -89,   -89,   -89,   -89,   -18,   232,   227,   232,    -5,
-     232,    44,    35,   234,   -89,   -89,   232,   235,   232,   224,
-     -18,   236,   -89,   -89,   237,   238,   232,   216,   -89,   -89,
-     240,   -89,   241,   -89,    71,   -89,   -89,   -89,   242,     4,
-     -89,   -89,   -89,   -89,   -89
+       4,    42,   -90,    96,   -90,   111,   -90,    15,   -90,   -90,
+      75,   -90,    82,    42,   104,    42,   110,   107,    42,   115,
+     125,    -4,   121,   -90,   -90,   -90,   -90,   -90,   -90,   -90,
+     -90,   162,   -90,   163,   -90,   -90,   -90,   -90,   -90,   -90,
+     -90,   -90,   -90,   -90,   -90,   -90,   -90,   -90,   -90,   -90,
+     -90,   139,   -90,   -90,   138,   -90,   142,   -90,   143,   -90,
+     152,   -90,   164,   167,   168,   -90,   -90,    -4,    -4,    77,
+     -18,   -90,   177,   185,    33,    71,   195,   247,   236,    -2,
+     236,   171,   -90,   -90,   -90,   -90,   -90,   -90,    41,   -90,
+      -4,    -4,   138,    97,    97,   -90,   -90,   186,   187,   194,
+      42,    42,    -4,   196,    97,   -90,   219,   -90,   -90,   -90,
+     -90,   210,   -90,   -90,   204,    42,    42,   199,   -90,   -90,
+     -90,   -90,   -90,   -90,   -90,   -90,   -90,   -90,   -90,   -90,
+     -90,   222,   -90,   223,   -90,   -90,   -90,   -90,   -90,   -90,
+     -90,   -90,   -90,   -90,   215,   -90,   -90,   -90,   -90,   -90,
+      -4,   222,   228,   222,    -5,   222,    97,    35,   229,   -90,
+     -90,   222,   232,   222,    -4,   -90,   135,   233,   -90,   -90,
+     234,   235,   222,   240,   -90,   -90,   237,   -90,   239,   -13,
+     -90,   -90,   -90,   -90,   244,    42,   -90,   -90,   -90,   -90,
+     -90
 };
 
 /* YYPGOTO[NTERM-NUM].  */
 static const yytype_int16 yypgoto[] =
 {
-     -89,   -89,   255,   267,   -89,    47,   -57,   -89,   -89,   -89,
-     -89,   239,   -89,   -89,   -89,   -89,   -89,   -89,   -89,   130,
-     -89,   -89,   -89,   -89,   -89,   -89,   -89,   -89,   -89,   -89,
-     -89,   181,   -89,   -89,   -89,   -89,   -89,   199,   229,    16,
-     162,    -1,    74,    -7,   103,   -65,   -88,   -89
+     -90,   -90,   269,   271,   -90,    23,   -70,   -90,   -90,   -90,
+     -90,   243,   -90,   -90,   -90,   -90,   -90,   -90,   -90,   -48,
+     -90,   -90,   -90,   -90,   -90,   -90,   -90,   -90,   -90,   -90,
+     -90,   -20,   -90,   -90,   -90,   -90,   -90,   206,   205,   -68,
+     -90,   -90,   169,    -1,    27,    -7,   118,   -66,   -89,   -90
 };
 
 /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
    positive, shift that token.  If negative, reduce the rule which
    number is the opposite.  If zero, do what YYDEFACT says.
    If YYTABLE_NINF, syntax error.  */
-#define YYTABLE_NINF -85
+#define YYTABLE_NINF -86
 static const yytype_int16 yytable[] =
 {
-      10,    87,    88,    53,   141,   142,     1,    64,    65,   160,
-       1,    66,    55,    92,    57,   151,    67,    61,   118,    93,
-      11,   131,     2,   131,   139,   140,    89,    90,   138,     8,
-       9,    89,    90,     2,   -30,    96,   149,    51,   -30,   -30,
-     -30,   -30,   -30,   -30,   -30,   -30,    97,    54,   -30,   -30,
-      98,   -30,    99,   100,   101,   102,   103,   104,    56,   105,
-     167,    91,    58,   166,   106,   168,    60,   -32,    96,    64,
-      65,   -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,    97,
-     159,   -32,   -32,    98,   -32,    99,   100,   101,   102,   103,
-     104,   121,   105,    62,   132,   174,   132,   106,   146,    70,
-      -5,    12,    89,    90,    13,    14,    15,    16,    17,    18,
-      19,    20,    63,   156,    21,    22,    23,    24,    25,    26,
-      27,    28,    29,   122,   125,    30,   133,    -4,    12,    71,
-      31,    13,    14,    15,    16,    17,    18,    19,    20,    72,
-      51,    21,    22,    23,    24,    25,    26,    27,    28,    29,
-     124,   129,    30,   137,   -84,    96,    81,    31,   -84,   -84,
-     -84,   -84,   -84,   -84,   -84,   -84,    82,    83,   -84,   -84,
-      98,   -84,   -84,   -84,   -84,   -84,   -84,    84,   184,   105,
-      85,    96,    86,    94,   130,   -51,   -51,    95,   -51,   -51,
-     -51,   -51,    97,   143,   -51,   -51,    98,   113,   114,   115,
-     116,     2,    89,    90,   144,   105,   145,   126,    96,   134,
-     117,   -75,   -75,   -75,   -75,   -75,   -75,   -75,   -75,   150,
-     153,   -75,   -75,    98,    13,    14,    15,    16,    17,    18,
-      19,    20,   105,   155,    21,    22,   154,   130,    14,    15,
-     158,    17,    18,    19,    20,    90,   160,    21,    22,   179,
-      31,   163,   164,   165,   173,    89,    90,   162,   128,   170,
-     136,   172,    52,    31,   169,   171,   175,   176,   177,   178,
-     181,   182,   183,    50,   120,    74,    80,   157
+      10,    88,    89,    54,   146,   147,   119,     1,   122,   164,
+      93,   141,    56,   142,    58,   156,    94,    62,     1,    90,
+      91,   131,    65,    66,   144,   145,    67,    90,    91,   132,
+     127,    68,   136,   -31,    97,     2,   154,   -31,   -31,   -31,
+     -31,   -31,   -31,   -31,   -31,    98,    52,   -31,   -31,    99,
+     -31,   100,   101,   102,   103,   104,   -31,   105,   129,   106,
+     138,   173,    92,   141,   107,   142,   174,   172,     8,     9,
+     143,   -33,    97,    90,    91,   -33,   -33,   -33,   -33,   -33,
+     -33,   -33,   -33,    98,   166,   -33,   -33,    99,   -33,   100,
+     101,   102,   103,   104,   -33,   105,    11,   106,   179,   151,
+     123,   126,   107,   135,   125,   130,     2,   139,     2,    90,
+      91,    -5,    12,    55,   161,    13,    14,    15,    16,    17,
+      18,    19,    20,    65,    66,    21,    22,    23,    24,    25,
+      26,    27,    28,    29,    30,    57,    59,    31,    61,    -4,
+      12,    63,    32,    13,    14,    15,    16,    17,    18,    19,
+      20,    64,    71,    21,    22,    23,    24,    25,    26,    27,
+      28,    29,    30,    72,    73,    31,   180,    90,    91,    52,
+      32,   -85,    97,    82,    83,   -85,   -85,   -85,   -85,   -85,
+     -85,   -85,   -85,    84,   190,   -85,   -85,    99,   -85,   -85,
+     -85,   -85,   -85,   -85,   -85,    85,    97,   106,    86,    87,
+     -52,   -52,   140,   -52,   -52,   -52,   -52,    98,    95,   -52,
+     -52,    99,   114,   115,   116,   117,    96,   148,   149,   150,
+     158,   106,   155,   159,    97,   163,   118,   -76,   -76,   -76,
+     -76,   -76,   -76,   -76,   -76,   160,   164,   -76,   -76,    99,
+      13,    14,    15,    16,    17,    18,    19,    20,    91,   106,
+      21,    22,    14,    15,   140,    17,    18,    19,    20,   168,
+     175,    21,    22,   177,   181,   182,   183,    32,   187,   167,
+     188,   169,   170,   171,   185,   189,    53,    51,    32,   176,
+      75,   178,   121,     0,   133,   162,     0,     0,     0,     0,
+     184
 };
 
-static const yytype_uint8 yycheck[] =
+static const yytype_int16 yycheck[] =
 {
-       1,    66,    67,    10,    92,    93,     3,    25,    26,    14,
-       3,    29,    13,    27,    15,   103,    34,    18,    75,    33,
-       0,    78,    30,    80,    89,    90,    31,    32,    28,    25,
-      26,    31,    32,    30,     0,     1,   101,    30,     4,     5,
-       6,     7,     8,     9,    10,    11,    12,    30,    14,    15,
-      16,    17,    18,    19,    20,    21,    22,    23,    30,    25,
-      25,    68,    25,   151,    30,    30,    30,     0,     1,    25,
-      26,     4,     5,     6,     7,     8,     9,    10,    11,    12,
-     145,    14,    15,    16,    17,    18,    19,    20,    21,    22,
-      23,    75,    25,    25,    78,   160,    80,    30,    99,    30,
-       0,     1,    31,    32,     4,     5,     6,     7,     8,     9,
-      10,    11,    25,   114,    14,    15,    16,    17,    18,    19,
-      20,    21,    22,    76,    77,    25,    79,     0,     1,     1,
-      30,     4,     5,     6,     7,     8,     9,    10,    11,     1,
-      30,    14,    15,    16,    17,    18,    19,    20,    21,    22,
-      76,    77,    25,    79,     0,     1,    30,    30,     4,     5,
-       6,     7,     8,     9,    10,    11,    30,    30,    14,    15,
-      16,    17,    18,    19,    20,    21,    22,    30,   179,    25,
-      30,     1,    30,    30,    30,     5,     6,    30,     8,     9,
-      10,    11,    12,    30,    14,    15,    16,    17,    18,    19,
-      20,    30,    31,    32,    30,    25,    24,    77,     1,    79,
-      30,     4,     5,     6,     7,     8,     9,    10,    11,    25,
-       1,    14,    15,    16,     4,     5,     6,     7,     8,     9,
-      10,    11,    25,    30,    14,    15,    13,    30,     5,     6,
-      25,     8,     9,    10,    11,    32,    14,    14,    15,    33,
-      30,   148,   149,   150,    30,    31,    32,    30,    77,   156,
-      79,   158,     7,    30,    30,    30,    30,    30,    30,   166,
-      30,    30,    30,     6,    75,    36,    47,   115
+       1,    67,    68,    10,    93,    94,    76,     3,    76,    14,
+      28,    81,    13,    81,    15,   104,    34,    18,     3,    32,
+      33,    23,    26,    27,    90,    91,    30,    32,    33,    31,
+      78,    35,    80,     0,     1,    31,   102,     4,     5,     6,
+       7,     8,     9,    10,    11,    12,    31,    14,    15,    16,
+      17,    18,    19,    20,    21,    22,    23,    24,    78,    26,
+      80,    26,    69,   133,    31,   133,    31,   156,    26,    27,
+      29,     0,     1,    32,    33,     4,     5,     6,     7,     8,
+       9,    10,    11,    12,   150,    14,    15,    16,    17,    18,
+      19,    20,    21,    22,    23,    24,     0,    26,   164,   100,
+      77,    78,    31,    80,    77,    78,    31,    80,    31,    32,
+      33,     0,     1,    31,   115,     4,     5,     6,     7,     8,
+       9,    10,    11,    26,    27,    14,    15,    16,    17,    18,
+      19,    20,    21,    22,    23,    31,    26,    26,    31,     0,
+       1,    26,    31,     4,     5,     6,     7,     8,     9,    10,
+      11,    26,    31,    14,    15,    16,    17,    18,    19,    20,
+      21,    22,    23,     1,     1,    26,    31,    32,    33,    31,
+      31,     0,     1,    31,    31,     4,     5,     6,     7,     8,
+       9,    10,    11,    31,   185,    14,    15,    16,    17,    18,
+      19,    20,    21,    22,    23,    31,     1,    26,    31,    31,
+       5,     6,    31,     8,     9,    10,    11,    12,    31,    14,
+      15,    16,    17,    18,    19,    20,    31,    31,    31,    25,
+       1,    26,    26,    13,     1,    26,    31,     4,     5,     6,
+       7,     8,     9,    10,    11,    31,    14,    14,    15,    16,
+       4,     5,     6,     7,     8,     9,    10,    11,    33,    26,
+      14,    15,     5,     6,    31,     8,     9,    10,    11,    31,
+      31,    14,    15,    31,    31,    31,    31,    31,    31,   151,
+      31,   153,   154,   155,    34,    31,     7,     6,    31,   161,
+      37,   163,    76,    -1,    79,   116,    -1,    -1,    -1,    -1,
+     172
 };
 
 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
    symbol of state STATE-NUM.  */
 static const yytype_uint8 yystos[] =
 {
-       0,     3,    30,    36,    37,    38,    62,    78,    25,    26,
-      76,     0,     1,     4,     5,     6,     7,     8,     9,    10,
+       0,     3,    31,    37,    38,    39,    63,    81,    26,    27,
+      79,     0,     1,     4,     5,     6,     7,     8,     9,    10,
       11,    14,    15,    16,    17,    18,    19,    20,    21,    22,
-      25,    30,    39,    40,    42,    43,    44,    45,    51,    52,
-      54,    58,    60,    63,    64,    66,    68,    69,    70,    77,
-      38,    30,    37,    78,    30,    76,    30,    76,    25,    82,
-      30,    76,    25,    25,    25,    26,    29,    34,    80,    81,
-      30,     1,     1,    46,    46,    55,    57,    61,    73,    67,
-      73,    30,    30,    30,    30,    30,    30,    80,    80,    31,
-      32,    78,    27,    33,    30,    30,     1,    12,    16,    18,
-      19,    20,    21,    22,    23,    25,    30,    41,    47,    48,
-      71,    72,    74,    17,    18,    19,    20,    30,    41,    56,
-      72,    74,    40,    53,    77,    40,    54,    59,    66,    77,
-      30,    41,    74,    40,    54,    65,    66,    77,    28,    80,
-      80,    81,    81,    30,    30,    24,    76,    75,    76,    80,
-      25,    81,    49,     1,    13,    30,    76,    75,    25,    80,
-      14,    79,    30,    79,    79,    79,    81,    25,    30,    30,
-      79,    30,    79,    30,    80,    30,    30,    30,    79,    33,
-      50,    30,    30,    30,    76
+      23,    26,    31,    40,    41,    43,    44,    45,    46,    52,
+      53,    55,    59,    61,    64,    65,    67,    69,    70,    71,
+      80,    39,    31,    38,    81,    31,    79,    31,    79,    26,
+      85,    31,    79,    26,    26,    26,    27,    30,    35,    83,
+      84,    31,     1,     1,    47,    47,    56,    58,    62,    76,
+      68,    74,    31,    31,    31,    31,    31,    31,    83,    83,
+      32,    33,    81,    28,    34,    31,    31,     1,    12,    16,
+      18,    19,    20,    21,    22,    24,    26,    31,    42,    48,
+      49,    72,    73,    75,    17,    18,    19,    20,    31,    42,
+      57,    73,    75,    41,    54,    80,    41,    55,    60,    67,
+      80,    23,    31,    74,    77,    41,    55,    66,    67,    80,
+      31,    42,    75,    29,    83,    83,    84,    84,    31,    31,
+      25,    79,    78,    79,    83,    26,    84,    50,     1,    13,
+      31,    79,    78,    26,    14,    82,    83,    82,    31,    82,
+      82,    82,    84,    26,    31,    31,    82,    31,    82,    83,
+      31,    31,    31,    31,    82,    34,    51,    31,    31,    31,
+      79
 };
 
 #define yyerrok                (yyerrstatus = 0)
@@ -1292,7 +1302,7 @@ yydestruct (yymsg, yytype, yyvaluep)
 
   switch (yytype)
     {
-      case 52: /* "choice_entry" */
+      case 53: /* "choice_entry" */
 
        {
        fprintf(stderr, "%s:%d: missing end statement for this entry\n",
@@ -1302,7 +1312,7 @@ yydestruct (yymsg, yytype, yyvaluep)
 };
 
        break;
-      case 58: /* "if_entry" */
+      case 59: /* "if_entry" */
 
        {
        fprintf(stderr, "%s:%d: missing end statement for this entry\n",
@@ -1312,7 +1322,7 @@ yydestruct (yymsg, yytype, yyvaluep)
 };
 
        break;
-      case 64: /* "menu_entry" */
+      case 65: /* "menu_entry" */
 
        {
        fprintf(stderr, "%s:%d: missing end statement for this entry\n",
@@ -1644,17 +1654,17 @@ yyreduce:
     { zconf_error("invalid statement"); ;}
     break;
 
-  case 27:
+  case 28:
 
     { zconf_error("unknown option \"%s\"", (yyvsp[(1) - (3)].string)); ;}
     break;
 
-  case 28:
+  case 29:
 
     { zconf_error("invalid option"); ;}
     break;
 
-  case 29:
+  case 30:
 
     {
        struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), 0);
@@ -1664,7 +1674,7 @@ yyreduce:
 ;}
     break;
 
-  case 30:
+  case 31:
 
     {
        menu_end_entry();
@@ -1672,7 +1682,7 @@ yyreduce:
 ;}
     break;
 
-  case 31:
+  case 32:
 
     {
        struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), 0);
@@ -1682,7 +1692,7 @@ yyreduce:
 ;}
     break;
 
-  case 32:
+  case 33:
 
     {
        if (current_entry->prompt)
@@ -1694,7 +1704,7 @@ yyreduce:
 ;}
     break;
 
-  case 40:
+  case 41:
 
     {
        menu_set_type((yyvsp[(1) - (3)].id)->stype);
@@ -1704,7 +1714,7 @@ yyreduce:
 ;}
     break;
 
-  case 41:
+  case 42:
 
     {
        menu_add_prompt(P_PROMPT, (yyvsp[(2) - (4)].string), (yyvsp[(3) - (4)].expr));
@@ -1712,7 +1722,7 @@ yyreduce:
 ;}
     break;
 
-  case 42:
+  case 43:
 
     {
        menu_add_expr(P_DEFAULT, (yyvsp[(2) - (4)].expr), (yyvsp[(3) - (4)].expr));
@@ -1724,7 +1734,7 @@ yyreduce:
 ;}
     break;
 
-  case 43:
+  case 44:
 
     {
        menu_add_symbol(P_SELECT, sym_lookup((yyvsp[(2) - (4)].string), 0), (yyvsp[(3) - (4)].expr));
@@ -1732,7 +1742,7 @@ yyreduce:
 ;}
     break;
 
-  case 44:
+  case 45:
 
     {
        menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,(yyvsp[(2) - (5)].symbol), (yyvsp[(3) - (5)].symbol)), (yyvsp[(4) - (5)].expr));
@@ -1740,7 +1750,7 @@ yyreduce:
 ;}
     break;
 
-  case 47:
+  case 48:
 
     {
        struct kconf_id *id = kconf_id_lookup((yyvsp[(2) - (3)].string), strlen((yyvsp[(2) - (3)].string)));
@@ -1752,17 +1762,17 @@ yyreduce:
 ;}
     break;
 
-  case 48:
+  case 49:
 
     { (yyval.string) = NULL; ;}
     break;
 
-  case 49:
+  case 50:
 
     { (yyval.string) = (yyvsp[(2) - (2)].string); ;}
     break;
 
-  case 50:
+  case 51:
 
     {
        struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), SYMBOL_CHOICE);
@@ -1773,14 +1783,14 @@ yyreduce:
 ;}
     break;
 
-  case 51:
+  case 52:
 
     {
        (yyval.menu) = menu_add_menu();
 ;}
     break;
 
-  case 52:
+  case 53:
 
     {
        if (zconf_endtoken((yyvsp[(1) - (1)].id), T_CHOICE, T_ENDCHOICE)) {
@@ -1790,7 +1800,7 @@ yyreduce:
 ;}
     break;
 
-  case 60:
+  case 61:
 
     {
        menu_add_prompt(P_PROMPT, (yyvsp[(2) - (4)].string), (yyvsp[(3) - (4)].expr));
@@ -1798,7 +1808,7 @@ yyreduce:
 ;}
     break;
 
-  case 61:
+  case 62:
 
     {
        if ((yyvsp[(1) - (3)].id)->stype == S_BOOLEAN || (yyvsp[(1) - (3)].id)->stype == S_TRISTATE) {
@@ -1811,7 +1821,7 @@ yyreduce:
 ;}
     break;
 
-  case 62:
+  case 63:
 
     {
        current_entry->sym->flags |= SYMBOL_OPTIONAL;
@@ -1819,7 +1829,7 @@ yyreduce:
 ;}
     break;
 
-  case 63:
+  case 64:
 
     {
        if ((yyvsp[(1) - (4)].id)->stype == S_UNKNOWN) {
@@ -1831,7 +1841,7 @@ yyreduce:
 ;}
     break;
 
-  case 66:
+  case 67:
 
     {
        printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
@@ -1841,7 +1851,7 @@ yyreduce:
 ;}
     break;
 
-  case 67:
+  case 68:
 
     {
        if (zconf_endtoken((yyvsp[(1) - (1)].id), T_IF, T_ENDIF)) {
@@ -1851,14 +1861,14 @@ yyreduce:
 ;}
     break;
 
-  case 73:
+  case 74:
 
     {
        menu_add_prompt(P_MENU, (yyvsp[(2) - (3)].string), NULL);
 ;}
     break;
 
-  case 74:
+  case 75:
 
     {
        menu_add_entry(NULL);
@@ -1867,14 +1877,14 @@ yyreduce:
 ;}
     break;
 
-  case 75:
+  case 76:
 
     {
        (yyval.menu) = menu_add_menu();
 ;}
     break;
 
-  case 76:
+  case 77:
 
     {
        if (zconf_endtoken((yyvsp[(1) - (1)].id), T_MENU, T_ENDMENU)) {
@@ -1884,7 +1894,7 @@ yyreduce:
 ;}
     break;
 
-  case 82:
+  case 83:
 
     {
        printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), (yyvsp[(2) - (3)].string));
@@ -1892,7 +1902,7 @@ yyreduce:
 ;}
     break;
 
-  case 83:
+  case 84:
 
     {
        menu_add_entry(NULL);
@@ -1901,14 +1911,14 @@ yyreduce:
 ;}
     break;
 
-  case 84:
+  case 85:
 
     {
        menu_end_entry();
 ;}
     break;
 
-  case 85:
+  case 86:
 
     {
        printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno());
@@ -1916,14 +1926,14 @@ yyreduce:
 ;}
     break;
 
-  case 86:
+  case 87:
 
     {
        current_entry->help = (yyvsp[(2) - (2)].string);
 ;}
     break;
 
-  case 91:
+  case 92:
 
     {
        menu_add_dep((yyvsp[(3) - (4)].expr));
@@ -1931,84 +1941,91 @@ yyreduce:
 ;}
     break;
 
-  case 93:
+  case 96:
+
+    {
+       menu_add_visibility((yyvsp[(2) - (2)].expr));
+;}
+    break;
+
+  case 98:
 
     {
        menu_add_prompt(P_PROMPT, (yyvsp[(1) - (2)].string), (yyvsp[(2) - (2)].expr));
 ;}
     break;
 
-  case 96:
+  case 101:
 
     { (yyval.id) = (yyvsp[(1) - (2)].id); ;}
     break;
 
-  case 97:
+  case 102:
 
     { (yyval.id) = (yyvsp[(1) - (2)].id); ;}
     break;
 
-  case 98:
+  case 103:
 
     { (yyval.id) = (yyvsp[(1) - (2)].id); ;}
     break;
 
-  case 101:
+  case 106:
 
     { (yyval.expr) = NULL; ;}
     break;
 
-  case 102:
+  case 107:
 
     { (yyval.expr) = (yyvsp[(2) - (2)].expr); ;}
     break;
 
-  case 103:
+  case 108:
 
     { (yyval.expr) = expr_alloc_symbol((yyvsp[(1) - (1)].symbol)); ;}
     break;
 
-  case 104:
+  case 109:
 
     { (yyval.expr) = expr_alloc_comp(E_EQUAL, (yyvsp[(1) - (3)].symbol), (yyvsp[(3) - (3)].symbol)); ;}
     break;
 
-  case 105:
+  case 110:
 
     { (yyval.expr) = expr_alloc_comp(E_UNEQUAL, (yyvsp[(1) - (3)].symbol), (yyvsp[(3) - (3)].symbol)); ;}
     break;
 
-  case 106:
+  case 111:
 
     { (yyval.expr) = (yyvsp[(2) - (3)].expr); ;}
     break;
 
-  case 107:
+  case 112:
 
     { (yyval.expr) = expr_alloc_one(E_NOT, (yyvsp[(2) - (2)].expr)); ;}
     break;
 
-  case 108:
+  case 113:
 
     { (yyval.expr) = expr_alloc_two(E_OR, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;}
     break;
 
-  case 109:
+  case 114:
 
     { (yyval.expr) = expr_alloc_two(E_AND, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;}
     break;
 
-  case 110:
+  case 115:
 
     { (yyval.symbol) = sym_lookup((yyvsp[(1) - (1)].string), 0); free((yyvsp[(1) - (1)].string)); ;}
     break;
 
-  case 111:
+  case 116:
 
     { (yyval.symbol) = sym_lookup((yyvsp[(1) - (1)].string), SYMBOL_CONST); free((yyvsp[(1) - (1)].string)); ;}
     break;
 
-  case 112:
+  case 117:
 
     { (yyval.string) = NULL; ;}
     break;
@@ -2278,6 +2295,7 @@ static const char *zconf_tokenname(int token)
        case T_IF:              return "if";
        case T_ENDIF:           return "endif";
        case T_DEPENDS:         return "depends";
+       case T_VISIBLE:         return "visible";
        }
        return "<token>";
 }
index 2abd3c7..49fb4ab 100644 (file)
@@ -36,7 +36,7 @@ static struct menu *current_menu, *current_entry;
 #define YYERROR_VERBOSE
 #endif
 %}
-%expect 28
+%expect 30
 
 %union
 {
@@ -68,6 +68,7 @@ static struct menu *current_menu, *current_entry;
 %token <id>T_DEFAULT
 %token <id>T_SELECT
 %token <id>T_RANGE
+%token <id>T_VISIBLE
 %token <id>T_OPTION
 %token <id>T_ON
 %token <string> T_WORD
@@ -123,7 +124,7 @@ stmt_list:
 ;
 
 option_name:
-       T_DEPENDS | T_PROMPT | T_TYPE | T_SELECT | T_OPTIONAL | T_RANGE | T_DEFAULT
+       T_DEPENDS | T_PROMPT | T_TYPE | T_SELECT | T_OPTIONAL | T_RANGE | T_DEFAULT | T_VISIBLE
 ;
 
 common_stmt:
@@ -359,7 +360,7 @@ menu: T_MENU prompt T_EOL
        printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno());
 };
 
-menu_entry: menu depends_list
+menu_entry: menu visibility_list depends_list
 {
        $$ = menu_add_menu();
 };
@@ -430,6 +431,19 @@ depends: T_DEPENDS T_ON expr T_EOL
        printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno());
 };
 
+/* visibility option */
+
+visibility_list:
+         /* empty */
+       | visibility_list visible
+       | visibility_list T_EOL
+;
+
+visible: T_VISIBLE if_expr
+{
+       menu_add_visibility($2);
+};
+
 /* prompt statement */
 
 prompt_stmt_opt:
@@ -526,6 +540,7 @@ static const char *zconf_tokenname(int token)
        case T_IF:              return "if";
        case T_ENDIF:           return "endif";
        case T_DEPENDS:         return "depends";
+       case T_VISIBLE:         return "visible";
        }
        return "<token>";
 }
index 58e933a..3966717 100644 (file)
@@ -119,7 +119,7 @@ static uint_t (*Elf_r_sym)(Elf_Rel const *rp) = fn_ELF_R_SYM;
 
 static void fn_ELF_R_INFO(Elf_Rel *const rp, unsigned sym, unsigned type)
 {
-       rp->r_info = ELF_R_INFO(sym, type);
+       rp->r_info = _w(ELF_R_INFO(sym, type));
 }
 static void (*Elf_r_info)(Elf_Rel *const rp, unsigned sym, unsigned type) = fn_ELF_R_INFO;
 
index 8509bb5..bbbe584 100755 (executable)
@@ -125,7 +125,9 @@ exuberant()
        -I DEFINE_TRACE,EXPORT_TRACEPOINT_SYMBOL,EXPORT_TRACEPOINT_SYMBOL_GPL \
        --extra=+f --c-kinds=-px                                \
        --regex-asm='/^ENTRY\(([^)]*)\).*/\1/'                  \
-       --regex-c='/^SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/sys_\1/'
+       --regex-c='/^SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/sys_\1/' \
+       --regex-c++='/^TRACE_EVENT\(([^,)]*).*/trace_\1/'               \
+       --regex-c++='/^DEFINE_EVENT\(([^,)]*).*/trace_\1/'
 
        all_kconfigs | xargs $1 -a                              \
        --langdef=kconfig --language-force=kconfig              \
index 5c8c7df..b753ec6 100644 (file)
@@ -1510,16 +1510,19 @@ static ssize_t snd_pcm_oss_read1(struct snd_pcm_substream *substream, char __use
 static int snd_pcm_oss_reset(struct snd_pcm_oss_file *pcm_oss_file)
 {
        struct snd_pcm_substream *substream;
+       struct snd_pcm_runtime *runtime;
+       int i;
 
-       substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
-       if (substream != NULL) {
-               snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL);
-               substream->runtime->oss.prepare = 1;
-       }
-       substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE];
-       if (substream != NULL) {
+       for (i = 0; i < 2; i++) { 
+               substream = pcm_oss_file->streams[i];
+               if (!substream)
+                       continue;
+               runtime = substream->runtime;
                snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL);
-               substream->runtime->oss.prepare = 1;
+               runtime->oss.prepare = 1;
+               runtime->oss.buffer_used = 0;
+               runtime->oss.prev_hw_ptr_period = 0;
+               runtime->oss.period_ptr = 0;
        }
        return 0;
 }
index cb0c23a..4a66347 100644 (file)
@@ -189,6 +189,9 @@ static void hdmi_update_short_audio_desc(struct cea_sad *a,
        a->channels = GRAB_BITS(buf, 0, 0, 3);
        a->channels++;
 
+       a->sample_bits = 0;
+       a->max_bitrate = 0;
+
        a->format = GRAB_BITS(buf, 0, 3, 4);
        switch (a->format) {
        case AUDIO_CODING_TYPE_REF_STREAM_HEADER:
@@ -198,7 +201,6 @@ static void hdmi_update_short_audio_desc(struct cea_sad *a,
 
        case AUDIO_CODING_TYPE_LPCM:
                val = GRAB_BITS(buf, 2, 0, 3);
-               a->sample_bits = 0;
                for (i = 0; i < 3; i++)
                        if (val & (1 << i))
                                a->sample_bits |= cea_sample_sizes[i + 1];
@@ -598,24 +600,19 @@ void hdmi_eld_update_pcm_info(struct hdmi_eld *eld, struct hda_pcm_stream *pcm,
 {
        int i;
 
-       pcm->rates = 0;
-       pcm->formats = 0;
-       pcm->maxbps = 0;
-       pcm->channels_min = -1;
-       pcm->channels_max = 0;
+       /* assume basic audio support (the basic audio flag is not in ELD;
+        * however, all audio capable sinks are required to support basic
+        * audio) */
+       pcm->rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000;
+       pcm->formats = SNDRV_PCM_FMTBIT_S16_LE;
+       pcm->maxbps = 16;
+       pcm->channels_max = 2;
        for (i = 0; i < eld->sad_count; i++) {
                struct cea_sad *a = &eld->sad[i];
                pcm->rates |= a->rates;
-               if (a->channels < pcm->channels_min)
-                       pcm->channels_min = a->channels;
                if (a->channels > pcm->channels_max)
                        pcm->channels_max = a->channels;
                if (a->format == AUDIO_CODING_TYPE_LPCM) {
-                       if (a->sample_bits & AC_SUPPCM_BITS_16) {
-                               pcm->formats |= SNDRV_PCM_FMTBIT_S16_LE;
-                               if (pcm->maxbps < 16)
-                                       pcm->maxbps = 16;
-                       }
                        if (a->sample_bits & AC_SUPPCM_BITS_20) {
                                pcm->formats |= SNDRV_PCM_FMTBIT_S32_LE;
                                if (pcm->maxbps < 20)
@@ -635,7 +632,6 @@ void hdmi_eld_update_pcm_info(struct hdmi_eld *eld, struct hda_pcm_stream *pcm,
        /* restrict the parameters by the values the codec provides */
        pcm->rates &= codec_pars->rates;
        pcm->formats &= codec_pars->formats;
-       pcm->channels_min = max(pcm->channels_min, codec_pars->channels_min);
        pcm->channels_max = min(pcm->channels_max, codec_pars->channels_max);
        pcm->maxbps = min(pcm->maxbps, codec_pars->maxbps);
 }
index 21aa9b0..b030c8e 100644 (file)
@@ -2296,6 +2296,7 @@ static int azx_dev_free(struct snd_device *device)
  */
 static struct snd_pci_quirk position_fix_list[] __devinitdata = {
        SND_PCI_QUIRK(0x1025, 0x009f, "Acer Aspire 5110", POS_FIX_LPIB),
+       SND_PCI_QUIRK(0x1025, 0x026f, "Acer Aspire 5538", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB),
index 846d1ea..76bd58a 100644 (file)
@@ -2116,8 +2116,8 @@ static void cxt5066_update_speaker(struct hda_codec *codec)
        struct conexant_spec *spec = codec->spec;
        unsigned int pinctl;
 
-       snd_printdd("CXT5066: update speaker, hp_present=%d\n",
-               spec->hp_present);
+       snd_printdd("CXT5066: update speaker, hp_present=%d, cur_eapd=%d\n",
+                   spec->hp_present, spec->cur_eapd);
 
        /* Port A (HP) */
        pinctl = ((spec->hp_present & 1) && spec->cur_eapd) ? PIN_HP : 0;
@@ -2125,11 +2125,20 @@ static void cxt5066_update_speaker(struct hda_codec *codec)
                        pinctl);
 
        /* Port D (HP/LO) */
-       pinctl = ((spec->hp_present & 2) && spec->cur_eapd)
-               ? spec->port_d_mode : 0;
-       /* Mute if Port A is connected on Thinkpad */
-       if (spec->thinkpad && (spec->hp_present & 1))
-               pinctl = 0;
+       if (spec->dell_automute) {
+               /* DELL AIO Port Rule: PortA>  PortD>  IntSpk */
+               pinctl = (!(spec->hp_present & 1) && spec->cur_eapd)
+                       ? PIN_OUT : 0;
+       } else if (spec->thinkpad) {
+               if (spec->cur_eapd)
+                       pinctl = spec->port_d_mode;
+               /* Mute dock line-out if Port A (laptop HP) is present */
+               if (spec->hp_present&  1)
+                       pinctl = 0;
+       } else {
+               pinctl = ((spec->hp_present & 2) && spec->cur_eapd)
+                       ? spec->port_d_mode : 0;
+       }
        snd_hda_codec_write(codec, 0x1c, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
                        pinctl);
 
@@ -2137,14 +2146,6 @@ static void cxt5066_update_speaker(struct hda_codec *codec)
        pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0;
        snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
                        pinctl);
-
-       if (spec->dell_automute) {
-               /* DELL AIO Port Rule: PortA > PortD > IntSpk */
-               pinctl = (!(spec->hp_present & 1) && spec->cur_eapd)
-                       ? PIN_OUT : 0;
-               snd_hda_codec_write(codec, 0x1c, 0,
-                       AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl);
-       }
 }
 
 /* turn on/off EAPD (+ mute HP) as a master switch */
@@ -3095,8 +3096,7 @@ static const char *cxt5066_models[CXT5066_MODELS] = {
 static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
        SND_PCI_QUIRK_MASK(0x1025, 0xff00, 0x0400, "Acer", CXT5066_IDEAPAD),
        SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTRO),
-       SND_PCI_QUIRK(0x1028, 0x02f5, "Dell",
-                     CXT5066_DELL_LAPTOP),
+       SND_PCI_QUIRK(0x1028, 0x02f5, "Dell Vostro 320", CXT5066_IDEAPAD),
        SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTRO),
        SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD),
        SND_PCI_QUIRK(0x103c, 0x360b, "HP G60", CXT5066_HP_LAPTOP),
@@ -3109,6 +3109,7 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
        SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5),
        SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD),
        SND_PCI_QUIRK(0x17aa, 0x21b2, "Thinkpad X100e", CXT5066_IDEAPAD),
+       SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD),
        SND_PCI_QUIRK(0x17aa, 0x21b3, "Thinkpad Edge 13 (197)", CXT5066_IDEAPAD),
        SND_PCI_QUIRK(0x17aa, 0x21b4, "Thinkpad Edge", CXT5066_IDEAPAD),
        SND_PCI_QUIRK(0x17aa, 0x21c8, "Thinkpad Edge 11", CXT5066_IDEAPAD),
index d3e49aa..31df774 100644 (file)
@@ -834,7 +834,6 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
                        return -ENODEV;
        } else {
                /* fallback to the codec default */
-               hinfo->channels_min = codec_pars->channels_min;
                hinfo->channels_max = codec_pars->channels_max;
                hinfo->rates = codec_pars->rates;
                hinfo->formats = codec_pars->formats;
index 0ac6aed..427da45 100644 (file)
@@ -1614,6 +1614,7 @@ do_sku:
                spec->init_amp = ALC_INIT_GPIO3;
                break;
        case 5:
+       default:
                spec->init_amp = ALC_INIT_DEFAULT;
                break;
        }
@@ -2013,6 +2014,36 @@ static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
        { }
 };
 
+/*
+ *ALC888 Acer Aspire 7730G model
+ */
+
+static struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
+/* Bias voltage on for external mic port */
+       {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
+/* Front Mic: set to PIN_IN (empty by default) */
+       {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+/* Unselect Front Mic by default in input mixer 3 */
+       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
+/* Enable unsolicited event for HP jack */
+       {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
+/* Enable speaker output */
+       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+       {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+       {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
+/* Enable headphone output */
+       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
+       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+       {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
+       {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
+/*Enable internal subwoofer */
+       {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+       {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+       {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
+       {0x17, AC_VERB_SET_EAPD_BTLENABLE, 2},
+       { }
+};
+
 /*
  * ALC889 Acer Aspire 8930G model
  */
@@ -2200,6 +2231,16 @@ static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
        spec->autocfg.speaker_pins[2] = 0x17;
 }
 
+static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec)
+{
+       struct alc_spec *spec = codec->spec;
+
+       spec->autocfg.hp_pins[0] = 0x15;
+       spec->autocfg.speaker_pins[0] = 0x14;
+       spec->autocfg.speaker_pins[1] = 0x16;
+       spec->autocfg.speaker_pins[2] = 0x17;
+}
+
 static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
 {
        struct alc_spec *spec = codec->spec;
@@ -4554,6 +4595,7 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = {
        SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
        SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
        SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
+       SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
        SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
        SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
        SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
@@ -9524,13 +9566,6 @@ static struct hda_verb alc883_acer_eapd_verbs[] = {
        { }
 };
 
-static struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
-       {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
-       {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
-       {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
-       { } /* end */
-};
-
 static void alc888_6st_dell_setup(struct hda_codec *codec)
 {
        struct alc_spec *spec = codec->spec;
@@ -9831,7 +9866,6 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = {
        SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
        SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
        SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
-       SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
        SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
        SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
        SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
@@ -10328,7 +10362,7 @@ static struct alc_config_preset alc882_presets[] = {
                .const_channel_count = 6,
                .input_mux = &alc883_capture_source,
                .unsol_event = alc_automute_amp_unsol_event,
-               .setup = alc888_acer_aspire_6530g_setup,
+               .setup = alc888_acer_aspire_7730g_setup,
                .init_hook = alc_automute_amp,
        },
        [ALC883_MEDION] = {
@@ -10796,7 +10830,8 @@ static int alc_auto_add_mic_boost(struct hda_codec *codec)
 {
        struct alc_spec *spec = codec->spec;
        struct auto_pin_cfg *cfg = &spec->autocfg;
-       int i, err;
+       int i, err, type;
+       int type_idx = 0;
        hda_nid_t nid;
 
        for (i = 0; i < cfg->num_inputs; i++) {
@@ -10805,9 +10840,15 @@ static int alc_auto_add_mic_boost(struct hda_codec *codec)
                nid = cfg->inputs[i].pin;
                if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
                        char label[32];
+                       type = cfg->inputs[i].type;
+                       if (i > 0 && type == cfg->inputs[i - 1].type)
+                               type_idx++;
+                       else
+                               type_idx = 0;
                        snprintf(label, sizeof(label), "%s Boost",
                                 hda_get_autocfg_input_label(codec, cfg, i));
-                       err = add_control(spec, ALC_CTL_WIDGET_VOL, label, 0,
+                       err = add_control(spec, ALC_CTL_WIDGET_VOL, label,
+                                         type_idx,
                                  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
                        if (err < 0)
                                return err;
@@ -14766,6 +14807,8 @@ static int alc269_resume(struct hda_codec *codec)
 enum {
        ALC269_FIXUP_SONY_VAIO,
        ALC269_FIXUP_DELL_M101Z,
+       ALC269_FIXUP_LENOVO_EDGE14,
+       ALC269_FIXUP_ASUS_G73JW,
 };
 
 static const struct alc_fixup alc269_fixups[] = {
@@ -14783,11 +14826,22 @@ static const struct alc_fixup alc269_fixups[] = {
                        {}
                }
        },
+       [ALC269_FIXUP_LENOVO_EDGE14] = {
+               .sku = ALC_FIXUP_SKU_IGNORE,
+       },
+       [ALC269_FIXUP_ASUS_G73JW] = {
+               .pins = (const struct alc_pincfg[]) {
+                       { 0x17, 0x99130111 }, /* subwoofer */
+                       { }
+               }
+       },
 };
 
 static struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
        SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
+       SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_LENOVO_EDGE14),
+       SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
        {}
 };
 
@@ -16910,7 +16964,7 @@ static struct alc_config_preset alc861vd_presets[] = {
 static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
                                                const struct auto_pin_cfg *cfg)
 {
-       return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x09, 0);
+       return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x22, 0);
 }
 
 
@@ -18964,6 +19018,8 @@ static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid)
                return 0x02;
        else if (nid >= 0x0c && nid <= 0x0e)
                return nid - 0x0c + 0x02;
+       else if (nid == 0x26) /* ALC887-VD has this DAC too */
+               return 0x25;
        else
                return 0;
 }
@@ -18972,7 +19028,7 @@ static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid)
 static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
                                   hda_nid_t dac)
 {
-       hda_nid_t mix[4];
+       hda_nid_t mix[5];
        int i, num;
 
        num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
index 5c71080..efa4225 100644 (file)
@@ -1627,6 +1627,8 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = {
 static struct snd_pci_quirk stac92hd73xx_codec_id_cfg_tbl[] = {
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02a1,
                      "Alienware M17x", STAC_ALIENWARE_M17X),
+       SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x043a,
+                     "Alienware M17x", STAC_ALIENWARE_M17X),
        {} /* terminator */
 };
 
index 293569d..e521ada 100644 (file)
@@ -222,9 +222,9 @@ static int __init at91sam9g20ek_init(void)
        }
 
        pllb = clk_get(NULL, "pllb");
-       if (IS_ERR(mclk)) {
+       if (IS_ERR(pllb)) {
                printk(KERN_ERR "ASoC: Failed to get PLLB\n");
-               ret = PTR_ERR(mclk);
+               ret = PTR_ERR(pllb);
                goto err_mclk;
        }
        ret = clk_set_parent(mclk, pllb);
@@ -240,6 +240,7 @@ static int __init at91sam9g20ek_init(void)
        if (!at91sam9g20ek_snd_device) {
                printk(KERN_ERR "ASoC: Platform device allocation failed\n");
                ret = -ENOMEM;
+               goto err_mclk;
        }
 
        platform_set_drvdata(at91sam9g20ek_snd_device,
@@ -248,11 +249,13 @@ static int __init at91sam9g20ek_init(void)
        ret = platform_device_add(at91sam9g20ek_snd_device);
        if (ret) {
                printk(KERN_ERR "ASoC: Platform device allocation failed\n");
-               platform_device_put(at91sam9g20ek_snd_device);
+               goto err_device_add;
        }
 
        return ret;
 
+err_device_add:
+       platform_device_put(at91sam9g20ek_snd_device);
 err_mclk:
        clk_put(mclk);
        mclk = NULL;
index e3d2835..86e0f85 100644 (file)
@@ -167,7 +167,6 @@ static int __init afeb9260_soc_init(void)
 
        return 0;
 err1:
-       platform_device_del(afeb9260_snd_device);
        platform_device_put(afeb9260_snd_device);
        return err;
 }
index 470cb93..d63e287 100644 (file)
@@ -2019,7 +2019,10 @@ err_access:
 
 static int max98088_remove(struct snd_soc_codec *codec)
 {
+       struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
+
        max98088_set_bias_level(codec, SND_SOC_BIAS_OFF);
+       kfree(max98088->eq_texts);
 
        return 0;
 }
index 00d67cc..061f9e5 100644 (file)
@@ -383,6 +383,7 @@ static struct snd_soc_codec_driver soc_codec_dev_stac9766 = {
        .reg_cache_size = sizeof(stac9766_reg),
        .reg_word_size = sizeof(u16),
        .reg_cache_step = 2,
+       .reg_cache_default = stac9766_reg,
 };
 
 static __devinit int stac9766_probe(struct platform_device *pdev)
index fc68779..77b8f9a 100644 (file)
@@ -1176,7 +1176,7 @@ EXPORT_SYMBOL_GPL(aic3x_set_gpio);
 int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio)
 {
        u8 reg = gpio ? AIC3X_GPIO2_REG : AIC3X_GPIO1_REG;
-       u8 val, bit = gpio ? 2: 1;
+       u8 val = 0, bit = gpio ? 2 : 1;
 
        aic3x_read(codec, reg, &val);
        return (val >> bit) & 1;
@@ -1204,7 +1204,7 @@ EXPORT_SYMBOL_GPL(aic3x_set_headset_detection);
 
 int aic3x_headset_detected(struct snd_soc_codec *codec)
 {
-       u8 val;
+       u8 val = 0;
        aic3x_read(codec, AIC3X_HEADSET_DETECT_CTRL_B, &val);
        return (val >> 4) & 1;
 }
@@ -1212,7 +1212,7 @@ EXPORT_SYMBOL_GPL(aic3x_headset_detected);
 
 int aic3x_button_pressed(struct snd_soc_codec *codec)
 {
-       u8 val;
+       u8 val = 0;
        aic3x_read(codec, AIC3X_HEADSET_DETECT_CTRL_B, &val);
        return (val >> 5) & 1;
 }
index ee4fb20..d2c2430 100644 (file)
@@ -78,8 +78,10 @@ static int tpa6130a2_i2c_write(int reg, u8 value)
 
        if (data->power_state) {
                val = i2c_smbus_write_byte_data(tpa6130a2_client, reg, value);
-               if (val < 0)
+               if (val < 0) {
                        dev_err(&tpa6130a2_client->dev, "Write failed\n");
+                       return val;
+               }
        }
 
        /* Either powered on or off, we save the context */
index 712ef7c..9a433a5 100644 (file)
@@ -146,7 +146,6 @@ static int wm8523_startup(struct snd_pcm_substream *substream,
                return -EINVAL;
        }
 
-       return 0;
        snd_pcm_hw_constraint_list(substream->runtime, 0,
                                   SNDRV_PCM_HW_PARAM_RATE,
                                   &wm8523->rate_constraint);
index a2e0ed5..8725d4e 100644 (file)
 static const u16 wm8580_reg[] = {
        0x0121, 0x017e, 0x007d, 0x0014, /*R3*/
        0x0121, 0x017e, 0x007d, 0x0194, /*R7*/
-       0x001c, 0x0002, 0x0002, 0x00c2, /*R11*/
+       0x0010, 0x0002, 0x0002, 0x00c2, /*R11*/
        0x0182, 0x0082, 0x000a, 0x0024, /*R15*/
        0x0009, 0x0000, 0x00ff, 0x0000, /*R19*/
        0x00ff, 0x00ff, 0x00ff, 0x00ff, /*R23*/
@@ -491,16 +491,16 @@ static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,
                paifa |= 0x8;
                break;
        case SNDRV_PCM_FORMAT_S20_3LE:
-               paifa |= 0x10;
+               paifa |= 0x0;
                paifb |= WM8580_AIF_LENGTH_20;
                break;
        case SNDRV_PCM_FORMAT_S24_LE:
-               paifa |= 0x10;
+               paifa |= 0x0;
                paifb |= WM8580_AIF_LENGTH_24;
                break;
        case SNDRV_PCM_FORMAT_S32_LE:
-               paifa |= 0x10;
-               paifb |= WM8580_AIF_LENGTH_24;
+               paifa |= 0x0;
+               paifb |= WM8580_AIF_LENGTH_32;
                break;
        default:
                return -EINVAL;
index 6313858..e725c09 100644 (file)
@@ -526,7 +526,7 @@ static int wm8731_probe(struct snd_soc_codec *codec)
        snd_soc_update_bits(codec, WM8731_RINVOL, 0x100, 0);
 
        /* Disable bypass path by default */
-       snd_soc_update_bits(codec, WM8731_APANA, 0x4, 0);
+       snd_soc_update_bits(codec, WM8731_APANA, 0x8, 0);
 
        snd_soc_add_controls(codec, wm8731_snd_controls,
                             ARRAY_SIZE(wm8731_snd_controls));
index 33be84e..9001cc4 100644 (file)
@@ -818,7 +818,8 @@ static int wm8904_get_deemph(struct snd_kcontrol *kcontrol,
        struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
        struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
 
-       return wm8904->deemph;
+       ucontrol->value.enumerated.item[0] = wm8904->deemph;
+       return 0;
 }
 
 static int wm8904_put_deemph(struct snd_kcontrol *kcontrol,
@@ -2498,6 +2499,8 @@ static int wm8904_remove(struct snd_soc_codec *codec)
 
        wm8904_set_bias_level(codec, SND_SOC_BIAS_OFF);
        regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
+       kfree(wm8904->retune_mobile_texts);
+       kfree(wm8904->drc_texts);
 
        return 0;
 }
index f89ad6c..9cbab8e 100644 (file)
@@ -380,7 +380,8 @@ static int wm8955_get_deemph(struct snd_kcontrol *kcontrol,
        struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
        struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
 
-       return wm8955->deemph;
+       ucontrol->value.enumerated.item[0] = wm8955->deemph;
+       return 0;
 }
 
 static int wm8955_put_deemph(struct snd_kcontrol *kcontrol,
index 8d5efb3..21986c4 100644 (file)
@@ -138,7 +138,8 @@ static int wm8960_get_deemph(struct snd_kcontrol *kcontrol,
        struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
        struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
 
-       return wm8960->deemph;
+       ucontrol->value.enumerated.item[0] = wm8960->deemph;
+       return 0;
 }
 
 static int wm8960_put_deemph(struct snd_kcontrol *kcontrol,
index 4f326f6..8340485 100644 (file)
@@ -711,7 +711,7 @@ static int wm8961_hw_params(struct snd_pcm_substream *substream,
        if (fs <= 24000)
                reg |= WM8961_DACSLOPE;
        else
-               reg &= WM8961_DACSLOPE;
+               reg &= ~WM8961_DACSLOPE;
        snd_soc_write(codec, WM8961_ADC_DAC_CONTROL_2, reg);
 
        return 0;
@@ -736,7 +736,7 @@ static int wm8961_set_sysclk(struct snd_soc_dai *dai, int clk_id,
                freq /= 2;
        } else {
                dev_dbg(codec->dev, "Using MCLK/1 for %dHz MCLK\n", freq);
-               reg &= WM8961_MCLKDIV;
+               reg &= ~WM8961_MCLKDIV;
        }
 
        snd_soc_write(codec, WM8961_CLOCKING1, reg);
index e809274..1304ca9 100644 (file)
@@ -3339,7 +3339,7 @@ static irqreturn_t wm8962_irq(int irq, void *data)
        int mask;
        int active;
 
-       mask = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2);
+       mask = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2_MASK);
 
        active = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2);
        active &= ~mask;
index 830dfdd..4d3e6f1 100644 (file)
@@ -4061,6 +4061,8 @@ static int  wm8994_codec_remove(struct snd_soc_codec *codec)
        wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, wm8994);
        wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, wm8994);
        wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET, wm8994);
+       kfree(wm8994->retune_mobile_texts);
+       kfree(wm8994->drc_texts);
        kfree(wm8994);
 
        return 0;
@@ -4073,6 +4075,8 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8994 = {
        .resume =       wm8994_resume,
        .read = wm8994_read,
        .write = wm8994_write,
+       .readable_register = wm8994_readable,
+       .volatile_register = wm8994_volatile,
        .set_bias_level = wm8994_set_bias_level,
 };
 
index 19ca782..0e24092 100644 (file)
@@ -293,7 +293,7 @@ SOC_DOUBLE_R("Speaker Switch",
 SOC_DOUBLE_R("Speaker ZC Switch",
             WM8993_SPEAKER_VOLUME_LEFT, WM8993_SPEAKER_VOLUME_RIGHT,
             7, 1, 0),
-SOC_DOUBLE_TLV("Speaker Boost Volume", WM8993_SPKOUT_BOOST, 0, 3, 7, 0,
+SOC_DOUBLE_TLV("Speaker Boost Volume", WM8993_SPKOUT_BOOST, 3, 0, 7, 0,
               spkboost_tlv),
 SOC_ENUM("Speaker Reference", speaker_ref),
 SOC_ENUM("Speaker Mode", speaker_mode),
index fb4cc1e..9d2afcc 100644 (file)
@@ -247,7 +247,10 @@ fail:
 
 static int davinci_vcif_remove(struct platform_device *pdev)
 {
+       struct davinci_vcif_dev *davinci_vcif_dev = dev_get_drvdata(&pdev->dev);
+
        snd_soc_unregister_dai(&pdev->dev);
+       kfree(davinci_vcif_dev);
 
        return 0;
 }
index 4b0d199..2868179 100644 (file)
@@ -54,24 +54,26 @@ static int __init simone_init(void)
 
        ret = platform_device_add(simone_snd_ac97_device);
        if (ret)
-               goto fail;
+               goto fail1;
 
        simone_snd_device = platform_device_alloc("soc-audio", -1);
        if (!simone_snd_device) {
                ret = -ENOMEM;
-               goto fail;
+               goto fail2;
        }
 
        platform_set_drvdata(simone_snd_device, &snd_soc_simone);
        ret = platform_device_add(simone_snd_device);
-       if (ret) {
-               platform_device_put(simone_snd_device);
-               goto fail;
-       }
+       if (ret)
+               goto fail3;
 
-       return ret;
+       return 0;
 
-fail:
+fail3:
+       platform_device_put(simone_snd_device);
+fail2:
+       platform_device_del(simone_snd_ac97_device);
+fail1:
        platform_device_put(simone_snd_ac97_device);
        return ret;
 }
index 53251e6..108b5d8 100644 (file)
@@ -76,6 +76,7 @@ static __init int efika_fabric_init(void)
        rc = platform_device_add(pdev);
        if (rc) {
                pr_err("efika_fabric_init: platform_device_add() failed\n");
+               platform_device_put(pdev);
                return -ENODEV;
        }
        return 0;
index dce6b55..f92dca0 100644 (file)
@@ -9,7 +9,6 @@
 #include <linux/module.h>
 #include <linux/of_device.h>
 #include <linux/slab.h>
-#include <linux/of_device.h>
 #include <linux/of_platform.h>
 
 #include <sound/soc.h>
index 0d7dcf1..7d7847a 100644 (file)
@@ -498,6 +498,7 @@ static int mpc8610_hpcd_probe(struct platform_device *pdev)
                dev_err(&pdev->dev, "platform device add failed\n");
                goto error;
        }
+       dev_set_drvdata(&pdev->dev, sound_device);
 
        of_node_put(codec_np);
 
index 63b9eaa..026b756 100644 (file)
@@ -498,6 +498,7 @@ static int p1022_ds_probe(struct platform_device *pdev)
                dev_err(&pdev->dev, "platform device add failed\n");
                goto error;
        }
+       dev_set_drvdata(&pdev->dev, sound_device);
 
        of_node_put(codec_np);
 
index 25f27ec..ba4d85e 100644 (file)
@@ -76,6 +76,7 @@ static __init int pcm030_fabric_init(void)
        rc = platform_device_add(pdev);
        if (rc) {
                pr_err("pcm030_fabric_init: platform_device_add() failed\n");
+               platform_device_put(pdev);
                return -ENODEV;
        }
        return 0;
index d2d98c7..390b6ff 100644 (file)
@@ -679,8 +679,11 @@ static int imx_ssi_probe(struct platform_device *pdev)
        }
 
        ssi->soc_platform_pdev_fiq = platform_device_alloc("imx-fiq-pcm-audio", pdev->id);
-       if (!ssi->soc_platform_pdev_fiq)
+       if (!ssi->soc_platform_pdev_fiq) {
+               ret = -ENOMEM;
                goto failed_pdev_fiq_alloc;
+       }
+
        platform_set_drvdata(ssi->soc_platform_pdev_fiq, ssi);
        ret = platform_device_add(ssi->soc_platform_pdev_fiq);
        if (ret) {
@@ -689,8 +692,11 @@ static int imx_ssi_probe(struct platform_device *pdev)
        }
 
        ssi->soc_platform_pdev = platform_device_alloc("imx-pcm-audio", pdev->id);
-       if (!ssi->soc_platform_pdev)
+       if (!ssi->soc_platform_pdev) {
+               ret = -ENOMEM;
                goto failed_pdev_alloc;
+       }
+
        platform_set_drvdata(ssi->soc_platform_pdev, ssi);
        ret = platform_device_add(ssi->soc_platform_pdev);
        if (ret) {
@@ -703,6 +709,7 @@ static int imx_ssi_probe(struct platform_device *pdev)
 failed_pdev_add:
        platform_device_put(ssi->soc_platform_pdev);
 failed_pdev_alloc:
+       platform_device_del(ssi->soc_platform_pdev_fiq);
 failed_pdev_fiq_add:
        platform_device_put(ssi->soc_platform_pdev_fiq);
 failed_pdev_fiq_alloc:
@@ -726,8 +733,8 @@ static int __devexit imx_ssi_remove(struct platform_device *pdev)
        struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        struct imx_ssi *ssi = platform_get_drvdata(pdev);
 
-       platform_device_del(ssi->soc_platform_pdev);
-       platform_device_put(ssi->soc_platform_pdev);
+       platform_device_unregister(ssi->soc_platform_pdev);
+       platform_device_unregister(ssi->soc_platform_pdev_fiq);
 
        snd_soc_unregister_dai(&pdev->dev);
 
index 39f2373..9eabc28 100644 (file)
@@ -43,6 +43,7 @@ static struct snd_soc_card imx_phycore = {
        .num_links      = ARRAY_SIZE(imx_phycore_dai_ac97),
 };
 
+static struct platform_device *imx_phycore_snd_ac97_device;
 static struct platform_device *imx_phycore_snd_device;
 
 static int __init imx_phycore_init(void)
@@ -53,29 +54,42 @@ static int __init imx_phycore_init(void)
                /* return happy. We might run on a totally different machine */
                return 0;
 
-       imx_phycore_snd_device = platform_device_alloc("soc-audio", -1);
-       if (!imx_phycore_snd_device)
+       imx_phycore_snd_ac97_device = platform_device_alloc("soc-audio", -1);
+       if (!imx_phycore_snd_ac97_device)
                return -ENOMEM;
 
-       platform_set_drvdata(imx_phycore_snd_device, &imx_phycore);
-       ret = platform_device_add(imx_phycore_snd_device);
+       platform_set_drvdata(imx_phycore_snd_ac97_device, &imx_phycore);
+       ret = platform_device_add(imx_phycore_snd_ac97_device);
+       if (ret)
+               goto fail1;
 
        imx_phycore_snd_device = platform_device_alloc("wm9712-codec", -1);
-       if (!imx_phycore_snd_device)
-               return -ENOMEM;
+       if (!imx_phycore_snd_device) {
+               ret = -ENOMEM;
+               goto fail2;
+       }
        ret = platform_device_add(imx_phycore_snd_device);
 
        if (ret) {
                printk(KERN_ERR "ASoC: Platform device allocation failed\n");
-               platform_device_put(imx_phycore_snd_device);
+               goto fail3;
        }
 
+       return 0;
+
+fail3:
+       platform_device_put(imx_phycore_snd_device);
+fail2:
+       platform_device_del(imx_phycore_snd_ac97_device);
+fail1:
+       platform_device_put(imx_phycore_snd_ac97_device);
        return ret;
 }
 
 static void __exit imx_phycore_exit(void)
 {
        platform_device_unregister(imx_phycore_snd_device);
+       platform_device_unregister(imx_phycore_snd_ac97_device);
 }
 
 late_initcall(imx_phycore_init);
index 293dc74..dac6732 100644 (file)
@@ -49,7 +49,7 @@ static unsigned short nuc900_ac97_read(struct snd_ac97 *ac97,
        mutex_lock(&ac97_mutex);
 
        val = nuc900_checkready();
-       if (!!val) {
+       if (val) {
                dev_err(nuc900_audio->dev, "AC97 codec is not ready\n");
                goto out;
        }
@@ -102,7 +102,7 @@ static void nuc900_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
        mutex_lock(&ac97_mutex);
 
        tmp = nuc900_checkready();
-       if (!!tmp)
+       if (tmp)
                dev_err(nuc900_audio->dev, "AC97 codec is not ready\n");
 
        /* clear the R_WB bit and write register index */
@@ -149,7 +149,7 @@ static void nuc900_ac97_warm_reset(struct snd_ac97 *ac97)
        udelay(100);
 
        val = nuc900_checkready();
-       if (!!val)
+       if (val)
                dev_err(nuc900_audio->dev, "AC97 codec is not ready\n");
 
        mutex_unlock(&ac97_mutex);
@@ -263,8 +263,7 @@ static int nuc900_ac97_trigger(struct snd_pcm_substream *substream,
        return ret;
 }
 
-static int nuc900_ac97_probe(struct platform_device *pdev,
-                                       struct snd_soc_dai *dai)
+static int nuc900_ac97_probe(struct snd_soc_dai *dai)
 {
        struct nuc900_audio *nuc900_audio = nuc900_ac97_data;
        unsigned long val;
@@ -284,12 +283,12 @@ static int nuc900_ac97_probe(struct platform_device *pdev,
        return 0;
 }
 
-static void nuc900_ac97_remove(struct platform_device *pdev,
-                                               struct snd_soc_dai *dai)
+static int nuc900_ac97_remove(struct snd_soc_dai *dai)
 {
        struct nuc900_audio *nuc900_audio = nuc900_ac97_data;
 
        clk_disable(nuc900_audio->clk);
+       return 0;
 }
 
 static struct snd_soc_dai_ops nuc900_ac97_dai_ops = {
@@ -313,7 +312,7 @@ static struct snd_soc_dai_driver nuc900_ac97_dai = {
                .channels_max   = 2,
        },
        .ops = &nuc900_ac97_dai_ops,
-}
+};
 
 static int __devinit nuc900_ac97_drvprobe(struct platform_device *pdev)
 {
@@ -384,7 +383,6 @@ out0:
 
 static int __devexit nuc900_ac97_drvremove(struct platform_device *pdev)
 {
-
        snd_soc_unregister_dai(&pdev->dev);
 
        clk_put(nuc900_ac97_data->clk);
@@ -392,6 +390,7 @@ static int __devexit nuc900_ac97_drvremove(struct platform_device *pdev)
        release_mem_region(nuc900_ac97_data->res->start,
                                resource_size(nuc900_ac97_data->res));
 
+       kfree(nuc900_ac97_data);
        nuc900_ac97_data = NULL;
 
        return 0;
index aeed8ea..59f7e8e 100644 (file)
@@ -110,4 +110,6 @@ struct nuc900_audio {
 
 };
 
+extern struct nuc900_audio *nuc900_ac97_data;
+
 #endif /*end _NUC900_AUDIO_H */
index 195d1ac..8263f56 100644 (file)
@@ -50,12 +50,12 @@ static int nuc900_dma_hw_params(struct snd_pcm_substream *substream,
        unsigned long flags;
        int ret = 0;
 
-       spin_lock_irqsave(&nuc900_audio->lock, flags);
-
        ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
        if (ret < 0)
                return ret;
 
+       spin_lock_irqsave(&nuc900_audio->lock, flags);
+
        nuc900_audio->substream = substream;
        nuc900_audio->dma_addr[substream->stream] = runtime->dma_addr;
        nuc900_audio->buffersize[substream->stream] =
@@ -169,6 +169,7 @@ static int nuc900_dma_prepare(struct snd_pcm_substream *substream)
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct nuc900_audio *nuc900_audio = runtime->private_data;
        unsigned long flags, val;
+       int ret = 0;
 
        spin_lock_irqsave(&nuc900_audio->lock, flags);
 
@@ -197,10 +198,10 @@ static int nuc900_dma_prepare(struct snd_pcm_substream *substream)
                AUDIO_WRITE(nuc900_audio->mmio + ACTL_RESET, val);
                break;
        default:
-               return -EINVAL;
+               ret = -EINVAL;
        }
        spin_unlock_irqrestore(&nuc900_audio->lock, flags);
-       return 0;
+       return ret;
 }
 
 static int nuc900_dma_trigger(struct snd_pcm_substream *substream, int cmd)
@@ -332,7 +333,7 @@ static struct snd_soc_platform_driver nuc900_soc_platform = {
        .ops            = &nuc900_dma_ops,
        .pcm_new        = nuc900_dma_new,
        .pcm_free       = nuc900_dma_free_dma_buffers,
-}
+};
 
 static int __devinit nuc900_soc_platform_probe(struct platform_device *pdev)
 {
index d542ea2..a088db6 100644 (file)
@@ -12,8 +12,8 @@ config SND_OMAP_SOC_MCPDM
 config SND_OMAP_SOC_N810
        tristate "SoC Audio support for Nokia N810"
        depends on SND_OMAP_SOC && MACH_NOKIA_N810 && I2C
+       depends on OMAP_MUX
        select SND_OMAP_SOC_MCBSP
-       select OMAP_MUX
        select SND_SOC_TLV320AIC3X
        help
          Say Y if you want to add support for SoC audio on Nokia N810.
index dbd9d96..4ee33ce 100644 (file)
@@ -306,6 +306,7 @@ static int __init omap3pandora_soc_init(void)
                pr_err(PREFIX "Failed to get DAC regulator from %s: %ld\n",
                        dev_name(&omap3pandora_snd_device->dev),
                        PTR_ERR(omap3pandora_dac_reg));
+               ret = PTR_ERR(omap3pandora_dac_reg);
                goto fail3;
        }
 
index f0e6625..65ae00e 100644 (file)
@@ -177,7 +177,8 @@ static int __init osk_soc_init(void)
        tlv320aic23_mclk = clk_get(dev, "mclk");
        if (IS_ERR(tlv320aic23_mclk)) {
                printk(KERN_ERR "Could not get mclk clock\n");
-               return -ENODEV;
+               err = PTR_ERR(tlv320aic23_mclk);
+               goto err2;
        }
 
        /*
@@ -188,7 +189,7 @@ static int __init osk_soc_init(void)
                if (clk_set_rate(tlv320aic23_mclk, CODEC_CLOCK)) {
                        printk(KERN_ERR "Cannot set MCLK for AIC23 CODEC\n");
                        err = -ECANCELED;
-                       goto err1;
+                       goto err3;
                }
        }
 
@@ -196,9 +197,12 @@ static int __init osk_soc_init(void)
               (uint) clk_get_rate(tlv320aic23_mclk), CODEC_CLOCK);
 
        return 0;
-err1:
+
+err3:
        clk_put(tlv320aic23_mclk);
+err2:
        platform_device_del(osk_snd_device);
+err1:
        platform_device_put(osk_snd_device);
 
        return err;
@@ -207,6 +211,7 @@ err1:
 
 static void __exit osk_soc_exit(void)
 {
+       clk_put(tlv320aic23_mclk);
        platform_device_unregister(osk_snd_device);
 }
 
index 37f191b..580f485 100644 (file)
@@ -1,6 +1,7 @@
 config SND_PXA2XX_SOC
        tristate "SoC Audio for the Intel PXA2xx chip"
        depends on ARCH_PXA
+       select SND_ARM
        select SND_PXA2XX_LIB
        help
          Say Y or M if you want to add support for codecs attached to
index f31d22a..c8bd904 100644 (file)
@@ -38,7 +38,7 @@ static int set_audio_clock_heirachy(struct platform_device *pdev)
        }
 
        mout_epll = clk_get(NULL, "mout_epll");
-       if (IS_ERR(fout_epll)) {
+       if (IS_ERR(mout_epll)) {
                printk(KERN_WARNING "%s: Cannot find mout_epll.\n",
                                __func__);
                ret = -EINVAL;
@@ -54,7 +54,7 @@ static int set_audio_clock_heirachy(struct platform_device *pdev)
        }
 
        sclk_spdif = clk_get(NULL, "sclk_spdif");
-       if (IS_ERR(fout_epll)) {
+       if (IS_ERR(sclk_spdif)) {
                printk(KERN_WARNING "%s: Cannot find sclk_spdif.\n",
                                __func__);
                ret = -EINVAL;
index 8778faa..3052f64 100644 (file)
@@ -434,7 +434,7 @@ static struct snd_soc_dai_driver s6000_i2s_dai = {
                .rate_max = 1562500,
        },
        .ops = &s6000_i2s_dai_ops,
-}
+};
 
 static int __devinit s6000_i2s_probe(struct platform_device *pdev)
 {
index 271fd22..ab3ccae 100644 (file)
@@ -473,7 +473,7 @@ static int s6000_pcm_new(struct snd_card *card,
        }
 
        res = request_irq(params->irq, s6000_pcm_irq, IRQF_SHARED,
-                         s6000_soc_platform.name, pcm);
+                         "s6000-audio", pcm);
        if (res) {
                printk(KERN_ERR "s6000-pcm couldn't get IRQ\n");
                return res;
index 96c05e1..c1244c5 100644 (file)
@@ -167,7 +167,7 @@ static int s6105_aic3x_init(struct snd_soc_pcm_runtime *rtd)
 
        snd_soc_dapm_sync(codec);
 
-       snd_ctl_add(codec->snd_card, snd_ctl_new1(&audio_out_mux, codec));
+       snd_ctl_add(codec->card->snd_card, snd_ctl_new1(&audio_out_mux, codec));
 
        return 0;
 }
index 40bbdf1..05192d9 100644 (file)
@@ -387,7 +387,7 @@ static int __devinit sh4_soc_dai_probe(struct platform_device *pdev)
 
 static int __devexit sh4_soc_dai_remove(struct platform_device *pdev)
 {
-       snd_soc_unregister_dai(&pdev->dev, ARRAY_SIZE(sh4_ssi_dai));
+       snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(sh4_ssi_dai));
        return 0;
 }
 
index 441285a..85b7d54 100644 (file)
@@ -1619,12 +1619,14 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
 #ifdef CONFIG_SND_SOC_AC97_BUS
        /* register any AC97 codecs */
        for (i = 0; i < card->num_rtd; i++) {
-                       ret = soc_register_ac97_dai_link(&card->rtd[i]);
-                       if (ret < 0) {
-                               printk(KERN_ERR "asoc: failed to register AC97 %s\n", card->name);
-                               goto probe_dai_err;
-                       }
+               ret = soc_register_ac97_dai_link(&card->rtd[i]);
+               if (ret < 0) {
+                       printk(KERN_ERR "asoc: failed to register AC97 %s\n", card->name);
+                       while (--i >= 0)
+                               soc_unregister_ac97_dai_link(&card->rtd[i]);
+                       goto probe_dai_err;
                }
+       }
 #endif
 
        card->instantiated = 1;
@@ -3072,7 +3074,9 @@ int snd_soc_register_dais(struct device *dev,
                pr_debug("Registered DAI '%s'\n", dai->name);
        }
 
+       mutex_lock(&client_mutex);
        snd_soc_instantiate_cards();
+       mutex_unlock(&client_mutex);
        return 0;
 
 err:
index 75ed649..c721502 100644 (file)
@@ -944,6 +944,9 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
                case SND_SOC_DAPM_STREAM_RESUME:
                        sys_power = 1;
                        break;
+               case SND_SOC_DAPM_STREAM_STOP:
+                       sys_power = !!codec->active;
+                       break;
                case SND_SOC_DAPM_STREAM_SUSPEND:
                        sys_power = 0;
                        break;
index e2c2de2..564491f 100644 (file)
@@ -197,7 +197,7 @@ static void sig_atexit(void)
        if (child_pid > 0)
                kill(child_pid, SIGTERM);
 
-       if (signr == -1)
+       if (signr == -1 || signr == SIGUSR1)
                return;
 
        signal(signr, SIG_DFL);
@@ -515,6 +515,7 @@ static int __cmd_record(int argc, const char **argv)
        atexit(sig_atexit);
        signal(SIGCHLD, sig_handler);
        signal(SIGINT, sig_handler);
+       signal(SIGUSR1, sig_handler);
 
        if (forks && (pipe(child_ready_pipe) < 0 || pipe(go_pipe) < 0)) {
                perror("failed to create pipes");
@@ -606,6 +607,7 @@ static int __cmd_record(int argc, const char **argv)
                        execvp(argv[0], (char **)argv);
 
                        perror(argv[0]);
+                       kill(getppid(), SIGUSR1);
                        exit(-1);
                }
 
@@ -762,7 +764,7 @@ static int __cmd_record(int argc, const char **argv)
                }
        }
 
-       if (quiet)
+       if (quiet || signr == SIGUSR1)
                return 0;
 
        fprintf(stderr, "[ perf record: Woken up %ld times to write data ]\n", waking);
index d7e67b1..64a85ba 100644 (file)
@@ -946,11 +946,16 @@ perf_header__find_attr(u64 id, struct perf_header *header)
 
        /*
         * We set id to -1 if the data file doesn't contain sample
-        * ids. Check for this and avoid walking through the entire
-        * list of ids which may be large.
+        * ids. This can happen when the data file contains one type
+        * of event and in that case, the header can still store the
+        * event attribute information. Check for this and avoid
+        * walking through the entire list of ids which may be large.
         */
-       if (id == -1ULL)
+       if (id == -1ULL) {
+               if (header->attrs > 0)
+                       return &header->attr[0]->attr;
                return NULL;
+       }
 
        for (i = 0; i < header->attrs; i++) {
                struct perf_header_attr *attr = header->attr[i];
index 0500895..d628c8d 100644 (file)
@@ -532,7 +532,7 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
        struct machine *machine = kmaps->machine;
        struct map *curr_map = map;
        struct symbol *pos;
-       int count = 0;
+       int count = 0, moved = 0;       
        struct rb_root *root = &self->symbols[map->type];
        struct rb_node *next = rb_first(root);
        int kernel_range = 0;
@@ -590,6 +590,11 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
                        char dso_name[PATH_MAX];
                        struct dso *dso;
 
+                       if (count == 0) {
+                               curr_map = map;
+                               goto filter_symbol;
+                       }
+
                        if (self->kernel == DSO_TYPE_GUEST_KERNEL)
                                snprintf(dso_name, sizeof(dso_name),
                                        "[guest.kernel].%d",
@@ -615,7 +620,7 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
                        map_groups__insert(kmaps, curr_map);
                        ++kernel_range;
                }
-
+filter_symbol:
                if (filter && filter(curr_map, pos)) {
 discard_symbol:                rb_erase(&pos->rb_node, root);
                        symbol__delete(pos);
@@ -623,8 +628,9 @@ discard_symbol:             rb_erase(&pos->rb_node, root);
                        if (curr_map != map) {
                                rb_erase(&pos->rb_node, root);
                                symbols__insert(&curr_map->dso->symbols[curr_map->type], pos);
-                       }
-                       count++;
+                               ++moved;
+                       } else
+                               ++count;
                }
        }
 
@@ -634,7 +640,7 @@ discard_symbol:             rb_erase(&pos->rb_node, root);
                dso__set_loaded(curr_map->dso, curr_map->type);
        }
 
-       return count;
+       return count + moved;
 }
 
 int dso__load_kallsyms(struct dso *self, const char *filename,
@@ -2125,14 +2131,55 @@ static struct dso *machine__create_kernel(struct machine *self)
        return kernel;
 }
 
+struct process_args {
+       u64 start;
+};
+
+static int symbol__in_kernel(void *arg, const char *name,
+                            char type __used, u64 start)
+{
+       struct process_args *args = arg;
+
+       if (strchr(name, '['))
+               return 0;
+
+       args->start = start;
+       return 1;
+}
+
+/* Figure out the start address of kernel map from /proc/kallsyms */
+static u64 machine__get_kernel_start_addr(struct machine *machine)
+{
+       const char *filename;
+       char path[PATH_MAX];
+       struct process_args args;
+
+       if (machine__is_host(machine)) {
+               filename = "/proc/kallsyms";
+       } else {
+               if (machine__is_default_guest(machine))
+                       filename = (char *)symbol_conf.default_guest_kallsyms;
+               else {
+                       sprintf(path, "%s/proc/kallsyms", machine->root_dir);
+                       filename = path;
+               }
+       }
+
+       if (kallsyms__parse(filename, &args, symbol__in_kernel) <= 0)
+               return 0;
+
+       return args.start;
+}
+
 int __machine__create_kernel_maps(struct machine *self, struct dso *kernel)
 {
        enum map_type type;
+       u64 start = machine__get_kernel_start_addr(self);
 
        for (type = 0; type < MAP__NR_TYPES; ++type) {
                struct kmap *kmap;
 
-               self->vmlinux_maps[type] = map__new2(0, kernel, type);
+               self->vmlinux_maps[type] = map__new2(start, kernel, type);
                if (self->vmlinux_maps[type] == NULL)
                        return -1;
 
index 792a750..c14322d 100644 (file)
 */
 
 #include <linux/stringify.h>
+#include <asm-generic/vmlinux.lds.h>
 
 .section .init.ramfs,"a"
 __irf_start:
 .incbin __stringify(INITRAMFS_IMAGE)
 __irf_end:
 .section .init.ramfs.info,"a"
-.globl __initramfs_size
-__initramfs_size:
+.globl VMLINUX_SYMBOL(__initramfs_size)
+VMLINUX_SYMBOL(__initramfs_size):
 #ifdef CONFIG_64BIT
        .quad __irf_end - __irf_start
 #else