]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 20 Nov 2010 03:46:45 +0000 (19:46 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 20 Nov 2010 03:46:45 +0000 (19:46 -0800)
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4:
  ext4: Add EXT4_IOC_TRIM ioctl to handle batched discard
  fs: Do not dispatch FITRIM through separate super_operation
  ext4: ext4_fill_super shouldn't return 0 on corruption
  jbd2: fix /proc/fs/jbd2/<dev> when using an external journal
  ext4: missing unlock in ext4_clear_request_list()
  ext4: fix setting random pages PageUptodate

406 files changed:
Documentation/DocBook/uio-howto.tmpl
Documentation/development-process/2.Process
Documentation/filesystems/configfs/configfs_example_explicit.c
Documentation/gpio.txt
Documentation/hwmon/lm93
Documentation/hwmon/max6650
Documentation/power/opp.txt
MAINTAINERS
arch/blackfin/kernel/process.c
arch/frv/kernel/process.c
arch/h8300/kernel/process.c
arch/ia64/hp/sim/simscsi.c
arch/m68k/kernel/process.c
arch/m68knommu/kernel/process.c
arch/mn10300/kernel/process.c
arch/parisc/hpux/sys_hpux.c
arch/parisc/kernel/sys_parisc32.c
arch/powerpc/Kconfig
arch/powerpc/boot/div64.S
arch/powerpc/kernel/kgdb.c
arch/powerpc/kernel/setup_64.c
arch/powerpc/kernel/sys_ppc32.c
arch/powerpc/mm/hash_utils_64.c
arch/powerpc/mm/tlb_low_64e.S
arch/powerpc/mm/tlb_nohash.c
arch/powerpc/platforms/pseries/Kconfig
arch/powerpc/platforms/pseries/eeh.c
arch/powerpc/platforms/pseries/pci_dlpar.c
arch/s390/Kconfig.debug
arch/s390/include/asm/page.h
arch/s390/kernel/compat_linux.c
arch/s390/kernel/kprobes.c
arch/s390/mm/gup.c
arch/sparc/kernel/leon_smp.c
arch/sparc/kernel/sys_sparc32.c
arch/sparc/kernel/sys_sparc_32.c
arch/sparc/kernel/unaligned_32.c
arch/sparc/kernel/windows.c
arch/tile/kernel/compat.c
arch/tile/kernel/compat_signal.c
arch/tile/kernel/signal.c
arch/tile/kernel/smpboot.c
arch/tile/kernel/sys.c
arch/tile/mm/fault.c
arch/tile/mm/hugetlbpage.c
arch/um/kernel/exec.c
arch/x86/ia32/sys_ia32.c
arch/x86/kernel/cpuid.c
arch/x86/kernel/kgdb.c
arch/x86/kernel/msr.c
arch/x86/kvm/svm.c
arch/x86/kvm/vmx.c
block/compat_ioctl.c
block/ioctl.c
drivers/ata/libata-scsi.c
drivers/ata/sata_via.c
drivers/base/power/main.c
drivers/block/cciss_scsi.c
drivers/block/drbd/drbd_receiver.c
drivers/block/drbd/drbd_worker.c
drivers/char/agp/frontend.c
drivers/char/amiserial.c
drivers/char/briq_panel.c
drivers/char/hpet.c
drivers/char/hw_random/core.c
drivers/char/istallion.c
drivers/char/serial167.c
drivers/char/specialix.c
drivers/char/stallion.c
drivers/char/sx.c
drivers/char/uv_mmtimer.c
drivers/firewire/sbp2.c
drivers/gpu/drm/drm_fops.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/intel_crt.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_i2c.c
drivers/gpu/drm/nouveau/nouveau_backlight.c
drivers/gpu/drm/nouveau/nouveau_bios.c
drivers/gpu/drm/nouveau/nouveau_bo.c
drivers/gpu/drm/nouveau/nouveau_connector.c
drivers/gpu/drm/nouveau/nouveau_connector.h
drivers/gpu/drm/nouveau/nouveau_drv.h
drivers/gpu/drm/nouveau/nouveau_fence.c
drivers/gpu/drm/nouveau/nouveau_gem.c
drivers/gpu/drm/nouveau/nouveau_hw.c
drivers/gpu/drm/nouveau/nouveau_hw.h
drivers/gpu/drm/nouveau/nouveau_i2c.c
drivers/gpu/drm/nouveau/nouveau_irq.c
drivers/gpu/drm/nouveau/nouveau_mem.c
drivers/gpu/drm/nouveau/nouveau_object.c
drivers/gpu/drm/nouveau/nouveau_pm.c
drivers/gpu/drm/nouveau/nouveau_ramht.c
drivers/gpu/drm/nouveau/nouveau_sgdma.c
drivers/gpu/drm/nouveau/nouveau_state.c
drivers/gpu/drm/nouveau/nouveau_temp.c
drivers/gpu/drm/nouveau/nv04_crtc.c
drivers/gpu/drm/nouveau/nv04_dfp.c
drivers/gpu/drm/nouveau/nv04_pm.c
drivers/gpu/drm/nouveau/nv50_calc.c
drivers/gpu/drm/nouveau/nv50_crtc.c
drivers/gpu/drm/nouveau/nv50_display.c
drivers/gpu/drm/nouveau/nv50_fifo.c
drivers/gpu/drm/nouveau/nv50_graph.c
drivers/gpu/drm/nouveau/nv50_instmem.c
drivers/gpu/drm/radeon/evergreen.c
drivers/gpu/drm/radeon/evergreen_blit_kms.c
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/r600_blit_kms.c
drivers/gpu/drm/radeon/r600_cs.c
drivers/gpu/drm/radeon/r600d.h
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_benchmark.c
drivers/gpu/drm/radeon/radeon_combios.c
drivers/gpu/drm/radeon/radeon_connectors.c
drivers/gpu/drm/radeon/radeon_device.c
drivers/gpu/drm/radeon/radeon_encoders.c
drivers/gpu/drm/radeon/radeon_gart.c
drivers/gpu/drm/radeon/radeon_gem.c
drivers/gpu/drm/radeon/radeon_i2c.c
drivers/gpu/drm/radeon/radeon_irq.c
drivers/gpu/drm/radeon/radeon_legacy_encoders.c
drivers/gpu/drm/radeon/radeon_mode.h
drivers/gpu/drm/radeon/radeon_object.c
drivers/gpu/drm/radeon/radeon_object.h
drivers/gpu/drm/radeon/radeon_ring.c
drivers/gpu/drm/radeon/radeon_test.c
drivers/gpu/drm/radeon/radeon_ttm.c
drivers/gpu/drm/radeon/rv770.c
drivers/gpu/drm/ttm/ttm_bo.c
drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
drivers/hid/hidraw.c
drivers/hid/usbhid/hiddev.c
drivers/infiniband/hw/ipath/ipath_file_ops.c
drivers/infiniband/ulp/srp/ib_srp.c
drivers/input/input.c
drivers/input/serio/serio_raw.c
drivers/input/tablet/aiptek.c
drivers/media/dvb/dvb-core/dvb_ca_en50221.c
drivers/media/dvb/dvb-core/dvb_frontend.c
drivers/media/dvb/ngene/ngene-core.c
drivers/media/dvb/ngene/ngene-dvb.c
drivers/media/dvb/ngene/ngene-i2c.c
drivers/media/radio/radio-mr800.c
drivers/media/radio/si470x/radio-si470x.h
drivers/media/video/bt8xx/bttv-driver.c
drivers/media/video/cx88/cx88-blackbird.c
drivers/media/video/cx88/cx88-video.c
drivers/media/video/pwc/pwc-if.c
drivers/media/video/s2255drv.c
drivers/media/video/saa7134/saa7134-empress.c
drivers/media/video/saa7164/saa7164.h
drivers/media/video/usbvision/usbvision-video.c
drivers/media/video/v4l2-compat-ioctl32.c
drivers/message/fusion/mptfc.c
drivers/message/fusion/mptsas.c
drivers/message/fusion/mptspi.c
drivers/message/i2o/i2o_scsi.c
drivers/net/3c59x.c
drivers/net/8139cp.c
drivers/net/benet/be_main.c
drivers/net/bnx2x/bnx2x_main.c
drivers/net/bonding/bond_main.c
drivers/net/caif/caif_spi.c
drivers/net/gianfar.c
drivers/net/ipg.c
drivers/net/r8169.c
drivers/net/wireless/ath/ath9k/eeprom_9287.c
drivers/net/wireless/ath/ath9k/hif_usb.c
drivers/net/wireless/ath/ath9k/htc_drv_init.c
drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
drivers/net/wireless/ath/ath9k/init.c
drivers/net/wireless/ath/ath9k/reg.h
drivers/net/wireless/ath/carl9170/usb.c
drivers/net/wireless/orinoco/orinoco_usb.c
drivers/parisc/eisa_eeprom.c
drivers/pci/pci-sysfs.c
drivers/pci/proc.c
drivers/pnp/isapnp/proc.c
drivers/s390/block/dasd_eer.c
drivers/s390/char/fs3270.c
drivers/s390/char/tape_char.c
drivers/s390/char/tape_core.c
drivers/s390/char/vmlogrdr.c
drivers/s390/char/vmur.c
drivers/s390/cio/device.c
drivers/s390/crypto/zcrypt_api.c
drivers/s390/scsi/zfcp_scsi.c
drivers/scsi/3w-9xxx.c
drivers/scsi/3w-sas.c
drivers/scsi/3w-xxxx.c
drivers/scsi/53c700.c
drivers/scsi/BusLogic.c
drivers/scsi/BusLogic.h
drivers/scsi/NCR5380.c
drivers/scsi/NCR5380.h
drivers/scsi/NCR53c406a.c
drivers/scsi/a100u2w.c
drivers/scsi/aacraid/linit.c
drivers/scsi/advansys.c
drivers/scsi/aha152x.c
drivers/scsi/aha1542.c
drivers/scsi/aha1542.h
drivers/scsi/aha1740.c
drivers/scsi/aic7xxx/aic79xx_osm.c
drivers/scsi/aic7xxx/aic7xxx_osm.c
drivers/scsi/aic7xxx_old.c
drivers/scsi/arcmsr/arcmsr_hba.c
drivers/scsi/arm/acornscsi.c
drivers/scsi/arm/fas216.c
drivers/scsi/arm/fas216.h
drivers/scsi/atari_NCR5380.c
drivers/scsi/atari_scsi.c
drivers/scsi/atp870u.c
drivers/scsi/bfa/bfad_im.c
drivers/scsi/dc395x.c
drivers/scsi/dpt_i2o.c
drivers/scsi/dpti.h
drivers/scsi/dtc.h
drivers/scsi/eata.c
drivers/scsi/eata_pio.c
drivers/scsi/esp_scsi.c
drivers/scsi/fd_mcs.c
drivers/scsi/fdomain.c
drivers/scsi/fnic/fnic.h
drivers/scsi/fnic/fnic_scsi.c
drivers/scsi/g_NCR5380.h
drivers/scsi/gdth.c
drivers/scsi/hpsa.c
drivers/scsi/hptiop.c
drivers/scsi/ibmmca.c
drivers/scsi/ibmvscsi/ibmvfc.c
drivers/scsi/ibmvscsi/ibmvscsi.c
drivers/scsi/imm.c
drivers/scsi/in2000.c
drivers/scsi/in2000.h
drivers/scsi/initio.c
drivers/scsi/ipr.c
drivers/scsi/ips.c
drivers/scsi/libfc/fc_fcp.c
drivers/scsi/libiscsi.c
drivers/scsi/libsas/sas_scsi_host.c
drivers/scsi/lpfc/lpfc_scsi.c
drivers/scsi/mac53c94.c
drivers/scsi/megaraid.c
drivers/scsi/megaraid.h
drivers/scsi/megaraid/megaraid_mbox.c
drivers/scsi/megaraid/megaraid_sas.c
drivers/scsi/mesh.c
drivers/scsi/mpt2sas/mpt2sas_scsih.c
drivers/scsi/ncr53c8xx.c
drivers/scsi/nsp32.c
drivers/scsi/pas16.h
drivers/scsi/pcmcia/nsp_cs.c
drivers/scsi/pcmcia/nsp_cs.h
drivers/scsi/pcmcia/sym53c500_cs.c
drivers/scsi/pm8001/pm8001_sas.h
drivers/scsi/pmcraid.c
drivers/scsi/ppa.c
drivers/scsi/ps3rom.c
drivers/scsi/qla1280.c
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/qla4xxx/ql4_os.c
drivers/scsi/qlogicfas408.c
drivers/scsi/qlogicfas408.h
drivers/scsi/qlogicpti.c
drivers/scsi/scsi.c
drivers/scsi/scsi_debug.c
drivers/scsi/scsi_error.c
drivers/scsi/sd.c
drivers/scsi/stex.c
drivers/scsi/sun3_NCR5380.c
drivers/scsi/sun3_scsi.h
drivers/scsi/sym53c416.c
drivers/scsi/sym53c416.h
drivers/scsi/sym53c8xx_2/sym_glue.c
drivers/scsi/t128.h
drivers/scsi/tmscsim.c
drivers/scsi/u14-34f.c
drivers/scsi/ultrastor.c
drivers/scsi/ultrastor.h
drivers/scsi/vmw_pvscsi.c
drivers/scsi/wd33c93.c
drivers/scsi/wd33c93.h
drivers/scsi/wd7000.c
drivers/serial/crisv10.c
drivers/serial/serial_core.c
drivers/staging/easycap/easycap.h
drivers/staging/hv/storvsc_drv.c
drivers/staging/intel_sst/intel_sst_app_interface.c
drivers/staging/keucr/scsiglue.c
drivers/staging/rtl8712/osdep_service.h
drivers/staging/speakup/buffers.c
drivers/staging/stradis/Kconfig
drivers/tty/sysrq.c
drivers/usb/core/devices.c
drivers/usb/core/devio.c
drivers/usb/core/file.c
drivers/usb/core/inode.c
drivers/usb/gadget/f_fs.c
drivers/usb/gadget/f_hid.c
drivers/usb/host/isp1362-hcd.c
drivers/usb/host/uhci-debug.c
drivers/usb/image/microtek.c
drivers/usb/mon/mon_bin.c
drivers/usb/mon/mon_stat.c
drivers/usb/serial/usb-serial.c
drivers/usb/storage/scsiglue.c
drivers/usb/storage/uas.c
drivers/video/console/vgacon.c
drivers/xen/xenfs/privcmd.c
drivers/zorro/proc.c
fs/block_dev.c
fs/ceph/addr.c
fs/ceph/caps.c
fs/ceph/dir.c
fs/ceph/file.c
fs/ceph/inode.c
fs/ceph/mds_client.c
fs/ceph/mds_client.h
fs/ceph/super.h
fs/compat_ioctl.c
fs/ecryptfs/super.c
fs/ext3/super.c
fs/ioctl.c
fs/lockd/clntlock.c
fs/lockd/clntproc.c
fs/lockd/host.c
fs/lockd/svc4proc.c
fs/lockd/svclock.c
fs/lockd/svcproc.c
fs/locks.c
fs/namespace.c
fs/ncpfs/dir.c
fs/ncpfs/file.c
fs/ncpfs/inode.c
fs/ncpfs/ioctl.c
fs/nfs/callback.c
fs/nfs/delegation.c
fs/nfs/dir.c
fs/nfs/nfs2xdr.c
fs/nfs/nfs3xdr.c
fs/nfs/nfs4proc.c
fs/nfs/nfs4xdr.c
fs/nfs/super.c
fs/nfsd/nfs4state.c
fs/ocfs2/super.c
fs/proc/inode.c
fs/read_write.c
fs/reiserfs/inode.c
fs/reiserfs/ioctl.c
fs/reiserfs/journal.c
fs/reiserfs/super.c
include/drm/nouveau_drm.h
include/linux/ceph/libceph.h
include/linux/ceph/messenger.h
include/linux/ceph/osd_client.h
include/linux/hardirq.h
include/linux/libata.h
include/linux/lockd/lockd.h
include/linux/nfs_fs.h
include/linux/reiserfs_fs.h
include/linux/rtnetlink.h
include/linux/sched.h
include/linux/smp_lock.h
include/linux/tty.h
include/net/cfg80211.h
include/net/neighbour.h
include/scsi/libfc.h
include/scsi/libiscsi.h
include/scsi/libsas.h
include/scsi/scsi_host.h
init/main.c
kernel/debug/kdb/kdb_main.c
kernel/futex.c
kernel/futex_compat.c
kernel/pm_qos_params.c
kernel/power/Kconfig
kernel/sched.c
kernel/sched_fair.c
kernel/sched_stoptask.c
kernel/sysctl.c
kernel/trace/Kconfig
kernel/trace/trace.c
net/ceph/messenger.c
net/ceph/osd_client.c
net/ceph/pagevec.c
net/core/filter.c
net/core/net-sysfs.c
net/ipv4/icmp.c
net/ipv6/addrconf.c
net/irda/af_irda.c
net/irda/irnet/irnet_ppp.c
net/irda/irttp.c
net/netfilter/ipvs/Kconfig
net/rds/rdma.c
net/sunrpc/stats.c
net/sunrpc/svc_xprt.c
net/wireless/chan.c
scripts/kernel-doc
sound/core/info.c
sound/core/pcm_native.c
sound/core/sound.c
sound/sound_core.c

index 4d4ce0e61e424708a94db666e0496d7c0f3fc253..b4665b9c40b0ec46253b9ae6cf9bb1bbd06ec563 100644 (file)
@@ -16,7 +16,7 @@
        </orgname>
 
        <address>
-          <email>hjk@linutronix.de</email>
+          <email>hjk@hansjkoch.de</email>
        </address>
     </affiliation>
 </author>
@@ -114,7 +114,7 @@ GPL version 2.
 
 <para>If you know of any translations for this document, or you are
 interested in translating it, please email me
-<email>hjk@linutronix.de</email>.
+<email>hjk@hansjkoch.de</email>.
 </para>
 </sect1>
 
@@ -171,7 +171,7 @@ interested in translating it, please email me
 <title>Feedback</title>
        <para>Find something wrong with this document? (Or perhaps something
        right?) I would love to hear from you. Please email me at
-       <email>hjk@linutronix.de</email>.</para>
+       <email>hjk@hansjkoch.de</email>.</para>
 </sect1>
 </chapter>
 
index 97726eba6102ca31410028391d8f637b3d7a01c5..911a4518634048d9098a02865d328c18824c8248 100644 (file)
@@ -154,7 +154,7 @@ The stages that a patch goes through are, generally:
    inclusion, it should be accepted by a relevant subsystem maintainer -
    though this acceptance is not a guarantee that the patch will make it
    all the way to the mainline.  The patch will show up in the maintainer's
-   subsystem tree and into the staging trees (described below).  When the
+   subsystem tree and into the -next trees (described below).  When the
    process works, this step leads to more extensive review of the patch and
    the discovery of any problems resulting from the integration of this
    patch with work being done by others.
@@ -236,7 +236,7 @@ finding the right maintainer.  Sending patches directly to Linus is not
 normally the right way to go.
 
 
-2.4: STAGING TREES
+2.4: NEXT TREES
 
 The chain of subsystem trees guides the flow of patches into the kernel,
 but it also raises an interesting question: what if somebody wants to look
@@ -250,7 +250,7 @@ changes land in the mainline kernel.  One could pull changes from all of
 the interesting subsystem trees, but that would be a big and error-prone
 job.
 
-The answer comes in the form of staging trees, where subsystem trees are
+The answer comes in the form of -next trees, where subsystem trees are
 collected for testing and review.  The older of these trees, maintained by
 Andrew Morton, is called "-mm" (for memory management, which is how it got
 started).  The -mm tree integrates patches from a long list of subsystem
@@ -275,7 +275,7 @@ directory at:
 Use of the MMOTM tree is likely to be a frustrating experience, though;
 there is a definite chance that it will not even compile.
 
-The other staging tree, started more recently, is linux-next, maintained by
+The other -next tree, started more recently, is linux-next, maintained by
 Stephen Rothwell.  The linux-next tree is, by design, a snapshot of what
 the mainline is expected to look like after the next merge window closes.
 Linux-next trees are announced on the linux-kernel and linux-next mailing
@@ -303,12 +303,25 @@ volatility of linux-next tends to make it a difficult development target.
 See http://lwn.net/Articles/289013/ for more information on this topic, and
 stay tuned; much is still in flux where linux-next is involved.
 
-Besides the mmotm and linux-next trees, the kernel source tree now contains
-the drivers/staging/ directory and many sub-directories for drivers or
-filesystems that are on their way to being added to the kernel tree
-proper, but they remain in drivers/staging/ while they still need more
-work.
-
+2.4.1: STAGING TREES
+
+The kernel source tree now contains the drivers/staging/ directory, where
+many sub-directories for drivers or filesystems that are on their way to
+being added to the kernel tree live.  They remain in drivers/staging while
+they still need more work; once complete, they can be moved into the
+kernel proper.  This is a way to keep track of drivers that aren't
+up to Linux kernel coding or quality standards, but people may want to use
+them and track development.
+
+Greg Kroah-Hartman currently (as of 2.6.36) maintains the staging tree.
+Drivers that still need work are sent to him, with each driver having
+its own subdirectory in drivers/staging/.  Along with the driver source
+files, a TODO file should be present in the directory as well.  The TODO
+file lists the pending work that the driver needs for acceptance into
+the kernel proper, as well as a list of people that should be Cc'd for any
+patches to the driver.  Staging drivers that don't currently build should
+have their config entries depend upon CONFIG_BROKEN.  Once they can
+be successfully built without outside patches, CONFIG_BROKEN can be removed.
 
 2.5: TOOLS
 
index d428cc9f07f399141e643fc6d8df8ce88433365b..fd53869f5633f2994fe06365fe53c1754747dc6a 100644 (file)
@@ -89,7 +89,7 @@ static ssize_t childless_storeme_write(struct childless *childless,
        char *p = (char *) page;
 
        tmp = simple_strtoul(p, &p, 10);
-       if (!p || (*p && (*p != '\n')))
+       if ((*p != '\0') && (*p != '\n'))
                return -EINVAL;
 
        if (tmp > INT_MAX)
index 9633da01ff46afb008566ccb53aa381606654e85..792faa3c06cf7ccda5ab081dbf568276324538e5 100644 (file)
@@ -617,6 +617,16 @@ and have the following read/write attributes:
                is configured as an output, this value may be written;
                any nonzero value is treated as high.
 
+               If the pin can be configured as interrupt-generating interrupt
+               and if it has been configured to generate interrupts (see the
+               description of "edge"), you can poll(2) on that file and
+               poll(2) will return whenever the interrupt was triggered. If
+               you use poll(2), set the events POLLPRI and POLLERR. If you
+               use select(2), set the file descriptor in exceptfds. After
+               poll(2) returns, either lseek(2) to the beginning of the sysfs
+               file and read the new value or close the file and re-open it
+               to read the value.
+
        "edge" ... reads as either "none", "rising", "falling", or
                "both". Write these strings to select the signal edge(s)
                that will make poll(2) on the "value" file return.
index ac711f357fafb0793d10c3cb31d2cd882647f767..7a10616d0b441c473e82d8c2c31489d7dd5e80c2 100644 (file)
@@ -11,7 +11,7 @@ Authors:
        Mark M. Hoffman <mhoffman@lightlink.com>
        Ported to 2.6 by Eric J. Bowersox <ericb@aspsys.com>
        Adapted to 2.6.20 by Carsten Emde <ce@osadl.org>
-       Modified for mainline integration by Hans J. Koch <hjk@linutronix.de>
+       Modified for mainline integration by Hans J. Koch <hjk@hansjkoch.de>
 
 Module Parameters
 -----------------
index 8be7beb9e3e81122d015a3eab8f634d22562bd91..c565650fcfc6f6949c8a24ae1bd2002ae9da86fa 100644 (file)
@@ -8,7 +8,7 @@ Supported chips:
     Datasheet: http://pdfserv.maxim-ic.com/en/ds/MAX6650-MAX6651.pdf
 
 Authors:
-    Hans J. Koch <hjk@linutronix.de>
+    Hans J. Koch <hjk@hansjkoch.de>
     John Morris <john.morris@spirentcom.com>
     Claus Gindhart <claus.gindhart@kontron.com>
 
index 44d87ad3cea9fd345a774e196578a0cc8bf4d779..cd445582d1f80a91abb619230d7b0a9dcb84e6e3 100644 (file)
@@ -37,6 +37,9 @@ Typical usage of the OPP library is as follows:
 SoC framework  -> modifies on required cases certain OPPs      -> OPP layer
                -> queries to search/retrieve information       ->
 
+Architectures that provide a SoC framework for OPP should select ARCH_HAS_OPP
+to make the OPP layer available.
+
 OPP layer expects each domain to be represented by a unique device pointer. SoC
 framework registers a set of initial OPPs per device with the OPP layer. This
 list is expected to be an optimally small number typically around 5 per device.
index 8e6548dbd5db50c4e80f24fd9ae4bdd4597bd6c3..a92c994ba935234d8e9cbf60552d4a6e171519af 100644 (file)
@@ -1829,6 +1829,13 @@ W:       http://www.chelsio.com
 S:     Supported
 F:     drivers/net/cxgb4vf/
 
+STMMAC ETHERNET DRIVER
+M:     Giuseppe Cavallaro <peppe.cavallaro@st.com>
+L:     netdev@vger.kernel.org
+W:     http://www.stlinux.com
+S:     Supported
+F:     drivers/net/stmmac/
+
 CYBERPRO FB DRIVER
 M:     Russell King <linux@arm.linux.org.uk>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -2008,6 +2015,7 @@ F:        drivers/hwmon/dme1737.c
 DOCBOOK FOR DOCUMENTATION
 M:     Randy Dunlap <rdunlap@xenotime.net>
 S:     Maintained
+F:     scripts/kernel-doc
 
 DOCKING STATION DRIVER
 M:     Shaohua Li <shaohua.li@intel.com>
@@ -2018,6 +2026,7 @@ F:        drivers/acpi/dock.c
 DOCUMENTATION
 M:     Randy Dunlap <rdunlap@xenotime.net>
 L:     linux-doc@vger.kernel.org
+T:     quilt oss.oracle.com/~rdunlap/kernel-doc-patches/current/
 S:     Maintained
 F:     Documentation/
 
index cd0c090ebc54e1c59225144d2bf9118f7c74dca5..b407bc8ad9186f05fee0f657ffec48e7aab87efe 100644 (file)
@@ -7,7 +7,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/smp_lock.h>
 #include <linux/unistd.h>
 #include <linux/user.h>
 #include <linux/uaccess.h>
index 2b63b0191f529d187f0cde1298c637e32973fabb..efad12071c2e7b95324e9a1f0a8f7e88a6a7d645 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
index 97478138e361ad702308539b4d067543402df7cb..933bd388efb28c35804b482aab8014f75036afce 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
index 3a078ad3aa44e4a91ebfb256ca49ba674a35a3da..331de723c6767f264e8ee682fcb73aa44d4a7bf7 100644 (file)
@@ -202,7 +202,7 @@ simscsi_readwrite10 (struct scsi_cmnd *sc, int mode)
 }
 
 static int
-simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
+simscsi_queuecommand_lck (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
 {
        unsigned int target_id = sc->device->id;
        char fname[MAX_ROOT_LEN+16];
@@ -326,6 +326,8 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
        return 0;
 }
 
+static DEF_SCSI_QCMD(simscsi_queuecommand)
+
 static int
 simscsi_host_reset (struct scsi_cmnd *sc)
 {
index 18732ab232923faeedbbcd80c02a98364f285215..c2a1fc23dd758e69a49bb45d6e62247f4adf68ce 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
index 6d3390590e5ba24be497b5c4a42d0327dbae6cf9..e2a63af5d517510820cfa9085d46b08bcd403f46 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
index 0d0f8049a17b557183be48f844bb4b100f5cc87a..e1b14a6ed544675bf7929dc7861876a1a3bf2cc8 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
index ba430a03bc7a51cd99f8dd9ed3688ba531748c0e..30394081d9b6d51ab7486c70054b4bea7beaec89 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/namei.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/syscalls.h>
 #include <linux/utsname.h>
 #include <linux/vfs.h>
index 9779ece2b07079189884f2f17807adb85e6e5bbe..88a0ad14a9c99a466c9aaaf6ba6459868a61d1fa 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/times.h>
 #include <linux/time.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/sem.h>
 #include <linux/msg.h>
 #include <linux/shm.h>
index b6447190e1a2acee2b6fddf9ef90bd5a3d0a1da9..e625e9e034ae19abe973282a3d83952493e8b709 100644 (file)
@@ -4,6 +4,10 @@ config PPC32
        bool
        default y if !PPC64
 
+config 32BIT
+       bool
+       default y if PPC32
+
 config 64BIT
        bool
        default y if PPC64
index 722f360a32a9e905b2edf6f3cdb90b9ef9e5d588..d271ab5426732ab07ec0bec73e52a195e493fe64 100644 (file)
@@ -33,9 +33,10 @@ __div64_32:
        cntlzw  r0,r5           # we are shifting the dividend right
        li      r10,-1          # to make it < 2^32, and shifting
        srw     r10,r10,r0      # the divisor right the same amount,
-       add     r9,r4,r10       # rounding up (so the estimate cannot
+       addc    r9,r4,r10       # rounding up (so the estimate cannot
        andc    r11,r6,r10      # ever be too large, only too small)
        andc    r9,r9,r10
+       addze   r9,r9
        or      r11,r5,r11
        rotlw   r9,r9,r0
        rotlw   r11,r11,r0
index 7a9db64f3f0438f8bf366b9cb2244f1ef3178004..42850ee00adabfa33f0bb5ccd69efe1388d8ec96 100644 (file)
@@ -337,7 +337,7 @@ char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs)
                /* FP registers 32 -> 63 */
 #if defined(CONFIG_FSL_BOOKE) && defined(CONFIG_SPE)
                if (current)
-                       memcpy(mem, current->thread.evr[regno-32],
+                       memcpy(mem, &current->thread.evr[regno-32],
                                        dbg_reg_def[regno].size);
 #else
                /* fp registers not used by kernel, leave zero */
@@ -362,7 +362,7 @@ int dbg_set_reg(int regno, void *mem, struct pt_regs *regs)
        if (regno >= 32 && regno < 64) {
                /* FP registers 32 -> 63 */
 #if defined(CONFIG_FSL_BOOKE) && defined(CONFIG_SPE)
-               memcpy(current->thread.evr[regno-32], mem,
+               memcpy(&current->thread.evr[regno-32], mem,
                                dbg_reg_def[regno].size);
 #else
                /* fp registers not used by kernel, leave zero */
index 2a178b0ebcdf8ea33ed67c8a4516b7ec0f1d9f26..ce6f61c6f871022baedac98bd751de6110ff42c1 100644 (file)
@@ -497,9 +497,8 @@ static void __init emergency_stack_init(void)
 }
 
 /*
- * Called into from start_kernel, after lock_kernel has been called.
- * Initializes bootmem, which is unsed to manage page allocation until
- * mem_init is called.
+ * Called into from start_kernel this initializes bootmem, which is used
+ * to manage page allocation until mem_init is called.
  */
 void __init setup_arch(char **cmdline_p)
 {
index b1b6043a56c44f6b07537e8eb4a0aa720400e296..4e5bf1edc0f2e19690175719fcaf20bc2994237f 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/resource.h>
 #include <linux/times.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/sem.h>
 #include <linux/msg.h>
 #include <linux/shm.h>
index 83f534d862db2cd3934fca431e9b4d67b4ac7d38..5e9584405c4560c13c5567ba6affa81b2391e6bd 100644 (file)
@@ -1123,7 +1123,7 @@ void hash_preload(struct mm_struct *mm, unsigned long ea,
        else
 #endif /* CONFIG_PPC_HAS_HASH_64K */
                rc = __hash_page_4K(ea, access, vsid, ptep, trap, local, ssize,
-                                   subpage_protection(pgdir, ea));
+                                   subpage_protection(mm, ea));
 
        /* Dump some info in case of hash insertion failure, they should
         * never happen so it is really useful to know if/when they do
index 8b04c54e596f2a5a1bf770cb44013808eaf27246..8526bd9d2aa33603be03dbf10bc3656c7a833448 100644 (file)
        cmpldi  cr0,r15,0                       /* Check for user region */
        std     r14,EX_TLB_ESR(r12)             /* write crazy -1 to frame */
        beq     normal_tlb_miss
+
+       li      r11,_PAGE_PRESENT|_PAGE_BAP_SX  /* Base perm */
+       oris    r11,r11,_PAGE_ACCESSED@h
        /* XXX replace the RMW cycles with immediate loads + writes */
-1:     mfspr   r10,SPRN_MAS1
+       mfspr   r10,SPRN_MAS1
        cmpldi  cr0,r15,8                       /* Check for vmalloc region */
        rlwinm  r10,r10,0,16,1                  /* Clear TID */
        mtspr   SPRN_MAS1,r10
index 36c0c449a89993659c60d1b4c4b772fb5aa5f94c..2a030d89bbc6e65a847a29f6c4bf012f2e6188b0 100644 (file)
@@ -585,6 +585,6 @@ void setup_initial_memory_limit(phys_addr_t first_memblock_base,
        ppc64_rma_size = min_t(u64, first_memblock_size, 0x40000000);
 
        /* Finally limit subsequent allocations */
-       memblock_set_current_limit(ppc64_memblock_base + ppc64_rma_size);
+       memblock_set_current_limit(first_memblock_base + ppc64_rma_size);
 }
 #endif /* CONFIG_PPC64 */
index c667f0f02c34cc44eb75138e8eae6b140a49c3e8..3139814f643985e1879ed876b651a7f1e2a370a7 100644 (file)
@@ -47,6 +47,12 @@ config LPARCFG
 config PPC_PSERIES_DEBUG
        depends on PPC_PSERIES && PPC_EARLY_DEBUG
        bool "Enable extra debug logging in platforms/pseries"
+        help
+         Say Y here if you want the pseries core to produce a bunch of
+         debug messages to the system log. Select this if you are having a
+         problem with the pseries core and want to see more of what is
+         going on. This does not enable debugging in lpar.c, which must
+         be manually done due to its verbosity.
        default y
 
 config PPC_SMLPAR
index 34b7dc12e731231e9c0110bbe7caeda20ec5c0c0..17a11c82e6f8d61676edc341783a81fc4da1cb4a 100644 (file)
@@ -21,8 +21,6 @@
  * Please address comments and feedback to Linas Vepstas <linas@austin.ibm.com>
  */
 
-#undef DEBUG
-
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/list.h>
index 4b7a062dee15373e93b0b44c66c5ad0fbd5ee086..5fcc92a12d3e1256b1c5d648b624f4791e3b0817 100644 (file)
@@ -25,8 +25,6 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#undef DEBUG
-
 #include <linux/pci.h>
 #include <asm/pci-bridge.h>
 #include <asm/ppc-pci.h>
index 45e0c6199f36d6484df7adc657527c02c7974a4e..05221b13ffb1ed746b4a276a06ad0b9bfca95364 100644 (file)
@@ -6,6 +6,18 @@ config TRACE_IRQFLAGS_SUPPORT
 
 source "lib/Kconfig.debug"
 
+config STRICT_DEVMEM
+       def_bool y
+       prompt "Filter access to /dev/mem"
+       ---help---
+         This option restricts access to /dev/mem.  If this option is
+         disabled, you allow userspace access to all memory, including
+         kernel and userspace memory. Accidental memory access is likely
+         to be disastrous.
+         Memory access is required for experts who want to debug the kernel.
+
+         If you are unsure, say Y.
+
 config DEBUG_STRICT_USER_COPY_CHECKS
        bool "Strict user copy size checks"
        ---help---
index a8729ea7e9ac1d12826fb4a0e76923a19af307fa..3c987e9ec8d69e61d4eaaa5f21e409613662324c 100644 (file)
@@ -130,6 +130,11 @@ struct page;
 void arch_free_page(struct page *page, int order);
 void arch_alloc_page(struct page *page, int order);
 
+static inline int devmem_is_allowed(unsigned long pfn)
+{
+       return 0;
+}
+
 #define HAVE_ARCH_FREE_PAGE
 #define HAVE_ARCH_ALLOC_PAGE
 
index 1e6449c79ab6de6de8d7c9f1de8ed1b8bdde66d5..53acaa86dd94f353e36beb03f5c9e904c14d42d3 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/resource.h>
 #include <linux/times.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/sem.h>
 #include <linux/msg.h>
 #include <linux/shm.h>
index d60fc439851658761cd105d8d403be2e69fee0ad..2564793ec2b6fd0dede210f10694615606239511 100644 (file)
@@ -30,6 +30,7 @@
 #include <asm/sections.h>
 #include <linux/module.h>
 #include <linux/slab.h>
+#include <linux/hardirq.h>
 
 DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
 DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
@@ -212,7 +213,7 @@ static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
        /* Set the PER control regs, turns on single step for this address */
        __ctl_load(kprobe_per_regs, 9, 11);
        regs->psw.mask |= PSW_MASK_PER;
-       regs->psw.mask &= ~(PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK);
+       regs->psw.mask &= ~(PSW_MASK_IO | PSW_MASK_EXT);
 }
 
 static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
@@ -239,7 +240,7 @@ static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
        __get_cpu_var(current_kprobe) = p;
        /* Save the interrupt and per flags */
        kcb->kprobe_saved_imask = regs->psw.mask &
-           (PSW_MASK_PER | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK);
+               (PSW_MASK_PER | PSW_MASK_IO | PSW_MASK_EXT);
        /* Save the control regs that govern PER */
        __ctl_store(kcb->kprobe_saved_ctl, 9, 11);
 }
@@ -316,8 +317,6 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
                return 1;
 
 ss_probe:
-       if (regs->psw.mask & (PSW_MASK_PER | PSW_MASK_IO))
-               local_irq_disable();
        prepare_singlestep(p, regs);
        kcb->kprobe_status = KPROBE_HIT_SS;
        return 1;
@@ -350,6 +349,7 @@ static int __kprobes trampoline_probe_handler(struct kprobe *p,
        struct hlist_node *node, *tmp;
        unsigned long flags, orig_ret_address = 0;
        unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline;
+       kprobe_opcode_t *correct_ret_addr = NULL;
 
        INIT_HLIST_HEAD(&empty_rp);
        kretprobe_hash_lock(current, &head, &flags);
@@ -372,10 +372,32 @@ static int __kprobes trampoline_probe_handler(struct kprobe *p,
                        /* another task is sharing our hash bucket */
                        continue;
 
-               if (ri->rp && ri->rp->handler)
-                       ri->rp->handler(ri, regs);
+               orig_ret_address = (unsigned long)ri->ret_addr;
+
+               if (orig_ret_address != trampoline_address)
+                       /*
+                        * This is the real return address. Any other
+                        * instances associated with this task are for
+                        * other calls deeper on the call stack
+                        */
+                       break;
+       }
+
+       kretprobe_assert(ri, orig_ret_address, trampoline_address);
+
+       correct_ret_addr = ri->ret_addr;
+       hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
+               if (ri->task != current)
+                       /* another task is sharing our hash bucket */
+                       continue;
 
                orig_ret_address = (unsigned long)ri->ret_addr;
+
+               if (ri->rp && ri->rp->handler) {
+                       ri->ret_addr = correct_ret_addr;
+                       ri->rp->handler(ri, regs);
+               }
+
                recycle_rp_inst(ri, &empty_rp);
 
                if (orig_ret_address != trampoline_address) {
@@ -387,7 +409,7 @@ static int __kprobes trampoline_probe_handler(struct kprobe *p,
                        break;
                }
        }
-       kretprobe_assert(ri, orig_ret_address, trampoline_address);
+
        regs->psw.addr = orig_ret_address | PSW_ADDR_AMODE;
 
        reset_current_kprobe();
@@ -465,8 +487,6 @@ static int __kprobes post_kprobe_handler(struct pt_regs *regs)
                goto out;
        }
        reset_current_kprobe();
-       if (regs->psw.mask & (PSW_MASK_PER | PSW_MASK_IO))
-               local_irq_enable();
 out:
        preempt_enable_no_resched();
 
@@ -482,7 +502,7 @@ out:
        return 1;
 }
 
-int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
+static int __kprobes kprobe_trap_handler(struct pt_regs *regs, int trapnr)
 {
        struct kprobe *cur = kprobe_running();
        struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
@@ -508,8 +528,6 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
                        restore_previous_kprobe(kcb);
                else {
                        reset_current_kprobe();
-                       if (regs->psw.mask & (PSW_MASK_PER | PSW_MASK_IO))
-                               local_irq_enable();
                }
                preempt_enable_no_resched();
                break;
@@ -553,6 +571,18 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
        return 0;
 }
 
+int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
+{
+       int ret;
+
+       if (regs->psw.mask & (PSW_MASK_IO | PSW_MASK_EXT))
+               local_irq_disable();
+       ret = kprobe_trap_handler(regs, trapnr);
+       if (regs->psw.mask & (PSW_MASK_IO | PSW_MASK_EXT))
+               local_irq_restore(regs->psw.mask & ~PSW_MASK_PER);
+       return ret;
+}
+
 /*
  * Wrapper routine to for handling exceptions.
  */
@@ -560,8 +590,12 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
                                       unsigned long val, void *data)
 {
        struct die_args *args = (struct die_args *)data;
+       struct pt_regs *regs = args->regs;
        int ret = NOTIFY_DONE;
 
+       if (regs->psw.mask & (PSW_MASK_IO | PSW_MASK_EXT))
+               local_irq_disable();
+
        switch (val) {
        case DIE_BPT:
                if (kprobe_handler(args->regs))
@@ -572,16 +606,17 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
                        ret = NOTIFY_STOP;
                break;
        case DIE_TRAP:
-               /* kprobe_running() needs smp_processor_id() */
-               preempt_disable();
-               if (kprobe_running() &&
-                   kprobe_fault_handler(args->regs, args->trapnr))
+               if (!preemptible() && kprobe_running() &&
+                   kprobe_trap_handler(args->regs, args->trapnr))
                        ret = NOTIFY_STOP;
-               preempt_enable();
                break;
        default:
                break;
        }
+
+       if (regs->psw.mask & (PSW_MASK_IO | PSW_MASK_EXT))
+               local_irq_restore(regs->psw.mask & ~PSW_MASK_PER);
+
        return ret;
 }
 
@@ -595,6 +630,7 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
 
        /* setup return addr to the jprobe handler routine */
        regs->psw.addr = (unsigned long)(jp->entry) | PSW_ADDR_AMODE;
+       regs->psw.mask &= ~(PSW_MASK_IO | PSW_MASK_EXT);
 
        /* r14 is the function return address */
        kcb->jprobe_saved_r14 = (unsigned long)regs->gprs[14];
index 38e641cdd9779ca3c96a1accf6faeb0d7148f82c..45b405ca25673a416ca33bfdd5b20a81c4876264 100644 (file)
 static inline int gup_pte_range(pmd_t *pmdp, pmd_t pmd, unsigned long addr,
                unsigned long end, int write, struct page **pages, int *nr)
 {
-       unsigned long mask, result;
+       unsigned long mask;
        pte_t *ptep, pte;
        struct page *page;
 
-       result = write ? 0 : _PAGE_RO;
-       mask = result | _PAGE_INVALID | _PAGE_SPECIAL;
+       mask = (write ? _PAGE_RO : 0) | _PAGE_INVALID | _PAGE_SPECIAL;
 
        ptep = ((pte_t *) pmd_deref(pmd)) + pte_index(addr);
        do {
                pte = *ptep;
                barrier();
-               if ((pte_val(pte) & mask) != result)
+               if ((pte_val(pte) & mask) != 0)
                        return 0;
                VM_BUG_ON(!pfn_valid(pte_pfn(pte)));
                page = pte_page(pte);
index 7524689b03d24465f78500f87e804803509b3367..16582d85368af84b891fded4406d7f0088bf3056 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/sched.h>
 #include <linux/threads.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/interrupt.h>
 #include <linux/kernel_stat.h>
 #include <linux/init.h>
index e6375a750d9a641f4b253fdf2894fa989973b347..6db18c6927fbee68a20125e1eb31e486798eeac0 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/resource.h>
 #include <linux/times.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/sem.h>
 #include <linux/msg.h>
 #include <linux/shm.h>
index 675c9e11ada5541085e2fd6e6129272c05713df4..42b282fa6112933681082c12bb95ef04fccc4b41 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/mman.h>
 #include <linux/utsname.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/ipc.h>
 
 #include <asm/uaccess.h>
index 12b9f352595f44e26c3f5730d3a84e8557d8cca8..4491f4cb26953c1582e0344311b62fe82b956900 100644 (file)
@@ -16,7 +16,6 @@
 #include <asm/system.h>
 #include <asm/uaccess.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/perf_event.h>
 
 enum direction {
index b351770cbdd6aded05ca53554b30c8716a24a4ce..3107381e576d6f78431d0ccde6c73114ae387944 100644 (file)
@@ -9,7 +9,6 @@
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 
 #include <asm/uaccess.h>
 
index 67617a05e602380a7d1fba86dadba25db17a13ef..dbc213adf5e1dac8557e38647266c730ecb7e6eb 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/kdev_t.h>
 #include <linux/fs.h>
 #include <linux/fcntl.h>
-#include <linux/smp_lock.h>
 #include <linux/uaccess.h>
 #include <linux/signal.h>
 #include <asm/syscalls.h>
index fb64b99959d42dd796c6d16c4b471cc8d9769a50..543d6a33aa26f6c02f7f41f59fcdceea1729bcd8 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/kernel.h>
 #include <linux/signal.h>
 #include <linux/errno.h>
index 687719d4abd1eba56fbd591852c8fab51950bc52..757407e36696688d59810453b1ffca8da8522a62 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/kernel.h>
 #include <linux/signal.h>
 #include <linux/errno.h>
index 74d62d098edf455bddb73852535b69e733d442a0..b949edcec200b60018c7ecf6a9aef049771e0260 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/mm.h>
 #include <linux/sched.h>
 #include <linux/kernel_stat.h>
-#include <linux/smp_lock.h>
 #include <linux/bootmem.h>
 #include <linux/notifier.h>
 #include <linux/cpu.h>
index 7e764669a0222755db93373089539e18ade539d8..e2187d24a9b41d8ad765f1a383347525dc728a5f 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/syscalls.h>
 #include <linux/mman.h>
 #include <linux/file.h>
index f295b4ac941de22b760651f5ac019361e00802d2..dcebfc831cd6e94a23571681cd341db358d8d807 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/mman.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/tty.h>
index 24688b697a8d92e48284daff0643b61cfd11c281..201a582c413752c40ec6fc87bfc87ca3e73bb8d2 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/mm.h>
 #include <linux/hugetlb.h>
 #include <linux/pagemap.h>
-#include <linux/smp_lock.h>
 #include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/sysctl.h>
index 340268be00b5a934f6fc3ac632c26e53b58623ec..09bd7b585726cdcd2109a5a70250a8871bbdcaf7 100644 (file)
@@ -5,7 +5,6 @@
 
 #include "linux/stddef.h"
 #include "linux/fs.h"
-#include "linux/smp_lock.h"
 #include "linux/ptrace.h"
 #include "linux/sched.h"
 #include "linux/slab.h"
index 849813f398e75e8f699b5a5e999efad7df1a76a8..5852519b2d0f94005d688159c045b52b69c8766b 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/syscalls.h>
 #include <linux/times.h>
 #include <linux/utsname.h>
-#include <linux/smp_lock.h>
 #include <linux/mm.h>
 #include <linux/uio.h>
 #include <linux/poll.h>
index 1b7b31ab7d86536ecde1d68034cf882216ac32a6..212a6a42527c5fcbd0a79f05e4ed7d1cff077cf7 100644 (file)
@@ -33,7 +33,6 @@
 #include <linux/init.h>
 #include <linux/poll.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/major.h>
 #include <linux/fs.h>
 #include <linux/device.h>
index ec592caac4b4e11b5d7ac0bc2986d6617ac4b90b..cd21b654dec6c70382b68ab29f4364ab60ff4e88 100644 (file)
@@ -315,14 +315,18 @@ static void kgdb_remove_all_hw_break(void)
                if (!breakinfo[i].enabled)
                        continue;
                bp = *per_cpu_ptr(breakinfo[i].pev, cpu);
-               if (bp->attr.disabled == 1)
+               if (!bp->attr.disabled) {
+                       arch_uninstall_hw_breakpoint(bp);
+                       bp->attr.disabled = 1;
                        continue;
+               }
                if (dbg_is_early)
                        early_dr7 &= ~encode_dr7(i, breakinfo[i].len,
                                                 breakinfo[i].type);
-               else
-                       arch_uninstall_hw_breakpoint(bp);
-               bp->attr.disabled = 1;
+               else if (hw_break_release_slot(i))
+                       printk(KERN_ERR "KGDB: hw bpt remove failed %lx\n",
+                              breakinfo[i].addr);
+               breakinfo[i].enabled = 0;
        }
 }
 
index 7bf2dc4c8f701de8965fc1e124126863c7384552..12fcbe2c143e5e3c7a9e62f58981a78f5355bd64 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/init.h>
 #include <linux/poll.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/major.h>
 #include <linux/fs.h>
 #include <linux/device.h>
index 82e144a4e514249c140f5c28a8bd0df00869b5ca..1ca12298ffc74f2d783effb35da0953163bbb314 100644 (file)
@@ -3395,6 +3395,7 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
        vcpu->arch.regs[VCPU_REGS_RIP] = svm->vmcb->save.rip;
 
        load_host_msrs(vcpu);
+       kvm_load_ldt(ldt_selector);
        loadsegment(fs, fs_selector);
 #ifdef CONFIG_X86_64
        load_gs_index(gs_selector);
@@ -3402,7 +3403,6 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
 #else
        loadsegment(gs, gs_selector);
 #endif
-       kvm_load_ldt(ldt_selector);
 
        reload_tss(vcpu);
 
index 8da0e45ff7c9cde22d424583adbb2786cf78a72a..ff21fdda0c53b6dbf2ca84b1e4e2300e2a659b90 100644 (file)
@@ -821,10 +821,9 @@ static void vmx_save_host_state(struct kvm_vcpu *vcpu)
 #endif
 
 #ifdef CONFIG_X86_64
-       if (is_long_mode(&vmx->vcpu)) {
-               rdmsrl(MSR_KERNEL_GS_BASE, vmx->msr_host_kernel_gs_base);
+       rdmsrl(MSR_KERNEL_GS_BASE, vmx->msr_host_kernel_gs_base);
+       if (is_long_mode(&vmx->vcpu))
                wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base);
-       }
 #endif
        for (i = 0; i < vmx->save_nmsrs; ++i)
                kvm_set_shared_msr(vmx->guest_msrs[i].index,
@@ -839,23 +838,23 @@ static void __vmx_load_host_state(struct vcpu_vmx *vmx)
 
        ++vmx->vcpu.stat.host_state_reload;
        vmx->host_state.loaded = 0;
-       if (vmx->host_state.fs_reload_needed)
-               loadsegment(fs, vmx->host_state.fs_sel);
+#ifdef CONFIG_X86_64
+       if (is_long_mode(&vmx->vcpu))
+               rdmsrl(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base);
+#endif
        if (vmx->host_state.gs_ldt_reload_needed) {
                kvm_load_ldt(vmx->host_state.ldt_sel);
 #ifdef CONFIG_X86_64
                load_gs_index(vmx->host_state.gs_sel);
-               wrmsrl(MSR_KERNEL_GS_BASE, current->thread.gs);
 #else
                loadsegment(gs, vmx->host_state.gs_sel);
 #endif
        }
+       if (vmx->host_state.fs_reload_needed)
+               loadsegment(fs, vmx->host_state.fs_sel);
        reload_tss();
 #ifdef CONFIG_X86_64
-       if (is_long_mode(&vmx->vcpu)) {
-               rdmsrl(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base);
-               wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_host_kernel_gs_base);
-       }
+       wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_host_kernel_gs_base);
 #endif
        if (current_thread_info()->status & TS_USEDFPU)
                clts();
index 58c6ee5b010c4fd4a22206e9c88c5cadedc1a1a2..cc3eb78e333acaf14eb27a4ae8e54737d816f255 100644 (file)
@@ -8,7 +8,6 @@
 #include <linux/hdreg.h>
 #include <linux/slab.h>
 #include <linux/syscalls.h>
-#include <linux/smp_lock.h>
 #include <linux/types.h>
 #include <linux/uaccess.h>
 
index 3d866d0037f240c8d636f8b8523df962e72ab123..a9a302eba01e6a78b46e3af154c4f1b2a1c2c510 100644 (file)
@@ -5,7 +5,6 @@
 #include <linux/hdreg.h>
 #include <linux/backing-dev.h>
 #include <linux/buffer_head.h>
-#include <linux/smp_lock.h>
 #include <linux/blktrace_api.h>
 #include <asm/uaccess.h>
 
index 3f91c01c217fe8179a58da9dd00c59465b700aba..66aa4bee80a659712b75e8b3949678d56e8bd5a3 100644 (file)
@@ -3166,8 +3166,8 @@ static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd,
 
 /**
  *     ata_scsi_queuecmd - Issue SCSI cdb to libata-managed device
+ *     @shost: SCSI host of command to be sent
  *     @cmd: SCSI command to be sent
- *     @done: Completion function, called when command is complete
  *
  *     In some cases, this function translates SCSI commands into
  *     ATA taskfiles, and queues the taskfiles to be sent to
@@ -3177,37 +3177,36 @@ static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd,
  *     ATA and ATAPI devices appearing as SCSI devices.
  *
  *     LOCKING:
- *     Releases scsi-layer-held lock, and obtains host lock.
+ *     ATA host lock
  *
  *     RETURNS:
  *     Return value from __ata_scsi_queuecmd() if @cmd can be queued,
  *     0 otherwise.
  */
-int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
+int ata_scsi_queuecmd(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
 {
        struct ata_port *ap;
        struct ata_device *dev;
        struct scsi_device *scsidev = cmd->device;
-       struct Scsi_Host *shost = scsidev->host;
        int rc = 0;
+       unsigned long irq_flags;
 
        ap = ata_shost_to_port(shost);
 
-       spin_unlock(shost->host_lock);
-       spin_lock(ap->lock);
+       spin_lock_irqsave(ap->lock, irq_flags);
 
        ata_scsi_dump_cdb(ap, cmd);
 
        dev = ata_scsi_find_dev(ap, scsidev);
        if (likely(dev))
-               rc = __ata_scsi_queuecmd(cmd, done, dev);
+               rc = __ata_scsi_queuecmd(cmd, cmd->scsi_done, dev);
        else {
                cmd->result = (DID_BAD_TARGET << 16);
-               done(cmd);
+               cmd->scsi_done(cmd);
        }
 
-       spin_unlock(ap->lock);
-       spin_lock(shost->host_lock);
+       spin_unlock_irqrestore(ap->lock, irq_flags);
+
        return rc;
 }
 
index c21589986c695f38756d1ced8a13422acfa3cac9..8b677bbf2d37be97d37e89c57441e26807a55e87 100644 (file)
@@ -538,7 +538,7 @@ static int vt8251_prepare_host(struct pci_dev *pdev, struct ata_host **r_host)
        return 0;
 }
 
-static void svia_configure(struct pci_dev *pdev)
+static void svia_configure(struct pci_dev *pdev, int board_id)
 {
        u8 tmp8;
 
@@ -577,7 +577,7 @@ static void svia_configure(struct pci_dev *pdev)
        }
 
        /*
-        * vt6421 has problems talking to some drives.  The following
+        * vt6420/1 has problems talking to some drives.  The following
         * is the fix from Joseph Chan <JosephChan@via.com.tw>.
         *
         * When host issues HOLD, device may send up to 20DW of data
@@ -596,8 +596,9 @@ static void svia_configure(struct pci_dev *pdev)
         *
         * https://bugzilla.kernel.org/show_bug.cgi?id=15173
         * http://article.gmane.org/gmane.linux.ide/46352
+        * http://thread.gmane.org/gmane.linux.kernel/1062139
         */
-       if (pdev->device == 0x3249) {
+       if (board_id == vt6420 || board_id == vt6421) {
                pci_read_config_byte(pdev, 0x52, &tmp8);
                tmp8 |= 1 << 2;
                pci_write_config_byte(pdev, 0x52, tmp8);
@@ -652,7 +653,7 @@ static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        if (rc)
                return rc;
 
-       svia_configure(pdev);
+       svia_configure(pdev, board_id);
 
        pci_set_master(pdev);
        return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt,
index 31b526661ec4d78346c3b6edd04b733705285797..ead3e79d6fcf10f684f8d8f55a30d7254356ff42 100644 (file)
@@ -475,20 +475,33 @@ End:
  */
 void dpm_resume_noirq(pm_message_t state)
 {
-       struct device *dev;
+       struct list_head list;
        ktime_t starttime = ktime_get();
 
+       INIT_LIST_HEAD(&list);
        mutex_lock(&dpm_list_mtx);
        transition_started = false;
-       list_for_each_entry(dev, &dpm_list, power.entry)
+       while (!list_empty(&dpm_list)) {
+               struct device *dev = to_device(dpm_list.next);
+
+               get_device(dev);
                if (dev->power.status > DPM_OFF) {
                        int error;
 
                        dev->power.status = DPM_OFF;
+                       mutex_unlock(&dpm_list_mtx);
+
                        error = device_resume_noirq(dev, state);
+
+                       mutex_lock(&dpm_list_mtx);
                        if (error)
                                pm_dev_err(dev, state, " early", error);
                }
+               if (!list_empty(&dev->power.entry))
+                       list_move_tail(&dev->power.entry, &list);
+               put_device(dev);
+       }
+       list_splice(&list, &dpm_list);
        mutex_unlock(&dpm_list_mtx);
        dpm_show_time(starttime, state, "early");
        resume_device_irqs();
@@ -789,20 +802,33 @@ End:
  */
 int dpm_suspend_noirq(pm_message_t state)
 {
-       struct device *dev;
+       struct list_head list;
        ktime_t starttime = ktime_get();
        int error = 0;
 
+       INIT_LIST_HEAD(&list);
        suspend_device_irqs();
        mutex_lock(&dpm_list_mtx);
-       list_for_each_entry_reverse(dev, &dpm_list, power.entry) {
+       while (!list_empty(&dpm_list)) {
+               struct device *dev = to_device(dpm_list.prev);
+
+               get_device(dev);
+               mutex_unlock(&dpm_list_mtx);
+
                error = device_suspend_noirq(dev, state);
+
+               mutex_lock(&dpm_list_mtx);
                if (error) {
                        pm_dev_err(dev, state, " late", error);
+                       put_device(dev);
                        break;
                }
                dev->power.status = DPM_OFF_IRQ;
+               if (!list_empty(&dev->power.entry))
+                       list_move(&dev->power.entry, &list);
+               put_device(dev);
        }
+       list_splice_tail(&list, &dpm_list);
        mutex_unlock(&dpm_list_mtx);
        if (error)
                dpm_resume_noirq(resume_event(state));
index 575495f3c4b870d2085347f5015f72efc32adb2b..727d0225b7d049e9f529655c081c513267d248bc 100644 (file)
@@ -62,8 +62,8 @@ static int cciss_scsi_proc_info(
                int length,        /* length of data in buffer */
                int func);         /* 0 == read, 1 == write */
 
-static int cciss_scsi_queue_command (struct scsi_cmnd *cmd,
-               void (* done)(struct scsi_cmnd *));
+static int cciss_scsi_queue_command (struct Scsi_Host *h,
+                                    struct scsi_cmnd *cmd);
 static int cciss_eh_device_reset_handler(struct scsi_cmnd *);
 static int cciss_eh_abort_handler(struct scsi_cmnd *);
 
@@ -1406,7 +1406,7 @@ static void cciss_scatter_gather(ctlr_info_t *h, CommandList_struct *c,
 
 
 static int
-cciss_scsi_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
+cciss_scsi_queue_command_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
 {
        ctlr_info_t *h;
        int rc;
@@ -1504,6 +1504,8 @@ cciss_scsi_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd
        return 0;
 }
 
+static DEF_SCSI_QCMD(cciss_scsi_queue_command)
+
 static void cciss_unregister_scsi(ctlr_info_t *h)
 {
        struct cciss_scsi_adapter_data_t *sa;
index d299fe9e78c8acc80b3a3f2fb370675bf7b299be..89d8a7cc4054ba627b670a8786e05b1824f5a8b3 100644 (file)
@@ -36,7 +36,6 @@
 #include <linux/memcontrol.h>
 #include <linux/mm_inline.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/pkt_sched.h>
 #define __KERNEL_SYSCALLS__
 #include <linux/unistd.h>
index b0551ba7ad0c9355a36621d3a6405ba76a8ab9d0..47d223c2409c8cebbd233103d8ff1790dfae833c 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/module.h>
 #include <linux/drbd.h>
 #include <linux/sched.h>
-#include <linux/smp_lock.h>
 #include <linux/wait.h>
 #include <linux/mm.h>
 #include <linux/memcontrol.h>
index 43412c03969e14d0d0b92f1323109128bdb22a35..3cb4539a98b2f56d3a32509cd2ae951160a2d3d4 100644 (file)
@@ -39,7 +39,6 @@
 #include <linux/mm.h>
 #include <linux/fs.h>
 #include <linux/sched.h>
-#include <linux/smp_lock.h>
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
 #include "agp.h"
index c0bd6f472c523a377f4d6efef8d90f8f6fbfe373..6ee3348bc3e4c922c3f9733830905c199ef85c29 100644 (file)
@@ -81,7 +81,6 @@ static char *serial_version = "4.30";
 #include <linux/mm.h>
 #include <linux/seq_file.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/init.h>
 #include <linux/bitops.h>
 #include <linux/platform_device.h>
index f6718f05dad4a4ca16465967dd8779984637238e..095ab90535cea7519cce26cdc948a48c38dec02f 100644 (file)
@@ -6,7 +6,6 @@
 
 #include <linux/module.h>
 
-#include <linux/smp_lock.h>
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/tty.h>
index 55b8667f739f64a82731ab926738601825cbb00c..7066e801b9d348e9506651e11bf51197b24d2847 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/smp_lock.h>
 #include <linux/types.h>
 #include <linux/miscdevice.h>
 #include <linux/major.h>
index 788da05190ccf865ab47f0e53848c70faa8f5d33..2016aad85203ac2e868d5be0df20b267ab9e5ecf 100644 (file)
@@ -37,7 +37,6 @@
 #include <linux/kernel.h>
 #include <linux/fs.h>
 #include <linux/sched.h>
-#include <linux/smp_lock.h>
 #include <linux/init.h>
 #include <linux/miscdevice.h>
 #include <linux/delay.h>
index 667abd23ad6ab91b81fa957f3c80260e9c7735a6..7c6de4c92458ded21561df8d75e6f92e5c6f6945 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/interrupt.h>
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
index f646725bd567ec279541dd968e9a1653746035fe..748c3b0ecd89413f4bbe918e783bb042fcb02d1a 100644 (file)
@@ -52,7 +52,6 @@
 #include <linux/interrupt.h>
 #include <linux/serial.h>
 #include <linux/serialP.h>
-#include <linux/smp_lock.h>
 #include <linux/string.h>
 #include <linux/fcntl.h>
 #include <linux/ptrace.h>
index 9f8495b4fc8f5d648529d9c57950718bf11e8fd0..a7616d226a491bb0c295441f5db66c8e2cd98cc8 100644 (file)
@@ -87,7 +87,6 @@
 #include <linux/tty_flip.h>
 #include <linux/mm.h>
 #include <linux/serial.h>
-#include <linux/smp_lock.h>
 #include <linux/fcntl.h>
 #include <linux/major.h>
 #include <linux/delay.h>
index 4bef6ab83622f5e0e71ed6532a7f4cca12397a1c..461a5a0455170b63807b1945451d69c9f1abd1fd 100644 (file)
@@ -40,7 +40,6 @@
 #include <linux/stallion.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
-#include <linux/smp_lock.h>
 #include <linux/device.h>
 #include <linux/delay.h>
 #include <linux/ctype.h>
index e53f16865397c491fa4afac65988c49b0f391ff9..a786326cea2f38163c343ff77997d2c2322c5e5b 100644 (file)
 #include <linux/eisa.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/init.h>
 #include <linux/miscdevice.h>
 #include <linux/bitops.h>
index 493b47a0d511bd1a01dcd8985b76666f66a03971..956ebe2080a584d4a8e7843a9e4110edbc15f7b6 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/interrupt.h>
 #include <linux/time.h>
 #include <linux/math64.h>
-#include <linux/smp_lock.h>
 
 #include <asm/genapic.h>
 #include <asm/uv/uv_hub.h>
index bfae4b309791103e48b2bb704300d1cd84da9750..afa576a75a8ed443273d4722c03edc2bb8c31720 100644 (file)
@@ -1468,7 +1468,7 @@ static int sbp2_map_scatterlist(struct sbp2_command_orb *orb,
 
 /* SCSI stack integration */
 
-static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
+static int sbp2_scsi_queuecommand_lck(struct scsi_cmnd *cmd, scsi_done_fn_t done)
 {
        struct sbp2_logical_unit *lu = cmd->device->hostdata;
        struct fw_device *device = target_device(lu->tgt);
@@ -1534,6 +1534,8 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
        return retval;
 }
 
+static DEF_SCSI_QCMD(sbp2_scsi_queuecommand)
+
 static int sbp2_scsi_slave_alloc(struct scsi_device *sdev)
 {
        struct sbp2_logical_unit *lu = sdev->hostdata;
index b744dad5c237f5371d571d13dc35d46a2fc95e2c..a39794bac04b4a57a8531c5ed38cccf081aa8ef9 100644 (file)
@@ -37,7 +37,6 @@
 #include "drmP.h"
 #include <linux/poll.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 
 /* from BKL pushdown: note that nothing else serializes idr_find() */
 DEFINE_MUTEX(drm_global_mutex);
index 80745f85902cf73fe17bf2ec41863dcb36a38550..f737960712e607c448eabc83d57e6d0557269f16 100644 (file)
@@ -150,7 +150,8 @@ static const struct intel_device_info intel_ironlake_d_info = {
 
 static const struct intel_device_info intel_ironlake_m_info = {
        .gen = 5, .is_mobile = 1,
-       .need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1, .has_hotplug = 1,
+       .need_gfx_hws = 1, .has_rc6 = 1, .has_hotplug = 1,
+       .has_fbc = 0, /* disabled due to buggy hardware */
        .has_bsd_ring = 1,
 };
 
index 90414ae86afcd0758d49b2c70dfb39f613ab22f5..409826da3099dcb594473685bdf4b5f2e78183c9 100644 (file)
@@ -1045,6 +1045,8 @@ void i915_gem_clflush_object(struct drm_gem_object *obj);
 int i915_gem_object_set_domain(struct drm_gem_object *obj,
                               uint32_t read_domains,
                               uint32_t write_domain);
+int i915_gem_object_flush_gpu(struct drm_i915_gem_object *obj,
+                             bool interruptible);
 int i915_gem_init_ringbuffer(struct drm_device *dev);
 void i915_gem_cleanup_ringbuffer(struct drm_device *dev);
 int i915_gem_do_init(struct drm_device *dev, unsigned long start,
index ef188e391406a1b3a2763e92d578c8f9e03b28b3..17b1cba3b5f11c281eedc13c5adaa5a98ac4eef8 100644 (file)
@@ -547,6 +547,19 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data,
        struct drm_i915_gem_object *obj_priv;
        int ret = 0;
 
+       if (args->size == 0)
+               return 0;
+
+       if (!access_ok(VERIFY_WRITE,
+                      (char __user *)(uintptr_t)args->data_ptr,
+                      args->size))
+               return -EFAULT;
+
+       ret = fault_in_pages_writeable((char __user *)(uintptr_t)args->data_ptr,
+                                      args->size);
+       if (ret)
+               return -EFAULT;
+
        ret = i915_mutex_lock_interruptible(dev);
        if (ret)
                return ret;
@@ -564,23 +577,6 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data,
                goto out;
        }
 
-       if (args->size == 0)
-               goto out;
-
-       if (!access_ok(VERIFY_WRITE,
-                      (char __user *)(uintptr_t)args->data_ptr,
-                      args->size)) {
-               ret = -EFAULT;
-               goto out;
-       }
-
-       ret = fault_in_pages_writeable((char __user *)(uintptr_t)args->data_ptr,
-                                      args->size);
-       if (ret) {
-               ret = -EFAULT;
-               goto out;
-       }
-
        ret = i915_gem_object_get_pages_or_evict(obj);
        if (ret)
                goto out;
@@ -981,7 +977,20 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
        struct drm_i915_gem_pwrite *args = data;
        struct drm_gem_object *obj;
        struct drm_i915_gem_object *obj_priv;
-       int ret = 0;
+       int ret;
+
+       if (args->size == 0)
+               return 0;
+
+       if (!access_ok(VERIFY_READ,
+                      (char __user *)(uintptr_t)args->data_ptr,
+                      args->size))
+               return -EFAULT;
+
+       ret = fault_in_pages_readable((char __user *)(uintptr_t)args->data_ptr,
+                                     args->size);
+       if (ret)
+               return -EFAULT;
 
        ret = i915_mutex_lock_interruptible(dev);
        if (ret)
@@ -994,30 +1003,12 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
        }
        obj_priv = to_intel_bo(obj);
 
-
        /* Bounds check destination. */
        if (args->offset > obj->size || args->size > obj->size - args->offset) {
                ret = -EINVAL;
                goto out;
        }
 
-       if (args->size == 0)
-               goto out;
-
-       if (!access_ok(VERIFY_READ,
-                      (char __user *)(uintptr_t)args->data_ptr,
-                      args->size)) {
-               ret = -EFAULT;
-               goto out;
-       }
-
-       ret = fault_in_pages_readable((char __user *)(uintptr_t)args->data_ptr,
-                                     args->size);
-       if (ret) {
-               ret = -EFAULT;
-               goto out;
-       }
-
        /* We can only do the GTT pwrite on untiled buffers, as otherwise
         * it would end up going through the fenced access, and we'll get
         * different detiling behavior between reading and writing.
@@ -2907,6 +2898,20 @@ i915_gem_object_set_to_display_plane(struct drm_gem_object *obj,
        return 0;
 }
 
+int
+i915_gem_object_flush_gpu(struct drm_i915_gem_object *obj,
+                         bool interruptible)
+{
+       if (!obj->active)
+               return 0;
+
+       if (obj->base.write_domain & I915_GEM_GPU_DOMAINS)
+               i915_gem_flush_ring(obj->base.dev, NULL, obj->ring,
+                                   0, obj->base.write_domain);
+
+       return i915_gem_object_wait_rendering(&obj->base, interruptible);
+}
+
 /**
  * Moves a single object to the CPU read, and possibly write domain.
  *
index c55c77043357cb0243a4b368a1e6d63b7a4af398..8df574316063fb751d683b4b9d5c0d59b82f42f1 100644 (file)
 #include "i915_drm.h"
 #include "i915_drv.h"
 
+/* Here's the desired hotplug mode */
+#define ADPA_HOTPLUG_BITS (ADPA_CRT_HOTPLUG_PERIOD_128 |               \
+                          ADPA_CRT_HOTPLUG_WARMUP_10MS |               \
+                          ADPA_CRT_HOTPLUG_SAMPLE_4S |                 \
+                          ADPA_CRT_HOTPLUG_VOLTAGE_50 |                \
+                          ADPA_CRT_HOTPLUG_VOLREF_325MV |              \
+                          ADPA_CRT_HOTPLUG_ENABLE)
+
+struct intel_crt {
+       struct intel_encoder base;
+       bool force_hotplug_required;
+};
+
+static struct intel_crt *intel_attached_crt(struct drm_connector *connector)
+{
+       return container_of(intel_attached_encoder(connector),
+                           struct intel_crt, base);
+}
+
 static void intel_crt_dpms(struct drm_encoder *encoder, int mode)
 {
        struct drm_device *dev = encoder->dev;
@@ -129,7 +148,7 @@ static void intel_crt_mode_set(struct drm_encoder *encoder,
                           dpll_md & ~DPLL_MD_UDI_MULTIPLIER_MASK);
        }
 
-       adpa = 0;
+       adpa = ADPA_HOTPLUG_BITS;
        if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
                adpa |= ADPA_HSYNC_ACTIVE_HIGH;
        if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
@@ -157,53 +176,44 @@ static void intel_crt_mode_set(struct drm_encoder *encoder,
 static bool intel_ironlake_crt_detect_hotplug(struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
+       struct intel_crt *crt = intel_attached_crt(connector);
        struct drm_i915_private *dev_priv = dev->dev_private;
-       u32 adpa, temp;
+       u32 adpa;
        bool ret;
-       bool turn_off_dac = false;
 
-       temp = adpa = I915_READ(PCH_ADPA);
+       /* The first time through, trigger an explicit detection cycle */
+       if (crt->force_hotplug_required) {
+               bool turn_off_dac = HAS_PCH_SPLIT(dev);
+               u32 save_adpa;
 
-       if (HAS_PCH_SPLIT(dev))
-               turn_off_dac = true;
-
-       adpa &= ~ADPA_CRT_HOTPLUG_MASK;
-       if (turn_off_dac)
-               adpa &= ~ADPA_DAC_ENABLE;
-
-       /* disable HPD first */
-       I915_WRITE(PCH_ADPA, adpa);
-       (void)I915_READ(PCH_ADPA);
-
-       adpa |= (ADPA_CRT_HOTPLUG_PERIOD_128 |
-                       ADPA_CRT_HOTPLUG_WARMUP_10MS |
-                       ADPA_CRT_HOTPLUG_SAMPLE_4S |
-                       ADPA_CRT_HOTPLUG_VOLTAGE_50 | /* default */
-                       ADPA_CRT_HOTPLUG_VOLREF_325MV |
-                       ADPA_CRT_HOTPLUG_ENABLE |
-                       ADPA_CRT_HOTPLUG_FORCE_TRIGGER);
-
-       DRM_DEBUG_KMS("pch crt adpa 0x%x", adpa);
-       I915_WRITE(PCH_ADPA, adpa);
-
-       if (wait_for((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) == 0,
-                    1000))
-               DRM_DEBUG_KMS("timed out waiting for FORCE_TRIGGER");
-
-       if (turn_off_dac) {
-               /* Make sure hotplug is enabled */
-               I915_WRITE(PCH_ADPA, temp | ADPA_CRT_HOTPLUG_ENABLE);
-               (void)I915_READ(PCH_ADPA);
+               crt->force_hotplug_required = 0;
+
+               save_adpa = adpa = I915_READ(PCH_ADPA);
+               DRM_DEBUG_KMS("trigger hotplug detect cycle: adpa=0x%x\n", adpa);
+
+               adpa |= ADPA_CRT_HOTPLUG_FORCE_TRIGGER;
+               if (turn_off_dac)
+                       adpa &= ~ADPA_DAC_ENABLE;
+
+               I915_WRITE(PCH_ADPA, adpa);
+
+               if (wait_for((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) == 0,
+                            1000))
+                       DRM_DEBUG_KMS("timed out waiting for FORCE_TRIGGER");
+
+               if (turn_off_dac) {
+                       I915_WRITE(PCH_ADPA, save_adpa);
+                       POSTING_READ(PCH_ADPA);
+               }
        }
 
        /* Check the status to see if both blue and green are on now */
        adpa = I915_READ(PCH_ADPA);
-       adpa &= ADPA_CRT_HOTPLUG_MONITOR_MASK;
-       if ((adpa == ADPA_CRT_HOTPLUG_MONITOR_COLOR) ||
-               (adpa == ADPA_CRT_HOTPLUG_MONITOR_MONO))
+       if ((adpa & ADPA_CRT_HOTPLUG_MONITOR_MASK) != 0)
                ret = true;
        else
                ret = false;
+       DRM_DEBUG_KMS("ironlake hotplug adpa=0x%x, result %d\n", adpa, ret);
 
        return ret;
 }
@@ -277,13 +287,12 @@ static bool intel_crt_ddc_probe(struct drm_i915_private *dev_priv, int ddc_bus)
        return i2c_transfer(&dev_priv->gmbus[ddc_bus].adapter, msgs, 1) == 1;
 }
 
-static bool intel_crt_detect_ddc(struct drm_encoder *encoder)
+static bool intel_crt_detect_ddc(struct intel_crt *crt)
 {
-       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
-       struct drm_i915_private *dev_priv = encoder->dev->dev_private;
+       struct drm_i915_private *dev_priv = crt->base.base.dev->dev_private;
 
        /* CRT should always be at 0, but check anyway */
-       if (intel_encoder->type != INTEL_OUTPUT_ANALOG)
+       if (crt->base.type != INTEL_OUTPUT_ANALOG)
                return false;
 
        if (intel_crt_ddc_probe(dev_priv, dev_priv->crt_ddc_pin)) {
@@ -291,7 +300,7 @@ static bool intel_crt_detect_ddc(struct drm_encoder *encoder)
                return true;
        }
 
-       if (intel_ddc_probe(intel_encoder, dev_priv->crt_ddc_pin)) {
+       if (intel_ddc_probe(&crt->base, dev_priv->crt_ddc_pin)) {
                DRM_DEBUG_KMS("CRT detected via DDC:0x50 [EDID]\n");
                return true;
        }
@@ -300,9 +309,9 @@ static bool intel_crt_detect_ddc(struct drm_encoder *encoder)
 }
 
 static enum drm_connector_status
-intel_crt_load_detect(struct drm_crtc *crtc, struct intel_encoder *intel_encoder)
+intel_crt_load_detect(struct drm_crtc *crtc, struct intel_crt *crt)
 {
-       struct drm_encoder *encoder = &intel_encoder->base;
+       struct drm_encoder *encoder = &crt->base.base;
        struct drm_device *dev = encoder->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@@ -434,7 +443,7 @@ static enum drm_connector_status
 intel_crt_detect(struct drm_connector *connector, bool force)
 {
        struct drm_device *dev = connector->dev;
-       struct intel_encoder *encoder = intel_attached_encoder(connector);
+       struct intel_crt *crt = intel_attached_crt(connector);
        struct drm_crtc *crtc;
        int dpms_mode;
        enum drm_connector_status status;
@@ -443,28 +452,31 @@ intel_crt_detect(struct drm_connector *connector, bool force)
                if (intel_crt_detect_hotplug(connector)) {
                        DRM_DEBUG_KMS("CRT detected via hotplug\n");
                        return connector_status_connected;
-               } else
+               } else {
+                       DRM_DEBUG_KMS("CRT not detected via hotplug\n");
                        return connector_status_disconnected;
+               }
        }
 
-       if (intel_crt_detect_ddc(&encoder->base))
+       if (intel_crt_detect_ddc(crt))
                return connector_status_connected;
 
        if (!force)
                return connector->status;
 
        /* for pre-945g platforms use load detect */
-       if (encoder->base.crtc && encoder->base.crtc->enabled) {
-               status = intel_crt_load_detect(encoder->base.crtc, encoder);
+       crtc = crt->base.base.crtc;
+       if (crtc && crtc->enabled) {
+               status = intel_crt_load_detect(crtc, crt);
        } else {
-               crtc = intel_get_load_detect_pipe(encoder, connector,
+               crtc = intel_get_load_detect_pipe(&crt->base, connector,
                                                  NULL, &dpms_mode);
                if (crtc) {
-                       if (intel_crt_detect_ddc(&encoder->base))
+                       if (intel_crt_detect_ddc(crt))
                                status = connector_status_connected;
                        else
-                               status = intel_crt_load_detect(crtc, encoder);
-                       intel_release_load_detect_pipe(encoder,
+                               status = intel_crt_load_detect(crtc, crt);
+                       intel_release_load_detect_pipe(&crt->base,
                                                       connector, dpms_mode);
                } else
                        status = connector_status_unknown;
@@ -536,17 +548,17 @@ static const struct drm_encoder_funcs intel_crt_enc_funcs = {
 void intel_crt_init(struct drm_device *dev)
 {
        struct drm_connector *connector;
-       struct intel_encoder *intel_encoder;
+       struct intel_crt *crt;
        struct intel_connector *intel_connector;
        struct drm_i915_private *dev_priv = dev->dev_private;
 
-       intel_encoder = kzalloc(sizeof(struct intel_encoder), GFP_KERNEL);
-       if (!intel_encoder)
+       crt = kzalloc(sizeof(struct intel_crt), GFP_KERNEL);
+       if (!crt)
                return;
 
        intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
        if (!intel_connector) {
-               kfree(intel_encoder);
+               kfree(crt);
                return;
        }
 
@@ -554,20 +566,20 @@ void intel_crt_init(struct drm_device *dev)
        drm_connector_init(dev, &intel_connector->base,
                           &intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA);
 
-       drm_encoder_init(dev, &intel_encoder->base, &intel_crt_enc_funcs,
+       drm_encoder_init(dev, &crt->base.base, &intel_crt_enc_funcs,
                         DRM_MODE_ENCODER_DAC);
 
-       intel_connector_attach_encoder(intel_connector, intel_encoder);
+       intel_connector_attach_encoder(intel_connector, &crt->base);
 
-       intel_encoder->type = INTEL_OUTPUT_ANALOG;
-       intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
-                                  (1 << INTEL_ANALOG_CLONE_BIT) |
-                                  (1 << INTEL_SDVO_LVDS_CLONE_BIT);
-       intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
+       crt->base.type = INTEL_OUTPUT_ANALOG;
+       crt->base.clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT |
+                               1 << INTEL_ANALOG_CLONE_BIT |
+                               1 << INTEL_SDVO_LVDS_CLONE_BIT);
+       crt->base.crtc_mask = (1 << 0) | (1 << 1);
        connector->interlace_allowed = 1;
        connector->doublescan_allowed = 0;
 
-       drm_encoder_helper_add(&intel_encoder->base, &intel_crt_helper_funcs);
+       drm_encoder_helper_add(&crt->base.base, &intel_crt_helper_funcs);
        drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs);
 
        drm_sysfs_connector_add(connector);
@@ -577,5 +589,22 @@ void intel_crt_init(struct drm_device *dev)
        else
                connector->polled = DRM_CONNECTOR_POLL_CONNECT;
 
+       /*
+        * Configure the automatic hotplug detection stuff
+        */
+       crt->force_hotplug_required = 0;
+       if (HAS_PCH_SPLIT(dev)) {
+               u32 adpa;
+
+               adpa = I915_READ(PCH_ADPA);
+               adpa &= ~ADPA_CRT_HOTPLUG_MASK;
+               adpa |= ADPA_HOTPLUG_BITS;
+               I915_WRITE(PCH_ADPA, adpa);
+               POSTING_READ(PCH_ADPA);
+
+               DRM_DEBUG_KMS("pch crt adpa set to 0x%x\n", adpa);
+               crt->force_hotplug_required = 1;
+       }
+
        dev_priv->hotplug_supported_mask |= CRT_HOTPLUG_INT_STATUS;
 }
index 48d8fd686ea91d9fb3ba307036ecd0f5388174e9..bee24b1a58e86b5dc1d1c038f8f1a653848bec97 100644 (file)
@@ -1611,6 +1611,18 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
 
                wait_event(dev_priv->pending_flip_queue,
                           atomic_read(&obj_priv->pending_flip) == 0);
+
+               /* Big Hammer, we also need to ensure that any pending
+                * MI_WAIT_FOR_EVENT inside a user batch buffer on the
+                * current scanout is retired before unpinning the old
+                * framebuffer.
+                */
+               ret = i915_gem_object_flush_gpu(obj_priv, false);
+               if (ret) {
+                       i915_gem_object_unpin(to_intel_framebuffer(crtc->fb)->obj);
+                       mutex_unlock(&dev->struct_mutex);
+                       return ret;
+               }
        }
 
        ret = intel_pipe_set_base_atomic(crtc, crtc->fb, x, y,
index 2be4f728ed0c7b250550613cc93259462db9735a..3dba086e7eea012947c410738e208a9ef39bfa9e 100644 (file)
@@ -160,7 +160,7 @@ intel_gpio_create(struct drm_i915_private *dev_priv, u32 pin)
        };
        struct intel_gpio *gpio;
 
-       if (pin < 1 || pin > 7)
+       if (pin >= ARRAY_SIZE(map_pin_to_reg) || !map_pin_to_reg[pin])
                return NULL;
 
        gpio = kzalloc(sizeof(struct intel_gpio), GFP_KERNEL);
@@ -172,7 +172,8 @@ intel_gpio_create(struct drm_i915_private *dev_priv, u32 pin)
                gpio->reg += PCH_GPIOA - GPIOA;
        gpio->dev_priv = dev_priv;
 
-       snprintf(gpio->adapter.name, I2C_NAME_SIZE, "GPIO%c", "?BACDEF?"[pin]);
+       snprintf(gpio->adapter.name, sizeof(gpio->adapter.name),
+                "i915 GPIO%c", "?BACDE?F"[pin]);
        gpio->adapter.owner = THIS_MODULE;
        gpio->adapter.algo_data = &gpio->algo;
        gpio->adapter.dev.parent = &dev_priv->dev->pdev->dev;
@@ -349,7 +350,7 @@ int intel_setup_gmbus(struct drm_device *dev)
                "panel",
                "dpc",
                "dpb",
-               "reserved"
+               "reserved",
                "dpd",
        };
        struct drm_i915_private *dev_priv = dev->dev_private;
@@ -366,8 +367,8 @@ int intel_setup_gmbus(struct drm_device *dev)
                bus->adapter.owner = THIS_MODULE;
                bus->adapter.class = I2C_CLASS_DDC;
                snprintf(bus->adapter.name,
-                        I2C_NAME_SIZE,
-                        "gmbus %s",
+                        sizeof(bus->adapter.name),
+                        "i915 gmbus %s",
                         names[i]);
 
                bus->adapter.dev.parent = &dev->pdev->dev;
index 406228f4a2a05e549090f8a4e4fca09253546833..b14c811105756706103fe770bc140f24e0a604a7 100644 (file)
@@ -31,6 +31,7 @@
  */
 
 #include <linux/backlight.h>
+#include <linux/acpi.h>
 
 #include "drmP.h"
 #include "nouveau_drv.h"
@@ -136,6 +137,14 @@ int nouveau_backlight_init(struct drm_device *dev)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
 
+#ifdef CONFIG_ACPI
+       if (acpi_video_backlight_support()) {
+               NV_INFO(dev, "ACPI backlight interface available, "
+                            "not registering our own\n");
+               return 0;
+       }
+#endif
+
        switch (dev_priv->card_type) {
        case NV_40:
                return nouveau_nv40_backlight_init(dev);
index 5f21030a293bbc3f373a76631a5e092a0075ea3f..b2293576f27895f3b67e41e563675ab52519b3ad 100644 (file)
@@ -6829,7 +6829,7 @@ nouveau_bios_posted(struct drm_device *dev)
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        unsigned htotal;
 
-       if (dev_priv->chipset >= NV_50) {
+       if (dev_priv->card_type >= NV_50) {
                if (NVReadVgaCrtc(dev, 0, 0x00) == 0 &&
                    NVReadVgaCrtc(dev, 0, 0x1a) == 0)
                        return false;
index 80353e2b8409fdfe34b620b54ce8fdc119af5acd..c41e1c200ef5f2143ea670b45eb3f1d0633864e2 100644 (file)
@@ -143,8 +143,10 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan,
        nvbo->no_vm = no_vm;
        nvbo->tile_mode = tile_mode;
        nvbo->tile_flags = tile_flags;
+       nvbo->bo.bdev = &dev_priv->ttm.bdev;
 
-       nouveau_bo_fixup_align(dev, tile_mode, tile_flags, &align, &size);
+       nouveau_bo_fixup_align(dev, tile_mode, nouveau_bo_tile_layout(nvbo),
+                              &align, &size);
        align >>= PAGE_SHIFT;
 
        nouveau_bo_placement_set(nvbo, flags, 0);
@@ -176,6 +178,31 @@ set_placement_list(uint32_t *pl, unsigned *n, uint32_t type, uint32_t flags)
                pl[(*n)++] = TTM_PL_FLAG_SYSTEM | flags;
 }
 
+static void
+set_placement_range(struct nouveau_bo *nvbo, uint32_t type)
+{
+       struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev);
+
+       if (dev_priv->card_type == NV_10 &&
+           nvbo->tile_mode && (type & TTM_PL_FLAG_VRAM)) {
+               /*
+                * Make sure that the color and depth buffers are handled
+                * by independent memory controller units. Up to a 9x
+                * speed up when alpha-blending and depth-test are enabled
+                * at the same time.
+                */
+               int vram_pages = dev_priv->vram_size >> PAGE_SHIFT;
+
+               if (nvbo->tile_flags & NOUVEAU_GEM_TILE_ZETA) {
+                       nvbo->placement.fpfn = vram_pages / 2;
+                       nvbo->placement.lpfn = ~0;
+               } else {
+                       nvbo->placement.fpfn = 0;
+                       nvbo->placement.lpfn = vram_pages / 2;
+               }
+       }
+}
+
 void
 nouveau_bo_placement_set(struct nouveau_bo *nvbo, uint32_t type, uint32_t busy)
 {
@@ -190,6 +217,8 @@ nouveau_bo_placement_set(struct nouveau_bo *nvbo, uint32_t type, uint32_t busy)
        pl->busy_placement = nvbo->busy_placements;
        set_placement_list(nvbo->busy_placements, &pl->num_busy_placement,
                           type | busy, flags);
+
+       set_placement_range(nvbo, type);
 }
 
 int
@@ -525,7 +554,8 @@ nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
                stride  = 16 * 4;
                height  = amount / stride;
 
-               if (new_mem->mem_type == TTM_PL_VRAM && nvbo->tile_flags) {
+               if (new_mem->mem_type == TTM_PL_VRAM &&
+                   nouveau_bo_tile_layout(nvbo)) {
                        ret = RING_SPACE(chan, 8);
                        if (ret)
                                return ret;
@@ -546,7 +576,8 @@ nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
                        BEGIN_RING(chan, NvSubM2MF, 0x0200, 1);
                        OUT_RING  (chan, 1);
                }
-               if (old_mem->mem_type == TTM_PL_VRAM && nvbo->tile_flags) {
+               if (old_mem->mem_type == TTM_PL_VRAM &&
+                   nouveau_bo_tile_layout(nvbo)) {
                        ret = RING_SPACE(chan, 8);
                        if (ret)
                                return ret;
@@ -753,7 +784,8 @@ nouveau_bo_vm_bind(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_mem,
        if (dev_priv->card_type == NV_50) {
                ret = nv50_mem_vm_bind_linear(dev,
                                              offset + dev_priv->vm_vram_base,
-                                             new_mem->size, nvbo->tile_flags,
+                                             new_mem->size,
+                                             nouveau_bo_tile_layout(nvbo),
                                              offset);
                if (ret)
                        return ret;
@@ -894,7 +926,8 @@ nouveau_ttm_fault_reserve_notify(struct ttm_buffer_object *bo)
         * nothing to do here.
         */
        if (bo->mem.mem_type != TTM_PL_VRAM) {
-               if (dev_priv->card_type < NV_50 || !nvbo->tile_flags)
+               if (dev_priv->card_type < NV_50 ||
+                   !nouveau_bo_tile_layout(nvbo))
                        return 0;
        }
 
index 0871495096fa86f1278f825c8420f8e14f1e6b38..52c356e9a3d177b92ed5013e8f55247a56468f5d 100644 (file)
@@ -281,7 +281,7 @@ detect_analog:
        nv_encoder = find_encoder_by_type(connector, OUTPUT_ANALOG);
        if (!nv_encoder && !nouveau_tv_disable)
                nv_encoder = find_encoder_by_type(connector, OUTPUT_TV);
-       if (nv_encoder) {
+       if (nv_encoder && force) {
                struct drm_encoder *encoder = to_drm_encoder(nv_encoder);
                struct drm_encoder_helper_funcs *helper =
                                                encoder->helper_private;
@@ -641,11 +641,28 @@ nouveau_connector_get_modes(struct drm_connector *connector)
        return ret;
 }
 
+static unsigned
+get_tmds_link_bandwidth(struct drm_connector *connector)
+{
+       struct nouveau_connector *nv_connector = nouveau_connector(connector);
+       struct drm_nouveau_private *dev_priv = connector->dev->dev_private;
+       struct dcb_entry *dcb = nv_connector->detected_encoder->dcb;
+
+       if (dcb->location != DCB_LOC_ON_CHIP ||
+           dev_priv->chipset >= 0x46)
+               return 165000;
+       else if (dev_priv->chipset >= 0x40)
+               return 155000;
+       else if (dev_priv->chipset >= 0x18)
+               return 135000;
+       else
+               return 112000;
+}
+
 static int
 nouveau_connector_mode_valid(struct drm_connector *connector,
                             struct drm_display_mode *mode)
 {
-       struct drm_nouveau_private *dev_priv = connector->dev->dev_private;
        struct nouveau_connector *nv_connector = nouveau_connector(connector);
        struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder;
        struct drm_encoder *encoder = to_drm_encoder(nv_encoder);
@@ -663,11 +680,9 @@ nouveau_connector_mode_valid(struct drm_connector *connector,
                max_clock = 400000;
                break;
        case OUTPUT_TMDS:
-               if ((dev_priv->card_type >= NV_50 && !nouveau_duallink) ||
-                   !nv_encoder->dcb->duallink_possible)
-                       max_clock = 165000;
-               else
-                       max_clock = 330000;
+               max_clock = get_tmds_link_bandwidth(connector);
+               if (nouveau_duallink && nv_encoder->dcb->duallink_possible)
+                       max_clock *= 2;
                break;
        case OUTPUT_ANALOG:
                max_clock = nv_encoder->dcb->crtconf.maxfreq;
@@ -709,44 +724,6 @@ nouveau_connector_best_encoder(struct drm_connector *connector)
        return NULL;
 }
 
-void
-nouveau_connector_set_polling(struct drm_connector *connector)
-{
-       struct drm_device *dev = connector->dev;
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct drm_crtc *crtc;
-       bool spare_crtc = false;
-
-       list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
-               spare_crtc |= !crtc->enabled;
-
-       connector->polled = 0;
-
-       switch (connector->connector_type) {
-       case DRM_MODE_CONNECTOR_VGA:
-       case DRM_MODE_CONNECTOR_TV:
-               if (dev_priv->card_type >= NV_50 ||
-                   (nv_gf4_disp_arch(dev) && spare_crtc))
-                       connector->polled = DRM_CONNECTOR_POLL_CONNECT;
-               break;
-
-       case DRM_MODE_CONNECTOR_DVII:
-       case DRM_MODE_CONNECTOR_DVID:
-       case DRM_MODE_CONNECTOR_HDMIA:
-       case DRM_MODE_CONNECTOR_DisplayPort:
-       case DRM_MODE_CONNECTOR_eDP:
-               if (dev_priv->card_type >= NV_50)
-                       connector->polled = DRM_CONNECTOR_POLL_HPD;
-               else if (connector->connector_type == DRM_MODE_CONNECTOR_DVID ||
-                        spare_crtc)
-                       connector->polled = DRM_CONNECTOR_POLL_CONNECT;
-               break;
-
-       default:
-               break;
-       }
-}
-
 static const struct drm_connector_helper_funcs
 nouveau_connector_helper_funcs = {
        .get_modes = nouveau_connector_get_modes,
@@ -872,6 +849,7 @@ nouveau_connector_create(struct drm_device *dev, int index)
                                        dev->mode_config.scaling_mode_property,
                                        nv_connector->scaling_mode);
                }
+               connector->polled = DRM_CONNECTOR_POLL_CONNECT;
                /* fall-through */
        case DCB_CONNECTOR_TV_0:
        case DCB_CONNECTOR_TV_1:
@@ -888,11 +866,16 @@ nouveau_connector_create(struct drm_device *dev, int index)
                                dev->mode_config.dithering_mode_property,
                                nv_connector->use_dithering ?
                                DRM_MODE_DITHERING_ON : DRM_MODE_DITHERING_OFF);
+
+               if (dcb->type != DCB_CONNECTOR_LVDS) {
+                       if (dev_priv->card_type >= NV_50)
+                               connector->polled = DRM_CONNECTOR_POLL_HPD;
+                       else
+                               connector->polled = DRM_CONNECTOR_POLL_CONNECT;
+               }
                break;
        }
 
-       nouveau_connector_set_polling(connector);
-
        drm_sysfs_connector_add(connector);
        dcb->drm = connector;
        return dcb->drm;
index c21ed6b16f88d41aebdee888997c12a7249fdd03..711b1e9203aff075c16757fd41394a5ea06d33e7 100644 (file)
@@ -52,9 +52,6 @@ static inline struct nouveau_connector *nouveau_connector(
 struct drm_connector *
 nouveau_connector_create(struct drm_device *, int index);
 
-void
-nouveau_connector_set_polling(struct drm_connector *);
-
 int
 nouveau_connector_bpp(struct drm_connector *);
 
index 3a07e580d27af548fe2fd247b4e7df4c67994956..1c7db64c03bf03b45070939f16bc5a0092820ba0 100644 (file)
@@ -100,6 +100,9 @@ struct nouveau_bo {
        int pin_refcnt;
 };
 
+#define nouveau_bo_tile_layout(nvbo)                           \
+       ((nvbo)->tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK)
+
 static inline struct nouveau_bo *
 nouveau_bo(struct ttm_buffer_object *bo)
 {
@@ -304,6 +307,7 @@ struct nouveau_fifo_engine {
        void (*destroy_context)(struct nouveau_channel *);
        int  (*load_context)(struct nouveau_channel *);
        int  (*unload_context)(struct drm_device *);
+       void (*tlb_flush)(struct drm_device *dev);
 };
 
 struct nouveau_pgraph_object_method {
@@ -336,6 +340,7 @@ struct nouveau_pgraph_engine {
        void (*destroy_context)(struct nouveau_channel *);
        int  (*load_context)(struct nouveau_channel *);
        int  (*unload_context)(struct drm_device *);
+       void (*tlb_flush)(struct drm_device *dev);
 
        void (*set_region_tiling)(struct drm_device *dev, int i, uint32_t addr,
                                  uint32_t size, uint32_t pitch);
@@ -485,13 +490,13 @@ enum nv04_fp_display_regs {
 };
 
 struct nv04_crtc_reg {
-       unsigned char MiscOutReg;     /* */
+       unsigned char MiscOutReg;
        uint8_t CRTC[0xa0];
        uint8_t CR58[0x10];
        uint8_t Sequencer[5];
        uint8_t Graphics[9];
        uint8_t Attribute[21];
-       unsigned char DAC[768];       /* Internal Colorlookuptable */
+       unsigned char DAC[768];
 
        /* PCRTC regs */
        uint32_t fb_start;
@@ -539,43 +544,9 @@ struct nv04_output_reg {
 };
 
 struct nv04_mode_state {
-       uint32_t bpp;
-       uint32_t width;
-       uint32_t height;
-       uint32_t interlace;
-       uint32_t repaint0;
-       uint32_t repaint1;
-       uint32_t screen;
-       uint32_t scale;
-       uint32_t dither;
-       uint32_t extra;
-       uint32_t fifo;
-       uint32_t pixel;
-       uint32_t horiz;
-       int arbitration0;
-       int arbitration1;
-       uint32_t pll;
-       uint32_t pllB;
-       uint32_t vpll;
-       uint32_t vpll2;
-       uint32_t vpllB;
-       uint32_t vpll2B;
+       struct nv04_crtc_reg crtc_reg[2];
        uint32_t pllsel;
        uint32_t sel_clk;
-       uint32_t general;
-       uint32_t crtcOwner;
-       uint32_t head;
-       uint32_t head2;
-       uint32_t cursorConfig;
-       uint32_t cursor0;
-       uint32_t cursor1;
-       uint32_t cursor2;
-       uint32_t timingH;
-       uint32_t timingV;
-       uint32_t displayV;
-       uint32_t crtcSync;
-
-       struct nv04_crtc_reg crtc_reg[2];
 };
 
 enum nouveau_card_type {
@@ -613,6 +584,12 @@ struct drm_nouveau_private {
        struct work_struct irq_work;
        struct work_struct hpd_work;
 
+       struct {
+               spinlock_t lock;
+               uint32_t hpd0_bits;
+               uint32_t hpd1_bits;
+       } hpd_state;
+
        struct list_head vbl_waiting;
 
        struct {
@@ -1045,6 +1022,7 @@ extern int  nv50_fifo_create_context(struct nouveau_channel *);
 extern void nv50_fifo_destroy_context(struct nouveau_channel *);
 extern int  nv50_fifo_load_context(struct nouveau_channel *);
 extern int  nv50_fifo_unload_context(struct drm_device *);
+extern void nv50_fifo_tlb_flush(struct drm_device *dev);
 
 /* nvc0_fifo.c */
 extern int  nvc0_fifo_init(struct drm_device *);
@@ -1122,6 +1100,8 @@ extern int  nv50_graph_load_context(struct nouveau_channel *);
 extern int  nv50_graph_unload_context(struct drm_device *);
 extern void nv50_graph_context_switch(struct drm_device *);
 extern int  nv50_grctx_init(struct nouveau_grctx *);
+extern void nv50_graph_tlb_flush(struct drm_device *dev);
+extern void nv86_graph_tlb_flush(struct drm_device *dev);
 
 /* nvc0_graph.c */
 extern int  nvc0_graph_init(struct drm_device *);
@@ -1239,7 +1219,6 @@ extern u16 nouveau_bo_rd16(struct nouveau_bo *nvbo, unsigned index);
 extern void nouveau_bo_wr16(struct nouveau_bo *nvbo, unsigned index, u16 val);
 extern u32 nouveau_bo_rd32(struct nouveau_bo *nvbo, unsigned index);
 extern void nouveau_bo_wr32(struct nouveau_bo *nvbo, unsigned index, u32 val);
-extern int nouveau_bo_sync_gpu(struct nouveau_bo *, struct nouveau_channel *);
 
 /* nouveau_fence.c */
 struct nouveau_fence;
index 441b12420bb1b713fb56b98edad389d31fe367ea..ab1bbfbf266e6a63755264ad461484f3608a10c1 100644 (file)
@@ -249,6 +249,7 @@ alloc_semaphore(struct drm_device *dev)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nouveau_semaphore *sema;
+       int ret;
 
        if (!USE_SEMA(dev))
                return NULL;
@@ -257,10 +258,14 @@ alloc_semaphore(struct drm_device *dev)
        if (!sema)
                goto fail;
 
+       ret = drm_mm_pre_get(&dev_priv->fence.heap);
+       if (ret)
+               goto fail;
+
        spin_lock(&dev_priv->fence.lock);
        sema->mem = drm_mm_search_free(&dev_priv->fence.heap, 4, 0, 0);
        if (sema->mem)
-               sema->mem = drm_mm_get_block(sema->mem, 4, 0);
+               sema->mem = drm_mm_get_block_atomic(sema->mem, 4, 0);
        spin_unlock(&dev_priv->fence.lock);
 
        if (!sema->mem)
index 5c4c929d7f744d6911c1a16b67924ab770b6de5c..9a1fdcf400c2fea235544f062fe8b33cd1b01fd4 100644 (file)
@@ -107,23 +107,29 @@ nouveau_gem_info(struct drm_gem_object *gem, struct drm_nouveau_gem_info *rep)
 }
 
 static bool
-nouveau_gem_tile_flags_valid(struct drm_device *dev, uint32_t tile_flags) {
-       switch (tile_flags) {
-       case 0x0000:
-       case 0x1800:
-       case 0x2800:
-       case 0x4800:
-       case 0x7000:
-       case 0x7400:
-       case 0x7a00:
-       case 0xe000:
-               break;
-       default:
-               NV_ERROR(dev, "bad page flags: 0x%08x\n", tile_flags);
-               return false;
+nouveau_gem_tile_flags_valid(struct drm_device *dev, uint32_t tile_flags)
+{
+       struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+       if (dev_priv->card_type >= NV_50) {
+               switch (tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK) {
+               case 0x0000:
+               case 0x1800:
+               case 0x2800:
+               case 0x4800:
+               case 0x7000:
+               case 0x7400:
+               case 0x7a00:
+               case 0xe000:
+                       return true;
+               }
+       } else {
+               if (!(tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK))
+                       return true;
        }
 
-       return true;
+       NV_ERROR(dev, "bad page flags: 0x%08x\n", tile_flags);
+       return false;
 }
 
 int
index bed669a54a2da0692af9a9a1cd4a89064f4d0fd0..b9672a05c411f12866035884acf8778a4742eb9c 100644 (file)
@@ -519,11 +519,11 @@ nouveau_hw_fix_bad_vpll(struct drm_device *dev, int head)
 
        struct pll_lims pll_lim;
        struct nouveau_pll_vals pv;
-       uint32_t pllreg = head ? NV_RAMDAC_VPLL2 : NV_PRAMDAC_VPLL_COEFF;
+       enum pll_types pll = head ? PLL_VPLL1 : PLL_VPLL0;
 
-       if (get_pll_limits(dev, pllreg, &pll_lim))
+       if (get_pll_limits(dev, pll, &pll_lim))
                return;
-       nouveau_hw_get_pllvals(dev, pllreg, &pv);
+       nouveau_hw_get_pllvals(dev, pll, &pv);
 
        if (pv.M1 >= pll_lim.vco1.min_m && pv.M1 <= pll_lim.vco1.max_m &&
            pv.N1 >= pll_lim.vco1.min_n && pv.N1 <= pll_lim.vco1.max_n &&
@@ -536,7 +536,7 @@ nouveau_hw_fix_bad_vpll(struct drm_device *dev, int head)
        pv.M1 = pll_lim.vco1.max_m;
        pv.N1 = pll_lim.vco1.min_n;
        pv.log2P = pll_lim.max_usable_log2p;
-       nouveau_hw_setpll(dev, pllreg, &pv);
+       nouveau_hw_setpll(dev, pll_lim.reg, &pv);
 }
 
 /*
index 869130f83602f6cf027a2329eb7be49eafb88ccc..2989090b94349abdcd05096f89735f641a748c3b 100644 (file)
@@ -415,6 +415,25 @@ nv_fix_nv40_hw_cursor(struct drm_device *dev, int head)
        NVWriteRAMDAC(dev, head, NV_PRAMDAC_CU_START_POS, curpos);
 }
 
+static inline void
+nv_set_crtc_base(struct drm_device *dev, int head, uint32_t offset)
+{
+       struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+       NVWriteCRTC(dev, head, NV_PCRTC_START, offset);
+
+       if (dev_priv->card_type == NV_04) {
+               /*
+                * Hilarious, the 24th bit doesn't want to stick to
+                * PCRTC_START...
+                */
+               int cre_heb = NVReadVgaCrtc(dev, head, NV_CIO_CRE_HEB__INDEX);
+
+               NVWriteVgaCrtc(dev, head, NV_CIO_CRE_HEB__INDEX,
+                              (cre_heb & ~0x40) | ((offset >> 18) & 0x40));
+       }
+}
+
 static inline void
 nv_show_cursor(struct drm_device *dev, int head, bool show)
 {
index fdd7e3de79c895138c93706bc023048772f93026..cb389d014326ae4c89b78724f3438a023e0f06b7 100644 (file)
@@ -256,7 +256,7 @@ nouveau_i2c_find(struct drm_device *dev, int index)
        if (index >= DCB_MAX_NUM_I2C_ENTRIES)
                return NULL;
 
-       if (dev_priv->chipset >= NV_50 && (i2c->entry & 0x00000100)) {
+       if (dev_priv->card_type >= NV_50 && (i2c->entry & 0x00000100)) {
                uint32_t reg = 0xe500, val;
 
                if (i2c->port_type == 6) {
index 6fd51a51c60861e697f43755593f4ad2a1830c9c..7bfd9e6c9d67194b298047d7670a54a996c16750 100644 (file)
 #include "nouveau_connector.h"
 #include "nv50_display.h"
 
+static DEFINE_RATELIMIT_STATE(nouveau_ratelimit_state, 3 * HZ, 20);
+
+static int nouveau_ratelimit(void)
+{
+       return __ratelimit(&nouveau_ratelimit_state);
+}
+
 void
 nouveau_irq_preinstall(struct drm_device *dev)
 {
@@ -53,6 +60,7 @@ nouveau_irq_preinstall(struct drm_device *dev)
        if (dev_priv->card_type >= NV_50) {
                INIT_WORK(&dev_priv->irq_work, nv50_display_irq_handler_bh);
                INIT_WORK(&dev_priv->hpd_work, nv50_display_irq_hotplug_bh);
+               spin_lock_init(&dev_priv->hpd_state.lock);
                INIT_LIST_HEAD(&dev_priv->vbl_waiting);
        }
 }
@@ -202,8 +210,8 @@ nouveau_fifo_irq_handler(struct drm_device *dev)
                }
 
                if (status & NV_PFIFO_INTR_DMA_PUSHER) {
-                       u32 get = nv_rd32(dev, 0x003244);
-                       u32 put = nv_rd32(dev, 0x003240);
+                       u32 dma_get = nv_rd32(dev, 0x003244);
+                       u32 dma_put = nv_rd32(dev, 0x003240);
                        u32 push = nv_rd32(dev, 0x003220);
                        u32 state = nv_rd32(dev, 0x003228);
 
@@ -213,16 +221,18 @@ nouveau_fifo_irq_handler(struct drm_device *dev)
                                u32 ib_get = nv_rd32(dev, 0x003334);
                                u32 ib_put = nv_rd32(dev, 0x003330);
 
-                               NV_INFO(dev, "PFIFO_DMA_PUSHER - Ch %d Get 0x%02x%08x "
+                               if (nouveau_ratelimit())
+                                       NV_INFO(dev, "PFIFO_DMA_PUSHER - Ch %d Get 0x%02x%08x "
                                             "Put 0x%02x%08x IbGet 0x%08x IbPut 0x%08x "
                                             "State 0x%08x Push 0x%08x\n",
-                                       chid, ho_get, get, ho_put, put, ib_get, ib_put,
-                                       state, push);
+                                               chid, ho_get, dma_get, ho_put,
+                                               dma_put, ib_get, ib_put, state,
+                                               push);
 
                                /* METHOD_COUNT, in DMA_STATE on earlier chipsets */
                                nv_wr32(dev, 0x003364, 0x00000000);
-                               if (get != put || ho_get != ho_put) {
-                                       nv_wr32(dev, 0x003244, put);
+                               if (dma_get != dma_put || ho_get != ho_put) {
+                                       nv_wr32(dev, 0x003244, dma_put);
                                        nv_wr32(dev, 0x003328, ho_put);
                                } else
                                if (ib_get != ib_put) {
@@ -231,10 +241,10 @@ nouveau_fifo_irq_handler(struct drm_device *dev)
                        } else {
                                NV_INFO(dev, "PFIFO_DMA_PUSHER - Ch %d Get 0x%08x "
                                             "Put 0x%08x State 0x%08x Push 0x%08x\n",
-                                       chid, get, put, state, push);
+                                       chid, dma_get, dma_put, state, push);
 
-                               if (get != put)
-                                       nv_wr32(dev, 0x003244, put);
+                               if (dma_get != dma_put)
+                                       nv_wr32(dev, 0x003244, dma_put);
                        }
 
                        nv_wr32(dev, 0x003228, 0x00000000);
@@ -266,8 +276,9 @@ nouveau_fifo_irq_handler(struct drm_device *dev)
                }
 
                if (status) {
-                       NV_INFO(dev, "PFIFO_INTR 0x%08x - Ch %d\n",
-                               status, chid);
+                       if (nouveau_ratelimit())
+                               NV_INFO(dev, "PFIFO_INTR 0x%08x - Ch %d\n",
+                                       status, chid);
                        nv_wr32(dev, NV03_PFIFO_INTR_0, status);
                        status = 0;
                }
@@ -544,13 +555,6 @@ nouveau_pgraph_intr_notify(struct drm_device *dev, uint32_t nsource)
                nouveau_graph_dump_trap_info(dev, "PGRAPH_NOTIFY", &trap);
 }
 
-static DEFINE_RATELIMIT_STATE(nouveau_ratelimit_state, 3 * HZ, 20);
-
-static int nouveau_ratelimit(void)
-{
-       return __ratelimit(&nouveau_ratelimit_state);
-}
-
 
 static inline void
 nouveau_pgraph_intr_error(struct drm_device *dev, uint32_t nsource)
index a163c7c612e78eb6b6718620ee75773cd49a26f7..fe4a30dc4b42e929f283d35e1094b26a422f4f2e 100644 (file)
@@ -33,9 +33,9 @@
 #include "drmP.h"
 #include "drm.h"
 #include "drm_sarea.h"
-#include "nouveau_drv.h"
 
-#define MIN(a,b) a < b ? a : b
+#include "nouveau_drv.h"
+#include "nouveau_pm.h"
 
 /*
  * NV10-NV40 tiling helpers
@@ -175,11 +175,10 @@ nv50_mem_vm_bind_linear(struct drm_device *dev, uint64_t virt, uint32_t size,
                        }
                }
        }
-       dev_priv->engine.instmem.flush(dev);
 
-       nv50_vm_flush(dev, 5);
-       nv50_vm_flush(dev, 0);
-       nv50_vm_flush(dev, 4);
+       dev_priv->engine.instmem.flush(dev);
+       dev_priv->engine.fifo.tlb_flush(dev);
+       dev_priv->engine.graph.tlb_flush(dev);
        nv50_vm_flush(dev, 6);
        return 0;
 }
@@ -209,11 +208,10 @@ nv50_mem_vm_unbind(struct drm_device *dev, uint64_t virt, uint32_t size)
                        pte++;
                }
        }
-       dev_priv->engine.instmem.flush(dev);
 
-       nv50_vm_flush(dev, 5);
-       nv50_vm_flush(dev, 0);
-       nv50_vm_flush(dev, 4);
+       dev_priv->engine.instmem.flush(dev);
+       dev_priv->engine.fifo.tlb_flush(dev);
+       dev_priv->engine.graph.tlb_flush(dev);
        nv50_vm_flush(dev, 6);
 }
 
@@ -653,6 +651,7 @@ nouveau_mem_gart_init(struct drm_device *dev)
 void
 nouveau_mem_timing_init(struct drm_device *dev)
 {
+       /* cards < NVC0 only */
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
        struct nouveau_pm_memtimings *memtimings = &pm->memtimings;
@@ -719,14 +718,14 @@ nouveau_mem_timing_init(struct drm_device *dev)
                tUNK_19 = 1;
                tUNK_20 = 0;
                tUNK_21 = 0;
-               switch (MIN(recordlen,21)) {
-               case 21:
+               switch (min(recordlen, 22)) {
+               case 22:
                        tUNK_21 = entry[21];
-               case 20:
+               case 21:
                        tUNK_20 = entry[20];
-               case 19:
+               case 20:
                        tUNK_19 = entry[19];
-               case 18:
+               case 19:
                        tUNK_18 = entry[18];
                default:
                        tUNK_0  = entry[0];
@@ -756,24 +755,30 @@ nouveau_mem_timing_init(struct drm_device *dev)
                timing->reg_100228 = (tUNK_12 << 16 | tUNK_11 << 8 | tUNK_10);
                if(recordlen > 19) {
                        timing->reg_100228 += (tUNK_19 - 1) << 24;
-               } else {
+               }/* I cannot back-up this else-statement right now
+                        else {
                        timing->reg_100228 += tUNK_12 << 24;
-               }
+               }*/
 
                /* XXX: reg_10022c */
+               timing->reg_10022c = tUNK_2 - 1;
 
                timing->reg_100230 = (tUNK_20 << 24 | tUNK_21 << 16 |
                                      tUNK_13 << 8  | tUNK_13);
 
                /* XXX: +6? */
                timing->reg_100234 = (tRAS << 24 | (tUNK_19 + 6) << 8 | tRC);
-               if(tUNK_10 > tUNK_11) {
-                       timing->reg_100234 += tUNK_10 << 16;
-               } else {
-                       timing->reg_100234 += tUNK_11 << 16;
+               timing->reg_100234 += max(tUNK_10,tUNK_11) << 16;
+
+               /* XXX; reg_100238, reg_10023c
+                * reg: 0x00??????
+                * reg_10023c:
+                *      0 for pre-NV50 cards
+                *      0x????0202 for NV50+ cards (empirical evidence) */
+               if(dev_priv->card_type >= NV_50) {
+                       timing->reg_10023c = 0x202;
                }
 
-               /* XXX; reg_100238, reg_10023c */
                NV_DEBUG(dev, "Entry %d: 220: %08x %08x %08x %08x\n", i,
                         timing->reg_100220, timing->reg_100224,
                         timing->reg_100228, timing->reg_10022c);
index 896cf8634144a2b5cf7f69fdd006c848b4b2eb79..dd572adca02ad0232df35715257ccc597adf86f3 100644 (file)
@@ -129,7 +129,7 @@ nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan,
                        if (ramin == NULL) {
                                spin_unlock(&dev_priv->ramin_lock);
                                nouveau_gpuobj_ref(NULL, &gpuobj);
-                               return ret;
+                               return -ENOMEM;
                        }
 
                        ramin = drm_mm_get_block_atomic(ramin, size, align);
index 1c99c55d6d468a91fb09cda39d5660d3bf712aa5..9f7b158f5825c7dfd97b5f112afef7a9858e7b23 100644 (file)
@@ -284,6 +284,7 @@ nouveau_sysfs_fini(struct drm_device *dev)
        }
 }
 
+#ifdef CONFIG_HWMON
 static ssize_t
 nouveau_hwmon_show_temp(struct device *d, struct device_attribute *a, char *buf)
 {
@@ -395,10 +396,12 @@ static struct attribute *hwmon_attributes[] = {
 static const struct attribute_group hwmon_attrgroup = {
        .attrs = hwmon_attributes,
 };
+#endif
 
 static int
 nouveau_hwmon_init(struct drm_device *dev)
 {
+#ifdef CONFIG_HWMON
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
        struct device *hwmon_dev;
@@ -425,13 +428,14 @@ nouveau_hwmon_init(struct drm_device *dev)
        }
 
        pm->hwmon = hwmon_dev;
-
+#endif
        return 0;
 }
 
 static void
 nouveau_hwmon_fini(struct drm_device *dev)
 {
+#ifdef CONFIG_HWMON
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
 
@@ -439,6 +443,7 @@ nouveau_hwmon_fini(struct drm_device *dev)
                sysfs_remove_group(&pm->hwmon->kobj, &hwmon_attrgroup);
                hwmon_device_unregister(pm->hwmon);
        }
+#endif
 }
 
 int
index 7f16697cc96ce6438896414735b5fa4d12a84a34..2d8580927ca4579075cd870e5cfdf6459c44d9c6 100644 (file)
@@ -153,26 +153,42 @@ nouveau_ramht_insert(struct nouveau_channel *chan, u32 handle,
        return -ENOMEM;
 }
 
+static struct nouveau_ramht_entry *
+nouveau_ramht_remove_entry(struct nouveau_channel *chan, u32 handle)
+{
+       struct nouveau_ramht *ramht = chan ? chan->ramht : NULL;
+       struct nouveau_ramht_entry *entry;
+       unsigned long flags;
+
+       if (!ramht)
+               return NULL;
+
+       spin_lock_irqsave(&ramht->lock, flags);
+       list_for_each_entry(entry, &ramht->entries, head) {
+               if (entry->channel == chan &&
+                   (!handle || entry->handle == handle)) {
+                       list_del(&entry->head);
+                       spin_unlock_irqrestore(&ramht->lock, flags);
+
+                       return entry;
+               }
+       }
+       spin_unlock_irqrestore(&ramht->lock, flags);
+
+       return NULL;
+}
+
 static void
-nouveau_ramht_remove_locked(struct nouveau_channel *chan, u32 handle)
+nouveau_ramht_remove_hash(struct nouveau_channel *chan, u32 handle)
 {
        struct drm_device *dev = chan->dev;
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem;
        struct nouveau_gpuobj *ramht = chan->ramht->gpuobj;
-       struct nouveau_ramht_entry *entry, *tmp;
+       unsigned long flags;
        u32 co, ho;
 
-       list_for_each_entry_safe(entry, tmp, &chan->ramht->entries, head) {
-               if (entry->channel != chan || entry->handle != handle)
-                       continue;
-
-               nouveau_gpuobj_ref(NULL, &entry->gpuobj);
-               list_del(&entry->head);
-               kfree(entry);
-               break;
-       }
-
+       spin_lock_irqsave(&chan->ramht->lock, flags);
        co = ho = nouveau_ramht_hash_handle(chan, handle);
        do {
                if (nouveau_ramht_entry_valid(dev, ramht, co) &&
@@ -184,7 +200,7 @@ nouveau_ramht_remove_locked(struct nouveau_channel *chan, u32 handle)
                        nv_wo32(ramht, co + 0, 0x00000000);
                        nv_wo32(ramht, co + 4, 0x00000000);
                        instmem->flush(dev);
-                       return;
+                       goto out;
                }
 
                co += 8;
@@ -194,17 +210,22 @@ nouveau_ramht_remove_locked(struct nouveau_channel *chan, u32 handle)
 
        NV_ERROR(dev, "RAMHT entry not found. ch=%d, handle=0x%08x\n",
                 chan->id, handle);
+out:
+       spin_unlock_irqrestore(&chan->ramht->lock, flags);
 }
 
 void
 nouveau_ramht_remove(struct nouveau_channel *chan, u32 handle)
 {
-       struct nouveau_ramht *ramht = chan->ramht;
-       unsigned long flags;
+       struct nouveau_ramht_entry *entry;
 
-       spin_lock_irqsave(&ramht->lock, flags);
-       nouveau_ramht_remove_locked(chan, handle);
-       spin_unlock_irqrestore(&ramht->lock, flags);
+       entry = nouveau_ramht_remove_entry(chan, handle);
+       if (!entry)
+               return;
+
+       nouveau_ramht_remove_hash(chan, entry->handle);
+       nouveau_gpuobj_ref(NULL, &entry->gpuobj);
+       kfree(entry);
 }
 
 struct nouveau_gpuobj *
@@ -265,23 +286,19 @@ void
 nouveau_ramht_ref(struct nouveau_ramht *ref, struct nouveau_ramht **ptr,
                  struct nouveau_channel *chan)
 {
-       struct nouveau_ramht_entry *entry, *tmp;
+       struct nouveau_ramht_entry *entry;
        struct nouveau_ramht *ramht;
-       unsigned long flags;
 
        if (ref)
                kref_get(&ref->refcount);
 
        ramht = *ptr;
        if (ramht) {
-               spin_lock_irqsave(&ramht->lock, flags);
-               list_for_each_entry_safe(entry, tmp, &ramht->entries, head) {
-                       if (entry->channel != chan)
-                               continue;
-
-                       nouveau_ramht_remove_locked(chan, entry->handle);
+               while ((entry = nouveau_ramht_remove_entry(chan, 0))) {
+                       nouveau_ramht_remove_hash(chan, entry->handle);
+                       nouveau_gpuobj_ref(NULL, &entry->gpuobj);
+                       kfree(entry);
                }
-               spin_unlock_irqrestore(&ramht->lock, flags);
 
                kref_put(&ramht->refcount, nouveau_ramht_del);
        }
index 288bacac7e5aefc2f3c6c9b4f461a7e48d6e9ce7..d4ac970070386cea340283ba459194eb8b1de50a 100644 (file)
@@ -120,8 +120,8 @@ nouveau_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem)
        dev_priv->engine.instmem.flush(nvbe->dev);
 
        if (dev_priv->card_type == NV_50) {
-               nv50_vm_flush(dev, 5); /* PGRAPH */
-               nv50_vm_flush(dev, 0); /* PFIFO */
+               dev_priv->engine.fifo.tlb_flush(dev);
+               dev_priv->engine.graph.tlb_flush(dev);
        }
 
        nvbe->bound = true;
@@ -162,8 +162,8 @@ nouveau_sgdma_unbind(struct ttm_backend *be)
        dev_priv->engine.instmem.flush(nvbe->dev);
 
        if (dev_priv->card_type == NV_50) {
-               nv50_vm_flush(dev, 5);
-               nv50_vm_flush(dev, 0);
+               dev_priv->engine.fifo.tlb_flush(dev);
+               dev_priv->engine.graph.tlb_flush(dev);
        }
 
        nvbe->bound = false;
@@ -224,7 +224,11 @@ nouveau_sgdma_init(struct drm_device *dev)
        int i, ret;
 
        if (dev_priv->card_type < NV_50) {
-               aper_size = (64 * 1024 * 1024);
+               if(dev_priv->ramin_rsvd_vram < 2 * 1024 * 1024)
+                       aper_size = 64 * 1024 * 1024;
+               else
+                       aper_size = 512 * 1024 * 1024;
+
                obj_size  = (aper_size >> NV_CTXDMA_PAGE_SHIFT) * 4;
                obj_size += 8; /* ctxdma header */
        } else {
index ed7757f14083a17e3122250ca83aa8ee2959ddec..049f755567e5c83b047298f74ff1c24b6ceea5fe 100644 (file)
@@ -354,6 +354,15 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->graph.destroy_context   = nv50_graph_destroy_context;
                engine->graph.load_context      = nv50_graph_load_context;
                engine->graph.unload_context    = nv50_graph_unload_context;
+               if (dev_priv->chipset != 0x86)
+                       engine->graph.tlb_flush = nv50_graph_tlb_flush;
+               else {
+                       /* from what i can see nvidia do this on every
+                        * pre-NVA3 board except NVAC, but, we've only
+                        * ever seen problems on NV86
+                        */
+                       engine->graph.tlb_flush = nv86_graph_tlb_flush;
+               }
                engine->fifo.channels           = 128;
                engine->fifo.init               = nv50_fifo_init;
                engine->fifo.takedown           = nv50_fifo_takedown;
@@ -365,6 +374,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->fifo.destroy_context    = nv50_fifo_destroy_context;
                engine->fifo.load_context       = nv50_fifo_load_context;
                engine->fifo.unload_context     = nv50_fifo_unload_context;
+               engine->fifo.tlb_flush          = nv50_fifo_tlb_flush;
                engine->display.early_init      = nv50_display_early_init;
                engine->display.late_takedown   = nv50_display_late_takedown;
                engine->display.create          = nv50_display_create;
@@ -1041,6 +1051,9 @@ int nouveau_ioctl_getparam(struct drm_device *dev, void *data,
        case NOUVEAU_GETPARAM_PTIMER_TIME:
                getparam->value = dev_priv->engine.timer.read(dev);
                break;
+       case NOUVEAU_GETPARAM_HAS_BO_USAGE:
+               getparam->value = 1;
+               break;
        case NOUVEAU_GETPARAM_GRAPH_UNITS:
                /* NV40 and NV50 versions are quite different, but register
                 * address is the same. User is supposed to know the card
@@ -1051,7 +1064,7 @@ int nouveau_ioctl_getparam(struct drm_device *dev, void *data,
                }
                /* FALLTHRU */
        default:
-               NV_ERROR(dev, "unknown parameter %lld\n", getparam->param);
+               NV_DEBUG(dev, "unknown parameter %lld\n", getparam->param);
                return -EINVAL;
        }
 
@@ -1066,7 +1079,7 @@ nouveau_ioctl_setparam(struct drm_device *dev, void *data,
 
        switch (setparam->param) {
        default:
-               NV_ERROR(dev, "unknown parameter %lld\n", setparam->param);
+               NV_DEBUG(dev, "unknown parameter %lld\n", setparam->param);
                return -EINVAL;
        }
 
index 16bbbf1eff63bc5ef37038e37d85fccc7f407a8d..7ecc4adc1e4575aca6ef2791752c25300ff7668b 100644 (file)
@@ -191,7 +191,7 @@ nv40_temp_get(struct drm_device *dev)
        int offset = sensor->offset_mult / sensor->offset_div;
        int core_temp;
 
-       if (dev_priv->chipset >= 0x50) {
+       if (dev_priv->card_type >= NV_50) {
                core_temp = nv_rd32(dev, 0x20008);
        } else {
                core_temp = nv_rd32(dev, 0x0015b4) & 0x1fff;
index c71abc2a34d5d9cf22a01d3c3bf455a29c5d1dbf..40e180741629e056f72445ffab06104760bd70ec 100644 (file)
@@ -158,7 +158,6 @@ nv_crtc_dpms(struct drm_crtc *crtc, int mode)
 {
        struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
        struct drm_device *dev = crtc->dev;
-       struct drm_connector *connector;
        unsigned char seq1 = 0, crtc17 = 0;
        unsigned char crtc1A;
 
@@ -213,10 +212,6 @@ nv_crtc_dpms(struct drm_crtc *crtc, int mode)
        NVVgaSeqReset(dev, nv_crtc->index, false);
 
        NVWriteVgaCrtc(dev, nv_crtc->index, NV_CIO_CRE_RPC1_INDEX, crtc1A);
-
-       /* Update connector polling modes */
-       list_for_each_entry(connector, &dev->mode_config.connector_list, head)
-               nouveau_connector_set_polling(connector);
 }
 
 static bool
@@ -831,7 +826,7 @@ nv04_crtc_do_mode_set_base(struct drm_crtc *crtc,
        /* Update the framebuffer location. */
        regp->fb_start = nv_crtc->fb.offset & ~3;
        regp->fb_start += (y * drm_fb->pitch) + (x * drm_fb->bits_per_pixel / 8);
-       NVWriteCRTC(dev, nv_crtc->index, NV_PCRTC_START, regp->fb_start);
+       nv_set_crtc_base(dev, nv_crtc->index, regp->fb_start);
 
        /* Update the arbitration parameters. */
        nouveau_calc_arb(dev, crtc->mode.clock, drm_fb->bits_per_pixel,
index c936403b26e22f7b4bcc1b4fee4fa6809498689b..ef23550407b5d7da95c0a4a5a6c35b82670ad4e5 100644 (file)
@@ -185,14 +185,15 @@ static bool nv04_dfp_mode_fixup(struct drm_encoder *encoder,
        struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
        struct nouveau_connector *nv_connector = nouveau_encoder_connector_get(nv_encoder);
 
-       /* For internal panels and gpu scaling on DVI we need the native mode */
-       if (nv_connector->scaling_mode != DRM_MODE_SCALE_NONE) {
-               if (!nv_connector->native_mode)
-                       return false;
+       if (!nv_connector->native_mode ||
+           nv_connector->scaling_mode == DRM_MODE_SCALE_NONE ||
+           mode->hdisplay > nv_connector->native_mode->hdisplay ||
+           mode->vdisplay > nv_connector->native_mode->vdisplay) {
+               nv_encoder->mode = *adjusted_mode;
+
+       } else {
                nv_encoder->mode = *nv_connector->native_mode;
                adjusted_mode->clock = nv_connector->native_mode->clock;
-       } else {
-               nv_encoder->mode = *adjusted_mode;
        }
 
        return true;
index 6a6eb697d38e0b387941b05b38dadc8a5bd371f1..eb1c70dd82ed41540629792dc7264452f511e6f3 100644 (file)
@@ -76,6 +76,15 @@ nv04_pm_clock_set(struct drm_device *dev, void *pre_state)
                reg += 4;
 
        nouveau_hw_setpll(dev, reg, &state->calc);
+
+       if (dev_priv->card_type < NV_30 && reg == NV_PRAMDAC_MPLL_COEFF) {
+               if (dev_priv->card_type == NV_20)
+                       nv_mask(dev, 0x1002c4, 0, 1 << 20);
+
+               /* Reset the DLLs */
+               nv_mask(dev, 0x1002c0, 0, 1 << 8);
+       }
+
        kfree(state);
 }
 
index 2cdc2bfe717924bf4f8e29237c11efcc0865408b..de81151648f831c5a7c97b9491d3670c356276f5 100644 (file)
@@ -51,24 +51,28 @@ nv50_calc_pll2(struct drm_device *dev, struct pll_lims *pll, int clk,
               int *N, int *fN, int *M, int *P)
 {
        fixed20_12 fb_div, a, b;
+       u32 refclk = pll->refclk / 10;
+       u32 max_vco_freq = pll->vco1.maxfreq / 10;
+       u32 max_vco_inputfreq = pll->vco1.max_inputfreq / 10;
+       clk /= 10;
 
-       *P = pll->vco1.maxfreq / clk;
+       *P = max_vco_freq / clk;
        if (*P > pll->max_p)
                *P = pll->max_p;
        if (*P < pll->min_p)
                *P = pll->min_p;
 
-       /* *M = ceil(refclk / pll->vco.max_inputfreq); */
-       a.full = dfixed_const(pll->refclk);
-       b.full = dfixed_const(pll->vco1.max_inputfreq);
+       /* *M = floor((refclk + max_vco_inputfreq) / max_vco_inputfreq); */
+       a.full = dfixed_const(refclk + max_vco_inputfreq);
+       b.full = dfixed_const(max_vco_inputfreq);
        a.full = dfixed_div(a, b);
-       a.full = dfixed_ceil(a);
+       a.full = dfixed_floor(a);
        *M = dfixed_trunc(a);
 
        /* fb_div = (vco * *M) / refclk; */
        fb_div.full = dfixed_const(clk * *P);
        fb_div.full = dfixed_mul(fb_div, a);
-       a.full = dfixed_const(pll->refclk);
+       a.full = dfixed_const(refclk);
        fb_div.full = dfixed_div(fb_div, a);
 
        /* *N = floor(fb_div); */
index 16380d52cd885599f349219c903f12cf7b9c6159..56476d0c6de8ee5255ff6c8916070a5c5ed86aec 100644 (file)
@@ -546,7 +546,7 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc,
        }
 
        nv_crtc->fb.offset = fb->nvbo->bo.offset - dev_priv->vm_vram_base;
-       nv_crtc->fb.tile_flags = fb->nvbo->tile_flags;
+       nv_crtc->fb.tile_flags = nouveau_bo_tile_layout(fb->nvbo);
        nv_crtc->fb.cpp = drm_fb->bits_per_pixel / 8;
        if (!nv_crtc->fb.blanked && dev_priv->chipset != 0x50) {
                ret = RING_SPACE(evo, 2);
@@ -578,7 +578,7 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc,
                                  fb->nvbo->tile_mode);
        }
        if (dev_priv->chipset == 0x50)
-               OUT_RING(evo, (fb->nvbo->tile_flags << 8) | format);
+               OUT_RING(evo, (nv_crtc->fb.tile_flags << 8) | format);
        else
                OUT_RING(evo, format);
 
index 55c9663ef2bf8ddd4df2cf15b452daed66abc583..f624c611ddeaf39cb1c46010d7da30e4461c35ad 100644 (file)
@@ -1032,11 +1032,18 @@ nv50_display_irq_hotplug_bh(struct work_struct *work)
        struct drm_connector *connector;
        const uint32_t gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 };
        uint32_t unplug_mask, plug_mask, change_mask;
-       uint32_t hpd0, hpd1 = 0;
+       uint32_t hpd0, hpd1;
 
-       hpd0 = nv_rd32(dev, 0xe054) & nv_rd32(dev, 0xe050);
+       spin_lock_irq(&dev_priv->hpd_state.lock);
+       hpd0 = dev_priv->hpd_state.hpd0_bits;
+       dev_priv->hpd_state.hpd0_bits = 0;
+       hpd1 = dev_priv->hpd_state.hpd1_bits;
+       dev_priv->hpd_state.hpd1_bits = 0;
+       spin_unlock_irq(&dev_priv->hpd_state.lock);
+
+       hpd0 &= nv_rd32(dev, 0xe050);
        if (dev_priv->chipset >= 0x90)
-               hpd1 = nv_rd32(dev, 0xe074) & nv_rd32(dev, 0xe070);
+               hpd1 &= nv_rd32(dev, 0xe070);
 
        plug_mask   = (hpd0 & 0x0000ffff) | (hpd1 << 16);
        unplug_mask = (hpd0 >> 16) | (hpd1 & 0xffff0000);
@@ -1078,10 +1085,6 @@ nv50_display_irq_hotplug_bh(struct work_struct *work)
                        helper->dpms(connector->encoder, DRM_MODE_DPMS_OFF);
        }
 
-       nv_wr32(dev, 0xe054, nv_rd32(dev, 0xe054));
-       if (dev_priv->chipset >= 0x90)
-               nv_wr32(dev, 0xe074, nv_rd32(dev, 0xe074));
-
        drm_helper_hpd_irq_event(dev);
 }
 
@@ -1092,8 +1095,22 @@ nv50_display_irq_handler(struct drm_device *dev)
        uint32_t delayed = 0;
 
        if (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_HOTPLUG) {
-               if (!work_pending(&dev_priv->hpd_work))
-                       queue_work(dev_priv->wq, &dev_priv->hpd_work);
+               uint32_t hpd0_bits, hpd1_bits = 0;
+
+               hpd0_bits = nv_rd32(dev, 0xe054);
+               nv_wr32(dev, 0xe054, hpd0_bits);
+
+               if (dev_priv->chipset >= 0x90) {
+                       hpd1_bits = nv_rd32(dev, 0xe074);
+                       nv_wr32(dev, 0xe074, hpd1_bits);
+               }
+
+               spin_lock(&dev_priv->hpd_state.lock);
+               dev_priv->hpd_state.hpd0_bits |= hpd0_bits;
+               dev_priv->hpd_state.hpd1_bits |= hpd1_bits;
+               spin_unlock(&dev_priv->hpd_state.lock);
+
+               queue_work(dev_priv->wq, &dev_priv->hpd_work);
        }
 
        while (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_DISPLAY) {
index a46a961102f39052832856cac762e3cfe8ae1f88..1da65bd60c109f89ea44e20a8eb561ec35a0f237 100644 (file)
@@ -464,3 +464,8 @@ nv50_fifo_unload_context(struct drm_device *dev)
        return 0;
 }
 
+void
+nv50_fifo_tlb_flush(struct drm_device *dev)
+{
+       nv50_vm_flush(dev, 5);
+}
index cbf5ae2f67d4a110de1bb9d9c129224fbcdd6c3c..8b669d0af6105fb934c3485457e7db18fb43e0ad 100644 (file)
@@ -402,3 +402,55 @@ struct nouveau_pgraph_object_class nv50_graph_grclass[] = {
        { 0x8597, false, NULL }, /* tesla (nva3, nva5, nva8) */
        {}
 };
+
+void
+nv50_graph_tlb_flush(struct drm_device *dev)
+{
+       nv50_vm_flush(dev, 0);
+}
+
+void
+nv86_graph_tlb_flush(struct drm_device *dev)
+{
+       struct drm_nouveau_private *dev_priv = dev->dev_private;
+       struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer;
+       bool idle, timeout = false;
+       unsigned long flags;
+       u64 start;
+       u32 tmp;
+
+       spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
+       nv_mask(dev, 0x400500, 0x00000001, 0x00000000);
+
+       start = ptimer->read(dev);
+       do {
+               idle = true;
+
+               for (tmp = nv_rd32(dev, 0x400380); tmp && idle; tmp >>= 3) {
+                       if ((tmp & 7) == 1)
+                               idle = false;
+               }
+
+               for (tmp = nv_rd32(dev, 0x400384); tmp && idle; tmp >>= 3) {
+                       if ((tmp & 7) == 1)
+                               idle = false;
+               }
+
+               for (tmp = nv_rd32(dev, 0x400388); tmp && idle; tmp >>= 3) {
+                       if ((tmp & 7) == 1)
+                               idle = false;
+               }
+       } while (!idle && !(timeout = ptimer->read(dev) - start > 2000000000));
+
+       if (timeout) {
+               NV_ERROR(dev, "PGRAPH TLB flush idle timeout fail: "
+                             "0x%08x 0x%08x 0x%08x 0x%08x\n",
+                        nv_rd32(dev, 0x400700), nv_rd32(dev, 0x400380),
+                        nv_rd32(dev, 0x400384), nv_rd32(dev, 0x400388));
+       }
+
+       nv50_vm_flush(dev, 0);
+
+       nv_mask(dev, 0x400500, 0x00000001, 0x00000001);
+       spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
+}
index a53fc974332b38ec659513e91a8421017e43c411..b773229b764793c1ee974462431ab5d9a4e57385 100644 (file)
@@ -402,7 +402,6 @@ nv50_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj)
        }
        dev_priv->engine.instmem.flush(dev);
 
-       nv50_vm_flush(dev, 4);
        nv50_vm_flush(dev, 6);
 
        gpuobj->im_bound = 1;
index 488c36c8f5e6069ebbb6cf5f9b830747a61c062e..4dc5b4714c5a6ae1919246ac55ed32d3bacc44ac 100644 (file)
@@ -1650,7 +1650,36 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
                }
        }
 
-       rdev->config.evergreen.tile_config = gb_addr_config;
+       /* setup tiling info dword.  gb_addr_config is not adequate since it does
+        * not have bank info, so create a custom tiling dword.
+        * bits 3:0   num_pipes
+        * bits 7:4   num_banks
+        * bits 11:8  group_size
+        * bits 15:12 row_size
+        */
+       rdev->config.evergreen.tile_config = 0;
+       switch (rdev->config.evergreen.max_tile_pipes) {
+       case 1:
+       default:
+               rdev->config.evergreen.tile_config |= (0 << 0);
+               break;
+       case 2:
+               rdev->config.evergreen.tile_config |= (1 << 0);
+               break;
+       case 4:
+               rdev->config.evergreen.tile_config |= (2 << 0);
+               break;
+       case 8:
+               rdev->config.evergreen.tile_config |= (3 << 0);
+               break;
+       }
+       rdev->config.evergreen.tile_config |=
+               ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) << 4;
+       rdev->config.evergreen.tile_config |=
+               ((mc_arb_ramcfg & BURSTLENGTH_MASK) >> BURSTLENGTH_SHIFT) << 8;
+       rdev->config.evergreen.tile_config |=
+               ((gb_addr_config & 0x30000000) >> 28) << 12;
+
        WREG32(GB_BACKEND_MAP, gb_backend_map);
        WREG32(GB_ADDR_CONFIG, gb_addr_config);
        WREG32(DMIF_ADDR_CONFIG, gb_addr_config);
index ac3b6dde23db7ca1fd5f80083436cb49fcce0312..e0e590110dd47ffb06b2161ed1058e731620c826 100644 (file)
@@ -459,7 +459,7 @@ int evergreen_blit_init(struct radeon_device *rdev)
        obj_size += evergreen_ps_size * 4;
        obj_size = ALIGN(obj_size, 256);
 
-       r = radeon_bo_create(rdev, NULL, obj_size, true, RADEON_GEM_DOMAIN_VRAM,
+       r = radeon_bo_create(rdev, NULL, obj_size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM,
                                &rdev->r600_blit.shader_obj);
        if (r) {
                DRM_ERROR("evergreen failed to allocate shader\n");
index 0f806cc7dc75f02f5bb00f98fc0d65b662aad688..a3552594ccc44c69b398980e539daf348d62322a 100644 (file)
@@ -2718,7 +2718,7 @@ static int r600_ih_ring_alloc(struct radeon_device *rdev)
        /* Allocate ring buffer */
        if (rdev->ih.ring_obj == NULL) {
                r = radeon_bo_create(rdev, NULL, rdev->ih.ring_size,
-                                    true,
+                                    PAGE_SIZE, true,
                                     RADEON_GEM_DOMAIN_GTT,
                                     &rdev->ih.ring_obj);
                if (r) {
index 8362974ef41ac9eac713f1e66377661aa7106c0b..86e5aa07f0db32ffe410f1c2dea0330fefd89d9d 100644 (file)
@@ -501,7 +501,7 @@ int r600_blit_init(struct radeon_device *rdev)
        obj_size += r6xx_ps_size * 4;
        obj_size = ALIGN(obj_size, 256);
 
-       r = radeon_bo_create(rdev, NULL, obj_size, true, RADEON_GEM_DOMAIN_VRAM,
+       r = radeon_bo_create(rdev, NULL, obj_size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM,
                                &rdev->r600_blit.shader_obj);
        if (r) {
                DRM_ERROR("r600 failed to allocate shader\n");
index 37cc2aa9f923cbace55e151d33870d1ac910a6a2..9bebac1ec006845f719b04cab125da2328c4d6bf 100644 (file)
@@ -50,6 +50,7 @@ struct r600_cs_track {
        u32                     nsamples;
        u32                     cb_color_base_last[8];
        struct radeon_bo        *cb_color_bo[8];
+       u64                     cb_color_bo_mc[8];
        u32                     cb_color_bo_offset[8];
        struct radeon_bo        *cb_color_frag_bo[8];
        struct radeon_bo        *cb_color_tile_bo[8];
@@ -67,6 +68,7 @@ struct r600_cs_track {
        u32                     db_depth_size;
        u32                     db_offset;
        struct radeon_bo        *db_bo;
+       u64                     db_bo_mc;
 };
 
 static inline int r600_bpe_from_format(u32 *bpe, u32 format)
@@ -140,6 +142,68 @@ static inline int r600_bpe_from_format(u32 *bpe, u32 format)
        return 0;
 }
 
+struct array_mode_checker {
+       int array_mode;
+       u32 group_size;
+       u32 nbanks;
+       u32 npipes;
+       u32 nsamples;
+       u32 bpe;
+};
+
+/* returns alignment in pixels for pitch/height/depth and bytes for base */
+static inline int r600_get_array_mode_alignment(struct array_mode_checker *values,
+                                               u32 *pitch_align,
+                                               u32 *height_align,
+                                               u32 *depth_align,
+                                               u64 *base_align)
+{
+       u32 tile_width = 8;
+       u32 tile_height = 8;
+       u32 macro_tile_width = values->nbanks;
+       u32 macro_tile_height = values->npipes;
+       u32 tile_bytes = tile_width * tile_height * values->bpe * values->nsamples;
+       u32 macro_tile_bytes = macro_tile_width * macro_tile_height * tile_bytes;
+
+       switch (values->array_mode) {
+       case ARRAY_LINEAR_GENERAL:
+               /* technically tile_width/_height for pitch/height */
+               *pitch_align = 1; /* tile_width */
+               *height_align = 1; /* tile_height */
+               *depth_align = 1;
+               *base_align = 1;
+               break;
+       case ARRAY_LINEAR_ALIGNED:
+               *pitch_align = max((u32)64, (u32)(values->group_size / values->bpe));
+               *height_align = tile_height;
+               *depth_align = 1;
+               *base_align = values->group_size;
+               break;
+       case ARRAY_1D_TILED_THIN1:
+               *pitch_align = max((u32)tile_width,
+                                  (u32)(values->group_size /
+                                        (tile_height * values->bpe * values->nsamples)));
+               *height_align = tile_height;
+               *depth_align = 1;
+               *base_align = values->group_size;
+               break;
+       case ARRAY_2D_TILED_THIN1:
+               *pitch_align = max((u32)macro_tile_width,
+                                 (u32)(((values->group_size / tile_height) /
+                                        (values->bpe * values->nsamples)) *
+                                       values->nbanks)) * tile_width;
+               *height_align = macro_tile_height * tile_height;
+               *depth_align = 1;
+               *base_align = max(macro_tile_bytes,
+                                 (*pitch_align) * values->bpe * (*height_align) * values->nsamples);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
 static void r600_cs_track_init(struct r600_cs_track *track)
 {
        int i;
@@ -153,10 +217,12 @@ static void r600_cs_track_init(struct r600_cs_track *track)
                track->cb_color_info[i] = 0;
                track->cb_color_bo[i] = NULL;
                track->cb_color_bo_offset[i] = 0xFFFFFFFF;
+               track->cb_color_bo_mc[i] = 0xFFFFFFFF;
        }
        track->cb_target_mask = 0xFFFFFFFF;
        track->cb_shader_mask = 0xFFFFFFFF;
        track->db_bo = NULL;
+       track->db_bo_mc = 0xFFFFFFFF;
        /* assume the biggest format and that htile is enabled */
        track->db_depth_info = 7 | (1 << 25);
        track->db_depth_view = 0xFFFFC000;
@@ -168,7 +234,10 @@ static void r600_cs_track_init(struct r600_cs_track *track)
 static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
 {
        struct r600_cs_track *track = p->track;
-       u32 bpe = 0, pitch, slice_tile_max, size, tmp, height, pitch_align;
+       u32 bpe = 0, slice_tile_max, size, tmp;
+       u32 height, height_align, pitch, pitch_align, depth_align;
+       u64 base_offset, base_align;
+       struct array_mode_checker array_check;
        volatile u32 *ib = p->ib->ptr;
        unsigned array_mode;
 
@@ -183,60 +252,40 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
                        i, track->cb_color_info[i]);
                return -EINVAL;
        }
-       /* pitch is the number of 8x8 tiles per row */
-       pitch = G_028060_PITCH_TILE_MAX(track->cb_color_size[i]) + 1;
+       /* pitch in pixels */
+       pitch = (G_028060_PITCH_TILE_MAX(track->cb_color_size[i]) + 1) * 8;
        slice_tile_max = G_028060_SLICE_TILE_MAX(track->cb_color_size[i]) + 1;
        slice_tile_max *= 64;
-       height = slice_tile_max / (pitch * 8);
+       height = slice_tile_max / pitch;
        if (height > 8192)
                height = 8192;
        array_mode = G_0280A0_ARRAY_MODE(track->cb_color_info[i]);
+
+       base_offset = track->cb_color_bo_mc[i] + track->cb_color_bo_offset[i];
+       array_check.array_mode = array_mode;
+       array_check.group_size = track->group_size;
+       array_check.nbanks = track->nbanks;
+       array_check.npipes = track->npipes;
+       array_check.nsamples = track->nsamples;
+       array_check.bpe = bpe;
+       if (r600_get_array_mode_alignment(&array_check,
+                                         &pitch_align, &height_align, &depth_align, &base_align)) {
+               dev_warn(p->dev, "%s invalid tiling %d for %d (0x%08X)\n", __func__,
+                        G_0280A0_ARRAY_MODE(track->cb_color_info[i]), i,
+                        track->cb_color_info[i]);
+               return -EINVAL;
+       }
        switch (array_mode) {
        case V_0280A0_ARRAY_LINEAR_GENERAL:
-               /* technically height & 0x7 */
                break;
        case V_0280A0_ARRAY_LINEAR_ALIGNED:
-               pitch_align = max((u32)64, (u32)(track->group_size / bpe)) / 8;
-               if (!IS_ALIGNED(pitch, pitch_align)) {
-                       dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n",
-                                __func__, __LINE__, pitch);
-                       return -EINVAL;
-               }
-               if (!IS_ALIGNED(height, 8)) {
-                       dev_warn(p->dev, "%s:%d cb height (%d) invalid\n",
-                                __func__, __LINE__, height);
-                       return -EINVAL;
-               }
                break;
        case V_0280A0_ARRAY_1D_TILED_THIN1:
-               pitch_align = max((u32)8, (u32)(track->group_size / (8 * bpe * track->nsamples))) / 8;
-               if (!IS_ALIGNED(pitch, pitch_align)) {
-                       dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n",
-                                __func__, __LINE__, pitch);
-                       return -EINVAL;
-               }
                /* avoid breaking userspace */
                if (height > 7)
                        height &= ~0x7;
-               if (!IS_ALIGNED(height, 8)) {
-                       dev_warn(p->dev, "%s:%d cb height (%d) invalid\n",
-                                __func__, __LINE__, height);
-                       return -EINVAL;
-               }
                break;
        case V_0280A0_ARRAY_2D_TILED_THIN1:
-               pitch_align = max((u32)track->nbanks,
-                                 (u32)(((track->group_size / 8) / (bpe * track->nsamples)) * track->nbanks)) / 8;
-               if (!IS_ALIGNED(pitch, pitch_align)) {
-                       dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n",
-                               __func__, __LINE__, pitch);
-                       return -EINVAL;
-               }
-               if (!IS_ALIGNED((height / 8), track->npipes)) {
-                       dev_warn(p->dev, "%s:%d cb height (%d) invalid\n",
-                                __func__, __LINE__, height);
-                       return -EINVAL;
-               }
                break;
        default:
                dev_warn(p->dev, "%s invalid tiling %d for %d (0x%08X)\n", __func__,
@@ -244,13 +293,29 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
                        track->cb_color_info[i]);
                return -EINVAL;
        }
+
+       if (!IS_ALIGNED(pitch, pitch_align)) {
+               dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n",
+                        __func__, __LINE__, pitch);
+               return -EINVAL;
+       }
+       if (!IS_ALIGNED(height, height_align)) {
+               dev_warn(p->dev, "%s:%d cb height (%d) invalid\n",
+                        __func__, __LINE__, height);
+               return -EINVAL;
+       }
+       if (!IS_ALIGNED(base_offset, base_align)) {
+               dev_warn(p->dev, "%s offset[%d] 0x%llx not aligned\n", __func__, i, base_offset);
+               return -EINVAL;
+       }
+
        /* check offset */
-       tmp = height * pitch * 8 * bpe;
+       tmp = height * pitch * bpe;
        if ((tmp + track->cb_color_bo_offset[i]) > radeon_bo_size(track->cb_color_bo[i])) {
                if (array_mode == V_0280A0_ARRAY_LINEAR_GENERAL) {
                        /* the initial DDX does bad things with the CB size occasionally */
                        /* it rounds up height too far for slice tile max but the BO is smaller */
-                       tmp = (height - 7) * 8 * bpe;
+                       tmp = (height - 7) * pitch * bpe;
                        if ((tmp + track->cb_color_bo_offset[i]) > radeon_bo_size(track->cb_color_bo[i])) {
                                dev_warn(p->dev, "%s offset[%d] %d %d %lu too big\n", __func__, i, track->cb_color_bo_offset[i], tmp, radeon_bo_size(track->cb_color_bo[i]));
                                return -EINVAL;
@@ -260,15 +325,11 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
                        return -EINVAL;
                }
        }
-       if (!IS_ALIGNED(track->cb_color_bo_offset[i], track->group_size)) {
-               dev_warn(p->dev, "%s offset[%d] %d not aligned\n", __func__, i, track->cb_color_bo_offset[i]);
-               return -EINVAL;
-       }
        /* limit max tile */
-       tmp = (height * pitch * 8) >> 6;
+       tmp = (height * pitch) >> 6;
        if (tmp < slice_tile_max)
                slice_tile_max = tmp;
-       tmp = S_028060_PITCH_TILE_MAX(pitch - 1) |
+       tmp = S_028060_PITCH_TILE_MAX((pitch / 8) - 1) |
                S_028060_SLICE_TILE_MAX(slice_tile_max - 1);
        ib[track->cb_color_size_idx[i]] = tmp;
        return 0;
@@ -310,7 +371,12 @@ static int r600_cs_track_check(struct radeon_cs_parser *p)
        /* Check depth buffer */
        if (G_028800_STENCIL_ENABLE(track->db_depth_control) ||
                G_028800_Z_ENABLE(track->db_depth_control)) {
-               u32 nviews, bpe, ntiles, pitch, pitch_align, height, size, slice_tile_max;
+               u32 nviews, bpe, ntiles, size, slice_tile_max;
+               u32 height, height_align, pitch, pitch_align, depth_align;
+               u64 base_offset, base_align;
+               struct array_mode_checker array_check;
+               int array_mode;
+
                if (track->db_bo == NULL) {
                        dev_warn(p->dev, "z/stencil with no depth buffer\n");
                        return -EINVAL;
@@ -353,41 +419,34 @@ static int r600_cs_track_check(struct radeon_cs_parser *p)
                        ib[track->db_depth_size_idx] = S_028000_SLICE_TILE_MAX(tmp - 1) | (track->db_depth_size & 0x3FF);
                } else {
                        size = radeon_bo_size(track->db_bo);
-                       pitch = G_028000_PITCH_TILE_MAX(track->db_depth_size) + 1;
+                       /* pitch in pixels */
+                       pitch = (G_028000_PITCH_TILE_MAX(track->db_depth_size) + 1) * 8;
                        slice_tile_max = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1;
                        slice_tile_max *= 64;
-                       height = slice_tile_max / (pitch * 8);
+                       height = slice_tile_max / pitch;
                        if (height > 8192)
                                height = 8192;
-                       switch (G_028010_ARRAY_MODE(track->db_depth_info)) {
+                       base_offset = track->db_bo_mc + track->db_offset;
+                       array_mode = G_028010_ARRAY_MODE(track->db_depth_info);
+                       array_check.array_mode = array_mode;
+                       array_check.group_size = track->group_size;
+                       array_check.nbanks = track->nbanks;
+                       array_check.npipes = track->npipes;
+                       array_check.nsamples = track->nsamples;
+                       array_check.bpe = bpe;
+                       if (r600_get_array_mode_alignment(&array_check,
+                                                         &pitch_align, &height_align, &depth_align, &base_align)) {
+                               dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__,
+                                        G_028010_ARRAY_MODE(track->db_depth_info),
+                                        track->db_depth_info);
+                               return -EINVAL;
+                       }
+                       switch (array_mode) {
                        case V_028010_ARRAY_1D_TILED_THIN1:
-                               pitch_align = (max((u32)8, (u32)(track->group_size / (8 * bpe))) / 8);
-                               if (!IS_ALIGNED(pitch, pitch_align)) {
-                                       dev_warn(p->dev, "%s:%d db pitch (%d) invalid\n",
-                                                __func__, __LINE__, pitch);
-                                       return -EINVAL;
-                               }
                                /* don't break userspace */
                                height &= ~0x7;
-                               if (!IS_ALIGNED(height, 8)) {
-                                       dev_warn(p->dev, "%s:%d db height (%d) invalid\n",
-                                                __func__, __LINE__, height);
-                                       return -EINVAL;
-                               }
                                break;
                        case V_028010_ARRAY_2D_TILED_THIN1:
-                               pitch_align = max((u32)track->nbanks,
-                                                 (u32)(((track->group_size / 8) / bpe) * track->nbanks)) / 8;
-                               if (!IS_ALIGNED(pitch, pitch_align)) {
-                                       dev_warn(p->dev, "%s:%d db pitch (%d) invalid\n",
-                                                __func__, __LINE__, pitch);
-                                       return -EINVAL;
-                               }
-                               if (!IS_ALIGNED((height / 8), track->npipes)) {
-                                       dev_warn(p->dev, "%s:%d db height (%d) invalid\n",
-                                                __func__, __LINE__, height);
-                                       return -EINVAL;
-                               }
                                break;
                        default:
                                dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__,
@@ -395,15 +454,27 @@ static int r600_cs_track_check(struct radeon_cs_parser *p)
                                         track->db_depth_info);
                                return -EINVAL;
                        }
-                       if (!IS_ALIGNED(track->db_offset, track->group_size)) {
-                               dev_warn(p->dev, "%s offset[%d] %d not aligned\n", __func__, i, track->db_offset);
+
+                       if (!IS_ALIGNED(pitch, pitch_align)) {
+                               dev_warn(p->dev, "%s:%d db pitch (%d) invalid\n",
+                                        __func__, __LINE__, pitch);
+                               return -EINVAL;
+                       }
+                       if (!IS_ALIGNED(height, height_align)) {
+                               dev_warn(p->dev, "%s:%d db height (%d) invalid\n",
+                                        __func__, __LINE__, height);
                                return -EINVAL;
                        }
+                       if (!IS_ALIGNED(base_offset, base_align)) {
+                               dev_warn(p->dev, "%s offset[%d] 0x%llx not aligned\n", __func__, i, base_offset);
+                               return -EINVAL;
+                       }
+
                        ntiles = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1;
                        nviews = G_028004_SLICE_MAX(track->db_depth_view) + 1;
                        tmp = ntiles * bpe * 64 * nviews;
                        if ((tmp + track->db_offset) > radeon_bo_size(track->db_bo)) {
-                               dev_warn(p->dev, "z/stencil buffer too small (0x%08X %d %d %d -> %d have %ld)\n",
+                               dev_warn(p->dev, "z/stencil buffer too small (0x%08X %d %d %d -> %u have %lu)\n",
                                                track->db_depth_size, ntiles, nviews, bpe, tmp + track->db_offset,
                                                radeon_bo_size(track->db_bo));
                                return -EINVAL;
@@ -954,6 +1025,7 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx
                ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
                track->cb_color_base_last[tmp] = ib[idx];
                track->cb_color_bo[tmp] = reloc->robj;
+               track->cb_color_bo_mc[tmp] = reloc->lobj.gpu_offset;
                break;
        case DB_DEPTH_BASE:
                r = r600_cs_packet_next_reloc(p, &reloc);
@@ -965,6 +1037,7 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx
                track->db_offset = radeon_get_ib_value(p, idx) << 8;
                ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
                track->db_bo = reloc->robj;
+               track->db_bo_mc = reloc->lobj.gpu_offset;
                break;
        case DB_HTILE_DATA_BASE:
        case SQ_PGM_START_FS:
@@ -1086,16 +1159,25 @@ static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned nlevels
 static inline int r600_check_texture_resource(struct radeon_cs_parser *p,  u32 idx,
                                              struct radeon_bo *texture,
                                              struct radeon_bo *mipmap,
+                                             u64 base_offset,
+                                             u64 mip_offset,
                                              u32 tiling_flags)
 {
        struct r600_cs_track *track = p->track;
        u32 nfaces, nlevels, blevel, w0, h0, d0, bpe = 0;
-       u32 word0, word1, l0_size, mipmap_size, pitch, pitch_align;
+       u32 word0, word1, l0_size, mipmap_size;
+       u32 height_align, pitch, pitch_align, depth_align;
+       u64 base_align;
+       struct array_mode_checker array_check;
 
        /* on legacy kernel we don't perform advanced check */
        if (p->rdev == NULL)
                return 0;
 
+       /* convert to bytes */
+       base_offset <<= 8;
+       mip_offset <<= 8;
+
        word0 = radeon_get_ib_value(p, idx + 0);
        if (tiling_flags & RADEON_TILING_MACRO)
                word0 |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1);
@@ -1128,46 +1210,38 @@ static inline int r600_check_texture_resource(struct radeon_cs_parser *p,  u32 i
                return -EINVAL;
        }
 
-       pitch = G_038000_PITCH(word0) + 1;
-       switch (G_038000_TILE_MODE(word0)) {
-       case V_038000_ARRAY_LINEAR_GENERAL:
-               pitch_align = 1;
-               /* XXX check height align */
-               break;
-       case V_038000_ARRAY_LINEAR_ALIGNED:
-               pitch_align = max((u32)64, (u32)(track->group_size / bpe)) / 8;
-               if (!IS_ALIGNED(pitch, pitch_align)) {
-                       dev_warn(p->dev, "%s:%d tex pitch (%d) invalid\n",
-                                __func__, __LINE__, pitch);
-                       return -EINVAL;
-               }
-               /* XXX check height align */
-               break;
-       case V_038000_ARRAY_1D_TILED_THIN1:
-               pitch_align = max((u32)8, (u32)(track->group_size / (8 * bpe))) / 8;
-               if (!IS_ALIGNED(pitch, pitch_align)) {
-                       dev_warn(p->dev, "%s:%d tex pitch (%d) invalid\n",
-                                __func__, __LINE__, pitch);
-                       return -EINVAL;
-               }
-               /* XXX check height align */
-               break;
-       case V_038000_ARRAY_2D_TILED_THIN1:
-               pitch_align = max((u32)track->nbanks,
-                                 (u32)(((track->group_size / 8) / bpe) * track->nbanks)) / 8;
-               if (!IS_ALIGNED(pitch, pitch_align)) {
-                       dev_warn(p->dev, "%s:%d tex pitch (%d) invalid\n",
-                               __func__, __LINE__, pitch);
-                       return -EINVAL;
-               }
-               /* XXX check height align */
-               break;
-       default:
-               dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__,
-                        G_038000_TILE_MODE(word0), word0);
+       /* pitch in texels */
+       pitch = (G_038000_PITCH(word0) + 1) * 8;
+       array_check.array_mode = G_038000_TILE_MODE(word0);
+       array_check.group_size = track->group_size;
+       array_check.nbanks = track->nbanks;
+       array_check.npipes = track->npipes;
+       array_check.nsamples = 1;
+       array_check.bpe = bpe;
+       if (r600_get_array_mode_alignment(&array_check,
+                                         &pitch_align, &height_align, &depth_align, &base_align)) {
+               dev_warn(p->dev, "%s:%d tex array mode (%d) invalid\n",
+                        __func__, __LINE__, G_038000_TILE_MODE(word0));
+               return -EINVAL;
+       }
+
+       /* XXX check height as well... */
+
+       if (!IS_ALIGNED(pitch, pitch_align)) {
+               dev_warn(p->dev, "%s:%d tex pitch (%d) invalid\n",
+                        __func__, __LINE__, pitch);
+               return -EINVAL;
+       }
+       if (!IS_ALIGNED(base_offset, base_align)) {
+               dev_warn(p->dev, "%s:%d tex base offset (0x%llx) invalid\n",
+                        __func__, __LINE__, base_offset);
+               return -EINVAL;
+       }
+       if (!IS_ALIGNED(mip_offset, base_align)) {
+               dev_warn(p->dev, "%s:%d tex mip offset (0x%llx) invalid\n",
+                        __func__, __LINE__, mip_offset);
                return -EINVAL;
        }
-       /* XXX check offset align */
 
        word0 = radeon_get_ib_value(p, idx + 4);
        word1 = radeon_get_ib_value(p, idx + 5);
@@ -1402,7 +1476,10 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
                                mip_offset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
                                mipmap = reloc->robj;
                                r = r600_check_texture_resource(p,  idx+(i*7)+1,
-                                                               texture, mipmap, reloc->lobj.tiling_flags);
+                                                               texture, mipmap,
+                                                               base_offset + radeon_get_ib_value(p, idx+1+(i*7)+2),
+                                                               mip_offset + radeon_get_ib_value(p, idx+1+(i*7)+3),
+                                                               reloc->lobj.tiling_flags);
                                if (r)
                                        return r;
                                ib[idx+1+(i*7)+2] += base_offset;
index 966a793e225b79a5bfdf3f8bf4c1f413ee2b3dc5..bff4dc4f410f8d5b514539c8ffecd914436a7f90 100644 (file)
 #define PTE_READABLE                           (1 << 5)
 #define PTE_WRITEABLE                          (1 << 6)
 
+/* tiling bits */
+#define     ARRAY_LINEAR_GENERAL              0x00000000
+#define     ARRAY_LINEAR_ALIGNED              0x00000001
+#define     ARRAY_1D_TILED_THIN1              0x00000002
+#define     ARRAY_2D_TILED_THIN1              0x00000004
+
 /* Registers */
 #define        ARB_POP                                         0x2418
 #define        ENABLE_TC128                                    (1 << 30)
index 73f600d39ad4bb79c4dfdeddee97972a8caeaec0..3a7095743d441b1bf71da544bd0f19007408362c 100644 (file)
@@ -1262,6 +1262,10 @@ void r100_pll_errata_after_index(struct radeon_device *rdev);
                (rdev->family == CHIP_RS400) ||                 \
                (rdev->family == CHIP_RS480))
 #define ASIC_IS_AVIVO(rdev) ((rdev->family >= CHIP_RS600))
+#define ASIC_IS_DCE2(rdev) ((rdev->family == CHIP_RS600)  ||   \
+                           (rdev->family == CHIP_RS690)  ||    \
+                           (rdev->family == CHIP_RS740)  ||    \
+                           (rdev->family >= CHIP_R600))
 #define ASIC_IS_DCE3(rdev) ((rdev->family >= CHIP_RV620))
 #define ASIC_IS_DCE32(rdev) ((rdev->family >= CHIP_RV730))
 #define ASIC_IS_DCE4(rdev) ((rdev->family >= CHIP_CEDAR))
index 7932dc4d6b90bde396e258108247402ec90ce8ca..c558685cc637698a83fb7ceed220df897f988b44 100644 (file)
@@ -41,7 +41,7 @@ void radeon_benchmark_move(struct radeon_device *rdev, unsigned bsize,
 
        size = bsize;
        n = 1024;
-       r = radeon_bo_create(rdev, NULL, size, true, sdomain, &sobj);
+       r = radeon_bo_create(rdev, NULL, size, PAGE_SIZE, true, sdomain, &sobj);
        if (r) {
                goto out_cleanup;
        }
@@ -53,7 +53,7 @@ void radeon_benchmark_move(struct radeon_device *rdev, unsigned bsize,
        if (r) {
                goto out_cleanup;
        }
-       r = radeon_bo_create(rdev, NULL, size, true, ddomain, &dobj);
+       r = radeon_bo_create(rdev, NULL, size, PAGE_SIZE, true, ddomain, &dobj);
        if (r) {
                goto out_cleanup;
        }
index 7b7ea269549ccef95c1e6c343083071774e7e9de..3bddea5b52956fbd9881193bac47827a7024ebe4 100644 (file)
@@ -571,6 +571,7 @@ static struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rde
        }
 
        if (clk_mask && data_mask) {
+               /* system specific masks */
                i2c.mask_clk_mask = clk_mask;
                i2c.mask_data_mask = data_mask;
                i2c.a_clk_mask = clk_mask;
@@ -579,7 +580,19 @@ static struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rde
                i2c.en_data_mask = data_mask;
                i2c.y_clk_mask = clk_mask;
                i2c.y_data_mask = data_mask;
+       } else if ((ddc_line == RADEON_GPIOPAD_MASK) ||
+                  (ddc_line == RADEON_MDGPIO_MASK)) {
+               /* default gpiopad masks */
+               i2c.mask_clk_mask = (0x20 << 8);
+               i2c.mask_data_mask = 0x80;
+               i2c.a_clk_mask = (0x20 << 8);
+               i2c.a_data_mask = 0x80;
+               i2c.en_clk_mask = (0x20 << 8);
+               i2c.en_data_mask = 0x80;
+               i2c.y_clk_mask = (0x20 << 8);
+               i2c.y_data_mask = 0x80;
        } else {
+               /* default masks for ddc pads */
                i2c.mask_clk_mask = RADEON_GPIO_EN_1;
                i2c.mask_data_mask = RADEON_GPIO_EN_0;
                i2c.a_clk_mask = RADEON_GPIO_A_1;
index fe6c74780f18e67bb55ea5fdeefdbb038ffadbf1..3bef9f6d66fd01299efdc62b0581c18f96ca108f 100644 (file)
@@ -1008,9 +1008,21 @@ static void radeon_dp_connector_destroy(struct drm_connector *connector)
 static int radeon_dp_get_modes(struct drm_connector *connector)
 {
        struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+       struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv;
        int ret;
 
+       if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
+               if (!radeon_dig_connector->edp_on)
+                       atombios_set_edp_panel_power(connector,
+                                                    ATOM_TRANSMITTER_ACTION_POWER_ON);
+       }
        ret = radeon_ddc_get_modes(radeon_connector);
+       if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
+               if (!radeon_dig_connector->edp_on)
+                       atombios_set_edp_panel_power(connector,
+                                                    ATOM_TRANSMITTER_ACTION_POWER_OFF);
+       }
+
        return ret;
 }
 
@@ -1029,8 +1041,14 @@ radeon_dp_detect(struct drm_connector *connector, bool force)
        if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
                /* eDP is always DP */
                radeon_dig_connector->dp_sink_type = CONNECTOR_OBJECT_ID_DISPLAYPORT;
+               if (!radeon_dig_connector->edp_on)
+                       atombios_set_edp_panel_power(connector,
+                                                    ATOM_TRANSMITTER_ACTION_POWER_ON);
                if (radeon_dp_getdpcd(radeon_connector))
                        ret = connector_status_connected;
+               if (!radeon_dig_connector->edp_on)
+                       atombios_set_edp_panel_power(connector,
+                                                    ATOM_TRANSMITTER_ACTION_POWER_OFF);
        } else {
                radeon_dig_connector->dp_sink_type = radeon_dp_getsinktype(radeon_connector);
                if (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) {
index 8adfedfe547f6b6455676deaa26dada2592ff6a5..d8ac1849180d5af379d5fe024057447c922d326f 100644 (file)
@@ -180,7 +180,7 @@ int radeon_wb_init(struct radeon_device *rdev)
        int r;
 
        if (rdev->wb.wb_obj == NULL) {
-               r = radeon_bo_create(rdev, NULL, RADEON_GPU_PAGE_SIZE, true,
+               r = radeon_bo_create(rdev, NULL, RADEON_GPU_PAGE_SIZE, PAGE_SIZE, true,
                                RADEON_GEM_DOMAIN_GTT, &rdev->wb.wb_obj);
                if (r) {
                        dev_warn(rdev->dev, "(%d) create WB bo failed\n", r);
index f678257c42e6ab54f668951b93e685cf04d287d5..041943df966be15803ebedc2e5291fa00953745e 100644 (file)
@@ -176,6 +176,7 @@ static inline bool radeon_encoder_is_digital(struct drm_encoder *encoder)
                return false;
        }
 }
+
 void
 radeon_link_encoder_connector(struct drm_device *dev)
 {
@@ -228,6 +229,27 @@ radeon_get_connector_for_encoder(struct drm_encoder *encoder)
        return NULL;
 }
 
+struct drm_encoder *radeon_atom_get_external_encoder(struct drm_encoder *encoder)
+{
+       struct drm_device *dev = encoder->dev;
+       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       struct drm_encoder *other_encoder;
+       struct radeon_encoder *other_radeon_encoder;
+
+       if (radeon_encoder->is_ext_encoder)
+               return NULL;
+
+       list_for_each_entry(other_encoder, &dev->mode_config.encoder_list, head) {
+               if (other_encoder == encoder)
+                       continue;
+               other_radeon_encoder = to_radeon_encoder(other_encoder);
+               if (other_radeon_encoder->is_ext_encoder &&
+                   (radeon_encoder->devices & other_radeon_encoder->devices))
+                       return other_encoder;
+       }
+       return NULL;
+}
+
 void radeon_panel_mode_fixup(struct drm_encoder *encoder,
                             struct drm_display_mode *adjusted_mode)
 {
@@ -426,52 +448,49 @@ atombios_tv_setup(struct drm_encoder *encoder, int action)
 
 }
 
-void
-atombios_external_tmds_setup(struct drm_encoder *encoder, int action)
-{
-       struct drm_device *dev = encoder->dev;
-       struct radeon_device *rdev = dev->dev_private;
-       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-       ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION args;
-       int index = 0;
-
-       memset(&args, 0, sizeof(args));
-
-       index = GetIndexIntoMasterTable(COMMAND, DVOEncoderControl);
-
-       args.sXTmdsEncoder.ucEnable = action;
-
-       if (radeon_encoder->pixel_clock > 165000)
-               args.sXTmdsEncoder.ucMisc = PANEL_ENCODER_MISC_DUAL;
-
-       /*if (pScrn->rgbBits == 8)*/
-       args.sXTmdsEncoder.ucMisc |= (1 << 1);
-
-       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
-
-}
+union dvo_encoder_control {
+       ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION ext_tmds;
+       DVO_ENCODER_CONTROL_PS_ALLOCATION dvo;
+       DVO_ENCODER_CONTROL_PS_ALLOCATION_V3 dvo_v3;
+};
 
-static void
-atombios_ddia_setup(struct drm_encoder *encoder, int action)
+void
+atombios_dvo_setup(struct drm_encoder *encoder, int action)
 {
        struct drm_device *dev = encoder->dev;
        struct radeon_device *rdev = dev->dev_private;
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-       DVO_ENCODER_CONTROL_PS_ALLOCATION args;
-       int index = 0;
+       union dvo_encoder_control args;
+       int index = GetIndexIntoMasterTable(COMMAND, DVOEncoderControl);
 
        memset(&args, 0, sizeof(args));
 
-       index = GetIndexIntoMasterTable(COMMAND, DVOEncoderControl);
+       if (ASIC_IS_DCE3(rdev)) {
+               /* DCE3+ */
+               args.dvo_v3.ucAction = action;
+               args.dvo_v3.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
+               args.dvo_v3.ucDVOConfig = 0; /* XXX */
+       } else if (ASIC_IS_DCE2(rdev)) {
+               /* DCE2 (pre-DCE3 R6xx, RS600/690/740 */
+               args.dvo.sDVOEncoder.ucAction = action;
+               args.dvo.sDVOEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
+               /* DFP1, CRT1, TV1 depending on the type of port */
+               args.dvo.sDVOEncoder.ucDeviceType = ATOM_DEVICE_DFP1_INDEX;
+
+               if (radeon_encoder->pixel_clock > 165000)
+                       args.dvo.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute |= PANEL_ENCODER_MISC_DUAL;
+       } else {
+               /* R4xx, R5xx */
+               args.ext_tmds.sXTmdsEncoder.ucEnable = action;
 
-       args.sDVOEncoder.ucAction = action;
-       args.sDVOEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
+               if (radeon_encoder->pixel_clock > 165000)
+                       args.ext_tmds.sXTmdsEncoder.ucMisc |= PANEL_ENCODER_MISC_DUAL;
 
-       if (radeon_encoder->pixel_clock > 165000)
-               args.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute = PANEL_ENCODER_MISC_DUAL;
+               /*if (pScrn->rgbBits == 8)*/
+               args.ext_tmds.sXTmdsEncoder.ucMisc |= ATOM_PANEL_MISC_888RGB;
+       }
 
        atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
-
 }
 
 union lvds_encoder_control {
@@ -532,14 +551,14 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
                                if (dig->lcd_misc & ATOM_PANEL_MISC_DUAL)
                                        args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL;
                                if (dig->lcd_misc & ATOM_PANEL_MISC_888RGB)
-                                       args.v1.ucMisc |= (1 << 1);
+                                       args.v1.ucMisc |= ATOM_PANEL_MISC_888RGB;
                        } else {
                                if (dig->linkb)
                                        args.v1.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB;
                                if (radeon_encoder->pixel_clock > 165000)
                                        args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL;
                                /*if (pScrn->rgbBits == 8) */
-                               args.v1.ucMisc |= (1 << 1);
+                               args.v1.ucMisc |= ATOM_PANEL_MISC_888RGB;
                        }
                        break;
                case 2:
@@ -595,6 +614,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
 int
 atombios_get_encoder_mode(struct drm_encoder *encoder)
 {
+       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
        struct drm_device *dev = encoder->dev;
        struct radeon_device *rdev = dev->dev_private;
        struct drm_connector *connector;
@@ -602,9 +622,20 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
        struct radeon_connector_atom_dig *dig_connector;
 
        connector = radeon_get_connector_for_encoder(encoder);
-       if (!connector)
-               return 0;
-
+       if (!connector) {
+               switch (radeon_encoder->encoder_id) {
+               case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
+               case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
+               case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+               case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
+               case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
+                       return ATOM_ENCODER_MODE_DVI;
+               case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
+               case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
+               default:
+                       return ATOM_ENCODER_MODE_CRT;
+               }
+       }
        radeon_connector = to_radeon_connector(connector);
 
        switch (connector->connector_type) {
@@ -834,6 +865,9 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
        memset(&args, 0, sizeof(args));
 
        switch (radeon_encoder->encoder_id) {
+       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
+               index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl);
+               break;
        case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
        case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
        case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
@@ -978,6 +1012,105 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
        atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 }
 
+void
+atombios_set_edp_panel_power(struct drm_connector *connector, int action)
+{
+       struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+       struct drm_device *dev = radeon_connector->base.dev;
+       struct radeon_device *rdev = dev->dev_private;
+       union dig_transmitter_control args;
+       int index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl);
+       uint8_t frev, crev;
+
+       if (connector->connector_type != DRM_MODE_CONNECTOR_eDP)
+               return;
+
+       if (!ASIC_IS_DCE4(rdev))
+               return;
+
+       if ((action != ATOM_TRANSMITTER_ACTION_POWER_ON) ||
+           (action != ATOM_TRANSMITTER_ACTION_POWER_OFF))
+               return;
+
+       if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
+               return;
+
+       memset(&args, 0, sizeof(args));
+
+       args.v1.ucAction = action;
+
+       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+}
+
+union external_encoder_control {
+       EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION v1;
+};
+
+static void
+atombios_external_encoder_setup(struct drm_encoder *encoder,
+                               struct drm_encoder *ext_encoder,
+                               int action)
+{
+       struct drm_device *dev = encoder->dev;
+       struct radeon_device *rdev = dev->dev_private;
+       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       union external_encoder_control args;
+       struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
+       int index = GetIndexIntoMasterTable(COMMAND, ExternalEncoderControl);
+       u8 frev, crev;
+       int dp_clock = 0;
+       int dp_lane_count = 0;
+       int connector_object_id = 0;
+
+       if (connector) {
+               struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+               struct radeon_connector_atom_dig *dig_connector =
+                       radeon_connector->con_priv;
+
+               dp_clock = dig_connector->dp_clock;
+               dp_lane_count = dig_connector->dp_lane_count;
+               connector_object_id =
+                       (radeon_connector->connector_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;
+       }
+
+       memset(&args, 0, sizeof(args));
+
+       if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
+               return;
+
+       switch (frev) {
+       case 1:
+               /* no params on frev 1 */
+               break;
+       case 2:
+               switch (crev) {
+               case 1:
+               case 2:
+                       args.v1.sDigEncoder.ucAction = action;
+                       args.v1.sDigEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
+                       args.v1.sDigEncoder.ucEncoderMode = atombios_get_encoder_mode(encoder);
+
+                       if (args.v1.sDigEncoder.ucEncoderMode == ATOM_ENCODER_MODE_DP) {
+                               if (dp_clock == 270000)
+                                       args.v1.sDigEncoder.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ;
+                               args.v1.sDigEncoder.ucLaneNum = dp_lane_count;
+                       } else if (radeon_encoder->pixel_clock > 165000)
+                               args.v1.sDigEncoder.ucLaneNum = 8;
+                       else
+                               args.v1.sDigEncoder.ucLaneNum = 4;
+                       break;
+               default:
+                       DRM_ERROR("Unknown table version: %d, %d\n", frev, crev);
+                       return;
+               }
+               break;
+       default:
+               DRM_ERROR("Unknown table version: %d, %d\n", frev, crev);
+               return;
+       }
+       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+}
+
 static void
 atombios_yuv_setup(struct drm_encoder *encoder, bool enable)
 {
@@ -1021,6 +1154,7 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
        struct drm_device *dev = encoder->dev;
        struct radeon_device *rdev = dev->dev_private;
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       struct drm_encoder *ext_encoder = radeon_atom_get_external_encoder(encoder);
        DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION args;
        int index = 0;
        bool is_dig = false;
@@ -1043,9 +1177,14 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
                break;
        case ENCODER_OBJECT_ID_INTERNAL_DVO1:
        case ENCODER_OBJECT_ID_INTERNAL_DDI:
-       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
                index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl);
                break;
+       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
+               if (ASIC_IS_DCE3(rdev))
+                       is_dig = true;
+               else
+                       index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl);
+               break;
        case ENCODER_OBJECT_ID_INTERNAL_LVDS:
                index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl);
                break;
@@ -1082,34 +1221,85 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
                        if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) {
                                struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
 
+                               if (connector &&
+                                   (connector->connector_type == DRM_MODE_CONNECTOR_eDP)) {
+                                       struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+                                       struct radeon_connector_atom_dig *radeon_dig_connector =
+                                               radeon_connector->con_priv;
+                                       atombios_set_edp_panel_power(connector,
+                                                                    ATOM_TRANSMITTER_ACTION_POWER_ON);
+                                       radeon_dig_connector->edp_on = true;
+                               }
                                dp_link_train(encoder, connector);
                                if (ASIC_IS_DCE4(rdev))
                                        atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON);
                        }
+                       if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
+                               atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLON, 0, 0);
                        break;
                case DRM_MODE_DPMS_STANDBY:
                case DRM_MODE_DPMS_SUSPEND:
                case DRM_MODE_DPMS_OFF:
                        atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0);
                        if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) {
+                               struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
+
                                if (ASIC_IS_DCE4(rdev))
                                        atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF);
+                               if (connector &&
+                                   (connector->connector_type == DRM_MODE_CONNECTOR_eDP)) {
+                                       struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+                                       struct radeon_connector_atom_dig *radeon_dig_connector =
+                                               radeon_connector->con_priv;
+                                       atombios_set_edp_panel_power(connector,
+                                                                    ATOM_TRANSMITTER_ACTION_POWER_OFF);
+                                       radeon_dig_connector->edp_on = false;
+                               }
                        }
+                       if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
+                               atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLOFF, 0, 0);
                        break;
                }
        } else {
                switch (mode) {
                case DRM_MODE_DPMS_ON:
                        args.ucAction = ATOM_ENABLE;
+                       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+                       if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
+                               args.ucAction = ATOM_LCD_BLON;
+                               atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+                       }
                        break;
                case DRM_MODE_DPMS_STANDBY:
                case DRM_MODE_DPMS_SUSPEND:
                case DRM_MODE_DPMS_OFF:
                        args.ucAction = ATOM_DISABLE;
+                       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+                       if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
+                               args.ucAction = ATOM_LCD_BLOFF;
+                               atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+                       }
                        break;
                }
-               atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
        }
+
+       if (ext_encoder) {
+               int action;
+
+               switch (mode) {
+               case DRM_MODE_DPMS_ON:
+               default:
+                       action = ATOM_ENABLE;
+                       break;
+               case DRM_MODE_DPMS_STANDBY:
+               case DRM_MODE_DPMS_SUSPEND:
+               case DRM_MODE_DPMS_OFF:
+                       action = ATOM_DISABLE;
+                       break;
+               }
+               atombios_external_encoder_setup(encoder, ext_encoder, action);
+       }
+
        radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false);
 
 }
@@ -1242,7 +1432,7 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder)
                break;
        default:
                DRM_ERROR("Unknown table version: %d, %d\n", frev, crev);
-               break;
+               return;
        }
 
        atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
@@ -1357,6 +1547,7 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
        struct drm_device *dev = encoder->dev;
        struct radeon_device *rdev = dev->dev_private;
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       struct drm_encoder *ext_encoder = radeon_atom_get_external_encoder(encoder);
 
        radeon_encoder->pixel_clock = adjusted_mode->clock;
 
@@ -1400,11 +1591,9 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
                }
                break;
        case ENCODER_OBJECT_ID_INTERNAL_DDI:
-               atombios_ddia_setup(encoder, ATOM_ENABLE);
-               break;
        case ENCODER_OBJECT_ID_INTERNAL_DVO1:
        case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
-               atombios_external_tmds_setup(encoder, ATOM_ENABLE);
+               atombios_dvo_setup(encoder, ATOM_ENABLE);
                break;
        case ENCODER_OBJECT_ID_INTERNAL_DAC1:
        case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
@@ -1419,6 +1608,11 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
                }
                break;
        }
+
+       if (ext_encoder) {
+               atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE);
+       }
+
        atombios_apply_encoder_quirks(encoder, adjusted_mode);
 
        if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) {
@@ -1595,11 +1789,9 @@ static void radeon_atom_encoder_disable(struct drm_encoder *encoder)
                }
                break;
        case ENCODER_OBJECT_ID_INTERNAL_DDI:
-               atombios_ddia_setup(encoder, ATOM_DISABLE);
-               break;
        case ENCODER_OBJECT_ID_INTERNAL_DVO1:
        case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
-               atombios_external_tmds_setup(encoder, ATOM_DISABLE);
+               atombios_dvo_setup(encoder, ATOM_DISABLE);
                break;
        case ENCODER_OBJECT_ID_INTERNAL_DAC1:
        case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
@@ -1621,6 +1813,53 @@ disable_done:
        radeon_encoder->active_device = 0;
 }
 
+/* these are handled by the primary encoders */
+static void radeon_atom_ext_prepare(struct drm_encoder *encoder)
+{
+
+}
+
+static void radeon_atom_ext_commit(struct drm_encoder *encoder)
+{
+
+}
+
+static void
+radeon_atom_ext_mode_set(struct drm_encoder *encoder,
+                        struct drm_display_mode *mode,
+                        struct drm_display_mode *adjusted_mode)
+{
+
+}
+
+static void radeon_atom_ext_disable(struct drm_encoder *encoder)
+{
+
+}
+
+static void
+radeon_atom_ext_dpms(struct drm_encoder *encoder, int mode)
+{
+
+}
+
+static bool radeon_atom_ext_mode_fixup(struct drm_encoder *encoder,
+                                      struct drm_display_mode *mode,
+                                      struct drm_display_mode *adjusted_mode)
+{
+       return true;
+}
+
+static const struct drm_encoder_helper_funcs radeon_atom_ext_helper_funcs = {
+       .dpms = radeon_atom_ext_dpms,
+       .mode_fixup = radeon_atom_ext_mode_fixup,
+       .prepare = radeon_atom_ext_prepare,
+       .mode_set = radeon_atom_ext_mode_set,
+       .commit = radeon_atom_ext_commit,
+       .disable = radeon_atom_ext_disable,
+       /* no detect for TMDS/LVDS yet */
+};
+
 static const struct drm_encoder_helper_funcs radeon_atom_dig_helper_funcs = {
        .dpms = radeon_atom_encoder_dpms,
        .mode_fixup = radeon_atom_mode_fixup,
@@ -1730,6 +1969,7 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_t
        radeon_encoder->devices = supported_device;
        radeon_encoder->rmx_type = RMX_OFF;
        radeon_encoder->underscan_type = UNDERSCAN_OFF;
+       radeon_encoder->is_ext_encoder = false;
 
        switch (radeon_encoder->encoder_id) {
        case ENCODER_OBJECT_ID_INTERNAL_LVDS:
@@ -1771,6 +2011,9 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_t
                        radeon_encoder->rmx_type = RMX_FULL;
                        drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_LVDS);
                        radeon_encoder->enc_priv = radeon_atombios_get_lvds_info(radeon_encoder);
+               } else if (radeon_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT)) {
+                       drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_DAC);
+                       radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder);
                } else {
                        drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS);
                        radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder);
@@ -1779,5 +2022,22 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_t
                }
                drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs);
                break;
+       case ENCODER_OBJECT_ID_SI170B:
+       case ENCODER_OBJECT_ID_CH7303:
+       case ENCODER_OBJECT_ID_EXTERNAL_SDVOA:
+       case ENCODER_OBJECT_ID_EXTERNAL_SDVOB:
+       case ENCODER_OBJECT_ID_TITFP513:
+       case ENCODER_OBJECT_ID_VT1623:
+       case ENCODER_OBJECT_ID_HDMI_SI1930:
+               /* these are handled by the primary encoders */
+               radeon_encoder->is_ext_encoder = true;
+               if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
+                       drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_LVDS);
+               else if (radeon_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT))
+                       drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_DAC);
+               else
+                       drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS);
+               drm_encoder_helper_add(encoder, &radeon_atom_ext_helper_funcs);
+               break;
        }
 }
index e65b90317fab282df8b97b6b11b277ea867a2647..65016117d95f2f4e332bc6bdd0d9de63e8dbeafe 100644 (file)
@@ -79,8 +79,8 @@ int radeon_gart_table_vram_alloc(struct radeon_device *rdev)
 
        if (rdev->gart.table.vram.robj == NULL) {
                r = radeon_bo_create(rdev, NULL, rdev->gart.table_size,
-                                       true, RADEON_GEM_DOMAIN_VRAM,
-                                       &rdev->gart.table.vram.robj);
+                                    PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM,
+                                    &rdev->gart.table.vram.robj);
                if (r) {
                        return r;
                }
index d1e595d9172396b8104d19c7a1d0a87d3b14b772..df95eb83dac6d52e4cad7f6570d6cca9e2807b1f 100644 (file)
@@ -67,7 +67,7 @@ int radeon_gem_object_create(struct radeon_device *rdev, int size,
        if (alignment < PAGE_SIZE) {
                alignment = PAGE_SIZE;
        }
-       r = radeon_bo_create(rdev, gobj, size, kernel, initial_domain, &robj);
+       r = radeon_bo_create(rdev, gobj, size, alignment, kernel, initial_domain, &robj);
        if (r) {
                if (r != -ERESTARTSYS)
                        DRM_ERROR("Failed to allocate GEM object (%d, %d, %u, %d)\n",
index 0cfbba02c4d03773df29eb07efe74010a989002b..ded2a45bc95cd5f2845b9d32009d98dc00105c5f 100644 (file)
@@ -896,7 +896,8 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
             ((rdev->family <= CHIP_RS480) ||
              ((rdev->family >= CHIP_RV515) && (rdev->family <= CHIP_R580))))) {
                /* set the radeon hw i2c adapter */
-               sprintf(i2c->adapter.name, "Radeon i2c hw bus %s", name);
+               snprintf(i2c->adapter.name, sizeof(i2c->adapter.name),
+                        "Radeon i2c hw bus %s", name);
                i2c->adapter.algo = &radeon_i2c_algo;
                ret = i2c_add_adapter(&i2c->adapter);
                if (ret) {
@@ -905,7 +906,8 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
                }
        } else {
                /* set the radeon bit adapter */
-               sprintf(i2c->adapter.name, "Radeon i2c bit bus %s", name);
+               snprintf(i2c->adapter.name, sizeof(i2c->adapter.name),
+                        "Radeon i2c bit bus %s", name);
                i2c->adapter.algo_data = &i2c->algo.bit;
                i2c->algo.bit.pre_xfer = pre_xfer;
                i2c->algo.bit.post_xfer = post_xfer;
@@ -946,6 +948,8 @@ struct radeon_i2c_chan *radeon_i2c_create_dp(struct drm_device *dev,
        i2c->rec = *rec;
        i2c->adapter.owner = THIS_MODULE;
        i2c->dev = dev;
+       snprintf(i2c->adapter.name, sizeof(i2c->adapter.name),
+                "Radeon aux bus %s", name);
        i2c_set_adapdata(&i2c->adapter, i2c);
        i2c->adapter.algo_data = &i2c->algo.dp;
        i2c->algo.dp.aux_ch = radeon_dp_i2c_aux_ch;
index 2f349a300195992c9450c9ddd1d6e091eed23ef8..465746bd51b76e4b88cbb1812f7729be430a6da7 100644 (file)
@@ -76,7 +76,7 @@ int radeon_enable_vblank(struct drm_device *dev, int crtc)
                default:
                        DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
                                  crtc);
-                       return EINVAL;
+                       return -EINVAL;
                }
        } else {
                switch (crtc) {
@@ -89,7 +89,7 @@ int radeon_enable_vblank(struct drm_device *dev, int crtc)
                default:
                        DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
                                  crtc);
-                       return EINVAL;
+                       return -EINVAL;
                }
        }
 
index 0b8397000f4c68ae98e80df717a652cb2ddf6253..59f834ba283dd3fa15dde00b373c6a330d62decc 100644 (file)
@@ -670,7 +670,7 @@ static void radeon_legacy_tmds_ext_mode_set(struct drm_encoder *encoder,
 
        if (rdev->is_atom_bios) {
                radeon_encoder->pixel_clock = adjusted_mode->clock;
-               atombios_external_tmds_setup(encoder, ATOM_ENABLE);
+               atombios_dvo_setup(encoder, ATOM_ENABLE);
                fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL);
        } else {
                fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL);
index 680f57644e865ce2a5e4fdc97b5154a7dffb11a5..e301c6f9e0595889a28a4ab99a10e530d41f2112 100644 (file)
@@ -375,6 +375,7 @@ struct radeon_encoder {
        int hdmi_config_offset;
        int hdmi_audio_workaround;
        int hdmi_buffer_status;
+       bool is_ext_encoder;
 };
 
 struct radeon_connector_atom_dig {
@@ -385,6 +386,7 @@ struct radeon_connector_atom_dig {
        u8 dp_sink_type;
        int dp_clock;
        int dp_lane_count;
+       bool edp_on;
 };
 
 struct radeon_gpio_rec {
@@ -523,9 +525,10 @@ struct drm_encoder *radeon_encoder_legacy_primary_dac_add(struct drm_device *dev
 struct drm_encoder *radeon_encoder_legacy_tv_dac_add(struct drm_device *dev, int bios_index, int with_tv);
 struct drm_encoder *radeon_encoder_legacy_tmds_int_add(struct drm_device *dev, int bios_index);
 struct drm_encoder *radeon_encoder_legacy_tmds_ext_add(struct drm_device *dev, int bios_index);
-extern void atombios_external_tmds_setup(struct drm_encoder *encoder, int action);
+extern void atombios_dvo_setup(struct drm_encoder *encoder, int action);
 extern void atombios_digital_setup(struct drm_encoder *encoder, int action);
 extern int atombios_get_encoder_mode(struct drm_encoder *encoder);
+extern void atombios_set_edp_panel_power(struct drm_connector *connector, int action);
 extern void radeon_encoder_set_active_device(struct drm_encoder *encoder);
 
 extern void radeon_crtc_load_lut(struct drm_crtc *crtc);
index 8eb183466015326f7ca93b2647e85a610fe91f6f..1d067743fee068174e3a5e85eb0e2d47b5b712ee 100644 (file)
@@ -86,11 +86,12 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain)
 }
 
 int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj,
-                       unsigned long size, bool kernel, u32 domain,
-                       struct radeon_bo **bo_ptr)
+                    unsigned long size, int byte_align, bool kernel, u32 domain,
+                    struct radeon_bo **bo_ptr)
 {
        struct radeon_bo *bo;
        enum ttm_bo_type type;
+       int page_align = roundup(byte_align, PAGE_SIZE) >> PAGE_SHIFT;
        int r;
 
        if (unlikely(rdev->mman.bdev.dev_mapping == NULL)) {
@@ -115,7 +116,7 @@ retry:
        /* Kernel allocation are uninterruptible */
        mutex_lock(&rdev->vram_mutex);
        r = ttm_bo_init(&rdev->mman.bdev, &bo->tbo, size, type,
-                       &bo->placement, 0, 0, !kernel, NULL, size,
+                       &bo->placement, page_align, 0, !kernel, NULL, size,
                        &radeon_ttm_bo_destroy);
        mutex_unlock(&rdev->vram_mutex);
        if (unlikely(r != 0)) {
index 3481bc7f6f582b08a0c2a9ff079fa9787defb6cd..d143702b244a4febdd51aa69ca7023e19d692a62 100644 (file)
@@ -137,9 +137,10 @@ static inline int radeon_bo_wait(struct radeon_bo *bo, u32 *mem_type,
 }
 
 extern int radeon_bo_create(struct radeon_device *rdev,
-                               struct drm_gem_object *gobj, unsigned long size,
-                               bool kernel, u32 domain,
-                               struct radeon_bo **bo_ptr);
+                           struct drm_gem_object *gobj, unsigned long size,
+                           int byte_align,
+                           bool kernel, u32 domain,
+                           struct radeon_bo **bo_ptr);
 extern int radeon_bo_kmap(struct radeon_bo *bo, void **ptr);
 extern void radeon_bo_kunmap(struct radeon_bo *bo);
 extern void radeon_bo_unref(struct radeon_bo **bo);
index 6ea798ce821896dd4b2704461b260578a63a2516..06e79822a2bff74b68fb74793c9ec906ad0834a1 100644 (file)
@@ -176,8 +176,8 @@ int radeon_ib_pool_init(struct radeon_device *rdev)
        INIT_LIST_HEAD(&rdev->ib_pool.bogus_ib);
        /* Allocate 1M object buffer */
        r = radeon_bo_create(rdev, NULL,  RADEON_IB_POOL_SIZE*64*1024,
-                               true, RADEON_GEM_DOMAIN_GTT,
-                               &rdev->ib_pool.robj);
+                            PAGE_SIZE, true, RADEON_GEM_DOMAIN_GTT,
+                            &rdev->ib_pool.robj);
        if (r) {
                DRM_ERROR("radeon: failed to ib pool (%d).\n", r);
                return r;
@@ -332,7 +332,7 @@ int radeon_ring_init(struct radeon_device *rdev, unsigned ring_size)
        rdev->cp.ring_size = ring_size;
        /* Allocate ring buffer */
        if (rdev->cp.ring_obj == NULL) {
-               r = radeon_bo_create(rdev, NULL, rdev->cp.ring_size, true,
+               r = radeon_bo_create(rdev, NULL, rdev->cp.ring_size, PAGE_SIZE, true,
                                        RADEON_GEM_DOMAIN_GTT,
                                        &rdev->cp.ring_obj);
                if (r) {
index 313c96bc09da1dcfcb0703ed3aa82a2038af0731..5b44f652145c45cb5b1b588fa263fb318739a168 100644 (file)
@@ -52,7 +52,7 @@ void radeon_test_moves(struct radeon_device *rdev)
                goto out_cleanup;
        }
 
-       r = radeon_bo_create(rdev, NULL, size, true, RADEON_GEM_DOMAIN_VRAM,
+       r = radeon_bo_create(rdev, NULL, size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM,
                                &vram_obj);
        if (r) {
                DRM_ERROR("Failed to create VRAM object\n");
@@ -71,7 +71,7 @@ void radeon_test_moves(struct radeon_device *rdev)
                void **gtt_start, **gtt_end;
                void **vram_start, **vram_end;
 
-               r = radeon_bo_create(rdev, NULL, size, true,
+               r = radeon_bo_create(rdev, NULL, size, PAGE_SIZE, true,
                                         RADEON_GEM_DOMAIN_GTT, gtt_obj + i);
                if (r) {
                        DRM_ERROR("Failed to create GTT object %d\n", i);
index 01c2c736a1daff116284db0f84f3896977e6eecb..1272e4b6a1d45469add57610a397c213704d5446 100644 (file)
@@ -529,7 +529,7 @@ int radeon_ttm_init(struct radeon_device *rdev)
                DRM_ERROR("Failed initializing VRAM heap.\n");
                return r;
        }
-       r = radeon_bo_create(rdev, NULL, 256 * 1024, true,
+       r = radeon_bo_create(rdev, NULL, 256 * 1024, PAGE_SIZE, true,
                                RADEON_GEM_DOMAIN_VRAM,
                                &rdev->stollen_vga_memory);
        if (r) {
index 245374e2b778b7706e9bf828c8a65876c1e11a00..4dfead8cee33907ae025c9c58adede92c12db4f6 100644 (file)
@@ -915,8 +915,8 @@ static int rv770_vram_scratch_init(struct radeon_device *rdev)
 
        if (rdev->vram_scratch.robj == NULL) {
                r = radeon_bo_create(rdev, NULL, RADEON_GPU_PAGE_SIZE,
-                                       true, RADEON_GEM_DOMAIN_VRAM,
-                                       &rdev->vram_scratch.robj);
+                                    PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM,
+                                    &rdev->vram_scratch.robj);
                if (r) {
                        return r;
                }
index 3ca77dc03915017e78d0e7f7e8e479d9f279fc56..148a322d8f5d7c45d0487351635f89eb9a9a0949 100644 (file)
@@ -224,6 +224,9 @@ int ttm_bo_reserve_locked(struct ttm_buffer_object *bo,
        int ret;
 
        while (unlikely(atomic_cmpxchg(&bo->reserved, 0, 1) != 0)) {
+               /**
+                * Deadlock avoidance for multi-bo reserving.
+                */
                if (use_sequence && bo->seq_valid &&
                        (sequence - bo->val_seq < (1 << 31))) {
                        return -EAGAIN;
@@ -241,6 +244,14 @@ int ttm_bo_reserve_locked(struct ttm_buffer_object *bo,
        }
 
        if (use_sequence) {
+               /**
+                * Wake up waiters that may need to recheck for deadlock,
+                * if we decreased the sequence number.
+                */
+               if (unlikely((bo->val_seq - sequence < (1 << 31))
+                            || !bo->seq_valid))
+                       wake_up_all(&bo->event_queue);
+
                bo->val_seq = sequence;
                bo->seq_valid = true;
        } else {
index 36e129f0023ffc3d6407b9c0251376aa3fc9f5c0..5408b1b7996f054dee95b9ed5aac4e9d63ee99a1 100644 (file)
@@ -862,7 +862,7 @@ int vmw_dmabuf_alloc_ioctl(struct drm_device *dev, void *data,
                              &vmw_vram_sys_placement, true,
                              &vmw_user_dmabuf_destroy);
        if (unlikely(ret != 0))
-               return ret;
+               goto out_no_dmabuf;
 
        tmp = ttm_bo_reference(&vmw_user_bo->dma.base);
        ret = ttm_base_object_init(vmw_fpriv(file_priv)->tfile,
@@ -870,19 +870,21 @@ int vmw_dmabuf_alloc_ioctl(struct drm_device *dev, void *data,
                                   false,
                                   ttm_buffer_type,
                                   &vmw_user_dmabuf_release, NULL);
-       if (unlikely(ret != 0)) {
-               ttm_bo_unref(&tmp);
-       else {
+       if (unlikely(ret != 0))
+               goto out_no_base_object;
+       else {
                rep->handle = vmw_user_bo->base.hash.key;
                rep->map_handle = vmw_user_bo->dma.base.addr_space_offset;
                rep->cur_gmr_id = vmw_user_bo->base.hash.key;
                rep->cur_gmr_offset = 0;
        }
-       ttm_bo_unref(&tmp);
 
+out_no_base_object:
+       ttm_bo_unref(&tmp);
+out_no_dmabuf:
        ttm_read_unlock(&vmaster->lock);
 
-       return 0;
+       return ret;
 }
 
 int vmw_dmabuf_unref_ioctl(struct drm_device *dev, void *data,
index 8a4b32dca9f74fd03621f3deffe0912929ee5cf3..e1f07483691f7823b46db14c38dc0d8daa536a13 100644 (file)
@@ -32,7 +32,6 @@
 #include <linux/hid.h>
 #include <linux/mutex.h>
 #include <linux/sched.h>
-#include <linux/smp_lock.h>
 
 #include <linux/hidraw.h>
 
index fedd88df9a18477de2699cb07e48feade407312f..984feb351a5a3205de716fdb68ad9e5f983bdadd 100644 (file)
@@ -29,7 +29,6 @@
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/smp_lock.h>
 #include <linux/input.h>
 #include <linux/usb.h>
 #include <linux/hid.h>
index 6078992da3f04d6de686838c46ccfd61f6f43922..9292a15ad7c4885b3920724eeeb27b9765051bc4 100644 (file)
@@ -40,7 +40,6 @@
 #include <linux/highmem.h>
 #include <linux/io.h>
 #include <linux/jiffies.h>
-#include <linux/smp_lock.h>
 #include <asm/pgtable.h>
 
 #include "ipath_kernel.h"
index cfc1d65c4577bf4ed2ce07bc2ea1924f406bd445..1e1e347a771531aa767f912a5fe38d3c2f2ac2dc 100644 (file)
@@ -1123,7 +1123,7 @@ static void srp_send_completion(struct ib_cq *cq, void *target_ptr)
        }
 }
 
-static int srp_queuecommand(struct scsi_cmnd *scmnd,
+static int srp_queuecommand_lck(struct scsi_cmnd *scmnd,
                            void (*done)(struct scsi_cmnd *))
 {
        struct srp_target_port *target = host_to_target(scmnd->device->host);
@@ -1196,6 +1196,8 @@ err:
        return SCSI_MLQUEUE_HOST_BUSY;
 }
 
+static DEF_SCSI_QCMD(srp_queuecommand)
+
 static int srp_alloc_iu_bufs(struct srp_target_port *target)
 {
        int i;
index 7f26ca6ecf75dc6f15185771a8bae6cfb24ce58d..db409d6bd5d2b9672ad94f370564f870bed25b19 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/device.h>
 #include <linux/mutex.h>
 #include <linux/rcupdate.h>
-#include <linux/smp_lock.h>
 #include "input-compat.h"
 
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
@@ -753,7 +752,7 @@ static int input_default_setkeycode(struct input_dev *dev,
        if (index >= dev->keycodemax)
                return -EINVAL;
 
-       if (dev->keycodesize < sizeof(dev->keycode) &&
+       if (dev->keycodesize < sizeof(ke->keycode) &&
                        (ke->keycode >> (dev->keycodesize * 8)))
                return -EINVAL;
 
index cd82bb12591593be230f06fbf89aa2a52f6b73b2..b7ba4597f7f0256a7fb4f14b76894a3b76f0ccb6 100644 (file)
@@ -11,7 +11,6 @@
 
 #include <linux/sched.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/poll.h>
 #include <linux/module.h>
 #include <linux/serio.h>
index 57b25b84d1fcfded0408788dbd8cbd2d0dcb3e8f..0a619c558bfb40a8223c94301462d6387f7dc388 100644 (file)
@@ -1097,7 +1097,7 @@ store_tabletPointerMode(struct device *dev, struct device_attribute *attr, const
 }
 
 static DEVICE_ATTR(pointer_mode,
-                  S_IRUGO | S_IWUGO,
+                  S_IRUGO | S_IWUSR,
                   show_tabletPointerMode, store_tabletPointerMode);
 
 /***********************************************************************
@@ -1134,7 +1134,7 @@ store_tabletCoordinateMode(struct device *dev, struct device_attribute *attr, co
 }
 
 static DEVICE_ATTR(coordinate_mode,
-                  S_IRUGO | S_IWUGO,
+                  S_IRUGO | S_IWUSR,
                   show_tabletCoordinateMode, store_tabletCoordinateMode);
 
 /***********************************************************************
@@ -1176,7 +1176,7 @@ store_tabletToolMode(struct device *dev, struct device_attribute *attr, const ch
 }
 
 static DEVICE_ATTR(tool_mode,
-                  S_IRUGO | S_IWUGO,
+                  S_IRUGO | S_IWUSR,
                   show_tabletToolMode, store_tabletToolMode);
 
 /***********************************************************************
@@ -1219,7 +1219,7 @@ store_tabletXtilt(struct device *dev, struct device_attribute *attr, const char
 }
 
 static DEVICE_ATTR(xtilt,
-                  S_IRUGO | S_IWUGO, show_tabletXtilt, store_tabletXtilt);
+                  S_IRUGO | S_IWUSR, show_tabletXtilt, store_tabletXtilt);
 
 /***********************************************************************
  * support routines for the 'ytilt' file. Note that this file
@@ -1261,7 +1261,7 @@ store_tabletYtilt(struct device *dev, struct device_attribute *attr, const char
 }
 
 static DEVICE_ATTR(ytilt,
-                  S_IRUGO | S_IWUGO, show_tabletYtilt, store_tabletYtilt);
+                  S_IRUGO | S_IWUSR, show_tabletYtilt, store_tabletYtilt);
 
 /***********************************************************************
  * support routines for the 'jitter' file. Note that this file
@@ -1288,7 +1288,7 @@ store_tabletJitterDelay(struct device *dev, struct device_attribute *attr, const
 }
 
 static DEVICE_ATTR(jitter,
-                  S_IRUGO | S_IWUGO,
+                  S_IRUGO | S_IWUSR,
                   show_tabletJitterDelay, store_tabletJitterDelay);
 
 /***********************************************************************
@@ -1317,7 +1317,7 @@ store_tabletProgrammableDelay(struct device *dev, struct device_attribute *attr,
 }
 
 static DEVICE_ATTR(delay,
-                  S_IRUGO | S_IWUGO,
+                  S_IRUGO | S_IWUSR,
                   show_tabletProgrammableDelay, store_tabletProgrammableDelay);
 
 /***********************************************************************
@@ -1406,7 +1406,7 @@ store_tabletStylusUpper(struct device *dev, struct device_attribute *attr, const
 }
 
 static DEVICE_ATTR(stylus_upper,
-                  S_IRUGO | S_IWUGO,
+                  S_IRUGO | S_IWUSR,
                   show_tabletStylusUpper, store_tabletStylusUpper);
 
 /***********************************************************************
@@ -1437,7 +1437,7 @@ store_tabletStylusLower(struct device *dev, struct device_attribute *attr, const
 }
 
 static DEVICE_ATTR(stylus_lower,
-                  S_IRUGO | S_IWUGO,
+                  S_IRUGO | S_IWUSR,
                   show_tabletStylusLower, store_tabletStylusLower);
 
 /***********************************************************************
@@ -1475,7 +1475,7 @@ store_tabletMouseLeft(struct device *dev, struct device_attribute *attr, const c
 }
 
 static DEVICE_ATTR(mouse_left,
-                  S_IRUGO | S_IWUGO,
+                  S_IRUGO | S_IWUSR,
                   show_tabletMouseLeft, store_tabletMouseLeft);
 
 /***********************************************************************
@@ -1505,7 +1505,7 @@ store_tabletMouseMiddle(struct device *dev, struct device_attribute *attr, const
 }
 
 static DEVICE_ATTR(mouse_middle,
-                  S_IRUGO | S_IWUGO,
+                  S_IRUGO | S_IWUSR,
                   show_tabletMouseMiddle, store_tabletMouseMiddle);
 
 /***********************************************************************
@@ -1535,7 +1535,7 @@ store_tabletMouseRight(struct device *dev, struct device_attribute *attr, const
 }
 
 static DEVICE_ATTR(mouse_right,
-                  S_IRUGO | S_IWUGO,
+                  S_IRUGO | S_IWUSR,
                   show_tabletMouseRight, store_tabletMouseRight);
 
 /***********************************************************************
@@ -1567,7 +1567,7 @@ store_tabletWheel(struct device *dev, struct device_attribute *attr, const char
 }
 
 static DEVICE_ATTR(wheel,
-                  S_IRUGO | S_IWUGO, show_tabletWheel, store_tabletWheel);
+                  S_IRUGO | S_IWUSR, show_tabletWheel, store_tabletWheel);
 
 /***********************************************************************
  * support routines for the 'execute' file. Note that this file
@@ -1600,7 +1600,7 @@ store_tabletExecute(struct device *dev, struct device_attribute *attr, const cha
 }
 
 static DEVICE_ATTR(execute,
-                  S_IRUGO | S_IWUGO, show_tabletExecute, store_tabletExecute);
+                  S_IRUGO | S_IWUSR, show_tabletExecute, store_tabletExecute);
 
 /***********************************************************************
  * support routines for the 'odm_code' file. Note that this file
index 4d0646da6087b05e02c87767232417c2b1f94d93..7ea517b7e18626fd5723c255cb0aee2a102970a8 100644 (file)
@@ -36,7 +36,6 @@
 #include <linux/delay.h>
 #include <linux/spinlock.h>
 #include <linux/sched.h>
-#include <linux/smp_lock.h>
 #include <linux/kthread.h>
 
 #include "dvb_ca_en50221.h"
index 1589d5a5cb4696ab2114019780866aab93622135..cad6634610ea5fb0d6ea59e6c86e322bd1e9638e 100644 (file)
@@ -36,7 +36,6 @@
 #include <linux/list.h>
 #include <linux/freezer.h>
 #include <linux/jiffies.h>
-#include <linux/smp_lock.h>
 #include <linux/kthread.h>
 #include <asm/processor.h>
 
index 4caeb163a66668da958cdae28058c2e0bb67a3af..3a7ef71087be7110174df8df4968bc65b995a04f 100644 (file)
@@ -34,7 +34,6 @@
 #include <linux/io.h>
 #include <asm/div64.h>
 #include <linux/pci.h>
-#include <linux/smp_lock.h>
 #include <linux/timer.h>
 #include <linux/byteorder/generic.h>
 #include <linux/firmware.h>
index 48f980b21d663ad94b89b17689d62737104b6ac4..3832e5983c19104b92c29d273392dfdae53cc074 100644 (file)
@@ -35,7 +35,6 @@
 #include <linux/io.h>
 #include <asm/div64.h>
 #include <linux/pci.h>
-#include <linux/smp_lock.h>
 #include <linux/timer.h>
 #include <linux/byteorder/generic.h>
 #include <linux/firmware.h>
index c3ae956714e77501954d17bc1a34843200365b2f..d28554f8ce9961f1102a9a22e8f28d71f057e7cd 100644 (file)
@@ -37,7 +37,6 @@
 #include <asm/div64.h>
 #include <linux/pci.h>
 #include <linux/pci_ids.h>
-#include <linux/smp_lock.h>
 #include <linux/timer.h>
 #include <linux/byteorder/generic.h>
 #include <linux/firmware.h>
index b540e8072e9295ca8551e65858e5f2670e381d0c..e6b2d085a449ae0a7ba4a424a70014e5a03b7112 100644 (file)
@@ -58,7 +58,6 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/input.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
index ea12782359a024d415dcda5cc87f724ba423f7ae..b9914d7a0c9ffeef06a0b7f02bd2f82c10f1dd9f 100644 (file)
@@ -31,7 +31,6 @@
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/input.h>
 #include <linux/version.h>
 #include <linux/videodev2.h>
index 3da6e80e1041358e594836fbd9b8146b4dfedb7d..a529619e51f687d1386c6c673a0feaa9ba8d517a 100644 (file)
@@ -42,7 +42,6 @@
 #include <linux/fs.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/smp_lock.h>
 #include <linux/interrupt.h>
 #include <linux/kdev_t.h>
 #include "bttvp.h"
index 417d1d5c73c4fead58a7c0133454debaed8a7f73..d7c94848249e1252018e58e25417d6fdd710cc47 100644 (file)
@@ -33,7 +33,6 @@
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/firmware.h>
-#include <linux/smp_lock.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
 #include <media/cx2341x.h>
index d2f159daa8b506d34c5f027f8650a64a7518d184..88b51194f917956a17c734a21d9c2a893b2e5104 100644 (file)
@@ -31,7 +31,6 @@
 #include <linux/kmod.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/interrupt.h>
 #include <linux/dma-mapping.h>
 #include <linux/delay.h>
index e62beb4efdb472e811609ec96717013ca6ffa74d..f3dc89da4c4eefcd23f7c457c75322c5eb96b0c9 100644 (file)
@@ -62,7 +62,6 @@
 #include <linux/module.h>
 #include <linux/poll.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #ifdef CONFIG_USB_PWC_INPUT_EVDEV
 #include <linux/usb/input.h>
 #endif
index f5a46c45871713df2eab2c0f43bccff5717fc05d..a845753665c1ed267002353703877b33c9d8f1db 100644 (file)
@@ -49,7 +49,6 @@
 #include <linux/videodev2.h>
 #include <linux/version.h>
 #include <linux/mm.h>
-#include <linux/smp_lock.h>
 #include <media/videobuf-vmalloc.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-device.h>
index 1467a30a434fe29d677d3289d322e6d34a940cff..b890aafe7d640bcc141b2c6edddb3009d73c5245 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/smp_lock.h>
 #include <linux/delay.h>
 
 #include "saa7134-reg.h"
index 1d9c5cbbbc52cbef4c8f4fe97719967b0f5250b7..041ae8e20f685fdd6a37831dca38862f5fa06927 100644 (file)
@@ -58,7 +58,6 @@
 #include <media/tveeprom.h>
 #include <media/videobuf-dma-sg.h>
 #include <media/videobuf-dvb.h>
-#include <linux/smp_lock.h>
 #include <dvb_demux.h>
 #include <dvb_frontend.h>
 #include <dvb_net.h>
index db6b828594f513ac562485692e918f63798e41dc..011c0c386995966cddaba715a7b13ced0a122a61 100644 (file)
@@ -50,7 +50,6 @@
 #include <linux/list.h>
 #include <linux/timer.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/mm.h>
 #include <linux/highmem.h>
 #include <linux/vmalloc.h>
index 86294ed35c9b643cc7bab7411904476d0f7467a7..e30e8dfb62052b70bf8d596c80c697d6a23405f3 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/videodev.h>
 #include <linux/videodev2.h>
 #include <linux/module.h>
-#include <linux/smp_lock.h>
 #include <media/v4l2-ioctl.h>
 
 #ifdef CONFIG_COMPAT
index e15220ff52fc7b150da7a11e04c1f7d84c4a5d55..d784c36707c0b12c318c1f2be20fe98b425eabad 100644 (file)
@@ -97,8 +97,7 @@ static u8     mptfcInternalCtx = MPT_MAX_PROTOCOL_DRIVERS;
 
 static int mptfc_target_alloc(struct scsi_target *starget);
 static int mptfc_slave_alloc(struct scsi_device *sdev);
-static int mptfc_qcmd(struct scsi_cmnd *SCpnt,
-                     void (*done)(struct scsi_cmnd *));
+static int mptfc_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *SCpnt);
 static void mptfc_target_destroy(struct scsi_target *starget);
 static void mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout);
 static void __devexit mptfc_remove(struct pci_dev *pdev);
@@ -650,7 +649,7 @@ mptfc_slave_alloc(struct scsi_device *sdev)
 }
 
 static int
-mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
+mptfc_qcmd_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
 {
        struct mptfc_rport_info *ri;
        struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device));
@@ -681,6 +680,8 @@ mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
        return mptscsih_qcmd(SCpnt,done);
 }
 
+static DEF_SCSI_QCMD(mptfc_qcmd)
+
 /*
  *     mptfc_display_port_link_speed - displaying link speed
  *     @ioc: Pointer to MPT_ADAPTER structure
index 83a5115f025113d89eb2c793901b443691d5f397..d48c2c6058e1d12f62316d2541cd36dfdb27daaa 100644 (file)
@@ -1889,7 +1889,7 @@ mptsas_slave_alloc(struct scsi_device *sdev)
 }
 
 static int
-mptsas_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
+mptsas_qcmd_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
 {
        MPT_SCSI_HOST   *hd;
        MPT_ADAPTER     *ioc;
@@ -1913,6 +1913,8 @@ mptsas_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
        return mptscsih_qcmd(SCpnt,done);
 }
 
+static DEF_SCSI_QCMD(mptsas_qcmd)
+
 /**
  *     mptsas_mptsas_eh_timed_out - resets the scsi_cmnd timeout
  *             if the device under question is currently in the
index 0e2803155ae20a1cacb1d67037e4d7de0d6155e8..6d9568d2ec59693235e2bf886c6daf46199e659f 100644 (file)
@@ -780,7 +780,7 @@ static int mptspi_slave_configure(struct scsi_device *sdev)
 }
 
 static int
-mptspi_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
+mptspi_qcmd_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
 {
        struct _MPT_SCSI_HOST *hd = shost_priv(SCpnt->device->host);
        VirtDevice      *vdevice = SCpnt->device->hostdata;
@@ -805,6 +805,8 @@ mptspi_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
        return mptscsih_qcmd(SCpnt,done);
 }
 
+static DEF_SCSI_QCMD(mptspi_qcmd)
+
 static void mptspi_slave_destroy(struct scsi_device *sdev)
 {
        struct scsi_target *starget = scsi_target(sdev);
index ea6b2197da8a2fc38afd18aaebd3d0a32338a993..97bdf82ec9059ddced228220d21bbb3e64dc2b99 100644 (file)
@@ -506,7 +506,7 @@ static struct i2o_driver i2o_scsi_driver = {
  *     Locks: takes the controller lock on error path only
  */
 
-static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt,
+static int i2o_scsi_queuecommand_lck(struct scsi_cmnd *SCpnt,
                                 void (*done) (struct scsi_cmnd *))
 {
        struct i2o_controller *c;
@@ -688,7 +688,9 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt,
 
       exit:
        return rc;
-};
+}
+
+static DEF_SCSI_QCMD(i2o_scsi_queuecommand)
 
 /**
  *     i2o_scsi_abort - abort a running command
index e1da258bbfb7bfd89c24354e7deb626f4da777f9..0a92436f05389883e8485bdf13fafc19cccd2ca2 100644 (file)
@@ -699,7 +699,8 @@ DEFINE_WINDOW_IO(32)
 #define DEVICE_PCI(dev) NULL
 #endif
 
-#define VORTEX_PCI(vp) (((vp)->gendev) ? DEVICE_PCI((vp)->gendev) : NULL)
+#define VORTEX_PCI(vp)                                                 \
+       ((struct pci_dev *) (((vp)->gendev) ? DEVICE_PCI((vp)->gendev) : NULL))
 
 #ifdef CONFIG_EISA
 #define DEVICE_EISA(dev) (((dev)->bus == &eisa_bus_type) ? to_eisa_device((dev)) : NULL)
@@ -707,7 +708,8 @@ DEFINE_WINDOW_IO(32)
 #define DEVICE_EISA(dev) NULL
 #endif
 
-#define VORTEX_EISA(vp) (((vp)->gendev) ? DEVICE_EISA((vp)->gendev) : NULL)
+#define VORTEX_EISA(vp)                                                        \
+       ((struct eisa_device *) (((vp)->gendev) ? DEVICE_EISA((vp)->gendev) : NULL))
 
 /* The action to take with a media selection timer tick.
    Note that we deviate from the 3Com order by checking 10base2 before AUI.
index ac422cd332eadd687823fcc4db7ca2eaef997fea..dd16e83933a28f817c1eaa0d47003cb4482c3aa5 100644 (file)
@@ -490,13 +490,11 @@ static inline unsigned int cp_rx_csum_ok (u32 status)
 {
        unsigned int protocol = (status >> 16) & 0x3;
 
-       if (likely((protocol == RxProtoTCP) && (!(status & TCPFail))))
+       if (((protocol == RxProtoTCP) && !(status & TCPFail)) ||
+           ((protocol == RxProtoUDP) && !(status & UDPFail)))
                return 1;
-       else if ((protocol == RxProtoUDP) && (!(status & UDPFail)))
-               return 1;
-       else if ((protocol == RxProtoIP) && (!(status & IPFail)))
-               return 1;
-       return 0;
+       else
+               return 0;
 }
 
 static int cp_rx_poll(struct napi_struct *napi, int budget)
index c36cd2ffbadcaa41e15a043a937d1b1ad62c22b4..93354eee2cfd1e679929054c9cc28fe7b35dea51 100644 (file)
@@ -2458,6 +2458,12 @@ int be_load_fw(struct be_adapter *adapter, u8 *func)
        int status, i = 0, num_imgs = 0;
        const u8 *p;
 
+       if (!netif_running(adapter->netdev)) {
+               dev_err(&adapter->pdev->dev,
+                       "Firmware load not allowed (interface is down)\n");
+               return -EPERM;
+       }
+
        strcpy(fw_file, func);
 
        status = request_firmware(&fw, fw_file, &adapter->pdev->dev);
index e9ad16f00b56755847eb887a898c999ef2c08c04..9709b8569666d56ff84fb263429eb6f27c244033 100644 (file)
@@ -9064,7 +9064,7 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,
        default:
                pr_err("Unknown board_type (%ld), aborting\n",
                           ent->driver_data);
-               return ENODEV;
+               return -ENODEV;
        }
 
        cid_count += CNIC_CONTEXT_USE;
index bdb68a600382bdcfbe8a9e2cf70f8360821e2567..71a169740d05daf463b04f2ff591a943f8c1847e 100644 (file)
@@ -878,8 +878,10 @@ static void __bond_resend_igmp_join_requests(struct net_device *dev)
        rcu_read_lock();
        in_dev = __in_dev_get_rcu(dev);
        if (in_dev) {
+               read_lock(&in_dev->mc_list_lock);
                for (im = in_dev->mc_list; im; im = im->next)
                        ip_mc_rejoin_group(im);
+               read_unlock(&in_dev->mc_list_lock);
        }
 
        rcu_read_unlock();
index 8b4cea57a6c5c47f585f5fcae935771e575dcd18..20da1996d354d563d8a2616276de477041b2368d 100644 (file)
@@ -635,8 +635,8 @@ int cfspi_spi_probe(struct platform_device *pdev)
 
        ndev = alloc_netdev(sizeof(struct cfspi),
                        "cfspi%d", cfspi_setup);
-       if (!dev)
-               return -ENODEV;
+       if (!ndev)
+               return -ENOMEM;
 
        cfspi = netdev_priv(ndev);
        netif_stop_queue(ndev);
index 49e4ce1246a75e01c30a623de0031707fe0273c9..d1bec6269173844cfb17786c99936beee8dfd197 100644 (file)
@@ -577,11 +577,10 @@ static int gfar_parse_group(struct device_node *np,
                        irq_of_parse_and_map(np, 1);
                priv->gfargrp[priv->num_grps].interruptError =
                        irq_of_parse_and_map(np,2);
-               if (priv->gfargrp[priv->num_grps].interruptTransmit < 0 ||
-                       priv->gfargrp[priv->num_grps].interruptReceive < 0 ||
-                       priv->gfargrp[priv->num_grps].interruptError < 0) {
+               if (priv->gfargrp[priv->num_grps].interruptTransmit == NO_IRQ ||
+                   priv->gfargrp[priv->num_grps].interruptReceive  == NO_IRQ ||
+                   priv->gfargrp[priv->num_grps].interruptError    == NO_IRQ)
                        return -EINVAL;
-               }
        }
 
        priv->gfargrp[priv->num_grps].grp_id = priv->num_grps;
index dc019809234352418978474531efa675a4e879a2..aa93655c3aa7c1da10f8aeda9eaf2a1535b06756 100644 (file)
@@ -88,16 +88,14 @@ static const char *ipg_brand_name[] = {
        "IC PLUS IP1000 1000/100/10 based NIC",
        "Sundance Technology ST2021 based NIC",
        "Tamarack Microelectronics TC9020/9021 based NIC",
-       "Tamarack Microelectronics TC9020/9021 based NIC",
        "D-Link NIC IP1000A"
 };
 
 static DEFINE_PCI_DEVICE_TABLE(ipg_pci_tbl) = {
        { PCI_VDEVICE(SUNDANCE, 0x1023), 0 },
        { PCI_VDEVICE(SUNDANCE, 0x2021), 1 },
-       { PCI_VDEVICE(SUNDANCE, 0x1021), 2 },
-       { PCI_VDEVICE(DLINK,    0x9021), 3 },
-       { PCI_VDEVICE(DLINK,    0x4020), 4 },
+       { PCI_VDEVICE(DLINK,    0x9021), 2 },
+       { PCI_VDEVICE(DLINK,    0x4020), 3 },
        { 0, }
 };
 
index 4c4d16905efb7253a055978e736edc93381cdd69..7d33ef4bcb4a1d6ca7125d6780e173889ebbb0d8 100644 (file)
@@ -4440,8 +4440,7 @@ static inline void rtl8169_rx_csum(struct sk_buff *skb, u32 opts1)
        u32 status = opts1 & RxProtoMask;
 
        if (((status == RxProtoTCP) && !(opts1 & TCPFail)) ||
-           ((status == RxProtoUDP) && !(opts1 & UDPFail)) ||
-           ((status == RxProtoIP) && !(opts1 & IPFail)))
+           ((status == RxProtoUDP) && !(opts1 & UDPFail)))
                skb->ip_summed = CHECKSUM_UNNECESSARY;
        else
                skb_checksum_none_assert(skb);
index 966b9496a9dd4b51cf5c1f850fc987ea4b6ffff2..195406db3bd899b28f96c7b8214428822c3735db 100644 (file)
@@ -37,7 +37,7 @@ static bool ath9k_hw_ar9287_fill_eeprom(struct ath_hw *ah)
        int addr, eep_start_loc;
        eep_data = (u16 *)eep;
 
-       if (ah->hw_version.devid == 0x7015)
+       if (AR9287_HTC_DEVID(ah))
                eep_start_loc = AR9287_HTC_EEP_START_LOC;
        else
                eep_start_loc = AR9287_EEP_START_LOC;
index f7ec31b4ddd3a9af801dcb8211763f21e6ab7e09..dfb6560dab9205c7502cc0a546c3549635d696f2 100644 (file)
@@ -36,8 +36,13 @@ static struct usb_device_id ath9k_hif_usb_ids[] = {
        { USB_DEVICE(0x13D3, 0x3327) }, /* Azurewave */
        { USB_DEVICE(0x13D3, 0x3328) }, /* Azurewave */
        { USB_DEVICE(0x13D3, 0x3346) }, /* IMC Networks */
+       { USB_DEVICE(0x13D3, 0x3348) }, /* Azurewave */
+       { USB_DEVICE(0x13D3, 0x3349) }, /* Azurewave */
+       { USB_DEVICE(0x13D3, 0x3350) }, /* Azurewave */
        { USB_DEVICE(0x04CA, 0x4605) }, /* Liteon */
        { USB_DEVICE(0x083A, 0xA704) }, /* SMC Networks */
+       { USB_DEVICE(0x040D, 0x3801) }, /* VIA */
+       { USB_DEVICE(0x1668, 0x1200) }, /* Verizon */
        { },
 };
 
@@ -806,6 +811,8 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev)
        case 0x7010:
        case 0x7015:
        case 0x9018:
+       case 0xA704:
+       case 0x1200:
                firm_offset = AR7010_FIRMWARE_TEXT;
                break;
        default:
@@ -928,6 +935,8 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface,
        case 0x7010:
        case 0x7015:
        case 0x9018:
+       case 0xA704:
+       case 0x1200:
                if (le16_to_cpu(udev->descriptor.bcdDevice) == 0x0202)
                        hif_dev->fw_name = FIRMWARE_AR7010_1_1;
                else
index 3d7b97f1b3aeebe5840c438b5ccf631de702d6c2..7c8a38d04561c26754147bea9e447724a9e8eb42 100644 (file)
@@ -249,6 +249,8 @@ static int ath9k_init_htc_services(struct ath9k_htc_priv *priv, u16 devid)
        case 0x7010:
        case 0x7015:
        case 0x9018:
+       case 0xA704:
+       case 0x1200:
                priv->htc->credits = 45;
                break;
        default:
index 3d19b5bc937f9c1c285e23645fcbf6a929037b21..29d80ca783933684b7c5c531cbb970ee7e006cda 100644 (file)
@@ -121,7 +121,7 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb)
                        tx_hdr.data_type = ATH9K_HTC_NORMAL;
                }
 
-               if (ieee80211_is_data(fc)) {
+               if (ieee80211_is_data_qos(fc)) {
                        qc = ieee80211_get_qos_ctl(hdr);
                        tx_hdr.tidno = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
                }
index 6a0d99eff404b77417856c7f1b7c035eb079359e..92bc5c5f48768ac42ca4b1bd02690d9d38ebed80 100644 (file)
@@ -817,8 +817,6 @@ void ath9k_deinit_device(struct ath_softc *sc)
 
        ath9k_ps_wakeup(sc);
 
-       pm_qos_remove_request(&ath9k_pm_qos_req);
-
        wiphy_rfkill_stop_polling(sc->hw->wiphy);
        ath_deinit_leds(sc);
 
@@ -832,6 +830,7 @@ void ath9k_deinit_device(struct ath_softc *sc)
        }
 
        ieee80211_unregister_hw(hw);
+       pm_qos_remove_request(&ath9k_pm_qos_req);
        ath_rx_cleanup(sc);
        ath_tx_cleanup(sc);
        ath9k_deinit_softc(sc);
index fa05b711e5cdfb7657f94ac420bc87a3f443c1ef..dddf579aacf1c391dfb3e9e73675de1a781760da 100644 (file)
 #define AR_DEVID_7010(_ah) \
        (((_ah)->hw_version.devid == 0x7010) || \
         ((_ah)->hw_version.devid == 0x7015) || \
-        ((_ah)->hw_version.devid == 0x9018))
+        ((_ah)->hw_version.devid == 0x9018) || \
+        ((_ah)->hw_version.devid == 0xA704) || \
+        ((_ah)->hw_version.devid == 0x1200))
+
+#define AR9287_HTC_DEVID(_ah) \
+       (((_ah)->hw_version.devid == 0x7015) || \
+        ((_ah)->hw_version.devid == 0x1200))
 
 #define AR_RADIO_SREV_MAJOR                   0xf0
 #define AR_RAD5133_SREV_MAJOR                 0xc0
index 3317039cd28fe5ae6b1e38ff0029bf345fd78d50..7504ed14c72575a7befb91b0c0d9dd2684660af9 100644 (file)
@@ -553,12 +553,12 @@ static int carl9170_usb_flush(struct ar9170 *ar)
                usb_free_urb(urb);
        }
 
-       ret = usb_wait_anchor_empty_timeout(&ar->tx_cmd, HZ);
+       ret = usb_wait_anchor_empty_timeout(&ar->tx_cmd, 1000);
        if (ret == 0)
                err = -ETIMEDOUT;
 
        /* lets wait a while until the tx - queues are dried out */
-       ret = usb_wait_anchor_empty_timeout(&ar->tx_anch, HZ);
+       ret = usb_wait_anchor_empty_timeout(&ar->tx_anch, 1000);
        if (ret == 0)
                err = -ETIMEDOUT;
 
index a38a7bd25f1916431bcf607a89bf4a0c126d5f8a..b9aedf18a04682dea5de87abc363546fcb054cd4 100644 (file)
@@ -57,7 +57,6 @@
 #include <linux/fcntl.h>
 #include <linux/spinlock.h>
 #include <linux/list.h>
-#include <linux/smp_lock.h>
 #include <linux/usb.h>
 #include <linux/timer.h>
 
index cce00ed81f37908fd062d34a89ad3f8f49a5d4e3..af212c6a615840e7bf777fb931ff2770d490fb5d 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/kernel.h>
 #include <linux/miscdevice.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/fs.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
index 95712a375cd521954f2a1f130a7ddf73704703cf..63d5042f2079141a8740d77fae118d9c5bb707af 100644 (file)
@@ -715,7 +715,7 @@ int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma,
        nr = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
        start = vma->vm_pgoff;
        size = ((pci_resource_len(pdev, resno) - 1) >> PAGE_SHIFT) + 1;
-       pci_start = (mmap_api == PCI_MMAP_SYSFS) ?
+       pci_start = (mmap_api == PCI_MMAP_PROCFS) ?
                        pci_resource_start(pdev, resno) >> PAGE_SHIFT : 0;
        if (start >= pci_start && start < pci_start + size &&
                        start + nr <= pci_start + size)
index ea00647f4732fcb83f60db140265e1b1465a3548..27911b55c2a52295a01bf834cbb9eacb3f9455c3 100644 (file)
@@ -10,7 +10,6 @@
 #include <linux/module.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
-#include <linux/smp_lock.h>
 #include <linux/capability.h>
 #include <asm/uaccess.h>
 #include <asm/byteorder.h>
index e73ebefdf3e0930ba979b3a3a9b348dfe181d730..315b3112aca85ece5a804778c6632a972ad32c7d 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/isapnp.h>
 #include <linux/proc_fs.h>
 #include <linux/init.h>
-#include <linux/smp_lock.h>
 #include <asm/uaccess.h>
 
 extern struct pnp_protocol isapnp_protocol;
index c71d89dba302cd1024ec3c167e5a168c390224c9..83b4615a3b62fc0faa3841dc6ded7844583b18e8 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/device.h>
 #include <linux/poll.h>
 #include <linux/mutex.h>
-#include <linux/smp_lock.h>
 #include <linux/err.h>
 #include <linux/slab.h>
 
index eb28fb01a38ad86e23580b53acf81f6a7d719745..f6489eb7e976a8c0aa1851ebbb21901d689030c1 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/list.h>
 #include <linux/slab.h>
 #include <linux/types.h>
-#include <linux/smp_lock.h>
 
 #include <asm/compat.h>
 #include <asm/ccwdev.h>
index 883e2db02bd3c8351e8195b5b45b12e84dd44fbf..e090a307fdeee341c66502d75ade8edf58f13afe 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/types.h>
 #include <linux/proc_fs.h>
 #include <linux/mtio.h>
-#include <linux/smp_lock.h>
 #include <linux/compat.h>
 
 #include <asm/uaccess.h>
index 6c408670e08d72336ecfe1e3298a6db285740787..b3a3e8e8656e6db1be5e3a50b63056c43f0897f6 100644 (file)
@@ -209,29 +209,79 @@ tape_state_set(struct tape_device *device, enum tape_state newstate)
        wake_up(&device->state_change_wq);
 }
 
+struct tape_med_state_work_data {
+       struct tape_device *device;
+       enum tape_medium_state state;
+       struct work_struct  work;
+};
+
+static void
+tape_med_state_work_handler(struct work_struct *work)
+{
+       static char env_state_loaded[] = "MEDIUM_STATE=LOADED";
+       static char env_state_unloaded[] = "MEDIUM_STATE=UNLOADED";
+       struct tape_med_state_work_data *p =
+               container_of(work, struct tape_med_state_work_data, work);
+       struct tape_device *device = p->device;
+       char *envp[] = { NULL, NULL };
+
+       switch (p->state) {
+       case MS_UNLOADED:
+               pr_info("%s: The tape cartridge has been successfully "
+                       "unloaded\n", dev_name(&device->cdev->dev));
+               envp[0] = env_state_unloaded;
+               kobject_uevent_env(&device->cdev->dev.kobj, KOBJ_CHANGE, envp);
+               break;
+       case MS_LOADED:
+               pr_info("%s: A tape cartridge has been mounted\n",
+                       dev_name(&device->cdev->dev));
+               envp[0] = env_state_loaded;
+               kobject_uevent_env(&device->cdev->dev.kobj, KOBJ_CHANGE, envp);
+               break;
+       default:
+               break;
+       }
+       tape_put_device(device);
+       kfree(p);
+}
+
+static void
+tape_med_state_work(struct tape_device *device, enum tape_medium_state state)
+{
+       struct tape_med_state_work_data *p;
+
+       p = kzalloc(sizeof(*p), GFP_ATOMIC);
+       if (p) {
+               INIT_WORK(&p->work, tape_med_state_work_handler);
+               p->device = tape_get_device(device);
+               p->state = state;
+               schedule_work(&p->work);
+       }
+}
+
 void
 tape_med_state_set(struct tape_device *device, enum tape_medium_state newstate)
 {
-       if (device->medium_state == newstate)
+       enum tape_medium_state oldstate;
+
+       oldstate = device->medium_state;
+       if (oldstate == newstate)
                return;
+       device->medium_state = newstate;
        switch(newstate){
        case MS_UNLOADED:
                device->tape_generic_status |= GMT_DR_OPEN(~0);
-               if (device->medium_state == MS_LOADED)
-                       pr_info("%s: The tape cartridge has been successfully "
-                               "unloaded\n", dev_name(&device->cdev->dev));
+               if (oldstate == MS_LOADED)
+                       tape_med_state_work(device, MS_UNLOADED);
                break;
        case MS_LOADED:
                device->tape_generic_status &= ~GMT_DR_OPEN(~0);
-               if (device->medium_state == MS_UNLOADED)
-                       pr_info("%s: A tape cartridge has been mounted\n",
-                               dev_name(&device->cdev->dev));
+               if (oldstate == MS_UNLOADED)
+                       tape_med_state_work(device, MS_LOADED);
                break;
        default:
-               // print nothing
                break;
        }
-       device->medium_state = newstate;
        wake_up(&device->state_change_wq);
 }
 
index 9f661426e4a1e28494bbe3054ee412696e0a6ad1..c837d7419a6a974b55383be923e4e4939c00bb62 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/kmod.h>
 #include <linux/cdev.h>
 #include <linux/device.h>
-#include <linux/smp_lock.h>
 #include <linux/string.h>
 
 MODULE_AUTHOR
@@ -249,27 +248,25 @@ static int vmlogrdr_recording(struct vmlogrdr_priv_t * logptr,
        char cp_command[80];
        char cp_response[160];
        char *onoff, *qid_string;
+       int rc;
 
-       memset(cp_command, 0x00, sizeof(cp_command));
-       memset(cp_response, 0x00, sizeof(cp_response));
-
-        onoff = ((action == 1) ? "ON" : "OFF");
+       onoff = ((action == 1) ? "ON" : "OFF");
        qid_string = ((recording_class_AB == 1) ? " QID * " : "");
 
-        /*
+       /*
         * The recording commands needs to be called with option QID
         * for guests that have previlege classes A or B.
         * Purging has to be done as separate step, because recording
         * can't be switched on as long as records are on the queue.
         * Doing both at the same time doesn't work.
         */
-
-       if (purge) {
+       if (purge && (action == 1)) {
+               memset(cp_command, 0x00, sizeof(cp_command));
+               memset(cp_response, 0x00, sizeof(cp_response));
                snprintf(cp_command, sizeof(cp_command),
                         "RECORDING %s PURGE %s",
                         logptr->recording_name,
                         qid_string);
-
                cpcmd(cp_command, cp_response, sizeof(cp_response), NULL);
        }
 
@@ -279,19 +276,33 @@ static int vmlogrdr_recording(struct vmlogrdr_priv_t * logptr,
                logptr->recording_name,
                onoff,
                qid_string);
-
        cpcmd(cp_command, cp_response, sizeof(cp_response), NULL);
        /* The recording command will usually answer with 'Command complete'
         * on success, but when the specific service was never connected
         * before then there might be an additional informational message
         * 'HCPCRC8072I Recording entry not found' before the
-         * 'Command complete'. So I use strstr rather then the strncmp.
+        * 'Command complete'. So I use strstr rather then the strncmp.
         */
        if (strstr(cp_response,"Command complete"))
-               return 0;
+               rc = 0;
        else
-               return -EIO;
+               rc = -EIO;
+       /*
+        * If we turn recording off, we have to purge any remaining records
+        * afterwards, as a large number of queued records may impact z/VM
+        * performance.
+        */
+       if (purge && (action == 0)) {
+               memset(cp_command, 0x00, sizeof(cp_command));
+               memset(cp_response, 0x00, sizeof(cp_response));
+               snprintf(cp_command, sizeof(cp_command),
+                        "RECORDING %s PURGE %s",
+                        logptr->recording_name,
+                        qid_string);
+               cpcmd(cp_command, cp_response, sizeof(cp_response), NULL);
+       }
 
+       return rc;
 }
 
 
index 1de672f21037bd70f57e06b4abcd43a89b65a864..f7e4ae6bf15a5be647bdf4a0223a228880d368a5 100644 (file)
@@ -13,7 +13,6 @@
 
 #include <linux/cdev.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 
 #include <asm/uaccess.h>
 #include <asm/cio.h>
index 2ff8a22d42574242eb0a07c1ab1d38f73cc81d6b..e8391b89eff4bbbcb41896b3232c05a4070d8917 100644 (file)
@@ -1455,7 +1455,16 @@ static int io_subchannel_sch_event(struct subchannel *sch, int process)
                break;
        case IO_SCH_UNREG_ATTACH:
        case IO_SCH_UNREG:
-               if (cdev)
+               if (!cdev)
+                       break;
+               if (cdev->private->state == DEV_STATE_SENSE_ID) {
+                       /*
+                        * Note: delayed work triggered by this event
+                        * and repeated calls to sch_event are synchronized
+                        * by the above check for work_pending(cdev).
+                        */
+                       dev_fsm_event(cdev, DEV_EVENT_NOTOPER);
+               } else
                        ccw_device_set_notoper(cdev);
                break;
        case IO_SCH_NOP:
index f5221749d18069dcbb7f917b0bbd09ccadba8dcc..7fca9c10ffcfad9b0901e7ae53fcac9b06697d82 100644 (file)
@@ -35,7 +35,6 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/compat.h>
-#include <linux/smp_lock.h>
 #include <linux/slab.h>
 #include <asm/atomic.h>
 #include <asm/uaccess.h>
index 50286d8707f305b981c1e56ffa02df7b3ce3b0d9..6bd2dbc4c31606d5019fb1e76d92ef88583a2140 100644 (file)
@@ -76,7 +76,7 @@ static void zfcp_scsi_command_fail(struct scsi_cmnd *scpnt, int result)
        scpnt->scsi_done(scpnt);
 }
 
-static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt,
+static int zfcp_scsi_queuecommand_lck(struct scsi_cmnd *scpnt,
                                  void (*done) (struct scsi_cmnd *))
 {
        struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scpnt->device);
@@ -127,6 +127,8 @@ static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt,
        return ret;
 }
 
+static DEF_SCSI_QCMD(zfcp_scsi_queuecommand)
+
 static int zfcp_scsi_slave_alloc(struct scsi_device *sdev)
 {
        struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
index fcf08b3f52c1f2ee6b514c0b88ad2985c4f814da..b7bd5b0cc7aa450e23ebe7f8b0ddc10814b82f05 100644 (file)
@@ -1765,7 +1765,7 @@ out:
 } /* End twa_scsi_eh_reset() */
 
 /* This is the main scsi queue function to handle scsi opcodes */
-static int twa_scsi_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
+static int twa_scsi_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
 {
        int request_id, retval;
        TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
@@ -1812,6 +1812,8 @@ out:
        return retval;
 } /* End twa_scsi_queue() */
 
+static DEF_SCSI_QCMD(twa_scsi_queue)
+
 /* This function hands scsi cdb's to the firmware */
 static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, char *cdb, int use_sg, TW_SG_Entry *sglistarg)
 {
index 6a95d111d207269a920fc57c8ceee220ac5d42d8..13e39e1fdfe288b88e9aded1305e21240debc48e 100644 (file)
@@ -1501,7 +1501,7 @@ out:
 } /* End twl_scsi_eh_reset() */
 
 /* This is the main scsi queue function to handle scsi opcodes */
-static int twl_scsi_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
+static int twl_scsi_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
 {
        int request_id, retval;
        TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
@@ -1536,6 +1536,8 @@ out:
        return retval;
 } /* End twl_scsi_queue() */
 
+static DEF_SCSI_QCMD(twl_scsi_queue)
+
 /* This function tells the controller to shut down */
 static void __twl_shutdown(TW_Device_Extension *tw_dev)
 {
index b1125341f4c89431521f978ca850135603f2c779..7fe96ff60c581c324a4eaecbf79d8c2e083bf7f8 100644 (file)
@@ -1947,7 +1947,7 @@ static int tw_scsiop_test_unit_ready_complete(TW_Device_Extension *tw_dev, int r
 } /* End tw_scsiop_test_unit_ready_complete() */
 
 /* This is the main scsi queue function to handle scsi opcodes */
-static int tw_scsi_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) 
+static int tw_scsi_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
 {
        unsigned char *command = SCpnt->cmnd;
        int request_id = 0;
@@ -2023,6 +2023,8 @@ static int tw_scsi_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd
        return retval;
 } /* End tw_scsi_queue() */
 
+static DEF_SCSI_QCMD(tw_scsi_queue)
+
 /* This function is the interrupt service routine */
 static irqreturn_t tw_interrupt(int irq, void *dev_instance) 
 {
index 89fc1c8af86b8774000233247fce6c880187f910..f672491774eb61756c2a36f8af3a36496a7ea53c 100644 (file)
@@ -167,7 +167,7 @@ MODULE_LICENSE("GPL");
 #include "53c700_d.h"
 
 
-STATIC int NCR_700_queuecommand(struct scsi_cmnd *, void (*done)(struct scsi_cmnd *));
+STATIC int NCR_700_queuecommand(struct Scsi_Host *h, struct scsi_cmnd *);
 STATIC int NCR_700_abort(struct scsi_cmnd * SCpnt);
 STATIC int NCR_700_bus_reset(struct scsi_cmnd * SCpnt);
 STATIC int NCR_700_host_reset(struct scsi_cmnd * SCpnt);
@@ -1749,8 +1749,8 @@ NCR_700_intr(int irq, void *dev_id)
        return IRQ_RETVAL(handled);
 }
 
-STATIC int
-NCR_700_queuecommand(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *))
+static int
+NCR_700_queuecommand_lck(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *))
 {
        struct NCR_700_Host_Parameters *hostdata = 
                (struct NCR_700_Host_Parameters *)SCp->device->host->hostdata[0];
@@ -1904,6 +1904,8 @@ NCR_700_queuecommand(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *))
        return 0;
 }
 
+STATIC DEF_SCSI_QCMD(NCR_700_queuecommand)
+
 STATIC int
 NCR_700_abort(struct scsi_cmnd * SCp)
 {
index fc0b4b81d5522ddaff339d3dc6187ce72a4c7d9a..f66c33b9ab41ac7333d99f3f3423ce497e47ae1d 100644 (file)
@@ -2807,7 +2807,7 @@ static int BusLogic_host_reset(struct scsi_cmnd * SCpnt)
   Outgoing Mailbox for execution by the associated Host Adapter.
 */
 
-static int BusLogic_QueueCommand(struct scsi_cmnd *Command, void (*CompletionRoutine) (struct scsi_cmnd *))
+static int BusLogic_QueueCommand_lck(struct scsi_cmnd *Command, void (*CompletionRoutine) (struct scsi_cmnd *))
 {
        struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) Command->device->host->hostdata;
        struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[Command->device->id];
@@ -2994,6 +2994,7 @@ static int BusLogic_QueueCommand(struct scsi_cmnd *Command, void (*CompletionRou
        return 0;
 }
 
+static DEF_SCSI_QCMD(BusLogic_QueueCommand)
 
 #if 0
 /*
index 73f237a1ed94f6e81ca686ba58a280e54e7056be..649fcb31f26da8e9b5269443574aa82a3dc45fa8 100644 (file)
@@ -1319,7 +1319,7 @@ static inline void BusLogic_IncrementSizeBucket(BusLogic_CommandSizeBuckets_T Co
 */
 
 static const char *BusLogic_DriverInfo(struct Scsi_Host *);
-static int BusLogic_QueueCommand(struct scsi_cmnd *, void (*CompletionRoutine) (struct scsi_cmnd *));
+static int BusLogic_QueueCommand(struct Scsi_Host *h, struct scsi_cmnd *);
 static int BusLogic_BIOSDiskParameters(struct scsi_device *, struct block_device *, sector_t, int *);
 static int BusLogic_ProcDirectoryInfo(struct Scsi_Host *, char *, char **, off_t, int, int);
 static int BusLogic_SlaveConfigure(struct scsi_device *);
index 5d2f148889adc117f90f2d0650ad2d2aeda047a5..9a5629f94f95aba802857a6d5162db4745235c8a 100644 (file)
@@ -952,7 +952,7 @@ static void NCR5380_exit(struct Scsi_Host *instance)
  *     Locks: host lock taken by caller
  */
 
-static int NCR5380_queue_command(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) 
+static int NCR5380_queue_command_lck(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
 {
        struct Scsi_Host *instance = cmd->device->host;
        struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
@@ -1021,6 +1021,7 @@ static int NCR5380_queue_command(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
        return 0;
 }
 
+static DEF_SCSI_QCMD(NCR5380_queue_command)
 
 /**
  *     NCR5380_main    -       NCR state machines
index bdc468c9e1d9d6de71ba091041096fd831512ee7..fd40a32b1f6f2d3690ac5d63c361cb9ece6a2120 100644 (file)
@@ -313,7 +313,7 @@ static void NCR5380_print(struct Scsi_Host *instance);
 #endif
 static int NCR5380_abort(Scsi_Cmnd * cmd);
 static int NCR5380_bus_reset(Scsi_Cmnd * cmd);
-static int NCR5380_queue_command(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *));
+static int NCR5380_queue_command(struct Scsi_Host *, struct scsi_cmnd *);
 static int __maybe_unused NCR5380_proc_info(struct Scsi_Host *instance,
        char *buffer, char **start, off_t offset, int length, int inout);
 
index 6961f78742aedbc86de34d810891737eeece4ec9..c91888a0a23cacf61354f0a3f1fdd1f3a08caef2 100644 (file)
@@ -693,7 +693,7 @@ static void wait_intr(void)
 }
 #endif
 
-static int NCR53c406a_queue(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
+static int NCR53c406a_queue_lck(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
 {
        int i;
 
@@ -726,6 +726,8 @@ static int NCR53c406a_queue(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
        return 0;
 }
 
+static DEF_SCSI_QCMD(NCR53c406a_queue)
+
 static int NCR53c406a_host_reset(Scsi_Cmnd * SCpnt)
 {
        DEB(printk("NCR53c406a_reset called\n"));
index dbbc601948e5328e4c9a0bbfeb18ee8ac7f7fd91..dc5ac6e528c4febb2b6dbdc51953a08cfe934938 100644 (file)
@@ -911,7 +911,7 @@ static int inia100_build_scb(struct orc_host * host, struct orc_scb * scb, struc
  *     queue the command down to the controller
  */
 
-static int inia100_queue(struct scsi_cmnd * cmd, void (*done) (struct scsi_cmnd *))
+static int inia100_queue_lck(struct scsi_cmnd * cmd, void (*done) (struct scsi_cmnd *))
 {
        struct orc_scb *scb;
        struct orc_host *host;          /* Point to Host adapter control block */
@@ -930,6 +930,8 @@ static int inia100_queue(struct scsi_cmnd * cmd, void (*done) (struct scsi_cmnd
        return 0;
 }
 
+static DEF_SCSI_QCMD(inia100_queue)
+
 /*****************************************************************************
  Function name  : inia100_abort
  Description    : Abort a queued command.
index 29c0ed1cf50753ba8b674c1193d97c1af4d31624..2c93d9496d62dae64b4c2aaf0b78e60edc61ba17 100644 (file)
@@ -248,7 +248,7 @@ static struct aac_driver_ident aac_drivers[] = {
  *     TODO: unify with aac_scsi_cmd().
  */
 
-static int aac_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
+static int aac_queuecommand_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
 {
        struct Scsi_Host *host = cmd->device->host;
        struct aac_dev *dev = (struct aac_dev *)host->hostdata;
@@ -267,6 +267,8 @@ static int aac_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd
        return (aac_scsi_cmd(cmd) ? FAILED : 0);
 }
 
+static DEF_SCSI_QCMD(aac_queuecommand)
+
 /**
  *     aac_info                -       Returns the host adapter name
  *     @shost:         Scsi host to report on
index 0ec3da6f3e12133823588e280fea24cc364cbe03..081c6de92bc5b5e060f3bf20eebbfa1e8b58c5c2 100644 (file)
@@ -9500,7 +9500,7 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
  * in the 'scp' result field.
  */
 static int
-advansys_queuecommand(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *))
+advansys_queuecommand_lck(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *))
 {
        struct Scsi_Host *shost = scp->device->host;
        int asc_res, result = 0;
@@ -9525,6 +9525,8 @@ advansys_queuecommand(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *))
        return result;
 }
 
+static DEF_SCSI_QCMD(advansys_queuecommand)
+
 static ushort __devinit AscGetEisaChipCfg(PortAddr iop_base)
 {
        PortAddr eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
index 8eab8587ff21b6c35bb31129fd62a30d8ddc9f06..c5169f01c1cdb8502e19111b8bfb175da0b1c585 100644 (file)
@@ -1056,7 +1056,7 @@ static int aha152x_internal_queue(Scsi_Cmnd *SCpnt, struct completion *complete,
  *  queue a command
  *
  */
-static int aha152x_queue(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
+static int aha152x_queue_lck(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
 {
 #if 0
        if(*SCpnt->cmnd == REQUEST_SENSE) {
@@ -1070,6 +1070,8 @@ static int aha152x_queue(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
        return aha152x_internal_queue(SCpnt, NULL, 0, done);
 }
 
+static DEF_SCSI_QCMD(aha152x_queue)
+
 
 /*
  *  
index 4f785f254c1f7f7619f25f0beb4a966c4b733ec4..195823a51aab5292e6ec43183d0e0829b6d9ff93 100644 (file)
@@ -558,7 +558,7 @@ static void aha1542_intr_handle(struct Scsi_Host *shost)
        };
 }
 
-static int aha1542_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
+static int aha1542_queuecommand_lck(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
 {
        unchar ahacmd = CMD_START_SCSI;
        unchar direction;
@@ -718,6 +718,8 @@ static int aha1542_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
        return 0;
 }
 
+static DEF_SCSI_QCMD(aha1542_queuecommand)
+
 /* Initialize mailboxes */
 static void setup_mailboxes(int bse, struct Scsi_Host *shpnt)
 {
index 1db538552d56b59faaf5053a1e93fcd0dff1c167..b871d2b57f93235652d55761cc66617f2a52c291 100644 (file)
@@ -132,7 +132,7 @@ struct ccb {                        /* Command Control Block 5.3 */
 };
 
 static int aha1542_detect(struct scsi_host_template *);
-static int aha1542_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+static int aha1542_queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
 static int aha1542_bus_reset(Scsi_Cmnd * SCpnt);
 static int aha1542_dev_reset(Scsi_Cmnd * SCpnt);
 static int aha1542_host_reset(Scsi_Cmnd * SCpnt);
index 0107a4cc33319bfef8c8e22cb5dbde9e9a700fe8..d058f1ab82b5612c328bafeba1b48a89c311f2a1 100644 (file)
@@ -331,7 +331,7 @@ static irqreturn_t aha1740_intr_handle(int irq, void *dev_id)
        return IRQ_RETVAL(handled);
 }
 
-static int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
+static int aha1740_queuecommand_lck(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
 {
        unchar direction;
        unchar *cmd = (unchar *) SCpnt->cmnd;
@@ -503,6 +503,8 @@ static int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
        return 0;
 }
 
+static DEF_SCSI_QCMD(aha1740_queuecommand)
+
 /* Query the board for its irq_level and irq_type.  Nothing else matters
    in enhanced mode on an EISA bus. */
 
index 88ad8482ef59b6e33cbdfeafe2d1c962ee05be8b..25d066624476e3b60ac0119d803f75bdfe5d721b 100644 (file)
@@ -573,7 +573,7 @@ ahd_linux_info(struct Scsi_Host *host)
  * Queue an SCB to the controller.
  */
 static int
-ahd_linux_queue(struct scsi_cmnd * cmd, void (*scsi_done) (struct scsi_cmnd *))
+ahd_linux_queue_lck(struct scsi_cmnd * cmd, void (*scsi_done) (struct scsi_cmnd *))
 {
        struct   ahd_softc *ahd;
        struct   ahd_linux_device *dev = scsi_transport_device_data(cmd->device);
@@ -588,6 +588,8 @@ ahd_linux_queue(struct scsi_cmnd * cmd, void (*scsi_done) (struct scsi_cmnd *))
        return rtn;
 }
 
+static DEF_SCSI_QCMD(ahd_linux_queue)
+
 static struct scsi_target **
 ahd_linux_target_in_softc(struct scsi_target *starget)
 {
index aeea7a61478e8bca16357299bf33dd5fdf2d2292..4a359bb307c6e38cc9e17cfc547968b6271b98d8 100644 (file)
@@ -528,7 +528,7 @@ ahc_linux_info(struct Scsi_Host *host)
  * Queue an SCB to the controller.
  */
 static int
-ahc_linux_queue(struct scsi_cmnd * cmd, void (*scsi_done) (struct scsi_cmnd *))
+ahc_linux_queue_lck(struct scsi_cmnd * cmd, void (*scsi_done) (struct scsi_cmnd *))
 {
        struct   ahc_softc *ahc;
        struct   ahc_linux_device *dev = scsi_transport_device_data(cmd->device);
@@ -548,6 +548,8 @@ ahc_linux_queue(struct scsi_cmnd * cmd, void (*scsi_done) (struct scsi_cmnd *))
        return rtn;
 }
 
+static DEF_SCSI_QCMD(ahc_linux_queue)
+
 static inline struct scsi_target **
 ahc_linux_target_in_softc(struct scsi_target *starget)
 {
index aee73fafccc834d5922baf4f5322bfede654464b..4ff60a08df0f184c2c84ed32093669e006a39b59 100644 (file)
@@ -10234,7 +10234,7 @@ static void aic7xxx_buildscb(struct aic7xxx_host *p, struct scsi_cmnd *cmd,
  * Description:
  *   Queue a SCB to the controller.
  *-F*************************************************************************/
-static int aic7xxx_queue(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *))
+static int aic7xxx_queue_lck(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *))
 {
   struct aic7xxx_host *p;
   struct aic7xxx_scb *scb;
@@ -10292,6 +10292,8 @@ static int aic7xxx_queue(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *))
   return (0);
 }
 
+static DEF_SCSI_QCMD(aic7xxx_queue)
+
 /*+F*************************************************************************
  * Function:
  *   aic7xxx_bus_device_reset
index 05a78e515a24101caa7dd6d9b4891cfe86312d3d..17e3df4f016f6590cc86aac3ccc586add42cb2c6 100644 (file)
@@ -85,8 +85,7 @@ static int arcmsr_abort(struct scsi_cmnd *);
 static int arcmsr_bus_reset(struct scsi_cmnd *);
 static int arcmsr_bios_param(struct scsi_device *sdev,
                struct block_device *bdev, sector_t capacity, int *info);
-static int arcmsr_queue_command(struct scsi_cmnd *cmd,
-                                       void (*done) (struct scsi_cmnd *));
+static int arcmsr_queue_command(struct Scsi_Host *h, struct scsi_cmnd *cmd);
 static int arcmsr_probe(struct pci_dev *pdev,
                                const struct pci_device_id *id);
 static void arcmsr_remove(struct pci_dev *pdev);
@@ -2081,7 +2080,7 @@ static void arcmsr_handle_virtual_command(struct AdapterControlBlock *acb,
        }
 }
 
-static int arcmsr_queue_command(struct scsi_cmnd *cmd,
+static int arcmsr_queue_command_lck(struct scsi_cmnd *cmd,
        void (* done)(struct scsi_cmnd *))
 {
        struct Scsi_Host *host = cmd->device->host;
@@ -2124,6 +2123,8 @@ static int arcmsr_queue_command(struct scsi_cmnd *cmd,
        return 0;
 }
 
+static DEF_SCSI_QCMD(arcmsr_queue_command)
+
 static bool arcmsr_get_hba_config(struct AdapterControlBlock *acb)
 {
        struct MessageUnit_A __iomem *reg = acb->pmuA;
index 918ccf8187577f1954f33084d33a77210a53fa48..ec166726b3149d2a270ffc3f1a491262b8c4dcd5 100644 (file)
@@ -2511,7 +2511,7 @@ acornscsi_intr(int irq, void *dev_id)
  *           done - function called on completion, with pointer to command descriptor
  * Returns  : 0, or < 0 on error.
  */
-int acornscsi_queuecmd(struct scsi_cmnd *SCpnt,
+static int acornscsi_queuecmd_lck(struct scsi_cmnd *SCpnt,
                       void (*done)(struct scsi_cmnd *))
 {
     AS_Host *host = (AS_Host *)SCpnt->device->host->hostdata;
@@ -2561,6 +2561,8 @@ int acornscsi_queuecmd(struct scsi_cmnd *SCpnt,
     return 0;
 }
 
+DEF_SCSI_QCMD(acornscsi_queuecmd)
+
 /*
  * Prototype: void acornscsi_reportstatus(struct scsi_cmnd **SCpntp1, struct scsi_cmnd **SCpntp2, int result)
  * Purpose  : pass a result to *SCpntp1, and check if *SCpntp1 = *SCpntp2
index 9e71ac611146ab86432664af1c2a40c7d2070ea0..2b2ce21e227ea95200ec437f2d2a29f7d1cc356e 100644 (file)
@@ -2198,7 +2198,7 @@ no_command:
  * Returns: 0 on success, else error.
  * Notes: io_request_lock is held, interrupts are disabled.
  */
-int fas216_queue_command(struct scsi_cmnd *SCpnt,
+static int fas216_queue_command_lck(struct scsi_cmnd *SCpnt,
                         void (*done)(struct scsi_cmnd *))
 {
        FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
@@ -2240,6 +2240,8 @@ int fas216_queue_command(struct scsi_cmnd *SCpnt,
        return result;
 }
 
+DEF_SCSI_QCMD(fas216_queue_command)
+
 /**
  * fas216_internal_done - trigger restart of a waiting thread in fas216_noqueue_command
  * @SCpnt: Command to wake
@@ -2263,7 +2265,7 @@ static void fas216_internal_done(struct scsi_cmnd *SCpnt)
  * Returns: scsi result code.
  * Notes: io_request_lock is held, interrupts are disabled.
  */
-int fas216_noqueue_command(struct scsi_cmnd *SCpnt,
+static int fas216_noqueue_command_lck(struct scsi_cmnd *SCpnt,
                           void (*done)(struct scsi_cmnd *))
 {
        FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
@@ -2277,7 +2279,7 @@ int fas216_noqueue_command(struct scsi_cmnd *SCpnt,
        BUG_ON(info->scsi.irq != NO_IRQ);
 
        info->internal_done = 0;
-       fas216_queue_command(SCpnt, fas216_internal_done);
+       fas216_queue_command_lck(SCpnt, fas216_internal_done);
 
        /*
         * This wastes time, since we can't return until the command is
@@ -2310,6 +2312,8 @@ int fas216_noqueue_command(struct scsi_cmnd *SCpnt,
        return 0;
 }
 
+DEF_SCSI_QCMD(fas216_noqueue_command)
+
 /*
  * Error handler timeout function.  Indicate that we timed out,
  * and wake up any error handler process so it can continue.
index b65f4cf0eec9929af885e1346ff004b16970984f..377cfb72cc66ade722b441f6842c1f0ed3d7fc3b 100644 (file)
@@ -331,23 +331,21 @@ extern int fas216_init (struct Scsi_Host *instance);
  */
 extern int fas216_add (struct Scsi_Host *instance, struct device *dev);
 
-/* Function: int fas216_queue_command(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
+/* Function: int fas216_queue_command(struct Scsi_Host *h, struct scsi_cmnd *SCpnt)
  * Purpose : queue a command for adapter to process.
- * Params  : SCpnt - Command to queue
- *          done  - done function to call once command is complete
+ * Params  : h - host adapter
+ *        : SCpnt - Command to queue
  * Returns : 0 - success, else error
  */
-extern int fas216_queue_command(struct scsi_cmnd *,
-                               void (*done)(struct scsi_cmnd *));
+extern int fas216_queue_command(struct Scsi_Host *h, struct scsi_cmnd *SCpnt);
 
-/* Function: int fas216_noqueue_command(istruct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
+/* Function: int fas216_noqueue_command(struct Scsi_Host *h, struct scsi_cmnd *SCpnt)
  * Purpose : queue a command for adapter to process, and process it to completion.
- * Params  : SCpnt - Command to queue
- *          done  - done function to call once command is complete
+ * Params  : h - host adapter
+ *        : SCpnt - Command to queue
  * Returns : 0 - success, else error
  */
-extern int fas216_noqueue_command(struct scsi_cmnd *,
-                                 void (*done)(struct scsi_cmnd *));
+extern int fas216_noqueue_command(struct Scsi_Host *, struct scsi_cmnd *)
 
 /* Function: irqreturn_t fas216_intr (FAS216_Info *info)
  * Purpose : handle interrupts from the interface to progress a command
index 158ebc3644d83f2188a1e0007950799db4246652..88b2928b4d3b76a18cf9d8354d8350dd9f5f745c 100644 (file)
@@ -910,7 +910,7 @@ static int __init NCR5380_init(struct Scsi_Host *instance, int flags)
  *
  */
 
-static int NCR5380_queue_command(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
+static int NCR5380_queue_command_lck(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
 {
        SETUP_HOSTDATA(cmd->device->host);
        Scsi_Cmnd *tmp;
@@ -1022,6 +1022,8 @@ static int NCR5380_queue_command(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
        return 0;
 }
 
+static DEF_SCSI_QCMD(NCR5380_queue_command)
+
 /*
  * Function : NCR5380_main (void)
  *
index ad7a23aef0ecf29536a21fe64d4f27874ddb6173..3e8658e2f154b82a0e5ad05e628d710f0c1c61e7 100644 (file)
@@ -572,23 +572,6 @@ static void falcon_get_lock(void)
 }
 
 
-/* This is the wrapper function for NCR5380_queue_command(). It just
- * tries to get the lock on the ST-DMA (see above) and then calls the
- * original function.
- */
-
-#if 0
-int atari_queue_command(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
-{
-       /* falcon_get_lock();
-        * ++guenther: moved to NCR5380_queue_command() to prevent
-        * race condition, see there for an explanation.
-        */
-       return NCR5380_queue_command(cmd, done);
-}
-#endif
-
-
 int __init atari_scsi_detect(struct scsi_host_template *host)
 {
        static int called = 0;
index ab5bdda6903e3f6f650fa63c203ab6401bcd71a4..76029d570beb8634c121c47f6a7eb5e906df9a14 100644 (file)
@@ -605,7 +605,7 @@ handled:
  *
  *     Queue a command to the ATP queue. Called with the host lock held.
  */
-static int atp870u_queuecommand(struct scsi_cmnd * req_p, 
+static int atp870u_queuecommand_lck(struct scsi_cmnd *req_p,
                         void (*done) (struct scsi_cmnd *))
 {
        unsigned char c;
@@ -694,6 +694,8 @@ static int atp870u_queuecommand(struct scsi_cmnd * req_p,
        return 0;
 }
 
+static DEF_SCSI_QCMD(atp870u_queuecommand)
+
 /**
  *     send_s870       -       send a command to the controller
  *     @host: host
index 8daa716739d1bd6d2a6a4180c008161e7f148f27..8ca967dee66d4eac1b551c82ff5416454e0ffcb6 100644 (file)
@@ -30,8 +30,7 @@ DEFINE_IDR(bfad_im_port_index);
 struct scsi_transport_template *bfad_im_scsi_transport_template;
 struct scsi_transport_template *bfad_im_scsi_vport_transport_template;
 static void bfad_im_itnim_work_handler(struct work_struct *work);
-static int bfad_im_queuecommand(struct scsi_cmnd *cmnd,
-                               void (*done)(struct scsi_cmnd *));
+static int bfad_im_queuecommand(struct Scsi_Host *h, struct scsi_cmnd *cmnd);
 static int bfad_im_slave_alloc(struct scsi_device *sdev);
 static void bfad_im_fc_rport_add(struct bfad_im_port_s  *im_port,
                                struct bfad_itnim_s *itnim);
@@ -1120,7 +1119,7 @@ bfad_im_itnim_work_handler(struct work_struct *work)
  * Scsi_Host template entry, queue a SCSI command to the BFAD.
  */
 static int
-bfad_im_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
+bfad_im_queuecommand_lck(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
 {
        struct bfad_im_port_s *im_port =
                (struct bfad_im_port_s *) cmnd->device->host->hostdata[0];
@@ -1187,6 +1186,8 @@ out_fail_cmd:
        return 0;
 }
 
+static DEF_SCSI_QCMD(bfad_im_queuecommand)
+
 void
 bfad_os_rport_online_wait(struct bfad_s *bfad)
 {
index 54f50b07dac7f36fe5950efb9bdaf34340d4bbed..8f1b5c8bf903bba0e32e398aeaf776915b42890a 100644 (file)
@@ -1080,7 +1080,7 @@ static void build_srb(struct scsi_cmnd *cmd, struct DeviceCtlBlk *dcb,
  *        and is expected to be held on return.
  *
  **/
-static int dc395x_queue_command(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
+static int dc395x_queue_command_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
 {
        struct DeviceCtlBlk *dcb;
        struct ScsiReqBlk *srb;
@@ -1154,6 +1154,7 @@ complete:
        return 0;
 }
 
+static DEF_SCSI_QCMD(dc395x_queue_command)
 
 /*
  * Return the disk geometry for the given SCSI device.
index 23dec006338512a479e60b5e9d0c5281dde2beca..cffcb108ac9639b4fd0a8ea4b32d503206fae319 100644 (file)
@@ -423,7 +423,7 @@ static int adpt_slave_configure(struct scsi_device * device)
        return 0;
 }
 
-static int adpt_queue(struct scsi_cmnd * cmd, void (*done) (struct scsi_cmnd *))
+static int adpt_queue_lck(struct scsi_cmnd * cmd, void (*done) (struct scsi_cmnd *))
 {
        adpt_hba* pHba = NULL;
        struct adpt_device* pDev = NULL;        /* dpt per device information */
@@ -491,6 +491,8 @@ static int adpt_queue(struct scsi_cmnd * cmd, void (*done) (struct scsi_cmnd *))
        return adpt_scsi_to_i2o(pHba, cmd, pDev);
 }
 
+static DEF_SCSI_QCMD(adpt_queue)
+
 static int adpt_bios_param(struct scsi_device *sdev, struct block_device *dev,
                sector_t capacity, int geom[])
 {
index 337746d460438417281d25c3aa9aec863f3e002d..beded716f93f4cbf4e929e9a354bba46d4c18be2 100644 (file)
@@ -29,7 +29,7 @@
  */
 
 static int adpt_detect(struct scsi_host_template * sht);
-static int adpt_queue(struct scsi_cmnd * cmd, void (*cmdcomplete) (struct scsi_cmnd *));
+static int adpt_queue(struct Scsi_Host *h, struct scsi_cmnd * cmd);
 static int adpt_abort(struct scsi_cmnd * cmd);
 static int adpt_reset(struct scsi_cmnd* cmd);
 static int adpt_release(struct Scsi_Host *host);
index 0b205f8c732682583b1d939a408066615b07fa22..cdc621204b667bb4dd317fd09b137afb6950c79b 100644 (file)
@@ -36,7 +36,7 @@ static int dtc_abort(Scsi_Cmnd *);
 static int dtc_biosparam(struct scsi_device *, struct block_device *,
                         sector_t, int*);
 static int dtc_detect(struct scsi_host_template *);
-static int dtc_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+static int dtc_queue_command(struct Scsi_Host *, struct scsi_cmnd *);
 static int dtc_bus_reset(Scsi_Cmnd *);
 
 #ifndef CMD_PER_LUN
index d1c31378f6da9823b67e895ae7143578cfa110ee..53925ac178fd1b13fd11747ec2fefa8033f00fa7 100644 (file)
 
 static int eata2x_detect(struct scsi_host_template *);
 static int eata2x_release(struct Scsi_Host *);
-static int eata2x_queuecommand(struct scsi_cmnd *,
-                              void (*done) (struct scsi_cmnd *));
+static int eata2x_queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
 static int eata2x_eh_abort(struct scsi_cmnd *);
 static int eata2x_eh_host_reset(struct scsi_cmnd *);
 static int eata2x_bios_param(struct scsi_device *, struct block_device *,
@@ -1758,7 +1757,7 @@ static void scsi_to_dev_dir(unsigned int i, struct hostdata *ha)
 
 }
 
-static int eata2x_queuecommand(struct scsi_cmnd *SCpnt,
+static int eata2x_queuecommand_lck(struct scsi_cmnd *SCpnt,
                               void (*done) (struct scsi_cmnd *))
 {
        struct Scsi_Host *shost = SCpnt->device->host;
@@ -1843,6 +1842,8 @@ static int eata2x_queuecommand(struct scsi_cmnd *SCpnt,
        return 0;
 }
 
+static DEF_SCSI_QCMD(eata2x_queuecommand)
+
 static int eata2x_eh_abort(struct scsi_cmnd *SCarg)
 {
        struct Scsi_Host *shost = SCarg->device->host;
index 60886c19065e290a4475822d183aa92c8dc4de0c..4a9641e69f54853860e9f6b82999c0955fcb00e4 100644 (file)
@@ -335,7 +335,7 @@ static inline unsigned int eata_pio_send_command(unsigned long base, unsigned ch
        return 0;
 }
 
-static int eata_pio_queue(struct scsi_cmnd *cmd,
+static int eata_pio_queue_lck(struct scsi_cmnd *cmd,
                void (*done)(struct scsi_cmnd *))
 {
        unsigned int x, y;
@@ -438,6 +438,8 @@ static int eata_pio_queue(struct scsi_cmnd *cmd,
        return 0;
 }
 
+static DEF_SCSI_QCMD(eata_pio_queue)
+
 static int eata_pio_abort(struct scsi_cmnd *cmd)
 {
        unsigned int loop = 100;
index e2bc779f86c1d4c7be559eb018904ac3d58ff0a6..57558523c1b8cd67ba8e83aacf8691eba8205928 100644 (file)
@@ -916,7 +916,7 @@ static void esp_event_queue_full(struct esp *esp, struct esp_cmd_entry *ent)
        scsi_track_queue_full(dev, lp->num_tagged - 1);
 }
 
-static int esp_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
+static int esp_queuecommand_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
 {
        struct scsi_device *dev = cmd->device;
        struct esp *esp = shost_priv(dev->host);
@@ -941,6 +941,8 @@ static int esp_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd
        return 0;
 }
 
+static DEF_SCSI_QCMD(esp_queuecommand)
+
 static int esp_check_gross_error(struct esp *esp)
 {
        if (esp->sreg & ESP_STAT_SPAM) {
index 2ad95aa8f58536a664a4c7d2114c4505d27355fe..a2c6135d337edab43838a94ee9c9ffc1061b216a 100644 (file)
@@ -1072,7 +1072,7 @@ static int fd_mcs_release(struct Scsi_Host *shpnt)
        return 0;
 }
 
-static int fd_mcs_queue(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
+static int fd_mcs_queue_lck(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
 {
        struct Scsi_Host *shpnt = SCpnt->device->host;
 
@@ -1122,6 +1122,8 @@ static int fd_mcs_queue(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
        return 0;
 }
 
+static DEF_SCSI_QCMD(fd_mcs_queue)
+
 #if DEBUG_ABORT || DEBUG_RESET
 static void fd_mcs_print_info(Scsi_Cmnd * SCpnt)
 {
index e296bcc57d5c8920a2b90cf9a0858cac91e60d07..69b7aa54f43fc2e6d943512d35dcb4b2e6de9c2a 100644 (file)
@@ -1419,7 +1419,7 @@ static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id)
    return IRQ_HANDLED;
 }
 
-static int fdomain_16x0_queue(struct scsi_cmnd *SCpnt,
+static int fdomain_16x0_queue_lck(struct scsi_cmnd *SCpnt,
                void (*done)(struct scsi_cmnd *))
 {
    if (in_command) {
@@ -1469,6 +1469,8 @@ static int fdomain_16x0_queue(struct scsi_cmnd *SCpnt,
    return 0;
 }
 
+static DEF_SCSI_QCMD(fdomain_16x0_queue)
+
 #if DEBUG_ABORT
 static void print_info(struct scsi_cmnd *SCpnt)
 {
index cbb20b13b2288957ad39781e774bcd8891245da5..92f185081e622657bdb279850caf979200eb63b9 100644 (file)
@@ -246,7 +246,7 @@ void fnic_set_port_id(struct fc_lport *, u32, struct fc_frame *);
 void fnic_update_mac(struct fc_lport *, u8 *new);
 void fnic_update_mac_locked(struct fnic *, u8 *new);
 
-int fnic_queuecommand(struct scsi_cmnd *, void (*done)(struct scsi_cmnd *));
+int fnic_queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
 int fnic_abort_cmd(struct scsi_cmnd *);
 int fnic_device_reset(struct scsi_cmnd *);
 int fnic_host_reset(struct scsi_cmnd *);
index 198cbab3e8941e0016720463e1279e9992ec193f..22d02404d15f6ce1a86a2b2fbccb852d8fd21003 100644 (file)
@@ -349,7 +349,7 @@ static inline int fnic_queue_wq_copy_desc(struct fnic *fnic,
  * Routine to send a scsi cdb
  * Called with host_lock held and interrupts disabled.
  */
-int fnic_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
+static int fnic_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
 {
        struct fc_lport *lp;
        struct fc_rport *rport;
@@ -457,6 +457,8 @@ out:
        return ret;
 }
 
+DEF_SCSI_QCMD(fnic_queuecommand)
+
 /*
  * fnic_fcpio_fw_reset_cmpl_handler
  * Routine to handle fw reset completion
index 921764c9ab2478334eaca4919fef8d4a4263dae3..1bcdb7beb77b37c08a6508318857e4f92363f0a9 100644 (file)
@@ -46,7 +46,7 @@
 static int generic_NCR5380_abort(Scsi_Cmnd *);
 static int generic_NCR5380_detect(struct scsi_host_template *);
 static int generic_NCR5380_release_resources(struct Scsi_Host *);
-static int generic_NCR5380_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+static int generic_NCR5380_queue_command(struct Scsi_Host *, struct scsi_cmnd *);
 static int generic_NCR5380_bus_reset(Scsi_Cmnd *);
 static const char* generic_NCR5380_info(struct Scsi_Host *);
 
index 841101846b88fe98e55a6c601b013ef9119cdf4a..76365700e2d537497dd3d844fc04c6699e92ac6b 100644 (file)
@@ -185,7 +185,7 @@ static long gdth_unlocked_ioctl(struct file *filep, unsigned int cmd,
                                unsigned long arg);
 
 static void gdth_flush(gdth_ha_str *ha);
-static int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *));
+static int gdth_queuecommand(struct Scsi_Host *h, struct scsi_cmnd *cmd);
 static int __gdth_queuecommand(gdth_ha_str *ha, struct scsi_cmnd *scp,
                                struct gdth_cmndinfo *cmndinfo);
 static void gdth_scsi_done(struct scsi_cmnd *scp);
@@ -4004,7 +4004,7 @@ static int gdth_bios_param(struct scsi_device *sdev,struct block_device *bdev,se
 }
 
 
-static int gdth_queuecommand(struct scsi_cmnd *scp,
+static int gdth_queuecommand_lck(struct scsi_cmnd *scp,
                                void (*done)(struct scsi_cmnd *))
 {
     gdth_ha_str *ha = shost_priv(scp->device->host);
@@ -4022,6 +4022,8 @@ static int gdth_queuecommand(struct scsi_cmnd *scp,
     return __gdth_queuecommand(ha, scp, cmndinfo);
 }
 
+static DEF_SCSI_QCMD(gdth_queuecommand)
+
 static int __gdth_queuecommand(gdth_ha_str *ha, struct scsi_cmnd *scp,
                                struct gdth_cmndinfo *cmndinfo)
 {
index c5d0606ad0974edab8c0326f4fadff905413c171..b2fb2b2a6e700e86d7de265503b70cb48830d994 100644 (file)
@@ -31,7 +31,6 @@
 #include <linux/seq_file.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
-#include <linux/smp_lock.h>
 #include <linux/compat.h>
 #include <linux/blktrace_api.h>
 #include <linux/uaccess.h>
@@ -143,8 +142,7 @@ static void fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h,
        void *buff, size_t size, u8 page_code, unsigned char *scsi3addr,
        int cmd_type);
 
-static int hpsa_scsi_queue_command(struct scsi_cmnd *cmd,
-               void (*done)(struct scsi_cmnd *));
+static int hpsa_scsi_queue_command(struct Scsi_Host *h, struct scsi_cmnd *cmd);
 static void hpsa_scan_start(struct Scsi_Host *);
 static int hpsa_scan_finished(struct Scsi_Host *sh,
        unsigned long elapsed_time);
@@ -1926,7 +1924,7 @@ sglist_finished:
 }
 
 
-static int hpsa_scsi_queue_command(struct scsi_cmnd *cmd,
+static int hpsa_scsi_queue_command_lck(struct scsi_cmnd *cmd,
        void (*done)(struct scsi_cmnd *))
 {
        struct ctlr_info *h;
@@ -2020,6 +2018,8 @@ static int hpsa_scsi_queue_command(struct scsi_cmnd *cmd,
        return 0;
 }
 
+static DEF_SCSI_QCMD(hpsa_scsi_queue_command)
+
 static void hpsa_scan_start(struct Scsi_Host *sh)
 {
        struct ctlr_info *h = shost_to_hba(sh);
index 0729f150b33aa038aa690f3122ae03dbd9115a5b..10b65556937b0478885ab5f528ab6098e61a1663 100644 (file)
@@ -751,7 +751,7 @@ static void hptiop_post_req_mv(struct hptiop_hba *hba,
                MVIOP_MU_QUEUE_ADDR_HOST_BIT | size_bit, hba);
 }
 
-static int hptiop_queuecommand(struct scsi_cmnd *scp,
+static int hptiop_queuecommand_lck(struct scsi_cmnd *scp,
                                void (*done)(struct scsi_cmnd *))
 {
        struct Scsi_Host *host = scp->device->host;
@@ -819,6 +819,8 @@ cmd_done:
        return 0;
 }
 
+static DEF_SCSI_QCMD(hptiop_queuecommand)
+
 static const char *hptiop_info(struct Scsi_Host *host)
 {
        return driver_name_long;
index 9a4b69d4f4eb0d80c47117963cecbef3b2a1ebc2..67fc8ffd52e68eeb2bfe311d04d6bc2052895f74 100644 (file)
@@ -39,7 +39,7 @@
 #include <scsi/scsi_host.h>
 
 /* Common forward declarations for all Linux-versions: */
-static int ibmmca_queuecommand (Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
+static int ibmmca_queuecommand (struct Scsi_Host *, struct scsi_cmnd *);
 static int ibmmca_abort (Scsi_Cmnd *);
 static int ibmmca_host_reset (Scsi_Cmnd *);
 static int ibmmca_biosparam (struct scsi_device *, struct block_device *, sector_t, int *);
@@ -1691,7 +1691,7 @@ static int __devexit ibmmca_remove(struct device *dev)
 }
 
 /* The following routine is the SCSI command queue for the midlevel driver */
-static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
+static int ibmmca_queuecommand_lck(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
 {
        unsigned int ldn;
        unsigned int scsi_cmd;
@@ -1996,6 +1996,8 @@ static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
        return 0;
 }
 
+static DEF_SCSI_QCMD(ibmmca_queuecommand)
+
 static int __ibmmca_abort(Scsi_Cmnd * cmd)
 {
        /* Abort does not work, as the adapter never generates an interrupt on
index 00d08b25425fdf2faea0a1e3bd063167943291fc..57cad7e20caaad0f5bfe4d47e721d494d1ef826d 100644 (file)
@@ -1606,7 +1606,7 @@ static inline int ibmvfc_host_chkready(struct ibmvfc_host *vhost)
  * Returns:
  *     0 on success / other on failure
  **/
-static int ibmvfc_queuecommand(struct scsi_cmnd *cmnd,
+static int ibmvfc_queuecommand_lck(struct scsi_cmnd *cmnd,
                               void (*done) (struct scsi_cmnd *))
 {
        struct ibmvfc_host *vhost = shost_priv(cmnd->device->host);
@@ -1672,6 +1672,8 @@ static int ibmvfc_queuecommand(struct scsi_cmnd *cmnd,
        return 0;
 }
 
+static DEF_SCSI_QCMD(ibmvfc_queuecommand)
+
 /**
  * ibmvfc_sync_completion - Signal that a synchronous command has completed
  * @evt:       ibmvfc event struct
index 67f78a470f5f091c6775fb17f37c1fd00293e1ac..041958453e2a6e6fc39bc4b727d1c44c904a5f9e 100644 (file)
@@ -713,7 +713,7 @@ static inline u16 lun_from_dev(struct scsi_device *dev)
  * @cmd:       struct scsi_cmnd to be executed
  * @done:      Callback function to be called when cmd is completed
 */
-static int ibmvscsi_queuecommand(struct scsi_cmnd *cmnd,
+static int ibmvscsi_queuecommand_lck(struct scsi_cmnd *cmnd,
                                 void (*done) (struct scsi_cmnd *))
 {
        struct srp_cmd *srp_cmd;
@@ -766,6 +766,8 @@ static int ibmvscsi_queuecommand(struct scsi_cmnd *cmnd,
        return ibmvscsi_send_srp_event(evt_struct, hostdata, 0);
 }
 
+static DEF_SCSI_QCMD(ibmvscsi_queuecommand)
+
 /* ------------------------------------------------------------
  * Routines for driver initialization
  */
index 4734ab0b3ff6ab9297352d532bf5aeb530757fe8..99aa0e5699bc9369eb144fc2c144b4082ce15348 100644 (file)
@@ -926,7 +926,7 @@ static int imm_engine(imm_struct *dev, struct scsi_cmnd *cmd)
        return 0;
 }
 
-static int imm_queuecommand(struct scsi_cmnd *cmd,
+static int imm_queuecommand_lck(struct scsi_cmnd *cmd,
                void (*done)(struct scsi_cmnd *))
 {
        imm_struct *dev = imm_dev(cmd->device->host);
@@ -949,6 +949,8 @@ static int imm_queuecommand(struct scsi_cmnd *cmd,
        return 0;
 }
 
+static DEF_SCSI_QCMD(imm_queuecommand)
+
 /*
  * Apparently the disk->capacity attribute is off by 1 sector 
  * for all disk drives.  We add the one here, but it should really
index 52bdc6df6b92b5363b234b31edc81566bad646ab..6568aab745a0014944f619465bf0fc7bc6429d32 100644 (file)
@@ -334,7 +334,7 @@ static uchar calc_sync_xfer(unsigned int period, unsigned int offset)
 
 static void in2000_execute(struct Scsi_Host *instance);
 
-static int in2000_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
+static int in2000_queuecommand_lck(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
 {
        struct Scsi_Host *instance;
        struct IN2000_hostdata *hostdata;
@@ -431,6 +431,8 @@ static int in2000_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
            return 0;
 }
 
+static DEF_SCSI_QCMD(in2000_queuecommand)
+
 
 
 /*
index 0fb8b06b8392cfbbf45ddbef8d291df21ca5414a..5821e1fbce084c9dfe2cf6f9975441245144b9cc 100644 (file)
@@ -396,7 +396,7 @@ struct IN2000_hostdata {
                                                           flags)
 
 static int in2000_detect(struct scsi_host_template *) in2000__INIT;
-static int in2000_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+static int in2000_queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
 static int in2000_abort(Scsi_Cmnd *);
 static void in2000_setup(char *, int *) in2000__INIT;
 static int in2000_biosparam(struct scsi_device *, struct block_device *,
index 108797761b95c2692fe942148a963c2ef51516ea..9627d062e16b3e819c11db4b5865f2f7a4cb8d85 100644 (file)
@@ -2639,7 +2639,7 @@ static void initio_build_scb(struct initio_host * host, struct scsi_ctrl_blk * c
  *     will cause the mid layer to call us again later with the command)
  */
 
-static int i91u_queuecommand(struct scsi_cmnd *cmd,
+static int i91u_queuecommand_lck(struct scsi_cmnd *cmd,
                void (*done)(struct scsi_cmnd *))
 {
        struct initio_host *host = (struct initio_host *) cmd->device->host->hostdata;
@@ -2656,6 +2656,8 @@ static int i91u_queuecommand(struct scsi_cmnd *cmd,
        return 0;
 }
 
+static DEF_SCSI_QCMD(i91u_queuecommand)
+
 /**
  *     i91u_bus_reset          -       reset the SCSI bus
  *     @cmnd: Command block we want to trigger the reset for
index fa60d7df44bed7154adf9aa784cecc937db64d23..5bbaee597e8857cbb2c09e66f06a278f2fb46353 100644 (file)
@@ -5709,7 +5709,7 @@ static void ipr_scsi_done(struct ipr_cmnd *ipr_cmd)
  *     SCSI_MLQUEUE_DEVICE_BUSY if device is busy
  *     SCSI_MLQUEUE_HOST_BUSY if host is busy
  **/
-static int ipr_queuecommand(struct scsi_cmnd *scsi_cmd,
+static int ipr_queuecommand_lck(struct scsi_cmnd *scsi_cmd,
                            void (*done) (struct scsi_cmnd *))
 {
        struct ipr_ioa_cfg *ioa_cfg;
@@ -5792,6 +5792,8 @@ static int ipr_queuecommand(struct scsi_cmnd *scsi_cmd,
        return 0;
 }
 
+static DEF_SCSI_QCMD(ipr_queuecommand)
+
 /**
  * ipr_ioctl - IOCTL handler
  * @sdev:      scsi device struct
index f83a116955f2f1c6409acfae27d2e91719d42276..b2511acd39bd3feeb7f87e6f956ffae6b8e73780 100644 (file)
@@ -232,7 +232,7 @@ static int ips_detect(struct scsi_host_template *);
 static int ips_release(struct Scsi_Host *);
 static int ips_eh_abort(struct scsi_cmnd *);
 static int ips_eh_reset(struct scsi_cmnd *);
-static int ips_queue(struct scsi_cmnd *, void (*)(struct scsi_cmnd *));
+static int ips_queue(struct Scsi_Host *, struct scsi_cmnd *);
 static const char *ips_info(struct Scsi_Host *);
 static irqreturn_t do_ipsintr(int, void *);
 static int ips_hainit(ips_ha_t *);
@@ -1046,7 +1046,7 @@ static int ips_eh_reset(struct scsi_cmnd *SC)
 /*    Linux obtains io_request_lock before calling this function            */
 /*                                                                          */
 /****************************************************************************/
-static int ips_queue(struct scsi_cmnd *SC, void (*done) (struct scsi_cmnd *))
+static int ips_queue_lck(struct scsi_cmnd *SC, void (*done) (struct scsi_cmnd *))
 {
        ips_ha_t *ha;
        ips_passthru_t *pt;
@@ -1137,6 +1137,8 @@ static int ips_queue(struct scsi_cmnd *SC, void (*done) (struct scsi_cmnd *))
        return (0);
 }
 
+static DEF_SCSI_QCMD(ips_queue)
+
 /****************************************************************************/
 /*                                                                          */
 /* Routine Name: ips_biosparam                                              */
index e340373b509b6528ea0602d410eb902c3b233321..2924363d142bc4affc6422de1272e73a70957486 100644 (file)
@@ -1753,7 +1753,7 @@ static inline int fc_fcp_lport_queue_ready(struct fc_lport *lport)
  * This is the i/o strategy routine, called by the SCSI layer. This routine
  * is called with the host_lock held.
  */
-int fc_queuecommand(struct scsi_cmnd *sc_cmd, void (*done)(struct scsi_cmnd *))
+static int fc_queuecommand_lck(struct scsi_cmnd *sc_cmd, void (*done)(struct scsi_cmnd *))
 {
        struct fc_lport *lport;
        struct fc_rport *rport = starget_to_rport(scsi_target(sc_cmd->device));
@@ -1851,6 +1851,8 @@ out:
        spin_lock_irq(lport->host->host_lock);
        return rc;
 }
+
+DEF_SCSI_QCMD(fc_queuecommand)
 EXPORT_SYMBOL(fc_queuecommand);
 
 /**
index 633e09036357828b87e1df84dacec85beda24492..c15fde808c33e98ea1b48398afaf951e19eedeaa 100644 (file)
@@ -1599,7 +1599,7 @@ enum {
        FAILURE_SESSION_NOT_READY,
 };
 
-int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
+static int iscsi_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
 {
        struct iscsi_cls_session *cls_session;
        struct Scsi_Host *host;
@@ -1736,6 +1736,8 @@ fault:
        spin_lock(host->host_lock);
        return 0;
 }
+
+DEF_SCSI_QCMD(iscsi_queuecommand)
 EXPORT_SYMBOL_GPL(iscsi_queuecommand);
 
 int iscsi_change_queue_depth(struct scsi_device *sdev, int depth, int reason)
index 55f09e92ab5918fd5019cacaded186d2cd1b1c55..29251fabecc65b50643a295bf3ca87c422f920d6 100644 (file)
@@ -189,7 +189,7 @@ int sas_queue_up(struct sas_task *task)
  * Note: XXX: Remove the host unlock/lock pair when SCSI Core can
  * call us without holding an IRQ spinlock...
  */
-int sas_queuecommand(struct scsi_cmnd *cmd,
+static int sas_queuecommand_lck(struct scsi_cmnd *cmd,
                     void (*scsi_done)(struct scsi_cmnd *))
        __releases(host->host_lock)
        __acquires(dev->sata_dev.ap->lock)
@@ -254,6 +254,8 @@ out:
        return res;
 }
 
+DEF_SCSI_QCMD(sas_queuecommand)
+
 static void sas_eh_finish_cmd(struct scsi_cmnd *cmd)
 {
        struct sas_task *task = TO_SAS_TASK(cmd);
index f64b65a770b8df3b3f0a3ba47decc0512a8df0a7..581837b3c71a9369c12f31d3b547f555bfca576d 100644 (file)
@@ -2899,7 +2899,7 @@ void lpfc_poll_timeout(unsigned long ptr)
  *   SCSI_MLQUEUE_HOST_BUSY - Block all devices served by this host temporarily.
  **/
 static int
-lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
+lpfc_queuecommand_lck(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
 {
        struct Scsi_Host  *shost = cmnd->device->host;
        struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
@@ -3060,6 +3060,8 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
        return 0;
 }
 
+static DEF_SCSI_QCMD(lpfc_queuecommand)
+
 /**
  * lpfc_abort_handler - scsi_host_template eh_abort_handler entry point
  * @cmnd: Pointer to scsi_cmnd data structure.
index 3ddb4dc62d5d5eed49ecc1a1228ddbdfbecd1f47..6c42dff0f4d30d77e68dbfc445e961bfb55a786a 100644 (file)
@@ -66,7 +66,7 @@ static void cmd_done(struct fsc_state *, int result);
 static void set_dma_cmds(struct fsc_state *, struct scsi_cmnd *);
 
 
-static int mac53c94_queue(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
+static int mac53c94_queue_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
 {
        struct fsc_state *state;
 
@@ -99,6 +99,8 @@ static int mac53c94_queue(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *
        return 0;
 }
 
+static DEF_SCSI_QCMD(mac53c94_queue)
+
 static int mac53c94_host_reset(struct scsi_cmnd *cmd)
 {
        struct fsc_state *state = (struct fsc_state *) cmd->device->host->hostdata;
index 7ceb5cf12c6be3be77ccba93e4a1d550a9d80800..9aa048525eb2544b8159a9495f1a604695a79d26 100644 (file)
@@ -366,7 +366,7 @@ mega_runpendq(adapter_t *adapter)
  * The command queuing entry point for the mid-layer.
  */
 static int
-megaraid_queue(Scsi_Cmnd *scmd, void (*done)(Scsi_Cmnd *))
+megaraid_queue_lck(Scsi_Cmnd *scmd, void (*done)(Scsi_Cmnd *))
 {
        adapter_t       *adapter;
        scb_t   *scb;
@@ -409,6 +409,8 @@ megaraid_queue(Scsi_Cmnd *scmd, void (*done)(Scsi_Cmnd *))
        return busy;
 }
 
+static DEF_SCSI_QCMD(megaraid_queue)
+
 /**
  * mega_allocate_scb()
  * @adapter - pointer to our soft state
@@ -4456,7 +4458,7 @@ mega_internal_command(adapter_t *adapter, megacmd_t *mc, mega_passthru *pthru)
 
        scb->idx = CMDID_INT_CMDS;
 
-       megaraid_queue(scmd, mega_internal_done);
+       megaraid_queue_lck(scmd, mega_internal_done);
 
        wait_for_completion(&adapter->int_waitq);
 
index 2b4a048cadf1b31d41a0659e1be55acb96815cd9..f5644745e24e1fe4980188d062d179753a5b024f 100644 (file)
@@ -987,7 +987,7 @@ static int mega_query_adapter(adapter_t *);
 static int issue_scb(adapter_t *, scb_t *);
 static int mega_setup_mailbox(adapter_t *);
 
-static int megaraid_queue (Scsi_Cmnd *, void (*)(Scsi_Cmnd *));
+static int megaraid_queue (struct Scsi_Host *, struct scsi_cmnd *);
 static scb_t * mega_build_cmd(adapter_t *, Scsi_Cmnd *, int *);
 static void __mega_runpendq(adapter_t *);
 static int issue_scb_block(adapter_t *, u_char *);
index a7810a106b37aed653e5183c192e60d1758d30bb..5708cb27d0783df3525fa1789dd10859a647f921 100644 (file)
@@ -113,8 +113,7 @@ static int megaraid_mbox_fire_sync_cmd(adapter_t *);
 static void megaraid_mbox_display_scb(adapter_t *, scb_t *);
 static void megaraid_mbox_setup_device_map(adapter_t *);
 
-static int megaraid_queue_command(struct scsi_cmnd *,
-               void (*)(struct scsi_cmnd *));
+static int megaraid_queue_command(struct Scsi_Host *, struct scsi_cmnd *);
 static scb_t *megaraid_mbox_build_cmd(adapter_t *, struct scsi_cmnd *, int *);
 static void megaraid_mbox_runpendq(adapter_t *, scb_t *);
 static void megaraid_mbox_prepare_pthru(adapter_t *, scb_t *,
@@ -1484,7 +1483,7 @@ mbox_post_cmd(adapter_t *adapter, scb_t *scb)
  * Queue entry point for mailbox based controllers.
  */
 static int
-megaraid_queue_command(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *))
+megaraid_queue_command_lck(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *))
 {
        adapter_t       *adapter;
        scb_t           *scb;
@@ -1513,6 +1512,8 @@ megaraid_queue_command(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *))
        return if_busy;
 }
 
+static DEF_SCSI_QCMD(megaraid_queue_command)
+
 /**
  * megaraid_mbox_build_cmd - transform the mid-layer scsi commands
  * @adapter    : controller's soft state
index eb29d508513148653fb492df24cee9ab0b14cb17..7451bc096a015db4ff38a42725387dabf3b0a58e 100644 (file)
@@ -1334,7 +1334,7 @@ megasas_dump_pending_frames(struct megasas_instance *instance)
  * @done:                      Callback entry point
  */
 static int
-megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *))
+megasas_queue_command_lck(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *))
 {
        u32 frame_count;
        struct megasas_cmd *cmd;
@@ -1417,6 +1417,8 @@ megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *))
        return 0;
 }
 
+static DEF_SCSI_QCMD(megasas_queue_command)
+
 static struct megasas_instance *megasas_lookup_instance(u16 host_no)
 {
        int i;
index 1f784fde25109b53ef86f2b79fd975ed5cc2bf38..197aa1b3f0f31f111b7980310d05aa948880eb7c 100644 (file)
@@ -1627,7 +1627,7 @@ static void cmd_complete(struct mesh_state *ms)
  * Called by midlayer with host locked to queue a new
  * request
  */
-static int mesh_queue(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
+static int mesh_queue_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
 {
        struct mesh_state *ms;
 
@@ -1648,6 +1648,8 @@ static int mesh_queue(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
        return 0;
 }
 
+static DEF_SCSI_QCMD(mesh_queue)
+
 /*
  * Called to handle interrupts, either call by the interrupt
  * handler (do_mesh_interrupt) or by other functions in
index 16e99b6863549ed0495cc283c884d9a162d34c01..1a96a00418a4faed68a77519a49d1bf81e02f6b2 100644 (file)
@@ -3315,7 +3315,7 @@ _scsih_eedp_error_handling(struct scsi_cmnd *scmd, u16 ioc_status)
  * SCSI_MLQUEUE_HOST_BUSY if the entire host queue is full
  */
 static int
-_scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
+_scsih_qcmd_lck(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
 {
        struct MPT2SAS_ADAPTER *ioc = shost_priv(scmd->device->host);
        struct MPT2SAS_DEVICE *sas_device_priv_data;
@@ -3441,6 +3441,8 @@ _scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
        return SCSI_MLQUEUE_HOST_BUSY;
 }
 
+static DEF_SCSI_QCMD(_scsih_qcmd)
+
 /**
  * _scsih_normalize_sense - normalize descriptor and fixed format sense data
  * @sense_buffer: sense data returned by target
index d013a2aa2fd54aac8e6d251f4aa2267ebe669922..46cc3825638d63fe50c6bd104214489b59c472ef 100644 (file)
@@ -8029,7 +8029,7 @@ static int ncr53c8xx_slave_configure(struct scsi_device *device)
        return 0;
 }
 
-static int ncr53c8xx_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
+static int ncr53c8xx_queue_command_lck (struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
 {
      struct ncb *np = ((struct host_data *) cmd->device->host->hostdata)->ncb;
      unsigned long flags;
@@ -8068,6 +8068,8 @@ printk("ncr53c8xx : command successfully queued\n");
      return sts;
 }
 
+static DEF_SCSI_QCMD(ncr53c8xx_queue_command)
+
 irqreturn_t ncr53c8xx_intr(int irq, void *dev_id)
 {
      unsigned long flags;
index 4c1e545452009c957baed7fa590018d93b4a3bfe..6b8b021400f848d9770684e4c1a5aebe4d2374e6 100644 (file)
@@ -196,8 +196,7 @@ static void __exit    exit_nsp32  (void);
 static int         nsp32_proc_info   (struct Scsi_Host *, char *, char **, off_t, int, int);
 
 static int         nsp32_detect      (struct pci_dev *pdev);
-static int         nsp32_queuecommand(struct scsi_cmnd *,
-               void (*done)(struct scsi_cmnd *));
+static int         nsp32_queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
 static const char *nsp32_info        (struct Scsi_Host *);
 static int         nsp32_release     (struct Scsi_Host *);
 
@@ -909,7 +908,7 @@ static int nsp32_setup_sg_table(struct scsi_cmnd *SCpnt)
        return TRUE;
 }
 
-static int nsp32_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
+static int nsp32_queuecommand_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
 {
        nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata;
        nsp32_target *target;
@@ -1050,6 +1049,8 @@ static int nsp32_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_
        return 0;
 }
 
+static DEF_SCSI_QCMD(nsp32_queuecommand)
+
 /* initialize asic */
 static int nsp32hw_init(nsp32_hw_data *data)
 {
index 8dc5b1a5f5da7ebacdbedbdbc9a8b5b9a135d42b..a04281cace2e318e8c1896f7d30b818e41e24000 100644 (file)
@@ -118,7 +118,7 @@ static int pas16_abort(Scsi_Cmnd *);
 static int pas16_biosparam(struct scsi_device *, struct block_device *,
                           sector_t, int*);
 static int pas16_detect(struct scsi_host_template *);
-static int pas16_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+static int pas16_queue_command(struct Scsi_Host *, struct scsi_cmnd *);
 static int pas16_bus_reset(Scsi_Cmnd *);
 
 #ifndef CMD_PER_LUN
index 9326c2c148803a6d1933faa0d183b6fad26be460..be3f33d31a99dc3e359190e233ae91b48e2066fe 100644 (file)
@@ -184,7 +184,7 @@ static void nsp_scsi_done(struct scsi_cmnd *SCpnt)
        SCpnt->scsi_done(SCpnt);
 }
 
-static int nsp_queuecommand(struct scsi_cmnd *SCpnt,
+static int nsp_queuecommand_lck(struct scsi_cmnd *SCpnt,
                            void (*done)(struct scsi_cmnd *))
 {
 #ifdef NSP_DEBUG
@@ -264,6 +264,8 @@ static int nsp_queuecommand(struct scsi_cmnd *SCpnt,
        return 0;
 }
 
+static DEF_SCSI_QCMD(nsp_queuecommand)
+
 /*
  * setup PIO FIFO transfer mode and enable/disable to data out
  */
index d68c9f267c5edc1aa285762d523e9ea58055bd29..7fc9a9d0a448b6a01c42461758ef118f5190ed93 100644 (file)
@@ -299,8 +299,7 @@ static        int        nsp_proc_info  (
                                         off_t   offset,
                                         int     length,
                                         int     inout);
-static int nsp_queuecommand(struct scsi_cmnd *SCpnt,
-                           void (* done)(struct scsi_cmnd *SCpnt));
+static int nsp_queuecommand(struct Scsi_Host *h, struct scsi_cmnd *SCpnt);
 
 /* Error handler */
 /*static int nsp_eh_abort       (struct scsi_cmnd *SCpnt);*/
index 0ae27cb5cd6f30334d6e2dd19bae9c187729733d..8552296edaa1e8062504e4b8ee63d46cc19694e2 100644 (file)
@@ -547,7 +547,7 @@ SYM53C500_info(struct Scsi_Host *SChost)
 }
 
 static int 
-SYM53C500_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
+SYM53C500_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
 {
        int i;
        int port_base = SCpnt->device->host->io_port;
@@ -583,6 +583,8 @@ SYM53C500_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
        return 0;
 }
 
+static DEF_SCSI_QCMD(SYM53C500_queue)
+
 static int 
 SYM53C500_host_reset(struct scsi_cmnd *SCpnt)
 {
index 8e38ca8cd1016461e9642d4032d579feb6fac6fc..7f064f9ca828d3ac1db449d352104899f31b84e8 100644 (file)
@@ -50,7 +50,6 @@
 #include <linux/dma-mapping.h>
 #include <linux/pci.h>
 #include <linux/interrupt.h>
-#include <linux/smp_lock.h>
 #include <scsi/libsas.h>
 #include <scsi/scsi_tcq.h>
 #include <scsi/sas_ata.h>
index cf89091e4c3d3befec59b89425792dcad23e2a87..5e76a624cb08a843d194e7102900dfac77c2aae4 100644 (file)
@@ -3478,7 +3478,7 @@ static int pmcraid_copy_sglist(
  *       SCSI_MLQUEUE_DEVICE_BUSY if device is busy
  *       SCSI_MLQUEUE_HOST_BUSY if host is busy
  */
-static int pmcraid_queuecommand(
+static int pmcraid_queuecommand_lck(
        struct scsi_cmnd *scsi_cmd,
        void (*done) (struct scsi_cmnd *)
 )
@@ -3584,6 +3584,8 @@ static int pmcraid_queuecommand(
        return rc;
 }
 
+static DEF_SCSI_QCMD(pmcraid_queuecommand)
+
 /**
  * pmcraid_open -char node "open" entry, allowed only users with admin access
  */
index 7bc2d796e4037712dd1113fe1e94d81f09782b85..d164c9639361c773fb41717509608587cb2ab9a6 100644 (file)
@@ -798,7 +798,7 @@ static int ppa_engine(ppa_struct *dev, struct scsi_cmnd *cmd)
        return 0;
 }
 
-static int ppa_queuecommand(struct scsi_cmnd *cmd,
+static int ppa_queuecommand_lck(struct scsi_cmnd *cmd,
                void (*done) (struct scsi_cmnd *))
 {
        ppa_struct *dev = ppa_dev(cmd->device->host);
@@ -821,6 +821,8 @@ static int ppa_queuecommand(struct scsi_cmnd *cmd,
        return 0;
 }
 
+static DEF_SCSI_QCMD(ppa_queuecommand)
+
 /*
  * Apparently the disk->capacity attribute is off by 1 sector 
  * for all disk drives.  We add the one here, but it should really
index 92ffbb5104980dc98bde7d839dce1cd6548d385d..cd178b9e40cdde6d0266d103974357028a3e3807 100644 (file)
@@ -211,7 +211,7 @@ static int ps3rom_write_request(struct ps3_storage_device *dev,
        return 0;
 }
 
-static int ps3rom_queuecommand(struct scsi_cmnd *cmd,
+static int ps3rom_queuecommand_lck(struct scsi_cmnd *cmd,
                               void (*done)(struct scsi_cmnd *))
 {
        struct ps3rom_private *priv = shost_priv(cmd->device->host);
@@ -260,6 +260,8 @@ static int ps3rom_queuecommand(struct scsi_cmnd *cmd,
        return 0;
 }
 
+static DEF_SCSI_QCMD(ps3rom_queuecommand)
+
 static int decode_lv1_status(u64 status, unsigned char *sense_key,
                             unsigned char *asc, unsigned char *ascq)
 {
index b8166ecfd0e35f17894a077679d5f5d2a29701cf..5dec684bf0103d5cb9fd244d5b3a706ab1109720 100644 (file)
@@ -727,7 +727,7 @@ qla1280_info(struct Scsi_Host *host)
  * context which is a big NO! NO!.
  **************************************************************************/
 static int
-qla1280_queuecommand(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *))
+qla1280_queuecommand_lck(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *))
 {
        struct Scsi_Host *host = cmd->device->host;
        struct scsi_qla_host *ha = (struct scsi_qla_host *)host->hostdata;
@@ -756,6 +756,8 @@ qla1280_queuecommand(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *))
        return status;
 }
 
+static DEF_SCSI_QCMD(qla1280_queuecommand)
+
 enum action {
        ABORT_COMMAND,
        DEVICE_RESET,
index 1830e6e973155684234710e129e564f82176ce2d..1644eabaafeb58cb3130dccdb97b489bcd0c708e 100644 (file)
@@ -179,8 +179,7 @@ static int qla2xxx_slave_alloc(struct scsi_device *);
 static int qla2xxx_scan_finished(struct Scsi_Host *, unsigned long time);
 static void qla2xxx_scan_start(struct Scsi_Host *);
 static void qla2xxx_slave_destroy(struct scsi_device *);
-static int qla2xxx_queuecommand(struct scsi_cmnd *cmd,
-               void (*fn)(struct scsi_cmnd *));
+static int qla2xxx_queuecommand(struct Scsi_Host *h, struct scsi_cmnd *cmd);
 static int qla2xxx_eh_abort(struct scsi_cmnd *);
 static int qla2xxx_eh_device_reset(struct scsi_cmnd *);
 static int qla2xxx_eh_target_reset(struct scsi_cmnd *);
@@ -535,7 +534,7 @@ qla2x00_get_new_sp(scsi_qla_host_t *vha, fc_port_t *fcport,
 }
 
 static int
-qla2xxx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
+qla2xxx_queuecommand_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
 {
        scsi_qla_host_t *vha = shost_priv(cmd->device->host);
        fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
@@ -609,6 +608,8 @@ qc24_fail_command:
        return 0;
 }
 
+static DEF_SCSI_QCMD(qla2xxx_queuecommand)
+
 
 /*
  * qla2x00_eh_wait_on_command
index f4cd846abf6dcf77dc7d6bd7a855437ba6a1868f..0d48fb4d1044480d8743ed355019891d1d03e907 100644 (file)
@@ -79,8 +79,7 @@ static enum blk_eh_timer_return qla4xxx_eh_cmd_timed_out(struct scsi_cmnd *sc);
 /*
  * SCSI host template entry points
  */
-static int qla4xxx_queuecommand(struct scsi_cmnd *cmd,
-                               void (*done) (struct scsi_cmnd *));
+static int qla4xxx_queuecommand(struct Scsi_Host *h, struct scsi_cmnd *cmd);
 static int qla4xxx_eh_abort(struct scsi_cmnd *cmd);
 static int qla4xxx_eh_device_reset(struct scsi_cmnd *cmd);
 static int qla4xxx_eh_target_reset(struct scsi_cmnd *cmd);
@@ -464,7 +463,7 @@ void qla4xxx_srb_compl(struct kref *ref)
  * completion handling).   Unfortunely, it sometimes calls the scheduler
  * in interrupt context which is a big NO! NO!.
  **/
-static int qla4xxx_queuecommand(struct scsi_cmnd *cmd,
+static int qla4xxx_queuecommand_lck(struct scsi_cmnd *cmd,
                                void (*done)(struct scsi_cmnd *))
 {
        struct scsi_qla_host *ha = to_qla_host(cmd->device->host);
@@ -538,6 +537,8 @@ qc_fail_command:
        return 0;
 }
 
+static DEF_SCSI_QCMD(qla4xxx_queuecommand)
+
 /**
  * qla4xxx_mem_free - frees memory allocated to adapter
  * @ha: Pointer to host adapter structure.
index 1ad51552d6b188aba1e206d5dc8e2a2ae96622a9..c3a9151ca823cb64651390e940794262d9b7d989 100644 (file)
@@ -439,7 +439,7 @@ irqreturn_t qlogicfas408_ihandl(int irq, void *dev_id)
  *     Queued command
  */
 
-int qlogicfas408_queuecommand(struct scsi_cmnd *cmd,
+static int qlogicfas408_queuecommand_lck(struct scsi_cmnd *cmd,
                              void (*done) (struct scsi_cmnd *))
 {
        struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd);
@@ -459,6 +459,8 @@ int qlogicfas408_queuecommand(struct scsi_cmnd *cmd,
        return 0;
 }
 
+DEF_SCSI_QCMD(qlogicfas408_queuecommand)
+
 /* 
  *     Return bios parameters 
  */
index 260626427a328f21ba57c40f86f05003e0b50ea2..2f6c0a166200fdea89aba2d8aee31281718a6be1 100644 (file)
@@ -103,8 +103,7 @@ struct qlogicfas408_priv {
 #define get_priv_by_host(x) (struct qlogicfas408_priv *)&((x)->hostdata[0])
 
 irqreturn_t qlogicfas408_ihandl(int irq, void *dev_id);
-int qlogicfas408_queuecommand(struct scsi_cmnd * cmd,
-                             void (*done) (struct scsi_cmnd *));
+int qlogicfas408_queuecommand(struct Scsi_Host *h, struct scsi_cmnd * cmd);
 int qlogicfas408_biosparam(struct scsi_device * disk,
                           struct block_device *dev,
                           sector_t capacity, int ip[]);
index f8c561cf751e46aa62e841a5e1d35920c3f6ecf1..664c9572d0c9a44b2540a05857c8710596d8b6c1 100644 (file)
@@ -1003,7 +1003,7 @@ static int qlogicpti_slave_configure(struct scsi_device *sdev)
  *
  * "This code must fly." -davem
  */
-static int qlogicpti_queuecommand(struct scsi_cmnd *Cmnd, void (*done)(struct scsi_cmnd *))
+static int qlogicpti_queuecommand_lck(struct scsi_cmnd *Cmnd, void (*done)(struct scsi_cmnd *))
 {
        struct Scsi_Host *host = Cmnd->device->host;
        struct qlogicpti *qpti = (struct qlogicpti *) host->hostdata;
@@ -1052,6 +1052,8 @@ toss_command:
        return 1;
 }
 
+static DEF_SCSI_QCMD(qlogicpti_queuecommand)
+
 static int qlogicpti_return_status(struct Status_Entry *sts, int id)
 {
        int host_status = DID_ERROR;
index 348fba0a8976467fa9724411699b918a9cd8b0ea..2aeb2e9c4d3bc708d5c12c7a117b021ffc160409 100644 (file)
@@ -634,12 +634,13 @@ void scsi_log_completion(struct scsi_cmnd *cmd, int disposition)
  * Description: a serial number identifies a request for error recovery
  * and debugging purposes.  Protected by the Host_Lock of host.
  */
-static inline void scsi_cmd_get_serial(struct Scsi_Host *host, struct scsi_cmnd *cmd)
+void scsi_cmd_get_serial(struct Scsi_Host *host, struct scsi_cmnd *cmd)
 {
        cmd->serial_number = host->cmd_serial_number++;
        if (cmd->serial_number == 0) 
                cmd->serial_number = host->cmd_serial_number++;
 }
+EXPORT_SYMBOL(scsi_cmd_get_serial);
 
 /**
  * scsi_dispatch_command - Dispatch a command to the low-level driver.
@@ -651,7 +652,6 @@ static inline void scsi_cmd_get_serial(struct Scsi_Host *host, struct scsi_cmnd
 int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
 {
        struct Scsi_Host *host = cmd->device->host;
-       unsigned long flags = 0;
        unsigned long timeout;
        int rtn = 0;
 
@@ -737,23 +737,15 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
                goto out;
        }
 
-       spin_lock_irqsave(host->host_lock, flags);
-       /*
-        * AK: unlikely race here: for some reason the timer could
-        * expire before the serial number is set up below.
-        *
-        * TODO: kill serial or move to blk layer
-        */
-       scsi_cmd_get_serial(host, cmd); 
-
        if (unlikely(host->shost_state == SHOST_DEL)) {
                cmd->result = (DID_NO_CONNECT << 16);
                scsi_done(cmd);
        } else {
                trace_scsi_dispatch_cmd_start(cmd);
-               rtn = host->hostt->queuecommand(cmd, scsi_done);
+               cmd->scsi_done = scsi_done;
+               rtn = host->hostt->queuecommand(host, cmd);
        }
-       spin_unlock_irqrestore(host->host_lock, flags);
+
        if (rtn) {
                trace_scsi_dispatch_cmd_error(cmd, rtn);
                if (rtn != SCSI_MLQUEUE_DEVICE_BUSY &&
index 2c36bae3bd4b7ea5c45f2c1c623d671e152a5bd3..2f1f9b079b1067fb078b74c471134bba9a7f55bb 100644 (file)
@@ -3538,7 +3538,7 @@ static void sdebug_remove_adapter(void)
 }
 
 static
-int scsi_debug_queuecommand(struct scsi_cmnd *SCpnt, done_funct_t done)
+int scsi_debug_queuecommand_lck(struct scsi_cmnd *SCpnt, done_funct_t done)
 {
        unsigned char *cmd = (unsigned char *) SCpnt->cmnd;
        int len, k;
@@ -3884,6 +3884,8 @@ write:
                             (delay_override ? 0 : scsi_debug_delay));
 }
 
+static DEF_SCSI_QCMD(scsi_debug_queuecommand)
+
 static struct scsi_host_template sdebug_driver_template = {
        .proc_info =            scsi_debug_proc_info,
        .proc_name =            sdebug_proc_name,
index f3cf924a2cd96f8c322e53d6012c8397c99f8a58..824b8fc03ce52f087dd3ca4d0fdadab15dfcac17 100644 (file)
@@ -773,17 +773,15 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd,
        struct Scsi_Host *shost = sdev->host;
        DECLARE_COMPLETION_ONSTACK(done);
        unsigned long timeleft;
-       unsigned long flags;
        struct scsi_eh_save ses;
        int rtn;
 
        scsi_eh_prep_cmnd(scmd, &ses, cmnd, cmnd_size, sense_bytes);
        shost->eh_action = &done;
 
-       spin_lock_irqsave(shost->host_lock, flags);
        scsi_log_send(scmd);
-       shost->hostt->queuecommand(scmd, scsi_eh_done);
-       spin_unlock_irqrestore(shost->host_lock, flags);
+       scmd->scsi_done = scsi_eh_done;
+       shost->hostt->queuecommand(shost, scmd);
 
        timeleft = wait_for_completion_timeout(&done, timeout);
 
index b9ab3a590e4b4fd891865a1f9d3d5f3cb55d9dc5..956496182c805d8dd7f0aa58cc3ddb7c12c91b8b 100644 (file)
@@ -46,7 +46,6 @@
 #include <linux/blkdev.h>
 #include <linux/blkpg.h>
 #include <linux/delay.h>
-#include <linux/smp_lock.h>
 #include <linux/mutex.h>
 #include <linux/string_helpers.h>
 #include <linux/async.h>
index 9c73dbda3bbb8d3137e8adaed717b61d83cf6551..606215e54b8896f38deeb51603a29f8e12cd5e40 100644 (file)
@@ -572,7 +572,7 @@ stex_slave_destroy(struct scsi_device *sdev)
 }
 
 static int
-stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
+stex_queuecommand_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
 {
        struct st_hba *hba;
        struct Scsi_Host *host;
@@ -698,6 +698,8 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
        return 0;
 }
 
+static DEF_SCSI_QCMD(stex_queuecommand)
+
 static void stex_scsi_done(struct st_ccb *ccb)
 {
        struct scsi_cmnd *cmd = ccb->cmd;
index 713620ed70d96ef4a8f6111a689a118d2a6f962d..4f0e5485ffde4bf0b859a3786191861f83e0a62f 100644 (file)
@@ -908,7 +908,7 @@ static int NCR5380_init (struct Scsi_Host *instance, int flags)
  */
 
 /* Only make static if a wrapper function is used */
-static int NCR5380_queue_command(struct scsi_cmnd *cmd,
+static int NCR5380_queue_command_lck(struct scsi_cmnd *cmd,
                                 void (*done)(struct scsi_cmnd *))
 {
     SETUP_HOSTDATA(cmd->device->host);
@@ -1019,6 +1019,8 @@ static int NCR5380_queue_command(struct scsi_cmnd *cmd,
     return 0;
 }
 
+static DEF_SCSI_QCMD(NCR5380_queue_command)
+
 /*
  * Function : NCR5380_main (void) 
  *
index b29a9d661ca41740b7e7a9693f4a04fb806ec64a..bcefd8458e653f086bf6387f6c80dbd82d0c3322 100644 (file)
@@ -51,8 +51,7 @@ static int sun3scsi_abort(struct scsi_cmnd *);
 static int sun3scsi_detect (struct scsi_host_template *);
 static const char *sun3scsi_info (struct Scsi_Host *);
 static int sun3scsi_bus_reset(struct scsi_cmnd *);
-static int sun3scsi_queue_command(struct scsi_cmnd *,
-                                 void (*done)(struct scsi_cmnd *));
+static int sun3scsi_queue_command(struct Scsi_Host *, struct scsi_cmnd *);
 static int sun3scsi_release (struct Scsi_Host *);
 
 #ifndef CMD_PER_LUN
index e5c369bb568f5d9ae5fd23b8bb8423c1be9c6ba1..190107ae120b5241d02864d94e6420cb826a3785 100644 (file)
@@ -734,7 +734,7 @@ const char *sym53c416_info(struct Scsi_Host *SChost)
        return info;
 }
 
-int sym53c416_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
+static int sym53c416_queuecommand_lck(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
 {
        int base;
        unsigned long flags = 0;
@@ -761,6 +761,8 @@ int sym53c416_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
        return 0;
 }
 
+DEF_SCSI_QCMD(sym53c416_queuecommand)
+
 static int sym53c416_host_reset(Scsi_Cmnd *SCpnt)
 {
        int base;
index 77860d0748ffc4d7c1eca48167f146427186524e..387de5d80a704373a3cbeeea42bbfb5d9ac08046 100644 (file)
@@ -25,7 +25,7 @@
 static int sym53c416_detect(struct scsi_host_template *);
 static const char *sym53c416_info(struct Scsi_Host *);
 static int sym53c416_release(struct Scsi_Host *);
-static int sym53c416_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+static int sym53c416_queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
 static int sym53c416_host_reset(Scsi_Cmnd *);
 static int sym53c416_bios_param(struct scsi_device *, struct block_device *,
                sector_t, int *);
index 8b955b534a36f7ce836967b49978b2deb7bd8d64..6b97ded9d45de641770335a851d29761b9c9e66a 100644 (file)
@@ -505,7 +505,7 @@ void sym_log_bus_error(struct Scsi_Host *shost)
  * queuecommand method.  Entered with the host adapter lock held and
  * interrupts disabled.
  */
-static int sym53c8xx_queue_command(struct scsi_cmnd *cmd,
+static int sym53c8xx_queue_command_lck(struct scsi_cmnd *cmd,
                                        void (*done)(struct scsi_cmnd *))
 {
        struct sym_hcb *np = SYM_SOFTC_PTR(cmd);
@@ -536,6 +536,8 @@ static int sym53c8xx_queue_command(struct scsi_cmnd *cmd,
        return 0;
 }
 
+static DEF_SCSI_QCMD(sym53c8xx_queue_command)
+
 /*
  *  Linux entry point of the interrupt handler.
  */
index 76a069b7ac0bbd7ef2ae26a61a4c612b4f67b340..ada1115079c9e6890b00108e83f70f15061058a0 100644 (file)
@@ -96,8 +96,7 @@ static int t128_abort(struct scsi_cmnd *);
 static int t128_biosparam(struct scsi_device *, struct block_device *,
                          sector_t, int*);
 static int t128_detect(struct scsi_host_template *);
-static int t128_queue_command(struct scsi_cmnd *,
-                             void (*done)(struct scsi_cmnd *));
+static int t128_queue_command(struct Scsi_Host *, struct scsi_cmnd *);
 static int t128_bus_reset(struct scsi_cmnd *);
 
 #ifndef CMD_PER_LUN
index 27866b0adfebd4901dbb1a38a4ebc752ecfd3d70..a124a28f2ccbf27f3e89981cc60eb57f0a305fc0 100644 (file)
@@ -1883,7 +1883,7 @@ dc390_ScsiRstDetect( struct dc390_acb* pACB )
     return;
 }
 
-static int DC390_queuecommand(struct scsi_cmnd *cmd,
+static int DC390_queuecommand_lck(struct scsi_cmnd *cmd,
                void (*done)(struct scsi_cmnd *))
 {
        struct scsi_device *sdev = cmd->device;
@@ -1944,6 +1944,8 @@ static int DC390_queuecommand(struct scsi_cmnd *cmd,
        return SCSI_MLQUEUE_DEVICE_BUSY;
 }
 
+static DEF_SCSI_QCMD(DC390_queuecommand)
+
 static void dc390_dumpinfo (struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb* pSRB)
 {
     struct pci_dev *pdev;
index 5d9fdeeb2315cdd5e9958bf24ea56cd3669fca47..edfc5da8be4c05aa5bc729c7ee47fca531bf797f 100644 (file)
 
 static int u14_34f_detect(struct scsi_host_template *);
 static int u14_34f_release(struct Scsi_Host *);
-static int u14_34f_queuecommand(struct scsi_cmnd *, void (*done)(struct scsi_cmnd *));
+static int u14_34f_queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
 static int u14_34f_eh_abort(struct scsi_cmnd *);
 static int u14_34f_eh_host_reset(struct scsi_cmnd *);
 static int u14_34f_bios_param(struct scsi_device *, struct block_device *,
@@ -1248,7 +1248,7 @@ static void scsi_to_dev_dir(unsigned int i, unsigned int j) {
 
 }
 
-static int u14_34f_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) {
+static int u14_34f_queuecommand_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) {
    unsigned int i, j, k;
    struct mscp *cpp;
 
@@ -1329,6 +1329,8 @@ static int u14_34f_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scs
    return 0;
 }
 
+static DEF_SCSI_QCMD(u14_34f_queuecommand)
+
 static int u14_34f_eh_abort(struct scsi_cmnd *SCarg) {
    unsigned int i, j;
 
index 27aa40f3980e56114ddb53847bda968a9e5d1a66..0571ef9639cbc15b6d5ace0384c03a895900ff7d 100644 (file)
@@ -700,7 +700,7 @@ static inline void build_sg_list(struct mscp *mscp, struct scsi_cmnd *SCpnt)
        mscp->transfer_data_length = transfer_length;
 }
 
-static int ultrastor_queuecommand(struct scsi_cmnd *SCpnt,
+static int ultrastor_queuecommand_lck(struct scsi_cmnd *SCpnt,
                                void (*done) (struct scsi_cmnd *))
 {
     struct mscp *my_mscp;
@@ -825,6 +825,8 @@ retry:
     return 0;
 }
 
+static DEF_SCSI_QCMD(ultrastor_queuecommand)
+
 /* This code must deal with 2 cases:
 
    1. The command has not been written to the OGM.  In this case, set
index a692905f95f76c3d3935ddfbd9b6f38daa60c788..165c18b5cf5f70a96801d181376a60c55c761c85 100644 (file)
@@ -15,8 +15,7 @@
 
 static int ultrastor_detect(struct scsi_host_template *);
 static const char *ultrastor_info(struct Scsi_Host *shpnt);
-static int ultrastor_queuecommand(struct scsi_cmnd *,
-                               void (*done)(struct scsi_cmnd *));
+static int ultrastor_queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
 static int ultrastor_abort(struct scsi_cmnd *);
 static int ultrastor_host_reset(struct scsi_cmnd *);
 static int ultrastor_biosparam(struct scsi_device *, struct block_device *,
index 26894459c37fe375076464330ef7809345b57408..a18996d244664588ac1f7d2ea07cca0be3e29e7d 100644 (file)
@@ -690,7 +690,7 @@ static int pvscsi_queue_ring(struct pvscsi_adapter *adapter,
        return 0;
 }
 
-static int pvscsi_queue(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
+static int pvscsi_queue_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
 {
        struct Scsi_Host *host = cmd->device->host;
        struct pvscsi_adapter *adapter = shost_priv(host);
@@ -719,6 +719,8 @@ static int pvscsi_queue(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
        return 0;
 }
 
+static DEF_SCSI_QCMD(pvscsi_queue)
+
 static int pvscsi_abort(struct scsi_cmnd *cmd)
 {
        struct pvscsi_adapter *adapter = shost_priv(cmd->device->host);
index b701bf2cc1873fb579b64d923f0950ce36d92c60..5f697e0bd0095c97f1c21326bc6c073a8fc61d40 100644 (file)
@@ -371,8 +371,8 @@ calc_sync_msg(unsigned int period, unsigned int offset, unsigned int fast,
        msg[1] = offset;
 }
 
-int
-wd33c93_queuecommand(struct scsi_cmnd *cmd,
+static int
+wd33c93_queuecommand_lck(struct scsi_cmnd *cmd,
                void (*done)(struct scsi_cmnd *))
 {
        struct WD33C93_hostdata *hostdata;
@@ -468,6 +468,8 @@ wd33c93_queuecommand(struct scsi_cmnd *cmd,
        return 0;
 }
 
+DEF_SCSI_QCMD(wd33c93_queuecommand)
+
 /*
  * This routine attempts to start a scsi command. If the host_card is
  * already connected, we give up immediately. Otherwise, look through
index 1ed5f3bf388eeea541ac6a097c3103d69528a5c8..3b463d7304dca635cf3f4360c7aa6d9430127f63 100644 (file)
@@ -343,8 +343,7 @@ struct WD33C93_hostdata {
 void wd33c93_init (struct Scsi_Host *instance, const wd33c93_regs regs,
          dma_setup_t setup, dma_stop_t stop, int clock_freq);
 int wd33c93_abort (struct scsi_cmnd *cmd);
-int wd33c93_queuecommand (struct scsi_cmnd *cmd,
-               void (*done)(struct scsi_cmnd *));
+int wd33c93_queuecommand (struct Scsi_Host *h, struct scsi_cmnd *cmd);
 void wd33c93_intr (struct Scsi_Host *instance);
 int wd33c93_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int);
 int wd33c93_host_reset (struct scsi_cmnd *);
index 333580bf37c5a7d6cbccf6587d55ad7a2b3b3b2b..db451ae0a36811427165b9d0431d3b38d356ec8e 100644 (file)
@@ -1082,7 +1082,7 @@ static irqreturn_t wd7000_intr(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
-static int wd7000_queuecommand(struct scsi_cmnd *SCpnt,
+static int wd7000_queuecommand_lck(struct scsi_cmnd *SCpnt,
                void (*done)(struct scsi_cmnd *))
 {
        Scb *scb;
@@ -1139,6 +1139,8 @@ static int wd7000_queuecommand(struct scsi_cmnd *SCpnt,
        return 0;
 }
 
+static DEF_SCSI_QCMD(wd7000_queuecommand)
+
 static int wd7000_diagnostics(Adapter * host, int code)
 {
        static IcbDiag icb = { ICB_OP_DIAGNOSTICS };
index fa62578fcd20f572dbd391b614e47f246250b978..bcc31f2140ac7528811d607fd0e3e1f1f6cd66d4 100644 (file)
@@ -18,7 +18,6 @@ static char *serial_version = "$Revision: 1.25 $";
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
 #include <linux/major.h>
-#include <linux/smp_lock.h>
 #include <linux/string.h>
 #include <linux/fcntl.h>
 #include <linux/mm.h>
index c4ea14670d4486fc142df31d806c528d2752c238..9ffa5bee44ab17b852f9bbaa5b9a5a8f3853286d 100644 (file)
@@ -29,7 +29,6 @@
 #include <linux/console.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
-#include <linux/smp_lock.h>
 #include <linux/device.h>
 #include <linux/serial.h> /* for serial_state and serial_icounter_struct */
 #include <linux/serial_core.h>
index f3c827eb0abe066bac548b0173cd86b01fb251d8..25961c23dc0f4dc3068e8d79eb9eaf7d749c5782 100644 (file)
@@ -77,7 +77,6 @@
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/kref.h>
-#include <linux/smp_lock.h>
 #include <linux/usb.h>
 #include <linux/uaccess.h>
 
index 41d9acf4cd6119c1d52254df01faaf793e47e622..6f8d67d0d64fd20b77b515b696d9e92c485ed5e4 100644 (file)
@@ -72,8 +72,7 @@ struct storvsc_driver_context {
 
 /* Static decl */
 static int storvsc_probe(struct device *dev);
-static int storvsc_queuecommand(struct scsi_cmnd *scmnd,
-                               void (*done)(struct scsi_cmnd *));
+static int storvsc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmnd);
 static int storvsc_device_alloc(struct scsi_device *);
 static int storvsc_device_configure(struct scsi_device *);
 static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd);
@@ -595,7 +594,7 @@ static unsigned int copy_from_bounce_buffer(struct scatterlist *orig_sgl,
 /*
  * storvsc_queuecommand - Initiate command processing
  */
-static int storvsc_queuecommand(struct scsi_cmnd *scmnd,
+static int storvsc_queuecommand_lck(struct scsi_cmnd *scmnd,
                                void (*done)(struct scsi_cmnd *))
 {
        int ret;
@@ -783,6 +782,8 @@ retry_request:
        return ret;
 }
 
+static DEF_SCSI_QCMD(storvsc_queuecommand)
+
 static int storvsc_merge_bvec(struct request_queue *q,
                              struct bvec_merge_data *bmd, struct bio_vec *bvec)
 {
index 9618c79974611f682a8d4dd575f704cf00f92443..991440015e9263e415a9449eb9fa7f34dae07f41 100644 (file)
@@ -34,7 +34,6 @@
 #include <linux/uaccess.h>
 #include <linux/firmware.h>
 #include <linux/ioctl.h>
-#include <linux/smp_lock.h>
 #ifdef CONFIG_MRST_RAR_HANDLER
 #include <linux/rar_register.h>
 #include "../../../drivers/staging/memrar/memrar.h"
index a2671404f7ac244c39f51c44303fae0df16fceaf..da4f42af3838eb209e7545128b74d0aaedcebe7b 100644 (file)
@@ -87,7 +87,7 @@ static int slave_configure(struct scsi_device *sdev)
 
 /* This is always called with scsi_lock(host) held */
 //----- queuecommand() ---------------------
-static int queuecommand(struct scsi_cmnd *srb, void (*done)(struct scsi_cmnd *))
+static int queuecommand_lck(struct scsi_cmnd *srb, void (*done)(struct scsi_cmnd *))
 {
        struct us_data *us = host_to_us(srb->device->host);
 
@@ -117,6 +117,8 @@ static int queuecommand(struct scsi_cmnd *srb, void (*done)(struct scsi_cmnd *))
        return 0;
 }
 
+static DEF_SCSI_QCMD(queuecommand)
+
 /***********************************************************************
  * Error handling functions
  ***********************************************************************/
index d1674cd282dcd7deb370cca6b75c8f0f69b3ed73..831d81e0e429b81924a53f8cad76aebd02d8be4d 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/kref.h>
-#include <linux/smp_lock.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/usb.h>
index b7b60d5e866023d461a8661a2fa278330ff8a5de..a2db956edd54db0f81979bd038bcfc5d348a7232 100644 (file)
@@ -1,5 +1,4 @@
 #include <linux/console.h>
-#include <linux/smp_lock.h>
 #include <linux/types.h>
 #include <linux/wait.h>
 
index 92e8911418962d19796e6dadf7db52d43ea745b7..02f0fc504cf5ef13595ad67b7668c28a54534ce7 100644 (file)
@@ -1,6 +1,6 @@
 config VIDEO_STRADIS
         tristate "Stradis 4:2:2 MPEG-2 video driver (DEPRECATED)"
-        depends on EXPERIMENTAL && PCI && VIDEO_V4L1 && VIRT_TO_BUS
+        depends on EXPERIMENTAL && PCI && VIDEO_V4L1 && VIRT_TO_BUS && BKL
         help
           Say Y here to enable support for the Stradis 4:2:2 MPEG-2 video
           driver for PCI.  There is a product page at
index eaa5d3efa79da4cb061b4fbaf9d6acb6f21afd5e..c556ed9db13d82a4bd7dcff1bb599dce6abd8341 100644 (file)
@@ -554,7 +554,7 @@ EXPORT_SYMBOL(handle_sysrq);
 #ifdef CONFIG_INPUT
 
 /* Simple translation table for the SysRq keys */
-static const unsigned char sysrq_xlate[KEY_MAX + 1] =
+static const unsigned char sysrq_xlate[KEY_CNT] =
         "\000\0331234567890-=\177\t"                    /* 0x00 - 0x0f */
         "qwertyuiop[]\r\000as"                          /* 0x10 - 0x1f */
         "dfghjkl;'`\000\\zxcv"                          /* 0x20 - 0x2f */
@@ -563,53 +563,129 @@ static const unsigned char sysrq_xlate[KEY_MAX + 1] =
         "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */
         "\r\000/";                                      /* 0x60 - 0x6f */
 
-static bool sysrq_down;
-static int sysrq_alt_use;
-static int sysrq_alt;
-static DEFINE_SPINLOCK(sysrq_event_lock);
+struct sysrq_state {
+       struct input_handle handle;
+       struct work_struct reinject_work;
+       unsigned long key_down[BITS_TO_LONGS(KEY_CNT)];
+       unsigned int alt;
+       unsigned int alt_use;
+       bool active;
+       bool need_reinject;
+};
+
+static void sysrq_reinject_alt_sysrq(struct work_struct *work)
+{
+       struct sysrq_state *sysrq =
+                       container_of(work, struct sysrq_state, reinject_work);
+       struct input_handle *handle = &sysrq->handle;
+       unsigned int alt_code = sysrq->alt_use;
+
+       if (sysrq->need_reinject) {
+               /* Simulate press and release of Alt + SysRq */
+               input_inject_event(handle, EV_KEY, alt_code, 1);
+               input_inject_event(handle, EV_KEY, KEY_SYSRQ, 1);
+               input_inject_event(handle, EV_SYN, SYN_REPORT, 1);
+
+               input_inject_event(handle, EV_KEY, KEY_SYSRQ, 0);
+               input_inject_event(handle, EV_KEY, alt_code, 0);
+               input_inject_event(handle, EV_SYN, SYN_REPORT, 1);
+       }
+}
 
-static bool sysrq_filter(struct input_handle *handle, unsigned int type,
-                        unsigned int code, int value)
+static bool sysrq_filter(struct input_handle *handle,
+                        unsigned int type, unsigned int code, int value)
 {
+       struct sysrq_state *sysrq = handle->private;
+       bool was_active = sysrq->active;
        bool suppress;
 
-       /* We are called with interrupts disabled, just take the lock */
-       spin_lock(&sysrq_event_lock);
+       switch (type) {
 
-       if (type != EV_KEY)
-               goto out;
+       case EV_SYN:
+               suppress = false;
+               break;
 
-       switch (code) {
+       case EV_KEY:
+               switch (code) {
 
-       case KEY_LEFTALT:
-       case KEY_RIGHTALT:
-               if (value)
-                       sysrq_alt = code;
-               else {
-                       if (sysrq_down && code == sysrq_alt_use)
-                               sysrq_down = false;
+               case KEY_LEFTALT:
+               case KEY_RIGHTALT:
+                       if (!value) {
+                               /* One of ALTs is being released */
+                               if (sysrq->active && code == sysrq->alt_use)
+                                       sysrq->active = false;
 
-                       sysrq_alt = 0;
+                               sysrq->alt = KEY_RESERVED;
+
+                       } else if (value != 2) {
+                               sysrq->alt = code;
+                               sysrq->need_reinject = false;
+                       }
+                       break;
+
+               case KEY_SYSRQ:
+                       if (value == 1 && sysrq->alt != KEY_RESERVED) {
+                               sysrq->active = true;
+                               sysrq->alt_use = sysrq->alt;
+                               /*
+                                * If nothing else will be pressed we'll need
+                                * to * re-inject Alt-SysRq keysroke.
+                                */
+                               sysrq->need_reinject = true;
+                       }
+
+                       /*
+                        * Pretend that sysrq was never pressed at all. This
+                        * is needed to properly handle KGDB which will try
+                        * to release all keys after exiting debugger. If we
+                        * do not clear key bit it KGDB will end up sending
+                        * release events for Alt and SysRq, potentially
+                        * triggering print screen function.
+                        */
+                       if (sysrq->active)
+                               clear_bit(KEY_SYSRQ, handle->dev->key);
+
+                       break;
+
+               default:
+                       if (sysrq->active && value && value != 2) {
+                               sysrq->need_reinject = false;
+                               __handle_sysrq(sysrq_xlate[code], true);
+                       }
+                       break;
                }
-               break;
 
-       case KEY_SYSRQ:
-               if (value == 1 && sysrq_alt) {
-                       sysrq_down = true;
-                       sysrq_alt_use = sysrq_alt;
+               suppress = sysrq->active;
+
+               if (!sysrq->active) {
+                       /*
+                        * If we are not suppressing key presses keep track of
+                        * keyboard state so we can release keys that have been
+                        * pressed before entering SysRq mode.
+                        */
+                       if (value)
+                               set_bit(code, sysrq->key_down);
+                       else
+                               clear_bit(code, sysrq->key_down);
+
+                       if (was_active)
+                               schedule_work(&sysrq->reinject_work);
+
+               } else if (value == 0 &&
+                          test_and_clear_bit(code, sysrq->key_down)) {
+                       /*
+                        * Pass on release events for keys that was pressed before
+                        * entering SysRq mode.
+                        */
+                       suppress = false;
                }
                break;
 
        default:
-               if (sysrq_down && value && value != 2)
-                       __handle_sysrq(sysrq_xlate[code], true);
+               suppress = sysrq->active;
                break;
        }
 
-out:
-       suppress = sysrq_down;
-       spin_unlock(&sysrq_event_lock);
-
        return suppress;
 }
 
@@ -617,28 +693,28 @@ static int sysrq_connect(struct input_handler *handler,
                         struct input_dev *dev,
                         const struct input_device_id *id)
 {
-       struct input_handle *handle;
+       struct sysrq_state *sysrq;
        int error;
 
-       sysrq_down = false;
-       sysrq_alt = 0;
-
-       handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
-       if (!handle)
+       sysrq = kzalloc(sizeof(struct sysrq_state), GFP_KERNEL);
+       if (!sysrq)
                return -ENOMEM;
 
-       handle->dev = dev;
-       handle->handler = handler;
-       handle->name = "sysrq";
+       INIT_WORK(&sysrq->reinject_work, sysrq_reinject_alt_sysrq);
+
+       sysrq->handle.dev = dev;
+       sysrq->handle.handler = handler;
+       sysrq->handle.name = "sysrq";
+       sysrq->handle.private = sysrq;
 
-       error = input_register_handle(handle);
+       error = input_register_handle(&sysrq->handle);
        if (error) {
                pr_err("Failed to register input sysrq handler, error %d\n",
                        error);
                goto err_free;
        }
 
-       error = input_open_device(handle);
+       error = input_open_device(&sysrq->handle);
        if (error) {
                pr_err("Failed to open input device, error %d\n", error);
                goto err_unregister;
@@ -647,17 +723,20 @@ static int sysrq_connect(struct input_handler *handler,
        return 0;
 
  err_unregister:
-       input_unregister_handle(handle);
+       input_unregister_handle(&sysrq->handle);
  err_free:
-       kfree(handle);
+       kfree(sysrq);
        return error;
 }
 
 static void sysrq_disconnect(struct input_handle *handle)
 {
+       struct sysrq_state *sysrq = handle->private;
+
        input_close_device(handle);
+       cancel_work_sync(&sysrq->reinject_work);
        input_unregister_handle(handle);
-       kfree(handle);
+       kfree(sysrq);
 }
 
 /*
index ddb4dc980923e443e9cc2f3e0da30855ca59ff5b..a3d2e2399655b84a348561e8aa27521212f21831 100644 (file)
@@ -54,7 +54,6 @@
 #include <linux/gfp.h>
 #include <linux/poll.h>
 #include <linux/usb.h>
-#include <linux/smp_lock.h>
 #include <linux/usbdevice_fs.h>
 #include <linux/usb/hcd.h>
 #include <linux/mutex.h>
index 045bb4b823e175fa2d16e228071e138a2c8a44e8..a7131ad630f9ad54535205017352ee10175df384 100644 (file)
@@ -37,7 +37,6 @@
 #include <linux/fs.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/signal.h>
 #include <linux/poll.h>
 #include <linux/module.h>
index 9fe34fb78ef11c4d0dd88065502c6e92cd4398f3..cf6a5423de0997b424fe06c051acd1e7d305519f 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/errno.h>
 #include <linux/rwsem.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/usb.h>
 
 #include "usb.h"
index 9819a4cc3b264d48111a08a8d51e242b0b1329d8..b690aa35df9a35117394c4177213e3f5ad286162 100644 (file)
@@ -39,7 +39,6 @@
 #include <linux/parser.h>
 #include <linux/notifier.h>
 #include <linux/seq_file.h>
-#include <linux/smp_lock.h>
 #include <linux/usb/hcd.h>
 #include <asm/byteorder.h>
 #include "usb.h"
index 4a830df4fc31a1a58692f6b1b5adc29a7a9895c4..484c5ba5450ebfc254613ca04cd9c8ac9227aaf6 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/blkdev.h>
 #include <linux/pagemap.h>
 #include <asm/unaligned.h>
-#include <linux/smp_lock.h>
 
 #include <linux/usb/composite.h>
 #include <linux/usb/functionfs.h>
index 4f891eddd06041886b664d54f7488d9b00fcf781..598e7e2ab80c666f1395f1db6c30aaa44f34d646 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/cdev.h>
 #include <linux/mutex.h>
 #include <linux/poll.h>
-#include <linux/smp_lock.h>
 #include <linux/uaccess.h>
 #include <linux/wait.h>
 #include <linux/usb/g_hid.h>
index 8196fa11fec43678cb96b4c3241fd63b7fc1b35f..6c4fb4efb4bb9251c531df4cabd51e8b7a65607b 100644 (file)
@@ -70,7 +70,6 @@
 #include <linux/ioport.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/list.h>
index 6e7fb5f38db6379f0318f223f31054798e4640f0..ee60cd3ea64201dc4e86d534651c0699d7e8f1ef 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/debugfs.h>
-#include <linux/smp_lock.h>
 #include <asm/io.h>
 
 #include "uhci-hcd.h"
index 5a47805d9580740c7ef33f75bb0fafd0a2c73dad..c90c89dc00035c1e3c2da06fb177f11c82ed28dd 100644 (file)
@@ -364,7 +364,7 @@ static int mts_scsi_host_reset(struct scsi_cmnd *srb)
 }
 
 static int
-mts_scsi_queuecommand(struct scsi_cmnd *srb, mts_scsi_cmnd_callback callback);
+mts_scsi_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *srb);
 
 static void mts_transfer_cleanup( struct urb *transfer );
 static void mts_do_sg(struct urb * transfer);
@@ -573,7 +573,7 @@ mts_build_transfer_context(struct scsi_cmnd *srb, struct mts_desc* desc)
 
 
 static int
-mts_scsi_queuecommand(struct scsi_cmnd *srb, mts_scsi_cmnd_callback callback)
+mts_scsi_queuecommand_lck(struct scsi_cmnd *srb, mts_scsi_cmnd_callback callback)
 {
        struct mts_desc* desc = (struct mts_desc*)(srb->device->host->hostdata[0]);
        int err = 0;
@@ -626,6 +626,8 @@ out:
        return err;
 }
 
+static DEF_SCSI_QCMD(mts_scsi_queuecommand)
+
 static struct scsi_host_template mts_scsi_host_template = {
        .module                 = THIS_MODULE,
        .name                   = "microtekX6",
index 44cb37b5a4dc1f9b27075e3db5346b9ebe307b22..c436e1e2c3b6274f0fdcdb699ec1fd10a9b2273f 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/poll.h>
 #include <linux/compat.h>
 #include <linux/mm.h>
-#include <linux/smp_lock.h>
 #include <linux/scatterlist.h>
 #include <linux/slab.h>
 
index 8ec94f15a73820ce5a1b26b8ed5d86fa04b6bba4..e5ce42bd316e5c68d29a72ffdc2d805b6a575f37 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/fs.h>
-#include <linux/smp_lock.h>
 #include <asm/uaccess.h>
 
 #include "usb_mon.h"
index e64da74bdcc5d112ff20cf46e0c074115ca3ee67..861223f2af6eddc0a3fb3c4a449b71af9221eed4 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/tty.h>
 #include <linux/tty_driver.h>
 #include <linux/tty_flip.h>
index a688b1e686eae326d26da45bf37fa378524e6624..689ee1fb702a4351a7fdb2a0e0a400a682eabd4f 100644 (file)
@@ -285,7 +285,7 @@ static int slave_configure(struct scsi_device *sdev)
 
 /* queue a command */
 /* This is always called with scsi_lock(host) held */
-static int queuecommand(struct scsi_cmnd *srb,
+static int queuecommand_lck(struct scsi_cmnd *srb,
                        void (*done)(struct scsi_cmnd *))
 {
        struct us_data *us = host_to_us(srb->device->host);
@@ -315,6 +315,8 @@ static int queuecommand(struct scsi_cmnd *srb,
        return 0;
 }
 
+static DEF_SCSI_QCMD(queuecommand)
+
 /***********************************************************************
  * Error handling functions
  ***********************************************************************/
index d1268191acbde5ead493c660558fce8a23e833a8..339fac3949df870bd838c08fe652386ddfdde172 100644 (file)
@@ -430,7 +430,7 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd,
        return 0;
 }
 
-static int uas_queuecommand(struct scsi_cmnd *cmnd,
+static int uas_queuecommand_lck(struct scsi_cmnd *cmnd,
                                        void (*done)(struct scsi_cmnd *))
 {
        struct scsi_device *sdev = cmnd->device;
@@ -488,6 +488,8 @@ static int uas_queuecommand(struct scsi_cmnd *cmnd,
        return 0;
 }
 
+static DEF_SCSI_QCMD(uas_queuecommand)
+
 static int uas_eh_abort_handler(struct scsi_cmnd *cmnd)
 {
        struct scsi_device *sdev = cmnd->device;
index 54e32c513610f8164839c2c167e3eccc09bbdb8b..915448ec75bf2fd33617eb73517876da74c68137 100644 (file)
@@ -47,7 +47,6 @@
 #include <linux/ioport.h>
 #include <linux/init.h>
 #include <linux/screen_info.h>
-#include <linux/smp_lock.h>
 #include <video/vga.h>
 #include <asm/io.h>
 
index f80be7f6eb95265d223a40f2166bc29b6fb8d3c6..0f5d4162b22d50b66ce84eca9add1f6fdaa5c3d2 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/mman.h>
 #include <linux/uaccess.h>
 #include <linux/swap.h>
-#include <linux/smp_lock.h>
 #include <linux/highmem.h>
 #include <linux/pagemap.h>
 #include <linux/seq_file.h>
index cafc504542927751f25650ce2ea2639dcdbc8bef..e0c84725d3e94e05a33482349dc90f45f59099a9 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/init.h>
-#include <linux/smp_lock.h>
 #include <asm/uaccess.h>
 #include <asm/amigahw.h>
 #include <asm/setup.h>
index 06e8ff12b97c8fa74d4b2eb05c900801b3adb150..4230252fd6895c97cb81541741f9e8e584e04322 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/slab.h>
 #include <linux/kmod.h>
 #include <linux/major.h>
-#include <linux/smp_lock.h>
 #include <linux/device_cgroup.h>
 #include <linux/highmem.h>
 #include <linux/blkdev.h>
index e9c874abc9e1f4a7ec00b68595fdd674a4f1da2e..561438b6a50cd3789b90d54e473562431d528ec8 100644 (file)
@@ -204,7 +204,7 @@ static int readpage_nounlock(struct file *filp, struct page *page)
        err = ceph_osdc_readpages(osdc, ceph_vino(inode), &ci->i_layout,
                                  page->index << PAGE_CACHE_SHIFT, &len,
                                  ci->i_truncate_seq, ci->i_truncate_size,
-                                 &page, 1);
+                                 &page, 1, 0);
        if (err == -ENOENT)
                err = 0;
        if (err < 0) {
@@ -287,7 +287,7 @@ static int ceph_readpages(struct file *file, struct address_space *mapping,
        rc = ceph_osdc_readpages(osdc, ceph_vino(inode), &ci->i_layout,
                                 offset, &len,
                                 ci->i_truncate_seq, ci->i_truncate_size,
-                                pages, nr_pages);
+                                pages, nr_pages, 0);
        if (rc == -ENOENT)
                rc = 0;
        if (rc < 0)
@@ -774,7 +774,7 @@ get_more_pages:
                                            snapc, do_sync,
                                            ci->i_truncate_seq,
                                            ci->i_truncate_size,
-                                           &inode->i_mtime, true, 1);
+                                           &inode->i_mtime, true, 1, 0);
                                max_pages = req->r_num_pages;
 
                                alloc_page_vec(fsc, req);
index 98ab13e2b71d9d8ebcbf1715da112d78cb0bac17..60d27bc9eb83d82f61e448031495625e42c752d3 100644 (file)
@@ -1430,8 +1430,8 @@ static int try_nonblocking_invalidate(struct inode *inode)
            invalidating_gen == ci->i_rdcache_gen) {
                /* success. */
                dout("try_nonblocking_invalidate %p success\n", inode);
-               ci->i_rdcache_gen = 0;
-               ci->i_rdcache_revoking = 0;
+               /* save any racing async invalidate some trouble */
+               ci->i_rdcache_revoking = ci->i_rdcache_gen - 1;
                return 0;
        }
        dout("try_nonblocking_invalidate %p failed\n", inode);
@@ -2273,8 +2273,7 @@ static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant,
 {
        struct ceph_inode_info *ci = ceph_inode(inode);
        int mds = session->s_mds;
-       unsigned seq = le32_to_cpu(grant->seq);
-       unsigned issue_seq = le32_to_cpu(grant->issue_seq);
+       int seq = le32_to_cpu(grant->seq);
        int newcaps = le32_to_cpu(grant->caps);
        int issued, implemented, used, wanted, dirty;
        u64 size = le64_to_cpu(grant->size);
@@ -2286,8 +2285,8 @@ static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant,
        int revoked_rdcache = 0;
        int queue_invalidate = 0;
 
-       dout("handle_cap_grant inode %p cap %p mds%d seq %u/%u %s\n",
-            inode, cap, mds, seq, issue_seq, ceph_cap_string(newcaps));
+       dout("handle_cap_grant inode %p cap %p mds%d seq %d %s\n",
+            inode, cap, mds, seq, ceph_cap_string(newcaps));
        dout(" size %llu max_size %llu, i_size %llu\n", size, max_size,
                inode->i_size);
 
@@ -2383,7 +2382,6 @@ static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant,
        }
 
        cap->seq = seq;
-       cap->issue_seq = issue_seq;
 
        /* file layout may have changed */
        ci->i_layout = grant->layout;
@@ -2691,6 +2689,11 @@ static void handle_cap_import(struct ceph_mds_client *mdsc,
                     NULL /* no caps context */);
        try_flush_caps(inode, session, NULL);
        up_read(&mdsc->snap_rwsem);
+
+       /* make sure we re-request max_size, if necessary */
+       spin_lock(&inode->i_lock);
+       ci->i_requested_max_size = 0;
+       spin_unlock(&inode->i_lock);
 }
 
 /*
index e0a2dc6fcafcb62266909c5ec71329e58083d1d7..7d447af84ec4861acee8cd82bcecf80a892132b1 100644 (file)
@@ -336,7 +336,10 @@ more:
                if (req->r_reply_info.dir_end) {
                        kfree(fi->last_name);
                        fi->last_name = NULL;
-                       fi->next_offset = 2;
+                       if (ceph_frag_is_rightmost(frag))
+                               fi->next_offset = 2;
+                       else
+                               fi->next_offset = 0;
                } else {
                        rinfo = &req->r_reply_info;
                        err = note_last_dentry(fi,
@@ -355,18 +358,22 @@ more:
                u64 pos = ceph_make_fpos(frag, off);
                struct ceph_mds_reply_inode *in =
                        rinfo->dir_in[off - fi->offset].in;
+               struct ceph_vino vino;
+               ino_t ino;
+
                dout("readdir off %d (%d/%d) -> %lld '%.*s' %p\n",
                     off, off - fi->offset, rinfo->dir_nr, pos,
                     rinfo->dir_dname_len[off - fi->offset],
                     rinfo->dir_dname[off - fi->offset], in);
                BUG_ON(!in);
                ftype = le32_to_cpu(in->mode) >> 12;
+               vino.ino = le64_to_cpu(in->ino);
+               vino.snap = le64_to_cpu(in->snapid);
+               ino = ceph_vino_to_ino(vino);
                if (filldir(dirent,
                            rinfo->dir_dname[off - fi->offset],
                            rinfo->dir_dname_len[off - fi->offset],
-                           pos,
-                           le64_to_cpu(in->ino),
-                           ftype) < 0) {
+                           pos, ino, ftype) < 0) {
                        dout("filldir stopping us...\n");
                        return 0;
                }
@@ -414,6 +421,7 @@ static void reset_readdir(struct ceph_file_info *fi)
                fi->last_readdir = NULL;
        }
        kfree(fi->last_name);
+       fi->last_name = NULL;
        fi->next_offset = 2;  /* compensate for . and .. */
        if (fi->dentry) {
                dput(fi->dentry);
index e77c28cf369059112dd06ee3b7c78c5146f0ffdc..8d79b8912e31e4cb8fcb4961ec1f81d63c3d5070 100644 (file)
@@ -154,11 +154,13 @@ int ceph_open(struct inode *inode, struct file *file)
        }
 
        /*
-        * No need to block if we have any caps.  Update wanted set
+        * No need to block if we have caps on the auth MDS (for
+        * write) or any MDS (for read).  Update wanted set
         * asynchronously.
         */
        spin_lock(&inode->i_lock);
-       if (__ceph_is_any_real_caps(ci)) {
+       if (__ceph_is_any_real_caps(ci) &&
+           (((fmode & CEPH_FILE_MODE_WR) == 0) || ci->i_auth_cap)) {
                int mds_wanted = __ceph_caps_mds_wanted(ci);
                int issued = __ceph_caps_issued(ci, NULL);
 
@@ -280,11 +282,12 @@ int ceph_release(struct inode *inode, struct file *file)
 static int striped_read(struct inode *inode,
                        u64 off, u64 len,
                        struct page **pages, int num_pages,
-                       int *checkeof)
+                       int *checkeof, bool align_to_pages)
 {
        struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
        struct ceph_inode_info *ci = ceph_inode(inode);
        u64 pos, this_len;
+       int io_align, page_align;
        int page_off = off & ~PAGE_CACHE_MASK; /* first byte's offset in page */
        int left, pages_left;
        int read;
@@ -300,14 +303,19 @@ static int striped_read(struct inode *inode,
        page_pos = pages;
        pages_left = num_pages;
        read = 0;
+       io_align = off & ~PAGE_MASK;
 
 more:
+       if (align_to_pages)
+               page_align = (pos - io_align) & ~PAGE_MASK;
+       else
+               page_align = pos & ~PAGE_MASK;
        this_len = left;
        ret = ceph_osdc_readpages(&fsc->client->osdc, ceph_vino(inode),
                                  &ci->i_layout, pos, &this_len,
                                  ci->i_truncate_seq,
                                  ci->i_truncate_size,
-                                 page_pos, pages_left);
+                                 page_pos, pages_left, page_align);
        hit_stripe = this_len < left;
        was_short = ret >= 0 && ret < this_len;
        if (ret == -ENOENT)
@@ -374,26 +382,25 @@ static ssize_t ceph_sync_read(struct file *file, char __user *data,
        dout("sync_read on file %p %llu~%u %s\n", file, off, len,
             (file->f_flags & O_DIRECT) ? "O_DIRECT" : "");
 
-       if (file->f_flags & O_DIRECT) {
-               pages = ceph_get_direct_page_vector(data, num_pages, off, len);
-
-               /*
-                * flush any page cache pages in this range.  this
-                * will make concurrent normal and O_DIRECT io slow,
-                * but it will at least behave sensibly when they are
-                * in sequence.
-                */
-       } else {
+       if (file->f_flags & O_DIRECT)
+               pages = ceph_get_direct_page_vector(data, num_pages);
+       else
                pages = ceph_alloc_page_vector(num_pages, GFP_NOFS);
-       }
        if (IS_ERR(pages))
                return PTR_ERR(pages);
 
+       /*
+        * flush any page cache pages in this range.  this
+        * will make concurrent normal and sync io slow,
+        * but it will at least behave sensibly when they are
+        * in sequence.
+        */
        ret = filemap_write_and_wait(inode->i_mapping);
        if (ret < 0)
                goto done;
 
-       ret = striped_read(inode, off, len, pages, num_pages, checkeof);
+       ret = striped_read(inode, off, len, pages, num_pages, checkeof,
+                          file->f_flags & O_DIRECT);
 
        if (ret >= 0 && (file->f_flags & O_DIRECT) == 0)
                ret = ceph_copy_page_vector_to_user(pages, data, off, ret);
@@ -448,6 +455,7 @@ static ssize_t ceph_sync_write(struct file *file, const char __user *data,
        int flags;
        int do_sync = 0;
        int check_caps = 0;
+       int page_align, io_align;
        int ret;
        struct timespec mtime = CURRENT_TIME;
 
@@ -462,6 +470,8 @@ static ssize_t ceph_sync_write(struct file *file, const char __user *data,
        else
                pos = *offset;
 
+       io_align = pos & ~PAGE_MASK;
+
        ret = filemap_write_and_wait_range(inode->i_mapping, pos, pos + left);
        if (ret < 0)
                return ret;
@@ -486,20 +496,26 @@ static ssize_t ceph_sync_write(struct file *file, const char __user *data,
         */
 more:
        len = left;
+       if (file->f_flags & O_DIRECT)
+               /* write from beginning of first page, regardless of
+                  io alignment */
+               page_align = (pos - io_align) & ~PAGE_MASK;
+       else
+               page_align = pos & ~PAGE_MASK;
        req = ceph_osdc_new_request(&fsc->client->osdc, &ci->i_layout,
                                    ceph_vino(inode), pos, &len,
                                    CEPH_OSD_OP_WRITE, flags,
                                    ci->i_snap_realm->cached_context,
                                    do_sync,
                                    ci->i_truncate_seq, ci->i_truncate_size,
-                                   &mtime, false, 2);
+                                   &mtime, false, 2, page_align);
        if (!req)
                return -ENOMEM;
 
        num_pages = calc_pages_for(pos, len);
 
        if (file->f_flags & O_DIRECT) {
-               pages = ceph_get_direct_page_vector(data, num_pages, pos, len);
+               pages = ceph_get_direct_page_vector(data, num_pages);
                if (IS_ERR(pages)) {
                        ret = PTR_ERR(pages);
                        goto out;
index 1d6a45b5a04c696591879d141165627746d6a476..bf1286588f26b3afb039e4036ddb2a469fcad638 100644 (file)
@@ -2,7 +2,6 @@
 
 #include <linux/module.h>
 #include <linux/fs.h>
-#include <linux/smp_lock.h>
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/uaccess.h>
@@ -471,7 +470,9 @@ void ceph_fill_file_time(struct inode *inode, int issued,
 
        if (issued & (CEPH_CAP_FILE_EXCL|
                      CEPH_CAP_FILE_WR|
-                     CEPH_CAP_FILE_BUFFER)) {
+                     CEPH_CAP_FILE_BUFFER|
+                     CEPH_CAP_AUTH_EXCL|
+                     CEPH_CAP_XATTR_EXCL)) {
                if (timespec_compare(ctime, &inode->i_ctime) > 0) {
                        dout("ctime %ld.%09ld -> %ld.%09ld inc w/ cap\n",
                             inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec,
@@ -511,7 +512,7 @@ void ceph_fill_file_time(struct inode *inode, int issued,
                        warn = 1;
                }
        } else {
-               /* we have no write caps; whatever the MDS says is true */
+               /* we have no write|excl caps; whatever the MDS says is true */
                if (ceph_seq_cmp(time_warp_seq, ci->i_time_warp_seq) >= 0) {
                        inode->i_ctime = *ctime;
                        inode->i_mtime = *mtime;
@@ -567,12 +568,17 @@ static int fill_inode(struct inode *inode,
 
        /*
         * provided version will be odd if inode value is projected,
-        * even if stable.  skip the update if we have a newer info
-        * (e.g., due to inode info racing form multiple MDSs), or if
-        * we are getting projected (unstable) inode info.
+        * even if stable.  skip the update if we have newer stable
+        * info (ours>=theirs, e.g. due to racing mds replies), unless
+        * we are getting projected (unstable) info (in which case the
+        * version is odd, and we want ours>theirs).
+        *   us   them
+        *   2    2     skip
+        *   3    2     skip
+        *   3    3     update
         */
        if (le64_to_cpu(info->version) > 0 &&
-           (ci->i_version & ~1) > le64_to_cpu(info->version))
+           (ci->i_version & ~1) >= le64_to_cpu(info->version))
                goto no_change;
 
        issued = __ceph_caps_issued(ci, &implemented);
@@ -606,7 +612,14 @@ static int fill_inode(struct inode *inode,
                            le32_to_cpu(info->time_warp_seq),
                            &ctime, &mtime, &atime);
 
-       ci->i_max_size = le64_to_cpu(info->max_size);
+       /* only update max_size on auth cap */
+       if ((info->cap.flags & CEPH_CAP_FLAG_AUTH) &&
+           ci->i_max_size != le64_to_cpu(info->max_size)) {
+               dout("max_size %lld -> %llu\n", ci->i_max_size,
+                    le64_to_cpu(info->max_size));
+               ci->i_max_size = le64_to_cpu(info->max_size);
+       }
+
        ci->i_layout = info->layout;
        inode->i_blkbits = fls(le32_to_cpu(info->layout.fl_stripe_unit)) - 1;
 
@@ -1055,7 +1068,8 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
                ininfo = rinfo->targeti.in;
                vino.ino = le64_to_cpu(ininfo->ino);
                vino.snap = le64_to_cpu(ininfo->snapid);
-               if (!dn->d_inode) {
+               in = dn->d_inode;
+               if (!in) {
                        in = ceph_get_inode(sb, vino);
                        if (IS_ERR(in)) {
                                pr_err("fill_trace bad get_inode "
@@ -1386,11 +1400,8 @@ static void ceph_invalidate_work(struct work_struct *work)
        spin_lock(&inode->i_lock);
        dout("invalidate_pages %p gen %d revoking %d\n", inode,
             ci->i_rdcache_gen, ci->i_rdcache_revoking);
-       if (ci->i_rdcache_gen == 0 ||
-           ci->i_rdcache_revoking != ci->i_rdcache_gen) {
-               BUG_ON(ci->i_rdcache_revoking > ci->i_rdcache_gen);
+       if (ci->i_rdcache_revoking != ci->i_rdcache_gen) {
                /* nevermind! */
-               ci->i_rdcache_revoking = 0;
                spin_unlock(&inode->i_lock);
                goto out;
        }
@@ -1400,15 +1411,16 @@ static void ceph_invalidate_work(struct work_struct *work)
        ceph_invalidate_nondirty_pages(inode->i_mapping);
 
        spin_lock(&inode->i_lock);
-       if (orig_gen == ci->i_rdcache_gen) {
+       if (orig_gen == ci->i_rdcache_gen &&
+           orig_gen == ci->i_rdcache_revoking) {
                dout("invalidate_pages %p gen %d successful\n", inode,
                     ci->i_rdcache_gen);
-               ci->i_rdcache_gen = 0;
-               ci->i_rdcache_revoking = 0;
+               ci->i_rdcache_revoking--;
                check = 1;
        } else {
-               dout("invalidate_pages %p gen %d raced, gen now %d\n",
-                    inode, orig_gen, ci->i_rdcache_gen);
+               dout("invalidate_pages %p gen %d raced, now %d revoking %d\n",
+                    inode, orig_gen, ci->i_rdcache_gen,
+                    ci->i_rdcache_revoking);
        }
        spin_unlock(&inode->i_lock);
 
@@ -1739,7 +1751,7 @@ int ceph_do_getattr(struct inode *inode, int mask)
                return 0;
        }
 
-       dout("do_getattr inode %p mask %s\n", inode, ceph_cap_string(mask));
+       dout("do_getattr inode %p mask %s mode 0%o\n", inode, ceph_cap_string(mask), inode->i_mode);
        if (ceph_caps_issued_mask(ceph_inode(inode), mask, 1))
                return 0;
 
index 3142b15940c25656a43ec3a5d72af3e1ee1cece9..098b185084791730ba0143111126bc066fdb9afb 100644 (file)
@@ -6,7 +6,6 @@
 #include <linux/sched.h>
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
-#include <linux/smp_lock.h>
 
 #include "super.h"
 #include "mds_client.h"
@@ -529,6 +528,9 @@ static void __register_request(struct ceph_mds_client *mdsc,
        ceph_mdsc_get_request(req);
        __insert_request(mdsc, req);
 
+       req->r_uid = current_fsuid();
+       req->r_gid = current_fsgid();
+
        if (dir) {
                struct ceph_inode_info *ci = ceph_inode(dir);
 
@@ -1588,8 +1590,8 @@ static struct ceph_msg *create_request_message(struct ceph_mds_client *mdsc,
 
        head->mdsmap_epoch = cpu_to_le32(mdsc->mdsmap->m_epoch);
        head->op = cpu_to_le32(req->r_op);
-       head->caller_uid = cpu_to_le32(current_fsuid());
-       head->caller_gid = cpu_to_le32(current_fsgid());
+       head->caller_uid = cpu_to_le32(req->r_uid);
+       head->caller_gid = cpu_to_le32(req->r_gid);
        head->args = req->r_args;
 
        ceph_encode_filepath(&p, end, ino1, path1);
index d66d63c7235526ef63d16ff0ea1e9ba3899df586..9341fd4f14320060a395c37f81b4a67b01c020d7 100644 (file)
@@ -170,6 +170,8 @@ struct ceph_mds_request {
 
        union ceph_mds_request_args r_args;
        int r_fmode;        /* file mode, if expecting cap */
+       uid_t r_uid;
+       gid_t r_gid;
 
        /* for choosing which mds to send this request to */
        int r_direct_mode;
index 1886294e12f7a3106c00f3376d92e43330514081..7f01728a46571f2fa22a47fbd062f6eadf4cba83 100644 (file)
@@ -293,9 +293,7 @@ struct ceph_inode_info {
        int i_rd_ref, i_rdcache_ref, i_wr_ref;
        int i_wrbuffer_ref, i_wrbuffer_ref_head;
        u32 i_shared_gen;       /* increment each time we get FILE_SHARED */
-       u32 i_rdcache_gen;      /* we increment this each time we get
-                                  FILE_CACHE.  If it's non-zero, we
-                                  _may_ have cached pages. */
+       u32 i_rdcache_gen;      /* incremented each time we get FILE_CACHE. */
        u32 i_rdcache_revoking; /* RDCACHE gen to async invalidate, if any */
 
        struct list_head i_unsafe_writes; /* uncommitted sync writes */
index 410ed188faa1376b7b0b10ed5bff0c36aa9c8806..a60579b007b03f38160ea541b099ab7a914bfbc1 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/compiler.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/ioctl.h>
 #include <linux/if.h>
 #include <linux/if_bridge.h>
index 253732382d375e848edc61ca40a3eaadb60f80c7..2720178b7718a9335a28d7ed4b0422ab11d6331f 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/key.h>
 #include <linux/slab.h>
 #include <linux/seq_file.h>
-#include <linux/smp_lock.h>
 #include <linux/file.h>
 #include <linux/crypto.h>
 #include "ecryptfs_kernel.h"
index 2fedaf8b50125bf65ad9b550537742de3109ecd4..acf8695fa8f035935390dd6bc0c8e44e8d3e5961 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/init.h>
 #include <linux/blkdev.h>
 #include <linux/parser.h>
-#include <linux/smp_lock.h>
 #include <linux/buffer_head.h>
 #include <linux/exportfs.h>
 #include <linux/vfs.h>
index f855ea4fc88895a13b53b075b9a3fb0dbcb53d8b..d6cc16476620760b6f01233f87fe5842335ba760 100644 (file)
@@ -6,7 +6,6 @@
 
 #include <linux/syscalls.h>
 #include <linux/mm.h>
-#include <linux/smp_lock.h>
 #include <linux/capability.h>
 #include <linux/file.h>
 #include <linux/fs.h>
index d5bb86866e6c19f85a359373742a37e24ad39ad7..25509eb28fd71980fa030aa39a1e81f225da43f9 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/sunrpc/clnt.h>
 #include <linux/sunrpc/svc.h>
 #include <linux/lockd/lockd.h>
-#include <linux/smp_lock.h>
 #include <linux/kthread.h>
 
 #define NLMDBG_FACILITY                NLMDBG_CLIENT
index 47ea1e1925b8c4fded4b156ea7cef916322377bf..332c54cf75e0f465f5ba91cc66999df386d4d4e0 100644 (file)
@@ -7,7 +7,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/smp_lock.h>
 #include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/errno.h>
index 25e21e4023b22a3f51ceb9d1c1869c2b7518f6d0..ed0c59fe23cef0dd038dd485545a14209fa11b78 100644 (file)
@@ -124,7 +124,7 @@ static struct nlm_host *nlm_lookup_host(struct nlm_lookup_host_info *ni)
                        continue;
                if (host->h_server != ni->server)
                        continue;
-               if (ni->server &&
+               if (ni->server && ni->src_len != 0 &&
                    !rpc_cmp_addr(nlm_srcaddr(host), ni->src_sap))
                        continue;
 
@@ -167,6 +167,7 @@ static struct nlm_host *nlm_lookup_host(struct nlm_lookup_host_info *ni)
        host->h_addrlen = ni->salen;
        rpc_set_port(nlm_addr(host), 0);
        memcpy(nlm_srcaddr(host), ni->src_sap, ni->src_len);
+       host->h_srcaddrlen = ni->src_len;
        host->h_version    = ni->version;
        host->h_proto      = ni->protocol;
        host->h_rpcclnt    = NULL;
@@ -238,9 +239,6 @@ struct nlm_host *nlmclnt_lookup_host(const struct sockaddr *sap,
                                     const char *hostname,
                                     int noresvport)
 {
-       const struct sockaddr source = {
-               .sa_family      = AF_UNSPEC,
-       };
        struct nlm_lookup_host_info ni = {
                .server         = 0,
                .sap            = sap,
@@ -249,8 +247,6 @@ struct nlm_host *nlmclnt_lookup_host(const struct sockaddr *sap,
                .version        = version,
                .hostname       = hostname,
                .hostname_len   = strlen(hostname),
-               .src_sap        = &source,
-               .src_len        = sizeof(source),
                .noresvport     = noresvport,
        };
 
@@ -357,7 +353,6 @@ nlm_bind_host(struct nlm_host *host)
                        .protocol       = host->h_proto,
                        .address        = nlm_addr(host),
                        .addrsize       = host->h_addrlen,
-                       .saddress       = nlm_srcaddr(host),
                        .timeout        = &timeparms,
                        .servername     = host->h_name,
                        .program        = &nlm_program,
@@ -376,6 +371,8 @@ nlm_bind_host(struct nlm_host *host)
                        args.flags |= RPC_CLNT_CREATE_HARDRTRY;
                if (host->h_noresvport)
                        args.flags |= RPC_CLNT_CREATE_NONPRIVPORT;
+               if (host->h_srcaddrlen)
+                       args.saddress = nlm_srcaddr(host);
 
                clnt = rpc_create(&args);
                if (!IS_ERR(clnt))
index a336e832475db7ffd5516a4cbe7e32daff49fd7c..38d261192453b5ee11300d577d0ebe66d3b9be72 100644 (file)
@@ -9,7 +9,6 @@
 
 #include <linux/types.h>
 #include <linux/time.h>
-#include <linux/smp_lock.h>
 #include <linux/lockd/lockd.h>
 #include <linux/lockd/share.h>
 
index c462d346acbda920a78ef03c153dc088b70ef7f4..ef5659b211e96cbcc8e4aa03d1cd332fd68c1a85 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/smp_lock.h>
 #include <linux/sunrpc/clnt.h>
 #include <linux/sunrpc/svc.h>
 #include <linux/lockd/nlm.h>
index c3069f38d60220e82726d5c318d0942e125ddb03..0caea5310ac3f0ea7ba24d36cdacaed03a55f9d3 100644 (file)
@@ -9,7 +9,6 @@
 
 #include <linux/types.h>
 #include <linux/time.h>
-#include <linux/smp_lock.h>
 #include <linux/lockd/lockd.h>
 #include <linux/lockd/share.h>
 
index 0e62dd35d088486ee2c04c62f312ffb2b0ca5149..8729347bcd1a1b0ab9953c85e7c3ffa46a1fce9c 100644 (file)
 #include <linux/module.h>
 #include <linux/security.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/syscalls.h>
 #include <linux/time.h>
 #include <linux/rcupdate.h>
index 8a415c9c5e552efd945cdb85af6f74af4b2b6de6..3dbfc072ec70aa0099b79b3ff1040455543c46ca 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/sched.h>
 #include <linux/spinlock.h>
 #include <linux/percpu.h>
-#include <linux/smp_lock.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/acct.h>
index aac8832e919e9a56cb95af787af658fb03d8d0d1..f22b12e7d337c37abc957ee2b4c2b204f52206b1 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/mm.h>
 #include <asm/uaccess.h>
 #include <asm/byteorder.h>
-#include <linux/smp_lock.h>
 
 #include <linux/ncp_fs.h>
 
index 6c754f70c5296be3fbe5c323bbb985d7ee326512..cb50aaf981dff5bf32dd2d4993ac14a1202dc27e 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/mm.h>
 #include <linux/vmalloc.h>
 #include <linux/sched.h>
-#include <linux/smp_lock.h>
 
 #include <linux/ncp_fs.h>
 #include "ncplib_kernel.h"
index d290545aa0c4b98c932e316c7dd4fcf3961b1126..8fb93b604e73a3a337a5f43ebc97b25d9f02d7f8 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/init.h>
-#include <linux/smp_lock.h>
 #include <linux/vfs.h>
 #include <linux/mount.h>
 #include <linux/seq_file.h>
index c2a1f9a155c3a6e8f82800334337b1b1b0aaa65a..d40a547e337707da380e752864926a65c70013cc 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/mount.h>
 #include <linux/slab.h>
 #include <linux/highuid.h>
-#include <linux/smp_lock.h>
 #include <linux/vmalloc.h>
 #include <linux/sched.h>
 
index aeec017fe814acbdf17947a68553765a335359ae..93a8b3bd69e37871795b93355e0550970cf7f421 100644 (file)
@@ -9,7 +9,6 @@
 #include <linux/completion.h>
 #include <linux/ip.h>
 #include <linux/module.h>
-#include <linux/smp_lock.h>
 #include <linux/sunrpc/svc.h>
 #include <linux/sunrpc/svcsock.h>
 #include <linux/nfs_fs.h>
index 232a7eead33a488c4a5d67bc83e3a1971d9665df..1fd62fc49be36310b45e54028f69905b4e4f0237 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/spinlock.h>
 
 #include <linux/nfs4.h>
index 07ac3847e562b54c26efd30c9a9eabab468c309d..662df2a5fad5d06fac235314220e7270fe9eef02 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/mount.h>
 #include <linux/sched.h>
 #include <linux/vmalloc.h>
+#include <linux/kmemleak.h>
 
 #include "delegation.h"
 #include "iostat.h"
@@ -194,9 +195,13 @@ typedef struct {
 static
 struct nfs_cache_array *nfs_readdir_get_array(struct page *page)
 {
+       void *ptr;
        if (page == NULL)
                return ERR_PTR(-EIO);
-       return (struct nfs_cache_array *)kmap(page);
+       ptr = kmap(page);
+       if (ptr == NULL)
+               return ERR_PTR(-ENOMEM);
+       return ptr;
 }
 
 static
@@ -213,6 +218,9 @@ int nfs_readdir_clear_array(struct page *page, gfp_t mask)
 {
        struct nfs_cache_array *array = nfs_readdir_get_array(page);
        int i;
+
+       if (IS_ERR(array))
+               return PTR_ERR(array);
        for (i = 0; i < array->size; i++)
                kfree(array->array[i].string.name);
        nfs_readdir_release_array(page);
@@ -231,6 +239,11 @@ int nfs_readdir_make_qstr(struct qstr *string, const char *name, unsigned int le
        string->name = kmemdup(name, len, GFP_KERNEL);
        if (string->name == NULL)
                return -ENOMEM;
+       /*
+        * Avoid a kmemleak false positive. The pointer to the name is stored
+        * in a page cache page which kmemleak does not scan.
+        */
+       kmemleak_not_leak(string->name);
        string->hash = full_name_hash(name, len);
        return 0;
 }
@@ -244,7 +257,7 @@ int nfs_readdir_add_to_array(struct nfs_entry *entry, struct page *page)
 
        if (IS_ERR(array))
                return PTR_ERR(array);
-       ret = -EIO;
+       ret = -ENOSPC;
        if (array->size >= MAX_READDIR_ARRAY)
                goto out;
 
@@ -255,9 +268,9 @@ int nfs_readdir_add_to_array(struct nfs_entry *entry, struct page *page)
        if (ret)
                goto out;
        array->last_cookie = entry->cookie;
+       array->size++;
        if (entry->eof == 1)
                array->eof_index = array->size;
-       array->size++;
 out:
        nfs_readdir_release_array(page);
        return ret;
@@ -272,7 +285,7 @@ int nfs_readdir_search_for_pos(struct nfs_cache_array *array, nfs_readdir_descri
        if (diff < 0)
                goto out_eof;
        if (diff >= array->size) {
-               if (array->eof_index > 0)
+               if (array->eof_index >= 0)
                        goto out_eof;
                desc->current_index += array->size;
                return -EAGAIN;
@@ -281,8 +294,6 @@ int nfs_readdir_search_for_pos(struct nfs_cache_array *array, nfs_readdir_descri
        index = (unsigned int)diff;
        *desc->dir_cookie = array->array[index].cookie;
        desc->cache_entry_index = index;
-       if (index == array->eof_index)
-               desc->eof = 1;
        return 0;
 out_eof:
        desc->eof = 1;
@@ -296,17 +307,17 @@ int nfs_readdir_search_for_cookie(struct nfs_cache_array *array, nfs_readdir_des
        int status = -EAGAIN;
 
        for (i = 0; i < array->size; i++) {
-               if (i == array->eof_index) {
-                       desc->eof = 1;
-                       status = -EBADCOOKIE;
-               }
                if (array->array[i].cookie == *desc->dir_cookie) {
                        desc->cache_entry_index = i;
                        status = 0;
-                       break;
+                       goto out;
                }
        }
-
+       if (i == array->eof_index) {
+               desc->eof = 1;
+               status = -EBADCOOKIE;
+       }
+out:
        return status;
 }
 
@@ -449,7 +460,7 @@ out:
 
 /* Perform conversion from xdr to cache array */
 static
-void nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *entry,
+int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *entry,
                                void *xdr_page, struct page *page, unsigned int buflen)
 {
        struct xdr_stream stream;
@@ -471,21 +482,29 @@ void nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *e
 
        do {
                status = xdr_decode(desc, entry, &stream);
-               if (status != 0)
+               if (status != 0) {
+                       if (status == -EAGAIN)
+                               status = 0;
                        break;
+               }
 
-               if (nfs_readdir_add_to_array(entry, page) == -1)
-                       break;
                if (desc->plus == 1)
                        nfs_prime_dcache(desc->file->f_path.dentry, entry);
+
+               status = nfs_readdir_add_to_array(entry, page);
+               if (status != 0)
+                       break;
        } while (!entry->eof);
 
        if (status == -EBADCOOKIE && entry->eof) {
                array = nfs_readdir_get_array(page);
-               array->eof_index = array->size - 1;
-               status = 0;
-               nfs_readdir_release_array(page);
+               if (!IS_ERR(array)) {
+                       array->eof_index = array->size;
+                       status = 0;
+                       nfs_readdir_release_array(page);
+               }
        }
+       return status;
 }
 
 static
@@ -537,7 +556,7 @@ int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page,
        struct nfs_entry entry;
        struct file     *file = desc->file;
        struct nfs_cache_array *array;
-       int status = 0;
+       int status = -ENOMEM;
        unsigned int array_size = ARRAY_SIZE(pages);
 
        entry.prev_cookie = 0;
@@ -549,6 +568,10 @@ int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page,
                goto out;
 
        array = nfs_readdir_get_array(page);
+       if (IS_ERR(array)) {
+               status = PTR_ERR(array);
+               goto out;
+       }
        memset(array, 0, sizeof(struct nfs_cache_array));
        array->eof_index = -1;
 
@@ -556,12 +579,19 @@ int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page,
        if (!pages_ptr)
                goto out_release_array;
        do {
+               unsigned int pglen;
                status = nfs_readdir_xdr_filler(pages, desc, &entry, file, inode);
 
                if (status < 0)
                        break;
-               nfs_readdir_page_filler(desc, &entry, pages_ptr, page, array_size * PAGE_SIZE);
-       } while (array->eof_index < 0 && array->size < MAX_READDIR_ARRAY);
+               pglen = status;
+               status = nfs_readdir_page_filler(desc, &entry, pages_ptr, page, pglen);
+               if (status < 0) {
+                       if (status == -ENOSPC)
+                               status = 0;
+                       break;
+               }
+       } while (array->eof_index < 0);
 
        nfs_readdir_free_large_page(pages_ptr, pages, array_size);
 out_release_array:
@@ -582,8 +612,10 @@ static
 int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page* page)
 {
        struct inode    *inode = desc->file->f_path.dentry->d_inode;
+       int ret;
 
-       if (nfs_readdir_xdr_to_array(desc, page, inode) < 0)
+       ret = nfs_readdir_xdr_to_array(desc, page, inode);
+       if (ret < 0)
                goto error;
        SetPageUptodate(page);
 
@@ -595,7 +627,7 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page* page)
        return 0;
  error:
        unlock_page(page);
-       return -EIO;
+       return ret;
 }
 
 static
@@ -608,12 +640,8 @@ void cache_page_release(nfs_readdir_descriptor_t *desc)
 static
 struct page *get_cache_page(nfs_readdir_descriptor_t *desc)
 {
-       struct page *page;
-       page = read_cache_page(desc->file->f_path.dentry->d_inode->i_mapping,
+       return read_cache_page(desc->file->f_path.dentry->d_inode->i_mapping,
                        desc->page_index, (filler_t *)nfs_readdir_filler, desc);
-       if (IS_ERR(page))
-               desc->eof = 1;
-       return page;
 }
 
 /*
@@ -639,8 +667,10 @@ int find_cache_page(nfs_readdir_descriptor_t *desc)
 static inline
 int readdir_search_pagecache(nfs_readdir_descriptor_t *desc)
 {
-       int res = -EAGAIN;
+       int res;
 
+       if (desc->page_index == 0)
+               desc->current_index = 0;
        while (1) {
                res = find_cache_page(desc);
                if (res != -EAGAIN)
@@ -670,6 +700,8 @@ int nfs_do_filldir(nfs_readdir_descriptor_t *desc, void *dirent,
        struct dentry *dentry = NULL;
 
        array = nfs_readdir_get_array(desc->page);
+       if (IS_ERR(array))
+               return PTR_ERR(array);
 
        for (i = desc->cache_entry_index; i < array->size; i++) {
                d_type = DT_UNKNOWN;
@@ -685,11 +717,9 @@ int nfs_do_filldir(nfs_readdir_descriptor_t *desc, void *dirent,
                        *desc->dir_cookie = array->array[i+1].cookie;
                else
                        *desc->dir_cookie = array->last_cookie;
-               if (i == array->eof_index) {
-                       desc->eof = 1;
-                       break;
-               }
        }
+       if (i == array->eof_index)
+               desc->eof = 1;
 
        nfs_readdir_release_array(desc->page);
        cache_page_release(desc);
@@ -1345,12 +1375,12 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
                                res = NULL;
                                goto out;
                        /* This turned out not to be a regular file */
-                       case -EISDIR:
                        case -ENOTDIR:
                                goto no_open;
                        case -ELOOP:
                                if (!(nd->intent.open.flags & O_NOFOLLOW))
                                        goto no_open;
+                       /* case -EISDIR: */
                        /* case -EINVAL: */
                        default:
                                res = ERR_CAST(inode);
index e6bf45710cc7fcd0348459ed7a27cc9454ee7e88..2563f765c9b4ba49b37615657f4c3f5f76e7576d 100644 (file)
@@ -423,7 +423,7 @@ nfs_xdr_readdirres(struct rpc_rqst *req, __be32 *p, void *dummy)
        struct page **page;
        size_t hdrlen;
        unsigned int pglen, recvd;
-       int status, nr = 0;
+       int status;
 
        if ((status = ntohl(*p++)))
                return nfs_stat_to_errno(status);
@@ -443,7 +443,7 @@ nfs_xdr_readdirres(struct rpc_rqst *req, __be32 *p, void *dummy)
        if (pglen > recvd)
                pglen = recvd;
        page = rcvbuf->pages;
-       return nr;
+       return pglen;
 }
 
 static void print_overflow_msg(const char *func, const struct xdr_stream *xdr)
index d9a5e832c2579f9b20c0164944ae139509d8fb79..748dc91a4a147466529d9b1b49a20cc0ab2aad93 100644 (file)
@@ -555,7 +555,7 @@ nfs3_xdr_readdirres(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirres *res
        struct page **page;
        size_t hdrlen;
        u32 recvd, pglen;
-       int status, nr = 0;
+       int status;
 
        status = ntohl(*p++);
        /* Decode post_op_attrs */
@@ -586,7 +586,7 @@ nfs3_xdr_readdirres(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirres *res
                pglen = recvd;
        page = rcvbuf->pages;
 
-       return nr;
+       return pglen;
 }
 
 __be32 *
index 0f24cdf2cb132b1ad7018a520a7abbea753ce330..6a653ffd8e4e121e37c29d88ff2f5b0b4dbe264f 100644 (file)
@@ -2852,8 +2852,10 @@ static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
        nfs4_setup_readdir(cookie, NFS_COOKIEVERF(dir), dentry, &args);
        res.pgbase = args.pgbase;
        status = nfs4_call_sync(NFS_SERVER(dir), &msg, &args, &res, 0);
-       if (status == 0)
+       if (status >= 0) {
                memcpy(NFS_COOKIEVERF(dir), res.verifier.data, NFS4_VERIFIER_SIZE);
+               status += args.pgbase;
+       }
 
        nfs_invalidate_atime(dir);
 
index f313c4cce7e4d1d087b8a1b47b55f769edf40a21..b7a204ff6fe1504efe287b7620532407cc692f89 100644 (file)
@@ -4518,7 +4518,7 @@ static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct n
        xdr_read_pages(xdr, pglen);
 
 
-       return 0;
+       return pglen;
 }
 
 static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req)
index 0a42e8f4adcbc1723b57a7dac93c78b0a34b975e..3c045044fca25183147704f3689c744549ebd77b 100644 (file)
@@ -39,7 +39,6 @@
 #include <linux/nfs_mount.h>
 #include <linux/nfs4_mount.h>
 #include <linux/lockd/bind.h>
-#include <linux/smp_lock.h>
 #include <linux/seq_file.h>
 #include <linux/mount.h>
 #include <linux/mnt_namespace.h>
 
 #define NFSDBG_FACILITY                NFSDBG_VFS
 
+#ifdef CONFIG_NFS_V3
+#define NFS_DEFAULT_VERSION 3
+#else
+#define NFS_DEFAULT_VERSION 2
+#endif
+
 enum {
        /* Mount options that take no arguments */
        Opt_soft, Opt_hard,
@@ -2277,7 +2282,7 @@ static int nfs_get_sb(struct file_system_type *fs_type,
        };
        int error = -ENOMEM;
 
-       data = nfs_alloc_parsed_mount_data(3);
+       data = nfs_alloc_parsed_mount_data(NFS_DEFAULT_VERSION);
        mntfh = nfs_alloc_fhandle();
        if (data == NULL || mntfh == NULL)
                goto out_free_fh;
index ad2bfa68d534d28531c3788b955734b5d9a76985..116cab970e0f3d737c8377bde9c3d97192568c71 100644 (file)
@@ -2262,7 +2262,7 @@ nfs4_file_downgrade(struct nfs4_file *fp, unsigned int share_access)
  * Spawn a thread to perform a recall on the delegation represented
  * by the lease (file_lock)
  *
- * Called from break_lease() with lock_kernel() held.
+ * Called from break_lease() with lock_flocks() held.
  * Note: we assume break_lease will only call this *once* for any given
  * lease.
  */
@@ -2286,7 +2286,7 @@ void nfsd_break_deleg_cb(struct file_lock *fl)
        list_add_tail(&dp->dl_recall_lru, &del_recall_lru);
        spin_unlock(&recall_lock);
 
-       /* only place dl_time is set. protected by lock_kernel*/
+       /* only place dl_time is set. protected by lock_flocks*/
        dp->dl_time = get_seconds();
 
        /*
@@ -2303,7 +2303,7 @@ void nfsd_break_deleg_cb(struct file_lock *fl)
 /*
  * The file_lock is being reapd.
  *
- * Called by locks_free_lock() with lock_kernel() held.
+ * Called by locks_free_lock() with lock_flocks() held.
  */
 static
 void nfsd_release_deleg_cb(struct file_lock *fl)
@@ -2318,7 +2318,7 @@ void nfsd_release_deleg_cb(struct file_lock *fl)
 }
 
 /*
- * Called from setlease() with lock_kernel() held
+ * Called from setlease() with lock_flocks() held
  */
 static
 int nfsd_same_client_deleg_cb(struct file_lock *onlist, struct file_lock *try)
index f02c0ef315788427e1f8b51e964f9b9dec513a10..cfeab7ce36974b6d448e7e0b7d96fd0a992dbaa5 100644 (file)
@@ -41,7 +41,6 @@
 #include <linux/mount.h>
 #include <linux/seq_file.h>
 #include <linux/quotaops.h>
-#include <linux/smp_lock.h>
 
 #define MLOG_MASK_PREFIX ML_SUPER
 #include <cluster/masklog.h>
index 9c2b5f484879ad37a1633a6023524e2cb0151a3f..3ddb6068177c9a7d359f45b8aa60d6fb92dec9b4 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/limits.h>
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/smp_lock.h>
 #include <linux/sysctl.h>
 #include <linux/slab.h>
 
index 431a0ed610c83a8750592e516ff23ac35ffbe524..5d431bacbea967e7a66755bf9320f20d9f464902 100644 (file)
@@ -9,7 +9,6 @@
 #include <linux/fcntl.h>
 #include <linux/file.h>
 #include <linux/uio.h>
-#include <linux/smp_lock.h>
 #include <linux/fsnotify.h>
 #include <linux/security.h>
 #include <linux/module.h>
index 41656d40dc5c87fc8bcfd9ec5aea4bc635ebc092..0bae036831e2ca2aeeae94eb78d74f2aa769b54d 100644 (file)
@@ -8,7 +8,6 @@
 #include <linux/reiserfs_acl.h>
 #include <linux/reiserfs_xattr.h>
 #include <linux/exportfs.h>
-#include <linux/smp_lock.h>
 #include <linux/pagemap.h>
 #include <linux/highmem.h>
 #include <linux/slab.h>
index adf22b485ceac01e0f5ed7b0a8d1593956a7b81f..bd9763e76bae42844a6cf792d1da86a3454dbe38 100644 (file)
@@ -9,7 +9,6 @@
 #include <linux/time.h>
 #include <asm/uaccess.h>
 #include <linux/pagemap.h>
-#include <linux/smp_lock.h>
 #include <linux/compat.h>
 
 /*
index 076c8b19468297dc71add1987b249ab054d6e20d..d31bce1a9f908e1df4c8046f371bec748c215440 100644 (file)
@@ -43,7 +43,6 @@
 #include <linux/fcntl.h>
 #include <linux/stat.h>
 #include <linux/string.h>
-#include <linux/smp_lock.h>
 #include <linux/buffer_head.h>
 #include <linux/workqueue.h>
 #include <linux/writeback.h>
index 3bf7a6457f4d3f021db9d561a34ab7fb07bf1e01..b243117b8752d0a9c81fa8f12773ca202a9cfabb 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/mount.h>
 #include <linux/namei.h>
 #include <linux/crc32.h>
-#include <linux/smp_lock.h>
 
 struct file_system_type reiserfs_fs_type;
 
index 01a7141195068c8e0fd384c0dde661adfb9601b6..bc5590b1a1acbe852314995f11b479e221ba6281 100644 (file)
@@ -80,6 +80,7 @@ struct drm_nouveau_gpuobj_free {
 #define NOUVEAU_GETPARAM_VM_VRAM_BASE    12
 #define NOUVEAU_GETPARAM_GRAPH_UNITS     13
 #define NOUVEAU_GETPARAM_PTIMER_TIME     14
+#define NOUVEAU_GETPARAM_HAS_BO_USAGE    15
 struct drm_nouveau_getparam {
        uint64_t param;
        uint64_t value;
@@ -95,6 +96,12 @@ struct drm_nouveau_setparam {
 #define NOUVEAU_GEM_DOMAIN_GART      (1 << 2)
 #define NOUVEAU_GEM_DOMAIN_MAPPABLE  (1 << 3)
 
+#define NOUVEAU_GEM_TILE_LAYOUT_MASK 0x0000ff00
+#define NOUVEAU_GEM_TILE_16BPP       0x00000001
+#define NOUVEAU_GEM_TILE_32BPP       0x00000002
+#define NOUVEAU_GEM_TILE_ZETA        0x00000004
+#define NOUVEAU_GEM_TILE_NONCONTIG   0x00000008
+
 struct drm_nouveau_gem_info {
        uint32_t handle;
        uint32_t domain;
index f22b2e941686fc370f85b942526ee392f1f9ead6..9e76d35670d204d6425b20d17595737fde4453ff 100644 (file)
@@ -227,8 +227,7 @@ extern int ceph_open_session(struct ceph_client *client);
 extern void ceph_release_page_vector(struct page **pages, int num_pages);
 
 extern struct page **ceph_get_direct_page_vector(const char __user *data,
-                                           int num_pages,
-                                           loff_t off, size_t len);
+                                                int num_pages);
 extern void ceph_put_page_vector(struct page **pages, int num_pages);
 extern void ceph_release_page_vector(struct page **pages, int num_pages);
 extern struct page **ceph_alloc_page_vector(int num_pages, gfp_t flags);
index 5956d62c3057139ac6634df8e13556659d07725e..a108b425fee25aff2cbf4dd1924c047b925f7ab0 100644 (file)
@@ -82,6 +82,7 @@ struct ceph_msg {
        struct ceph_buffer *middle;
        struct page **pages;            /* data payload.  NOT OWNER. */
        unsigned nr_pages;              /* size of page array */
+       unsigned page_alignment;        /* io offset in first page */
        struct ceph_pagelist *pagelist; /* instead of pages */
        struct list_head list_head;
        struct kref kref;
index 6c91fb032c39cd907a3ac509db75a3a860e564c1..a1af29648fb54be5c0b5ac1cfc62879314145d56 100644 (file)
@@ -79,6 +79,7 @@ struct ceph_osd_request {
        struct ceph_file_layout r_file_layout;
        struct ceph_snap_context *r_snapc;    /* snap context for writes */
        unsigned          r_num_pages;        /* size of page array (follows) */
+       unsigned          r_page_alignment;   /* io offset in first page */
        struct page     **r_pages;            /* pages for data payload */
        int               r_pages_from_pool;
        int               r_own_pages;        /* if true, i own page list */
@@ -194,7 +195,8 @@ extern struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *,
                                      int do_sync, u32 truncate_seq,
                                      u64 truncate_size,
                                      struct timespec *mtime,
-                                     bool use_mempool, int num_reply);
+                                     bool use_mempool, int num_reply,
+                                     int page_align);
 
 static inline void ceph_osdc_get_request(struct ceph_osd_request *req)
 {
@@ -218,7 +220,8 @@ extern int ceph_osdc_readpages(struct ceph_osd_client *osdc,
                               struct ceph_file_layout *layout,
                               u64 off, u64 *plen,
                               u32 truncate_seq, u64 truncate_size,
-                              struct page **pages, int nr_pages);
+                              struct page **pages, int nr_pages,
+                              int page_align);
 
 extern int ceph_osdc_writepages(struct ceph_osd_client *osdc,
                                struct ceph_vino vino,
index 41cb31f14ee3068cd3c232fb07e385676f2f9ba0..32f9fd6619b4160c997bba07e2661382f3afaacf 100644 (file)
@@ -2,9 +2,6 @@
 #define LINUX_HARDIRQ_H
 
 #include <linux/preempt.h>
-#ifdef CONFIG_PREEMPT
-#include <linux/smp_lock.h>
-#endif
 #include <linux/lockdep.h>
 #include <linux/ftrace_irq.h>
 #include <asm/hardirq.h>
@@ -97,7 +94,8 @@
 #define in_nmi()       (preempt_count() & NMI_MASK)
 
 #if defined(CONFIG_PREEMPT) && defined(CONFIG_BKL)
-# define PREEMPT_INATOMIC_BASE kernel_locked()
+# include <linux/sched.h>
+# define PREEMPT_INATOMIC_BASE (current->lock_depth >= 0)
 #else
 # define PREEMPT_INATOMIC_BASE 0
 #endif
index 15b77b8dc7e11f529b93cc9ba629f464627d3a74..d947b1231662b9f69b388d0c5e3393972285faa3 100644 (file)
@@ -986,7 +986,7 @@ extern void ata_host_init(struct ata_host *, struct device *,
                          unsigned long, struct ata_port_operations *);
 extern int ata_scsi_detect(struct scsi_host_template *sht);
 extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg);
-extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *));
+extern int ata_scsi_queuecmd(struct Scsi_Host *h, struct scsi_cmnd *cmd);
 extern int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *dev,
                            int cmd, void __user *arg);
 extern void ata_sas_port_destroy(struct ata_port *);
index a34dea46b62953cb2675f6b17c7539431f54114b..2dee05e5119a42138dda84e6aca032215994cfa0 100644 (file)
@@ -43,6 +43,7 @@ struct nlm_host {
        struct sockaddr_storage h_addr;         /* peer address */
        size_t                  h_addrlen;
        struct sockaddr_storage h_srcaddr;      /* our address (optional) */
+       size_t                  h_srcaddrlen;
        struct rpc_clnt         *h_rpcclnt;     /* RPC client to talk to peer */
        char                    *h_name;                /* remote hostname */
        u32                     h_version;      /* interface version */
index bba26684acdc5e0e9364419db9cc3fb7802c1109..c66fdb7d6998129701f6eaa653f1d28dd641e332 100644 (file)
@@ -593,12 +593,6 @@ nfs_fileid_to_ino_t(u64 fileid)
        return ino;
 }
 
-#define nfs_wait_event(clnt, wq, condition)                            \
-({                                                                     \
-       int __retval = wait_event_killable(wq, condition);              \
-       __retval;                                                       \
-})
-
 #define NFS_JUKEBOX_RETRY_TIME (5 * HZ)
 
 #endif /* __KERNEL__ */
index 5ca47e59b7278ffbb0dd4fc624d9e4cf1697d0ae..c21072adbfad7e84417b8cf925e2fc0b21172cea 100644 (file)
@@ -22,7 +22,6 @@
 #include <asm/unaligned.h>
 #include <linux/bitops.h>
 #include <linux/proc_fs.h>
-#include <linux/smp_lock.h>
 #include <linux/buffer_head.h>
 #include <linux/reiserfs_fs_i.h>
 #include <linux/reiserfs_fs_sb.h>
index d42f274418b884ea72f8de09cda464af817fd774..bbad657a37259c0f35e99341761a789731435e25 100644 (file)
@@ -6,7 +6,6 @@
 #include <linux/if_link.h>
 #include <linux/if_addr.h>
 #include <linux/neighbour.h>
-#include <linux/netdevice.h>
 
 /* rtnetlink families. Values up to 127 are reserved for real address
  * families, values above 128 may be used arbitrarily.
@@ -606,6 +605,7 @@ struct tcamsg {
 #ifdef __KERNEL__
 
 #include <linux/mutex.h>
+#include <linux/netdevice.h>
 
 static __inline__ int rtattr_strcmp(const struct rtattr *rta, const char *str)
 {
index d0036e52a24a1c28eaef9e60bb5aa100aaa18af1..2c79e921a68baeb9d5afa9b0deaa731232685ed5 100644 (file)
@@ -862,6 +862,7 @@ struct sched_group {
         * single CPU.
         */
        unsigned int cpu_power, cpu_power_orig;
+       unsigned int group_weight;
 
        /*
         * The CPUs this group covers.
index 291f721144c2e23c51e4fbb92288f89e6b68dc11..3a1988202731e55563315703ed3f5cfb52f8abc9 100644 (file)
@@ -4,8 +4,6 @@
 #ifdef CONFIG_LOCK_KERNEL
 #include <linux/sched.h>
 
-#define kernel_locked()                (current->lock_depth >= 0)
-
 extern int __lockfunc __reacquire_kernel_lock(void);
 extern void __lockfunc __release_kernel_lock(void);
 
@@ -58,7 +56,6 @@ static inline void cycle_kernel_lock(void)
 #define lock_kernel()
 #define unlock_kernel()
 #define cycle_kernel_lock()                    do { } while(0)
-#define kernel_locked()                                1
 #endif /* CONFIG_BKL */
 
 #define release_kernel_lock(task)              do { } while(0)
index c7ea9bc8897cb638208a88bcb6352814b4639dc8..032d79ff1d9d4ec7fcfb313261b27548f1d5f3dd 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/tty_driver.h>
 #include <linux/tty_ldisc.h>
 #include <linux/mutex.h>
-#include <linux/smp_lock.h>
 
 #include <asm/system.h>
 
index 2a7936d7851d55de60251fc708672a87d5beb81b..97b8b7c9b63cf9854e3b8c2e83154c8ecb0bea06 100644 (file)
@@ -1355,7 +1355,7 @@ enum wiphy_flags {
        WIPHY_FLAG_4ADDR_AP                     = BIT(5),
        WIPHY_FLAG_4ADDR_STATION                = BIT(6),
        WIPHY_FLAG_CONTROL_PORT_PROTOCOL        = BIT(7),
-       WIPHY_FLAG_IBSS_RSN                     = BIT(7),
+       WIPHY_FLAG_IBSS_RSN                     = BIT(8),
 };
 
 struct mac_address {
index 55590ab16b3ed5192413b4b6415a8785c1d1a5bb..6beb1ffc2b7fcfe9d360717ccde3f70bd8ac0e3d 100644 (file)
@@ -303,7 +303,7 @@ static inline void neigh_confirm(struct neighbour *neigh)
 
 static inline int neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
 {
-       unsigned long now = ACCESS_ONCE(jiffies);
+       unsigned long now = jiffies;
        
        if (neigh->used != now)
                neigh->used = now;
index f986ab7ffe6f040e9e00ac23d404bd8ad31e1f4e..5c4c1678f7be65d2d57d314dc5f583a974a1526e 100644 (file)
@@ -1006,8 +1006,7 @@ void fc_fcp_destroy(struct fc_lport *);
 /*
  * SCSI INTERACTION LAYER
  *****************************/
-int fc_queuecommand(struct scsi_cmnd *,
-                   void (*done)(struct scsi_cmnd *));
+int fc_queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
 int fc_eh_abort(struct scsi_cmnd *);
 int fc_eh_device_reset(struct scsi_cmnd *);
 int fc_eh_host_reset(struct scsi_cmnd *);
index ae5196aae1a5311421e72ba22d9b9f43cb748500..b81d969ddc67cbbfde3f4522cf11a7b2f7487509 100644 (file)
@@ -341,8 +341,7 @@ extern int iscsi_eh_abort(struct scsi_cmnd *sc);
 extern int iscsi_eh_recover_target(struct scsi_cmnd *sc);
 extern int iscsi_eh_session_reset(struct scsi_cmnd *sc);
 extern int iscsi_eh_device_reset(struct scsi_cmnd *sc);
-extern int iscsi_queuecommand(struct scsi_cmnd *sc,
-                             void (*done)(struct scsi_cmnd *));
+extern int iscsi_queuecommand(struct Scsi_Host *h, struct scsi_cmnd *sc);
 
 /*
  * iSCSI host helpers.
index 3dec1949f69cd75890368d40700f68399ac68427..90ce527ecf3d02c5c214308dc30098301d9892d5 100644 (file)
@@ -621,8 +621,7 @@ int sas_set_phy_speed(struct sas_phy *phy,
 int sas_phy_enable(struct sas_phy *phy, int enabled);
 int sas_phy_reset(struct sas_phy *phy, int hard_reset);
 int sas_queue_up(struct sas_task *task);
-extern int sas_queuecommand(struct scsi_cmnd *,
-                    void (*scsi_done)(struct scsi_cmnd *));
+extern int sas_queuecommand(struct Scsi_Host * ,struct scsi_cmnd *);
 extern int sas_target_alloc(struct scsi_target *);
 extern int sas_slave_alloc(struct scsi_device *);
 extern int sas_slave_configure(struct scsi_device *);
index d0a6a845f2045fb874481539e0c55d21a70fe7bb..e7e385842a38746d348eee460af6bc3d9e1a2ab6 100644 (file)
@@ -127,8 +127,7 @@ struct scsi_host_template {
         *
         * STATUS: REQUIRED
         */
-       int (* queuecommand)(struct scsi_cmnd *,
-                            void (*done)(struct scsi_cmnd *));
+       int (* queuecommand)(struct Scsi_Host *, struct scsi_cmnd *);
 
        /*
         * The transfer functions are used to queue a scsi command to
@@ -504,6 +503,25 @@ struct scsi_host_template {
        u64 vendor_id;
 };
 
+/*
+ * Temporary #define for host lock push down. Can be removed when all
+ * drivers have been updated to take advantage of unlocked
+ * queuecommand.
+ *
+ */
+#define DEF_SCSI_QCMD(func_name) \
+       int func_name(struct Scsi_Host *shost, struct scsi_cmnd *cmd)   \
+       {                                                               \
+               unsigned long irq_flags;                                \
+               int rc;                                                 \
+               spin_lock_irqsave(shost->host_lock, irq_flags);         \
+               scsi_cmd_get_serial(shost, cmd);                        \
+               rc = func_name##_lck (cmd, cmd->scsi_done);                     \
+               spin_unlock_irqrestore(shost->host_lock, irq_flags);    \
+               return rc;                                              \
+       }
+
+
 /*
  * shost state: If you alter this, you also need to alter scsi_sysfs.c
  * (for the ascii descriptions) and the state model enforcer:
@@ -752,6 +770,7 @@ extern struct Scsi_Host *scsi_host_get(struct Scsi_Host *);
 extern void scsi_host_put(struct Scsi_Host *t);
 extern struct Scsi_Host *scsi_host_lookup(unsigned short);
 extern const char *scsi_host_state_name(enum scsi_host_state);
+extern void scsi_cmd_get_serial(struct Scsi_Host *, struct scsi_cmnd *);
 
 extern u64 scsi_calculate_bounce_limit(struct Scsi_Host *);
 
index e59af24a0b7c0dbb8417ff3b5c0818d544ac8060..8646401f7a0e4b77579aa13f8de6ac191787be73 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/delay.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
-#include <linux/smp_lock.h>
 #include <linux/initrd.h>
 #include <linux/bootmem.h>
 #include <linux/acpi.h>
index 37755d621924e5256b3494d5e94b57415be5a3f1..a6e729766821307c7440fd4d321d3decdc3182d6 100644 (file)
@@ -82,7 +82,7 @@ static kdbtab_t kdb_base_commands[50];
 #define for_each_kdbcmd(cmd, num)                                      \
        for ((cmd) = kdb_base_commands, (num) = 0;                      \
             num < kdb_max_commands;                                    \
-            num == KDB_BASE_CMD_MAX ? cmd = kdb_commands : cmd++, num++)
+            num++, num == KDB_BASE_CMD_MAX ? cmd = kdb_commands : cmd++)
 
 typedef struct _kdbmsg {
        int     km_diag;        /* kdb diagnostic */
@@ -646,7 +646,7 @@ static int kdb_defcmd2(const char *cmdstr, const char *argv0)
        }
        if (!s->usable)
                return KDB_NOTIMP;
-       s->command = kmalloc((s->count + 1) * sizeof(*(s->command)), GFP_KDB);
+       s->command = kzalloc((s->count + 1) * sizeof(*(s->command)), GFP_KDB);
        if (!s->command) {
                kdb_printf("Could not allocate new kdb_defcmd table for %s\n",
                           cmdstr);
@@ -2361,7 +2361,7 @@ static int kdb_pid(int argc, const char **argv)
  */
 static int kdb_ll(int argc, const char **argv)
 {
-       int diag;
+       int diag = 0;
        unsigned long addr;
        long offset = 0;
        unsigned long va;
@@ -2400,20 +2400,21 @@ static int kdb_ll(int argc, const char **argv)
                char buf[80];
 
                if (KDB_FLAG(CMD_INTERRUPT))
-                       return 0;
+                       goto out;
 
                sprintf(buf, "%s " kdb_machreg_fmt "\n", command, va);
                diag = kdb_parse(buf);
                if (diag)
-                       return diag;
+                       goto out;
 
                addr = va + linkoffset;
                if (kdb_getword(&va, addr, sizeof(va)))
-                       return 0;
+                       goto out;
        }
-       kfree(command);
 
-       return 0;
+out:
+       kfree(command);
+       return diag;
 }
 
 static int kdb_kgdb(int argc, const char **argv)
@@ -2739,13 +2740,13 @@ int kdb_register_repeat(char *cmd,
                }
                if (kdb_commands) {
                        memcpy(new, kdb_commands,
-                              kdb_max_commands * sizeof(*new));
+                         (kdb_max_commands - KDB_BASE_CMD_MAX) * sizeof(*new));
                        kfree(kdb_commands);
                }
                memset(new + kdb_max_commands, 0,
                       kdb_command_extend * sizeof(*new));
                kdb_commands = new;
-               kp = kdb_commands + kdb_max_commands;
+               kp = kdb_commands + kdb_max_commands - KDB_BASE_CMD_MAX;
                kdb_max_commands += kdb_command_extend;
        }
 
index 6c683b37f2ce25291a5a0c8f490a16c08c84d674..40a8777a27d0d85e173f4b7a3efbd4ecff1c9654 100644 (file)
@@ -2489,7 +2489,8 @@ void exit_robust_list(struct task_struct *curr)
 {
        struct robust_list_head __user *head = curr->robust_list;
        struct robust_list __user *entry, *next_entry, *pending;
-       unsigned int limit = ROBUST_LIST_LIMIT, pi, next_pi, pip;
+       unsigned int limit = ROBUST_LIST_LIMIT, pi, pip;
+       unsigned int uninitialized_var(next_pi);
        unsigned long futex_offset;
        int rc;
 
index 06da4dfc339b7362716858f92bec749962241808..a7934ac75e5bf4b2b7f5b819d24e8f6f08a1ff1a 100644 (file)
@@ -49,7 +49,8 @@ void compat_exit_robust_list(struct task_struct *curr)
 {
        struct compat_robust_list_head __user *head = curr->compat_robust_list;
        struct robust_list __user *entry, *next_entry, *pending;
-       unsigned int limit = ROBUST_LIST_LIMIT, pi, next_pi, pip;
+       unsigned int limit = ROBUST_LIST_LIMIT, pi, pip;
+       unsigned int uninitialized_var(next_pi);
        compat_uptr_t uentry, next_uentry, upending;
        compat_long_t futex_offset;
        int rc;
index c7a8f453919e65a42e0251b968a2d3652e0a4c3a..aeaa7f8468216eb1d8795b14ff74cfc502318771 100644 (file)
@@ -121,10 +121,10 @@ static inline int pm_qos_get_value(struct pm_qos_object *o)
 
        switch (o->type) {
        case PM_QOS_MIN:
-               return plist_last(&o->requests)->prio;
+               return plist_first(&o->requests)->prio;
 
        case PM_QOS_MAX:
-               return plist_first(&o->requests)->prio;
+               return plist_last(&o->requests)->prio;
 
        default:
                /* runtime check for not using enum */
index 29bff6117abca747d31131424f58927e1a30558d..a5aff3ebad38b68629d341cb5a28856afb970796 100644 (file)
@@ -246,9 +246,13 @@ config PM_OPS
        depends on PM_SLEEP || PM_RUNTIME
        default y
 
+config ARCH_HAS_OPP
+       bool
+
 config PM_OPP
        bool "Operating Performance Point (OPP) Layer library"
        depends on PM
+       depends on ARCH_HAS_OPP
        ---help---
          SOCs have a standard set of tuples consisting of frequency and
          voltage pairs that the device will support per voltage domain. This
index aa14a56f9d037cde21ae19ef86b142e1c23fe736..dc91a4d09ac3b71a3c347187ff2a1691c952cebd 100644 (file)
@@ -560,18 +560,8 @@ struct rq {
 
 static DEFINE_PER_CPU_SHARED_ALIGNED(struct rq, runqueues);
 
-static inline
-void check_preempt_curr(struct rq *rq, struct task_struct *p, int flags)
-{
-       rq->curr->sched_class->check_preempt_curr(rq, p, flags);
 
-       /*
-        * A queue event has occurred, and we're going to schedule.  In
-        * this case, we can save a useless back to back clock update.
-        */
-       if (test_tsk_need_resched(p))
-               rq->skip_clock_update = 1;
-}
+static void check_preempt_curr(struct rq *rq, struct task_struct *p, int flags);
 
 static inline int cpu_of(struct rq *rq)
 {
@@ -2118,6 +2108,31 @@ static inline void check_class_changed(struct rq *rq, struct task_struct *p,
                p->sched_class->prio_changed(rq, p, oldprio, running);
 }
 
+static void check_preempt_curr(struct rq *rq, struct task_struct *p, int flags)
+{
+       const struct sched_class *class;
+
+       if (p->sched_class == rq->curr->sched_class) {
+               rq->curr->sched_class->check_preempt_curr(rq, p, flags);
+       } else {
+               for_each_class(class) {
+                       if (class == rq->curr->sched_class)
+                               break;
+                       if (class == p->sched_class) {
+                               resched_task(rq->curr);
+                               break;
+                       }
+               }
+       }
+
+       /*
+        * A queue event has occurred, and we're going to schedule.  In
+        * this case, we can save a useless back to back clock update.
+        */
+       if (test_tsk_need_resched(rq->curr))
+               rq->skip_clock_update = 1;
+}
+
 #ifdef CONFIG_SMP
 /*
  * Is this task likely cache-hot:
@@ -6960,6 +6975,8 @@ static void init_sched_groups_power(int cpu, struct sched_domain *sd)
        if (cpu != group_first_cpu(sd->groups))
                return;
 
+       sd->groups->group_weight = cpumask_weight(sched_group_cpus(sd->groups));
+
        child = sd->child;
 
        sd->groups->cpu_power = 0;
index f4f6a8326dd01ffc0353b369bbfddf5a4f0e2fde..52ab113d8bb95ee8e08299b9bad6b0df5691ea89 100644 (file)
@@ -1654,12 +1654,6 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int wake_
        struct cfs_rq *cfs_rq = task_cfs_rq(curr);
        int scale = cfs_rq->nr_running >= sched_nr_latency;
 
-       if (unlikely(rt_prio(p->prio)))
-               goto preempt;
-
-       if (unlikely(p->sched_class != &fair_sched_class))
-               return;
-
        if (unlikely(se == pse))
                return;
 
@@ -2035,13 +2029,16 @@ struct sd_lb_stats {
        unsigned long this_load_per_task;
        unsigned long this_nr_running;
        unsigned long this_has_capacity;
+       unsigned int  this_idle_cpus;
 
        /* Statistics of the busiest group */
+       unsigned int  busiest_idle_cpus;
        unsigned long max_load;
        unsigned long busiest_load_per_task;
        unsigned long busiest_nr_running;
        unsigned long busiest_group_capacity;
        unsigned long busiest_has_capacity;
+       unsigned int  busiest_group_weight;
 
        int group_imb; /* Is there imbalance in this sd */
 #if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT)
@@ -2063,6 +2060,8 @@ struct sg_lb_stats {
        unsigned long sum_nr_running; /* Nr tasks running in the group */
        unsigned long sum_weighted_load; /* Weighted load of group's tasks */
        unsigned long group_capacity;
+       unsigned long idle_cpus;
+       unsigned long group_weight;
        int group_imb; /* Is there an imbalance in the group ? */
        int group_has_capacity; /* Is there extra capacity in the group? */
 };
@@ -2431,7 +2430,8 @@ static inline void update_sg_lb_stats(struct sched_domain *sd,
                sgs->group_load += load;
                sgs->sum_nr_running += rq->nr_running;
                sgs->sum_weighted_load += weighted_cpuload(i);
-
+               if (idle_cpu(i))
+                       sgs->idle_cpus++;
        }
 
        /*
@@ -2469,6 +2469,7 @@ static inline void update_sg_lb_stats(struct sched_domain *sd,
        sgs->group_capacity = DIV_ROUND_CLOSEST(group->cpu_power, SCHED_LOAD_SCALE);
        if (!sgs->group_capacity)
                sgs->group_capacity = fix_small_capacity(sd, group);
+       sgs->group_weight = group->group_weight;
 
        if (sgs->group_capacity > sgs->sum_nr_running)
                sgs->group_has_capacity = 1;
@@ -2576,13 +2577,16 @@ static inline void update_sd_lb_stats(struct sched_domain *sd, int this_cpu,
                        sds->this_nr_running = sgs.sum_nr_running;
                        sds->this_load_per_task = sgs.sum_weighted_load;
                        sds->this_has_capacity = sgs.group_has_capacity;
+                       sds->this_idle_cpus = sgs.idle_cpus;
                } else if (update_sd_pick_busiest(sd, sds, sg, &sgs, this_cpu)) {
                        sds->max_load = sgs.avg_load;
                        sds->busiest = sg;
                        sds->busiest_nr_running = sgs.sum_nr_running;
+                       sds->busiest_idle_cpus = sgs.idle_cpus;
                        sds->busiest_group_capacity = sgs.group_capacity;
                        sds->busiest_load_per_task = sgs.sum_weighted_load;
                        sds->busiest_has_capacity = sgs.group_has_capacity;
+                       sds->busiest_group_weight = sgs.group_weight;
                        sds->group_imb = sgs.group_imb;
                }
 
@@ -2860,8 +2864,26 @@ find_busiest_group(struct sched_domain *sd, int this_cpu,
        if (sds.this_load >= sds.avg_load)
                goto out_balanced;
 
-       if (100 * sds.max_load <= sd->imbalance_pct * sds.this_load)
-               goto out_balanced;
+       /*
+        * In the CPU_NEWLY_IDLE, use imbalance_pct to be conservative.
+        * And to check for busy balance use !idle_cpu instead of
+        * CPU_NOT_IDLE. This is because HT siblings will use CPU_NOT_IDLE
+        * even when they are idle.
+        */
+       if (idle == CPU_NEWLY_IDLE || !idle_cpu(this_cpu)) {
+               if (100 * sds.max_load <= sd->imbalance_pct * sds.this_load)
+                       goto out_balanced;
+       } else {
+               /*
+                * This cpu is idle. If the busiest group load doesn't
+                * have more tasks than the number of available cpu's and
+                * there is no imbalance between this and busiest group
+                * wrt to idle cpu's, it is balanced.
+                */
+               if ((sds.this_idle_cpus  <= sds.busiest_idle_cpus + 1) &&
+                   sds.busiest_nr_running <= sds.busiest_group_weight)
+                       goto out_balanced;
+       }
 
 force_balance:
        /* Looks like there is an imbalance. Compute it */
index 45bddc0c104857f23e06c9126ed6dcb1d452450b..2bf6b47058c19f79a326a6b4f82d4baf7950cb1a 100644 (file)
@@ -19,14 +19,14 @@ select_task_rq_stop(struct rq *rq, struct task_struct *p,
 static void
 check_preempt_curr_stop(struct rq *rq, struct task_struct *p, int flags)
 {
-       resched_task(rq->curr); /* we preempt everything */
+       /* we're never preempted */
 }
 
 static struct task_struct *pick_next_task_stop(struct rq *rq)
 {
        struct task_struct *stop = rq->stop;
 
-       if (stop && stop->state == TASK_RUNNING)
+       if (stop && stop->se.on_rq)
                return stop;
 
        return NULL;
index b65bf634035ed0684693b9c7c02b3229c8d68e0d..5abfa151855493735a91fd45a255a45727c8ba97 100644 (file)
@@ -702,7 +702,6 @@ static struct ctl_table kern_table[] = {
                .extra1         = &zero,
                .extra2         = &ten_thousand,
        },
-#endif
        {
                .procname       = "dmesg_restrict",
                .data           = &dmesg_restrict,
@@ -712,6 +711,7 @@ static struct ctl_table kern_table[] = {
                .extra1         = &zero,
                .extra2         = &one,
        },
+#endif
        {
                .procname       = "ngroups_max",
                .data           = &ngroups_max,
index e04b8bcdef88dc92a3c52c9c53808528b0266b09..ea37e2ff416429d04cea3829e835ced7f0f35fc0 100644 (file)
@@ -126,7 +126,7 @@ if FTRACE
 config FUNCTION_TRACER
        bool "Kernel Function Tracer"
        depends on HAVE_FUNCTION_TRACER
-       select FRAME_POINTER if (!ARM_UNWIND)
+       select FRAME_POINTER if !ARM_UNWIND && !S390
        select KALLSYMS
        select GENERIC_TRACER
        select CONTEXT_SWITCH_TRACER
index 82d9b8106cd078970ea0c7343e12ad2b6a6eed36..0420841579806ce14b3fc86b9fe13df649dac711 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/writeback.h>
 #include <linux/kallsyms.h>
 #include <linux/seq_file.h>
-#include <linux/smp_lock.h>
 #include <linux/notifier.h>
 #include <linux/irqflags.h>
 #include <linux/debugfs.h>
index 0e8157ee5d4382a32992f34c2b1cf0d78f2868b4..1c7a2ec4f3cc81ee608821ddf589fc0b27db4dcc 100644 (file)
@@ -540,8 +540,7 @@ static void prepare_write_message(struct ceph_connection *con)
                /* initialize page iterator */
                con->out_msg_pos.page = 0;
                if (m->pages)
-                       con->out_msg_pos.page_pos =
-                               le16_to_cpu(m->hdr.data_off) & ~PAGE_MASK;
+                       con->out_msg_pos.page_pos = m->page_alignment;
                else
                        con->out_msg_pos.page_pos = 0;
                con->out_msg_pos.data_pos = 0;
@@ -1491,7 +1490,7 @@ static int read_partial_message(struct ceph_connection *con)
        struct ceph_msg *m = con->in_msg;
        int ret;
        int to, left;
-       unsigned front_len, middle_len, data_len, data_off;
+       unsigned front_len, middle_len, data_len;
        int datacrc = con->msgr->nocrc;
        int skip;
        u64 seq;
@@ -1527,19 +1526,17 @@ static int read_partial_message(struct ceph_connection *con)
        data_len = le32_to_cpu(con->in_hdr.data_len);
        if (data_len > CEPH_MSG_MAX_DATA_LEN)
                return -EIO;
-       data_off = le16_to_cpu(con->in_hdr.data_off);
 
        /* verify seq# */
        seq = le64_to_cpu(con->in_hdr.seq);
        if ((s64)seq - (s64)con->in_seq < 1) {
-               pr_info("skipping %s%lld %s seq %lld, expected %lld\n",
+               pr_info("skipping %s%lld %s seq %lld expected %lld\n",
                        ENTITY_NAME(con->peer_name),
                        ceph_pr_addr(&con->peer_addr.in_addr),
                        seq, con->in_seq + 1);
                con->in_base_pos = -front_len - middle_len - data_len -
                        sizeof(m->footer);
                con->in_tag = CEPH_MSGR_TAG_READY;
-               con->in_seq++;
                return 0;
        } else if ((s64)seq - (s64)con->in_seq > 1) {
                pr_err("read_partial_message bad seq %lld expected %lld\n",
@@ -1576,7 +1573,7 @@ static int read_partial_message(struct ceph_connection *con)
 
                con->in_msg_pos.page = 0;
                if (m->pages)
-                       con->in_msg_pos.page_pos = data_off & ~PAGE_MASK;
+                       con->in_msg_pos.page_pos = m->page_alignment;
                else
                        con->in_msg_pos.page_pos = 0;
                con->in_msg_pos.data_pos = 0;
@@ -2301,6 +2298,7 @@ struct ceph_msg *ceph_msg_new(int type, int front_len, gfp_t flags)
 
        /* data */
        m->nr_pages = 0;
+       m->page_alignment = 0;
        m->pages = NULL;
        m->pagelist = NULL;
        m->bio = NULL;
@@ -2370,6 +2368,7 @@ static struct ceph_msg *ceph_alloc_msg(struct ceph_connection *con,
                               type, front_len);
                        return NULL;
                }
+               msg->page_alignment = le16_to_cpu(hdr->data_off);
        }
        memcpy(&msg->hdr, &con->in_hdr, sizeof(con->in_hdr));
 
index 79391994b3edee7d531b823c0720262090db6618..3e20a122ffa2f2bf40a91596fe12bb93e6874b64 100644 (file)
@@ -71,6 +71,7 @@ void ceph_calc_raw_layout(struct ceph_osd_client *osdc,
                op->extent.length = objlen;
        }
        req->r_num_pages = calc_pages_for(off, *plen);
+       req->r_page_alignment = off & ~PAGE_MASK;
        if (op->op == CEPH_OSD_OP_WRITE)
                op->payload_len = *plen;
 
@@ -390,6 +391,8 @@ void ceph_osdc_build_request(struct ceph_osd_request *req,
                req->r_request->hdr.data_len = cpu_to_le32(data_len);
        }
 
+       req->r_request->page_alignment = req->r_page_alignment;
+
        BUG_ON(p > msg->front.iov_base + msg->front.iov_len);
        msg_size = p - msg->front.iov_base;
        msg->front.iov_len = msg_size;
@@ -419,7 +422,8 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc,
                                               u32 truncate_seq,
                                               u64 truncate_size,
                                               struct timespec *mtime,
-                                              bool use_mempool, int num_reply)
+                                              bool use_mempool, int num_reply,
+                                              int page_align)
 {
        struct ceph_osd_req_op ops[3];
        struct ceph_osd_request *req;
@@ -447,6 +451,10 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc,
        calc_layout(osdc, vino, layout, off, plen, req, ops);
        req->r_file_layout = *layout;  /* keep a copy */
 
+       /* in case it differs from natural alignment that calc_layout
+          filled in for us */
+       req->r_page_alignment = page_align;
+
        ceph_osdc_build_request(req, off, plen, ops,
                                snapc,
                                mtime,
@@ -1489,7 +1497,7 @@ int ceph_osdc_readpages(struct ceph_osd_client *osdc,
                        struct ceph_vino vino, struct ceph_file_layout *layout,
                        u64 off, u64 *plen,
                        u32 truncate_seq, u64 truncate_size,
-                       struct page **pages, int num_pages)
+                       struct page **pages, int num_pages, int page_align)
 {
        struct ceph_osd_request *req;
        int rc = 0;
@@ -1499,15 +1507,15 @@ int ceph_osdc_readpages(struct ceph_osd_client *osdc,
        req = ceph_osdc_new_request(osdc, layout, vino, off, plen,
                                    CEPH_OSD_OP_READ, CEPH_OSD_FLAG_READ,
                                    NULL, 0, truncate_seq, truncate_size, NULL,
-                                   false, 1);
+                                   false, 1, page_align);
        if (!req)
                return -ENOMEM;
 
        /* it may be a short read due to an object boundary */
        req->r_pages = pages;
 
-       dout("readpages  final extent is %llu~%llu (%d pages)\n",
-            off, *plen, req->r_num_pages);
+       dout("readpages  final extent is %llu~%llu (%d pages align %d)\n",
+            off, *plen, req->r_num_pages, page_align);
 
        rc = ceph_osdc_start_request(osdc, req, false);
        if (!rc)
@@ -1533,6 +1541,7 @@ int ceph_osdc_writepages(struct ceph_osd_client *osdc, struct ceph_vino vino,
 {
        struct ceph_osd_request *req;
        int rc = 0;
+       int page_align = off & ~PAGE_MASK;
 
        BUG_ON(vino.snap != CEPH_NOSNAP);
        req = ceph_osdc_new_request(osdc, layout, vino, off, &len,
@@ -1541,7 +1550,7 @@ int ceph_osdc_writepages(struct ceph_osd_client *osdc, struct ceph_vino vino,
                                            CEPH_OSD_FLAG_WRITE,
                                    snapc, do_sync,
                                    truncate_seq, truncate_size, mtime,
-                                   nofail, 1);
+                                   nofail, 1, page_align);
        if (!req)
                return -ENOMEM;
 
@@ -1638,8 +1647,7 @@ static struct ceph_msg *get_reply(struct ceph_connection *con,
        m = ceph_msg_get(req->r_reply);
 
        if (data_len > 0) {
-               unsigned data_off = le16_to_cpu(hdr->data_off);
-               int want = calc_pages_for(data_off & ~PAGE_MASK, data_len);
+               int want = calc_pages_for(req->r_page_alignment, data_len);
 
                if (unlikely(req->r_num_pages < want)) {
                        pr_warning("tid %lld reply %d > expected %d pages\n",
@@ -1651,6 +1659,7 @@ static struct ceph_msg *get_reply(struct ceph_connection *con,
                }
                m->pages = req->r_pages;
                m->nr_pages = req->r_num_pages;
+               m->page_alignment = req->r_page_alignment;
 #ifdef CONFIG_BLOCK
                m->bio = req->r_bio;
 #endif
index 54caf06871559adb490018023cea7163f2451706..ac34feeb2b3ab2202e02aeab2a0367f29ac6a2b2 100644 (file)
@@ -13,8 +13,7 @@
  * build a vector of user pages
  */
 struct page **ceph_get_direct_page_vector(const char __user *data,
-                                                int num_pages,
-                                                loff_t off, size_t len)
+                                         int num_pages)
 {
        struct page **pages;
        int rc;
index 23e9b2a6b4c8ade67fff929c78cea57483b49964..c1ee800bc080c3faf33033e1659021a0a356f7ce 100644 (file)
@@ -589,7 +589,7 @@ int sk_chk_filter(struct sock_filter *filter, int flen)
 EXPORT_SYMBOL(sk_chk_filter);
 
 /**
- *     sk_filter_rcu_release: Release a socket filter by rcu_head
+ *     sk_filter_rcu_release - Release a socket filter by rcu_head
  *     @rcu: rcu_head that contains the sk_filter to free
  */
 static void sk_filter_rcu_release(struct rcu_head *rcu)
index a5ff5a89f376bb1299dec78fa34abe9480ae01f1..7f902cad10f8b13d7096f53905e3a47bb3c12d25 100644 (file)
@@ -712,15 +712,21 @@ static void rx_queue_release(struct kobject *kobj)
 
 
        map = rcu_dereference_raw(queue->rps_map);
-       if (map)
+       if (map) {
+               RCU_INIT_POINTER(queue->rps_map, NULL);
                call_rcu(&map->rcu, rps_map_release);
+       }
 
        flow_table = rcu_dereference_raw(queue->rps_flow_table);
-       if (flow_table)
+       if (flow_table) {
+               RCU_INIT_POINTER(queue->rps_flow_table, NULL);
                call_rcu(&flow_table->rcu, rps_dev_flow_table_release);
+       }
 
        if (atomic_dec_and_test(&first->count))
                kfree(first);
+       else
+               memset(kobj, 0, sizeof(*kobj));
 }
 
 static struct kobj_type rx_queue_ktype = {
index 96bc7f9475a3f2f0124685cc1b7afb7b58c23d8d..e5d1a44bcbdf04b851d441ea5ebd8fbe44514704 100644 (file)
@@ -569,6 +569,9 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
                /* No need to clone since we're just using its address. */
                rt2 = rt;
 
+               if (!fl.nl_u.ip4_u.saddr)
+                       fl.nl_u.ip4_u.saddr = rt->rt_src;
+
                err = xfrm_lookup(net, (struct dst_entry **)&rt, &fl, NULL, 0);
                switch (err) {
                case 0:
index b41ce0f0d514154597753d549b5a29a3bc7e7ae0..2fc35b32df9eacb3c1dcebf153700b5056bc9689 100644 (file)
 #endif
 
 #define        INFINITY_LIFE_TIME      0xFFFFFFFF
-#define TIME_DELTA(a, b) ((unsigned long)((long)(a) - (long)(b)))
+
+static inline u32 cstamp_delta(unsigned long cstamp)
+{
+       return (cstamp - INITIAL_JIFFIES) * 100UL / HZ;
+}
 
 #define ADDRCONF_TIMER_FUZZ_MINUS      (HZ > 50 ? HZ/50 : 1)
 #define ADDRCONF_TIMER_FUZZ            (HZ / 4)
@@ -3444,10 +3448,8 @@ static int put_cacheinfo(struct sk_buff *skb, unsigned long cstamp,
 {
        struct ifa_cacheinfo ci;
 
-       ci.cstamp = (u32)(TIME_DELTA(cstamp, INITIAL_JIFFIES) / HZ * 100
-                       + TIME_DELTA(cstamp, INITIAL_JIFFIES) % HZ * 100 / HZ);
-       ci.tstamp = (u32)(TIME_DELTA(tstamp, INITIAL_JIFFIES) / HZ * 100
-                       + TIME_DELTA(tstamp, INITIAL_JIFFIES) % HZ * 100 / HZ);
+       ci.cstamp = cstamp_delta(cstamp);
+       ci.tstamp = cstamp_delta(tstamp);
        ci.ifa_prefered = preferred;
        ci.ifa_valid = valid;
 
@@ -3798,8 +3800,10 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
        array[DEVCONF_AUTOCONF] = cnf->autoconf;
        array[DEVCONF_DAD_TRANSMITS] = cnf->dad_transmits;
        array[DEVCONF_RTR_SOLICITS] = cnf->rtr_solicits;
-       array[DEVCONF_RTR_SOLICIT_INTERVAL] = cnf->rtr_solicit_interval;
-       array[DEVCONF_RTR_SOLICIT_DELAY] = cnf->rtr_solicit_delay;
+       array[DEVCONF_RTR_SOLICIT_INTERVAL] =
+               jiffies_to_msecs(cnf->rtr_solicit_interval);
+       array[DEVCONF_RTR_SOLICIT_DELAY] =
+               jiffies_to_msecs(cnf->rtr_solicit_delay);
        array[DEVCONF_FORCE_MLD_VERSION] = cnf->force_mld_version;
 #ifdef CONFIG_IPV6_PRIVACY
        array[DEVCONF_USE_TEMPADDR] = cnf->use_tempaddr;
@@ -3813,7 +3817,8 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
        array[DEVCONF_ACCEPT_RA_PINFO] = cnf->accept_ra_pinfo;
 #ifdef CONFIG_IPV6_ROUTER_PREF
        array[DEVCONF_ACCEPT_RA_RTR_PREF] = cnf->accept_ra_rtr_pref;
-       array[DEVCONF_RTR_PROBE_INTERVAL] = cnf->rtr_probe_interval;
+       array[DEVCONF_RTR_PROBE_INTERVAL] =
+               jiffies_to_msecs(cnf->rtr_probe_interval);
 #ifdef CONFIG_IPV6_ROUTE_INFO
        array[DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN] = cnf->accept_ra_rt_info_max_plen;
 #endif
@@ -3929,10 +3934,9 @@ static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev,
        NLA_PUT_U32(skb, IFLA_INET6_FLAGS, idev->if_flags);
 
        ci.max_reasm_len = IPV6_MAXPLEN;
-       ci.tstamp = (__u32)(TIME_DELTA(idev->tstamp, INITIAL_JIFFIES) / HZ * 100
-                   + TIME_DELTA(idev->tstamp, INITIAL_JIFFIES) % HZ * 100 / HZ);
-       ci.reachable_time = idev->nd_parms->reachable_time;
-       ci.retrans_time = idev->nd_parms->retrans_time;
+       ci.tstamp = cstamp_delta(idev->tstamp);
+       ci.reachable_time = jiffies_to_msecs(idev->nd_parms->reachable_time);
+       ci.retrans_time = jiffies_to_msecs(idev->nd_parms->retrans_time);
        NLA_PUT(skb, IFLA_INET6_CACHEINFO, sizeof(ci), &ci);
 
        nla = nla_reserve(skb, IFLA_INET6_CONF, DEVCONF_MAX * sizeof(s32));
index 7f097989cde2149714eab1ea7b1de02280531ed2..a6de3059746ddd3f3039d564f20acf394225e3ad 100644 (file)
@@ -45,7 +45,6 @@
 #include <linux/capability.h>
 #include <linux/module.h>
 #include <linux/types.h>
-#include <linux/smp_lock.h>
 #include <linux/socket.h>
 #include <linux/sockios.h>
 #include <linux/slab.h>
index 7fa86373de414a810be41e6973027d0b31c12168..7c567b8aa89a9e938dc442487b70d5e099bc2ade 100644 (file)
@@ -15,7 +15,6 @@
 
 #include <linux/sched.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include "irnet_ppp.h"         /* Private header */
 /* Please put other headers in irnet.h - Thanks */
 
index 285761e77d90f98ee15c6b47b34c8ead10692e33..f6054f9ccbe33c2fbd9aef8c88551c84bb5fbf62 100644 (file)
@@ -550,22 +550,30 @@ EXPORT_SYMBOL(irttp_close_tsap);
  */
 int irttp_udata_request(struct tsap_cb *self, struct sk_buff *skb)
 {
+       int ret;
+
        IRDA_ASSERT(self != NULL, return -1;);
        IRDA_ASSERT(self->magic == TTP_TSAP_MAGIC, return -1;);
        IRDA_ASSERT(skb != NULL, return -1;);
 
        IRDA_DEBUG(4, "%s()\n", __func__);
 
+       /* Take shortcut on zero byte packets */
+       if (skb->len == 0) {
+               ret = 0;
+               goto err;
+       }
+
        /* Check that nothing bad happens */
-       if ((skb->len == 0) || (!self->connected)) {
-               IRDA_DEBUG(1, "%s(), No data, or not connected\n",
-                          __func__);
+       if (!self->connected) {
+               IRDA_WARNING("%s(), Not connected\n", __func__);
+               ret = -ENOTCONN;
                goto err;
        }
 
        if (skb->len > self->max_seg_size) {
-               IRDA_DEBUG(1, "%s(), UData is too large for IrLAP!\n",
-                          __func__);
+               IRDA_ERROR("%s(), UData is too large for IrLAP!\n", __func__);
+               ret = -EMSGSIZE;
                goto err;
        }
 
@@ -576,7 +584,7 @@ int irttp_udata_request(struct tsap_cb *self, struct sk_buff *skb)
 
 err:
        dev_kfree_skb(skb);
-       return -1;
+       return ret;
 }
 EXPORT_SYMBOL(irttp_udata_request);
 
@@ -599,9 +607,15 @@ int irttp_data_request(struct tsap_cb *self, struct sk_buff *skb)
        IRDA_DEBUG(2, "%s() : queue len = %d\n", __func__,
                   skb_queue_len(&self->tx_queue));
 
+       /* Take shortcut on zero byte packets */
+       if (skb->len == 0) {
+               ret = 0;
+               goto err;
+       }
+
        /* Check that nothing bad happens */
-       if ((skb->len == 0) || (!self->connected)) {
-               IRDA_WARNING("%s: No data, or not connected\n", __func__);
+       if (!self->connected) {
+               IRDA_WARNING("%s: Not connected\n", __func__);
                ret = -ENOTCONN;
                goto err;
        }
index a22dac227055e7499bfd9d8dd509ee5fba3e1c9b..70bd1d0774c6bdb6b1f9d4d1f07284cfe43500dd 100644 (file)
@@ -4,6 +4,7 @@
 menuconfig IP_VS
        tristate "IP virtual server support"
        depends on NET && INET && NETFILTER
+       depends on (NF_CONNTRACK || NF_CONNTRACK=n)
        ---help---
          IP Virtual Server support will let you build a high-performance
          virtual server based on cluster of two or more real servers. This
index 8920f2a83327a42f10d20acdfb651f9c1b9620a3..4e37c1cbe8b2faf5928af6be551f3f5551684411 100644 (file)
@@ -567,7 +567,7 @@ int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm,
                goto out;
        }
 
-       if (args->nr_local > (u64)UINT_MAX) {
+       if (args->nr_local > UIO_MAXIOV) {
                ret = -EMSGSIZE;
                goto out;
        }
index f71a73107ae94adeae35303f95f0b3409aee9e07..80df89d957ba02dce1b977ec19f96b51d2c657b0 100644 (file)
@@ -115,9 +115,7 @@ EXPORT_SYMBOL_GPL(svc_seq_show);
  */
 struct rpc_iostats *rpc_alloc_iostats(struct rpc_clnt *clnt)
 {
-       struct rpc_iostats *new;
-       new = kcalloc(clnt->cl_maxproc, sizeof(struct rpc_iostats), GFP_KERNEL);
-       return new;
+       return kcalloc(clnt->cl_maxproc, sizeof(struct rpc_iostats), GFP_KERNEL);
 }
 EXPORT_SYMBOL_GPL(rpc_alloc_iostats);
 
index c82fe739fbdcc685fae1e59f1fdb7c9e5afd30b0..ea2ff78dcf7b7ec4f2555210af82379017e6e291 100644 (file)
@@ -5,7 +5,6 @@
  */
 
 #include <linux/sched.h>
-#include <linux/smp_lock.h>
 #include <linux/errno.h>
 #include <linux/freezer.h>
 #include <linux/kthread.h>
index d0c92dddb26bddb5b3d55a82ebf39fa8917e446c..17cd0c04d139045bbb0802a74d9628731d9428dc 100644 (file)
@@ -44,6 +44,38 @@ rdev_freq_to_chan(struct cfg80211_registered_device *rdev,
        return chan;
 }
 
+static bool can_beacon_sec_chan(struct wiphy *wiphy,
+                               struct ieee80211_channel *chan,
+                               enum nl80211_channel_type channel_type)
+{
+       struct ieee80211_channel *sec_chan;
+       int diff;
+
+       switch (channel_type) {
+       case NL80211_CHAN_HT40PLUS:
+               diff = 20;
+               break;
+       case NL80211_CHAN_HT40MINUS:
+               diff = -20;
+               break;
+       default:
+               return false;
+       }
+
+       sec_chan = ieee80211_get_channel(wiphy, chan->center_freq + diff);
+       if (!sec_chan)
+               return false;
+
+       /* we'll need a DFS capability later */
+       if (sec_chan->flags & (IEEE80211_CHAN_DISABLED |
+                              IEEE80211_CHAN_PASSIVE_SCAN |
+                              IEEE80211_CHAN_NO_IBSS |
+                              IEEE80211_CHAN_RADAR))
+               return false;
+
+       return true;
+}
+
 int cfg80211_set_freq(struct cfg80211_registered_device *rdev,
                      struct wireless_dev *wdev, int freq,
                      enum nl80211_channel_type channel_type)
@@ -68,6 +100,28 @@ int cfg80211_set_freq(struct cfg80211_registered_device *rdev,
        if (!chan)
                return -EINVAL;
 
+       /* Both channels should be able to initiate communication */
+       if (wdev && (wdev->iftype == NL80211_IFTYPE_ADHOC ||
+                    wdev->iftype == NL80211_IFTYPE_AP ||
+                    wdev->iftype == NL80211_IFTYPE_AP_VLAN ||
+                    wdev->iftype == NL80211_IFTYPE_MESH_POINT ||
+                    wdev->iftype == NL80211_IFTYPE_P2P_GO)) {
+               switch (channel_type) {
+               case NL80211_CHAN_HT40PLUS:
+               case NL80211_CHAN_HT40MINUS:
+                       if (!can_beacon_sec_chan(&rdev->wiphy, chan,
+                                                channel_type)) {
+                               printk(KERN_DEBUG
+                                      "cfg80211: Secondary channel not "
+                                      "allowed to initiate communication\n");
+                               return -EINVAL;
+                       }
+                       break;
+               default:
+                       break;
+               }
+       }
+
        result = rdev->ops->set_channel(&rdev->wiphy,
                                        wdev ? wdev->netdev : NULL,
                                        chan, channel_type);
index cdb6dc1f6458ba4634c0f8584ae3da615ce10696..39580a5dc5df6083a5766ae8853c6610e417474f 100755 (executable)
@@ -5,7 +5,7 @@ use strict;
 ## Copyright (c) 1998 Michael Zucchi, All Rights Reserved        ##
 ## Copyright (C) 2000, 1  Tim Waugh <twaugh@redhat.com>          ##
 ## Copyright (C) 2001  Simon Huggins                             ##
-## Copyright (C) 2005-2009  Randy Dunlap                         ##
+## Copyright (C) 2005-2010  Randy Dunlap                         ##
 ##                                                              ##
 ## #define enhancements by Armin Kuster <akuster@mvista.com>    ##
 ## Copyright (c) 2000 MontaVista Software, Inc.                         ##
@@ -453,7 +453,7 @@ sub output_highlight {
     if ($output_mode eq "html" || $output_mode eq "xml") {
        $contents = local_unescape($contents);
        # convert data read & converted thru xml_escape() into &xyz; format:
-       $contents =~ s/\\\\\\/&/g;
+       $contents =~ s/\\\\\\/\&/g;
     }
 #   print STDERR "contents b4:$contents\n";
     eval $dohighlight;
@@ -770,7 +770,11 @@ sub output_struct_xml(%) {
     print $args{'type'} . " " . $args{'struct'} . " {\n";
     foreach $parameter (@{$args{'parameterlist'}}) {
        if ($parameter =~ /^#/) {
-           print "$parameter\n";
+           my $prm = $parameter;
+           # convert data read & converted thru xml_escape() into &xyz; format:
+           # This allows us to have #define macros interspersed in a struct.
+           $prm =~ s/\\\\\\/\&/g;
+           print "$prm\n";
            next;
        }
 
@@ -1701,6 +1705,8 @@ sub push_parameter($$$) {
        }
        }
 
+       $param = xml_escape($param);
+
        # strip spaces from $param so that it is one continous string
        # on @parameterlist;
        # this fixes a problem where check_sections() cannot find
index b70564ed8b37821aa0f336d3585acf58da5854e3..7077f601da5a66a279bed9be77159f2ec80dfc78 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/time.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/string.h>
 #include <sound/core.h>
 #include <sound/minors.h>
index 8bc7cb3db33056abce9a03cec36a4266305aa12c..e82c1f97d99e9736b20523f7bf6eca63498f2587 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/mm.h>
 #include <linux/file.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/time.h>
 #include <linux/pm_qos_params.h>
 #include <linux/uio.h>
index 62a093efb453cc5d9657e4a3ce822ce42ca07748..66691fe437e63315fad4a1af8c073e9fbba058e5 100644 (file)
@@ -21,7 +21,6 @@
 
 #include <linux/init.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/time.h>
 #include <linux/device.h>
 #include <linux/moduleparam.h>
index c03bbaefdbc36c623e3f5b76cea86f6ad59e46cc..5580aced87308202e00d181194a6d4aa6689b920 100644 (file)
@@ -104,7 +104,6 @@ module_exit(cleanup_soundcore);
 
 #include <linux/init.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/sound.h>