Merge branch 'stable/broadcom.ibft-bugfixes' of git://git.kernel.org/pub/scm/linux...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 9 Jun 2011 19:52:30 +0000 (12:52 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 9 Jun 2011 19:52:30 +0000 (12:52 -0700)
* 'stable/broadcom.ibft-bugfixes' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/ibft-2.6:
  iscsi_ibft: iscsi_ibft_find unused variable i

413 files changed:
CREDITS
Documentation/kernel-parameters.txt
Documentation/virtual/lguest/Makefile
Documentation/virtual/lguest/lguest.c
MAINTAINERS
Makefile
arch/arm/mach-omap1/dma.c
arch/arm/mach-omap2/board-2430sdp.c
arch/arm/mach-omap2/board-3430sdp.c
arch/arm/mach-omap2/board-4430sdp.c
arch/arm/mach-omap2/board-apollon.c
arch/arm/mach-omap2/board-cm-t35.c
arch/arm/mach-omap2/board-cm-t3517.c
arch/arm/mach-omap2/board-devkit8000.c
arch/arm/mach-omap2/board-omap3beagle.c
arch/arm/mach-omap2/board-omap3pandora.c
arch/arm/mach-omap2/board-omap3touchbook.c
arch/arm/mach-omap2/board-omap4panda.c
arch/arm/mach-omap2/board-overo.c
arch/arm/mach-omap2/board-rx51-peripherals.c
arch/arm/mach-omap2/board-zoom-display.c
arch/arm/mach-omap2/common-board-devices.c
arch/arm/mach-omap2/common-board-devices.h
arch/arm/mach-omap2/devices.c
arch/arm/mach-omap2/hsmmc.c
arch/arm/mach-omap2/hsmmc.h
arch/arm/mach-omap2/mux.c
arch/arm/mach-omap2/mux.h
arch/arm/mach-omap2/mux44xx.c
arch/arm/mach-omap2/omap_hwmod.c
arch/arm/mach-omap2/omap_hwmod_44xx_data.c
arch/arm/mach-omap2/omap_phy_internal.c
arch/arm/mach-shmobile/board-ap4evb.c
arch/arm/mach-shmobile/board-mackerel.c
arch/arm/mach-shmobile/clock-sh7372.c
arch/arm/mach-tegra/board-harmony-power.c
arch/arm/mach-tegra/board-harmony.h
arch/arm/plat-omap/include/plat/flash.h
arch/arm/plat-omap/include/plat/iovmm.h
arch/arm/plat-omap/include/plat/mmc.h
arch/arm/plat-omap/iovmm.c
arch/arm/plat-omap/sram.c
arch/blackfin/lib/strncpy.S
arch/ia64/include/asm/unistd.h
arch/ia64/kernel/entry.S
arch/mn10300/kernel/traps.c
arch/mn10300/kernel/vmlinux.lds.S
arch/mn10300/mm/cache-dbg-flush-by-reg.S
arch/powerpc/platforms/powermac/pic.c
arch/s390/Kconfig
arch/s390/include/asm/pgalloc.h
arch/s390/include/asm/pgtable.h
arch/s390/include/asm/qdio.h
arch/s390/include/asm/tlb.h
arch/s390/kvm/kvm-s390.c
arch/s390/kvm/sie64a.S
arch/s390/mm/pgtable.c
arch/sh/Kconfig
arch/sh/boards/mach-ap325rxa/setup.c
arch/sh/boards/mach-ecovec24/setup.c
arch/sh/include/asm/pgtable.h
arch/sh/include/asm/ptrace.h
arch/sh/include/asm/tlb.h
arch/sh/include/cpu-sh4/cpu/sh7722.h
arch/sh/include/cpu-sh4/cpu/sh7724.h
arch/sh/include/cpu-sh4/cpu/sh7757.h
arch/sh/kernel/process_32.c
arch/sh/mm/consistent.c
arch/unicore32/Kconfig
arch/unicore32/Makefile
arch/unicore32/boot/compressed/Makefile
arch/unicore32/configs/debug_defconfig [deleted file]
arch/unicore32/configs/unicore32_defconfig [new file with mode: 0644]
arch/unicore32/include/asm/Kbuild
arch/unicore32/kernel/Makefile
arch/unicore32/kernel/rtc.c [deleted file]
arch/unicore32/kernel/vmlinux.lds.S
arch/x86/kernel/Makefile
arch/x86/kernel/amd_iommu.c
arch/x86/kernel/amd_iommu_init.c
arch/x86/kernel/process.c
arch/x86/kernel/process_32.c
arch/x86/kernel/process_64.c
arch/x86/kernel/smpboot.c
arch/x86/kvm/emulate.c
arch/x86/lguest/boot.c
arch/x86/xen/multicalls.c
block/blk-ioc.c
block/cfq-iosched.c
drivers/base/power/clock_ops.c
drivers/block/nbd.c
drivers/block/paride/pcd.c
drivers/block/virtio_blk.c
drivers/block/xen-blkback/blkback.c
drivers/block/xen-blkback/xenbus.c
drivers/bluetooth/hci_ldisc.c
drivers/cdrom/viocd.c
drivers/char/virtio_console.c
drivers/clocksource/sh_cmt.c
drivers/clocksource/sh_tmu.c
drivers/dma/shdma.c
drivers/gpio/Kconfig
drivers/gpio/gpio-exynos4.c
drivers/gpio/gpio-omap.c
drivers/gpu/drm/i915/i915_debugfs.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_irq.c
drivers/gpu/drm/i915/intel_crt.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_hdmi.c
drivers/gpu/drm/i915/intel_lvds.c
drivers/gpu/drm/i915/intel_modes.c
drivers/gpu/drm/i915/intel_sdvo.c
drivers/gpu/drm/nouveau/nouveau_hw.c
drivers/gpu/drm/nouveau/nouveau_mem.c
drivers/gpu/drm/nouveau/nouveau_sgdma.c
drivers/gpu/drm/nouveau/nouveau_state.c
drivers/gpu/drm/nouveau/nouveau_vm.c
drivers/gpu/drm/nouveau/nv04_crtc.c
drivers/gpu/drm/nouveau/nvreg.h
drivers/gpu/drm/radeon/Kconfig
drivers/gpu/drm/radeon/atombios_crtc.c
drivers/gpu/drm/radeon/cayman_blit_shaders.c
drivers/gpu/drm/radeon/cayman_blit_shaders.h
drivers/gpu/drm/radeon/evergreen.c
drivers/gpu/drm/radeon/evergreen_blit_kms.c
drivers/gpu/drm/radeon/evergreend.h
drivers/gpu/drm/radeon/ni.c
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/r600_cs.c
drivers/gpu/drm/radeon/r600d.h
drivers/gpu/drm/radeon/radeon_asic.c
drivers/gpu/drm/radeon/radeon_cs.c
drivers/gpu/drm/radeon/radeon_device.c
drivers/gpu/drm/radeon/radeon_display.c
drivers/gpu/drm/radeon/radeon_drv.c
drivers/gpu/drm/radeon/radeon_encoders.c
drivers/gpu/drm/radeon/radeon_family.h
drivers/gpu/drm/radeon/radeon_pm.c
drivers/gpu/drm/radeon/reg_srcs/r600
drivers/hwmon/coretemp.c
drivers/hwmon/max6642.c
drivers/ide/ide-cd.c
drivers/input/serio/serport.c
drivers/isdn/gigaset/ser-gigaset.c
drivers/media/dvb/dvb-usb/anysee.c
drivers/media/media-devnode.c
drivers/media/video/gspca/coarse_expo_autogain.h [deleted file]
drivers/media/video/gspca/ov519.c
drivers/media/video/gspca/sonixj.c
drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h
drivers/media/video/ivtv/ivtv-driver.c
drivers/media/video/ivtv/ivtv-firmware.c
drivers/media/video/ivtv/ivtv-ioctl.c
drivers/media/video/ivtv/ivtv-ioctl.h
drivers/media/video/ivtv/ivtv-streams.c
drivers/media/video/ivtv/ivtv-vbi.c
drivers/media/video/ivtv/ivtvfb.c
drivers/media/video/omap3isp/isp.c
drivers/media/video/soc_camera.c
drivers/media/video/uvc/uvc_entity.c
drivers/misc/kgdbts.c
drivers/misc/ti-st/st_core.c
drivers/mmc/host/omap_hsmmc.c
drivers/net/3c509.c
drivers/net/3c59x.c
drivers/net/caif/caif_serial.c
drivers/net/can/flexcan.c
drivers/net/can/slcan.c
drivers/net/davinci_emac.c
drivers/net/depca.c
drivers/net/dm9000.c
drivers/net/hamradio/6pack.c
drivers/net/hamradio/mkiss.c
drivers/net/hp100.c
drivers/net/ibmlana.c
drivers/net/irda/irtty-sir.c
drivers/net/irda/smsc-ircc2.c
drivers/net/ks8842.c
drivers/net/ne3210.c
drivers/net/ppp_async.c
drivers/net/ppp_synctty.c
drivers/net/slip.c
drivers/net/smc-mca.c
drivers/net/tg3.c
drivers/net/tokenring/madgemc.c
drivers/net/tulip/de4x5.c
drivers/net/usb/catc.c
drivers/net/usb/cdc_ncm.c
drivers/net/virtio_net.c
drivers/net/wan/x25_asy.c
drivers/net/wireless/ath/ath9k/Kconfig
drivers/net/wireless/ath/ath9k/ar9002_calib.c
drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
drivers/net/wireless/ath/ath9k/ar9003_phy.c
drivers/net/wireless/ath/ath9k/eeprom_9287.c
drivers/net/wireless/ath/ath9k/hw.c
drivers/net/wireless/ath/ath9k/hw.h
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/ath/ath9k/rc.c
drivers/net/wireless/b43/phy_n.c
drivers/net/wireless/iwlegacy/iwl-4965-lib.c
drivers/net/wireless/iwlegacy/iwl-4965.c
drivers/net/wireless/iwlwifi/iwl-6000.c
drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/iwlwifi/iwl-agn.h
drivers/net/wireless/libertas/cmd.c
drivers/net/wireless/mwifiex/sdio.h
drivers/net/wireless/rt2x00/Kconfig
drivers/net/wireless/rtlwifi/pci.c
drivers/net/wireless/wl12xx/conf.h
drivers/net/wireless/wl12xx/main.c
drivers/net/wireless/wl12xx/scan.c
drivers/net/wireless/wl12xx/scan.h
drivers/net/wireless/zd1211rw/zd_usb.c
drivers/pci/dmar.c
drivers/pci/intel-iommu.c
drivers/pci/iova.c
drivers/rtc/Kconfig
drivers/rtc/Makefile
drivers/rtc/rtc-m41t93.c
drivers/rtc/rtc-puv3.c [new file with mode: 0644]
drivers/s390/cio/qdio_main.c
drivers/s390/net/qeth_core.h
drivers/s390/net/qeth_core_main.c
drivers/s390/scsi/zfcp_fsf.c
drivers/s390/scsi/zfcp_qdio.c
drivers/s390/scsi/zfcp_qdio.h
drivers/scsi/scsi_scan.c
drivers/scsi/scsi_sysfs.c
drivers/spi/omap2_mcspi.c
drivers/tty/n_gsm.c
drivers/tty/n_hdlc.c
drivers/tty/n_r3964.c
drivers/tty/n_tty.c
drivers/tty/tty_buffer.c
drivers/tty/vt/selection.c
drivers/usb/class/cdc-acm.c
drivers/usb/core/hub.c
drivers/usb/core/inode.c
drivers/usb/gadget/Kconfig
drivers/usb/gadget/amd5536udc.c
drivers/usb/gadget/at91_udc.c
drivers/usb/gadget/dummy_hcd.c
drivers/usb/gadget/inode.c
drivers/usb/gadget/mv_udc_core.c
drivers/usb/gadget/net2280.c
drivers/usb/gadget/pxa25x_udc.c
drivers/usb/gadget/s3c-hsotg.c
drivers/usb/gadget/s3c-hsudc.c
drivers/usb/gadget/s3c2410_udc.c
drivers/usb/host/ohci-pxa27x.c
drivers/usb/host/xhci-dbg.c
drivers/usb/host/xhci-mem.c
drivers/usb/host/xhci-pci.c
drivers/usb/host/xhci-ring.c
drivers/usb/host/xhci.c
drivers/usb/host/xhci.h
drivers/usb/musb/musb_core.c
drivers/usb/renesas_usbhs/mod_gadget.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/ftdi_sio_ids.h
drivers/usb/serial/option.c
drivers/usb/storage/transport.c
drivers/usb/storage/unusual_devs.h
drivers/usb/storage/usb.c
drivers/usb/storage/usb.h
drivers/vhost/net.c
drivers/vhost/test.c
drivers/vhost/vhost.c
drivers/vhost/vhost.h
drivers/video/arcfb.c
drivers/video/bf537-lq035.c
drivers/video/broadsheetfb.c
drivers/video/efifb.c
drivers/video/hecubafb.c
drivers/video/imxfb.c
drivers/video/metronomefb.c
drivers/video/modedb.c
drivers/video/pxa168fb.c
drivers/video/savage/savagefb_driver.c
drivers/video/sh_mobile_lcdcfb.c
drivers/video/vga16fb.c
drivers/video/xen-fbfront.c
drivers/virtio/virtio_balloon.c
drivers/virtio/virtio_ring.c
drivers/xen/events.c
fs/autofs4/root.c
fs/block_dev.c
fs/btrfs/btrfs_inode.h
fs/btrfs/ctree.c
fs/btrfs/ctree.h
fs/btrfs/delayed-inode.c
fs/btrfs/disk-io.c
fs/btrfs/extent-tree.c
fs/btrfs/extent_io.c
fs/btrfs/file.c
fs/btrfs/free-space-cache.c
fs/btrfs/inode-map.c
fs/btrfs/inode.c
fs/btrfs/ioctl.c
fs/btrfs/relocation.c
fs/btrfs/scrub.c
fs/btrfs/super.c
fs/btrfs/transaction.c
fs/btrfs/transaction.h
fs/btrfs/volumes.c
fs/btrfs/xattr.c
fs/cifs/Kconfig
fs/cifs/cifsencrypt.c
fs/cifs/connect.c
fs/exec.c
fs/fat/file.c
fs/fuse/inode.c
fs/gfs2/glock.c
fs/jfs/jfs_logmgr.c
fs/namei.c
fs/ocfs2/super.c
fs/partitions/check.c
fs/super.c
fs/ubifs/io.c
fs/ubifs/journal.c
fs/ubifs/orphan.c
fs/ubifs/recovery.c
fs/ubifs/replay.c
fs/ubifs/shrinker.c
fs/ubifs/super.c
fs/ubifs/tnc.c
fs/ubifs/ubifs.h
include/asm-generic/unistd.h
include/drm/drm_pciids.h
include/linux/blkdev.h
include/linux/dma_remapping.h
include/linux/fs.h
include/linux/genhd.h
include/linux/ieee80211.h
include/linux/if_packet.h
include/linux/irqreturn.h
include/linux/mtd/physmap.h
include/linux/perf_event.h
include/linux/sched.h
include/linux/tty_ldisc.h
include/linux/usb_usual.h
include/linux/virtio.h
include/linux/virtio_9p.h
include/linux/virtio_balloon.h
include/linux/virtio_blk.h
include/linux/virtio_config.h
include/linux/virtio_console.h
include/linux/virtio_ids.h
include/linux/virtio_net.h
include/linux/virtio_pci.h
include/linux/virtio_ring.h
include/media/v4l2-dev.h
include/net/sctp/command.h
include/net/sctp/structs.h
include/trace/events/net.h
kernel/events/core.c
kernel/irq/handle.c
kernel/irq/irqdesc.c
kernel/irq/manage.c
kernel/irq/spurious.c
kernel/lockdep.c
kernel/rcutree.c
kernel/rcutree_plugin.h
kernel/sched.c
kernel/sysctl.c
kernel/time/clockevents.c
kernel/timer.c
lib/Kconfig.debug
lib/vsprintf.c
mm/filemap.c
mm/hugetlb.c
mm/page_alloc.c
net/8021q/vlan_dev.c
net/bluetooth/l2cap_core.c
net/caif/chnl_net.c
net/core/dev.c
net/ipv4/af_inet.c
net/ipv4/ip_options.c
net/mac80211/mlme.c
net/mac80211/scan.c
net/packet/af_packet.c
net/sctp/associola.c
net/sctp/sm_sideeffect.c
net/sctp/sm_statefuns.c
net/wireless/nl80211.c
net/wireless/scan.c
security/apparmor/lsm.c
security/selinux/hooks.c
sound/pci/asihpi/hpidspcd.c
sound/pci/fm801.c
sound/pci/hda/patch_analog.c
sound/soc/codecs/cx20442.c
sound/soc/codecs/wm_hubs.c
sound/soc/soc-dapm.c
sound/usb/6fire/firmware.c
sound/usb/quirks.c
tools/perf/builtin-test.c
tools/perf/util/event.c
tools/perf/util/event.h
tools/perf/util/evlist.c
tools/perf/util/evlist.h
tools/perf/util/evsel.c
tools/perf/util/evsel.h
tools/perf/util/python.c
tools/perf/util/session.c
tools/testing/ktest/ktest.pl
tools/virtio/virtio_test.c
virt/kvm/kvm_main.c

diff --git a/CREDITS b/CREDITS
index a7ea8e343836fb47fd82ef624d77c630ba199df2..d78359f5f64d7e581110166f9a2a7ecd410abc46 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -518,6 +518,14 @@ N: Zach Brown
 E: zab@zabbo.net
 D: maestro pci sound
 
+M: David Brownell
+D: Kernel engineer, mentor, and friend.  Maintained USB EHCI and
+D: gadget layers, SPI subsystem, GPIO subsystem, and more than a few
+D: device drivers.  His encouragement also helped many engineers get
+D: started working on the Linux kernel.  David passed away in early
+D: 2011, and will be greatly missed.
+W: https://lkml.org/lkml/2011/4/5/36
+
 N: Gary Brubaker
 E: xavyer@ix.netcom.com
 D: USB Serial Empeg Empeg-car Mark I/II Driver
index 5438a2d7907f564b05644a93931f081de19844d3..fd248a318211a189163f2c42ba911a44284ea0bc 100644 (file)
@@ -999,7 +999,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
                        With this option on every unmap_single operation will
                        result in a hardware IOTLB flush operation as opposed
                        to batching them for performance.
-
+               sp_off [Default Off]
+                       By default, super page will be supported if Intel IOMMU
+                       has the capability. With this option, super page will
+                       not be supported.
        intremap=       [X86-64, Intel-IOMMU]
                        Format: { on (default) | off | nosid }
                        on      enable Interrupt Remapping (default)
@@ -2595,6 +2598,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
                                        unlock ejectable media);
                                m = MAX_SECTORS_64 (don't transfer more
                                        than 64 sectors = 32 KB at a time);
+                               n = INITIAL_READ10 (force a retry of the
+                                       initial READ(10) command);
                                o = CAPACITY_OK (accept the capacity
                                        reported by the device);
                                r = IGNORE_RESIDUE (the device reports
index bebac6b4f332cc117287f58c0cf5df11bf5531f8..0ac34206f7a7c6fb44f92bd664f71487084580e3 100644 (file)
@@ -1,5 +1,5 @@
 # This creates the demonstration utility "lguest" which runs a Linux guest.
-# Missing headers?  Add "-I../../include -I../../arch/x86/include"
+# Missing headers?  Add "-I../../../include -I../../../arch/x86/include"
 CFLAGS:=-m32 -Wall -Wmissing-declarations -Wmissing-prototypes -O3 -U_FORTIFY_SOURCE
 
 all: lguest
index d9da7e148538286d78d6f11236f3a4db89218f45..cd9d6af61d070bbf3633753a45444eab46193541 100644 (file)
@@ -49,7 +49,7 @@
 #include <linux/virtio_rng.h>
 #include <linux/virtio_ring.h>
 #include <asm/bootparam.h>
-#include "../../include/linux/lguest_launcher.h"
+#include "../../../include/linux/lguest_launcher.h"
 /*L:110
  * We can ignore the 42 include files we need for this program, but I do want
  * to draw attention to the use of kernel-style types.
@@ -135,9 +135,6 @@ struct device {
        /* Is it operational */
        bool running;
 
-       /* Does Guest want an intrrupt on empty? */
-       bool irq_on_empty;
-
        /* Device-specific data. */
        void *priv;
 };
@@ -637,10 +634,7 @@ static void trigger_irq(struct virtqueue *vq)
 
        /* If they don't want an interrupt, don't send one... */
        if (vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT) {
-               /* ... unless they've asked us to force one on empty. */
-               if (!vq->dev->irq_on_empty
-                   || lg_last_avail(vq) != vq->vring.avail->idx)
-                       return;
+               return;
        }
 
        /* Send the Guest an interrupt tell them we used something up. */
@@ -1057,15 +1051,6 @@ static void create_thread(struct virtqueue *vq)
        close(vq->eventfd);
 }
 
-static bool accepted_feature(struct device *dev, unsigned int bit)
-{
-       const u8 *features = get_feature_bits(dev) + dev->feature_len;
-
-       if (dev->feature_len < bit / CHAR_BIT)
-               return false;
-       return features[bit / CHAR_BIT] & (1 << (bit % CHAR_BIT));
-}
-
 static void start_device(struct device *dev)
 {
        unsigned int i;
@@ -1079,8 +1064,6 @@ static void start_device(struct device *dev)
                verbose(" %02x", get_feature_bits(dev)
                        [dev->feature_len+i]);
 
-       dev->irq_on_empty = accepted_feature(dev, VIRTIO_F_NOTIFY_ON_EMPTY);
-
        for (vq = dev->vq; vq; vq = vq->next) {
                if (vq->service)
                        create_thread(vq);
@@ -1564,7 +1547,6 @@ static void setup_tun_net(char *arg)
        /* Set up the tun device. */
        configure_device(ipfd, tapif, ip);
 
-       add_feature(dev, VIRTIO_F_NOTIFY_ON_EMPTY);
        /* Expect Guest to handle everything except UFO */
        add_feature(dev, VIRTIO_NET_F_CSUM);
        add_feature(dev, VIRTIO_NET_F_GUEST_CSUM);
index 29801f760b6ff59c74a7e94ae05210ee437bfc8e..bbe49d8c22afb024a9fe10fe7146d7ced5cc18f1 100644 (file)
@@ -4252,8 +4252,7 @@ F:        drivers/mmc/
 F:     include/linux/mmc/
 
 MULTIMEDIA CARD (MMC) ETC. OVER SPI
-M:     David Brownell <dbrownell@users.sourceforge.net>
-S:     Odd Fixes
+S:     Orphan
 F:     drivers/mmc/host/mmc_spi.c
 F:     include/linux/spi/mmc_spi.h
 
@@ -4603,7 +4602,6 @@ F:        drivers/media/video/omap3isp/*
 
 OMAP USB SUPPORT
 M:     Felipe Balbi <balbi@ti.com>
-M:     David Brownell <dbrownell@users.sourceforge.net>
 L:     linux-usb@vger.kernel.org
 L:     linux-omap@vger.kernel.org
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git
@@ -4947,6 +4945,7 @@ T:        git git://git.kernel.org/pub/scm/linux/kernel/git/epip/linux-2.6-unicore32.gi
 F:     drivers/input/serio/i8042-unicore32io.h
 F:     drivers/i2c/busses/i2c-puv3.c
 F:     drivers/video/fb-puv3.c
+F:     drivers/rtc/rtc-puv3.c
 
 PMC SIERRA MaxRAID DRIVER
 M:     Anil Ravindranath <anil_ravindranath@pmc-sierra.com>
@@ -5984,7 +5983,6 @@ F:        Documentation/serial/specialix.txt
 F:     drivers/staging/tty/specialix*
 
 SPI SUBSYSTEM
-M:     David Brownell <dbrownell@users.sourceforge.net>
 M:     Grant Likely <grant.likely@secretlab.ca>
 L:     spi-devel-general@lists.sourceforge.net
 Q:     http://patchwork.kernel.org/project/spi-devel-general/list/
@@ -6432,9 +6430,8 @@ S:        Maintained
 F:     drivers/usb/misc/rio500*
 
 USB EHCI DRIVER
-M:     David Brownell <dbrownell@users.sourceforge.net>
 L:     linux-usb@vger.kernel.org
-S:     Odd Fixes
+S:     Orphan
 F:     Documentation/usb/ehci.txt
 F:     drivers/usb/host/ehci*
 
@@ -6448,9 +6445,10 @@ S:       Maintained
 F:     drivers/media/video/et61x251/
 
 USB GADGET/PERIPHERAL SUBSYSTEM
-M:     David Brownell <dbrownell@users.sourceforge.net>
+M:     Felipe Balbi <balbi@ti.com>
 L:     linux-usb@vger.kernel.org
 W:     http://www.linux-usb.org/gadget
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git
 S:     Maintained
 F:     drivers/usb/gadget/
 F:     include/linux/usb/gadget*
@@ -6492,9 +6490,8 @@ S:        Maintained
 F:     sound/usb/midi.*
 
 USB OHCI DRIVER
-M:     David Brownell <dbrownell@users.sourceforge.net>
 L:     linux-usb@vger.kernel.org
-S:     Odd Fixes
+S:     Orphan
 F:     Documentation/usb/ohci.txt
 F:     drivers/usb/host/ohci*
 
index afb8e0d26f2c6134828d5d63e557799e8ef6e199..0f1db8d9074124cddd1a71d627031ed674fd4e0a 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 3
 PATCHLEVEL = 0
 SUBLEVEL = 0
-EXTRAVERSION = -rc1
+EXTRAVERSION = -rc2
 NAME = Sneaky Weasel
 
 # *DOCUMENTATION*
index d8559344c6e2927581d19663de05e0b23c10c849..f5a52204b89fa8e85908ab8f2566594575324027 100644 (file)
@@ -284,14 +284,15 @@ static int __init omap1_system_dma_init(void)
        dma_base = ioremap(res[0].start, resource_size(&res[0]));
        if (!dma_base) {
                pr_err("%s: Unable to ioremap\n", __func__);
-               return -ENODEV;
+               ret = -ENODEV;
+               goto exit_device_put;
        }
 
        ret = platform_device_add_resources(pdev, res, ARRAY_SIZE(res));
        if (ret) {
                dev_err(&pdev->dev, "%s: Unable to add resources for %s%d\n",
                        __func__, pdev->name, pdev->id);
-               goto exit_device_del;
+               goto exit_device_put;
        }
 
        p = kzalloc(sizeof(struct omap_system_dma_plat_info), GFP_KERNEL);
@@ -299,7 +300,7 @@ static int __init omap1_system_dma_init(void)
                dev_err(&pdev->dev, "%s: Unable to allocate 'p' for %s\n",
                        __func__, pdev->name);
                ret = -ENOMEM;
-               goto exit_device_put;
+               goto exit_device_del;
        }
 
        d = kzalloc(sizeof(struct omap_dma_dev_attr), GFP_KERNEL);
@@ -380,10 +381,10 @@ exit_release_d:
        kfree(d);
 exit_release_p:
        kfree(p);
-exit_device_put:
-       platform_device_put(pdev);
 exit_device_del:
        platform_device_del(pdev);
+exit_device_put:
+       platform_device_put(pdev);
 
        return ret;
 }
index d54969be0a54e90535a3578f48a85c31144f0b9b..5de6eac0a72520a8b37e7a9d5cde73c3de40b1c5 100644 (file)
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/gpio.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
-#include <mach/gpio.h>
 #include <plat/board.h>
 #include <plat/common.h>
 #include <plat/gpmc.h>
index ae2963a98041711a091a473cc1a66283a851397c..5dac974be6256bd4a22a4fc570142d56bee90efa 100644 (file)
@@ -622,19 +622,19 @@ static struct omap_device_pad serial3_pads[] __initdata = {
                         OMAP_MUX_MODE0),
 };
 
-static struct omap_board_data serial1_data = {
+static struct omap_board_data serial1_data __initdata = {
        .id             = 0,
        .pads           = serial1_pads,
        .pads_cnt       = ARRAY_SIZE(serial1_pads),
 };
 
-static struct omap_board_data serial2_data = {
+static struct omap_board_data serial2_data __initdata = {
        .id             = 1,
        .pads           = serial2_pads,
        .pads_cnt       = ARRAY_SIZE(serial2_pads),
 };
 
-static struct omap_board_data serial3_data = {
+static struct omap_board_data serial3_data __initdata = {
        .id             = 2,
        .pads           = serial3_pads,
        .pads_cnt       = ARRAY_SIZE(serial3_pads),
index 73fa90bb6953dcffb47119328a0aa0f059ae6164..63de2d396e2dddf84eaec2b6035aad64aba49385 100644 (file)
@@ -258,7 +258,7 @@ static struct gpio sdp4430_eth_gpios[] __initdata = {
        { ETH_KS8851_IRQ,       GPIOF_IN,               "eth_irq"       },
 };
 
-static int omap_ethernet_init(void)
+static int __init omap_ethernet_init(void)
 {
        int status;
 
@@ -322,6 +322,7 @@ static struct omap2_hsmmc_info mmc[] = {
                .gpio_wp        = -EINVAL,
                .nonremovable   = true,
                .ocr_mask       = MMC_VDD_29_30,
+               .no_off_init    = true,
        },
        {
                .mmc            = 1,
@@ -681,19 +682,19 @@ static struct omap_device_pad serial4_pads[] __initdata = {
                         OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
 };
 
-static struct omap_board_data serial2_data = {
+static struct omap_board_data serial2_data __initdata = {
        .id             = 1,
        .pads           = serial2_pads,
        .pads_cnt       = ARRAY_SIZE(serial2_pads),
 };
 
-static struct omap_board_data serial3_data = {
+static struct omap_board_data serial3_data __initdata = {
        .id             = 2,
        .pads           = serial3_pads,
        .pads_cnt       = ARRAY_SIZE(serial3_pads),
 };
 
-static struct omap_board_data serial4_data = {
+static struct omap_board_data serial4_data __initdata = {
        .id             = 3,
        .pads           = serial4_pads,
        .pads_cnt       = ARRAY_SIZE(serial4_pads),
@@ -729,7 +730,7 @@ static void __init omap_4430sdp_init(void)
 
        if (omap_rev() == OMAP4430_REV_ES1_0)
                package = OMAP_PACKAGE_CBL;
-       omap4_mux_init(board_mux, package);
+       omap4_mux_init(board_mux, NULL, package);
 
        omap_board_config = sdp4430_config;
        omap_board_config_size = ARRAY_SIZE(sdp4430_config);
index f3beb8eeef77a2a2cc1c2d229f0d17420041460a..b124bdfb4239ebfcf42c8ca5ab011322cdec3182 100644 (file)
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/smc91x.h>
+#include <linux/gpio.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
 
-#include <mach/gpio.h>
 #include <plat/led.h>
 #include <plat/usb.h>
 #include <plat/board.h>
index c63115bc15368d7e953b3b784562f4a22c612ad2..77456dec93ea9640c60a7b48f7dcf3db4b68e568 100644 (file)
@@ -63,8 +63,6 @@
 #define SB_T35_SMSC911X_CS     4
 #define SB_T35_SMSC911X_GPIO   65
 
-#define NAND_BLOCK_SIZE                SZ_128K
-
 #if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
 #include <linux/smsc911x.h>
 #include <plat/gpmc-smsc911x.h>
index 08f08e812492920e24cb79d8f04eec5d3cc88659..c3a9fd35034a3b40ad33df50e2573c7f5a000cbb 100644 (file)
@@ -48,6 +48,7 @@
 
 #include "mux.h"
 #include "control.h"
+#include "common-board-devices.h"
 
 #if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
 static struct gpio_led cm_t3517_leds[] = {
@@ -177,7 +178,7 @@ static struct usbhs_omap_board_data cm_t3517_ehci_pdata __initdata = {
        .reset_gpio_port[2]  = -EINVAL,
 };
 
-static int cm_t3517_init_usbh(void)
+static int __init cm_t3517_init_usbh(void)
 {
        int err;
 
@@ -203,8 +204,6 @@ static inline int cm_t3517_init_usbh(void)
 #endif
 
 #if defined(CONFIG_MTD_NAND_OMAP2) || defined(CONFIG_MTD_NAND_OMAP2_MODULE)
-#define NAND_BLOCK_SIZE                SZ_128K
-
 static struct mtd_partition cm_t3517_nand_partitions[] = {
        {
                .name           = "xloader",
index cf520d7dd614a999879ebdb64ff1bda2c6d2ba44..34956ec832960f1e215241f196ef2d89b3006d91 100644 (file)
@@ -61,8 +61,6 @@
 #include "timer-gp.h"
 #include "common-board-devices.h"
 
-#define NAND_BLOCK_SIZE                SZ_128K
-
 #define OMAP_DM9000_GPIO_IRQ   25
 #define OMAP3_DEVKIT_TS_GPIO   27
 
index be71426359f2ecda9644f41a7e6cd6e64ab6e58b..7f21d24bd437732724a45af9302c50a514f56482 100644 (file)
@@ -54,8 +54,6 @@
 #include "pm.h"
 #include "common-board-devices.h"
 
-#define NAND_BLOCK_SIZE                SZ_128K
-
 /*
  * OMAP3 Beagle revision
  * Run time detection of Beagle revision is done by reading GPIO.
@@ -106,6 +104,9 @@ static void __init omap3_beagle_init_rev(void)
        beagle_rev = gpio_get_value(171) | (gpio_get_value(172) << 1)
                        | (gpio_get_value(173) << 2);
 
+       gpio_free_array(omap3_beagle_rev_gpios,
+                       ARRAY_SIZE(omap3_beagle_rev_gpios));
+
        switch (beagle_rev) {
        case 7:
                printk(KERN_INFO "OMAP3 Beagle Rev: Ax/Bx\n");
@@ -579,6 +580,9 @@ static void __init omap3_beagle_init(void)
        omap_nand_flash_init(NAND_BUSWIDTH_16, omap3beagle_nand_partitions,
                             ARRAY_SIZE(omap3beagle_nand_partitions));
 
+       /* Ensure msecure is mux'd to be able to set the RTC. */
+       omap_mux_init_signal("sys_drm_msecure", OMAP_PIN_OFF_OUTPUT_HIGH);
+
        /* Ensure SDRC pins are mux'd for self-refresh */
        omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
        omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
index 1d10736c6d3c1d358cbef88468294cb7d4f1834b..2a0bb4818caef6a99a99e068946f970f8adcee1e 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/leds.h>
 #include <linux/input.h>
 #include <linux/input/matrix_keypad.h>
+#include <linux/gpio.h>
 #include <linux/gpio_keys.h>
 #include <linux/mmc/host.h>
 #include <linux/mmc/card.h>
@@ -41,7 +42,6 @@
 
 #include <plat/board.h>
 #include <plat/common.h>
-#include <mach/gpio.h>
 #include <mach/hardware.h>
 #include <plat/mcspi.h>
 #include <plat/usb.h>
@@ -57,8 +57,6 @@
 #define PANDORA_WIFI_NRESET_GPIO       23
 #define OMAP3_PANDORA_TS_GPIO          94
 
-#define NAND_BLOCK_SIZE                        SZ_128K
-
 static struct mtd_partition omap3pandora_nand_partitions[] = {
        {
                .name           = "xloader",
index 82872d7d313b7dd624bf5f39c0a819e61bf4bf9e..5f649faf7377ecb757c49c73e9430d91adf2940f 100644 (file)
@@ -56,8 +56,6 @@
 
 #include <asm/setup.h>
 
-#define NAND_BLOCK_SIZE                SZ_128K
-
 #define OMAP3_AC_GPIO          136
 #define OMAP3_TS_GPIO          162
 #define TB_BL_PWM_TIMER                9
index 90485fced973db9ee265465eac4c474a1adf3848..0cfe2005cb506a32c79d96f9864bb7e24bd35a0f 100644 (file)
@@ -526,19 +526,19 @@ static struct omap_device_pad serial4_pads[] __initdata = {
                         OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
 };
 
-static struct omap_board_data serial2_data = {
+static struct omap_board_data serial2_data __initdata = {
        .id             = 1,
        .pads           = serial2_pads,
        .pads_cnt       = ARRAY_SIZE(serial2_pads),
 };
 
-static struct omap_board_data serial3_data = {
+static struct omap_board_data serial3_data __initdata = {
        .id             = 2,
        .pads           = serial3_pads,
        .pads_cnt       = ARRAY_SIZE(serial3_pads),
 };
 
-static struct omap_board_data serial4_data = {
+static struct omap_board_data serial4_data __initdata = {
        .id             = 3,
        .pads           = serial4_pads,
        .pads_cnt       = ARRAY_SIZE(serial4_pads),
@@ -687,7 +687,7 @@ static void __init omap4_panda_init(void)
 
        if (omap_rev() == OMAP4430_REV_ES1_0)
                package = OMAP_PACKAGE_CBL;
-       omap4_mux_init(board_mux, package);
+       omap4_mux_init(board_mux, NULL, package);
 
        if (wl12xx_set_platform_data(&omap_panda_wlan_data))
                pr_err("error setting wl12xx data\n");
index 1555918e3ffa05c0a79e501e24cf6041b4cca30c..175e1ab2b04d7225a0a13485e12e239e9692030d 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/err.h>
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/i2c/twl.h>
@@ -45,7 +46,6 @@
 #include <plat/common.h>
 #include <video/omapdss.h>
 #include <video/omap-panel-generic-dpi.h>
-#include <mach/gpio.h>
 #include <plat/gpmc.h>
 #include <mach/hardware.h>
 #include <plat/nand.h>
@@ -65,8 +65,6 @@
 #define OVERO_GPIO_USBH_CPEN   168
 #define OVERO_GPIO_USBH_NRESET 183
 
-#define NAND_BLOCK_SIZE SZ_128K
-
 #define OVERO_SMSC911X_CS      5
 #define OVERO_SMSC911X_GPIO    176
 #define OVERO_SMSC911X2_CS     4
index f6247e71a194419063064c906f690655bf83fceb..990366726c58f2c2614e43536dc28c5f36b70cbf 100644 (file)
@@ -488,6 +488,7 @@ static struct regulator_init_data rx51_vmmc2 = {
                .name                   = "V28_A",
                .min_uV                 = 2800000,
                .max_uV                 = 3000000,
+               .always_on              = true, /* due VIO leak to AIC34 VDDs */
                .apply_uV               = true,
                .valid_modes_mask       = REGULATOR_MODE_NORMAL
                                        | REGULATOR_MODE_STANDBY,
@@ -582,7 +583,7 @@ static int rx51_twlgpio_setup(struct device *dev, unsigned gpio, unsigned n)
 {
        /* FIXME this gpio setup is just a placeholder for now */
        gpio_request_one(gpio + 6, GPIOF_OUT_INIT_LOW, "backlight_pwm");
-       gpio_request_one(gpio + 7, GPIOF_OUT_INIT_HIGH, "speaker_en");
+       gpio_request_one(gpio + 7, GPIOF_OUT_INIT_LOW, "speaker_en");
 
        return 0;
 }
index c7c6beb1ec24743737c5b9abe99a85909d5e310b..d4683ba5f72182aa47ef94267ff9dc97c446b043 100644 (file)
@@ -26,7 +26,7 @@ static struct gpio zoom_lcd_gpios[] __initdata = {
        { LCD_PANEL_QVGA_GPIO,  GPIOF_OUT_INIT_HIGH, "lcd qvga"  },
 };
 
-static void zoom_lcd_panel_init(void)
+static void __init zoom_lcd_panel_init(void)
 {
        zoom_lcd_gpios[0].gpio = (omap_rev() > OMAP3430_REV_ES3_0) ?
                        LCD_PANEL_RESET_GPIO_PROD :
index e94903b2c65bb0f4d0a1cc1fecb5c8512ff9bdeb..94ccf464677b78eeb831671f54f862325881a0ac 100644 (file)
@@ -85,17 +85,17 @@ void __init omap_ads7846_init(int bus_num, int gpio_pendown, int gpio_debounce,
        struct spi_board_info *spi_bi = &ads7846_spi_board_info;
        int err;
 
-       err = gpio_request(gpio_pendown, "TS PenDown");
-       if (err) {
-               pr_err("Could not obtain gpio for TS PenDown: %d\n", err);
-               return;
-       }
-
-       gpio_direction_input(gpio_pendown);
-       gpio_export(gpio_pendown, 0);
+       if (board_pdata && board_pdata->get_pendown_state) {
+               err = gpio_request_one(gpio_pendown, GPIOF_IN, "TSPenDown");
+               if (err) {
+                       pr_err("Couldn't obtain gpio for TSPenDown: %d\n", err);
+                       return;
+               }
+               gpio_export(gpio_pendown, 0);
 
-       if (gpio_debounce)
-               gpio_set_debounce(gpio_pendown, gpio_debounce);
+               if (gpio_debounce)
+                       gpio_set_debounce(gpio_pendown, gpio_debounce);
+       }
 
        ads7846_config.gpio_pendown = gpio_pendown;
 
index eb80b3b0ef478678d4dd914749d7632780f664cd..679719051df5bdfa70569ead1291e9206604ce6a 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef __OMAP_COMMON_BOARD_DEVICES__
 #define __OMAP_COMMON_BOARD_DEVICES__
 
+#define NAND_BLOCK_SIZE        SZ_128K
+
 struct twl4030_platform_data;
 struct mtd_partition;
 
index 7b855856459143a6cfaa8c20ab597d661c5213a5..5b8ca680ed93d2e9f919548cca05cb656f4ee787 100644 (file)
@@ -97,7 +97,7 @@ static int __init omap4_l3_init(void)
 
        WARN(IS_ERR(od), "could not build omap_device for %s\n", oh_name);
 
-       return PTR_ERR(od);
+       return IS_ERR(od) ? PTR_ERR(od) : 0;
 }
 postcore_initcall(omap4_l3_init);
 
index b2f30bed5a2041d5e27a7b3ce24a172eb8d966e1..66868c5d5a29b8207da355ef7163e941296f615c 100644 (file)
@@ -145,6 +145,7 @@ static void omap4_hsmmc1_after_set_reg(struct device *dev, int slot,
                                 int power_on, int vdd)
 {
        u32 reg;
+       unsigned long timeout;
 
        if (power_on) {
                reg = omap4_ctrl_pad_readl(control_pbias_offset);
@@ -157,9 +158,15 @@ static void omap4_hsmmc1_after_set_reg(struct device *dev, int slot,
                        OMAP4_MMC1_PWRDNZ_MASK |
                        OMAP4_USBC1_ICUSB_PWRDNZ_MASK);
                omap4_ctrl_pad_writel(reg, control_pbias_offset);
-               /* 4 microsec delay for comparator to generate an error*/
-               udelay(4);
-               reg = omap4_ctrl_pad_readl(control_pbias_offset);
+
+               timeout = jiffies + msecs_to_jiffies(5);
+               do {
+                       reg = omap4_ctrl_pad_readl(control_pbias_offset);
+                       if (!(reg & OMAP4_MMC1_PBIASLITE_VMODE_ERROR_MASK))
+                               break;
+                       usleep_range(100, 200);
+               } while (!time_after(jiffies, timeout));
+
                if (reg & OMAP4_MMC1_PBIASLITE_VMODE_ERROR_MASK) {
                        pr_err("Pbias Voltage is not same as LDO\n");
                        /* Caution : On VMODE_ERROR Power Down MMC IO */
@@ -331,6 +338,9 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
        if (c->no_off)
                mmc->slots[0].no_off = 1;
 
+       if (c->no_off_init)
+               mmc->slots[0].no_regulator_off_init = c->no_off_init;
+
        if (c->vcc_aux_disable_is_sleep)
                mmc->slots[0].vcc_aux_disable_is_sleep = 1;
 
index f119348827d46d029c3cc7544ca1293420b7156c..f757e78d4d4f5759f73bdc27acc502c1ef8f497f 100644 (file)
@@ -18,6 +18,7 @@ struct omap2_hsmmc_info {
        bool    nonremovable;   /* Nonremovable e.g. eMMC */
        bool    power_saving;   /* Try to sleep or power off when possible */
        bool    no_off;         /* power_saving and power is not to go off */
+       bool    no_off_init;    /* no power off when not in MMC sleep state */
        bool    vcc_aux_disable_is_sleep; /* Regulator off remapped to sleep */
        int     gpio_cd;        /* or -EINVAL */
        int     gpio_wp;        /* or -EINVAL */
index a4ab1e364313693dcdef6292e3310a8afa9fe6be..c7fb22abc219db3756758275e0aa30c90fcdd5e6 100644 (file)
@@ -83,6 +83,9 @@ void omap_mux_write(struct omap_mux_partition *partition, u16 val,
 void omap_mux_write_array(struct omap_mux_partition *partition,
                                 struct omap_board_mux *board_mux)
 {
+       if (!board_mux)
+               return;
+
        while (board_mux->reg_offset != OMAP_MUX_TERMINATOR) {
                omap_mux_write(partition, board_mux->value,
                               board_mux->reg_offset);
@@ -906,7 +909,7 @@ static struct omap_mux *omap_mux_get_by_gpio(
 u16 omap_mux_get_gpio(int gpio)
 {
        struct omap_mux_partition *partition;
-       struct omap_mux *m;
+       struct omap_mux *m = NULL;
 
        list_for_each_entry(partition, &mux_partitions, node) {
                m = omap_mux_get_by_gpio(partition, gpio);
index 137f321c029f59a240fd885cfd7c8538c59bf9d8..2132308ad1e41fffc14856b48294ffd42e748c8b 100644 (file)
@@ -323,10 +323,12 @@ int omap3_mux_init(struct omap_board_mux *board_mux, int flags);
 
 /**
  * omap4_mux_init() - initialize mux system with board specific set
- * @board_mux:         Board specific mux table
+ * @board_subset:      Board specific mux table
+ * @board_wkup_subset: Board specific mux table for wakeup instance
  * @flags:             OMAP package type used for the board
  */
-int omap4_mux_init(struct omap_board_mux *board_mux, int flags);
+int omap4_mux_init(struct omap_board_mux *board_subset,
+       struct omap_board_mux *board_wkup_subset, int flags);
 
 /**
  * omap_mux_init - private mux init function, do not call
index 9a66445112ae8ca37a7ad8b1c136c04d7cebaa4f..f5a74daab2ff679ecfc7717d1b8dd3b1295d8606 100644 (file)
@@ -1309,7 +1309,8 @@ static struct omap_ball __initdata omap4_wkup_cbl_cbs_ball[] = {
 #define omap4_wkup_cbl_cbs_ball  NULL
 #endif
 
-int __init omap4_mux_init(struct omap_board_mux *board_subset, int flags)
+int __init omap4_mux_init(struct omap_board_mux *board_subset,
+       struct omap_board_mux *board_wkup_subset, int flags)
 {
        struct omap_ball *package_balls_core;
        struct omap_ball *package_balls_wkup = omap4_wkup_cbl_cbs_ball;
@@ -1347,7 +1348,7 @@ int __init omap4_mux_init(struct omap_board_mux *board_subset, int flags)
                            OMAP_MUX_GPIO_IN_MODE3,
                            OMAP4_CTRL_MODULE_PAD_WKUP_MUX_PBASE,
                            OMAP4_CTRL_MODULE_PAD_WKUP_MUX_SIZE,
-                           omap4_wkup_muxmodes, NULL, board_subset,
+                           omap4_wkup_muxmodes, NULL, board_wkup_subset,
                            package_balls_wkup);
 
        return ret;
index e03429453ce7aa8b20eee7fe0b1026a66fec8c5b..293fa6cd50e14192cf075e1b9f9937c307b7c2e4 100644 (file)
@@ -1628,7 +1628,7 @@ int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh, void *data),
                        void *data)
 {
        struct omap_hwmod *temp_oh;
-       int ret;
+       int ret = 0;
 
        if (!fn)
                return -EINVAL;
index abc548a0c98dacae4bd6c5fc7d8eb615dde9b4c5..e1c69ffe0f69db181b9dd6245be9e72ffbaf63f0 100644 (file)
@@ -5109,7 +5109,7 @@ static __initdata struct omap_hwmod *omap44xx_hwmods[] = {
        &omap44xx_iva_seq1_hwmod,
 
        /* kbd class */
-/*     &omap44xx_kbd_hwmod, */
+       &omap44xx_kbd_hwmod,
 
        /* mailbox class */
        &omap44xx_mailbox_hwmod,
index f47813edd95143d938c554fd3dc19b71f492237a..58775e3c84762e59b9cbe3c82a5d4022638f15ae 100644 (file)
@@ -56,8 +56,10 @@ int omap4430_phy_init(struct device *dev)
        /* Power down the phy */
        __raw_writel(PHY_PD, ctrl_base + CONTROL_DEV_CONF);
 
-       if (!dev)
+       if (!dev) {
+               iounmap(ctrl_base);
                return 0;
+       }
 
        phyclk = clk_get(dev, "ocp2scp_usb_phy_ick");
        if (IS_ERR(phyclk)) {
index 08acb6ec81390c5a4eb6204dfda57b5a5e28d862..f6b687f61c28ebe4def01c748e0a576a53a362d9 100644 (file)
@@ -249,6 +249,29 @@ static int slot_cn7_get_cd(struct platform_device *pdev)
 {
        return !gpio_get_value(GPIO_PORT41);
 }
+/* MERAM */
+static struct sh_mobile_meram_info meram_info = {
+       .addr_mode      = SH_MOBILE_MERAM_MODE1,
+};
+
+static struct resource meram_resources[] = {
+       [0] = {
+               .name   = "MERAM",
+               .start  = 0xe8000000,
+               .end    = 0xe81fffff,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+static struct platform_device meram_device = {
+       .name           = "sh_mobile_meram",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(meram_resources),
+       .resource       = meram_resources,
+       .dev            = {
+               .platform_data = &meram_info,
+       },
+};
 
 /* SH_MMCIF */
 static struct resource sh_mmcif_resources[] = {
@@ -447,13 +470,29 @@ const static struct fb_videomode ap4evb_lcdc_modes[] = {
 #endif
        },
 };
+static struct sh_mobile_meram_cfg lcd_meram_cfg = {
+       .icb[0] = {
+               .marker_icb     = 28,
+               .cache_icb      = 24,
+               .meram_offset   = 0x0,
+               .meram_size     = 0x40,
+       },
+       .icb[1] = {
+               .marker_icb     = 29,
+               .cache_icb      = 25,
+               .meram_offset   = 0x40,
+               .meram_size     = 0x40,
+       },
+};
 
 static struct sh_mobile_lcdc_info lcdc_info = {
+       .meram_dev = &meram_info,
        .ch[0] = {
                .chan = LCDC_CHAN_MAINLCD,
                .bpp = 16,
                .lcd_cfg = ap4evb_lcdc_modes,
                .num_cfg = ARRAY_SIZE(ap4evb_lcdc_modes),
+               .meram_cfg = &lcd_meram_cfg,
        }
 };
 
@@ -724,15 +763,31 @@ static struct platform_device fsi_device = {
 static struct platform_device fsi_ak4643_device = {
        .name           = "sh_fsi2_a_ak4643",
 };
+static struct sh_mobile_meram_cfg hdmi_meram_cfg = {
+       .icb[0] = {
+               .marker_icb     = 30,
+               .cache_icb      = 26,
+               .meram_offset   = 0x80,
+               .meram_size     = 0x100,
+       },
+       .icb[1] = {
+               .marker_icb     = 31,
+               .cache_icb      = 27,
+               .meram_offset   = 0x180,
+               .meram_size     = 0x100,
+       },
+};
 
 static struct sh_mobile_lcdc_info sh_mobile_lcdc1_info = {
        .clock_source = LCDC_CLK_EXTERNAL,
+       .meram_dev = &meram_info,
        .ch[0] = {
                .chan = LCDC_CHAN_MAINLCD,
                .bpp = 16,
                .interface_type = RGB24,
                .clock_divider = 1,
                .flags = LCDC_FLAGS_DWPOL,
+               .meram_cfg = &hdmi_meram_cfg,
        }
 };
 
@@ -961,6 +1016,7 @@ static struct platform_device *ap4evb_devices[] __initdata = {
        &csi2_device,
        &ceu_device,
        &ap4evb_camera,
+       &meram_device,
 };
 
 static void __init hdmi_init_pm_clock(void)
index 448ddbe4333504d517a0ba5c70099c198fb2e9a9..776f20560e721579d5adbc6d25176d9915f96bfe 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/physmap.h>
+#include <linux/pm_runtime.h>
 #include <linux/smsc911x.h>
 #include <linux/sh_intc.h>
 #include <linux/tca6416_keypad.h>
@@ -314,6 +315,30 @@ static struct platform_device smc911x_device = {
        },
 };
 
+/* MERAM */
+static struct sh_mobile_meram_info mackerel_meram_info = {
+       .addr_mode      = SH_MOBILE_MERAM_MODE1,
+};
+
+static struct resource meram_resources[] = {
+       [0] = {
+               .name   = "MERAM",
+               .start  = 0xe8000000,
+               .end    = 0xe81fffff,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+static struct platform_device meram_device = {
+       .name           = "sh_mobile_meram",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(meram_resources),
+       .resource       = meram_resources,
+       .dev            = {
+               .platform_data = &mackerel_meram_info,
+       },
+};
+
 /* LCDC */
 static struct fb_videomode mackerel_lcdc_modes[] = {
        {
@@ -342,7 +367,23 @@ static int mackerel_get_brightness(void *board_data)
        return gpio_get_value(GPIO_PORT31);
 }
 
+static struct sh_mobile_meram_cfg lcd_meram_cfg = {
+       .icb[0] = {
+               .marker_icb     = 28,
+               .cache_icb      = 24,
+               .meram_offset   = 0x0,
+               .meram_size     = 0x40,
+       },
+       .icb[1] = {
+               .marker_icb     = 29,
+               .cache_icb      = 25,
+               .meram_offset   = 0x40,
+               .meram_size     = 0x40,
+       },
+};
+
 static struct sh_mobile_lcdc_info lcdc_info = {
+       .meram_dev = &mackerel_meram_info,
        .clock_source = LCDC_CLK_BUS,
        .ch[0] = {
                .chan = LCDC_CHAN_MAINLCD,
@@ -362,6 +403,7 @@ static struct sh_mobile_lcdc_info lcdc_info = {
                        .name = "sh_mobile_lcdc_bl",
                        .max_brightness = 1,
                },
+               .meram_cfg = &lcd_meram_cfg,
        }
 };
 
@@ -388,8 +430,23 @@ static struct platform_device lcdc_device = {
        },
 };
 
+static struct sh_mobile_meram_cfg hdmi_meram_cfg = {
+       .icb[0] = {
+               .marker_icb     = 30,
+               .cache_icb      = 26,
+               .meram_offset   = 0x80,
+               .meram_size     = 0x100,
+       },
+       .icb[1] = {
+               .marker_icb     = 31,
+               .cache_icb      = 27,
+               .meram_offset   = 0x180,
+               .meram_size     = 0x100,
+       },
+};
 /* HDMI */
 static struct sh_mobile_lcdc_info hdmi_lcdc_info = {
+       .meram_dev = &mackerel_meram_info,
        .clock_source = LCDC_CLK_EXTERNAL,
        .ch[0] = {
                .chan = LCDC_CHAN_MAINLCD,
@@ -397,6 +454,7 @@ static struct sh_mobile_lcdc_info hdmi_lcdc_info = {
                .interface_type = RGB24,
                .clock_divider = 1,
                .flags = LCDC_FLAGS_DWPOL,
+               .meram_cfg = &hdmi_meram_cfg,
        }
 };
 
@@ -856,6 +914,17 @@ static int slot_cn7_get_cd(struct platform_device *pdev)
 }
 
 /* SDHI0 */
+static irqreturn_t mackerel_sdhi0_gpio_cd(int irq, void *arg)
+{
+       struct device *dev = arg;
+       struct sh_mobile_sdhi_info *info = dev->platform_data;
+       struct tmio_mmc_data *pdata = info->pdata;
+
+       tmio_mmc_cd_wakeup(pdata);
+
+       return IRQ_HANDLED;
+}
+
 static struct sh_mobile_sdhi_info sdhi0_info = {
        .dma_slave_tx   = SHDMA_SLAVE_SDHI0_TX,
        .dma_slave_rx   = SHDMA_SLAVE_SDHI0_RX,
@@ -1150,6 +1219,7 @@ static struct platform_device *mackerel_devices[] __initdata = {
        &mackerel_camera,
        &hdmi_lcdc_device,
        &hdmi_device,
+       &meram_device,
 };
 
 /* Keypad Initialization */
@@ -1238,6 +1308,7 @@ static void __init mackerel_init(void)
 {
        u32 srcr4;
        struct clk *clk;
+       int ret;
 
        sh7372_pinmux_init();
 
@@ -1343,6 +1414,13 @@ static void __init mackerel_init(void)
        gpio_request(GPIO_FN_SDHID0_1, NULL);
        gpio_request(GPIO_FN_SDHID0_0, NULL);
 
+       ret = request_irq(evt2irq(0x3340), mackerel_sdhi0_gpio_cd,
+                         IRQF_TRIGGER_FALLING, "sdhi0 cd", &sdhi0_device.dev);
+       if (!ret)
+               sdhi0_info.tmio_flags |= TMIO_MMC_HAS_COLD_CD;
+       else
+               pr_err("Cannot get IRQ #%d: %d\n", evt2irq(0x3340), ret);
+
 #if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE)
        /* enable SDHI1 */
        gpio_request(GPIO_FN_SDHICMD1, NULL);
index d17eb66f4ac20980fb7ec441edf15e80b9f142b3..c0800d83971e62c591993cce8ad77c87a5d3b6dd 100644 (file)
@@ -509,6 +509,7 @@ enum { MSTP001,
        MSTP118, MSTP117, MSTP116, MSTP113,
        MSTP106, MSTP101, MSTP100,
        MSTP223,
+       MSTP218, MSTP217, MSTP216,
        MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
        MSTP329, MSTP328, MSTP323, MSTP322, MSTP314, MSTP313, MSTP312,
        MSTP423, MSTP415, MSTP413, MSTP411, MSTP410, MSTP406, MSTP403,
@@ -534,6 +535,9 @@ static struct clk mstp_clks[MSTP_NR] = {
        [MSTP101] = MSTP(&div4_clks[DIV4_M1], SMSTPCR1, 1, 0), /* VPU */
        [MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */
        [MSTP223] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR2, 23, 0), /* SPU2 */
+       [MSTP218] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* DMAC1 */
+       [MSTP217] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 17, 0), /* DMAC2 */
+       [MSTP216] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 16, 0), /* DMAC3 */
        [MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */
        [MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */
        [MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */
@@ -626,6 +630,9 @@ static struct clk_lookup lookups[] = {
        CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */
        CLKDEV_DEV_ID("uio_pdrv_genirq.6", &mstp_clks[MSTP223]), /* SPU2DSP0 */
        CLKDEV_DEV_ID("uio_pdrv_genirq.7", &mstp_clks[MSTP223]), /* SPU2DSP1 */
+       CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), /* DMAC1 */
+       CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[MSTP217]), /* DMAC2 */
+       CLKDEV_DEV_ID("sh-dma-engine.2", &mstp_clks[MSTP216]), /* DMAC3 */
        CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */
        CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP206]), /* SCIFB */
        CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */
index c84442cabe077b3fad50b110641cbbd95f96afd8..5ad8b2f94f8dbbbaa374c2c6ab307c307591ce72 100644 (file)
@@ -24,6 +24,8 @@
 
 #include <mach/irqs.h>
 
+#include "board-harmony.h"
+
 #define PMC_CTRL               0x0
 #define PMC_CTRL_INTR_LOW      (1 << 17)
 
@@ -98,7 +100,7 @@ static struct tps6586x_platform_data tps_platform = {
        .irq_base       = TEGRA_NR_IRQS,
        .num_subdevs    = ARRAY_SIZE(tps_devs),
        .subdevs        = tps_devs,
-       .gpio_base      = TEGRA_NR_GPIOS,
+       .gpio_base      = HARMONY_GPIO_TPS6586X(0),
 };
 
 static struct i2c_board_info __initdata harmony_regulators[] = {
index 1e57b071f52de9c6d37178bca02f0d6a563db1e8..d85142edaf6bc0eebc7d66b385e457d91fc5a100 100644 (file)
@@ -17,7 +17,8 @@
 #ifndef _MACH_TEGRA_BOARD_HARMONY_H
 #define _MACH_TEGRA_BOARD_HARMONY_H
 
-#define HARMONY_GPIO_WM8903(_x_)       (TEGRA_NR_GPIOS + (_x_))
+#define HARMONY_GPIO_TPS6586X(_x_)     (TEGRA_NR_GPIOS + (_x_))
+#define HARMONY_GPIO_WM8903(_x_)       (HARMONY_GPIO_TPS6586X(4) + (_x_))
 
 #define TEGRA_GPIO_SD2_CD              TEGRA_GPIO_PI5
 #define TEGRA_GPIO_SD2_WP              TEGRA_GPIO_PH1
index 3083195123ea2c1f9c46ea840d56a83ceda838b0..0d88499b79e903b1f7cf9ef4d2afe5c31d61c086 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/mtd/map.h>
 
+struct platform_device;
 extern void omap1_set_vpp(struct platform_device *pdev, int enable);
 
 #endif
index 32a2f6c4d39e3b37437f9e9c60b792a84297ed6e..e992b9655fbc4fb873d489846ce82e8644ea5ea6 100644 (file)
@@ -29,9 +29,6 @@ struct iovm_struct {
  * lower 16 bit is used for h/w and upper 16 bit is for s/w.
  */
 #define IOVMF_SW_SHIFT         16
-#define IOVMF_HW_SIZE          (1 << IOVMF_SW_SHIFT)
-#define IOVMF_HW_MASK          (IOVMF_HW_SIZE - 1)
-#define IOVMF_SW_MASK          (~IOVMF_HW_MASK)UL
 
 /*
  * iovma: h/w flags derived from cam and ram attribute
index f38fef9f1310ca56fdf73fb3a3816ec674ba06a9..c7b874186c27017d58a38bc4209e1c225752d3f5 100644 (file)
@@ -101,6 +101,9 @@ struct omap_mmc_platform_data {
                /* If using power_saving and the MMC power is not to go off */
                unsigned no_off:1;
 
+               /* eMMC does not handle power off when not in sleep state */
+               unsigned no_regulator_off_init:1;
+
                /* Regulator off remapped to sleep */
                unsigned vcc_aux_disable_is_sleep:1;
 
index 51ef43e8def6194e5d7bacfc361f093c3f89c79e..83a37c54342f414573d942c2c28f5bb9459b4ec7 100644 (file)
@@ -648,7 +648,6 @@ u32 iommu_vmap(struct iommu *obj, u32 da, const struct sg_table *sgt,
                        return PTR_ERR(va);
        }
 
-       flags &= IOVMF_HW_MASK;
        flags |= IOVMF_DISCONT;
        flags |= IOVMF_MMIO;
 
@@ -706,7 +705,6 @@ u32 iommu_vmalloc(struct iommu *obj, u32 da, size_t bytes, u32 flags)
        if (!va)
                return -ENOMEM;
 
-       flags &= IOVMF_HW_MASK;
        flags |= IOVMF_DISCONT;
        flags |= IOVMF_ALLOC;
 
@@ -795,7 +793,6 @@ u32 iommu_kmap(struct iommu *obj, u32 da, u32 pa, size_t bytes,
        if (!va)
                return -ENOMEM;
 
-       flags &= IOVMF_HW_MASK;
        flags |= IOVMF_LINEAR;
        flags |= IOVMF_MMIO;
 
@@ -853,7 +850,6 @@ u32 iommu_kmalloc(struct iommu *obj, u32 da, size_t bytes, u32 flags)
                return -ENOMEM;
        pa = virt_to_phys(va);
 
-       flags &= IOVMF_HW_MASK;
        flags |= IOVMF_LINEAR;
        flags |= IOVMF_ALLOC;
 
index a3f50b34a90d3ffed85c0fcd4bc6baad080df7cd..6af3d0b1f8d058e8387697b3c560bce32f7e31ef 100644 (file)
@@ -166,7 +166,7 @@ static void __init omap_detect_sram(void)
                else if (cpu_is_omap1611())
                        omap_sram_size = SZ_256K;
                else {
-                       printk(KERN_ERR "Could not detect SRAM size\n");
+                       pr_err("Could not detect SRAM size\n");
                        omap_sram_size = 0x4000;
                }
        }
@@ -221,10 +221,10 @@ static void __init omap_map_sram(void)
        omap_sram_io_desc[0].length = ROUND_DOWN(omap_sram_size, PAGE_SIZE);
        iotable_init(omap_sram_io_desc, ARRAY_SIZE(omap_sram_io_desc));
 
-       printk(KERN_INFO "SRAM: Mapped pa 0x%08lx to va 0x%08lx size: 0x%lx\n",
-       __pfn_to_phys(omap_sram_io_desc[0].pfn),
-       omap_sram_io_desc[0].virtual,
-              omap_sram_io_desc[0].length);
+       pr_info("SRAM: Mapped pa 0x%08llx to va 0x%08lx size: 0x%lx\n",
+               (long long) __pfn_to_phys(omap_sram_io_desc[0].pfn),
+               omap_sram_io_desc[0].virtual,
+               omap_sram_io_desc[0].length);
 
        /*
         * Normally devicemaps_init() would flush caches and tlb after
@@ -252,7 +252,7 @@ static void __init omap_map_sram(void)
 void *omap_sram_push_address(unsigned long size)
 {
        if (size > (omap_sram_ceil - (omap_sram_base + SRAM_BOOTLOADER_SZ))) {
-               printk(KERN_ERR "Not enough space in SRAM\n");
+               pr_err("Not enough space in SRAM\n");
                return NULL;
        }
 
index f3931d50b4a715a50878363a43bd14e9c63b9dd1..2c07dddac9956bd24da0603910c9a7d35957f42b 100644 (file)
@@ -25,7 +25,7 @@
 
 ENTRY(_strncpy)
        CC = R2 == 0;
-       if CC JUMP 4f;
+       if CC JUMP 6f;
 
        P2 = R2 ;       /* size */
        P0 = R0 ;       /* dst*/
index 1cf0f496f7442ae918942f3cfe647beab6e4b031..7c928da35b173732cc01d9a8d6f749ef4310d691 100644 (file)
 #define __NR_clock_adjtime             1328
 #define __NR_syncfs                    1329
 #define __NR_setns                     1330
+#define __NR_sendmmsg                  1331
 
 #ifdef __KERNEL__
 
 
-#define NR_syscalls                    307 /* length of syscall table */
+#define NR_syscalls                    308 /* length of syscall table */
 
 /*
  * The following defines stop scripts/checksyscalls.sh from complaining about
index 9ca80193cd4eecbf8d562727ddb8537d3c1453c8..97dd2abdeb1a3b2cd66a409d1dc4bf8ec0345b55 100644 (file)
@@ -1776,6 +1776,7 @@ sys_call_table:
        data8 sys_clock_adjtime
        data8 sys_syncfs
        data8 sys_setns                         // 1330
+       data8 sys_sendmmsg
 
        .org sys_call_table + 8*NR_syscalls     // guard against failures to increase NR_syscalls
 #endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */
index f03cb278828f400c1e66580be491c30da507e9b3..bd3e5e73826e1839b307d5ae7a279a3e93f6afbc 100644 (file)
@@ -28,7 +28,7 @@
 #include <linux/irq.h>
 #include <asm/processor.h>
 #include <asm/system.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <asm/io.h>
 #include <asm/atomic.h>
 #include <asm/smp.h>
@@ -156,7 +156,7 @@ int die_if_no_fixup(const char *str, struct pt_regs *regs,
 
        case EXCEP_TRAP:
        case EXCEP_UNIMPINS:
-               if (get_user(opcode, (uint8_t __user *)regs->pc) != 0)
+               if (probe_kernel_read(&opcode, (u8 *)regs->pc, 1) < 0)
                        break;
                if (opcode == 0xff) {
                        if (notify_die(DIE_BREAKPOINT, str, regs, code, 0, 0))
index 6f702a6ab3955531ff31f65fb7ace7c37f01aa1f..13c4814c29f840dd4ecb95e4e7206da7127aef49 100644 (file)
@@ -44,6 +44,7 @@ SECTIONS
   RO_DATA(PAGE_SIZE)
 
   /* writeable */
+  _sdata = .;     /* Start of rw data section */
   RW_DATA_SECTION(32, PAGE_SIZE, THREAD_SIZE)
   _edata = .;
 
index 665919f2ab62ef3e8f43c4466f6f72fdd69988e9..a775ea5d7cee077cf37c5ceb90c8bfe773e4fd99 100644 (file)
@@ -120,14 +120,14 @@ debugger_local_cache_flushinv_one:
        # conditionally purge this line in all ways
        mov     d1,(L1_CACHE_WAYDISP*0,a0)
 
-debugger_local_cache_flushinv_no_dcache:
+debugger_local_cache_flushinv_one_no_dcache:
        #
        # now try to flush the icache
        #
        mov     CHCTR,a0
        movhu   (a0),d0
        btst    CHCTR_ICEN,d0
-       beq     mn10300_local_icache_inv_range_reg_end
+       beq     debugger_local_cache_flushinv_one_end
 
        LOCAL_CLI_SAVE(d1)
 
index 9089b04211919506cb1a443025d0f058d5deff3c..7667db448aa73cc58aacaf72e74fa0c5a2339fc6 100644 (file)
@@ -715,7 +715,8 @@ static struct syscore_ops pmacpic_syscore_ops = {
 
 static int __init init_pmacpic_syscore(void)
 {
-       register_syscore_ops(&pmacpic_syscore_ops);
+       if (pmac_irq_hw[0])
+               register_syscore_ops(&pmacpic_syscore_ops);
        return 0;
 }
 
index 9fab2aa9c2c80d0bbf1fbf0f943b377de3583118..90d77bd078f51acc243b21ee0c63432d01369ee9 100644 (file)
@@ -89,6 +89,7 @@ config S390
        select HAVE_GET_USER_PAGES_FAST
        select HAVE_ARCH_MUTEX_CPU_RELAX
        select HAVE_ARCH_JUMP_LABEL if !MARCH_G5
+       select HAVE_RCU_TABLE_FREE if SMP
        select ARCH_INLINE_SPIN_TRYLOCK
        select ARCH_INLINE_SPIN_TRYLOCK_BH
        select ARCH_INLINE_SPIN_LOCK
index f6314af3b354ca4375547db504367bc547c351eb..38e71ebcd3c276c2483d5e378f4cc63f189c20a2 100644 (file)
 #include <linux/gfp.h>
 #include <linux/mm.h>
 
-#define check_pgt_cache()      do {} while (0)
-
 unsigned long *crst_table_alloc(struct mm_struct *);
 void crst_table_free(struct mm_struct *, unsigned long *);
-void crst_table_free_rcu(struct mm_struct *, unsigned long *);
 
 unsigned long *page_table_alloc(struct mm_struct *);
 void page_table_free(struct mm_struct *, unsigned long *);
-void page_table_free_rcu(struct mm_struct *, unsigned long *);
+#ifdef CONFIG_HAVE_RCU_TABLE_FREE
+void page_table_free_rcu(struct mmu_gather *, unsigned long *);
+void __tlb_remove_table(void *_table);
+#endif
 
 static inline void clear_table(unsigned long *s, unsigned long val, size_t n)
 {
index e4efacfe1b63a7ea936910e230f2e7a701729a76..801fbe1d837d32f04e4c3106da6cb85dae2c6ec9 100644 (file)
@@ -293,19 +293,6 @@ extern unsigned long VMALLOC_START;
  * swap pte is 1011 and 0001, 0011, 0101, 0111 are invalid.
  */
 
-/* Page status table bits for virtualization */
-#define RCP_ACC_BITS   0xf000000000000000UL
-#define RCP_FP_BIT     0x0800000000000000UL
-#define RCP_PCL_BIT    0x0080000000000000UL
-#define RCP_HR_BIT     0x0040000000000000UL
-#define RCP_HC_BIT     0x0020000000000000UL
-#define RCP_GR_BIT     0x0004000000000000UL
-#define RCP_GC_BIT     0x0002000000000000UL
-
-/* User dirty / referenced bit for KVM's migration feature */
-#define KVM_UR_BIT     0x0000800000000000UL
-#define KVM_UC_BIT     0x0000400000000000UL
-
 #ifndef __s390x__
 
 /* Bits in the segment table address-space-control-element */
@@ -325,6 +312,19 @@ extern unsigned long VMALLOC_START;
 #define _SEGMENT_ENTRY         (_SEGMENT_ENTRY_PTL)
 #define _SEGMENT_ENTRY_EMPTY   (_SEGMENT_ENTRY_INV)
 
+/* Page status table bits for virtualization */
+#define RCP_ACC_BITS   0xf0000000UL
+#define RCP_FP_BIT     0x08000000UL
+#define RCP_PCL_BIT    0x00800000UL
+#define RCP_HR_BIT     0x00400000UL
+#define RCP_HC_BIT     0x00200000UL
+#define RCP_GR_BIT     0x00040000UL
+#define RCP_GC_BIT     0x00020000UL
+
+/* User dirty / referenced bit for KVM's migration feature */
+#define KVM_UR_BIT     0x00008000UL
+#define KVM_UC_BIT     0x00004000UL
+
 #else /* __s390x__ */
 
 /* Bits in the segment/region table address-space-control-element */
@@ -367,6 +367,19 @@ extern unsigned long VMALLOC_START;
 #define _SEGMENT_ENTRY_LARGE   0x400   /* STE-format control, large page   */
 #define _SEGMENT_ENTRY_CO      0x100   /* change-recording override   */
 
+/* Page status table bits for virtualization */
+#define RCP_ACC_BITS   0xf000000000000000UL
+#define RCP_FP_BIT     0x0800000000000000UL
+#define RCP_PCL_BIT    0x0080000000000000UL
+#define RCP_HR_BIT     0x0040000000000000UL
+#define RCP_HC_BIT     0x0020000000000000UL
+#define RCP_GR_BIT     0x0004000000000000UL
+#define RCP_GC_BIT     0x0002000000000000UL
+
+/* User dirty / referenced bit for KVM's migration feature */
+#define KVM_UR_BIT     0x0000800000000000UL
+#define KVM_UC_BIT     0x0000400000000000UL
+
 #endif /* __s390x__ */
 
 /*
index 350e7ee5952daaa025ed239189a1df2f78f9142d..15c97625df8d3f0411c17a44c999b117ef1ff49d 100644 (file)
@@ -139,110 +139,47 @@ struct slib {
        struct slibe slibe[QDIO_MAX_BUFFERS_PER_Q];
 } __attribute__ ((packed, aligned(2048)));
 
-/**
- * struct sbal_flags - storage block address list flags
- * @last: last entry
- * @cont: contiguous storage
- * @frag: fragmentation
- */
-struct sbal_flags {
-       u8      : 1;
-       u8 last : 1;
-       u8 cont : 1;
-       u8      : 1;
-       u8 frag : 2;
-       u8      : 2;
-} __attribute__ ((packed));
-
-#define SBAL_FLAGS_FIRST_FRAG          0x04000000UL
-#define SBAL_FLAGS_MIDDLE_FRAG         0x08000000UL
-#define SBAL_FLAGS_LAST_FRAG           0x0c000000UL
-#define SBAL_FLAGS_LAST_ENTRY          0x40000000UL
-#define SBAL_FLAGS_CONTIGUOUS          0x20000000UL
+#define SBAL_EFLAGS_LAST_ENTRY         0x40
+#define SBAL_EFLAGS_CONTIGUOUS         0x20
+#define SBAL_EFLAGS_FIRST_FRAG         0x04
+#define SBAL_EFLAGS_MIDDLE_FRAG                0x08
+#define SBAL_EFLAGS_LAST_FRAG          0x0c
+#define SBAL_EFLAGS_MASK               0x6f
 
-#define SBAL_FLAGS0_DATA_CONTINUATION  0x20UL
+#define SBAL_SFLAGS0_PCI_REQ           0x40
+#define SBAL_SFLAGS0_DATA_CONTINUATION 0x20
 
 /* Awesome OpenFCP extensions */
-#define SBAL_FLAGS0_TYPE_STATUS                0x00UL
-#define SBAL_FLAGS0_TYPE_WRITE         0x08UL
-#define SBAL_FLAGS0_TYPE_READ          0x10UL
-#define SBAL_FLAGS0_TYPE_WRITE_READ    0x18UL
-#define SBAL_FLAGS0_MORE_SBALS         0x04UL
-#define SBAL_FLAGS0_COMMAND            0x02UL
-#define SBAL_FLAGS0_LAST_SBAL          0x00UL
-#define SBAL_FLAGS0_ONLY_SBAL          SBAL_FLAGS0_COMMAND
-#define SBAL_FLAGS0_MIDDLE_SBAL                SBAL_FLAGS0_MORE_SBALS
-#define SBAL_FLAGS0_FIRST_SBAL SBAL_FLAGS0_MORE_SBALS | SBAL_FLAGS0_COMMAND
-#define SBAL_FLAGS0_PCI                        0x40
-
-/**
- * struct sbal_sbalf_0 - sbal flags for sbale 0
- * @pci: PCI indicator
- * @cont: data continuation
- * @sbtype: storage-block type (FCP)
- */
-struct sbal_sbalf_0 {
-       u8        : 1;
-       u8 pci    : 1;
-       u8 cont   : 1;
-       u8 sbtype : 2;
-       u8        : 3;
-} __attribute__ ((packed));
-
-/**
- * struct sbal_sbalf_1 - sbal flags for sbale 1
- * @key: storage key
- */
-struct sbal_sbalf_1 {
-       u8     : 4;
-       u8 key : 4;
-} __attribute__ ((packed));
-
-/**
- * struct sbal_sbalf_14 - sbal flags for sbale 14
- * @erridx: error index
- */
-struct sbal_sbalf_14 {
-       u8        : 4;
-       u8 erridx : 4;
-} __attribute__ ((packed));
-
-/**
- * struct sbal_sbalf_15 - sbal flags for sbale 15
- * @reason: reason for error state
- */
-struct sbal_sbalf_15 {
-       u8 reason;
-} __attribute__ ((packed));
-
-/**
- * union sbal_sbalf - storage block address list flags
- * @i0: sbalf0
- * @i1: sbalf1
- * @i14: sbalf14
- * @i15: sblaf15
- * @value: raw value
- */
-union sbal_sbalf {
-       struct sbal_sbalf_0  i0;
-       struct sbal_sbalf_1  i1;
-       struct sbal_sbalf_14 i14;
-       struct sbal_sbalf_15 i15;
-       u8 value;
-};
+#define SBAL_SFLAGS0_TYPE_STATUS       0x00
+#define SBAL_SFLAGS0_TYPE_WRITE                0x08
+#define SBAL_SFLAGS0_TYPE_READ         0x10
+#define SBAL_SFLAGS0_TYPE_WRITE_READ   0x18
+#define SBAL_SFLAGS0_MORE_SBALS                0x04
+#define SBAL_SFLAGS0_COMMAND           0x02
+#define SBAL_SFLAGS0_LAST_SBAL         0x00
+#define SBAL_SFLAGS0_ONLY_SBAL         SBAL_SFLAGS0_COMMAND
+#define SBAL_SFLAGS0_MIDDLE_SBAL       SBAL_SFLAGS0_MORE_SBALS
+#define SBAL_SFLAGS0_FIRST_SBAL (SBAL_SFLAGS0_MORE_SBALS | SBAL_SFLAGS0_COMMAND)
 
 /**
  * struct qdio_buffer_element - SBAL entry
- * @flags: flags
+ * @eflags: SBAL entry flags
+ * @scount: SBAL count
+ * @sflags: whole SBAL flags
  * @length: length
  * @addr: address
 */
 struct qdio_buffer_element {
-       u32 flags;
+       u8 eflags;
+       /* private: */
+       u8 res1;
+       /* public: */
+       u8 scount;
+       u8 sflags;
        u32 length;
 #ifdef CONFIG_32BIT
        /* private: */
-       void *reserved;
+       void *res2;
        /* public: */
 #endif
        void *addr;
index 77eee5477a52fa8ce8404d8c6fd8a4fdfdac51f5..c687a2c834626adb1f01cc24ae4f62713d83adaa 100644 (file)
 #include <linux/swap.h>
 #include <asm/processor.h>
 #include <asm/pgalloc.h>
-#include <asm/smp.h>
 #include <asm/tlbflush.h>
 
 struct mmu_gather {
        struct mm_struct *mm;
+#ifdef CONFIG_HAVE_RCU_TABLE_FREE
+       struct mmu_table_batch *batch;
+#endif
        unsigned int fullmm;
-       unsigned int nr_ptes;
-       unsigned int nr_pxds;
-       unsigned int max;
-       void **array;
-       void *local[8];
+       unsigned int need_flush;
 };
 
-static inline void __tlb_alloc_page(struct mmu_gather *tlb)
-{
-       unsigned long addr = __get_free_pages(GFP_NOWAIT | __GFP_NOWARN, 0);
+#ifdef CONFIG_HAVE_RCU_TABLE_FREE
+struct mmu_table_batch {
+       struct rcu_head         rcu;
+       unsigned int            nr;
+       void                    *tables[0];
+};
 
-       if (addr) {
-               tlb->array = (void *) addr;
-               tlb->max = PAGE_SIZE / sizeof(void *);
-       }
-}
+#define MAX_TABLE_BATCH                \
+       ((PAGE_SIZE - sizeof(struct mmu_table_batch)) / sizeof(void *))
+
+extern void tlb_table_flush(struct mmu_gather *tlb);
+extern void tlb_remove_table(struct mmu_gather *tlb, void *table);
+#endif
 
 static inline void tlb_gather_mmu(struct mmu_gather *tlb,
                                  struct mm_struct *mm,
                                  unsigned int full_mm_flush)
 {
        tlb->mm = mm;
-       tlb->max = ARRAY_SIZE(tlb->local);
-       tlb->array = tlb->local;
        tlb->fullmm = full_mm_flush;
+       tlb->need_flush = 0;
+#ifdef CONFIG_HAVE_RCU_TABLE_FREE
+       tlb->batch = NULL;
+#endif
        if (tlb->fullmm)
                __tlb_flush_mm(mm);
-       else
-               __tlb_alloc_page(tlb);
-       tlb->nr_ptes = 0;
-       tlb->nr_pxds = tlb->max;
 }
 
 static inline void tlb_flush_mmu(struct mmu_gather *tlb)
 {
-       if (!tlb->fullmm && (tlb->nr_ptes > 0 || tlb->nr_pxds < tlb->max))
-               __tlb_flush_mm(tlb->mm);
-       while (tlb->nr_ptes > 0)
-               page_table_free_rcu(tlb->mm, tlb->array[--tlb->nr_ptes]);
-       while (tlb->nr_pxds < tlb->max)
-               crst_table_free_rcu(tlb->mm, tlb->array[tlb->nr_pxds++]);
+       if (!tlb->need_flush)
+               return;
+       tlb->need_flush = 0;
+       __tlb_flush_mm(tlb->mm);
+#ifdef CONFIG_HAVE_RCU_TABLE_FREE
+       tlb_table_flush(tlb);
+#endif
 }
 
 static inline void tlb_finish_mmu(struct mmu_gather *tlb,
                                  unsigned long start, unsigned long end)
 {
        tlb_flush_mmu(tlb);
-
-       rcu_table_freelist_finish();
-
-       /* keep the page table cache within bounds */
-       check_pgt_cache();
-
-       if (tlb->array != tlb->local)
-               free_pages((unsigned long) tlb->array, 0);
 }
 
 /*
@@ -112,12 +105,11 @@ static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page)
 static inline void pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
                                unsigned long address)
 {
-       if (!tlb->fullmm) {
-               tlb->array[tlb->nr_ptes++] = pte;
-               if (tlb->nr_ptes >= tlb->nr_pxds)
-                       tlb_flush_mmu(tlb);
-       } else
-               page_table_free(tlb->mm, (unsigned long *) pte);
+#ifdef CONFIG_HAVE_RCU_TABLE_FREE
+       if (!tlb->fullmm)
+               return page_table_free_rcu(tlb, (unsigned long *) pte);
+#endif
+       page_table_free(tlb->mm, (unsigned long *) pte);
 }
 
 /*
@@ -133,12 +125,11 @@ static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd,
 #ifdef __s390x__
        if (tlb->mm->context.asce_limit <= (1UL << 31))
                return;
-       if (!tlb->fullmm) {
-               tlb->array[--tlb->nr_pxds] = pmd;
-               if (tlb->nr_ptes >= tlb->nr_pxds)
-                       tlb_flush_mmu(tlb);
-       } else
-               crst_table_free(tlb->mm, (unsigned long *) pmd);
+#ifdef CONFIG_HAVE_RCU_TABLE_FREE
+       if (!tlb->fullmm)
+               return tlb_remove_table(tlb, pmd);
+#endif
+       crst_table_free(tlb->mm, (unsigned long *) pmd);
 #endif
 }
 
@@ -155,12 +146,11 @@ static inline void pud_free_tlb(struct mmu_gather *tlb, pud_t *pud,
 #ifdef __s390x__
        if (tlb->mm->context.asce_limit <= (1UL << 42))
                return;
-       if (!tlb->fullmm) {
-               tlb->array[--tlb->nr_pxds] = pud;
-               if (tlb->nr_ptes >= tlb->nr_pxds)
-                       tlb_flush_mmu(tlb);
-       } else
-               crst_table_free(tlb->mm, (unsigned long *) pud);
+#ifdef CONFIG_HAVE_RCU_TABLE_FREE
+       if (!tlb->fullmm)
+               return tlb_remove_table(tlb, pud);
+#endif
+       crst_table_free(tlb->mm, (unsigned long *) pud);
 #endif
 }
 
index 30ca85cce3147f89b70cb2ba991c20e1275a1a5a..67345ae7ce8d967a6e952070e2969d10ad7dcd5e 100644 (file)
@@ -731,6 +731,7 @@ static int __init kvm_s390_init(void)
        }
        memcpy(facilities, S390_lowcore.stfle_fac_list, 16);
        facilities[0] &= 0xff00fff3f47c0000ULL;
+       facilities[1] &= 0x201c000000000000ULL;
        return 0;
 }
 
index ab0e041ac54cf2b17fc0b631bf0ed6cd4f59fd53..5faa1b1b23fa78f19d8f399f7681e3573ade6ee7 100644 (file)
@@ -93,4 +93,6 @@ sie_err:
 
        .section __ex_table,"a"
        .quad   sie_inst,sie_err
+       .quad   sie_exit,sie_err
+       .quad   sie_reenter,sie_err
        .previous
index b09763fe5da1a5385f1b77c17f5949c0ffdd592d..37a23c22370576415441e7542728b79a233f2f58 100644 (file)
 #include <asm/tlbflush.h>
 #include <asm/mmu_context.h>
 
-struct rcu_table_freelist {
-       struct rcu_head rcu;
-       struct mm_struct *mm;
-       unsigned int pgt_index;
-       unsigned int crst_index;
-       unsigned long *table[0];
-};
-
-#define RCU_FREELIST_SIZE \
-       ((PAGE_SIZE - sizeof(struct rcu_table_freelist)) \
-         / sizeof(unsigned long))
-
-static DEFINE_PER_CPU(struct rcu_table_freelist *, rcu_table_freelist);
-
-static void __page_table_free(struct mm_struct *mm, unsigned long *table);
-
-static struct rcu_table_freelist *rcu_table_freelist_get(struct mm_struct *mm)
-{
-       struct rcu_table_freelist **batchp = &__get_cpu_var(rcu_table_freelist);
-       struct rcu_table_freelist *batch = *batchp;
-
-       if (batch)
-               return batch;
-       batch = (struct rcu_table_freelist *) __get_free_page(GFP_ATOMIC);
-       if (batch) {
-               batch->mm = mm;
-               batch->pgt_index = 0;
-               batch->crst_index = RCU_FREELIST_SIZE;
-               *batchp = batch;
-       }
-       return batch;
-}
-
-static void rcu_table_freelist_callback(struct rcu_head *head)
-{
-       struct rcu_table_freelist *batch =
-               container_of(head, struct rcu_table_freelist, rcu);
-
-       while (batch->pgt_index > 0)
-               __page_table_free(batch->mm, batch->table[--batch->pgt_index]);
-       while (batch->crst_index < RCU_FREELIST_SIZE)
-               crst_table_free(batch->mm, batch->table[batch->crst_index++]);
-       free_page((unsigned long) batch);
-}
-
-void rcu_table_freelist_finish(void)
-{
-       struct rcu_table_freelist **batchp = &get_cpu_var(rcu_table_freelist);
-       struct rcu_table_freelist *batch = *batchp;
-
-       if (!batch)
-               goto out;
-       call_rcu(&batch->rcu, rcu_table_freelist_callback);
-       *batchp = NULL;
-out:
-       put_cpu_var(rcu_table_freelist);
-}
-
-static void smp_sync(void *arg)
-{
-}
-
 #ifndef CONFIG_64BIT
 #define ALLOC_ORDER    1
-#define TABLES_PER_PAGE        4
-#define FRAG_MASK      15UL
-#define SECOND_HALVES  10UL
-
-void clear_table_pgstes(unsigned long *table)
-{
-       clear_table(table, _PAGE_TYPE_EMPTY, PAGE_SIZE/4);
-       memset(table + 256, 0, PAGE_SIZE/4);
-       clear_table(table + 512, _PAGE_TYPE_EMPTY, PAGE_SIZE/4);
-       memset(table + 768, 0, PAGE_SIZE/4);
-}
-
+#define FRAG_MASK      0x0f
 #else
 #define ALLOC_ORDER    2
-#define TABLES_PER_PAGE        2
-#define FRAG_MASK      3UL
-#define SECOND_HALVES  2UL
-
-void clear_table_pgstes(unsigned long *table)
-{
-       clear_table(table, _PAGE_TYPE_EMPTY, PAGE_SIZE/2);
-       memset(table + 256, 0, PAGE_SIZE/2);
-}
-
+#define FRAG_MASK      0x03
 #endif
 
 unsigned long VMALLOC_START = VMALLOC_END - VMALLOC_SIZE;
@@ -140,29 +58,6 @@ void crst_table_free(struct mm_struct *mm, unsigned long *table)
        free_pages((unsigned long) table, ALLOC_ORDER);
 }
 
-void crst_table_free_rcu(struct mm_struct *mm, unsigned long *table)
-{
-       struct rcu_table_freelist *batch;
-
-       preempt_disable();
-       if (atomic_read(&mm->mm_users) < 2 &&
-           cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id()))) {
-               crst_table_free(mm, table);
-               goto out;
-       }
-       batch = rcu_table_freelist_get(mm);
-       if (!batch) {
-               smp_call_function(smp_sync, NULL, 1);
-               crst_table_free(mm, table);
-               goto out;
-       }
-       batch->table[--batch->crst_index] = table;
-       if (batch->pgt_index >= batch->crst_index)
-               rcu_table_freelist_finish();
-out:
-       preempt_enable();
-}
-
 #ifdef CONFIG_64BIT
 int crst_table_upgrade(struct mm_struct *mm, unsigned long limit)
 {
@@ -238,124 +133,175 @@ void crst_table_downgrade(struct mm_struct *mm, unsigned long limit)
 }
 #endif
 
+static inline unsigned int atomic_xor_bits(atomic_t *v, unsigned int bits)
+{
+       unsigned int old, new;
+
+       do {
+               old = atomic_read(v);
+               new = old ^ bits;
+       } while (atomic_cmpxchg(v, old, new) != old);
+       return new;
+}
+
 /*
  * page table entry allocation/free routines.
  */
+#ifdef CONFIG_PGSTE
+static inline unsigned long *page_table_alloc_pgste(struct mm_struct *mm)
+{
+       struct page *page;
+       unsigned long *table;
+
+       page = alloc_page(GFP_KERNEL|__GFP_REPEAT);
+       if (!page)
+               return NULL;
+       pgtable_page_ctor(page);
+       atomic_set(&page->_mapcount, 3);
+       table = (unsigned long *) page_to_phys(page);
+       clear_table(table, _PAGE_TYPE_EMPTY, PAGE_SIZE/2);
+       clear_table(table + PTRS_PER_PTE, 0, PAGE_SIZE/2);
+       return table;
+}
+
+static inline void page_table_free_pgste(unsigned long *table)
+{
+       struct page *page;
+
+       page = pfn_to_page(__pa(table) >> PAGE_SHIFT);
+       pgtable_page_ctor(page);
+       atomic_set(&page->_mapcount, -1);
+       __free_page(page);
+}
+#endif
+
 unsigned long *page_table_alloc(struct mm_struct *mm)
 {
        struct page *page;
        unsigned long *table;
-       unsigned long bits;
+       unsigned int mask, bit;
 
-       bits = (mm->context.has_pgste) ? 3UL : 1UL;
+#ifdef CONFIG_PGSTE
+       if (mm_has_pgste(mm))
+               return page_table_alloc_pgste(mm);
+#endif
+       /* Allocate fragments of a 4K page as 1K/2K page table */
        spin_lock_bh(&mm->context.list_lock);
-       page = NULL;
+       mask = FRAG_MASK;
        if (!list_empty(&mm->context.pgtable_list)) {
                page = list_first_entry(&mm->context.pgtable_list,
                                        struct page, lru);
-               if ((page->flags & FRAG_MASK) == ((1UL << TABLES_PER_PAGE) - 1))
-                       page = NULL;
+               table = (unsigned long *) page_to_phys(page);
+               mask = atomic_read(&page->_mapcount);
+               mask = mask | (mask >> 4);
        }
-       if (!page) {
+       if ((mask & FRAG_MASK) == FRAG_MASK) {
                spin_unlock_bh(&mm->context.list_lock);
                page = alloc_page(GFP_KERNEL|__GFP_REPEAT);
                if (!page)
                        return NULL;
                pgtable_page_ctor(page);
-               page->flags &= ~FRAG_MASK;
+               atomic_set(&page->_mapcount, 1);
                table = (unsigned long *) page_to_phys(page);
-               if (mm->context.has_pgste)
-                       clear_table_pgstes(table);
-               else
-                       clear_table(table, _PAGE_TYPE_EMPTY, PAGE_SIZE);
+               clear_table(table, _PAGE_TYPE_EMPTY, PAGE_SIZE);
                spin_lock_bh(&mm->context.list_lock);
                list_add(&page->lru, &mm->context.pgtable_list);
+       } else {
+               for (bit = 1; mask & bit; bit <<= 1)
+                       table += PTRS_PER_PTE;
+               mask = atomic_xor_bits(&page->_mapcount, bit);
+               if ((mask & FRAG_MASK) == FRAG_MASK)
+                       list_del(&page->lru);
        }
-       table = (unsigned long *) page_to_phys(page);
-       while (page->flags & bits) {
-               table += 256;
-               bits <<= 1;
-       }
-       page->flags |= bits;
-       if ((page->flags & FRAG_MASK) == ((1UL << TABLES_PER_PAGE) - 1))
-               list_move_tail(&page->lru, &mm->context.pgtable_list);
        spin_unlock_bh(&mm->context.list_lock);
        return table;
 }
 
-static void __page_table_free(struct mm_struct *mm, unsigned long *table)
+void page_table_free(struct mm_struct *mm, unsigned long *table)
 {
        struct page *page;
-       unsigned long bits;
+       unsigned int bit, mask;
 
-       bits = ((unsigned long) table) & 15;
-       table = (unsigned long *)(((unsigned long) table) ^ bits);
+#ifdef CONFIG_PGSTE
+       if (mm_has_pgste(mm))
+               return page_table_free_pgste(table);
+#endif
+       /* Free 1K/2K page table fragment of a 4K page */
        page = pfn_to_page(__pa(table) >> PAGE_SHIFT);
-       page->flags ^= bits;
-       if (!(page->flags & FRAG_MASK)) {
+       bit = 1 << ((__pa(table) & ~PAGE_MASK)/(PTRS_PER_PTE*sizeof(pte_t)));
+       spin_lock_bh(&mm->context.list_lock);
+       if ((atomic_read(&page->_mapcount) & FRAG_MASK) != FRAG_MASK)
+               list_del(&page->lru);
+       mask = atomic_xor_bits(&page->_mapcount, bit);
+       if (mask & FRAG_MASK)
+               list_add(&page->lru, &mm->context.pgtable_list);
+       spin_unlock_bh(&mm->context.list_lock);
+       if (mask == 0) {
                pgtable_page_dtor(page);
+               atomic_set(&page->_mapcount, -1);
                __free_page(page);
        }
 }
 
-void page_table_free(struct mm_struct *mm, unsigned long *table)
+#ifdef CONFIG_HAVE_RCU_TABLE_FREE
+
+static void __page_table_free_rcu(void *table, unsigned bit)
 {
        struct page *page;
-       unsigned long bits;
 
-       bits = (mm->context.has_pgste) ? 3UL : 1UL;
-       bits <<= (__pa(table) & (PAGE_SIZE - 1)) / 256 / sizeof(unsigned long);
+#ifdef CONFIG_PGSTE
+       if (bit == FRAG_MASK)
+               return page_table_free_pgste(table);
+#endif
+       /* Free 1K/2K page table fragment of a 4K page */
        page = pfn_to_page(__pa(table) >> PAGE_SHIFT);
-       spin_lock_bh(&mm->context.list_lock);
-       page->flags ^= bits;
-       if (page->flags & FRAG_MASK) {
-               /* Page now has some free pgtable fragments. */
-               if (!list_empty(&page->lru))
-                       list_move(&page->lru, &mm->context.pgtable_list);
-               page = NULL;
-       } else
-               /* All fragments of the 4K page have been freed. */
-               list_del(&page->lru);
-       spin_unlock_bh(&mm->context.list_lock);
-       if (page) {
+       if (atomic_xor_bits(&page->_mapcount, bit) == 0) {
                pgtable_page_dtor(page);
+               atomic_set(&page->_mapcount, -1);
                __free_page(page);
        }
 }
 
-void page_table_free_rcu(struct mm_struct *mm, unsigned long *table)
+void page_table_free_rcu(struct mmu_gather *tlb, unsigned long *table)
 {
-       struct rcu_table_freelist *batch;
+       struct mm_struct *mm;
        struct page *page;
-       unsigned long bits;
+       unsigned int bit, mask;
 
-       preempt_disable();
-       if (atomic_read(&mm->mm_users) < 2 &&
-           cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id()))) {
-               page_table_free(mm, table);
-               goto out;
-       }
-       batch = rcu_table_freelist_get(mm);
-       if (!batch) {
-               smp_call_function(smp_sync, NULL, 1);
-               page_table_free(mm, table);
-               goto out;
+       mm = tlb->mm;
+#ifdef CONFIG_PGSTE
+       if (mm_has_pgste(mm)) {
+               table = (unsigned long *) (__pa(table) | FRAG_MASK);
+               tlb_remove_table(tlb, table);
+               return;
        }
-       bits = (mm->context.has_pgste) ? 3UL : 1UL;
-       bits <<= (__pa(table) & (PAGE_SIZE - 1)) / 256 / sizeof(unsigned long);
+#endif
+       bit = 1 << ((__pa(table) & ~PAGE_MASK) / (PTRS_PER_PTE*sizeof(pte_t)));
        page = pfn_to_page(__pa(table) >> PAGE_SHIFT);
        spin_lock_bh(&mm->context.list_lock);
-       /* Delayed freeing with rcu prevents reuse of pgtable fragments */
-       list_del_init(&page->lru);
+       if ((atomic_read(&page->_mapcount) & FRAG_MASK) != FRAG_MASK)
+               list_del(&page->lru);
+       mask = atomic_xor_bits(&page->_mapcount, bit | (bit << 4));
+       if (mask & FRAG_MASK)
+               list_add_tail(&page->lru, &mm->context.pgtable_list);
        spin_unlock_bh(&mm->context.list_lock);
-       table = (unsigned long *)(((unsigned long) table) | bits);
-       batch->table[batch->pgt_index++] = table;
-       if (batch->pgt_index >= batch->crst_index)
-               rcu_table_freelist_finish();
-out:
-       preempt_enable();
+       table = (unsigned long *) (__pa(table) | (bit << 4));
+       tlb_remove_table(tlb, table);
 }
 
+void __tlb_remove_table(void *_table)
+{
+       void *table = (void *)((unsigned long) _table & PAGE_MASK);
+       unsigned type = (unsigned long) _table & ~PAGE_MASK;
+
+       if (type)
+               __page_table_free_rcu(table, type);
+       else
+               free_pages((unsigned long) table, ALLOC_ORDER);
+}
+
+#endif
+
 /*
  * switch on pgstes for its userspace process (for kvm)
  */
@@ -369,7 +315,7 @@ int s390_enable_sie(void)
                return -EINVAL;
 
        /* Do we have pgstes? if yes, we are done */
-       if (tsk->mm->context.has_pgste)
+       if (mm_has_pgste(tsk->mm))
                return 0;
 
        /* lets check if we are allowed to replace the mm */
index 74495a5ea02738f8cd90fa1536a7daefb0c88be9..f03338c2f0886bbb830973f15e4a929d19981e6d 100644 (file)
@@ -161,7 +161,7 @@ config ARCH_HAS_CPU_IDLE_WAIT
 
 config NO_IOPORT
        def_bool !PCI
-       depends on !SH_CAYMAN && !SH_SH4202_MICRODEV
+       depends on !SH_CAYMAN && !SH_SH4202_MICRODEV && !SH_SHMIN
 
 config IO_TRAPPED
        bool
index 618bd566cf53bfe70b85b825072e0e7fa2b8aab5..969421f64a150a777b6a7f97e1d7b69aff4e1534 100644 (file)
@@ -359,37 +359,31 @@ static struct soc_camera_link camera_link = {
        .priv           = &camera_info,
 };
 
-static void dummy_release(struct device *dev)
+static struct platform_device *camera_device;
+
+static void ap325rxa_camera_release(struct device *dev)
 {
+       soc_camera_platform_release(&camera_device);
 }
 
-static struct platform_device camera_device = {
-       .name           = "soc_camera_platform",
-       .dev            = {
-               .platform_data  = &camera_info,
-               .release        = dummy_release,
-       },
-};
-
 static int ap325rxa_camera_add(struct soc_camera_link *icl,
                               struct device *dev)
 {
-       if (icl != &camera_link || camera_probe() <= 0)
-               return -ENODEV;
+       int ret = soc_camera_platform_add(icl, dev, &camera_device, &camera_link,
+                                         ap325rxa_camera_release, 0);
+       if (ret < 0)
+               return ret;
 
-       camera_info.dev = dev;
+       ret = camera_probe();
+       if (ret < 0)
+               soc_camera_platform_del(icl, camera_device, &camera_link);
 
-       return platform_device_register(&camera_device);
+       return ret;
 }
 
 static void ap325rxa_camera_del(struct soc_camera_link *icl)
 {
-       if (icl != &camera_link)
-               return;
-
-       platform_device_unregister(&camera_device);
-       memset(&camera_device.dev.kobj, 0,
-              sizeof(camera_device.dev.kobj));
+       soc_camera_platform_del(icl, camera_device, &camera_link);
 }
 #endif /* CONFIG_I2C */
 
index bb13d0e1b964cc912de97ff9579cd26ca72de3f2..3a32741cc0ac34ad7adde46b27ec3beb2d47adb2 100644 (file)
@@ -885,6 +885,9 @@ static struct platform_device sh_mmcif_device = {
        },
        .num_resources  = ARRAY_SIZE(sh_mmcif_resources),
        .resource       = sh_mmcif_resources,
+       .archdata = {
+               .hwblk_id = HWBLK_MMC,
+       },
 };
 #endif
 
index db85916b9e95aa8def960feff9b7b9ca1a5549f4..9210e93a92c337f18c94fd962bbeb5e23cfbb739 100644 (file)
@@ -18,6 +18,7 @@
 #include <asm/pgtable-2level.h>
 #endif
 #include <asm/page.h>
+#include <asm/mmu.h>
 
 #ifndef __ASSEMBLY__
 #include <asm/addrspace.h>
index 40725b4a80186a773cc4f72371cc77e9f3b0cd73..88bd6be168a9c3c4ceb1c2494930a858958473f1 100644 (file)
@@ -41,7 +41,9 @@
 
 #define user_mode(regs)                        (((regs)->sr & 0x40000000)==0)
 #define kernel_stack_pointer(_regs)    ((unsigned long)(_regs)->regs[15])
-#define GET_USP(regs) ((regs)->regs[15])
+
+#define GET_FP(regs)   ((regs)->regs[14])
+#define GET_USP(regs)  ((regs)->regs[15])
 
 extern void show_regs(struct pt_regs *);
 
@@ -131,7 +133,7 @@ extern void ptrace_triggered(struct perf_event *bp, int nmi,
 
 static inline unsigned long profile_pc(struct pt_regs *regs)
 {
-       unsigned long pc = instruction_pointer(regs);
+       unsigned long pc = regs->pc;
 
        if (virt_addr_uncached(pc))
                return CAC_ADDR(pc);
index 6c308d8b9a50a96335a170fb13aa8069f619782a..ec88bfcdf7ce57202e1402a03e491c01ef97af28 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/pagemap.h>
 
 #ifdef CONFIG_MMU
+#include <linux/swap.h>
 #include <asm/pgalloc.h>
 #include <asm/tlbflush.h>
 #include <asm/mmu_context.h>
index 7a5b8a331b4aa55f6d7141486fd6153491c4a4a6..bd0622788d64a83ccb7f57799cb16c3143360cc9 100644 (file)
@@ -236,6 +236,7 @@ enum {
 };
 
 enum {
+       SHDMA_SLAVE_INVALID,
        SHDMA_SLAVE_SCIF0_TX,
        SHDMA_SLAVE_SCIF0_RX,
        SHDMA_SLAVE_SCIF1_TX,
index 7eb435999426e1979a5127942a4686114626e724..3daef8ecbc635eaf47fe7eb6e63dd092d9125c11 100644 (file)
@@ -285,6 +285,7 @@ enum {
 };
 
 enum {
+       SHDMA_SLAVE_INVALID,
        SHDMA_SLAVE_SCIF0_TX,
        SHDMA_SLAVE_SCIF0_RX,
        SHDMA_SLAVE_SCIF1_TX,
index 05b8196c77539a647650311d9006a2d3e04b7c9e..41f9f8b9db735164fb9755d874f10576229968a5 100644 (file)
@@ -252,6 +252,7 @@ enum {
 };
 
 enum {
+       SHDMA_SLAVE_INVALID,
        SHDMA_SLAVE_SDHI_TX,
        SHDMA_SLAVE_SDHI_RX,
        SHDMA_SLAVE_MMCIF_TX,
index 762a13984bbd76c897963c10f6513809d0cc345f..b473f0c06fbc11bf545f66b84bd0a566fb344286 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/fs.h>
 #include <linux/ftrace.h>
 #include <linux/hw_breakpoint.h>
+#include <linux/prefetch.h>
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
 #include <asm/system.h>
index 40733a9524021d42d42ddc5a8d7e08ef77a1c155..f251b5f27652f3aa278c3789d198e88c841c3938 100644 (file)
@@ -82,7 +82,7 @@ void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
        void *addr;
 
        addr = __in_29bit_mode() ?
-              (void *)P1SEGADDR((unsigned long)vaddr) : vaddr;
+              (void *)CAC_ADDR((unsigned long)vaddr) : vaddr;
 
        switch (direction) {
        case DMA_FROM_DEVICE:           /* invalidate only */
index d3a303246c9f0967ff1ac86e9359eded8fae15da..e57dcce9bfda4da6ea6be362a542bf891289f0c0 100644 (file)
@@ -231,10 +231,6 @@ config PUV3_PWM
        help
          Enable support for NB0916 PWM controllers
 
-config PUV3_RTC
-       tristate "PKUnity v3 RTC Support"
-       depends on !ARCH_FPGA
-
 if PUV3_NB0916
 
 menu "PKUnity NetBook-0916 Features"
index 76a8beec7d03e454d49e9da70a6c6dbc734566ef..6af4bc415f2b34ec19fc024c1242a470a4feef73 100644 (file)
@@ -40,42 +40,10 @@ core-y                      += arch/unicore32/mm/
 
 libs-y                 += arch/unicore32/lib/
 
-ASM_GENERATED_DIR      := $(srctree)/arch/unicore32/include/generated
-LINUXINCLUDE           += -I$(ASM_GENERATED_DIR)
-
-ASM_GENERIC_HEADERS    := atomic.h auxvec.h
-ASM_GENERIC_HEADERS    += bitsperlong.h bug.h bugs.h
-ASM_GENERIC_HEADERS    += cputime.h current.h
-ASM_GENERIC_HEADERS    += device.h div64.h
-ASM_GENERIC_HEADERS    += emergency-restart.h errno.h
-ASM_GENERIC_HEADERS    += fb.h fcntl.h ftrace.h futex.h
-ASM_GENERIC_HEADERS    += hardirq.h hw_irq.h
-ASM_GENERIC_HEADERS    += ioctl.h ioctls.h ipcbuf.h irq_regs.h
-ASM_GENERIC_HEADERS    += kdebug.h kmap_types.h
-ASM_GENERIC_HEADERS    += local.h
-ASM_GENERIC_HEADERS    += mman.h module.h msgbuf.h
-ASM_GENERIC_HEADERS    += param.h parport.h percpu.h poll.h posix_types.h
-ASM_GENERIC_HEADERS    += resource.h
-ASM_GENERIC_HEADERS    += scatterlist.h sections.h segment.h sembuf.h serial.h
-ASM_GENERIC_HEADERS    += setup.h shmbuf.h shmparam.h
-ASM_GENERIC_HEADERS    += siginfo.h signal.h sizes.h
-ASM_GENERIC_HEADERS    += socket.h sockios.h stat.h statfs.h swab.h syscalls.h
-ASM_GENERIC_HEADERS    += termbits.h termios.h topology.h types.h
-ASM_GENERIC_HEADERS    += ucontext.h unaligned.h user.h
-ASM_GENERIC_HEADERS    += vga.h
-ASM_GENERIC_HEADERS    += xor.h
-
-archprepare:
-ifneq ($(ASM_GENERATED_DIR), $(wildcard $(ASM_GENERATED_DIR)))
-       $(Q)mkdir -p $(ASM_GENERATED_DIR)/asm
-       $(Q)$(foreach a, $(ASM_GENERIC_HEADERS),        \
-               echo '#include <asm-generic/$a>'        \
-                       > $(ASM_GENERATED_DIR)/asm/$a; )
-endif
-
 boot                   := arch/unicore32/boot
 
-# Default target when executing plain make
+# Default defconfig and target when executing plain make
+KBUILD_DEFCONFIG       := $(ARCH)_defconfig
 KBUILD_IMAGE           := zImage
 
 all:   $(KBUILD_IMAGE)
@@ -83,8 +51,6 @@ all:  $(KBUILD_IMAGE)
 zImage Image uImage: vmlinux
        $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
 
-MRPROPER_DIRS          += $(ASM_GENERATED_DIR)
-
 archclean:
        $(Q)$(MAKE) $(clean)=$(boot)
 
index 95373428cb3d846029312a737669c5a522895c8e..b0954a2d23cfaf5b4db0bbe1b6e95493d75ebc03 100644 (file)
@@ -59,7 +59,7 @@ $(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/head.o $(obj)/piggy.o \
 # We now have a PIC decompressor implementation.  Decompressors running
 # from RAM should not define ZTEXTADDR.  Decompressors running directly
 # from ROM or Flash must define ZTEXTADDR (preferably via the config)
-ZTEXTADDR      := 0
+ZTEXTADDR      := 0x03000000
 ZBSSADDR       := ALIGN(4)
 
 SEDFLAGS_lds   = s/TEXT_START/$(ZTEXTADDR)/;s/BSS_START/$(ZBSSADDR)/
diff --git a/arch/unicore32/configs/debug_defconfig b/arch/unicore32/configs/debug_defconfig
deleted file mode 100644 (file)
index b5fbde9..0000000
+++ /dev/null
@@ -1,215 +0,0 @@
-### General setup
-CONFIG_EXPERIMENTAL=y
-CONFIG_LOCALVERSION="-debug"
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_HOTPLUG=y
-#      Initial RAM filesystem and RAM disk (initramfs/initrd) support
-#CONFIG_BLK_DEV_INITRD=y
-#CONFIG_INITRAMFS_SOURCE="arch/unicore/ramfs/ramfs_config"
-
-### Enable loadable module support
-CONFIG_MODULES=n
-CONFIG_MODULE_UNLOAD=y
-
-### System Type
-CONFIG_ARCH_PUV3=y
-#      Board Selection
-CONFIG_PUV3_NB0916=y
-#      Processor Features
-CONFIG_CPU_DCACHE_LINE_DISABLE=y
-CONFIG_CPU_TLB_SINGLE_ENTRY_DISABLE=n
-
-### Bus support
-CONFIG_PCI=y
-CONFIG_PCI_LEGACY=n
-
-### Boot options
-#      for debug, adding: earlyprintk=ocd,keep initcall_debug
-#      others support: test_suspend=mem root=/dev/sda
-#      hibernate support: resume=/dev/sda3
-CONFIG_CMDLINE="earlyprintk=ocd,keep ignore_loglevel"
-# TODO: mem=512M video=unifb:1024x600-16@75
-# for nfs: root=/dev/nfs rw nfsroot=192.168.10.88:/home/udb/nfs/,rsize=1024,wsize=1024
-#      ip=192.168.10.83:192.168.10.88:192.168.10.1:255.255.255.0::eth0:off
-CONFIG_CMDLINE_FORCE=y
-
-### Power management options
-CONFIG_PM=y
-CONFIG_HIBERNATION=y
-CONFIG_PM_STD_PARTITION="/dev/sda3"
-CONFIG_CPU_FREQ=n
-CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
-
-### Networking support
-CONFIG_NET=y
-#      Networking options
-CONFIG_PACKET=m
-CONFIG_UNIX=m
-#      TCP/IP networking
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_PNP=y
-CONFIG_IPV6=n
-#      Wireless
-CONFIG_WIRELESS=y
-CONFIG_WIRELESS_EXT=y
-CONFIG_MAC80211=m
-
-### PKUnity SoC Features
-CONFIG_USB_WLAN_HED_AQ3=n
-CONFIG_USB_CMMB_INNOFIDEI=n
-CONFIG_I2C_BATTERY_BQ27200=n
-CONFIG_I2C_EEPROM_AT24=n
-CONFIG_LCD_BACKLIGHT=n
-
-CONFIG_PUV3_RTC=y
-CONFIG_PUV3_UMAL=y
-CONFIG_PUV3_MUSB=n
-CONFIG_PUV3_AC97=n
-CONFIG_PUV3_NAND=n
-CONFIG_PUV3_MMC=n
-CONFIG_PUV3_UART=n
-
-### Device Drivers
-#      Memory Technology Device (MTD) support
-CONFIG_MTD=m
-CONFIG_MTD_UBI=m
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CHAR=m
-CONFIG_MTD_BLKDEVS=m
-#      RAM/ROM/Flash chip drivers
-CONFIG_MTD_CFI=m
-CONFIG_MTD_JEDECPROBE=m
-CONFIG_MTD_CFI_AMDSTD=m
-#      Mapping drivers for chip access
-CONFIG_MTD_PHYSMAP=m
-
-#      Block devices
-CONFIG_BLK_DEV_LOOP=m
-
-#      SCSI device support
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_BLK_DEV_SR=m
-CONFIG_CHR_DEV_SG=m
-
-#      Serial ATA (prod) and Parallel ATA (experimental) drivers
-CONFIG_ATA=y
-CONFIG_SATA_VIA=y
-
-#      Network device support
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_NETDEV_1000=y
-#      Wireless LAN
-CONFIG_WLAN_80211=n
-CONFIG_RT2X00=n
-CONFIG_RT73USB=n
-
-#      Input device support
-CONFIG_INPUT_EVDEV=m
-#      Keyboards
-CONFIG_KEYBOARD_GPIO=m
-
-#      I2C support
-CONFIG_I2C=y
-CONFIG_I2C_PUV3=y
-
-#      Hardware Monitoring support
-#CONFIG_SENSORS_LM75=m
-#      Generic Thermal sysfs driver
-#CONFIG_THERMAL=m
-#CONFIG_THERMAL_HWMON=y
-
-#      Multimedia support
-CONFIG_MEDIA_SUPPORT=n
-CONFIG_VIDEO_DEV=n
-CONFIG_USB_VIDEO_CLASS=n
-
-#      Graphics support
-CONFIG_FB=y
-CONFIG_FB_PUV3_UNIGFX=y
-#      Console display driver support
-CONFIG_VGA_CONSOLE=n
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_FONTS=y
-CONFIG_FONT_8x8=y
-CONFIG_FONT_8x16=y
-#      Bootup logo
-CONFIG_LOGO=n
-
-#      Sound card support
-CONFIG_SOUND=m
-#      Advanced Linux Sound Architecture
-CONFIG_SND=m
-CONFIG_SND_MIXER_OSS=m
-CONFIG_SND_PCM_OSS=m
-
-#      USB support
-CONFIG_USB_ARCH_HAS_HCD=n
-CONFIG_USB=n
-CONFIG_USB_DEVICEFS=n
-CONFIG_USB_PRINTER=n
-CONFIG_USB_STORAGE=n
-#      Inventra Highspeed Dual Role Controller
-CONFIG_USB_MUSB_HDRC=n
-
-#      LED Support
-CONFIG_NEW_LEDS=y
-CONFIG_LEDS_CLASS=y
-CONFIG_LEDS_GPIO=y
-#      LED Triggers
-CONFIG_LEDS_TRIGGERS=y
-CONFIG_LEDS_TRIGGER_TIMER=y
-CONFIG_LEDS_TRIGGER_IDE_DISK=y
-CONFIG_LEDS_TRIGGER_HEARTBEAT=y
-
-#      Real Time Clock
-CONFIG_RTC_LIB=m
-CONFIG_RTC_CLASS=m
-
-### File systems
-CONFIG_EXT2_FS=m
-CONFIG_EXT3_FS=y
-CONFIG_EXT4_FS=y
-CONFIG_FUSE_FS=m
-#      CD-ROM/DVD Filesystems
-CONFIG_ISO9660_FS=m
-CONFIG_JOLIET=y
-CONFIG_UDF_FS=m
-#      DOS/FAT/NT Filesystems
-CONFIG_VFAT_FS=m
-#      Pseudo filesystems
-CONFIG_PROC_FS=y
-CONFIG_SYSFS=y
-CONFIG_TMPFS=y
-#      Miscellaneous filesystems
-CONFIG_MISC_FILESYSTEMS=y
-CONFIG_JFFS2_FS=m
-CONFIG_UBIFS_FS=m
-#      Network File Systems
-CONFIG_NETWORK_FILESYSTEMS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_ROOT_NFS=y
-#      Partition Types
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_MSDOS_PARTITION=y
-#      Native language support
-CONFIG_NLS=y
-CONFIG_NLS_CODEPAGE_437=m
-CONFIG_NLS_CODEPAGE_936=m
-CONFIG_NLS_ISO8859_1=m
-CONFIG_NLS_UTF8=m
-
-### Kernel hacking
-CONFIG_FRAME_WARN=8096
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_PROVE_LOCKING=n
-CONFIG_DEBUG_BUGVERBOSE=y
-CONFIG_FRAME_POINTER=y
-CONFIG_DEBUG_LL=y
-
diff --git a/arch/unicore32/configs/unicore32_defconfig b/arch/unicore32/configs/unicore32_defconfig
new file mode 100644 (file)
index 0000000..c9dd319
--- /dev/null
@@ -0,0 +1,215 @@
+### General setup
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCALVERSION="-unicore32"
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_HOTPLUG=y
+#      Initial RAM filesystem and RAM disk (initramfs/initrd) support
+#CONFIG_BLK_DEV_INITRD=y
+#CONFIG_INITRAMFS_SOURCE="arch/unicore/ramfs/ramfs_config"
+
+### Enable loadable module support
+CONFIG_MODULES=n
+CONFIG_MODULE_UNLOAD=y
+
+### System Type
+CONFIG_ARCH_PUV3=y
+#      Board Selection
+CONFIG_PUV3_NB0916=y
+#      Processor Features
+CONFIG_CPU_DCACHE_LINE_DISABLE=y
+CONFIG_CPU_TLB_SINGLE_ENTRY_DISABLE=n
+
+### Bus support
+CONFIG_PCI=y
+CONFIG_PCI_LEGACY=n
+
+### Boot options
+#      for debug, adding: earlyprintk=ocd,keep initcall_debug
+#      others support: test_suspend=mem root=/dev/sda
+#      hibernate support: resume=/dev/sda3
+CONFIG_CMDLINE="earlyprintk=ocd,keep ignore_loglevel"
+# TODO: mem=512M video=unifb:1024x600-16@75
+# for nfs: root=/dev/nfs rw nfsroot=192.168.10.88:/home/udb/nfs/,rsize=1024,wsize=1024
+#      ip=192.168.10.83:192.168.10.88:192.168.10.1:255.255.255.0::eth0:off
+CONFIG_CMDLINE_FORCE=y
+
+### Power management options
+CONFIG_PM=y
+CONFIG_HIBERNATION=y
+CONFIG_PM_STD_PARTITION="/dev/sda3"
+CONFIG_CPU_FREQ=n
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+
+### Networking support
+CONFIG_NET=y
+#      Networking options
+CONFIG_PACKET=m
+CONFIG_UNIX=m
+#      TCP/IP networking
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IPV6=n
+#      Wireless
+CONFIG_WIRELESS=y
+CONFIG_WIRELESS_EXT=y
+CONFIG_MAC80211=m
+
+### PKUnity SoC Features
+CONFIG_USB_WLAN_HED_AQ3=n
+CONFIG_USB_CMMB_INNOFIDEI=n
+CONFIG_I2C_BATTERY_BQ27200=n
+CONFIG_I2C_EEPROM_AT24=n
+CONFIG_LCD_BACKLIGHT=n
+
+CONFIG_PUV3_UMAL=y
+CONFIG_PUV3_MUSB=n
+CONFIG_PUV3_AC97=n
+CONFIG_PUV3_NAND=n
+CONFIG_PUV3_MMC=n
+CONFIG_PUV3_UART=n
+
+### Device Drivers
+#      Memory Technology Device (MTD) support
+CONFIG_MTD=m
+CONFIG_MTD_UBI=m
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLKDEVS=m
+#      RAM/ROM/Flash chip drivers
+CONFIG_MTD_CFI=m
+CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_CFI_AMDSTD=m
+#      Mapping drivers for chip access
+CONFIG_MTD_PHYSMAP=m
+
+#      Block devices
+CONFIG_BLK_DEV_LOOP=m
+
+#      SCSI device support
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_DEV_SR=m
+CONFIG_CHR_DEV_SG=m
+
+#      Serial ATA (prod) and Parallel ATA (experimental) drivers
+CONFIG_ATA=y
+CONFIG_SATA_VIA=y
+
+#      Network device support
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_NETDEV_1000=y
+#      Wireless LAN
+CONFIG_WLAN_80211=n
+CONFIG_RT2X00=n
+CONFIG_RT73USB=n
+
+#      Input device support
+CONFIG_INPUT_EVDEV=m
+#      Keyboards
+CONFIG_KEYBOARD_GPIO=m
+
+#      I2C support
+CONFIG_I2C=y
+CONFIG_I2C_PUV3=y
+
+#      Hardware Monitoring support
+#CONFIG_SENSORS_LM75=m
+#      Generic Thermal sysfs driver
+#CONFIG_THERMAL=m
+#CONFIG_THERMAL_HWMON=y
+
+#      Multimedia support
+CONFIG_MEDIA_SUPPORT=n
+CONFIG_VIDEO_DEV=n
+CONFIG_USB_VIDEO_CLASS=n
+
+#      Graphics support
+CONFIG_FB=y
+CONFIG_FB_PUV3_UNIGFX=y
+#      Console display driver support
+CONFIG_VGA_CONSOLE=n
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+#      Bootup logo
+CONFIG_LOGO=n
+
+#      Sound card support
+CONFIG_SOUND=m
+#      Advanced Linux Sound Architecture
+CONFIG_SND=m
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+
+#      USB support
+CONFIG_USB_ARCH_HAS_HCD=n
+CONFIG_USB=n
+CONFIG_USB_DEVICEFS=n
+CONFIG_USB_PRINTER=n
+CONFIG_USB_STORAGE=n
+#      Inventra Highspeed Dual Role Controller
+CONFIG_USB_MUSB_HDRC=n
+
+#      LED Support
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+#      LED Triggers
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_IDE_DISK=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+
+#      Real Time Clock
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_PUV3=y
+
+### File systems
+CONFIG_EXT2_FS=m
+CONFIG_EXT3_FS=y
+CONFIG_EXT4_FS=y
+CONFIG_FUSE_FS=m
+#      CD-ROM/DVD Filesystems
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_UDF_FS=m
+#      DOS/FAT/NT Filesystems
+CONFIG_VFAT_FS=m
+#      Pseudo filesystems
+CONFIG_PROC_FS=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+#      Miscellaneous filesystems
+CONFIG_MISC_FILESYSTEMS=y
+CONFIG_JFFS2_FS=m
+CONFIG_UBIFS_FS=m
+#      Network File Systems
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+#      Partition Types
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_MSDOS_PARTITION=y
+#      Native language support
+CONFIG_NLS=y
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_UTF8=m
+
+### Kernel hacking
+CONFIG_FRAME_WARN=8096
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_PROVE_LOCKING=n
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_LL=y
+
index b200fdaca44de8061175e02d95c47c58489abc0b..ca113d6999c5279df35ad1d47a275ace8fd18463 100644 (file)
@@ -1,2 +1,61 @@
 include include/asm-generic/Kbuild.asm
 
+generic-y += atomic.h
+generic-y += auxvec.h
+generic-y += bitsperlong.h
+generic-y += bug.h
+generic-y += bugs.h
+generic-y += cputime.h
+generic-y += current.h
+generic-y += device.h
+generic-y += div64.h
+generic-y += emergency-restart.h
+generic-y += errno.h
+generic-y += fb.h
+generic-y += fcntl.h
+generic-y += ftrace.h
+generic-y += futex.h
+generic-y += hardirq.h
+generic-y += hw_irq.h
+generic-y += ioctl.h
+generic-y += ioctls.h
+generic-y += ipcbuf.h
+generic-y += irq_regs.h
+generic-y += kdebug.h
+generic-y += kmap_types.h
+generic-y += local.h
+generic-y += mman.h
+generic-y += module.h
+generic-y += msgbuf.h
+generic-y += param.h
+generic-y += parport.h
+generic-y += percpu.h
+generic-y += poll.h
+generic-y += posix_types.h
+generic-y += resource.h
+generic-y += scatterlist.h
+generic-y += sections.h
+generic-y += segment.h
+generic-y += sembuf.h
+generic-y += serial.h
+generic-y += setup.h
+generic-y += shmbuf.h
+generic-y += shmparam.h
+generic-y += siginfo.h
+generic-y += signal.h
+generic-y += sizes.h
+generic-y += socket.h
+generic-y += sockios.h
+generic-y += stat.h
+generic-y += statfs.h
+generic-y += swab.h
+generic-y += syscalls.h
+generic-y += termbits.h
+generic-y += termios.h
+generic-y += topology.h
+generic-y += types.h
+generic-y += ucontext.h
+generic-y += unaligned.h
+generic-y += user.h
+generic-y += vga.h
+generic-y += xor.h
index ec23a2fb2f508646d38c76ce7bbd89ed20bc8168..aeb0f181568e39f5537f70d7078163c09f29c2cb 100644 (file)
@@ -16,7 +16,6 @@ obj-$(CONFIG_UNICORE_FPU_F64) += fpu-ucf64.o
 obj-$(CONFIG_ARCH_PUV3)                += clock.o irq.o time.o
 
 obj-$(CONFIG_PUV3_GPIO)                += gpio.o
-obj-$(CONFIG_PUV3_RTC)         += rtc.o
 obj-$(CONFIG_PUV3_PWM)         += pwm.o
 obj-$(CONFIG_PUV3_PM)          += pm.o sleep.o
 obj-$(CONFIG_HIBERNATION)      += hibernate.o hibernate_asm.o
diff --git a/arch/unicore32/kernel/rtc.c b/arch/unicore32/kernel/rtc.c
deleted file mode 100644 (file)
index 8cad70b..0000000
+++ /dev/null
@@ -1,371 +0,0 @@
-/*
- * linux/arch/unicore32/kernel/rtc.c
- *
- * Code specific to PKUnity SoC and UniCore ISA
- *
- *     Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn>
- *     Copyright (C) 2001-2010 Guan Xuetao
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/rtc.h>
-#include <linux/bcd.h>
-#include <linux/clk.h>
-#include <linux/log2.h>
-#include <linux/slab.h>
-#include <linux/uaccess.h>
-#include <linux/io.h>
-
-#include <asm/irq.h>
-#include <mach/hardware.h>
-
-static struct resource *puv3_rtc_mem;
-
-static int puv3_rtc_alarmno = IRQ_RTCAlarm;
-static int puv3_rtc_tickno  = IRQ_RTC;
-
-static DEFINE_SPINLOCK(puv3_rtc_pie_lock);
-
-/* IRQ Handlers */
-
-static irqreturn_t puv3_rtc_alarmirq(int irq, void *id)
-{
-       struct rtc_device *rdev = id;
-
-       writel(readl(RTC_RTSR) | RTC_RTSR_AL, RTC_RTSR);
-       rtc_update_irq(rdev, 1, RTC_AF | RTC_IRQF);
-       return IRQ_HANDLED;
-}
-
-static irqreturn_t puv3_rtc_tickirq(int irq, void *id)
-{
-       struct rtc_device *rdev = id;
-
-       writel(readl(RTC_RTSR) | RTC_RTSR_HZ, RTC_RTSR);
-       rtc_update_irq(rdev, 1, RTC_PF | RTC_IRQF);
-       return IRQ_HANDLED;
-}
-
-/* Update control registers */
-static void puv3_rtc_setaie(int to)
-{
-       unsigned int tmp;
-
-       pr_debug("%s: aie=%d\n", __func__, to);
-
-       tmp = readl(RTC_RTSR) & ~RTC_RTSR_ALE;
-
-       if (to)
-               tmp |= RTC_RTSR_ALE;
-
-       writel(tmp, RTC_RTSR);
-}
-
-static int puv3_rtc_setpie(struct device *dev, int enabled)
-{
-       unsigned int tmp;
-
-       pr_debug("%s: pie=%d\n", __func__, enabled);
-
-       spin_lock_irq(&puv3_rtc_pie_lock);
-       tmp = readl(RTC_RTSR) & ~RTC_RTSR_HZE;
-
-       if (enabled)
-               tmp |= RTC_RTSR_HZE;
-
-       writel(tmp, RTC_RTSR);
-       spin_unlock_irq(&puv3_rtc_pie_lock);
-
-       return 0;
-}
-
-/* Time read/write */
-
-static int puv3_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
-{
-       rtc_time_to_tm(readl(RTC_RCNR), rtc_tm);
-
-       pr_debug("read time %02x.%02x.%02x %02x/%02x/%02x\n",
-                rtc_tm->tm_year, rtc_tm->tm_mon, rtc_tm->tm_mday,
-                rtc_tm->tm_hour, rtc_tm->tm_min, rtc_tm->tm_sec);
-
-       return 0;
-}
-
-static int puv3_rtc_settime(struct device *dev, struct rtc_time *tm)
-{
-       unsigned long rtc_count = 0;
-
-       pr_debug("set time %02d.%02d.%02d %02d/%02d/%02d\n",
-                tm->tm_year, tm->tm_mon, tm->tm_mday,
-                tm->tm_hour, tm->tm_min, tm->tm_sec);
-
-       rtc_tm_to_time(tm, &rtc_count);
-       writel(rtc_count, RTC_RCNR);
-
-       return 0;
-}
-
-static int puv3_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm)
-{
-       struct rtc_time *alm_tm = &alrm->time;
-
-       rtc_time_to_tm(readl(RTC_RTAR), alm_tm);
-
-       alrm->enabled = readl(RTC_RTSR) & RTC_RTSR_ALE;
-
-       pr_debug("read alarm %02x %02x.%02x.%02x %02x/%02x/%02x\n",
-                alrm->enabled,
-                alm_tm->tm_year, alm_tm->tm_mon, alm_tm->tm_mday,
-                alm_tm->tm_hour, alm_tm->tm_min, alm_tm->tm_sec);
-
-       return 0;
-}
-
-static int puv3_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
-{
-       struct rtc_time *tm = &alrm->time;
-       unsigned long rtcalarm_count = 0;
-
-       pr_debug("puv3_rtc_setalarm: %d, %02x/%02x/%02x %02x.%02x.%02x\n",
-                alrm->enabled,
-                tm->tm_mday & 0xff, tm->tm_mon & 0xff, tm->tm_year & 0xff,
-                tm->tm_hour & 0xff, tm->tm_min & 0xff, tm->tm_sec);
-
-       rtc_tm_to_time(tm, &rtcalarm_count);
-       writel(rtcalarm_count, RTC_RTAR);
-
-       puv3_rtc_setaie(alrm->enabled);
-
-       if (alrm->enabled)
-               enable_irq_wake(puv3_rtc_alarmno);
-       else
-               disable_irq_wake(puv3_rtc_alarmno);
-
-       return 0;
-}
-
-static int puv3_rtc_proc(struct device *dev, struct seq_file *seq)
-{
-       seq_printf(seq, "periodic_IRQ\t: %s\n",
-                    (readl(RTC_RTSR) & RTC_RTSR_HZE) ? "yes" : "no");
-       return 0;
-}
-
-static int puv3_rtc_open(struct device *dev)
-{
-       struct platform_device *pdev = to_platform_device(dev);
-       struct rtc_device *rtc_dev = platform_get_drvdata(pdev);
-       int ret;
-
-       ret = request_irq(puv3_rtc_alarmno, puv3_rtc_alarmirq,
-                         IRQF_DISABLED,  "pkunity-rtc alarm", rtc_dev);
-
-       if (ret) {
-               dev_err(dev, "IRQ%d error %d\n", puv3_rtc_alarmno, ret);
-               return ret;
-       }
-
-       ret = request_irq(puv3_rtc_tickno, puv3_rtc_tickirq,
-                         IRQF_DISABLED,  "pkunity-rtc tick", rtc_dev);
-
-       if (ret) {
-               dev_err(dev, "IRQ%d error %d\n", puv3_rtc_tickno, ret);
-               goto tick_err;
-       }
-
-       return ret;
-
- tick_err:
-       free_irq(puv3_rtc_alarmno, rtc_dev);
-       return ret;
-}
-
-static void puv3_rtc_release(struct device *dev)
-{
-       struct platform_device *pdev = to_platform_device(dev);
-       struct rtc_device *rtc_dev = platform_get_drvdata(pdev);
-
-       /* do not clear AIE here, it may be needed for wake */
-
-       puv3_rtc_setpie(dev, 0);
-       free_irq(puv3_rtc_alarmno, rtc_dev);
-       free_irq(puv3_rtc_tickno, rtc_dev);
-}
-
-static const struct rtc_class_ops puv3_rtcops = {
-       .open           = puv3_rtc_open,
-       .release        = puv3_rtc_release,
-       .read_time      = puv3_rtc_gettime,
-       .set_time       = puv3_rtc_settime,
-       .read_alarm     = puv3_rtc_getalarm,
-       .set_alarm      = puv3_rtc_setalarm,
-       .proc           = puv3_rtc_proc,
-};
-
-static void puv3_rtc_enable(struct platform_device *pdev, int en)
-{
-       if (!en) {
-               writel(readl(RTC_RTSR) & ~RTC_RTSR_HZE, RTC_RTSR);
-       } else {
-               /* re-enable the device, and check it is ok */
-
-               if ((readl(RTC_RTSR) & RTC_RTSR_HZE) == 0) {
-                       dev_info(&pdev->dev, "rtc disabled, re-enabling\n");
-                       writel(readl(RTC_RTSR) | RTC_RTSR_HZE, RTC_RTSR);
-               }
-       }
-}
-
-static int puv3_rtc_remove(struct platform_device *dev)
-{
-       struct rtc_device *rtc = platform_get_drvdata(dev);
-
-       platform_set_drvdata(dev, NULL);
-       rtc_device_unregister(rtc);
-
-       puv3_rtc_setpie(&dev->dev, 0);
-       puv3_rtc_setaie(0);
-
-       release_resource(puv3_rtc_mem);
-       kfree(puv3_rtc_mem);
-
-       return 0;
-}
-
-static int puv3_rtc_probe(struct platform_device *pdev)
-{
-       struct rtc_device *rtc;
-       struct resource *res;
-       int ret;
-
-       pr_debug("%s: probe=%p\n", __func__, pdev);
-
-       /* find the IRQs */
-
-       puv3_rtc_tickno = platform_get_irq(pdev, 1);
-       if (puv3_rtc_tickno < 0) {
-               dev_err(&pdev->dev, "no irq for rtc tick\n");
-               return -ENOENT;
-       }
-
-       puv3_rtc_alarmno = platform_get_irq(pdev, 0);
-       if (puv3_rtc_alarmno < 0) {
-               dev_err(&pdev->dev, "no irq for alarm\n");
-               return -ENOENT;
-       }
-
-       pr_debug("PKUnity_rtc: tick irq %d, alarm irq %d\n",
-                puv3_rtc_tickno, puv3_rtc_alarmno);
-
-       /* get the memory region */
-
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (res == NULL) {
-               dev_err(&pdev->dev, "failed to get memory region resource\n");
-               return -ENOENT;
-       }
-
-       puv3_rtc_mem = request_mem_region(res->start,
-                                        res->end-res->start+1,
-                                        pdev->name);
-
-       if (puv3_rtc_mem == NULL) {
-               dev_err(&pdev->dev, "failed to reserve memory region\n");
-               ret = -ENOENT;
-               goto err_nores;
-       }
-
-       puv3_rtc_enable(pdev, 1);
-
-       /* register RTC and exit */
-
-       rtc = rtc_device_register("pkunity", &pdev->dev, &puv3_rtcops,
-                                 THIS_MODULE);
-
-       if (IS_ERR(rtc)) {
-               dev_err(&pdev->dev, "cannot attach rtc\n");
-               ret = PTR_ERR(rtc);
-               goto err_nortc;
-       }
-
-       /* platform setup code should have handled this; sigh */
-       if (!device_can_wakeup(&pdev->dev))
-               device_init_wakeup(&pdev->dev, 1);
-
-       platform_set_drvdata(pdev, rtc);
-       return 0;
-
- err_nortc:
-       puv3_rtc_enable(pdev, 0);
-       release_resource(puv3_rtc_mem);
-
- err_nores:
-       return ret;
-}
-
-#ifdef CONFIG_PM
-
-/* RTC Power management control */
-
-static int ticnt_save;
-
-static int puv3_rtc_suspend(struct platform_device *pdev, pm_message_t state)
-{
-       /* save RTAR for anyone using periodic interrupts */
-       ticnt_save = readl(RTC_RTAR);
-       puv3_rtc_enable(pdev, 0);
-       return 0;
-}
-
-static int puv3_rtc_resume(struct platform_device *pdev)
-{
-       puv3_rtc_enable(pdev, 1);
-       writel(ticnt_save, RTC_RTAR);
-       return 0;
-}
-#else
-#define puv3_rtc_suspend NULL
-#define puv3_rtc_resume  NULL
-#endif
-
-static struct platform_driver puv3_rtcdrv = {
-       .probe          = puv3_rtc_probe,
-       .remove         = __devexit_p(puv3_rtc_remove),
-       .suspend        = puv3_rtc_suspend,
-       .resume         = puv3_rtc_resume,
-       .driver         = {
-               .name   = "PKUnity-v3-RTC",
-               .owner  = THIS_MODULE,
-       }
-};
-
-static char __initdata banner[] = "PKUnity-v3 RTC, (c) 2009 PKUnity Co.\n";
-
-static int __init puv3_rtc_init(void)
-{
-       printk(banner);
-       return platform_driver_register(&puv3_rtcdrv);
-}
-
-static void __exit puv3_rtc_exit(void)
-{
-       platform_driver_unregister(&puv3_rtcdrv);
-}
-
-module_init(puv3_rtc_init);
-module_exit(puv3_rtc_exit);
-
-MODULE_DESCRIPTION("RTC Driver for the PKUnity v3 chip");
-MODULE_AUTHOR("Hu Dongliang");
-MODULE_LICENSE("GPL v2");
-
index 9bf7f7af52c529f10566dbf8a9a816ecf0b65567..77e407e49a632c84cfb4957580c13dfbbebd1df4 100644 (file)
@@ -30,7 +30,7 @@ SECTIONS
        HEAD_TEXT_SECTION
        INIT_TEXT_SECTION(PAGE_SIZE)
        INIT_DATA_SECTION(16)
-       PERCPU(L1_CACHE_BYTES, PAGE_SIZE)
+       PERCPU_SECTION(L1_CACHE_BYTES)
        __init_end = .;
 
        _stext = .;
index f5abe3a245b84ce698472051d873b33f882a9d97..90b06d4daee252e758f72af1d4566c5c58fbd5a6 100644 (file)
@@ -8,6 +8,7 @@ CPPFLAGS_vmlinux.lds += -U$(UTS_MACHINE)
 
 ifdef CONFIG_FUNCTION_TRACER
 # Do not profile debug and lowlevel utilities
+CFLAGS_REMOVE_tsc.o = -pg
 CFLAGS_REMOVE_rtc.o = -pg
 CFLAGS_REMOVE_paravirt-spinlocks.o = -pg
 CFLAGS_REMOVE_pvclock.o = -pg
@@ -28,6 +29,7 @@ CFLAGS_paravirt.o     := $(nostackp)
 GCOV_PROFILE_vsyscall_64.o     := n
 GCOV_PROFILE_hpet.o            := n
 GCOV_PROFILE_tsc.o             := n
+GCOV_PROFILE_vread_tsc_64.o    := n
 GCOV_PROFILE_paravirt.o                := n
 
 # vread_tsc_64 is hot and should be fully optimized:
index cd8cbeb5fa34f4ed685d9247995846e4c2d0fd32..7c3a95e54ec57cae2f9dd96a831bc5b7f53a6f69 100644 (file)
@@ -30,6 +30,7 @@
 #include <asm/proto.h>
 #include <asm/iommu.h>
 #include <asm/gart.h>
+#include <asm/dma.h>
 #include <asm/amd_iommu_proto.h>
 #include <asm/amd_iommu_types.h>
 #include <asm/amd_iommu.h>
@@ -154,6 +155,10 @@ static int iommu_init_device(struct device *dev)
        pdev = pci_get_bus_and_slot(PCI_BUS(alias), alias & 0xff);
        if (pdev)
                dev_data->alias = &pdev->dev;
+       else {
+               kfree(dev_data);
+               return -ENOTSUPP;
+       }
 
        atomic_set(&dev_data->bind, 0);
 
@@ -163,6 +168,20 @@ static int iommu_init_device(struct device *dev)
        return 0;
 }
 
+static void iommu_ignore_device(struct device *dev)
+{
+       u16 devid, alias;
+
+       devid = get_device_id(dev);
+       alias = amd_iommu_alias_table[devid];
+
+       memset(&amd_iommu_dev_table[devid], 0, sizeof(struct dev_table_entry));
+       memset(&amd_iommu_dev_table[alias], 0, sizeof(struct dev_table_entry));
+
+       amd_iommu_rlookup_table[devid] = NULL;
+       amd_iommu_rlookup_table[alias] = NULL;
+}
+
 static void iommu_uninit_device(struct device *dev)
 {
        kfree(dev->archdata.iommu);
@@ -192,7 +211,9 @@ int __init amd_iommu_init_devices(void)
                        continue;
 
                ret = iommu_init_device(&pdev->dev);
-               if (ret)
+               if (ret == -ENOTSUPP)
+                       iommu_ignore_device(&pdev->dev);
+               else if (ret)
                        goto out_free;
        }
 
@@ -2383,6 +2404,23 @@ static struct dma_map_ops amd_iommu_dma_ops = {
        .dma_supported = amd_iommu_dma_supported,
 };
 
+static unsigned device_dma_ops_init(void)
+{
+       struct pci_dev *pdev = NULL;
+       unsigned unhandled = 0;
+
+       for_each_pci_dev(pdev) {
+               if (!check_device(&pdev->dev)) {
+                       unhandled += 1;
+                       continue;
+               }
+
+               pdev->dev.archdata.dma_ops = &amd_iommu_dma_ops;
+       }
+
+       return unhandled;
+}
+
 /*
  * The function which clues the AMD IOMMU driver into dma_ops.
  */
@@ -2395,7 +2433,7 @@ void __init amd_iommu_init_api(void)
 int __init amd_iommu_init_dma_ops(void)
 {
        struct amd_iommu *iommu;
-       int ret;
+       int ret, unhandled;
 
        /*
         * first allocate a default protection domain for every IOMMU we
@@ -2421,7 +2459,11 @@ int __init amd_iommu_init_dma_ops(void)
        swiotlb = 0;
 
        /* Make the driver finally visible to the drivers */
-       dma_ops = &amd_iommu_dma_ops;
+       unhandled = device_dma_ops_init();
+       if (unhandled && max_pfn > MAX_DMA32_PFN) {
+               /* There are unhandled devices - initialize swiotlb for them */
+               swiotlb = 1;
+       }
 
        amd_iommu_stats_init();
 
index 9179c21120a88ea5e764297fc5c91c6a488fb51c..bfc8453bd98dfae4bd62620e1ebd20a9151b9ea3 100644 (file)
@@ -731,8 +731,8 @@ static void __init init_iommu_from_acpi(struct amd_iommu *iommu,
 {
        u8 *p = (u8 *)h;
        u8 *end = p, flags = 0;
-       u16 dev_i, devid = 0, devid_start = 0, devid_to = 0;
-       u32 ext_flags = 0;
+       u16 devid = 0, devid_start = 0, devid_to = 0;
+       u32 dev_i, ext_flags = 0;
        bool alias = false;
        struct ivhd_entry *e;
 
@@ -887,7 +887,7 @@ static void __init init_iommu_from_acpi(struct amd_iommu *iommu,
 /* Initializes the device->iommu mapping for the driver */
 static int __init init_iommu_devices(struct amd_iommu *iommu)
 {
-       u16 i;
+       u32 i;
 
        for (i = iommu->first_device; i <= iommu->last_device; ++i)
                set_iommu_for_device(iommu, i);
@@ -1177,7 +1177,7 @@ static int __init init_memory_definitions(struct acpi_table_header *table)
  */
 static void init_device_table(void)
 {
-       u16 devid;
+       u32 devid;
 
        for (devid = 0; devid <= amd_iommu_last_bdf; ++devid) {
                set_dev_entry_bit(devid, DEV_ENTRY_VALID);
index 426a5b66f7e40a51caaf24932af01b7c36656a24..2e4928d45a2dd476d89904778df6ac2dbf5e681c 100644 (file)
@@ -642,7 +642,7 @@ static int __init idle_setup(char *str)
                boot_option_idle_override = IDLE_POLL;
        } else if (!strcmp(str, "mwait")) {
                boot_option_idle_override = IDLE_FORCE_MWAIT;
-               WARN_ONCE(1, "\idle=mwait\" will be removed in 2012\"\n");
+               WARN_ONCE(1, "\"idle=mwait\" will be removed in 2012\n");
        } else if (!strcmp(str, "halt")) {
                /*
                 * When the boot option of idle=halt is added, halt is
index 8d128783af47374e56412d01d0488aa12af1647b..a3d0dc59067be542d7423d2a8abbc99801c0d3f6 100644 (file)
@@ -245,7 +245,6 @@ start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp)
 {
        set_user_gs(regs, 0);
        regs->fs                = 0;
-       set_fs(USER_DS);
        regs->ds                = __USER_DS;
        regs->es                = __USER_DS;
        regs->ss                = __USER_DS;
index 6c9dd922ac0d8b34ff9cac883ef86bf8843cb912..ca6f7ab8df332992166d51c802216d350c8729cc 100644 (file)
@@ -338,7 +338,6 @@ start_thread_common(struct pt_regs *regs, unsigned long new_ip,
        regs->cs                = _cs;
        regs->ss                = _ss;
        regs->flags             = X86_EFLAGS_IF;
-       set_fs(USER_DS);
        /*
         * Free the old FP and other extended state
         */
index eefd96765e79a1c7ded62bd86c9d2c5da8c95062..33a0c11797de758004b399225eec21db5a1e932e 100644 (file)
@@ -1332,7 +1332,7 @@ static inline void mwait_play_dead(void)
        void *mwait_ptr;
        struct cpuinfo_x86 *c = __this_cpu_ptr(&cpu_info);
 
-       if (!this_cpu_has(X86_FEATURE_MWAIT) && mwait_usable(c))
+       if (!(this_cpu_has(X86_FEATURE_MWAIT) && mwait_usable(c)))
                return;
        if (!this_cpu_has(X86_FEATURE_CLFLSH))
                return;
index d6e2477feb180e3787b57758f3e0151eb4a3f0b6..6df88c7885c0e24bbbdfcad54682d52cbfb085fb 100644 (file)
 #define DstDI       (5<<1)     /* Destination is in ES:(E)DI */
 #define DstMem64    (6<<1)     /* 64bit memory operand */
 #define DstImmUByte (7<<1)     /* 8-bit unsigned immediate operand */
-#define DstMask     (7<<1)
+#define DstDX       (8<<1)     /* Destination is in DX register */
+#define DstMask     (0xf<<1)
 /* Source operand type. */
-#define SrcNone     (0<<4)     /* No source operand. */
-#define SrcReg      (1<<4)     /* Register operand. */
-#define SrcMem      (2<<4)     /* Memory operand. */
-#define SrcMem16    (3<<4)     /* Memory operand (16-bit). */
-#define SrcMem32    (4<<4)     /* Memory operand (32-bit). */
-#define SrcImm      (5<<4)     /* Immediate operand. */
-#define SrcImmByte  (6<<4)     /* 8-bit sign-extended immediate operand. */
-#define SrcOne      (7<<4)     /* Implied '1' */
-#define SrcImmUByte (8<<4)      /* 8-bit unsigned immediate operand. */
-#define SrcImmU     (9<<4)      /* Immediate operand, unsigned */
-#define SrcSI       (0xa<<4)   /* Source is in the DS:RSI */
-#define SrcImmFAddr (0xb<<4)   /* Source is immediate far address */
-#define SrcMemFAddr (0xc<<4)   /* Source is far address in memory */
-#define SrcAcc      (0xd<<4)   /* Source Accumulator */
-#define SrcImmU16   (0xe<<4)    /* Immediate operand, unsigned, 16 bits */
-#define SrcMask     (0xf<<4)
+#define SrcNone     (0<<5)     /* No source operand. */
+#define SrcReg      (1<<5)     /* Register operand. */
+#define SrcMem      (2<<5)     /* Memory operand. */
+#define SrcMem16    (3<<5)     /* Memory operand (16-bit). */
+#define SrcMem32    (4<<5)     /* Memory operand (32-bit). */
+#define SrcImm      (5<<5)     /* Immediate operand. */
+#define SrcImmByte  (6<<5)     /* 8-bit sign-extended immediate operand. */
+#define SrcOne      (7<<5)     /* Implied '1' */
+#define SrcImmUByte (8<<5)      /* 8-bit unsigned immediate operand. */
+#define SrcImmU     (9<<5)      /* Immediate operand, unsigned */
+#define SrcSI       (0xa<<5)   /* Source is in the DS:RSI */
+#define SrcImmFAddr (0xb<<5)   /* Source is immediate far address */
+#define SrcMemFAddr (0xc<<5)   /* Source is far address in memory */
+#define SrcAcc      (0xd<<5)   /* Source Accumulator */
+#define SrcImmU16   (0xe<<5)    /* Immediate operand, unsigned, 16 bits */
+#define SrcDX       (0xf<<5)   /* Source is in DX register */
+#define SrcMask     (0xf<<5)
 /* Generic ModRM decode. */
-#define ModRM       (1<<8)
+#define ModRM       (1<<9)
 /* Destination is only written; never read. */
-#define Mov         (1<<9)
-#define BitOp       (1<<10)
-#define MemAbs      (1<<11)      /* Memory operand is absolute displacement */
-#define String      (1<<12)     /* String instruction (rep capable) */
-#define Stack       (1<<13)     /* Stack instruction (push/pop) */
-#define GroupMask   (7<<14)     /* Opcode uses one of the group mechanisms */
-#define Group       (1<<14)     /* Bits 3:5 of modrm byte extend opcode */
-#define GroupDual   (2<<14)     /* Alternate decoding of mod == 3 */
-#define Prefix      (3<<14)     /* Instruction varies with 66/f2/f3 prefix */
-#define RMExt       (4<<14)     /* Opcode extension in ModRM r/m if mod == 3 */
-#define Sse         (1<<17)     /* SSE Vector instruction */
+#define Mov         (1<<10)
+#define BitOp       (1<<11)
+#define MemAbs      (1<<12)      /* Memory operand is absolute displacement */
+#define String      (1<<13)     /* String instruction (rep capable) */
+#define Stack       (1<<14)     /* Stack instruction (push/pop) */
+#define GroupMask   (7<<15)     /* Opcode uses one of the group mechanisms */
+#define Group       (1<<15)     /* Bits 3:5 of modrm byte extend opcode */
+#define GroupDual   (2<<15)     /* Alternate decoding of mod == 3 */
+#define Prefix      (3<<15)     /* Instruction varies with 66/f2/f3 prefix */
+#define RMExt       (4<<15)     /* Opcode extension in ModRM r/m if mod == 3 */
+#define Sse         (1<<18)     /* SSE Vector instruction */
 /* Misc flags */
 #define Prot        (1<<21) /* instruction generates #UD if not in prot-mode */
 #define VendorSpecific (1<<22) /* Vendor specific instruction */
@@ -3154,8 +3156,8 @@ static struct opcode opcode_table[256] = {
        I(DstReg | SrcMem | ModRM | Src2Imm, em_imul_3op),
        I(SrcImmByte | Mov | Stack, em_push),
        I(DstReg | SrcMem | ModRM | Src2ImmByte, em_imul_3op),
-       D2bvIP(DstDI | Mov | String, ins, check_perm_in), /* insb, insw/insd */
-       D2bvIP(SrcSI | ImplicitOps | String, outs, check_perm_out), /* outsb, outsw/outsd */
+       D2bvIP(DstDI | SrcDX | Mov | String, ins, check_perm_in), /* insb, insw/insd */
+       D2bvIP(SrcSI | DstDX | String, outs, check_perm_out), /* outsb, outsw/outsd */
        /* 0x70 - 0x7F */
        X16(D(SrcImmByte)),
        /* 0x80 - 0x87 */
@@ -3212,8 +3214,8 @@ static struct opcode opcode_table[256] = {
        /* 0xE8 - 0xEF */
        D(SrcImm | Stack), D(SrcImm | ImplicitOps),
        D(SrcImmFAddr | No64), D(SrcImmByte | ImplicitOps),
-       D2bvIP(SrcNone | DstAcc,     in,  check_perm_in),
-       D2bvIP(SrcAcc | ImplicitOps, out, check_perm_out),
+       D2bvIP(SrcDX | DstAcc, in,  check_perm_in),
+       D2bvIP(SrcAcc | DstDX, out, check_perm_out),
        /* 0xF0 - 0xF7 */
        N, DI(ImplicitOps, icebp), N, N,
        DI(ImplicitOps | Priv, hlt), D(ImplicitOps),
@@ -3613,6 +3615,12 @@ done_prefixes:
                memop.bytes = c->op_bytes + 2;
                goto srcmem_common;
                break;
+       case SrcDX:
+               c->src.type = OP_REG;
+               c->src.bytes = 2;
+               c->src.addr.reg = &c->regs[VCPU_REGS_RDX];
+               fetch_register_operand(&c->src);
+               break;
        }
 
        if (rc != X86EMUL_CONTINUE)
@@ -3682,6 +3690,12 @@ done_prefixes:
                c->dst.addr.mem.seg = VCPU_SREG_ES;
                c->dst.val = 0;
                break;
+       case DstDX:
+               c->dst.type = OP_REG;
+               c->dst.bytes = 2;
+               c->dst.addr.reg = &c->regs[VCPU_REGS_RDX];
+               fetch_register_operand(&c->dst);
+               break;
        case ImplicitOps:
                /* Special instructions do their own operand decoding. */
        default:
@@ -4027,7 +4041,6 @@ special_insn:
                break;
        case 0xec: /* in al,dx */
        case 0xed: /* in (e/r)ax,dx */
-               c->src.val = c->regs[VCPU_REGS_RDX];
        do_io_in:
                if (!pio_in_emulated(ctxt, ops, c->dst.bytes, c->src.val,
                                     &c->dst.val))
@@ -4035,7 +4048,6 @@ special_insn:
                break;
        case 0xee: /* out dx,al */
        case 0xef: /* out dx,(e/r)ax */
-               c->dst.val = c->regs[VCPU_REGS_RDX];
        do_io_out:
                ops->pio_out_emulated(ctxt, c->src.bytes, c->dst.val,
                                      &c->src.val, 1);
index e191c096ab90363228965e746a0f898d6f8a9451..db832fd65ecbf8d749720b449eed3fd2b8d55cab 100644 (file)
@@ -993,6 +993,7 @@ static void lguest_time_irq(unsigned int irq, struct irq_desc *desc)
 static void lguest_time_init(void)
 {
        /* Set up the timer interrupt (0) to go to our simple timer routine */
+       lguest_setup_irq(0);
        irq_set_handler(0, lguest_time_irq);
 
        clocksource_register_hz(&lguest_clock, NSEC_PER_SEC);
index 8bff7e7c290b7d30ef805061115690e7267dc4a9..1b2b73ff0a6e52176ba4a08d324ade8785382bd4 100644 (file)
@@ -189,10 +189,10 @@ struct multicall_space __xen_mc_entry(size_t args)
        unsigned argidx = roundup(b->argidx, sizeof(u64));
 
        BUG_ON(preemptible());
-       BUG_ON(b->argidx > MC_ARGS);
+       BUG_ON(b->argidx >= MC_ARGS);
 
        if (b->mcidx == MC_BATCH ||
-           (argidx + args) > MC_ARGS) {
+           (argidx + args) >= MC_ARGS) {
                mc_stats_flush(b->mcidx == MC_BATCH ? FL_SLOTS : FL_ARGS);
                xen_mc_flush();
                argidx = roundup(b->argidx, sizeof(u64));
@@ -206,7 +206,7 @@ struct multicall_space __xen_mc_entry(size_t args)
        ret.args = &b->args[argidx];
        b->argidx = argidx + args;
 
-       BUG_ON(b->argidx > MC_ARGS);
+       BUG_ON(b->argidx >= MC_ARGS);
        return ret;
 }
 
@@ -216,7 +216,7 @@ struct multicall_space xen_mc_extend_args(unsigned long op, size_t size)
        struct multicall_space ret = { NULL, NULL };
 
        BUG_ON(preemptible());
-       BUG_ON(b->argidx > MC_ARGS);
+       BUG_ON(b->argidx >= MC_ARGS);
 
        if (b->mcidx == 0)
                return ret;
@@ -224,14 +224,14 @@ struct multicall_space xen_mc_extend_args(unsigned long op, size_t size)
        if (b->entries[b->mcidx - 1].op != op)
                return ret;
 
-       if ((b->argidx + size) > MC_ARGS)
+       if ((b->argidx + size) >= MC_ARGS)
                return ret;
 
        ret.mc = &b->entries[b->mcidx - 1];
        ret.args = &b->args[b->argidx];
        b->argidx += size;
 
-       BUG_ON(b->argidx > MC_ARGS);
+       BUG_ON(b->argidx >= MC_ARGS);
        return ret;
 }
 
index c898049dafd54d8ea9deed98885b02db10ce43e7..342eae9b0d3cf982762987dfc5efb9a59f9b7275 100644 (file)
@@ -21,7 +21,7 @@ static void cfq_dtor(struct io_context *ioc)
        if (!hlist_empty(&ioc->cic_list)) {
                struct cfq_io_context *cic;
 
-               cic = list_entry(ioc->cic_list.first, struct cfq_io_context,
+               cic = hlist_entry(ioc->cic_list.first, struct cfq_io_context,
                                                                cic_list);
                cic->dtor(ioc);
        }
@@ -57,7 +57,7 @@ static void cfq_exit(struct io_context *ioc)
        if (!hlist_empty(&ioc->cic_list)) {
                struct cfq_io_context *cic;
 
-               cic = list_entry(ioc->cic_list.first, struct cfq_io_context,
+               cic = hlist_entry(ioc->cic_list.first, struct cfq_io_context,
                                                                cic_list);
                cic->exit(ioc);
        }
index 7c52d6888924c53215579b1b663083be376dfa48..3c7b537bf9081f9f43b90c7cdcd9a95073f1c02b 100644 (file)
@@ -185,7 +185,7 @@ struct cfq_group {
        int nr_cfqq;
 
        /*
-        * Per group busy queus average. Useful for workload slice calc. We
+        * Per group busy queues average. Useful for workload slice calc. We
         * create the array for each prio class but at run time it is used
         * only for RT and BE class and slot for IDLE class remains unused.
         * This is primarily done to avoid confusion and a gcc warning.
@@ -369,16 +369,16 @@ CFQ_CFQQ_FNS(wait_busy);
 #define cfq_log_cfqq(cfqd, cfqq, fmt, args...) \
        blk_add_trace_msg((cfqd)->queue, "cfq%d%c %s " fmt, (cfqq)->pid, \
                        cfq_cfqq_sync((cfqq)) ? 'S' : 'A', \
-                       blkg_path(&(cfqq)->cfqg->blkg), ##args);
+                       blkg_path(&(cfqq)->cfqg->blkg), ##args)
 
 #define cfq_log_cfqg(cfqd, cfqg, fmt, args...)                         \
        blk_add_trace_msg((cfqd)->queue, "%s " fmt,                     \
-                               blkg_path(&(cfqg)->blkg), ##args);      \
+                               blkg_path(&(cfqg)->blkg), ##args)       \
 
 #else
 #define cfq_log_cfqq(cfqd, cfqq, fmt, args...) \
        blk_add_trace_msg((cfqd)->queue, "cfq%d " fmt, (cfqq)->pid, ##args)
-#define cfq_log_cfqg(cfqd, cfqg, fmt, args...)         do {} while (0);
+#define cfq_log_cfqg(cfqd, cfqg, fmt, args...)         do {} while (0)
 #endif
 #define cfq_log(cfqd, fmt, args...)    \
        blk_add_trace_msg((cfqd)->queue, "cfq " fmt, ##args)
@@ -3786,9 +3786,6 @@ new_queue:
        return 0;
 
 queue_fail:
-       if (cic)
-               put_io_context(cic->ioc);
-
        cfq_schedule_dispatch(cfqd);
        spin_unlock_irqrestore(q->queue_lock, flags);
        cfq_log(cfqd, "set_request fail");
index c0dd09df7be891a113e94bd2a53cc7a6de8bd1e5..eaa8a854af03f6d4adc902fece195e7aabb69fd6 100644 (file)
@@ -291,7 +291,7 @@ static int pm_runtime_clk_notify(struct notifier_block *nb,
 {
        struct pm_clk_notifier_block *clknb;
        struct device *dev = data;
-       char *con_id;
+       char **con_id;
        int error;
 
        dev_dbg(dev, "%s() %ld\n", __func__, action);
@@ -309,8 +309,8 @@ static int pm_runtime_clk_notify(struct notifier_block *nb,
 
                dev->pwr_domain = clknb->pwr_domain;
                if (clknb->con_ids[0]) {
-                       for (con_id = clknb->con_ids[0]; *con_id; con_id++)
-                               pm_runtime_clk_add(dev, con_id);
+                       for (con_id = clknb->con_ids; *con_id; con_id++)
+                               pm_runtime_clk_add(dev, *con_id);
                } else {
                        pm_runtime_clk_add(dev, NULL);
                }
@@ -380,7 +380,7 @@ static int pm_runtime_clk_notify(struct notifier_block *nb,
 {
        struct pm_clk_notifier_block *clknb;
        struct device *dev = data;
-       char *con_id;
+       char **con_id;
 
        dev_dbg(dev, "%s() %ld\n", __func__, action);
 
@@ -389,16 +389,16 @@ static int pm_runtime_clk_notify(struct notifier_block *nb,
        switch (action) {
        case BUS_NOTIFY_ADD_DEVICE:
                if (clknb->con_ids[0]) {
-                       for (con_id = clknb->con_ids[0]; *con_id; con_id++)
-                               enable_clock(dev, con_id);
+                       for (con_id = clknb->con_ids; *con_id; con_id++)
+                               enable_clock(dev, *con_id);
                } else {
                        enable_clock(dev, NULL);
                }
                break;
        case BUS_NOTIFY_DEL_DEVICE:
                if (clknb->con_ids[0]) {
-                       for (con_id = clknb->con_ids[0]; *con_id; con_id++)
-                               disable_clock(dev, con_id);
+                       for (con_id = clknb->con_ids; *con_id; con_id++)
+                               disable_clock(dev, *con_id);
                } else {
                        disable_clock(dev, NULL);
                }
index e6fc716aca4521cc7537e09a393b6213b0a3ea88..f533f3375e24751feaf4e065b920291c7abe149d 100644 (file)
@@ -192,7 +192,8 @@ static int sock_xmit(struct nbd_device *lo, int send, void *buf, int size,
                        if (lo->xmit_timeout)
                                del_timer_sync(&ti);
                } else
-                       result = kernel_recvmsg(sock, &msg, &iov, 1, size, 0);
+                       result = kernel_recvmsg(sock, &msg, &iov, 1, size,
+                                               msg.msg_flags);
 
                if (signal_pending(current)) {
                        siginfo_t info;
@@ -753,9 +754,26 @@ static int __init nbd_init(void)
                return -ENOMEM;
 
        part_shift = 0;
-       if (max_part > 0)
+       if (max_part > 0) {
                part_shift = fls(max_part);
 
+               /*
+                * Adjust max_part according to part_shift as it is exported
+                * to user space so that user can know the max number of
+                * partition kernel should be able to manage.
+                *
+                * Note that -1 is required because partition 0 is reserved
+                * for the whole disk.
+                */
+               max_part = (1UL << part_shift) - 1;
+       }
+
+       if ((1UL << part_shift) > DISK_MAX_PARTS)
+               return -EINVAL;
+
+       if (nbds_max > 1UL << (MINORBITS - part_shift))
+               return -EINVAL;
+
        for (i = 0; i < nbds_max; i++) {
                struct gendisk *disk = alloc_disk(1 << part_shift);
                if (!disk)
index a0aabd904a51294605a20e39de391660bff77e90..46b8136c31bbe4aab3bccee9923ca755f6833ea8 100644 (file)
@@ -321,7 +321,6 @@ static void pcd_init_units(void)
                strcpy(disk->disk_name, cd->name);      /* umm... */
                disk->fops = &pcd_bdops;
                disk->flags = GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE;
-               disk->events = DISK_EVENT_MEDIA_CHANGE;
        }
 }
 
index 6ecf89cdf006a3f6605d15fb062f134a2d3a0621..079c08808d8a41b7fe5d27b00d389579ffae0930 100644 (file)
@@ -6,10 +6,13 @@
 #include <linux/virtio.h>
 #include <linux/virtio_blk.h>
 #include <linux/scatterlist.h>
+#include <linux/string_helpers.h>
+#include <scsi/scsi_cmnd.h>
 
 #define PART_BITS 4
 
 static int major, index;
+struct workqueue_struct *virtblk_wq;
 
 struct virtio_blk
 {
@@ -26,6 +29,9 @@ struct virtio_blk
 
        mempool_t *pool;
 
+       /* Process context for config space updates */
+       struct work_struct config_work;
+
        /* What host tells us, plus 2 for header & tailer. */
        unsigned int sg_elems;
 
@@ -141,7 +147,7 @@ static bool do_req(struct request_queue *q, struct virtio_blk *vblk,
        num = blk_rq_map_sg(q, vbr->req, vblk->sg + out);
 
        if (vbr->req->cmd_type == REQ_TYPE_BLOCK_PC) {
-               sg_set_buf(&vblk->sg[num + out + in++], vbr->req->sense, 96);
+               sg_set_buf(&vblk->sg[num + out + in++], vbr->req->sense, SCSI_SENSE_BUFFERSIZE);
                sg_set_buf(&vblk->sg[num + out + in++], &vbr->in_hdr,
                           sizeof(vbr->in_hdr));
        }
@@ -291,6 +297,46 @@ static ssize_t virtblk_serial_show(struct device *dev,
 }
 DEVICE_ATTR(serial, S_IRUGO, virtblk_serial_show, NULL);
 
+static void virtblk_config_changed_work(struct work_struct *work)
+{
+       struct virtio_blk *vblk =
+               container_of(work, struct virtio_blk, config_work);
+       struct virtio_device *vdev = vblk->vdev;
+       struct request_queue *q = vblk->disk->queue;
+       char cap_str_2[10], cap_str_10[10];
+       u64 capacity, size;
+
+       /* Host must always specify the capacity. */
+       vdev->config->get(vdev, offsetof(struct virtio_blk_config, capacity),
+                         &capacity, sizeof(capacity));
+
+       /* If capacity is too big, truncate with warning. */
+       if ((sector_t)capacity != capacity) {
+               dev_warn(&vdev->dev, "Capacity %llu too large: truncating\n",
+                        (unsigned long long)capacity);
+               capacity = (sector_t)-1;
+       }
+
+       size = capacity * queue_logical_block_size(q);
+       string_get_size(size, STRING_UNITS_2, cap_str_2, sizeof(cap_str_2));
+       string_get_size(size, STRING_UNITS_10, cap_str_10, sizeof(cap_str_10));
+
+       dev_notice(&vdev->dev,
+                 "new size: %llu %d-byte logical blocks (%s/%s)\n",
+                 (unsigned long long)capacity,
+                 queue_logical_block_size(q),
+                 cap_str_10, cap_str_2);
+
+       set_capacity(vblk->disk, capacity);
+}
+
+static void virtblk_config_changed(struct virtio_device *vdev)
+{
+       struct virtio_blk *vblk = vdev->priv;
+
+       queue_work(virtblk_wq, &vblk->config_work);
+}
+
 static int __devinit virtblk_probe(struct virtio_device *vdev)
 {
        struct virtio_blk *vblk;
@@ -327,6 +373,7 @@ static int __devinit virtblk_probe(struct virtio_device *vdev)
        vblk->vdev = vdev;
        vblk->sg_elems = sg_elems;
        sg_init_table(vblk->sg, vblk->sg_elems);
+       INIT_WORK(&vblk->config_work, virtblk_config_changed_work);
 
        /* We expect one virtqueue, for output. */
        vblk->vq = virtio_find_single_vq(vdev, blk_done, "requests");
@@ -477,6 +524,8 @@ static void __devexit virtblk_remove(struct virtio_device *vdev)
 {
        struct virtio_blk *vblk = vdev->priv;
 
+       flush_work(&vblk->config_work);
+
        /* Nothing should be pending. */
        BUG_ON(!list_empty(&vblk->reqs));
 
@@ -508,27 +557,47 @@ static unsigned int features[] = {
  * Use __refdata to avoid this warning.
  */
 static struct virtio_driver __refdata virtio_blk = {
-       .feature_table = features,
-       .feature_table_size = ARRAY_SIZE(features),
-       .driver.name =  KBUILD_MODNAME,
-       .driver.owner = THIS_MODULE,
-       .id_table =     id_table,
-       .probe =        virtblk_probe,
-       .remove =       __devexit_p(virtblk_remove),
+       .feature_table          = features,
+       .feature_table_size     = ARRAY_SIZE(features),
+       .driver.name            = KBUILD_MODNAME,
+       .driver.owner           = THIS_MODULE,
+       .id_table               = id_table,
+       .probe                  = virtblk_probe,
+       .remove                 = __devexit_p(virtblk_remove),
+       .config_changed         = virtblk_config_changed,
 };
 
 static int __init init(void)
 {
+       int error;
+
+       virtblk_wq = alloc_workqueue("virtio-blk", 0, 0);
+       if (!virtblk_wq)
+               return -ENOMEM;
+
        major = register_blkdev(0, "virtblk");
-       if (major < 0)
-               return major;
-       return register_virtio_driver(&virtio_blk);
+       if (major < 0) {
+               error = major;
+               goto out_destroy_workqueue;
+       }
+
+       error = register_virtio_driver(&virtio_blk);
+       if (error)
+               goto out_unregister_blkdev;
+       return 0;
+
+out_unregister_blkdev:
+       unregister_blkdev(major, "virtblk");
+out_destroy_workqueue:
+       destroy_workqueue(virtblk_wq);
+       return error;
 }
 
 static void __exit fini(void)
 {
        unregister_blkdev(major, "virtblk");
        unregister_virtio_driver(&virtio_blk);
+       destroy_workqueue(virtblk_wq);
 }
 module_init(init);
 module_exit(fini);
index c73910cc28c919bfdcdc6f1972af1f1f95822138..5cf2993a8338c9e325fb6126d5a6ec3ca371f6e3 100644 (file)
@@ -809,11 +809,13 @@ static int __init xen_blkif_init(void)
  failed_init:
        kfree(blkbk->pending_reqs);
        kfree(blkbk->pending_grant_handles);
-       for (i = 0; i < mmap_pages; i++) {
-               if (blkbk->pending_pages[i])
-                       __free_page(blkbk->pending_pages[i]);
+       if (blkbk->pending_pages) {
+               for (i = 0; i < mmap_pages; i++) {
+                       if (blkbk->pending_pages[i])
+                               __free_page(blkbk->pending_pages[i]);
+               }
+               kfree(blkbk->pending_pages);
        }
-       kfree(blkbk->pending_pages);
        kfree(blkbk);
        blkbk = NULL;
        return rc;
index 34570823355be5715c35bc86eabfc33d7ea41b83..6cc0db1bf52252f2a981544116bf419d2a6a28e6 100644 (file)
@@ -357,14 +357,13 @@ static int xen_vbd_create(struct xen_blkif *blkif, blkif_vdev_t handle,
        }
 
        vbd->bdev = bdev;
-       vbd->size = vbd_sz(vbd);
-
        if (vbd->bdev->bd_disk == NULL) {
                DPRINTK("xen_vbd_create: device %08x doesn't exist.\n",
                        vbd->pdevice);
                xen_vbd_free(vbd);
                return -ENOENT;
        }
+       vbd->size = vbd_sz(vbd);
 
        if (vbd->bdev->bd_disk->flags & GENHD_FL_CD || cdrom)
                vbd->type |= VDISK_CDROM;
index b3f01996318f04c0f432a38112226dbbeba0efcf..48ad2a7ab080ba9a58c425da7cc959dba0e1e3de 100644 (file)
@@ -355,29 +355,24 @@ static void hci_uart_tty_wakeup(struct tty_struct *tty)
  *             flags        pointer to flags for data
  *             count        count of received data in bytes
  *     
- * Return Value:    Number of bytes received
+ * Return Value:    None
  */
-static unsigned int hci_uart_tty_receive(struct tty_struct *tty,
-               const u8 *data, char *flags, int count)
+static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *flags, int count)
 {
        struct hci_uart *hu = (void *)tty->disc_data;
-       int received;
 
        if (!hu || tty != hu->tty)
-               return -ENODEV;
+               return;
 
        if (!test_bit(HCI_UART_PROTO_SET, &hu->flags))
-               return -EINVAL;
+               return;
 
        spin_lock(&hu->rx_lock);
-       received = hu->proto->recv(hu, (void *) data, count);
-       if (received > 0)
-               hu->hdev->stat.byte_rx += received;
+       hu->proto->recv(hu, (void *) data, count);
+       hu->hdev->stat.byte_rx += count;
        spin_unlock(&hu->rx_lock);
 
        tty_unthrottle(tty);
-
-       return received;
 }
 
 static int hci_uart_register_dev(struct hci_uart *hu)
index ae15a4ddaa9b0a3d7ff172e737dbaafd9fe8ac46..7878da89d29e2afef850461254f43ab4ae58722e 100644 (file)
@@ -627,7 +627,6 @@ static int viocd_probe(struct vio_dev *vdev, const struct vio_device_id *id)
        gendisk->fops = &viocd_fops;
        gendisk->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE |
                         GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE;
-       gendisk->events = DISK_EVENT_MEDIA_CHANGE;
        set_capacity(gendisk, 0);
        gendisk->private_data = d;
        d->viocd_disk = gendisk;
index 838568a7dbf56845755bf6e579142505a7172809..fb68b1295373e7287aa92a577b6aa937ba7ffe09 100644 (file)
@@ -1677,17 +1677,12 @@ static int __devinit virtcons_probe(struct virtio_device *vdev)
        portdev->config.max_nr_ports = 1;
        if (virtio_has_feature(vdev, VIRTIO_CONSOLE_F_MULTIPORT)) {
                multiport = true;
-               vdev->features[0] |= 1 << VIRTIO_CONSOLE_F_MULTIPORT;
-
                vdev->config->get(vdev, offsetof(struct virtio_console_config,
                                                 max_nr_ports),
                                  &portdev->config.max_nr_ports,
                                  sizeof(portdev->config.max_nr_ports));
        }
 
-       /* Let the Host know we support multiple ports.*/
-       vdev->config->finalize_features(vdev);
-
        err = init_vqs(portdev);
        if (err < 0) {
                dev_err(&vdev->dev, "Error %d initializing vqs\n", err);
index 036e5865eb40005f026f571fd679a7db09bd4859..dc7c033ef587142ce080e33a2b2711a94ece1d89 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/ioport.h>
 #include <linux/io.h>
 #include <linux/clk.h>
-#include <linux/pm_runtime.h>
 #include <linux/irq.h>
 #include <linux/err.h>
 #include <linux/clocksource.h>
@@ -153,12 +152,10 @@ static int sh_cmt_enable(struct sh_cmt_priv *p, unsigned long *rate)
 {
        int ret;
 
-       /* wake up device and enable clock */
-       pm_runtime_get_sync(&p->pdev->dev);
+       /* enable clock */
        ret = clk_enable(p->clk);
        if (ret) {
                dev_err(&p->pdev->dev, "cannot enable clock\n");
-               pm_runtime_put_sync(&p->pdev->dev);
                return ret;
        }
 
@@ -190,9 +187,8 @@ static void sh_cmt_disable(struct sh_cmt_priv *p)
        /* disable interrupts in CMT block */
        sh_cmt_write(p, CMCSR, 0);
 
-       /* stop clock and mark device as idle */
+       /* stop clock */
        clk_disable(p->clk);
-       pm_runtime_put_sync(&p->pdev->dev);
 }
 
 /* private flags */
@@ -664,7 +660,6 @@ static int __devinit sh_cmt_probe(struct platform_device *pdev)
 
        if (p) {
                dev_info(&pdev->dev, "kept as earlytimer\n");
-               pm_runtime_enable(&pdev->dev);
                return 0;
        }
 
@@ -679,9 +674,6 @@ static int __devinit sh_cmt_probe(struct platform_device *pdev)
                kfree(p);
                platform_set_drvdata(pdev, NULL);
        }
-
-       if (!is_early_platform_device(pdev))
-               pm_runtime_enable(&pdev->dev);
        return ret;
 }
 
index 17296288a2052ef757a5e22b6a0d3e52d37036ee..80813576861781194f235f52507480e1d44a92f7 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/clk.h>
-#include <linux/pm_runtime.h>
 #include <linux/irq.h>
 #include <linux/err.h>
 #include <linux/clocksource.h>
@@ -110,12 +109,10 @@ static int sh_tmu_enable(struct sh_tmu_priv *p)
 {
        int ret;
 
-       /* wake up device and enable clock */
-       pm_runtime_get_sync(&p->pdev->dev);
+       /* enable clock */
        ret = clk_enable(p->clk);
        if (ret) {
                dev_err(&p->pdev->dev, "cannot enable clock\n");
-               pm_runtime_put_sync(&p->pdev->dev);
                return ret;
        }
 
@@ -144,9 +141,8 @@ static void sh_tmu_disable(struct sh_tmu_priv *p)
        /* disable interrupts in TMU block */
        sh_tmu_write(p, TCR, 0x0000);
 
-       /* stop clock and mark device as idle */
+       /* stop clock */
        clk_disable(p->clk);
-       pm_runtime_put_sync(&p->pdev->dev);
 }
 
 static void sh_tmu_set_next(struct sh_tmu_priv *p, unsigned long delta,
@@ -415,7 +411,6 @@ static int __devinit sh_tmu_probe(struct platform_device *pdev)
 
        if (p) {
                dev_info(&pdev->dev, "kept as earlytimer\n");
-               pm_runtime_enable(&pdev->dev);
                return 0;
        }
 
@@ -430,9 +425,6 @@ static int __devinit sh_tmu_probe(struct platform_device *pdev)
                kfree(p);
                platform_set_drvdata(pdev, NULL);
        }
-
-       if (!is_early_platform_device(pdev))
-               pm_runtime_enable(&pdev->dev);
        return ret;
 }
 
index 636e40925b165e544618692fce8640503ddd65a6..2a638f9f09a25d5ed37411d7a997172b928491ce 100644 (file)
@@ -343,7 +343,7 @@ static int sh_dmae_alloc_chan_resources(struct dma_chan *chan)
 
                dmae_set_dmars(sh_chan, cfg->mid_rid);
                dmae_set_chcr(sh_chan, cfg->chcr);
-       } else if ((sh_dmae_readl(sh_chan, CHCR) & 0xf00) != 0x400) {
+       } else {
                dmae_init(sh_chan);
        }
 
@@ -1144,6 +1144,8 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
        /* platform data */
        shdev->pdata = pdata;
 
+       platform_set_drvdata(pdev, shdev);
+
        pm_runtime_enable(&pdev->dev);
        pm_runtime_get_sync(&pdev->dev);
 
@@ -1256,7 +1258,6 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
 
        pm_runtime_put(&pdev->dev);
 
-       platform_set_drvdata(pdev, shdev);
        dma_async_device_register(&shdev->common);
 
        return err;
@@ -1278,6 +1279,8 @@ rst_err:
 
        if (dmars)
                iounmap(shdev->dmars);
+
+       platform_set_drvdata(pdev, NULL);
 emapdmars:
        iounmap(shdev->chan_reg);
        synchronize_rcu();
@@ -1316,6 +1319,8 @@ static int __exit sh_dmae_remove(struct platform_device *pdev)
                iounmap(shdev->dmars);
        iounmap(shdev->chan_reg);
 
+       platform_set_drvdata(pdev, NULL);
+
        synchronize_rcu();
        kfree(shdev);
 
index 4a7f6314345506c1b347c505ad15783c61b7f17b..2967002a9f820b2894dd1f8f1110a47a9694e250 100644 (file)
@@ -87,32 +87,20 @@ config GPIO_IT8761E
          Say yes here to support GPIO functionality of IT8761E super I/O chip.
 
 config GPIO_EXYNOS4
-       bool "Samsung Exynos4 GPIO library support"
-       default y if CPU_EXYNOS4210
-       depends on ARM
-       help
-         Say yes here to support Samsung Exynos4 series SoCs GPIO library
+       def_bool y
+       depends on CPU_EXYNOS4210
 
 config GPIO_PLAT_SAMSUNG
-       bool "Samsung SoCs GPIO library support"
-       default y if SAMSUNG_GPIOLIB_4BIT
-       depends on ARM
-       help
-         Say yes here to support Samsung SoCs GPIO library
+       def_bool y
+       depends on SAMSUNG_GPIOLIB_4BIT
 
 config GPIO_S5PC100
-       bool "Samsung S5PC100 GPIO library support"
-       default y if CPU_S5PC100
-       depends on ARM
-       help
-         Say yes here to support Samsung S5PC100 SoCs GPIO library
+       def_bool y
+       depends on CPU_S5PC100
 
 config GPIO_S5PV210
-       bool "Samsung S5PV210/S5PC110 GPIO library support"
-       default y if CPU_S5PV210
-       depends on ARM
-       help
-         Say yes here to support Samsung S5PV210/S5PC110 SoCs GPIO library
+       def_bool y
+       depends on CPU_S5PV210
 
 config GPIO_PL061
        bool "PrimeCell PL061 GPIO support"
index d54ca6adb660be5c92a320c829a4361492ef226e..9029835112e7e0989321a346f95d89c3da63087d 100644 (file)
 #include <plat/gpio-cfg.h>
 #include <plat/gpio-cfg-helpers.h>
 
+int s3c_gpio_setpull_exynos4(struct s3c_gpio_chip *chip,
+                               unsigned int off, s3c_gpio_pull_t pull)
+{
+       if (pull == S3C_GPIO_PULL_UP)
+               pull = 3;
+
+       return s3c_gpio_setpull_updown(chip, off, pull);
+}
+
+s3c_gpio_pull_t s3c_gpio_getpull_exynos4(struct s3c_gpio_chip *chip,
+                                               unsigned int off)
+{
+       s3c_gpio_pull_t pull;
+
+       pull = s3c_gpio_getpull_updown(chip, off);
+       if (pull == 3)
+               pull = S3C_GPIO_PULL_UP;
+
+       return pull;
+}
+
 static struct s3c_gpio_cfg gpio_cfg = {
        .set_config     = s3c_gpio_setcfg_s3c64xx_4bit,
-       .set_pull       = s3c_gpio_setpull_updown,
-       .get_pull       = s3c_gpio_getpull_updown,
+       .set_pull       = s3c_gpio_setpull_exynos4,
+       .get_pull       = s3c_gpio_getpull_exynos4,
 };
 
 static struct s3c_gpio_cfg gpio_cfg_noint = {
        .set_config     = s3c_gpio_setcfg_s3c64xx_4bit,
-       .set_pull       = s3c_gpio_setpull_updown,
-       .get_pull       = s3c_gpio_getpull_updown,
+       .set_pull       = s3c_gpio_setpull_exynos4,
+       .get_pull       = s3c_gpio_getpull_exynos4,
 };
 
 /*
index 6c51191da567e1fba91e774573f08f087e90daee..01f74a8459d99e6b12a7d5bebe5820f17769a62d 100644 (file)
@@ -432,7 +432,6 @@ static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio,
 {
        void __iomem *base = bank->base;
        u32 gpio_bit = 1 << gpio;
-       u32 val;
 
        if (cpu_is_omap44xx()) {
                MOD_REG_BIT(OMAP4_GPIO_LEVELDETECT0, gpio_bit,
@@ -455,15 +454,8 @@ static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio,
        }
        if (likely(!(bank->non_wakeup_gpios & gpio_bit))) {
                if (cpu_is_omap44xx()) {
-                       if (trigger != 0)
-                               __raw_writel(1 << gpio, bank->base+
-                                               OMAP4_GPIO_IRQWAKEN0);
-                       else {
-                               val = __raw_readl(bank->base +
-                                                       OMAP4_GPIO_IRQWAKEN0);
-                               __raw_writel(val & (~(1 << gpio)), bank->base +
-                                                        OMAP4_GPIO_IRQWAKEN0);
-                       }
+                       MOD_REG_BIT(OMAP4_GPIO_IRQWAKEN0, gpio_bit,
+                               trigger != 0);
                } else {
                        /*
                         * GPIO wakeup request can only be generated on edge
@@ -1134,8 +1126,11 @@ static void gpio_irq_shutdown(struct irq_data *d)
 {
        unsigned int gpio = d->irq - IH_GPIO_BASE;
        struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
+       unsigned long flags;
 
+       spin_lock_irqsave(&bank->lock, flags);
        _reset_gpio(bank, gpio);
+       spin_unlock_irqrestore(&bank->lock, flags);
 }
 
 static void gpio_ack_irq(struct irq_data *d)
@@ -1150,9 +1145,12 @@ static void gpio_mask_irq(struct irq_data *d)
 {
        unsigned int gpio = d->irq - IH_GPIO_BASE;
        struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
+       unsigned long flags;
 
+       spin_lock_irqsave(&bank->lock, flags);
        _set_gpio_irqenable(bank, gpio, 0);
        _set_gpio_triggering(bank, get_gpio_index(gpio), IRQ_TYPE_NONE);
+       spin_unlock_irqrestore(&bank->lock, flags);
 }
 
 static void gpio_unmask_irq(struct irq_data *d)
@@ -1161,7 +1159,9 @@ static void gpio_unmask_irq(struct irq_data *d)
        struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
        unsigned int irq_mask = 1 << get_gpio_index(gpio);
        u32 trigger = irqd_get_trigger_type(d);
+       unsigned long flags;
 
+       spin_lock_irqsave(&bank->lock, flags);
        if (trigger)
                _set_gpio_triggering(bank, get_gpio_index(gpio), trigger);
 
@@ -1173,6 +1173,7 @@ static void gpio_unmask_irq(struct irq_data *d)
        }
 
        _set_gpio_irqenable(bank, gpio, 1);
+       spin_unlock_irqrestore(&bank->lock, flags);
 }
 
 static struct irq_chip gpio_irq_chip = {
@@ -1524,7 +1525,7 @@ static void omap_gpio_mod_init(struct gpio_bank *bank, int id)
        }
 }
 
-static void __init omap_gpio_chip_init(struct gpio_bank *bank)
+static void __devinit omap_gpio_chip_init(struct gpio_bank *bank)
 {
        int j;
        static int gpio;
index 51c2257b11e6d7cfb990b6a667b8fa00e59dd92e..4d46441cbe2d830de73ffacdb5821dbdd11f6340 100644 (file)
@@ -776,7 +776,7 @@ static int i915_error_state(struct seq_file *m, void *unused)
        seq_printf(m, "  INSTPM: 0x%08x\n", error->instpm);
        seq_printf(m, "  seqno: 0x%08x\n", error->seqno);
 
-       for (i = 0; i < 16; i++)
+       for (i = 0; i < dev_priv->num_fence_regs; i++)
                seq_printf(m, "  fence[%d] = %08llx\n", i, error->fence[i]);
 
        if (error->active_bo)
index ee660355ae6839839713ae3ecca369cf60f81a6d..f63ee162f1245dcffc5844c6c401df7ce9b885c8 100644 (file)
@@ -716,6 +716,7 @@ typedef struct drm_i915_private {
        struct intel_fbdev *fbdev;
 
        struct drm_property *broadcast_rgb_property;
+       struct drm_property *force_audio_property;
 
        atomic_t forcewake_count;
 } drm_i915_private_t;
@@ -909,13 +910,6 @@ struct drm_i915_file_private {
        } mm;
 };
 
-enum intel_chip_family {
-       CHIP_I8XX = 0x01,
-       CHIP_I9XX = 0x02,
-       CHIP_I915 = 0x04,
-       CHIP_I965 = 0x08,
-};
-
 #define INTEL_INFO(dev)        (((struct drm_i915_private *) (dev)->dev_private)->info)
 
 #define IS_I830(dev)           ((dev)->pci_device == 0x3577)
index 0b2e167d2bce856c9b9ef55ea73e22174abf7d2f..12d32579b9514bda3446865fa3ba1588a81fcafb 100644 (file)
@@ -354,7 +354,7 @@ i915_gem_shmem_pread_fast(struct drm_device *dev,
                 * page_offset = offset within page
                 * page_length = bytes to copy for this page
                 */
-               page_offset = offset & (PAGE_SIZE-1);
+               page_offset = offset_in_page(offset);
                page_length = remain;
                if ((page_offset + remain) > PAGE_SIZE)
                        page_length = PAGE_SIZE - page_offset;
@@ -453,9 +453,9 @@ i915_gem_shmem_pread_slow(struct drm_device *dev,
                 * data_page_offset = offset with data_page_index page.
                 * page_length = bytes to copy for this page
                 */
-               shmem_page_offset = offset & ~PAGE_MASK;
+               shmem_page_offset = offset_in_page(offset);
                data_page_index = data_ptr / PAGE_SIZE - first_data_page;
-               data_page_offset = data_ptr & ~PAGE_MASK;
+               data_page_offset = offset_in_page(data_ptr);
 
                page_length = remain;
                if ((shmem_page_offset + page_length) > PAGE_SIZE)
@@ -638,8 +638,8 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev,
                 * page_offset = offset within page
                 * page_length = bytes to copy for this page
                 */
-               page_base = (offset & ~(PAGE_SIZE-1));
-               page_offset = offset & (PAGE_SIZE-1);
+               page_base = offset & PAGE_MASK;
+               page_offset = offset_in_page(offset);
                page_length = remain;
                if ((page_offset + remain) > PAGE_SIZE)
                        page_length = PAGE_SIZE - page_offset;
@@ -650,7 +650,6 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev,
                 */
                if (fast_user_write(dev_priv->mm.gtt_mapping, page_base,
                                    page_offset, user_data, page_length))
-
                        return -EFAULT;
 
                remain -= page_length;
@@ -730,9 +729,9 @@ i915_gem_gtt_pwrite_slow(struct drm_device *dev,
                 * page_length = bytes to copy for this page
                 */
                gtt_page_base = offset & PAGE_MASK;
-               gtt_page_offset = offset & ~PAGE_MASK;
+               gtt_page_offset = offset_in_page(offset);
                data_page_index = data_ptr / PAGE_SIZE - first_data_page;
-               data_page_offset = data_ptr & ~PAGE_MASK;
+               data_page_offset = offset_in_page(data_ptr);
 
                page_length = remain;
                if ((gtt_page_offset + page_length) > PAGE_SIZE)
@@ -791,7 +790,7 @@ i915_gem_shmem_pwrite_fast(struct drm_device *dev,
                 * page_offset = offset within page
                 * page_length = bytes to copy for this page
                 */
-               page_offset = offset & (PAGE_SIZE-1);
+               page_offset = offset_in_page(offset);
                page_length = remain;
                if ((page_offset + remain) > PAGE_SIZE)
                        page_length = PAGE_SIZE - page_offset;
@@ -896,9 +895,9 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev,
                 * data_page_offset = offset with data_page_index page.
                 * page_length = bytes to copy for this page
                 */
-               shmem_page_offset = offset & ~PAGE_MASK;
+               shmem_page_offset = offset_in_page(offset);
                data_page_index = data_ptr / PAGE_SIZE - first_data_page;
-               data_page_offset = data_ptr & ~PAGE_MASK;
+               data_page_offset = offset_in_page(data_ptr);
 
                page_length = remain;
                if ((shmem_page_offset + page_length) > PAGE_SIZE)
@@ -1450,8 +1449,9 @@ i915_gem_get_unfenced_gtt_alignment(struct drm_i915_gem_object *obj)
         * edge of an even tile row (where tile rows are counted as if the bo is
         * placed in a fenced gtt region).
         */
-       if (IS_GEN2(dev) ||
-           (obj->tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev)))
+       if (IS_GEN2(dev))
+               tile_height = 16;
+       else if (obj->tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev))
                tile_height = 32;
        else
                tile_height = 8;
index b79619a7b78880f9823ba87de0ec888608630515..b9fafe3b045bda5817047f2a5cde8a6fc1b58265 100644 (file)
@@ -517,7 +517,7 @@ irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS)
        if (de_iir & DE_PIPEA_VBLANK_IVB)
                drm_handle_vblank(dev, 0);
 
-       if (de_iir & DE_PIPEB_VBLANK_IVB);
+       if (de_iir & DE_PIPEB_VBLANK_IVB)
                drm_handle_vblank(dev, 1);
 
        /* check event from PCH */
index e93f93cc7e78725b4fbe52ba4e5c0b2f522a3768..0979d8877880d11acacd692de840660e6e60022c 100644 (file)
@@ -288,6 +288,8 @@ static bool intel_crt_detect_ddc(struct drm_connector *connector)
                 * This may be a DVI-I connector with a shared DDC
                 * link between analog and digital outputs, so we
                 * have to check the EDID input spec of the attached device.
+                *
+                * On the other hand, what should we do if it is a broken EDID?
                 */
                if (edid != NULL) {
                        is_digital = edid->input & DRM_EDID_INPUT_DIGITAL;
@@ -298,6 +300,8 @@ static bool intel_crt_detect_ddc(struct drm_connector *connector)
                if (!is_digital) {
                        DRM_DEBUG_KMS("CRT detected via DDC:0x50 [EDID]\n");
                        return true;
+               } else {
+                       DRM_DEBUG_KMS("CRT not detected via DDC:0x50 [EDID reports a digital panel]\n");
                }
        }
 
index f553ddfdc16819fa343b4780c27de14fa37d1337..81a9059b6a94ea0278bd691342294f4c0893cf21 100644 (file)
@@ -3983,54 +3983,6 @@ static void i830_update_wm(struct drm_device *dev)
 #define ILK_LP0_PLANE_LATENCY          700
 #define ILK_LP0_CURSOR_LATENCY         1300
 
-static bool ironlake_compute_wm0(struct drm_device *dev,
-                                int pipe,
-                                const struct intel_watermark_params *display,
-                                int display_latency_ns,
-                                const struct intel_watermark_params *cursor,
-                                int cursor_latency_ns,
-                                int *plane_wm,
-                                int *cursor_wm)
-{
-       struct drm_crtc *crtc;
-       int htotal, hdisplay, clock, pixel_size;
-       int line_time_us, line_count;
-       int entries, tlb_miss;
-
-       crtc = intel_get_crtc_for_pipe(dev, pipe);
-       if (crtc->fb == NULL || !crtc->enabled)
-               return false;
-
-       htotal = crtc->mode.htotal;
-       hdisplay = crtc->mode.hdisplay;
-       clock = crtc->mode.clock;
-       pixel_size = crtc->fb->bits_per_pixel / 8;
-
-       /* Use the small buffer method to calculate plane watermark */
-       entries = ((clock * pixel_size / 1000) * display_latency_ns) / 1000;
-       tlb_miss = display->fifo_size*display->cacheline_size - hdisplay * 8;
-       if (tlb_miss > 0)
-               entries += tlb_miss;
-       entries = DIV_ROUND_UP(entries, display->cacheline_size);
-       *plane_wm = entries + display->guard_size;
-       if (*plane_wm > (int)display->max_wm)
-               *plane_wm = display->max_wm;
-
-       /* Use the large buffer method to calculate cursor watermark */
-       line_time_us = ((htotal * 1000) / clock);
-       line_count = (cursor_latency_ns / line_time_us + 1000) / 1000;
-       entries = line_count * 64 * pixel_size;
-       tlb_miss = cursor->fifo_size*cursor->cacheline_size - hdisplay * 8;
-       if (tlb_miss > 0)
-               entries += tlb_miss;
-       entries = DIV_ROUND_UP(entries, cursor->cacheline_size);
-       *cursor_wm = entries + cursor->guard_size;
-       if (*cursor_wm > (int)cursor->max_wm)
-               *cursor_wm = (int)cursor->max_wm;
-
-       return true;
-}
-
 /*
  * Check the wm result.
  *
@@ -4139,12 +4091,12 @@ static void ironlake_update_wm(struct drm_device *dev)
        unsigned int enabled;
 
        enabled = 0;
-       if (ironlake_compute_wm0(dev, 0,
-                                &ironlake_display_wm_info,
-                                ILK_LP0_PLANE_LATENCY,
-                                &ironlake_cursor_wm_info,
-                                ILK_LP0_CURSOR_LATENCY,
-                                &plane_wm, &cursor_wm)) {
+       if (g4x_compute_wm0(dev, 0,
+                           &ironlake_display_wm_info,
+                           ILK_LP0_PLANE_LATENCY,
+                           &ironlake_cursor_wm_info,
+                           ILK_LP0_CURSOR_LATENCY,
+                           &plane_wm, &cursor_wm)) {
                I915_WRITE(WM0_PIPEA_ILK,
                           (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm);
                DRM_DEBUG_KMS("FIFO watermarks For pipe A -"
@@ -4153,12 +4105,12 @@ static void ironlake_update_wm(struct drm_device *dev)
                enabled |= 1;
        }
 
-       if (ironlake_compute_wm0(dev, 1,
-                                &ironlake_display_wm_info,
-                                ILK_LP0_PLANE_LATENCY,
-                                &ironlake_cursor_wm_info,
-                                ILK_LP0_CURSOR_LATENCY,
-                                &plane_wm, &cursor_wm)) {
+       if (g4x_compute_wm0(dev, 1,
+                           &ironlake_display_wm_info,
+                           ILK_LP0_PLANE_LATENCY,
+                           &ironlake_cursor_wm_info,
+                           ILK_LP0_CURSOR_LATENCY,
+                           &plane_wm, &cursor_wm)) {
                I915_WRITE(WM0_PIPEB_ILK,
                           (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm);
                DRM_DEBUG_KMS("FIFO watermarks For pipe B -"
@@ -4223,10 +4175,10 @@ static void sandybridge_update_wm(struct drm_device *dev)
        unsigned int enabled;
 
        enabled = 0;
-       if (ironlake_compute_wm0(dev, 0,
-                                &sandybridge_display_wm_info, latency,
-                                &sandybridge_cursor_wm_info, latency,
-                                &plane_wm, &cursor_wm)) {
+       if (g4x_compute_wm0(dev, 0,
+                           &sandybridge_display_wm_info, latency,
+                           &sandybridge_cursor_wm_info, latency,
+                           &plane_wm, &cursor_wm)) {
                I915_WRITE(WM0_PIPEA_ILK,
                           (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm);
                DRM_DEBUG_KMS("FIFO watermarks For pipe A -"
@@ -4235,10 +4187,10 @@ static void sandybridge_update_wm(struct drm_device *dev)
                enabled |= 1;
        }
 
-       if (ironlake_compute_wm0(dev, 1,
-                                &sandybridge_display_wm_info, latency,
-                                &sandybridge_cursor_wm_info, latency,
-                                &plane_wm, &cursor_wm)) {
+       if (g4x_compute_wm0(dev, 1,
+                           &sandybridge_display_wm_info, latency,
+                           &sandybridge_cursor_wm_info, latency,
+                           &plane_wm, &cursor_wm)) {
                I915_WRITE(WM0_PIPEB_ILK,
                           (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm);
                DRM_DEBUG_KMS("FIFO watermarks For pipe B -"
@@ -7675,6 +7627,7 @@ static void intel_init_display(struct drm_device *dev)
                        dev_priv->display.update_wm = NULL;
                } else
                        dev_priv->display.update_wm = pineview_update_wm;
+               dev_priv->display.init_clock_gating = gen3_init_clock_gating;
        } else if (IS_G4X(dev)) {
                dev_priv->display.update_wm = g4x_update_wm;
                dev_priv->display.init_clock_gating = g4x_init_clock_gating;
index a4d80314e7f8cf5edb13bce97328a60f1f26f6ce..391b55f1cc7496e2e313d77332fafb35ecd4aa15 100644 (file)
@@ -59,8 +59,6 @@ struct intel_dp {
        bool is_pch_edp;
        uint8_t train_set[4];
        uint8_t link_status[DP_LINK_STATUS_SIZE];
-
-       struct drm_property *force_audio_property;
 };
 
 /**
@@ -1702,7 +1700,7 @@ intel_dp_set_property(struct drm_connector *connector,
        if (ret)
                return ret;
 
-       if (property == intel_dp->force_audio_property) {
+       if (property == dev_priv->force_audio_property) {
                int i = val;
                bool has_audio;
 
@@ -1841,16 +1839,7 @@ bool intel_dpd_is_edp(struct drm_device *dev)
 static void
 intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connector)
 {
-       struct drm_device *dev = connector->dev;
-
-       intel_dp->force_audio_property =
-               drm_property_create(dev, DRM_MODE_PROP_RANGE, "force_audio", 2);
-       if (intel_dp->force_audio_property) {
-               intel_dp->force_audio_property->values[0] = -1;
-               intel_dp->force_audio_property->values[1] = 1;
-               drm_connector_attach_property(connector, intel_dp->force_audio_property, 0);
-       }
-
+       intel_attach_force_audio_property(connector);
        intel_attach_broadcast_rgb_property(connector);
 }
 
index 831d7a4a0d18ce4eb52c86c76cacde8ac804f22e..9ffa61eb4d7efab156819980452e22e5507c3c76 100644 (file)
@@ -236,6 +236,7 @@ struct intel_unpin_work {
 int intel_ddc_get_modes(struct drm_connector *c, struct i2c_adapter *adapter);
 extern bool intel_ddc_probe(struct intel_encoder *intel_encoder, int ddc_bus);
 
+extern void intel_attach_force_audio_property(struct drm_connector *connector);
 extern void intel_attach_broadcast_rgb_property(struct drm_connector *connector);
 
 extern void intel_crt_init(struct drm_device *dev);
index f289b86429762e7b644e3b454c7f8b1a0d345987..aa0a8e83142e1c8ee5562d0884ad92c8656b30ed 100644 (file)
@@ -45,7 +45,6 @@ struct intel_hdmi {
        bool has_hdmi_sink;
        bool has_audio;
        int force_audio;
-       struct drm_property *force_audio_property;
 };
 
 static struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder)
@@ -194,7 +193,7 @@ static int intel_hdmi_mode_valid(struct drm_connector *connector,
        if (mode->clock > 165000)
                return MODE_CLOCK_HIGH;
        if (mode->clock < 20000)
-               return MODE_CLOCK_HIGH;
+               return MODE_CLOCK_LOW;
 
        if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
                return MODE_NO_DBLESCAN;
@@ -287,7 +286,7 @@ intel_hdmi_set_property(struct drm_connector *connector,
        if (ret)
                return ret;
 
-       if (property == intel_hdmi->force_audio_property) {
+       if (property == dev_priv->force_audio_property) {
                int i = val;
                bool has_audio;
 
@@ -365,16 +364,7 @@ static const struct drm_encoder_funcs intel_hdmi_enc_funcs = {
 static void
 intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *connector)
 {
-       struct drm_device *dev = connector->dev;
-
-       intel_hdmi->force_audio_property =
-               drm_property_create(dev, DRM_MODE_PROP_RANGE, "force_audio", 2);
-       if (intel_hdmi->force_audio_property) {
-               intel_hdmi->force_audio_property->values[0] = -1;
-               intel_hdmi->force_audio_property->values[1] = 1;
-               drm_connector_attach_property(connector, intel_hdmi->force_audio_property, 0);
-       }
-
+       intel_attach_force_audio_property(connector);
        intel_attach_broadcast_rgb_property(connector);
 }
 
index 67cb076d271b5eb00a4c87a9022f0957f3ff569e..b28f7bd9f88a1fca15fdb0ade73cb724658d1cf8 100644 (file)
@@ -727,6 +727,14 @@ static const struct dmi_system_id intel_no_lvds[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "U800"),
                },
        },
+       {
+               .callback = intel_no_lvds_dmi_callback,
+               .ident = "Asus EeeBox PC EB1007",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer INC."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "EB1007"),
+               },
+       },
 
        { }     /* terminating entry */
 };
index 9034dd8f33c75646eedceeba9d010e26f198ae5c..3b26a3ba02dd349c9715ad16768a1a06a52b7bdb 100644 (file)
@@ -81,6 +81,36 @@ int intel_ddc_get_modes(struct drm_connector *connector,
        return ret;
 }
 
+static const char *force_audio_names[] = {
+       "off",
+       "auto",
+       "on",
+};
+
+void
+intel_attach_force_audio_property(struct drm_connector *connector)
+{
+       struct drm_device *dev = connector->dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct drm_property *prop;
+       int i;
+
+       prop = dev_priv->force_audio_property;
+       if (prop == NULL) {
+               prop = drm_property_create(dev, DRM_MODE_PROP_ENUM,
+                                          "audio",
+                                          ARRAY_SIZE(force_audio_names));
+               if (prop == NULL)
+                       return;
+
+               for (i = 0; i < ARRAY_SIZE(force_audio_names); i++)
+                       drm_property_add_enum(prop, i, i-1, force_audio_names[i]);
+
+               dev_priv->force_audio_property = prop;
+       }
+       drm_connector_attach_property(connector, prop, 0);
+}
+
 static const char *broadcast_rgb_names[] = {
        "Full",
        "Limited 16:235",
index 754086f83941148027633e001988ebdbef6ecda1..30fe554d8936a8cd965b083a0de9064f44865db6 100644 (file)
@@ -148,8 +148,6 @@ struct intel_sdvo_connector {
        int   format_supported_num;
        struct drm_property *tv_format;
 
-       struct drm_property *force_audio_property;
-
        /* add the property for the SDVO-TV */
        struct drm_property *left;
        struct drm_property *right;
@@ -1712,7 +1710,7 @@ intel_sdvo_set_property(struct drm_connector *connector,
        if (ret)
                return ret;
 
-       if (property == intel_sdvo_connector->force_audio_property) {
+       if (property == dev_priv->force_audio_property) {
                int i = val;
                bool has_audio;
 
@@ -2037,15 +2035,7 @@ intel_sdvo_add_hdmi_properties(struct intel_sdvo_connector *connector)
 {
        struct drm_device *dev = connector->base.base.dev;
 
-       connector->force_audio_property =
-               drm_property_create(dev, DRM_MODE_PROP_RANGE, "force_audio", 2);
-       if (connector->force_audio_property) {
-               connector->force_audio_property->values[0] = -1;
-               connector->force_audio_property->values[1] = 1;
-               drm_connector_attach_property(&connector->base.base,
-                                             connector->force_audio_property, 0);
-       }
-
+       intel_attach_force_audio_property(&connector->base.base);
        if (INTEL_INFO(dev)->gen >= 4 && IS_MOBILE(dev))
                intel_attach_broadcast_rgb_property(&connector->base.base);
 }
index 053edf9d2f67db4c6ed86536ea08f89d8c5b8b51..ba896e54b799bfd43b92291358234197c4cd56b3 100644 (file)
@@ -900,6 +900,7 @@ nv_save_state_ext(struct drm_device *dev, int head,
        }
        /* NV11 and NV20 don't have this, they stop at 0x52. */
        if (nv_gf4_disp_arch(dev)) {
+               rd_cio_state(dev, head, regp, NV_CIO_CRE_42);
                rd_cio_state(dev, head, regp, NV_CIO_CRE_53);
                rd_cio_state(dev, head, regp, NV_CIO_CRE_54);
 
@@ -1003,6 +1004,7 @@ nv_load_state_ext(struct drm_device *dev, int head,
                        nouveau_wait_eq(dev, 650000000, NV_PRMCIO_INP0__COLOR, 0x8, 0x0);
                }
 
+               wr_cio_state(dev, head, regp, NV_CIO_CRE_42);
                wr_cio_state(dev, head, regp, NV_CIO_CRE_53);
                wr_cio_state(dev, head, regp, NV_CIO_CRE_54);
 
index 2960f583dc389fac112de1d4ad7ee615a0d6ca31..5ee14d216ce88474eb3d903b5b3519a69019d218 100644 (file)
@@ -397,7 +397,7 @@ nouveau_mem_vram_init(struct drm_device *dev)
                if (pci_dma_supported(dev->pdev, DMA_BIT_MASK(40)))
                        dma_bits = 40;
        } else
-       if (drm_pci_device_is_pcie(dev) &&
+       if (0 && drm_pci_device_is_pcie(dev) &&
            dev_priv->chipset  > 0x40 &&
            dev_priv->chipset != 0x45) {
                if (pci_dma_supported(dev->pdev, DMA_BIT_MASK(39)))
@@ -868,7 +868,9 @@ nouveau_gart_manager_del(struct ttm_mem_type_manager *man,
                nouveau_vm_unmap(&node->tmp_vma);
                nouveau_vm_put(&node->tmp_vma);
        }
+
        mem->mm_node = NULL;
+       kfree(node);
 }
 
 static int
index c77111eca6acefc8ab31acb7bb060547b64b5f7a..82fad914e648441340a836bf306d761d09afc904 100644 (file)
@@ -458,7 +458,7 @@ nouveau_sgdma_init(struct drm_device *dev)
                dev_priv->gart_info.type = NOUVEAU_GART_HW;
                dev_priv->gart_info.func = &nv50_sgdma_backend;
        } else
-       if (drm_pci_device_is_pcie(dev) &&
+       if (0 && drm_pci_device_is_pcie(dev) &&
            dev_priv->chipset > 0x40 && dev_priv->chipset != 0x45) {
                if (nv44_graph_class(dev)) {
                        dev_priv->gart_info.func = &nv44_sgdma_backend;
index 38ea662568c1062a6486426408ef5648265e360a..80218887e0a004fc19337f180a93fe4ecb4196d2 100644 (file)
@@ -371,6 +371,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->vram.flags_valid        = nv50_vram_flags_valid;
                break;
        case 0xC0:
+       case 0xD0:
                engine->instmem.init            = nvc0_instmem_init;
                engine->instmem.takedown        = nvc0_instmem_takedown;
                engine->instmem.suspend         = nvc0_instmem_suspend;
@@ -563,68 +564,68 @@ nouveau_card_init(struct drm_device *dev)
        if (ret)
                goto out_timer;
 
-       switch (dev_priv->card_type) {
-       case NV_04:
-               nv04_graph_create(dev);
-               break;
-       case NV_10:
-               nv10_graph_create(dev);
-               break;
-       case NV_20:
-       case NV_30:
-               nv20_graph_create(dev);
-               break;
-       case NV_40:
-               nv40_graph_create(dev);
-               break;
-       case NV_50:
-               nv50_graph_create(dev);
-               break;
-       case NV_C0:
-               nvc0_graph_create(dev);
-               break;
-       default:
-               break;
-       }
-
-       switch (dev_priv->chipset) {
-       case 0x84:
-       case 0x86:
-       case 0x92:
-       case 0x94:
-       case 0x96:
-       case 0xa0:
-               nv84_crypt_create(dev);
-               break;
-       }
+       if (!nouveau_noaccel) {
+               switch (dev_priv->card_type) {
+               case NV_04:
+                       nv04_graph_create(dev);
+                       break;
+               case NV_10:
+                       nv10_graph_create(dev);
+                       break;
+               case NV_20:
+               case NV_30:
+                       nv20_graph_create(dev);
+                       break;
+               case NV_40:
+                       nv40_graph_create(dev);
+                       break;
+               case NV_50:
+                       nv50_graph_create(dev);
+                       break;
+               case NV_C0:
+                       nvc0_graph_create(dev);
+                       break;
+               default:
+                       break;
+               }
 
-       switch (dev_priv->card_type) {
-       case NV_50:
                switch (dev_priv->chipset) {
-               case 0xa3:
-               case 0xa5:
-               case 0xa8:
-               case 0xaf:
-                       nva3_copy_create(dev);
+               case 0x84:
+               case 0x86:
+               case 0x92:
+               case 0x94:
+               case 0x96:
+               case 0xa0:
+                       nv84_crypt_create(dev);
                        break;
                }
-               break;
-       case NV_C0:
-               nvc0_copy_create(dev, 0);
-               nvc0_copy_create(dev, 1);
-               break;
-       default:
-               break;
-       }
 
-       if (dev_priv->card_type == NV_40)
-               nv40_mpeg_create(dev);
-       else
-       if (dev_priv->card_type == NV_50 &&
-           (dev_priv->chipset < 0x98 || dev_priv->chipset == 0xa0))
-               nv50_mpeg_create(dev);
+               switch (dev_priv->card_type) {
+               case NV_50:
+                       switch (dev_priv->chipset) {
+                       case 0xa3:
+                       case 0xa5:
+                       case 0xa8:
+                       case 0xaf:
+                               nva3_copy_create(dev);
+                               break;
+                       }
+                       break;
+               case NV_C0:
+                       nvc0_copy_create(dev, 0);
+                       nvc0_copy_create(dev, 1);
+                       break;
+               default:
+                       break;
+               }
+
+               if (dev_priv->card_type == NV_40)
+                       nv40_mpeg_create(dev);
+               else
+               if (dev_priv->card_type == NV_50 &&
+                   (dev_priv->chipset < 0x98 || dev_priv->chipset == 0xa0))
+                       nv50_mpeg_create(dev);
 
-       if (!nouveau_noaccel) {
                for (e = 0; e < NVOBJ_ENGINE_NR; e++) {
                        if (dev_priv->eng[e]) {
                                ret = dev_priv->eng[e]->init(dev, e);
@@ -922,6 +923,7 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
                dev_priv->card_type = NV_50;
                break;
        case 0xc0:
+       case 0xd0:
                dev_priv->card_type = NV_C0;
                break;
        default:
index 0059e6f58a8b642c9d88f00b7991a97dc68b1772..519a6b4bba466fce9a46577908b411e5cfdbbdfa 100644 (file)
@@ -58,6 +58,7 @@ nouveau_vm_map_at(struct nouveau_vma *vma, u64 delta, struct nouveau_mem *node)
                        num -= len;
                        pte += len;
                        if (unlikely(end >= max)) {
+                               phys += len << (bits + 12);
                                pde++;
                                pte = 0;
                        }
index 3c78bc81357e0e838ec933e330748d9bd019f661..f1a3ae49199505d7ab1d0b187733a33a6bb6a0a2 100644 (file)
@@ -376,7 +376,10 @@ nv_crtc_mode_set_vga(struct drm_crtc *crtc, struct drm_display_mode *mode)
         */
 
        /* framebuffer can be larger than crtc scanout area. */
-       regp->CRTC[NV_CIO_CRE_RPC0_INDEX] = XLATE(fb->pitch / 8, 8, NV_CIO_CRE_RPC0_OFFSET_10_8);
+       regp->CRTC[NV_CIO_CRE_RPC0_INDEX] =
+               XLATE(fb->pitch / 8, 8, NV_CIO_CRE_RPC0_OFFSET_10_8);
+       regp->CRTC[NV_CIO_CRE_42] =
+               XLATE(fb->pitch / 8, 11, NV_CIO_CRE_42_OFFSET_11);
        regp->CRTC[NV_CIO_CRE_RPC1_INDEX] = mode->crtc_hdisplay < 1280 ?
                                            MASK(NV_CIO_CRE_RPC1_LARGE) : 0x00;
        regp->CRTC[NV_CIO_CRE_LSR_INDEX] = XLATE(horizBlankEnd, 6, NV_CIO_CRE_LSR_HBE_6) |
@@ -824,8 +827,11 @@ nv04_crtc_do_mode_set_base(struct drm_crtc *crtc,
        regp->CRTC[NV_CIO_CR_OFFSET_INDEX] = drm_fb->pitch >> 3;
        regp->CRTC[NV_CIO_CRE_RPC0_INDEX] =
                XLATE(drm_fb->pitch >> 3, 8, NV_CIO_CRE_RPC0_OFFSET_10_8);
+       regp->CRTC[NV_CIO_CRE_42] =
+               XLATE(drm_fb->pitch / 8, 11, NV_CIO_CRE_42_OFFSET_11);
        crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_RPC0_INDEX);
        crtc_wr_cio_state(crtc, regp, NV_CIO_CR_OFFSET_INDEX);
+       crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_42);
 
        /* Update the framebuffer location. */
        regp->fb_start = nv_crtc->fb.offset & ~3;
index fe0f253089acf6e15de9d1dd93934fd23d315fdb..bbfb1a68fb1170d1a48f45d03f3ce08d38496f31 100644 (file)
 #              define NV_CIO_CRE_EBR_VDE_11            2:2
 #              define NV_CIO_CRE_EBR_VRS_11            4:4
 #              define NV_CIO_CRE_EBR_VBS_11            6:6
+#      define NV_CIO_CRE_42                    0x42
+#              define NV_CIO_CRE_42_OFFSET_11          6:6
 #      define NV_CIO_CRE_43                    0x43
 #      define NV_CIO_CRE_44                    0x44    /* head control */
 #      define NV_CIO_CRE_CSB                   0x45    /* colour saturation boost */
index 9746fee59f567856511b0eae1a2ed9310e3e52d0..ea92bbe3ed37002865f8850255a4e68859a0c8c7 100644 (file)
@@ -28,11 +28,4 @@ config DRM_RADEON_KMS
          The kernel will also perform security check on command stream
          provided by the user, we want to catch and forbid any illegal use
          of the GPU such as DMA into random system memory or into memory
-         not owned by the process supplying the command stream. This part
-         of the code is still incomplete and this why we propose that patch
-         as a staging driver addition, future security might forbid current
-         experimental userspace to run.
-
-         This code support the following hardware : R1XX,R2XX,R3XX,R4XX,R5XX
-         (radeon up to X1950). Works is underway to provide support for R6XX,
-         R7XX and newer hardware (radeon from HD2XXX to HD4XXX).
+         not owned by the process supplying the command stream.
index ec848787d7d9ee260e8edd6642563f6f7436fe94..84a69e7fa11e898769041160be2cc32fbb5ec146 100644 (file)
@@ -1045,7 +1045,7 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
        uint64_t fb_location;
        uint32_t fb_format, fb_pitch_pixels, tiling_flags;
        u32 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_NONE);
-       u32 tmp;
+       u32 tmp, viewport_w, viewport_h;
        int r;
 
        /* no fb bound */
@@ -1171,8 +1171,10 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
        y &= ~1;
        WREG32(EVERGREEN_VIEWPORT_START + radeon_crtc->crtc_offset,
               (x << 16) | y);
+       viewport_w = crtc->mode.hdisplay;
+       viewport_h = (crtc->mode.vdisplay + 1) & ~1;
        WREG32(EVERGREEN_VIEWPORT_SIZE + radeon_crtc->crtc_offset,
-              (crtc->mode.hdisplay << 16) | crtc->mode.vdisplay);
+              (viewport_w << 16) | viewport_h);
 
        /* pageflip setup */
        /* make sure flip is at vb rather than hb */
@@ -1213,7 +1215,7 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc,
        uint64_t fb_location;
        uint32_t fb_format, fb_pitch_pixels, tiling_flags;
        u32 fb_swap = R600_D1GRPH_SWAP_ENDIAN_NONE;
-       u32 tmp;
+       u32 tmp, viewport_w, viewport_h;
        int r;
 
        /* no fb bound */
@@ -1338,8 +1340,10 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc,
        y &= ~1;
        WREG32(AVIVO_D1MODE_VIEWPORT_START + radeon_crtc->crtc_offset,
               (x << 16) | y);
+       viewport_w = crtc->mode.hdisplay;
+       viewport_h = (crtc->mode.vdisplay + 1) & ~1;
        WREG32(AVIVO_D1MODE_VIEWPORT_SIZE + radeon_crtc->crtc_offset,
-              (crtc->mode.hdisplay << 16) | crtc->mode.vdisplay);
+              (viewport_w << 16) | viewport_h);
 
        /* pageflip setup */
        /* make sure flip is at vb rather than hb */
index e148ab04b80b3adc88d0ac4a0329599f57ac2c00..7b4eeb7b4a8c5c3205e1f5c91cd3e51c53658c42 100644 (file)
 
 const u32 cayman_default_state[] =
 {
-       /* XXX fill in additional blit state */
+       0xc0066900,
+       0x00000000,
+       0x00000060, /* DB_RENDER_CONTROL */
+       0x00000000, /* DB_COUNT_CONTROL */
+       0x00000000, /* DB_DEPTH_VIEW */
+       0x0000002a, /* DB_RENDER_OVERRIDE */
+       0x00000000, /* DB_RENDER_OVERRIDE2 */
+       0x00000000, /* DB_HTILE_DATA_BASE */
 
        0xc0026900,
-       0x00000316,
-       0x0000000e, /* VGT_VERTEX_REUSE_BLOCK_CNTL */
-       0x00000010, /*  */
+       0x0000000a,
+       0x00000000, /* DB_STENCIL_CLEAR */
+       0x00000000, /* DB_DEPTH_CLEAR */
+
+       0xc0036900,
+       0x0000000f,
+       0x00000000, /* DB_DEPTH_INFO */
+       0x00000000, /* DB_Z_INFO */
+       0x00000000, /* DB_STENCIL_INFO */
+
+       0xc0016900,
+       0x00000080,
+       0x00000000, /* PA_SC_WINDOW_OFFSET */
+
+       0xc00d6900,
+       0x00000083,
+       0x0000ffff, /* PA_SC_CLIPRECT_RULE */
+       0x00000000, /* PA_SC_CLIPRECT_0_TL */
+       0x20002000, /* PA_SC_CLIPRECT_0_BR */
+       0x00000000,
+       0x20002000,
+       0x00000000,
+       0x20002000,
+       0x00000000,
+       0x20002000,
+       0xaaaaaaaa, /* PA_SC_EDGERULE */
+       0x00000000, /* PA_SU_HARDWARE_SCREEN_OFFSET */
+       0x0000000f, /* CB_TARGET_MASK */
+       0x0000000f, /* CB_SHADER_MASK */
+
+       0xc0226900,
+       0x00000094,
+       0x80000000, /* PA_SC_VPORT_SCISSOR_0_TL */
+       0x20002000, /* PA_SC_VPORT_SCISSOR_0_BR */
+       0x80000000,
+       0x20002000,
+       0x80000000,
+       0x20002000,
+       0x80000000,
+       0x20002000,
+       0x80000000,
+       0x20002000,
+       0x80000000,
+       0x20002000,
+       0x80000000,
+       0x20002000,
+       0x80000000,
+       0x20002000,
+       0x80000000,
+       0x20002000,
+       0x80000000,
+       0x20002000,
+       0x80000000,
+       0x20002000,
+       0x80000000,
+       0x20002000,
+       0x80000000,
+       0x20002000,
+       0x80000000,
+       0x20002000,
+       0x80000000,
+       0x20002000,
+       0x80000000,
+       0x20002000,
+       0x00000000, /* PA_SC_VPORT_ZMIN_0 */
+       0x3f800000, /* PA_SC_VPORT_ZMAX_0 */
+
+       0xc0016900,
+       0x000000d4,
+       0x00000000, /* SX_MISC */
 
        0xc0026900,
        0x000000d9,
        0x00000000, /* CP_RINGID */
        0x00000000, /* CP_VMID */
+
+       0xc0096900,
+       0x00000100,
+       0x00ffffff, /* VGT_MAX_VTX_INDX */
+       0x00000000, /* VGT_MIN_VTX_INDX */
+       0x00000000, /* VGT_INDX_OFFSET */
+       0x00000000, /* VGT_MULTI_PRIM_IB_RESET_INDX */
+       0x00000000, /* SX_ALPHA_TEST_CONTROL */
+       0x00000000, /* CB_BLEND_RED */
+       0x00000000, /* CB_BLEND_GREEN */
+       0x00000000, /* CB_BLEND_BLUE */
+       0x00000000, /* CB_BLEND_ALPHA */
+
+       0xc0016900,
+       0x00000187,
+       0x00000100, /* SPI_VS_OUT_ID_0 */
+
+       0xc0026900,
+       0x00000191,
+       0x00000100, /* SPI_PS_INPUT_CNTL_0 */
+       0x00000101, /* SPI_PS_INPUT_CNTL_1 */
+
+       0xc0016900,
+       0x000001b1,
+       0x00000000, /* SPI_VS_OUT_CONFIG */
+
+       0xc0106900,
+       0x000001b3,
+       0x20000001, /* SPI_PS_IN_CONTROL_0 */
+       0x00000000, /* SPI_PS_IN_CONTROL_1 */
+       0x00000000, /* SPI_INTERP_CONTROL_0 */
+       0x00000000, /* SPI_INPUT_Z */
+       0x00000000, /* SPI_FOG_CNTL */
+       0x00100000, /* SPI_BARYC_CNTL */
+       0x00000000, /* SPI_PS_IN_CONTROL_2 */
+       0x00000000, /* SPI_COMPUTE_INPUT_CNTL */
+       0x00000000, /* SPI_COMPUTE_NUM_THREAD_X */
+       0x00000000, /* SPI_COMPUTE_NUM_THREAD_Y */
+       0x00000000, /* SPI_COMPUTE_NUM_THREAD_Z */
+       0x00000000, /* SPI_GPR_MGMT */
+       0x00000000, /* SPI_LDS_MGMT */
+       0x00000000, /* SPI_STACK_MGMT */
+       0x00000000, /* SPI_WAVE_MGMT_1 */
+       0x00000000, /* SPI_WAVE_MGMT_2 */
+
+       0xc0016900,
+       0x000001e0,
+       0x00000000, /* CB_BLEND0_CONTROL */
+
+       0xc00e6900,
+       0x00000200,
+       0x00000000, /* DB_DEPTH_CONTROL */
+       0x00000000, /* DB_EQAA */
+       0x00cc0010, /* CB_COLOR_CONTROL */
+       0x00000210, /* DB_SHADER_CONTROL */
+       0x00010000, /* PA_CL_CLIP_CNTL */
+       0x00000004, /* PA_SU_SC_MODE_CNTL */
+       0x00000100, /* PA_CL_VTE_CNTL */
+       0x00000000, /* PA_CL_VS_OUT_CNTL */
+       0x00000000, /* PA_CL_NANINF_CNTL */
+       0x00000000, /* PA_SU_LINE_STIPPLE_CNTL */
+       0x00000000, /* PA_SU_LINE_STIPPLE_SCALE */
+       0x00000000, /* PA_SU_PRIM_FILTER_CNTL */
+       0x00000000, /*  */
+       0x00000000, /*  */
+
+       0xc0026900,
+       0x00000229,
+       0x00000000, /* SQ_PGM_START_FS */
+       0x00000000,
+
+       0xc0016900,
+       0x0000023b,
+       0x00000000, /* SQ_LDS_ALLOC_PS */
+
+       0xc0066900,
+       0x00000240,
+       0x00000000, /* SQ_ESGS_RING_ITEMSIZE */
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+
+       0xc0046900,
+       0x00000247,
+       0x00000000, /* SQ_GS_VERT_ITEMSIZE */
+       0x00000000,
+       0x00000000,
+       0x00000000,
+
+       0xc0116900,
+       0x00000280,
+       0x00000000, /* PA_SU_POINT_SIZE */
+       0x00000000, /* PA_SU_POINT_MINMAX */
+       0x00000008, /* PA_SU_LINE_CNTL */
+       0x00000000, /* PA_SC_LINE_STIPPLE */
+       0x00000000, /* VGT_OUTPUT_PATH_CNTL */
+       0x00000000, /* VGT_HOS_CNTL */
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000, /* VGT_GS_MODE */
+
+       0xc0026900,
+       0x00000292,
+       0x00000000, /* PA_SC_MODE_CNTL_0 */
+       0x00000000, /* PA_SC_MODE_CNTL_1 */
+
+       0xc0016900,
+       0x000002a1,
+       0x00000000, /* VGT_PRIMITIVEID_EN */
+
+       0xc0016900,
+       0x000002a5,
+       0x00000000, /* VGT_MULTI_PRIM_IB_RESET_EN */
+
+       0xc0026900,
+       0x000002a8,
+       0x00000000, /* VGT_INSTANCE_STEP_RATE_0 */
+       0x00000000,
+
+       0xc0026900,
+       0x000002ad,
+       0x00000000, /* VGT_REUSE_OFF */
+       0x00000000,
+
+       0xc0016900,
+       0x000002d5,
+       0x00000000, /* VGT_SHADER_STAGES_EN */
+
+       0xc0016900,
+       0x000002dc,
+       0x0000aa00, /* DB_ALPHA_TO_MASK */
+
+       0xc0066900,
+       0x000002de,
+       0x00000000, /* PA_SU_POLY_OFFSET_DB_FMT_CNTL */
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+
+       0xc0026900,
+       0x000002e5,
+       0x00000000, /* VGT_STRMOUT_CONFIG */
+       0x00000000,
+
+       0xc01b6900,
+       0x000002f5,
+       0x76543210, /* PA_SC_CENTROID_PRIORITY_0 */
+       0xfedcba98, /* PA_SC_CENTROID_PRIORITY_1 */
+       0x00000000, /* PA_SC_LINE_CNTL */
+       0x00000000, /* PA_SC_AA_CONFIG */
+       0x00000005, /* PA_SU_VTX_CNTL */
+       0x3f800000, /* PA_CL_GB_VERT_CLIP_ADJ */
+       0x3f800000, /* PA_CL_GB_VERT_DISC_ADJ */
+       0x3f800000, /* PA_CL_GB_HORZ_CLIP_ADJ */
+       0x3f800000, /* PA_CL_GB_HORZ_DISC_ADJ */
+       0x00000000, /* PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0 */
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0xffffffff, /* PA_SC_AA_MASK_X0Y0_X1Y0 */
+       0xffffffff,
+
+       0xc0026900,
+       0x00000316,
+       0x0000000e, /* VGT_VERTEX_REUSE_BLOCK_CNTL */
+       0x00000010, /*  */
+};
+
+const u32 cayman_vs[] =
+{
+       0x00000004,
+       0x80400400,
+       0x0000a03c,
+       0x95000688,
+       0x00004000,
+       0x15000688,
+       0x00000000,
+       0x88000000,
+       0x04000000,
+       0x67961001,
+#ifdef __BIG_ENDIAN
+       0x00020000,
+#else
+       0x00000000,
+#endif
+       0x00000000,
+       0x04000000,
+       0x67961000,
+#ifdef __BIG_ENDIAN
+       0x00020008,
+#else
+       0x00000008,
+#endif
+       0x00000000,
+};
+
+const u32 cayman_ps[] =
+{
+       0x00000004,
+       0xa00c0000,
+       0x00000008,
+       0x80400000,
+       0x00000000,
+       0x95000688,
+       0x00000000,
+       0x88000000,
+       0x00380400,
+       0x00146b10,
+       0x00380000,
+       0x20146b10,
+       0x00380400,
+       0x40146b00,
+       0x80380000,
+       0x60146b00,
+       0x00000010,
+       0x000d1000,
+       0xb0800000,
+       0x00000000,
 };
 
+const u32 cayman_ps_size = ARRAY_SIZE(cayman_ps);
+const u32 cayman_vs_size = ARRAY_SIZE(cayman_vs);
 const u32 cayman_default_size = ARRAY_SIZE(cayman_default_state);
index 33b75e5d0fa468e64d1a0c15292fa72a7bc0cee6..f5d0e9a602675d24b135a4491d583d44e53bcbec 100644 (file)
 #ifndef CAYMAN_BLIT_SHADERS_H
 #define CAYMAN_BLIT_SHADERS_H
 
+extern const u32 cayman_ps[];
+extern const u32 cayman_vs[];
 extern const u32 cayman_default_state[];
 
+extern const u32 cayman_ps_size, cayman_vs_size;
 extern const u32 cayman_default_size;
 
 #endif
index 7c37638095f7d1fa01624116d464e1d2a22ce8d9..98ea597bc76d88566644a00eca83113c6d8a787e 100644 (file)
@@ -88,21 +88,39 @@ u32 evergreen_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
 /* get temperature in millidegrees */
 int evergreen_get_temp(struct radeon_device *rdev)
 {
-       u32 temp = (RREG32(CG_MULT_THERMAL_STATUS) & ASIC_T_MASK) >>
-               ASIC_T_SHIFT;
-       u32 actual_temp = 0;
-
-       if (temp & 0x400)
-               actual_temp = -256;
-       else if (temp & 0x200)
-               actual_temp = 255;
-       else if (temp & 0x100) {
-               actual_temp = temp & 0x1ff;
-               actual_temp |= ~0x1ff;
-       } else
-               actual_temp = temp & 0xff;
+       u32 temp, toffset, actual_temp = 0;
+
+       if (rdev->family == CHIP_JUNIPER) {
+               toffset = (RREG32(CG_THERMAL_CTRL) & TOFFSET_MASK) >>
+                       TOFFSET_SHIFT;
+               temp = (RREG32(CG_TS0_STATUS) & TS0_ADC_DOUT_MASK) >>
+                       TS0_ADC_DOUT_SHIFT;
+
+               if (toffset & 0x100)
+                       actual_temp = temp / 2 - (0x200 - toffset);
+               else
+                       actual_temp = temp / 2 + toffset;
+
+               actual_temp = actual_temp * 1000;
+
+       } else {
+               temp = (RREG32(CG_MULT_THERMAL_STATUS) & ASIC_T_MASK) >>
+                       ASIC_T_SHIFT;
 
-       return (actual_temp * 1000) / 2;
+               if (temp & 0x400)
+                       actual_temp = -256;
+               else if (temp & 0x200)
+                       actual_temp = 255;
+               else if (temp & 0x100) {
+                       actual_temp = temp & 0x1ff;
+                       actual_temp |= ~0x1ff;
+               } else
+                       actual_temp = temp & 0xff;
+
+               actual_temp = (actual_temp * 1000) / 2;
+       }
+
+       return actual_temp;
 }
 
 int sumo_get_temp(struct radeon_device *rdev)
@@ -1415,6 +1433,8 @@ static u32 evergreen_get_tile_pipe_to_backend_map(struct radeon_device *rdev,
        case CHIP_CEDAR:
        case CHIP_REDWOOD:
        case CHIP_PALM:
+       case CHIP_SUMO:
+       case CHIP_SUMO2:
        case CHIP_TURKS:
        case CHIP_CAICOS:
                force_no_swizzle = false;
@@ -1544,6 +1564,8 @@ static void evergreen_program_channel_remap(struct radeon_device *rdev)
        case CHIP_REDWOOD:
        case CHIP_CEDAR:
        case CHIP_PALM:
+       case CHIP_SUMO:
+       case CHIP_SUMO2:
        case CHIP_TURKS:
        case CHIP_CAICOS:
        default:
@@ -1685,6 +1707,54 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
                rdev->config.evergreen.max_hw_contexts = 4;
                rdev->config.evergreen.sq_num_cf_insts = 1;
 
+               rdev->config.evergreen.sc_prim_fifo_size = 0x40;
+               rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30;
+               rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130;
+               break;
+       case CHIP_SUMO:
+               rdev->config.evergreen.num_ses = 1;
+               rdev->config.evergreen.max_pipes = 4;
+               rdev->config.evergreen.max_tile_pipes = 2;
+               if (rdev->pdev->device == 0x9648)
+                       rdev->config.evergreen.max_simds = 3;
+               else if ((rdev->pdev->device == 0x9647) ||
+                        (rdev->pdev->device == 0x964a))
+                       rdev->config.evergreen.max_simds = 4;
+               else
+                       rdev->config.evergreen.max_simds = 5;
+               rdev->config.evergreen.max_backends = 2 * rdev->config.evergreen.num_ses;
+               rdev->config.evergreen.max_gprs = 256;
+               rdev->config.evergreen.max_threads = 248;
+               rdev->config.evergreen.max_gs_threads = 32;
+               rdev->config.evergreen.max_stack_entries = 256;
+               rdev->config.evergreen.sx_num_of_sets = 4;
+               rdev->config.evergreen.sx_max_export_size = 256;
+               rdev->config.evergreen.sx_max_export_pos_size = 64;
+               rdev->config.evergreen.sx_max_export_smx_size = 192;
+               rdev->config.evergreen.max_hw_contexts = 8;
+               rdev->config.evergreen.sq_num_cf_insts = 2;
+
+               rdev->config.evergreen.sc_prim_fifo_size = 0x40;
+               rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30;
+               rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130;
+               break;
+       case CHIP_SUMO2:
+               rdev->config.evergreen.num_ses = 1;
+               rdev->config.evergreen.max_pipes = 4;
+               rdev->config.evergreen.max_tile_pipes = 4;
+               rdev->config.evergreen.max_simds = 2;
+               rdev->config.evergreen.max_backends = 1 * rdev->config.evergreen.num_ses;
+               rdev->config.evergreen.max_gprs = 256;
+               rdev->config.evergreen.max_threads = 248;
+               rdev->config.evergreen.max_gs_threads = 32;
+               rdev->config.evergreen.max_stack_entries = 512;
+               rdev->config.evergreen.sx_num_of_sets = 4;
+               rdev->config.evergreen.sx_max_export_size = 256;
+               rdev->config.evergreen.sx_max_export_pos_size = 64;
+               rdev->config.evergreen.sx_max_export_smx_size = 192;
+               rdev->config.evergreen.max_hw_contexts = 8;
+               rdev->config.evergreen.sq_num_cf_insts = 2;
+
                rdev->config.evergreen.sc_prim_fifo_size = 0x40;
                rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30;
                rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130;
@@ -2039,6 +2109,8 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
        switch (rdev->family) {
        case CHIP_CEDAR:
        case CHIP_PALM:
+       case CHIP_SUMO:
+       case CHIP_SUMO2:
        case CHIP_CAICOS:
                /* no vertex cache */
                sq_config &= ~VC_ENABLE;
@@ -2060,6 +2132,8 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
        switch (rdev->family) {
        case CHIP_CEDAR:
        case CHIP_PALM:
+       case CHIP_SUMO:
+       case CHIP_SUMO2:
                ps_thread_count = 96;
                break;
        default:
@@ -2099,6 +2173,8 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
        switch (rdev->family) {
        case CHIP_CEDAR:
        case CHIP_PALM:
+       case CHIP_SUMO:
+       case CHIP_SUMO2:
        case CHIP_CAICOS:
                vgt_cache_invalidation = CACHE_INVALIDATION(TC_ONLY);
                break;
index ba06a69c6de857bd250b6c7258faa8a308361e43..57f3bc17b87e09a9dd0d1fd99fe66800e43ee9fb 100644 (file)
@@ -31,6 +31,7 @@
 
 #include "evergreend.h"
 #include "evergreen_blit_shaders.h"
+#include "cayman_blit_shaders.h"
 
 #define DI_PT_RECTLIST        0x11
 #define DI_INDEX_SIZE_16_BIT  0x0
@@ -152,6 +153,8 @@ set_vtx_resource(struct radeon_device *rdev, u64 gpu_addr)
 
        if ((rdev->family == CHIP_CEDAR) ||
            (rdev->family == CHIP_PALM) ||
+           (rdev->family == CHIP_SUMO) ||
+           (rdev->family == CHIP_SUMO2) ||
            (rdev->family == CHIP_CAICOS))
                cp_set_surface_sync(rdev,
                                    PACKET3_TC_ACTION_ENA, 48, gpu_addr);
@@ -199,6 +202,16 @@ static void
 set_scissors(struct radeon_device *rdev, int x1, int y1,
             int x2, int y2)
 {
+       /* workaround some hw bugs */
+       if (x2 == 0)
+               x1 = 1;
+       if (y2 == 0)
+               y1 = 1;
+       if (rdev->family == CHIP_CAYMAN) {
+               if ((x2 == 1) && (y2 == 1))
+                       x2 = 2;
+       }
+
        radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 2));
        radeon_ring_write(rdev, (PA_SC_SCREEN_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_START) >> 2);
        radeon_ring_write(rdev, (x1 << 0) | (y1 << 16));
@@ -255,238 +268,284 @@ set_default_state(struct radeon_device *rdev)
        u64 gpu_addr;
        int dwords;
 
-       switch (rdev->family) {
-       case CHIP_CEDAR:
-       default:
-               num_ps_gprs = 93;
-               num_vs_gprs = 46;
-               num_temp_gprs = 4;
-               num_gs_gprs = 31;
-               num_es_gprs = 31;
-               num_hs_gprs = 23;
-               num_ls_gprs = 23;
-               num_ps_threads = 96;
-               num_vs_threads = 16;
-               num_gs_threads = 16;
-               num_es_threads = 16;
-               num_hs_threads = 16;
-               num_ls_threads = 16;
-               num_ps_stack_entries = 42;
-               num_vs_stack_entries = 42;
-               num_gs_stack_entries = 42;
-               num_es_stack_entries = 42;
-               num_hs_stack_entries = 42;
-               num_ls_stack_entries = 42;
-               break;
-       case CHIP_REDWOOD:
-               num_ps_gprs = 93;
-               num_vs_gprs = 46;
-               num_temp_gprs = 4;
-               num_gs_gprs = 31;
-               num_es_gprs = 31;
-               num_hs_gprs = 23;
-               num_ls_gprs = 23;
-               num_ps_threads = 128;
-               num_vs_threads = 20;
-               num_gs_threads = 20;
-               num_es_threads = 20;
-               num_hs_threads = 20;
-               num_ls_threads = 20;
-               num_ps_stack_entries = 42;
-               num_vs_stack_entries = 42;
-               num_gs_stack_entries = 42;
-               num_es_stack_entries = 42;
-               num_hs_stack_entries = 42;
-               num_ls_stack_entries = 42;
-               break;
-       case CHIP_JUNIPER:
-               num_ps_gprs = 93;
-               num_vs_gprs = 46;
-               num_temp_gprs = 4;
-               num_gs_gprs = 31;
-               num_es_gprs = 31;
-               num_hs_gprs = 23;
-               num_ls_gprs = 23;
-               num_ps_threads = 128;
-               num_vs_threads = 20;
-               num_gs_threads = 20;
-               num_es_threads = 20;
-               num_hs_threads = 20;
-               num_ls_threads = 20;
-               num_ps_stack_entries = 85;
-               num_vs_stack_entries = 85;
-               num_gs_stack_entries = 85;
-               num_es_stack_entries = 85;
-               num_hs_stack_entries = 85;
-               num_ls_stack_entries = 85;
-               break;
-       case CHIP_CYPRESS:
-       case CHIP_HEMLOCK:
-               num_ps_gprs = 93;
-               num_vs_gprs = 46;
-               num_temp_gprs = 4;
-               num_gs_gprs = 31;
-               num_es_gprs = 31;
-               num_hs_gprs = 23;
-               num_ls_gprs = 23;
-               num_ps_threads = 128;
-               num_vs_threads = 20;
-               num_gs_threads = 20;
-               num_es_threads = 20;
-               num_hs_threads = 20;
-               num_ls_threads = 20;
-               num_ps_stack_entries = 85;
-               num_vs_stack_entries = 85;
-               num_gs_stack_entries = 85;
-               num_es_stack_entries = 85;
-               num_hs_stack_entries = 85;
-               num_ls_stack_entries = 85;
-               break;
-       case CHIP_PALM:
-               num_ps_gprs = 93;
-               num_vs_gprs = 46;
-               num_temp_gprs = 4;
-               num_gs_gprs = 31;
-               num_es_gprs = 31;
-               num_hs_gprs = 23;
-               num_ls_gprs = 23;
-               num_ps_threads = 96;
-               num_vs_threads = 16;
-               num_gs_threads = 16;
-               num_es_threads = 16;
-               num_hs_threads = 16;
-               num_ls_threads = 16;
-               num_ps_stack_entries = 42;
-               num_vs_stack_entries = 42;
-               num_gs_stack_entries = 42;
-               num_es_stack_entries = 42;
-               num_hs_stack_entries = 42;
-               num_ls_stack_entries = 42;
-               break;
-       case CHIP_BARTS:
-               num_ps_gprs = 93;
-               num_vs_gprs = 46;
-               num_temp_gprs = 4;
-               num_gs_gprs = 31;
-               num_es_gprs = 31;
-               num_hs_gprs = 23;
-               num_ls_gprs = 23;
-               num_ps_threads = 128;
-               num_vs_threads = 20;
-               num_gs_threads = 20;
-               num_es_threads = 20;
-               num_hs_threads = 20;
-               num_ls_threads = 20;
-               num_ps_stack_entries = 85;
-               num_vs_stack_entries = 85;
-               num_gs_stack_entries = 85;
-               num_es_stack_entries = 85;
-               num_hs_stack_entries = 85;
-               num_ls_stack_entries = 85;
-               break;
-       case CHIP_TURKS:
-               num_ps_gprs = 93;
-               num_vs_gprs = 46;
-               num_temp_gprs = 4;
-               num_gs_gprs = 31;
-               num_es_gprs = 31;
-               num_hs_gprs = 23;
-               num_ls_gprs = 23;
-               num_ps_threads = 128;
-               num_vs_threads = 20;
-               num_gs_threads = 20;
-               num_es_threads = 20;
-               num_hs_threads = 20;
-               num_ls_threads = 20;
-               num_ps_stack_entries = 42;
-               num_vs_stack_entries = 42;
-               num_gs_stack_entries = 42;
-               num_es_stack_entries = 42;
-               num_hs_stack_entries = 42;
-               num_ls_stack_entries = 42;
-               break;
-       case CHIP_CAICOS:
-               num_ps_gprs = 93;
-               num_vs_gprs = 46;
-               num_temp_gprs = 4;
-               num_gs_gprs = 31;
-               num_es_gprs = 31;
-               num_hs_gprs = 23;
-               num_ls_gprs = 23;
-               num_ps_threads = 128;
-               num_vs_threads = 10;
-               num_gs_threads = 10;
-               num_es_threads = 10;
-               num_hs_threads = 10;
-               num_ls_threads = 10;
-               num_ps_stack_entries = 42;
-               num_vs_stack_entries = 42;
-               num_gs_stack_entries = 42;
-               num_es_stack_entries = 42;
-               num_hs_stack_entries = 42;
-               num_ls_stack_entries = 42;
-               break;
-       }
-
-       if ((rdev->family == CHIP_CEDAR) ||
-           (rdev->family == CHIP_PALM) ||
-           (rdev->family == CHIP_CAICOS))
-               sq_config = 0;
-       else
-               sq_config = VC_ENABLE;
-
-       sq_config |= (EXPORT_SRC_C |
-                     CS_PRIO(0) |
-                     LS_PRIO(0) |
-                     HS_PRIO(0) |
-                     PS_PRIO(0) |
-                     VS_PRIO(1) |
-                     GS_PRIO(2) |
-                     ES_PRIO(3));
-
-       sq_gpr_resource_mgmt_1 = (NUM_PS_GPRS(num_ps_gprs) |
-                                 NUM_VS_GPRS(num_vs_gprs) |
-                                 NUM_CLAUSE_TEMP_GPRS(num_temp_gprs));
-       sq_gpr_resource_mgmt_2 = (NUM_GS_GPRS(num_gs_gprs) |
-                                 NUM_ES_GPRS(num_es_gprs));
-       sq_gpr_resource_mgmt_3 = (NUM_HS_GPRS(num_hs_gprs) |
-                                 NUM_LS_GPRS(num_ls_gprs));
-       sq_thread_resource_mgmt = (NUM_PS_THREADS(num_ps_threads) |
-                                  NUM_VS_THREADS(num_vs_threads) |
-                                  NUM_GS_THREADS(num_gs_threads) |
-                                  NUM_ES_THREADS(num_es_threads));
-       sq_thread_resource_mgmt_2 = (NUM_HS_THREADS(num_hs_threads) |
-                                    NUM_LS_THREADS(num_ls_threads));
-       sq_stack_resource_mgmt_1 = (NUM_PS_STACK_ENTRIES(num_ps_stack_entries) |
-                                   NUM_VS_STACK_ENTRIES(num_vs_stack_entries));
-       sq_stack_resource_mgmt_2 = (NUM_GS_STACK_ENTRIES(num_gs_stack_entries) |
-                                   NUM_ES_STACK_ENTRIES(num_es_stack_entries));
-       sq_stack_resource_mgmt_3 = (NUM_HS_STACK_ENTRIES(num_hs_stack_entries) |
-                                   NUM_LS_STACK_ENTRIES(num_ls_stack_entries));
-
        /* set clear context state */
        radeon_ring_write(rdev, PACKET3(PACKET3_CLEAR_STATE, 0));
        radeon_ring_write(rdev, 0);
 
-       /* disable dyn gprs */
-       radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1));
-       radeon_ring_write(rdev, (SQ_DYN_GPR_CNTL_PS_FLUSH_REQ - PACKET3_SET_CONFIG_REG_START) >> 2);
-       radeon_ring_write(rdev, 0);
+       if (rdev->family < CHIP_CAYMAN) {
+               switch (rdev->family) {
+               case CHIP_CEDAR:
+               default:
+                       num_ps_gprs = 93;
+                       num_vs_gprs = 46;
+                       num_temp_gprs = 4;
+                       num_gs_gprs = 31;
+                       num_es_gprs = 31;
+                       num_hs_gprs = 23;
+                       num_ls_gprs = 23;
+                       num_ps_threads = 96;
+                       num_vs_threads = 16;
+                       num_gs_threads = 16;
+                       num_es_threads = 16;
+                       num_hs_threads = 16;
+                       num_ls_threads = 16;
+                       num_ps_stack_entries = 42;
+                       num_vs_stack_entries = 42;
+                       num_gs_stack_entries = 42;
+                       num_es_stack_entries = 42;
+                       num_hs_stack_entries = 42;
+                       num_ls_stack_entries = 42;
+                       break;
+               case CHIP_REDWOOD:
+                       num_ps_gprs = 93;
+                       num_vs_gprs = 46;
+                       num_temp_gprs = 4;
+                       num_gs_gprs = 31;
+                       num_es_gprs = 31;
+                       num_hs_gprs = 23;
+                       num_ls_gprs = 23;
+                       num_ps_threads = 128;
+                       num_vs_threads = 20;
+                       num_gs_threads = 20;
+                       num_es_threads = 20;
+                       num_hs_threads = 20;
+                       num_ls_threads = 20;
+                       num_ps_stack_entries = 42;
+                       num_vs_stack_entries = 42;
+                       num_gs_stack_entries = 42;
+                       num_es_stack_entries = 42;
+                       num_hs_stack_entries = 42;
+                       num_ls_stack_entries = 42;
+                       break;
+               case CHIP_JUNIPER:
+                       num_ps_gprs = 93;
+                       num_vs_gprs = 46;
+                       num_temp_gprs = 4;
+                       num_gs_gprs = 31;
+                       num_es_gprs = 31;
+                       num_hs_gprs = 23;
+                       num_ls_gprs = 23;
+                       num_ps_threads = 128;
+                       num_vs_threads = 20;
+                       num_gs_threads = 20;
+                       num_es_threads = 20;
+                       num_hs_threads = 20;
+                       num_ls_threads = 20;
+                       num_ps_stack_entries = 85;
+                       num_vs_stack_entries = 85;
+                       num_gs_stack_entries = 85;
+                       num_es_stack_entries = 85;
+                       num_hs_stack_entries = 85;
+                       num_ls_stack_entries = 85;
+                       break;
+               case CHIP_CYPRESS:
+               case CHIP_HEMLOCK:
+                       num_ps_gprs = 93;
+                       num_vs_gprs = 46;
+                       num_temp_gprs = 4;
+                       num_gs_gprs = 31;
+                       num_es_gprs = 31;
+                       num_hs_gprs = 23;
+                       num_ls_gprs = 23;
+                       num_ps_threads = 128;
+                       num_vs_threads = 20;
+                       num_gs_threads = 20;
+                       num_es_threads = 20;
+                       num_hs_threads = 20;
+                       num_ls_threads = 20;
+                       num_ps_stack_entries = 85;
+                       num_vs_stack_entries = 85;
+                       num_gs_stack_entries = 85;
+                       num_es_stack_entries = 85;
+                       num_hs_stack_entries = 85;
+                       num_ls_stack_entries = 85;
+                       break;
+               case CHIP_PALM:
+                       num_ps_gprs = 93;
+                       num_vs_gprs = 46;
+                       num_temp_gprs = 4;
+                       num_gs_gprs = 31;
+                       num_es_gprs = 31;
+                       num_hs_gprs = 23;
+                       num_ls_gprs = 23;
+                       num_ps_threads = 96;
+                       num_vs_threads = 16;
+                       num_gs_threads = 16;
+                       num_es_threads = 16;
+                       num_hs_threads = 16;
+                       num_ls_threads = 16;
+                       num_ps_stack_entries = 42;
+                       num_vs_stack_entries = 42;
+                       num_gs_stack_entries = 42;
+                       num_es_stack_entries = 42;
+                       num_hs_stack_entries = 42;
+                       num_ls_stack_entries = 42;
+                       break;
+               case CHIP_SUMO:
+                       num_ps_gprs = 93;
+                       num_vs_gprs = 46;
+                       num_temp_gprs = 4;
+                       num_gs_gprs = 31;
+                       num_es_gprs = 31;
+                       num_hs_gprs = 23;
+                       num_ls_gprs = 23;
+                       num_ps_threads = 96;
+                       num_vs_threads = 25;
+                       num_gs_threads = 25;
+                       num_es_threads = 25;
+                       num_hs_threads = 25;
+                       num_ls_threads = 25;
+                       num_ps_stack_entries = 42;
+                       num_vs_stack_entries = 42;
+                       num_gs_stack_entries = 42;
+                       num_es_stack_entries = 42;
+                       num_hs_stack_entries = 42;
+                       num_ls_stack_entries = 42;
+                       break;
+               case CHIP_SUMO2:
+                       num_ps_gprs = 93;
+                       num_vs_gprs = 46;
+                       num_temp_gprs = 4;
+                       num_gs_gprs = 31;
+                       num_es_gprs = 31;
+                       num_hs_gprs = 23;
+                       num_ls_gprs = 23;
+                       num_ps_threads = 96;
+                       num_vs_threads = 25;
+                       num_gs_threads = 25;
+                       num_es_threads = 25;
+                       num_hs_threads = 25;
+                       num_ls_threads = 25;
+                       num_ps_stack_entries = 85;
+                       num_vs_stack_entries = 85;
+                       num_gs_stack_entries = 85;
+                       num_es_stack_entries = 85;
+                       num_hs_stack_entries = 85;
+                       num_ls_stack_entries = 85;
+                       break;
+               case CHIP_BARTS:
+                       num_ps_gprs = 93;
+                       num_vs_gprs = 46;
+                       num_temp_gprs = 4;
+                       num_gs_gprs = 31;
+                       num_es_gprs = 31;
+                       num_hs_gprs = 23;
+                       num_ls_gprs = 23;
+                       num_ps_threads = 128;
+                       num_vs_threads = 20;
+                       num_gs_threads = 20;
+                       num_es_threads = 20;
+                       num_hs_threads = 20;
+                       num_ls_threads = 20;
+                       num_ps_stack_entries = 85;
+                       num_vs_stack_entries = 85;
+                       num_gs_stack_entries = 85;
+                       num_es_stack_entries = 85;
+                       num_hs_stack_entries = 85;
+                       num_ls_stack_entries = 85;
+                       break;
+               case CHIP_TURKS:
+                       num_ps_gprs = 93;
+                       num_vs_gprs = 46;
+                       num_temp_gprs = 4;
+                       num_gs_gprs = 31;
+                       num_es_gprs = 31;
+                       num_hs_gprs = 23;
+                       num_ls_gprs = 23;
+                       num_ps_threads = 128;
+                       num_vs_threads = 20;
+                       num_gs_threads = 20;
+                       num_es_threads = 20;
+                       num_hs_threads = 20;
+                       num_ls_threads = 20;
+                       num_ps_stack_entries = 42;
+                       num_vs_stack_entries = 42;
+                       num_gs_stack_entries = 42;
+                       num_es_stack_entries = 42;
+                       num_hs_stack_entries = 42;
+                       num_ls_stack_entries = 42;
+                       break;
+               case CHIP_CAICOS:
+                       num_ps_gprs = 93;
+                       num_vs_gprs = 46;
+                       num_temp_gprs = 4;
+                       num_gs_gprs = 31;
+                       num_es_gprs = 31;
+                       num_hs_gprs = 23;
+                       num_ls_gprs = 23;
+                       num_ps_threads = 128;
+                       num_vs_threads = 10;
+                       num_gs_threads = 10;
+                       num_es_threads = 10;
+                       num_hs_threads = 10;
+                       num_ls_threads = 10;
+                       num_ps_stack_entries = 42;
+                       num_vs_stack_entries = 42;
+                       num_gs_stack_entries = 42;
+                       num_es_stack_entries = 42;
+                       num_hs_stack_entries = 42;
+                       num_ls_stack_entries = 42;
+                       break;
+               }
 
-       /* SQ config */
-       radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 11));
-       radeon_ring_write(rdev, (SQ_CONFIG - PACKET3_SET_CONFIG_REG_START) >> 2);
-       radeon_ring_write(rdev, sq_config);
-       radeon_ring_write(rdev, sq_gpr_resource_mgmt_1);
-       radeon_ring_write(rdev, sq_gpr_resource_mgmt_2);
-       radeon_ring_write(rdev, sq_gpr_resource_mgmt_3);
-       radeon_ring_write(rdev, 0);
-       radeon_ring_write(rdev, 0);
-       radeon_ring_write(rdev, sq_thread_resource_mgmt);
-       radeon_ring_write(rdev, sq_thread_resource_mgmt_2);
-       radeon_ring_write(rdev, sq_stack_resource_mgmt_1);
-       radeon_ring_write(rdev, sq_stack_resource_mgmt_2);
-       radeon_ring_write(rdev, sq_stack_resource_mgmt_3);
+               if ((rdev->family == CHIP_CEDAR) ||
+                   (rdev->family == CHIP_PALM) ||
+                   (rdev->family == CHIP_SUMO) ||
+                   (rdev->family == CHIP_SUMO2) ||
+                   (rdev->family == CHIP_CAICOS))
+                       sq_config = 0;
+               else
+                       sq_config = VC_ENABLE;
+
+               sq_config |= (EXPORT_SRC_C |
+                             CS_PRIO(0) |
+                             LS_PRIO(0) |
+                             HS_PRIO(0) |
+                             PS_PRIO(0) |
+                             VS_PRIO(1) |
+                             GS_PRIO(2) |
+                             ES_PRIO(3));
+
+               sq_gpr_resource_mgmt_1 = (NUM_PS_GPRS(num_ps_gprs) |
+                                         NUM_VS_GPRS(num_vs_gprs) |
+                                         NUM_CLAUSE_TEMP_GPRS(num_temp_gprs));
+               sq_gpr_resource_mgmt_2 = (NUM_GS_GPRS(num_gs_gprs) |
+                                         NUM_ES_GPRS(num_es_gprs));
+               sq_gpr_resource_mgmt_3 = (NUM_HS_GPRS(num_hs_gprs) |
+                                         NUM_LS_GPRS(num_ls_gprs));
+               sq_thread_resource_mgmt = (NUM_PS_THREADS(num_ps_threads) |
+                                          NUM_VS_THREADS(num_vs_threads) |
+                                          NUM_GS_THREADS(num_gs_threads) |
+                                          NUM_ES_THREADS(num_es_threads));
+               sq_thread_resource_mgmt_2 = (NUM_HS_THREADS(num_hs_threads) |
+                                            NUM_LS_THREADS(num_ls_threads));
+               sq_stack_resource_mgmt_1 = (NUM_PS_STACK_ENTRIES(num_ps_stack_entries) |
+                                           NUM_VS_STACK_ENTRIES(num_vs_stack_entries));
+               sq_stack_resource_mgmt_2 = (NUM_GS_STACK_ENTRIES(num_gs_stack_entries) |
+                                           NUM_ES_STACK_ENTRIES(num_es_stack_entries));
+               sq_stack_resource_mgmt_3 = (NUM_HS_STACK_ENTRIES(num_hs_stack_entries) |
+                                           NUM_LS_STACK_ENTRIES(num_ls_stack_entries));
+
+               /* disable dyn gprs */
+               radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1));
+               radeon_ring_write(rdev, (SQ_DYN_GPR_CNTL_PS_FLUSH_REQ - PACKET3_SET_CONFIG_REG_START) >> 2);
+               radeon_ring_write(rdev, 0);
+
+               /* SQ config */
+               radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 11));
+               radeon_ring_write(rdev, (SQ_CONFIG - PACKET3_SET_CONFIG_REG_START) >> 2);
+               radeon_ring_write(rdev, sq_config);
+               radeon_ring_write(rdev, sq_gpr_resource_mgmt_1);
+               radeon_ring_write(rdev, sq_gpr_resource_mgmt_2);
+               radeon_ring_write(rdev, sq_gpr_resource_mgmt_3);
+               radeon_ring_write(rdev, 0);
+               radeon_ring_write(rdev, 0);
+               radeon_ring_write(rdev, sq_thread_resource_mgmt);
+               radeon_ring_write(rdev, sq_thread_resource_mgmt_2);
+               radeon_ring_write(rdev, sq_stack_resource_mgmt_1);
+               radeon_ring_write(rdev, sq_stack_resource_mgmt_2);
+               radeon_ring_write(rdev, sq_stack_resource_mgmt_3);
+       }
 
        /* CONTEXT_CONTROL */
        radeon_ring_write(rdev, 0xc0012800);
@@ -560,7 +619,10 @@ int evergreen_blit_init(struct radeon_device *rdev)
        mutex_init(&rdev->r600_blit.mutex);
        rdev->r600_blit.state_offset = 0;
 
-       rdev->r600_blit.state_len = evergreen_default_size;
+       if (rdev->family < CHIP_CAYMAN)
+               rdev->r600_blit.state_len = evergreen_default_size;
+       else
+               rdev->r600_blit.state_len = cayman_default_size;
 
        dwords = rdev->r600_blit.state_len;
        while (dwords & 0xf) {
@@ -572,11 +634,17 @@ int evergreen_blit_init(struct radeon_device *rdev)
        obj_size = ALIGN(obj_size, 256);
 
        rdev->r600_blit.vs_offset = obj_size;
-       obj_size += evergreen_vs_size * 4;
+       if (rdev->family < CHIP_CAYMAN)
+               obj_size += evergreen_vs_size * 4;
+       else
+               obj_size += cayman_vs_size * 4;
        obj_size = ALIGN(obj_size, 256);
 
        rdev->r600_blit.ps_offset = obj_size;
-       obj_size += evergreen_ps_size * 4;
+       if (rdev->family < CHIP_CAYMAN)
+               obj_size += evergreen_ps_size * 4;
+       else
+               obj_size += cayman_ps_size * 4;
        obj_size = ALIGN(obj_size, 256);
 
        r = radeon_bo_create(rdev, obj_size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM,
@@ -599,16 +667,29 @@ int evergreen_blit_init(struct radeon_device *rdev)
                return r;
        }
 
-       memcpy_toio(ptr + rdev->r600_blit.state_offset,
-                   evergreen_default_state, rdev->r600_blit.state_len * 4);
-
-       if (num_packet2s)
-               memcpy_toio(ptr + rdev->r600_blit.state_offset + (rdev->r600_blit.state_len * 4),
-                           packet2s, num_packet2s * 4);
-       for (i = 0; i < evergreen_vs_size; i++)
-               *(u32 *)((unsigned long)ptr + rdev->r600_blit.vs_offset + i * 4) = cpu_to_le32(evergreen_vs[i]);
-       for (i = 0; i < evergreen_ps_size; i++)
-               *(u32 *)((unsigned long)ptr + rdev->r600_blit.ps_offset + i * 4) = cpu_to_le32(evergreen_ps[i]);
+       if (rdev->family < CHIP_CAYMAN) {
+               memcpy_toio(ptr + rdev->r600_blit.state_offset,
+                           evergreen_default_state, rdev->r600_blit.state_len * 4);
+
+               if (num_packet2s)
+                       memcpy_toio(ptr + rdev->r600_blit.state_offset + (rdev->r600_blit.state_len * 4),
+                                   packet2s, num_packet2s * 4);
+               for (i = 0; i < evergreen_vs_size; i++)
+                       *(u32 *)((unsigned long)ptr + rdev->r600_blit.vs_offset + i * 4) = cpu_to_le32(evergreen_vs[i]);
+               for (i = 0; i < evergreen_ps_size; i++)
+                       *(u32 *)((unsigned long)ptr + rdev->r600_blit.ps_offset + i * 4) = cpu_to_le32(evergreen_ps[i]);
+       } else {
+               memcpy_toio(ptr + rdev->r600_blit.state_offset,
+                           cayman_default_state, rdev->r600_blit.state_len * 4);
+
+               if (num_packet2s)
+                       memcpy_toio(ptr + rdev->r600_blit.state_offset + (rdev->r600_blit.state_len * 4),
+                                   packet2s, num_packet2s * 4);
+               for (i = 0; i < cayman_vs_size; i++)
+                       *(u32 *)((unsigned long)ptr + rdev->r600_blit.vs_offset + i * 4) = cpu_to_le32(cayman_vs[i]);
+               for (i = 0; i < cayman_ps_size; i++)
+                       *(u32 *)((unsigned long)ptr + rdev->r600_blit.ps_offset + i * 4) = cpu_to_le32(cayman_ps[i]);
+       }
        radeon_bo_kunmap(rdev->r600_blit.shader_obj);
        radeon_bo_unreserve(rdev->r600_blit.shader_obj);
 
index f37e91ee8a1114aed16bab49143fd5d1fe206914..1636e34498252c3550e17a6515aa6097974bbf7f 100644 (file)
 #define                SE_DB_BUSY                                      (1 << 30)
 #define                SE_CB_BUSY                                      (1 << 31)
 /* evergreen */
+#define        CG_THERMAL_CTRL                                 0x72c
+#define                TOFFSET_MASK                            0x00003FE0
+#define                TOFFSET_SHIFT                           5
 #define        CG_MULT_THERMAL_STATUS                          0x740
 #define                ASIC_T(x)                               ((x) << 16)
-#define                ASIC_T_MASK                             0x7FF0000
+#define                ASIC_T_MASK                             0x07FF0000
 #define                ASIC_T_SHIFT                            16
+#define        CG_TS0_STATUS                                   0x760
+#define                TS0_ADC_DOUT_MASK                       0x000003FF
+#define                TS0_ADC_DOUT_SHIFT                      0
 /* APU */
 #define        CG_THERMAL_STATUS                               0x678
 
index b205ba1cdd8f9b562a2033c9fec000a7b0b83e7e..16caafeadf5e5603208a3055b2344355106d5a05 100644 (file)
@@ -1387,14 +1387,12 @@ static int cayman_startup(struct radeon_device *rdev)
                return r;
        cayman_gpu_init(rdev);
 
-#if 0
-       r = cayman_blit_init(rdev);
+       r = evergreen_blit_init(rdev);
        if (r) {
-               cayman_blit_fini(rdev);
+               evergreen_blit_fini(rdev);
                rdev->asic->copy = NULL;
                dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r);
        }
-#endif
 
        /* allocate wb buffer */
        r = radeon_wb_init(rdev);
@@ -1452,7 +1450,7 @@ int cayman_resume(struct radeon_device *rdev)
 
 int cayman_suspend(struct radeon_device *rdev)
 {
-       /* int r; */
+       int r;
 
        /* FIXME: we should wait for ring to be empty */
        cayman_cp_enable(rdev, false);
@@ -1461,14 +1459,13 @@ int cayman_suspend(struct radeon_device *rdev)
        radeon_wb_disable(rdev);
        cayman_pcie_gart_disable(rdev);
 
-#if 0
        /* unpin shaders bo */
        r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
        if (likely(r == 0)) {
                radeon_bo_unpin(rdev->r600_blit.shader_obj);
                radeon_bo_unreserve(rdev->r600_blit.shader_obj);
        }
-#endif
+
        return 0;
 }
 
@@ -1580,7 +1577,7 @@ int cayman_init(struct radeon_device *rdev)
 
 void cayman_fini(struct radeon_device *rdev)
 {
-       /* cayman_blit_fini(rdev); */
+       evergreen_blit_fini(rdev);
        cayman_cp_fini(rdev);
        r600_irq_fini(rdev);
        radeon_wb_fini(rdev);
index 6f27593901c7110752b9b2f39267f04546f544eb..d74d4d71437f1aa75c111bdb4d4e8def3ea13cb9 100644 (file)
@@ -87,6 +87,10 @@ MODULE_FIRMWARE("radeon/CYPRESS_rlc.bin");
 MODULE_FIRMWARE("radeon/PALM_pfp.bin");
 MODULE_FIRMWARE("radeon/PALM_me.bin");
 MODULE_FIRMWARE("radeon/SUMO_rlc.bin");
+MODULE_FIRMWARE("radeon/SUMO_pfp.bin");
+MODULE_FIRMWARE("radeon/SUMO_me.bin");
+MODULE_FIRMWARE("radeon/SUMO2_pfp.bin");
+MODULE_FIRMWARE("radeon/SUMO2_me.bin");
 
 int r600_debugfs_mc_info_init(struct radeon_device *rdev);
 
@@ -2024,6 +2028,14 @@ int r600_init_microcode(struct radeon_device *rdev)
                chip_name = "PALM";
                rlc_chip_name = "SUMO";
                break;
+       case CHIP_SUMO:
+               chip_name = "SUMO";
+               rlc_chip_name = "SUMO";
+               break;
+       case CHIP_SUMO2:
+               chip_name = "SUMO2";
+               rlc_chip_name = "SUMO";
+               break;
        default: BUG();
        }
 
index fd18be9871ab5b897cc93c4a309a9081653f9489..909bda8dd550c54a9965e787d6876ff3fc325d33 100644 (file)
@@ -71,20 +71,21 @@ struct r600_cs_track {
        u64                     db_bo_mc;
 };
 
-#define FMT_8_BIT(fmt, vc) [fmt] = { 1, 1, 1, vc }
-#define FMT_16_BIT(fmt, vc) [fmt] = { 1, 1, 2, vc }
-#define FMT_24_BIT(fmt) [fmt] = { 1, 1, 3, 0 }
-#define FMT_32_BIT(fmt, vc) [fmt] = { 1, 1, 4, vc }
-#define FMT_48_BIT(fmt) [fmt] = { 1, 1, 6, 0 }
-#define FMT_64_BIT(fmt, vc) [fmt] = { 1, 1, 8, vc }
-#define FMT_96_BIT(fmt) [fmt] = { 1, 1, 12, 0 }
-#define FMT_128_BIT(fmt, vc) [fmt] = { 1, 1, 16, vc }
+#define FMT_8_BIT(fmt, vc)   [fmt] = { 1, 1, 1, vc, CHIP_R600 }
+#define FMT_16_BIT(fmt, vc)  [fmt] = { 1, 1, 2, vc, CHIP_R600 }
+#define FMT_24_BIT(fmt)      [fmt] = { 1, 1, 3,  0, CHIP_R600 }
+#define FMT_32_BIT(fmt, vc)  [fmt] = { 1, 1, 4, vc, CHIP_R600 }
+#define FMT_48_BIT(fmt)      [fmt] = { 1, 1, 6,  0, CHIP_R600 }
+#define FMT_64_BIT(fmt, vc)  [fmt] = { 1, 1, 8, vc, CHIP_R600 }
+#define FMT_96_BIT(fmt)      [fmt] = { 1, 1, 12, 0, CHIP_R600 }
+#define FMT_128_BIT(fmt, vc) [fmt] = { 1, 1, 16,vc, CHIP_R600 }
 
 struct gpu_formats {
        unsigned blockwidth;
        unsigned blockheight;
        unsigned blocksize;
        unsigned valid_color;
+       enum radeon_family min_family;
 };
 
 static const struct gpu_formats color_formats_table[] = {
@@ -154,7 +155,11 @@ static const struct gpu_formats color_formats_table[] = {
        [V_038004_FMT_BC3] = { 4, 4, 16, 0 },
        [V_038004_FMT_BC4] = { 4, 4, 8, 0 },
        [V_038004_FMT_BC5] = { 4, 4, 16, 0},
+       [V_038004_FMT_BC6] = { 4, 4, 16, 0, CHIP_CEDAR}, /* Evergreen-only */
+       [V_038004_FMT_BC7] = { 4, 4, 16, 0, CHIP_CEDAR}, /* Evergreen-only */
 
+       /* The other Evergreen formats */
+       [V_038004_FMT_32_AS_32_32_32_32] = { 1, 1, 4, 0, CHIP_CEDAR},
 };
 
 static inline bool fmt_is_valid_color(u32 format)
@@ -168,11 +173,14 @@ static inline bool fmt_is_valid_color(u32 format)
        return false;
 }
 
-static inline bool fmt_is_valid_texture(u32 format)
+static inline bool fmt_is_valid_texture(u32 format, enum radeon_family family)
 {
        if (format >= ARRAY_SIZE(color_formats_table))
                return false;
        
+       if (family < color_formats_table[format].min_family)
+               return false;
+
        if (color_formats_table[format].blockwidth > 0)
                return true;
 
@@ -1325,7 +1333,7 @@ static inline int r600_check_texture_resource(struct radeon_cs_parser *p,  u32 i
                return -EINVAL;
        }
        format = G_038004_DATA_FORMAT(word1);
-       if (!fmt_is_valid_texture(format)) {
+       if (!fmt_is_valid_texture(format, p->family)) {
                dev_warn(p->dev, "%s:%d texture invalid format %d\n",
                         __func__, __LINE__, format);
                return -EINVAL;
index b2b944bcd05ae53d1ff19aa16edeee941aba3187..f140a0d5cb543c0281c8e8a85f62df873fa51809 100644 (file)
 #define     V_038004_FMT_BC3                           0x00000033
 #define     V_038004_FMT_BC4                           0x00000034
 #define     V_038004_FMT_BC5                           0x00000035
+#define     V_038004_FMT_BC6                           0x00000036
+#define     V_038004_FMT_BC7                           0x00000037
+#define     V_038004_FMT_32_AS_32_32_32_32             0x00000038
 #define R_038010_SQ_TEX_RESOURCE_WORD4_0             0x038010
 #define   S_038010_FORMAT_COMP_X(x)                    (((x) & 0x3) << 0)
 #define   G_038010_FORMAT_COMP_X(x)                    (((x) >> 0) & 0x3)
index d948265db87e7140bae6bc1c0fc15005ba2940bd..9bd162fc9b0c5ecdf079f68e83b618d1d1bf1b3e 100644 (file)
@@ -906,9 +906,9 @@ static struct radeon_asic cayman_asic = {
        .get_vblank_counter = &evergreen_get_vblank_counter,
        .fence_ring_emit = &r600_fence_ring_emit,
        .cs_parse = &evergreen_cs_parse,
-       .copy_blit = NULL,
-       .copy_dma = NULL,
-       .copy = NULL,
+       .copy_blit = &evergreen_copy_blit,
+       .copy_dma = &evergreen_copy_blit,
+       .copy = &evergreen_copy_blit,
        .get_engine_clock = &radeon_atom_get_engine_clock,
        .set_engine_clock = &radeon_atom_set_engine_clock,
        .get_memory_clock = &radeon_atom_get_memory_clock,
@@ -1020,6 +1020,8 @@ int radeon_asic_init(struct radeon_device *rdev)
                rdev->asic = &evergreen_asic;
                break;
        case CHIP_PALM:
+       case CHIP_SUMO:
+       case CHIP_SUMO2:
                rdev->asic = &sumo_asic;
                break;
        case CHIP_BARTS:
index 8c1916941871d4bd10b0c3fda53eecdaad3e96cd..fae00c0d75aaf1fae7fcbfc9b504370f560f5d42 100644 (file)
@@ -228,6 +228,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
        parser.filp = filp;
        parser.rdev = rdev;
        parser.dev = rdev->dev;
+       parser.family = rdev->family;
        r = radeon_cs_parser_init(&parser, data);
        if (r) {
                DRM_ERROR("Failed to initialize parser !\n");
index 5b61364e31f4b2be689c481969d62302f1f2e5c0..e680501c78ea50e7d7a9d9d8f5d727c7c4e3337a 100644 (file)
@@ -82,6 +82,8 @@ static const char radeon_family_name[][16] = {
        "CYPRESS",
        "HEMLOCK",
        "PALM",
+       "SUMO",
+       "SUMO2",
        "BARTS",
        "TURKS",
        "CAICOS",
@@ -752,6 +754,7 @@ int radeon_device_init(struct radeon_device *rdev,
        dma_bits = rdev->need_dma32 ? 32 : 40;
        r = pci_set_dma_mask(rdev->pdev, DMA_BIT_MASK(dma_bits));
        if (r) {
+               rdev->need_dma32 = true;
                printk(KERN_WARNING "radeon: No suitable DMA available.\n");
        }
 
index ae247eec87c0be7181b4649ee4fc79d890c9b19a..292f73f0ddbd51210b8bf3494acdd79dc3d54719 100644 (file)
@@ -264,6 +264,8 @@ static void radeon_unpin_work_func(struct work_struct *__work)
                radeon_bo_unreserve(work->old_rbo);
        } else
                DRM_ERROR("failed to reserve buffer after flip\n");
+
+       drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base);
        kfree(work);
 }
 
@@ -371,6 +373,8 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc,
        new_radeon_fb = to_radeon_framebuffer(fb);
        /* schedule unpin of the old buffer */
        obj = old_radeon_fb->obj;
+       /* take a reference to the old object */
+       drm_gem_object_reference(obj);
        rbo = gem_to_radeon_bo(obj);
        work->old_rbo = rbo;
        INIT_WORK(&work->work, radeon_unpin_work_func);
@@ -378,12 +382,9 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc,
        /* We borrow the event spin lock for protecting unpin_work */
        spin_lock_irqsave(&dev->event_lock, flags);
        if (radeon_crtc->unpin_work) {
-               spin_unlock_irqrestore(&dev->event_lock, flags);
-               kfree(work);
-               radeon_fence_unref(&fence);
-
                DRM_DEBUG_DRIVER("flip queue: crtc already busy\n");
-               return -EBUSY;
+               r = -EBUSY;
+               goto unlock_free;
        }
        radeon_crtc->unpin_work = work;
        radeon_crtc->deferred_flip_completion = 0;
@@ -497,6 +498,8 @@ pflip_cleanup1:
 pflip_cleanup:
        spin_lock_irqsave(&dev->event_lock, flags);
        radeon_crtc->unpin_work = NULL;
+unlock_free:
+       drm_gem_object_unreference_unlocked(old_radeon_fb->obj);
        spin_unlock_irqrestore(&dev->event_lock, flags);
        radeon_fence_unref(&fence);
        kfree(work);
index 1d330606292feb8d2bec2fafc1ea3593bb82a980..73dfbe8e5f9ed7d750a424c5fa9aa7a8ed6ab025 100644 (file)
@@ -113,7 +113,7 @@ int radeon_benchmarking = 0;
 int radeon_testing = 0;
 int radeon_connector_table = 0;
 int radeon_tv = 1;
-int radeon_audio = 1;
+int radeon_audio = 0;
 int radeon_disp_priority = 0;
 int radeon_hw_i2c = 0;
 int radeon_pcie_gen2 = 0;
@@ -151,7 +151,7 @@ module_param_named(connector_table, radeon_connector_table, int, 0444);
 MODULE_PARM_DESC(tv, "TV enable (0 = disable)");
 module_param_named(tv, radeon_tv, int, 0444);
 
-MODULE_PARM_DESC(audio, "Audio enable (0 = disable)");
+MODULE_PARM_DESC(audio, "Audio enable (1 = enable)");
 module_param_named(audio, radeon_audio, int, 0444);
 
 MODULE_PARM_DESC(disp_priority, "Display Priority (0 = auto, 1 = normal, 2 = high)");
index 1b557554696e09b871486236b8449e7e2f131311..03f124d626c2aba034d0d74d4ac1f2f1d4e9c636 100644 (file)
@@ -954,10 +954,15 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
        int dp_lane_count = 0;
        int connector_object_id = 0;
        int igp_lane_info = 0;
+       int dig_encoder = dig->dig_encoder;
 
-       if (action == ATOM_TRANSMITTER_ACTION_INIT)
+       if (action == ATOM_TRANSMITTER_ACTION_INIT) {
                connector = radeon_get_connector_for_encoder_init(encoder);
-       else
+               /* just needed to avoid bailing in the encoder check.  the encoder
+                * isn't used for init
+                */
+               dig_encoder = 0;
+       } else
                connector = radeon_get_connector_for_encoder(encoder);
 
        if (connector) {
@@ -973,7 +978,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
        }
 
        /* no dig encoder assigned */
-       if (dig->dig_encoder == -1)
+       if (dig_encoder == -1)
                return;
 
        if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP)
@@ -1023,7 +1028,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
 
                if (dig->linkb)
                        args.v3.acConfig.ucLinkSel = 1;
-               if (dig->dig_encoder & 1)
+               if (dig_encoder & 1)
                        args.v3.acConfig.ucEncoderSel = 1;
 
                /* Select the PLL for the PHY
@@ -1073,7 +1078,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
                                args.v3.acConfig.fDualLinkConnector = 1;
                }
        } else if (ASIC_IS_DCE32(rdev)) {
-               args.v2.acConfig.ucEncoderSel = dig->dig_encoder;
+               args.v2.acConfig.ucEncoderSel = dig_encoder;
                if (dig->linkb)
                        args.v2.acConfig.ucLinkSel = 1;
 
@@ -1100,7 +1105,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
        } else {
                args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL;
 
-               if (dig->dig_encoder)
+               if (dig_encoder)
                        args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER;
                else
                        args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER;
index 6f1d9e563e7701f4f6817769e9ea02955ac70f96..ec2f1ea84f81e6c292543aa1e1a56433a19a253f 100644 (file)
@@ -81,6 +81,8 @@ enum radeon_family {
        CHIP_CYPRESS,
        CHIP_HEMLOCK,
        CHIP_PALM,
+       CHIP_SUMO,
+       CHIP_SUMO2,
        CHIP_BARTS,
        CHIP_TURKS,
        CHIP_CAICOS,
index 86eda1ea94dfc7a250d7add83ad2b25b8ae0dd76..aaa19dc418a0f0bf194d789592de943d3e5c2dca 100644 (file)
@@ -487,6 +487,7 @@ static int radeon_hwmon_init(struct radeon_device *rdev)
        case THERMAL_TYPE_RV6XX:
        case THERMAL_TYPE_RV770:
        case THERMAL_TYPE_EVERGREEN:
+       case THERMAL_TYPE_NI:
        case THERMAL_TYPE_SUMO:
                rdev->pm.int_hwmon_dev = hwmon_device_register(rdev->dev);
                if (IS_ERR(rdev->pm.int_hwmon_dev)) {
index 92f1900dc7caf10f14dba34edec2e34b721ff09d..ea49752ee99c472a15025efb2335c9a03394ce61 100644 (file)
@@ -758,6 +758,5 @@ r600 0x9400
 0x00009714 VC_ENHANCE
 0x00009830 DB_DEBUG
 0x00009838 DB_WATERMARKS
-0x00028D28 DB_SRESULTS_COMPARE_STATE0
 0x00028D44 DB_ALPHA_TO_MASK
 0x00009700 VC_CNTL
index de3d2465fe24eeabe835b9f76cc34eeb2b106d98..85e937984ff7594a8a610db84c08871898c67f15 100644 (file)
@@ -296,7 +296,7 @@ static int get_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev)
                 * If the TjMax is not plausible, an assumption
                 * will be used
                 */
-               if (val > 80 && val < 120) {
+               if (val) {
                        dev_info(dev, "TjMax is %d C.\n", val);
                        return val * 1000;
                }
@@ -304,24 +304,9 @@ static int get_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev)
 
        /*
         * An assumption is made for early CPUs and unreadable MSR.
-        * NOTE: the given value may not be correct.
+        * NOTE: the calculated value may not be correct.
         */
-
-       switch (c->x86_model) {
-       case 0xe:
-       case 0xf:
-       case 0x16:
-       case 0x1a:
-               dev_warn(dev, "TjMax is assumed as 100 C!\n");
-               return 100000;
-       case 0x17:
-       case 0x1c:              /* Atom CPUs */
-               return adjust_tjmax(c, id, dev);
-       default:
-               dev_warn(dev, "CPU (model=0x%x) is not supported yet,"
-                       " using default TjMax of 100C.\n", c->x86_model);
-               return 100000;
-       }
+       return adjust_tjmax(c, id, dev);
 }
 
 static void __devinit get_ucode_rev_on_cpu(void *edx)
@@ -341,7 +326,7 @@ static int get_pkg_tjmax(unsigned int cpu, struct device *dev)
        err = rdmsr_safe_on_cpu(cpu, MSR_IA32_TEMPERATURE_TARGET, &eax, &edx);
        if (!err) {
                val = (eax >> 16) & 0xff;
-               if (val > 80 && val < 120)
+               if (val)
                        return val * 1000;
        }
        dev_warn(dev, "Unable to read Pkg-TjMax from CPU:%u\n", cpu);
index 0f9fc40379cd14df869f15f8d8608d9f8393eb19..e855d3b0bd1f1d5e623c913343ae8ec9d6834e01 100644 (file)
@@ -136,15 +136,29 @@ static int max6642_detect(struct i2c_client *client,
        if (man_id != 0x4D)
                return -ENODEV;
 
+       /* sanity check */
+       if (i2c_smbus_read_byte_data(client, 0x04) != 0x4D
+           || i2c_smbus_read_byte_data(client, 0x06) != 0x4D
+           || i2c_smbus_read_byte_data(client, 0xff) != 0x4D)
+               return -ENODEV;
+
        /*
         * We read the config and status register, the 4 lower bits in the
         * config register should be zero and bit 5, 3, 1 and 0 should be
         * zero in the status register.
         */
        reg_config = i2c_smbus_read_byte_data(client, MAX6642_REG_R_CONFIG);
+       if ((reg_config & 0x0f) != 0x00)
+               return -ENODEV;
+
+       /* in between, another round of sanity checks */
+       if (i2c_smbus_read_byte_data(client, 0x04) != reg_config
+           || i2c_smbus_read_byte_data(client, 0x06) != reg_config
+           || i2c_smbus_read_byte_data(client, 0xff) != reg_config)
+               return -ENODEV;
+
        reg_status = i2c_smbus_read_byte_data(client, MAX6642_REG_R_STATUS);
-       if (((reg_config & 0x0f) != 0x00) ||
-           ((reg_status & 0x2b) != 0x00))
+       if ((reg_status & 0x2b) != 0x00)
                return -ENODEV;
 
        strlcpy(info->type, "max6642", I2C_NAME_SIZE);
@@ -246,7 +260,7 @@ static SENSOR_DEVICE_ATTR_2(temp1_max, S_IWUSR | S_IRUGO, show_temp_max,
                            set_temp_max, 0, MAX6642_REG_W_LOCAL_HIGH);
 static SENSOR_DEVICE_ATTR_2(temp2_max, S_IWUSR | S_IRUGO, show_temp_max,
                            set_temp_max, 1, MAX6642_REG_W_REMOTE_HIGH);
-static SENSOR_DEVICE_ATTR(temp_fault, S_IRUGO, show_alarm, NULL, 2);
+static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_alarm, NULL, 2);
 static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 6);
 static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 4);
 
@@ -256,7 +270,7 @@ static struct attribute *max6642_attributes[] = {
        &sensor_dev_attr_temp1_max.dev_attr.attr,
        &sensor_dev_attr_temp2_max.dev_attr.attr,
 
-       &sensor_dev_attr_temp_fault.dev_attr.attr,
+       &sensor_dev_attr_temp2_fault.dev_attr.attr,
        &sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
        &sensor_dev_attr_temp2_max_alarm.dev_attr.attr,
        NULL
index 6e5123b1d341746341d9c3feda2ad445606c327c..144d27261e43396161f0b0b196cbfc74bdccd285 100644 (file)
@@ -1782,7 +1782,6 @@ static int ide_cd_probe(ide_drive_t *drive)
        ide_cd_read_toc(drive, &sense);
        g->fops = &idecd_ops;
        g->flags |= GENHD_FL_REMOVABLE | GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE;
-       g->events = DISK_EVENT_MEDIA_CHANGE;
        add_disk(g);
        return 0;
 
index f3698967edf6bdd0e8b7f4b19abdb19e335a2c3d..8755f5f3ad37c2218de60b96782c0863615a705e 100644 (file)
@@ -120,21 +120,17 @@ static void serport_ldisc_close(struct tty_struct *tty)
  * 'interrupt' routine.
  */
 
-static unsigned int serport_ldisc_receive(struct tty_struct *tty,
-               const unsigned char *cp, char *fp, int count)
+static void serport_ldisc_receive(struct tty_struct *tty, const unsigned char *cp, char *fp, int count)
 {
        struct serport *serport = (struct serport*) tty->disc_data;
        unsigned long flags;
        unsigned int ch_flags;
-       int ret = 0;
        int i;
 
        spin_lock_irqsave(&serport->lock, flags);
 
-       if (!test_bit(SERPORT_ACTIVE, &serport->flags)) {
-               ret = -EINVAL;
+       if (!test_bit(SERPORT_ACTIVE, &serport->flags))
                goto out;
-       }
 
        for (i = 0; i < count; i++) {
                switch (fp[i]) {
@@ -156,8 +152,6 @@ static unsigned int serport_ldisc_receive(struct tty_struct *tty,
 
 out:
        spin_unlock_irqrestore(&serport->lock, flags);
-
-       return ret == 0 ? count : ret;
 }
 
 /*
index 1d44d470897ca4660b6e4f4e05218293f3e9c398..86a5c4f7775eb5c95a23a35b1bf05a77a8ba9681 100644 (file)
@@ -674,7 +674,7 @@ gigaset_tty_ioctl(struct tty_struct *tty, struct file *file,
  *     cflags  buffer containing error flags for received characters (ignored)
  *     count   number of received characters
  */
-static unsigned int
+static void
 gigaset_tty_receive(struct tty_struct *tty, const unsigned char *buf,
                    char *cflags, int count)
 {
@@ -683,12 +683,12 @@ gigaset_tty_receive(struct tty_struct *tty, const unsigned char *buf,
        struct inbuf_t *inbuf;
 
        if (!cs)
-               return -ENODEV;
+               return;
        inbuf = cs->inbuf;
        if (!inbuf) {
                dev_err(cs->dev, "%s: no inbuf\n", __func__);
                cs_put(cs);
-               return -EINVAL;
+               return;
        }
 
        tail = inbuf->tail;
@@ -725,8 +725,6 @@ gigaset_tty_receive(struct tty_struct *tty, const unsigned char *buf,
        gig_dbg(DEBUG_INTR, "%s-->BH", __func__);
        gigaset_schedule_event(cs);
        cs_put(cs);
-
-       return count;
 }
 
 /*
index 4dc1ca3332363e7569f34e08a034f13186f677fd..7c327b54308e30312848d7b9c4c289f28fe2d937 100644 (file)
@@ -60,8 +60,6 @@ static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen,
        int act_len, ret;
        u8 buf[64];
 
-       if (slen > sizeof(buf))
-               slen = sizeof(buf);
        memcpy(&buf[0], sbuf, slen);
        buf[60] = state->seq++;
 
@@ -180,30 +178,37 @@ static int anysee_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
 {
        struct dvb_usb_device *d = i2c_get_adapdata(adap);
        int ret = 0, inc, i = 0;
+       u8 buf[52]; /* 4 + 48 (I2C WR USB command header + I2C WR max) */
 
        if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
                return -EAGAIN;
 
        while (i < num) {
                if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
-                       u8 buf[6];
+                       if (msg[i].len > 2 || msg[i+1].len > 60) {
+                               ret = -EOPNOTSUPP;
+                               break;
+                       }
                        buf[0] = CMD_I2C_READ;
                        buf[1] = (msg[i].addr << 1) | 0x01;
                        buf[2] = msg[i].buf[0];
                        buf[3] = msg[i].buf[1];
                        buf[4] = msg[i].len-1;
                        buf[5] = msg[i+1].len;
-                       ret = anysee_ctrl_msg(d, buf, sizeof(buf), msg[i+1].buf,
+                       ret = anysee_ctrl_msg(d, buf, 6, msg[i+1].buf,
                                msg[i+1].len);
                        inc = 2;
                } else {
-                       u8 buf[4+msg[i].len];
+                       if (msg[i].len > 48) {
+                               ret = -EOPNOTSUPP;
+                               break;
+                       }
                        buf[0] = CMD_I2C_WRITE;
                        buf[1] = (msg[i].addr << 1);
                        buf[2] = msg[i].len;
                        buf[3] = 0x01;
                        memcpy(&buf[4], msg[i].buf, msg[i].len);
-                       ret = anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
+                       ret = anysee_ctrl_msg(d, buf, 4 + msg[i].len, NULL, 0);
                        inc = 1;
                }
                if (ret)
index af5263c6625adeafab44bfa5cdff167122ff52d5..7b42ace419d9378c32407650044b2daa69adc0a6 100644 (file)
@@ -213,14 +213,14 @@ int __must_check media_devnode_register(struct media_devnode *mdev)
 
        /* Part 1: Find a free minor number */
        mutex_lock(&media_devnode_lock);
-       minor = find_next_zero_bit(media_devnode_nums, 0, MEDIA_NUM_DEVICES);
+       minor = find_next_zero_bit(media_devnode_nums, MEDIA_NUM_DEVICES, 0);
        if (minor == MEDIA_NUM_DEVICES) {
                mutex_unlock(&media_devnode_lock);
                printk(KERN_ERR "could not get a free minor\n");
                return -ENFILE;
        }
 
-       set_bit(mdev->minor, media_devnode_nums);
+       set_bit(minor, media_devnode_nums);
        mutex_unlock(&media_devnode_lock);
 
        mdev->minor = minor;
diff --git a/drivers/media/video/gspca/coarse_expo_autogain.h b/drivers/media/video/gspca/coarse_expo_autogain.h
deleted file mode 100644 (file)
index 1cb9d94..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Auto gain algorithm for camera's with a coarse exposure control
- *
- * Copyright (C) 2010 Hans de Goede <hdegoede@redhat.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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
- */
-
-/* Autogain + exposure algorithm for cameras with a coarse exposure control
-   (usually this means we can only control the clockdiv to change exposure)
-   As changing the clockdiv so that the fps drops from 30 to 15 fps for
-   example, will lead to a huge exposure change (it effectively doubles),
-   this algorithm normally tries to only adjust the gain (between 40 and
-   80 %) and if that does not help, only then changes exposure. This leads
-   to a much more stable image then using the knee algorithm which at
-   certain points of the knee graph will only try to adjust exposure,
-   which leads to oscilating as one exposure step is huge.
-
-   Note this assumes that the sd struct for the cam in question has
-   exp_too_high_cnt and exp_too_high_cnt int members for use by this function.
-
-   Returns 0 if no changes were made, 1 if the gain and or exposure settings
-   where changed. */
-static int gspca_coarse_grained_expo_autogain(struct gspca_dev *gspca_dev,
-       int avg_lum, int desired_avg_lum, int deadzone)
-{
-       int i, steps, gain, orig_gain, exposure, orig_exposure;
-       int gain_low, gain_high;
-       const struct ctrl *gain_ctrl = NULL;
-       const struct ctrl *exposure_ctrl = NULL;
-       struct sd *sd = (struct sd *) gspca_dev;
-       int retval = 0;
-
-       for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) {
-               if (gspca_dev->ctrl_dis & (1 << i))
-                       continue;
-               if (gspca_dev->sd_desc->ctrls[i].qctrl.id == V4L2_CID_GAIN)
-                       gain_ctrl = &gspca_dev->sd_desc->ctrls[i];
-               if (gspca_dev->sd_desc->ctrls[i].qctrl.id == V4L2_CID_EXPOSURE)
-                       exposure_ctrl = &gspca_dev->sd_desc->ctrls[i];
-       }
-       if (!gain_ctrl || !exposure_ctrl) {
-               PDEBUG(D_ERR, "Error: gspca_coarse_grained_expo_autogain "
-                       "called on cam without gain or exposure");
-               return 0;
-       }
-
-       if (gain_ctrl->get(gspca_dev, &gain) ||
-           exposure_ctrl->get(gspca_dev, &exposure))
-               return 0;
-
-       orig_gain = gain;
-       orig_exposure = exposure;
-       gain_low =
-               (gain_ctrl->qctrl.maximum - gain_ctrl->qctrl.minimum) / 5 * 2;
-       gain_low += gain_ctrl->qctrl.minimum;
-       gain_high =
-               (gain_ctrl->qctrl.maximum - gain_ctrl->qctrl.minimum) / 5 * 4;
-       gain_high += gain_ctrl->qctrl.minimum;
-
-       /* If we are of a multiple of deadzone, do multiple steps to reach the
-          desired lumination fast (with the risc of a slight overshoot) */
-       steps = (desired_avg_lum - avg_lum) / deadzone;
-
-       PDEBUG(D_FRAM, "autogain: lum: %d, desired: %d, steps: %d",
-               avg_lum, desired_avg_lum, steps);
-
-       if ((gain + steps) > gain_high &&
-           sd->exposure < exposure_ctrl->qctrl.maximum) {
-               gain = gain_high;
-               sd->exp_too_low_cnt++;
-       } else if ((gain + steps) < gain_low &&
-                  sd->exposure > exposure_ctrl->qctrl.minimum) {
-               gain = gain_low;
-               sd->exp_too_high_cnt++;
-       } else {
-               gain += steps;
-               if (gain > gain_ctrl->qctrl.maximum)
-                       gain = gain_ctrl->qctrl.maximum;
-               else if (gain < gain_ctrl->qctrl.minimum)
-                       gain = gain_ctrl->qctrl.minimum;
-               sd->exp_too_high_cnt = 0;
-               sd->exp_too_low_cnt = 0;
-       }
-
-       if (sd->exp_too_high_cnt > 3) {
-               exposure--;
-               sd->exp_too_high_cnt = 0;
-       } else if (sd->exp_too_low_cnt > 3) {
-               exposure++;
-               sd->exp_too_low_cnt = 0;
-       }
-
-       if (gain != orig_gain) {
-               gain_ctrl->set(gspca_dev, gain);
-               retval = 1;
-       }
-       if (exposure != orig_exposure) {
-               exposure_ctrl->set(gspca_dev, exposure);
-               retval = 1;
-       }
-
-       return retval;
-}
index 36a46fc787341b86dbd8ceaa1fef5c1ab21541b7..057e287b9152a78fea793bdefa8ec6d26b699085 100644 (file)
@@ -609,7 +609,7 @@ static const struct v4l2_pix_format ovfx2_ov3610_mode[] = {
  * buffers, there are some pretty strict real time constraints for
  * isochronous transfer for larger frame sizes).
  */
-/*jfm: this value works well for 1600x1200, but not 800x600 - see isoc_init */
+/*jfm: this value does not work for 800x600 - see isoc_init */
 #define OVFX2_BULK_SIZE (13 * 4096)
 
 /* I2C registers */
@@ -3307,6 +3307,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
 
        gspca_dev->cam.ctrls = sd->ctrls;
        sd->quality = QUALITY_DEF;
+       sd->frame_rate = 15;
 
        return 0;
 }
@@ -3469,7 +3470,6 @@ static int sd_init(struct gspca_dev *gspca_dev)
                                ARRAY_SIZE(init_519_ov7660));
                write_i2c_regvals(sd, norm_7660, ARRAY_SIZE(norm_7660));
                sd->gspca_dev.curr_mode = 1;    /* 640x480 */
-               sd->frame_rate = 15;
                ov519_set_mode(sd);
                ov519_set_fr(sd);
                sd->ctrls[COLORS].max = 4;      /* 0..4 */
@@ -3511,7 +3511,7 @@ static int sd_isoc_init(struct gspca_dev *gspca_dev)
 
        switch (sd->bridge) {
        case BRIDGE_OVFX2:
-               if (gspca_dev->width == 1600)
+               if (gspca_dev->width != 800)
                        gspca_dev->cam.bulk_size = OVFX2_BULK_SIZE;
                else
                        gspca_dev->cam.bulk_size = 7 * 4096;
@@ -4478,7 +4478,7 @@ static void ovfx2_pkt_scan(struct gspca_dev *gspca_dev,
        gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 
        /* A short read signals EOF */
-       if (len < OVFX2_BULK_SIZE) {
+       if (len < gspca_dev->cam.bulk_size) {
                /* If the frame is short, and it is one of the first ones
                   the sensor and bridge are still syncing, so drop it. */
                if (sd->first_frame) {
index 6415aff5cbd1675cb4f96d106b9eb72b78b8977b..81b8a600783b575290814af47931ee5b1702ebcf 100644 (file)
@@ -60,7 +60,7 @@ struct sd {
 
        u32 pktsz;                      /* (used by pkt_scan) */
        u16 npkt;
-       u8 nchg;
+       s8 nchg;
        s8 short_mark;
 
        u8 quality;                     /* image quality */
index b538dce96f78d8cbb1c7297ea8b40ce21712ea7b..a14a84a5079b96d4da4b932d206d99b4d1a9532e 100644 (file)
 #define HDCS_SLEEP_MODE                (1 << 1)
 
 #define HDCS_DEFAULT_EXPOSURE  48
-#define HDCS_DEFAULT_GAIN      128
+#define HDCS_DEFAULT_GAIN      50
 
 static int hdcs_probe_1x00(struct sd *sd);
 static int hdcs_probe_1020(struct sd *sd);
index a4e4dfdbc2f2c9474c5616b9b68f44abb762dd75..0fb75524484d909af4925c3c33c9f12cf6d6519e 100644 (file)
@@ -1328,6 +1328,8 @@ int ivtv_init_on_first_open(struct ivtv *itv)
        if (!itv->has_cx23415)
                write_reg_sync(0x03, IVTV_REG_DMACONTROL);
 
+       ivtv_s_std_enc(itv, &itv->tuner_std);
+
        /* Default interrupts enabled. For the PVR350 this includes the
           decoder VSYNC interrupt, which is always on. It is not only used
           during decoding but also by the OSD.
@@ -1336,12 +1338,10 @@ int ivtv_init_on_first_open(struct ivtv *itv)
        if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
                ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_INIT | IVTV_IRQ_DEC_VSYNC);
                ivtv_set_osd_alpha(itv);
-       }
-       else
+               ivtv_s_std_dec(itv, &itv->tuner_std);
+       } else {
                ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_INIT);
-
-       /* For cards with video out, this call needs interrupts enabled */
-       ivtv_s_std(NULL, &fh, &itv->tuner_std);
+       }
 
        /* Setup initial controls */
        cx2341x_handler_setup(&itv->cxhdl);
index 14a1cea1d70da6bdcefc06184d4153f804348de8..02c5adebf517aac57248c473a60c793952629e75 100644 (file)
@@ -280,8 +280,6 @@ int ivtv_firmware_restart(struct ivtv *itv)
 {
        int rc = 0;
        v4l2_std_id std;
-       struct ivtv_open_id fh;
-       fh.itv = itv;
 
        if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)
                /* Display test image during restart */
@@ -301,14 +299,19 @@ int ivtv_firmware_restart(struct ivtv *itv)
        /* Allow settings to reload */
        ivtv_mailbox_cache_invalidate(itv);
 
-       /* Restore video standard */
+       /* Restore encoder video standard */
        std = itv->std;
        itv->std = 0;
-       ivtv_s_std(NULL, &fh, &std);
+       ivtv_s_std_enc(itv, &std);
 
        if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
                ivtv_init_mpeg_decoder(itv);
 
+               /* Restore decoder video standard */
+               std = itv->std_out;
+               itv->std_out = 0;
+               ivtv_s_std_dec(itv, &std);
+
                /* Restore framebuffer if active */
                if (itv->ivtvfb_restore)
                        itv->ivtvfb_restore(itv);
index 1689783cd19aa81261147b35870a485eb16736aa..f9e347dae7391a4487e15ac17e9e16578f59d16e 100644 (file)
@@ -1071,28 +1071,8 @@ static int ivtv_g_std(struct file *file, void *fh, v4l2_std_id *std)
        return 0;
 }
 
-int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std)
+void ivtv_s_std_enc(struct ivtv *itv, v4l2_std_id *std)
 {
-       DEFINE_WAIT(wait);
-       struct ivtv *itv = fh2id(fh)->itv;
-       struct yuv_playback_info *yi = &itv->yuv_info;
-       int f;
-
-       if ((*std & V4L2_STD_ALL) == 0)
-               return -EINVAL;
-
-       if (*std == itv->std)
-               return 0;
-
-       if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ||
-           atomic_read(&itv->capturing) > 0 ||
-           atomic_read(&itv->decoding) > 0) {
-               /* Switching standard would turn off the radio or mess
-                  with already running streams, prevent that by
-                  returning EBUSY. */
-               return -EBUSY;
-       }
-
        itv->std = *std;
        itv->is_60hz = (*std & V4L2_STD_525_60) ? 1 : 0;
        itv->is_50hz = !itv->is_60hz;
@@ -1106,48 +1086,79 @@ int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std)
        if (itv->hw_flags & IVTV_HW_CX25840)
                itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284;
 
-       IVTV_DEBUG_INFO("Switching standard to %llx.\n", (unsigned long long)itv->std);
-
        /* Tuner */
        ivtv_call_all(itv, core, s_std, itv->std);
+}
 
-       if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
-               /* set display standard */
-               itv->std_out = *std;
-               itv->is_out_60hz = itv->is_60hz;
-               itv->is_out_50hz = itv->is_50hz;
-               ivtv_call_all(itv, video, s_std_output, itv->std_out);
-
-               /*
-                * The next firmware call is time sensitive. Time it to
-                * avoid risk of a hard lock, by trying to ensure the call
-                * happens within the first 100 lines of the top field.
-                * Make 4 attempts to sync to the decoder before giving up.
-                */
-               for (f = 0; f < 4; f++) {
-                       prepare_to_wait(&itv->vsync_waitq, &wait,
-                                       TASK_UNINTERRUPTIBLE);
-                       if ((read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16) < 100)
-                               break;
-                       schedule_timeout(msecs_to_jiffies(25));
-               }
-               finish_wait(&itv->vsync_waitq, &wait);
-
-               if (f == 4)
-                       IVTV_WARN("Mode change failed to sync to decoder\n");
-
-               ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz);
-               itv->main_rect.left = itv->main_rect.top = 0;
-               itv->main_rect.width = 720;
-               itv->main_rect.height = itv->cxhdl.height;
-               ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
-                       720, itv->main_rect.height, 0, 0);
-               yi->main_rect = itv->main_rect;
-               if (!itv->osd_info) {
-                       yi->osd_full_w = 720;
-                       yi->osd_full_h = itv->is_out_50hz ? 576 : 480;
-               }
+void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id *std)
+{
+       struct yuv_playback_info *yi = &itv->yuv_info;
+       DEFINE_WAIT(wait);
+       int f;
+
+       /* set display standard */
+       itv->std_out = *std;
+       itv->is_out_60hz = (*std & V4L2_STD_525_60) ? 1 : 0;
+       itv->is_out_50hz = !itv->is_out_60hz;
+       ivtv_call_all(itv, video, s_std_output, itv->std_out);
+
+       /*
+        * The next firmware call is time sensitive. Time it to
+        * avoid risk of a hard lock, by trying to ensure the call
+        * happens within the first 100 lines of the top field.
+        * Make 4 attempts to sync to the decoder before giving up.
+        */
+       for (f = 0; f < 4; f++) {
+               prepare_to_wait(&itv->vsync_waitq, &wait,
+                               TASK_UNINTERRUPTIBLE);
+               if ((read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16) < 100)
+                       break;
+               schedule_timeout(msecs_to_jiffies(25));
        }
+       finish_wait(&itv->vsync_waitq, &wait);
+
+       if (f == 4)
+               IVTV_WARN("Mode change failed to sync to decoder\n");
+
+       ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz);
+       itv->main_rect.left = 0;
+       itv->main_rect.top = 0;
+       itv->main_rect.width = 720;
+       itv->main_rect.height = itv->is_out_50hz ? 576 : 480;
+       ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
+               720, itv->main_rect.height, 0, 0);
+       yi->main_rect = itv->main_rect;
+       if (!itv->osd_info) {
+               yi->osd_full_w = 720;
+               yi->osd_full_h = itv->is_out_50hz ? 576 : 480;
+       }
+}
+
+int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std)
+{
+       struct ivtv *itv = fh2id(fh)->itv;
+
+       if ((*std & V4L2_STD_ALL) == 0)
+               return -EINVAL;
+
+       if (*std == itv->std)
+               return 0;
+
+       if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ||
+           atomic_read(&itv->capturing) > 0 ||
+           atomic_read(&itv->decoding) > 0) {
+               /* Switching standard would mess with already running
+                  streams, prevent that by returning EBUSY. */
+               return -EBUSY;
+       }
+
+       IVTV_DEBUG_INFO("Switching standard to %llx.\n",
+               (unsigned long long)itv->std);
+
+       ivtv_s_std_enc(itv, std);
+       if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)
+               ivtv_s_std_dec(itv, std);
+
        return 0;
 }
 
index 58f003412afdd5141a854c41779b80ad38a4884d..89185caeafae0a5c72c8423d6b3ad6b242947227 100644 (file)
@@ -27,7 +27,8 @@ u16 ivtv_get_service_set(struct v4l2_sliced_vbi_format *fmt);
 void ivtv_set_osd_alpha(struct ivtv *itv);
 int ivtv_set_speed(struct ivtv *itv, int speed);
 void ivtv_set_funcs(struct video_device *vdev);
-int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std);
+void ivtv_s_std_enc(struct ivtv *itv, v4l2_std_id *std);
+void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id *std);
 int ivtv_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf);
 int ivtv_s_input(struct file *file, void *fh, unsigned int inp);
 long ivtv_v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
index 942683336555e02311c6d0b1d63acdab633fc777..e7794dc1330e50348a5e358714abf9f54702e56d 100644 (file)
@@ -589,7 +589,7 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
                v4l2_subdev_call(itv->sd_audio, audio, s_stream, 1);
                /* Avoid unpredictable PCI bus hang - disable video clocks */
                v4l2_subdev_call(itv->sd_video, video, s_stream, 0);
-               ivtv_msleep_timeout(300, 1);
+               ivtv_msleep_timeout(300, 0);
                ivtv_vapi(itv, CX2341X_ENC_INITIALIZE_INPUT, 0);
                v4l2_subdev_call(itv->sd_video, video, s_stream, 1);
        }
@@ -834,7 +834,7 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end)
                }
 
                /* Handle any pending interrupts */
-               ivtv_msleep_timeout(100, 1);
+               ivtv_msleep_timeout(100, 0);
        }
 
        atomic_dec(&itv->capturing);
index b6eb51ce773503ad60031b999934253edbc39d67..293db806d9362b688f000ed90ed3475c0b85ae09 100644 (file)
@@ -71,7 +71,7 @@ static void ivtv_set_wss(struct ivtv *itv, int enabled, int mode)
           Turning this signal on and off can confuse certain
           TVs. As far as I can tell there is no reason not to
           transmit this signal. */
-       if ((itv->std & V4L2_STD_625_50) && !enabled) {
+       if ((itv->std_out & V4L2_STD_625_50) && !enabled) {
                enabled = 1;
                mode = 0x08;  /* 4x3 full format */
        }
index 17247451c69326f3159cb6913e7eabaa152d72fc..6b7c9c8233309975726e42a65f97296df84cff54 100644 (file)
@@ -247,7 +247,7 @@ static int ivtvfb_set_osd_coords(struct ivtv *itv, const struct ivtv_osd_coords
 
 static int ivtvfb_set_display_window(struct ivtv *itv, struct v4l2_rect *ivtv_window)
 {
-       int osd_height_limit = itv->is_50hz ? 576 : 480;
+       int osd_height_limit = itv->is_out_50hz ? 576 : 480;
 
        /* Only fail if resolution too high, otherwise fudge the start coords. */
        if ((ivtv_window->height > osd_height_limit) || (ivtv_window->width > IVTV_OSD_MAX_WIDTH))
@@ -471,9 +471,9 @@ static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long ar
                        vblank.flags = FB_VBLANK_HAVE_COUNT |FB_VBLANK_HAVE_VCOUNT |
                                        FB_VBLANK_HAVE_VSYNC;
                        trace = read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16;
-                       if (itv->is_50hz && trace > 312)
+                       if (itv->is_out_50hz && trace > 312)
                                trace -= 312;
-                       else if (itv->is_60hz && trace > 262)
+                       else if (itv->is_out_60hz && trace > 262)
                                trace -= 262;
                        if (trace == 1)
                                vblank.flags |= FB_VBLANK_VSYNCING;
@@ -656,7 +656,7 @@ static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv)
        IVTVFB_DEBUG_INFO("ivtvfb_check_var\n");
 
        /* Set base references for mode calcs. */
-       if (itv->is_50hz) {
+       if (itv->is_out_50hz) {
                pixclock = 84316;
                hlimit = 776;
                vlimit = 591;
@@ -784,12 +784,12 @@ static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv)
           If the margins are too large, just center the screen
           (enforcing margins causes too many problems) */
 
-       if (var->left_margin + var->xres > IVTV_OSD_MAX_WIDTH + 1) {
+       if (var->left_margin + var->xres > IVTV_OSD_MAX_WIDTH + 1)
                var->left_margin = 1 + ((IVTV_OSD_MAX_WIDTH - var->xres) / 2);
-       }
-       if (var->upper_margin + var->yres > (itv->is_50hz ? 577 : 481)) {
-               var->upper_margin = 1 + (((itv->is_50hz ? 576 : 480) - var->yres) / 2);
-       }
+
+       if (var->upper_margin + var->yres > (itv->is_out_50hz ? 577 : 481))
+               var->upper_margin = 1 + (((itv->is_out_50hz ? 576 : 480) -
+                       var->yres) / 2);
 
        /* Maintain overall 'size' for a constant refresh rate */
        var->right_margin = hlimit - var->left_margin - var->xres;
@@ -836,7 +836,12 @@ static int ivtvfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *inf
        u32 osd_pan_index;
        struct ivtv *itv = (struct ivtv *) info->par;
 
-       osd_pan_index = (var->xoffset + (var->yoffset * var->xres_virtual))*var->bits_per_pixel/8;
+       if (var->yoffset + info->var.yres > info->var.yres_virtual ||
+           var->xoffset + info->var.xres > info->var.xres_virtual)
+               return -EINVAL;
+
+       osd_pan_index = var->yoffset * info->fix.line_length
+                     + var->xoffset * info->var.bits_per_pixel / 8;
        write_reg(osd_pan_index, 0x02A0C);
 
        /* Pass this info back the yuv handler */
@@ -1003,19 +1008,21 @@ static int ivtvfb_init_vidmode(struct ivtv *itv)
        /* Hardware coords start at 0, user coords start at 1. */
        osd_left--;
 
-       start_window.left = osd_left >= 0 ? osd_left : ((IVTV_OSD_MAX_WIDTH - start_window.width) / 2);
+       start_window.left = osd_left >= 0 ?
+                osd_left : ((IVTV_OSD_MAX_WIDTH - start_window.width) / 2);
 
        oi->display_byte_stride =
                        start_window.width * oi->bytes_per_pixel;
 
        /* Vertical size & position */
 
-       max_height = itv->is_50hz ? 576 : 480;
+       max_height = itv->is_out_50hz ? 576 : 480;
 
        if (osd_yres > max_height)
                osd_yres = max_height;
 
-       start_window.height = osd_yres ? osd_yres : itv->is_50hz ? 480 : 400;
+       start_window.height = osd_yres ?
+               osd_yres : itv->is_out_50hz ? 480 : 400;
 
        /* Check vertical start (osd_upper). */
        if (osd_upper + start_window.height > max_height + 1) {
index 472a69359e609c16c67b014da479e7bbeb2c29ed..c9fd04ee70a8ae766811059c6942657334ac7621 100644 (file)
@@ -391,7 +391,7 @@ static inline void isp_isr_dbg(struct isp_device *isp, u32 irqstatus)
        };
        int i;
 
-       dev_dbg(isp->dev, "");
+       dev_dbg(isp->dev, "ISP IRQ: ");
 
        for (i = 0; i < ARRAY_SIZE(name); i++) {
                if ((1 << i) & irqstatus)
index 398864370267f33d12a7fe56a5feaa5ce6c916fa..4e4d4122d9a60339175486b999a8576b25565c09 100644 (file)
@@ -1512,7 +1512,7 @@ static int video_dev_create(struct soc_camera_device *icd)
  */
 static int soc_camera_video_start(struct soc_camera_device *icd)
 {
-       struct device_type *type = icd->vdev->dev.type;
+       const struct device_type *type = icd->vdev->dev.type;
        int ret;
 
        if (!icd->dev.parent)
index ede7852bb1df15b63ab575d968a6fe6862c1c875..c3ab0c813be249d4957fa93e83cfac0df567b703 100644 (file)
@@ -30,7 +30,7 @@ static int uvc_mc_register_entity(struct uvc_video_chain *chain,
        struct uvc_entity *remote;
        unsigned int i;
        u8 remote_pad;
-       int ret;
+       int ret = 0;
 
        for (i = 0; i < entity->num_pads; ++i) {
                struct media_entity *source;
index b0c56313dbbb4928826c08f535f3305490c7c61e..8cebec5e85eeb3d3c80bd998815a3e07f1a913ad 100644 (file)
@@ -304,7 +304,10 @@ static int check_and_rewind_pc(char *put_str, char *arg)
                return 1;
        }
        /* Readjust the instruction pointer if needed */
-       instruction_pointer_set(&kgdbts_regs, ip + offset);
+       ip += offset;
+#ifdef GDB_ADJUSTS_BREAK_OFFSET
+       instruction_pointer_set(&kgdbts_regs, ip);
+#endif
        return 0;
 }
 
index 1a05fe08e2cb7dc4462b76d360115e725321fc7e..f91f82eabda72a311602a8979ab835e0d938ffd6 100644 (file)
@@ -747,8 +747,8 @@ static void st_tty_close(struct tty_struct *tty)
        pr_debug("%s: done ", __func__);
 }
 
-static unsigned int st_tty_receive(struct tty_struct *tty,
-               const unsigned char *data, char *tty_flags, int count)
+static void st_tty_receive(struct tty_struct *tty, const unsigned char *data,
+                          char *tty_flags, int count)
 {
 #ifdef VERBOSE
        print_hex_dump(KERN_DEBUG, ">in>", DUMP_PREFIX_NONE,
@@ -761,8 +761,6 @@ static unsigned int st_tty_receive(struct tty_struct *tty,
         */
        st_recv(tty->disc_data, data, count);
        pr_debug("done %s", __func__);
-
-       return count;
 }
 
 /* wake-up function called in from the TTY layer
index 259ece047afcd6057bff748f7850d15430ae2136..5b2e2155b413bc988cabbd5125fe5c4c64f27d5b 100644 (file)
@@ -435,6 +435,9 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host)
                reg = regulator_get(host->dev, "vmmc_aux");
                host->vcc_aux = IS_ERR(reg) ? NULL : reg;
 
+               /* For eMMC do not power off when not in sleep state */
+               if (mmc_slot(host).no_regulator_off_init)
+                       return 0;
                /*
                * UGLY HACK:  workaround regulator framework bugs.
                * When the bootloader leaves a supply active, it's
index 5f25889e27efdafee0941407ab0c39c9f7b1ee36..44b28b2d70039e959811a4c9cfa173ed5c6b7b43 100644 (file)
@@ -185,7 +185,7 @@ static int max_interrupt_work = 10;
 static int nopnp;
 #endif
 
-static int el3_common_init(struct net_device *dev);
+static int __devinit el3_common_init(struct net_device *dev);
 static void el3_common_remove(struct net_device *dev);
 static ushort id_read_eeprom(int index);
 static ushort read_eeprom(int ioaddr, int index);
@@ -395,7 +395,7 @@ static struct isa_driver el3_isa_driver = {
 static int isa_registered;
 
 #ifdef CONFIG_PNP
-static const struct pnp_device_id el3_pnp_ids[] __devinitconst = {
+static struct pnp_device_id el3_pnp_ids[] = {
        { .id = "TCM5090" }, /* 3Com Etherlink III (TP) */
        { .id = "TCM5091" }, /* 3Com Etherlink III */
        { .id = "TCM5094" }, /* 3Com Etherlink III (combo) */
@@ -478,7 +478,7 @@ static int pnp_registered;
 #endif /* CONFIG_PNP */
 
 #ifdef CONFIG_EISA
-static const struct eisa_device_id el3_eisa_ids[] __devinitconst = {
+static struct eisa_device_id el3_eisa_ids[] = {
                { "TCM5090" },
                { "TCM5091" },
                { "TCM5092" },
@@ -508,7 +508,7 @@ static int eisa_registered;
 #ifdef CONFIG_MCA
 static int el3_mca_probe(struct device *dev);
 
-static const short el3_mca_adapter_ids[] __devinitconst = {
+static short el3_mca_adapter_ids[] __initdata = {
                0x627c,
                0x627d,
                0x62db,
@@ -517,7 +517,7 @@ static const short el3_mca_adapter_ids[] __devinitconst = {
                0x0000
 };
 
-static const char *const el3_mca_adapter_names[] __devinitconst = {
+static char *el3_mca_adapter_names[] __initdata = {
                "3Com 3c529 EtherLink III (10base2)",
                "3Com 3c529 EtherLink III (10baseT)",
                "3Com 3c529 EtherLink III (test mode)",
@@ -601,7 +601,7 @@ static void el3_common_remove (struct net_device *dev)
 }
 
 #ifdef CONFIG_MCA
-static int __devinit el3_mca_probe(struct device *device)
+static int __init el3_mca_probe(struct device *device)
 {
        /* Based on Erik Nygren's (nygren@mit.edu) 3c529 patch,
         * heavily modified by Chris Beauregard
@@ -671,7 +671,7 @@ static int __devinit el3_mca_probe(struct device *device)
 #endif /* CONFIG_MCA */
 
 #ifdef CONFIG_EISA
-static int __devinit el3_eisa_probe (struct device *device)
+static int __init el3_eisa_probe (struct device *device)
 {
        short i;
        int ioaddr, irq, if_port;
index 99f43d275442f793e117cc6064d3f894eee6f928..8cc22568ebd3429282b8674b912cb8fe80eb7a03 100644 (file)
@@ -901,14 +901,14 @@ static const struct dev_pm_ops vortex_pm_ops = {
 #endif /* !CONFIG_PM */
 
 #ifdef CONFIG_EISA
-static const struct eisa_device_id vortex_eisa_ids[] __devinitconst = {
+static struct eisa_device_id vortex_eisa_ids[] = {
        { "TCM5920", CH_3C592 },
        { "TCM5970", CH_3C597 },
        { "" }
 };
 MODULE_DEVICE_TABLE(eisa, vortex_eisa_ids);
 
-static int __devinit vortex_eisa_probe(struct device *device)
+static int __init vortex_eisa_probe(struct device *device)
 {
        void __iomem *ioaddr;
        struct eisa_device *edev;
index 73c7e03617ecc52313af4335f8b245d46b7eecb4..3df0c0f8b8bf93ca98a8829e7c09162a70f384c4 100644 (file)
@@ -167,8 +167,8 @@ static inline void debugfs_tx(struct ser_device *ser, const u8 *data, int size)
 
 #endif
 
-static unsigned int ldisc_receive(struct tty_struct *tty,
-               const u8 *data, char *flags, int count)
+static void ldisc_receive(struct tty_struct *tty, const u8 *data,
+                       char *flags, int count)
 {
        struct sk_buff *skb = NULL;
        struct ser_device *ser;
@@ -215,8 +215,6 @@ static unsigned int ldisc_receive(struct tty_struct *tty,
        } else
                ++ser->dev->stats.rx_dropped;
        update_tty_status(ser);
-
-       return count;
 }
 
 static int handle_tx(struct ser_device *ser)
index d4990568baee071cd5ceaaac9a91c6bc5d6cf7c9..17678117ed69dba42d02339ec76b962bf25f1695 100644 (file)
@@ -923,7 +923,7 @@ static int __devinit flexcan_probe(struct platform_device *pdev)
        mem_size = resource_size(mem);
        if (!request_mem_region(mem->start, mem_size, pdev->name)) {
                err = -EBUSY;
-               goto failed_req;
+               goto failed_get;
        }
 
        base = ioremap(mem->start, mem_size);
@@ -977,9 +977,8 @@ static int __devinit flexcan_probe(struct platform_device *pdev)
        iounmap(base);
  failed_map:
        release_mem_region(mem->start, mem_size);
- failed_req:
-       clk_put(clk);
  failed_get:
+       clk_put(clk);
  failed_clock:
        return err;
 }
index 75622d54581f15f87ea3ca4b893e7f37cbf34e9e..1b49df6b2470874b0cb76cf45214f247c6d3bf29 100644 (file)
@@ -425,17 +425,16 @@ static void slc_setup(struct net_device *dev)
  * in parallel
  */
 
-static unsigned int slcan_receive_buf(struct tty_struct *tty,
+static void slcan_receive_buf(struct tty_struct *tty,
                              const unsigned char *cp, char *fp, int count)
 {
        struct slcan *sl = (struct slcan *) tty->disc_data;
-       int bytes = count;
 
        if (!sl || sl->magic != SLCAN_MAGIC || !netif_running(sl->dev))
-               return -ENODEV;
+               return;
 
        /* Read the characters out of the buffer */
-       while (bytes--) {
+       while (count--) {
                if (fp && *fp++) {
                        if (!test_and_set_bit(SLF_ERROR, &sl->flags))
                                sl->dev->stats.rx_errors++;
@@ -444,8 +443,6 @@ static unsigned int slcan_receive_buf(struct tty_struct *tty,
                }
                slcan_unesc(sl, *cp++);
        }
-
-       return count;
 }
 
 /************************************
index 29a4f06fbfcf0004c53e96d51cc5d6da0aaaf76b..dcc4a170b0f397ed5362341a8d5a62fb07d411a4 100644 (file)
@@ -1781,8 +1781,8 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev)
        ndev = alloc_etherdev(sizeof(struct emac_priv));
        if (!ndev) {
                dev_err(&pdev->dev, "error allocating net_device\n");
-               clk_put(emac_clk);
-               return -ENOMEM;
+               rc = -ENOMEM;
+               goto free_clk;
        }
 
        platform_set_drvdata(pdev, ndev);
@@ -1796,7 +1796,8 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev)
        pdata = pdev->dev.platform_data;
        if (!pdata) {
                dev_err(&pdev->dev, "no platform data\n");
-               return -ENODEV;
+               rc = -ENODEV;
+               goto probe_quit;
        }
 
        /* MAC addr and PHY mask , RMII enable info from platform_data */
@@ -1929,8 +1930,9 @@ no_dma:
        iounmap(priv->remap_addr);
 
 probe_quit:
-       clk_put(emac_clk);
        free_netdev(ndev);
+free_clk:
+       clk_put(emac_clk);
        return rc;
 }
 
index 17654059922de988574f7c888d7367164265fda8..8b0084d17c8c82f1a6c30a273614a0689999661c 100644 (file)
@@ -331,18 +331,18 @@ static struct {
                          "DE422",\
                          ""}
 
-static const char* const depca_signature[] __devinitconst = DEPCA_SIGNATURE;
+static char* __initdata depca_signature[] = DEPCA_SIGNATURE;
 
 enum depca_type {
        DEPCA, de100, de101, de200, de201, de202, de210, de212, de422, unknown
 };
 
-static const char depca_string[] = "depca";
+static char depca_string[] = "depca";
 
 static int depca_device_remove (struct device *device);
 
 #ifdef CONFIG_EISA
-static const struct eisa_device_id depca_eisa_ids[] __devinitconst = {
+static struct eisa_device_id depca_eisa_ids[] = {
        { "DEC4220", de422 },
        { "" }
 };
@@ -367,19 +367,19 @@ static struct eisa_driver depca_eisa_driver = {
 #define DE210_ID 0x628d
 #define DE212_ID 0x6def
 
-static const short depca_mca_adapter_ids[] __devinitconst = {
+static short depca_mca_adapter_ids[] = {
        DE210_ID,
        DE212_ID,
        0x0000
 };
 
-static const char *depca_mca_adapter_name[] = {
+static char *depca_mca_adapter_name[] = {
        "DEC EtherWORKS MC Adapter (DE210)",
        "DEC EtherWORKS MC Adapter (DE212)",
        NULL
 };
 
-static const enum depca_type depca_mca_adapter_type[] = {
+static enum depca_type depca_mca_adapter_type[] = {
        de210,
        de212,
        0
@@ -541,9 +541,10 @@ static void SetMulticastFilter(struct net_device *dev);
 static int load_packet(struct net_device *dev, struct sk_buff *skb);
 static void depca_dbg_open(struct net_device *dev);
 
-static const u_char de1xx_irq[] __devinitconst = { 2, 3, 4, 5, 7, 9, 0 };
-static const u_char de2xx_irq[] __devinitconst = { 5, 9, 10, 11, 15, 0 };
-static const u_char de422_irq[] __devinitconst = { 5, 9, 10, 11, 0 };
+static u_char de1xx_irq[] __initdata = { 2, 3, 4, 5, 7, 9, 0 };
+static u_char de2xx_irq[] __initdata = { 5, 9, 10, 11, 15, 0 };
+static u_char de422_irq[] __initdata = { 5, 9, 10, 11, 0 };
+static u_char *depca_irq;
 
 static int irq;
 static int io;
@@ -579,7 +580,7 @@ static const struct net_device_ops depca_netdev_ops = {
        .ndo_validate_addr      = eth_validate_addr,
 };
 
-static int __devinit depca_hw_init (struct net_device *dev, struct device *device)
+static int __init depca_hw_init (struct net_device *dev, struct device *device)
 {
        struct depca_private *lp;
        int i, j, offset, netRAM, mem_len, status = 0;
@@ -747,7 +748,6 @@ static int __devinit depca_hw_init (struct net_device *dev, struct device *devic
        if (dev->irq < 2) {
                unsigned char irqnum;
                unsigned long irq_mask, delay;
-               const u_char *depca_irq;
 
                irq_mask = probe_irq_on();
 
@@ -770,7 +770,6 @@ static int __devinit depca_hw_init (struct net_device *dev, struct device *devic
                        break;
 
                default:
-                       depca_irq = NULL;
                        break;  /* Not reached */
                }
 
@@ -1303,7 +1302,7 @@ static void SetMulticastFilter(struct net_device *dev)
        }
 }
 
-static int __devinit depca_common_init (u_long ioaddr, struct net_device **devp)
+static int __init depca_common_init (u_long ioaddr, struct net_device **devp)
 {
        int status = 0;
 
@@ -1334,7 +1333,7 @@ static int __devinit depca_common_init (u_long ioaddr, struct net_device **devp)
 /*
 ** Microchannel bus I/O device probe
 */
-static int __devinit depca_mca_probe(struct device *device)
+static int __init depca_mca_probe(struct device *device)
 {
        unsigned char pos[2];
        unsigned char where;
@@ -1458,7 +1457,7 @@ static int __devinit depca_mca_probe(struct device *device)
 ** ISA bus I/O device probe
 */
 
-static void __devinit depca_platform_probe (void)
+static void __init depca_platform_probe (void)
 {
        int i;
        struct platform_device *pldev;
@@ -1498,7 +1497,7 @@ static void __devinit depca_platform_probe (void)
        }
 }
 
-static enum depca_type __devinit depca_shmem_probe (ulong *mem_start)
+static enum depca_type __init depca_shmem_probe (ulong *mem_start)
 {
        u_long mem_base[] = DEPCA_RAM_BASE_ADDRESSES;
        enum depca_type adapter = unknown;
@@ -1559,7 +1558,7 @@ static int __devinit depca_isa_probe (struct platform_device *device)
 */
 
 #ifdef CONFIG_EISA
-static int __devinit depca_eisa_probe (struct device *device)
+static int __init depca_eisa_probe (struct device *device)
 {
        enum depca_type adapter = unknown;
        struct eisa_device *edev;
@@ -1630,7 +1629,7 @@ static int __devexit depca_device_remove (struct device *device)
 ** and Boot (readb) ROM. This will also give us a clue to the network RAM
 ** base address.
 */
-static int __devinit DepcaSignature(char *name, u_long base_addr)
+static int __init DepcaSignature(char *name, u_long base_addr)
 {
        u_int i, j, k;
        void __iomem *ptr;
index fbaff3584bd4982e5c3f72c6079d86f6d12b5f22..ee597e676ee500235f7dace13c570ad92e20724f 100644 (file)
@@ -1157,9 +1157,6 @@ dm9000_open(struct net_device *dev)
 
        irqflags |= IRQF_SHARED;
 
-       if (request_irq(dev->irq, dm9000_interrupt, irqflags, dev->name, dev))
-               return -EAGAIN;
-
        /* GPIO0 on pre-activate PHY, Reg 1F is not set by reset */
        iow(db, DM9000_GPR, 0); /* REG_1F bit0 activate phyxcer */
        mdelay(1); /* delay needs by DM9000B */
@@ -1168,6 +1165,9 @@ dm9000_open(struct net_device *dev)
        dm9000_reset(db);
        dm9000_init_dm9000(dev);
 
+       if (request_irq(dev->irq, dm9000_interrupt, irqflags, dev->name, dev))
+               return -EAGAIN;
+
        /* Init driver variable */
        db->dbug_cnt = 0;
 
index 992089639ea4824404f42d53e5362eab2c2fb586..3e5d0b6b6516133039192fa5dfd1fdf88660d81b 100644 (file)
@@ -456,7 +456,7 @@ out:
  * a block of 6pack data has been received, which can now be decapsulated
  * and sent on to some IP layer for further processing.
  */
-static unsigned int sixpack_receive_buf(struct tty_struct *tty,
+static void sixpack_receive_buf(struct tty_struct *tty,
        const unsigned char *cp, char *fp, int count)
 {
        struct sixpack *sp;
@@ -464,11 +464,11 @@ static unsigned int sixpack_receive_buf(struct tty_struct *tty,
        int count1;
 
        if (!count)
-               return 0;
+               return;
 
        sp = sp_get(tty);
        if (!sp)
-               return -ENODEV;
+               return;
 
        memcpy(buf, cp, count < sizeof(buf) ? count : sizeof(buf));
 
@@ -487,8 +487,6 @@ static unsigned int sixpack_receive_buf(struct tty_struct *tty,
 
        sp_put(sp);
        tty_unthrottle(tty);
-
-       return count1;
 }
 
 /*
index 0e4f23531140c8ca6f938447f145351c39b93a37..4c628393c8b157cbc09de52d902b5fa8c3d370a3 100644 (file)
@@ -923,14 +923,13 @@ static long mkiss_compat_ioctl(struct tty_struct *tty, struct file *file,
  * a block of data has been received, which can now be decapsulated
  * and sent on to the AX.25 layer for further processing.
  */
-static unsigned int mkiss_receive_buf(struct tty_struct *tty,
-               const unsigned char *cp, char *fp, int count)
+static void mkiss_receive_buf(struct tty_struct *tty, const unsigned char *cp,
+       char *fp, int count)
 {
        struct mkiss *ax = mkiss_get(tty);
-       int bytes = count;
 
        if (!ax)
-               return -ENODEV;
+               return;
 
        /*
         * Argh! mtu change time! - costs us the packet part received
@@ -940,7 +939,7 @@ static unsigned int mkiss_receive_buf(struct tty_struct *tty,
                ax_changedmtu(ax);
 
        /* Read the characters out of the buffer */
-       while (bytes--) {
+       while (count--) {
                if (fp != NULL && *fp++) {
                        if (!test_and_set_bit(AXF_ERROR, &ax->flags))
                                ax->dev->stats.rx_errors++;
@@ -953,8 +952,6 @@ static unsigned int mkiss_receive_buf(struct tty_struct *tty,
 
        mkiss_put(ax);
        tty_unthrottle(tty);
-
-       return count;
 }
 
 /*
index c52a1df5d922b0e0e22bced1d0d0d046003acddc..8e10d2f6a5adc8340d239c729e835fb0122b3acd 100644 (file)
@@ -188,14 +188,14 @@ struct hp100_private {
  *  variables
  */
 #ifdef CONFIG_ISA
-static const char *const hp100_isa_tbl[] __devinitconst = {
+static const char *hp100_isa_tbl[] = {
        "HWPF150", /* HP J2573 rev A */
        "HWP1950", /* HP J2573 */
 };
 #endif
 
 #ifdef CONFIG_EISA
-static const struct eisa_device_id hp100_eisa_tbl[] __devinitconst = {
+static struct eisa_device_id hp100_eisa_tbl[] = {
        { "HWPF180" }, /* HP J2577 rev A */
        { "HWP1920" }, /* HP 27248B */
        { "HWP1940" }, /* HP J2577 */
@@ -336,7 +336,7 @@ static __devinit const char *hp100_read_id(int ioaddr)
 }
 
 #ifdef CONFIG_ISA
-static __devinit int hp100_isa_probe1(struct net_device *dev, int ioaddr)
+static __init int hp100_isa_probe1(struct net_device *dev, int ioaddr)
 {
        const char *sig;
        int i;
@@ -372,7 +372,7 @@ static __devinit int hp100_isa_probe1(struct net_device *dev, int ioaddr)
  * EISA and PCI are handled by device infrastructure.
  */
 
-static int  __devinit hp100_isa_probe(struct net_device *dev, int addr)
+static int  __init hp100_isa_probe(struct net_device *dev, int addr)
 {
        int err = -ENODEV;
 
@@ -396,7 +396,7 @@ static int  __devinit hp100_isa_probe(struct net_device *dev, int addr)
 #endif /* CONFIG_ISA */
 
 #if !defined(MODULE) && defined(CONFIG_ISA)
-struct net_device * __devinit hp100_probe(int unit)
+struct net_device * __init hp100_probe(int unit)
 {
        struct net_device *dev = alloc_etherdev(sizeof(struct hp100_private));
        int err;
@@ -2843,7 +2843,7 @@ static void cleanup_dev(struct net_device *d)
 }
 
 #ifdef CONFIG_EISA
-static int __devinit hp100_eisa_probe (struct device *gendev)
+static int __init hp100_eisa_probe (struct device *gendev)
 {
        struct net_device *dev = alloc_etherdev(sizeof(struct hp100_private));
        struct eisa_device *edev = to_eisa_device(gendev);
index 136d7544cc33331c735684b56b44cffb27ef8b94..a7d6cad3295368a85f5720965746930141f51ac6 100644 (file)
@@ -895,12 +895,12 @@ static int ibmlana_irq;
 static int ibmlana_io;
 static int startslot;          /* counts through slots when probing multiple devices */
 
-static const short ibmlana_adapter_ids[] __devinitconst = {
+static short ibmlana_adapter_ids[] __initdata = {
        IBM_LANA_ID,
        0x0000
 };
 
-static const char *const ibmlana_adapter_names[] __devinitconst = {
+static char *ibmlana_adapter_names[] __devinitdata = {
        "IBM LAN Adapter/A",
        NULL
 };
index 035861d8acb157f47d080b074c1de9a73a2988e1..3352b2443e58eb1ca0a45856c628850c08092be6 100644 (file)
@@ -216,23 +216,23 @@ static int irtty_do_write(struct sir_dev *dev, const unsigned char *ptr, size_t
  * usbserial:  urb-complete-interrupt / softint
  */
 
-static unsigned int irtty_receive_buf(struct tty_struct *tty,
-               const unsigned char *cp, char *fp, int count)
+static void irtty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
+                             char *fp, int count) 
 {
        struct sir_dev *dev;
        struct sirtty_cb *priv = tty->disc_data;
        int     i;
 
-       IRDA_ASSERT(priv != NULL, return -ENODEV;);
-       IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return -EINVAL;);
+       IRDA_ASSERT(priv != NULL, return;);
+       IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return;);
 
        if (unlikely(count==0))         /* yes, this happens */
-               return 0;
+               return;
 
        dev = priv->dev;
        if (!dev) {
                IRDA_WARNING("%s(), not ready yet!\n", __func__);
-               return -ENODEV;
+               return;
        }
 
        for (i = 0; i < count; i++) {
@@ -242,13 +242,11 @@ static unsigned int irtty_receive_buf(struct tty_struct *tty,
                if (fp && *fp++) { 
                        IRDA_DEBUG(0, "Framing or parity error!\n");
                        sirdev_receive(dev, NULL, 0);   /* notify sir_dev (updating stats) */
-                       return -EINVAL;
+                       return;
                }
        }
 
        sirdev_receive(dev, cp, count);
-
-       return count;
 }
 
 /*
index 69b5707db369e3dfdcbde140b5aa69e60803e47b..8800e1fe4129a84a41b2a6d5da495b5e807b8301 100644 (file)
@@ -222,19 +222,19 @@ static void smsc_ircc_set_transceiver_for_speed(struct smsc_ircc_cb *self, u32 s
 static void smsc_ircc_sir_wait_hw_transmitter_finish(struct smsc_ircc_cb *self);
 
 /* Probing */
-static int smsc_ircc_look_for_chips(void);
-static const struct smsc_chip * smsc_ircc_probe(unsigned short cfg_base, u8 reg, const struct smsc_chip *chip, char *type);
-static int smsc_superio_flat(const struct smsc_chip *chips, unsigned short cfg_base, char *type);
-static int smsc_superio_paged(const struct smsc_chip *chips, unsigned short cfg_base, char *type);
-static int smsc_superio_fdc(unsigned short cfg_base);
-static int smsc_superio_lpc(unsigned short cfg_base);
+static int __init smsc_ircc_look_for_chips(void);
+static const struct smsc_chip * __init smsc_ircc_probe(unsigned short cfg_base, u8 reg, const struct smsc_chip *chip, char *type);
+static int __init smsc_superio_flat(const struct smsc_chip *chips, unsigned short cfg_base, char *type);
+static int __init smsc_superio_paged(const struct smsc_chip *chips, unsigned short cfg_base, char *type);
+static int __init smsc_superio_fdc(unsigned short cfg_base);
+static int __init smsc_superio_lpc(unsigned short cfg_base);
 #ifdef CONFIG_PCI
-static int preconfigure_smsc_chip(struct smsc_ircc_subsystem_configuration *conf);
-static int preconfigure_through_82801(struct pci_dev *dev, struct smsc_ircc_subsystem_configuration *conf);
-static void preconfigure_ali_port(struct pci_dev *dev,
+static int __init preconfigure_smsc_chip(struct smsc_ircc_subsystem_configuration *conf);
+static int __init preconfigure_through_82801(struct pci_dev *dev, struct smsc_ircc_subsystem_configuration *conf);
+static void __init preconfigure_ali_port(struct pci_dev *dev,
                                         unsigned short port);
-static int preconfigure_through_ali(struct pci_dev *dev, struct smsc_ircc_subsystem_configuration *conf);
-static int smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg,
+static int __init preconfigure_through_ali(struct pci_dev *dev, struct smsc_ircc_subsystem_configuration *conf);
+static int __init smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg,
                                                    unsigned short ircc_fir,
                                                    unsigned short ircc_sir,
                                                    unsigned char ircc_dma,
@@ -366,7 +366,7 @@ static inline void register_bank(int iobase, int bank)
 }
 
 /* PNP hotplug support */
-static const struct pnp_device_id smsc_ircc_pnp_table[] __devinitconst = {
+static const struct pnp_device_id smsc_ircc_pnp_table[] = {
        { .id = "SMCf010", .driver_data = 0 },
        /* and presumably others */
        { }
@@ -515,7 +515,7 @@ static const struct net_device_ops smsc_ircc_netdev_ops = {
  *    Try to open driver instance
  *
  */
-static int __devinit smsc_ircc_open(unsigned int fir_base, unsigned int sir_base, u8 dma, u8 irq)
+static int __init smsc_ircc_open(unsigned int fir_base, unsigned int sir_base, u8 dma, u8 irq)
 {
        struct smsc_ircc_cb *self;
        struct net_device *dev;
@@ -2273,7 +2273,7 @@ static int __init smsc_superio_paged(const struct smsc_chip *chips, unsigned sho
 }
 
 
-static int __devinit smsc_access(unsigned short cfg_base, unsigned char reg)
+static int __init smsc_access(unsigned short cfg_base, unsigned char reg)
 {
        IRDA_DEBUG(1, "%s\n", __func__);
 
@@ -2281,7 +2281,7 @@ static int __devinit smsc_access(unsigned short cfg_base, unsigned char reg)
        return inb(cfg_base) != reg ? -1 : 0;
 }
 
-static const struct smsc_chip * __devinit smsc_ircc_probe(unsigned short cfg_base, u8 reg, const struct smsc_chip *chip, char *type)
+static const struct smsc_chip * __init smsc_ircc_probe(unsigned short cfg_base, u8 reg, const struct smsc_chip *chip, char *type)
 {
        u8 devid, xdevid, rev;
 
@@ -2406,7 +2406,7 @@ static int __init smsc_superio_lpc(unsigned short cfg_base)
 #ifdef CONFIG_PCI
 #define PCIID_VENDOR_INTEL 0x8086
 #define PCIID_VENDOR_ALI 0x10b9
-static const struct smsc_ircc_subsystem_configuration subsystem_configurations[] __devinitconst = {
+static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __initdata = {
        /*
         * Subsystems needing entries:
         * 0x10b9:0x1533 0x103c:0x0850 HP nx9010 family
@@ -2532,7 +2532,7 @@ static const struct smsc_ircc_subsystem_configuration subsystem_configurations[]
  * (FIR port, SIR port, FIR DMA, FIR IRQ)
  * through the chip configuration port.
  */
-static int __devinit preconfigure_smsc_chip(struct
+static int __init preconfigure_smsc_chip(struct
                                         smsc_ircc_subsystem_configuration
                                         *conf)
 {
@@ -2633,7 +2633,7 @@ static int __devinit preconfigure_smsc_chip(struct
  * or Intel 82801DB/DBL (ICH4/ICH4-L) LPC Interface Bridge.
  * They all work the same way!
  */
-static int __devinit preconfigure_through_82801(struct pci_dev *dev,
+static int __init preconfigure_through_82801(struct pci_dev *dev,
                                             struct
                                             smsc_ircc_subsystem_configuration
                                             *conf)
@@ -2786,7 +2786,7 @@ static int __devinit preconfigure_through_82801(struct pci_dev *dev,
  * This is based on reverse-engineering since ALi does not
  * provide any data sheet for the 1533 chip.
  */
-static void __devinit preconfigure_ali_port(struct pci_dev *dev,
+static void __init preconfigure_ali_port(struct pci_dev *dev,
                                         unsigned short port)
 {
        unsigned char reg;
@@ -2824,7 +2824,7 @@ static void __devinit preconfigure_ali_port(struct pci_dev *dev,
        IRDA_MESSAGE("Activated ALi 1533 ISA bridge port 0x%04x.\n", port);
 }
 
-static int __devinit preconfigure_through_ali(struct pci_dev *dev,
+static int __init preconfigure_through_ali(struct pci_dev *dev,
                                           struct
                                           smsc_ircc_subsystem_configuration
                                           *conf)
@@ -2837,7 +2837,7 @@ static int __devinit preconfigure_through_ali(struct pci_dev *dev,
        return preconfigure_smsc_chip(conf);
 }
 
-static int __devinit smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg,
+static int __init smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg,
                                                    unsigned short ircc_fir,
                                                    unsigned short ircc_sir,
                                                    unsigned char ircc_dma,
@@ -2849,7 +2849,7 @@ static int __devinit smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg,
        int ret = 0;
 
        for_each_pci_dev(dev) {
-               const struct smsc_ircc_subsystem_configuration *conf;
+               struct smsc_ircc_subsystem_configuration *conf;
 
                /*
                 * Cache the subsystem vendor/device:
index 4d40626b3bfa989b7051a7ea5872faa06ba61601..fc12ac0d9f2e55012d202a44acfca9e8d432c6bd 100644 (file)
@@ -661,7 +661,7 @@ static void ks8842_rx_frame(struct net_device *netdev,
 
        /* check the status */
        if ((status & RXSR_VALID) && !(status & RXSR_ERROR)) {
-               struct sk_buff *skb = netdev_alloc_skb_ip_align(netdev, len);
+               struct sk_buff *skb = netdev_alloc_skb_ip_align(netdev, len + 3);
 
                if (skb) {
 
index e8984b0ca52104c08e9bddf4eafeec8630a5d167..243ed2aee88e35e801a2c6582f8a80d4e287ba7b 100644 (file)
@@ -80,20 +80,17 @@ static void ne3210_block_output(struct net_device *dev, int count, const unsigne
 
 #define NE3210_DEBUG   0x0
 
-static const unsigned char irq_map[] __devinitconst =
-       { 15, 12, 11, 10, 9, 7, 5, 3 };
-static const unsigned int shmem_map[] __devinitconst =
-       { 0xff0, 0xfe0, 0xfff0, 0xd8, 0xffe0, 0xffc0, 0xd0, 0x0 };
-static const char *const ifmap[] __devinitconst =
-       { "UTP", "?", "BNC", "AUI" };
-static const int ifmap_val[] __devinitconst = {
+static unsigned char irq_map[] __initdata = {15, 12, 11, 10, 9, 7, 5, 3};
+static unsigned int shmem_map[] __initdata = {0xff0, 0xfe0, 0xfff0, 0xd8, 0xffe0, 0xffc0, 0xd0, 0x0};
+static const char *ifmap[] __initdata = {"UTP", "?", "BNC", "AUI"};
+static int ifmap_val[] __initdata = {
                IF_PORT_10BASET,
                IF_PORT_UNKNOWN,
                IF_PORT_10BASE2,
                IF_PORT_AUI,
 };
 
-static int __devinit ne3210_eisa_probe (struct device *device)
+static int __init ne3210_eisa_probe (struct device *device)
 {
        unsigned long ioaddr, phys_mem;
        int i, retval, port_index;
@@ -316,7 +313,7 @@ static void ne3210_block_output(struct net_device *dev, int count,
        memcpy_toio(shmem, buf, count);
 }
 
-static const struct eisa_device_id ne3210_ids[] __devinitconst = {
+static struct eisa_device_id ne3210_ids[] = {
        { "EGL0101" },
        { "NVL1801" },
        { "" },
index 53872d7d738219968a0f433beb0ac128bdb67d6d..a1b82c9c67d246c64f41ee1ec51f83b04fe0a6fa 100644 (file)
@@ -340,7 +340,7 @@ ppp_asynctty_poll(struct tty_struct *tty, struct file *file, poll_table *wait)
 }
 
 /* May sleep, don't call from interrupt level or with interrupts disabled */
-static unsigned int
+static void
 ppp_asynctty_receive(struct tty_struct *tty, const unsigned char *buf,
                  char *cflags, int count)
 {
@@ -348,7 +348,7 @@ ppp_asynctty_receive(struct tty_struct *tty, const unsigned char *buf,
        unsigned long flags;
 
        if (!ap)
-               return -ENODEV;
+               return;
        spin_lock_irqsave(&ap->recv_lock, flags);
        ppp_async_input(ap, buf, cflags, count);
        spin_unlock_irqrestore(&ap->recv_lock, flags);
@@ -356,8 +356,6 @@ ppp_asynctty_receive(struct tty_struct *tty, const unsigned char *buf,
                tasklet_schedule(&ap->tsk);
        ap_put(ap);
        tty_unthrottle(tty);
-
-       return count;
 }
 
 static void
index 0815790a5cf9930c017f490ae5d52e1d3ea67ecb..2573f525f11c31ced737e750fefc66807bbbfc65 100644 (file)
@@ -381,7 +381,7 @@ ppp_sync_poll(struct tty_struct *tty, struct file *file, poll_table *wait)
 }
 
 /* May sleep, don't call from interrupt level or with interrupts disabled */
-static unsigned int
+static void
 ppp_sync_receive(struct tty_struct *tty, const unsigned char *buf,
                  char *cflags, int count)
 {
@@ -389,7 +389,7 @@ ppp_sync_receive(struct tty_struct *tty, const unsigned char *buf,
        unsigned long flags;
 
        if (!ap)
-               return -ENODEV;
+               return;
        spin_lock_irqsave(&ap->recv_lock, flags);
        ppp_sync_input(ap, buf, cflags, count);
        spin_unlock_irqrestore(&ap->recv_lock, flags);
@@ -397,8 +397,6 @@ ppp_sync_receive(struct tty_struct *tty, const unsigned char *buf,
                tasklet_schedule(&ap->tsk);
        sp_put(ap);
        tty_unthrottle(tty);
-
-       return count;
 }
 
 static void
index 584809c656d5aaecda43d638fcaba1f48c929c89..8ec1a9a0bb9ae007c69865b2599f07d3f23c99c8 100644 (file)
@@ -670,17 +670,16 @@ static void sl_setup(struct net_device *dev)
  * in parallel
  */
 
-static unsigned int slip_receive_buf(struct tty_struct *tty,
-               const unsigned char *cp, char *fp, int count)
+static void slip_receive_buf(struct tty_struct *tty, const unsigned char *cp,
+                                                       char *fp, int count)
 {
        struct slip *sl = tty->disc_data;
-       int bytes = count;
 
        if (!sl || sl->magic != SLIP_MAGIC || !netif_running(sl->dev))
-               return -ENODEV;
+               return;
 
        /* Read the characters out of the buffer */
-       while (bytes--) {
+       while (count--) {
                if (fp && *fp++) {
                        if (!test_and_set_bit(SLF_ERROR, &sl->flags))
                                sl->dev->stats.rx_errors++;
@@ -694,8 +693,6 @@ static unsigned int slip_receive_buf(struct tty_struct *tty,
 #endif
                        slip_unesc(sl, *cp++);
        }
-
-       return count;
 }
 
 /************************************
index 0f29f261fcfeb9b7658bbdb862b6676e1d1b5cb0..d07c39cb4daf59ae1e765b927d5156e816b80a9b 100644 (file)
@@ -156,7 +156,7 @@ static const struct {
    { 14, 15 }
 };
 
-static const short smc_mca_adapter_ids[] __devinitconst = {
+static short smc_mca_adapter_ids[] __initdata = {
        0x61c8,
        0x61c9,
        0x6fc0,
@@ -168,7 +168,7 @@ static const short smc_mca_adapter_ids[] __devinitconst = {
        0x0000
 };
 
-static const char *const smc_mca_adapter_names[] __devinitconst = {
+static char *smc_mca_adapter_names[] __initdata = {
        "SMC Ethercard PLUS Elite/A BNC/AUI (WD8013EP/A)",
        "SMC Ethercard PLUS Elite/A UTP/AUI (WD8013WP/A)",
        "WD Ethercard PLUS/A (WD8003E/A or WD8003ET/A)",
@@ -199,7 +199,7 @@ static const struct net_device_ops ultramca_netdev_ops = {
 #endif
 };
 
-static int __devinit ultramca_probe(struct device *gen_dev)
+static int __init ultramca_probe(struct device *gen_dev)
 {
        unsigned short ioaddr;
        struct net_device *dev;
index f4b01c638a330d969ab32f88178bc51ab7eebf73..a1f9f9eef37d3b04b8d1344c964eec0a57c56eb2 100644 (file)
@@ -5774,7 +5774,7 @@ static void tg3_skb_error_unmap(struct tg3_napi *tnapi,
                         dma_unmap_addr(txb, mapping),
                         skb_headlen(skb),
                         PCI_DMA_TODEVICE);
-       for (i = 0; i <= last; i++) {
+       for (i = 0; i < last; i++) {
                skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
 
                entry = NEXT_TX(entry);
index 1313aa1315f01bcc241dbb41276831d2931b005d..2bedc0ace812ac2b5bfbf4ec05a54acc7f7c1ed5 100644 (file)
@@ -727,7 +727,7 @@ static int __devexit madgemc_remove(struct device *device)
        return 0;
 }
 
-static const short madgemc_adapter_ids[] __devinitconst = {
+static short madgemc_adapter_ids[] __initdata = {
        0x002d,
        0x0000
 };
index 45144d5bd11b26f6f86bd5db3e127239c2b0675c..efaa1d69b72082b5a0729710d0e86647b96bcc1e 100644 (file)
@@ -1995,7 +1995,7 @@ SetMulticastFilter(struct net_device *dev)
 
 static u_char de4x5_irq[] = EISA_ALLOWED_IRQ_LIST;
 
-static int __devinit de4x5_eisa_probe (struct device *gendev)
+static int __init de4x5_eisa_probe (struct device *gendev)
 {
        struct eisa_device *edev;
        u_long iobase;
@@ -2097,7 +2097,7 @@ static int __devexit de4x5_eisa_remove (struct device *device)
        return 0;
 }
 
-static const struct eisa_device_id de4x5_eisa_ids[] __devinitconst = {
+static struct eisa_device_id de4x5_eisa_ids[] = {
         { "DEC4250", 0 },      /* 0 is the board name index... */
         { "" }
 };
index d7221c4a5dcf97973b97ee50d93aec593a90b434..8056f8a27c6a0695f660648875dfeb0f60e7ee7e 100644 (file)
@@ -495,7 +495,7 @@ static void catc_ctrl_run(struct catc *catc)
        if (!q->dir && q->buf && q->len)
                memcpy(catc->ctrl_buf, q->buf, q->len);
 
-       if ((status = usb_submit_urb(catc->ctrl_urb, GFP_KERNEL)))
+       if ((status = usb_submit_urb(catc->ctrl_urb, GFP_ATOMIC)))
                err("submit(ctrl_urb) status %d", status);
 }
 
index cdd3ae486109419949612b0df069be7ac001c0a3..f33ca6aa29e9cb95a8277891298317ca810cefa7 100644 (file)
@@ -54,7 +54,7 @@
 #include <linux/usb/usbnet.h>
 #include <linux/usb/cdc.h>
 
-#define        DRIVER_VERSION                          "24-May-2011"
+#define        DRIVER_VERSION                          "01-June-2011"
 
 /* CDC NCM subclass 3.2.1 */
 #define USB_CDC_NCM_NDP16_LENGTH_MIN           0x10
@@ -1234,6 +1234,7 @@ static struct usb_driver cdc_ncm_driver = {
        .disconnect = cdc_ncm_disconnect,
        .suspend = usbnet_suspend,
        .resume = usbnet_resume,
+       .reset_resume = usbnet_resume,
        .supports_autosuspend = 1,
 };
 
index 0cb0b0632672ac877c927195bde052a2d38f9ecf..f6853247a620046a12e9dab53c9e4f3adcf4d2b2 100644 (file)
@@ -609,7 +609,7 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev)
         * before it gets out of hand.  Naturally, this wastes entries. */
        if (capacity < 2+MAX_SKB_FRAGS) {
                netif_stop_queue(dev);
-               if (unlikely(!virtqueue_enable_cb(vi->svq))) {
+               if (unlikely(!virtqueue_enable_cb_delayed(vi->svq))) {
                        /* More just got used, free them then recheck. */
                        capacity += free_old_xmit_skbs(vi);
                        if (capacity >= 2+MAX_SKB_FRAGS) {
index 40398bf7d036fca1d1b56047f638375fdfd6f796..24297b274cd475ac855114394784c7eeaab2bcd0 100644 (file)
@@ -517,18 +517,17 @@ static int x25_asy_close(struct net_device *dev)
  * and sent on to some IP layer for further processing.
  */
 
-static unsigned int x25_asy_receive_buf(struct tty_struct *tty,
+static void x25_asy_receive_buf(struct tty_struct *tty,
                                const unsigned char *cp, char *fp, int count)
 {
        struct x25_asy *sl = tty->disc_data;
-       int bytes = count;
 
        if (!sl || sl->magic != X25_ASY_MAGIC || !netif_running(sl->dev))
                return;
 
 
        /* Read the characters out of the buffer */
-       while (bytes--) {
+       while (count--) {
                if (fp && *fp++) {
                        if (!test_and_set_bit(SLF_ERROR, &sl->flags))
                                sl->dev->stats.rx_errors++;
@@ -537,8 +536,6 @@ static unsigned int x25_asy_receive_buf(struct tty_struct *tty,
                }
                x25_asy_unesc(sl, *cp++);
        }
-
-       return count;
 }
 
 /*
index d9ff8413ab9af4e6e9634277cec7e58752c833b0..d9c08c619a3ab045fe7950aff6dc6f50d1f08b49 100644 (file)
@@ -26,7 +26,6 @@ config ATH9K
 config ATH9K_PCI
        bool "Atheros ath9k PCI/PCIe bus support"
        depends on ATH9K && PCI
-       default PCI
        ---help---
          This option enables the PCI bus support in ath9k.
 
index 015d97439935d05b0deb119471334929b7891f0f..2d4c0910295bd39b08cb4abdc845c140d6bc22de 100644 (file)
@@ -829,7 +829,7 @@ static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
        if (AR_SREV_9271(ah)) {
                if (!ar9285_hw_cl_cal(ah, chan))
                        return false;
-       } else if (AR_SREV_9285_12_OR_LATER(ah)) {
+       } else if (AR_SREV_9285(ah) && AR_SREV_9285_12_OR_LATER(ah)) {
                if (!ar9285_hw_clc(ah, chan))
                        return false;
        } else {
index 0ca7635d0669c276683762f85cd493b3a21e5b87..ff8150e46f0e969a159d3b481cee5752432fcace 100644 (file)
@@ -4645,10 +4645,16 @@ static void ar9003_hw_set_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;
        }
 
index eee23ecd118a292f35e959018414d6a548ed74d4..892c48b15434569c7b74d12d426e4cdb1c15dcfb 100644 (file)
@@ -1381,3 +1381,25 @@ void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah)
                "==== BB update: done ====\n\n");
 }
 EXPORT_SYMBOL(ar9003_hw_bb_watchdog_dbg_info);
+
+void ar9003_hw_disable_phy_restart(struct ath_hw *ah)
+{
+       u32 val;
+
+       /* While receiving unsupported rate frame rx state machine
+        * gets into a state 0xb and if phy_restart happens in that
+        * state, BB would go hang. If RXSM is in 0xb state after
+        * first bb panic, ensure to disable the phy_restart.
+        */
+       if (!((MS(ah->bb_watchdog_last_status,
+                 AR_PHY_WATCHDOG_RX_OFDM_SM) == 0xb) ||
+           ah->bb_hang_rx_ofdm))
+               return;
+
+       ah->bb_hang_rx_ofdm = true;
+       val = REG_READ(ah, AR_PHY_RESTART);
+       val &= ~AR_PHY_RESTART_ENA;
+
+       REG_WRITE(ah, AR_PHY_RESTART, val);
+}
+EXPORT_SYMBOL(ar9003_hw_disable_phy_restart);
index 7856f0d4512d6292a1a70ef3f4f98360666f1847..343fc9f946dbc7dcb6b613cad3cff3b2bb12e84e 100644 (file)
@@ -524,10 +524,16 @@ static void ath9k_hw_set_ar9287_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);
index 72543ce8f616a23b84d2949117ea65d1bd29982c..1be7c8bbef842f5cef15e10f60e47eb46d7d9aa7 100644 (file)
@@ -1555,9 +1555,12 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
        if (ah->btcoex_hw.enabled)
                ath9k_hw_btcoex_enable(ah);
 
-       if (AR_SREV_9300_20_OR_LATER(ah))
+       if (AR_SREV_9300_20_OR_LATER(ah)) {
                ar9003_hw_bb_watchdog_config(ah);
 
+               ar9003_hw_disable_phy_restart(ah);
+       }
+
        ath9k_hw_apply_gpio_override(ah);
 
        return 0;
index 57435ce627928adaada552ce1aa5636f140ea8cd..4b157c53d1a8da11ec217a498c5bdf94b12d3e93 100644 (file)
@@ -842,6 +842,7 @@ struct ath_hw {
 
        u32 bb_watchdog_last_status;
        u32 bb_watchdog_timeout_ms; /* in ms, 0 to disable */
+       u8 bb_hang_rx_ofdm; /* true if bb hang due to rx_ofdm */
 
        unsigned int paprd_target_power;
        unsigned int paprd_training_power;
@@ -990,6 +991,7 @@ void ar9002_hw_enable_wep_aggregation(struct ath_hw *ah);
 void ar9003_hw_bb_watchdog_config(struct ath_hw *ah);
 void ar9003_hw_bb_watchdog_read(struct ath_hw *ah);
 void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah);
+void ar9003_hw_disable_phy_restart(struct ath_hw *ah);
 void ar9003_paprd_enable(struct ath_hw *ah, bool val);
 void ar9003_paprd_populate_single_table(struct ath_hw *ah,
                                        struct ath9k_hw_cal_data *caldata,
index a198ee374b050b6d331107510be54b0618904ccd..2ca351fe6d3c0b056d4ecb8be14388aac195e85b 100644 (file)
@@ -670,7 +670,8 @@ void ath9k_tasklet(unsigned long data)
        u32 status = sc->intrstatus;
        u32 rxmask;
 
-       if (status & ATH9K_INT_FATAL) {
+       if ((status & ATH9K_INT_FATAL) ||
+           (status & ATH9K_INT_BB_WATCHDOG)) {
                ath_reset(sc, true);
                return;
        }
@@ -737,6 +738,7 @@ irqreturn_t ath_isr(int irq, void *dev)
 {
 #define SCHED_INTR (                           \
                ATH9K_INT_FATAL |               \
+               ATH9K_INT_BB_WATCHDOG |         \
                ATH9K_INT_RXORN |               \
                ATH9K_INT_RXEOL |               \
                ATH9K_INT_RX |                  \
index 17542214c93f65bfb1727547258f20e11c8440be..ba7f36ab0a74231eb82731e9292ffcd737601852 100644 (file)
@@ -689,7 +689,8 @@ static void ath_rc_rate_set_series(const struct ath_rate_table *rate_table,
 
        if (WLAN_RC_PHY_HT(rate_table->info[rix].phy)) {
                rate->flags |= IEEE80211_TX_RC_MCS;
-               if (WLAN_RC_PHY_40(rate_table->info[rix].phy))
+               if (WLAN_RC_PHY_40(rate_table->info[rix].phy) &&
+                   conf_is_ht40(&txrc->hw->conf))
                        rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
                if (WLAN_RC_PHY_SGI(rate_table->info[rix].phy))
                        rate->flags |= IEEE80211_TX_RC_SHORT_GI;
index 9ed65157bef554bcbcd1e857e3d80177a9af60bd..05960ddde24ee4fef9eb12801522eb95ea3e4825 100644 (file)
@@ -3093,7 +3093,7 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev,
        int freq;
        bool avoid = false;
        u8 length;
-       u16 tmp, core, type, count, max, numb, last, cmd;
+       u16 tmp, core, type, count, max, numb, last = 0, cmd;
        const u16 *table;
        bool phy6or5x;
 
index 7e5e85a017b5c0f9da0435f84cf94965b72a6ee3..a7a4739880dc91d7075b5eb6e1ee309e2dd16049 100644 (file)
@@ -628,11 +628,11 @@ void iwl4965_rx_reply_rx(struct iwl_priv *priv,
 
        /* rx_status carries information about the packet to mac80211 */
        rx_status.mactime = le64_to_cpu(phy_res->timestamp);
+       rx_status.band = (phy_res->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
+                               IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
        rx_status.freq =
                ieee80211_channel_to_frequency(le16_to_cpu(phy_res->channel),
                                                        rx_status.band);
-       rx_status.band = (phy_res->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
-                               IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
        rx_status.rate_idx =
                iwl4965_hwrate_to_mac80211_idx(rate_n_flags, rx_status.band);
        rx_status.flag = 0;
index f5433c74b845d54e6ac2869eb9664feb64bcd6bc..f9db25bb35c338f0b7f503e192293e78937d60f6 100644 (file)
@@ -1543,7 +1543,7 @@ static void iwl4965_temperature_calib(struct iwl_priv *priv)
        s32 temp;
 
        temp = iwl4965_hw_get_temperature(priv);
-       if (temp < 0)
+       if (IWL_TX_POWER_TEMPERATURE_OUT_OF_RANGE(temp))
                return;
 
        if (priv->temperature != temp) {
index f8c710db6e6f90345a8a1f42e7ce1b2d8a7d85aa..fda6fe08cf91c10b875b9f738ca66d143fd2e2f4 100644 (file)
@@ -603,19 +603,27 @@ struct iwl_cfg iwl6050_2abg_cfg = {
        IWL_DEVICE_6050,
 };
 
+#define IWL_DEVICE_6150                                                \
+       .fw_name_pre = IWL6050_FW_PRE,                          \
+       .ucode_api_max = IWL6050_UCODE_API_MAX,                 \
+       .ucode_api_min = IWL6050_UCODE_API_MIN,                 \
+       .ops = &iwl6150_ops,                                    \
+       .eeprom_ver = EEPROM_6150_EEPROM_VERSION,               \
+       .eeprom_calib_ver = EEPROM_6150_TX_POWER_VERSION,       \
+       .base_params = &iwl6050_base_params,                    \
+       .need_dc_calib = true,                                  \
+       .led_mode = IWL_LED_BLINK,                              \
+       .internal_wimax_coex = true
+
 struct iwl_cfg iwl6150_bgn_cfg = {
        .name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BGN",
-       .fw_name_pre = IWL6050_FW_PRE,
-       .ucode_api_max = IWL6050_UCODE_API_MAX,
-       .ucode_api_min = IWL6050_UCODE_API_MIN,
-       .eeprom_ver = EEPROM_6150_EEPROM_VERSION,
-       .eeprom_calib_ver = EEPROM_6150_TX_POWER_VERSION,
-       .ops = &iwl6150_ops,
-       .base_params = &iwl6050_base_params,
+       IWL_DEVICE_6150,
        .ht_params = &iwl6000_ht_params,
-       .need_dc_calib = true,
-       .led_mode = IWL_LED_RF_STATE,
-       .internal_wimax_coex = true,
+};
+
+struct iwl_cfg iwl6150_bg_cfg = {
+       .name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BG",
+       IWL_DEVICE_6150,
 };
 
 struct iwl_cfg iwl6000_3agn_cfg = {
index 11c6c1169e78ad980df93572feed15184a9f2295..a662adcb2adbba26ce06045d48e7977390999447 100644 (file)
@@ -3831,11 +3831,11 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
 
 /* 6150 WiFi/WiMax Series */
        {IWL_PCI_DEVICE(0x0885, 0x1305, iwl6150_bgn_cfg)},
-       {IWL_PCI_DEVICE(0x0885, 0x1306, iwl6150_bgn_cfg)},
+       {IWL_PCI_DEVICE(0x0885, 0x1307, iwl6150_bg_cfg)},
        {IWL_PCI_DEVICE(0x0885, 0x1325, iwl6150_bgn_cfg)},
-       {IWL_PCI_DEVICE(0x0885, 0x1326, iwl6150_bgn_cfg)},
+       {IWL_PCI_DEVICE(0x0885, 0x1327, iwl6150_bg_cfg)},
        {IWL_PCI_DEVICE(0x0886, 0x1315, iwl6150_bgn_cfg)},
-       {IWL_PCI_DEVICE(0x0886, 0x1316, iwl6150_bgn_cfg)},
+       {IWL_PCI_DEVICE(0x0886, 0x1317, iwl6150_bg_cfg)},
 
 /* 1000 Series WiFi */
        {IWL_PCI_DEVICE(0x0083, 0x1205, iwl1000_bgn_cfg)},
index 2495fe7a58cbb5f7d61399c6dacb8ebf358ede73..d1716844002eae2ea5ded5e2fe9724317964ffb8 100644 (file)
@@ -89,6 +89,7 @@ extern struct iwl_cfg iwl6000_3agn_cfg;
 extern struct iwl_cfg iwl6050_2agn_cfg;
 extern struct iwl_cfg iwl6050_2abg_cfg;
 extern struct iwl_cfg iwl6150_bgn_cfg;
+extern struct iwl_cfg iwl6150_bg_cfg;
 extern struct iwl_cfg iwl1000_bgn_cfg;
 extern struct iwl_cfg iwl1000_bg_cfg;
 extern struct iwl_cfg iwl100_bgn_cfg;
index 84566db486d21291196c353327a68fec6fd05dba..71c8f3fccfa1474b3dfe196b3785b75a0d8417eb 100644 (file)
@@ -994,6 +994,8 @@ static void lbs_submit_command(struct lbs_private *priv,
        cmd = cmdnode->cmdbuf;
 
        spin_lock_irqsave(&priv->driver_lock, flags);
+       priv->seqnum++;
+       cmd->seqnum = cpu_to_le16(priv->seqnum);
        priv->cur_cmd = cmdnode;
        spin_unlock_irqrestore(&priv->driver_lock, flags);
 
@@ -1621,11 +1623,9 @@ struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv,
        /* Copy the incoming command to the buffer */
        memcpy(cmdnode->cmdbuf, in_cmd, in_cmd_size);
 
-       /* Set sequence number, clean result, move to buffer */
-       priv->seqnum++;
+       /* Set command, clean result, move to buffer */
        cmdnode->cmdbuf->command = cpu_to_le16(command);
        cmdnode->cmdbuf->size    = cpu_to_le16(in_cmd_size);
-       cmdnode->cmdbuf->seqnum  = cpu_to_le16(priv->seqnum);
        cmdnode->cmdbuf->result  = 0;
 
        lbs_deb_host("PREP_CMD: command 0x%04x\n", command);
index a0e9bc5253e06dd8001dd2733d3c85f0e34046a0..4e97e90aa3994cacc80cadbd034caa581549011e 100644 (file)
 /* Rx unit register */
 #define CARD_RX_UNIT_REG               0x63
 
-/* Event header Len*/
-#define MWIFIEX_EVENT_HEADER_LEN           8
+/* Event header len w/o 4 bytes of interface header */
+#define MWIFIEX_EVENT_HEADER_LEN           4
 
 /* Max retry number of CMD53 write */
 #define MAX_WRITE_IOMEM_RETRY          2
index 9def1e5369a1c9dcfcbbee164444902efd16884b..b2f8b8fd4d2dc911dbb4f590430f8caa60dc70ab 100644 (file)
@@ -166,7 +166,6 @@ config RT2800USB_RT35XX
 config RT2800USB_RT53XX
        bool "rt2800usb - Include support for rt53xx devices (EXPERIMENTAL)"
        depends on EXPERIMENTAL
-       default y
        ---help---
          This adds support for rt53xx wireless chipset family to the
          rt2800pci driver.
index a4095284543677d28fc39852361ede477546f654..89100e7c553b782aa02b349075c488da54323e10 100644 (file)
@@ -669,11 +669,6 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
                                                         &rx_status,
                                                         (u8 *) pdesc, skb);
 
-                       pci_unmap_single(rtlpci->pdev,
-                                        *((dma_addr_t *) skb->cb),
-                                        rtlpci->rxbuffersize,
-                                        PCI_DMA_FROMDEVICE);
-
                        skb_put(skb, rtlpriv->cfg->ops->get_desc((u8 *) pdesc,
                                                         false,
                                                         HW_DESC_RXPKT_LEN));
@@ -690,6 +685,21 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
                        hdr = rtl_get_hdr(skb);
                        fc = rtl_get_fc(skb);
 
+                       /* try for new buffer - if allocation fails, drop
+                        * frame and reuse old buffer
+                        */
+                       new_skb = dev_alloc_skb(rtlpci->rxbuffersize);
+                       if (unlikely(!new_skb)) {
+                               RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV),
+                                        DBG_DMESG,
+                                        ("can't alloc skb for rx\n"));
+                               goto done;
+                       }
+                       pci_unmap_single(rtlpci->pdev,
+                                        *((dma_addr_t *) skb->cb),
+                                        rtlpci->rxbuffersize,
+                                        PCI_DMA_FROMDEVICE);
+
                        if (!stats.crc || !stats.hwerror) {
                                memcpy(IEEE80211_SKB_RXCB(skb), &rx_status,
                                       sizeof(rx_status));
@@ -758,15 +768,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
                                rtl_lps_leave(hw);
                        }
 
-                       new_skb = dev_alloc_skb(rtlpci->rxbuffersize);
-                       if (unlikely(!new_skb)) {
-                               RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV),
-                                        DBG_DMESG,
-                                        ("can't alloc skb for rx\n"));
-                               goto done;
-                       }
                        skb = new_skb;
-                       /*skb->dev = dev; */
 
                        rtlpci->rx_ring[rx_queue_idx].rx_buf[rtlpci->
                                                             rx_ring
@@ -1113,6 +1115,13 @@ static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw)
 
                rtlpci->rx_ring[rx_queue_idx].idx = 0;
 
+               /* If amsdu_8k is disabled, set buffersize to 4096. This
+                * change will reduce memory fragmentation.
+                */
+               if (rtlpci->rxbuffersize > 4096 &&
+                   rtlpriv->rtlhal.disable_amsdu_8k)
+                       rtlpci->rxbuffersize = 4096;
+
                for (i = 0; i < rtlpci->rxringcount; i++) {
                        struct sk_buff *skb =
                            dev_alloc_skb(rtlpci->rxbuffersize);
index 1ab6c86aac40d201d8f973c85367edf30831feba..c83fefb6662f3a2a433294c01e210098241e3c00 100644 (file)
@@ -1157,6 +1157,9 @@ struct conf_sched_scan_settings {
        /* time to wait on the channel for passive scans (in TUs) */
        u32 dwell_time_passive;
 
+       /* time to wait on the channel for DFS scans (in TUs) */
+       u32 dwell_time_dfs;
+
        /* number of probe requests to send on each channel in active scans */
        u8 num_probe_reqs;
 
index bc00e52f6445daec57326299829eee976d62a4bf..e6497dc669df096a57bc914e515b9212c18784c8 100644 (file)
@@ -311,6 +311,7 @@ static struct conf_drv_settings default_conf = {
                .min_dwell_time_active = 8,
                .max_dwell_time_active = 30,
                .dwell_time_passive    = 100,
+               .dwell_time_dfs        = 150,
                .num_probe_reqs        = 2,
                .rssi_threshold        = -90,
                .snr_threshold         = 0,
index f37e5a3919763b45f5b2f96f4f9b9d6d54e3f9ad..56f76abc754d170b8982961df3013a64ebd24ba0 100644 (file)
@@ -331,16 +331,22 @@ wl1271_scan_get_sched_scan_channels(struct wl1271 *wl,
        struct conf_sched_scan_settings *c = &wl->conf.sched_scan;
        int i, j;
        u32 flags;
+       bool force_passive = !req->n_ssids;
 
        for (i = 0, j = start;
             i < req->n_channels && j < MAX_CHANNELS_ALL_BANDS;
             i++) {
                flags = req->channels[i]->flags;
 
-               if (!(flags & IEEE80211_CHAN_DISABLED) &&
-                   ((flags & IEEE80211_CHAN_PASSIVE_SCAN) == passive) &&
-                   ((flags & IEEE80211_CHAN_RADAR) == radar) &&
-                   (req->channels[i]->band == band)) {
+               if (force_passive)
+                       flags |= IEEE80211_CHAN_PASSIVE_SCAN;
+
+               if ((req->channels[i]->band == band) &&
+                   !(flags & IEEE80211_CHAN_DISABLED) &&
+                   (!!(flags & IEEE80211_CHAN_RADAR) == radar) &&
+                   /* if radar is set, we ignore the passive flag */
+                   (radar ||
+                    !!(flags & IEEE80211_CHAN_PASSIVE_SCAN) == passive)) {
                        wl1271_debug(DEBUG_SCAN, "band %d, center_freq %d ",
                                     req->channels[i]->band,
                                     req->channels[i]->center_freq);
@@ -350,7 +356,12 @@ wl1271_scan_get_sched_scan_channels(struct wl1271 *wl,
                        wl1271_debug(DEBUG_SCAN, "max_power %d",
                                     req->channels[i]->max_power);
 
-                       if (flags & IEEE80211_CHAN_PASSIVE_SCAN) {
+                       if (flags & IEEE80211_CHAN_RADAR) {
+                               channels[j].flags |= SCAN_CHANNEL_FLAGS_DFS;
+                               channels[j].passive_duration =
+                                       cpu_to_le16(c->dwell_time_dfs);
+                       }
+                       else if (flags & IEEE80211_CHAN_PASSIVE_SCAN) {
                                channels[j].passive_duration =
                                        cpu_to_le16(c->dwell_time_passive);
                        } else {
@@ -359,7 +370,7 @@ wl1271_scan_get_sched_scan_channels(struct wl1271 *wl,
                                channels[j].max_duration =
                                        cpu_to_le16(c->max_dwell_time_active);
                        }
-                       channels[j].tx_power_att = req->channels[j]->max_power;
+                       channels[j].tx_power_att = req->channels[i]->max_power;
                        channels[j].channel = req->channels[i]->hw_value;
 
                        j++;
@@ -386,7 +397,11 @@ wl1271_scan_sched_scan_channels(struct wl1271 *wl,
                wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels,
                                                    IEEE80211_BAND_2GHZ,
                                                    false, false, idx);
-       idx += cfg->active[0];
+       /*
+        * 5GHz channels always start at position 14, not immediately
+        * after the last 2.4GHz channel
+        */
+       idx = 14;
 
        cfg->passive[1] =
                wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels,
@@ -394,22 +409,23 @@ wl1271_scan_sched_scan_channels(struct wl1271 *wl,
                                                    false, true, idx);
        idx += cfg->passive[1];
 
-       cfg->active[1] =
+       cfg->dfs =
                wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels,
                                                    IEEE80211_BAND_5GHZ,
-                                                   false, false, 14);
-       idx += cfg->active[1];
+                                                   true, true, idx);
+       idx += cfg->dfs;
 
-       cfg->dfs =
+       cfg->active[1] =
                wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels,
                                                    IEEE80211_BAND_5GHZ,
-                                                   true, false, idx);
-       idx += cfg->dfs;
+                                                   false, false, idx);
+       idx += cfg->active[1];
 
        wl1271_debug(DEBUG_SCAN, "    2.4GHz: active %d passive %d",
                     cfg->active[0], cfg->passive[0]);
        wl1271_debug(DEBUG_SCAN, "    5GHz: active %d passive %d",
                     cfg->active[1], cfg->passive[1]);
+       wl1271_debug(DEBUG_SCAN, "    DFS: %d", cfg->dfs);
 
        return idx;
 }
@@ -421,6 +437,7 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl,
        struct wl1271_cmd_sched_scan_config *cfg = NULL;
        struct conf_sched_scan_settings *c = &wl->conf.sched_scan;
        int i, total_channels, ret;
+       bool force_passive = !req->n_ssids;
 
        wl1271_debug(DEBUG_CMD, "cmd sched_scan scan config");
 
@@ -444,7 +461,7 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl,
        for (i = 0; i < SCAN_MAX_CYCLE_INTERVALS; i++)
                cfg->intervals[i] = cpu_to_le32(req->interval);
 
-       if (req->ssids[0].ssid_len && req->ssids[0].ssid) {
+       if (!force_passive && req->ssids[0].ssid_len && req->ssids[0].ssid) {
                cfg->filter_type = SCAN_SSID_FILTER_SPECIFIC;
                cfg->ssid_len = req->ssids[0].ssid_len;
                memcpy(cfg->ssid, req->ssids[0].ssid,
@@ -461,7 +478,7 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl,
                goto out;
        }
 
-       if (cfg->active[0]) {
+       if (!force_passive && cfg->active[0]) {
                ret = wl1271_cmd_build_probe_req(wl, req->ssids[0].ssid,
                                                 req->ssids[0].ssid_len,
                                                 ies->ie[IEEE80211_BAND_2GHZ],
@@ -473,7 +490,7 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl,
                }
        }
 
-       if (cfg->active[1]) {
+       if (!force_passive && cfg->active[1]) {
                ret = wl1271_cmd_build_probe_req(wl,  req->ssids[0].ssid,
                                                 req->ssids[0].ssid_len,
                                                 ies->ie[IEEE80211_BAND_5GHZ],
index c83319579ca33a4a9e4f6f5767ceb0c546a87040..a0b6c5d67b0745218bb99396115c4386c0048b4e 100644 (file)
@@ -137,6 +137,9 @@ enum {
        SCAN_BSS_TYPE_ANY,
 };
 
+#define SCAN_CHANNEL_FLAGS_DFS         BIT(0)
+#define SCAN_CHANNEL_FLAGS_DFS_ENABLED BIT(1)
+
 struct conn_scan_ch_params {
        __le16 min_duration;
        __le16 max_duration;
index 0e819943b9e479879dae4fc3f368760346feabfe..631194d498288aecff07f190cb76500ae107cd3f 100644 (file)
@@ -1533,6 +1533,31 @@ static void __exit usb_exit(void)
 module_init(usb_init);
 module_exit(usb_exit);
 
+static int zd_ep_regs_out_msg(struct usb_device *udev, void *data, int len,
+                             int *actual_length, int timeout)
+{
+       /* In USB 2.0 mode EP_REGS_OUT endpoint is interrupt type. However in
+        * USB 1.1 mode endpoint is bulk. Select correct type URB by endpoint
+        * descriptor.
+        */
+       struct usb_host_endpoint *ep;
+       unsigned int pipe;
+
+       pipe = usb_sndintpipe(udev, EP_REGS_OUT);
+       ep = usb_pipe_endpoint(udev, pipe);
+       if (!ep)
+               return -EINVAL;
+
+       if (usb_endpoint_xfer_int(&ep->desc)) {
+               return usb_interrupt_msg(udev, pipe, data, len,
+                                        actual_length, timeout);
+       } else {
+               pipe = usb_sndbulkpipe(udev, EP_REGS_OUT);
+               return usb_bulk_msg(udev, pipe, data, len, actual_length,
+                                   timeout);
+       }
+}
+
 static int usb_int_regs_length(unsigned int count)
 {
        return sizeof(struct usb_int_regs) + count * sizeof(struct reg_data);
@@ -1648,15 +1673,14 @@ int zd_usb_ioread16v(struct zd_usb *usb, u16 *values,
 
        udev = zd_usb_to_usbdev(usb);
        prepare_read_regs_int(usb);
-       r = usb_interrupt_msg(udev, usb_sndintpipe(udev, EP_REGS_OUT),
-                             req, req_len, &actual_req_len, 50 /* ms */);
+       r = zd_ep_regs_out_msg(udev, req, req_len, &actual_req_len, 50 /*ms*/);
        if (r) {
                dev_dbg_f(zd_usb_dev(usb),
-                       "error in usb_interrupt_msg(). Error number %d\n", r);
+                       "error in zd_ep_regs_out_msg(). Error number %d\n", r);
                goto error;
        }
        if (req_len != actual_req_len) {
-               dev_dbg_f(zd_usb_dev(usb), "error in usb_interrupt_msg()\n"
+               dev_dbg_f(zd_usb_dev(usb), "error in zd_ep_regs_out_msg()\n"
                        " req_len %d != actual_req_len %d\n",
                        req_len, actual_req_len);
                r = -EIO;
@@ -1818,9 +1842,17 @@ int zd_usb_iowrite16v_async(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs,
                rw->value = cpu_to_le16(ioreqs[i].value);
        }
 
-       usb_fill_int_urb(urb, udev, usb_sndintpipe(udev, EP_REGS_OUT),
-                        req, req_len, iowrite16v_urb_complete, usb,
-                        ep->desc.bInterval);
+       /* In USB 2.0 mode endpoint is interrupt type. However in USB 1.1 mode
+        * endpoint is bulk. Select correct type URB by endpoint descriptor.
+        */
+       if (usb_endpoint_xfer_int(&ep->desc))
+               usb_fill_int_urb(urb, udev, usb_sndintpipe(udev, EP_REGS_OUT),
+                                req, req_len, iowrite16v_urb_complete, usb,
+                                ep->desc.bInterval);
+       else
+               usb_fill_bulk_urb(urb, udev, usb_sndbulkpipe(udev, EP_REGS_OUT),
+                                 req, req_len, iowrite16v_urb_complete, usb);
+
        urb->transfer_flags |= URB_FREE_BUFFER;
 
        /* Submit previous URB */
@@ -1924,15 +1956,14 @@ int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits)
        }
 
        udev = zd_usb_to_usbdev(usb);
-       r = usb_interrupt_msg(udev, usb_sndintpipe(udev, EP_REGS_OUT),
-                             req, req_len, &actual_req_len, 50 /* ms */);
+       r = zd_ep_regs_out_msg(udev, req, req_len, &actual_req_len, 50 /*ms*/);
        if (r) {
                dev_dbg_f(zd_usb_dev(usb),
-                       "error in usb_interrupt_msg(). Error number %d\n", r);
+                       "error in zd_ep_regs_out_msg(). Error number %d\n", r);
                goto out;
        }
        if (req_len != actual_req_len) {
-               dev_dbg_f(zd_usb_dev(usb), "error in usb_interrupt_msg()"
+               dev_dbg_f(zd_usb_dev(usb), "error in zd_ep_regs_out_msg()"
                        " req_len %d != actual_req_len %d\n",
                        req_len, actual_req_len);
                r = -EIO;
index 12e02bf92c4ac81f8fce8b8c18e96dc298e05b2d..3dc9befa5aec06343691474420ad203963119bdb 100644 (file)
@@ -698,12 +698,7 @@ int __init detect_intel_iommu(void)
        {
 #ifdef CONFIG_INTR_REMAP
                struct acpi_table_dmar *dmar;
-               /*
-                * for now we will disable dma-remapping when interrupt
-                * remapping is enabled.
-                * When support for queued invalidation for IOTLB invalidation
-                * is added, we will not need this any more.
-                */
+
                dmar = (struct acpi_table_dmar *) dmar_tbl;
                if (ret && cpu_has_x2apic && dmar->flags & 0x1)
                        printk(KERN_INFO
index 6af6b628175b459f03c2f0969f9b2be6d65dba48..f02c34d26d1b08226599cfa4c183da703b9486ed 100644 (file)
@@ -47,6 +47,8 @@
 #define ROOT_SIZE              VTD_PAGE_SIZE
 #define CONTEXT_SIZE           VTD_PAGE_SIZE
 
+#define IS_BRIDGE_HOST_DEVICE(pdev) \
+                           ((pdev->class >> 8) == PCI_CLASS_BRIDGE_HOST)
 #define IS_GFX_DEVICE(pdev) ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY)
 #define IS_ISA_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_BRIDGE_ISA)
 #define IS_AZALIA(pdev) ((pdev)->vendor == 0x8086 && (pdev)->device == 0x3a3e)
@@ -116,6 +118,11 @@ static inline unsigned long align_to_level(unsigned long pfn, int level)
        return (pfn + level_size(level) - 1) & level_mask(level);
 }
 
+static inline unsigned long lvl_to_nr_pages(unsigned int lvl)
+{
+       return  1 << ((lvl - 1) * LEVEL_STRIDE);
+}
+
 /* VT-d pages must always be _smaller_ than MM pages. Otherwise things
    are never going to work. */
 static inline unsigned long dma_to_mm_pfn(unsigned long dma_pfn)
@@ -142,6 +149,12 @@ static struct intel_iommu **g_iommus;
 static void __init check_tylersburg_isoch(void);
 static int rwbf_quirk;
 
+/*
+ * set to 1 to panic kernel if can't successfully enable VT-d
+ * (used when kernel is launched w/ TXT)
+ */
+static int force_on = 0;
+
 /*
  * 0: Present
  * 1-11: Reserved
@@ -338,6 +351,9 @@ struct dmar_domain {
        int             iommu_coherency;/* indicate coherency of iommu access */
        int             iommu_snooping; /* indicate snooping control feature*/
        int             iommu_count;    /* reference count of iommu */
+       int             iommu_superpage;/* Level of superpages supported:
+                                          0 == 4KiB (no superpages), 1 == 2MiB,
+                                          2 == 1GiB, 3 == 512GiB, 4 == 1TiB */
        spinlock_t      iommu_lock;     /* protect iommu set in domain */
        u64             max_addr;       /* maximum mapped address */
 };
@@ -387,6 +403,7 @@ int dmar_disabled = 1;
 static int dmar_map_gfx = 1;
 static int dmar_forcedac;
 static int intel_iommu_strict;
+static int intel_iommu_superpage = 1;
 
 #define DUMMY_DEVICE_DOMAIN_INFO ((struct device_domain_info *)(-1))
 static DEFINE_SPINLOCK(device_domain_lock);
@@ -417,6 +434,10 @@ static int __init intel_iommu_setup(char *str)
                        printk(KERN_INFO
                                "Intel-IOMMU: disable batched IOTLB flush\n");
                        intel_iommu_strict = 1;
+               } else if (!strncmp(str, "sp_off", 6)) {
+                       printk(KERN_INFO
+                               "Intel-IOMMU: disable supported super page\n");
+                       intel_iommu_superpage = 0;
                }
 
                str += strcspn(str, ",");
@@ -555,11 +576,32 @@ static void domain_update_iommu_snooping(struct dmar_domain *domain)
        }
 }
 
+static void domain_update_iommu_superpage(struct dmar_domain *domain)
+{
+       int i, mask = 0xf;
+
+       if (!intel_iommu_superpage) {
+               domain->iommu_superpage = 0;
+               return;
+       }
+
+       domain->iommu_superpage = 4; /* 1TiB */
+
+       for_each_set_bit(i, &domain->iommu_bmp, g_num_of_iommus) {
+               mask |= cap_super_page_val(g_iommus[i]->cap);
+               if (!mask) {
+                       break;
+               }
+       }
+       domain->iommu_superpage = fls(mask);
+}
+
 /* Some capabilities may be different across iommus */
 static void domain_update_iommu_cap(struct dmar_domain *domain)
 {
        domain_update_iommu_coherency(domain);
        domain_update_iommu_snooping(domain);
+       domain_update_iommu_superpage(domain);
 }
 
 static struct intel_iommu *device_to_iommu(int segment, u8 bus, u8 devfn)
@@ -689,23 +731,31 @@ out:
 }
 
 static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain,
-                                     unsigned long pfn)
+                                     unsigned long pfn, int large_level)
 {
        int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT;
        struct dma_pte *parent, *pte = NULL;
        int level = agaw_to_level(domain->agaw);
-       int offset;
+       int offset, target_level;
 
        BUG_ON(!domain->pgd);
        BUG_ON(addr_width < BITS_PER_LONG && pfn >> addr_width);
        parent = domain->pgd;
 
+       /* Search pte */
+       if (!large_level)
+               target_level = 1;
+       else
+               target_level = large_level;
+
        while (level > 0) {
                void *tmp_page;
 
                offset = pfn_level_offset(pfn, level);
                pte = &parent[offset];
-               if (level == 1)
+               if (!large_level && (pte->val & DMA_PTE_LARGE_PAGE))
+                       break;
+               if (level == target_level)
                        break;
 
                if (!dma_pte_present(pte)) {
@@ -733,10 +783,11 @@ static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain,
        return pte;
 }
 
+
 /* return address's pte at specific level */
 static struct dma_pte *dma_pfn_level_pte(struct dmar_domain *domain,
                                         unsigned long pfn,
-                                        int level)
+                                        int level, int *large_page)
 {
        struct dma_pte *parent, *pte = NULL;
        int total = agaw_to_level(domain->agaw);
@@ -749,8 +800,16 @@ static struct dma_pte *dma_pfn_level_pte(struct dmar_domain *domain,
                if (level == total)
                        return pte;
 
-               if (!dma_pte_present(pte))
+               if (!dma_pte_present(pte)) {
+                       *large_page = total;
                        break;
+               }
+
+               if (pte->val & DMA_PTE_LARGE_PAGE) {
+                       *large_page = total;
+                       return pte;
+               }
+
                parent = phys_to_virt(dma_pte_addr(pte));
                total--;
        }
@@ -763,6 +822,7 @@ static void dma_pte_clear_range(struct dmar_domain *domain,
                                unsigned long last_pfn)
 {
        int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT;
+       unsigned int large_page = 1;
        struct dma_pte *first_pte, *pte;
 
        BUG_ON(addr_width < BITS_PER_LONG && start_pfn >> addr_width);
@@ -771,14 +831,15 @@ static void dma_pte_clear_range(struct dmar_domain *domain,
 
        /* we don't need lock here; nobody else touches the iova range */
        do {
-               first_pte = pte = dma_pfn_level_pte(domain, start_pfn, 1);
+               large_page = 1;
+               first_pte = pte = dma_pfn_level_pte(domain, start_pfn, 1, &large_page);
                if (!pte) {
-                       start_pfn = align_to_level(start_pfn + 1, 2);
+                       start_pfn = align_to_level(start_pfn + 1, large_page + 1);
                        continue;
                }
-               do { 
+               do {
                        dma_clear_pte(pte);
-                       start_pfn++;
+                       start_pfn += lvl_to_nr_pages(large_page);
                        pte++;
                } while (start_pfn <= last_pfn && !first_pte_in_page(pte));
 
@@ -798,6 +859,7 @@ static void dma_pte_free_pagetable(struct dmar_domain *domain,
        int total = agaw_to_level(domain->agaw);
        int level;
        unsigned long tmp;
+       int large_page = 2;
 
        BUG_ON(addr_width < BITS_PER_LONG && start_pfn >> addr_width);
        BUG_ON(addr_width < BITS_PER_LONG && last_pfn >> addr_width);
@@ -813,7 +875,10 @@ static void dma_pte_free_pagetable(struct dmar_domain *domain,
                        return;
 
                do {
-                       first_pte = pte = dma_pfn_level_pte(domain, tmp, level);
+                       large_page = level;
+                       first_pte = pte = dma_pfn_level_pte(domain, tmp, level, &large_page);
+                       if (large_page > level)
+                               level = large_page + 1;
                        if (!pte) {
                                tmp = align_to_level(tmp + 1, level + 1);
                                continue;
@@ -1397,6 +1462,7 @@ static int domain_init(struct dmar_domain *domain, int guest_width)
        else
                domain->iommu_snooping = 0;
 
+       domain->iommu_superpage = fls(cap_super_page_val(iommu->cap));
        domain->iommu_count = 1;
        domain->nid = iommu->node;
 
@@ -1417,6 +1483,10 @@ static void domain_exit(struct dmar_domain *domain)
        if (!domain)
                return;
 
+       /* Flush any lazy unmaps that may reference this domain */
+       if (!intel_iommu_strict)
+               flush_unmaps_timeout(0);
+
        domain_remove_dev_info(domain);
        /* destroy iovas */
        put_iova_domain(&domain->iovad);
@@ -1648,6 +1718,34 @@ static inline unsigned long aligned_nrpages(unsigned long host_addr,
        return PAGE_ALIGN(host_addr + size) >> VTD_PAGE_SHIFT;
 }
 
+/* Return largest possible superpage level for a given mapping */
+static inline int hardware_largepage_caps(struct dmar_domain *domain,
+                                         unsigned long iov_pfn,
+                                         unsigned long phy_pfn,
+                                         unsigned long pages)
+{
+       int support, level = 1;
+       unsigned long pfnmerge;
+
+       support = domain->iommu_superpage;
+
+       /* To use a large page, the virtual *and* physical addresses
+          must be aligned to 2MiB/1GiB/etc. Lower bits set in either
+          of them will mean we have to use smaller pages. So just
+          merge them and check both at once. */
+       pfnmerge = iov_pfn | phy_pfn;
+
+       while (support && !(pfnmerge & ~VTD_STRIDE_MASK)) {
+               pages >>= VTD_STRIDE_SHIFT;
+               if (!pages)
+                       break;
+               pfnmerge >>= VTD_STRIDE_SHIFT;
+               level++;
+               support--;
+       }
+       return level;
+}
+
 static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
                            struct scatterlist *sg, unsigned long phys_pfn,
                            unsigned long nr_pages, int prot)
@@ -1656,6 +1754,8 @@ static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
        phys_addr_t uninitialized_var(pteval);
        int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT;
        unsigned long sg_res;
+       unsigned int largepage_lvl = 0;
+       unsigned long lvl_pages = 0;
 
        BUG_ON(addr_width < BITS_PER_LONG && (iov_pfn + nr_pages - 1) >> addr_width);
 
@@ -1671,7 +1771,7 @@ static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
                pteval = ((phys_addr_t)phys_pfn << VTD_PAGE_SHIFT) | prot;
        }
 
-       while (nr_pages--) {
+       while (nr_pages > 0) {
                uint64_t tmp;
 
                if (!sg_res) {
@@ -1679,11 +1779,21 @@ static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
                        sg->dma_address = ((dma_addr_t)iov_pfn << VTD_PAGE_SHIFT) + sg->offset;
                        sg->dma_length = sg->length;
                        pteval = page_to_phys(sg_page(sg)) | prot;
+                       phys_pfn = pteval >> VTD_PAGE_SHIFT;
                }
+
                if (!pte) {
-                       first_pte = pte = pfn_to_dma_pte(domain, iov_pfn);
+                       largepage_lvl = hardware_largepage_caps(domain, iov_pfn, phys_pfn, sg_res);
+
+                       first_pte = pte = pfn_to_dma_pte(domain, iov_pfn, largepage_lvl);
                        if (!pte)
                                return -ENOMEM;
+                       /* It is large page*/
+                       if (largepage_lvl > 1)
+                               pteval |= DMA_PTE_LARGE_PAGE;
+                       else
+                               pteval &= ~(uint64_t)DMA_PTE_LARGE_PAGE;
+
                }
                /* We don't need lock here, nobody else
                 * touches the iova range
@@ -1699,16 +1809,38 @@ static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
                        }
                        WARN_ON(1);
                }
+
+               lvl_pages = lvl_to_nr_pages(largepage_lvl);
+
+               BUG_ON(nr_pages < lvl_pages);
+               BUG_ON(sg_res < lvl_pages);
+
+               nr_pages -= lvl_pages;
+               iov_pfn += lvl_pages;
+               phys_pfn += lvl_pages;
+               pteval += lvl_pages * VTD_PAGE_SIZE;
+               sg_res -= lvl_pages;
+
+               /* If the next PTE would be the first in a new page, then we
+                  need to flush the cache on the entries we've just written.
+                  And then we'll need to recalculate 'pte', so clear it and
+                  let it get set again in the if (!pte) block above.
+
+                  If we're done (!nr_pages) we need to flush the cache too.
+
+                  Also if we've been setting superpages, we may need to
+                  recalculate 'pte' and switch back to smaller pages for the
+                  end of the mapping, if the trailing size is not enough to
+                  use another superpage (i.e. sg_res < lvl_pages). */
                pte++;
-               if (!nr_pages || first_pte_in_page(pte)) {
+               if (!nr_pages || first_pte_in_page(pte) ||
+                   (largepage_lvl > 1 && sg_res < lvl_pages)) {
                        domain_flush_cache(domain, first_pte,
                                           (void *)pte - (void *)first_pte);
                        pte = NULL;
                }
-               iov_pfn++;
-               pteval += VTD_PAGE_SIZE;
-               sg_res--;
-               if (!sg_res)
+
+               if (!sg_res && nr_pages)
                        sg = sg_next(sg);
        }
        return 0;
@@ -2016,7 +2148,7 @@ static inline int iommu_prepare_rmrr_dev(struct dmar_rmrr_unit *rmrr,
        if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO)
                return 0;
        return iommu_prepare_identity_map(pdev, rmrr->base_address,
-               rmrr->end_address + 1);
+               rmrr->end_address);
 }
 
 #ifdef CONFIG_DMAR_FLOPPY_WA
@@ -2030,7 +2162,7 @@ static inline void iommu_prepare_isa(void)
                return;
 
        printk(KERN_INFO "IOMMU: Prepare 0-16MiB unity mapping for LPC\n");
-       ret = iommu_prepare_identity_map(pdev, 0, 16*1024*1024);
+       ret = iommu_prepare_identity_map(pdev, 0, 16*1024*1024 - 1);
 
        if (ret)
                printk(KERN_ERR "IOMMU: Failed to create 0-16MiB identity map; "
@@ -2106,10 +2238,10 @@ static int identity_mapping(struct pci_dev *pdev)
        if (likely(!iommu_identity_mapping))
                return 0;
 
+       info = pdev->dev.archdata.iommu;
+       if (info && info != DUMMY_DEVICE_DOMAIN_INFO)
+               return (info->domain == si_domain);
 
-       list_for_each_entry(info, &si_domain->devices, link)
-               if (info->dev == pdev)
-                       return 1;
        return 0;
 }
 
@@ -2187,8 +2319,19 @@ static int iommu_should_identity_map(struct pci_dev *pdev, int startup)
         * Assume that they will -- if they turn out not to be, then we can 
         * take them out of the 1:1 domain later.
         */
-       if (!startup)
-               return pdev->dma_mask > DMA_BIT_MASK(32);
+       if (!startup) {
+               /*
+                * If the device's dma_mask is less than the system's memory
+                * size then this is not a candidate for identity mapping.
+                */
+               u64 dma_mask = pdev->dma_mask;
+
+               if (pdev->dev.coherent_dma_mask &&
+                   pdev->dev.coherent_dma_mask < dma_mask)
+                       dma_mask = pdev->dev.coherent_dma_mask;
+
+               return dma_mask >= dma_get_required_mask(&pdev->dev);
+       }
 
        return 1;
 }
@@ -2203,6 +2346,9 @@ static int __init iommu_prepare_static_identity_mapping(int hw)
                return -EFAULT;
 
        for_each_pci_dev(pdev) {
+               /* Skip Host/PCI Bridge devices */
+               if (IS_BRIDGE_HOST_DEVICE(pdev))
+                       continue;
                if (iommu_should_identity_map(pdev, 1)) {
                        printk(KERN_INFO "IOMMU: %s identity mapping for device %s\n",
                               hw ? "hardware" : "software", pci_name(pdev));
@@ -2218,7 +2364,7 @@ static int __init iommu_prepare_static_identity_mapping(int hw)
        return 0;
 }
 
-static int __init init_dmars(int force_on)
+static int __init init_dmars(void)
 {
        struct dmar_drhd_unit *drhd;
        struct dmar_rmrr_unit *rmrr;
@@ -2592,8 +2738,7 @@ static dma_addr_t __intel_map_single(struct device *hwdev, phys_addr_t paddr,
        iommu = domain_get_iommu(domain);
        size = aligned_nrpages(paddr, size);
 
-       iova = intel_alloc_iova(hwdev, domain, dma_to_mm_pfn(size),
-                               pdev->dma_mask);
+       iova = intel_alloc_iova(hwdev, domain, dma_to_mm_pfn(size), dma_mask);
        if (!iova)
                goto error;
 
@@ -3118,7 +3263,17 @@ static int init_iommu_hw(void)
                if (iommu->qi)
                        dmar_reenable_qi(iommu);
 
-       for_each_active_iommu(iommu, drhd) {
+       for_each_iommu(iommu, drhd) {
+               if (drhd->ignored) {
+                       /*
+                        * we always have to disable PMRs or DMA may fail on
+                        * this device
+                        */
+                       if (force_on)
+                               iommu_disable_protect_mem_regions(iommu);
+                       continue;
+               }
+       
                iommu_flush_write_buffer(iommu);
 
                iommu_set_root_entry(iommu);
@@ -3127,7 +3282,8 @@ static int init_iommu_hw(void)
                                           DMA_CCMD_GLOBAL_INVL);
                iommu->flush.flush_iotlb(iommu, 0, 0, 0,
                                         DMA_TLB_GLOBAL_FLUSH);
-               iommu_enable_translation(iommu);
+               if (iommu_enable_translation(iommu))
+                       return 1;
                iommu_disable_protect_mem_regions(iommu);
        }
 
@@ -3194,7 +3350,10 @@ static void iommu_resume(void)
        unsigned long flag;
 
        if (init_iommu_hw()) {
-               WARN(1, "IOMMU setup failed, DMAR can not resume!\n");
+               if (force_on)
+                       panic("tboot: IOMMU setup failed, DMAR can not resume!\n");
+               else
+                       WARN(1, "IOMMU setup failed, DMAR can not resume!\n");
                return;
        }
 
@@ -3229,7 +3388,7 @@ static void __init init_iommu_pm_ops(void)
 }
 
 #else
-static inline int init_iommu_pm_ops(void) { }
+static inline void init_iommu_pm_ops(void) {}
 #endif /* CONFIG_PM */
 
 /*
@@ -3271,7 +3430,6 @@ static struct notifier_block device_nb = {
 int __init intel_iommu_init(void)
 {
        int ret = 0;
-       int force_on = 0;
 
        /* VT-d is required for a TXT/tboot launch, so enforce that */
        force_on = tboot_force_iommu();
@@ -3309,7 +3467,7 @@ int __init intel_iommu_init(void)
 
        init_no_remapping_devices();
 
-       ret = init_dmars(force_on);
+       ret = init_dmars();
        if (ret) {
                if (force_on)
                        panic("tboot: Failed to initialize DMARs\n");
@@ -3380,8 +3538,8 @@ static void domain_remove_one_dev_info(struct dmar_domain *domain,
        spin_lock_irqsave(&device_domain_lock, flags);
        list_for_each_safe(entry, tmp, &domain->devices) {
                info = list_entry(entry, struct device_domain_info, link);
-               /* No need to compare PCI domain; it has to be the same */
-               if (info->bus == pdev->bus->number &&
+               if (info->segment == pci_domain_nr(pdev->bus) &&
+                   info->bus == pdev->bus->number &&
                    info->devfn == pdev->devfn) {
                        list_del(&info->link);
                        list_del(&info->global);
@@ -3419,10 +3577,13 @@ static void domain_remove_one_dev_info(struct dmar_domain *domain,
                domain_update_iommu_cap(domain);
                spin_unlock_irqrestore(&domain->iommu_lock, tmp_flags);
 
-               spin_lock_irqsave(&iommu->lock, tmp_flags);
-               clear_bit(domain->id, iommu->domain_ids);
-               iommu->domains[domain->id] = NULL;
-               spin_unlock_irqrestore(&iommu->lock, tmp_flags);
+               if (!(domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE) &&
+                   !(domain->flags & DOMAIN_FLAG_STATIC_IDENTITY)) {
+                       spin_lock_irqsave(&iommu->lock, tmp_flags);
+                       clear_bit(domain->id, iommu->domain_ids);
+                       iommu->domains[domain->id] = NULL;
+                       spin_unlock_irqrestore(&iommu->lock, tmp_flags);
+               }
        }
 
        spin_unlock_irqrestore(&device_domain_lock, flags);
@@ -3505,6 +3666,7 @@ static int md_domain_init(struct dmar_domain *domain, int guest_width)
        domain->iommu_count = 0;
        domain->iommu_coherency = 0;
        domain->iommu_snooping = 0;
+       domain->iommu_superpage = 0;
        domain->max_addr = 0;
        domain->nid = -1;
 
@@ -3720,7 +3882,7 @@ static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain,
        struct dma_pte *pte;
        u64 phys = 0;
 
-       pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT);
+       pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, 0);
        if (pte)
                phys = dma_pte_addr(pte);
 
index 9606e599a47552f9119425c077f62a0c807d3b9f..c5c274ab5c5a034abe91fb1f1f5dcf6380c9315e 100644 (file)
@@ -63,8 +63,16 @@ __cached_rbnode_delete_update(struct iova_domain *iovad, struct iova *free)
        curr = iovad->cached32_node;
        cached_iova = container_of(curr, struct iova, node);
 
-       if (free->pfn_lo >= cached_iova->pfn_lo)
-               iovad->cached32_node = rb_next(&free->node);
+       if (free->pfn_lo >= cached_iova->pfn_lo) {
+               struct rb_node *node = rb_next(&free->node);
+               struct iova *iova = container_of(node, struct iova, node);
+
+               /* only cache if it's below 32bit pfn */
+               if (node && iova->pfn_lo < iovad->dma_32bit_pfn)
+                       iovad->cached32_node = node;
+               else
+                       iovad->cached32_node = NULL;
+       }
 }
 
 /* Computes the padding size required, to make the
index f822e13dc04b43ca0902e273c6060f1f838fbfdb..ce2aabf5c550a2706bc39dd17ac2b1c5a94142e8 100644 (file)
@@ -1051,4 +1051,13 @@ config RTC_DRV_TILE
          Enable support for the Linux driver side of the Tilera
          hypervisor's real-time clock interface.
 
+config RTC_DRV_PUV3
+       tristate "PKUnity v3 RTC support"
+       depends on ARCH_PUV3
+       help
+         This enables support for the RTC in the PKUnity-v3 SoCs.
+
+         This drive can also be built as a module. If so, the module
+         will be called rtc-puv3.
+
 endif # RTC_CLASS
index 213d725f16d464cc0cc7527a2041f2d468d899f8..0ffefe877bfadca0fcf1730beaff016adc268ea2 100644 (file)
@@ -78,6 +78,7 @@ obj-$(CONFIG_RTC_DRV_PCF50633)        += rtc-pcf50633.o
 obj-$(CONFIG_RTC_DRV_PL030)    += rtc-pl030.o
 obj-$(CONFIG_RTC_DRV_PL031)    += rtc-pl031.o
 obj-$(CONFIG_RTC_DRV_PS3)      += rtc-ps3.o
+obj-$(CONFIG_RTC_DRV_PUV3)     += rtc-puv3.o
 obj-$(CONFIG_RTC_DRV_PXA)      += rtc-pxa.o
 obj-$(CONFIG_RTC_DRV_R9701)    += rtc-r9701.o
 obj-$(CONFIG_RTC_DRV_RP5C01)   += rtc-rp5c01.o
index 1a84b3e227d1a449287af1efa5b10c7151782510..7317d3b9a3d54ffacdde1c40773eacf1309a075c 100644 (file)
@@ -189,7 +189,7 @@ static int __devinit m41t93_probe(struct spi_device *spi)
 
 static int __devexit m41t93_remove(struct spi_device *spi)
 {
-       struct rtc_device *rtc = platform_get_drvdata(spi);
+       struct rtc_device *rtc = spi_get_drvdata(spi);
 
        if (rtc)
                rtc_device_unregister(rtc);
diff --git a/drivers/rtc/rtc-puv3.c b/drivers/rtc/rtc-puv3.c
new file mode 100644 (file)
index 0000000..46f14b8
--- /dev/null
@@ -0,0 +1,359 @@
+/*
+ * RTC driver code specific to PKUnity SoC and UniCore ISA
+ *
+ *     Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn>
+ *     Copyright (C) 2001-2010 Guan Xuetao
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/rtc.h>
+#include <linux/bcd.h>
+#include <linux/clk.h>
+#include <linux/log2.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
+
+#include <asm/irq.h>
+#include <mach/hardware.h>
+
+static struct resource *puv3_rtc_mem;
+
+static int puv3_rtc_alarmno = IRQ_RTCAlarm;
+static int puv3_rtc_tickno  = IRQ_RTC;
+
+static DEFINE_SPINLOCK(puv3_rtc_pie_lock);
+
+/* IRQ Handlers */
+static irqreturn_t puv3_rtc_alarmirq(int irq, void *id)
+{
+       struct rtc_device *rdev = id;
+
+       writel(readl(RTC_RTSR) | RTC_RTSR_AL, RTC_RTSR);
+       rtc_update_irq(rdev, 1, RTC_AF | RTC_IRQF);
+       return IRQ_HANDLED;
+}
+
+static irqreturn_t puv3_rtc_tickirq(int irq, void *id)
+{
+       struct rtc_device *rdev = id;
+
+       writel(readl(RTC_RTSR) | RTC_RTSR_HZ, RTC_RTSR);
+       rtc_update_irq(rdev, 1, RTC_PF | RTC_IRQF);
+       return IRQ_HANDLED;
+}
+
+/* Update control registers */
+static void puv3_rtc_setaie(int to)
+{
+       unsigned int tmp;
+
+       pr_debug("%s: aie=%d\n", __func__, to);
+
+       tmp = readl(RTC_RTSR) & ~RTC_RTSR_ALE;
+
+       if (to)
+               tmp |= RTC_RTSR_ALE;
+
+       writel(tmp, RTC_RTSR);
+}
+
+static int puv3_rtc_setpie(struct device *dev, int enabled)
+{
+       unsigned int tmp;
+
+       pr_debug("%s: pie=%d\n", __func__, enabled);
+
+       spin_lock_irq(&puv3_rtc_pie_lock);
+       tmp = readl(RTC_RTSR) & ~RTC_RTSR_HZE;
+
+       if (enabled)
+               tmp |= RTC_RTSR_HZE;
+
+       writel(tmp, RTC_RTSR);
+       spin_unlock_irq(&puv3_rtc_pie_lock);
+
+       return 0;
+}
+
+/* Time read/write */
+static int puv3_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
+{
+       rtc_time_to_tm(readl(RTC_RCNR), rtc_tm);
+
+       pr_debug("read time %02x.%02x.%02x %02x/%02x/%02x\n",
+                rtc_tm->tm_year, rtc_tm->tm_mon, rtc_tm->tm_mday,
+                rtc_tm->tm_hour, rtc_tm->tm_min, rtc_tm->tm_sec);
+
+       return 0;
+}
+
+static int puv3_rtc_settime(struct device *dev, struct rtc_time *tm)
+{
+       unsigned long rtc_count = 0;
+
+       pr_debug("set time %02d.%02d.%02d %02d/%02d/%02d\n",
+                tm->tm_year, tm->tm_mon, tm->tm_mday,
+                tm->tm_hour, tm->tm_min, tm->tm_sec);
+
+       rtc_tm_to_time(tm, &rtc_count);
+       writel(rtc_count, RTC_RCNR);
+
+       return 0;
+}
+
+static int puv3_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+       struct rtc_time *alm_tm = &alrm->time;
+
+       rtc_time_to_tm(readl(RTC_RTAR), alm_tm);
+
+       alrm->enabled = readl(RTC_RTSR) & RTC_RTSR_ALE;
+
+       pr_debug("read alarm %02x %02x.%02x.%02x %02x/%02x/%02x\n",
+                alrm->enabled,
+                alm_tm->tm_year, alm_tm->tm_mon, alm_tm->tm_mday,
+                alm_tm->tm_hour, alm_tm->tm_min, alm_tm->tm_sec);
+
+       return 0;
+}
+
+static int puv3_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+       struct rtc_time *tm = &alrm->time;
+       unsigned long rtcalarm_count = 0;
+
+       pr_debug("puv3_rtc_setalarm: %d, %02x/%02x/%02x %02x.%02x.%02x\n",
+                alrm->enabled,
+                tm->tm_mday & 0xff, tm->tm_mon & 0xff, tm->tm_year & 0xff,
+                tm->tm_hour & 0xff, tm->tm_min & 0xff, tm->tm_sec);
+
+       rtc_tm_to_time(tm, &rtcalarm_count);
+       writel(rtcalarm_count, RTC_RTAR);
+
+       puv3_rtc_setaie(alrm->enabled);
+
+       if (alrm->enabled)
+               enable_irq_wake(puv3_rtc_alarmno);
+       else
+               disable_irq_wake(puv3_rtc_alarmno);
+
+       return 0;
+}
+
+static int puv3_rtc_proc(struct device *dev, struct seq_file *seq)
+{
+       seq_printf(seq, "periodic_IRQ\t: %s\n",
+                    (readl(RTC_RTSR) & RTC_RTSR_HZE) ? "yes" : "no");
+       return 0;
+}
+
+static int puv3_rtc_open(struct device *dev)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct rtc_device *rtc_dev = platform_get_drvdata(pdev);
+       int ret;
+
+       ret = request_irq(puv3_rtc_alarmno, puv3_rtc_alarmirq,
+                         IRQF_DISABLED,  "pkunity-rtc alarm", rtc_dev);
+
+       if (ret) {
+               dev_err(dev, "IRQ%d error %d\n", puv3_rtc_alarmno, ret);
+               return ret;
+       }
+
+       ret = request_irq(puv3_rtc_tickno, puv3_rtc_tickirq,
+                         IRQF_DISABLED,  "pkunity-rtc tick", rtc_dev);
+
+       if (ret) {
+               dev_err(dev, "IRQ%d error %d\n", puv3_rtc_tickno, ret);
+               goto tick_err;
+       }
+
+       return ret;
+
+ tick_err:
+       free_irq(puv3_rtc_alarmno, rtc_dev);
+       return ret;
+}
+
+static void puv3_rtc_release(struct device *dev)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct rtc_device *rtc_dev = platform_get_drvdata(pdev);
+
+       /* do not clear AIE here, it may be needed for wake */
+       puv3_rtc_setpie(dev, 0);
+       free_irq(puv3_rtc_alarmno, rtc_dev);
+       free_irq(puv3_rtc_tickno, rtc_dev);
+}
+
+static const struct rtc_class_ops puv3_rtcops = {
+       .open           = puv3_rtc_open,
+       .release        = puv3_rtc_release,
+       .read_time      = puv3_rtc_gettime,
+       .set_time       = puv3_rtc_settime,
+       .read_alarm     = puv3_rtc_getalarm,
+       .set_alarm      = puv3_rtc_setalarm,
+       .proc           = puv3_rtc_proc,
+};
+
+static void puv3_rtc_enable(struct platform_device *pdev, int en)
+{
+       if (!en) {
+               writel(readl(RTC_RTSR) & ~RTC_RTSR_HZE, RTC_RTSR);
+       } else {
+               /* re-enable the device, and check it is ok */
+               if ((readl(RTC_RTSR) & RTC_RTSR_HZE) == 0) {
+                       dev_info(&pdev->dev, "rtc disabled, re-enabling\n");
+                       writel(readl(RTC_RTSR) | RTC_RTSR_HZE, RTC_RTSR);
+               }
+       }
+}
+
+static int puv3_rtc_remove(struct platform_device *dev)
+{
+       struct rtc_device *rtc = platform_get_drvdata(dev);
+
+       platform_set_drvdata(dev, NULL);
+       rtc_device_unregister(rtc);
+
+       puv3_rtc_setpie(&dev->dev, 0);
+       puv3_rtc_setaie(0);
+
+       release_resource(puv3_rtc_mem);
+       kfree(puv3_rtc_mem);
+
+       return 0;
+}
+
+static int puv3_rtc_probe(struct platform_device *pdev)
+{
+       struct rtc_device *rtc;
+       struct resource *res;
+       int ret;
+
+       pr_debug("%s: probe=%p\n", __func__, pdev);
+
+       /* find the IRQs */
+       puv3_rtc_tickno = platform_get_irq(pdev, 1);
+       if (puv3_rtc_tickno < 0) {
+               dev_err(&pdev->dev, "no irq for rtc tick\n");
+               return -ENOENT;
+       }
+
+       puv3_rtc_alarmno = platform_get_irq(pdev, 0);
+       if (puv3_rtc_alarmno < 0) {
+               dev_err(&pdev->dev, "no irq for alarm\n");
+               return -ENOENT;
+       }
+
+       pr_debug("PKUnity_rtc: tick irq %d, alarm irq %d\n",
+                puv3_rtc_tickno, puv3_rtc_alarmno);
+
+       /* get the memory region */
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (res == NULL) {
+               dev_err(&pdev->dev, "failed to get memory region resource\n");
+               return -ENOENT;
+       }
+
+       puv3_rtc_mem = request_mem_region(res->start,
+                                        res->end-res->start+1,
+                                        pdev->name);
+
+       if (puv3_rtc_mem == NULL) {
+               dev_err(&pdev->dev, "failed to reserve memory region\n");
+               ret = -ENOENT;
+               goto err_nores;
+       }
+
+       puv3_rtc_enable(pdev, 1);
+
+       /* register RTC and exit */
+       rtc = rtc_device_register("pkunity", &pdev->dev, &puv3_rtcops,
+                                 THIS_MODULE);
+
+       if (IS_ERR(rtc)) {
+               dev_err(&pdev->dev, "cannot attach rtc\n");
+               ret = PTR_ERR(rtc);
+               goto err_nortc;
+       }
+
+       /* platform setup code should have handled this; sigh */
+       if (!device_can_wakeup(&pdev->dev))
+               device_init_wakeup(&pdev->dev, 1);
+
+       platform_set_drvdata(pdev, rtc);
+       return 0;
+
+ err_nortc:
+       puv3_rtc_enable(pdev, 0);
+       release_resource(puv3_rtc_mem);
+
+ err_nores:
+       return ret;
+}
+
+#ifdef CONFIG_PM
+
+static int ticnt_save;
+
+static int puv3_rtc_suspend(struct platform_device *pdev, pm_message_t state)
+{
+       /* save RTAR for anyone using periodic interrupts */
+       ticnt_save = readl(RTC_RTAR);
+       puv3_rtc_enable(pdev, 0);
+       return 0;
+}
+
+static int puv3_rtc_resume(struct platform_device *pdev)
+{
+       puv3_rtc_enable(pdev, 1);
+       writel(ticnt_save, RTC_RTAR);
+       return 0;
+}
+#else
+#define puv3_rtc_suspend NULL
+#define puv3_rtc_resume  NULL
+#endif
+
+static struct platform_driver puv3_rtcdrv = {
+       .probe          = puv3_rtc_probe,
+       .remove         = __devexit_p(puv3_rtc_remove),
+       .suspend        = puv3_rtc_suspend,
+       .resume         = puv3_rtc_resume,
+       .driver         = {
+               .name   = "PKUnity-v3-RTC",
+               .owner  = THIS_MODULE,
+       }
+};
+
+static char __initdata banner[] = "PKUnity-v3 RTC, (c) 2009 PKUnity Co.\n";
+
+static int __init puv3_rtc_init(void)
+{
+       printk(banner);
+       return platform_driver_register(&puv3_rtcdrv);
+}
+
+static void __exit puv3_rtc_exit(void)
+{
+       platform_driver_unregister(&puv3_rtcdrv);
+}
+
+module_init(puv3_rtc_init);
+module_exit(puv3_rtc_exit);
+
+MODULE_DESCRIPTION("RTC Driver for the PKUnity v3 chip");
+MODULE_AUTHOR("Hu Dongliang");
+MODULE_LICENSE("GPL v2");
index 55e8f721e38a7209e5875c60c1af7b3c1486fb1a..570d4da10696177e6a05ed78dbeb459617d8f49c 100644 (file)
@@ -416,7 +416,7 @@ static void process_buffer_error(struct qdio_q *q, int count)
 
        /* special handling for no target buffer empty */
        if ((!q->is_input_q &&
-           (q->sbal[q->first_to_check]->element[15].flags & 0xff) == 0x10)) {
+           (q->sbal[q->first_to_check]->element[15].sflags) == 0x10)) {
                qperf_inc(q, target_full);
                DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "OUTFULL FTC:%02x",
                              q->first_to_check);
@@ -427,8 +427,8 @@ static void process_buffer_error(struct qdio_q *q, int count)
        DBF_ERROR((q->is_input_q) ? "IN:%2d" : "OUT:%2d", q->nr);
        DBF_ERROR("FTC:%3d C:%3d", q->first_to_check, count);
        DBF_ERROR("F14:%2x F15:%2x",
-                 q->sbal[q->first_to_check]->element[14].flags & 0xff,
-                 q->sbal[q->first_to_check]->element[15].flags & 0xff);
+                 q->sbal[q->first_to_check]->element[14].sflags,
+                 q->sbal[q->first_to_check]->element[15].sflags);
 
        /*
         * Interrupts may be avoided as long as the error is present
index 55c6aa1c9704f54e5c6f26e21a7b1f5c7610dbe0..d3cee33e554cace96b035b82c80ac87fc1485b01 100644 (file)
@@ -361,7 +361,7 @@ enum qeth_header_ids {
 
 static inline int qeth_is_last_sbale(struct qdio_buffer_element *sbale)
 {
-       return (sbale->flags & SBAL_FLAGS_LAST_ENTRY);
+       return (sbale->eflags & SBAL_EFLAGS_LAST_ENTRY);
 }
 
 enum qeth_qdio_buffer_states {
index 503678a30981f071f8e8ef9db25729817cc5d07a..dd08f7b42fb8ff26ebf91d943fa58d01376d6184 100644 (file)
@@ -890,7 +890,7 @@ static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue,
        struct sk_buff *skb;
 
        /* is PCI flag set on buffer? */
-       if (buf->buffer->element[0].flags & 0x40)
+       if (buf->buffer->element[0].sflags & SBAL_SFLAGS0_PCI_REQ)
                atomic_dec(&queue->set_pci_flags_count);
 
        skb = skb_dequeue(&buf->skb_list);
@@ -906,9 +906,11 @@ static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue,
                buf->is_header[i] = 0;
                buf->buffer->element[i].length = 0;
                buf->buffer->element[i].addr = NULL;
-               buf->buffer->element[i].flags = 0;
+               buf->buffer->element[i].eflags = 0;
+               buf->buffer->element[i].sflags = 0;
        }
-       buf->buffer->element[15].flags = 0;
+       buf->buffer->element[15].eflags = 0;
+       buf->buffer->element[15].sflags = 0;
        buf->next_element_to_fill = 0;
        atomic_set(&buf->state, QETH_QDIO_BUF_EMPTY);
 }
@@ -2368,9 +2370,10 @@ static int qeth_init_input_buffer(struct qeth_card *card,
                buf->buffer->element[i].length = PAGE_SIZE;
                buf->buffer->element[i].addr =  pool_entry->elements[i];
                if (i == QETH_MAX_BUFFER_ELEMENTS(card) - 1)
-                       buf->buffer->element[i].flags = SBAL_FLAGS_LAST_ENTRY;
+                       buf->buffer->element[i].eflags = SBAL_EFLAGS_LAST_ENTRY;
                else
-                       buf->buffer->element[i].flags = 0;
+                       buf->buffer->element[i].eflags = 0;
+               buf->buffer->element[i].sflags = 0;
        }
        return 0;
 }
@@ -2718,11 +2721,11 @@ int qeth_check_qdio_errors(struct qeth_card *card, struct qdio_buffer *buf,
        if (qdio_error) {
                QETH_CARD_TEXT(card, 2, dbftext);
                QETH_CARD_TEXT_(card, 2, " F15=%02X",
-                              buf->element[15].flags & 0xff);
+                              buf->element[15].sflags);
                QETH_CARD_TEXT_(card, 2, " F14=%02X",
-                              buf->element[14].flags & 0xff);
+                              buf->element[14].sflags);
                QETH_CARD_TEXT_(card, 2, " qerr=%X", qdio_error);
-               if ((buf->element[15].flags & 0xff) == 0x12) {
+               if ((buf->element[15].sflags) == 0x12) {
                        card->stats.rx_dropped++;
                        return 0;
                } else
@@ -2798,7 +2801,7 @@ EXPORT_SYMBOL_GPL(qeth_queue_input_buffer);
 static int qeth_handle_send_error(struct qeth_card *card,
                struct qeth_qdio_out_buffer *buffer, unsigned int qdio_err)
 {
-       int sbalf15 = buffer->buffer->element[15].flags & 0xff;
+       int sbalf15 = buffer->buffer->element[15].sflags;
 
        QETH_CARD_TEXT(card, 6, "hdsnderr");
        if (card->info.type == QETH_CARD_TYPE_IQD) {
@@ -2907,8 +2910,8 @@ static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index,
 
        for (i = index; i < index + count; ++i) {
                buf = &queue->bufs[i % QDIO_MAX_BUFFERS_PER_Q];
-               buf->buffer->element[buf->next_element_to_fill - 1].flags |=
-                               SBAL_FLAGS_LAST_ENTRY;
+               buf->buffer->element[buf->next_element_to_fill - 1].eflags |=
+                               SBAL_EFLAGS_LAST_ENTRY;
 
                if (queue->card->info.type == QETH_CARD_TYPE_IQD)
                        continue;
@@ -2921,7 +2924,7 @@ static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index,
                                /* it's likely that we'll go to packing
                                 * mode soon */
                                atomic_inc(&queue->set_pci_flags_count);
-                               buf->buffer->element[0].flags |= 0x40;
+                               buf->buffer->element[0].sflags |= SBAL_SFLAGS0_PCI_REQ;
                        }
                } else {
                        if (!atomic_read(&queue->set_pci_flags_count)) {
@@ -2934,7 +2937,7 @@ static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index,
                                 * further send was requested by the stack
                                 */
                                atomic_inc(&queue->set_pci_flags_count);
-                               buf->buffer->element[0].flags |= 0x40;
+                               buf->buffer->element[0].sflags |= SBAL_SFLAGS0_PCI_REQ;
                        }
                }
        }
@@ -3180,20 +3183,20 @@ static inline void __qeth_fill_buffer(struct sk_buff *skb,
                if (!length) {
                        if (first_lap)
                                if (skb_shinfo(skb)->nr_frags)
-                                       buffer->element[element].flags =
-                                               SBAL_FLAGS_FIRST_FRAG;
+                                       buffer->element[element].eflags =
+                                               SBAL_EFLAGS_FIRST_FRAG;
                                else
-                                       buffer->element[element].flags = 0;
+                                       buffer->element[element].eflags = 0;
                        else
-                               buffer->element[element].flags =
-                                   SBAL_FLAGS_MIDDLE_FRAG;
+                               buffer->element[element].eflags =
+                                   SBAL_EFLAGS_MIDDLE_FRAG;
                } else {
                        if (first_lap)
-                               buffer->element[element].flags =
-                                   SBAL_FLAGS_FIRST_FRAG;
+                               buffer->element[element].eflags =
+                                   SBAL_EFLAGS_FIRST_FRAG;
                        else
-                               buffer->element[element].flags =
-                                   SBAL_FLAGS_MIDDLE_FRAG;
+                               buffer->element[element].eflags =
+                                   SBAL_EFLAGS_MIDDLE_FRAG;
                }
                data += length_here;
                element++;
@@ -3205,12 +3208,12 @@ static inline void __qeth_fill_buffer(struct sk_buff *skb,
                buffer->element[element].addr = (char *)page_to_phys(frag->page)
                        + frag->page_offset;
                buffer->element[element].length = frag->size;
-               buffer->element[element].flags = SBAL_FLAGS_MIDDLE_FRAG;
+               buffer->element[element].eflags = SBAL_EFLAGS_MIDDLE_FRAG;
                element++;
        }
 
-       if (buffer->element[element - 1].flags)
-               buffer->element[element - 1].flags = SBAL_FLAGS_LAST_FRAG;
+       if (buffer->element[element - 1].eflags)
+               buffer->element[element - 1].eflags = SBAL_EFLAGS_LAST_FRAG;
        *next_element_to_fill = element;
 }
 
@@ -3234,7 +3237,7 @@ static inline int qeth_fill_buffer(struct qeth_qdio_out_q *queue,
                /*fill first buffer entry only with header information */
                buffer->element[element].addr = skb->data;
                buffer->element[element].length = hdr_len;
-               buffer->element[element].flags = SBAL_FLAGS_FIRST_FRAG;
+               buffer->element[element].eflags = SBAL_EFLAGS_FIRST_FRAG;
                buf->next_element_to_fill++;
                skb->data += hdr_len;
                skb->len  -= hdr_len;
@@ -3246,7 +3249,7 @@ static inline int qeth_fill_buffer(struct qeth_qdio_out_q *queue,
                buffer->element[element].addr = hdr;
                buffer->element[element].length = sizeof(struct qeth_hdr) +
                                                        hd_len;
-               buffer->element[element].flags = SBAL_FLAGS_FIRST_FRAG;
+               buffer->element[element].eflags = SBAL_EFLAGS_FIRST_FRAG;
                buf->is_header[element] = 1;
                buf->next_element_to_fill++;
        }
index 8512b5c0ef82868d0a5ac87b0d813b84abacff81..022fb6a8cb8339a6a8854b69ffc7021a3bdce1cf 100644 (file)
@@ -640,7 +640,7 @@ static struct fsf_qtcb *zfcp_qtcb_alloc(mempool_t *pool)
 }
 
 static struct zfcp_fsf_req *zfcp_fsf_req_create(struct zfcp_qdio *qdio,
-                                               u32 fsf_cmd, u32 sbtype,
+                                               u32 fsf_cmd, u8 sbtype,
                                                mempool_t *pool)
 {
        struct zfcp_adapter *adapter = qdio->adapter;
@@ -841,7 +841,7 @@ struct zfcp_fsf_req *zfcp_fsf_abort_fcp_cmnd(struct scsi_cmnd *scmnd)
        if (zfcp_qdio_sbal_get(qdio))
                goto out;
        req = zfcp_fsf_req_create(qdio, FSF_QTCB_ABORT_FCP_CMND,
-                                 SBAL_FLAGS0_TYPE_READ,
+                                 SBAL_SFLAGS0_TYPE_READ,
                                  qdio->adapter->pool.scsi_abort);
        if (IS_ERR(req)) {
                req = NULL;
@@ -1012,7 +1012,7 @@ int zfcp_fsf_send_ct(struct zfcp_fc_wka_port *wka_port,
                goto out;
 
        req = zfcp_fsf_req_create(qdio, FSF_QTCB_SEND_GENERIC,
-                                 SBAL_FLAGS0_TYPE_WRITE_READ, pool);
+                                 SBAL_SFLAGS0_TYPE_WRITE_READ, pool);
 
        if (IS_ERR(req)) {
                ret = PTR_ERR(req);
@@ -1110,7 +1110,7 @@ int zfcp_fsf_send_els(struct zfcp_adapter *adapter, u32 d_id,
                goto out;
 
        req = zfcp_fsf_req_create(qdio, FSF_QTCB_SEND_ELS,
-                                 SBAL_FLAGS0_TYPE_WRITE_READ, NULL);
+                                 SBAL_SFLAGS0_TYPE_WRITE_READ, NULL);
 
        if (IS_ERR(req)) {
                ret = PTR_ERR(req);
@@ -1156,7 +1156,7 @@ int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action)
                goto out;
 
        req = zfcp_fsf_req_create(qdio, FSF_QTCB_EXCHANGE_CONFIG_DATA,
-                                 SBAL_FLAGS0_TYPE_READ,
+                                 SBAL_SFLAGS0_TYPE_READ,
                                  qdio->adapter->pool.erp_req);
 
        if (IS_ERR(req)) {
@@ -1198,7 +1198,7 @@ int zfcp_fsf_exchange_config_data_sync(struct zfcp_qdio *qdio,
                goto out_unlock;
 
        req = zfcp_fsf_req_create(qdio, FSF_QTCB_EXCHANGE_CONFIG_DATA,
-                                 SBAL_FLAGS0_TYPE_READ, NULL);
+                                 SBAL_SFLAGS0_TYPE_READ, NULL);
 
        if (IS_ERR(req)) {
                retval = PTR_ERR(req);
@@ -1250,7 +1250,7 @@ int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action)
                goto out;
 
        req = zfcp_fsf_req_create(qdio, FSF_QTCB_EXCHANGE_PORT_DATA,
-                                 SBAL_FLAGS0_TYPE_READ,
+                                 SBAL_SFLAGS0_TYPE_READ,
                                  qdio->adapter->pool.erp_req);
 
        if (IS_ERR(req)) {
@@ -1296,7 +1296,7 @@ int zfcp_fsf_exchange_port_data_sync(struct zfcp_qdio *qdio,
                goto out_unlock;
 
        req = zfcp_fsf_req_create(qdio, FSF_QTCB_EXCHANGE_PORT_DATA,
-                                 SBAL_FLAGS0_TYPE_READ, NULL);
+                                 SBAL_SFLAGS0_TYPE_READ, NULL);
 
        if (IS_ERR(req)) {
                retval = PTR_ERR(req);
@@ -1412,7 +1412,7 @@ int zfcp_fsf_open_port(struct zfcp_erp_action *erp_action)
                goto out;
 
        req = zfcp_fsf_req_create(qdio, FSF_QTCB_OPEN_PORT_WITH_DID,
-                                 SBAL_FLAGS0_TYPE_READ,
+                                 SBAL_SFLAGS0_TYPE_READ,
                                  qdio->adapter->pool.erp_req);
 
        if (IS_ERR(req)) {
@@ -1478,7 +1478,7 @@ int zfcp_fsf_close_port(struct zfcp_erp_action *erp_action)
                goto out;
 
        req = zfcp_fsf_req_create(qdio, FSF_QTCB_CLOSE_PORT,
-                                 SBAL_FLAGS0_TYPE_READ,
+                                 SBAL_SFLAGS0_TYPE_READ,
                                  qdio->adapter->pool.erp_req);
 
        if (IS_ERR(req)) {
@@ -1553,7 +1553,7 @@ int zfcp_fsf_open_wka_port(struct zfcp_fc_wka_port *wka_port)
                goto out;
 
        req = zfcp_fsf_req_create(qdio, FSF_QTCB_OPEN_PORT_WITH_DID,
-                                 SBAL_FLAGS0_TYPE_READ,
+                                 SBAL_SFLAGS0_TYPE_READ,
                                  qdio->adapter->pool.erp_req);
 
        if (IS_ERR(req)) {
@@ -1606,7 +1606,7 @@ int zfcp_fsf_close_wka_port(struct zfcp_fc_wka_port *wka_port)
                goto out;
 
        req = zfcp_fsf_req_create(qdio, FSF_QTCB_CLOSE_PORT,
-                                 SBAL_FLAGS0_TYPE_READ,
+                                 SBAL_SFLAGS0_TYPE_READ,
                                  qdio->adapter->pool.erp_req);
 
        if (IS_ERR(req)) {
@@ -1698,7 +1698,7 @@ int zfcp_fsf_close_physical_port(struct zfcp_erp_action *erp_action)
                goto out;
 
        req = zfcp_fsf_req_create(qdio, FSF_QTCB_CLOSE_PHYSICAL_PORT,
-                                 SBAL_FLAGS0_TYPE_READ,
+                                 SBAL_SFLAGS0_TYPE_READ,
                                  qdio->adapter->pool.erp_req);
 
        if (IS_ERR(req)) {
@@ -1812,7 +1812,7 @@ int zfcp_fsf_open_lun(struct zfcp_erp_action *erp_action)
                goto out;
 
        req = zfcp_fsf_req_create(qdio, FSF_QTCB_OPEN_LUN,
-                                 SBAL_FLAGS0_TYPE_READ,
+                                 SBAL_SFLAGS0_TYPE_READ,
                                  adapter->pool.erp_req);
 
        if (IS_ERR(req)) {
@@ -1901,7 +1901,7 @@ int zfcp_fsf_close_lun(struct zfcp_erp_action *erp_action)
                goto out;
 
        req = zfcp_fsf_req_create(qdio, FSF_QTCB_CLOSE_LUN,
-                                 SBAL_FLAGS0_TYPE_READ,
+                                 SBAL_SFLAGS0_TYPE_READ,
                                  qdio->adapter->pool.erp_req);
 
        if (IS_ERR(req)) {
@@ -2161,7 +2161,7 @@ int zfcp_fsf_fcp_cmnd(struct scsi_cmnd *scsi_cmnd)
 {
        struct zfcp_fsf_req *req;
        struct fcp_cmnd *fcp_cmnd;
-       unsigned int sbtype = SBAL_FLAGS0_TYPE_READ;
+       u8 sbtype = SBAL_SFLAGS0_TYPE_READ;
        int real_bytes, retval = -EIO, dix_bytes = 0;
        struct scsi_device *sdev = scsi_cmnd->device;
        struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
@@ -2181,7 +2181,7 @@ int zfcp_fsf_fcp_cmnd(struct scsi_cmnd *scsi_cmnd)
        }
 
        if (scsi_cmnd->sc_data_direction == DMA_TO_DEVICE)
-               sbtype = SBAL_FLAGS0_TYPE_WRITE;
+               sbtype = SBAL_SFLAGS0_TYPE_WRITE;
 
        req = zfcp_fsf_req_create(qdio, FSF_QTCB_FCP_CMND,
                                  sbtype, adapter->pool.scsi_req);
@@ -2280,7 +2280,7 @@ struct zfcp_fsf_req *zfcp_fsf_fcp_task_mgmt(struct scsi_cmnd *scmnd,
                goto out;
 
        req = zfcp_fsf_req_create(qdio, FSF_QTCB_FCP_CMND,
-                                 SBAL_FLAGS0_TYPE_WRITE,
+                                 SBAL_SFLAGS0_TYPE_WRITE,
                                  qdio->adapter->pool.scsi_req);
 
        if (IS_ERR(req)) {
@@ -2328,17 +2328,18 @@ struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter,
        struct zfcp_qdio *qdio = adapter->qdio;
        struct zfcp_fsf_req *req = NULL;
        struct fsf_qtcb_bottom_support *bottom;
-       int direction, retval = -EIO, bytes;
+       int retval = -EIO, bytes;
+       u8 direction;
 
        if (!(adapter->adapter_features & FSF_FEATURE_CFDC))
                return ERR_PTR(-EOPNOTSUPP);
 
        switch (fsf_cfdc->command) {
        case FSF_QTCB_DOWNLOAD_CONTROL_FILE:
-               direction = SBAL_FLAGS0_TYPE_WRITE;
+               direction = SBAL_SFLAGS0_TYPE_WRITE;
                break;
        case FSF_QTCB_UPLOAD_CONTROL_FILE:
-               direction = SBAL_FLAGS0_TYPE_READ;
+               direction = SBAL_SFLAGS0_TYPE_READ;
                break;
        default:
                return ERR_PTR(-EINVAL);
@@ -2413,7 +2414,7 @@ void zfcp_fsf_reqid_check(struct zfcp_qdio *qdio, int sbal_idx)
                fsf_req->qdio_req.sbal_response = sbal_idx;
                zfcp_fsf_req_complete(fsf_req);
 
-               if (likely(sbale->flags & SBAL_FLAGS_LAST_ENTRY))
+               if (likely(sbale->eflags & SBAL_EFLAGS_LAST_ENTRY))
                        break;
        }
 }
index 98e97d90835b673e770af3911e876537644073b7..d9c40ea73eef4864e6a477d2803b61309e037a1a 100644 (file)
@@ -124,7 +124,7 @@ zfcp_qdio_sbal_chain(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req)
 
        /* set last entry flag in current SBALE of current SBAL */
        sbale = zfcp_qdio_sbale_curr(qdio, q_req);
-       sbale->flags |= SBAL_FLAGS_LAST_ENTRY;
+       sbale->eflags |= SBAL_EFLAGS_LAST_ENTRY;
 
        /* don't exceed last allowed SBAL */
        if (q_req->sbal_last == q_req->sbal_limit)
@@ -132,7 +132,7 @@ zfcp_qdio_sbal_chain(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req)
 
        /* set chaining flag in first SBALE of current SBAL */
        sbale = zfcp_qdio_sbale_req(qdio, q_req);
-       sbale->flags |= SBAL_FLAGS0_MORE_SBALS;
+       sbale->sflags |= SBAL_SFLAGS0_MORE_SBALS;
 
        /* calculate index of next SBAL */
        q_req->sbal_last++;
@@ -147,7 +147,7 @@ zfcp_qdio_sbal_chain(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req)
 
        /* set storage-block type for new SBAL */
        sbale = zfcp_qdio_sbale_curr(qdio, q_req);
-       sbale->flags |= q_req->sbtype;
+       sbale->sflags |= q_req->sbtype;
 
        return sbale;
 }
@@ -177,7 +177,7 @@ int zfcp_qdio_sbals_from_sg(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req,
 
        /* set storage-block type for this request */
        sbale = zfcp_qdio_sbale_req(qdio, q_req);
-       sbale->flags |= q_req->sbtype;
+       sbale->sflags |= q_req->sbtype;
 
        for (; sg; sg = sg_next(sg)) {
                sbale = zfcp_qdio_sbale_next(qdio, q_req);
@@ -384,7 +384,8 @@ int zfcp_qdio_open(struct zfcp_qdio *qdio)
        for (cc = 0; cc < QDIO_MAX_BUFFERS_PER_Q; cc++) {
                sbale = &(qdio->res_q[cc]->element[0]);
                sbale->length = 0;
-               sbale->flags = SBAL_FLAGS_LAST_ENTRY;
+               sbale->eflags = SBAL_EFLAGS_LAST_ENTRY;
+               sbale->sflags = 0;
                sbale->addr = NULL;
        }
 
index 2297d8d3e947b0aa16ba1d4c0d68251c6eade33d..54e22ace012b601f5a3cc8dd3cc33505458b8cfd 100644 (file)
@@ -67,7 +67,7 @@ struct zfcp_qdio {
  * @qdio_outb_usage: usage of outbound queue
  */
 struct zfcp_qdio_req {
-       u32     sbtype;
+       u     sbtype;
        u8      sbal_number;
        u8      sbal_first;
        u8      sbal_last;
@@ -116,7 +116,7 @@ zfcp_qdio_sbale_curr(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req)
  */
 static inline
 void zfcp_qdio_req_init(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req,
-                       unsigned long req_id, u32 sbtype, void *data, u32 len)
+                       unsigned long req_id, u8 sbtype, void *data, u32 len)
 {
        struct qdio_buffer_element *sbale;
        int count = min(atomic_read(&qdio->req_q_free),
@@ -131,7 +131,8 @@ void zfcp_qdio_req_init(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req,
 
        sbale = zfcp_qdio_sbale_req(qdio, q_req);
        sbale->addr = (void *) req_id;
-       sbale->flags = SBAL_FLAGS0_COMMAND | sbtype;
+       sbale->eflags = 0;
+       sbale->sflags = SBAL_SFLAGS0_COMMAND | sbtype;
 
        if (unlikely(!data))
                return;
@@ -173,7 +174,7 @@ void zfcp_qdio_set_sbale_last(struct zfcp_qdio *qdio,
        struct qdio_buffer_element *sbale;
 
        sbale = zfcp_qdio_sbale_curr(qdio, q_req);
-       sbale->flags |= SBAL_FLAGS_LAST_ENTRY;
+       sbale->eflags |= SBAL_EFLAGS_LAST_ENTRY;
 }
 
 /**
index 58584dc0724ade4fb4b2d5fc12d48b962d2b91bd..44e8ca398efa790083006131f5adb3bf37cd57aa 100644 (file)
@@ -297,7 +297,7 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget,
                kfree(sdev);
                goto out;
        }
-
+       blk_get_queue(sdev->request_queue);
        sdev->request_queue->queuedata = sdev;
        scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
 
index e63912510fb9349b31ede55df1c0b20011b6235e..e0bd3f790fca1bf50e4e66e3b2f30f9a130547f3 100644 (file)
@@ -322,6 +322,7 @@ static void scsi_device_dev_release_usercontext(struct work_struct *work)
                kfree(evt);
        }
 
+       blk_put_queue(sdev->request_queue);
        /* NULL queue means the device can't be used */
        sdev->request_queue = NULL;
 
index 6f86ba0175ac9636e564f44cf23ff41223de6b8a..969cdd2fe124602d1e65c4218190ed3e7d78ccf6 100644 (file)
@@ -298,7 +298,7 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer)
        unsigned int            count, c;
        unsigned long           base, tx_reg, rx_reg;
        int                     word_len, data_type, element_count;
-       int                     elements;
+       int                     elements = 0;
        u32                     l;
        u8                      * rx;
        const u8                * tx;
index a4c42a75a3bfea0f0143e8dd70454fde5dddf524..09e8c7d53af3e7d72ebfe25b45100789f4f5185a 100644 (file)
@@ -2128,8 +2128,8 @@ static void gsmld_detach_gsm(struct tty_struct *tty, struct gsm_mux *gsm)
        gsm->tty = NULL;
 }
 
-static unsigned int gsmld_receive_buf(struct tty_struct *tty,
-               const unsigned char *cp, char *fp, int count)
+static void gsmld_receive_buf(struct tty_struct *tty, const unsigned char *cp,
+                             char *fp, int count)
 {
        struct gsm_mux *gsm = tty->disc_data;
        const unsigned char *dp;
@@ -2162,8 +2162,6 @@ static unsigned int gsmld_receive_buf(struct tty_struct *tty,
        }
        /* FASYNC if needed ? */
        /* If clogged call tty_throttle(tty); */
-
-       return count;
 }
 
 /**
index cac666314aef4a5f453c5031caaa5b8fac4f0508..cea56033b34c2b490e796ae75df0fbea4e550a3f 100644 (file)
@@ -188,8 +188,8 @@ static unsigned int n_hdlc_tty_poll(struct tty_struct *tty, struct file *filp,
                                    poll_table *wait);
 static int n_hdlc_tty_open(struct tty_struct *tty);
 static void n_hdlc_tty_close(struct tty_struct *tty);
-static unsigned int n_hdlc_tty_receive(struct tty_struct *tty,
-               const __u8 *cp, char *fp, int count);
+static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *cp,
+                              char *fp, int count);
 static void n_hdlc_tty_wakeup(struct tty_struct *tty);
 
 #define bset(p,b)      ((p)[(b) >> 5] |= (1 << ((b) & 0x1f)))
@@ -509,8 +509,8 @@ static void n_hdlc_tty_wakeup(struct tty_struct *tty)
  * Called by tty low level driver when receive data is available. Data is
  * interpreted as one HDLC frame.
  */
-static unsigned int n_hdlc_tty_receive(struct tty_struct *tty,
-               const __u8 *data, char *flags, int count)
+static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *data,
+                              char *flags, int count)
 {
        register struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
        register struct n_hdlc_buf *buf;
@@ -521,20 +521,20 @@ static unsigned int n_hdlc_tty_receive(struct tty_struct *tty,
                
        /* This can happen if stuff comes in on the backup tty */
        if (!n_hdlc || tty != n_hdlc->tty)
-               return -ENODEV;
+               return;
                
        /* verify line is using HDLC discipline */
        if (n_hdlc->magic != HDLC_MAGIC) {
                printk("%s(%d) line not using HDLC discipline\n",
                        __FILE__,__LINE__);
-               return -EINVAL;
+               return;
        }
        
        if ( count>maxframe ) {
                if (debuglevel >= DEBUG_LEVEL_INFO)     
                        printk("%s(%d) rx count>maxframesize, data discarded\n",
                               __FILE__,__LINE__);
-               return -EINVAL;
+               return;
        }
 
        /* get a free HDLC buffer */    
@@ -550,7 +550,7 @@ static unsigned int n_hdlc_tty_receive(struct tty_struct *tty,
                if (debuglevel >= DEBUG_LEVEL_INFO)     
                        printk("%s(%d) no more rx buffers, data discarded\n",
                               __FILE__,__LINE__);
-               return -EINVAL;
+               return;
        }
                
        /* copy received data to HDLC buffer */
@@ -565,8 +565,6 @@ static unsigned int n_hdlc_tty_receive(struct tty_struct *tty,
        if (n_hdlc->tty->fasync != NULL)
                kill_fasync (&n_hdlc->tty->fasync, SIGIO, POLL_IN);
 
-       return count;
-
 }      /* end of n_hdlc_tty_receive() */
 
 /**
index a4bc39c21a436476b7ea8363f6c4d892882a5520..5c6c31459a2f6618cb7cf9d83c7100cf1a6d86ea 100644 (file)
@@ -139,8 +139,8 @@ static int r3964_ioctl(struct tty_struct *tty, struct file *file,
 static void r3964_set_termios(struct tty_struct *tty, struct ktermios *old);
 static unsigned int r3964_poll(struct tty_struct *tty, struct file *file,
                struct poll_table_struct *wait);
-static unsigned int r3964_receive_buf(struct tty_struct *tty,
-               const unsigned char *cp, char *fp, int count);
+static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp,
+               char *fp, int count);
 
 static struct tty_ldisc_ops tty_ldisc_N_R3964 = {
        .owner = THIS_MODULE,
@@ -1239,8 +1239,8 @@ static unsigned int r3964_poll(struct tty_struct *tty, struct file *file,
        return result;
 }
 
-static unsigned int r3964_receive_buf(struct tty_struct *tty,
-               const unsigned char *cp, char *fp, int count)
+static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp,
+                       char *fp, int count)
 {
        struct r3964_info *pInfo = tty->disc_data;
        const unsigned char *p;
@@ -1257,8 +1257,6 @@ static unsigned int r3964_receive_buf(struct tty_struct *tty,
                }
 
        }
-
-       return count;
 }
 
 MODULE_LICENSE("GPL");
index 95d0a9c2dd13e3e625d8b287d911d327cebe2ee4..0ad32888091c16c1c27de4c032517df583ea4c9f 100644 (file)
@@ -81,6 +81,38 @@ static inline int tty_put_user(struct tty_struct *tty, unsigned char x,
        return put_user(x, ptr);
 }
 
+/**
+ *     n_tty_set__room -       receive space
+ *     @tty: terminal
+ *
+ *     Called by the driver to find out how much data it is
+ *     permitted to feed to the line discipline without any being lost
+ *     and thus to manage flow control. Not serialized. Answers for the
+ *     "instant".
+ */
+
+static void n_tty_set_room(struct tty_struct *tty)
+{
+       /* tty->read_cnt is not read locked ? */
+       int     left = N_TTY_BUF_SIZE - tty->read_cnt - 1;
+       int old_left;
+
+       /*
+        * If we are doing input canonicalization, and there are no
+        * pending newlines, let characters through without limit, so
+        * that erase characters will be handled.  Other excess
+        * characters will be beeped.
+        */
+       if (left <= 0)
+               left = tty->icanon && !tty->canon_data;
+       old_left = tty->receive_room;
+       tty->receive_room = left;
+
+       /* Did this open up the receive buffer? We may need to flip */
+       if (left && !old_left)
+               schedule_work(&tty->buf.work);
+}
+
 static void put_tty_queue_nolock(unsigned char c, struct tty_struct *tty)
 {
        if (tty->read_cnt < N_TTY_BUF_SIZE) {
@@ -152,6 +184,7 @@ static void reset_buffer_flags(struct tty_struct *tty)
 
        tty->canon_head = tty->canon_data = tty->erasing = 0;
        memset(&tty->read_flags, 0, sizeof tty->read_flags);
+       n_tty_set_room(tty);
        check_unthrottle(tty);
 }
 
@@ -1327,19 +1360,17 @@ static void n_tty_write_wakeup(struct tty_struct *tty)
  *     calls one at a time and in order (or using flush_to_ldisc)
  */
 
-static unsigned int n_tty_receive_buf(struct tty_struct *tty,
-               const unsigned char *cp, char *fp, int count)
+static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
+                             char *fp, int count)
 {
        const unsigned char *p;
        char *f, flags = TTY_NORMAL;
        int     i;
        char    buf[64];
        unsigned long cpuflags;
-       int left;
-       int ret = 0;
 
        if (!tty->read_buf)
-               return 0;
+               return;
 
        if (tty->real_raw) {
                spin_lock_irqsave(&tty->read_lock, cpuflags);
@@ -1349,7 +1380,6 @@ static unsigned int n_tty_receive_buf(struct tty_struct *tty,
                memcpy(tty->read_buf + tty->read_head, cp, i);
                tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1);
                tty->read_cnt += i;
-               ret += i;
                cp += i;
                count -= i;
 
@@ -1359,10 +1389,8 @@ static unsigned int n_tty_receive_buf(struct tty_struct *tty,
                memcpy(tty->read_buf + tty->read_head, cp, i);
                tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1);
                tty->read_cnt += i;
-               ret += i;
                spin_unlock_irqrestore(&tty->read_lock, cpuflags);
        } else {
-               ret = count;
                for (i = count, p = cp, f = fp; i; i--, p++) {
                        if (f)
                                flags = *f++;
@@ -1390,6 +1418,8 @@ static unsigned int n_tty_receive_buf(struct tty_struct *tty,
                        tty->ops->flush_chars(tty);
        }
 
+       n_tty_set_room(tty);
+
        if ((!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) ||
                L_EXTPROC(tty)) {
                kill_fasync(&tty->fasync, SIGIO, POLL_IN);
@@ -1402,12 +1432,8 @@ static unsigned int n_tty_receive_buf(struct tty_struct *tty,
         * mode.  We don't want to throttle the driver if we're in
         * canonical mode and don't have a newline yet!
         */
-       left = N_TTY_BUF_SIZE - tty->read_cnt - 1;
-
-       if (left < TTY_THRESHOLD_THROTTLE)
+       if (tty->receive_room < TTY_THRESHOLD_THROTTLE)
                tty_throttle(tty);
-
-       return ret;
 }
 
 int is_ignored(int sig)
@@ -1451,6 +1477,7 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
        if (test_bit(TTY_HW_COOK_IN, &tty->flags)) {
                tty->raw = 1;
                tty->real_raw = 1;
+               n_tty_set_room(tty);
                return;
        }
        if (I_ISTRIP(tty) || I_IUCLC(tty) || I_IGNCR(tty) ||
@@ -1503,6 +1530,7 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
                else
                        tty->real_raw = 0;
        }
+       n_tty_set_room(tty);
        /* The termios change make the tty ready for I/O */
        wake_up_interruptible(&tty->write_wait);
        wake_up_interruptible(&tty->read_wait);
@@ -1784,6 +1812,8 @@ do_it_again:
                                retval = -ERESTARTSYS;
                                break;
                        }
+                       /* FIXME: does n_tty_set_room need locking ? */
+                       n_tty_set_room(tty);
                        timeout = schedule_timeout(timeout);
                        continue;
                }
@@ -1855,8 +1885,10 @@ do_it_again:
                 * longer than TTY_THRESHOLD_UNTHROTTLE in canonical mode,
                 * we won't get any more characters.
                 */
-               if (n_tty_chars_in_buffer(tty) <= TTY_THRESHOLD_UNTHROTTLE)
+               if (n_tty_chars_in_buffer(tty) <= TTY_THRESHOLD_UNTHROTTLE) {
+                       n_tty_set_room(tty);
                        check_unthrottle(tty);
+               }
 
                if (b - buf >= minimum)
                        break;
@@ -1878,6 +1910,7 @@ do_it_again:
        } else if (test_and_clear_bit(TTY_PUSH, &tty->flags))
                 goto do_it_again;
 
+       n_tty_set_room(tty);
        return retval;
 }
 
index 46de2e075dacda019589cc5462a0d60f6eea8d51..6c9b7cd6778a9613542d739358f309a38fa56070 100644 (file)
@@ -413,10 +413,8 @@ static void flush_to_ldisc(struct work_struct *work)
        spin_lock_irqsave(&tty->buf.lock, flags);
 
        if (!test_and_set_bit(TTY_FLUSHING, &tty->flags)) {
-               struct tty_buffer *head, *tail = tty->buf.tail;
-               int seen_tail = 0;
+               struct tty_buffer *head;
                while ((head = tty->buf.head) != NULL) {
-                       int copied;
                        int count;
                        char *char_buf;
                        unsigned char *flag_buf;
@@ -425,15 +423,6 @@ static void flush_to_ldisc(struct work_struct *work)
                        if (!count) {
                                if (head->next == NULL)
                                        break;
-                               /*
-                                 There's a possibility tty might get new buffer
-                                 added during the unlock window below. We could
-                                 end up spinning in here forever hogging the CPU
-                                 completely. To avoid this let's have a rest each
-                                 time we processed the tail buffer.
-                               */
-                               if (tail == head)
-                                       seen_tail = 1;
                                tty->buf.head = head->next;
                                tty_buffer_free(tty, head);
                                continue;
@@ -443,19 +432,17 @@ static void flush_to_ldisc(struct work_struct *work)
                           line discipline as we want to empty the queue */
                        if (test_bit(TTY_FLUSHPENDING, &tty->flags))
                                break;
+                       if (!tty->receive_room)
+                               break;
+                       if (count > tty->receive_room)
+                               count = tty->receive_room;
                        char_buf = head->char_buf_ptr + head->read;
                        flag_buf = head->flag_buf_ptr + head->read;
+                       head->read += count;
                        spin_unlock_irqrestore(&tty->buf.lock, flags);
-                       copied = disc->ops->receive_buf(tty, char_buf,
+                       disc->ops->receive_buf(tty, char_buf,
                                                        flag_buf, count);
                        spin_lock_irqsave(&tty->buf.lock, flags);
-
-                       head->read += copied;
-
-                       if (copied == 0 || seen_tail) {
-                               schedule_work(&tty->buf.work);
-                               break;
-                       }
                }
                clear_bit(TTY_FLUSHING, &tty->flags);
        }
index 67b1d0d7c8acb924fdc481cfc75b36fa6c925de8..fb864e7fcd13f684e30108a02189f6b99c9315fc 100644 (file)
@@ -332,7 +332,8 @@ int paste_selection(struct tty_struct *tty)
                        continue;
                }
                count = sel_buffer_lth - pasted;
-               count = tty->ldisc->ops->receive_buf(tty, sel_buffer + pasted,
+               count = min(count, tty->receive_room);
+               tty->ldisc->ops->receive_buf(tty, sel_buffer + pasted,
                                                                NULL, count);
                pasted += count;
        }
index 395a347f2ebbea52d86b20cb97bec70548b6a34a..dac7676ce21bb6d9121d8fa4d178ea5cc0708438 100644 (file)
@@ -1530,6 +1530,8 @@ static const struct usb_device_id acm_ids[] = {
        { NOKIA_PCSUITE_ACM_INFO(0x04ce), }, /* Nokia E90 */
        { NOKIA_PCSUITE_ACM_INFO(0x01d4), }, /* Nokia E55 */
        { NOKIA_PCSUITE_ACM_INFO(0x0302), }, /* Nokia N8 */
+       { NOKIA_PCSUITE_ACM_INFO(0x0335), }, /* Nokia E7 */
+       { NOKIA_PCSUITE_ACM_INFO(0x03cd), }, /* Nokia C7 */
        { SAMSUNG_PCSUITE_ACM_INFO(0x6651), }, /* Samsung GTi8510 (INNOV8) */
 
        /* NOTE: non-Nokia COMM/ACM/0xff is likely MSFT RNDIS... NOT a modem! */
index 79a58c3a2e2a3a254b48a9f2fb7ac78c5c3bd27e..90ae1753dda16bab13f0cebb759d961fb5598cbc 100644 (file)
@@ -339,7 +339,8 @@ static int get_hub_status(struct usb_device *hdev,
 {
        int i, status = -ETIMEDOUT;
 
-       for (i = 0; i < USB_STS_RETRIES && status == -ETIMEDOUT; i++) {
+       for (i = 0; i < USB_STS_RETRIES &&
+                       (status == -ETIMEDOUT || status == -EPIPE); i++) {
                status = usb_control_msg(hdev, usb_rcvctrlpipe(hdev, 0),
                        USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_HUB, 0, 0,
                        data, sizeof(*data), USB_STS_TIMEOUT);
@@ -355,7 +356,8 @@ static int get_port_status(struct usb_device *hdev, int port1,
 {
        int i, status = -ETIMEDOUT;
 
-       for (i = 0; i < USB_STS_RETRIES && status == -ETIMEDOUT; i++) {
+       for (i = 0; i < USB_STS_RETRIES &&
+                       (status == -ETIMEDOUT || status == -EPIPE); i++) {
                status = usb_control_msg(hdev, usb_rcvctrlpipe(hdev, 0),
                        USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_PORT, 0, port1,
                        data, sizeof(*data), USB_STS_TIMEOUT);
index 1b125c224dcf8d4d73f5a094edb6f4417c8e88e4..2278dad886e2e8b028b2809eb39ccba8c09dff46 100644 (file)
@@ -389,7 +389,6 @@ static int usbfs_rmdir(struct inode *dir, struct dentry *dentry)
        mutex_unlock(&inode->i_mutex);
        if (!error)
                d_delete(dentry);
-       dput(dentry);
        return error;
 }
 
index 58456d1aec21611dcb395ef343ce80e4c9bc315e..029e288805b6c1ab1eeb99d6235093b0b4ee1058 100644 (file)
@@ -632,13 +632,10 @@ config USB_DUMMY_HCD
 
 endchoice
 
+# Selected by UDC drivers that support high-speed operation.
 config USB_GADGET_DUALSPEED
        bool
        depends on USB_GADGET
-       default n
-       help
-         Means that gadget drivers should include extra descriptors
-         and code to handle dual-speed controllers.
 
 #
 # USB Gadget Drivers
index 6e42aab75806e12c58e7b572e1dc953a13a32fa0..95e8138cd48fd9ff9be91f170777f562d3c88ede 100644 (file)
@@ -60,6 +60,7 @@
 #include <linux/device.h>
 #include <linux/io.h>
 #include <linux/irq.h>
+#include <linux/prefetch.h>
 
 #include <asm/byteorder.h>
 #include <asm/system.h>
index 41dc093c0a1b943fa44a69629dbd19e8cc5f098c..f4690ffcb4890af84e0ba88a82dd929e3e2fab82 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/clk.h>
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
+#include <linux/prefetch.h>
 
 #include <asm/byteorder.h>
 #include <mach/hardware.h>
index 61ff927928ab9620231eddce21056a4160488e5f..d3dcabc1a5fca0e7ad221236285d4064b69abd0d 100644 (file)
@@ -1906,6 +1906,7 @@ static int dummy_hcd_probe(struct platform_device *pdev)
        if (!hcd)
                return -ENOMEM;
        the_controller = hcd_to_dummy (hcd);
+       hcd->has_tt = 1;
 
        retval = usb_add_hcd(hcd, 0, 0);
        if (retval != 0) {
index a01383f71f38639c5539f5b82431ef1186ee6b60..a56876aaf76cdc1dfbec0a331f70739a2a27b04f 100644 (file)
@@ -431,8 +431,10 @@ ep_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
 
        /* halt any endpoint by doing a "wrong direction" i/o call */
        if (!usb_endpoint_dir_in(&data->desc)) {
-               if (usb_endpoint_xfer_isoc(&data->desc))
+               if (usb_endpoint_xfer_isoc(&data->desc)) {
+                       mutex_unlock(&data->lock);
                        return -EINVAL;
+               }
                DBG (data->dev, "%s halt\n", data->name);
                spin_lock_irq (&data->dev->lock);
                if (likely (data->ep != NULL))
index b62b2640deb0b7c9e6a0f9cf81f2c8242fdf37d1..b1a8146b9d50d4180ca762e9ab47c7f41899d736 100644 (file)
@@ -2083,7 +2083,7 @@ out:
 }
 
 #ifdef CONFIG_PM
-static int mv_udc_suspend(struct platform_device *_dev, pm_message_t state)
+static int mv_udc_suspend(struct device *_dev)
 {
        struct mv_udc *udc = the_controller;
 
@@ -2092,7 +2092,7 @@ static int mv_udc_suspend(struct platform_device *_dev, pm_message_t state)
        return 0;
 }
 
-static int mv_udc_resume(struct platform_device *_dev)
+static int mv_udc_resume(struct device *_dev)
 {
        struct mv_udc *udc = the_controller;
        int retval;
@@ -2100,7 +2100,7 @@ static int mv_udc_resume(struct platform_device *_dev)
        retval = mv_udc_phy_init(udc->phy_regs);
        if (retval) {
                dev_err(_dev, "phy initialization error %d\n", retval);
-               goto error;
+               return retval;
        }
        udc_reset(udc);
        ep0_reset(udc);
@@ -2122,7 +2122,7 @@ static struct platform_driver udc_driver = {
                .owner  = THIS_MODULE,
                .name   = "pxa-u2o",
 #ifdef CONFIG_PM
-               .pm     = mv_udc_pm_ops,
+               .pm     = &mv_udc_pm_ops,
 #endif
        },
 };
index 24696f7fa6a9a7a412c229f8667edd1895e1226d..476d88e1ae97daaaf67dd78b5e8565b9ff7d7e9e 100644 (file)
@@ -63,6 +63,7 @@
 #include <linux/device.h>
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
+#include <linux/prefetch.h>
 
 #include <asm/byteorder.h>
 #include <asm/io.h>
index 365c02fc25fcf0f89668b79ce2a72933ada22a40..774545494cf222ed8515474f48d5d346317c5619 100644 (file)
@@ -2216,7 +2216,6 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev)
                if (retval != 0) {
                        pr_err("%s: can't get irq %i, err %d\n",
                                driver_name, LUBBOCK_USB_DISC_IRQ, retval);
-lubbock_fail0:
                        goto err_irq_lub;
                }
                retval = request_irq(LUBBOCK_USB_IRQ,
@@ -2226,7 +2225,6 @@ lubbock_fail0:
                if (retval != 0) {
                        pr_err("%s: can't get irq %i, err %d\n",
                                driver_name, LUBBOCK_USB_IRQ, retval);
-                       free_irq(LUBBOCK_USB_DISC_IRQ, dev);
                        goto lubbock_fail0;
                }
        } else
@@ -2236,10 +2234,11 @@ lubbock_fail0:
        return 0;
 
 #ifdef CONFIG_ARCH_LUBBOCK
+lubbock_fail0:
        free_irq(LUBBOCK_USB_DISC_IRQ, dev);
  err_irq_lub:
-#endif
        free_irq(irq, dev);
+#endif
  err_irq1:
        if (gpio_is_valid(dev->mach->gpio_pullup))
                gpio_free(dev->mach->gpio_pullup);
index acb9cc418df9a59b4db4ee57bdcbe68144475d6e..0dfee282878a86ef70fdd9b03bb09c1cf9823108 100644 (file)
@@ -2680,9 +2680,9 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
 
        writel(0, hsotg->regs + S3C_DAINTMSK);
 
-       dev_info(hsotg->dev, "EP0: DIEPCTL0=0x%08x, DOEPCTL0=0x%08x\n",
-                readl(hsotg->regs + S3C_DIEPCTL0),
-                readl(hsotg->regs + S3C_DOEPCTL0));
+       dev_dbg(hsotg->dev, "EP0: DIEPCTL0=0x%08x, DOEPCTL0=0x%08x\n",
+               readl(hsotg->regs + S3C_DIEPCTL0),
+               readl(hsotg->regs + S3C_DOEPCTL0));
 
        /* enable in and out endpoint interrupts */
        s3c_hsotg_en_gsint(hsotg, S3C_GINTSTS_OEPInt | S3C_GINTSTS_IEPInt);
@@ -2701,7 +2701,7 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
        udelay(10);  /* see openiboot */
        __bic32(hsotg->regs + S3C_DCTL, S3C_DCTL_PWROnPrgDone);
 
-       dev_info(hsotg->dev, "DCTL=0x%08x\n", readl(hsotg->regs + S3C_DCTL));
+       dev_dbg(hsotg->dev, "DCTL=0x%08x\n", readl(hsotg->regs + S3C_DCTL));
 
        /* S3C_DxEPCTL_USBActEp says RO in manual, but seems to be set by
           writing to the EPCTL register.. */
@@ -2721,9 +2721,9 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
 
        s3c_hsotg_enqueue_setup(hsotg);
 
-       dev_info(hsotg->dev, "EP0: DIEPCTL0=0x%08x, DOEPCTL0=0x%08x\n",
-                readl(hsotg->regs + S3C_DIEPCTL0),
-                readl(hsotg->regs + S3C_DOEPCTL0));
+       dev_dbg(hsotg->dev, "EP0: DIEPCTL0=0x%08x, DOEPCTL0=0x%08x\n",
+               readl(hsotg->regs + S3C_DIEPCTL0),
+               readl(hsotg->regs + S3C_DOEPCTL0));
 
        /* clear global NAKs */
        writel(S3C_DCTL_CGOUTNak | S3C_DCTL_CGNPInNAK,
@@ -2921,9 +2921,9 @@ static void s3c_hsotg_init(struct s3c_hsotg *hsotg)
 
        /* setup fifos */
 
-       dev_info(hsotg->dev, "GRXFSIZ=0x%08x, GNPTXFSIZ=0x%08x\n",
-                readl(hsotg->regs + S3C_GRXFSIZ),
-                readl(hsotg->regs + S3C_GNPTXFSIZ));
+       dev_dbg(hsotg->dev, "GRXFSIZ=0x%08x, GNPTXFSIZ=0x%08x\n",
+               readl(hsotg->regs + S3C_GRXFSIZ),
+               readl(hsotg->regs + S3C_GNPTXFSIZ));
 
        s3c_hsotg_init_fifo(hsotg);
 
@@ -2945,6 +2945,7 @@ static void s3c_hsotg_init(struct s3c_hsotg *hsotg)
 
 static void s3c_hsotg_dump(struct s3c_hsotg *hsotg)
 {
+#ifdef DEBUG
        struct device *dev = hsotg->dev;
        void __iomem *regs = hsotg->regs;
        u32 val;
@@ -2987,6 +2988,7 @@ static void s3c_hsotg_dump(struct s3c_hsotg *hsotg)
 
        dev_info(dev, "DVBUSDIS=0x%08x, DVBUSPULSE=%08x\n",
                 readl(regs + S3C_DVBUSDIS), readl(regs + S3C_DVBUSPULSE));
+#endif
 }
 
 
index cfe3cf56d6bd5e531682f928b02023b6c863660e..d5e3e1e586265c093a1002664af6f55cebb883bd 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/clk.h>
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
+#include <linux/prefetch.h>
 
 #include <mach/regs-s3c2443-clock.h>
 #include <plat/udc.h>
@@ -1301,7 +1302,8 @@ static int s3c_hsudc_probe(struct platform_device *pdev)
        hsudc->uclk = clk_get(&pdev->dev, "usb-device");
        if (IS_ERR(hsudc->uclk)) {
                dev_err(dev, "failed to find usb-device clock source\n");
-               return PTR_ERR(hsudc->uclk);
+               ret = PTR_ERR(hsudc->uclk);
+               goto err_clk;
        }
        clk_enable(hsudc->uclk);
 
@@ -1310,7 +1312,8 @@ static int s3c_hsudc_probe(struct platform_device *pdev)
        disable_irq(hsudc->irq);
        local_irq_enable();
        return 0;
-
+err_clk:
+       free_irq(hsudc->irq, hsudc);
 err_irq:
        iounmap(hsudc->regs);
 
index 6d8b04061d5d6772f076c9792315a8ee8c42499d..100f2635cf0a1d2ee3ef0a175c685e6f35a2b213 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/platform_device.h>
 #include <linux/clk.h>
 #include <linux/gpio.h>
+#include <linux/prefetch.h>
 
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
index afef7b0a419567ab92643d0809a1da5f1a4f13a9..80be5472783a4f30e8a791a205958f176ff2dbf1 100644 (file)
@@ -312,8 +312,10 @@ int usb_hcd_pxa27x_probe (const struct hc_driver *driver, struct platform_device
                return PTR_ERR(usb_clk);
 
        hcd = usb_create_hcd (driver, &pdev->dev, "pxa27x");
-       if (!hcd)
-               return -ENOMEM;
+       if (!hcd) {
+               retval = -ENOMEM;
+               goto err0;
+       }
 
        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!r) {
@@ -368,6 +370,7 @@ int usb_hcd_pxa27x_probe (const struct hc_driver *driver, struct platform_device
        release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
  err1:
        usb_put_hcd(hcd);
+ err0:
        clk_put(usb_clk);
        return retval;
 }
index 2e0486178dbe4c45dd984eab0663bd3a2d97f392..1f50b4468e87bfe90f7b14b1327187a7395609f3 100644 (file)
@@ -438,13 +438,13 @@ char *xhci_get_slot_state(struct xhci_hcd *xhci,
        struct xhci_slot_ctx *slot_ctx = xhci_get_slot_ctx(xhci, ctx);
 
        switch (GET_SLOT_STATE(le32_to_cpu(slot_ctx->dev_state))) {
-       case 0:
+       case SLOT_STATE_ENABLED:
                return "enabled/disabled";
-       case 1:
+       case SLOT_STATE_DEFAULT:
                return "default";
-       case 2:
+       case SLOT_STATE_ADDRESSED:
                return "addressed";
-       case 3:
+       case SLOT_STATE_CONFIGURED:
                return "configured";
        default:
                return "reserved";
index 26caba4c1950a04dc71488d33fcca3328b7cb391..0f8e1d29a858e6c5e00e287a11f8ff1ba2b212e1 100644 (file)
@@ -985,9 +985,19 @@ static unsigned int xhci_parse_exponent_interval(struct usb_device *udev,
        interval = clamp_val(ep->desc.bInterval, 1, 16) - 1;
        if (interval != ep->desc.bInterval - 1)
                dev_warn(&udev->dev,
-                        "ep %#x - rounding interval to %d microframes\n",
+                        "ep %#x - rounding interval to %d %sframes\n",
                         ep->desc.bEndpointAddress,
-                        1 << interval);
+                        1 << interval,
+                        udev->speed == USB_SPEED_FULL ? "" : "micro");
+
+       if (udev->speed == USB_SPEED_FULL) {
+               /*
+                * Full speed isoc endpoints specify interval in frames,
+                * not microframes. We are using microframes everywhere,
+                * so adjust accordingly.
+                */
+               interval += 3;  /* 1 frame = 2^3 uframes */
+       }
 
        return interval;
 }
index c408e9f6a707a51f396b94554e3d07970d29fe84..17541d09eabbc9b867c5be1dcdeba349b45bfa82 100644 (file)
@@ -106,12 +106,22 @@ static int xhci_pci_setup(struct usb_hcd *hcd)
 
        /* Look for vendor-specific quirks */
        if (pdev->vendor == PCI_VENDOR_ID_FRESCO_LOGIC &&
-                       pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK &&
-                       pdev->revision == 0x0) {
+                       pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK) {
+               if (pdev->revision == 0x0) {
                        xhci->quirks |= XHCI_RESET_EP_QUIRK;
                        xhci_dbg(xhci, "QUIRK: Fresco Logic xHC needs configure"
                                        " endpoint cmd after reset endpoint\n");
+               }
+               /* Fresco Logic confirms: all revisions of this chip do not
+                * support MSI, even though some of them claim to in their PCI
+                * capabilities.
+                */
+               xhci->quirks |= XHCI_BROKEN_MSI;
+               xhci_dbg(xhci, "QUIRK: Fresco Logic revision %u "
+                               "has broken MSI implementation\n",
+                               pdev->revision);
        }
+
        if (pdev->vendor == PCI_VENDOR_ID_NEC)
                xhci->quirks |= XHCI_NEC_HOST;
 
index cc1485bfed385dc7df6b51a7de70500e453776ef..800f417c730900271a98ccf0410d7617afc3aa20 100644 (file)
@@ -1782,7 +1782,7 @@ static int skip_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td,
        struct usb_iso_packet_descriptor *frame;
        int idx;
 
-       ep_ring = xhci_dma_to_transfer_ring(ep, event->buffer);
+       ep_ring = xhci_dma_to_transfer_ring(ep, le64_to_cpu(event->buffer));
        urb_priv = td->urb->hcpriv;
        idx = urb_priv->td_cnt;
        frame = &td->urb->iso_frame_desc[idx];
index d9660eb97eb9a4ede02ff49111b46d71d4ac89bb..06e7023258d0f4e3e4b603d6c2ae68b1fbd38f4f 100644 (file)
@@ -430,12 +430,19 @@ int xhci_run(struct usb_hcd *hcd)
                free_irq(hcd->irq, hcd);
        hcd->irq = -1;
 
+       /* Some Fresco Logic host controllers advertise MSI, but fail to
+        * generate interrupts.  Don't even try to enable MSI.
+        */
+       if (xhci->quirks & XHCI_BROKEN_MSI)
+               goto legacy_irq;
+
        ret = xhci_setup_msix(xhci);
        if (ret)
                /* fall back to msi*/
                ret = xhci_setup_msi(xhci);
 
        if (ret) {
+legacy_irq:
                /* fall back to legacy interrupt*/
                ret = request_irq(pdev->irq, &usb_hcd_irq, IRQF_SHARED,
                                        hcd->irq_descr, hcd);
@@ -1849,8 +1856,8 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
 
        /* Free any rings that were dropped, but not changed. */
        for (i = 1; i < 31; ++i) {
-               if ((ctrl_ctx->drop_flags & (1 << (i + 1))) &&
-                               !(ctrl_ctx->add_flags & (1 << (i + 1))))
+               if ((le32_to_cpu(ctrl_ctx->drop_flags) & (1 << (i + 1))) &&
+                   !(le32_to_cpu(ctrl_ctx->add_flags) & (1 << (i + 1))))
                        xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i);
        }
        xhci_zero_in_ctx(xhci, virt_dev);
@@ -2467,6 +2474,7 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev)
        struct xhci_command *reset_device_cmd;
        int timeleft;
        int last_freed_endpoint;
+       struct xhci_slot_ctx *slot_ctx;
 
        ret = xhci_check_args(hcd, udev, NULL, 0, false, __func__);
        if (ret <= 0)
@@ -2499,6 +2507,12 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev)
                        return -EINVAL;
        }
 
+       /* If device is not setup, there is no point in resetting it */
+       slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->out_ctx);
+       if (GET_SLOT_STATE(le32_to_cpu(slot_ctx->dev_state)) ==
+                                               SLOT_STATE_DISABLED)
+               return 0;
+
        xhci_dbg(xhci, "Resetting device with slot ID %u\n", slot_id);
        /* Allocate the command structure that holds the struct completion.
         * Assume we're in process context, since the normal device reset
index ac0196e7fcf11dba0c1df87ffb24ea57cd6c379f..7d1ea3bf5e1fa0187210f6c89ad87a9f53f1f8e2 100644 (file)
@@ -560,6 +560,11 @@ struct xhci_slot_ctx {
 #define SLOT_STATE     (0x1f << 27)
 #define GET_SLOT_STATE(p)      (((p) & (0x1f << 27)) >> 27)
 
+#define SLOT_STATE_DISABLED    0
+#define SLOT_STATE_ENABLED     SLOT_STATE_DISABLED
+#define SLOT_STATE_DEFAULT     1
+#define SLOT_STATE_ADDRESSED   2
+#define SLOT_STATE_CONFIGURED  3
 
 /**
  * struct xhci_ep_ctx
@@ -1302,6 +1307,7 @@ struct xhci_hcd {
  * commands.
  */
 #define XHCI_EP_LIMIT_QUIRK    (1 << 5)
+#define XHCI_BROKEN_MSI                (1 << 6)
        unsigned int            num_active_eps;
        unsigned int            limit_active_eps;
        /* There are two roothubs to keep track of bus suspend info for */
index ab8e1001e5e288ae9fd06417567cc62b4d4897f5..c71b0372786e00482bf2f9fadf4bf6293721d27f 100644 (file)
@@ -96,6 +96,7 @@
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/kobject.h>
+#include <linux/prefetch.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
 
index 206cfabc92863e0d409e8c76a32bf3129883eeda..547486ccd0592d21a2b2a5ca8bf4480192ffaf73 100644 (file)
@@ -1380,5 +1380,6 @@ void __devexit usbhs_mod_gadget_remove(struct usbhs_priv *priv)
 {
        struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv);
 
+       kfree(gpriv->uep);
        kfree(gpriv);
 }
index e8dbde55f6c51553216b53b7d0c973ac2059c41e..1627289775538eaa2b1967e2547c54717c82baa3 100644 (file)
@@ -647,6 +647,7 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(FTDI_VID, EVER_ECO_PRO_CDS) },
        { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_1_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_2_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_3_PID) },
        { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_0_PID) },
        { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_1_PID) },
        { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_2_PID) },
index 1d946cd238ba2989da8bb197a3b0eb8c44f68570..ab1fcdf3c378e954882a8a7db9bc1e4cb672aed8 100644 (file)
  */
 #define FTDI_4N_GALAXY_DE_1_PID        0xF3C0
 #define FTDI_4N_GALAXY_DE_2_PID        0xF3C1
+#define FTDI_4N_GALAXY_DE_3_PID        0xF3C2
 
 /*
  * Linx Technologies product ids
index 318dd00040a3fdb28fbce657d7a3880d12ba505d..60b25d8ea0e2c14376ee4fad71d21a680f0502f7 100644 (file)
@@ -311,10 +311,6 @@ static void option_instat_callback(struct urb *urb);
 #define ZTE_PRODUCT_AC2726                     0xfff5
 #define ZTE_PRODUCT_AC8710T                    0xffff
 
-/* ZTE PRODUCTS -- alternate vendor ID */
-#define ZTE_VENDOR_ID2                         0x1d6b
-#define ZTE_PRODUCT_MF_330                     0x0002
-
 #define BENQ_VENDOR_ID                         0x04a5
 #define BENQ_PRODUCT_H10                       0x4068
 
@@ -340,11 +336,12 @@ static void option_instat_callback(struct urb *urb);
 #define TOSHIBA_PRODUCT_G450                   0x0d45
 
 #define ALINK_VENDOR_ID                                0x1e0e
+#define ALINK_PRODUCT_PH300                    0x9100
 #define ALINK_PRODUCT_3GU                      0x9200
 
 /* ALCATEL PRODUCTS */
 #define ALCATEL_VENDOR_ID                      0x1bbb
-#define ALCATEL_PRODUCT_X060S                  0x0000
+#define ALCATEL_PRODUCT_X060S_X200             0x0000
 
 #define PIRELLI_VENDOR_ID                      0x1266
 #define PIRELLI_PRODUCT_C100_1                 0x1002
@@ -379,6 +376,9 @@ static void option_instat_callback(struct urb *urb);
  * It seems to contain a Qualcomm QSC6240/6290 chipset            */
 #define FOUR_G_SYSTEMS_PRODUCT_W14             0x9603
 
+/* Zoom */
+#define ZOOM_PRODUCT_4597                      0x9607
+
 /* Haier products */
 #define HAIER_VENDOR_ID                                0x201e
 #define HAIER_PRODUCT_CE100                    0x2009
@@ -432,6 +432,20 @@ static const struct option_blacklist_info four_g_w14_blacklist = {
        .reason = OPTION_BLACKLIST_SENDSETUP
 };
 
+static const u8 alcatel_x200_no_sendsetup[] = { 0, 1 };
+static const struct option_blacklist_info alcatel_x200_blacklist = {
+       .infolen = ARRAY_SIZE(alcatel_x200_no_sendsetup),
+       .ifaceinfo = alcatel_x200_no_sendsetup,
+       .reason = OPTION_BLACKLIST_SENDSETUP
+};
+
+static const u8 zte_k3765_z_no_sendsetup[] = { 0, 1, 2 };
+static const struct option_blacklist_info zte_k3765_z_blacklist = {
+       .infolen = ARRAY_SIZE(zte_k3765_z_no_sendsetup),
+       .ifaceinfo = zte_k3765_z_no_sendsetup,
+       .reason = OPTION_BLACKLIST_SENDSETUP
+};
+
 static const struct usb_device_id option_ids[] = {
        { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
        { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
@@ -916,13 +930,13 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0073, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0130, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0141, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff,
+         0xff, 0xff), .driver_info = (kernel_ulong_t)&zte_k3765_z_blacklist },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2003, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710T, 0xff, 0xff, 0xff) },
-       { USB_DEVICE(ZTE_VENDOR_ID2, ZTE_PRODUCT_MF_330) },
        { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) },
        { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) },
        { USB_DEVICE(ALINK_VENDOR_ID, DLINK_PRODUCT_DWM_652_U5) }, /* Yes, ALINK_VENDOR_ID */
@@ -935,13 +949,17 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_G450) },
        { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_HSDPA_MINICARD ) }, /* Toshiba 3G HSDPA == Novatel Expedite EU870D MiniCard */
        { USB_DEVICE(ALINK_VENDOR_ID, 0x9000) },
+       { USB_DEVICE(ALINK_VENDOR_ID, ALINK_PRODUCT_PH300) },
        { USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) },
-       { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S) },
+       { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S_X200),
+         .driver_info = (kernel_ulong_t)&alcatel_x200_blacklist
+       },
        { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) },
        { USB_DEVICE(TLAYTECH_VENDOR_ID, TLAYTECH_PRODUCT_TEU800) },
        { USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14),
          .driver_info = (kernel_ulong_t)&four_g_w14_blacklist
        },
+       { USB_DEVICE(LONGCHEER_VENDOR_ID, ZOOM_PRODUCT_4597) },
        { USB_DEVICE(HAIER_VENDOR_ID, HAIER_PRODUCT_CE100) },
        /* Pirelli  */
        { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_C100_1)},
index 00418995d8e9e549c835ec209e1f1e5dbf7e5076..e8ae21b2d387c11a1a1038ae98855d9db1228dc1 100644 (file)
@@ -819,6 +819,35 @@ Retry_Sense:
                }
        }
 
+       /*
+        * Some devices don't work or return incorrect data the first
+        * time they get a READ(10) command, or for the first READ(10)
+        * after a media change.  If the INITIAL_READ10 flag is set,
+        * keep track of whether READ(10) commands succeed.  If the
+        * previous one succeeded and this one failed, set the REDO_READ10
+        * flag to force a retry.
+        */
+       if (unlikely((us->fflags & US_FL_INITIAL_READ10) &&
+                       srb->cmnd[0] == READ_10)) {
+               if (srb->result == SAM_STAT_GOOD) {
+                       set_bit(US_FLIDX_READ10_WORKED, &us->dflags);
+               } else if (test_bit(US_FLIDX_READ10_WORKED, &us->dflags)) {
+                       clear_bit(US_FLIDX_READ10_WORKED, &us->dflags);
+                       set_bit(US_FLIDX_REDO_READ10, &us->dflags);
+               }
+
+               /*
+                * Next, if the REDO_READ10 flag is set, return a result
+                * code that will cause the SCSI core to retry the READ(10)
+                * command immediately.
+                */
+               if (test_bit(US_FLIDX_REDO_READ10, &us->dflags)) {
+                       clear_bit(US_FLIDX_REDO_READ10, &us->dflags);
+                       srb->result = DID_IMM_RETRY << 16;
+                       srb->sense_buffer[0] = 0;
+               }
+       }
+
        /* Did we transfer less than the minimum amount required? */
        if ((srb->result == SAM_STAT_GOOD || srb->sense_buffer[2] == 0) &&
                        scsi_bufflen(srb) - scsi_get_resid(srb) < srb->underflow)
index c1602b8c55949e0b5c1e4a99042d1409f953008f..ccff3483eebc87d0c82a562cbffa3f5ab36ab878 100644 (file)
@@ -1114,6 +1114,16 @@ UNUSUAL_DEV( 0x090c, 0x1132, 0x0000, 0xffff,
                USB_SC_DEVICE, USB_PR_DEVICE, NULL,
                US_FL_FIX_CAPACITY ),
 
+/* Reported by Paul Hartman <paul.hartman+linux@gmail.com>
+ * This card reader returns "Illegal Request, Logical Block Address
+ * Out of Range" for the first READ(10) after a new card is inserted.
+ */
+UNUSUAL_DEV(  0x090c, 0x6000, 0x0100, 0x0100,
+               "Feiya",
+               "SD/SDHC Card Reader",
+               USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+               US_FL_INITIAL_READ10 ),
+
 /* This Pentax still camera is not conformant
  * to the USB storage specification: -
  * - It does not like the INQUIRY command. So we must handle this command
@@ -1888,6 +1898,15 @@ UNUSUAL_DEV( 0x1908, 0x3335, 0x0200, 0x0200,
                USB_SC_DEVICE, USB_PR_DEVICE, NULL,
                US_FL_NO_READ_DISC_INFO ),
 
+/* Reported by Sven Geggus <sven-usbst@geggus.net>
+ * This encrypted pen drive returns bogus data for the initial READ(10).
+ */
+UNUSUAL_DEV(  0x1b1c, 0x1ab5, 0x0200, 0x0200,
+               "Corsair",
+               "Padlock v2",
+               USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+               US_FL_INITIAL_READ10 ),
+
 /* Patch by Richard Schütz <r.schtz@t-online.de>
  * This external hard drive enclosure uses a JMicron chip which
  * needs the US_FL_IGNORE_RESIDUE flag to work properly. */
index 5ee7ac42e08f3bddb892109d07e99d6a216e2509..0ca095820f3e7ca10c98e27a4eaeea728e5c533e 100644 (file)
@@ -440,7 +440,8 @@ static void adjust_quirks(struct us_data *us)
                        US_FL_NOT_LOCKABLE | US_FL_MAX_SECTORS_64 |
                        US_FL_CAPACITY_OK | US_FL_IGNORE_RESIDUE |
                        US_FL_SINGLE_LUN | US_FL_NO_WP_DETECT |
-                       US_FL_NO_READ_DISC_INFO | US_FL_NO_READ_CAPACITY_16);
+                       US_FL_NO_READ_DISC_INFO | US_FL_NO_READ_CAPACITY_16 |
+                       US_FL_INITIAL_READ10);
 
        p = quirks;
        while (*p) {
@@ -490,6 +491,9 @@ static void adjust_quirks(struct us_data *us)
                case 'm':
                        f |= US_FL_MAX_SECTORS_64;
                        break;
+               case 'n':
+                       f |= US_FL_INITIAL_READ10;
+                       break;
                case 'o':
                        f |= US_FL_CAPACITY_OK;
                        break;
@@ -953,6 +957,13 @@ int usb_stor_probe2(struct us_data *us)
        if (result)
                goto BadDevice;
 
+       /*
+        * If the device returns invalid data for the first READ(10)
+        * command, indicate the command should be retried.
+        */
+       if (us->fflags & US_FL_INITIAL_READ10)
+               set_bit(US_FLIDX_REDO_READ10, &us->dflags);
+
        /* Acquire all the other resources and add the host */
        result = usb_stor_acquire_resources(us);
        if (result)
index 89d3bfff98df47d34b78b516aeaa19b101d572b5..7b0f2113632efb52ada464fc17dd83a74f34ea5a 100644 (file)
@@ -73,6 +73,8 @@ struct us_unusual_dev {
 #define US_FLIDX_RESETTING     4       /* device reset in progress */
 #define US_FLIDX_TIMED_OUT     5       /* SCSI midlayer timed out  */
 #define US_FLIDX_DONT_SCAN     6       /* don't scan (disconnect)  */
+#define US_FLIDX_REDO_READ10   7       /* redo READ(10) command    */
+#define US_FLIDX_READ10_WORKED 8       /* previous READ(10) succeeded */
 
 #define USB_STOR_STRING_LEN 32
 
index 2f7c76a85e532a658bf9652b0875887346ff374c..e224a92baa16c808b9f3d8c2baa4b449f210c214 100644 (file)
@@ -144,7 +144,7 @@ static void handle_tx(struct vhost_net *net)
        }
 
        mutex_lock(&vq->mutex);
-       vhost_disable_notify(vq);
+       vhost_disable_notify(&net->dev, vq);
 
        if (wmem < sock->sk->sk_sndbuf / 2)
                tx_poll_stop(net);
@@ -166,8 +166,8 @@ static void handle_tx(struct vhost_net *net)
                                set_bit(SOCK_ASYNC_NOSPACE, &sock->flags);
                                break;
                        }
-                       if (unlikely(vhost_enable_notify(vq))) {
-                               vhost_disable_notify(vq);
+                       if (unlikely(vhost_enable_notify(&net->dev, vq))) {
+                               vhost_disable_notify(&net->dev, vq);
                                continue;
                        }
                        break;
@@ -315,7 +315,7 @@ static void handle_rx(struct vhost_net *net)
                return;
 
        mutex_lock(&vq->mutex);
-       vhost_disable_notify(vq);
+       vhost_disable_notify(&net->dev, vq);
        vhost_hlen = vq->vhost_hlen;
        sock_hlen = vq->sock_hlen;
 
@@ -334,10 +334,10 @@ static void handle_rx(struct vhost_net *net)
                        break;
                /* OK, now we need to know about added descriptors. */
                if (!headcount) {
-                       if (unlikely(vhost_enable_notify(vq))) {
+                       if (unlikely(vhost_enable_notify(&net->dev, vq))) {
                                /* They have slipped one in as we were
                                 * doing that: check again. */
-                               vhost_disable_notify(vq);
+                               vhost_disable_notify(&net->dev, vq);
                                continue;
                        }
                        /* Nothing new?  Wait for eventfd to tell us
index 099f30230d0625a3d102da68c9236d9718993107..734e1d74ad805a1547ed867dd8363f09bcd9e2f8 100644 (file)
@@ -49,7 +49,7 @@ static void handle_vq(struct vhost_test *n)
                return;
 
        mutex_lock(&vq->mutex);
-       vhost_disable_notify(vq);
+       vhost_disable_notify(&n->dev, vq);
 
        for (;;) {
                head = vhost_get_vq_desc(&n->dev, vq, vq->iov,
@@ -61,8 +61,8 @@ static void handle_vq(struct vhost_test *n)
                        break;
                /* Nothing new?  Wait for eventfd to tell us they refilled. */
                if (head == vq->num) {
-                       if (unlikely(vhost_enable_notify(vq))) {
-                               vhost_disable_notify(vq);
+                       if (unlikely(vhost_enable_notify(&n->dev, vq))) {
+                               vhost_disable_notify(&n->dev, vq);
                                continue;
                        }
                        break;
index 7aa4eea930f1310077012eeab05a511bd1febdfe..ea966b356352084beaa9f491be2b57871c98482e 100644 (file)
@@ -37,6 +37,9 @@ enum {
        VHOST_MEMORY_F_LOG = 0x1,
 };
 
+#define vhost_used_event(vq) ((u16 __user *)&vq->avail->ring[vq->num])
+#define vhost_avail_event(vq) ((u16 __user *)&vq->used->ring[vq->num])
+
 static void vhost_poll_func(struct file *file, wait_queue_head_t *wqh,
                            poll_table *pt)
 {
@@ -161,6 +164,8 @@ static void vhost_vq_reset(struct vhost_dev *dev,
        vq->last_avail_idx = 0;
        vq->avail_idx = 0;
        vq->last_used_idx = 0;
+       vq->signalled_used = 0;
+       vq->signalled_used_valid = false;
        vq->used_flags = 0;
        vq->log_used = false;
        vq->log_addr = -1ull;
@@ -489,16 +494,17 @@ static int memory_access_ok(struct vhost_dev *d, struct vhost_memory *mem,
        return 1;
 }
 
-static int vq_access_ok(unsigned int num,
+static int vq_access_ok(struct vhost_dev *d, unsigned int num,
                        struct vring_desc __user *desc,
                        struct vring_avail __user *avail,
                        struct vring_used __user *used)
 {
+       size_t s = vhost_has_feature(d, VIRTIO_RING_F_EVENT_IDX) ? 2 : 0;
        return access_ok(VERIFY_READ, desc, num * sizeof *desc) &&
               access_ok(VERIFY_READ, avail,
-                        sizeof *avail + num * sizeof *avail->ring) &&
+                        sizeof *avail + num * sizeof *avail->ring + s) &&
               access_ok(VERIFY_WRITE, used,
-                       sizeof *used + num * sizeof *used->ring);
+                       sizeof *used + num * sizeof *used->ring + s);
 }
 
 /* Can we log writes? */
@@ -514,9 +520,11 @@ int vhost_log_access_ok(struct vhost_dev *dev)
 
 /* Verify access for write logging. */
 /* Caller should have vq mutex and device mutex */
-static int vq_log_access_ok(struct vhost_virtqueue *vq, void __user *log_base)
+static int vq_log_access_ok(struct vhost_dev *d, struct vhost_virtqueue *vq,
+                           void __user *log_base)
 {
        struct vhost_memory *mp;
+       size_t s = vhost_has_feature(d, VIRTIO_RING_F_EVENT_IDX) ? 2 : 0;
 
        mp = rcu_dereference_protected(vq->dev->memory,
                                       lockdep_is_held(&vq->mutex));
@@ -524,15 +532,15 @@ static int vq_log_access_ok(struct vhost_virtqueue *vq, void __user *log_base)
                            vhost_has_feature(vq->dev, VHOST_F_LOG_ALL)) &&
                (!vq->log_used || log_access_ok(log_base, vq->log_addr,
                                        sizeof *vq->used +
-                                       vq->num * sizeof *vq->used->ring));
+                                       vq->num * sizeof *vq->used->ring + s));
 }
 
 /* Can we start vq? */
 /* Caller should have vq mutex and device mutex */
 int vhost_vq_access_ok(struct vhost_virtqueue *vq)
 {
-       return vq_access_ok(vq->num, vq->desc, vq->avail, vq->used) &&
-               vq_log_access_ok(vq, vq->log_base);
+       return vq_access_ok(vq->dev, vq->num, vq->desc, vq->avail, vq->used) &&
+               vq_log_access_ok(vq->dev, vq, vq->log_base);
 }
 
 static long vhost_set_memory(struct vhost_dev *d, struct vhost_memory __user *m)
@@ -577,6 +585,7 @@ static int init_used(struct vhost_virtqueue *vq,
 
        if (r)
                return r;
+       vq->signalled_used_valid = false;
        return get_user(vq->last_used_idx, &used->idx);
 }
 
@@ -674,7 +683,7 @@ static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp)
                 * If it is not, we don't as size might not have been setup.
                 * We will verify when backend is configured. */
                if (vq->private_data) {
-                       if (!vq_access_ok(vq->num,
+                       if (!vq_access_ok(d, vq->num,
                                (void __user *)(unsigned long)a.desc_user_addr,
                                (void __user *)(unsigned long)a.avail_user_addr,
                                (void __user *)(unsigned long)a.used_user_addr)) {
@@ -818,7 +827,7 @@ long vhost_dev_ioctl(struct vhost_dev *d, unsigned int ioctl, unsigned long arg)
                        vq = d->vqs + i;
                        mutex_lock(&vq->mutex);
                        /* If ring is inactive, will check when it's enabled. */
-                       if (vq->private_data && !vq_log_access_ok(vq, base))
+                       if (vq->private_data && !vq_log_access_ok(d, vq, base))
                                r = -EFAULT;
                        else
                                vq->log_base = base;
@@ -1219,6 +1228,10 @@ int vhost_get_vq_desc(struct vhost_dev *dev, struct vhost_virtqueue *vq,
 
        /* On success, increment avail index. */
        vq->last_avail_idx++;
+
+       /* Assume notifications from guest are disabled at this point,
+        * if they aren't we would need to update avail_event index. */
+       BUG_ON(!(vq->used_flags & VRING_USED_F_NO_NOTIFY));
        return head;
 }
 
@@ -1267,6 +1280,12 @@ int vhost_add_used(struct vhost_virtqueue *vq, unsigned int head, int len)
                        eventfd_signal(vq->log_ctx, 1);
        }
        vq->last_used_idx++;
+       /* If the driver never bothers to signal in a very long while,
+        * used index might wrap around. If that happens, invalidate
+        * signalled_used index we stored. TODO: make sure driver
+        * signals at least once in 2^16 and remove this. */
+       if (unlikely(vq->last_used_idx == vq->signalled_used))
+               vq->signalled_used_valid = false;
        return 0;
 }
 
@@ -1275,6 +1294,7 @@ static int __vhost_add_used_n(struct vhost_virtqueue *vq,
                            unsigned count)
 {
        struct vring_used_elem __user *used;
+       u16 old, new;
        int start;
 
        start = vq->last_used_idx % vq->num;
@@ -1292,7 +1312,14 @@ static int __vhost_add_used_n(struct vhost_virtqueue *vq,
                           ((void __user *)used - (void __user *)vq->used),
                          count * sizeof *used);
        }
-       vq->last_used_idx += count;
+       old = vq->last_used_idx;
+       new = (vq->last_used_idx += count);
+       /* If the driver never bothers to signal in a very long while,
+        * used index might wrap around. If that happens, invalidate
+        * signalled_used index we stored. TODO: make sure driver
+        * signals at least once in 2^16 and remove this. */
+       if (unlikely((u16)(new - vq->signalled_used) < (u16)(new - old)))
+               vq->signalled_used_valid = false;
        return 0;
 }
 
@@ -1331,29 +1358,47 @@ int vhost_add_used_n(struct vhost_virtqueue *vq, struct vring_used_elem *heads,
        return r;
 }
 
-/* This actually signals the guest, using eventfd. */
-void vhost_signal(struct vhost_dev *dev, struct vhost_virtqueue *vq)
+static bool vhost_notify(struct vhost_dev *dev, struct vhost_virtqueue *vq)
 {
-       __u16 flags;
-
+       __u16 old, new, event;
+       bool v;
        /* Flush out used index updates. This is paired
         * with the barrier that the Guest executes when enabling
         * interrupts. */
        smp_mb();
 
-       if (__get_user(flags, &vq->avail->flags)) {
-               vq_err(vq, "Failed to get flags");
-               return;
+       if (vhost_has_feature(dev, VIRTIO_F_NOTIFY_ON_EMPTY) &&
+           unlikely(vq->avail_idx == vq->last_avail_idx))
+               return true;
+
+       if (!vhost_has_feature(dev, VIRTIO_RING_F_EVENT_IDX)) {
+               __u16 flags;
+               if (__get_user(flags, &vq->avail->flags)) {
+                       vq_err(vq, "Failed to get flags");
+                       return true;
+               }
+               return !(flags & VRING_AVAIL_F_NO_INTERRUPT);
        }
+       old = vq->signalled_used;
+       v = vq->signalled_used_valid;
+       new = vq->signalled_used = vq->last_used_idx;
+       vq->signalled_used_valid = true;
 
-       /* If they don't want an interrupt, don't signal, unless empty. */
-       if ((flags & VRING_AVAIL_F_NO_INTERRUPT) &&
-           (vq->avail_idx != vq->last_avail_idx ||
-            !vhost_has_feature(dev, VIRTIO_F_NOTIFY_ON_EMPTY)))
-               return;
+       if (unlikely(!v))
+               return true;
 
+       if (get_user(event, vhost_used_event(vq))) {
+               vq_err(vq, "Failed to get used event idx");
+               return true;
+       }
+       return vring_need_event(event, new, old);
+}
+
+/* This actually signals the guest, using eventfd. */
+void vhost_signal(struct vhost_dev *dev, struct vhost_virtqueue *vq)
+{
        /* Signal the Guest tell them we used something up. */
-       if (vq->call_ctx)
+       if (vq->call_ctx && vhost_notify(dev, vq))
                eventfd_signal(vq->call_ctx, 1);
 }
 
@@ -1376,7 +1421,7 @@ void vhost_add_used_and_signal_n(struct vhost_dev *dev,
 }
 
 /* OK, now we need to know about added descriptors. */
-bool vhost_enable_notify(struct vhost_virtqueue *vq)
+bool vhost_enable_notify(struct vhost_dev *dev, struct vhost_virtqueue *vq)
 {
        u16 avail_idx;
        int r;
@@ -1384,11 +1429,34 @@ bool vhost_enable_notify(struct vhost_virtqueue *vq)
        if (!(vq->used_flags & VRING_USED_F_NO_NOTIFY))
                return false;
        vq->used_flags &= ~VRING_USED_F_NO_NOTIFY;
-       r = put_user(vq->used_flags, &vq->used->flags);
-       if (r) {
-               vq_err(vq, "Failed to enable notification at %p: %d\n",
-                      &vq->used->flags, r);
-               return false;
+       if (!vhost_has_feature(dev, VIRTIO_RING_F_EVENT_IDX)) {
+               r = put_user(vq->used_flags, &vq->used->flags);
+               if (r) {
+                       vq_err(vq, "Failed to enable notification at %p: %d\n",
+                              &vq->used->flags, r);
+                       return false;
+               }
+       } else {
+               r = put_user(vq->avail_idx, vhost_avail_event(vq));
+               if (r) {
+                       vq_err(vq, "Failed to update avail event index at %p: %d\n",
+                              vhost_avail_event(vq), r);
+                       return false;
+               }
+       }
+       if (unlikely(vq->log_used)) {
+               void __user *used;
+               /* Make sure data is seen before log. */
+               smp_wmb();
+               used = vhost_has_feature(dev, VIRTIO_RING_F_EVENT_IDX) ?
+                       &vq->used->flags : vhost_avail_event(vq);
+               /* Log used flags or event index entry write. Both are 16 bit
+                * fields. */
+               log_write(vq->log_base, vq->log_addr +
+                          (used - (void __user *)vq->used),
+                         sizeof(u16));
+               if (vq->log_ctx)
+                       eventfd_signal(vq->log_ctx, 1);
        }
        /* They could have slipped one in as we were doing that: make
         * sure it's written, then check again. */
@@ -1404,15 +1472,17 @@ bool vhost_enable_notify(struct vhost_virtqueue *vq)
 }
 
 /* We don't need to be notified again. */
-void vhost_disable_notify(struct vhost_virtqueue *vq)
+void vhost_disable_notify(struct vhost_dev *dev, struct vhost_virtqueue *vq)
 {
        int r;
 
        if (vq->used_flags & VRING_USED_F_NO_NOTIFY)
                return;
        vq->used_flags |= VRING_USED_F_NO_NOTIFY;
-       r = put_user(vq->used_flags, &vq->used->flags);
-       if (r)
-               vq_err(vq, "Failed to enable notification at %p: %d\n",
-                      &vq->used->flags, r);
+       if (!vhost_has_feature(dev, VIRTIO_RING_F_EVENT_IDX)) {
+               r = put_user(vq->used_flags, &vq->used->flags);
+               if (r)
+                       vq_err(vq, "Failed to enable notification at %p: %d\n",
+                              &vq->used->flags, r);
+       }
 }
index b3363ae38518c56fad4de8b862918e54a3320b27..8e03379dd30f3abbe9ecabdbe5db8b6adc879d4e 100644 (file)
@@ -84,6 +84,12 @@ struct vhost_virtqueue {
        /* Used flags */
        u16 used_flags;
 
+       /* Last used index value we have signalled on */
+       u16 signalled_used;
+
+       /* Last used index value we have signalled on */
+       bool signalled_used_valid;
+
        /* Log writes to used structure. */
        bool log_used;
        u64 log_addr;
@@ -149,8 +155,8 @@ void vhost_add_used_and_signal(struct vhost_dev *, struct vhost_virtqueue *,
 void vhost_add_used_and_signal_n(struct vhost_dev *, struct vhost_virtqueue *,
                               struct vring_used_elem *heads, unsigned count);
 void vhost_signal(struct vhost_dev *, struct vhost_virtqueue *);
-void vhost_disable_notify(struct vhost_virtqueue *);
-bool vhost_enable_notify(struct vhost_virtqueue *);
+void vhost_disable_notify(struct vhost_dev *, struct vhost_virtqueue *);
+bool vhost_enable_notify(struct vhost_dev *, struct vhost_virtqueue *);
 
 int vhost_log_write(struct vhost_virtqueue *vq, struct vhost_log *log,
                    unsigned int log_num, u64 len);
@@ -162,11 +168,12 @@ int vhost_log_write(struct vhost_virtqueue *vq, struct vhost_log *log,
        } while (0)
 
 enum {
-       VHOST_FEATURES = (1 << VIRTIO_F_NOTIFY_ON_EMPTY) |
-                        (1 << VIRTIO_RING_F_INDIRECT_DESC) |
-                        (1 << VHOST_F_LOG_ALL) |
-                        (1 << VHOST_NET_F_VIRTIO_NET_HDR) |
-                        (1 << VIRTIO_NET_F_MRG_RXBUF),
+       VHOST_FEATURES = (1ULL << VIRTIO_F_NOTIFY_ON_EMPTY) |
+                        (1ULL << VIRTIO_RING_F_INDIRECT_DESC) |
+                        (1ULL << VIRTIO_RING_F_EVENT_IDX) |
+                        (1ULL << VHOST_F_LOG_ALL) |
+                        (1ULL << VHOST_NET_F_VIRTIO_NET_HDR) |
+                        (1ULL << VIRTIO_NET_F_MRG_RXBUF),
 };
 
 static inline int vhost_has_feature(struct vhost_dev *dev, int bit)
index 3ec4923c2d84e875eb27bc1119c1765ea7e73989..c22e8d39a2cb1371ff88bc6840cacbbbc8123c37 100644 (file)
@@ -515,11 +515,10 @@ static int __devinit arcfb_probe(struct platform_device *dev)
 
        /* We need a flat backing store for the Arc's
           less-flat actual paged framebuffer */
-       if (!(videomemory = vmalloc(videomemorysize)))
+       videomemory = vzalloc(videomemorysize);
+       if (!videomemory)
                return retval;
 
-       memset(videomemory, 0, videomemorysize);
-
        info = framebuffer_alloc(sizeof(struct arcfb_par), &dev->dev);
        if (!info)
                goto err;
index 47c21fb2c82fc50b2ac1329c30c1055b96874391..bea53c1a4950143d149a6694334dc8606f37fdd0 100644 (file)
@@ -789,6 +789,7 @@ static int __devinit bfin_lq035_probe(struct platform_device *pdev)
        i2c_add_driver(&ad5280_driver);
 
        memset(&props, 0, sizeof(props));
+       props.type = BACKLIGHT_RAW;
        props.max_brightness = MAX_BRIGHENESS;
        bl_dev = backlight_device_register("bf537-bl", NULL, NULL,
                                           &bfin_lq035fb_bl_ops, &props);
index ebda6876d3a9efe26c2883ac7e73f8fad020c4fc..377dde3d5bfc8954aaccfc643b9664408e0c9da1 100644 (file)
@@ -1101,12 +1101,10 @@ static int __devinit broadsheetfb_probe(struct platform_device *dev)
 
        videomemorysize = roundup((dpyw*dpyh), PAGE_SIZE);
 
-       videomemory = vmalloc(videomemorysize);
+       videomemory = vzalloc(videomemorysize);
        if (!videomemory)
                goto err_fb_rel;
 
-       memset(videomemory, 0, videomemorysize);
-
        info->screen_base = (char *)videomemory;
        info->fbops = &broadsheetfb_ops;
 
index fb205843c2c726da59b7f5f20c0c338ddba005d6..69c49dfce9cf93aa3c771dbf4af91f0669fea260 100644 (file)
@@ -16,6 +16,8 @@
 #include <linux/pci.h>
 #include <video/vga.h>
 
+static bool request_mem_succeeded = false;
+
 static struct fb_var_screeninfo efifb_defined __devinitdata = {
        .activate               = FB_ACTIVATE_NOW,
        .height                 = -1,
@@ -281,7 +283,9 @@ static void efifb_destroy(struct fb_info *info)
 {
        if (info->screen_base)
                iounmap(info->screen_base);
-       release_mem_region(info->apertures->ranges[0].base, info->apertures->ranges[0].size);
+       if (request_mem_succeeded)
+               release_mem_region(info->apertures->ranges[0].base,
+                                  info->apertures->ranges[0].size);
        framebuffer_release(info);
 }
 
@@ -326,14 +330,13 @@ static int __init efifb_setup(char *options)
        return 0;
 }
 
-static int __devinit efifb_probe(struct platform_device *dev)
+static int __init efifb_probe(struct platform_device *dev)
 {
        struct fb_info *info;
        int err;
        unsigned int size_vmode;
        unsigned int size_remap;
        unsigned int size_total;
-       int request_succeeded = 0;
 
        if (!screen_info.lfb_depth)
                screen_info.lfb_depth = 32;
@@ -387,7 +390,7 @@ static int __devinit efifb_probe(struct platform_device *dev)
        efifb_fix.smem_len = size_remap;
 
        if (request_mem_region(efifb_fix.smem_start, size_remap, "efifb")) {
-               request_succeeded = 1;
+               request_mem_succeeded = true;
        } else {
                /* We cannot make this fatal. Sometimes this comes from magic
                   spaces our resource handlers simply don't know about */
@@ -413,7 +416,7 @@ static int __devinit efifb_probe(struct platform_device *dev)
        info->apertures->ranges[0].base = efifb_fix.smem_start;
        info->apertures->ranges[0].size = size_remap;
 
-       info->screen_base = ioremap(efifb_fix.smem_start, efifb_fix.smem_len);
+       info->screen_base = ioremap_wc(efifb_fix.smem_start, efifb_fix.smem_len);
        if (!info->screen_base) {
                printk(KERN_ERR "efifb: abort, cannot ioremap video memory "
                                "0x%x @ 0x%lx\n",
@@ -491,13 +494,12 @@ err_unmap:
 err_release_fb:
        framebuffer_release(info);
 err_release_mem:
-       if (request_succeeded)
+       if (request_mem_succeeded)
                release_mem_region(efifb_fix.smem_start, size_total);
        return err;
 }
 
 static struct platform_driver efifb_driver = {
-       .probe  = efifb_probe,
        .driver = {
                .name   = "efifb",
        },
@@ -528,13 +530,21 @@ static int __init efifb_init(void)
        if (!screen_info.lfb_linelength)
                return -ENODEV;
 
-       ret = platform_driver_register(&efifb_driver);
+       ret = platform_device_register(&efifb_device);
+       if (ret)
+               return ret;
 
-       if (!ret) {
-               ret = platform_device_register(&efifb_device);
-               if (ret)
-                       platform_driver_unregister(&efifb_driver);
+       /*
+        * This is not just an optimization.  We will interfere
+        * with a real driver if we get reprobed, so don't allow
+        * it.
+        */
+       ret = platform_driver_probe(&efifb_driver, efifb_probe);
+       if (ret) {
+               platform_device_unregister(&efifb_driver);
+               return ret;
        }
+
        return ret;
 }
 module_init(efifb_init);
index 1b94643ecbcfff4dd63eca7b52953ba2f702f21e..fbef15f7a21803051e778b89436cd08c2f0f0561 100644 (file)
@@ -231,11 +231,10 @@ static int __devinit hecubafb_probe(struct platform_device *dev)
 
        videomemorysize = (DPY_W*DPY_H)/8;
 
-       if (!(videomemory = vmalloc(videomemorysize)))
+       videomemory = vzalloc(videomemorysize);
+       if (!videomemory)
                return retval;
 
-       memset(videomemory, 0, videomemorysize);
-
        info = framebuffer_alloc(sizeof(struct hecubafb_par), &dev->dev);
        if (!info)
                goto err_fballoc;
index d2ccfd6e662cbe1fda2da5d766750e21793ebc4c..f135dbead07d8921068de3513dafb2c32ea10973 100644 (file)
@@ -856,10 +856,10 @@ failed_platform_init:
                dma_free_writecombine(&pdev->dev,fbi->map_size,fbi->map_cpu,
                        fbi->map_dma);
 failed_map:
-       clk_put(fbi->clk);
-failed_getclock:
        iounmap(fbi->regs);
 failed_ioremap:
+       clk_put(fbi->clk);
+failed_getclock:
        release_mem_region(res->start, resource_size(res));
 failed_req:
        kfree(info->pseudo_palette);
index ed64edfd2c43b7a97e693ff30b6e26972caaf7f7..97d45e5115e254647454d7c5b7598053944c7273 100644 (file)
@@ -628,12 +628,10 @@ static int __devinit metronomefb_probe(struct platform_device *dev)
        /* we need to add a spare page because our csum caching scheme walks
         * to the end of the page */
        videomemorysize = PAGE_SIZE + (fw * fh);
-       videomemory = vmalloc(videomemorysize);
+       videomemory = vzalloc(videomemorysize);
        if (!videomemory)
                goto err_fb_rel;
 
-       memset(videomemory, 0, videomemorysize);
-
        info->screen_base = (char __force __iomem *)videomemory;
        info->fbops = &metronomefb_ops;
 
index 48c3ea8652b66e0b7862a392c5d4a04b4df95f32..cb175fe7abc0829f65d7aeb3c54082bb80a8999a 100644 (file)
@@ -1128,3 +1128,4 @@ EXPORT_SYMBOL(fb_find_best_mode);
 EXPORT_SYMBOL(fb_find_nearest_mode);
 EXPORT_SYMBOL(fb_videomode_to_modelist);
 EXPORT_SYMBOL(fb_find_mode);
+EXPORT_SYMBOL(fb_find_mode_cvt);
index 35f61dd0cb3a43f5a9e3f70ac0dc5a07136a91b1..bb95ec56d25d9943aef4150595c0f190c9bb0cbc 100644 (file)
@@ -623,19 +623,21 @@ static int __devinit pxa168fb_probe(struct platform_device *pdev)
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (res == NULL) {
                dev_err(&pdev->dev, "no IO memory defined\n");
-               return -ENOENT;
+               ret = -ENOENT;
+               goto failed_put_clk;
        }
 
        irq = platform_get_irq(pdev, 0);
        if (irq < 0) {
                dev_err(&pdev->dev, "no IRQ defined\n");
-               return -ENOENT;
+               ret = -ENOENT;
+               goto failed_put_clk;
        }
 
        info = framebuffer_alloc(sizeof(struct pxa168fb_info), &pdev->dev);
        if (info == NULL) {
-               clk_put(clk);
-               return -ENOMEM;
+               ret = -ENOMEM;
+               goto failed_put_clk;
        }
 
        /* Initialize private data */
@@ -671,7 +673,7 @@ static int __devinit pxa168fb_probe(struct platform_device *pdev)
        fbi->reg_base = ioremap_nocache(res->start, resource_size(res));
        if (fbi->reg_base == NULL) {
                ret = -ENOMEM;
-               goto failed;
+               goto failed_free_info;
        }
 
        /*
@@ -683,7 +685,7 @@ static int __devinit pxa168fb_probe(struct platform_device *pdev)
                                                &fbi->fb_start_dma, GFP_KERNEL);
        if (info->screen_base == NULL) {
                ret = -ENOMEM;
-               goto failed;
+               goto failed_free_info;
        }
 
        info->fix.smem_start = (unsigned long)fbi->fb_start_dma;
@@ -772,8 +774,9 @@ failed_free_clk:
 failed_free_fbmem:
        dma_free_coherent(fbi->dev, info->fix.smem_len,
                        info->screen_base, fbi->fb_start_dma);
-failed:
+failed_free_info:
        kfree(info);
+failed_put_clk:
        clk_put(clk);
 
        dev_err(&pdev->dev, "frame buffer device init failed with %d\n", ret);
index 3b7f2f5bae71dc78b98bf8e4d7befd1b75c05bba..4de541ca9c52c14d38cb95762ba86034e71d59fd 100644 (file)
@@ -2237,6 +2237,22 @@ static int __devinit savagefb_probe(struct pci_dev* dev,
                                 &info->modelist);
 #endif
        info->var = savagefb_var800x600x8;
+       /* if a panel was detected, default to a CVT mode instead */
+       if (par->SavagePanelWidth) {
+               struct fb_videomode cvt_mode;
+
+               memset(&cvt_mode, 0, sizeof(cvt_mode));
+               cvt_mode.xres = par->SavagePanelWidth;
+               cvt_mode.yres = par->SavagePanelHeight;
+               cvt_mode.refresh = 60;
+               /* FIXME: if we know there is only the panel
+                * we can enable reduced blanking as well */
+               if (fb_find_mode_cvt(&cvt_mode, 0, 0))
+                       printk(KERN_WARNING "No CVT mode found for panel\n");
+               else if (fb_find_mode(&info->var, info, NULL, NULL, 0,
+                                     &cvt_mode, 0) != 3)
+                       info->var = savagefb_var800x600x8;
+       }
 
        if (mode_option) {
                fb_find_mode(&info->var, info, mode_option,
index 404c03b4b7c7c4e570646a3fb4461e8a70a8855f..019dbd3f12b247d3fec1fb4836dd8f36cf5a3819 100644 (file)
@@ -470,7 +470,7 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
        unsigned long tmp;
        int bpp = 0;
        unsigned long ldddsr;
-       int k, m;
+       int k, m, ret;
 
        /* enable clocks before accessing the hardware */
        for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
@@ -540,7 +540,7 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
 
                board_cfg = &ch->cfg.board_cfg;
                if (board_cfg->setup_sys) {
-                       int ret = board_cfg->setup_sys(board_cfg->board_data,
+                       ret = board_cfg->setup_sys(board_cfg->board_data,
                                                ch, &sh_mobile_lcdc_sys_bus_ops);
                        if (ret)
                                return ret;
index 53b2c5aae06791becfea4721a3d0ad702e24f109..305c975b1787ea0628d600d2ac89c89cd0afdee9 100644 (file)
@@ -1265,9 +1265,11 @@ static void vga16fb_imageblit(struct fb_info *info, const struct fb_image *image
 
 static void vga16fb_destroy(struct fb_info *info)
 {
+       struct platform_device *dev = container_of(info->device, struct platform_device, dev);
        iounmap(info->screen_base);
        fb_dealloc_cmap(&info->cmap);
        /* XXX unshare VGA regions */
+       platform_set_drvdata(dev, NULL);
        framebuffer_release(info);
 }
 
index a20218c2fda8be0a98b4a219bff743db2a0b5018..beac52fc1c0eea6c1cadf337983c3b2b5c78614d 100644 (file)
@@ -395,10 +395,9 @@ static int __devinit xenfb_probe(struct xenbus_device *dev,
        spin_lock_init(&info->dirty_lock);
        spin_lock_init(&info->resize_lock);
 
-       info->fb = vmalloc(fb_size);
+       info->fb = vzalloc(fb_size);
        if (info->fb == NULL)
                goto error_nomem;
-       memset(info->fb, 0, fb_size);
 
        info->nr_pages = (fb_size + PAGE_SIZE - 1) >> PAGE_SHIFT;
 
index 0f1da45ba47dd8a917c38a797beca69a00f0a67c..e058ace2a4ad4af69b6ec198ad01fbe8f07362f8 100644 (file)
@@ -40,9 +40,6 @@ struct virtio_balloon
        /* Waiting for host to ack the pages we released. */
        struct completion acked;
 
-       /* Do we have to tell Host *before* we reuse pages? */
-       bool tell_host_first;
-
        /* The pages we've told the Host we're not using. */
        unsigned int num_pages;
        struct list_head pages;
@@ -151,13 +148,14 @@ static void leak_balloon(struct virtio_balloon *vb, size_t num)
                vb->num_pages--;
        }
 
-       if (vb->tell_host_first) {
-               tell_host(vb, vb->deflate_vq);
-               release_pages_by_pfn(vb->pfns, vb->num_pfns);
-       } else {
-               release_pages_by_pfn(vb->pfns, vb->num_pfns);
-               tell_host(vb, vb->deflate_vq);
-       }
+
+       /*
+        * Note that if
+        * virtio_has_feature(vdev, VIRTIO_BALLOON_F_MUST_TELL_HOST);
+        * is true, we *have* to do it in this order
+        */
+       tell_host(vb, vb->deflate_vq);
+       release_pages_by_pfn(vb->pfns, vb->num_pfns);
 }
 
 static inline void update_stat(struct virtio_balloon *vb, int idx,
@@ -325,9 +323,6 @@ static int virtballoon_probe(struct virtio_device *vdev)
                goto out_del_vqs;
        }
 
-       vb->tell_host_first
-               = virtio_has_feature(vdev, VIRTIO_BALLOON_F_MUST_TELL_HOST);
-
        return 0;
 
 out_del_vqs:
index b0043fb26a4d5dd8fcc9a2b7b66a18b3b44053b0..68b9136847afb65687a426a0c16e6cca6760caf8 100644 (file)
@@ -82,6 +82,9 @@ struct vring_virtqueue
        /* Host supports indirect buffers */
        bool indirect;
 
+       /* Host publishes avail event idx */
+       bool event;
+
        /* Number of free buffers */
        unsigned int num_free;
        /* Head of free buffer list. */
@@ -237,18 +240,22 @@ EXPORT_SYMBOL_GPL(virtqueue_add_buf_gfp);
 void virtqueue_kick(struct virtqueue *_vq)
 {
        struct vring_virtqueue *vq = to_vvq(_vq);
+       u16 new, old;
        START_USE(vq);
        /* Descriptors and available array need to be set before we expose the
         * new available array entries. */
        virtio_wmb();
 
-       vq->vring.avail->idx += vq->num_added;
+       old = vq->vring.avail->idx;
+       new = vq->vring.avail->idx = old + vq->num_added;
        vq->num_added = 0;
 
        /* Need to update avail index before checking if we should notify */
        virtio_mb();
 
-       if (!(vq->vring.used->flags & VRING_USED_F_NO_NOTIFY))
+       if (vq->event ?
+           vring_need_event(vring_avail_event(&vq->vring), new, old) :
+           !(vq->vring.used->flags & VRING_USED_F_NO_NOTIFY))
                /* Prod other side to tell it about changes. */
                vq->notify(&vq->vq);
 
@@ -324,6 +331,14 @@ void *virtqueue_get_buf(struct virtqueue *_vq, unsigned int *len)
        ret = vq->data[i];
        detach_buf(vq, i);
        vq->last_used_idx++;
+       /* If we expect an interrupt for the next entry, tell host
+        * by writing event index and flush out the write before
+        * the read in the next get_buf call. */
+       if (!(vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT)) {
+               vring_used_event(&vq->vring) = vq->last_used_idx;
+               virtio_mb();
+       }
+
        END_USE(vq);
        return ret;
 }
@@ -345,7 +360,11 @@ bool virtqueue_enable_cb(struct virtqueue *_vq)
 
        /* We optimistically turn back on interrupts, then check if there was
         * more to do. */
+       /* Depending on the VIRTIO_RING_F_EVENT_IDX feature, we need to
+        * either clear the flags bit or point the event index at the next
+        * entry. Always do both to keep code simple. */
        vq->vring.avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT;
+       vring_used_event(&vq->vring) = vq->last_used_idx;
        virtio_mb();
        if (unlikely(more_used(vq))) {
                END_USE(vq);
@@ -357,6 +376,33 @@ bool virtqueue_enable_cb(struct virtqueue *_vq)
 }
 EXPORT_SYMBOL_GPL(virtqueue_enable_cb);
 
+bool virtqueue_enable_cb_delayed(struct virtqueue *_vq)
+{
+       struct vring_virtqueue *vq = to_vvq(_vq);
+       u16 bufs;
+
+       START_USE(vq);
+
+       /* We optimistically turn back on interrupts, then check if there was
+        * more to do. */
+       /* Depending on the VIRTIO_RING_F_USED_EVENT_IDX feature, we need to
+        * either clear the flags bit or point the event index at the next
+        * entry. Always do both to keep code simple. */
+       vq->vring.avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT;
+       /* TODO: tune this threshold */
+       bufs = (u16)(vq->vring.avail->idx - vq->last_used_idx) * 3 / 4;
+       vring_used_event(&vq->vring) = vq->last_used_idx + bufs;
+       virtio_mb();
+       if (unlikely((u16)(vq->vring.used->idx - vq->last_used_idx) > bufs)) {
+               END_USE(vq);
+               return false;
+       }
+
+       END_USE(vq);
+       return true;
+}
+EXPORT_SYMBOL_GPL(virtqueue_enable_cb_delayed);
+
 void *virtqueue_detach_unused_buf(struct virtqueue *_vq)
 {
        struct vring_virtqueue *vq = to_vvq(_vq);
@@ -438,6 +484,7 @@ struct virtqueue *vring_new_virtqueue(unsigned int num,
 #endif
 
        vq->indirect = virtio_has_feature(vdev, VIRTIO_RING_F_INDIRECT_DESC);
+       vq->event = virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX);
 
        /* No callback?  Tell other side not to bother us. */
        if (!callback)
@@ -472,6 +519,8 @@ void vring_transport_features(struct virtio_device *vdev)
                switch (i) {
                case VIRTIO_RING_F_INDIRECT_DESC:
                        break;
+               case VIRTIO_RING_F_EVENT_IDX:
+                       break;
                default:
                        /* We don't understand this bit. */
                        clear_bit(i, vdev->features);
index 3ff822b481454847487b2c3eeaaa18d354f33721..553da68bd510c8ef0c7fecc2f5676778d6525954 100644 (file)
@@ -626,6 +626,9 @@ int xen_allocate_pirq_gsi(unsigned gsi)
  *
  * Note: We don't assign an event channel until the irq actually started
  * up.  Return an existing irq if we've already got one for the gsi.
+ *
+ * Shareable implies level triggered, not shareable implies edge
+ * triggered here.
  */
 int xen_bind_pirq_gsi_to_irq(unsigned gsi,
                             unsigned pirq, int shareable, char *name)
@@ -664,16 +667,13 @@ int xen_bind_pirq_gsi_to_irq(unsigned gsi,
 
        pirq_query_unmask(irq);
        /* We try to use the handler with the appropriate semantic for the
-        * type of interrupt: if the interrupt doesn't need an eoi
-        * (pirq_needs_eoi returns false), we treat it like an edge
-        * triggered interrupt so we use handle_edge_irq.
-        * As a matter of fact this only happens when the corresponding
-        * physical interrupt is edge triggered or an msi.
+        * type of interrupt: if the interrupt is an edge triggered
+        * interrupt we use handle_edge_irq.
         *
-        * On the other hand if the interrupt needs an eoi (pirq_needs_eoi
-        * returns true) we treat it like a level triggered interrupt so we
-        * use handle_fasteoi_irq like the native code does for this kind of
+        * On the other hand if the interrupt is level triggered we use
+        * handle_fasteoi_irq like the native code does for this kind of
         * interrupts.
+        *
         * Depending on the Xen version, pirq_needs_eoi might return true
         * not only for level triggered interrupts but for edge triggered
         * interrupts too. In any case Xen always honors the eoi mechanism,
@@ -681,7 +681,7 @@ int xen_bind_pirq_gsi_to_irq(unsigned gsi,
         * hasn't received an eoi yet. Therefore using the fasteoi handler
         * is the right choice either way.
         */
-       if (pirq_needs_eoi(irq))
+       if (shareable)
                irq_set_chip_and_handler_name(irq, &xen_pirq_chip,
                                handle_fasteoi_irq, name);
        else
index 87d95a8cddbc4223c77e9aa642292b784912b807..f55ae23b137e2a21001948e1c4b6b17795abc1b0 100644 (file)
@@ -583,8 +583,6 @@ static int autofs4_dir_unlink(struct inode *dir, struct dentry *dentry)
        if (!autofs4_oz_mode(sbi) && !capable(CAP_SYS_ADMIN))
                return -EACCES;
 
-       dentry_unhash(dentry);
-
        if (atomic_dec_and_test(&ino->count)) {
                p_ino = autofs4_dentry_ino(dentry->d_parent);
                if (p_ino && dentry->d_parent != dentry)
index 1f2b1997833340fc4e80b0c5a3c115a7f949fd15..1a2421f908f0a471f028d7e0f320caeed18592bd 100644 (file)
@@ -1272,8 +1272,8 @@ int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder)
                 * individual writeable reference is too fragile given the
                 * way @mode is used in blkdev_get/put().
                 */
-               if ((disk->flags & GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE) &&
-                   !res && (mode & FMODE_WRITE) && !bdev->bd_write_holder) {
+               if (!res && (mode & FMODE_WRITE) && !bdev->bd_write_holder &&
+                   (disk->flags & GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE)) {
                        bdev->bd_write_holder = true;
                        disk_block_events(disk);
                }
index 93b1aa9320143e921a31dde1d0586529ce75ea8e..52d7eca8c7bfe9d599e60cd0918b36c7f5fefe42 100644 (file)
@@ -121,9 +121,6 @@ struct btrfs_inode {
         */
        u64 index_cnt;
 
-       /* the start of block group preferred for allocations. */
-       u64 block_group;
-
        /* the fsync log has some corner cases that mean we have to check
         * directories to see if any unlinks have been done before
         * the directory was logged.  See tree-log.c for all the
index b0e18d986e0ac37f432dbad1141aea714d34f6a0..d84089349c82c15d1801787f62cf97c4ed469119 100644 (file)
@@ -43,8 +43,6 @@ struct btrfs_path *btrfs_alloc_path(void)
 {
        struct btrfs_path *path;
        path = kmem_cache_zalloc(btrfs_path_cachep, GFP_NOFS);
-       if (path)
-               path->reada = 1;
        return path;
 }
 
@@ -1224,6 +1222,7 @@ static void reada_for_search(struct btrfs_root *root,
        u64 search;
        u64 target;
        u64 nread = 0;
+       u64 gen;
        int direction = path->reada;
        struct extent_buffer *eb;
        u32 nr;
@@ -1251,6 +1250,15 @@ static void reada_for_search(struct btrfs_root *root,
        nritems = btrfs_header_nritems(node);
        nr = slot;
        while (1) {
+               if (!node->map_token) {
+                       unsigned long offset = btrfs_node_key_ptr_offset(nr);
+                       map_private_extent_buffer(node, offset,
+                                                 sizeof(struct btrfs_key_ptr),
+                                                 &node->map_token,
+                                                 &node->kaddr,
+                                                 &node->map_start,
+                                                 &node->map_len, KM_USER1);
+               }
                if (direction < 0) {
                        if (nr == 0)
                                break;
@@ -1268,14 +1276,23 @@ static void reada_for_search(struct btrfs_root *root,
                search = btrfs_node_blockptr(node, nr);
                if ((search <= target && target - search <= 65536) ||
                    (search > target && search - target <= 65536)) {
-                       readahead_tree_block(root, search, blocksize,
-                                    btrfs_node_ptr_generation(node, nr));
+                       gen = btrfs_node_ptr_generation(node, nr);
+                       if (node->map_token) {
+                               unmap_extent_buffer(node, node->map_token,
+                                                   KM_USER1);
+                               node->map_token = NULL;
+                       }
+                       readahead_tree_block(root, search, blocksize, gen);
                        nread += blocksize;
                }
                nscan++;
                if ((nread > 65536 || nscan > 32))
                        break;
        }
+       if (node->map_token) {
+               unmap_extent_buffer(node, node->map_token, KM_USER1);
+               node->map_token = NULL;
+       }
 }
 
 /*
@@ -1648,9 +1665,6 @@ again:
                }
 cow_done:
                BUG_ON(!cow && ins_len);
-               if (level != btrfs_header_level(b))
-                       WARN_ON(1);
-               level = btrfs_header_level(b);
 
                p->nodes[level] = b;
                if (!p->skip_locking)
index 6c093fa98f61f45f4d98344fab0e52de088a8aa2..378b5b4443f3a6991e1313d4009b89160d16539e 100644 (file)
@@ -930,7 +930,6 @@ struct btrfs_fs_info {
         * is required instead of the faster short fsync log commits
         */
        u64 last_trans_log_full_commit;
-       u64 open_ioctl_trans;
        unsigned long mount_opt:20;
        unsigned long compress_type:4;
        u64 max_inline;
@@ -947,7 +946,6 @@ struct btrfs_fs_info {
        struct super_block *sb;
        struct inode *btree_inode;
        struct backing_dev_info bdi;
-       struct mutex trans_mutex;
        struct mutex tree_log_mutex;
        struct mutex transaction_kthread_mutex;
        struct mutex cleaner_mutex;
@@ -968,6 +966,7 @@ struct btrfs_fs_info {
        struct rw_semaphore subvol_sem;
        struct srcu_struct subvol_srcu;
 
+       spinlock_t trans_lock;
        struct list_head trans_list;
        struct list_head hashers;
        struct list_head dead_roots;
@@ -980,6 +979,7 @@ struct btrfs_fs_info {
        atomic_t async_submit_draining;
        atomic_t nr_async_bios;
        atomic_t async_delalloc_pages;
+       atomic_t open_ioctl_trans;
 
        /*
         * this is used by the balancing code to wait for all the pending
@@ -1044,6 +1044,7 @@ struct btrfs_fs_info {
        int closing;
        int log_root_recovering;
        int enospc_unlink;
+       int trans_no_join;
 
        u64 total_pinned;
 
@@ -1065,7 +1066,6 @@ struct btrfs_fs_info {
        struct reloc_control *reloc_ctl;
 
        spinlock_t delalloc_lock;
-       spinlock_t new_trans_lock;
        u64 delalloc_bytes;
 
        /* data_alloc_cluster is only used in ssd mode */
@@ -1340,6 +1340,7 @@ struct btrfs_ioctl_defrag_range_args {
 #define BTRFS_MOUNT_USER_SUBVOL_RM_ALLOWED (1 << 14)
 #define BTRFS_MOUNT_ENOSPC_DEBUG        (1 << 15)
 #define BTRFS_MOUNT_AUTO_DEFRAG                (1 << 16)
+#define BTRFS_MOUNT_INODE_MAP_CACHE    (1 << 17)
 
 #define btrfs_clear_opt(o, opt)                ((o) &= ~BTRFS_MOUNT_##opt)
 #define btrfs_set_opt(o, opt)          ((o) |= BTRFS_MOUNT_##opt)
@@ -2238,6 +2239,9 @@ int btrfs_block_rsv_migrate(struct btrfs_block_rsv *src_rsv,
 void btrfs_block_rsv_release(struct btrfs_root *root,
                             struct btrfs_block_rsv *block_rsv,
                             u64 num_bytes);
+int btrfs_truncate_reserve_metadata(struct btrfs_trans_handle *trans,
+                                   struct btrfs_root *root,
+                                   struct btrfs_block_rsv *rsv);
 int btrfs_set_block_group_ro(struct btrfs_root *root,
                             struct btrfs_block_group_cache *cache);
 int btrfs_set_block_group_rw(struct btrfs_root *root,
@@ -2350,6 +2354,15 @@ int btrfs_drop_subtree(struct btrfs_trans_handle *trans,
                        struct btrfs_root *root,
                        struct extent_buffer *node,
                        struct extent_buffer *parent);
+static inline int btrfs_fs_closing(struct btrfs_fs_info *fs_info)
+{
+       /*
+        * Get synced with close_ctree()
+        */
+       smp_mb();
+       return fs_info->closing;
+}
+
 /* root-item.c */
 int btrfs_find_root_ref(struct btrfs_root *tree_root,
                        struct btrfs_path *path,
@@ -2512,8 +2525,7 @@ int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end,
 int btrfs_writepages(struct address_space *mapping,
                     struct writeback_control *wbc);
 int btrfs_create_subvol_root(struct btrfs_trans_handle *trans,
-                            struct btrfs_root *new_root,
-                            u64 new_dirid, u64 alloc_hint);
+                            struct btrfs_root *new_root, u64 new_dirid);
 int btrfs_merge_bio_hook(struct page *page, unsigned long offset,
                         size_t size, struct bio *bio, unsigned long bio_flags);
 
index 01e29503a54bd0aae2a972ba04284b94afcb8489..6462c29d2d37fcc8ec779f1d6d3b6817003a68c2 100644 (file)
@@ -678,6 +678,7 @@ static int btrfs_batch_insert_items(struct btrfs_trans_handle *trans,
        INIT_LIST_HEAD(&head);
 
        next = item;
+       nitems = 0;
 
        /*
         * count the number of the continuous items that we can insert in batch
@@ -1129,7 +1130,7 @@ static void btrfs_async_run_delayed_node_done(struct btrfs_work *work)
        delayed_node = async_node->delayed_node;
        root = delayed_node->root;
 
-       trans = btrfs_join_transaction(root, 0);
+       trans = btrfs_join_transaction(root);
        if (IS_ERR(trans))
                goto free_path;
 
@@ -1572,8 +1573,7 @@ static void fill_stack_inode_item(struct btrfs_trans_handle *trans,
        btrfs_set_stack_inode_transid(inode_item, trans->transid);
        btrfs_set_stack_inode_rdev(inode_item, inode->i_rdev);
        btrfs_set_stack_inode_flags(inode_item, BTRFS_I(inode)->flags);
-       btrfs_set_stack_inode_block_group(inode_item,
-                                         BTRFS_I(inode)->block_group);
+       btrfs_set_stack_inode_block_group(inode_item, 0);
 
        btrfs_set_stack_timespec_sec(btrfs_inode_atime(inode_item),
                                     inode->i_atime.tv_sec);
@@ -1595,7 +1595,7 @@ int btrfs_delayed_update_inode(struct btrfs_trans_handle *trans,
                               struct btrfs_root *root, struct inode *inode)
 {
        struct btrfs_delayed_node *delayed_node;
-       int ret;
+       int ret = 0;
 
        delayed_node = btrfs_get_or_create_delayed_node(inode);
        if (IS_ERR(delayed_node))
index 98b6a71decba105616ef5727b07b18c6d79dd8e0..a203d363184de575e4dcd9506c0feffb4807ab7c 100644 (file)
@@ -1505,24 +1505,24 @@ static int transaction_kthread(void *arg)
                vfs_check_frozen(root->fs_info->sb, SB_FREEZE_WRITE);
                mutex_lock(&root->fs_info->transaction_kthread_mutex);
 
-               spin_lock(&root->fs_info->new_trans_lock);
+               spin_lock(&root->fs_info->trans_lock);
                cur = root->fs_info->running_transaction;
                if (!cur) {
-                       spin_unlock(&root->fs_info->new_trans_lock);
+                       spin_unlock(&root->fs_info->trans_lock);
                        goto sleep;
                }
 
                now = get_seconds();
                if (!cur->blocked &&
                    (now < cur->start_time || now - cur->start_time < 30)) {
-                       spin_unlock(&root->fs_info->new_trans_lock);
+                       spin_unlock(&root->fs_info->trans_lock);
                        delay = HZ * 5;
                        goto sleep;
                }
                transid = cur->transid;
-               spin_unlock(&root->fs_info->new_trans_lock);
+               spin_unlock(&root->fs_info->trans_lock);
 
-               trans = btrfs_join_transaction(root, 1);
+               trans = btrfs_join_transaction(root);
                BUG_ON(IS_ERR(trans));
                if (transid == trans->transid) {
                        ret = btrfs_commit_transaction(trans, root);
@@ -1613,7 +1613,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
        INIT_LIST_HEAD(&fs_info->ordered_operations);
        INIT_LIST_HEAD(&fs_info->caching_block_groups);
        spin_lock_init(&fs_info->delalloc_lock);
-       spin_lock_init(&fs_info->new_trans_lock);
+       spin_lock_init(&fs_info->trans_lock);
        spin_lock_init(&fs_info->ref_cache_lock);
        spin_lock_init(&fs_info->fs_roots_radix_lock);
        spin_lock_init(&fs_info->delayed_iput_lock);
@@ -1645,6 +1645,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
        fs_info->max_inline = 8192 * 1024;
        fs_info->metadata_ratio = 0;
        fs_info->defrag_inodes = RB_ROOT;
+       fs_info->trans_no_join = 0;
 
        fs_info->thread_pool_size = min_t(unsigned long,
                                          num_online_cpus() + 2, 8);
@@ -1709,7 +1710,6 @@ struct btrfs_root *open_ctree(struct super_block *sb,
        fs_info->do_barriers = 1;
 
 
-       mutex_init(&fs_info->trans_mutex);
        mutex_init(&fs_info->ordered_operations_mutex);
        mutex_init(&fs_info->tree_log_mutex);
        mutex_init(&fs_info->chunk_mutex);
@@ -2479,13 +2479,13 @@ int btrfs_commit_super(struct btrfs_root *root)
        down_write(&root->fs_info->cleanup_work_sem);
        up_write(&root->fs_info->cleanup_work_sem);
 
-       trans = btrfs_join_transaction(root, 1);
+       trans = btrfs_join_transaction(root);
        if (IS_ERR(trans))
                return PTR_ERR(trans);
        ret = btrfs_commit_transaction(trans, root);
        BUG_ON(ret);
        /* run commit again to drop the original snapshot */
-       trans = btrfs_join_transaction(root, 1);
+       trans = btrfs_join_transaction(root);
        if (IS_ERR(trans))
                return PTR_ERR(trans);
        btrfs_commit_transaction(trans, root);
@@ -3024,10 +3024,13 @@ static int btrfs_cleanup_transaction(struct btrfs_root *root)
 
        WARN_ON(1);
 
-       mutex_lock(&root->fs_info->trans_mutex);
        mutex_lock(&root->fs_info->transaction_kthread_mutex);
 
+       spin_lock(&root->fs_info->trans_lock);
        list_splice_init(&root->fs_info->trans_list, &list);
+       root->fs_info->trans_no_join = 1;
+       spin_unlock(&root->fs_info->trans_lock);
+
        while (!list_empty(&list)) {
                t = list_entry(list.next, struct btrfs_transaction, list);
                if (!t)
@@ -3052,23 +3055,18 @@ static int btrfs_cleanup_transaction(struct btrfs_root *root)
                t->blocked = 0;
                if (waitqueue_active(&root->fs_info->transaction_wait))
                        wake_up(&root->fs_info->transaction_wait);
-               mutex_unlock(&root->fs_info->trans_mutex);
 
-               mutex_lock(&root->fs_info->trans_mutex);
                t->commit_done = 1;
                if (waitqueue_active(&t->commit_wait))
                        wake_up(&t->commit_wait);
-               mutex_unlock(&root->fs_info->trans_mutex);
-
-               mutex_lock(&root->fs_info->trans_mutex);
 
                btrfs_destroy_pending_snapshots(t);
 
                btrfs_destroy_delalloc_inodes(root);
 
-               spin_lock(&root->fs_info->new_trans_lock);
+               spin_lock(&root->fs_info->trans_lock);
                root->fs_info->running_transaction = NULL;
-               spin_unlock(&root->fs_info->new_trans_lock);
+               spin_unlock(&root->fs_info->trans_lock);
 
                btrfs_destroy_marked_extents(root, &t->dirty_pages,
                                             EXTENT_DIRTY);
@@ -3082,8 +3080,10 @@ static int btrfs_cleanup_transaction(struct btrfs_root *root)
                kmem_cache_free(btrfs_transaction_cachep, t);
        }
 
+       spin_lock(&root->fs_info->trans_lock);
+       root->fs_info->trans_no_join = 0;
+       spin_unlock(&root->fs_info->trans_lock);
        mutex_unlock(&root->fs_info->transaction_kthread_mutex);
-       mutex_unlock(&root->fs_info->trans_mutex);
 
        return 0;
 }
index 169bd62ce776257e72badbb2f16f4dbb1d0eaa56..5b9b6b6df242a67a4f38a14533d33e3643f4d836 100644 (file)
@@ -348,7 +348,7 @@ static int caching_kthread(void *data)
         */
        path->skip_locking = 1;
        path->search_commit_root = 1;
-       path->reada = 2;
+       path->reada = 1;
 
        key.objectid = last;
        key.offset = 0;
@@ -366,8 +366,7 @@ again:
        nritems = btrfs_header_nritems(leaf);
 
        while (1) {
-               smp_mb();
-               if (fs_info->closing > 1) {
+               if (btrfs_fs_closing(fs_info) > 1) {
                        last = (u64)-1;
                        break;
                }
@@ -379,15 +378,18 @@ again:
                        if (ret)
                                break;
 
-                       caching_ctl->progress = last;
-                       btrfs_release_path(path);
-                       up_read(&fs_info->extent_commit_sem);
-                       mutex_unlock(&caching_ctl->mutex);
-                       if (btrfs_transaction_in_commit(fs_info))
-                               schedule_timeout(1);
-                       else
+                       if (need_resched() ||
+                           btrfs_next_leaf(extent_root, path)) {
+                               caching_ctl->progress = last;
+                               btrfs_release_path(path);
+                               up_read(&fs_info->extent_commit_sem);
+                               mutex_unlock(&caching_ctl->mutex);
                                cond_resched();
-                       goto again;
+                               goto again;
+                       }
+                       leaf = path->nodes[0];
+                       nritems = btrfs_header_nritems(leaf);
+                       continue;
                }
 
                if (key.objectid < block_group->key.objectid) {
@@ -3065,7 +3067,7 @@ again:
                        spin_unlock(&data_sinfo->lock);
 alloc:
                        alloc_target = btrfs_get_alloc_profile(root, 1);
-                       trans = btrfs_join_transaction(root, 1);
+                       trans = btrfs_join_transaction(root);
                        if (IS_ERR(trans))
                                return PTR_ERR(trans);
 
@@ -3091,9 +3093,10 @@ alloc:
 
                /* commit the current transaction and try again */
 commit_trans:
-               if (!committed && !root->fs_info->open_ioctl_trans) {
+               if (!committed &&
+                   !atomic_read(&root->fs_info->open_ioctl_trans)) {
                        committed = 1;
-                       trans = btrfs_join_transaction(root, 1);
+                       trans = btrfs_join_transaction(root);
                        if (IS_ERR(trans))
                                return PTR_ERR(trans);
                        ret = btrfs_commit_transaction(trans, root);
@@ -3472,7 +3475,7 @@ again:
                goto out;
 
        ret = -ENOSPC;
-       trans = btrfs_join_transaction(root, 1);
+       trans = btrfs_join_transaction(root);
        if (IS_ERR(trans))
                goto out;
        ret = btrfs_commit_transaction(trans, root);
@@ -3699,7 +3702,7 @@ int btrfs_block_rsv_check(struct btrfs_trans_handle *trans,
                if (trans)
                        return -EAGAIN;
 
-               trans = btrfs_join_transaction(root, 1);
+               trans = btrfs_join_transaction(root);
                BUG_ON(IS_ERR(trans));
                ret = btrfs_commit_transaction(trans, root);
                return 0;
@@ -3837,6 +3840,37 @@ static void release_global_block_rsv(struct btrfs_fs_info *fs_info)
        WARN_ON(fs_info->chunk_block_rsv.reserved > 0);
 }
 
+int btrfs_truncate_reserve_metadata(struct btrfs_trans_handle *trans,
+                                   struct btrfs_root *root,
+                                   struct btrfs_block_rsv *rsv)
+{
+       struct btrfs_block_rsv *trans_rsv = &root->fs_info->trans_block_rsv;
+       u64 num_bytes;
+       int ret;
+
+       /*
+        * Truncate should be freeing data, but give us 2 items just in case it
+        * needs to use some space.  We may want to be smarter about this in the
+        * future.
+        */
+       num_bytes = btrfs_calc_trans_metadata_size(root, 2);
+
+       /* We already have enough bytes, just return */
+       if (rsv->reserved >= num_bytes)
+               return 0;
+
+       num_bytes -= rsv->reserved;
+
+       /*
+        * You should have reserved enough space before hand to do this, so this
+        * should not fail.
+        */
+       ret = block_rsv_migrate_bytes(trans_rsv, rsv, num_bytes);
+       BUG_ON(ret);
+
+       return 0;
+}
+
 int btrfs_trans_reserve_metadata(struct btrfs_trans_handle *trans,
                                 struct btrfs_root *root,
                                 int num_items)
@@ -3877,23 +3911,18 @@ int btrfs_orphan_reserve_metadata(struct btrfs_trans_handle *trans,
        struct btrfs_block_rsv *dst_rsv = root->orphan_block_rsv;
 
        /*
-        * one for deleting orphan item, one for updating inode and
-        * two for calling btrfs_truncate_inode_items.
-        *
-        * btrfs_truncate_inode_items is a delete operation, it frees
-        * more space than it uses in most cases. So two units of
-        * metadata space should be enough for calling it many times.
-        * If all of the metadata space is used, we can commit
-        * transaction and use space it freed.
+        * We need to hold space in order to delete our orphan item once we've
+        * added it, so this takes the reservation so we can release it later
+        * when we are truly done with the orphan item.
         */
-       u64 num_bytes = btrfs_calc_trans_metadata_size(root, 4);
+       u64 num_bytes = btrfs_calc_trans_metadata_size(root, 1);
        return block_rsv_migrate_bytes(src_rsv, dst_rsv, num_bytes);
 }
 
 void btrfs_orphan_release_metadata(struct inode *inode)
 {
        struct btrfs_root *root = BTRFS_I(inode)->root;
-       u64 num_bytes = btrfs_calc_trans_metadata_size(root, 4);
+       u64 num_bytes = btrfs_calc_trans_metadata_size(root, 1);
        btrfs_block_rsv_release(root, root->orphan_block_rsv, num_bytes);
 }
 
@@ -4987,6 +5016,15 @@ have_block_group:
                if (unlikely(block_group->ro))
                        goto loop;
 
+               spin_lock(&block_group->free_space_ctl->tree_lock);
+               if (cached &&
+                   block_group->free_space_ctl->free_space <
+                   num_bytes + empty_size) {
+                       spin_unlock(&block_group->free_space_ctl->tree_lock);
+                       goto loop;
+               }
+               spin_unlock(&block_group->free_space_ctl->tree_lock);
+
                /*
                 * Ok we want to try and use the cluster allocator, so lets look
                 * there, unless we are on LOOP_NO_EMPTY_SIZE, since we will
@@ -5150,6 +5188,7 @@ checks:
                        btrfs_add_free_space(block_group, offset,
                                             search_start - offset);
                BUG_ON(offset > search_start);
+               btrfs_put_block_group(block_group);
                break;
 loop:
                failed_cluster_refill = false;
@@ -5242,14 +5281,7 @@ loop:
                ret = -ENOSPC;
        } else if (!ins->objectid) {
                ret = -ENOSPC;
-       }
-
-       /* we found what we needed */
-       if (ins->objectid) {
-               if (!(data & BTRFS_BLOCK_GROUP_DATA))
-                       trans->block_group = block_group->key.objectid;
-
-               btrfs_put_block_group(block_group);
+       } else if (ins->objectid) {
                ret = 0;
        }
 
@@ -6526,7 +6558,7 @@ int btrfs_set_block_group_ro(struct btrfs_root *root,
 
        BUG_ON(cache->ro);
 
-       trans = btrfs_join_transaction(root, 1);
+       trans = btrfs_join_transaction(root);
        BUG_ON(IS_ERR(trans));
 
        alloc_flags = update_block_group_flags(root, cache->flags);
@@ -6882,6 +6914,7 @@ int btrfs_read_block_groups(struct btrfs_root *root)
        path = btrfs_alloc_path();
        if (!path)
                return -ENOMEM;
+       path->reada = 1;
 
        cache_gen = btrfs_super_cache_generation(&root->fs_info->super_copy);
        if (cache_gen != 0 &&
index c5d9fbb92bc31b50ec9c7e2fd955a267661afe2d..7055d11c1efdd2efef6668b18e0dfcae802a9dd7 100644 (file)
@@ -1476,7 +1476,7 @@ u64 count_range_bits(struct extent_io_tree *tree,
                        if (total_bytes >= max_bytes)
                                break;
                        if (!found) {
-                               *start = state->start;
+                               *start = max(cur_start, state->start);
                                found = 1;
                        }
                        last = state->end;
index c6a22d783c35576253d96f1c3380b01d949f9eca..fa4ef18b66b150a975d4143288b1de699dc0ecf0 100644 (file)
@@ -129,7 +129,7 @@ int btrfs_add_inode_defrag(struct btrfs_trans_handle *trans,
        if (!btrfs_test_opt(root, AUTO_DEFRAG))
                return 0;
 
-       if (root->fs_info->closing)
+       if (btrfs_fs_closing(root->fs_info))
                return 0;
 
        if (BTRFS_I(inode)->in_defrag)
@@ -144,7 +144,7 @@ int btrfs_add_inode_defrag(struct btrfs_trans_handle *trans,
        if (!defrag)
                return -ENOMEM;
 
-       defrag->ino = inode->i_ino;
+       defrag->ino = btrfs_ino(inode);
        defrag->transid = transid;
        defrag->root = root->root_key.objectid;
 
@@ -229,7 +229,7 @@ int btrfs_run_defrag_inodes(struct btrfs_fs_info *fs_info)
                first_ino = defrag->ino + 1;
                rb_erase(&defrag->rb_node, &fs_info->defrag_inodes);
 
-               if (fs_info->closing)
+               if (btrfs_fs_closing(fs_info))
                        goto next_free;
 
                spin_unlock(&fs_info->defrag_inodes_lock);
@@ -1480,14 +1480,12 @@ int btrfs_sync_file(struct file *file, int datasync)
         * the current transaction, we can bail out now without any
         * syncing
         */
-       mutex_lock(&root->fs_info->trans_mutex);
+       smp_mb();
        if (BTRFS_I(inode)->last_trans <=
            root->fs_info->last_trans_committed) {
                BTRFS_I(inode)->last_trans = 0;
-               mutex_unlock(&root->fs_info->trans_mutex);
                goto out;
        }
-       mutex_unlock(&root->fs_info->trans_mutex);
 
        /*
         * ok we haven't committed the transaction yet, lets do a commit
index 70d45795d758e63cd6303327245e80aeffcfa7ae..ad144736a5fd82bff71ef67146d30c6c7dab943a 100644 (file)
@@ -98,7 +98,7 @@ struct inode *lookup_free_space_inode(struct btrfs_root *root,
                return inode;
 
        spin_lock(&block_group->lock);
-       if (!root->fs_info->closing) {
+       if (!btrfs_fs_closing(root->fs_info)) {
                block_group->inode = igrab(inode);
                block_group->iref = 1;
        }
@@ -402,7 +402,14 @@ int __load_free_space_cache(struct btrfs_root *root, struct inode *inode,
                                spin_lock(&ctl->tree_lock);
                                ret = link_free_space(ctl, e);
                                spin_unlock(&ctl->tree_lock);
-                               BUG_ON(ret);
+                               if (ret) {
+                                       printk(KERN_ERR "Duplicate entries in "
+                                              "free space cache, dumping\n");
+                                       kunmap(page);
+                                       unlock_page(page);
+                                       page_cache_release(page);
+                                       goto free_cache;
+                               }
                        } else {
                                e->bitmap = kzalloc(PAGE_CACHE_SIZE, GFP_NOFS);
                                if (!e->bitmap) {
@@ -419,6 +426,14 @@ int __load_free_space_cache(struct btrfs_root *root, struct inode *inode,
                                ctl->op->recalc_thresholds(ctl);
                                spin_unlock(&ctl->tree_lock);
                                list_add_tail(&e->list, &bitmaps);
+                               if (ret) {
+                                       printk(KERN_ERR "Duplicate entries in "
+                                              "free space cache, dumping\n");
+                                       kunmap(page);
+                                       unlock_page(page);
+                                       page_cache_release(page);
+                                       goto free_cache;
+                               }
                        }
 
                        num_entries--;
@@ -478,8 +493,7 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info,
         * If we're unmounting then just return, since this does a search on the
         * normal root and not the commit root and we could deadlock.
         */
-       smp_mb();
-       if (fs_info->closing)
+       if (btrfs_fs_closing(fs_info))
                return 0;
 
        /*
@@ -575,10 +589,25 @@ int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode,
 
        num_pages = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >>
                PAGE_CACHE_SHIFT;
+
+       /* Since the first page has all of our checksums and our generation we
+        * need to calculate the offset into the page that we can start writing
+        * our entries.
+        */
+       first_page_offset = (sizeof(u32) * num_pages) + sizeof(u64);
+
        filemap_write_and_wait(inode->i_mapping);
        btrfs_wait_ordered_range(inode, inode->i_size &
                                 ~(root->sectorsize - 1), (u64)-1);
 
+       /* make sure we don't overflow that first page */
+       if (first_page_offset + sizeof(struct btrfs_free_space_entry) >= PAGE_CACHE_SIZE) {
+               /* this is really the same as running out of space, where we also return 0 */
+               printk(KERN_CRIT "Btrfs: free space cache was too big for the crc page\n");
+               ret = 0;
+               goto out_update;
+       }
+
        /* We need a checksum per page. */
        crc = checksums = kzalloc(sizeof(u32) * num_pages, GFP_NOFS);
        if (!crc)
@@ -590,12 +619,6 @@ int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode,
                return -1;
        }
 
-       /* Since the first page has all of our checksums and our generation we
-        * need to calculate the offset into the page that we can start writing
-        * our entries.
-        */
-       first_page_offset = (sizeof(u32) * num_pages) + sizeof(u64);
-
        /* Get the cluster for this block_group if it exists */
        if (block_group && !list_empty(&block_group->cluster_list))
                cluster = list_entry(block_group->cluster_list.next,
@@ -857,12 +880,14 @@ int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode,
        ret = 1;
 
 out_free:
+       kfree(checksums);
+       kfree(pages);
+
+out_update:
        if (ret != 1) {
                invalidate_inode_pages2_range(inode->i_mapping, 0, index);
                BTRFS_I(inode)->generation = 0;
        }
-       kfree(checksums);
-       kfree(pages);
        btrfs_update_inode(trans, root, inode);
        return ret;
 }
@@ -963,10 +988,16 @@ static int tree_insert_offset(struct rb_root *root, u64 offset,
                         * logically.
                         */
                        if (bitmap) {
-                               WARN_ON(info->bitmap);
+                               if (info->bitmap) {
+                                       WARN_ON_ONCE(1);
+                                       return -EEXIST;
+                               }
                                p = &(*p)->rb_right;
                        } else {
-                               WARN_ON(!info->bitmap);
+                               if (!info->bitmap) {
+                                       WARN_ON_ONCE(1);
+                                       return -EEXIST;
+                               }
                                p = &(*p)->rb_left;
                        }
                }
@@ -2481,7 +2512,7 @@ struct inode *lookup_free_ino_inode(struct btrfs_root *root,
                return inode;
 
        spin_lock(&root->cache_lock);
-       if (!root->fs_info->closing)
+       if (!btrfs_fs_closing(root->fs_info))
                root->cache_inode = igrab(inode);
        spin_unlock(&root->cache_lock);
 
@@ -2504,12 +2535,14 @@ int load_free_ino_cache(struct btrfs_fs_info *fs_info, struct btrfs_root *root)
        int ret = 0;
        u64 root_gen = btrfs_root_generation(&root->root_item);
 
+       if (!btrfs_test_opt(root, INODE_MAP_CACHE))
+               return 0;
+
        /*
         * If we're unmounting then just return, since this does a search on the
         * normal root and not the commit root and we could deadlock.
         */
-       smp_mb();
-       if (fs_info->closing)
+       if (btrfs_fs_closing(fs_info))
                return 0;
 
        path = btrfs_alloc_path();
@@ -2543,6 +2576,9 @@ int btrfs_write_out_ino_cache(struct btrfs_root *root,
        struct inode *inode;
        int ret;
 
+       if (!btrfs_test_opt(root, INODE_MAP_CACHE))
+               return 0;
+
        inode = lookup_free_ino_inode(root, path);
        if (IS_ERR(inode))
                return 0;
index 3262cd17a12f89192ce0c3e5394d5936ce003049..b4087e0fa8714bca45e5fc026caf3491e212dd14 100644 (file)
@@ -38,6 +38,9 @@ static int caching_kthread(void *data)
        int slot;
        int ret;
 
+       if (!btrfs_test_opt(root, INODE_MAP_CACHE))
+               return 0;
+
        path = btrfs_alloc_path();
        if (!path)
                return -ENOMEM;
@@ -59,8 +62,7 @@ again:
                goto out;
 
        while (1) {
-               smp_mb();
-               if (fs_info->closing)
+               if (btrfs_fs_closing(fs_info))
                        goto out;
 
                leaf = path->nodes[0];
@@ -141,6 +143,9 @@ static void start_caching(struct btrfs_root *root)
        int ret;
        u64 objectid;
 
+       if (!btrfs_test_opt(root, INODE_MAP_CACHE))
+               return;
+
        spin_lock(&root->cache_lock);
        if (root->cached != BTRFS_CACHE_NO) {
                spin_unlock(&root->cache_lock);
@@ -178,6 +183,9 @@ static void start_caching(struct btrfs_root *root)
 
 int btrfs_find_free_ino(struct btrfs_root *root, u64 *objectid)
 {
+       if (!btrfs_test_opt(root, INODE_MAP_CACHE))
+               return btrfs_find_free_objectid(root, objectid);
+
 again:
        *objectid = btrfs_find_ino_for_alloc(root);
 
@@ -201,6 +209,10 @@ void btrfs_return_ino(struct btrfs_root *root, u64 objectid)
 {
        struct btrfs_free_space_ctl *ctl = root->free_ino_ctl;
        struct btrfs_free_space_ctl *pinned = root->free_ino_pinned;
+
+       if (!btrfs_test_opt(root, INODE_MAP_CACHE))
+               return;
+
 again:
        if (root->cached == BTRFS_CACHE_FINISHED) {
                __btrfs_add_free_space(ctl, objectid, 1);
@@ -250,6 +262,9 @@ void btrfs_unpin_free_ino(struct btrfs_root *root)
        struct rb_node *n;
        u64 count;
 
+       if (!btrfs_test_opt(root, INODE_MAP_CACHE))
+               return;
+
        while (1) {
                n = rb_first(rbroot);
                if (!n)
@@ -388,9 +403,24 @@ int btrfs_save_ino_cache(struct btrfs_root *root,
        int prealloc;
        bool retry = false;
 
+       /* only fs tree and subvol/snap needs ino cache */
+       if (root->root_key.objectid != BTRFS_FS_TREE_OBJECTID &&
+           (root->root_key.objectid < BTRFS_FIRST_FREE_OBJECTID ||
+            root->root_key.objectid > BTRFS_LAST_FREE_OBJECTID))
+               return 0;
+
+       /* Don't save inode cache if we are deleting this root */
+       if (btrfs_root_refs(&root->root_item) == 0 &&
+           root != root->fs_info->tree_root)
+               return 0;
+
+       if (!btrfs_test_opt(root, INODE_MAP_CACHE))
+               return 0;
+
        path = btrfs_alloc_path();
        if (!path)
                return -ENOMEM;
+
 again:
        inode = lookup_free_ino_inode(root, path);
        if (IS_ERR(inode) && PTR_ERR(inode) != -ENOENT) {
index 39a9d5750efdaf9401f414cc4e6824ecf2bc301b..ebf95f7a44d69aaba80e11a0744894a6a2e873fd 100644 (file)
@@ -138,7 +138,6 @@ static noinline int insert_inline_extent(struct btrfs_trans_handle *trans,
                return -ENOMEM;
 
        path->leave_spinning = 1;
-       btrfs_set_trans_block_group(trans, inode);
 
        key.objectid = btrfs_ino(inode);
        key.offset = start;
@@ -426,9 +425,8 @@ again:
                }
        }
        if (start == 0) {
-               trans = btrfs_join_transaction(root, 1);
+               trans = btrfs_join_transaction(root);
                BUG_ON(IS_ERR(trans));
-               btrfs_set_trans_block_group(trans, inode);
                trans->block_rsv = &root->fs_info->delalloc_block_rsv;
 
                /* lets try to make an inline extent */
@@ -623,8 +621,9 @@ retry:
                            async_extent->start + async_extent->ram_size - 1,
                            GFP_NOFS);
 
-               trans = btrfs_join_transaction(root, 1);
+               trans = btrfs_join_transaction(root);
                BUG_ON(IS_ERR(trans));
+               trans->block_rsv = &root->fs_info->delalloc_block_rsv;
                ret = btrfs_reserve_extent(trans, root,
                                           async_extent->compressed_size,
                                           async_extent->compressed_size,
@@ -793,9 +792,8 @@ static noinline int cow_file_range(struct inode *inode,
        int ret = 0;
 
        BUG_ON(is_free_space_inode(root, inode));
-       trans = btrfs_join_transaction(root, 1);
+       trans = btrfs_join_transaction(root);
        BUG_ON(IS_ERR(trans));
-       btrfs_set_trans_block_group(trans, inode);
        trans->block_rsv = &root->fs_info->delalloc_block_rsv;
 
        num_bytes = (end - start + blocksize) & ~(blocksize - 1);
@@ -1077,10 +1075,12 @@ static noinline int run_delalloc_nocow(struct inode *inode,
        nolock = is_free_space_inode(root, inode);
 
        if (nolock)
-               trans = btrfs_join_transaction_nolock(root, 1);
+               trans = btrfs_join_transaction_nolock(root);
        else
-               trans = btrfs_join_transaction(root, 1);
+               trans = btrfs_join_transaction(root);
+
        BUG_ON(IS_ERR(trans));
+       trans->block_rsv = &root->fs_info->delalloc_block_rsv;
 
        cow_start = (u64)-1;
        cur_offset = start;
@@ -1519,8 +1519,6 @@ static noinline int add_pending_csums(struct btrfs_trans_handle *trans,
 {
        struct btrfs_ordered_sum *sum;
 
-       btrfs_set_trans_block_group(trans, inode);
-
        list_for_each_entry(sum, list, list) {
                btrfs_csum_file_blocks(trans,
                       BTRFS_I(inode)->root->fs_info->csum_root, sum);
@@ -1735,11 +1733,10 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end)
                ret = btrfs_ordered_update_i_size(inode, 0, ordered_extent);
                if (!ret) {
                        if (nolock)
-                               trans = btrfs_join_transaction_nolock(root, 1);
+                               trans = btrfs_join_transaction_nolock(root);
                        else
-                               trans = btrfs_join_transaction(root, 1);
+                               trans = btrfs_join_transaction(root);
                        BUG_ON(IS_ERR(trans));
-                       btrfs_set_trans_block_group(trans, inode);
                        trans->block_rsv = &root->fs_info->delalloc_block_rsv;
                        ret = btrfs_update_inode(trans, root, inode);
                        BUG_ON(ret);
@@ -1752,11 +1749,10 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end)
                         0, &cached_state, GFP_NOFS);
 
        if (nolock)
-               trans = btrfs_join_transaction_nolock(root, 1);
+               trans = btrfs_join_transaction_nolock(root);
        else
-               trans = btrfs_join_transaction(root, 1);
+               trans = btrfs_join_transaction(root);
        BUG_ON(IS_ERR(trans));
-       btrfs_set_trans_block_group(trans, inode);
        trans->block_rsv = &root->fs_info->delalloc_block_rsv;
 
        if (test_bit(BTRFS_ORDERED_COMPRESSED, &ordered_extent->flags))
@@ -2431,7 +2427,7 @@ int btrfs_orphan_cleanup(struct btrfs_root *root)
                                        (u64)-1);
 
        if (root->orphan_block_rsv || root->orphan_item_inserted) {
-               trans = btrfs_join_transaction(root, 1);
+               trans = btrfs_join_transaction(root);
                if (!IS_ERR(trans))
                        btrfs_end_transaction(trans, root);
        }
@@ -2511,12 +2507,12 @@ static void btrfs_read_locked_inode(struct inode *inode)
        struct btrfs_root *root = BTRFS_I(inode)->root;
        struct btrfs_key location;
        int maybe_acls;
-       u64 alloc_group_block;
        u32 rdev;
        int ret;
 
        path = btrfs_alloc_path();
        BUG_ON(!path);
+       path->leave_spinning = 1;
        memcpy(&location, &BTRFS_I(inode)->location, sizeof(location));
 
        ret = btrfs_lookup_inode(NULL, root, path, &location, 0);
@@ -2526,6 +2522,12 @@ static void btrfs_read_locked_inode(struct inode *inode)
        leaf = path->nodes[0];
        inode_item = btrfs_item_ptr(leaf, path->slots[0],
                                    struct btrfs_inode_item);
+       if (!leaf->map_token)
+               map_private_extent_buffer(leaf, (unsigned long)inode_item,
+                                         sizeof(struct btrfs_inode_item),
+                                         &leaf->map_token, &leaf->kaddr,
+                                         &leaf->map_start, &leaf->map_len,
+                                         KM_USER1);
 
        inode->i_mode = btrfs_inode_mode(leaf, inode_item);
        inode->i_nlink = btrfs_inode_nlink(leaf, inode_item);
@@ -2555,8 +2557,6 @@ static void btrfs_read_locked_inode(struct inode *inode)
        BTRFS_I(inode)->index_cnt = (u64)-1;
        BTRFS_I(inode)->flags = btrfs_inode_flags(leaf, inode_item);
 
-       alloc_group_block = btrfs_inode_block_group(leaf, inode_item);
-
        /*
         * try to precache a NULL acl entry for files that don't have
         * any xattrs or acls
@@ -2566,8 +2566,11 @@ static void btrfs_read_locked_inode(struct inode *inode)
        if (!maybe_acls)
                cache_no_acl(inode);
 
-       BTRFS_I(inode)->block_group = btrfs_find_block_group(root, 0,
-                                               alloc_group_block, 0);
+       if (leaf->map_token) {
+               unmap_extent_buffer(leaf, leaf->map_token, KM_USER1);
+               leaf->map_token = NULL;
+       }
+
        btrfs_free_path(path);
        inode_item = NULL;
 
@@ -2647,7 +2650,7 @@ static void fill_inode_item(struct btrfs_trans_handle *trans,
        btrfs_set_inode_transid(leaf, item, trans->transid);
        btrfs_set_inode_rdev(leaf, item, inode->i_rdev);
        btrfs_set_inode_flags(leaf, item, BTRFS_I(inode)->flags);
-       btrfs_set_inode_block_group(leaf, item, BTRFS_I(inode)->block_group);
+       btrfs_set_inode_block_group(leaf, item, 0);
 
        if (leaf->map_token) {
                unmap_extent_buffer(leaf, leaf->map_token, KM_USER1);
@@ -3004,8 +3007,6 @@ static int btrfs_unlink(struct inode *dir, struct dentry *dentry)
        if (IS_ERR(trans))
                return PTR_ERR(trans);
 
-       btrfs_set_trans_block_group(trans, dir);
-
        btrfs_record_unlink_dir(trans, dir, dentry->d_inode, 0);
 
        ret = btrfs_unlink_inode(trans, root, dir, dentry->d_inode,
@@ -3094,8 +3095,6 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry)
        if (IS_ERR(trans))
                return PTR_ERR(trans);
 
-       btrfs_set_trans_block_group(trans, dir);
-
        if (unlikely(btrfs_ino(inode) == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID)) {
                err = btrfs_unlink_subvol(trans, root, dir,
                                          BTRFS_I(inode)->location.objectid,
@@ -3514,7 +3513,6 @@ int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size)
                                err = PTR_ERR(trans);
                                break;
                        }
-                       btrfs_set_trans_block_group(trans, inode);
 
                        err = btrfs_drop_extents(trans, inode, cur_offset,
                                                 cur_offset + hole_size,
@@ -3650,7 +3648,6 @@ void btrfs_evict_inode(struct inode *inode)
        while (1) {
                trans = btrfs_start_transaction(root, 0);
                BUG_ON(IS_ERR(trans));
-               btrfs_set_trans_block_group(trans, inode);
                trans->block_rsv = root->orphan_block_rsv;
 
                ret = btrfs_block_rsv_check(trans, root,
@@ -4133,7 +4130,8 @@ static int btrfs_real_readdir(struct file *filp, void *dirent,
        path = btrfs_alloc_path();
        if (!path)
                return -ENOMEM;
-       path->reada = 2;
+
+       path->reada = 1;
 
        if (key_type == BTRFS_DIR_INDEX_KEY) {
                INIT_LIST_HEAD(&ins_list);
@@ -4268,18 +4266,16 @@ int btrfs_write_inode(struct inode *inode, struct writeback_control *wbc)
        if (BTRFS_I(inode)->dummy_inode)
                return 0;
 
-       smp_mb();
-       if (root->fs_info->closing && is_free_space_inode(root, inode))
+       if (btrfs_fs_closing(root->fs_info) && is_free_space_inode(root, inode))
                nolock = true;
 
        if (wbc->sync_mode == WB_SYNC_ALL) {
                if (nolock)
-                       trans = btrfs_join_transaction_nolock(root, 1);
+                       trans = btrfs_join_transaction_nolock(root);
                else
-                       trans = btrfs_join_transaction(root, 1);
+                       trans = btrfs_join_transaction(root);
                if (IS_ERR(trans))
                        return PTR_ERR(trans);
-               btrfs_set_trans_block_group(trans, inode);
                if (nolock)
                        ret = btrfs_end_transaction_nolock(trans, root);
                else
@@ -4303,9 +4299,8 @@ void btrfs_dirty_inode(struct inode *inode, int flags)
        if (BTRFS_I(inode)->dummy_inode)
                return;
 
-       trans = btrfs_join_transaction(root, 1);
+       trans = btrfs_join_transaction(root);
        BUG_ON(IS_ERR(trans));
-       btrfs_set_trans_block_group(trans, inode);
 
        ret = btrfs_update_inode(trans, root, inode);
        if (ret && ret == -ENOSPC) {
@@ -4319,7 +4314,6 @@ void btrfs_dirty_inode(struct inode *inode, int flags)
                                       PTR_ERR(trans));
                        return;
                }
-               btrfs_set_trans_block_group(trans, inode);
 
                ret = btrfs_update_inode(trans, root, inode);
                if (ret) {
@@ -4418,8 +4412,8 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
                                     struct btrfs_root *root,
                                     struct inode *dir,
                                     const char *name, int name_len,
-                                    u64 ref_objectid, u64 objectid,
-                                    u64 alloc_hint, int mode, u64 *index)
+                                    u64 ref_objectid, u64 objectid, int mode,
+                                    u64 *index)
 {
        struct inode *inode;
        struct btrfs_inode_item *inode_item;
@@ -4472,8 +4466,6 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
                owner = 0;
        else
                owner = 1;
-       BTRFS_I(inode)->block_group =
-                       btrfs_find_block_group(root, 0, alloc_hint, owner);
 
        key[0].objectid = objectid;
        btrfs_set_key_type(&key[0], BTRFS_INODE_ITEM_KEY);
@@ -4629,15 +4621,13 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry,
        if (IS_ERR(trans))
                return PTR_ERR(trans);
 
-       btrfs_set_trans_block_group(trans, dir);
-
        err = btrfs_find_free_ino(root, &objectid);
        if (err)
                goto out_unlock;
 
        inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name,
                                dentry->d_name.len, btrfs_ino(dir), objectid,
-                               BTRFS_I(dir)->block_group, mode, &index);
+                               mode, &index);
        if (IS_ERR(inode)) {
                err = PTR_ERR(inode);
                goto out_unlock;
@@ -4649,7 +4639,6 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry,
                goto out_unlock;
        }
 
-       btrfs_set_trans_block_group(trans, inode);
        err = btrfs_add_nondir(trans, dir, dentry, inode, 0, index);
        if (err)
                drop_inode = 1;
@@ -4658,8 +4647,6 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry,
                init_special_inode(inode, inode->i_mode, rdev);
                btrfs_update_inode(trans, root, inode);
        }
-       btrfs_update_inode_block_group(trans, inode);
-       btrfs_update_inode_block_group(trans, dir);
 out_unlock:
        nr = trans->blocks_used;
        btrfs_end_transaction_throttle(trans, root);
@@ -4692,15 +4679,13 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
        if (IS_ERR(trans))
                return PTR_ERR(trans);
 
-       btrfs_set_trans_block_group(trans, dir);
-
        err = btrfs_find_free_ino(root, &objectid);
        if (err)
                goto out_unlock;
 
        inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name,
                                dentry->d_name.len, btrfs_ino(dir), objectid,
-                               BTRFS_I(dir)->block_group, mode, &index);
+                               mode, &index);
        if (IS_ERR(inode)) {
                err = PTR_ERR(inode);
                goto out_unlock;
@@ -4712,7 +4697,6 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
                goto out_unlock;
        }
 
-       btrfs_set_trans_block_group(trans, inode);
        err = btrfs_add_nondir(trans, dir, dentry, inode, 0, index);
        if (err)
                drop_inode = 1;
@@ -4723,8 +4707,6 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
                inode->i_op = &btrfs_file_inode_operations;
                BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops;
        }
-       btrfs_update_inode_block_group(trans, inode);
-       btrfs_update_inode_block_group(trans, dir);
 out_unlock:
        nr = trans->blocks_used;
        btrfs_end_transaction_throttle(trans, root);
@@ -4771,8 +4753,6 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
 
        btrfs_inc_nlink(inode);
        inode->i_ctime = CURRENT_TIME;
-
-       btrfs_set_trans_block_group(trans, dir);
        ihold(inode);
 
        err = btrfs_add_nondir(trans, dir, dentry, inode, 1, index);
@@ -4781,7 +4761,6 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
                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, parent);
@@ -4818,7 +4797,6 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
        trans = btrfs_start_transaction(root, 5);
        if (IS_ERR(trans))
                return PTR_ERR(trans);
-       btrfs_set_trans_block_group(trans, dir);
 
        err = btrfs_find_free_ino(root, &objectid);
        if (err)
@@ -4826,8 +4804,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
 
        inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name,
                                dentry->d_name.len, btrfs_ino(dir), objectid,
-                               BTRFS_I(dir)->block_group, S_IFDIR | mode,
-                               &index);
+                               S_IFDIR | mode, &index);
        if (IS_ERR(inode)) {
                err = PTR_ERR(inode);
                goto out_fail;
@@ -4841,7 +4818,6 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
 
        inode->i_op = &btrfs_dir_inode_operations;
        inode->i_fop = &btrfs_dir_file_operations;
-       btrfs_set_trans_block_group(trans, inode);
 
        btrfs_i_size_write(inode, 0);
        err = btrfs_update_inode(trans, root, inode);
@@ -4855,8 +4831,6 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
 
        d_instantiate(dentry, inode);
        drop_on_err = 0;
-       btrfs_update_inode_block_group(trans, inode);
-       btrfs_update_inode_block_group(trans, dir);
 
 out_fail:
        nr = trans->blocks_used;
@@ -4989,7 +4963,15 @@ again:
 
        if (!path) {
                path = btrfs_alloc_path();
-               BUG_ON(!path);
+               if (!path) {
+                       err = -ENOMEM;
+                       goto out;
+               }
+               /*
+                * Chances are we'll be called again, so go ahead and do
+                * readahead
+                */
+               path->reada = 1;
        }
 
        ret = btrfs_lookup_file_extent(trans, root, path,
@@ -5130,8 +5112,10 @@ again:
                                kunmap(page);
                                free_extent_map(em);
                                em = NULL;
+
                                btrfs_release_path(path);
-                               trans = btrfs_join_transaction(root, 1);
+                               trans = btrfs_join_transaction(root);
+
                                if (IS_ERR(trans))
                                        return ERR_CAST(trans);
                                goto again;
@@ -5375,7 +5359,7 @@ static struct extent_map *btrfs_new_extent_direct(struct inode *inode,
                btrfs_drop_extent_cache(inode, start, start + len - 1, 0);
        }
 
-       trans = btrfs_join_transaction(root, 0);
+       trans = btrfs_join_transaction(root);
        if (IS_ERR(trans))
                return ERR_CAST(trans);
 
@@ -5611,7 +5595,7 @@ static int btrfs_get_blocks_direct(struct inode *inode, sector_t iblock,
                 * to make sure the current transaction stays open
                 * while we look for nocow cross refs
                 */
-               trans = btrfs_join_transaction(root, 0);
+               trans = btrfs_join_transaction(root);
                if (IS_ERR(trans))
                        goto must_cow;
 
@@ -5750,7 +5734,7 @@ again:
 
        BUG_ON(!ordered);
 
-       trans = btrfs_join_transaction(root, 1);
+       trans = btrfs_join_transaction(root);
        if (IS_ERR(trans)) {
                err = -ENOMEM;
                goto out;
@@ -6500,6 +6484,7 @@ out:
 static int btrfs_truncate(struct inode *inode)
 {
        struct btrfs_root *root = BTRFS_I(inode)->root;
+       struct btrfs_block_rsv *rsv;
        int ret;
        int err = 0;
        struct btrfs_trans_handle *trans;
@@ -6513,28 +6498,80 @@ static int btrfs_truncate(struct inode *inode)
        btrfs_wait_ordered_range(inode, inode->i_size & (~mask), (u64)-1);
        btrfs_ordered_update_i_size(inode, inode->i_size, NULL);
 
-       trans = btrfs_start_transaction(root, 5);
-       if (IS_ERR(trans))
-               return PTR_ERR(trans);
+       /*
+        * Yes ladies and gentelment, this is indeed ugly.  The fact is we have
+        * 3 things going on here
+        *
+        * 1) We need to reserve space for our orphan item and the space to
+        * delete our orphan item.  Lord knows we don't want to have a dangling
+        * orphan item because we didn't reserve space to remove it.
+        *
+        * 2) We need to reserve space to update our inode.
+        *
+        * 3) We need to have something to cache all the space that is going to
+        * be free'd up by the truncate operation, but also have some slack
+        * space reserved in case it uses space during the truncate (thank you
+        * very much snapshotting).
+        *
+        * And we need these to all be seperate.  The fact is we can use alot of
+        * space doing the truncate, and we have no earthly idea how much space
+        * we will use, so we need the truncate reservation to be seperate so it
+        * doesn't end up using space reserved for updating the inode or
+        * removing the orphan item.  We also need to be able to stop the
+        * transaction and start a new one, which means we need to be able to
+        * update the inode several times, and we have no idea of knowing how
+        * many times that will be, so we can't just reserve 1 item for the
+        * entirety of the opration, so that has to be done seperately as well.
+        * Then there is the orphan item, which does indeed need to be held on
+        * to for the whole operation, and we need nobody to touch this reserved
+        * space except the orphan code.
+        *
+        * So that leaves us with
+        *
+        * 1) root->orphan_block_rsv - for the orphan deletion.
+        * 2) rsv - for the truncate reservation, which we will steal from the
+        * transaction reservation.
+        * 3) fs_info->trans_block_rsv - this will have 1 items worth left for
+        * updating the inode.
+        */
+       rsv = btrfs_alloc_block_rsv(root);
+       if (!rsv)
+               return -ENOMEM;
+       btrfs_add_durable_block_rsv(root->fs_info, rsv);
+
+       trans = btrfs_start_transaction(root, 4);
+       if (IS_ERR(trans)) {
+               err = PTR_ERR(trans);
+               goto out;
+       }
 
-       btrfs_set_trans_block_group(trans, inode);
+       /*
+        * Reserve space for the truncate process.  Truncate should be adding
+        * space, but if there are snapshots it may end up using space.
+        */
+       ret = btrfs_truncate_reserve_metadata(trans, root, rsv);
+       BUG_ON(ret);
 
        ret = btrfs_orphan_add(trans, inode);
        if (ret) {
                btrfs_end_transaction(trans, root);
-               return ret;
+               goto out;
        }
 
        nr = trans->blocks_used;
        btrfs_end_transaction(trans, root);
        btrfs_btree_balance_dirty(root, nr);
 
-       /* Now start a transaction for the truncate */
-       trans = btrfs_start_transaction(root, 0);
-       if (IS_ERR(trans))
-               return PTR_ERR(trans);
-       btrfs_set_trans_block_group(trans, inode);
-       trans->block_rsv = root->orphan_block_rsv;
+       /*
+        * Ok so we've already migrated our bytes over for the truncate, so here
+        * just reserve the one slot we need for updating the inode.
+        */
+       trans = btrfs_start_transaction(root, 1);
+       if (IS_ERR(trans)) {
+               err = PTR_ERR(trans);
+               goto out;
+       }
+       trans->block_rsv = rsv;
 
        /*
         * setattr is responsible for setting the ordered_data_close flag,
@@ -6558,24 +6595,17 @@ static int btrfs_truncate(struct inode *inode)
 
        while (1) {
                if (!trans) {
-                       trans = btrfs_start_transaction(root, 0);
-                       if (IS_ERR(trans))
-                               return PTR_ERR(trans);
-                       btrfs_set_trans_block_group(trans, inode);
-                       trans->block_rsv = root->orphan_block_rsv;
-               }
+                       trans = btrfs_start_transaction(root, 3);
+                       if (IS_ERR(trans)) {
+                               err = PTR_ERR(trans);
+                               goto out;
+                       }
 
-               ret = btrfs_block_rsv_check(trans, root,
-                                           root->orphan_block_rsv, 0, 5);
-               if (ret == -EAGAIN) {
-                       ret = btrfs_commit_transaction(trans, root);
-                       if (ret)
-                               return ret;
-                       trans = NULL;
-                       continue;
-               } else if (ret) {
-                       err = ret;
-                       break;
+                       ret = btrfs_truncate_reserve_metadata(trans, root,
+                                                             rsv);
+                       BUG_ON(ret);
+
+                       trans->block_rsv = rsv;
                }
 
                ret = btrfs_truncate_inode_items(trans, root, inode,
@@ -6586,6 +6616,7 @@ static int btrfs_truncate(struct inode *inode)
                        break;
                }
 
+               trans->block_rsv = &root->fs_info->trans_block_rsv;
                ret = btrfs_update_inode(trans, root, inode);
                if (ret) {
                        err = ret;
@@ -6599,6 +6630,7 @@ static int btrfs_truncate(struct inode *inode)
        }
 
        if (ret == 0 && inode->i_nlink > 0) {
+               trans->block_rsv = root->orphan_block_rsv;
                ret = btrfs_orphan_del(trans, inode);
                if (ret)
                        err = ret;
@@ -6610,15 +6642,20 @@ static int btrfs_truncate(struct inode *inode)
                ret = btrfs_orphan_del(NULL, inode);
        }
 
+       trans->block_rsv = &root->fs_info->trans_block_rsv;
        ret = btrfs_update_inode(trans, root, inode);
        if (ret && !err)
                err = ret;
 
        nr = trans->blocks_used;
        ret = btrfs_end_transaction_throttle(trans, root);
+       btrfs_btree_balance_dirty(root, nr);
+
+out:
+       btrfs_free_block_rsv(root, rsv);
+
        if (ret && !err)
                err = ret;
-       btrfs_btree_balance_dirty(root, nr);
 
        return err;
 }
@@ -6627,15 +6664,14 @@ static int btrfs_truncate(struct inode *inode)
  * create a new subvolume directory/inode (helper for the ioctl).
  */
 int btrfs_create_subvol_root(struct btrfs_trans_handle *trans,
-                            struct btrfs_root *new_root,
-                            u64 new_dirid, u64 alloc_hint)
+                            struct btrfs_root *new_root, u64 new_dirid)
 {
        struct inode *inode;
        int err;
        u64 index = 0;
 
        inode = btrfs_new_inode(trans, new_root, NULL, "..", 2, new_dirid,
-                               new_dirid, alloc_hint, S_IFDIR | 0700, &index);
+                               new_dirid, S_IFDIR | 0700, &index);
        if (IS_ERR(inode))
                return PTR_ERR(inode);
        inode->i_op = &btrfs_dir_inode_operations;
@@ -6748,21 +6784,6 @@ void btrfs_destroy_inode(struct inode *inode)
                spin_unlock(&root->fs_info->ordered_extent_lock);
        }
 
-       if (root == root->fs_info->tree_root) {
-               struct btrfs_block_group_cache *block_group;
-
-               block_group = btrfs_lookup_block_group(root->fs_info,
-                                               BTRFS_I(inode)->block_group);
-               if (block_group && block_group->inode == inode) {
-                       spin_lock(&block_group->lock);
-                       block_group->inode = NULL;
-                       spin_unlock(&block_group->lock);
-                       btrfs_put_block_group(block_group);
-               } else if (block_group) {
-                       btrfs_put_block_group(block_group);
-               }
-       }
-
        spin_lock(&root->orphan_lock);
        if (!list_empty(&BTRFS_I(inode)->i_orphan)) {
                printk(KERN_INFO "BTRFS: inode %llu still on the orphan list\n",
@@ -6948,8 +6969,6 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
                 goto out_notrans;
         }
 
-       btrfs_set_trans_block_group(trans, new_dir);
-
        if (dest != root)
                btrfs_record_root_in_trans(trans, dest);
 
@@ -7131,16 +7150,13 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
        if (IS_ERR(trans))
                return PTR_ERR(trans);
 
-       btrfs_set_trans_block_group(trans, dir);
-
        err = btrfs_find_free_ino(root, &objectid);
        if (err)
                goto out_unlock;
 
        inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name,
                                dentry->d_name.len, btrfs_ino(dir), objectid,
-                               BTRFS_I(dir)->block_group, S_IFLNK|S_IRWXUGO,
-                               &index);
+                               S_IFLNK|S_IRWXUGO, &index);
        if (IS_ERR(inode)) {
                err = PTR_ERR(inode);
                goto out_unlock;
@@ -7152,7 +7168,6 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
                goto out_unlock;
        }
 
-       btrfs_set_trans_block_group(trans, inode);
        err = btrfs_add_nondir(trans, dir, dentry, inode, 0, index);
        if (err)
                drop_inode = 1;
@@ -7163,8 +7178,6 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
                inode->i_op = &btrfs_file_inode_operations;
                BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops;
        }
-       btrfs_update_inode_block_group(trans, inode);
-       btrfs_update_inode_block_group(trans, dir);
        if (drop_inode)
                goto out_unlock;
 
index 85e818ce00c5df0be84c6ce3c1894ab6c5303615..ac37040e426a0794b1eff39e8f74de96d07db75e 100644 (file)
@@ -243,7 +243,7 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg)
                ip->flags &= ~(BTRFS_INODE_COMPRESS | BTRFS_INODE_NOCOMPRESS);
        }
 
-       trans = btrfs_join_transaction(root, 1);
+       trans = btrfs_join_transaction(root);
        BUG_ON(IS_ERR(trans));
 
        ret = btrfs_update_inode(trans, root, inode);
@@ -414,8 +414,7 @@ static noinline int create_subvol(struct btrfs_root *root,
 
        btrfs_record_root_in_trans(trans, new_root);
 
-       ret = btrfs_create_subvol_root(trans, new_root, new_dirid,
-                                      BTRFS_I(dir)->block_group);
+       ret = btrfs_create_subvol_root(trans, new_root, new_dirid);
        /*
         * insert the directory item
         */
@@ -707,16 +706,17 @@ static int find_new_extents(struct btrfs_root *root,
        struct btrfs_file_extent_item *extent;
        int type;
        int ret;
+       u64 ino = btrfs_ino(inode);
 
        path = btrfs_alloc_path();
        if (!path)
                return -ENOMEM;
 
-       min_key.objectid = inode->i_ino;
+       min_key.objectid = ino;
        min_key.type = BTRFS_EXTENT_DATA_KEY;
        min_key.offset = *off;
 
-       max_key.objectid = inode->i_ino;
+       max_key.objectid = ino;
        max_key.type = (u8)-1;
        max_key.offset = (u64)-1;
 
@@ -727,7 +727,7 @@ static int find_new_extents(struct btrfs_root *root,
                                           path, 0, newer_than);
                if (ret != 0)
                        goto none;
-               if (min_key.objectid != inode->i_ino)
+               if (min_key.objectid != ino)
                        goto none;
                if (min_key.type != BTRFS_EXTENT_DATA_KEY)
                        goto none;
@@ -2489,12 +2489,10 @@ static long btrfs_ioctl_trans_start(struct file *file)
        if (ret)
                goto out;
 
-       mutex_lock(&root->fs_info->trans_mutex);
-       root->fs_info->open_ioctl_trans++;
-       mutex_unlock(&root->fs_info->trans_mutex);
+       atomic_inc(&root->fs_info->open_ioctl_trans);
 
        ret = -ENOMEM;
-       trans = btrfs_start_ioctl_transaction(root, 0);
+       trans = btrfs_start_ioctl_transaction(root);
        if (IS_ERR(trans))
                goto out_drop;
 
@@ -2502,9 +2500,7 @@ static long btrfs_ioctl_trans_start(struct file *file)
        return 0;
 
 out_drop:
-       mutex_lock(&root->fs_info->trans_mutex);
-       root->fs_info->open_ioctl_trans--;
-       mutex_unlock(&root->fs_info->trans_mutex);
+       atomic_dec(&root->fs_info->open_ioctl_trans);
        mnt_drop_write(file->f_path.mnt);
 out:
        return ret;
@@ -2738,9 +2734,7 @@ long btrfs_ioctl_trans_end(struct file *file)
 
        btrfs_end_transaction(trans, root);
 
-       mutex_lock(&root->fs_info->trans_mutex);
-       root->fs_info->open_ioctl_trans--;
-       mutex_unlock(&root->fs_info->trans_mutex);
+       atomic_dec(&root->fs_info->open_ioctl_trans);
 
        mnt_drop_write(file->f_path.mnt);
        return 0;
index ca38eca70af0b3b552c60cc8615b70925c575635..b1ef27cc673b8abc9e135b05e0da24ff7a0c7bb2 100644 (file)
@@ -677,6 +677,8 @@ struct backref_node *build_backref_tree(struct reloc_control *rc,
                err = -ENOMEM;
                goto out;
        }
+       path1->reada = 1;
+       path2->reada = 2;
 
        node = alloc_backref_node(cache);
        if (!node) {
@@ -1999,6 +2001,7 @@ static noinline_for_stack int merge_reloc_root(struct reloc_control *rc,
        path = btrfs_alloc_path();
        if (!path)
                return -ENOMEM;
+       path->reada = 1;
 
        reloc_root = root->reloc_root;
        root_item = &reloc_root->root_item;
@@ -2139,10 +2142,10 @@ int prepare_to_merge(struct reloc_control *rc, int err)
        u64 num_bytes = 0;
        int ret;
 
-       mutex_lock(&root->fs_info->trans_mutex);
+       spin_lock(&root->fs_info->trans_lock);
        rc->merging_rsv_size += root->nodesize * (BTRFS_MAX_LEVEL - 1) * 2;
        rc->merging_rsv_size += rc->nodes_relocated * 2;
-       mutex_unlock(&root->fs_info->trans_mutex);
+       spin_unlock(&root->fs_info->trans_lock);
 again:
        if (!err) {
                num_bytes = rc->merging_rsv_size;
@@ -2152,7 +2155,7 @@ again:
                        err = ret;
        }
 
-       trans = btrfs_join_transaction(rc->extent_root, 1);
+       trans = btrfs_join_transaction(rc->extent_root);
        if (IS_ERR(trans)) {
                if (!err)
                        btrfs_block_rsv_release(rc->extent_root,
@@ -2211,9 +2214,9 @@ int merge_reloc_roots(struct reloc_control *rc)
        int ret;
 again:
        root = rc->extent_root;
-       mutex_lock(&root->fs_info->trans_mutex);
+       spin_lock(&root->fs_info->trans_lock);
        list_splice_init(&rc->reloc_roots, &reloc_roots);
-       mutex_unlock(&root->fs_info->trans_mutex);
+       spin_unlock(&root->fs_info->trans_lock);
 
        while (!list_empty(&reloc_roots)) {
                found = 1;
@@ -3236,7 +3239,7 @@ truncate:
                goto out;
        }
 
-       trans = btrfs_join_transaction(root, 0);
+       trans = btrfs_join_transaction(root);
        if (IS_ERR(trans)) {
                btrfs_free_path(path);
                ret = PTR_ERR(trans);
@@ -3300,6 +3303,7 @@ static int find_data_references(struct reloc_control *rc,
        path = btrfs_alloc_path();
        if (!path)
                return -ENOMEM;
+       path->reada = 1;
 
        root = read_fs_root(rc->extent_root->fs_info, ref_root);
        if (IS_ERR(root)) {
@@ -3586,17 +3590,17 @@ next:
 static void set_reloc_control(struct reloc_control *rc)
 {
        struct btrfs_fs_info *fs_info = rc->extent_root->fs_info;
-       mutex_lock(&fs_info->trans_mutex);
+       spin_lock(&fs_info->trans_lock);
        fs_info->reloc_ctl = rc;
-       mutex_unlock(&fs_info->trans_mutex);
+       spin_unlock(&fs_info->trans_lock);
 }
 
 static void unset_reloc_control(struct reloc_control *rc)
 {
        struct btrfs_fs_info *fs_info = rc->extent_root->fs_info;
-       mutex_lock(&fs_info->trans_mutex);
+       spin_lock(&fs_info->trans_lock);
        fs_info->reloc_ctl = NULL;
-       mutex_unlock(&fs_info->trans_mutex);
+       spin_unlock(&fs_info->trans_lock);
 }
 
 static int check_extent_flags(u64 flags)
@@ -3645,7 +3649,7 @@ int prepare_to_relocate(struct reloc_control *rc)
        rc->create_reloc_tree = 1;
        set_reloc_control(rc);
 
-       trans = btrfs_join_transaction(rc->extent_root, 1);
+       trans = btrfs_join_transaction(rc->extent_root);
        BUG_ON(IS_ERR(trans));
        btrfs_commit_transaction(trans, rc->extent_root);
        return 0;
@@ -3668,6 +3672,7 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc)
        path = btrfs_alloc_path();
        if (!path)
                return -ENOMEM;
+       path->reada = 1;
 
        ret = prepare_to_relocate(rc);
        if (ret) {
@@ -3834,7 +3839,7 @@ restart:
        btrfs_block_rsv_release(rc->extent_root, rc->block_rsv, (u64)-1);
 
        /* get rid of pinned extents */
-       trans = btrfs_join_transaction(rc->extent_root, 1);
+       trans = btrfs_join_transaction(rc->extent_root);
        if (IS_ERR(trans))
                err = PTR_ERR(trans);
        else
@@ -4093,6 +4098,7 @@ int btrfs_recover_relocation(struct btrfs_root *root)
        path = btrfs_alloc_path();
        if (!path)
                return -ENOMEM;
+       path->reada = -1;
 
        key.objectid = BTRFS_TREE_RELOC_OBJECTID;
        key.type = BTRFS_ROOT_ITEM_KEY;
@@ -4159,7 +4165,7 @@ int btrfs_recover_relocation(struct btrfs_root *root)
 
        set_reloc_control(rc);
 
-       trans = btrfs_join_transaction(rc->extent_root, 1);
+       trans = btrfs_join_transaction(rc->extent_root);
        if (IS_ERR(trans)) {
                unset_reloc_control(rc);
                err = PTR_ERR(trans);
@@ -4193,7 +4199,7 @@ int btrfs_recover_relocation(struct btrfs_root *root)
 
        unset_reloc_control(rc);
 
-       trans = btrfs_join_transaction(rc->extent_root, 1);
+       trans = btrfs_join_transaction(rc->extent_root);
        if (IS_ERR(trans))
                err = PTR_ERR(trans);
        else
index 6dfed0c27ac3b64d337b81b2a6fe374d8fd44afe..df50fd1eca8f46cbd7eed9f4a1f52ca87b64aa8f 100644 (file)
@@ -117,33 +117,37 @@ static void scrub_free_csums(struct scrub_dev *sdev)
        }
 }
 
+static void scrub_free_bio(struct bio *bio)
+{
+       int i;
+       struct page *last_page = NULL;
+
+       if (!bio)
+               return;
+
+       for (i = 0; i < bio->bi_vcnt; ++i) {
+               if (bio->bi_io_vec[i].bv_page == last_page)
+                       continue;
+               last_page = bio->bi_io_vec[i].bv_page;
+               __free_page(last_page);
+       }
+       bio_put(bio);
+}
+
 static noinline_for_stack void scrub_free_dev(struct scrub_dev *sdev)
 {
        int i;
-       int j;
-       struct page *last_page;
 
        if (!sdev)
                return;
 
        for (i = 0; i < SCRUB_BIOS_PER_DEV; ++i) {
                struct scrub_bio *sbio = sdev->bios[i];
-               struct bio *bio;
 
                if (!sbio)
                        break;
 
-               bio = sbio->bio;
-               if (bio) {
-                       last_page = NULL;
-                       for (j = 0; j < bio->bi_vcnt; ++j) {
-                               if (bio->bi_io_vec[j].bv_page == last_page)
-                                       continue;
-                               last_page = bio->bi_io_vec[j].bv_page;
-                               __free_page(last_page);
-                       }
-                       bio_put(bio);
-               }
+               scrub_free_bio(sbio->bio);
                kfree(sbio);
        }
 
@@ -156,8 +160,6 @@ struct scrub_dev *scrub_setup_dev(struct btrfs_device *dev)
 {
        struct scrub_dev *sdev;
        int             i;
-       int             j;
-       int             ret;
        struct btrfs_fs_info *fs_info = dev->dev_root->fs_info;
 
        sdev = kzalloc(sizeof(*sdev), GFP_NOFS);
@@ -165,7 +167,6 @@ struct scrub_dev *scrub_setup_dev(struct btrfs_device *dev)
                goto nomem;
        sdev->dev = dev;
        for (i = 0; i < SCRUB_BIOS_PER_DEV; ++i) {
-               struct bio *bio;
                struct scrub_bio *sbio;
 
                sbio = kzalloc(sizeof(*sbio), GFP_NOFS);
@@ -173,32 +174,10 @@ struct scrub_dev *scrub_setup_dev(struct btrfs_device *dev)
                        goto nomem;
                sdev->bios[i] = sbio;
 
-               bio = bio_kmalloc(GFP_NOFS, SCRUB_PAGES_PER_BIO);
-               if (!bio)
-                       goto nomem;
-
                sbio->index = i;
                sbio->sdev = sdev;
-               sbio->bio = bio;
                sbio->count = 0;
                sbio->work.func = scrub_checksum;
-               bio->bi_private = sdev->bios[i];
-               bio->bi_end_io = scrub_bio_end_io;
-               bio->bi_sector = 0;
-               bio->bi_bdev = dev->bdev;
-               bio->bi_size = 0;
-
-               for (j = 0; j < SCRUB_PAGES_PER_BIO; ++j) {
-                       struct page *page;
-                       page = alloc_page(GFP_NOFS);
-                       if (!page)
-                               goto nomem;
-
-                       ret = bio_add_page(bio, page, PAGE_SIZE, 0);
-                       if (!ret)
-                               goto nomem;
-               }
-               WARN_ON(bio->bi_vcnt != SCRUB_PAGES_PER_BIO);
 
                if (i != SCRUB_BIOS_PER_DEV-1)
                        sdev->bios[i]->next_free = i + 1;
@@ -369,9 +348,6 @@ static int scrub_fixup_io(int rw, struct block_device *bdev, sector_t sector,
        int ret;
        DECLARE_COMPLETION_ONSTACK(complete);
 
-       /* we are going to wait on this IO */
-       rw |= REQ_SYNC;
-
        bio = bio_alloc(GFP_NOFS, 1);
        bio->bi_bdev = bdev;
        bio->bi_sector = sector;
@@ -380,6 +356,7 @@ static int scrub_fixup_io(int rw, struct block_device *bdev, sector_t sector,
        bio->bi_private = &complete;
        submit_bio(rw, bio);
 
+       /* this will also unplug the queue */
        wait_for_completion(&complete);
 
        ret = !test_bit(BIO_UPTODATE, &bio->bi_flags);
@@ -394,6 +371,7 @@ static void scrub_bio_end_io(struct bio *bio, int err)
        struct btrfs_fs_info *fs_info = sdev->dev->dev_root->fs_info;
 
        sbio->err = err;
+       sbio->bio = bio;
 
        btrfs_queue_worker(&fs_info->scrub_workers, &sbio->work);
 }
@@ -453,6 +431,8 @@ static void scrub_checksum(struct btrfs_work *work)
        }
 
 out:
+       scrub_free_bio(sbio->bio);
+       sbio->bio = NULL;
        spin_lock(&sdev->list_lock);
        sbio->next_free = sdev->first_free;
        sdev->first_free = sbio->index;
@@ -583,25 +563,50 @@ static int scrub_checksum_super(struct scrub_bio *sbio, void *buffer)
 static int scrub_submit(struct scrub_dev *sdev)
 {
        struct scrub_bio *sbio;
+       struct bio *bio;
+       int i;
 
        if (sdev->curr == -1)
                return 0;
 
        sbio = sdev->bios[sdev->curr];
 
-       sbio->bio->bi_sector = sbio->physical >> 9;
-       sbio->bio->bi_size = sbio->count * PAGE_SIZE;
-       sbio->bio->bi_next = NULL;
-       sbio->bio->bi_flags |= 1 << BIO_UPTODATE;
-       sbio->bio->bi_comp_cpu = -1;
-       sbio->bio->bi_bdev = sdev->dev->bdev;
+       bio = bio_alloc(GFP_NOFS, sbio->count);
+       if (!bio)
+               goto nomem;
+
+       bio->bi_private = sbio;
+       bio->bi_end_io = scrub_bio_end_io;
+       bio->bi_bdev = sdev->dev->bdev;
+       bio->bi_sector = sbio->physical >> 9;
+
+       for (i = 0; i < sbio->count; ++i) {
+               struct page *page;
+               int ret;
+
+               page = alloc_page(GFP_NOFS);
+               if (!page)
+                       goto nomem;
+
+               ret = bio_add_page(bio, page, PAGE_SIZE, 0);
+               if (!ret) {
+                       __free_page(page);
+                       goto nomem;
+               }
+       }
+
        sbio->err = 0;
        sdev->curr = -1;
        atomic_inc(&sdev->in_flight);
 
-       submit_bio(0, sbio->bio);
+       submit_bio(READ, bio);
 
        return 0;
+
+nomem:
+       scrub_free_bio(bio);
+
+       return -ENOMEM;
 }
 
 static int scrub_page(struct scrub_dev *sdev, u64 logical, u64 len,
@@ -633,7 +638,11 @@ again:
                sbio->logical = logical;
        } else if (sbio->physical + sbio->count * PAGE_SIZE != physical ||
                   sbio->logical + sbio->count * PAGE_SIZE != logical) {
-               scrub_submit(sdev);
+               int ret;
+
+               ret = scrub_submit(sdev);
+               if (ret)
+                       return ret;
                goto again;
        }
        sbio->spag[sbio->count].flags = flags;
@@ -645,8 +654,13 @@ again:
                memcpy(sbio->spag[sbio->count].csum, csum, sdev->csum_size);
        }
        ++sbio->count;
-       if (sbio->count == SCRUB_PAGES_PER_BIO || force)
-               scrub_submit(sdev);
+       if (sbio->count == SCRUB_PAGES_PER_BIO || force) {
+               int ret;
+
+               ret = scrub_submit(sdev);
+               if (ret)
+                       return ret;
+       }
 
        return 0;
 }
@@ -727,6 +741,7 @@ static noinline_for_stack int scrub_stripe(struct scrub_dev *sdev,
        struct btrfs_root *root = fs_info->extent_root;
        struct btrfs_root *csum_root = fs_info->csum_root;
        struct btrfs_extent_item *extent;
+       struct blk_plug plug;
        u64 flags;
        int ret;
        int slot;
@@ -831,6 +846,7 @@ static noinline_for_stack int scrub_stripe(struct scrub_dev *sdev,
         * the scrub. This might currently (crc32) end up to be about 1MB
         */
        start_stripe = 0;
+       blk_start_plug(&plug);
 again:
        logical = base + offset + start_stripe * increment;
        for (i = start_stripe; i < nstripes; ++i) {
@@ -972,6 +988,7 @@ next:
        scrub_submit(sdev);
 
 out:
+       blk_finish_plug(&plug);
        btrfs_free_path(path);
        return ret < 0 ? ret : 0;
 }
@@ -1166,7 +1183,7 @@ int btrfs_scrub_dev(struct btrfs_root *root, u64 devid, u64 start, u64 end,
        int ret;
        struct btrfs_device *dev;
 
-       if (root->fs_info->closing)
+       if (btrfs_fs_closing(root->fs_info))
                return -EINVAL;
 
        /*
index 9b2e7e5bc3efa40e2779ba450ee99ac7623087d8..0bb4ebbb71b7b0bf6861b7a5efde6f5cf2f5b97e 100644 (file)
@@ -161,7 +161,8 @@ enum {
        Opt_compress_type, Opt_compress_force, Opt_compress_force_type,
        Opt_notreelog, Opt_ratio, Opt_flushoncommit, Opt_discard,
        Opt_space_cache, Opt_clear_cache, Opt_user_subvol_rm_allowed,
-       Opt_enospc_debug, Opt_subvolrootid, Opt_defrag, Opt_err,
+       Opt_enospc_debug, Opt_subvolrootid, Opt_defrag,
+       Opt_inode_cache, Opt_err,
 };
 
 static match_table_t tokens = {
@@ -193,6 +194,7 @@ static match_table_t tokens = {
        {Opt_enospc_debug, "enospc_debug"},
        {Opt_subvolrootid, "subvolrootid=%d"},
        {Opt_defrag, "autodefrag"},
+       {Opt_inode_cache, "inode_cache"},
        {Opt_err, NULL},
 };
 
@@ -361,6 +363,10 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
                        printk(KERN_INFO "btrfs: enabling disk space caching\n");
                        btrfs_set_opt(info->mount_opt, SPACE_CACHE);
                        break;
+               case Opt_inode_cache:
+                       printk(KERN_INFO "btrfs: enabling inode map caching\n");
+                       btrfs_set_opt(info->mount_opt, INODE_MAP_CACHE);
+                       break;
                case Opt_clear_cache:
                        printk(KERN_INFO "btrfs: force clearing of disk cache\n");
                        btrfs_set_opt(info->mount_opt, CLEAR_CACHE);
@@ -819,7 +825,7 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
        } else {
                char b[BDEVNAME_SIZE];
 
-               s->s_flags = flags;
+               s->s_flags = flags | MS_NOSEC;
                strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id));
                error = btrfs_fill_super(s, fs_devices, data,
                                         flags & MS_SILENT ? 1 : 0);
index dc80f7156923ae120c5496f3fd0093a8616fbeec..dd719662340ed618ff5b543678a3881466e1a045 100644 (file)
@@ -35,6 +35,7 @@ static noinline void put_transaction(struct btrfs_transaction *transaction)
 {
        WARN_ON(atomic_read(&transaction->use_count) == 0);
        if (atomic_dec_and_test(&transaction->use_count)) {
+               BUG_ON(!list_empty(&transaction->list));
                memset(transaction, 0, sizeof(*transaction));
                kmem_cache_free(btrfs_transaction_cachep, transaction);
        }
@@ -49,46 +50,72 @@ static noinline void switch_commit_root(struct btrfs_root *root)
 /*
  * either allocate a new transaction or hop into the existing one
  */
-static noinline int join_transaction(struct btrfs_root *root)
+static noinline int join_transaction(struct btrfs_root *root, int nofail)
 {
        struct btrfs_transaction *cur_trans;
+
+       spin_lock(&root->fs_info->trans_lock);
+       if (root->fs_info->trans_no_join) {
+               if (!nofail) {
+                       spin_unlock(&root->fs_info->trans_lock);
+                       return -EBUSY;
+               }
+       }
+
        cur_trans = root->fs_info->running_transaction;
-       if (!cur_trans) {
-               cur_trans = kmem_cache_alloc(btrfs_transaction_cachep,
-                                            GFP_NOFS);
-               if (!cur_trans)
-                       return -ENOMEM;
-               root->fs_info->generation++;
-               atomic_set(&cur_trans->num_writers, 1);
-               cur_trans->num_joined = 0;
-               cur_trans->transid = root->fs_info->generation;
-               init_waitqueue_head(&cur_trans->writer_wait);
-               init_waitqueue_head(&cur_trans->commit_wait);
-               cur_trans->in_commit = 0;
-               cur_trans->blocked = 0;
-               atomic_set(&cur_trans->use_count, 1);
-               cur_trans->commit_done = 0;
-               cur_trans->start_time = get_seconds();
-
-               cur_trans->delayed_refs.root = RB_ROOT;
-               cur_trans->delayed_refs.num_entries = 0;
-               cur_trans->delayed_refs.num_heads_ready = 0;
-               cur_trans->delayed_refs.num_heads = 0;
-               cur_trans->delayed_refs.flushing = 0;
-               cur_trans->delayed_refs.run_delayed_start = 0;
-               spin_lock_init(&cur_trans->delayed_refs.lock);
-
-               INIT_LIST_HEAD(&cur_trans->pending_snapshots);
-               list_add_tail(&cur_trans->list, &root->fs_info->trans_list);
-               extent_io_tree_init(&cur_trans->dirty_pages,
-                                    root->fs_info->btree_inode->i_mapping);
-               spin_lock(&root->fs_info->new_trans_lock);
-               root->fs_info->running_transaction = cur_trans;
-               spin_unlock(&root->fs_info->new_trans_lock);
-       } else {
+       if (cur_trans) {
+               atomic_inc(&cur_trans->use_count);
                atomic_inc(&cur_trans->num_writers);
                cur_trans->num_joined++;
+               spin_unlock(&root->fs_info->trans_lock);
+               return 0;
        }
+       spin_unlock(&root->fs_info->trans_lock);
+
+       cur_trans = kmem_cache_alloc(btrfs_transaction_cachep, GFP_NOFS);
+       if (!cur_trans)
+               return -ENOMEM;
+       spin_lock(&root->fs_info->trans_lock);
+       if (root->fs_info->running_transaction) {
+               kmem_cache_free(btrfs_transaction_cachep, cur_trans);
+               cur_trans = root->fs_info->running_transaction;
+               atomic_inc(&cur_trans->use_count);
+               atomic_inc(&cur_trans->num_writers);
+               cur_trans->num_joined++;
+               spin_unlock(&root->fs_info->trans_lock);
+               return 0;
+       }
+       atomic_set(&cur_trans->num_writers, 1);
+       cur_trans->num_joined = 0;
+       init_waitqueue_head(&cur_trans->writer_wait);
+       init_waitqueue_head(&cur_trans->commit_wait);
+       cur_trans->in_commit = 0;
+       cur_trans->blocked = 0;
+       /*
+        * One for this trans handle, one so it will live on until we
+        * commit the transaction.
+        */
+       atomic_set(&cur_trans->use_count, 2);
+       cur_trans->commit_done = 0;
+       cur_trans->start_time = get_seconds();
+
+       cur_trans->delayed_refs.root = RB_ROOT;
+       cur_trans->delayed_refs.num_entries = 0;
+       cur_trans->delayed_refs.num_heads_ready = 0;
+       cur_trans->delayed_refs.num_heads = 0;
+       cur_trans->delayed_refs.flushing = 0;
+       cur_trans->delayed_refs.run_delayed_start = 0;
+       spin_lock_init(&cur_trans->commit_lock);
+       spin_lock_init(&cur_trans->delayed_refs.lock);
+
+       INIT_LIST_HEAD(&cur_trans->pending_snapshots);
+       list_add_tail(&cur_trans->list, &root->fs_info->trans_list);
+       extent_io_tree_init(&cur_trans->dirty_pages,
+                            root->fs_info->btree_inode->i_mapping);
+       root->fs_info->generation++;
+       cur_trans->transid = root->fs_info->generation;
+       root->fs_info->running_transaction = cur_trans;
+       spin_unlock(&root->fs_info->trans_lock);
 
        return 0;
 }
@@ -99,39 +126,28 @@ static noinline int join_transaction(struct btrfs_root *root)
  * to make sure the old root from before we joined the transaction is deleted
  * when the transaction commits
  */
-static noinline int record_root_in_trans(struct btrfs_trans_handle *trans,
-                                        struct btrfs_root *root)
+int btrfs_record_root_in_trans(struct btrfs_trans_handle *trans,
+                              struct btrfs_root *root)
 {
        if (root->ref_cows && root->last_trans < trans->transid) {
                WARN_ON(root == root->fs_info->extent_root);
                WARN_ON(root->commit_root != root->node);
 
+               spin_lock(&root->fs_info->fs_roots_radix_lock);
+               if (root->last_trans == trans->transid) {
+                       spin_unlock(&root->fs_info->fs_roots_radix_lock);
+                       return 0;
+               }
+               root->last_trans = trans->transid;
                radix_tree_tag_set(&root->fs_info->fs_roots_radix,
                           (unsigned long)root->root_key.objectid,
                           BTRFS_ROOT_TRANS_TAG);
-               root->last_trans = trans->transid;
+               spin_unlock(&root->fs_info->fs_roots_radix_lock);
                btrfs_init_reloc_root(trans, root);
        }
        return 0;
 }
 
-int btrfs_record_root_in_trans(struct btrfs_trans_handle *trans,
-                              struct btrfs_root *root)
-{
-       if (!root->ref_cows)
-               return 0;
-
-       mutex_lock(&root->fs_info->trans_mutex);
-       if (root->last_trans == trans->transid) {
-               mutex_unlock(&root->fs_info->trans_mutex);
-               return 0;
-       }
-
-       record_root_in_trans(trans, root);
-       mutex_unlock(&root->fs_info->trans_mutex);
-       return 0;
-}
-
 /* wait for commit against the current transaction to become unblocked
  * when this is done, it is safe to start a new transaction, but the current
  * transaction might not be fully on disk.
@@ -140,21 +156,23 @@ static void wait_current_trans(struct btrfs_root *root)
 {
        struct btrfs_transaction *cur_trans;
 
+       spin_lock(&root->fs_info->trans_lock);
        cur_trans = root->fs_info->running_transaction;
        if (cur_trans && cur_trans->blocked) {
                DEFINE_WAIT(wait);
                atomic_inc(&cur_trans->use_count);
+               spin_unlock(&root->fs_info->trans_lock);
                while (1) {
                        prepare_to_wait(&root->fs_info->transaction_wait, &wait,
                                        TASK_UNINTERRUPTIBLE);
                        if (!cur_trans->blocked)
                                break;
-                       mutex_unlock(&root->fs_info->trans_mutex);
                        schedule();
-                       mutex_lock(&root->fs_info->trans_mutex);
                }
                finish_wait(&root->fs_info->transaction_wait, &wait);
                put_transaction(cur_trans);
+       } else {
+               spin_unlock(&root->fs_info->trans_lock);
        }
 }
 
@@ -167,10 +185,16 @@ enum btrfs_trans_type {
 
 static int may_wait_transaction(struct btrfs_root *root, int type)
 {
-       if (!root->fs_info->log_root_recovering &&
-           ((type == TRANS_START && !root->fs_info->open_ioctl_trans) ||
-            type == TRANS_USERSPACE))
+       if (root->fs_info->log_root_recovering)
+               return 0;
+
+       if (type == TRANS_USERSPACE)
+               return 1;
+
+       if (type == TRANS_START &&
+           !atomic_read(&root->fs_info->open_ioctl_trans))
                return 1;
+
        return 0;
 }
 
@@ -184,36 +208,44 @@ static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
 
        if (root->fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR)
                return ERR_PTR(-EROFS);
+
+       if (current->journal_info) {
+               WARN_ON(type != TRANS_JOIN && type != TRANS_JOIN_NOLOCK);
+               h = current->journal_info;
+               h->use_count++;
+               h->orig_rsv = h->block_rsv;
+               h->block_rsv = NULL;
+               goto got_it;
+       }
 again:
        h = kmem_cache_alloc(btrfs_trans_handle_cachep, GFP_NOFS);
        if (!h)
                return ERR_PTR(-ENOMEM);
 
-       if (type != TRANS_JOIN_NOLOCK)
-               mutex_lock(&root->fs_info->trans_mutex);
        if (may_wait_transaction(root, type))
                wait_current_trans(root);
 
-       ret = join_transaction(root);
+       do {
+               ret = join_transaction(root, type == TRANS_JOIN_NOLOCK);
+               if (ret == -EBUSY)
+                       wait_current_trans(root);
+       } while (ret == -EBUSY);
+
        if (ret < 0) {
                kmem_cache_free(btrfs_trans_handle_cachep, h);
-               if (type != TRANS_JOIN_NOLOCK)
-                       mutex_unlock(&root->fs_info->trans_mutex);
                return ERR_PTR(ret);
        }
 
        cur_trans = root->fs_info->running_transaction;
-       atomic_inc(&cur_trans->use_count);
-       if (type != TRANS_JOIN_NOLOCK)
-               mutex_unlock(&root->fs_info->trans_mutex);
 
        h->transid = cur_trans->transid;
        h->transaction = cur_trans;
        h->blocks_used = 0;
-       h->block_group = 0;
        h->bytes_reserved = 0;
        h->delayed_ref_updates = 0;
+       h->use_count = 1;
        h->block_rsv = NULL;
+       h->orig_rsv = NULL;
 
        smp_mb();
        if (cur_trans->blocked && may_wait_transaction(root, type)) {
@@ -241,11 +273,8 @@ again:
                }
        }
 
-       if (type != TRANS_JOIN_NOLOCK)
-               mutex_lock(&root->fs_info->trans_mutex);
-       record_root_in_trans(h, root);
-       if (type != TRANS_JOIN_NOLOCK)
-               mutex_unlock(&root->fs_info->trans_mutex);
+got_it:
+       btrfs_record_root_in_trans(h, root);
 
        if (!current->journal_info && type != TRANS_USERSPACE)
                current->journal_info = h;
@@ -257,22 +286,19 @@ struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root,
 {
        return start_transaction(root, num_items, TRANS_START);
 }
-struct btrfs_trans_handle *btrfs_join_transaction(struct btrfs_root *root,
-                                                  int num_blocks)
+struct btrfs_trans_handle *btrfs_join_transaction(struct btrfs_root *root)
 {
        return start_transaction(root, 0, TRANS_JOIN);
 }
 
-struct btrfs_trans_handle *btrfs_join_transaction_nolock(struct btrfs_root *root,
-                                                         int num_blocks)
+struct btrfs_trans_handle *btrfs_join_transaction_nolock(struct btrfs_root *root)
 {
        return start_transaction(root, 0, TRANS_JOIN_NOLOCK);
 }
 
-struct btrfs_trans_handle *btrfs_start_ioctl_transaction(struct btrfs_root *r,
-                                                        int num_blocks)
+struct btrfs_trans_handle *btrfs_start_ioctl_transaction(struct btrfs_root *root)
 {
-       return start_transaction(r, 0, TRANS_USERSPACE);
+       return start_transaction(root, 0, TRANS_USERSPACE);
 }
 
 /* wait for a transaction commit to be fully complete */
@@ -280,17 +306,13 @@ static noinline int wait_for_commit(struct btrfs_root *root,
                                    struct btrfs_transaction *commit)
 {
        DEFINE_WAIT(wait);
-       mutex_lock(&root->fs_info->trans_mutex);
        while (!commit->commit_done) {
                prepare_to_wait(&commit->commit_wait, &wait,
                                TASK_UNINTERRUPTIBLE);
                if (commit->commit_done)
                        break;
-               mutex_unlock(&root->fs_info->trans_mutex);
                schedule();
-               mutex_lock(&root->fs_info->trans_mutex);
        }
-       mutex_unlock(&root->fs_info->trans_mutex);
        finish_wait(&commit->commit_wait, &wait);
        return 0;
 }
@@ -300,59 +322,56 @@ int btrfs_wait_for_commit(struct btrfs_root *root, u64 transid)
        struct btrfs_transaction *cur_trans = NULL, *t;
        int ret;
 
-       mutex_lock(&root->fs_info->trans_mutex);
-
        ret = 0;
        if (transid) {
                if (transid <= root->fs_info->last_trans_committed)
-                       goto out_unlock;
+                       goto out;
 
                /* find specified transaction */
+               spin_lock(&root->fs_info->trans_lock);
                list_for_each_entry(t, &root->fs_info->trans_list, list) {
                        if (t->transid == transid) {
                                cur_trans = t;
+                               atomic_inc(&cur_trans->use_count);
                                break;
                        }
                        if (t->transid > transid)
                                break;
                }
+               spin_unlock(&root->fs_info->trans_lock);
                ret = -EINVAL;
                if (!cur_trans)
-                       goto out_unlock;  /* bad transid */
+                       goto out;  /* bad transid */
        } else {
                /* find newest transaction that is committing | committed */
+               spin_lock(&root->fs_info->trans_lock);
                list_for_each_entry_reverse(t, &root->fs_info->trans_list,
                                            list) {
                        if (t->in_commit) {
                                if (t->commit_done)
-                                       goto out_unlock;
+                                       goto out;
                                cur_trans = t;
+                               atomic_inc(&cur_trans->use_count);
                                break;
                        }
                }
+               spin_unlock(&root->fs_info->trans_lock);
                if (!cur_trans)
-                       goto out_unlock;  /* nothing committing|committed */
+                       goto out;  /* nothing committing|committed */
        }
 
-       atomic_inc(&cur_trans->use_count);
-       mutex_unlock(&root->fs_info->trans_mutex);
-
        wait_for_commit(root, cur_trans);
 
-       mutex_lock(&root->fs_info->trans_mutex);
        put_transaction(cur_trans);
        ret = 0;
-out_unlock:
-       mutex_unlock(&root->fs_info->trans_mutex);
+out:
        return ret;
 }
 
 void btrfs_throttle(struct btrfs_root *root)
 {
-       mutex_lock(&root->fs_info->trans_mutex);
-       if (!root->fs_info->open_ioctl_trans)
+       if (!atomic_read(&root->fs_info->open_ioctl_trans))
                wait_current_trans(root);
-       mutex_unlock(&root->fs_info->trans_mutex);
 }
 
 static int should_end_transaction(struct btrfs_trans_handle *trans,
@@ -370,6 +389,7 @@ int btrfs_should_end_transaction(struct btrfs_trans_handle *trans,
        struct btrfs_transaction *cur_trans = trans->transaction;
        int updates;
 
+       smp_mb();
        if (cur_trans->blocked || cur_trans->delayed_refs.flushing)
                return 1;
 
@@ -388,6 +408,11 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
        struct btrfs_fs_info *info = root->fs_info;
        int count = 0;
 
+       if (--trans->use_count) {
+               trans->block_rsv = trans->orig_rsv;
+               return 0;
+       }
+
        while (count < 4) {
                unsigned long cur = trans->delayed_ref_updates;
                trans->delayed_ref_updates = 0;
@@ -410,9 +435,11 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
 
        btrfs_trans_release_metadata(trans, root);
 
-       if (lock && !root->fs_info->open_ioctl_trans &&
-           should_end_transaction(trans, root))
+       if (lock && !atomic_read(&root->fs_info->open_ioctl_trans) &&
+           should_end_transaction(trans, root)) {
                trans->transaction->blocked = 1;
+               smp_wmb();
+       }
 
        if (lock && cur_trans->blocked && !cur_trans->in_commit) {
                if (throttle)
@@ -703,9 +730,9 @@ static noinline int commit_cowonly_roots(struct btrfs_trans_handle *trans,
  */
 int btrfs_add_dead_root(struct btrfs_root *root)
 {
-       mutex_lock(&root->fs_info->trans_mutex);
+       spin_lock(&root->fs_info->trans_lock);
        list_add(&root->root_list, &root->fs_info->dead_roots);
-       mutex_unlock(&root->fs_info->trans_mutex);
+       spin_unlock(&root->fs_info->trans_lock);
        return 0;
 }
 
@@ -721,6 +748,7 @@ static noinline int commit_fs_roots(struct btrfs_trans_handle *trans,
        int ret;
        int err = 0;
 
+       spin_lock(&fs_info->fs_roots_radix_lock);
        while (1) {
                ret = radix_tree_gang_lookup_tag(&fs_info->fs_roots_radix,
                                                 (void **)gang, 0,
@@ -733,6 +761,7 @@ static noinline int commit_fs_roots(struct btrfs_trans_handle *trans,
                        radix_tree_tag_clear(&fs_info->fs_roots_radix,
                                        (unsigned long)root->root_key.objectid,
                                        BTRFS_ROOT_TRANS_TAG);
+                       spin_unlock(&fs_info->fs_roots_radix_lock);
 
                        btrfs_free_log(trans, root);
                        btrfs_update_reloc_root(trans, root);
@@ -753,10 +782,12 @@ static noinline int commit_fs_roots(struct btrfs_trans_handle *trans,
                        err = btrfs_update_root(trans, fs_info->tree_root,
                                                &root->root_key,
                                                &root->root_item);
+                       spin_lock(&fs_info->fs_roots_radix_lock);
                        if (err)
                                break;
                }
        }
+       spin_unlock(&fs_info->fs_roots_radix_lock);
        return err;
 }
 
@@ -786,7 +817,7 @@ int btrfs_defrag_root(struct btrfs_root *root, int cacheonly)
                btrfs_btree_balance_dirty(info->tree_root, nr);
                cond_resched();
 
-               if (root->fs_info->closing || ret != -EAGAIN)
+               if (btrfs_fs_closing(root->fs_info) || ret != -EAGAIN)
                        break;
        }
        root->defrag_running = 0;
@@ -851,7 +882,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
        parent = dget_parent(dentry);
        parent_inode = parent->d_inode;
        parent_root = BTRFS_I(parent_inode)->root;
-       record_root_in_trans(trans, parent_root);
+       btrfs_record_root_in_trans(trans, parent_root);
 
        /*
         * insert the directory item
@@ -869,7 +900,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
        ret = btrfs_update_inode(trans, parent_root, parent_inode);
        BUG_ON(ret);
 
-       record_root_in_trans(trans, root);
+       btrfs_record_root_in_trans(trans, root);
        btrfs_set_root_last_snapshot(&root->root_item, trans->transid);
        memcpy(new_root_item, &root->root_item, sizeof(*new_root_item));
        btrfs_check_and_init_root_item(new_root_item);
@@ -967,20 +998,20 @@ static void update_super_roots(struct btrfs_root *root)
 int btrfs_transaction_in_commit(struct btrfs_fs_info *info)
 {
        int ret = 0;
-       spin_lock(&info->new_trans_lock);
+       spin_lock(&info->trans_lock);
        if (info->running_transaction)
                ret = info->running_transaction->in_commit;
-       spin_unlock(&info->new_trans_lock);
+       spin_unlock(&info->trans_lock);
        return ret;
 }
 
 int btrfs_transaction_blocked(struct btrfs_fs_info *info)
 {
        int ret = 0;
-       spin_lock(&info->new_trans_lock);
+       spin_lock(&info->trans_lock);
        if (info->running_transaction)
                ret = info->running_transaction->blocked;
-       spin_unlock(&info->new_trans_lock);
+       spin_unlock(&info->trans_lock);
        return ret;
 }
 
@@ -1004,9 +1035,7 @@ static void wait_current_trans_commit_start(struct btrfs_root *root,
                                    &wait);
                        break;
                }
-               mutex_unlock(&root->fs_info->trans_mutex);
                schedule();
-               mutex_lock(&root->fs_info->trans_mutex);
                finish_wait(&root->fs_info->transaction_blocked_wait, &wait);
        }
 }
@@ -1032,9 +1061,7 @@ static void wait_current_trans_commit_start_and_unblock(struct btrfs_root *root,
                                    &wait);
                        break;
                }
-               mutex_unlock(&root->fs_info->trans_mutex);
                schedule();
-               mutex_lock(&root->fs_info->trans_mutex);
                finish_wait(&root->fs_info->transaction_wait,
                            &wait);
        }
@@ -1072,7 +1099,7 @@ int btrfs_commit_transaction_async(struct btrfs_trans_handle *trans,
 
        INIT_DELAYED_WORK(&ac->work, do_async_commit);
        ac->root = root;
-       ac->newtrans = btrfs_join_transaction(root, 0);
+       ac->newtrans = btrfs_join_transaction(root);
        if (IS_ERR(ac->newtrans)) {
                int err = PTR_ERR(ac->newtrans);
                kfree(ac);
@@ -1080,22 +1107,18 @@ int btrfs_commit_transaction_async(struct btrfs_trans_handle *trans,
        }
 
        /* take transaction reference */
-       mutex_lock(&root->fs_info->trans_mutex);
        cur_trans = trans->transaction;
        atomic_inc(&cur_trans->use_count);
-       mutex_unlock(&root->fs_info->trans_mutex);
 
        btrfs_end_transaction(trans, root);
        schedule_delayed_work(&ac->work, 0);
 
        /* wait for transaction to start and unblock */
-       mutex_lock(&root->fs_info->trans_mutex);
        if (wait_for_unblock)
                wait_current_trans_commit_start_and_unblock(root, cur_trans);
        else
                wait_current_trans_commit_start(root, cur_trans);
        put_transaction(cur_trans);
-       mutex_unlock(&root->fs_info->trans_mutex);
 
        return 0;
 }
@@ -1139,38 +1162,41 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
        ret = btrfs_run_delayed_refs(trans, root, 0);
        BUG_ON(ret);
 
-       mutex_lock(&root->fs_info->trans_mutex);
+       spin_lock(&cur_trans->commit_lock);
        if (cur_trans->in_commit) {
+               spin_unlock(&cur_trans->commit_lock);
                atomic_inc(&cur_trans->use_count);
-               mutex_unlock(&root->fs_info->trans_mutex);
                btrfs_end_transaction(trans, root);
 
                ret = wait_for_commit(root, cur_trans);
                BUG_ON(ret);
 
-               mutex_lock(&root->fs_info->trans_mutex);
                put_transaction(cur_trans);
-               mutex_unlock(&root->fs_info->trans_mutex);
 
                return 0;
        }
 
        trans->transaction->in_commit = 1;
        trans->transaction->blocked = 1;
+       spin_unlock(&cur_trans->commit_lock);
        wake_up(&root->fs_info->transaction_blocked_wait);
 
+       spin_lock(&root->fs_info->trans_lock);
        if (cur_trans->list.prev != &root->fs_info->trans_list) {
                prev_trans = list_entry(cur_trans->list.prev,
                                        struct btrfs_transaction, list);
                if (!prev_trans->commit_done) {
                        atomic_inc(&prev_trans->use_count);
-                       mutex_unlock(&root->fs_info->trans_mutex);
+                       spin_unlock(&root->fs_info->trans_lock);
 
                        wait_for_commit(root, prev_trans);
 
-                       mutex_lock(&root->fs_info->trans_mutex);
                        put_transaction(prev_trans);
+               } else {
+                       spin_unlock(&root->fs_info->trans_lock);
                }
+       } else {
+               spin_unlock(&root->fs_info->trans_lock);
        }
 
        if (now < cur_trans->start_time || now - cur_trans->start_time < 1)
@@ -1178,12 +1204,12 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
 
        do {
                int snap_pending = 0;
+
                joined = cur_trans->num_joined;
                if (!list_empty(&trans->transaction->pending_snapshots))
                        snap_pending = 1;
 
                WARN_ON(cur_trans != trans->transaction);
-               mutex_unlock(&root->fs_info->trans_mutex);
 
                if (flush_on_commit || snap_pending) {
                        btrfs_start_delalloc_inodes(root, 1);
@@ -1206,14 +1232,15 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
                prepare_to_wait(&cur_trans->writer_wait, &wait,
                                TASK_UNINTERRUPTIBLE);
 
-               smp_mb();
                if (atomic_read(&cur_trans->num_writers) > 1)
                        schedule_timeout(MAX_SCHEDULE_TIMEOUT);
                else if (should_grow)
                        schedule_timeout(1);
 
-               mutex_lock(&root->fs_info->trans_mutex);
                finish_wait(&cur_trans->writer_wait, &wait);
+               spin_lock(&root->fs_info->trans_lock);
+               root->fs_info->trans_no_join = 1;
+               spin_unlock(&root->fs_info->trans_lock);
        } while (atomic_read(&cur_trans->num_writers) > 1 ||
                 (should_grow && cur_trans->num_joined != joined));
 
@@ -1258,9 +1285,6 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
        btrfs_prepare_extent_commit(trans, root);
 
        cur_trans = root->fs_info->running_transaction;
-       spin_lock(&root->fs_info->new_trans_lock);
-       root->fs_info->running_transaction = NULL;
-       spin_unlock(&root->fs_info->new_trans_lock);
 
        btrfs_set_root_node(&root->fs_info->tree_root->root_item,
                            root->fs_info->tree_root->node);
@@ -1281,10 +1305,13 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
               sizeof(root->fs_info->super_copy));
 
        trans->transaction->blocked = 0;
+       spin_lock(&root->fs_info->trans_lock);
+       root->fs_info->running_transaction = NULL;
+       root->fs_info->trans_no_join = 0;
+       spin_unlock(&root->fs_info->trans_lock);
 
        wake_up(&root->fs_info->transaction_wait);
 
-       mutex_unlock(&root->fs_info->trans_mutex);
        ret = btrfs_write_and_wait_transaction(trans, root);
        BUG_ON(ret);
        write_ctree_super(trans, root, 0);
@@ -1297,22 +1324,21 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
 
        btrfs_finish_extent_commit(trans, root);
 
-       mutex_lock(&root->fs_info->trans_mutex);
-
        cur_trans->commit_done = 1;
 
        root->fs_info->last_trans_committed = cur_trans->transid;
 
        wake_up(&cur_trans->commit_wait);
 
+       spin_lock(&root->fs_info->trans_lock);
        list_del_init(&cur_trans->list);
+       spin_unlock(&root->fs_info->trans_lock);
+
        put_transaction(cur_trans);
        put_transaction(cur_trans);
 
        trace_btrfs_transaction_commit(root);
 
-       mutex_unlock(&root->fs_info->trans_mutex);
-
        btrfs_scrub_continue(root);
 
        if (current->journal_info == trans)
@@ -1334,9 +1360,9 @@ int btrfs_clean_old_snapshots(struct btrfs_root *root)
        LIST_HEAD(list);
        struct btrfs_fs_info *fs_info = root->fs_info;
 
-       mutex_lock(&fs_info->trans_mutex);
+       spin_lock(&fs_info->trans_lock);
        list_splice_init(&fs_info->dead_roots, &list);
-       mutex_unlock(&fs_info->trans_mutex);
+       spin_unlock(&fs_info->trans_lock);
 
        while (!list_empty(&list)) {
                root = list_entry(list.next, struct btrfs_root, root_list);
index 804c88639e5de00a4065267aaf52d050dd88303c..02564e6230acd672b5fa6539cc88890417204e41 100644 (file)
@@ -28,10 +28,12 @@ struct btrfs_transaction {
         * transaction can end
         */
        atomic_t num_writers;
+       atomic_t use_count;
 
        unsigned long num_joined;
+
+       spinlock_t commit_lock;
        int in_commit;
-       atomic_t use_count;
        int commit_done;
        int blocked;
        struct list_head list;
@@ -45,13 +47,14 @@ struct btrfs_transaction {
 
 struct btrfs_trans_handle {
        u64 transid;
-       u64 block_group;
        u64 bytes_reserved;
+       unsigned long use_count;
        unsigned long blocks_reserved;
        unsigned long blocks_used;
        unsigned long delayed_ref_updates;
        struct btrfs_transaction *transaction;
        struct btrfs_block_rsv *block_rsv;
+       struct btrfs_block_rsv *orig_rsv;
 };
 
 struct btrfs_pending_snapshot {
@@ -66,19 +69,6 @@ struct btrfs_pending_snapshot {
        struct list_head list;
 };
 
-static inline void btrfs_set_trans_block_group(struct btrfs_trans_handle *trans,
-                                              struct inode *inode)
-{
-       trans->block_group = BTRFS_I(inode)->block_group;
-}
-
-static inline void btrfs_update_inode_block_group(
-                                         struct btrfs_trans_handle *trans,
-                                         struct inode *inode)
-{
-       BTRFS_I(inode)->block_group = trans->block_group;
-}
-
 static inline void btrfs_set_inode_last_trans(struct btrfs_trans_handle *trans,
                                              struct inode *inode)
 {
@@ -92,12 +82,9 @@ int btrfs_end_transaction_nolock(struct btrfs_trans_handle *trans,
                                 struct btrfs_root *root);
 struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root,
                                                   int num_items);
-struct btrfs_trans_handle *btrfs_join_transaction(struct btrfs_root *root,
-                                                 int num_blocks);
-struct btrfs_trans_handle *btrfs_join_transaction_nolock(struct btrfs_root *root,
-                                                         int num_blocks);
-struct btrfs_trans_handle *btrfs_start_ioctl_transaction(struct btrfs_root *r,
-                                                        int num_blocks);
+struct btrfs_trans_handle *btrfs_join_transaction(struct btrfs_root *root);
+struct btrfs_trans_handle *btrfs_join_transaction_nolock(struct btrfs_root *root);
+struct btrfs_trans_handle *btrfs_start_ioctl_transaction(struct btrfs_root *root);
 int btrfs_wait_for_commit(struct btrfs_root *root, u64 transid);
 int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans,
                                     struct btrfs_root *root);
index c48214ef5c09611100590c75f1eed8c8f0547e04..da541dfca2e335c2419242b44d7a3fbaa9ccc300 100644 (file)
@@ -504,7 +504,7 @@ static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices)
                BUG_ON(!new_device);
                memcpy(new_device, device, sizeof(*new_device));
                new_device->name = kstrdup(device->name, GFP_NOFS);
-               BUG_ON(!new_device->name);
+               BUG_ON(device->name && !new_device->name);
                new_device->bdev = NULL;
                new_device->writeable = 0;
                new_device->in_fs_metadata = 0;
index f3107e4b4d56a3d4b31a5f889ff321328e881978..5366fe452ab07db7402402e96351c1b956809e20 100644 (file)
@@ -158,8 +158,6 @@ int __btrfs_setxattr(struct btrfs_trans_handle *trans,
        if (IS_ERR(trans))
                return PTR_ERR(trans);
 
-       btrfs_set_trans_block_group(trans, inode);
-
        ret = do_setxattr(trans, inode, name, value, size, flags);
        if (ret)
                goto out;
index 1cd4c3a1862d72491432bd4a017782e78b331dcd..53ed1ad2c112808ea27c92dce5fff5ebefad8651 100644 (file)
@@ -7,6 +7,7 @@ config CIFS
        select CRYPTO_MD5
        select CRYPTO_HMAC
        select CRYPTO_ARC4
+       select CRYPTO_ECB
        select CRYPTO_DES
        help
          This is the client VFS module for the Common Internet File System
@@ -148,7 +149,7 @@ config CIFS_FSCACHE
 
 config CIFS_ACL
          bool "Provide CIFS ACL support (EXPERIMENTAL)"
-         depends on EXPERIMENTAL && CIFS_XATTR
+         depends on EXPERIMENTAL && CIFS_XATTR && KEYS
          help
            Allows to fetch CIFS/NTFS ACL from the server.  The DACL blob
            is handed over to the application/caller.
index dfbd9f1f373daa9b39adeb852595438af0c4177b..5a0ee7f2af062a68fdec065c43099274486c1b2d 100644 (file)
@@ -184,7 +184,7 @@ int cifs_verify_signature(struct smb_hdr *cifs_pdu,
        if (cifs_pdu == NULL || server == NULL)
                return -EINVAL;
 
-       if (cifs_pdu->Command == SMB_COM_NEGOTIATE)
+       if (!server->session_estab)
                return 0;
 
        if (cifs_pdu->Command == SMB_COM_LOCKING_ANDX) {
index 6d88b82537c3d4cf899a5741c114bb50c61ad564..bb659eb738100036dc726790b7be947df253cb27 100644 (file)
@@ -784,7 +784,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
                         struct smb_vol *vol)
 {
        char *value, *data, *end;
-       char *mountdata_copy, *options;
+       char *mountdata_copy = NULL, *options;
        unsigned int  temp_len, i, j;
        char separator[2];
        short int override_uid = -1;
@@ -1391,7 +1391,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
                                "/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"
+                       cERROR(1, "FS-Cache support needs CONFIG_CIFS_FSCACHE "
                                  "kernel config option set");
                        goto cifs_parse_mount_err;
 #endif
@@ -1976,7 +1976,7 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
                warned_on_ntlm = true;
                cERROR(1, "default security mechanism requested.  The default "
                        "security mechanism will be upgraded from ntlm to "
-                       "ntlmv2 in kernel release 2.6.41");
+                       "ntlmv2 in kernel release 3.1");
        }
        ses->overrideSecFlg = volume_info->secFlg;
 
index ea5f748906a83218eae60cbb241aaab53cec8ac8..97e0d52d72fdd65a365f3cab7027ae22c230582e 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1093,6 +1093,7 @@ int flush_old_exec(struct linux_binprm * bprm)
 
        bprm->mm = NULL;                /* We're using it now */
 
+       set_fs(USER_DS);
        current->flags &= ~(PF_RANDOMIZE | PF_KTHREAD);
        flush_thread();
        current->personality &= ~bprm->per_clear;
@@ -1357,10 +1358,6 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
        if (retval)
                return retval;
 
-       /* kernel module loader fixup */
-       /* so we don't try to load run modprobe in kernel space. */
-       set_fs(USER_DS);
-
        retval = audit_bprm(bprm);
        if (retval)
                return retval;
index 7257752b6d5d3f0c8c133597135cb2f92821f784..7018e1d8902dee6c4b38f7247a38e9315cba27f5 100644 (file)
@@ -102,7 +102,7 @@ static int fat_ioctl_set_attributes(struct file *file, u32 __user *user_attr)
                if (attr & ATTR_SYS)
                        inode->i_flags |= S_IMMUTABLE;
                else
-                       inode->i_flags &= S_IMMUTABLE;
+                       inode->i_flags &= ~S_IMMUTABLE;
        }
 
        fat_save_attrs(inode, attr);
index cc6ec4b2f0ffed9c05959b149614a8a1e19e467d..38f84cd48b67d057798f8f75fe5c8f22f12b10dc 100644 (file)
@@ -921,6 +921,8 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
        if (sb->s_flags & MS_MANDLOCK)
                goto err;
 
+       sb->s_flags &= ~MS_NOSEC;
+
        if (!parse_fuse_opt((char *) data, &d, is_bdev))
                goto err;
 
index 2792a790e50ba9ae2eae255eccc68e47f39d9501..1c1336e7b3b222d347f657fa2895ddc1c2f05c65 100644 (file)
@@ -663,14 +663,19 @@ static void glock_work_func(struct work_struct *work)
                drop_ref = 1;
        }
        spin_lock(&gl->gl_spin);
-       if (test_and_clear_bit(GLF_PENDING_DEMOTE, &gl->gl_flags) &&
+       if (test_bit(GLF_PENDING_DEMOTE, &gl->gl_flags) &&
            gl->gl_state != LM_ST_UNLOCKED &&
            gl->gl_demote_state != LM_ST_EXCLUSIVE) {
                unsigned long holdtime, now = jiffies;
+
                holdtime = gl->gl_tchange + gl->gl_ops->go_min_hold_time;
                if (time_before(now, holdtime))
                        delay = holdtime - now;
-               set_bit(delay ? GLF_PENDING_DEMOTE : GLF_DEMOTE, &gl->gl_flags);
+
+               if (!delay) {
+                       clear_bit(GLF_PENDING_DEMOTE, &gl->gl_flags);
+                       set_bit(GLF_DEMOTE, &gl->gl_flags);
+               }
        }
        run_queue(gl, 0);
        spin_unlock(&gl->gl_spin);
index 278e3fb40b71e259b3eab7492fcebbd2c2a033e2..583636f745e59dbe7e66e1b3871496ac3b29a63d 100644 (file)
@@ -1123,7 +1123,7 @@ int lmLogOpen(struct super_block *sb)
        bdev = blkdev_get_by_dev(sbi->logdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL,
                                 log);
        if (IS_ERR(bdev)) {
-               rc = -PTR_ERR(bdev);
+               rc = PTR_ERR(bdev);
                goto free;
        }
 
index 1ab641f2e78ebdddff0306073ddbb0d06685f004..9802345df5e78c86396fa05f4c29c760e3a270a9 100644 (file)
@@ -2579,6 +2579,7 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry)
        if (error)
                goto out;
 
+       shrink_dcache_parent(dentry);
        error = dir->i_op->rmdir(dir, dentry);
        if (error)
                goto out;
@@ -2623,6 +2624,10 @@ static long do_rmdir(int dfd, const char __user *pathname)
        error = PTR_ERR(dentry);
        if (IS_ERR(dentry))
                goto exit2;
+       if (!dentry->d_inode) {
+               error = -ENOENT;
+               goto exit3;
+       }
        error = mnt_want_write(nd.path.mnt);
        if (error)
                goto exit3;
@@ -2708,11 +2713,10 @@ static long do_unlinkat(int dfd, const char __user *pathname)
        error = PTR_ERR(dentry);
        if (!IS_ERR(dentry)) {
                /* Why not before? Because we want correct error value */
-               if (nd.last.name[nd.last.len])
-                       goto slashes;
                inode = dentry->d_inode;
-               if (inode)
-                       ihold(inode);
+               if (nd.last.name[nd.last.len] || !inode)
+                       goto slashes;
+               ihold(inode);
                error = mnt_want_write(nd.path.mnt);
                if (error)
                        goto exit2;
@@ -2993,6 +2997,8 @@ static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
        if (d_mountpoint(old_dentry) || d_mountpoint(new_dentry))
                goto out;
 
+       if (target)
+               shrink_dcache_parent(new_dentry);
        error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
        if (error)
                goto out;
index cdbaf5e97308f3564af7820c575c591e3cfcbf95..56f61027236b696fce1ccde3e1edaf86acee59a0 100644 (file)
@@ -1072,7 +1072,7 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
 
        sb->s_magic = OCFS2_SUPER_MAGIC;
 
-       sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
+       sb->s_flags = (sb->s_flags & ~(MS_POSIXACL | MS_NOSEC)) |
                ((osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
 
        /* Hard readonly mode only if: bdev_read_only, MS_RDONLY,
index f82e762eeca277683a49b23e4ce9534d29a672de..d545e97d99c3390706894ff1b030c2491a2c0a38 100644 (file)
@@ -255,13 +255,7 @@ ssize_t part_discard_alignment_show(struct device *dev,
                                   struct device_attribute *attr, char *buf)
 {
        struct hd_struct *p = dev_to_part(dev);
-       struct gendisk *disk = dev_to_disk(dev);
-       unsigned int alignment = 0;
-
-       if (disk->queue)
-               alignment = queue_limit_discard_alignment(&disk->queue->limits,
-                                                               p->start_sect);
-       return sprintf(buf, "%u\n", alignment);
+       return sprintf(buf, "%u\n", p->discard_alignment);
 }
 
 ssize_t part_stat_show(struct device *dev,
@@ -455,6 +449,8 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno,
        p->start_sect = start;
        p->alignment_offset =
                queue_limit_alignment_offset(&disk->queue->limits, start);
+       p->discard_alignment =
+               queue_limit_discard_alignment(&disk->queue->limits, start);
        p->nr_sects = len;
        p->partno = partno;
        p->policy = get_disk_ro(disk);
index c75593953c5275eb89b56b08358d25830728cf1e..ab3d672db0deae0a84a01bc1938cd967cc27e79f 100644 (file)
@@ -822,7 +822,7 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
        } else {
                char b[BDEVNAME_SIZE];
 
-               s->s_flags = flags;
+               s->s_flags = flags | MS_NOSEC;
                s->s_mode = mode;
                strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id));
                sb_set_blocksize(s, block_size(bdev));
index 166951e0dcd3c7b1dc232102c74bf8b8d61e8c1e..3be645e012c9358170ad45a87af3b83b8fbd72ca 100644 (file)
@@ -581,6 +581,7 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len)
        ubifs_assert(wbuf->size % c->min_io_size == 0);
        ubifs_assert(mutex_is_locked(&wbuf->io_mutex));
        ubifs_assert(!c->ro_media && !c->ro_mount);
+       ubifs_assert(!c->space_fixup);
        if (c->leb_size - wbuf->offs >= c->max_write_size)
                ubifs_assert(!((wbuf->offs + wbuf->size) % c->max_write_size));
 
@@ -759,6 +760,7 @@ int ubifs_write_node(struct ubifs_info *c, void *buf, int len, int lnum,
        ubifs_assert(lnum >= 0 && lnum < c->leb_cnt && offs >= 0);
        ubifs_assert(offs % c->min_io_size == 0 && offs < c->leb_size);
        ubifs_assert(!c->ro_media && !c->ro_mount);
+       ubifs_assert(!c->space_fixup);
 
        if (c->ro_error)
                return -EROFS;
index 34b1679e6e3a671684a1f08be42e155ce4a48ded..cef0460f4c54651bbe5c432d8fc4e3307ee45d07 100644 (file)
@@ -669,6 +669,7 @@ out_free:
 
 out_release:
        release_head(c, BASEHD);
+       kfree(dent);
 out_ro:
        ubifs_ro_mode(c, err);
        if (last_reference)
index bd644bf587a8a7afbef10b83fdef31f4cb71fdf3..a5422fffbd69e10a11b27143feab3cc6a7d7f3f5 100644 (file)
@@ -674,7 +674,7 @@ static int kill_orphans(struct ubifs_info *c)
                if (IS_ERR(sleb)) {
                        if (PTR_ERR(sleb) == -EUCLEAN)
                                sleb = ubifs_recover_leb(c, lnum, 0,
-                                                        c->sbuf, 0);
+                                                        c->sbuf, -1);
                        if (IS_ERR(sleb)) {
                                err = PTR_ERR(sleb);
                                break;
index 731d9e2e7b50c848bf6088237922c43e0f00ef88..783d8e0beb76b59da67c2509d0371b194f994045 100644 (file)
@@ -564,19 +564,15 @@ static int fix_unclean_leb(struct ubifs_info *c, struct ubifs_scan_leb *sleb,
 }
 
 /**
- * drop_last_node - drop the last node or group of nodes.
+ * drop_last_group - drop the last group of nodes.
  * @sleb: scanned LEB information
  * @offs: offset of dropped nodes is returned here
- * @grouped: non-zero if whole group of nodes have to be dropped
  *
  * This is a helper function for 'ubifs_recover_leb()' which drops the last
- * node of the scanned LEB or the last group of nodes if @grouped is not zero.
- * This function returns %1 if a node was dropped and %0 otherwise.
+ * group of nodes of the scanned LEB.
  */
-static int drop_last_node(struct ubifs_scan_leb *sleb, int *offs, int grouped)
+static void drop_last_group(struct ubifs_scan_leb *sleb, int *offs)
 {
-       int dropped = 0;
-
        while (!list_empty(&sleb->nodes)) {
                struct ubifs_scan_node *snod;
                struct ubifs_ch *ch;
@@ -585,17 +581,40 @@ static int drop_last_node(struct ubifs_scan_leb *sleb, int *offs, int grouped)
                                  list);
                ch = snod->node;
                if (ch->group_type != UBIFS_IN_NODE_GROUP)
-                       return dropped;
-               dbg_rcvry("dropping node at %d:%d", sleb->lnum, snod->offs);
+                       break;
+
+               dbg_rcvry("dropping grouped node at %d:%d",
+                         sleb->lnum, snod->offs);
+               *offs = snod->offs;
+               list_del(&snod->list);
+               kfree(snod);
+               sleb->nodes_cnt -= 1;
+       }
+}
+
+/**
+ * drop_last_node - drop the last node.
+ * @sleb: scanned LEB information
+ * @offs: offset of dropped nodes is returned here
+ * @grouped: non-zero if whole group of nodes have to be dropped
+ *
+ * This is a helper function for 'ubifs_recover_leb()' which drops the last
+ * node of the scanned LEB.
+ */
+static void drop_last_node(struct ubifs_scan_leb *sleb, int *offs)
+{
+       struct ubifs_scan_node *snod;
+
+       if (!list_empty(&sleb->nodes)) {
+               snod = list_entry(sleb->nodes.prev, struct ubifs_scan_node,
+                                 list);
+
+               dbg_rcvry("dropping last node at %d:%d", sleb->lnum, snod->offs);
                *offs = snod->offs;
                list_del(&snod->list);
                kfree(snod);
                sleb->nodes_cnt -= 1;
-               dropped = 1;
-               if (!grouped)
-                       break;
        }
-       return dropped;
 }
 
 /**
@@ -604,7 +623,8 @@ static int drop_last_node(struct ubifs_scan_leb *sleb, int *offs, int grouped)
  * @lnum: LEB number
  * @offs: offset
  * @sbuf: LEB-sized buffer to use
- * @grouped: nodes may be grouped for recovery
+ * @jhead: journal head number this LEB belongs to (%-1 if the LEB does not
+ *         belong to any journal head)
  *
  * This function does a scan of a LEB, but caters for errors that might have
  * been caused by the unclean unmount from which we are attempting to recover.
@@ -612,13 +632,14 @@ static int drop_last_node(struct ubifs_scan_leb *sleb, int *offs, int grouped)
  * found, and a negative error code in case of failure.
  */
 struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum,
-                                        int offs, void *sbuf, int grouped)
+                                        int offs, void *sbuf, int jhead)
 {
        int ret = 0, err, len = c->leb_size - offs, start = offs, min_io_unit;
+       int grouped = jhead == -1 ? 0 : c->jheads[jhead].grouped;
        struct ubifs_scan_leb *sleb;
        void *buf = sbuf + offs;
 
-       dbg_rcvry("%d:%d", lnum, offs);
+       dbg_rcvry("%d:%d, jhead %d, grouped %d", lnum, offs, jhead, grouped);
 
        sleb = ubifs_start_scan(c, lnum, offs, sbuf);
        if (IS_ERR(sleb))
@@ -635,7 +656,7 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum,
                 * Scan quietly until there is an error from which we cannot
                 * recover
                 */
-               ret = ubifs_scan_a_node(c, buf, len, lnum, offs, 0);
+               ret = ubifs_scan_a_node(c, buf, len, lnum, offs, 1);
                if (ret == SCANNED_A_NODE) {
                        /* A valid node, and not a padding node */
                        struct ubifs_ch *ch = buf;
@@ -695,59 +716,62 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum,
                 * If nodes are grouped, always drop the incomplete group at
                 * the end.
                 */
-               drop_last_node(sleb, &offs, 1);
+               drop_last_group(sleb, &offs);
 
-       /*
-        * While we are in the middle of the same min. I/O unit keep dropping
-        * nodes. So basically, what we want is to make sure that the last min.
-        * I/O unit where we saw the corruption is dropped completely with all
-        * the uncorrupted node which may possibly sit there.
-        *
-        * In other words, let's name the min. I/O unit where the corruption
-        * starts B, and the previous min. I/O unit A. The below code tries to
-        * deal with a situation when half of B contains valid nodes or the end
-        * of a valid node, and the second half of B contains corrupted data or
-        * garbage. This means that UBIFS had been writing to B just before the
-        * power cut happened. I do not know how realistic is this scenario
-        * that half of the min. I/O unit had been written successfully and the
-        * other half not, but this is possible in our 'failure mode emulation'
-        * infrastructure at least.
-        *
-        * So what is the problem, why we need to drop those nodes? Whey can't
-        * we just clean-up the second half of B by putting a padding node
-        * there? We can, and this works fine with one exception which was
-        * reproduced with power cut emulation testing and happens extremely
-        * rarely. The description follows, but it is worth noting that that is
-        * only about the GC head, so we could do this trick only if the bud
-        * belongs to the GC head, but it does not seem to be worth an
-        * additional "if" statement.
-        *
-        * So, imagine the file-system is full, we run GC which is moving valid
-        * nodes from LEB X to LEB Y (obviously, LEB Y is the current GC head
-        * LEB). The @c->gc_lnum is -1, which means that GC will retain LEB X
-        * and will try to continue. Imagine that LEB X is currently the
-        * dirtiest LEB, and the amount of used space in LEB Y is exactly the
-        * same as amount of free space in LEB X.
-        *
-        * And a power cut happens when nodes are moved from LEB X to LEB Y. We
-        * are here trying to recover LEB Y which is the GC head LEB. We find
-        * the min. I/O unit B as described above. Then we clean-up LEB Y by
-        * padding min. I/O unit. And later 'ubifs_rcvry_gc_commit()' function
-        * fails, because it cannot find a dirty LEB which could be GC'd into
-        * LEB Y! Even LEB X does not match because the amount of valid nodes
-        * there does not fit the free space in LEB Y any more! And this is
-        * because of the padding node which we added to LEB Y. The
-        * user-visible effect of this which I once observed and analysed is
-        * that we cannot mount the file-system with -ENOSPC error.
-        *
-        * So obviously, to make sure that situation does not happen we should
-        * free min. I/O unit B in LEB Y completely and the last used min. I/O
-        * unit in LEB Y should be A. This is basically what the below code
-        * tries to do.
-        */
-       while (min_io_unit == round_down(offs, c->min_io_size) &&
-              min_io_unit != offs &&
-              drop_last_node(sleb, &offs, grouped));
+       if (jhead == GCHD) {
+               /*
+                * If this LEB belongs to the GC head then while we are in the
+                * middle of the same min. I/O unit keep dropping nodes. So
+                * basically, what we want is to make sure that the last min.
+                * I/O unit where we saw the corruption is dropped completely
+                * with all the uncorrupted nodes which may possibly sit there.
+                *
+                * In other words, let's name the min. I/O unit where the
+                * corruption starts B, and the previous min. I/O unit A. The
+                * below code tries to deal with a situation when half of B
+                * contains valid nodes or the end of a valid node, and the
+                * second half of B contains corrupted data or garbage. This
+                * means that UBIFS had been writing to B just before the power
+                * cut happened. I do not know how realistic is this scenario
+                * that half of the min. I/O unit had been written successfully
+                * and the other half not, but this is possible in our 'failure
+                * mode emulation' infrastructure at least.
+                *
+                * So what is the problem, why we need to drop those nodes? Why
+                * can't we just clean-up the second half of B by putting a
+                * padding node there? We can, and this works fine with one
+                * exception which was reproduced with power cut emulation
+                * testing and happens extremely rarely.
+                *
+                * Imagine the file-system is full, we run GC which starts
+                * moving valid nodes from LEB X to LEB Y (obviously, LEB Y is
+                * the current GC head LEB). The @c->gc_lnum is -1, which means
+                * that GC will retain LEB X and will try to continue. Imagine
+                * that LEB X is currently the dirtiest LEB, and the amount of
+                * used space in LEB Y is exactly the same as amount of free
+                * space in LEB X.
+                *
+                * And a power cut happens when nodes are moved from LEB X to
+                * LEB Y. We are here trying to recover LEB Y which is the GC
+                * head LEB. We find the min. I/O unit B as described above.
+                * Then we clean-up LEB Y by padding min. I/O unit. And later
+                * 'ubifs_rcvry_gc_commit()' function fails, because it cannot
+                * find a dirty LEB which could be GC'd into LEB Y! Even LEB X
+                * does not match because the amount of valid nodes there does
+                * not fit the free space in LEB Y any more! And this is
+                * because of the padding node which we added to LEB Y. The
+                * user-visible effect of this which I once observed and
+                * analysed is that we cannot mount the file-system with
+                * -ENOSPC error.
+                *
+                * So obviously, to make sure that situation does not happen we
+                * should free min. I/O unit B in LEB Y completely and the last
+                * used min. I/O unit in LEB Y should be A. This is basically
+                * what the below code tries to do.
+                */
+               while (offs > min_io_unit)
+                       drop_last_node(sleb, &offs);
+       }
 
        buf = sbuf + offs;
        len = c->leb_size - offs;
@@ -881,7 +905,7 @@ struct ubifs_scan_leb *ubifs_recover_log_leb(struct ubifs_info *c, int lnum,
                }
                ubifs_scan_destroy(sleb);
        }
-       return ubifs_recover_leb(c, lnum, offs, sbuf, 0);
+       return ubifs_recover_leb(c, lnum, offs, sbuf, -1);
 }
 
 /**
index 6617280d167938a7bbf8f925c1af0fe0986c8496..5e97161ce4d35f929a953184098057f37454dde2 100644 (file)
@@ -557,8 +557,7 @@ static int replay_bud(struct ubifs_info *c, struct bud_entry *b)
                 * these LEBs could possibly be written to at the power cut
                 * time.
                 */
-               sleb = ubifs_recover_leb(c, lnum, offs, c->sbuf,
-                                        b->bud->jhead != GCHD);
+               sleb = ubifs_recover_leb(c, lnum, offs, c->sbuf, b->bud->jhead);
        else
                sleb = ubifs_scan(c, lnum, offs, c->sbuf, 0);
        if (IS_ERR(sleb))
index ca953a945029ad38ab770845e80b165f8d09a8e2..9e1d05666fed5d1ad03589995f8ecb3f78ec7b82 100644 (file)
@@ -284,7 +284,11 @@ int ubifs_shrinker(struct shrinker *shrink, struct shrink_control *sc)
        long clean_zn_cnt = atomic_long_read(&ubifs_clean_zn_cnt);
 
        if (nr == 0)
-               return clean_zn_cnt;
+               /*
+                * Due to the way UBIFS updates the clean znode counter it may
+                * temporarily be negative.
+                */
+               return clean_zn_cnt >= 0 ? clean_zn_cnt : 1;
 
        if (!clean_zn_cnt) {
                /*
index 1ab0d22e4c941cd74db7c5486ea05e94b8b7a427..b5aeb5a8ebed11f0448c8ff8ed20db57b5178a69 100644 (file)
@@ -811,15 +811,18 @@ static int alloc_wbufs(struct ubifs_info *c)
 
                c->jheads[i].wbuf.sync_callback = &bud_wbuf_callback;
                c->jheads[i].wbuf.jhead = i;
+               c->jheads[i].grouped = 1;
        }
 
        c->jheads[BASEHD].wbuf.dtype = UBI_SHORTTERM;
        /*
         * Garbage Collector head likely contains long-term data and
-        * does not need to be synchronized by timer.
+        * does not need to be synchronized by timer. Also GC head nodes are
+        * not grouped.
         */
        c->jheads[GCHD].wbuf.dtype = UBI_LONGTERM;
        c->jheads[GCHD].wbuf.no_timer = 1;
+       c->jheads[GCHD].grouped = 0;
 
        return 0;
 }
@@ -1284,12 +1287,25 @@ static int mount_ubifs(struct ubifs_info *c)
        if ((c->mst_node->flags & cpu_to_le32(UBIFS_MST_DIRTY)) != 0) {
                ubifs_msg("recovery needed");
                c->need_recovery = 1;
-               if (!c->ro_mount) {
-                       err = ubifs_recover_inl_heads(c, c->sbuf);
-                       if (err)
-                               goto out_master;
-               }
-       } else if (!c->ro_mount) {
+       }
+
+       if (c->need_recovery && !c->ro_mount) {
+               err = ubifs_recover_inl_heads(c, c->sbuf);
+               if (err)
+                       goto out_master;
+       }
+
+       err = ubifs_lpt_init(c, 1, !c->ro_mount);
+       if (err)
+               goto out_master;
+
+       if (!c->ro_mount && c->space_fixup) {
+               err = ubifs_fixup_free_space(c);
+               if (err)
+                       goto out_master;
+       }
+
+       if (!c->ro_mount) {
                /*
                 * Set the "dirty" flag so that if we reboot uncleanly we
                 * will notice this immediately on the next mount.
@@ -1297,13 +1313,9 @@ static int mount_ubifs(struct ubifs_info *c)
                c->mst_node->flags |= cpu_to_le32(UBIFS_MST_DIRTY);
                err = ubifs_write_master(c);
                if (err)
-                       goto out_master;
+                       goto out_lpt;
        }
 
-       err = ubifs_lpt_init(c, 1, !c->ro_mount);
-       if (err)
-               goto out_lpt;
-
        err = dbg_check_idx_size(c, c->bi.old_idx_sz);
        if (err)
                goto out_lpt;
@@ -1396,12 +1408,6 @@ static int mount_ubifs(struct ubifs_info *c)
        } else
                ubifs_assert(c->lst.taken_empty_lebs > 0);
 
-       if (!c->ro_mount && c->space_fixup) {
-               err = ubifs_fixup_free_space(c);
-               if (err)
-                       goto out_infos;
-       }
-
        err = dbg_check_filesystem(c);
        if (err)
                goto out_infos;
index 8119b1fd8d94b9be59320e1c31e1d5b41d050dc1..91b4213dde84d11934fc32741b2f902d76a1a84e 100644 (file)
@@ -2876,12 +2876,13 @@ static void tnc_destroy_cnext(struct ubifs_info *c)
  */
 void ubifs_tnc_close(struct ubifs_info *c)
 {
-       long clean_freed;
-
        tnc_destroy_cnext(c);
        if (c->zroot.znode) {
-               clean_freed = ubifs_destroy_tnc_subtree(c->zroot.znode);
-               atomic_long_sub(clean_freed, &ubifs_clean_zn_cnt);
+               long n;
+
+               ubifs_destroy_tnc_subtree(c->zroot.znode);
+               n = atomic_long_read(&c->clean_zn_cnt);
+               atomic_long_sub(n, &ubifs_clean_zn_cnt);
        }
        kfree(c->gap_lebs);
        kfree(c->ilebs);
index a70d7b4ffb25e0c37af1cec0e22793b64d33a305..f79983d6f860eb43ec766dab9b6b044f1e23dd7b 100644 (file)
@@ -722,12 +722,14 @@ struct ubifs_bud {
  * struct ubifs_jhead - journal head.
  * @wbuf: head's write-buffer
  * @buds_list: list of bud LEBs belonging to this journal head
+ * @grouped: non-zero if UBIFS groups nodes when writing to this journal head
  *
  * Note, the @buds list is protected by the @c->buds_lock.
  */
 struct ubifs_jhead {
        struct ubifs_wbuf wbuf;
        struct list_head buds_list;
+       unsigned int grouped:1;
 };
 
 /**
@@ -1742,7 +1744,7 @@ struct inode *ubifs_iget(struct super_block *sb, unsigned long inum);
 int ubifs_recover_master_node(struct ubifs_info *c);
 int ubifs_write_rcvrd_mst_node(struct ubifs_info *c);
 struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum,
-                                        int offs, void *sbuf, int grouped);
+                                        int offs, void *sbuf, int jhead);
 struct ubifs_scan_leb *ubifs_recover_log_leb(struct ubifs_info *c, int lnum,
                                             int offs, void *sbuf);
 int ubifs_recover_inl_heads(const struct ubifs_info *c, void *sbuf);
index ae90e0f63995d39f0bf90e3dd86d222042e3f413..4f76959397fa88a869dff276ba5ab0ccc9494071 100644 (file)
@@ -683,9 +683,11 @@ __SC_COMP(__NR_clock_adjtime, sys_clock_adjtime, compat_sys_clock_adjtime)
 __SYSCALL(__NR_syncfs, sys_syncfs)
 #define __NR_setns 268
 __SYSCALL(__NR_setns, sys_setns)
+#define __NR_sendmmsg 269
+__SC_COMP(__NR_sendmmsg, sys_sendmmsg, compat_sys_sendmmsg)
 
 #undef __NR_syscalls
-#define __NR_syscalls 269
+#define __NR_syscalls 270
 
 /*
  * All syscalls below here should go away really,
index f04b2a3b0f49b7117cb74163af0997a7a6fd4742..e08f344c6cffc546660506b37e8659679ac78211 100644 (file)
        {0x1002, 0x9614, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS780|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
        {0x1002, 0x9615, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS780|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
        {0x1002, 0x9616, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS780|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
+       {0x1002, 0x9640, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SUMO|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
+       {0x1002, 0x9641, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SUMO|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
+       {0x1002, 0x9642, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SUMO2|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
+       {0x1002, 0x9643, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SUMO2|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
+       {0x1002, 0x9644, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SUMO2|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
+       {0x1002, 0x9645, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SUMO2|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
+       {0x1002, 0x9647, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SUMO|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP},\
+       {0x1002, 0x9648, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SUMO|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP},\
+       {0x1002, 0x964a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SUMO|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
+       {0x1002, 0x964e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SUMO|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP},\
+       {0x1002, 0x964f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SUMO|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP},\
        {0x1002, 0x9710, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS880|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
        {0x1002, 0x9711, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS880|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
        {0x1002, 0x9712, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS880|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
index ae9091a684807ffcc95fa6c0fb6de3233383d4cf..1a23722e8878619aec4017cbbd31b951439fdb2b 100644 (file)
@@ -1282,8 +1282,8 @@ queue_max_integrity_segments(struct request_queue *q)
 #define blk_get_integrity(a)                   (0)
 #define blk_integrity_compare(a, b)            (0)
 #define blk_integrity_register(a, b)           (0)
-#define blk_integrity_unregister(a)            do { } while (0);
-#define blk_queue_max_integrity_segments(a, b) do { } while (0);
+#define blk_integrity_unregister(a)            do { } while (0)
+#define blk_queue_max_integrity_segments(a, b) do { } while (0)
 #define queue_max_integrity_segments(a)                (0)
 #define blk_integrity_merge_rq(a, b, c)                (0)
 #define blk_integrity_merge_bio(a, b, c)       (0)
index 5619f8522738b44f3318392da050e7ef9f246020..bbd8661b34736f80e392f05d8b0fcdeff5fdf067 100644 (file)
@@ -9,8 +9,12 @@
 #define VTD_PAGE_MASK          (((u64)-1) << VTD_PAGE_SHIFT)
 #define VTD_PAGE_ALIGN(addr)   (((addr) + VTD_PAGE_SIZE - 1) & VTD_PAGE_MASK)
 
+#define VTD_STRIDE_SHIFT        (9)
+#define VTD_STRIDE_MASK         (((u64)-1) << VTD_STRIDE_SHIFT)
+
 #define DMA_PTE_READ (1)
 #define DMA_PTE_WRITE (2)
+#define DMA_PTE_LARGE_PAGE (1 << 7)
 #define DMA_PTE_SNP (1 << 11)
 
 #define CONTEXT_TT_MULTI_LEVEL 0
index c55d6b7cd5d686fdf4165c1cf1ccffba67e3b207..1c777878f1ea5d375be6f04f3364ac2fb9d6c8ba 100644 (file)
@@ -208,6 +208,7 @@ struct inodes_stat_t {
 #define MS_KERNMOUNT   (1<<22) /* this is a kern_mount call */
 #define MS_I_VERSION   (1<<23) /* Update inode I_version field */
 #define MS_STRICTATIME (1<<24) /* Always perform atime updates */
+#define MS_NOSEC       (1<<28)
 #define MS_BORN                (1<<29)
 #define MS_ACTIVE      (1<<30)
 #define MS_NOUSER      (1<<31)
@@ -743,9 +744,13 @@ struct inode {
 
        spinlock_t              i_lock; /* i_blocks, i_bytes, maybe i_size */
        unsigned int            i_flags;
+       unsigned int            i_state;
+#ifdef CONFIG_SECURITY
+       void                    *i_security;
+#endif
        struct mutex            i_mutex;
 
-       unsigned long           i_state;
+
        unsigned long           dirtied_when;   /* jiffies of first dirtying */
 
        struct hlist_node       i_hash;
@@ -797,9 +802,6 @@ struct inode {
        atomic_t                i_readcount; /* struct files open RO */
 #endif
        atomic_t                i_writecount;
-#ifdef CONFIG_SECURITY
-       void                    *i_security;
-#endif
 #ifdef CONFIG_FS_POSIX_ACL
        struct posix_acl        *i_acl;
        struct posix_acl        *i_default_acl;
@@ -2591,7 +2593,7 @@ static inline int is_sxid(mode_t mode)
 
 static inline void inode_has_no_xattr(struct inode *inode)
 {
-       if (!is_sxid(inode->i_mode))
+       if (!is_sxid(inode->i_mode) && (inode->i_sb->s_flags & MS_NOSEC))
                inode->i_flags |= S_NOSEC;
 }
 
index b78956b3c2e749076078cf74e439144c447c9058..300d7582006e49f6ea08a3df09fc9070748c5256 100644 (file)
@@ -100,6 +100,7 @@ struct hd_struct {
        sector_t start_sect;
        sector_t nr_sects;
        sector_t alignment_offset;
+       unsigned int discard_alignment;
        struct device __dev;
        struct kobject *holder_dir;
        int policy, partno;
index b2eee5879883b3fbaf4d00ce28330320c03a9213..bf56b6f78270e6a60a63e4870295006a07ca23d8 100644 (file)
@@ -1003,8 +1003,12 @@ struct ieee80211_ht_info {
 #define WLAN_CAPABILITY_ESS            (1<<0)
 #define WLAN_CAPABILITY_IBSS           (1<<1)
 
-/* A mesh STA sets the ESS and IBSS capability bits to zero */
-#define WLAN_CAPABILITY_IS_MBSS(cap)   \
+/*
+ * A mesh STA sets the ESS and IBSS capability bits to zero.
+ * however, this holds true for p2p probe responses (in the p2p_find
+ * phase) as well.
+ */
+#define WLAN_CAPABILITY_IS_STA_BSS(cap)        \
        (!((cap) & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)))
 
 #define WLAN_CAPABILITY_CF_POLLABLE    (1<<2)
index 72bfa5a034dd430a1a79aa2ef1cb24a1b79836df..6d66ce1791a912c34add6ca9ec04ec875c379f93 100644 (file)
@@ -70,6 +70,7 @@ struct tpacket_auxdata {
 #define TP_STATUS_COPY         0x2
 #define TP_STATUS_LOSING       0x4
 #define TP_STATUS_CSUMNOTREADY 0x8
+#define TP_STATUS_VLAN_VALID   0x10 /* auxdata has valid tp_vlan_tci */
 
 /* Tx ring - header status */
 #define TP_STATUS_AVAILABLE    0x0
index 819acaaac3f5877bc4802bbbc928a5c21686fde2..714ba08dc09265922fe8ab81dee1caadc12a9100 100644 (file)
@@ -8,9 +8,9 @@
  * @IRQ_WAKE_THREAD    handler requests to wake the handler thread
  */
 enum irqreturn {
-       IRQ_NONE,
-       IRQ_HANDLED,
-       IRQ_WAKE_THREAD,
+       IRQ_NONE                = (0 << 0),
+       IRQ_HANDLED             = (1 << 0),
+       IRQ_WAKE_THREAD         = (1 << 1),
 };
 
 typedef enum irqreturn irqreturn_t;
index d40bfa1d9c914d42cea30f5a0946f185b117d055..e5f21d293c70175f1395c3355b3da5a230ee0d99 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/mtd/partitions.h>
 
 struct map_info;
+struct platform_device;
 
 struct physmap_flash_data {
        unsigned int            width;
index 3412684ce5d541176ba1e5b64f09244e8d3cdc45..e0786e35f247664a8fd9838dced3a46d4f71257c 100644 (file)
@@ -137,14 +137,14 @@ enum perf_event_sample_format {
  *
  * struct read_format {
  *     { u64           value;
- *       { u64         time_enabled; } && PERF_FORMAT_ENABLED
- *       { u64         time_running; } && PERF_FORMAT_RUNNING
+ *       { u64         time_enabled; } && PERF_FORMAT_TOTAL_TIME_ENABLED
+ *       { u64         time_running; } && PERF_FORMAT_TOTAL_TIME_RUNNING
  *       { u64         id;           } && PERF_FORMAT_ID
  *     } && !PERF_FORMAT_GROUP
  *
  *     { u64           nr;
- *       { u64         time_enabled; } && PERF_FORMAT_ENABLED
- *       { u64         time_running; } && PERF_FORMAT_RUNNING
+ *       { u64         time_enabled; } && PERF_FORMAT_TOTAL_TIME_ENABLED
+ *       { u64         time_running; } && PERF_FORMAT_TOTAL_TIME_RUNNING
  *       { u64         value;
  *         { u64       id;           } && PERF_FORMAT_ID
  *       }             cntr[nr];
index 2a8621c4be1e36d6e713f1b30e51cc607f8b4e02..a837b20ba190330c23b59ec5a3fb584fc9f6308f 100644 (file)
@@ -1063,6 +1063,7 @@ struct sched_domain;
  */
 #define WF_SYNC                0x01            /* waker goes to sleep after wakup */
 #define WF_FORK                0x02            /* child wakeup after fork */
+#define WF_MIGRATED    0x04            /* internal use, task got migrated */
 
 #define ENQUEUE_WAKEUP         1
 #define ENQUEUE_HEAD           2
index 5b07792ccb46cb62280438159f3f6e3f00de573d..ff7dc08696a8cc67c812ea516e9bcd9fee9c53c7 100644 (file)
@@ -76,7 +76,7 @@
  *     tty device.  It is solely the responsibility of the line
  *     discipline to handle poll requests.
  *
- * unsigned int (*receive_buf)(struct tty_struct *, const unsigned char *cp,
+ * void        (*receive_buf)(struct tty_struct *, const unsigned char *cp,
  *                    char *fp, int count);
  *
  *     This function is called by the low-level tty driver to send
@@ -84,8 +84,7 @@
  *     processing.  <cp> is a pointer to the buffer of input
  *     character received by the device.  <fp> is a pointer to a
  *     pointer of flag bytes which indicate whether a character was
- *     received with a parity error, etc. Returns the amount of bytes
- *     received.
+ *     received with a parity error, etc.
  * 
  * void        (*write_wakeup)(struct tty_struct *);
  *
@@ -141,8 +140,8 @@ struct tty_ldisc_ops {
        /*
         * The following routines are called from below.
         */
-       unsigned int (*receive_buf)(struct tty_struct *,
-                       const unsigned char *cp, char *fp, int count);
+       void    (*receive_buf)(struct tty_struct *, const unsigned char *cp,
+                              char *fp, int count);
        void    (*write_wakeup)(struct tty_struct *);
        void    (*dcd_change)(struct tty_struct *, unsigned int,
                                struct pps_event_time *);
index 71693d4a4fe187db6da029ec670ae124b90a3ef6..17df3600bcef74bf674b9d13c9db5657e64cc558 100644 (file)
@@ -62,7 +62,9 @@
        US_FLAG(NO_READ_DISC_INFO,      0x00040000)             \
                /* cannot handle READ_DISC_INFO */              \
        US_FLAG(NO_READ_CAPACITY_16,    0x00080000)             \
-               /* cannot handle READ_CAPACITY_16 */
+               /* cannot handle READ_CAPACITY_16 */            \
+       US_FLAG(INITIAL_READ10, 0x00100000)                     \
+               /* Initial READ(10) (and others) must be retried */
 
 #define US_FLAG(name, value)   US_FL_##name = value ,
 enum { US_DO_ALL_FLAGS };
index aff5b4f740417ee39cc3b42c8c70bfe351fc4564..7108857496055b1ed9f437ef22ae96c2ae9f0bf3 100644 (file)
@@ -51,6 +51,13 @@ struct virtqueue {
  *     This re-enables callbacks; it returns "false" if there are pending
  *     buffers in the queue, to detect a possible race between the driver
  *     checking for more work, and enabling callbacks.
+ * virtqueue_enable_cb_delayed: restart callbacks after disable_cb.
+ *     vq: the struct virtqueue we're talking about.
+ *     This re-enables callbacks but hints to the other side to delay
+ *     interrupts until most of the available buffers have been processed;
+ *     it returns "false" if there are many pending buffers in the queue,
+ *     to detect a possible race between the driver checking for more work,
+ *     and enabling callbacks.
  * virtqueue_detach_unused_buf: detach first unused buffer
  *     vq: the struct virtqueue we're talking about.
  *     Returns NULL or the "data" token handed to add_buf
@@ -86,6 +93,8 @@ void virtqueue_disable_cb(struct virtqueue *vq);
 
 bool virtqueue_enable_cb(struct virtqueue *vq);
 
+bool virtqueue_enable_cb_delayed(struct virtqueue *vq);
+
 void *virtqueue_detach_unused_buf(struct virtqueue *vq);
 
 /**
index e68b439b2860e7aa5e9490fec542fdfe245c6b2f..277c4ad44e842448df79c1afda9322e84c32e842 100644 (file)
@@ -1,7 +1,30 @@
 #ifndef _LINUX_VIRTIO_9P_H
 #define _LINUX_VIRTIO_9P_H
 /* This header is BSD licensed so anyone can use the definitions to implement
- * compatible drivers/servers. */
+ * compatible drivers/servers.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of IBM nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE. */
 #include <linux/types.h>
 #include <linux/virtio_ids.h>
 #include <linux/virtio_config.h>
index a50ecd1b81a2acce1da35758767d3abcf0b06a99..652dc8bea92131a4d3134fe6b59ae75cdc6092a8 100644 (file)
@@ -1,7 +1,30 @@
 #ifndef _LINUX_VIRTIO_BALLOON_H
 #define _LINUX_VIRTIO_BALLOON_H
 /* This header is BSD licensed so anyone can use the definitions to implement
- * compatible drivers/servers. */
+ * compatible drivers/servers.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of IBM nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE. */
 #include <linux/virtio_ids.h>
 #include <linux/virtio_config.h>
 
index 167720d695ed00bb94b9174381de80f13fd6d009..e0edb40ca7aaca3ffeeb9261fa017eedd6548291 100644 (file)
@@ -1,7 +1,30 @@
 #ifndef _LINUX_VIRTIO_BLK_H
 #define _LINUX_VIRTIO_BLK_H
 /* This header is BSD licensed so anyone can use the definitions to implement
- * compatible drivers/servers. */
+ * compatible drivers/servers.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of IBM nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE. */
 #include <linux/types.h>
 #include <linux/virtio_ids.h>
 #include <linux/virtio_config.h>
index 800617b4ddd56c3dd0a790f97a4c73f2fa38de64..39c88c5ad19dfd85c5fcbed38837d514c477679f 100644 (file)
@@ -1,7 +1,30 @@
 #ifndef _LINUX_VIRTIO_CONFIG_H
 #define _LINUX_VIRTIO_CONFIG_H
 /* This header, excluding the #ifdef __KERNEL__ part, is BSD licensed so
- * anyone can use the definitions to implement compatible drivers/servers. */
+ * anyone can use the definitions to implement compatible drivers/servers.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of IBM nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE. */
 
 /* Virtio devices use a standardized configuration space to define their
  * features and pass configuration information, but each implementation can
index e4d333543a33a65b450f637f0ed2ce231ae0f088..bdf4b0034739e379b4eae94e17171aaca64f3bd0 100644 (file)
@@ -5,7 +5,31 @@
 #include <linux/virtio_config.h>
 /*
  * This header, excluding the #ifdef __KERNEL__ part, is BSD licensed so
- * anyone can use the definitions to implement compatible drivers/servers.
+ * anyone can use the definitions to implement compatible drivers/servers:
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of IBM nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
  *
  * Copyright (C) Red Hat, Inc., 2009, 2010, 2011
  * Copyright (C) Amit Shah <amit.shah@redhat.com>, 2009, 2010, 2011
index 06660c0a78d720e5d4b2155041c10b3800c9ffbd..85bb0bb66ffc5c33b985194975466bb30189657b 100644 (file)
@@ -5,7 +5,29 @@
  *
  * This header is BSD licensed so anyone can use the definitions to implement
  * compatible drivers/servers.
- */
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of IBM nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE. */
 
 #define VIRTIO_ID_NET          1 /* virtio net */
 #define VIRTIO_ID_BLOCK                2 /* virtio block */
index 085e42298ce5b1b9f353f457951e7fc49a5ef949..136040bba3e36068364c276e38f3ab975b0cabef 100644 (file)
@@ -1,7 +1,30 @@
 #ifndef _LINUX_VIRTIO_NET_H
 #define _LINUX_VIRTIO_NET_H
 /* This header is BSD licensed so anyone can use the definitions to implement
- * compatible drivers/servers. */
+ * compatible drivers/servers.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of IBM nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE. */
 #include <linux/types.h>
 #include <linux/virtio_ids.h>
 #include <linux/virtio_config.h>
index 9a3d7c48c622d8c3e525ce5653fd12e98b4d9f9a..ea66f3f60d63f7db3234c2f75058826af072a771 100644 (file)
  *
  * This header is BSD licensed so anyone can use the definitions to implement
  * compatible drivers/servers.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of IBM nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
  */
 
 #ifndef _LINUX_VIRTIO_PCI_H
index e4d144b132b5e27d3c4713738acfc63ce6262781..4a32cb6da425abe92c9eaa019121f4710171c77a 100644 (file)
@@ -7,6 +7,29 @@
  * This header is BSD licensed so anyone can use the definitions to implement
  * compatible drivers/servers.
  *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of IBM nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
  * Copyright Rusty Russell IBM Corporation 2007. */
 #include <linux/types.h>
 
 /* We support indirect buffer descriptors */
 #define VIRTIO_RING_F_INDIRECT_DESC    28
 
+/* The Guest publishes the used index for which it expects an interrupt
+ * at the end of the avail ring. Host should ignore the avail->flags field. */
+/* The Host publishes the avail index for which it expects a kick
+ * at the end of the used ring. Guest should ignore the used->flags field. */
+#define VIRTIO_RING_F_EVENT_IDX                29
+
 /* Virtio ring descriptors: 16 bytes.  These can chain together via "next". */
 struct vring_desc {
        /* Address (guest-physical). */
@@ -83,6 +112,7 @@ struct vring {
  *     __u16 avail_flags;
  *     __u16 avail_idx;
  *     __u16 available[num];
+ *     __u16 used_event_idx;
  *
  *     // Padding to the next align boundary.
  *     char pad[];
@@ -91,8 +121,14 @@ struct vring {
  *     __u16 used_flags;
  *     __u16 used_idx;
  *     struct vring_used_elem used[num];
+ *     __u16 avail_event_idx;
  * };
  */
+/* We publish the used event index at the end of the available ring, and vice
+ * versa. They are at the end for backwards compatibility. */
+#define vring_used_event(vr) ((vr)->avail->ring[(vr)->num])
+#define vring_avail_event(vr) (*(__u16 *)&(vr)->used->ring[(vr)->num])
+
 static inline void vring_init(struct vring *vr, unsigned int num, void *p,
                              unsigned long align)
 {
@@ -107,7 +143,21 @@ static inline unsigned vring_size(unsigned int num, unsigned long align)
 {
        return ((sizeof(struct vring_desc) * num + sizeof(__u16) * (2 + num)
                 + align - 1) & ~(align - 1))
-               + sizeof(__u16) * 2 + sizeof(struct vring_used_elem) * num;
+               + sizeof(__u16) * 3 + sizeof(struct vring_used_elem) * num;
+}
+
+/* The following is used with USED_EVENT_IDX and AVAIL_EVENT_IDX */
+/* Assuming a given event_idx value from the other size, if
+ * we have just incremented index from old to new_idx,
+ * should we trigger an event? */
+static inline int vring_need_event(__u16 event_idx, __u16 new_idx, __u16 old)
+{
+       /* Note: Xen has similar logic for notification hold-off
+        * in include/xen/interface/io/ring.h with req_event and req_prod
+        * corresponding to event_idx + 1 and new_idx respectively.
+        * Note also that req_event and req_prod in Xen start at 1,
+        * event indexes in virtio start at 0. */
+       return (__u16)(new_idx - event_idx - 1) < (__u16)(new_idx - old);
 }
 
 #ifdef __KERNEL__
index 93e96fb934526e44b327e8d677bb91f7accd80c4..c7c40f1d2624a7eb7988ee376e324904b54c1d39 100644 (file)
@@ -128,8 +128,8 @@ struct video_device
        struct mutex *lock;
 };
 
-#define media_entity_to_video_device(entity) \
-       container_of(entity, struct video_device, entity)
+#define media_entity_to_video_device(__e) \
+       container_of(__e, struct video_device, entity)
 /* dev to video-device */
 #define to_video_device(cd) container_of(cd, struct video_device, dev)
 
index 2b447646ce4bf3d64926d4c8a7bdd969f1a8bb1d..dd6847e5d6e46264ffe6db00ccb7128ce61483fa 100644 (file)
@@ -107,6 +107,7 @@ typedef enum {
        SCTP_CMD_UPDATE_INITTAG, /* Update peer inittag */
        SCTP_CMD_SEND_MSG,       /* Send the whole use message */
        SCTP_CMD_SEND_NEXT_ASCONF, /* Send the next ASCONF after ACK */
+       SCTP_CMD_PURGE_ASCONF_QUEUE, /* Purge all asconf queues.*/
        SCTP_CMD_LAST
 } sctp_verb_t;
 
index 795f4886e1112dc7245e841f29f0465ae4aa1d59..7df327a6d564e8b2b57609ff714d4eb9a0e8b872 100644 (file)
@@ -1993,7 +1993,7 @@ void sctp_assoc_clean_asconf_ack_cache(const struct sctp_association *asoc);
 struct sctp_chunk *sctp_assoc_lookup_asconf_ack(
                                        const struct sctp_association *asoc,
                                        __be32 serial);
-
+void sctp_asconf_queue_teardown(struct sctp_association *asoc);
 
 int sctp_cmp_addr_exact(const union sctp_addr *ss1,
                        const union sctp_addr *ss2);
index 5f247f5ffc565c50e49f70eb84f52b101d3c03f0..f99645d05a8f201eea78a399468e51b3876d2019 100644 (file)
 TRACE_EVENT(net_dev_xmit,
 
        TP_PROTO(struct sk_buff *skb,
-                int rc),
+                int rc,
+                struct net_device *dev,
+                unsigned int skb_len),
 
-       TP_ARGS(skb, rc),
+       TP_ARGS(skb, rc, dev, skb_len),
 
        TP_STRUCT__entry(
                __field(        void *,         skbaddr         )
                __field(        unsigned int,   len             )
                __field(        int,            rc              )
-               __string(       name,           skb->dev->name  )
+               __string(       name,           dev->name       )
        ),
 
        TP_fast_assign(
                __entry->skbaddr = skb;
-               __entry->len = skb->len;
+               __entry->len = skb_len;
                __entry->rc = rc;
-               __assign_str(name, skb->dev->name);
+               __assign_str(name, dev->name);
        ),
 
        TP_printk("dev=%s skbaddr=%p len=%u rc=%d",
index d863b3c057bba8fe4add3e774a3bb86083c493a5..9efe7108ccaf8debca9bd9a70e2bf6265a50949c 100644 (file)
@@ -7402,26 +7402,12 @@ static int __perf_cgroup_move(void *info)
        return 0;
 }
 
-static void perf_cgroup_move(struct task_struct *task)
+static void
+perf_cgroup_attach_task(struct cgroup *cgrp, struct task_struct *task)
 {
        task_function_call(task, __perf_cgroup_move, task);
 }
 
-static void perf_cgroup_attach(struct cgroup_subsys *ss, struct cgroup *cgrp,
-               struct cgroup *old_cgrp, struct task_struct *task,
-               bool threadgroup)
-{
-       perf_cgroup_move(task);
-       if (threadgroup) {
-               struct task_struct *c;
-               rcu_read_lock();
-               list_for_each_entry_rcu(c, &task->thread_group, thread_group) {
-                       perf_cgroup_move(c);
-               }
-               rcu_read_unlock();
-       }
-}
-
 static void perf_cgroup_exit(struct cgroup_subsys *ss, struct cgroup *cgrp,
                struct cgroup *old_cgrp, struct task_struct *task)
 {
@@ -7433,7 +7419,7 @@ static void perf_cgroup_exit(struct cgroup_subsys *ss, struct cgroup *cgrp,
        if (!(task->flags & PF_EXITING))
                return;
 
-       perf_cgroup_move(task);
+       perf_cgroup_attach_task(cgrp, task);
 }
 
 struct cgroup_subsys perf_subsys = {
@@ -7442,6 +7428,6 @@ struct cgroup_subsys perf_subsys = {
        .create         = perf_cgroup_create,
        .destroy        = perf_cgroup_destroy,
        .exit           = perf_cgroup_exit,
-       .attach         = perf_cgroup_attach,
+       .attach_task    = perf_cgroup_attach_task,
 };
 #endif /* CONFIG_CGROUP_PERF */
index 90cb55f6d7ebe4496b339f5202f0a31926854963..470d08c82bbe29f373a9aa79d07794d56985763b 100644 (file)
@@ -132,12 +132,6 @@ handle_irq_event_percpu(struct irq_desc *desc, struct irqaction *action)
 
                switch (res) {
                case IRQ_WAKE_THREAD:
-                       /*
-                        * Set result to handled so the spurious check
-                        * does not trigger.
-                        */
-                       res = IRQ_HANDLED;
-
                        /*
                         * Catch drivers which return WAKE_THREAD but
                         * did not set up a thread function
index 886e80347b322795b56630857fd98996545ea5a4..4c60a50e66b237922381c5b0d0d82d55b436b6dc 100644 (file)
@@ -257,13 +257,11 @@ int __init early_irq_init(void)
        count = ARRAY_SIZE(irq_desc);
 
        for (i = 0; i < count; i++) {
-               desc[i].irq_data.irq = i;
-               desc[i].irq_data.chip = &no_irq_chip;
                desc[i].kstat_irqs = alloc_percpu(unsigned int);
-               irq_settings_clr_and_set(desc, ~0, _IRQ_DEFAULT_INIT_FLAGS);
-               alloc_masks(desc + i, GFP_KERNEL, node);
-               desc_smp_init(desc + i, node);
+               alloc_masks(&desc[i], GFP_KERNEL, node);
+               raw_spin_lock_init(&desc[i].lock);
                lockdep_set_class(&desc[i].lock, &irq_desc_lock_class);
+               desc_set_defaults(i, &desc[i], node);
        }
        return arch_early_irq_init();
 }
@@ -346,6 +344,12 @@ irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node)
        if (!cnt)
                return -EINVAL;
 
+       if (irq >= 0) {
+               if (from > irq)
+                       return -EINVAL;
+               from = irq;
+       }
+
        mutex_lock(&sparse_irq_lock);
 
        start = bitmap_find_next_zero_area(allocated_irqs, IRQ_BITMAP_BITS,
index f7ce0021e1c48eb02e2eb6531265ac84bfc24d96..d64bafb1afd08d7e64378d3e9b98c66b015781c8 100644 (file)
@@ -723,13 +723,16 @@ irq_thread_check_affinity(struct irq_desc *desc, struct irqaction *action) { }
  * context. So we need to disable bh here to avoid deadlocks and other
  * side effects.
  */
-static void
+static irqreturn_t
 irq_forced_thread_fn(struct irq_desc *desc, struct irqaction *action)
 {
+       irqreturn_t ret;
+
        local_bh_disable();
-       action->thread_fn(action->irq, action->dev_id);
+       ret = action->thread_fn(action->irq, action->dev_id);
        irq_finalize_oneshot(desc, action, false);
        local_bh_enable();
+       return ret;
 }
 
 /*
@@ -737,10 +740,14 @@ irq_forced_thread_fn(struct irq_desc *desc, struct irqaction *action)
  * preemtible - many of them need to sleep and wait for slow busses to
  * complete.
  */
-static void irq_thread_fn(struct irq_desc *desc, struct irqaction *action)
+static irqreturn_t irq_thread_fn(struct irq_desc *desc,
+               struct irqaction *action)
 {
-       action->thread_fn(action->irq, action->dev_id);
+       irqreturn_t ret;
+
+       ret = action->thread_fn(action->irq, action->dev_id);
        irq_finalize_oneshot(desc, action, false);
+       return ret;
 }
 
 /*
@@ -753,7 +760,8 @@ static int irq_thread(void *data)
        };
        struct irqaction *action = data;
        struct irq_desc *desc = irq_to_desc(action->irq);
-       void (*handler_fn)(struct irq_desc *desc, struct irqaction *action);
+       irqreturn_t (*handler_fn)(struct irq_desc *desc,
+                       struct irqaction *action);
        int wake;
 
        if (force_irqthreads & test_bit(IRQTF_FORCED_THREAD,
@@ -783,8 +791,12 @@ static int irq_thread(void *data)
                        desc->istate |= IRQS_PENDING;
                        raw_spin_unlock_irq(&desc->lock);
                } else {
+                       irqreturn_t action_ret;
+
                        raw_spin_unlock_irq(&desc->lock);
-                       handler_fn(desc, action);
+                       action_ret = handler_fn(desc, action);
+                       if (!noirqdebug)
+                               note_interrupt(action->irq, desc, action_ret);
                }
 
                wake = atomic_dec_and_test(&desc->threads_active);
index dfbd550401b28f29a4db69807fae318c8ec7341a..aa57d5da18c1de65e807098702ad9b841fa3788d 100644 (file)
@@ -167,6 +167,13 @@ out:
                  jiffies + POLL_SPURIOUS_IRQ_INTERVAL);
 }
 
+static inline int bad_action_ret(irqreturn_t action_ret)
+{
+       if (likely(action_ret <= (IRQ_HANDLED | IRQ_WAKE_THREAD)))
+               return 0;
+       return 1;
+}
+
 /*
  * If 99,900 of the previous 100,000 interrupts have not been handled
  * then assume that the IRQ is stuck in some manner. Drop a diagnostic
@@ -182,7 +189,7 @@ __report_bad_irq(unsigned int irq, struct irq_desc *desc,
        struct irqaction *action;
        unsigned long flags;
 
-       if (action_ret != IRQ_HANDLED && action_ret != IRQ_NONE) {
+       if (bad_action_ret(action_ret)) {
                printk(KERN_ERR "irq event %d: bogus return value %x\n",
                                irq, action_ret);
        } else {
@@ -201,10 +208,11 @@ __report_bad_irq(unsigned int irq, struct irq_desc *desc,
        raw_spin_lock_irqsave(&desc->lock, flags);
        action = desc->action;
        while (action) {
-               printk(KERN_ERR "[<%p>]", action->handler);
-               print_symbol(" (%s)",
-                       (unsigned long)action->handler);
-               printk("\n");
+               printk(KERN_ERR "[<%p>] %pf", action->handler, action->handler);
+               if (action->thread_fn)
+                       printk(KERN_CONT " threaded [<%p>] %pf",
+                                       action->thread_fn, action->thread_fn);
+               printk(KERN_CONT "\n");
                action = action->next;
        }
        raw_spin_unlock_irqrestore(&desc->lock, flags);
@@ -262,7 +270,16 @@ void note_interrupt(unsigned int irq, struct irq_desc *desc,
        if (desc->istate & IRQS_POLL_INPROGRESS)
                return;
 
-       if (unlikely(action_ret != IRQ_HANDLED)) {
+       /* we get here again via the threaded handler */
+       if (action_ret == IRQ_WAKE_THREAD)
+               return;
+
+       if (bad_action_ret(action_ret)) {
+               report_bad_irq(irq, desc, action_ret);
+               return;
+       }
+
+       if (unlikely(action_ret == IRQ_NONE)) {
                /*
                 * If we are seeing only the odd spurious IRQ caused by
                 * bus asynchronicity then don't eventually trigger an error,
@@ -274,8 +291,6 @@ void note_interrupt(unsigned int irq, struct irq_desc *desc,
                else
                        desc->irqs_unhandled++;
                desc->last_unhandled = jiffies;
-               if (unlikely(action_ret != IRQ_NONE))
-                       report_bad_irq(irq, desc, action_ret);
        }
 
        if (unlikely(try_misrouted_irq(irq, desc, action_ret))) {
index 63437d065ac89d69bbc6e70fd3789e64ac7e1d6a..298c9276dfdb378877249384db860c3658485ef2 100644 (file)
@@ -3426,7 +3426,7 @@ int lock_is_held(struct lockdep_map *lock)
        int ret = 0;
 
        if (unlikely(current->lockdep_recursion))
-               return ret;
+               return 1; /* avoid false negative lockdep_assert_held() */
 
        raw_local_irq_save(flags);
        check_flags(flags);
index 77a7671dd1472b10567fcaba0fd0d308565215cc..89419ff92e996c1e52fade38475ba14604a8f7bd 100644 (file)
@@ -1648,7 +1648,6 @@ static int __cpuinit rcu_spawn_one_cpu_kthread(int cpu)
        if (IS_ERR(t))
                return PTR_ERR(t);
        kthread_bind(t, cpu);
-       set_task_state(t, TASK_INTERRUPTIBLE);
        per_cpu(rcu_cpu_kthread_cpu, cpu) = cpu;
        WARN_ON_ONCE(per_cpu(rcu_cpu_kthread_task, cpu) != NULL);
        per_cpu(rcu_cpu_kthread_task, cpu) = t;
@@ -1756,7 +1755,6 @@ static int __cpuinit rcu_spawn_one_node_kthread(struct rcu_state *rsp,
                if (IS_ERR(t))
                        return PTR_ERR(t);
                raw_spin_lock_irqsave(&rnp->lock, flags);
-               set_task_state(t, TASK_INTERRUPTIBLE);
                rnp->node_kthread_task = t;
                raw_spin_unlock_irqrestore(&rnp->lock, flags);
                sp.sched_priority = 99;
@@ -1765,6 +1763,8 @@ static int __cpuinit rcu_spawn_one_node_kthread(struct rcu_state *rsp,
        return rcu_spawn_one_boost_kthread(rsp, rnp, rnp_index);
 }
 
+static void rcu_wake_one_boost_kthread(struct rcu_node *rnp);
+
 /*
  * Spawn all kthreads -- called as soon as the scheduler is running.
  */
@@ -1772,18 +1772,30 @@ static int __init rcu_spawn_kthreads(void)
 {
        int cpu;
        struct rcu_node *rnp;
+       struct task_struct *t;
 
        rcu_kthreads_spawnable = 1;
        for_each_possible_cpu(cpu) {
                per_cpu(rcu_cpu_has_work, cpu) = 0;
-               if (cpu_online(cpu))
+               if (cpu_online(cpu)) {
                        (void)rcu_spawn_one_cpu_kthread(cpu);
+                       t = per_cpu(rcu_cpu_kthread_task, cpu);
+                       if (t)
+                               wake_up_process(t);
+               }
        }
        rnp = rcu_get_root(rcu_state);
        (void)rcu_spawn_one_node_kthread(rcu_state, rnp);
+       if (rnp->node_kthread_task)
+               wake_up_process(rnp->node_kthread_task);
        if (NUM_RCU_NODES > 1) {
-               rcu_for_each_leaf_node(rcu_state, rnp)
+               rcu_for_each_leaf_node(rcu_state, rnp) {
                        (void)rcu_spawn_one_node_kthread(rcu_state, rnp);
+                       t = rnp->node_kthread_task;
+                       if (t)
+                               wake_up_process(t);
+                       rcu_wake_one_boost_kthread(rnp);
+               }
        }
        return 0;
 }
@@ -2188,14 +2200,14 @@ rcu_init_percpu_data(int cpu, struct rcu_state *rsp, int preemptible)
        raw_spin_unlock_irqrestore(&rsp->onofflock, flags);
 }
 
-static void __cpuinit rcu_online_cpu(int cpu)
+static void __cpuinit rcu_prepare_cpu(int cpu)
 {
        rcu_init_percpu_data(cpu, &rcu_sched_state, 0);
        rcu_init_percpu_data(cpu, &rcu_bh_state, 0);
        rcu_preempt_init_percpu_data(cpu);
 }
 
-static void __cpuinit rcu_online_kthreads(int cpu)
+static void __cpuinit rcu_prepare_kthreads(int cpu)
 {
        struct rcu_data *rdp = per_cpu_ptr(rcu_state->rda, cpu);
        struct rcu_node *rnp = rdp->mynode;
@@ -2208,6 +2220,31 @@ static void __cpuinit rcu_online_kthreads(int cpu)
        }
 }
 
+/*
+ * kthread_create() creates threads in TASK_UNINTERRUPTIBLE state,
+ * but the RCU threads are woken on demand, and if demand is low this
+ * could be a while triggering the hung task watchdog.
+ *
+ * In order to avoid this, poke all tasks once the CPU is fully
+ * up and running.
+ */
+static void __cpuinit rcu_online_kthreads(int cpu)
+{
+       struct rcu_data *rdp = per_cpu_ptr(rcu_state->rda, cpu);
+       struct rcu_node *rnp = rdp->mynode;
+       struct task_struct *t;
+
+       t = per_cpu(rcu_cpu_kthread_task, cpu);
+       if (t)
+               wake_up_process(t);
+
+       t = rnp->node_kthread_task;
+       if (t)
+               wake_up_process(t);
+
+       rcu_wake_one_boost_kthread(rnp);
+}
+
 /*
  * Handle CPU online/offline notification events.
  */
@@ -2221,10 +2258,11 @@ static int __cpuinit rcu_cpu_notify(struct notifier_block *self,
        switch (action) {
        case CPU_UP_PREPARE:
        case CPU_UP_PREPARE_FROZEN:
-               rcu_online_cpu(cpu);
-               rcu_online_kthreads(cpu);
+               rcu_prepare_cpu(cpu);
+               rcu_prepare_kthreads(cpu);
                break;
        case CPU_ONLINE:
+               rcu_online_kthreads(cpu);
        case CPU_DOWN_FAILED:
                rcu_node_kthread_setaffinity(rnp, -1);
                rcu_cpu_kthread_setrt(cpu, 1);
index a767b7dac36517b389d2953036fc6097bcfcae96..c8bff3099a89eeeccf9e3d330a16f6c4d9a2c340 100644 (file)
@@ -1295,7 +1295,6 @@ static int __cpuinit rcu_spawn_one_boost_kthread(struct rcu_state *rsp,
        if (IS_ERR(t))
                return PTR_ERR(t);
        raw_spin_lock_irqsave(&rnp->lock, flags);
-       set_task_state(t, TASK_INTERRUPTIBLE);
        rnp->boost_kthread_task = t;
        raw_spin_unlock_irqrestore(&rnp->lock, flags);
        sp.sched_priority = RCU_KTHREAD_PRIO;
@@ -1303,6 +1302,12 @@ static int __cpuinit rcu_spawn_one_boost_kthread(struct rcu_state *rsp,
        return 0;
 }
 
+static void __cpuinit rcu_wake_one_boost_kthread(struct rcu_node *rnp)
+{
+       if (rnp->boost_kthread_task)
+               wake_up_process(rnp->boost_kthread_task);
+}
+
 #else /* #ifdef CONFIG_RCU_BOOST */
 
 static void rcu_initiate_boost(struct rcu_node *rnp, unsigned long flags)
@@ -1326,6 +1331,10 @@ static int __cpuinit rcu_spawn_one_boost_kthread(struct rcu_state *rsp,
        return 0;
 }
 
+static void __cpuinit rcu_wake_one_boost_kthread(struct rcu_node *rnp)
+{
+}
+
 #endif /* #else #ifdef CONFIG_RCU_BOOST */
 
 #ifndef CONFIG_SMP
index cbb3a0eee58eb2c5c6748b949fca5579bbb57432..3f2e502d609bb7957e10b4ec6aa647c9b3069c6e 100644 (file)
@@ -605,10 +605,10 @@ static inline int cpu_of(struct rq *rq)
 /*
  * Return the group to which this tasks belongs.
  *
- * We use task_subsys_state_check() and extend the RCU verification
- * with lockdep_is_held(&p->pi_lock) because cpu_cgroup_attach()
- * holds that lock for each task it moves into the cgroup. Therefore
- * by holding that lock, we pin the task to the current cgroup.
+ * We use task_subsys_state_check() and extend the RCU verification with
+ * pi->lock and rq->lock because cpu_cgroup_attach() holds those locks for each
+ * task it moves into the cgroup. Therefore by holding either of those locks,
+ * we pin the task to the current cgroup.
  */
 static inline struct task_group *task_group(struct task_struct *p)
 {
@@ -616,7 +616,8 @@ static inline struct task_group *task_group(struct task_struct *p)
        struct cgroup_subsys_state *css;
 
        css = task_subsys_state_check(p, cpu_cgroup_subsys_id,
-                       lockdep_is_held(&p->pi_lock));
+                       lockdep_is_held(&p->pi_lock) ||
+                       lockdep_is_held(&task_rq(p)->lock));
        tg = container_of(css, struct task_group, css);
 
        return autogroup_task_group(p, tg);
@@ -2200,6 +2201,16 @@ void set_task_cpu(struct task_struct *p, unsigned int new_cpu)
                        !(task_thread_info(p)->preempt_count & PREEMPT_ACTIVE));
 
 #ifdef CONFIG_LOCKDEP
+       /*
+        * The caller should hold either p->pi_lock or rq->lock, when changing
+        * a task's CPU. ->pi_lock for waking tasks, rq->lock for runnable tasks.
+        *
+        * sched_move_task() holds both and thus holding either pins the cgroup,
+        * see set_task_rq().
+        *
+        * Furthermore, all task_rq users should acquire both locks, see
+        * task_rq_lock().
+        */
        WARN_ON_ONCE(debug_locks && !(lockdep_is_held(&p->pi_lock) ||
                                      lockdep_is_held(&task_rq(p)->lock)));
 #endif
@@ -2447,6 +2458,10 @@ ttwu_stat(struct task_struct *p, int cpu, int wake_flags)
                }
                rcu_read_unlock();
        }
+
+       if (wake_flags & WF_MIGRATED)
+               schedstat_inc(p, se.statistics.nr_wakeups_migrate);
+
 #endif /* CONFIG_SMP */
 
        schedstat_inc(rq, ttwu_count);
@@ -2455,9 +2470,6 @@ ttwu_stat(struct task_struct *p, int cpu, int wake_flags)
        if (wake_flags & WF_SYNC)
                schedstat_inc(p, se.statistics.nr_wakeups_sync);
 
-       if (cpu != task_cpu(p))
-               schedstat_inc(p, se.statistics.nr_wakeups_migrate);
-
 #endif /* CONFIG_SCHEDSTATS */
 }
 
@@ -2600,6 +2612,7 @@ static void ttwu_queue(struct task_struct *p, int cpu)
 
 #if defined(CONFIG_SMP)
        if (sched_feat(TTWU_QUEUE) && cpu != smp_processor_id()) {
+               sched_clock_cpu(cpu); /* sync clocks x-cpu */
                ttwu_queue_remote(p, cpu);
                return;
        }
@@ -2674,8 +2687,10 @@ try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags)
                p->sched_class->task_waking(p);
 
        cpu = select_task_rq(p, SD_BALANCE_WAKE, wake_flags);
-       if (task_cpu(p) != cpu)
+       if (task_cpu(p) != cpu) {
+               wake_flags |= WF_MIGRATED;
                set_task_cpu(p, cpu);
+       }
 #endif /* CONFIG_SMP */
 
        ttwu_queue(p, cpu);
index 4fc92445a29c920405935176b473485af8140f17..f175d98bd3557c912e15f65fcd98be713f400f29 100644 (file)
@@ -938,6 +938,12 @@ static struct ctl_table kern_table[] = {
        },
 #endif
 #ifdef CONFIG_PERF_EVENTS
+       /*
+        * User-space scripts rely on the existence of this file
+        * as a feature check for perf_events being enabled.
+        *
+        * So it's an ABI, do not remove!
+        */
        {
                .procname       = "perf_event_paranoid",
                .data           = &sysctl_perf_event_paranoid,
index c027d4f602f18276f73694a593cefb6ea77bc3a0..e4c699dfa4e8776ee3ed9e671922e962002b6a06 100644 (file)
@@ -182,7 +182,10 @@ void clockevents_register_device(struct clock_event_device *dev)
        unsigned long flags;
 
        BUG_ON(dev->mode != CLOCK_EVT_MODE_UNUSED);
-       BUG_ON(!dev->cpumask);
+       if (!dev->cpumask) {
+               WARN_ON(num_possible_cpus() > 1);
+               dev->cpumask = cpumask_of(smp_processor_id());
+       }
 
        raw_spin_lock_irqsave(&clockevents_lock, flags);
 
index fd6198692b57b16e47132d1eb5183bafd98b050e..8cff36119e4d50f7336a06e8d01e59e8b162e694 100644 (file)
@@ -749,16 +749,15 @@ unsigned long apply_slack(struct timer_list *timer, unsigned long expires)
        unsigned long expires_limit, mask;
        int bit;
 
-       expires_limit = expires;
-
        if (timer->slack >= 0) {
                expires_limit = expires + timer->slack;
        } else {
-               unsigned long now = jiffies;
+               long delta = expires - jiffies;
+
+               if (delta < 256)
+                       return expires;
 
-               /* No slack, if already expired else auto slack 0.4% */
-               if (time_after(expires, now))
-                       expires_limit = expires + (expires - now)/256;
+               expires_limit = expires + delta / 256;
        }
        mask = expires ^ expires_limit;
        if (mask == 0)
@@ -795,6 +794,8 @@ unsigned long apply_slack(struct timer_list *timer, unsigned long expires)
  */
 int mod_timer(struct timer_list *timer, unsigned long expires)
 {
+       expires = apply_slack(timer, expires);
+
        /*
         * This is a common optimization triggered by the
         * networking code - if the timer is re-modified
@@ -803,8 +804,6 @@ int mod_timer(struct timer_list *timer, unsigned long expires)
        if (timer_pending(timer) && timer->expires == expires)
                return 1;
 
-       expires = apply_slack(timer, expires);
-
        return __mod_timer(timer, expires, false, TIMER_NOT_PINNED);
 }
 EXPORT_SYMBOL(mod_timer);
index 28afa4c5333c121e8a9feac719892fb17e5ef9a0..dd373c8ee94399efad67ad5bc3adf57e51cf4a3d 100644 (file)
@@ -697,7 +697,7 @@ config DEBUG_BUGVERBOSE
        bool "Verbose BUG() reporting (adds 70K)" if DEBUG_KERNEL && EXPERT
        depends on BUG
        depends on ARM || AVR32 || M32R || M68K || SPARC32 || SPARC64 || \
-                  FRV || SUPERH || GENERIC_BUG || BLACKFIN || MN10300
+                  FRV || SUPERH || GENERIC_BUG || BLACKFIN || MN10300 || TILE
        default y
        help
          Say Y here to make BUG() panics output the file name and line number
index c11205688fb4d4ff070409557b633cf05c2d7c07..4365df31a1d52122cd670d5ad2fe321fc887337f 100644 (file)
@@ -666,6 +666,8 @@ char *ip6_compressed_string(char *p, const char *addr)
                        colonpos = i;
                }
        }
+       if (longest == 1)               /* don't compress a single 0 */
+               colonpos = -1;
 
        /* emit address */
        for (i = 0; i < range; i++) {
@@ -826,7 +828,7 @@ int kptr_restrict __read_mostly;
  *       IPv4 uses dot-separated decimal with leading 0's (010.123.045.006)
  * - '[Ii]4[hnbl]' IPv4 addresses in host, network, big or little endian order
  * - 'I6c' for IPv6 addresses printed as specified by
- *       http://tools.ietf.org/html/draft-ietf-6man-text-addr-representation-00
+ *       http://tools.ietf.org/html/rfc5952
  * - 'U' For a 16 byte UUID/GUID, it prints the UUID/GUID in the form
  *       "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
  *       Options for %pU are:
index d7b10578a64ba39b2862464f71d6439609c6fa22..a8251a8d3457d28802164d6538c9226e98416f73 100644 (file)
@@ -2000,7 +2000,7 @@ int file_remove_suid(struct file *file)
                error = security_inode_killpriv(dentry);
        if (!error && killsuid)
                error = __remove_suid(dentry, killsuid);
-       if (!error)
+       if (!error && (inode->i_sb->s_flags & MS_NOSEC))
                inode->i_flags |= S_NOSEC;
 
        return error;
index f33bb319b73f093ce38e828a265b24d9c18e0525..6402458fee38ca5ba2109882e92ebbf63e97c787 100644 (file)
@@ -1033,10 +1033,10 @@ static struct page *alloc_huge_page(struct vm_area_struct *vma,
         */
        chg = vma_needs_reservation(h, vma, addr);
        if (chg < 0)
-               return ERR_PTR(chg);
+               return ERR_PTR(-VM_FAULT_OOM);
        if (chg)
                if (hugetlb_get_quota(inode->i_mapping, chg))
-                       return ERR_PTR(-ENOSPC);
+                       return ERR_PTR(-VM_FAULT_SIGBUS);
 
        spin_lock(&hugetlb_lock);
        page = dequeue_huge_page_vma(h, vma, addr, avoid_reserve);
index a4e1db3f19812e8fc900e4b22fd778e0f959324e..4e8985acdab8b5c234a6486b3c84caf5fb89dca0 100644 (file)
@@ -2247,10 +2247,6 @@ __alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order,
 
        if (should_fail_alloc_page(gfp_mask, order))
                return NULL;
-#ifndef CONFIG_ZONE_DMA
-       if (WARN_ON_ONCE(gfp_mask & __GFP_DMA))
-               return NULL;
-#endif
 
        /*
         * Check the zones suitable for the gfp_mask contain at least one
index f247f5bff88ddb61d252951f57a965789e63f45d..7ea5cf9ea08a9db7f3b6edaf083f14030914463c 100644 (file)
@@ -165,7 +165,7 @@ static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb,
                u64_stats_update_begin(&stats->syncp);
                stats->tx_packets++;
                stats->tx_bytes += len;
-               u64_stats_update_begin(&stats->syncp);
+               u64_stats_update_end(&stats->syncp);
        } else {
                this_cpu_inc(vlan_dev_info(dev)->vlan_pcpu_stats->tx_dropped);
        }
index a86f9ba4f05cd473b6ccd20c17a1d293a459877a..e64a1c2df238d3fc0aac368075b8b0fd3bbb6917 100644 (file)
@@ -906,7 +906,7 @@ static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm, bdaddr
                if (c->psm == psm) {
                        /* Exact match. */
                        if (!bacmp(&bt_sk(sk)->src, src)) {
-                               read_unlock_bh(&chan_list_lock);
+                               read_unlock(&chan_list_lock);
                                return c;
                        }
 
index 649ebacaf6bce69f29028e33c20233fb1932bbee..adbb424403d48982624f36e62418ec9cb47c0132 100644 (file)
@@ -139,17 +139,14 @@ static void close_work(struct work_struct *work)
        struct chnl_net *dev = NULL;
        struct list_head *list_node;
        struct list_head *_tmp;
-       /* May be called with or without RTNL lock held */
-       int islocked = rtnl_is_locked();
-       if (!islocked)
-               rtnl_lock();
+
+       rtnl_lock();
        list_for_each_safe(list_node, _tmp, &chnl_net_list) {
                dev = list_entry(list_node, struct chnl_net, list_field);
                if (dev->state == CAIF_SHUTDOWN)
                        dev_close(dev->netdev);
        }
-       if (!islocked)
-               rtnl_unlock();
+       rtnl_unlock();
 }
 static DECLARE_WORK(close_worker, close_work);
 
index c7e305d13b71b9371aa8973354c2b4cbe09889f6..939307891e71ed36fcc888ea3194f57b7026c6cc 100644 (file)
@@ -2096,6 +2096,7 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
 {
        const struct net_device_ops *ops = dev->netdev_ops;
        int rc = NETDEV_TX_OK;
+       unsigned int skb_len;
 
        if (likely(!skb->next)) {
                u32 features;
@@ -2146,8 +2147,9 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
                        }
                }
 
+               skb_len = skb->len;
                rc = ops->ndo_start_xmit(skb, dev);
-               trace_net_dev_xmit(skb, rc);
+               trace_net_dev_xmit(skb, rc, dev, skb_len);
                if (rc == NETDEV_TX_OK)
                        txq_trans_update(txq);
                return rc;
@@ -2167,8 +2169,9 @@ gso:
                if (dev->priv_flags & IFF_XMIT_DST_RELEASE)
                        skb_dst_drop(nskb);
 
+               skb_len = nskb->len;
                rc = ops->ndo_start_xmit(nskb, dev);
-               trace_net_dev_xmit(nskb, rc);
+               trace_net_dev_xmit(nskb, rc, dev, skb_len);
                if (unlikely(rc != NETDEV_TX_OK)) {
                        if (rc & ~NETDEV_TX_MASK)
                                goto out_kfree_gso_skb;
index cc1463156cd037ad08b6a2f637c90b4d43fc5e7a..9c1926027a268162a3c37374a5f3397661c6dba6 100644 (file)
@@ -465,6 +465,9 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
        if (addr_len < sizeof(struct sockaddr_in))
                goto out;
 
+       if (addr->sin_family != AF_INET)
+               goto out;
+
        chk_addr_ret = inet_addr_type(sock_net(sk), addr->sin_addr.s_addr);
 
        /* Not specified by any standard per-se, however it breaks too
index c3118e1cd3bb502c293748e40b2c3ccc648c8b94..ec93335901ddc45d09f7c85c53270ea9a6772207 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/slab.h>
 #include <linux/types.h>
 #include <asm/uaccess.h>
+#include <asm/unaligned.h>
 #include <linux/skbuff.h>
 #include <linux/ip.h>
 #include <linux/icmp.h>
@@ -350,7 +351,7 @@ int ip_options_compile(struct net *net,
                                goto error;
                        }
                        if (optptr[2] <= optlen) {
-                               __be32 *timeptr = NULL;
+                               unsigned char *timeptr = NULL;
                                if (optptr[2]+3 > optptr[1]) {
                                        pp_ptr = optptr + 2;
                                        goto error;
@@ -359,7 +360,7 @@ int ip_options_compile(struct net *net,
                                      case IPOPT_TS_TSONLY:
                                        opt->ts = optptr - iph;
                                        if (skb)
-                                               timeptr = (__be32*)&optptr[optptr[2]-1];
+                                               timeptr = &optptr[optptr[2]-1];
                                        opt->ts_needtime = 1;
                                        optptr[2] += 4;
                                        break;
@@ -371,7 +372,7 @@ int ip_options_compile(struct net *net,
                                        opt->ts = optptr - iph;
                                        if (rt)  {
                                                memcpy(&optptr[optptr[2]-1], &rt->rt_spec_dst, 4);
-                                               timeptr = (__be32*)&optptr[optptr[2]+3];
+                                               timeptr = &optptr[optptr[2]+3];
                                        }
                                        opt->ts_needaddr = 1;
                                        opt->ts_needtime = 1;
@@ -389,7 +390,7 @@ int ip_options_compile(struct net *net,
                                                if (inet_addr_type(net, addr) == RTN_UNICAST)
                                                        break;
                                                if (skb)
-                                                       timeptr = (__be32*)&optptr[optptr[2]+3];
+                                                       timeptr = &optptr[optptr[2]+3];
                                        }
                                        opt->ts_needtime = 1;
                                        optptr[2] += 8;
@@ -403,10 +404,10 @@ int ip_options_compile(struct net *net,
                                }
                                if (timeptr) {
                                        struct timespec tv;
-                                       __be32  midtime;
+                                       u32  midtime;
                                        getnstimeofday(&tv);
-                                       midtime = htonl((tv.tv_sec % 86400) * MSEC_PER_SEC + tv.tv_nsec / NSEC_PER_MSEC);
-                                       memcpy(timeptr, &midtime, sizeof(__be32));
+                                       midtime = (tv.tv_sec % 86400) * MSEC_PER_SEC + tv.tv_nsec / NSEC_PER_MSEC;
+                                       put_unaligned_be32(midtime, timeptr);
                                        opt->is_changed = 1;
                                }
                        } else {
index 4f6b2675e41d43fd8335e35094875b41774d9ca8..456cccf26b512ef1babb0420471dd95b51f16670 100644 (file)
@@ -232,6 +232,9 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
                WARN_ON(!ieee80211_set_channel_type(local, sdata, channel_type));
        }
 
+       ieee80211_stop_queues_by_reason(&sdata->local->hw,
+                                       IEEE80211_QUEUE_STOP_REASON_CSA);
+
        /* channel_type change automatically detected */
        ieee80211_hw_config(local, 0);
 
@@ -245,6 +248,9 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
                rcu_read_unlock();
        }
 
+       ieee80211_wake_queues_by_reason(&sdata->local->hw,
+                                       IEEE80211_QUEUE_STOP_REASON_CSA);
+
        ht_opmode = le16_to_cpu(hti->operation_mode);
 
        /* if bss configuration changed store the new one */
@@ -1089,6 +1095,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
                local->hw.conf.flags &= ~IEEE80211_CONF_PS;
                config_changed |= IEEE80211_CONF_CHANGE_PS;
        }
+       local->ps_sdata = NULL;
 
        ieee80211_hw_config(local, config_changed);
 
index 27af6723cb5e5496efc606010bf04541806da43e..58ffa7d069c791c7d2c2c681861212d806260956 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/if_arp.h>
 #include <linux/rtnetlink.h>
 #include <linux/pm_qos_params.h>
-#include <linux/slab.h>
 #include <net/sch_generic.h>
 #include <linux/slab.h>
 #include <net/mac80211.h>
index 925f715686a5d0e57c657ee6af40b5792c085a6d..ba248d93399a95213717b8e170cfd635717b42d9 100644 (file)
@@ -798,7 +798,12 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
                        getnstimeofday(&ts);
                h.h2->tp_sec = ts.tv_sec;
                h.h2->tp_nsec = ts.tv_nsec;
-               h.h2->tp_vlan_tci = vlan_tx_tag_get(skb);
+               if (vlan_tx_tag_present(skb)) {
+                       h.h2->tp_vlan_tci = vlan_tx_tag_get(skb);
+                       status |= TP_STATUS_VLAN_VALID;
+               } else {
+                       h.h2->tp_vlan_tci = 0;
+               }
                hdrlen = sizeof(*h.h2);
                break;
        default:
@@ -1725,8 +1730,12 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
                aux.tp_snaplen = skb->len;
                aux.tp_mac = 0;
                aux.tp_net = skb_network_offset(skb);
-               aux.tp_vlan_tci = vlan_tx_tag_get(skb);
-
+               if (vlan_tx_tag_present(skb)) {
+                       aux.tp_vlan_tci = vlan_tx_tag_get(skb);
+                       aux.tp_status |= TP_STATUS_VLAN_VALID;
+               } else {
+                       aux.tp_vlan_tci = 0;
+               }
                put_cmsg(msg, SOL_PACKET, PACKET_AUXDATA, sizeof(aux), &aux);
        }
 
index 525f97c467e97e3e04a3d279431fc0bf08ff0d2f..4a62888f2e43f43a7037f556257520a462d5ece2 100644 (file)
@@ -444,15 +444,7 @@ void sctp_association_free(struct sctp_association *asoc)
 
        asoc->peer.transport_count = 0;
 
-       /* Free any cached ASCONF_ACK chunk. */
-       sctp_assoc_free_asconf_acks(asoc);
-
-       /* Free the ASCONF queue. */
-       sctp_assoc_free_asconf_queue(asoc);
-
-       /* Free any cached ASCONF chunk. */
-       if (asoc->addip_last_asconf)
-               sctp_chunk_free(asoc->addip_last_asconf);
+       sctp_asconf_queue_teardown(asoc);
 
        /* AUTH - Free the endpoint shared keys */
        sctp_auth_destroy_keys(&asoc->endpoint_shared_keys);
@@ -1646,3 +1638,16 @@ struct sctp_chunk *sctp_assoc_lookup_asconf_ack(
 
        return NULL;
 }
+
+void sctp_asconf_queue_teardown(struct sctp_association *asoc)
+{
+       /* Free any cached ASCONF_ACK chunk. */
+       sctp_assoc_free_asconf_acks(asoc);
+
+       /* Free the ASCONF queue. */
+       sctp_assoc_free_asconf_queue(asoc);
+
+       /* Free any cached ASCONF chunk. */
+       if (asoc->addip_last_asconf)
+               sctp_chunk_free(asoc->addip_last_asconf);
+}
index d612ca1ca6c08fb979bbfad4f6252e27be729be6..534c2e5feb054c933cbd0dcf46a0cb66386646dd 100644 (file)
@@ -1670,6 +1670,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
                case SCTP_CMD_SEND_NEXT_ASCONF:
                        sctp_cmd_send_asconf(asoc);
                        break;
+               case SCTP_CMD_PURGE_ASCONF_QUEUE:
+                       sctp_asconf_queue_teardown(asoc);
+                       break;
                default:
                        pr_warn("Impossible command: %u, %p\n",
                                cmd->verb, cmd->obj.ptr);
index 7f4a4f8368ee0df6b6ccab07ada25df655b7b521..a297283154d5035c6342e54916f10445aa610d83 100644 (file)
@@ -1718,11 +1718,21 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(const struct sctp_endpoint *ep,
                return SCTP_DISPOSITION_CONSUME;
        }
 
-       /* For now, fail any unsent/unacked data.  Consider the optional
-        * choice of resending of this data.
+       /* For now, stop pending T3-rtx and SACK timers, fail any unsent/unacked
+        * data. Consider the optional choice of resending of this data.
         */
+       sctp_add_cmd_sf(commands, SCTP_CMD_T3_RTX_TIMERS_STOP, SCTP_NULL());
+       sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
+                       SCTP_TO(SCTP_EVENT_TIMEOUT_SACK));
        sctp_add_cmd_sf(commands, SCTP_CMD_PURGE_OUTQUEUE, SCTP_NULL());
 
+       /* Stop pending T4-rto timer, teardown ASCONF queue, ASCONF-ACK queue
+        * and ASCONF-ACK cache.
+        */
+       sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
+                       SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO));
+       sctp_add_cmd_sf(commands, SCTP_CMD_PURGE_ASCONF_QUEUE, SCTP_NULL());
+
        repl = sctp_make_cookie_ack(new_asoc, chunk);
        if (!repl)
                goto nomem;
index ec83f413a7ed19d41b3a37a0a7e0b1d7b1ce9988..88a565f130a5a2e2e0f72fca3c204505a810a652 100644 (file)
@@ -3406,12 +3406,12 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
        i = 0;
        if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) {
                nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) {
+                       request->ssids[i].ssid_len = nla_len(attr);
                        if (request->ssids[i].ssid_len > IEEE80211_MAX_SSID_LEN) {
                                err = -EINVAL;
                                goto out_free;
                        }
                        memcpy(request->ssids[i].ssid, nla_data(attr), nla_len(attr));
-                       request->ssids[i].ssid_len = nla_len(attr);
                        i++;
                }
        }
@@ -3572,6 +3572,7 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
        if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) {
                nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS],
                                    tmp) {
+                       request->ssids[i].ssid_len = nla_len(attr);
                        if (request->ssids[i].ssid_len >
                            IEEE80211_MAX_SSID_LEN) {
                                err = -EINVAL;
@@ -3579,7 +3580,6 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
                        }
                        memcpy(request->ssids[i].ssid, nla_data(attr),
                               nla_len(attr));
-                       request->ssids[i].ssid_len = nla_len(attr);
                        i++;
                }
        }
index 73a441d237b59ea89eaef14598299877459a3f61..7a6c67667d708e97400a6974175323f7cfd712e6 100644 (file)
@@ -267,13 +267,35 @@ static bool is_bss(struct cfg80211_bss *a,
        return memcmp(ssidie + 2, ssid, ssid_len) == 0;
 }
 
+static bool is_mesh_bss(struct cfg80211_bss *a)
+{
+       const u8 *ie;
+
+       if (!WLAN_CAPABILITY_IS_STA_BSS(a->capability))
+               return false;
+
+       ie = cfg80211_find_ie(WLAN_EID_MESH_ID,
+                             a->information_elements,
+                             a->len_information_elements);
+       if (!ie)
+               return false;
+
+       ie = cfg80211_find_ie(WLAN_EID_MESH_CONFIG,
+                             a->information_elements,
+                             a->len_information_elements);
+       if (!ie)
+               return false;
+
+       return true;
+}
+
 static bool is_mesh(struct cfg80211_bss *a,
                    const u8 *meshid, size_t meshidlen,
                    const u8 *meshcfg)
 {
        const u8 *ie;
 
-       if (!WLAN_CAPABILITY_IS_MBSS(a->capability))
+       if (!WLAN_CAPABILITY_IS_STA_BSS(a->capability))
                return false;
 
        ie = cfg80211_find_ie(WLAN_EID_MESH_ID,
@@ -311,7 +333,7 @@ static int cmp_bss(struct cfg80211_bss *a,
        if (a->channel != b->channel)
                return b->channel->center_freq - a->channel->center_freq;
 
-       if (WLAN_CAPABILITY_IS_MBSS(a->capability | b->capability)) {
+       if (is_mesh_bss(a) && is_mesh_bss(b)) {
                r = cmp_ies(WLAN_EID_MESH_ID,
                            a->information_elements,
                            a->len_information_elements,
@@ -457,7 +479,6 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
                    struct cfg80211_internal_bss *res)
 {
        struct cfg80211_internal_bss *found = NULL;
-       const u8 *meshid, *meshcfg;
 
        /*
         * The reference to "res" is donated to this function.
@@ -470,22 +491,6 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
 
        res->ts = jiffies;
 
-       if (WLAN_CAPABILITY_IS_MBSS(res->pub.capability)) {
-               /* must be mesh, verify */
-               meshid = cfg80211_find_ie(WLAN_EID_MESH_ID,
-                                         res->pub.information_elements,
-                                         res->pub.len_information_elements);
-               meshcfg = cfg80211_find_ie(WLAN_EID_MESH_CONFIG,
-                                          res->pub.information_elements,
-                                          res->pub.len_information_elements);
-               if (!meshid || !meshcfg ||
-                   meshcfg[1] != sizeof(struct ieee80211_meshconf_ie)) {
-                       /* bogus mesh */
-                       kref_put(&res->ref, bss_release);
-                       return NULL;
-               }
-       }
-
        spin_lock_bh(&dev->bss_lock);
 
        found = rb_find_bss(dev, res);
index ae3a698415e63603d9b159814b45c58b0f83eee0..ec1bcecf2cdacd6009c79d6a809d4b7b8443f29d 100644 (file)
@@ -593,7 +593,8 @@ static int apparmor_setprocattr(struct task_struct *task, char *name,
                        sa.aad.op = OP_SETPROCATTR;
                        sa.aad.info = name;
                        sa.aad.error = -EINVAL;
-                       return aa_audit(AUDIT_APPARMOR_DENIED, NULL, GFP_KERNEL,
+                       return aa_audit(AUDIT_APPARMOR_DENIED,
+                                       __aa_current_profile(), GFP_KERNEL,
                                        &sa, NULL);
                }
        } else if (strcmp(name, "exec") == 0) {
index a0d38459d650af32fe844ca18d4b5ff5ad03be98..20219ef5439ac69d63b61445a97403524e51c69b 100644 (file)
@@ -1476,7 +1476,6 @@ static int inode_has_perm(const struct cred *cred,
                          unsigned flags)
 {
        struct inode_security_struct *isec;
-       struct common_audit_data ad;
        u32 sid;
 
        validate_creds(cred);
@@ -1487,15 +1486,21 @@ static int inode_has_perm(const struct cred *cred,
        sid = cred_sid(cred);
        isec = inode->i_security;
 
-       if (!adp) {
-               adp = &ad;
-               COMMON_AUDIT_DATA_INIT(&ad, INODE);
-               ad.u.inode = inode;
-       }
-
        return avc_has_perm_flags(sid, isec->sid, isec->sclass, perms, adp, flags);
 }
 
+static int inode_has_perm_noadp(const struct cred *cred,
+                               struct inode *inode,
+                               u32 perms,
+                               unsigned flags)
+{
+       struct common_audit_data ad;
+
+       COMMON_AUDIT_DATA_INIT(&ad, INODE);
+       ad.u.inode = inode;
+       return inode_has_perm(cred, inode, perms, &ad, flags);
+}
+
 /* Same as inode_has_perm, but pass explicit audit data containing
    the dentry to help the auditing code to more easily generate the
    pathname if needed. */
@@ -2122,8 +2127,8 @@ static inline void flush_unauthorized_files(const struct cred *cred,
                                                struct tty_file_private, list);
                        file = file_priv->file;
                        inode = file->f_path.dentry->d_inode;
-                       if (inode_has_perm(cred, inode,
-                                          FILE__READ | FILE__WRITE, NULL, 0)) {
+                       if (inode_has_perm_noadp(cred, inode,
+                                          FILE__READ | FILE__WRITE, 0)) {
                                drop_tty = 1;
                        }
                }
@@ -3228,7 +3233,7 @@ static int selinux_dentry_open(struct file *file, const struct cred *cred)
         * new inode label or new policy.
         * This check is not redundant - do not remove.
         */
-       return inode_has_perm(cred, inode, open_file_to_av(file), NULL, 0);
+       return inode_has_perm_noadp(cred, inode, open_file_to_av(file), 0);
 }
 
 /* task security operations */
index fb311d8c05bff2365776260b089f878c7cb02ac6..5c6ea113d219cc2566a75d05d0d1e9b7f8272f2e 100644 (file)
@@ -60,7 +60,7 @@ struct code_header {
            HPI_VER_MINOR(HPI_VER) * 100 + HPI_VER_RELEASE(HPI_VER)))
 
 /***********************************************************************/
-#include "linux/pci.h"
+#include <linux/pci.h>
 /*-------------------------------------------------------------------*/
 short hpi_dsp_code_open(u32 adapter, struct dsp_code *ps_dsp_code,
        u32 *pos_error_code)
index eacd4901a308d8b0b3c6a269ccd8c38bbf4f4f67..a7ec7030cf87e9773a1ce1f58ee318ace075498a 100644 (file)
@@ -1234,9 +1234,12 @@ static int __devinit snd_fm801_create(struct snd_card *card,
        sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci));
        if ((tea575x_tuner & TUNER_TYPE_MASK) > 0 &&
            (tea575x_tuner & TUNER_TYPE_MASK) < 4) {
-               if (snd_tea575x_init(&chip->tea))
+               if (snd_tea575x_init(&chip->tea)) {
                        snd_printk(KERN_ERR "TEA575x radio not found\n");
-       } else if ((tea575x_tuner & TUNER_TYPE_MASK) == 0)
+                       snd_fm801_free(chip);
+                       return -ENODEV;
+               }
+       } else if ((tea575x_tuner & TUNER_TYPE_MASK) == 0) {
                /* autodetect tuner connection */
                for (tea575x_tuner = 1; tea575x_tuner <= 3; tea575x_tuner++) {
                        chip->tea575x_tuner = tea575x_tuner;
@@ -1246,6 +1249,12 @@ static int __devinit snd_fm801_create(struct snd_card *card,
                                break;
                        }
                }
+               if (tea575x_tuner == 4) {
+                       snd_printk(KERN_ERR "TEA575x radio not found\n");
+                       snd_fm801_free(chip);
+                       return -ENODEV;
+               }
+       }
        strlcpy(chip->tea.card, snd_fm801_tea575x_gpios[(tea575x_tuner & TUNER_TYPE_MASK) - 1].name, sizeof(chip->tea.card));
 #endif
 
index 696ac2590307d7d46d8733a08cdef40cead16de7..d694e9d4921d85eef34f6588386c0235c9913e10 100644 (file)
@@ -506,9 +506,11 @@ static void ad198x_power_eapd_write(struct hda_codec *codec, hda_nid_t front,
                                hda_nid_t hp)
 {
        struct ad198x_spec *spec = codec->spec;
-       snd_hda_codec_write(codec, front, 0, AC_VERB_SET_EAPD_BTLENABLE,
+       if (snd_hda_query_pin_caps(codec, front) & AC_PINCAP_EAPD)
+               snd_hda_codec_write(codec, front, 0, AC_VERB_SET_EAPD_BTLENABLE,
                            !spec->inv_eapd ? 0x00 : 0x02);
-       snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_EAPD_BTLENABLE,
+       if (snd_hda_query_pin_caps(codec, hp) & AC_PINCAP_EAPD)
+               snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_EAPD_BTLENABLE,
                            !spec->inv_eapd ? 0x00 : 0x02);
 }
 
@@ -524,6 +526,10 @@ static void ad198x_power_eapd(struct hda_codec *codec)
        case 0x11d4184a:
        case 0x11d4194a:
        case 0x11d4194b:
+       case 0x11d41988:
+       case 0x11d4198b:
+       case 0x11d4989a:
+       case 0x11d4989b:
                ad198x_power_eapd_write(codec, 0x12, 0x11);
                break;
        case 0x11d41981:
@@ -533,12 +539,6 @@ static void ad198x_power_eapd(struct hda_codec *codec)
        case 0x11d41986:
                ad198x_power_eapd_write(codec, 0x1b, 0x1a);
                break;
-       case 0x11d41988:
-       case 0x11d4198b:
-       case 0x11d4989a:
-       case 0x11d4989b:
-               ad198x_power_eapd_write(codec, 0x29, 0x22);
-               break;
        }
 }
 
index f8c663dcff027d9d10083a41d0a6f5cd3b082e20..d68ea532cc7f59a52e46be1a89ccf4d0c35ad518 100644 (file)
@@ -262,14 +262,14 @@ static int v253_hangup(struct tty_struct *tty)
 }
 
 /* Line discipline .receive_buf() */
-static unsigned int v253_receive(struct tty_struct *tty,
-                                const unsigned char *cp, char *fp, int count)
+static void v253_receive(struct tty_struct *tty,
+                               const unsigned char *cp, char *fp, int count)
 {
        struct snd_soc_codec *codec = tty->disc_data;
        struct cx20442_priv *cx20442;
 
        if (!codec)
-               return count;
+               return;
 
        cx20442 = snd_soc_codec_get_drvdata(codec);
 
@@ -281,8 +281,6 @@ static unsigned int v253_receive(struct tty_struct *tty,
                codec->hw_write = (hw_write_t)tty->ops->write;
                codec->card->pop_time = 1;
        }
-
-       return count;
 }
 
 /* Line discipline .write_wakeup() */
index e55b298c14a06e249f54453829295c880c39998a..9e370d14ad88f2bce72ccd0ce1204eb01bd854fa 100644 (file)
@@ -215,23 +215,23 @@ static const struct snd_kcontrol_new analogue_snd_controls[] = {
 SOC_SINGLE_TLV("IN1L Volume", WM8993_LEFT_LINE_INPUT_1_2_VOLUME, 0, 31, 0,
               inpga_tlv),
 SOC_SINGLE("IN1L Switch", WM8993_LEFT_LINE_INPUT_1_2_VOLUME, 7, 1, 1),
-SOC_SINGLE("IN1L ZC Switch", WM8993_LEFT_LINE_INPUT_1_2_VOLUME, 7, 1, 0),
+SOC_SINGLE("IN1L ZC Switch", WM8993_LEFT_LINE_INPUT_1_2_VOLUME, 6, 1, 0),
 
 SOC_SINGLE_TLV("IN1R Volume", WM8993_RIGHT_LINE_INPUT_1_2_VOLUME, 0, 31, 0,
               inpga_tlv),
 SOC_SINGLE("IN1R Switch", WM8993_RIGHT_LINE_INPUT_1_2_VOLUME, 7, 1, 1),
-SOC_SINGLE("IN1R ZC Switch", WM8993_RIGHT_LINE_INPUT_1_2_VOLUME, 7, 1, 0),
+SOC_SINGLE("IN1R ZC Switch", WM8993_RIGHT_LINE_INPUT_1_2_VOLUME, 6, 1, 0),
 
 
 SOC_SINGLE_TLV("IN2L Volume", WM8993_LEFT_LINE_INPUT_3_4_VOLUME, 0, 31, 0,
               inpga_tlv),
 SOC_SINGLE("IN2L Switch", WM8993_LEFT_LINE_INPUT_3_4_VOLUME, 7, 1, 1),
-SOC_SINGLE("IN2L ZC Switch", WM8993_LEFT_LINE_INPUT_3_4_VOLUME, 7, 1, 0),
+SOC_SINGLE("IN2L ZC Switch", WM8993_LEFT_LINE_INPUT_3_4_VOLUME, 6, 1, 0),
 
 SOC_SINGLE_TLV("IN2R Volume", WM8993_RIGHT_LINE_INPUT_3_4_VOLUME, 0, 31, 0,
               inpga_tlv),
 SOC_SINGLE("IN2R Switch", WM8993_RIGHT_LINE_INPUT_3_4_VOLUME, 7, 1, 1),
-SOC_SINGLE("IN2R ZC Switch", WM8993_RIGHT_LINE_INPUT_3_4_VOLUME, 7, 1, 0),
+SOC_SINGLE("IN2R ZC Switch", WM8993_RIGHT_LINE_INPUT_3_4_VOLUME, 6, 1, 0),
 
 SOC_SINGLE_TLV("MIXINL IN2L Volume", WM8993_INPUT_MIXER3, 7, 1, 0,
               inmix_sw_tlv),
index 999bb08cdfb143708312cd0da0e358caa077d766..776e6f418306fe004936692fd70dab7c89cdec6d 100644 (file)
@@ -325,6 +325,7 @@ static int dapm_connect_mixer(struct snd_soc_dapm_context *dapm,
 }
 
 static int dapm_is_shared_kcontrol(struct snd_soc_dapm_context *dapm,
+       struct snd_soc_dapm_widget *kcontrolw,
        const struct snd_kcontrol_new *kcontrol_new,
        struct snd_kcontrol **kcontrol)
 {
@@ -334,6 +335,8 @@ static int dapm_is_shared_kcontrol(struct snd_soc_dapm_context *dapm,
        *kcontrol = NULL;
 
        list_for_each_entry(w, &dapm->card->widgets, list) {
+               if (w == kcontrolw || w->dapm != kcontrolw->dapm)
+                       continue;
                for (i = 0; i < w->num_kcontrols; i++) {
                        if (&w->kcontrol_news[i] == kcontrol_new) {
                                if (w->kcontrols)
@@ -468,7 +471,7 @@ static int dapm_new_mux(struct snd_soc_dapm_context *dapm,
                return -EINVAL;
        }
 
-       shared = dapm_is_shared_kcontrol(dapm, &w->kcontrol_news[0],
+       shared = dapm_is_shared_kcontrol(dapm, w, &w->kcontrol_news[0],
                                         &kcontrol);
        if (kcontrol) {
                wlist = kcontrol->private_data;
index d47beffedb0ff5b4be36bab35a1014e5bd5aa22f..a91719d5918b69c6e76e577364c59f892f5768bd 100644 (file)
@@ -227,6 +227,7 @@ static int usb6fire_fw_ezusb_upload(
        ret = usb6fire_fw_ihex_init(fw, rec);
        if (ret < 0) {
                kfree(rec);
+               release_firmware(fw);
                snd_printk(KERN_ERR PREFIX "error validating ezusb "
                                "firmware %s.\n", fwname);
                return ret;
index 2e969cbb393b004af02d37419fccb080ce99e9d6..090e1930dfdcc6b37c68b7731e0862cb703a7689 100644 (file)
@@ -403,7 +403,7 @@ static int snd_usb_cm106_boot_quirk(struct usb_device *dev)
 static int snd_usb_cm6206_boot_quirk(struct usb_device *dev)
 {
        int err, reg;
-       int val[] = {0x200c, 0x3000, 0xf800, 0x143f, 0x0000, 0x3000};
+       int val[] = {0x2004, 0x3000, 0xf800, 0x143f, 0x0000, 0x3000};
 
        for (reg = 0; reg < ARRAY_SIZE(val); reg++) {
                err = snd_usb_cm106_write_int_reg(dev, reg, val[reg]);
index b67186228c8916747042db705e9781d131171897..2da9162262b05a189fb969440f8816d90e55b99a 100644 (file)
@@ -474,7 +474,7 @@ static int test__basic_mmap(void)
        unsigned int nr_events[nsyscalls],
                     expected_nr_events[nsyscalls], i, j;
        struct perf_evsel *evsels[nsyscalls], *evsel;
-       int sample_size = perf_sample_size(attr.sample_type);
+       int sample_size = __perf_evsel__sample_size(attr.sample_type);
 
        for (i = 0; i < nsyscalls; ++i) {
                char name[64];
index 0fe9adf76379ecc02895cfbb46f35dcc8666dcbd..3c1b8a6321017efdb75fde50cbe5d1d520a62153 100644 (file)
@@ -35,22 +35,6 @@ const char *perf_event__name(unsigned int id)
        return perf_event__names[id];
 }
 
-int perf_sample_size(u64 sample_type)
-{
-       u64 mask = sample_type & PERF_SAMPLE_MASK;
-       int size = 0;
-       int i;
-
-       for (i = 0; i < 64; i++) {
-               if (mask & (1ULL << i))
-                       size++;
-       }
-
-       size *= sizeof(u64);
-
-       return size;
-}
-
 static struct perf_sample synth_sample = {
        .pid       = -1,
        .tid       = -1,
index c083328714082503b7927ee1401d699f1afc8efc..1d7f66488a885456ab4dac49bcc3ecaadad904c2 100644 (file)
@@ -82,8 +82,6 @@ struct perf_sample {
        struct ip_callchain *callchain;
 };
 
-int perf_sample_size(u64 sample_type);
-
 #define BUILD_ID_SIZE 20
 
 struct build_id_event {
index 50aa34879c33dbaee76fa8230ec2ecacc82e40f3..b021ea9265c3e39b9f18fb9e65f731516b49642d 100644 (file)
@@ -12,7 +12,6 @@
 #include "evlist.h"
 #include "evsel.h"
 #include "util.h"
-#include "debug.h"
 
 #include <sys/mman.h>
 
@@ -257,19 +256,15 @@ int perf_evlist__alloc_mmap(struct perf_evlist *evlist)
        return evlist->mmap != NULL ? 0 : -ENOMEM;
 }
 
-static int __perf_evlist__mmap(struct perf_evlist *evlist, struct perf_evsel *evsel,
+static int __perf_evlist__mmap(struct perf_evlist *evlist,
                               int idx, int prot, int mask, int fd)
 {
        evlist->mmap[idx].prev = 0;
        evlist->mmap[idx].mask = mask;
        evlist->mmap[idx].base = mmap(NULL, evlist->mmap_len, prot,
                                      MAP_SHARED, fd, 0);
-       if (evlist->mmap[idx].base == MAP_FAILED) {
-               if (evlist->cpus->map[idx] == -1 && evsel->attr.inherit)
-                       ui__warning("Inherit is not allowed on per-task "
-                                   "events using mmap.\n");
+       if (evlist->mmap[idx].base == MAP_FAILED)
                return -1;
-       }
 
        perf_evlist__add_pollfd(evlist, fd);
        return 0;
@@ -289,7 +284,7 @@ static int perf_evlist__mmap_per_cpu(struct perf_evlist *evlist, int prot, int m
 
                                if (output == -1) {
                                        output = fd;
-                                       if (__perf_evlist__mmap(evlist, evsel, cpu,
+                                       if (__perf_evlist__mmap(evlist, cpu,
                                                                prot, mask, output) < 0)
                                                goto out_unmap;
                                } else {
@@ -329,7 +324,7 @@ static int perf_evlist__mmap_per_thread(struct perf_evlist *evlist, int prot, in
 
                        if (output == -1) {
                                output = fd;
-                               if (__perf_evlist__mmap(evlist, evsel, thread,
+                               if (__perf_evlist__mmap(evlist, thread,
                                                        prot, mask, output) < 0)
                                        goto out_unmap;
                        } else {
@@ -460,33 +455,46 @@ int perf_evlist__set_filters(struct perf_evlist *evlist)
        return 0;
 }
 
-u64 perf_evlist__sample_type(struct perf_evlist *evlist)
+bool perf_evlist__valid_sample_type(const struct perf_evlist *evlist)
 {
-       struct perf_evsel *pos;
-       u64 type = 0;
-
-       list_for_each_entry(pos, &evlist->entries, node) {
-               if (!type)
-                       type = pos->attr.sample_type;
-               else if (type != pos->attr.sample_type)
-                       die("non matching sample_type");
+       struct perf_evsel *pos, *first;
+
+       pos = first = list_entry(evlist->entries.next, struct perf_evsel, node);
+
+       list_for_each_entry_continue(pos, &evlist->entries, node) {
+               if (first->attr.sample_type != pos->attr.sample_type)
+                       return false;
        }
 
-       return type;
+       return true;
 }
 
-bool perf_evlist__sample_id_all(const struct perf_evlist *evlist)
+u64 perf_evlist__sample_type(const struct perf_evlist *evlist)
+{
+       struct perf_evsel *first;
+
+       first = list_entry(evlist->entries.next, struct perf_evsel, node);
+       return first->attr.sample_type;
+}
+
+bool perf_evlist__valid_sample_id_all(const struct perf_evlist *evlist)
 {
-       bool value = false, first = true;
-       struct perf_evsel *pos;
-
-       list_for_each_entry(pos, &evlist->entries, node) {
-               if (first) {
-                       value = pos->attr.sample_id_all;
-                       first = false;
-               } else if (value != pos->attr.sample_id_all)
-                       die("non matching sample_id_all");
+       struct perf_evsel *pos, *first;
+
+       pos = first = list_entry(evlist->entries.next, struct perf_evsel, node);
+
+       list_for_each_entry_continue(pos, &evlist->entries, node) {
+               if (first->attr.sample_id_all != pos->attr.sample_id_all)
+                       return false;
        }
 
-       return value;
+       return true;
+}
+
+bool perf_evlist__sample_id_all(const struct perf_evlist *evlist)
+{
+       struct perf_evsel *first;
+
+       first = list_entry(evlist->entries.next, struct perf_evsel, node);
+       return first->attr.sample_id_all;
 }
index 0a1ef1f051f0cb0db67c86df9b4e3fe12acfc472..b2b862374f371d363bc19ed3cc684fde1de9f6d3 100644 (file)
@@ -66,7 +66,9 @@ int perf_evlist__create_maps(struct perf_evlist *evlist, pid_t target_pid,
 void perf_evlist__delete_maps(struct perf_evlist *evlist);
 int perf_evlist__set_filters(struct perf_evlist *evlist);
 
-u64 perf_evlist__sample_type(struct perf_evlist *evlist);
-bool perf_evlist__sample_id_all(const struct perf_evlist *evlist);
+u64 perf_evlist__sample_type(const struct perf_evlist *evlist);
+bool perf_evlist__sample_id_all(const const struct perf_evlist *evlist);
 
+bool perf_evlist__valid_sample_type(const struct perf_evlist *evlist);
+bool perf_evlist__valid_sample_id_all(const struct perf_evlist *evlist);
 #endif /* __PERF_EVLIST_H */
index cca29ededb5b7118c6b2dc91d718c61ed00304ba..0239eb87b2321ea9e4fe208605020e83b1d7c718 100644 (file)
 
 #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y))
 
+int __perf_evsel__sample_size(u64 sample_type)
+{
+       u64 mask = sample_type & PERF_SAMPLE_MASK;
+       int size = 0;
+       int i;
+
+       for (i = 0; i < 64; i++) {
+               if (mask & (1ULL << i))
+                       size++;
+       }
+
+       size *= sizeof(u64);
+
+       return size;
+}
+
 void perf_evsel__init(struct perf_evsel *evsel,
                      struct perf_event_attr *attr, int idx)
 {
index f79bb2c09a6cbea510e31d260a1fabb778e13950..7e9366e4490b532bce4facc7b92e38a83c9c68e4 100644 (file)
@@ -149,4 +149,11 @@ static inline int perf_evsel__read_scaled(struct perf_evsel *evsel,
        return __perf_evsel__read(evsel, ncpus, nthreads, true);
 }
 
+int __perf_evsel__sample_size(u64 sample_type);
+
+static inline int perf_evsel__sample_size(struct perf_evsel *evsel)
+{
+       return __perf_evsel__sample_size(evsel->attr.sample_type);
+}
+
 #endif /* __PERF_EVSEL_H */
index 69436b3200a45d20a27a2e0481da3b2bbcd7535c..a9ac0504aabd25f3dc4a528f5e86d291eed4da05 100644 (file)
@@ -674,7 +674,7 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
        struct perf_evlist *evlist = &pevlist->evlist;
        union perf_event *event;
        int sample_id_all = 1, cpu;
-       static char *kwlist[] = {"sample_id_all", NULL, NULL};
+       static char *kwlist[] = {"cpu", "sample_id_all", NULL, NULL};
        int err;
 
        if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i", kwlist,
@@ -692,16 +692,14 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
 
                first = list_entry(evlist->entries.next, struct perf_evsel, node);
                err = perf_event__parse_sample(event, first->attr.sample_type,
-                                              perf_sample_size(first->attr.sample_type),
+                                              perf_evsel__sample_size(first),
                                               sample_id_all, &pevent->sample);
-               if (err) {
-                       pr_err("Can't parse sample, err = %d\n", err);
-                       goto end;
-               }
-
+               if (err)
+                       return PyErr_Format(PyExc_OSError,
+                                           "perf: can't parse sample, err=%d", err);
                return pyevent;
        }
-end:
+
        Py_INCREF(Py_None);
        return Py_None;
 }
index 64500fc787997e700a556f80531440926dfcf0c1..f5a8fbdd3f76b51f9b5abf0bd551c964c3d301ed 100644 (file)
@@ -58,6 +58,16 @@ static int perf_session__open(struct perf_session *self, bool force)
                goto out_close;
        }
 
+       if (!perf_evlist__valid_sample_type(self->evlist)) {
+               pr_err("non matching sample_type");
+               goto out_close;
+       }
+
+       if (!perf_evlist__valid_sample_id_all(self->evlist)) {
+               pr_err("non matching sample_id_all");
+               goto out_close;
+       }
+
        self->size = input_stat.st_size;
        return 0;
 
@@ -97,7 +107,7 @@ out:
 void perf_session__update_sample_type(struct perf_session *self)
 {
        self->sample_type = perf_evlist__sample_type(self->evlist);
-       self->sample_size = perf_sample_size(self->sample_type);
+       self->sample_size = __perf_evsel__sample_size(self->sample_type);
        self->sample_id_all = perf_evlist__sample_id_all(self->evlist);
        perf_session__id_header_size(self);
 }
index 1fd29b2daa9204fff6e345c8871799dcb0e04e5e..cef28e6632b98cd4e82426f45805f676c2fc0543 100755 (executable)
@@ -788,7 +788,7 @@ sub wait_for_input
 
 sub reboot_to {
     if ($reboot_type eq "grub") {
-       run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch; reboot)'";
+       run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch && reboot)'";
        return;
     }
 
@@ -1480,7 +1480,7 @@ sub process_config_ignore {
        or dodie "Failed to read $config";
 
     while (<IN>) {
-       if (/^(.*?(CONFIG\S*)(=.*| is not set))/) {
+       if (/^((CONFIG\S*)=.*)/) {
            $config_ignore{$2} = $1;
        }
     }
@@ -1638,7 +1638,7 @@ sub run_config_bisect {
        if (!$found) {
            # try the other half
            doprint "Top half produced no set configs, trying bottom half\n";
-           @tophalf = @start_list[$half .. $#start_list];
+           @tophalf = @start_list[$half + 1 .. $#start_list];
            create_config @tophalf;
            read_current_config \%current_config;
            foreach my $config (@tophalf) {
@@ -1690,7 +1690,7 @@ sub run_config_bisect {
        # remove half the configs we are looking at and see if
        # they are good.
        $half = int($#start_list / 2);
-    } while ($half > 0);
+    } while ($#start_list > 0);
 
     # we found a single config, try it again unless we are running manually
 
index df0c6d2c386098cb4a23ed963af885f6a7945cc1..74d3331bdaf992b10bdf38d630d0dca00cc08360 100644 (file)
@@ -197,6 +197,14 @@ const struct option longopts[] = {
                .name = "help",
                .val = 'h',
        },
+       {
+               .name = "event-idx",
+               .val = 'E',
+       },
+       {
+               .name = "no-event-idx",
+               .val = 'e',
+       },
        {
                .name = "indirect",
                .val = 'I',
@@ -211,13 +219,17 @@ const struct option longopts[] = {
 
 static void help()
 {
-       fprintf(stderr, "Usage: virtio_test [--help] [--no-indirect]\n");
+       fprintf(stderr, "Usage: virtio_test [--help]"
+               " [--no-indirect]"
+               " [--no-event-idx]"
+               "\n");
 }
 
 int main(int argc, char **argv)
 {
        struct vdev_info dev;
-       unsigned long long features = 1ULL << VIRTIO_RING_F_INDIRECT_DESC;
+       unsigned long long features = (1ULL << VIRTIO_RING_F_INDIRECT_DESC) |
+               (1ULL << VIRTIO_RING_F_EVENT_IDX);
        int o;
 
        for (;;) {
@@ -228,6 +240,9 @@ int main(int argc, char **argv)
                case '?':
                        help();
                        exit(2);
+               case 'e':
+                       features &= ~(1ULL << VIRTIO_RING_F_EVENT_IDX);
+                       break;
                case 'h':
                        help();
                        goto done;
index 22cdb960660a61cd6c142278b08ed175b3d9110b..96ebc0679415baeff88d7764b1c0e956820adad2 100644 (file)
@@ -467,12 +467,8 @@ static struct kvm *kvm_create_vm(void)
                if (!kvm->buses[i])
                        goto out_err;
        }
-       spin_lock_init(&kvm->mmu_lock);
-
-       r = kvm_init_mmu_notifier(kvm);
-       if (r)
-               goto out_err;
 
+       spin_lock_init(&kvm->mmu_lock);
        kvm->mm = current->mm;
        atomic_inc(&kvm->mm->mm_count);
        kvm_eventfd_init(kvm);
@@ -480,6 +476,11 @@ static struct kvm *kvm_create_vm(void)
        mutex_init(&kvm->irq_lock);
        mutex_init(&kvm->slots_lock);
        atomic_set(&kvm->users_count, 1);
+
+       r = kvm_init_mmu_notifier(kvm);
+       if (r)
+               goto out_err;
+
        raw_spin_lock(&kvm_lock);
        list_add(&kvm->vm_list, &vm_list);
        raw_spin_unlock(&kvm_lock);
@@ -651,7 +652,9 @@ int __kvm_set_memory_region(struct kvm *kvm,
        /* We can read the guest memory with __xxx_user() later on. */
        if (user_alloc &&
            ((mem->userspace_addr & (PAGE_SIZE - 1)) ||
-            !access_ok(VERIFY_WRITE, mem->userspace_addr, mem->memory_size)))
+            !access_ok(VERIFY_WRITE,
+                       (void __user *)(unsigned long)mem->userspace_addr,
+                       mem->memory_size)))
                goto out;
        if (mem->slot >= KVM_MEMORY_SLOTS + KVM_PRIVATE_MEM_SLOTS)
                goto out;