diff options
author | Dave Airlie <airlied@redhat.com> | 2013-06-27 20:40:44 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2013-06-27 20:40:44 +1000 |
commit | 4300a0f8bdcce5a03b88bfa16fc9827e15c52dc4 (patch) | |
tree | dea0276d7d0a12147f04ddbef9121e32e903c5ca | |
parent | 160954b7bca43da7cd3cfbce310e6df919a8216e (diff) | |
parent | 9e895ace5d82df8929b16f58e9f515f6d54ab82d (diff) |
Merge tag 'v3.10-rc7' into drm-next
Linux 3.10-rc7
The sdvo lvds fix in this -fixes pull
commit c3456fb3e4712d0448592af3c5d644c9472cd3c1
Author: Daniel Vetter <daniel.vetter@ffwll.ch>
Date: Mon Jun 10 09:47:58 2013 +0200
drm/i915: prefer VBT modes for SVDO-LVDS over EDID
has a silent functional conflict with
commit 990256aec2f10800595dddf4d1c3441fcd6b2616
Author: Ville Syrjälä <ville.syrjala@linux.intel.com>
Date: Fri May 31 12:17:07 2013 +0000
drm: Add probed modes in probe order
in drm-next. W simply need to add the vbt modes before edid modes, i.e. the
other way round than now.
Conflicts:
drivers/gpu/drm/drm_prime.c
drivers/gpu/drm/i915/intel_sdvo.c
1058 files changed, 13456 insertions, 7048 deletions
diff --git a/Documentation/DocBook/media/v4l/dev-codec.xml b/Documentation/DocBook/media/v4l/dev-codec.xml index dca0ecd54dc6..ff44c16fc080 100644 --- a/Documentation/DocBook/media/v4l/dev-codec.xml +++ b/Documentation/DocBook/media/v4l/dev-codec.xml @@ -1,18 +1,27 @@ <title>Codec Interface</title> - <note> - <title>Suspended</title> + <para>A V4L2 codec can compress, decompress, transform, or otherwise +convert video data from one format into another format, in memory. Typically +such devices are memory-to-memory devices (i.e. devices with the +<constant>V4L2_CAP_VIDEO_M2M</constant> or <constant>V4L2_CAP_VIDEO_M2M_MPLANE</constant> +capability set). +</para> - <para>This interface has been be suspended from the V4L2 API -implemented in Linux 2.6 until we have more experience with codec -device interfaces.</para> - </note> + <para>A memory-to-memory video node acts just like a normal video node, but it +supports both output (sending frames from memory to the codec hardware) and +capture (receiving the processed frames from the codec hardware into memory) +stream I/O. An application will have to setup the stream +I/O for both sides and finally call &VIDIOC-STREAMON; for both capture and output +to start the codec.</para> - <para>A V4L2 codec can compress, decompress, transform, or otherwise -convert video data from one format into another format, in memory. -Applications send data to be converted to the driver through a -&func-write; call, and receive the converted data through a -&func-read; call. For efficiency a driver may also support streaming -I/O.</para> + <para>Video compression codecs use the MPEG controls to setup their codec parameters +(note that the MPEG controls actually support many more codecs than just MPEG). +See <xref linkend="mpeg-controls"></xref>.</para> - <para>[to do]</para> + <para>Memory-to-memory devices can often be used as a shared resource: you can +open the video node multiple times, each application setting up their own codec properties +that are local to the file handle, and each can use it independently from the others. +The driver will arbitrate access to the codec and reprogram it whenever another file +handler gets access. This is different from the usual video node behavior where the video properties +are global to the device (i.e. changing something through one file handle is visible +through another file handle).</para> diff --git a/Documentation/DocBook/media/v4l/v4l2.xml b/Documentation/DocBook/media/v4l/v4l2.xml index bfc93cdcf696..bfe823dd0f31 100644 --- a/Documentation/DocBook/media/v4l/v4l2.xml +++ b/Documentation/DocBook/media/v4l/v4l2.xml @@ -493,7 +493,7 @@ and discussions on the V4L mailing list.</revremark> </partinfo> <title>Video for Linux Two API Specification</title> - <subtitle>Revision 3.9</subtitle> + <subtitle>Revision 3.10</subtitle> <chapter id="common"> &sub-common; diff --git a/Documentation/bcache.txt b/Documentation/bcache.txt index 77db8809bd96..b3a7e7d384f6 100644 --- a/Documentation/bcache.txt +++ b/Documentation/bcache.txt @@ -319,7 +319,10 @@ cache<0..n> Symlink to each of the cache devices comprising this cache set. cache_available_percent - Percentage of cache device free. + Percentage of cache device which doesn't contain dirty data, and could + potentially be used for writeback. This doesn't mean this space isn't used + for clean cached data; the unused statistic (in priority_stats) is typically + much lower. clear_stats Clears the statistics associated with this cache @@ -423,8 +426,11 @@ nbuckets Total buckets in this cache priority_stats - Statistics about how recently data in the cache has been accessed. This can - reveal your working set size. + Statistics about how recently data in the cache has been accessed. + This can reveal your working set size. Unused is the percentage of + the cache that doesn't contain any data. Metadata is bcache's + metadata overhead. Average is the average priority of cache buckets. + Next is a list of quantiles with the priority threshold of each. written Sum of all data that has been written to the cache; comparison with diff --git a/Documentation/devices.txt b/Documentation/devices.txt index 08f01e79c41a..b9015912bca6 100644 --- a/Documentation/devices.txt +++ b/Documentation/devices.txt @@ -498,12 +498,8 @@ Your cooperation is appreciated. Each device type has 5 bits (32 minors). - 13 block 8-bit MFM/RLL/IDE controller - 0 = /dev/xda First XT disk whole disk - 64 = /dev/xdb Second XT disk whole disk - - Partitions are handled in the same way as IDE disks - (see major number 3). + 13 block Previously used for the XT disk (/dev/xdN) + Deleted in kernel v3.9. 14 char Open Sound System (OSS) 0 = /dev/mixer Mixer control diff --git a/Documentation/devicetree/bindings/media/exynos-fimc-lite.txt b/Documentation/devicetree/bindings/media/exynos-fimc-lite.txt index 3f62adfb3e0b..de9f6b78ee51 100644 --- a/Documentation/devicetree/bindings/media/exynos-fimc-lite.txt +++ b/Documentation/devicetree/bindings/media/exynos-fimc-lite.txt @@ -2,7 +2,7 @@ Exynos4x12/Exynos5 SoC series camera host interface (FIMC-LITE) Required properties: -- compatible : should be "samsung,exynos4212-fimc" for Exynos4212 and +- compatible : should be "samsung,exynos4212-fimc-lite" for Exynos4212 and Exynos4412 SoCs; - reg : physical base address and size of the device memory mapped registers; diff --git a/Documentation/devicetree/bindings/net/macb.txt b/Documentation/devicetree/bindings/net/macb.txt index 44afa0e5057d..4ff65047bb9a 100644 --- a/Documentation/devicetree/bindings/net/macb.txt +++ b/Documentation/devicetree/bindings/net/macb.txt @@ -4,7 +4,7 @@ Required properties: - compatible: Should be "cdns,[<chip>-]{macb|gem}" Use "cdns,at91sam9260-macb" Atmel at91sam9260 and at91sam9263 SoCs. Use "cdns,at32ap7000-macb" for other 10/100 usage or use the generic form: "cdns,macb". - Use "cnds,pc302-gem" for Picochip picoXcell pc302 and later devices based on + Use "cdns,pc302-gem" for Picochip picoXcell pc302 and later devices based on the Cadence GEM, or the generic form: "cdns,gem". - reg: Address and length of the register set for the device - interrupts: Should contain macb interrupt diff --git a/Documentation/devicetree/bindings/rtc/atmel,at91rm9200-rtc.txt b/Documentation/devicetree/bindings/rtc/atmel,at91rm9200-rtc.txt index 2a3feabd3b22..34c1505774bf 100644 --- a/Documentation/devicetree/bindings/rtc/atmel,at91rm9200-rtc.txt +++ b/Documentation/devicetree/bindings/rtc/atmel,at91rm9200-rtc.txt @@ -1,7 +1,7 @@ Atmel AT91RM9200 Real Time Clock Required properties: -- compatible: should be: "atmel,at91rm9200-rtc" +- compatible: should be: "atmel,at91rm9200-rtc" or "atmel,at91sam9x5-rtc" - reg: physical base address of the controller and length of memory mapped region. - interrupts: rtc alarm/event interrupt diff --git a/Documentation/devicetree/bindings/video/simple-framebuffer.txt b/Documentation/devicetree/bindings/video/simple-framebuffer.txt new file mode 100644 index 000000000000..3ea460583111 --- /dev/null +++ b/Documentation/devicetree/bindings/video/simple-framebuffer.txt @@ -0,0 +1,25 @@ +Simple Framebuffer + +A simple frame-buffer describes a raw memory region that may be rendered to, +with the assumption that the display hardware has already been set up to scan +out from that buffer. + +Required properties: +- compatible: "simple-framebuffer" +- reg: Should contain the location and size of the framebuffer memory. +- width: The width of the framebuffer in pixels. +- height: The height of the framebuffer in pixels. +- stride: The number of bytes in each line of the framebuffer. +- format: The format of the framebuffer surface. Valid values are: + - r5g6b5 (16-bit pixels, d[15:11]=r, d[10:5]=g, d[4:0]=b). + +Example: + + framebuffer { + compatible = "simple-framebuffer"; + reg = <0x1d385000 (1600 * 1200 * 2)>; + width = <1600>; + height = <1200>; + stride = <(1600 * 2)>; + format = "r5g6b5"; + }; diff --git a/Documentation/dmatest.txt b/Documentation/dmatest.txt index 279ac0a8c5b1..132a094c7bc3 100644 --- a/Documentation/dmatest.txt +++ b/Documentation/dmatest.txt @@ -34,7 +34,7 @@ command: After a while you will start to get messages about current status or error like in the original code. -Note that running a new test will stop any in progress test. +Note that running a new test will not stop any in progress test. The following command should return actual state of the test. % cat /sys/kernel/debug/dmatest/run @@ -52,8 +52,8 @@ To wait for test done the user may perform a busy loop that checks the state. The module parameters that is supplied to the kernel command line will be used for the first performed test. After user gets a control, the test could be -interrupted or re-run with same or different parameters. For the details see -the above section "Part 2 - When dmatest is built as a module..." +re-run with the same or different parameters. For the details see the above +section "Part 2 - When dmatest is built as a module..." In both cases the module parameters are used as initial values for the test case. You always could check them at run-time by running diff --git a/Documentation/filesystems/xfs.txt b/Documentation/filesystems/xfs.txt index 3e4b3dd1e046..83577f0232a0 100644 --- a/Documentation/filesystems/xfs.txt +++ b/Documentation/filesystems/xfs.txt @@ -33,6 +33,9 @@ When mounting an XFS filesystem, the following options are accepted. removing extended attributes) the on-disk superblock feature bit field will be updated to reflect this format being in use. + CRC enabled filesystems always use the attr2 format, and so + will reject the noattr2 mount option if it is set. + barrier Enables the use of block layer write barriers for writes into the journal and unwritten extent conversion. This allows for diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 6e3b18a8afc6..2fe6e767b3d6 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -3351,9 +3351,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted. plus one apbt timer for broadcast timer. x86_mrst_timer=apbt_only | lapic_and_apbt - xd= [HW,XT] Original XT pre-IDE (RLL encoded) disks. - xd_geo= See header of drivers/block/xd.c. - xen_emul_unplug= [HW,X86,XEN] Unplug Xen emulated devices Format: [unplug0,][unplug1] diff --git a/Documentation/m68k/kernel-options.txt b/Documentation/m68k/kernel-options.txt index 97d45f276fe6..eaf32a1fd0b1 100644 --- a/Documentation/m68k/kernel-options.txt +++ b/Documentation/m68k/kernel-options.txt @@ -80,8 +80,6 @@ Valid names are: /dev/sdd: -> 0x0830 (forth SCSI disk) /dev/sde: -> 0x0840 (fifth SCSI disk) /dev/fd : -> 0x0200 (floppy disk) - /dev/xda: -> 0x0c00 (first XT disk, unused in Linux/m68k) - /dev/xdb: -> 0x0c40 (second XT disk, unused in Linux/m68k) The name must be followed by a decimal number, that stands for the partition number. Internally, the value of the number is just diff --git a/Documentation/powerpc/transactional_memory.txt b/Documentation/powerpc/transactional_memory.txt index c907be41d60f..dc23e58ae264 100644 --- a/Documentation/powerpc/transactional_memory.txt +++ b/Documentation/powerpc/transactional_memory.txt @@ -147,6 +147,25 @@ Example signal handler: fix_the_problem(ucp->dar); } +When in an active transaction that takes a signal, we need to be careful with +the stack. It's possible that the stack has moved back up after the tbegin. +The obvious case here is when the tbegin is called inside a function that +returns before a tend. In this case, the stack is part of the checkpointed +transactional memory state. If we write over this non transactionally or in +suspend, we are in trouble because if we get a tm abort, the program counter and +stack pointer will be back at the tbegin but our in memory stack won't be valid +anymore. + +To avoid this, when taking a signal in an active transaction, we need to use +the stack pointer from the checkpointed state, rather than the speculated +state. This ensures that the signal context (written tm suspended) will be +written below the stack required for the rollback. The transaction is aborted +becuase of the treclaim, so any memory written between the tbegin and the +signal will be rolled back anyway. + +For signals taken in non-TM or suspended mode, we use the +normal/non-checkpointed stack pointer. + Failure cause codes used by kernel ================================== @@ -155,14 +174,18 @@ These are defined in <asm/reg.h>, and distinguish different reasons why the kernel aborted a transaction: TM_CAUSE_RESCHED Thread was rescheduled. + TM_CAUSE_TLBI Software TLB invalide. TM_CAUSE_FAC_UNAV FP/VEC/VSX unavailable trap. TM_CAUSE_SYSCALL Currently unused; future syscalls that must abort transactions for consistency will use this. TM_CAUSE_SIGNAL Signal delivered. TM_CAUSE_MISC Currently unused. + TM_CAUSE_ALIGNMENT Alignment fault. + TM_CAUSE_EMULATE Emulation that touched memory. -These can be checked by the user program's abort handler as TEXASR[0:7]. - +These can be checked by the user program's abort handler as TEXASR[0:7]. If +bit 7 is set, it indicates that the error is consider persistent. For example +a TM_CAUSE_ALIGNMENT will be persistent while a TM_CAUSE_RESCHED will not.q GDB === diff --git a/Documentation/rapidio/rapidio.txt b/Documentation/rapidio/rapidio.txt index c75694b35d08..a9c16c979da2 100644 --- a/Documentation/rapidio/rapidio.txt +++ b/Documentation/rapidio/rapidio.txt @@ -79,20 +79,63 @@ master port that is used to communicate with devices within the network. In order to initialize the RapidIO subsystem, a platform must initialize and register at least one master port within the RapidIO network. To register mport within the subsystem controller driver initialization code calls function -rio_register_mport() for each available master port. After all active master -ports are registered with a RapidIO subsystem, the rio_init_mports() routine -is called to perform enumeration and discovery. +rio_register_mport() for each available master port. -In the current PowerPC-based implementation a subsys_initcall() is specified to -perform controller initialization and mport registration. At the end it directly -calls rio_init_mports() to execute RapidIO enumeration and discovery. +RapidIO subsystem uses subsys_initcall() or device_initcall() to perform +controller initialization (depending on controller device type). + +After all active master ports are registered with a RapidIO subsystem, +an enumeration and/or discovery routine may be called automatically or +by user-space command. 4. Enumeration and Discovery ---------------------------- -When rio_init_mports() is called it scans a list of registered master ports and -calls an enumeration or discovery routine depending on the configured role of a -master port: host or agent. +4.1 Overview +------------ + +RapidIO subsystem configuration options allow users to specify enumeration and +discovery methods as statically linked components or loadable modules. +An enumeration/discovery method implementation and available input parameters +define how any given method can be attached to available RapidIO mports: +simply to all available mports OR individually to the specified mport device. + +Depending on selected enumeration/discovery build configuration, there are +several methods to initiate an enumeration and/or discovery process: + + (a) Statically linked enumeration and discovery process can be started + automatically during kernel initialization time using corresponding module + parameters. This was the original method used since introduction of RapidIO + subsystem. Now this method relies on enumerator module parameter which is + 'rio-scan.scan' for existing basic enumeration/discovery method. + When automatic start of enumeration/discovery is used a user has to ensure + that all discovering endpoints are started before the enumerating endpoint + and are waiting for enumeration to be completed. + Configuration option CONFIG_RAPIDIO_DISC_TIMEOUT defines time that discovering + endpoint waits for enumeration to be completed. If the specified timeout + expires the discovery process is terminated without obtaining RapidIO network + information. NOTE: a timed out discovery process may be restarted later using + a user-space command as it is described later if the given endpoint was + enumerated successfully. + + (b) Statically linked enumeration and discovery process can be started by + a command from user space. This initiation method provides more flexibility + for a system startup compared to the option (a) above. After all participating + endpoints have been successfully booted, an enumeration process shall be + started first by issuing a user-space command, after an enumeration is + completed a discovery process can be started on all remaining endpoints. + + (c) Modular enumeration and discovery process can be started by a command from + user space. After an enumeration/discovery module is loaded, a network scan + process can be started by issuing a user-space command. + Similar to the option (b) above, an enumerator has to be started first. + + (d) Modular enumeration and discovery process can be started by a module + initialization routine. In this case an enumerating module shall be loaded + first. + +When a network scan process is started it calls an enumeration or discovery +routine depending on the configured role of a master port: host or agent. Enumeration is performed by a master port if it is configured as a host port by assigning a host device ID greater than or equal to zero. A host device ID is @@ -104,8 +147,58 @@ for it. The enumeration and discovery routines use RapidIO maintenance transactions to access the configuration space of devices. -The enumeration process is implemented according to the enumeration algorithm -outlined in the RapidIO Interconnect Specification: Annex I [1]. +4.2 Automatic Start of Enumeration and Discovery +------------------------------------------------ + +Automatic enumeration/discovery start method is applicable only to built-in +enumeration/discovery RapidIO configuration selection. To enable automatic +enumeration/discovery start by existing basic enumerator method set use boot +command line parameter "rio-scan.scan=1". + +This configuration requires synchronized start of all RapidIO endpoints that +form a network which will be enumerated/discovered. Discovering endpoints have +to be started before an enumeration starts to ensure that all RapidIO +controllers have been initialized and are ready to be discovered. Configuration +parameter CONFIG_RAPIDIO_DISC_TIMEOUT defines time (in seconds) which +a discovering endpoint will wait for enumeration to be completed. + +When automatic enumeration/discovery start is selected, basic method's +initialization routine calls rio_init_mports() to perform enumeration or +discovery for all known mport devices. + +Depending on RapidIO network size and configuration this automatic +enumeration/discovery start method may be difficult to use due to the +requirement for synchronized start of all endpoints. + +4.3 User-space Start of Enumeration and Discovery +------------------------------------------------- + +User-space start of enumeration and discovery can be used with built-in and +modular build configurations. For user-space controlled start RapidIO subsystem +creates the sysfs write-only attribute file '/sys/bus/rapidio/scan'. To initiate +an enumeration or discovery process on specific mport device, a user needs to +write mport_ID (not RapidIO destination ID) into that file. The mport_ID is a +sequential number (0 ... RIO_MAX_MPORTS) assigned during mport device +registration. For example for machine with single RapidIO controller, mport_ID +for that controller always will be 0. + +To initiate RapidIO enumeration/discovery on all available mports a user may +write '-1' (or RIO_MPORT_ANY) into the scan attribute file. + +4.4 Basic Enumeration Method +---------------------------- + +This is an original enumeration/discovery method which is available since +first release of RapidIO subsystem code. The enumeration process is +implemented according to the enumeration algorithm outlined in the RapidIO +Interconnect Specification: Annex I [1]. + +This method can be configured as statically linked or loadable module. +The method's single parameter "scan" allows to trigger the enumeration/discovery +process from module initialization routine. + +This enumeration/discovery method can be started only once and does not support +unloading if it is built as a module. The enumeration process traverses the network using a recursive depth-first algorithm. When a new device is found, the enumerator takes ownership of that @@ -160,6 +253,19 @@ time period. If this wait time period expires before enumeration is completed, an agent skips RapidIO discovery and continues with remaining kernel initialization. +4.5 Adding New Enumeration/Discovery Method +------------------------------------------- + +RapidIO subsystem code organization allows addition of new enumeration/discovery +methods as new configuration options without significant impact to to the core +RapidIO code. + +A new enumeration/discovery method has to be attached to one or more mport +devices before an enumeration/discovery process can be started. Normally, +method's module initialization routine calls rio_register_scan() to attach +an enumerator to a specified mport device (or devices). The basic enumerator +implementation demonstrates this process. + 5. References ------------- diff --git a/Documentation/rapidio/sysfs.txt b/Documentation/rapidio/sysfs.txt index 97f71ce575d6..19878179da4c 100644 --- a/Documentation/rapidio/sysfs.txt +++ b/Documentation/rapidio/sysfs.txt @@ -88,3 +88,20 @@ that exports additional attributes. IDT_GEN2: errlog - reads contents of device error log until it is empty. + + +5. RapidIO Bus Attributes +------------------------- + +RapidIO bus subdirectory /sys/bus/rapidio implements the following bus-specific +attribute: + + scan - allows to trigger enumeration discovery process from user space. This + is a write-only attribute. To initiate an enumeration or discovery + process on specific mport device, a user needs to write mport_ID (not + RapidIO destination ID) into this file. The mport_ID is a sequential + number (0 ... RIO_MAX_MPORTS) assigned to the mport device. + For example, for a machine with a single RapidIO controller, mport_ID + for that controller always will be 0. + To initiate RapidIO enumeration/discovery on all available mports + a user must write '-1' (or RIO_MPORT_ANY) into this attribute file. diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt index bb8b0dc532b8..77d68e23b247 100644 --- a/Documentation/sound/alsa/HD-Audio-Models.txt +++ b/Documentation/sound/alsa/HD-Audio-Models.txt @@ -29,6 +29,8 @@ ALC269/270/275/276/280/282 alc271-dmic Enable ALC271X digital mic workaround inv-dmic Inverted internal mic workaround lenovo-dock Enables docking station I/O for some Lenovos + dell-headset-multi Headset jack, which can also be used as mic-in + dell-headset-dock Headset jack (without mic-in), and also dock I/O ALC662/663/272 ============== @@ -42,6 +44,7 @@ ALC662/663/272 asus-mode7 ASUS asus-mode8 ASUS inv-dmic Inverted internal mic workaround + dell-headset-multi Headset jack, which can also be used as mic-in ALC680 ====== diff --git a/MAINTAINERS b/MAINTAINERS index 94b5a60b19c5..5be702cc8449 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2890,8 +2890,8 @@ F: drivers/media/dvb-frontends/ec100* ECRYPT FILE SYSTEM M: Tyler Hicks <tyhicks@canonical.com> -M: Dustin Kirkland <dustin.kirkland@gazzang.com> L: ecryptfs@vger.kernel.org +W: http://ecryptfs.org W: https://launchpad.net/ecryptfs S: Supported F: Documentation/filesystems/ecryptfs.txt @@ -3322,11 +3322,12 @@ F: drivers/net/wan/dlci.c F: drivers/net/wan/sdla.c FRAMEBUFFER LAYER -M: Florian Tobias Schandinat <FlorianSchandinat@gmx.de> +M: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com> +M: Tomi Valkeinen <tomi.valkeinen@ti.com> L: linux-fbdev@vger.kernel.org W: http://linux-fbdev.sourceforge.net/ Q: http://patchwork.kernel.org/project/linux-fbdev/list/ -T: git git://github.com/schandinat/linux-2.6.git fbdev-next +T: git git://git.kernel.org/pub/scm/linux/kernel/git/plagnioj/linux-fbdev.git S: Maintained F: Documentation/fb/ F: Documentation/devicetree/bindings/fb/ @@ -4447,6 +4448,16 @@ S: Maintained F: drivers/scsi/*iscsi* F: include/scsi/*iscsi* +ISCSI EXTENSIONS FOR RDMA (ISER) INITIATOR +M: Or Gerlitz <ogerlitz@mellanox.com> +M: Roi Dayan <roid@mellanox.com> +L: linux-rdma@vger.kernel.org +S: Supported +W: http://www.openfabrics.org +W: www.open-iscsi.org +Q: http://patchwork.kernel.org/project/linux-rdma/list/ +F: drivers/infiniband/ulp/iser + ISDN SUBSYSTEM M: Karsten Keil <isdn@linux-pingi.de> L: isdn4linux@listserv.isdn4linux.de (subscribers-only) @@ -5524,18 +5535,18 @@ F: Documentation/networking/s2io.txt F: Documentation/networking/vxge.txt F: drivers/net/ethernet/neterion/ -NETFILTER/IPTABLES/IPCHAINS -P: Harald Welte -P: Jozsef Kadlecsik +NETFILTER/IPTABLES M: Pablo Neira Ayuso <pablo@netfilter.org> M: Patrick McHardy <kaber@trash.net> +M: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> L: netfilter-devel@vger.kernel.org L: netfilter@vger.kernel.org L: coreteam@netfilter.org W: http://www.netfilter.org/ W: http://www.iptables.org/ -T: git git://1984.lsi.us.es/nf -T: git git://1984.lsi.us.es/nf-next +Q: http://patchwork.ozlabs.org/project/netfilter-devel/list/ +T: git git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git S: Supported F: include/linux/netfilter* F: include/linux/netfilter/ @@ -5755,7 +5766,7 @@ M: Matthew Wilcox <willy@linux.intel.com> L: linux-nvme@lists.infradead.org T: git git://git.infradead.org/users/willy/linux-nvme.git S: Supported -F: drivers/block/nvme.c +F: drivers/block/nvme* F: include/linux/nvme.h OMAP SUPPORT @@ -6084,9 +6095,18 @@ L: linux-parisc@vger.kernel.org W: http://www.parisc-linux.org/ Q: http://patchwork.kernel.org/project/linux-parisc/list/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/jejb/parisc-2.6.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux.git S: Maintained F: arch/parisc/ +F: Documentation/parisc/ F: drivers/parisc/ +F: drivers/char/agp/parisc-agp.c +F: drivers/input/serio/gscps2.c +F: drivers/parport/parport_gsc.* +F: drivers/tty/serial/8250/8250_gsc.c +F: drivers/video/sti* +F: drivers/video/console/sti* +F: drivers/video/logo/logo_parisc* PC87360 HARDWARE MONITORING DRIVER M: Jim Cromie <jim.cromie@gmail.com> @@ -7604,7 +7624,7 @@ F: drivers/clk/spear/ SPI SUBSYSTEM M: Mark Brown <broonie@kernel.org> M: Grant Likely <grant.likely@linaro.org> -L: spi-devel-general@lists.sourceforge.net +L: linux-spi@vger.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git Q: http://patchwork.kernel.org/project/spi-devel-general/list/ S: Maintained @@ -8984,7 +9004,7 @@ S: Maintained F: drivers/net/wireless/wl3501* WM97XX TOUCHSCREEN DRIVERS -M: Mark Brown <broonie@opensource.wolfsonmicro.com> +M: Mark Brown <broonie@kernel.org> M: Liam Girdwood <lrg@slimlogic.co.uk> L: linux-input@vger.kernel.org T: git git://opensource.wolfsonmicro.com/linux-2.6-touch @@ -8994,7 +9014,6 @@ F: drivers/input/touchscreen/*wm97* F: include/linux/wm97xx.h WOLFSON MICROELECTRONICS DRIVERS -M: Mark Brown <broonie@opensource.wolfsonmicro.com> L: patches@opensource.wolfsonmicro.com T: git git://opensource.wolfsonmicro.com/linux-2.6-asoc T: git git://opensource.wolfsonmicro.com/linux-2.6-audioplus @@ -1,7 +1,7 @@ VERSION = 3 PATCHLEVEL = 10 SUBLEVEL = 0 -EXTRAVERSION = -rc2 +EXTRAVERSION = -rc7 NAME = Unicycling Gorilla # *DOCUMENTATION* diff --git a/arch/arc/boot/dts/abilis_tb100_dvk.dts b/arch/arc/boot/dts/abilis_tb100_dvk.dts index c0fd3623c393..0fa0d4abe795 100644 --- a/arch/arc/boot/dts/abilis_tb100_dvk.dts +++ b/arch/arc/boot/dts/abilis_tb100_dvk.dts @@ -37,7 +37,7 @@ soc100 { uart@FF100000 { - pinctrl-names = "abilis,simple-default"; + pinctrl-names = "default"; pinctrl-0 = <&pctl_uart0>; }; ethernet@FE100000 { diff --git a/arch/arc/boot/dts/abilis_tb101_dvk.dts b/arch/arc/boot/dts/abilis_tb101_dvk.dts index 6f8c381f6268..a4d80ce283ae 100644 --- a/arch/arc/boot/dts/abilis_tb101_dvk.dts +++ b/arch/arc/boot/dts/abilis_tb101_dvk.dts @@ -37,7 +37,7 @@ soc100 { uart@FF100000 { - pinctrl-names = "abilis,simple-default"; + pinctrl-names = "default"; pinctrl-0 = <&pctl_uart0>; }; ethernet@FE100000 { diff --git a/arch/arc/boot/dts/abilis_tb10x.dtsi b/arch/arc/boot/dts/abilis_tb10x.dtsi index a6139fc5aaa3..b97e3051ba4b 100644 --- a/arch/arc/boot/dts/abilis_tb10x.dtsi +++ b/arch/arc/boot/dts/abilis_tb10x.dtsi @@ -88,8 +88,7 @@ }; uart@FF100000 { - compatible = "snps,dw-apb-uart", - "abilis,simple-pinctrl"; + compatible = "snps,dw-apb-uart"; reg = <0xFF100000 0x100>; clock-frequency = <166666666>; interrupts = <25 1>; @@ -184,8 +183,7 @@ #address-cells = <1>; #size-cells = <0>; cell-index = <1>; - compatible = "abilis,tb100-spi", - "abilis,simple-pinctrl"; + compatible = "abilis,tb100-spi"; num-cs = <2>; reg = <0xFE011000 0x20>; interrupt-parent = <&tb10x_ictl>; diff --git a/arch/arc/include/asm/cacheflush.h b/arch/arc/include/asm/cacheflush.h index 9f841af41092..ef62682e8d95 100644 --- a/arch/arc/include/asm/cacheflush.h +++ b/arch/arc/include/asm/cacheflush.h @@ -93,14 +93,16 @@ static inline int cache_is_vipt_aliasing(void) #endif } -#define CACHE_COLOR(addr) (((unsigned long)(addr) >> (PAGE_SHIFT)) & 3) +#define CACHE_COLOR(addr) (((unsigned long)(addr) >> (PAGE_SHIFT)) & 1) /* * checks if two addresses (after page aligning) index into same cache set */ #define addr_not_cache_congruent(addr1, addr2) \ +({ \ cache_is_vipt_aliasing() ? \ - (CACHE_COLOR(addr1) != CACHE_COLOR(addr2)) : 0 \ + (CACHE_COLOR(addr1) != CACHE_COLOR(addr2)) : 0; \ +}) #define copy_to_user_page(vma, page, vaddr, dst, src, len) \ do { \ diff --git a/arch/arc/include/asm/page.h b/arch/arc/include/asm/page.h index 374a35514116..ab84bf131fe1 100644 --- a/arch/arc/include/asm/page.h +++ b/arch/arc/include/asm/page.h @@ -19,13 +19,6 @@ #define clear_page(paddr) memset((paddr), 0, PAGE_SIZE) #define copy_page(to, from) memcpy((to), (from), PAGE_SIZE) -#ifndef CONFIG_ARC_CACHE_VIPT_ALIASING - -#define clear_user_page(addr, vaddr, pg) clear_page(addr) -#define copy_user_page(vto, vfrom, vaddr, pg) copy_page(vto, vfrom) - -#else /* VIPT aliasing dcache */ - struct vm_area_struct; struct page; @@ -35,8 +28,6 @@ void copy_user_highpage(struct page *to, struct page *from, unsigned long u_vaddr, struct vm_area_struct *vma); void clear_user_page(void *to, unsigned long u_vaddr, struct page *page); -#endif /* CONFIG_ARC_CACHE_VIPT_ALIASING */ - #undef STRICT_MM_TYPECHECKS #ifdef STRICT_MM_TYPECHECKS diff --git a/arch/arc/include/asm/pgtable.h b/arch/arc/include/asm/pgtable.h index 1cc4720faccb..95b1522212a7 100644 --- a/arch/arc/include/asm/pgtable.h +++ b/arch/arc/include/asm/pgtable.h @@ -57,9 +57,9 @@ #define _PAGE_ACCESSED (1<<1) /* Page is accessed (S) */ #define _PAGE_CACHEABLE (1<<2) /* Page is cached (H) */ -#define _PAGE_EXECUTE (1<<3) /* Page has user execute perm (H) */ -#define _PAGE_WRITE (1<<4) /* Page has user write perm (H) */ -#define _PAGE_READ (1<<5) /* Page has user read perm (H) */ +#define _PAGE_U_EXECUTE (1<<3) /* Page has user execute perm (H) */ +#define _PAGE_U_WRITE (1<<4) /* Page has user write perm (H) */ +#define _PAGE_U_READ (1<<5) /* Page has user read perm (H) */ #define _PAGE_K_EXECUTE (1<<6) /* Page has kernel execute perm (H) */ #define _PAGE_K_WRITE (1<<7) /* Page has kernel write perm (H) */ #define _PAGE_K_READ (1<<8) /* Page has kernel perm (H) */ @@ -72,9 +72,9 @@ /* PD1 */ #define _PAGE_CACHEABLE (1<<0) /* Page is cached (H) */ -#define _PAGE_EXECUTE (1<<1) /* Page has user execute perm (H) */ -#define _PAGE_WRITE (1<<2) /* Page has user write perm (H) */ -#define _PAGE_READ (1<<3) /* Page has user read perm (H) */ +#define _PAGE_U_EXECUTE (1<<1) /* Page has user execute perm (H) */ +#define _PAGE_U_WRITE (1<<2) /* Page has user write perm (H) */ +#define _PAGE_U_READ (1<<3) /* Page has user read perm (H) */ #define _PAGE_K_EXECUTE (1<<4) /* Page has kernel execute perm (H) */ #define _PAGE_K_WRITE (1<<5) /* Page has kernel write perm (H) */ #define _PAGE_K_READ (1<<6) /* Page has kernel perm (H) */ @@ -93,7 +93,8 @@ #endif /* Kernel allowed all permissions for all pages */ -#define _K_PAGE_PERMS (_PAGE_K_EXECUTE | _PAGE_K_WRITE | _PAGE_K_READ) +#define _K_PAGE_PERMS (_PAGE_K_EXECUTE | _PAGE_K_WRITE | _PAGE_K_READ | \ + _PAGE_GLOBAL | _PAGE_PRESENT) #ifdef CONFIG_ARC_CACHE_PAGES #define _PAGE_DEF_CACHEABLE _PAGE_CACHEABLE @@ -106,7 +107,11 @@ * -by default cached, unless config otherwise * -present in memory */ -#define ___DEF (_PAGE_PRESENT | _K_PAGE_PERMS | _PAGE_DEF_CACHEABLE) +#define ___DEF (_PAGE_PRESENT | _PAGE_DEF_CACHEABLE) + +#define _PAGE_READ (_PAGE_U_READ | _PAGE_K_READ) +#define _PAGE_WRITE (_PAGE_U_WRITE | _PAGE_K_WRITE) +#define _PAGE_EXECUTE (_PAGE_U_EXECUTE | _PAGE_K_EXECUTE) /* Set of bits not changed in pte_modify */ #define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_MODIFIED) @@ -125,11 +130,10 @@ * kernel vaddr space - visible in all addr spaces, but kernel mode only * Thus Global, all-kernel-access, no-user-access, cached */ -#define PAGE_KERNEL __pgprot(___DEF | _PAGE_GLOBAL) +#define PAGE_KERNEL __pgprot(_K_PAGE_PERMS | _PAGE_DEF_CACHEABLE) /* ioremap */ -#define PAGE_KERNEL_NO_CACHE __pgprot(_PAGE_PRESENT | _K_PAGE_PERMS | \ - _PAGE_GLOBAL) +#define PAGE_KERNEL_NO_CACHE __pgprot(_K_PAGE_PERMS) /************************************************************************** * Mapping of vm_flags (Generic VM) to PTE flags (arch specific) diff --git a/arch/arc/include/asm/tlb.h b/arch/arc/include/asm/tlb.h index 85b6df839bd7..cb0c708ca665 100644 --- a/arch/arc/include/asm/tlb.h +++ b/arch/arc/include/asm/tlb.h @@ -16,7 +16,7 @@ /* Masks for actual TLB "PD"s */ #define PTE_BITS_IN_PD0 (_PAGE_GLOBAL | _PAGE_PRESENT) #define PTE_BITS_IN_PD1 (PAGE_MASK | _PAGE_CACHEABLE | \ - _PAGE_EXECUTE | _PAGE_WRITE | _PAGE_READ | \ + _PAGE_U_EXECUTE | _PAGE_U_WRITE | _PAGE_U_READ | \ _PAGE_K_EXECUTE | _PAGE_K_WRITE | _PAGE_K_READ) #ifndef __ASSEMBLY__ diff --git a/arch/arc/mm/cache_arc700.c b/arch/arc/mm/cache_arc700.c index 2f12bca8aef3..aedce1905441 100644 --- a/arch/arc/mm/cache_arc700.c +++ b/arch/arc/mm/cache_arc700.c @@ -610,7 +610,7 @@ void __sync_icache_dcache(unsigned long paddr, unsigned long vaddr, int len) local_irq_save(flags); __ic_line_inv_vaddr(paddr, vaddr, len); - __dc_line_op(paddr, vaddr, len, OP_FLUSH); + __dc_line_op(paddr, vaddr, len, OP_FLUSH_N_INV); local_irq_restore(flags); } @@ -676,6 +676,17 @@ void flush_cache_range(struct vm_area_struct *vma, unsigned long start, flush_cache_all(); } +void flush_anon_page(struct vm_area_struct *vma, struct page *page, + unsigned long u_vaddr) +{ + /* TBD: do we really need to clear the kernel mapping */ + __flush_dcache_page(page_address(page), u_vaddr); + __flush_dcache_page(page_address(page), page_address(page)); + +} + +#endif + void copy_user_highpage(struct page *to, struct page *from, unsigned long u_vaddr, struct vm_area_struct *vma) { @@ -725,16 +736,6 @@ void clear_user_page(void *to, unsigned long u_vaddr, struct page *page) set_bit(PG_arch_1, &page->flags); } -void flush_anon_page(struct vm_area_struct *vma, struct page *page, - unsigned long u_vaddr) -{ - /* TBD: do we really need to clear the kernel mapping */ - __flush_dcache_page(page_address(page), u_vaddr); - __flush_dcache_page(page_address(page), page_address(page)); - -} - -#endif /********************************************************************** * Explicit Cache flush request from user space via syscall diff --git a/arch/arc/mm/tlb.c b/arch/arc/mm/tlb.c index 066145b5f348..fe1c5a073afe 100644 --- a/arch/arc/mm/tlb.c +++ b/arch/arc/mm/tlb.c @@ -444,7 +444,8 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long vaddr_unaligned, * so userspace sees the right data. * (Avoids the flush for Non-exec + congruent mapping case) */ - if (vma->vm_flags & VM_EXEC || addr_not_cache_congruent(paddr, vaddr)) { + if ((vma->vm_flags & VM_EXEC) || + addr_not_cache_congruent(paddr, vaddr)) { struct page *page = pfn_to_page(pte_pfn(*ptep)); int dirty = test_and_clear_bit(PG_arch_1, &page->flags); diff --git a/arch/arc/mm/tlbex.S b/arch/arc/mm/tlbex.S index 9df765dc7c3a..3357d26ffe54 100644 --- a/arch/arc/mm/tlbex.S +++ b/arch/arc/mm/tlbex.S @@ -277,7 +277,7 @@ ARC_ENTRY EV_TLBMissI ;---------------------------------------------------------------- ; VERIFY_PTE: Check if PTE permissions approp for executing code cmp_s r2, VMALLOC_START - mov.lo r2, (_PAGE_PRESENT | _PAGE_READ | _PAGE_EXECUTE) + mov.lo r2, (_PAGE_PRESENT | _PAGE_U_READ | _PAGE_U_EXECUTE) mov.hs r2, (_PAGE_PRESENT | _PAGE_K_READ | _PAGE_K_EXECUTE) and r3, r0, r2 ; Mask out NON Flag bits from PTE @@ -320,9 +320,9 @@ ARC_ENTRY EV_TLBMissD mov_s r2, 0 lr r3, [ecr] btst_s r3, ECR_C_BIT_DTLB_LD_MISS ; Read Access - or.nz r2, r2, _PAGE_READ ; chk for Read flag in PTE + or.nz r2, r2, _PAGE_U_READ ; chk for Read flag in PTE btst_s r3, ECR_C_BIT_DTLB_ST_MISS ; Write Access - or.nz r2, r2, _PAGE_WRITE ; chk for Write flag in PTE + or.nz r2, r2, _PAGE_U_WRITE ; chk for Write flag in PTE ; Above laddering takes care of XCHG access ; which is both Read and Write diff --git a/arch/arc/plat-tb10x/tb10x.c b/arch/arc/plat-tb10x/tb10x.c index d3567691c7e1..06cb30929460 100644 --- a/arch/arc/plat-tb10x/tb10x.c +++ b/arch/arc/plat-tb10x/tb10x.c @@ -34,31 +34,6 @@ static void __init tb10x_platform_init(void) of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); } -static void __init tb10x_platform_late_init(void) -{ - struct device_node *dn; - - /* - * Pinctrl documentation recommends setting up the iomux here for - * all modules which don't require control over the pins themselves. - * Modules which need this kind of assistance are compatible with - * "abilis,simple-pinctrl", i.e. we can easily iterate over them. - * TODO: Does this recommended method work cleanly with pins required - * by modules? - */ - for_each_compatible_node(dn, NULL, "abilis,simple-pinctrl") { - struct platform_device *pd = of_find_device_by_node(dn); - struct pinctrl *pctl; - - pctl = pinctrl_get_select(&pd->dev, "abilis,simple-default"); - if (IS_ERR(pctl)) { - int ret = PTR_ERR(pctl); - dev_err(&pd->dev, "Could not set up pinctrl: %d\n", - ret); - } - } -} - static const char *tb10x_compat[] __initdata = { "abilis,arc-tb10x", NULL, @@ -67,5 +42,4 @@ static const char *tb10x_compat[] __initdata = { MACHINE_START(TB10x, "tb10x") .dt_compat = tb10x_compat, .init_machine = tb10x_platform_init, - .init_late = tb10x_platform_late_init, MACHINE_END diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 49d993cee512..2651b1da1c56 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1189,6 +1189,16 @@ config PL310_ERRATA_588369 is not correctly implemented in PL310 as clean lines are not invalidated as a result of these operations. +config ARM_ERRATA_643719 + bool "ARM errata: LoUIS bit field in CLIDR register is incorrect" + depends on CPU_V7 && SMP + help + This option enables the workaround for the 643719 Cortex-A9 (prior to + r1p0) erratum. On affected cores the LoUIS bit field of the CLIDR + register returns zero when it should return one. The workaround + corrects this value, ensuring cache maintenance operations which use + it behave as intended and avoiding data corruption. + config ARM_ERRATA_720789 bool "ARM errata: TLBIASIDIS and TLBIMVAIS operations can broadcast a faulty ASID" depends on CPU_V7 @@ -2006,7 +2016,7 @@ config XIP_PHYS_ADDR config KEXEC bool "Kexec system call (EXPERIMENTAL)" - depends on (!SMP || HOTPLUG_CPU) + depends on (!SMP || PM_SLEEP_SMP) help kexec is a system call that implements the ability to shutdown your current kernel, and to start another kernel. It is like a reboot diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index 3580d57ea218..120b83bfde20 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile @@ -116,7 +116,8 @@ targets := vmlinux vmlinux.lds \ # Make sure files are removed during clean extra-y += piggy.gzip piggy.lzo piggy.lzma piggy.xzkern \ - lib1funcs.S ashldi3.S $(libfdt) $(libfdt_hdrs) + lib1funcs.S ashldi3.S $(libfdt) $(libfdt_hdrs) \ + hyp-stub.S ifeq ($(CONFIG_FUNCTION_TRACER),y) ORIG_CFLAGS := $(KBUILD_CFLAGS) @@ -124,7 +125,7 @@ KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS)) endif ccflags-y := -fpic -mno-single-pic-base -fno-builtin -I$(obj) -asflags-y := -Wa,-march=all -DZIMAGE +asflags-y := -DZIMAGE # Supply kernel BSS size to the decompressor via a linker symbol. KBSS_SZ = $(shell $(CROSS_COMPILE)size $(obj)/../../../../vmlinux | \ diff --git a/arch/arm/boot/compressed/debug.S b/arch/arm/boot/compressed/debug.S index 6e8382d5b7a4..5392ee63338f 100644 --- a/arch/arm/boot/compressed/debug.S +++ b/arch/arm/boot/compressed/debug.S @@ -1,6 +1,8 @@ #include <linux/linkage.h> #include <asm/assembler.h> +#ifndef CONFIG_DEBUG_SEMIHOSTING + #include CONFIG_DEBUG_LL_INCLUDE ENTRY(putc) @@ -10,3 +12,29 @@ ENTRY(putc) busyuart r3, r1 mov pc, lr ENDPROC(putc) + +#else + +ENTRY(putc) + adr r1, 1f + ldmia r1, {r2, r3} + add r2, r2, r1 + ldr r1, [r2, r3] + strb r0, [r1] + mov r0, #0x03 @ SYS_WRITEC + ARM( svc #0x123456 ) + THUMB( svc #0xab ) + mov pc, lr + .align 2 +1: .word _GLOBAL_OFFSET_TABLE_ - . + .word semi_writec_buf(GOT) +ENDPROC(putc) + + .bss + .global semi_writec_buf + .type semi_writec_buf, %object +semi_writec_buf: + .space 4 + .size semi_writec_buf, 4 + +#endif diff --git a/arch/arm/boot/compressed/head-sa1100.S b/arch/arm/boot/compressed/head-sa1100.S index 6179d94dd5c6..3115e313d9f6 100644 --- a/arch/arm/boot/compressed/head-sa1100.S +++ b/arch/arm/boot/compressed/head-sa1100.S @@ -11,6 +11,7 @@ #include <asm/mach-types.h> .section ".start", "ax" + .arch armv4 __SA1100_start: diff --git a/arch/arm/boot/compressed/head-shark.S b/arch/arm/boot/compressed/head-shark.S index 089c560e07f1..92b56897ed64 100644 --- a/arch/arm/boot/compressed/head-shark.S +++ b/arch/arm/boot/compressed/head-shark.S @@ -18,6 +18,7 @@ .section ".start", "ax" + .arch armv4 b __beginning __ofw_data: .long 0 @ the number of memory blocks diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index fe4d9c3ad761..032a8d987148 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -11,6 +11,7 @@ #include <linux/linkage.h> #include <asm/assembler.h> + .arch armv7-a /* * Debugging stuff * @@ -805,8 +806,8 @@ call_cache_fn: adr r12, proc_types .align 2 .type proc_types,#object proc_types: - .word 0x00000000 @ old ARM ID - .word 0x0000f000 + .word 0x41000000 @ old ARM ID + .word 0xff00f000 mov pc, lr THUMB( nop ) mov pc, lr diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index b9f7121e6ecf..f0895c581a89 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -177,7 +177,9 @@ dtb-$(CONFIG_ARCH_SPEAR3XX)+= spear300-evb.dtb \ spear320-evb.dtb \ spear320-hmi.dtb dtb-$(CONFIG_ARCH_SPEAR6XX)+= spear600-evb.dtb -dtb-$(CONFIG_ARCH_SUNXI) += sun4i-a10-cubieboard.dtb \ +dtb-$(CONFIG_ARCH_SUNXI) += \ + sun4i-a10-cubieboard.dtb \ + sun4i-a10-mini-xplus.dtb \ sun4i-a10-hackberry.dtb \ sun5i-a13-olinuxino.dtb dtb-$(CONFIG_ARCH_TEGRA) += tegra20-harmony.dtb \ diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi index 1460d9b88adf..8e1248f01fab 100644 --- a/arch/arm/boot/dts/am33xx.dtsi +++ b/arch/arm/boot/dts/am33xx.dtsi @@ -409,8 +409,8 @@ ti,hwmods = "gpmc"; reg = <0x50000000 0x2000>; interrupts = <100>; - num-cs = <7>; - num-waitpins = <2>; + gpmc,num-cs = <7>; + gpmc,num-waitpins = <2>; #address-cells = <2>; #size-cells = <1>; status = "disabled"; diff --git a/arch/arm/boot/dts/armada-370-xp.dtsi b/arch/arm/boot/dts/armada-370-xp.dtsi index 272bbc65fab0..550eb772c30e 100644 --- a/arch/arm/boot/dts/armada-370-xp.dtsi +++ b/arch/arm/boot/dts/armada-370-xp.dtsi @@ -33,7 +33,8 @@ #size-cells = <1>; compatible = "simple-bus"; interrupt-parent = <&mpic>; - ranges = <0 0 0xd0000000 0x100000>; + ranges = <0 0 0xd0000000 0x0100000 /* internal registers */ + 0xe0000000 0 0xe0000000 0x8100000 /* PCIe */>; internal-regs { compatible = "simple-bus"; diff --git a/arch/arm/boot/dts/armada-370.dtsi b/arch/arm/boot/dts/armada-370.dtsi index b2c1b5af9749..aee2b1866ce2 100644 --- a/arch/arm/boot/dts/armada-370.dtsi +++ b/arch/arm/boot/dts/armada-370.dtsi @@ -29,7 +29,8 @@ }; soc { - ranges = <0 0xd0000000 0x100000>; + ranges = <0 0xd0000000 0x0100000 /* internal registers */ + 0xe0000000 0xe0000000 0x8100000 /* PCIe */>; internal-regs { system-controller@18200 { compatible = "marvell,armada-370-xp-system-controller"; @@ -38,12 +39,12 @@ L2: l2-cache { compatible = "marvell,aurora-outer-cache"; - reg = <0xd0008000 0x1000>; + reg = <0x08000 0x1000>; cache-id-part = <0x100>; wt-override; }; - mpic: interrupt-controller@20000 { + interrupt-controller@20000 { reg = <0x20a00 0x1d0>, <0x21870 0x58>; }; diff --git a/arch/arm/boot/dts/armada-xp-gp.dts b/arch/arm/boot/dts/armada-xp-gp.dts index 26ad06fc147e..76db557adbe7 100644 --- a/arch/arm/boot/dts/armada-xp-gp.dts +++ b/arch/arm/boot/dts/armada-xp-gp.dts @@ -39,6 +39,10 @@ }; soc { + ranges = <0 0 0xd0000000 0x100000 /* Internal registers 1MiB */ + 0xe0000000 0 0xe0000000 0x8100000 /* PCIe */ + 0xf0000000 0 0xf0000000 0x1000000 /* Device Bus, NOR 16MiB */>; + internal-regs { serial@12000 { clock-frequency = <250000000>; diff --git a/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts b/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts index f14d36c46159..fdea75c73411 100644 --- a/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts +++ b/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts @@ -27,6 +27,10 @@ }; soc { + ranges = <0 0 0xd0000000 0x100000 /* Internal registers 1MiB */ + 0xe0000000 0 0xe0000000 0x8100000 /* PCIe */ + 0xf0000000 0 0xf0000000 0x8000000 /* Device Bus, NOR 128MiB */>; + internal-regs { serial@12000 { clock-frequency = <250000000>; diff --git a/arch/arm/boot/dts/armada-xp.dtsi b/arch/arm/boot/dts/armada-xp.dtsi index bacab11c10dc..5b902f9a3af2 100644 --- a/arch/arm/boot/dts/armada-xp.dtsi +++ b/arch/arm/boot/dts/armada-xp.dtsi @@ -31,7 +31,7 @@ wt-override; }; - mpic: interrupt-controller@20000 { + interrupt-controller@20000 { reg = <0x20a00 0x2d0>, <0x21070 0x58>; }; diff --git a/arch/arm/boot/dts/at91sam9260.dtsi b/arch/arm/boot/dts/at91sam9260.dtsi index 70b5ccbac234..84c4bef2d726 100644 --- a/arch/arm/boot/dts/at91sam9260.dtsi +++ b/arch/arm/boot/dts/at91sam9260.dtsi @@ -264,7 +264,7 @@ atmel,pins = <0 10 0x2 0x0 /* PA10 periph B */ 0 11 0x2 0x0 /* PA11 periph B */ - 0 24 0x2 0x0 /* PA24 periph B */ + 0 22 0x2 0x0 /* PA22 periph B */ 0 25 0x2 0x0 /* PA25 periph B */ 0 26 0x2 0x0 /* PA26 periph B */ 0 27 0x2 0x0 /* PA27 periph B */ diff --git a/arch/arm/boot/dts/at91sam9n12.dtsi b/arch/arm/boot/dts/at91sam9n12.dtsi index 3de8e6dfbcb1..8d25f889928e 100644 --- a/arch/arm/boot/dts/at91sam9n12.dtsi +++ b/arch/arm/boot/dts/at91sam9n12.dtsi @@ -57,6 +57,7 @@ compatible = "atmel,at91rm9200-aic"; interrupt-controller; reg = <0xfffff000 0x200>; + atmel,external-irqs = <31>; }; ramc0: ramc@ffffe800 { diff --git a/arch/arm/boot/dts/at91sam9x25ek.dts b/arch/arm/boot/dts/at91sam9x25ek.dts index 3b40d11d65e7..315250b4995e 100644 --- a/arch/arm/boot/dts/at91sam9x25ek.dts +++ b/arch/arm/boot/dts/at91sam9x25ek.dts @@ -11,7 +11,7 @@ /include/ "at91sam9x5ek.dtsi" / { - model = "Atmel AT91SAM9G25-EK"; + model = "Atmel AT91SAM9X25-EK"; compatible = "atmel,at91sam9x25ek", "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9"; ahb { diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi index f0052dccf9a8..1e12aeff403b 100644 --- a/arch/arm/boot/dts/bcm2835.dtsi +++ b/arch/arm/boot/dts/bcm2835.dtsi @@ -44,6 +44,7 @@ reg = <0x7e201000 0x1000>; interrupts = <2 25>; clock-frequency = <3000000>; + arm,primecell-periphid = <0x00241011>; }; gpio: gpio { diff --git a/arch/arm/boot/dts/exynos5250-pinctrl.dtsi b/arch/arm/boot/dts/exynos5250-pinctrl.dtsi index d1650fb34c0a..ded558bb0f3b 100644 --- a/arch/arm/boot/dts/exynos5250-pinctrl.dtsi +++ b/arch/arm/boot/dts/exynos5250-pinctrl.dtsi @@ -763,7 +763,7 @@ }; }; - pinctrl@03680000 { + pinctrl@03860000 { gpz: gpz { gpio-controller; #gpio-cells = <2>; diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi index 98dfc3ea5c0b..fc9fb3d526e2 100644 --- a/arch/arm/boot/dts/exynos5250.dtsi +++ b/arch/arm/boot/dts/exynos5250.dtsi @@ -161,9 +161,9 @@ interrupts = <0 50 0>; }; - pinctrl_3: pinctrl@03680000 { + pinctrl_3: pinctrl@03860000 { compatible = "samsung,exynos5250-pinctrl"; - reg = <0x0368000 0x1000>; + reg = <0x03860000 0x1000>; interrupts = <0 47 0>; }; @@ -497,6 +497,21 @@ clock-names = "usbhost"; }; + usbphy@12130000 { + compatible = "samsung,exynos5250-usb2phy"; + reg = <0x12130000 0x100>; + clocks = <&clock 1>, <&clock 285>; + clock-names = "ext_xtal", "usbhost"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + usbphy-sys { + reg = <0x10040704 0x8>, + <0x10050230 0x4>; + }; + }; + amba { #address-cells = <1>; #size-cells = <1>; diff --git a/arch/arm/boot/dts/imx25.dtsi b/arch/arm/boot/dts/imx25.dtsi index d2550e0bca24..701153992c69 100644 --- a/arch/arm/boot/dts/imx25.dtsi +++ b/arch/arm/boot/dts/imx25.dtsi @@ -141,8 +141,8 @@ #size-cells = <0>; compatible = "fsl,imx25-cspi", "fsl,imx35-cspi"; reg = <0x43fa4000 0x4000>; - clocks = <&clks 62>; - clock-names = "ipg"; + clocks = <&clks 62>, <&clks 62>; + clock-names = "ipg", "per"; interrupts = <14>; status = "disabled"; }; @@ -182,8 +182,8 @@ compatible = "fsl,imx25-cspi", "fsl,imx35-cspi"; reg = <0x50004000 0x4000>; interrupts = <0>; - clocks = <&clks 80>; - clock-names = "ipg"; + clocks = <&clks 80>, <&clks 80>; + clock-names = "ipg", "per"; status = "disabled"; }; @@ -210,8 +210,8 @@ #size-cells = <0>; compatible = "fsl,imx25-cspi", "fsl,imx35-cspi"; reg = <0x50010000 0x4000>; - clocks = <&clks 79>; - clock-names = "ipg"; + clocks = <&clks 79>, <&clks 79>; + clock-names = "ipg", "per"; interrupts = <13>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/imx27.dtsi b/arch/arm/boot/dts/imx27.dtsi index ff4bd4873edf..75bd11386516 100644 --- a/arch/arm/boot/dts/imx27.dtsi +++ b/arch/arm/boot/dts/imx27.dtsi @@ -131,7 +131,7 @@ compatible = "fsl,imx27-cspi"; reg = <0x1000e000 0x1000>; interrupts = <16>; - clocks = <&clks 53>, <&clks 0>; + clocks = <&clks 53>, <&clks 53>; clock-names = "ipg", "per"; status = "disabled"; }; @@ -142,7 +142,7 @@ compatible = "fsl,imx27-cspi"; reg = <0x1000f000 0x1000>; interrupts = <15>; - clocks = <&clks 52>, <&clks 0>; + clocks = <&clks 52>, <&clks 52>; clock-names = "ipg", "per"; status = "disabled"; }; @@ -223,7 +223,7 @@ compatible = "fsl,imx27-cspi"; reg = <0x10017000 0x1000>; interrupts = <6>; - clocks = <&clks 51>, <&clks 0>; + clocks = <&clks 51>, <&clks 51>; clock-names = "ipg", "per"; status = "disabled"; }; diff --git a/arch/arm/boot/dts/imx51.dtsi b/arch/arm/boot/dts/imx51.dtsi index 21bb786c5b31..53fdde69bbf4 100644 --- a/arch/arm/boot/dts/imx51.dtsi +++ b/arch/arm/boot/dts/imx51.dtsi @@ -631,7 +631,7 @@ compatible = "fsl,imx51-cspi", "fsl,imx35-cspi"; reg = <0x83fc0000 0x4000>; interrupts = <38>; - clocks = <&clks 55>, <&clks 0>; + clocks = <&clks 55>, <&clks 55>; clock-names = "ipg", "per"; status = "disabled"; }; diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi index 845982eaac22..eb83aa039b8b 100644 --- a/arch/arm/boot/dts/imx53.dtsi +++ b/arch/arm/boot/dts/imx53.dtsi @@ -714,7 +714,7 @@ compatible = "fsl,imx53-cspi", "fsl,imx35-cspi"; reg = <0x63fc0000 0x4000>; interrupts = <38>; - clocks = <&clks 55>, <&clks 0>; + clocks = <&clks 55>, <&clks 55>; clock-names = "ipg", "per"; status = "disabled"; }; diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi index 82a404da1c0d..99ba6e14ebf3 100644 --- a/arch/arm/boot/dts/omap3.dtsi +++ b/arch/arm/boot/dts/omap3.dtsi @@ -516,7 +516,7 @@ usb_otg_hs: usb_otg_hs@480ab000 { compatible = "ti,omap3-musb"; reg = <0x480ab000 0x1000>; - interrupts = <0 92 0x4>, <0 93 0x4>; + interrupts = <92>, <93>; interrupt-names = "mc", "dma"; ti,hwmods = "usb_otg_hs"; multipoint = <1>; diff --git a/arch/arm/boot/dts/omap4-panda-common.dtsi b/arch/arm/boot/dts/omap4-panda-common.dtsi index 03bd60deb52b..eeb734e25709 100644 --- a/arch/arm/boot/dts/omap4-panda-common.dtsi +++ b/arch/arm/boot/dts/omap4-panda-common.dtsi @@ -56,9 +56,23 @@ }; }; +&omap4_pmx_wkup { + pinctrl-names = "default"; + pinctrl-0 = < + &twl6030_wkup_pins + >; + + twl6030_wkup_pins: pinmux_twl6030_wkup_pins { + pinctrl-single,pins = < + 0x14 0x2 /* fref_clk0_out.sys_drm_msecure OUTPUT | MODE2 */ + >; + }; +}; + &omap4_pmx_core { pinctrl-names = "default"; pinctrl-0 = < + &twl6030_pins &twl6040_pins &mcpdm_pins &mcbsp1_pins @@ -66,6 +80,12 @@ &tpd12s015_pins >; + twl6030_pins: pinmux_twl6030_pins { + pinctrl-single,pins = < + 0x15e 0x4118 /* sys_nirq1.sys_nirq1 OMAP_WAKEUP_EN | INPUT_PULLUP | MODE0 */ + >; + }; + twl6040_pins: pinmux_twl6040_pins { pinctrl-single,pins = < 0xe0 0x3 /* hdq_sio.gpio_127 OUTPUT | MODE3 */ diff --git a/arch/arm/boot/dts/omap4-sdp.dts b/arch/arm/boot/dts/omap4-sdp.dts index a35d9cd58063..98505a2ef162 100644 --- a/arch/arm/boot/dts/omap4-sdp.dts +++ b/arch/arm/boot/dts/omap4-sdp.dts @@ -142,9 +142,23 @@ }; }; +&omap4_pmx_wkup { + pinctrl-names = "default"; + pinctrl-0 = < + &twl6030_wkup_pins + >; + + twl6030_wkup_pins: pinmux_twl6030_wkup_pins { + pinctrl-single,pins = < + 0x14 0x2 /* fref_clk0_out.sys_drm_msecure OUTPUT | MODE2 */ + >; + }; +}; + &omap4_pmx_core { pinctrl-names = "default"; pinctrl-0 = < + &twl6030_pins &twl6040_pins &mcpdm_pins &dmic_pins @@ -179,6 +193,12 @@ >; }; + twl6030_pins: pinmux_twl6030_pins { + pinctrl-single,pins = < + 0x15e 0x4118 /* sys_nirq1.sys_nirq1 OMAP_WAKEUP_EN | INPUT_PULLUP | MODE0 */ + >; + }; + twl6040_pins: pinmux_twl6040_pins { pinctrl-single,pins = < 0xe0 0x3 /* hdq_sio.gpio_127 OUTPUT | MODE3 */ diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi index 3dd7ff825828..635cae283011 100644 --- a/arch/arm/boot/dts/omap5.dtsi +++ b/arch/arm/boot/dts/omap5.dtsi @@ -538,6 +538,7 @@ interrupts = <0 41 0x4>; ti,hwmods = "timer5"; ti,timer-dsp; + ti,timer-pwm; }; timer6: timer@4013a000 { @@ -574,6 +575,7 @@ reg = <0x4803e000 0x80>; interrupts = <0 45 0x4>; ti,hwmods = "timer9"; + ti,timer-pwm; }; timer10: timer@48086000 { @@ -581,6 +583,7 @@ reg = <0x48086000 0x80>; interrupts = <0 46 0x4>; ti,hwmods = "timer10"; + ti,timer-pwm; }; timer11: timer@48088000 { diff --git a/arch/arm/boot/dts/sama5d3.dtsi b/arch/arm/boot/dts/sama5d3.dtsi index 2e643ea51cce..5000e0d42849 100644 --- a/arch/arm/boot/dts/sama5d3.dtsi +++ b/arch/arm/boot/dts/sama5d3.dtsi @@ -75,11 +75,6 @@ compatible = "atmel,at91sam9x5-spi"; reg = <0xf0004000 0x100>; interrupts = <24 4 3>; - cs-gpios = <&pioD 13 0 - &pioD 14 0 /* conflicts with SCK0 and CANRX0 */ - &pioD 15 0 /* conflicts with CTS0 and CANTX0 */ - &pioD 16 0 /* conflicts with RTS0 and PWMFI3 */ - >; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_spi0>; status = "disabled"; @@ -156,7 +151,7 @@ }; macb0: ethernet@f0028000 { - compatible = "cnds,pc302-gem", "cdns,gem"; + compatible = "cdns,pc302-gem", "cdns,gem"; reg = <0xf0028000 0x100>; interrupts = <34 4 3>; pinctrl-names = "default"; @@ -203,11 +198,6 @@ compatible = "atmel,at91sam9x5-spi"; reg = <0xf8008000 0x100>; interrupts = <25 4 3>; - cs-gpios = <&pioC 25 0 - &pioC 26 0 /* conflitcs with TWD1 and ISI_D11 */ - &pioC 27 0 /* conflitcs with TWCK1 and ISI_D10 */ - &pioC 28 0 /* conflitcs with PWMFI0 and ISI_D9 */ - >; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_spi1>; status = "disabled"; diff --git a/arch/arm/boot/dts/sama5d3xcm.dtsi b/arch/arm/boot/dts/sama5d3xcm.dtsi index 1f8ed404626c..b336e7787cb3 100644 --- a/arch/arm/boot/dts/sama5d3xcm.dtsi +++ b/arch/arm/boot/dts/sama5d3xcm.dtsi @@ -32,6 +32,10 @@ ahb { apb { + spi0: spi@f0004000 { + cs-gpios = <&pioD 13 0>, <0>, <0>, <0>; + }; + macb0: ethernet@f0028000 { phy-mode = "rgmii"; }; diff --git a/arch/arm/boot/dts/ste-nomadik-s8815.dts b/arch/arm/boot/dts/ste-nomadik-s8815.dts index b28fbf3408e3..6f82d9368948 100644 --- a/arch/arm/boot/dts/ste-nomadik-s8815.dts +++ b/arch/arm/boot/dts/ste-nomadik-s8815.dts @@ -14,13 +14,19 @@ bootargs = "root=/dev/ram0 console=ttyAMA1,115200n8 earlyprintk"; }; + /* This is where the interrupt is routed on the S8815 board */ + external-bus@34000000 { + ethernet@300 { + interrupt-parent = <&gpio3>; + interrupts = <8 0x1>; + }; + }; + /* Custom board node with GPIO pins to active etc */ usb-s8815 { /* The S8815 is using this very GPIO pin for the SMSC91x IRQs */ ethernet-gpio { - gpios = <&gpio3 19 0x1>; - interrupts = <19 0x1>; - interrupt-parent = <&gpio3>; + gpios = <&gpio3 8 0x1>; }; /* This will bias the MMC/SD card detect line */ mmcsd-gpio { diff --git a/arch/arm/boot/dts/sun4i-a10-mini-xplus.dts b/arch/arm/boot/dts/sun4i-a10-mini-xplus.dts index 4a7c35d6726a..078ed7f618d7 100644 --- a/arch/arm/boot/dts/sun4i-a10-mini-xplus.dts +++ b/arch/arm/boot/dts/sun4i-a10-mini-xplus.dts @@ -22,8 +22,8 @@ bootargs = "earlyprintk console=ttyS0,115200"; }; - soc { - uart0: uart@01c28000 { + soc@01c20000 { + uart0: serial@01c28000 { pinctrl-names = "default"; pinctrl-0 = <&uart0_pins_a>; status = "okay"; diff --git a/arch/arm/configs/exynos_defconfig b/arch/arm/configs/exynos_defconfig index e40b435d204e..227abf9cc601 100644 --- a/arch/arm/configs/exynos_defconfig +++ b/arch/arm/configs/exynos_defconfig @@ -1,4 +1,4 @@ -CONFIG_EXPERIMENTAL=y +CONFIG_SYSVIPC=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_BLK_DEV_INITRD=y @@ -7,17 +7,18 @@ CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_BLK_DEV_BSG is not set CONFIG_PARTITION_ADVANCED=y -CONFIG_EFI_PARTITION=y CONFIG_ARCH_EXYNOS=y -CONFIG_S3C_LOWLEVEL_UART_PORT=1 +CONFIG_S3C_LOWLEVEL_UART_PORT=3 CONFIG_S3C24XX_PWM=y CONFIG_ARCH_EXYNOS5=y CONFIG_MACH_EXYNOS4_DT=y -CONFIG_MACH_EXYNOS5_DT=y CONFIG_SMP=y CONFIG_NR_CPUS=2 CONFIG_PREEMPT=y CONFIG_AEABI=y +CONFIG_HIGHMEM=y +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 CONFIG_ARM_APPENDED_DTB=y CONFIG_ARM_ATAG_DTB_COMPAT=y CONFIG_CMDLINE="root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC1,115200 init=/linuxrc mem=256M" @@ -30,35 +31,58 @@ CONFIG_NET_KEY=y CONFIG_INET=y CONFIG_RFKILL_REGULATOR=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y CONFIG_PROC_DEVICETREE=y CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_CRYPTOLOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_SG=y +CONFIG_MD=y +CONFIG_BLK_DEV_DM=y +CONFIG_DM_CRYPT=m CONFIG_NETDEVICES=y CONFIG_SMSC911X=y CONFIG_USB_USBNET=y CONFIG_USB_NET_SMSC75XX=y CONFIG_USB_NET_SMSC95XX=y CONFIG_INPUT_EVDEV=y -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set +CONFIG_KEYBOARD_CROS_EC=y +# CONFIG_MOUSE_PS2 is not set +CONFIG_MOUSE_CYAPA=y CONFIG_INPUT_TOUCHSCREEN=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_SAMSUNG=y CONFIG_SERIAL_SAMSUNG_CONSOLE=y CONFIG_SERIAL_OF_PLATFORM=y CONFIG_HW_RANDOM=y +CONFIG_TCG_TPM=y +CONFIG_TCG_TIS_I2C_INFINEON=y CONFIG_I2C=y +CONFIG_I2C_MUX=y +CONFIG_I2C_ARB_GPIO_CHALLENGE=y +CONFIG_I2C_S3C2410=y +CONFIG_DEBUG_GPIO=y # CONFIG_HWMON is not set +CONFIG_MFD_CROS_EC=y +CONFIG_MFD_CROS_EC_I2C=y +CONFIG_MFD_MAX77686=y +CONFIG_MFD_MAX8997=y +CONFIG_MFD_SEC_CORE=y CONFIG_MFD_TPS65090=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_GPIO=y +CONFIG_REGULATOR_MAX8997=y +CONFIG_REGULATOR_MAX77686=y +CONFIG_REGULATOR_S5M8767=y CONFIG_REGULATOR_TPS65090=y CONFIG_FB=y +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_SIMPLE=y CONFIG_EXYNOS_VIDEO=y CONFIG_EXYNOS_MIPI_DSI=y CONFIG_EXYNOS_DP=y @@ -67,6 +91,20 @@ CONFIG_FONTS=y CONFIG_FONT_7x14=y CONFIG_LOGO=y CONFIG_USB=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_S5P=y +CONFIG_USB_STORAGE=y +CONFIG_USB_DWC3=y +CONFIG_USB_PHY=y +CONFIG_SAMSUNG_USB2PHY=y +CONFIG_SAMSUNG_USB3PHY=y +CONFIG_MMC=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_S3C=y +CONFIG_MMC_DW=y +CONFIG_MMC_DW_IDMAC=y +CONFIG_MMC_DW_EXYNOS=y +CONFIG_COMMON_CLK_MAX77686=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y CONFIG_EXT4_FS=y @@ -79,6 +117,7 @@ CONFIG_ROMFS_FS=y CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ASCII=y CONFIG_NLS_ISO8859_1=y +CONFIG_PRINTK_TIME=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y CONFIG_DETECT_HUNG_TASK=y @@ -87,6 +126,5 @@ CONFIG_DEBUG_SPINLOCK=y CONFIG_DEBUG_MUTEXES=y CONFIG_DEBUG_INFO=y CONFIG_DEBUG_USER=y -CONFIG_DEBUG_LL=y -CONFIG_EARLY_PRINTK=y +CONFIG_CRYPTO_SHA256=y CONFIG_CRC_CCITT=y diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig index 435d69b83e32..abbe31937c65 100644 --- a/arch/arm/configs/omap2plus_defconfig +++ b/arch/arm/configs/omap2plus_defconfig @@ -20,6 +20,7 @@ CONFIG_MODULE_FORCE_UNLOAD=y CONFIG_MODVERSIONS=y CONFIG_MODULE_SRCVERSION_ALL=y # CONFIG_BLK_DEV_BSG is not set +CONFIG_ARCH_MULTI_V6=y CONFIG_ARCH_OMAP2PLUS=y CONFIG_OMAP_RESET_CLOCKS=y CONFIG_OMAP_MUX_DEBUG=y diff --git a/arch/arm/configs/tegra_defconfig b/arch/arm/configs/tegra_defconfig index a5f0485133cf..f7ba316164d4 100644 --- a/arch/arm/configs/tegra_defconfig +++ b/arch/arm/configs/tegra_defconfig @@ -153,6 +153,7 @@ CONFIG_MEDIA_CAMERA_SUPPORT=y CONFIG_MEDIA_USB_SUPPORT=y CONFIG_USB_VIDEO_CLASS=m CONFIG_DRM=y +CONFIG_TEGRA_HOST1X=y CONFIG_DRM_TEGRA=y CONFIG_BACKLIGHT_LCD_SUPPORT=y # CONFIG_LCD_CLASS_DEVICE is not set @@ -202,7 +203,7 @@ CONFIG_TEGRA20_APB_DMA=y CONFIG_STAGING=y CONFIG_SENSORS_ISL29018=y CONFIG_SENSORS_ISL29028=y -CONFIG_SENSORS_AK8975=y +CONFIG_AK8975=y CONFIG_MFD_NVEC=y CONFIG_KEYBOARD_NVEC=y CONFIG_SERIO_NVEC_PS2=y diff --git a/arch/arm/crypto/sha1-armv4-large.S b/arch/arm/crypto/sha1-armv4-large.S index 92c6eed7aac9..99207c45ec10 100644 --- a/arch/arm/crypto/sha1-armv4-large.S +++ b/arch/arm/crypto/sha1-armv4-large.S @@ -195,6 +195,7 @@ ENTRY(sha1_block_data_order) add r3,r3,r10 @ E+=F_00_19(B,C,D) cmp r14,sp bne .L_00_15 @ [((11+4)*5+2)*3] + sub sp,sp,#25*4 #if __ARM_ARCH__<7 ldrb r10,[r1,#2] ldrb r9,[r1,#3] @@ -290,7 +291,6 @@ ENTRY(sha1_block_data_order) add r3,r3,r10 @ E+=F_00_19(B,C,D) ldr r8,.LK_20_39 @ [+15+16*4] - sub sp,sp,#25*4 cmn sp,#0 @ [+3], clear carry to denote 20_39 .L_20_39_or_60_79: ldr r9,[r14,#15*4] diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h index bff71388e72a..17d0ae8672fa 100644 --- a/arch/arm/include/asm/cacheflush.h +++ b/arch/arm/include/asm/cacheflush.h @@ -320,9 +320,7 @@ static inline void flush_anon_page(struct vm_area_struct *vma, } #define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE -static inline void flush_kernel_dcache_page(struct page *page) -{ -} +extern void flush_kernel_dcache_page(struct page *); #define flush_dcache_mmap_lock(mapping) \ spin_lock_irq(&(mapping)->tree_lock) diff --git a/arch/arm/include/asm/percpu.h b/arch/arm/include/asm/percpu.h index 968c0a14e0a3..209e6504922e 100644 --- a/arch/arm/include/asm/percpu.h +++ b/arch/arm/include/asm/percpu.h @@ -30,8 +30,15 @@ static inline void set_my_cpu_offset(unsigned long off) static inline unsigned long __my_cpu_offset(void) { unsigned long off; - /* Read TPIDRPRW */ - asm("mrc p15, 0, %0, c13, c0, 4" : "=r" (off) : : "memory"); + register unsigned long *sp asm ("sp"); + + /* + * Read TPIDRPRW. + * We want to allow caching the value, so avoid using volatile and + * instead use a fake stack read to hazard against barrier(). + */ + asm("mrc p15, 0, %0, c13, c0, 4" : "=r" (off) : "Q" (*sp)); + return off; } #define __my_cpu_offset __my_cpu_offset() diff --git a/arch/arm/include/asm/tlb.h b/arch/arm/include/asm/tlb.h index 99a19512ee26..bdf2b8458ec1 100644 --- a/arch/arm/include/asm/tlb.h +++ b/arch/arm/include/asm/tlb.h @@ -33,18 +33,6 @@ #include <asm/pgalloc.h> #include <asm/tlbflush.h> -/* - * We need to delay page freeing for SMP as other CPUs can access pages - * which have been removed but not yet had their TLB entries invalidated. - * Also, as ARMv7 speculative prefetch can drag new entries into the TLB, - * we need to apply this same delaying tactic to ensure correct operation. - */ -#if defined(CONFIG_SMP) || defined(CONFIG_CPU_32v7) -#define tlb_fast_mode(tlb) 0 -#else -#define tlb_fast_mode(tlb) 1 -#endif - #define MMU_GATHER_BUNDLE 8 /* @@ -112,12 +100,10 @@ static inline void __tlb_alloc_page(struct mmu_gather *tlb) static inline void tlb_flush_mmu(struct mmu_gather *tlb) { tlb_flush(tlb); - if (!tlb_fast_mode(tlb)) { - free_pages_and_swap_cache(tlb->pages, tlb->nr); - tlb->nr = 0; - if (tlb->pages == tlb->local) - __tlb_alloc_page(tlb); - } + free_pages_and_swap_cache(tlb->pages, tlb->nr); + tlb->nr = 0; + if (tlb->pages == tlb->local) + __tlb_alloc_page(tlb); } static inline void @@ -178,11 +164,6 @@ tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vma) static inline int __tlb_remove_page(struct mmu_gather *tlb, struct page *page) { - if (tlb_fast_mode(tlb)) { - free_page_and_swap_cache(page); - return 1; /* avoid calling tlb_flush_mmu */ - } - tlb->pages[tlb->nr++] = page; VM_BUG_ON(tlb->nr > tlb->max); return tlb->max - tlb->nr; diff --git a/arch/arm/include/debug/ux500.S b/arch/arm/include/debug/ux500.S index 2848857f5b62..fbd24beeb1fa 100644 --- a/arch/arm/include/debug/ux500.S +++ b/arch/arm/include/debug/ux500.S @@ -24,9 +24,9 @@ #define U8500_UART0_PHYS_BASE (0x80120000) #define U8500_UART1_PHYS_BASE (0x80121000) #define U8500_UART2_PHYS_BASE (0x80007000) -#define U8500_UART0_VIRT_BASE (0xa8120000) -#define U8500_UART1_VIRT_BASE (0xa8121000) -#define U8500_UART2_VIRT_BASE (0xa8007000) +#define U8500_UART0_VIRT_BASE (0xf8120000) +#define U8500_UART1_VIRT_BASE (0xf8121000) +#define U8500_UART2_VIRT_BASE (0xf8007000) #define __UX500_PHYS_UART(n) U8500_UART##n##_PHYS_BASE #define __UX500_VIRT_UART(n) U8500_UART##n##_VIRT_BASE #endif diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c index 8ef8c9337809..4fb074c446bf 100644 --- a/arch/arm/kernel/machine_kexec.c +++ b/arch/arm/kernel/machine_kexec.c @@ -134,6 +134,10 @@ void machine_kexec(struct kimage *image) unsigned long reboot_code_buffer_phys; void *reboot_code_buffer; + if (num_online_cpus() > 1) { + pr_err("kexec: error: multiple CPUs still online\n"); + return; + } page_list = image->head & PAGE_MASK; diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index f21970316836..6e8931ccf13e 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -184,30 +184,61 @@ int __init reboot_setup(char *str) __setup("reboot=", reboot_setup); +/* + * Called by kexec, immediately prior to machine_kexec(). + * + * This must completely disable all secondary CPUs; simply causing those CPUs + * to execute e.g. a RAM-based pin loop is not sufficient. This allows the + * kexec'd kernel to use any and all RAM as it sees fit, without having to + * avoid any code or data used by any SW CPU pin loop. The CPU hotplug + * functionality embodied in disable_nonboot_cpus() to achieve this. + */ void machine_shutdown(void) { -#ifdef CONFIG_SMP - smp_send_stop(); -#endif + disable_nonboot_cpus(); } +/* + * Halting simply requires that the secondary CPUs stop performing any + * activity (executing tasks, handling interrupts). smp_send_stop() + * achieves this. + */ void machine_halt(void) { - machine_shutdown(); + smp_send_stop(); + local_irq_disable(); while (1); } +/* + * Power-off simply requires that the secondary CPUs stop performing any + * activity (executing tasks, handling interrupts). smp_send_stop() + * achieves this. When the system power is turned off, it will take all CPUs + * with it. + */ void machine_power_off(void) { - machine_shutdown(); + smp_send_stop(); + if (pm_power_off) pm_power_off(); } +/* + * Restart requires that the secondary CPUs stop performing any activity + * while the primary CPU resets the system. Systems with a single CPU can + * use soft_restart() as their machine descriptor's .restart hook, since that + * will cause the only available CPU to reset. Systems with multiple CPUs must + * provide a HW restart implementation, to ensure that all CPUs reset at once. + * This is required so that any code running after reset on the primary CPU + * doesn't have to co-ordinate with other CPUs to ensure they aren't still + * executing pre-reset code, and using RAM that the primary CPU's code wishes + * to use. Implementing such co-ordination would be essentially impossible. + */ void machine_restart(char *cmd) { - machine_shutdown(); + smp_send_stop(); arm_pm_restart(reboot_mode, cmd); @@ -411,7 +442,6 @@ static struct vm_area_struct gate_vma = { .vm_start = 0xffff0000, .vm_end = 0xffff0000 + PAGE_SIZE, .vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC, - .vm_mm = &init_mm, }; static int __init gate_vma_init(void) diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 550d63cef68e..5919eb451bb9 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -651,17 +651,6 @@ void smp_send_reschedule(int cpu) smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE); } -#ifdef CONFIG_HOTPLUG_CPU -static void smp_kill_cpus(cpumask_t *mask) -{ - unsigned int cpu; - for_each_cpu(cpu, mask) - platform_cpu_kill(cpu); -} -#else -static void smp_kill_cpus(cpumask_t *mask) { } -#endif - void smp_send_stop(void) { unsigned long timeout; @@ -679,8 +668,6 @@ void smp_send_stop(void) if (num_online_cpus() > 1) pr_warning("SMP: failed to stop secondary CPUs\n"); - - smp_kill_cpus(&mask); } /* diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c index f10316b4ecdc..c5a59546a256 100644 --- a/arch/arm/kernel/topology.c +++ b/arch/arm/kernel/topology.c @@ -13,6 +13,7 @@ #include <linux/cpu.h> #include <linux/cpumask.h> +#include <linux/export.h> #include <linux/init.h> #include <linux/percpu.h> #include <linux/node.h> @@ -200,6 +201,7 @@ static inline void update_cpu_power(unsigned int cpuid, unsigned int mpidr) {} * cpu topology table */ struct cputopo_arm cpu_topology[NR_CPUS]; +EXPORT_SYMBOL_GPL(cpu_topology); const struct cpumask *cpu_coregroup_mask(int cpu) { diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index 37d216d814cd..ef1703b9587b 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c @@ -492,6 +492,11 @@ static void vcpu_pause(struct kvm_vcpu *vcpu) wait_event_interruptible(*wq, !vcpu->arch.pause); } +static int kvm_vcpu_initialized(struct kvm_vcpu *vcpu) +{ + return vcpu->arch.target >= 0; +} + /** * kvm_arch_vcpu_ioctl_run - the main VCPU run function to execute guest code * @vcpu: The VCPU pointer @@ -508,8 +513,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) int ret; sigset_t sigsaved; - /* Make sure they initialize the vcpu with KVM_ARM_VCPU_INIT */ - if (unlikely(vcpu->arch.target < 0)) + if (unlikely(!kvm_vcpu_initialized(vcpu))) return -ENOEXEC; ret = kvm_vcpu_first_run_init(vcpu); @@ -710,6 +714,10 @@ long kvm_arch_vcpu_ioctl(struct file *filp, case KVM_SET_ONE_REG: case KVM_GET_ONE_REG: { struct kvm_one_reg reg; + + if (unlikely(!kvm_vcpu_initialized(vcpu))) + return -ENOEXEC; + if (copy_from_user(®, argp, sizeof(reg))) return -EFAULT; if (ioctl == KVM_SET_ONE_REG) @@ -722,6 +730,9 @@ long kvm_arch_vcpu_ioctl(struct file *filp, struct kvm_reg_list reg_list; unsigned n; + if (unlikely(!kvm_vcpu_initialized(vcpu))) + return -ENOEXEC; + if (copy_from_user(®_list, user_list, sizeof(reg_list))) return -EFAULT; n = reg_list.n; diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c index 965706578f13..84ba67b982c0 100644 --- a/arch/arm/kvm/mmu.c +++ b/arch/arm/kvm/mmu.c @@ -43,7 +43,14 @@ static phys_addr_t hyp_idmap_vector; static void kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa) { - kvm_call_hyp(__kvm_tlb_flush_vmid_ipa, kvm, ipa); + /* + * This function also gets called when dealing with HYP page + * tables. As HYP doesn't have an associated struct kvm (and + * the HYP page tables are fairly static), we don't do + * anything there. + */ + if (kvm) + kvm_call_hyp(__kvm_tlb_flush_vmid_ipa, kvm, ipa); } static int mmu_topup_memory_cache(struct kvm_mmu_memory_cache *cache, @@ -78,18 +85,20 @@ static void *mmu_memory_cache_alloc(struct kvm_mmu_memory_cache *mc) return p; } -static void clear_pud_entry(pud_t *pud) +static void clear_pud_entry(struct kvm *kvm, pud_t *pud, phys_addr_t addr) { pmd_t *pmd_table = pmd_offset(pud, 0); pud_clear(pud); + kvm_tlb_flush_vmid_ipa(kvm, addr); pmd_free(NULL, pmd_table); put_page(virt_to_page(pud)); } -static void clear_pmd_entry(pmd_t *pmd) +static void clear_pmd_entry(struct kvm *kvm, pmd_t *pmd, phys_addr_t addr) { pte_t *pte_table = pte_offset_kernel(pmd, 0); pmd_clear(pmd); + kvm_tlb_flush_vmid_ipa(kvm, addr); pte_free_kernel(NULL, pte_table); put_page(virt_to_page(pmd)); } @@ -100,11 +109,12 @@ static bool pmd_empty(pmd_t *pmd) return page_count(pmd_page) == 1; } -static void clear_pte_entry(pte_t *pte) +static void clear_pte_entry(struct kvm *kvm, pte_t *pte, phys_addr_t addr) { if (pte_present(*pte)) { kvm_set_pte(pte, __pte(0)); put_page(virt_to_page(pte)); + kvm_tlb_flush_vmid_ipa(kvm, addr); } } @@ -114,7 +124,8 @@ static bool pte_empty(pte_t *pte) return page_count(pte_page) == 1; } -static void unmap_range(pgd_t *pgdp, unsigned long long start, u64 size) +static void unmap_range(struct kvm *kvm, pgd_t *pgdp, + unsigned long long start, u64 size) { pgd_t *pgd; pud_t *pud; @@ -138,15 +149,15 @@ static void unmap_range(pgd_t *pgdp, unsigned long long start, u64 size) } pte = pte_offset_kernel(pmd, addr); - clear_pte_entry(pte); + clear_pte_entry(kvm, pte, addr); range = PAGE_SIZE; /* If we emptied the pte, walk back up the ladder */ if (pte_empty(pte)) { - clear_pmd_entry(pmd); + clear_pmd_entry(kvm, pmd, addr); range = PMD_SIZE; if (pmd_empty(pmd)) { - clear_pud_entry(pud); + clear_pud_entry(kvm, pud, addr); range = PUD_SIZE; } } @@ -165,14 +176,14 @@ void free_boot_hyp_pgd(void) mutex_lock(&kvm_hyp_pgd_mutex); if (boot_hyp_pgd) { - unmap_range(boot_hyp_pgd, hyp_idmap_start, PAGE_SIZE); - unmap_range(boot_hyp_pgd, TRAMPOLINE_VA, PAGE_SIZE); + unmap_range(NULL, boot_hyp_pgd, hyp_idmap_start, PAGE_SIZE); + unmap_range(NULL, boot_hyp_pgd, TRAMPOLINE_VA, PAGE_SIZE); kfree(boot_hyp_pgd); boot_hyp_pgd = NULL; } if (hyp_pgd) - unmap_range(hyp_pgd, TRAMPOLINE_VA, PAGE_SIZE); + unmap_range(NULL, hyp_pgd, TRAMPOLINE_VA, PAGE_SIZE); kfree(init_bounce_page); init_bounce_page = NULL; @@ -200,9 +211,10 @@ void free_hyp_pgds(void) if (hyp_pgd) { for (addr = PAGE_OFFSET; virt_addr_valid(addr); addr += PGDIR_SIZE) - unmap_range(hyp_pgd, KERN_TO_HYP(addr), PGDIR_SIZE); + unmap_range(NULL, hyp_pgd, KERN_TO_HYP(addr), PGDIR_SIZE); for (addr = VMALLOC_START; is_vmalloc_addr((void*)addr); addr += PGDIR_SIZE) - unmap_range(hyp_pgd, KERN_TO_HYP(addr), PGDIR_SIZE); + unmap_range(NULL, hyp_pgd, KERN_TO_HYP(addr), PGDIR_SIZE); + kfree(hyp_pgd); hyp_pgd = NULL; } @@ -393,7 +405,7 @@ int kvm_alloc_stage2_pgd(struct kvm *kvm) */ static void unmap_stage2_range(struct kvm *kvm, phys_addr_t start, u64 size) { - unmap_range(kvm->arch.pgd, start, size); + unmap_range(kvm, kvm->arch.pgd, start, size); } /** @@ -675,7 +687,6 @@ static void handle_hva_to_gpa(struct kvm *kvm, static void kvm_unmap_hva_handler(struct kvm *kvm, gpa_t gpa, void *data) { unmap_stage2_range(kvm, gpa, PAGE_SIZE); - kvm_tlb_flush_vmid_ipa(kvm, gpa); } int kvm_unmap_hva(struct kvm *kvm, unsigned long hva) diff --git a/arch/arm/mach-at91/at91rm9200_time.c b/arch/arm/mach-at91/at91rm9200_time.c index 2acdff4c1dfe..180b3024bec3 100644 --- a/arch/arm/mach-at91/at91rm9200_time.c +++ b/arch/arm/mach-at91/at91rm9200_time.c @@ -174,6 +174,7 @@ clkevt32k_next_event(unsigned long delta, struct clock_event_device *dev) static struct clock_event_device clkevt = { .name = "at91_tick", .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, + .shift = 32, .rating = 150, .set_next_event = clkevt32k_next_event, .set_mode = clkevt32k_mode, @@ -264,9 +265,11 @@ void __init at91rm9200_timer_init(void) at91_st_write(AT91_ST_RTMR, 1); /* Setup timer clockevent, with minimum of two ticks (important!!) */ + clkevt.mult = div_sc(AT91_SLOW_CLOCK, NSEC_PER_SEC, clkevt.shift); + clkevt.max_delta_ns = clockevent_delta2ns(AT91_ST_ALMV, &clkevt); + clkevt.min_delta_ns = clockevent_delta2ns(2, &clkevt) + 1; clkevt.cpumask = cpumask_of(0); - clockevents_config_and_register(&clkevt, AT91_SLOW_CLOCK, - 2, AT91_ST_ALMV); + clockevents_register_device(&clkevt); /* register clocksource */ clocksource_register_hz(&clk32k, AT91_SLOW_CLOCK); diff --git a/arch/arm/mach-at91/at91sam9n12.c b/arch/arm/mach-at91/at91sam9n12.c index 13cdbcd48f51..c7d670d11802 100644 --- a/arch/arm/mach-at91/at91sam9n12.c +++ b/arch/arm/mach-at91/at91sam9n12.c @@ -223,13 +223,7 @@ static void __init at91sam9n12_map_io(void) at91_init_sram(0, AT91SAM9N12_SRAM_BASE, AT91SAM9N12_SRAM_SIZE); } -void __init at91sam9n12_initialize(void) -{ - at91_extern_irq = (1 << AT91SAM9N12_ID_IRQ0); -} - AT91_SOC_START(at91sam9n12) .map_io = at91sam9n12_map_io, .register_clocks = at91sam9n12_register_clocks, - .init = at91sam9n12_initialize, AT91_SOC_END diff --git a/arch/arm/mach-at91/include/mach/at91_pmc.h b/arch/arm/mach-at91/include/mach/at91_pmc.h index 31df12029c4e..2bd7f51b0b82 100644 --- a/arch/arm/mach-at91/include/mach/at91_pmc.h +++ b/arch/arm/mach-at91/include/mach/at91_pmc.h @@ -179,9 +179,9 @@ extern void __iomem *at91_pmc_base; #define AT91_PMC_PCR_CMD (0x1 << 12) /* Command (read=0, write=1) */ #define AT91_PMC_PCR_DIV(n) ((n) << 16) /* Divisor Value */ #define AT91_PMC_PCR_DIV0 0x0 /* Peripheral clock is MCK */ -#define AT91_PMC_PCR_DIV2 0x2 /* Peripheral clock is MCK/2 */ -#define AT91_PMC_PCR_DIV4 0x4 /* Peripheral clock is MCK/4 */ -#define AT91_PMC_PCR_DIV8 0x8 /* Peripheral clock is MCK/8 */ +#define AT91_PMC_PCR_DIV2 0x1 /* Peripheral clock is MCK/2 */ +#define AT91_PMC_PCR_DIV4 0x2 /* Peripheral clock is MCK/4 */ +#define AT91_PMC_PCR_DIV8 0x3 /* Peripheral clock is MCK/8 */ #define AT91_PMC_PCR_EN (0x1 << 28) /* Enable */ #endif diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig index d19edff0ea6e..ff18fc2ea46f 100644 --- a/arch/arm/mach-exynos/Kconfig +++ b/arch/arm/mach-exynos/Kconfig @@ -250,6 +250,7 @@ config MACH_ARMLEX4210 config MACH_UNIVERSAL_C210 bool "Mobile UNIVERSAL_C210 Board" select CLKSRC_MMIO + select CLKSRC_SAMSUNG_PWM select CPU_EXYNOS4210 select EXYNOS4_SETUP_FIMC select EXYNOS4_SETUP_FIMD0 @@ -281,7 +282,6 @@ config MACH_UNIVERSAL_C210 select S5P_DEV_TV select S5P_GPIO_INT select S5P_SETUP_MIPIPHY - select SAMSUNG_HRT help Machine support for Samsung Mobile Universal S5PC210 Reference Board. @@ -410,6 +410,7 @@ config MACH_EXYNOS4_DT depends on ARCH_EXYNOS4 select ARM_AMBA select CLKSRC_OF + select CLKSRC_SAMSUNG_PWM if CPU_EXYNOS4210 select CPU_EXYNOS4210 select KEYBOARD_SAMSUNG if INPUT_KEYBOARD select PINCTRL diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c index 745e304ad0de..f7e504b7874d 100644 --- a/arch/arm/mach-exynos/common.c +++ b/arch/arm/mach-exynos/common.c @@ -10,12 +10,14 @@ */ #include <linux/kernel.h> +#include <linux/bitops.h> #include <linux/interrupt.h> #include <linux/irq.h> #include <linux/irqchip.h> #include <linux/io.h> #include <linux/device.h> #include <linux/gpio.h> +#include <clocksource/samsung_pwm.h> #include <linux/sched.h> #include <linux/serial_core.h> #include <linux/of.h> @@ -302,6 +304,13 @@ static struct map_desc exynos5440_iodesc0[] __initdata = { }, }; +static struct samsung_pwm_variant exynos4_pwm_variant = { + .bits = 32, + .div_base = 0, + .has_tint_cstat = true, + .tclk_mask = 0, +}; + void exynos4_restart(char mode, const char *cmd) { __raw_writel(0x1, S5P_SWRESET); @@ -317,9 +326,16 @@ void exynos5_restart(char mode, const char *cmd) val = 0x1; addr = EXYNOS_SWRESET; } else if (of_machine_is_compatible("samsung,exynos5440")) { + u32 status; np = of_find_compatible_node(NULL, NULL, "samsung,exynos5440-clock"); + + addr = of_iomap(np, 0) + 0xbc; + status = __raw_readl(addr); + addr = of_iomap(np, 0) + 0xcc; - val = (0xfff << 20) | (0x1 << 16); + val = __raw_readl(addr); + + val = (val & 0xffff0000) | (status & 0xffff); } else { pr_err("%s: cannot support non-DT\n", __func__); return; @@ -370,6 +386,8 @@ int __init exynos_fdt_map_chipid(unsigned long node, const char *uname, void __init exynos_init_io(struct map_desc *mach_desc, int size) { + debug_ll_io_init(); + #ifdef CONFIG_OF if (initial_boot_params) of_scan_flat_dt(exynos_fdt_map_chipid, NULL); @@ -442,8 +460,20 @@ static void __init exynos5440_map_io(void) iotable_init(exynos5440_iodesc0, ARRAY_SIZE(exynos5440_iodesc0)); } +void __init exynos_set_timer_source(u8 channels) +{ + exynos4_pwm_variant.output_mask = BIT(SAMSUNG_PWM_NUM) - 1; + exynos4_pwm_variant.output_mask &= ~channels; +} + void __init exynos_init_time(void) { + unsigned int timer_irqs[SAMSUNG_PWM_NUM] = { + EXYNOS4_IRQ_TIMER0_VIC, EXYNOS4_IRQ_TIMER1_VIC, + EXYNOS4_IRQ_TIMER2_VIC, EXYNOS4_IRQ_TIMER3_VIC, + EXYNOS4_IRQ_TIMER4_VIC, + }; + if (of_have_populated_dt()) { #ifdef CONFIG_OF of_clk_init(NULL); @@ -455,7 +485,14 @@ void __init exynos_init_time(void) exynos4_clk_init(NULL, !soc_is_exynos4210(), S5P_VA_CMU, readl(S5P_VA_CHIPID + 8) & 1); exynos4_clk_register_fixed_ext(xxti_f, xusbxti_f); #endif - mct_init(S5P_VA_SYSTIMER, EXYNOS4_IRQ_MCT_G0, EXYNOS4_IRQ_MCT_L0, EXYNOS4_IRQ_MCT_L1); +#ifdef CONFIG_CLKSRC_SAMSUNG_PWM + if (soc_is_exynos4210() && samsung_rev() == EXYNOS4210_REV_0) + samsung_pwm_clocksource_init(S3C_VA_TIMER, + timer_irqs, &exynos4_pwm_variant); + else +#endif + mct_init(S5P_VA_SYSTIMER, EXYNOS4_IRQ_MCT_G0, + EXYNOS4_IRQ_MCT_L0, EXYNOS4_IRQ_MCT_L1); } } diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h index 60dd35cc01a6..11fc1e29819b 100644 --- a/arch/arm/mach-exynos/common.h +++ b/arch/arm/mach-exynos/common.h @@ -32,6 +32,8 @@ void exynos4_clk_register_fixed_ext(unsigned long, unsigned long); void exynos_firmware_init(void); +void exynos_set_timer_source(u8 channels); + #ifdef CONFIG_PM_GENERIC_DOMAINS int exynos_pm_late_initcall(void); #else diff --git a/arch/arm/mach-exynos/include/mach/pm-core.h b/arch/arm/mach-exynos/include/mach/pm-core.h index 7dbbfec13ea5..296090e7f423 100644 --- a/arch/arm/mach-exynos/include/mach/pm-core.h +++ b/arch/arm/mach-exynos/include/mach/pm-core.h @@ -18,8 +18,15 @@ #ifndef __ASM_ARCH_PM_CORE_H #define __ASM_ARCH_PM_CORE_H __FILE__ +#include <linux/of.h> #include <mach/regs-pmu.h> +#ifdef CONFIG_PINCTRL_EXYNOS +extern u32 exynos_get_eint_wake_mask(void); +#else +static inline u32 exynos_get_eint_wake_mask(void) { return 0xffffffff; } +#endif + static inline void s3c_pm_debug_init_uart(void) { /* nothing here yet */ @@ -27,7 +34,12 @@ static inline void s3c_pm_debug_init_uart(void) static inline void s3c_pm_arch_prepare_irqs(void) { - __raw_writel(s3c_irqwake_eintmask, S5P_EINT_WAKEUP_MASK); + u32 eintmask = s3c_irqwake_eintmask; + + if (of_have_populated_dt()) + eintmask = exynos_get_eint_wake_mask(); + + __raw_writel(eintmask, S5P_EINT_WAKEUP_MASK); __raw_writel(s3c_irqwake_intmask & ~(1 << 31), S5P_WAKEUP_MASK); } diff --git a/arch/arm/mach-exynos/mach-universal_c210.c b/arch/arm/mach-exynos/mach-universal_c210.c index 327d50d4681d..74ddb2b55614 100644 --- a/arch/arm/mach-exynos/mach-universal_c210.c +++ b/arch/arm/mach-exynos/mach-universal_c210.c @@ -41,7 +41,6 @@ #include <plat/mfc.h> #include <plat/sdhci.h> #include <plat/fimc-core.h> -#include <plat/samsung-time.h> #include <plat/camport.h> #include <mach/map.h> @@ -1094,7 +1093,7 @@ static void __init universal_map_io(void) { exynos_init_io(NULL, 0); s3c24xx_init_uarts(universal_uartcfgs, ARRAY_SIZE(universal_uartcfgs)); - samsung_set_timer_source(SAMSUNG_PWM2, SAMSUNG_PWM4); + exynos_set_timer_source(BIT(2) | BIT(4)); xxti_f = 0; xusbxti_f = 24000000; } @@ -1154,7 +1153,7 @@ MACHINE_START(UNIVERSAL_C210, "UNIVERSAL_C210") .map_io = universal_map_io, .init_machine = universal_machine_init, .init_late = exynos_init_late, - .init_time = samsung_timer_init, + .init_time = exynos_init_time, .reserve = &universal_reserve, .restart = exynos4_restart, MACHINE_END diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index 151259003086..4e3148ce852d 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -177,17 +177,18 @@ int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) static const char *step_sels[] = { "osc", "pll2_pfd2_396m", }; static const char *pll1_sw_sels[] = { "pll1_sys", "step", }; static const char *periph_pre_sels[] = { "pll2_bus", "pll2_pfd2_396m", "pll2_pfd0_352m", "pll2_198m", }; -static const char *periph_clk2_sels[] = { "pll3_usb_otg", "osc", }; +static const char *periph_clk2_sels[] = { "pll3_usb_otg", "osc", "osc", "dummy", }; +static const char *periph2_clk2_sels[] = { "pll3_usb_otg", "pll2_bus", }; static const char *periph_sels[] = { "periph_pre", "periph_clk2", }; static const char *periph2_sels[] = { "periph2_pre", "periph2_clk2", }; -static const char *axi_sels[] = { "periph", "pll2_pfd2_396m", "pll3_pfd1_540m", }; +static const char *axi_sels[] = { "periph", "pll2_pfd2_396m", "periph", "pll3_pfd1_540m", }; static const char *audio_sels[] = { "pll4_post_div", "pll3_pfd2_508m", "pll3_pfd3_454m", "pll3_usb_otg", }; static const char *gpu_axi_sels[] = { "axi", "ahb", }; static const char *gpu2d_core_sels[] = { "axi", "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", }; static const char *gpu3d_core_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd2_396m", }; -static const char *gpu3d_shader_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd9_720m", }; +static const char *gpu3d_shader_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll3_pfd0_720m", }; static const char *ipu_sels[] = { "mmdc_ch0_axi", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", }; -static const char *ldb_di_sels[] = { "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "mmdc_ch1_axi", "pll3_usb_otg", }; +static const char *ldb_di_sels[] = { "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "mmdc_ch1_axi", "pll3_usb_otg", }; static const char *ipu_di_pre_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd1_540m", }; static const char *ipu1_di0_sels[] = { "ipu1_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; static const char *ipu1_di1_sels[] = { "ipu1_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; @@ -369,8 +370,8 @@ int __init mx6q_clocks_init(void) clk[pll1_sw] = imx_clk_mux("pll1_sw", base + 0xc, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels)); clk[periph_pre] = imx_clk_mux("periph_pre", base + 0x18, 18, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels)); clk[periph2_pre] = imx_clk_mux("periph2_pre", base + 0x18, 21, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels)); - clk[periph_clk2_sel] = imx_clk_mux("periph_clk2_sel", base + 0x18, 12, 1, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels)); - clk[periph2_clk2_sel] = imx_clk_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels)); + clk[periph_clk2_sel] = imx_clk_mux("periph_clk2_sel", base + 0x18, 12, 2, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels)); + clk[periph2_clk2_sel] = imx_clk_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels)); clk[axi_sel] = imx_clk_mux("axi_sel", base + 0x14, 6, 2, axi_sels, ARRAY_SIZE(axi_sels)); clk[esai_sel] = imx_clk_mux("esai_sel", base + 0x20, 19, 2, audio_sels, ARRAY_SIZE(audio_sels)); clk[asrc_sel] = imx_clk_mux("asrc_sel", base + 0x30, 7, 2, audio_sels, ARRAY_SIZE(audio_sels)); @@ -498,7 +499,7 @@ int __init mx6q_clocks_init(void) clk[ldb_di1] = imx_clk_gate2("ldb_di1", "ldb_di1_podf", base + 0x74, 14); clk[ipu2_di1] = imx_clk_gate2("ipu2_di1", "ipu2_di1_sel", base + 0x74, 10); clk[hsi_tx] = imx_clk_gate2("hsi_tx", "hsi_tx_podf", base + 0x74, 16); - clk[mlb] = imx_clk_gate2("mlb", "pll8_mlb", base + 0x74, 18); + clk[mlb] = imx_clk_gate2("mlb", "axi", base + 0x74, 18); clk[mmdc_ch0_axi] = imx_clk_gate2("mmdc_ch0_axi", "mmdc_ch0_axi_podf", base + 0x74, 20); clk[mmdc_ch1_axi] = imx_clk_gate2("mmdc_ch1_axi", "mmdc_ch1_axi_podf", base + 0x74, 22); clk[ocram] = imx_clk_gate2("ocram", "ahb", base + 0x74, 28); diff --git a/arch/arm/mach-imx/headsmp.S b/arch/arm/mach-imx/headsmp.S index 67b9c48dcafe..627f16f0e9d1 100644 --- a/arch/arm/mach-imx/headsmp.S +++ b/arch/arm/mach-imx/headsmp.S @@ -18,8 +18,20 @@ .section ".text.head", "ax" #ifdef CONFIG_SMP +diag_reg_offset: + .word g_diag_reg - . + + .macro set_diag_reg + adr r0, diag_reg_offset + ldr r1, [r0] + add r1, r1, r0 @ r1 = physical &g_diag_reg + ldr r0, [r1] + mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register + .endm + ENTRY(v7_secondary_startup) bl v7_invalidate_l1 + set_diag_reg b secondary_startup ENDPROC(v7_secondary_startup) #endif diff --git a/arch/arm/mach-imx/platsmp.c b/arch/arm/mach-imx/platsmp.c index 4a69305db65e..c6e1ab544882 100644 --- a/arch/arm/mach-imx/platsmp.c +++ b/arch/arm/mach-imx/platsmp.c @@ -12,6 +12,7 @@ #include <linux/init.h> #include <linux/smp.h> +#include <asm/cacheflush.h> #include <asm/page.h> #include <asm/smp_scu.h> #include <asm/mach/map.h> @@ -21,6 +22,7 @@ #define SCU_STANDBY_ENABLE (1 << 5) +u32 g_diag_reg; static void __iomem *scu_base; static struct map_desc scu_io_desc __initdata = { @@ -80,6 +82,18 @@ void imx_smp_prepare(void) static void __init imx_smp_prepare_cpus(unsigned int max_cpus) { imx_smp_prepare(); + + /* + * The diagnostic register holds the errata bits. Mostly bootloader + * does not bring up secondary cores, so that when errata bits are set + * in bootloader, they are set only for boot cpu. But on a SMP + * configuration, it should be equally done on every single core. + * Read the register from boot cpu here, and will replicate it into + * secondary cores when booting them. + */ + asm("mrc p15, 0, %0, c15, c0, 1" : "=r" (g_diag_reg) : : "cc"); + __cpuc_flush_dcache_area(&g_diag_reg, sizeof(g_diag_reg)); + outer_clean_range(__pa(&g_diag_reg), __pa(&g_diag_reg + 1)); } struct smp_operations imx_smp_ops __initdata = { diff --git a/arch/arm/mach-kirkwood/board-ts219.c b/arch/arm/mach-kirkwood/board-ts219.c index acb0187c7ee1..4695d5f35fc9 100644 --- a/arch/arm/mach-kirkwood/board-ts219.c +++ b/arch/arm/mach-kirkwood/board-ts219.c @@ -41,13 +41,3 @@ void __init qnap_dt_ts219_init(void) pm_power_off = qnap_tsx1x_power_off; } - -/* FIXME: Will not work with DT. Maybe use MPP40_GPIO? */ -static int __init ts219_pci_init(void) -{ - if (machine_is_ts219()) - kirkwood_pcie_init(KW_PCIE0); - - return 0; -} -subsys_initcall(ts219_pci_init); diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index c2cae69e6d2b..f38922897563 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c @@ -528,12 +528,6 @@ void __init kirkwood_init_early(void) { orion_time_set_base(TIMER_VIRT_BASE); - /* - * Some Kirkwood devices allocate their coherent buffers from atomic - * context. Increase size of atomic coherent pool to make sure such - * the allocations won't fail. - */ - init_dma_coherent_pool_size(SZ_1M); mvebu_mbus_init("marvell,kirkwood-mbus", BRIDGE_WINS_BASE, BRIDGE_WINS_SZ, DDR_WINDOW_CPU_BASE, DDR_WINDOW_CPU_SZ); diff --git a/arch/arm/mach-kirkwood/mpp.c b/arch/arm/mach-kirkwood/mpp.c index 827cde42414f..e96fd71abd76 100644 --- a/arch/arm/mach-kirkwood/mpp.c +++ b/arch/arm/mach-kirkwood/mpp.c @@ -22,9 +22,10 @@ static unsigned int __init kirkwood_variant(void) kirkwood_pcie_id(&dev, &rev); - if ((dev == MV88F6281_DEV_ID && rev >= MV88F6281_REV_A0) || - (dev == MV88F6282_DEV_ID)) + if (dev == MV88F6281_DEV_ID && rev >= MV88F6281_REV_A0) return MPP_F6281_MASK; + if (dev == MV88F6282_DEV_ID) + return MPP_F6282_MASK; if (dev == MV88F6192_DEV_ID && rev >= MV88F6192_REV_A0) return MPP_F6192_MASK; if (dev == MV88F6180_DEV_ID) diff --git a/arch/arm/mach-kirkwood/ts219-setup.c b/arch/arm/mach-kirkwood/ts219-setup.c index 283abff90228..e1267d6b468f 100644 --- a/arch/arm/mach-kirkwood/ts219-setup.c +++ b/arch/arm/mach-kirkwood/ts219-setup.c @@ -124,7 +124,7 @@ static void __init qnap_ts219_init(void) static int __init ts219_pci_init(void) { if (machine_is_ts219()) - kirkwood_pcie_init(KW_PCIE0); + kirkwood_pcie_init(KW_PCIE1 | KW_PCIE0); return 0; } diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig index e11acbb0a46d..80a8bcacd9d5 100644 --- a/arch/arm/mach-mvebu/Kconfig +++ b/arch/arm/mach-mvebu/Kconfig @@ -15,6 +15,7 @@ config ARCH_MVEBU select MVEBU_CLK_GATING select MVEBU_MBUS select ZONE_DMA if ARM_LPAE + select ARCH_REQUIRE_GPIOLIB if ARCH_MVEBU diff --git a/arch/arm/mach-mvebu/armada-370-xp.c b/arch/arm/mach-mvebu/armada-370-xp.c index 42a4cb3087e2..1c48890bb72b 100644 --- a/arch/arm/mach-mvebu/armada-370-xp.c +++ b/arch/arm/mach-mvebu/armada-370-xp.c @@ -54,13 +54,6 @@ void __init armada_370_xp_init_early(void) char *mbus_soc_name; /* - * Some Armada 370/XP devices allocate their coherent buffers - * from atomic context. Increase size of atomic coherent pool - * to make sure such the allocations won't fail. - */ - init_dma_coherent_pool_size(SZ_1M); - - /* * This initialization will be replaced by a DT-based * initialization once the mvebu-mbus driver gains DT support. */ diff --git a/arch/arm/mach-mvebu/coherency_ll.S b/arch/arm/mach-mvebu/coherency_ll.S index 53e8391192cd..5476669ba905 100644 --- a/arch/arm/mach-mvebu/coherency_ll.S +++ b/arch/arm/mach-mvebu/coherency_ll.S @@ -32,15 +32,21 @@ ENTRY(ll_set_cpu_coherent) /* Add CPU to SMP group - Atomic */ add r3, r0, #ARMADA_XP_CFB_CTL_REG_OFFSET - ldr r2, [r3] +1: + ldrex r2, [r3] orr r2, r2, r1 - str r2, [r3] + strex r0, r2, [r3] + cmp r0, #0 + bne 1b /* Enable coherency on CPU - Atomic */ - add r3, r0, #ARMADA_XP_CFB_CFG_REG_OFFSET - ldr r2, [r3] + add r3, r3, #ARMADA_XP_CFB_CFG_REG_OFFSET +1: + ldrex r2, [r3] orr r2, r2, r1 - str r2, [r3] + strex r0, r2, [r3] + cmp r0, #0 + bne 1b dsb diff --git a/arch/arm/mach-omap1/dma.c b/arch/arm/mach-omap1/dma.c index 68ab858e27b7..a94b3a718d1a 100644 --- a/arch/arm/mach-omap1/dma.c +++ b/arch/arm/mach-omap1/dma.c @@ -345,6 +345,7 @@ static int __init omap1_system_dma_init(void) dev_err(&pdev->dev, "%s: Memory allocation failed for d->chan!\n", __func__); + ret = -ENOMEM; goto exit_release_d; } diff --git a/arch/arm/mach-omap2/cclock33xx_data.c b/arch/arm/mach-omap2/cclock33xx_data.c index 6ebc7803bc3e..af3544ce4f02 100644 --- a/arch/arm/mach-omap2/cclock33xx_data.c +++ b/arch/arm/mach-omap2/cclock33xx_data.c @@ -454,9 +454,29 @@ DEFINE_CLK_GATE(cefuse_fck, "sys_clkin_ck", &sys_clkin_ck, 0x0, */ DEFINE_CLK_FIXED_FACTOR(clkdiv32k_ck, "clk_24mhz", &clk_24mhz, 0x0, 1, 732); -DEFINE_CLK_GATE(clkdiv32k_ick, "clkdiv32k_ck", &clkdiv32k_ck, 0x0, - AM33XX_CM_PER_CLKDIV32K_CLKCTRL, AM33XX_MODULEMODE_SWCTRL_SHIFT, - 0x0, NULL); +static struct clk clkdiv32k_ick; + +static const char *clkdiv32k_ick_parent_names[] = { + "clkdiv32k_ck", +}; + +static const struct clk_ops clkdiv32k_ick_ops = { + .enable = &omap2_dflt_clk_enable, + .disable = &omap2_dflt_clk_disable, + .is_enabled = &omap2_dflt_clk_is_enabled, + .init = &omap2_init_clk_clkdm, +}; + +static struct clk_hw_omap clkdiv32k_ick_hw = { + .hw = { + .clk = &clkdiv32k_ick, + }, + .enable_reg = AM33XX_CM_PER_CLKDIV32K_CLKCTRL, + .enable_bit = AM33XX_MODULEMODE_SWCTRL_SHIFT, + .clkdm_name = "clk_24mhz_clkdm", +}; + +DEFINE_STRUCT_CLK(clkdiv32k_ick, clkdiv32k_ick_parent_names, clkdiv32k_ick_ops); /* "usbotg_fck" is an additional clock and not really a modulemode */ DEFINE_CLK_GATE(usbotg_fck, "dpll_per_ck", &dpll_per_ck, 0x0, diff --git a/arch/arm/mach-omap2/clock36xx.c b/arch/arm/mach-omap2/clock36xx.c index 8f3bf4e50908..bbd6a3f717e6 100644 --- a/arch/arm/mach-omap2/clock36xx.c +++ b/arch/arm/mach-omap2/clock36xx.c @@ -20,11 +20,12 @@ #include <linux/kernel.h> #include <linux/clk.h> +#include <linux/clk-provider.h> #include <linux/io.h> #include "clock.h" #include "clock36xx.h" - +#define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw) /** * omap36xx_pwrdn_clk_enable_with_hsdiv_restore - enable clocks suffering @@ -39,29 +40,28 @@ */ int omap36xx_pwrdn_clk_enable_with_hsdiv_restore(struct clk_hw *clk) { - struct clk_hw_omap *parent; + struct clk_divider *parent; struct clk_hw *parent_hw; - u32 dummy_v, orig_v, clksel_shift; + u32 dummy_v, orig_v; int ret; /* Clear PWRDN bit of HSDIVIDER */ ret = omap2_dflt_clk_enable(clk); parent_hw = __clk_get_hw(__clk_get_parent(clk->clk)); - parent = to_clk_hw_omap(parent_hw); + parent = to_clk_divider(parent_hw); /* Restore the dividers */ if (!ret) { - clksel_shift = __ffs(parent->clksel_mask); - orig_v = __raw_readl(parent->clksel_reg); + orig_v = __raw_readl(parent->reg); dummy_v = orig_v; /* Write any other value different from the Read value */ - dummy_v ^= (1 << clksel_shift); - __raw_writel(dummy_v, parent->clksel_reg); + dummy_v ^= (1 << parent->shift); + __raw_writel(dummy_v, parent->reg); /* Write the original divider */ - __raw_writel(orig_v, parent->clksel_reg); + __raw_writel(orig_v, parent->reg); } return ret; diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index d25a95fe9921..7341eff63f56 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -1356,13 +1356,27 @@ static void _enable_sysc(struct omap_hwmod *oh) clkdm = _get_clkdm(oh); if (sf & SYSC_HAS_SIDLEMODE) { + if (oh->flags & HWMOD_SWSUP_SIDLE || + oh->flags & HWMOD_SWSUP_SIDLE_ACT) { + idlemode = HWMOD_IDLEMODE_NO; + } else { + if (sf & SYSC_HAS_ENAWAKEUP) + _enable_wakeup(oh, &v); + if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP) + idlemode = HWMOD_IDLEMODE_SMART_WKUP; + else + idlemode = HWMOD_IDLEMODE_SMART; + } + + /* + * This is special handling for some IPs like + * 32k sync timer. Force them to idle! + */ clkdm_act = (clkdm && clkdm->flags & CLKDM_ACTIVE_WITH_MPU); if (clkdm_act && !(oh->class->sysc->idlemodes & (SIDLE_SMART | SIDLE_SMART_WKUP))) idlemode = HWMOD_IDLEMODE_FORCE; - else - idlemode = (oh->flags & HWMOD_SWSUP_SIDLE) ? - HWMOD_IDLEMODE_NO : HWMOD_IDLEMODE_SMART; + _set_slave_idlemode(oh, idlemode, &v); } @@ -1391,10 +1405,6 @@ static void _enable_sysc(struct omap_hwmod *oh) (sf & SYSC_HAS_CLOCKACTIVITY)) _set_clockactivity(oh, oh->class->sysc->clockact, &v); - /* If slave is in SMARTIDLE, also enable wakeup */ - if ((sf & SYSC_HAS_SIDLEMODE) && !(oh->flags & HWMOD_SWSUP_SIDLE)) - _enable_wakeup(oh, &v); - _write_sysconfig(v, oh); /* @@ -1430,13 +1440,16 @@ static void _idle_sysc(struct omap_hwmod *oh) sf = oh->class->sysc->sysc_flags; if (sf & SYSC_HAS_SIDLEMODE) { - /* XXX What about HWMOD_IDLEMODE_SMART_WKUP? */ - if (oh->flags & HWMOD_SWSUP_SIDLE || - !(oh->class->sysc->idlemodes & - (SIDLE_SMART | SIDLE_SMART_WKUP))) + if (oh->flags & HWMOD_SWSUP_SIDLE) { idlemode = HWMOD_IDLEMODE_FORCE; - else - idlemode = HWMOD_IDLEMODE_SMART; + } else { + if (sf & SYSC_HAS_ENAWAKEUP) + _enable_wakeup(oh, &v); + if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP) + idlemode = HWMOD_IDLEMODE_SMART_WKUP; + else + idlemode = HWMOD_IDLEMODE_SMART; + } _set_slave_idlemode(oh, idlemode, &v); } @@ -1455,10 +1468,6 @@ static void _idle_sysc(struct omap_hwmod *oh) _set_master_standbymode(oh, idlemode, &v); } - /* If slave is in SMARTIDLE, also enable wakeup */ - if ((sf & SYSC_HAS_SIDLEMODE) && !(oh->flags & HWMOD_SWSUP_SIDLE)) - _enable_wakeup(oh, &v); - _write_sysconfig(v, oh); } @@ -2065,7 +2074,7 @@ static int _omap4_get_context_lost(struct omap_hwmod *oh) * do so is present in the hwmod data, then call it and pass along the * return value; otherwise, return 0. */ -static int __init _enable_preprogram(struct omap_hwmod *oh) +static int _enable_preprogram(struct omap_hwmod *oh) { if (!oh->class->enable_preprogram) return 0; @@ -2246,42 +2255,6 @@ static int _idle(struct omap_hwmod *oh) } /** - * omap_hwmod_set_ocp_autoidle - set the hwmod's OCP autoidle bit - * @oh: struct omap_hwmod * - * @autoidle: desired AUTOIDLE bitfield value (0 or 1) - * - * Sets the IP block's OCP autoidle bit in hardware, and updates our - * local copy. Intended to be used by drivers that require - * direct manipulation of the AUTOIDLE bits. - * Returns -EINVAL if @oh is null or is not in the ENABLED state, or passes - * along the return value from _set_module_autoidle(). - * - * Any users of this function should be scrutinized carefully. - */ -int omap_hwmod_set_ocp_autoidle(struct omap_hwmod *oh, u8 autoidle) -{ - u32 v; - int retval = 0; - unsigned long flags; - - if (!oh || oh->_state != _HWMOD_STATE_ENABLED) - return -EINVAL; - - spin_lock_irqsave(&oh->_lock, flags); - - v = oh->_sysc_cache; - - retval = _set_module_autoidle(oh, autoidle, &v); - - if (!retval) - _write_sysconfig(v, oh); - - spin_unlock_irqrestore(&oh->_lock, flags); - - return retval; -} - -/** * _shutdown - shutdown an omap_hwmod * @oh: struct omap_hwmod * * @@ -3180,38 +3153,6 @@ error: } /** - * omap_hwmod_set_slave_idlemode - set the hwmod's OCP slave idlemode - * @oh: struct omap_hwmod * - * @idlemode: SIDLEMODE field bits (shifted to bit 0) - * - * Sets the IP block's OCP slave idlemode in hardware, and updates our - * local copy. Intended to be used by drivers that have some erratum - * that requires direct manipulation of the SIDLEMODE bits. Returns - * -EINVAL if @oh is null, or passes along the return value from - * _set_slave_idlemode(). - * - * XXX Does this function have any current users? If not, we should - * remove it; it is better to let the rest of the hwmod code handle this. - * Any users of this function should be scrutinized carefully. - */ -int omap_hwmod_set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode) -{ - u32 v; - int retval = 0; - - if (!oh) - return -EINVAL; - - v = oh->_sysc_cache; - - retval = _set_slave_idlemode(oh, idlemode, &v); - if (!retval) - _write_sysconfig(v, oh); - - return retval; -} - -/** * omap_hwmod_lookup - look up a registered omap_hwmod by name * @name: name of the omap_hwmod to look up * diff --git a/arch/arm/mach-omap2/omap_hwmod.h b/arch/arm/mach-omap2/omap_hwmod.h index fe5962921f07..0c898f58ac9b 100644 --- a/arch/arm/mach-omap2/omap_hwmod.h +++ b/arch/arm/mach-omap2/omap_hwmod.h @@ -463,6 +463,9 @@ struct omap_hwmod_omap4_prcm { * is kept in force-standby mode. Failing to do so causes PM problems * with musb on OMAP3630 at least. Note that musb has a dedicated register * to control MSTANDBY signal when MIDLEMODE is set to force-standby. + * HWMOD_SWSUP_SIDLE_ACT: omap_hwmod code should manually bring the module + * out of idle, but rely on smart-idle to the put it back in idle, + * so the wakeups are still functional (Only known case for now is UART) */ #define HWMOD_SWSUP_SIDLE (1 << 0) #define HWMOD_SWSUP_MSTANDBY (1 << 1) @@ -476,6 +479,7 @@ struct omap_hwmod_omap4_prcm { #define HWMOD_EXT_OPT_MAIN_CLK (1 << 9) #define HWMOD_BLOCK_WFI (1 << 10) #define HWMOD_FORCE_MSTANDBY (1 << 11) +#define HWMOD_SWSUP_SIDLE_ACT (1 << 12) /* * omap_hwmod._int_flags definitions @@ -641,9 +645,6 @@ int omap_hwmod_read_hardreset(struct omap_hwmod *oh, const char *name); int omap_hwmod_enable_clocks(struct omap_hwmod *oh); int omap_hwmod_disable_clocks(struct omap_hwmod *oh); -int omap_hwmod_set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode); -int omap_hwmod_set_ocp_autoidle(struct omap_hwmod *oh, u8 autoidle); - int omap_hwmod_reset(struct omap_hwmod *oh); void omap_hwmod_ocp_barrier(struct omap_hwmod *oh); diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c index c8c64b3e1acc..d05fc7b54567 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c @@ -512,6 +512,7 @@ struct omap_hwmod omap2xxx_uart1_hwmod = { .mpu_irqs = omap2_uart1_mpu_irqs, .sdma_reqs = omap2_uart1_sdma_reqs, .main_clk = "uart1_fck", + .flags = HWMOD_SWSUP_SIDLE_ACT, .prcm = { .omap2 = { .module_offs = CORE_MOD, @@ -531,6 +532,7 @@ struct omap_hwmod omap2xxx_uart2_hwmod = { .mpu_irqs = omap2_uart2_mpu_irqs, .sdma_reqs = omap2_uart2_sdma_reqs, .main_clk = "uart2_fck", + .flags = HWMOD_SWSUP_SIDLE_ACT, .prcm = { .omap2 = { .module_offs = CORE_MOD, @@ -550,6 +552,7 @@ struct omap_hwmod omap2xxx_uart3_hwmod = { .mpu_irqs = omap2_uart3_mpu_irqs, .sdma_reqs = omap2_uart3_sdma_reqs, .main_clk = "uart3_fck", + .flags = HWMOD_SWSUP_SIDLE_ACT, .prcm = { .omap2 = { .module_offs = CORE_MOD, diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c index 01d8f324450a..69337af748cc 100644 --- a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c @@ -1995,6 +1995,7 @@ static struct omap_hwmod am33xx_uart1_hwmod = { .name = "uart1", .class = &uart_class, .clkdm_name = "l4_wkup_clkdm", + .flags = HWMOD_SWSUP_SIDLE_ACT, .mpu_irqs = am33xx_uart1_irqs, .sdma_reqs = uart1_edma_reqs, .main_clk = "dpll_per_m2_div4_wkupdm_ck", @@ -2006,6 +2007,13 @@ static struct omap_hwmod am33xx_uart1_hwmod = { }, }; +/* uart2 */ +static struct omap_hwmod_dma_info uart2_edma_reqs[] = { + { .name = "tx", .dma_req = 28, }, + { .name = "rx", .dma_req = 29, }, + { .dma_req = -1 } +}; + static struct omap_hwmod_irq_info am33xx_uart2_irqs[] = { { .irq = 73 + OMAP_INTC_START, }, { .irq = -1 }, @@ -2015,8 +2023,9 @@ static struct omap_hwmod am33xx_uart2_hwmod = { .name = "uart2", .class = &uart_class, .clkdm_name = "l4ls_clkdm", + .flags = HWMOD_SWSUP_SIDLE_ACT, .mpu_irqs = am33xx_uart2_irqs, - .sdma_reqs = uart1_edma_reqs, + .sdma_reqs = uart2_edma_reqs, .main_clk = "dpll_per_m2_div4_ck", .prcm = { .omap4 = { @@ -2042,6 +2051,7 @@ static struct omap_hwmod am33xx_uart3_hwmod = { .name = "uart3", .class = &uart_class, .clkdm_name = "l4ls_clkdm", + .flags = HWMOD_SWSUP_SIDLE_ACT, .mpu_irqs = am33xx_uart3_irqs, .sdma_reqs = uart3_edma_reqs, .main_clk = "dpll_per_m2_div4_ck", @@ -2062,6 +2072,7 @@ static struct omap_hwmod am33xx_uart4_hwmod = { .name = "uart4", .class = &uart_class, .clkdm_name = "l4ls_clkdm", + .flags = HWMOD_SWSUP_SIDLE_ACT, .mpu_irqs = am33xx_uart4_irqs, .sdma_reqs = uart1_edma_reqs, .main_clk = "dpll_per_m2_div4_ck", @@ -2082,6 +2093,7 @@ static struct omap_hwmod am33xx_uart5_hwmod = { .name = "uart5", .class = &uart_class, .clkdm_name = "l4ls_clkdm", + .flags = HWMOD_SWSUP_SIDLE_ACT, .mpu_irqs = am33xx_uart5_irqs, .sdma_reqs = uart1_edma_reqs, .main_clk = "dpll_per_m2_div4_ck", @@ -2102,6 +2114,7 @@ static struct omap_hwmod am33xx_uart6_hwmod = { .name = "uart6", .class = &uart_class, .clkdm_name = "l4ls_clkdm", + .flags = HWMOD_SWSUP_SIDLE_ACT, .mpu_irqs = am33xx_uart6_irqs, .sdma_reqs = uart1_edma_reqs, .main_clk = "dpll_per_m2_div4_ck", diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 4083606ea1da..31c7126eb3bb 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -490,6 +490,7 @@ static struct omap_hwmod omap3xxx_uart1_hwmod = { .mpu_irqs = omap2_uart1_mpu_irqs, .sdma_reqs = omap2_uart1_sdma_reqs, .main_clk = "uart1_fck", + .flags = HWMOD_SWSUP_SIDLE_ACT, .prcm = { .omap2 = { .module_offs = CORE_MOD, @@ -508,6 +509,7 @@ static struct omap_hwmod omap3xxx_uart2_hwmod = { .mpu_irqs = omap2_uart2_mpu_irqs, .sdma_reqs = omap2_uart2_sdma_reqs, .main_clk = "uart2_fck", + .flags = HWMOD_SWSUP_SIDLE_ACT, .prcm = { .omap2 = { .module_offs = CORE_MOD, @@ -526,6 +528,7 @@ static struct omap_hwmod omap3xxx_uart3_hwmod = { .mpu_irqs = omap2_uart3_mpu_irqs, .sdma_reqs = omap2_uart3_sdma_reqs, .main_clk = "uart3_fck", + .flags = HWMOD_SWSUP_SIDLE_ACT, .prcm = { .omap2 = { .module_offs = OMAP3430_PER_MOD, @@ -555,6 +558,7 @@ static struct omap_hwmod omap36xx_uart4_hwmod = { .mpu_irqs = uart4_mpu_irqs, .sdma_reqs = uart4_sdma_reqs, .main_clk = "uart4_fck", + .flags = HWMOD_SWSUP_SIDLE_ACT, .prcm = { .omap2 = { .module_offs = OMAP3430_PER_MOD, diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index eaba9dc91a0d..848b6dc67590 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -3434,6 +3434,7 @@ static struct omap_hwmod omap44xx_uart1_hwmod = { .name = "uart1", .class = &omap44xx_uart_hwmod_class, .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_SWSUP_SIDLE_ACT, .mpu_irqs = omap44xx_uart1_irqs, .sdma_reqs = omap44xx_uart1_sdma_reqs, .main_clk = "func_48m_fclk", @@ -3462,6 +3463,7 @@ static struct omap_hwmod omap44xx_uart2_hwmod = { .name = "uart2", .class = &omap44xx_uart_hwmod_class, .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_SWSUP_SIDLE_ACT, .mpu_irqs = omap44xx_uart2_irqs, .sdma_reqs = omap44xx_uart2_sdma_reqs, .main_clk = "func_48m_fclk", @@ -3490,7 +3492,8 @@ static struct omap_hwmod omap44xx_uart3_hwmod = { .name = "uart3", .class = &omap44xx_uart_hwmod_class, .clkdm_name = "l4_per_clkdm", - .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET, + .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET | + HWMOD_SWSUP_SIDLE_ACT, .mpu_irqs = omap44xx_uart3_irqs, .sdma_reqs = omap44xx_uart3_sdma_reqs, .main_clk = "func_48m_fclk", @@ -3519,6 +3522,7 @@ static struct omap_hwmod omap44xx_uart4_hwmod = { .name = "uart4", .class = &omap44xx_uart_hwmod_class, .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_SWSUP_SIDLE_ACT, .mpu_irqs = omap44xx_uart4_irqs, .sdma_reqs = omap44xx_uart4_sdma_reqs, .main_clk = "func_48m_fclk", diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index c01859398b54..5a2d8034c8de 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -546,8 +546,10 @@ static void __init prcm_setup_regs(void) /* Clear any pending PRCM interrupts */ omap2_prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET); - if (omap3_has_iva()) - omap3_iva_idle(); + /* + * We need to idle iva2_pwrdm even on am3703 with no iva2. + */ + omap3_iva_idle(); omap3_d2d_idle(); } diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 8396b5b7e912..f6601563aa69 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -95,38 +95,9 @@ static void omap_uart_enable_wakeup(struct device *dev, bool enable) omap_hwmod_disable_wakeup(od->hwmods[0]); } -/* - * Errata i291: [UART]:Cannot Acknowledge Idle Requests - * in Smartidle Mode When Configured for DMA Operations. - * WA: configure uart in force idle mode. - */ -static void omap_uart_set_noidle(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct omap_device *od = to_omap_device(pdev); - - omap_hwmod_set_slave_idlemode(od->hwmods[0], HWMOD_IDLEMODE_NO); -} - -static void omap_uart_set_smartidle(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct omap_device *od = to_omap_device(pdev); - u8 idlemode; - - if (od->hwmods[0]->class->sysc->idlemodes & SIDLE_SMART_WKUP) - idlemode = HWMOD_IDLEMODE_SMART_WKUP; - else - idlemode = HWMOD_IDLEMODE_SMART; - - omap_hwmod_set_slave_idlemode(od->hwmods[0], idlemode); -} - #else static void omap_uart_enable_wakeup(struct device *dev, bool enable) {} -static void omap_uart_set_noidle(struct device *dev) {} -static void omap_uart_set_smartidle(struct device *dev) {} #endif /* CONFIG_PM */ #ifdef CONFIG_OMAP_MUX @@ -299,8 +270,6 @@ void __init omap_serial_init_port(struct omap_board_data *bdata, omap_up.uartclk = OMAP24XX_BASE_BAUD * 16; omap_up.flags = UPF_BOOT_AUTOCONF; omap_up.get_context_loss_count = omap_pm_get_dev_context_loss_count; - omap_up.set_forceidle = omap_uart_set_smartidle; - omap_up.set_noidle = omap_uart_set_noidle; omap_up.enable_wakeup = omap_uart_enable_wakeup; omap_up.dma_rx_buf_size = info->dma_rx_buf_size; omap_up.dma_rx_timeout = info->dma_rx_timeout; diff --git a/arch/arm/mach-orion5x/common.c b/arch/arm/mach-orion5x/common.c index b97fd672e89d..f8a6db9239bf 100644 --- a/arch/arm/mach-orion5x/common.c +++ b/arch/arm/mach-orion5x/common.c @@ -199,13 +199,6 @@ void __init orion5x_init_early(void) orion_time_set_base(TIMER_VIRT_BASE); - /* - * Some Orion5x devices allocate their coherent buffers from atomic - * context. Increase size of atomic coherent pool to make sure such - * the allocations won't fail. - */ - init_dma_coherent_pool_size(SZ_1M); - /* Initialize the MBUS driver */ orion5x_pcie_id(&dev, &rev); if (dev == MV88F5281_DEV_ID) diff --git a/arch/arm/mach-prima2/pm.c b/arch/arm/mach-prima2/pm.c index 9936c180bf01..8f595c0cc8d9 100644 --- a/arch/arm/mach-prima2/pm.c +++ b/arch/arm/mach-prima2/pm.c @@ -101,8 +101,10 @@ static int __init sirfsoc_of_pwrc_init(void) struct device_node *np; np = of_find_matching_node(NULL, pwrc_ids); - if (!np) - panic("unable to find compatible pwrc node in dtb\n"); + if (!np) { + pr_err("unable to find compatible sirf pwrc node in dtb\n"); + return -ENOENT; + } /* * pwrc behind rtciobrg is not located in memory space diff --git a/arch/arm/mach-prima2/rstc.c b/arch/arm/mach-prima2/rstc.c index 435019ca0a48..d5e0cbc934c0 100644 --- a/arch/arm/mach-prima2/rstc.c +++ b/arch/arm/mach-prima2/rstc.c @@ -28,8 +28,10 @@ static int __init sirfsoc_of_rstc_init(void) struct device_node *np; np = of_find_matching_node(NULL, rstc_ids); - if (!np) - panic("unable to find compatible rstc node in dtb\n"); + if (!np) { + pr_err("unable to find compatible sirf rstc node in dtb\n"); + return -ENOENT; + } sirfsoc_rstc_base = of_iomap(np, 0); if (!sirfsoc_rstc_base) diff --git a/arch/arm/mach-shmobile/board-marzen.c b/arch/arm/mach-shmobile/board-marzen.c index 91052855cc12..b9594e911ce7 100644 --- a/arch/arm/mach-shmobile/board-marzen.c +++ b/arch/arm/mach-shmobile/board-marzen.c @@ -212,8 +212,8 @@ static struct platform_device *marzen_devices[] __initdata = { static struct usb_phy *phy; static int usb_power_on(struct platform_device *pdev) { - if (!phy) - return -EIO; + if (IS_ERR(phy)) + return PTR_ERR(phy); pm_runtime_enable(&pdev->dev); pm_runtime_get_sync(&pdev->dev); @@ -225,7 +225,7 @@ static int usb_power_on(struct platform_device *pdev) static void usb_power_off(struct platform_device *pdev) { - if (!phy) + if (IS_ERR(phy)) return; usb_phy_shutdown(phy); diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c index fdf3894b1cc3..9696f3646864 100644 --- a/arch/arm/mach-shmobile/setup-sh73a0.c +++ b/arch/arm/mach-shmobile/setup-sh73a0.c @@ -252,7 +252,7 @@ static struct sh_timer_config cmt10_platform_data = { .name = "CMT10", .channel_offset = 0x10, .timer_bit = 0, - .clockevent_rating = 125, + .clockevent_rating = 80, .clocksource_rating = 125, }; diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig index d259c782d742..5b045e302b43 100644 --- a/arch/arm/mach-sunxi/Kconfig +++ b/arch/arm/mach-sunxi/Kconfig @@ -1,5 +1,6 @@ config ARCH_SUNXI bool "Allwinner A1X SOCs" if ARCH_MULTI_V7 + select ARCH_REQUIRE_GPIOLIB select CLKSRC_MMIO select CLKSRC_OF select COMMON_CLK diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig index 6a4387e39df8..b19b07204aaf 100644 --- a/arch/arm/mach-ux500/Kconfig +++ b/arch/arm/mach-ux500/Kconfig @@ -51,6 +51,7 @@ config MACH_MOP500 bool "U8500 Development platform, MOP500 versions" select I2C select I2C_NOMADIK + select REGULATOR select REGULATOR_FIXED_VOLTAGE select SOC_BUS select UX500_SOC_DB8500 diff --git a/arch/arm/mach-ux500/board-mop500-regulators.c b/arch/arm/mach-ux500/board-mop500-regulators.c index 33c353bc1c4a..d6b7c8556fa1 100644 --- a/arch/arm/mach-ux500/board-mop500-regulators.c +++ b/arch/arm/mach-ux500/board-mop500-regulators.c @@ -374,6 +374,7 @@ static struct ab8500_regulator_reg_init ab8500_reg_init[] = { static struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = { /* supplies to the display/camera */ [AB8500_LDO_AUX1] = { + .supply_regulator = "ab8500-ext-supply3", .constraints = { .name = "V-DISPLAY", .min_uV = 2800000, @@ -387,6 +388,7 @@ static struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = { }, /* supplies to the on-board eMMC */ [AB8500_LDO_AUX2] = { + .supply_regulator = "ab8500-ext-supply3", .constraints = { .name = "V-eMMC1", .min_uV = 1100000, @@ -402,6 +404,7 @@ static struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = { }, /* supply for VAUX3, supplies to SDcard slots */ [AB8500_LDO_AUX3] = { + .supply_regulator = "ab8500-ext-supply3", .constraints = { .name = "V-MMC-SD", .min_uV = 1100000, diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index 3cd555ac6d0a..78389de94dde 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -623,7 +623,7 @@ static void __init mop500_init_machine(void) sdi0_reg_info.gpios[0].gpio = GPIO_SDMMC_1V8_3V_SEL; mop500_pinmaps_init(); - parent = u8500_init_devices(&ab8500_platdata); + parent = u8500_init_devices(); for (i = 0; i < ARRAY_SIZE(mop500_platform_devs); i++) mop500_platform_devs[i]->dev.parent = parent; @@ -660,7 +660,7 @@ static void __init snowball_init_machine(void) sdi0_reg_info.gpios[0].gpio = SNOWBALL_SDMMC_1V8_3V_GPIO; snowball_pinmaps_init(); - parent = u8500_init_devices(&ab8500_platdata); + parent = u8500_init_devices(); for (i = 0; i < ARRAY_SIZE(snowball_platform_devs); i++) snowball_platform_devs[i]->dev.parent = parent; @@ -698,7 +698,7 @@ static void __init hrefv60_init_machine(void) sdi0_reg_info.gpios[0].gpio = HREFV60_SDMMC_1V8_3V_GPIO; hrefv60_pinmaps_init(); - parent = u8500_init_devices(&ab8500_platdata); + parent = u8500_init_devices(); for (i = 0; i < ARRAY_SIZE(mop500_platform_devs); i++) mop500_platform_devs[i]->dev.parent = parent; diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index e90b5ab23b6d..46cca52890bc 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c @@ -206,7 +206,7 @@ static struct device * __init db8500_soc_device_init(void) /* * This function is called from the board init */ -struct device * __init u8500_init_devices(struct ab8500_platform_data *ab8500) +struct device * __init u8500_init_devices(void) { struct device *parent; int i; @@ -220,8 +220,6 @@ struct device * __init u8500_init_devices(struct ab8500_platform_data *ab8500) for (i = 0; i < ARRAY_SIZE(platform_devs); i++) platform_devs[i]->dev.parent = parent; - db8500_prcmu_device.dev.platform_data = ab8500; - platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); return parent; @@ -278,7 +276,7 @@ static struct of_dev_auxdata u8500_auxdata_lookup[] __initdata = { OF_DEV_AUXDATA("st,nomadik-i2c", 0x8012a000, "nmk-i2c.4", NULL), OF_DEV_AUXDATA("stericsson,db8500-prcmu", 0x80157000, "db8500-prcmu", &db8500_prcmu_pdata), - OF_DEV_AUXDATA("smsc,lan9115", 0x50000000, "smsc911x", NULL), + OF_DEV_AUXDATA("smsc,lan9115", 0x50000000, "smsc911x.0", NULL), /* Requires device name bindings. */ OF_DEV_AUXDATA("stericsson,nmk-pinctrl", U8500_PRCMU_BASE, "pinctrl-db8500", NULL), diff --git a/arch/arm/mach-ux500/cpuidle.c b/arch/arm/mach-ux500/cpuidle.c index 317a2be129fb..a45dd09daed9 100644 --- a/arch/arm/mach-ux500/cpuidle.c +++ b/arch/arm/mach-ux500/cpuidle.c @@ -21,6 +21,7 @@ #include <asm/proc-fns.h> #include "db8500-regs.h" +#include "id.h" static atomic_t master = ATOMIC_INIT(0); static DEFINE_SPINLOCK(master_lock); @@ -114,6 +115,9 @@ static struct cpuidle_driver ux500_idle_driver = { int __init ux500_idle_init(void) { + if (!(cpu_is_u8500_family() || cpu_is_ux540_family())) + return -ENODEV; + /* Configure wake up reasons */ prcmu_enable_wakeups(PRCMU_WAKEUP(ARM) | PRCMU_WAKEUP(RTC) | PRCMU_WAKEUP(ABB)); diff --git a/arch/arm/mach-ux500/setup.h b/arch/arm/mach-ux500/setup.h index bddce2b49372..cad3ca86c540 100644 --- a/arch/arm/mach-ux500/setup.h +++ b/arch/arm/mach-ux500/setup.h @@ -18,7 +18,7 @@ void __init ux500_map_io(void); extern void __init u8500_map_io(void); -extern struct device * __init u8500_init_devices(struct ab8500_platform_data *ab8500); +extern struct device * __init u8500_init_devices(void); extern void __init ux500_init_irq(void); extern void __init ux500_init_late(void); diff --git a/arch/arm/mach-vt8500/vt8500.c b/arch/arm/mach-vt8500/vt8500.c index 1dd281efc020..f5c33df7a597 100644 --- a/arch/arm/mach-vt8500/vt8500.c +++ b/arch/arm/mach-vt8500/vt8500.c @@ -173,6 +173,7 @@ static const char * const vt8500_dt_compat[] = { "wm,wm8505", "wm,wm8750", "wm,wm8850", + NULL }; DT_MACHINE_START(WMT_DT, "VIA/Wondermedia SoC (Device Tree Support)") diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S index 15451ee4acc8..515b00064da8 100644 --- a/arch/arm/mm/cache-v7.S +++ b/arch/arm/mm/cache-v7.S @@ -92,6 +92,14 @@ ENTRY(v7_flush_dcache_louis) mrc p15, 1, r0, c0, c0, 1 @ read clidr, r0 = clidr ALT_SMP(ands r3, r0, #(7 << 21)) @ extract LoUIS from clidr ALT_UP(ands r3, r0, #(7 << 27)) @ extract LoUU from clidr +#ifdef CONFIG_ARM_ERRATA_643719 + ALT_SMP(mrceq p15, 0, r2, c0, c0, 0) @ read main ID register + ALT_UP(moveq pc, lr) @ LoUU is zero, so nothing to do + ldreq r1, =0x410fc090 @ ID of ARM Cortex A9 r0p? + biceq r2, r2, #0x0000000f @ clear minor revision number + teqeq r2, r1 @ test for errata affected core and if so... + orreqs r3, #(1 << 21) @ fix LoUIS value (and set flags state to 'ne') +#endif ALT_SMP(mov r3, r3, lsr #20) @ r3 = LoUIS * 2 ALT_UP(mov r3, r3, lsr #26) @ r3 = LoUU * 2 moveq pc, lr @ return if level == 0 diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c index 0d473cce501c..32aa5861119f 100644 --- a/arch/arm/mm/flush.c +++ b/arch/arm/mm/flush.c @@ -301,6 +301,39 @@ void flush_dcache_page(struct page *page) EXPORT_SYMBOL(flush_dcache_page); /* + * Ensure cache coherency for the kernel mapping of this page. We can + * assume that the page is pinned via kmap. + * + * If the page only exists in the page cache and there are no user + * space mappings, this is a no-op since the page was already marked + * dirty at creation. Otherwise, we need to flush the dirty kernel + * cache lines directly. + */ +void flush_kernel_dcache_page(struct page *page) +{ + if (cache_is_vivt() || cache_is_vipt_aliasing()) { + struct address_space *mapping; + + mapping = page_mapping(page); + + if (!mapping || mapping_mapped(mapping)) { + void *addr; + + addr = page_address(page); + /* + * kmap_atomic() doesn't set the page virtual + * address for highmem pages, and + * kunmap_atomic() takes care of cache + * flushing already. + */ + if (!IS_ENABLED(CONFIG_HIGHMEM) || addr) + __cpuc_flush_dcache_area(addr, PAGE_SIZE); + } + } +} +EXPORT_SYMBOL(flush_kernel_dcache_page); + +/* * Flush an anonymous page so that users of get_user_pages() * can safely access the data. The expected sequence is: * diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index e0d8565671a6..4d409e6a552d 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -616,10 +616,12 @@ static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr, } while (pte++, addr += PAGE_SIZE, addr != end); } -static void __init map_init_section(pmd_t *pmd, unsigned long addr, +static void __init __map_init_section(pmd_t *pmd, unsigned long addr, unsigned long end, phys_addr_t phys, const struct mem_type *type) { + pmd_t *p = pmd; + #ifndef CONFIG_ARM_LPAE /* * In classic MMU format, puds and pmds are folded in to @@ -638,7 +640,7 @@ static void __init map_init_section(pmd_t *pmd, unsigned long addr, phys += SECTION_SIZE; } while (pmd++, addr += SECTION_SIZE, addr != end); - flush_pmd_entry(pmd); + flush_pmd_entry(p); } static void __init alloc_init_pmd(pud_t *pud, unsigned long addr, @@ -661,7 +663,7 @@ static void __init alloc_init_pmd(pud_t *pud, unsigned long addr, */ if (type->prot_sect && ((addr | next | phys) & ~SECTION_MASK) == 0) { - map_init_section(pmd, addr, next, phys, type); + __map_init_section(pmd, addr, next, phys, type); } else { alloc_init_pte(pmd, addr, next, __phys_to_pfn(phys), type); diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index 2c73a7301ff7..4c8c9c10a388 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S @@ -409,8 +409,8 @@ __v7_ca9mp_proc_info: */ .type __v7_pj4b_proc_info, #object __v7_pj4b_proc_info: - .long 0x562f5840 - .long 0xfffffff0 + .long 0x560f5800 + .long 0xff0fff00 __v7_proc __v7_pj4b_setup .size __v7_pj4b_proc_info, . - __v7_pj4b_proc_info diff --git a/arch/arm/plat-orion/common.c b/arch/arm/plat-orion/common.c index 251f827271e9..c019b7aaf776 100644 --- a/arch/arm/plat-orion/common.c +++ b/arch/arm/plat-orion/common.c @@ -383,7 +383,7 @@ static struct resource orion_ge10_shared_resources[] = { static struct platform_device orion_ge10_shared = { .name = MV643XX_ETH_SHARED_NAME, - .id = 1, + .id = 2, .dev = { .platform_data = &orion_ge10_shared_data, }, @@ -398,8 +398,8 @@ static struct resource orion_ge10_resources[] = { static struct platform_device orion_ge10 = { .name = MV643XX_ETH_NAME, - .id = 1, - .num_resources = 2, + .id = 2, + .num_resources = 1, .resource = orion_ge10_resources, .dev = { .coherent_dma_mask = DMA_BIT_MASK(32), @@ -432,7 +432,7 @@ static struct resource orion_ge11_shared_resources[] = { static struct platform_device orion_ge11_shared = { .name = MV643XX_ETH_SHARED_NAME, - .id = 1, + .id = 3, .dev = { .platform_data = &orion_ge11_shared_data, }, @@ -447,8 +447,8 @@ static struct resource orion_ge11_resources[] = { static struct platform_device orion_ge11 = { .name = MV643XX_ETH_NAME, - .id = 1, - .num_resources = 2, + .id = 3, + .num_resources = 1, .resource = orion_ge11_resources, .dev = { .coherent_dma_mask = DMA_BIT_MASK(32), diff --git a/arch/arm/plat-orion/include/plat/common.h b/arch/arm/plat-orion/include/plat/common.h index e06fc5fefa14..d9a24f605a2b 100644 --- a/arch/arm/plat-orion/include/plat/common.h +++ b/arch/arm/plat-orion/include/plat/common.h @@ -10,6 +10,7 @@ #ifndef __PLAT_COMMON_H #include <linux/mv643xx_eth.h> +#include <linux/platform_data/usb-ehci-orion.h> struct dsa_platform_data; struct mv_sata_platform_data; diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c index 30c2fe243f76..0f9c3f431a5f 100644 --- a/arch/arm/plat-samsung/devs.c +++ b/arch/arm/plat-samsung/devs.c @@ -311,9 +311,9 @@ struct platform_device s5p_device_jpeg = { #ifdef CONFIG_S5P_DEV_FIMD0 static struct resource s5p_fimd0_resource[] = { [0] = DEFINE_RES_MEM(S5P_PA_FIMD0, SZ_32K), - [1] = DEFINE_RES_IRQ(IRQ_FIMD0_VSYNC), - [2] = DEFINE_RES_IRQ(IRQ_FIMD0_FIFO), - [3] = DEFINE_RES_IRQ(IRQ_FIMD0_SYSTEM), + [1] = DEFINE_RES_IRQ_NAMED(IRQ_FIMD0_VSYNC, "vsync"), + [2] = DEFINE_RES_IRQ_NAMED(IRQ_FIMD0_FIFO, "fifo"), + [3] = DEFINE_RES_IRQ_NAMED(IRQ_FIMD0_SYSTEM, "lcd_sys"), }; struct platform_device s5p_device_fimd0 = { diff --git a/arch/arm/plat-samsung/include/plat/uncompress.h b/arch/arm/plat-samsung/include/plat/uncompress.h index 438b24846e7f..02b66d723d1a 100644 --- a/arch/arm/plat-samsung/include/plat/uncompress.h +++ b/arch/arm/plat-samsung/include/plat/uncompress.h @@ -66,6 +66,9 @@ uart_rd(unsigned int reg) static void putc(int ch) { + if (!config_enabled(CONFIG_DEBUG_LL)) + return; + if (uart_rd(S3C2410_UFCON) & S3C2410_UFCON_FIFOMODE) { int level; @@ -118,7 +121,12 @@ static void arch_decomp_error(const char *x) #ifdef CONFIG_S3C_BOOT_UART_FORCE_FIFO static inline void arch_enable_uart_fifo(void) { - u32 fifocon = uart_rd(S3C2410_UFCON); + u32 fifocon; + + if (!config_enabled(CONFIG_DEBUG_LL)) + return; + + fifocon = uart_rd(S3C2410_UFCON); if (!(fifocon & S3C2410_UFCON_FIFOMODE)) { fifocon |= S3C2410_UFCON_RESETBOTH; diff --git a/arch/arm/plat-samsung/pm.c b/arch/arm/plat-samsung/pm.c index 53210ec4e8ec..bd7124c87fea 100644 --- a/arch/arm/plat-samsung/pm.c +++ b/arch/arm/plat-samsung/pm.c @@ -16,6 +16,7 @@ #include <linux/suspend.h> #include <linux/errno.h> #include <linux/delay.h> +#include <linux/of.h> #include <linux/serial_core.h> #include <linux/io.h> @@ -261,7 +262,8 @@ static int s3c_pm_enter(suspend_state_t state) * require a full power-cycle) */ - if (!any_allowed(s3c_irqwake_intmask, s3c_irqwake_intallow) && + if (!of_have_populated_dt() && + !any_allowed(s3c_irqwake_intmask, s3c_irqwake_intallow) && !any_allowed(s3c_irqwake_eintmask, s3c_irqwake_eintallow)) { printk(KERN_ERR "%s: No wake-up sources!\n", __func__); printk(KERN_ERR "%s: Aborting sleep\n", __func__); @@ -270,8 +272,11 @@ static int s3c_pm_enter(suspend_state_t state) /* save all necessary core registers not covered by the drivers */ - samsung_pm_save_gpios(); - samsung_pm_saved_gpios(); + if (!of_have_populated_dt()) { + samsung_pm_save_gpios(); + samsung_pm_saved_gpios(); + } + s3c_pm_save_uarts(); s3c_pm_save_core(); @@ -310,8 +315,11 @@ static int s3c_pm_enter(suspend_state_t state) s3c_pm_restore_core(); s3c_pm_restore_uarts(); - samsung_pm_restore_gpios(); - s3c_pm_restored_gpios(); + + if (!of_have_populated_dt()) { + samsung_pm_restore_gpios(); + s3c_pm_restored_gpios(); + } s3c_pm_debug_init(); diff --git a/arch/arm/vfp/entry.S b/arch/arm/vfp/entry.S index 323ce1a62bbf..46e17492fd1f 100644 --- a/arch/arm/vfp/entry.S +++ b/arch/arm/vfp/entry.S @@ -60,7 +60,7 @@ ENTRY(vfp_testing_entry) str r11, [r10, #TI_PREEMPT] #endif ldr r0, VFP_arch_address - str r5, [r0] @ known non-zero value + str r0, [r0] @ set to non-zero value mov pc, r9 @ we have handled the fault ENDPROC(vfp_testing_entry) diff --git a/arch/arm64/kernel/arm64ksyms.c b/arch/arm64/kernel/arm64ksyms.c index 7df1aad29b67..41b4f626d554 100644 --- a/arch/arm64/kernel/arm64ksyms.c +++ b/arch/arm64/kernel/arm64ksyms.c @@ -34,6 +34,7 @@ EXPORT_SYMBOL(__strnlen_user); EXPORT_SYMBOL(__strncpy_from_user); EXPORT_SYMBOL(copy_page); +EXPORT_SYMBOL(clear_page); EXPORT_SYMBOL(__copy_from_user); EXPORT_SYMBOL(__copy_to_user); diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S index c7e047049f2c..1d1314280a03 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S @@ -390,6 +390,16 @@ el0_sync_compat: b.eq el0_fpsimd_exc cmp x24, #ESR_EL1_EC_UNKNOWN // unknown exception in EL0 b.eq el0_undef + cmp x24, #ESR_EL1_EC_CP15_32 // CP15 MRC/MCR trap + b.eq el0_undef + cmp x24, #ESR_EL1_EC_CP15_64 // CP15 MRRC/MCRR trap + b.eq el0_undef + cmp x24, #ESR_EL1_EC_CP14_MR // CP14 MRC/MCR trap + b.eq el0_undef + cmp x24, #ESR_EL1_EC_CP14_LS // CP14 LDC/STC trap + b.eq el0_undef + cmp x24, #ESR_EL1_EC_CP14_64 // CP14 MRRC/MCRR trap + b.eq el0_undef cmp x24, #ESR_EL1_EC_BREAKPT_EL0 // debug exception in EL0 b.ge el0_dbg b el0_inv diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c index 1e49e5eb81e9..9ba33c40cdf8 100644 --- a/arch/arm64/kernel/perf_event.c +++ b/arch/arm64/kernel/perf_event.c @@ -1336,6 +1336,7 @@ void perf_callchain_user(struct perf_callchain_entry *entry, return; } + perf_callchain_store(entry, regs->pc); tail = (struct frame_tail __user *)regs->regs[29]; while (entry->nr < PERF_MAX_STACK_DEPTH && diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index 61d7dd29f756..f30852d28590 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c @@ -267,7 +267,8 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs) return; #endif - if (show_unhandled_signals) { + if (show_unhandled_signals && unhandled_signal(current, SIGILL) && + printk_ratelimit()) { pr_info("%s[%d]: undefined instruction: pc=%p\n", current->comm, task_pid_nr(current), pc); dump_instr(KERN_INFO, regs); @@ -294,7 +295,7 @@ asmlinkage long do_ni_syscall(struct pt_regs *regs) } #endif - if (show_unhandled_signals) { + if (show_unhandled_signals && printk_ratelimit()) { pr_info("%s[%d]: syscall %d\n", current->comm, task_pid_nr(current), (int)regs->syscallno); dump_instr("", regs); @@ -310,14 +311,20 @@ asmlinkage long do_ni_syscall(struct pt_regs *regs) */ asmlinkage void bad_mode(struct pt_regs *regs, int reason, unsigned int esr) { + siginfo_t info; + void __user *pc = (void __user *)instruction_pointer(regs); console_verbose(); pr_crit("Bad mode in %s handler detected, code 0x%08x\n", handler[reason], esr); + __show_regs(regs); + + info.si_signo = SIGILL; + info.si_errno = 0; + info.si_code = ILL_ILLOPC; + info.si_addr = pc; - die("Oops - bad mode", regs, 0); - local_irq_disable(); - panic("bad mode"); + arm64_notify_die("Oops - bad mode", regs, &info, 0); } void __pte_error(const char *file, int line, unsigned long val) diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index 98af6e760cce..1426468b77f3 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -113,7 +113,8 @@ static void __do_user_fault(struct task_struct *tsk, unsigned long addr, { struct siginfo si; - if (show_unhandled_signals) { + if (show_unhandled_signals && unhandled_signal(tsk, sig) && + printk_ratelimit()) { pr_info("%s[%d]: unhandled %s (%d) at 0x%08lx, esr 0x%03x\n", tsk->comm, task_pid_nr(tsk), fault_name(esr), sig, addr, esr); diff --git a/arch/ia64/include/asm/irqflags.h b/arch/ia64/include/asm/irqflags.h index 1bf2cf2f4ab4..cec6c06b52c0 100644 --- a/arch/ia64/include/asm/irqflags.h +++ b/arch/ia64/include/asm/irqflags.h @@ -11,6 +11,7 @@ #define _ASM_IA64_IRQFLAGS_H #include <asm/pal.h> +#include <asm/kregs.h> #ifdef CONFIG_IA64_DEBUG_IRQ extern unsigned long last_cli_ip; diff --git a/arch/ia64/include/asm/tlb.h b/arch/ia64/include/asm/tlb.h index c3ffe3e54edc..ef3a9de01954 100644 --- a/arch/ia64/include/asm/tlb.h +++ b/arch/ia64/include/asm/tlb.h @@ -46,12 +46,6 @@ #include <asm/tlbflush.h> #include <asm/machvec.h> -#ifdef CONFIG_SMP -# define tlb_fast_mode(tlb) ((tlb)->nr == ~0U) -#else -# define tlb_fast_mode(tlb) (1) -#endif - /* * If we can't allocate a page to make a big batch of page pointers * to work on, then just handle a few from the on-stack structure. @@ -60,7 +54,7 @@ struct mmu_gather { struct mm_struct *mm; - unsigned int nr; /* == ~0U => fast mode */ + unsigned int nr; unsigned int max; unsigned char fullmm; /* non-zero means full mm flush */ unsigned char need_flush; /* really unmapped some PTEs? */ @@ -103,6 +97,7 @@ extern struct ia64_tr_entry *ia64_idtrs[NR_CPUS]; static inline void ia64_tlb_flush_mmu (struct mmu_gather *tlb, unsigned long start, unsigned long end) { + unsigned long i; unsigned int nr; if (!tlb->need_flush) @@ -141,13 +136,11 @@ ia64_tlb_flush_mmu (struct mmu_gather *tlb, unsigned long start, unsigned long e /* lastly, release the freed pages */ nr = tlb->nr; - if (!tlb_fast_mode(tlb)) { - unsigned long i; - tlb->nr = 0; - tlb->start_addr = ~0UL; - for (i = 0; i < nr; ++i) - free_page_and_swap_cache(tlb->pages[i]); - } + + tlb->nr = 0; + tlb->start_addr = ~0UL; + for (i = 0; i < nr; ++i) + free_page_and_swap_cache(tlb->pages[i]); } static inline void __tlb_alloc_page(struct mmu_gather *tlb) @@ -167,20 +160,7 @@ tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned int full_m tlb->mm = mm; tlb->max = ARRAY_SIZE(tlb->local); tlb->pages = tlb->local; - /* - * Use fast mode if only 1 CPU is online. - * - * It would be tempting to turn on fast-mode for full_mm_flush as well. But this - * doesn't work because of speculative accesses and software prefetching: the page - * table of "mm" may (and usually is) the currently active page table and even - * though the kernel won't do any user-space accesses during the TLB shoot down, a - * compiler might use speculation or lfetch.fault on what happens to be a valid - * user-space address. This in turn could trigger a TLB miss fault (or a VHPT - * walk) and re-insert a TLB entry we just removed. Slow mode avoids such - * problems. (We could make fast-mode work by switching the current task to a - * different "mm" during the shootdown.) --davidm 08/02/2002 - */ - tlb->nr = (num_online_cpus() == 1) ? ~0U : 0; + tlb->nr = 0; tlb->fullmm = full_mm_flush; tlb->start_addr = ~0UL; } @@ -214,11 +194,6 @@ static inline int __tlb_remove_page(struct mmu_gather *tlb, struct page *page) { tlb->need_flush = 1; - if (tlb_fast_mode(tlb)) { - free_page_and_swap_cache(page); - return 1; /* avoid calling tlb_flush_mmu */ - } - if (!tlb->nr && tlb->pages == tlb->local) __tlb_alloc_page(tlb); diff --git a/arch/m68k/configs/amiga_defconfig b/arch/m68k/configs/amiga_defconfig index 90d3109c82f4..19325e117eea 100644 --- a/arch/m68k/configs/amiga_defconfig +++ b/arch/m68k/configs/amiga_defconfig @@ -1,55 +1,78 @@ -CONFIG_EXPERIMENTAL=y CONFIG_LOCALVERSION="-amiga" CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y +CONFIG_FHANDLE=y CONFIG_BSD_PROCESS_ACCT=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_RELAY=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_LOG_BUF_SHIFT=16 +# CONFIG_UTS_NS is not set +# CONFIG_IPC_NS is not set +# CONFIG_PID_NS is not set +# CONFIG_NET_NS is not set CONFIG_BLK_DEV_INITRD=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SLAB=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y -CONFIG_AMIGA=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_ATARI_PARTITION=y +CONFIG_MAC_PARTITION=y +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_SUN_PARTITION=y +# CONFIG_EFI_PARTITION is not set +CONFIG_SYSV68_PARTITION=y +CONFIG_IOSCHED_DEADLINE=m CONFIG_M68020=y CONFIG_M68030=y CONFIG_M68040=y CONFIG_M68060=y -CONFIG_BINFMT_AOUT=m -CONFIG_BINFMT_MISC=m +CONFIG_AMIGA=y CONFIG_ZORRO=y CONFIG_AMIGA_PCMCIA=y -CONFIG_HEARTBEAT=y -CONFIG_PROC_HARDWARE=y CONFIG_ZORRO_NAMES=y +# CONFIG_COMPACTION is not set +CONFIG_CLEANCACHE=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_BINFMT_AOUT=m +CONFIG_BINFMT_MISC=m CONFIG_NET=y CONFIG_PACKET=y +CONFIG_PACKET_DIAG=m CONFIG_UNIX=y +CONFIG_UNIX_DIAG=m +CONFIG_XFRM_MIGRATE=y CONFIG_NET_KEY=y -CONFIG_NET_KEY_MIGRATE=y CONFIG_INET=y CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE_DEMUX=m CONFIG_NET_IPGRE=m CONFIG_SYN_COOKIES=y +CONFIG_NET_IPVTI=m CONFIG_INET_AH=m CONFIG_INET_ESP=m CONFIG_INET_IPCOMP=m CONFIG_INET_XFRM_MODE_TRANSPORT=m CONFIG_INET_XFRM_MODE_TUNNEL=m CONFIG_INET_XFRM_MODE_BEET=m +# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=m +CONFIG_INET_UDP_DIAG=m CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y -CONFIG_IPV6_ROUTE_INFO=y CONFIG_INET6_AH=m CONFIG_INET6_ESP=m CONFIG_INET6_IPCOMP=m -CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m -CONFIG_IPV6_TUNNEL=m +CONFIG_IPV6_GRE=m CONFIG_NETFILTER=y -CONFIG_NETFILTER_NETLINK_QUEUE=m CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_ZONES=y +# CONFIG_NF_CONNTRACK_PROCFS is not set # CONFIG_NF_CT_PROTO_DCCP is not set CONFIG_NF_CT_PROTO_UDPLITE=m CONFIG_NF_CONNTRACK_AMANDA=m @@ -57,25 +80,37 @@ CONFIG_NF_CONNTRACK_FTP=m CONFIG_NF_CONNTRACK_H323=m CONFIG_NF_CONNTRACK_IRC=m CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_SNMP=m CONFIG_NF_CONNTRACK_PPTP=m CONFIG_NF_CONNTRACK_SANE=m CONFIG_NF_CONNTRACK_SIP=m CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NETFILTER_XT_SET=m +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m CONFIG_NETFILTER_XT_TARGET_CONNMARK=m CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HMARK=m +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m +CONFIG_NETFILTER_XT_TARGET_LOG=m CONFIG_NETFILTER_XT_TARGET_MARK=m CONFIG_NETFILTER_XT_TARGET_NFLOG=m CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_TEE=m CONFIG_NETFILTER_XT_TARGET_TRACE=m CONFIG_NETFILTER_XT_TARGET_TCPMSS=m CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +CONFIG_NETFILTER_XT_MATCH_BPF=m CONFIG_NETFILTER_XT_MATCH_CLUSTER=m CONFIG_NETFILTER_XT_MATCH_COMMENT=m CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m CONFIG_NETFILTER_XT_MATCH_CONNMARK=m CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m CONFIG_NETFILTER_XT_MATCH_DSCP=m CONFIG_NETFILTER_XT_MATCH_ESP=m CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m @@ -86,6 +121,8 @@ CONFIG_NETFILTER_XT_MATCH_LIMIT=m CONFIG_NETFILTER_XT_MATCH_MAC=m CONFIG_NETFILTER_XT_MATCH_MARK=m CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_NFACCT=m +CONFIG_NETFILTER_XT_MATCH_OSF=m CONFIG_NETFILTER_XT_MATCH_OWNER=m CONFIG_NETFILTER_XT_MATCH_POLICY=m CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m @@ -99,22 +136,31 @@ CONFIG_NETFILTER_XT_MATCH_STRING=m CONFIG_NETFILTER_XT_MATCH_TCPMSS=m CONFIG_NETFILTER_XT_MATCH_TIME=m CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_IP_SET=m +CONFIG_IP_SET_BITMAP_IP=m +CONFIG_IP_SET_BITMAP_IPMAC=m +CONFIG_IP_SET_BITMAP_PORT=m +CONFIG_IP_SET_HASH_IP=m +CONFIG_IP_SET_HASH_IPPORT=m +CONFIG_IP_SET_HASH_IPPORTIP=m +CONFIG_IP_SET_HASH_IPPORTNET=m +CONFIG_IP_SET_HASH_NET=m +CONFIG_IP_SET_HASH_NETPORT=m +CONFIG_IP_SET_HASH_NETIFACE=m +CONFIG_IP_SET_LIST_SET=m CONFIG_NF_CONNTRACK_IPV4=m -CONFIG_IP_NF_QUEUE=m CONFIG_IP_NF_IPTABLES=m -CONFIG_IP_NF_MATCH_ADDRTYPE=m CONFIG_IP_NF_MATCH_AH=m CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_RPFILTER=m CONFIG_IP_NF_MATCH_TTL=m CONFIG_IP_NF_FILTER=m CONFIG_IP_NF_TARGET_REJECT=m -CONFIG_IP_NF_TARGET_LOG=m CONFIG_IP_NF_TARGET_ULOG=m -CONFIG_NF_NAT=m +CONFIG_NF_NAT_IPV4=m CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_REDIRECT=m -CONFIG_NF_NAT_SNMP_BASIC=m CONFIG_IP_NF_MANGLE=m CONFIG_IP_NF_TARGET_CLUSTERIP=m CONFIG_IP_NF_TARGET_ECN=m @@ -124,7 +170,6 @@ CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m CONFIG_NF_CONNTRACK_IPV6=m -CONFIG_IP6_NF_QUEUE=m CONFIG_IP6_NF_IPTABLES=m CONFIG_IP6_NF_MATCH_AH=m CONFIG_IP6_NF_MATCH_EUI64=m @@ -133,18 +178,30 @@ CONFIG_IP6_NF_MATCH_OPTS=m CONFIG_IP6_NF_MATCH_HL=m CONFIG_IP6_NF_MATCH_IPV6HEADER=m CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_RPFILTER=m CONFIG_IP6_NF_MATCH_RT=m CONFIG_IP6_NF_TARGET_HL=m -CONFIG_IP6_NF_TARGET_LOG=m CONFIG_IP6_NF_FILTER=m CONFIG_IP6_NF_TARGET_REJECT=m CONFIG_IP6_NF_MANGLE=m CONFIG_IP6_NF_RAW=m +CONFIG_NF_NAT_IPV6=m +CONFIG_IP6_NF_TARGET_MASQUERADE=m +CONFIG_IP6_NF_TARGET_NPT=m CONFIG_IP_DCCP=m # CONFIG_IP_DCCP_CCID3 is not set +CONFIG_SCTP_COOKIE_HMAC_SHA1=y +CONFIG_RDS=m +CONFIG_RDS_TCP=m +CONFIG_L2TP=m CONFIG_ATALK=m +CONFIG_BATMAN_ADV=m +CONFIG_BATMAN_ADV_DAT=y +# CONFIG_WIRELESS is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y # CONFIG_FIRMWARE_IN_KERNEL is not set +# CONFIG_FW_LOADER_USER_HELPER is not set CONFIG_CONNECTOR=m CONFIG_PARPORT=m CONFIG_PARPORT_AMIGA=m @@ -154,11 +211,13 @@ CONFIG_AMIGA_FLOPPY=y CONFIG_AMIGA_Z2RAM=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_DRBD=m CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=y CONFIG_CDROM_PKTCDVD=m CONFIG_ATA_OVER_ETH=m CONFIG_IDE=y +CONFIG_IDE_GD_ATAPI=y CONFIG_BLK_DEV_IDECD=y CONFIG_BLK_DEV_GAYLE=y CONFIG_BLK_DEV_BUDDHA=y @@ -172,57 +231,77 @@ CONFIG_BLK_DEV_SR=y CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y -CONFIG_SCSI_SAS_LIBSAS=m -# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set -CONFIG_SCSI_SRP_ATTRS=m -CONFIG_SCSI_SRP_TGT_ATTRS=y +CONFIG_SCSI_SAS_ATTRS=m CONFIG_ISCSI_TCP=m +CONFIG_ISCSI_BOOT_SYSFS=m CONFIG_A3000_SCSI=y CONFIG_A2091_SCSI=y CONFIG_GVP11_SCSI=y CONFIG_SCSI_A4000T=y CONFIG_SCSI_ZORRO7XX=y CONFIG_MD=y -CONFIG_BLK_DEV_MD=m CONFIG_MD_LINEAR=m CONFIG_MD_RAID0=m -CONFIG_MD_RAID1=m -CONFIG_MD_RAID456=m CONFIG_BLK_DEV_DM=m CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m +CONFIG_DM_THIN_PROVISIONING=m +CONFIG_DM_CACHE=m CONFIG_DM_MIRROR=m +CONFIG_DM_RAID=m CONFIG_DM_ZERO=m CONFIG_DM_MULTIPATH=m CONFIG_DM_UEVENT=y +CONFIG_TARGET_CORE=m +CONFIG_TCM_IBLOCK=m +CONFIG_TCM_FILEIO=m +CONFIG_TCM_PSCSI=m CONFIG_NETDEVICES=y CONFIG_DUMMY=m -CONFIG_MACVLAN=m CONFIG_EQUALIZER=m +CONFIG_NET_TEAM=m +CONFIG_NET_TEAM_MODE_BROADCAST=m +CONFIG_NET_TEAM_MODE_ROUNDROBIN=m +CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m +CONFIG_NET_TEAM_MODE_LOADBALANCE=m +CONFIG_VXLAN=m +CONFIG_NETCONSOLE=m +CONFIG_NETCONSOLE_DYNAMIC=y CONFIG_VETH=m -CONFIG_NET_ETHERNET=y -CONFIG_ARIADNE=y +# CONFIG_NET_VENDOR_3COM is not set CONFIG_A2065=y +CONFIG_ARIADNE=y +# CONFIG_NET_CADENCE is not set +# CONFIG_NET_VENDOR_BROADCOM is not set +# CONFIG_NET_VENDOR_CIRRUS is not set +# CONFIG_NET_VENDOR_FUJITSU is not set +# CONFIG_NET_VENDOR_HP is not set +# CONFIG_NET_VENDOR_INTEL is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MICREL is not set CONFIG_HYDRA=y -CONFIG_ZORRO8390=y CONFIG_APNE=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set +CONFIG_ZORRO8390=y +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_SMSC is not set +# CONFIG_NET_VENDOR_STMICRO is not set +# CONFIG_NET_VENDOR_WIZNET is not set CONFIG_PPP=m -CONFIG_PPP_FILTER=y -CONFIG_PPP_ASYNC=m -CONFIG_PPP_SYNC_TTY=m -CONFIG_PPP_DEFLATE=m CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_FILTER=y CONFIG_PPP_MPPE=m CONFIG_PPPOE=m +CONFIG_PPTP=m +CONFIG_PPPOL2TP=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m CONFIG_SLIP=m CONFIG_SLIP_COMPRESSED=y CONFIG_SLIP_SMART=y CONFIG_SLIP_MODE_SLIP6=y -CONFIG_NETCONSOLE=m -CONFIG_NETCONSOLE_DYNAMIC=y -CONFIG_INPUT_FF_MEMLESS=m +# CONFIG_WLAN is not set +CONFIG_INPUT_EVDEV=m CONFIG_KEYBOARD_AMIGA=y # CONFIG_KEYBOARD_ATKBD is not set # CONFIG_MOUSE_PS2 is not set @@ -233,11 +312,14 @@ CONFIG_INPUT_MISC=y CONFIG_INPUT_M68K_BEEP=m # CONFIG_SERIO is not set CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_LEGACY_PTYS is not set # CONFIG_DEVKMEM is not set CONFIG_PRINTER=m # CONFIG_HW_RANDOM is not set -CONFIG_GEN_RTC=m -CONFIG_GEN_RTC_X=y +CONFIG_NTP_PPS=y +CONFIG_PPS_CLIENT_LDISC=m +CONFIG_PPS_CLIENT_PARPORT=m +CONFIG_PTP_1588_CLOCK=m # CONFIG_HWMON is not set CONFIG_FB=y CONFIG_FB_CIRRUS=y @@ -252,48 +334,64 @@ CONFIG_SOUND=m CONFIG_DMASOUND_PAULA=m CONFIG_HID=m CONFIG_HIDRAW=y +CONFIG_UHID=m +# CONFIG_HID_GENERIC is not set # CONFIG_USB_SUPPORT is not set +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_MSM6242=m +CONFIG_RTC_DRV_RP5C01=m +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_HEARTBEAT=y +CONFIG_PROC_HARDWARE=y CONFIG_AMIGA_BUILTIN_SERIAL=y CONFIG_SERIAL_CONSOLE=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set # CONFIG_EXT3_FS_XATTR is not set +CONFIG_EXT4_FS=y CONFIG_REISERFS_FS=m CONFIG_JFS_FS=m CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m -# CONFIG_OCFS2_FS_STATS is not set # CONFIG_OCFS2_DEBUG_MASKLOG is not set +CONFIG_FANOTIFY=y CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set -CONFIG_AUTOFS_FS=m CONFIG_AUTOFS4_FS=m CONFIG_FUSE_FS=m +CONFIG_CUSE=m CONFIG_ISO9660_FS=y CONFIG_JOLIET=y CONFIG_ZISOFS=y CONFIG_UDF_FS=m -CONFIG_MSDOS_FS=y +CONFIG_MSDOS_FS=m CONFIG_VFAT_FS=m CONFIG_PROC_KCORE=y CONFIG_TMPFS=y CONFIG_AFFS_FS=m +CONFIG_ECRYPT_FS=m +CONFIG_ECRYPT_FS_MESSAGING=y CONFIG_HFS_FS=m CONFIG_HFSPLUS_FS=m CONFIG_CRAMFS=m CONFIG_SQUASHFS=m -CONFIG_MINIX_FS=y +CONFIG_SQUASHFS_LZO=y +CONFIG_MINIX_FS=m +CONFIG_OMFS_FS=m CONFIG_HPFS_FS=m +CONFIG_QNX4FS_FS=m +CONFIG_QNX6FS_FS=m CONFIG_SYSV_FS=m CONFIG_UFS_FS=m CONFIG_NFS_FS=y -CONFIG_NFS_V3=y CONFIG_NFS_V4=y +CONFIG_NFS_SWAP=y +CONFIG_ROOT_NFS=y CONFIG_NFSD=m CONFIG_NFSD_V3=y -CONFIG_SMB_FS=m -CONFIG_SMB_NLS_DEFAULT=y +CONFIG_CIFS=m +# CONFIG_CIFS_DEBUG is not set CONFIG_CODA_FS=m CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_CODEPAGE_737=m @@ -332,10 +430,23 @@ CONFIG_NLS_ISO8859_14=m CONFIG_NLS_ISO8859_15=m CONFIG_NLS_KOI8_R=m CONFIG_NLS_KOI8_U=m +CONFIG_NLS_MAC_ROMAN=m +CONFIG_NLS_MAC_CELTIC=m +CONFIG_NLS_MAC_CENTEURO=m +CONFIG_NLS_MAC_CROATIAN=m +CONFIG_NLS_MAC_CYRILLIC=m +CONFIG_NLS_MAC_GAELIC=m +CONFIG_NLS_MAC_GREEK=m +CONFIG_NLS_MAC_ICELAND=m +CONFIG_NLS_MAC_INUIT=m +CONFIG_NLS_MAC_ROMANIAN=m +CONFIG_NLS_MAC_TURKISH=m CONFIG_DLM=m CONFIG_MAGIC_SYSRQ=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y +CONFIG_ASYNC_RAID6_TEST=m +CONFIG_ENCRYPTED_KEYS=m +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_USER=m CONFIG_CRYPTO_NULL=m CONFIG_CRYPTO_CRYPTD=m CONFIG_CRYPTO_TEST=m @@ -345,19 +456,16 @@ CONFIG_CRYPTO_CTS=m CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_PCBC=m CONFIG_CRYPTO_XTS=m -CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_XCBC=m -CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_VMAC=m CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_RMD128=m CONFIG_CRYPTO_RMD160=m CONFIG_CRYPTO_RMD256=m CONFIG_CRYPTO_RMD320=m -CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m CONFIG_CRYPTO_TGR192=m CONFIG_CRYPTO_WP512=m -CONFIG_CRYPTO_AES=m CONFIG_CRYPTO_ANUBIS=m CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_CAMELLIA=m @@ -373,6 +481,14 @@ CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_ZLIB=m CONFIG_CRYPTO_LZO=m # CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_USER_API_HASH=m +CONFIG_CRYPTO_USER_API_SKCIPHER=m # CONFIG_CRYPTO_HW is not set -CONFIG_CRC16=m CONFIG_CRC_T10DIF=y +CONFIG_XZ_DEC_X86=y +CONFIG_XZ_DEC_POWERPC=y +CONFIG_XZ_DEC_IA64=y +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_ARMTHUMB=y +CONFIG_XZ_DEC_SPARC=y +CONFIG_XZ_DEC_TEST=m diff --git a/arch/m68k/configs/apollo_defconfig b/arch/m68k/configs/apollo_defconfig index 8f4f657fdbc6..14dc6ccda7f4 100644 --- a/arch/m68k/configs/apollo_defconfig +++ b/arch/m68k/configs/apollo_defconfig @@ -1,55 +1,76 @@ -CONFIG_EXPERIMENTAL=y CONFIG_LOCALVERSION="-apollo" CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y +CONFIG_FHANDLE=y CONFIG_BSD_PROCESS_ACCT=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_RELAY=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_LOG_BUF_SHIFT=16 +# CONFIG_UTS_NS is not set +# CONFIG_IPC_NS is not set +# CONFIG_PID_NS is not set +# CONFIG_NET_NS is not set CONFIG_BLK_DEV_INITRD=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SLAB=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y -CONFIG_APOLLO=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_AMIGA_PARTITION=y +CONFIG_ATARI_PARTITION=y +CONFIG_MAC_PARTITION=y +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_SUN_PARTITION=y +# CONFIG_EFI_PARTITION is not set +CONFIG_SYSV68_PARTITION=y +CONFIG_IOSCHED_DEADLINE=m CONFIG_M68020=y CONFIG_M68030=y CONFIG_M68040=y CONFIG_M68060=y +CONFIG_APOLLO=y +# CONFIG_COMPACTION is not set +CONFIG_CLEANCACHE=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_BINFMT_AOUT=m CONFIG_BINFMT_MISC=m -CONFIG_HEARTBEAT=y -CONFIG_PROC_HARDWARE=y CONFIG_NET=y CONFIG_PACKET=y +CONFIG_PACKET_DIAG=m CONFIG_UNIX=y +CONFIG_UNIX_DIAG=m +CONFIG_XFRM_MIGRATE=y CONFIG_NET_KEY=y -CONFIG_NET_KEY_MIGRATE=y CONFIG_INET=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_IP_PNP_RARP=y CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE_DEMUX=m CONFIG_NET_IPGRE=m CONFIG_SYN_COOKIES=y +CONFIG_NET_IPVTI=m CONFIG_INET_AH=m CONFIG_INET_ESP=m CONFIG_INET_IPCOMP=m CONFIG_INET_XFRM_MODE_TRANSPORT=m CONFIG_INET_XFRM_MODE_TUNNEL=m CONFIG_INET_XFRM_MODE_BEET=m +# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=m +CONFIG_INET_UDP_DIAG=m CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y -CONFIG_IPV6_ROUTE_INFO=y CONFIG_INET6_AH=m CONFIG_INET6_ESP=m CONFIG_INET6_IPCOMP=m -CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m -CONFIG_IPV6_TUNNEL=m +CONFIG_IPV6_GRE=m CONFIG_NETFILTER=y -CONFIG_NETFILTER_NETLINK_QUEUE=m CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_ZONES=y +# CONFIG_NF_CONNTRACK_PROCFS is not set # CONFIG_NF_CT_PROTO_DCCP is not set CONFIG_NF_CT_PROTO_UDPLITE=m CONFIG_NF_CONNTRACK_AMANDA=m @@ -57,25 +78,37 @@ CONFIG_NF_CONNTRACK_FTP=m CONFIG_NF_CONNTRACK_H323=m CONFIG_NF_CONNTRACK_IRC=m CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_SNMP=m CONFIG_NF_CONNTRACK_PPTP=m CONFIG_NF_CONNTRACK_SANE=m CONFIG_NF_CONNTRACK_SIP=m CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NETFILTER_XT_SET=m +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m CONFIG_NETFILTER_XT_TARGET_CONNMARK=m CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HMARK=m +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m +CONFIG_NETFILTER_XT_TARGET_LOG=m CONFIG_NETFILTER_XT_TARGET_MARK=m CONFIG_NETFILTER_XT_TARGET_NFLOG=m CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_TEE=m CONFIG_NETFILTER_XT_TARGET_TRACE=m CONFIG_NETFILTER_XT_TARGET_TCPMSS=m CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +CONFIG_NETFILTER_XT_MATCH_BPF=m CONFIG_NETFILTER_XT_MATCH_CLUSTER=m CONFIG_NETFILTER_XT_MATCH_COMMENT=m CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m CONFIG_NETFILTER_XT_MATCH_CONNMARK=m CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m CONFIG_NETFILTER_XT_MATCH_DSCP=m CONFIG_NETFILTER_XT_MATCH_ESP=m CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m @@ -86,6 +119,8 @@ CONFIG_NETFILTER_XT_MATCH_LIMIT=m CONFIG_NETFILTER_XT_MATCH_MAC=m CONFIG_NETFILTER_XT_MATCH_MARK=m CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_NFACCT=m +CONFIG_NETFILTER_XT_MATCH_OSF=m CONFIG_NETFILTER_XT_MATCH_OWNER=m CONFIG_NETFILTER_XT_MATCH_POLICY=m CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m @@ -99,22 +134,31 @@ CONFIG_NETFILTER_XT_MATCH_STRING=m CONFIG_NETFILTER_XT_MATCH_TCPMSS=m CONFIG_NETFILTER_XT_MATCH_TIME=m CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_IP_SET=m +CONFIG_IP_SET_BITMAP_IP=m +CONFIG_IP_SET_BITMAP_IPMAC=m +CONFIG_IP_SET_BITMAP_PORT=m +CONFIG_IP_SET_HASH_IP=m +CONFIG_IP_SET_HASH_IPPORT=m +CONFIG_IP_SET_HASH_IPPORTIP=m +CONFIG_IP_SET_HASH_IPPORTNET=m +CONFIG_IP_SET_HASH_NET=m +CONFIG_IP_SET_HASH_NETPORT=m +CONFIG_IP_SET_HASH_NETIFACE=m +CONFIG_IP_SET_LIST_SET=m CONFIG_NF_CONNTRACK_IPV4=m -CONFIG_IP_NF_QUEUE=m CONFIG_IP_NF_IPTABLES=m -CONFIG_IP_NF_MATCH_ADDRTYPE=m CONFIG_IP_NF_MATCH_AH=m CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_RPFILTER=m CONFIG_IP_NF_MATCH_TTL=m CONFIG_IP_NF_FILTER=m CONFIG_IP_NF_TARGET_REJECT=m -CONFIG_IP_NF_TARGET_LOG=m CONFIG_IP_NF_TARGET_ULOG=m -CONFIG_NF_NAT=m +CONFIG_NF_NAT_IPV4=m CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_REDIRECT=m -CONFIG_NF_NAT_SNMP_BASIC=m CONFIG_IP_NF_MANGLE=m CONFIG_IP_NF_TARGET_CLUSTERIP=m CONFIG_IP_NF_TARGET_ECN=m @@ -124,7 +168,6 @@ CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m CONFIG_NF_CONNTRACK_IPV6=m -CONFIG_IP6_NF_QUEUE=m CONFIG_IP6_NF_IPTABLES=m CONFIG_IP6_NF_MATCH_AH=m CONFIG_IP6_NF_MATCH_EUI64=m @@ -133,21 +176,34 @@ CONFIG_IP6_NF_MATCH_OPTS=m CONFIG_IP6_NF_MATCH_HL=m CONFIG_IP6_NF_MATCH_IPV6HEADER=m CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_RPFILTER=m CONFIG_IP6_NF_MATCH_RT=m CONFIG_IP6_NF_TARGET_HL=m -CONFIG_IP6_NF_TARGET_LOG=m CONFIG_IP6_NF_FILTER=m CONFIG_IP6_NF_TARGET_REJECT=m CONFIG_IP6_NF_MANGLE=m CONFIG_IP6_NF_RAW=m +CONFIG_NF_NAT_IPV6=m +CONFIG_IP6_NF_TARGET_MASQUERADE=m +CONFIG_IP6_NF_TARGET_NPT=m CONFIG_IP_DCCP=m # CONFIG_IP_DCCP_CCID3 is not set +CONFIG_SCTP_COOKIE_HMAC_SHA1=y +CONFIG_RDS=m +CONFIG_RDS_TCP=m +CONFIG_L2TP=m CONFIG_ATALK=m +CONFIG_BATMAN_ADV=m +CONFIG_BATMAN_ADV_DAT=y +# CONFIG_WIRELESS is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y # CONFIG_FIRMWARE_IN_KERNEL is not set +# CONFIG_FW_LOADER_USER_HELPER is not set CONFIG_CONNECTOR=m CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_DRBD=m CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=y CONFIG_CDROM_PKTCDVD=m @@ -162,57 +218,74 @@ CONFIG_BLK_DEV_SR=y CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y -CONFIG_SCSI_SAS_LIBSAS=m -# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set -CONFIG_SCSI_SRP_ATTRS=m -CONFIG_SCSI_SRP_TGT_ATTRS=y +CONFIG_SCSI_SAS_ATTRS=m CONFIG_ISCSI_TCP=m +CONFIG_ISCSI_BOOT_SYSFS=m CONFIG_MD=y -CONFIG_BLK_DEV_MD=m CONFIG_MD_LINEAR=m CONFIG_MD_RAID0=m -CONFIG_MD_RAID1=m -CONFIG_MD_RAID456=m CONFIG_BLK_DEV_DM=m CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m +CONFIG_DM_THIN_PROVISIONING=m +CONFIG_DM_CACHE=m CONFIG_DM_MIRROR=m +CONFIG_DM_RAID=m CONFIG_DM_ZERO=m CONFIG_DM_MULTIPATH=m CONFIG_DM_UEVENT=y +CONFIG_TARGET_CORE=m +CONFIG_TCM_IBLOCK=m +CONFIG_TCM_FILEIO=m +CONFIG_TCM_PSCSI=m CONFIG_NETDEVICES=y CONFIG_DUMMY=m -CONFIG_MACVLAN=m CONFIG_EQUALIZER=m +CONFIG_NET_TEAM=m +CONFIG_NET_TEAM_MODE_BROADCAST=m +CONFIG_NET_TEAM_MODE_ROUNDROBIN=m +CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m +CONFIG_NET_TEAM_MODE_LOADBALANCE=m +CONFIG_VXLAN=m +CONFIG_NETCONSOLE=m +CONFIG_NETCONSOLE_DYNAMIC=y CONFIG_VETH=m -CONFIG_NET_ETHERNET=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set +# CONFIG_NET_CADENCE is not set +# CONFIG_NET_VENDOR_BROADCOM is not set +# CONFIG_NET_VENDOR_INTEL is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_STMICRO is not set +# CONFIG_NET_VENDOR_WIZNET is not set CONFIG_PPP=m -CONFIG_PPP_FILTER=y -CONFIG_PPP_ASYNC=m -CONFIG_PPP_SYNC_TTY=m -CONFIG_PPP_DEFLATE=m CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_FILTER=y CONFIG_PPP_MPPE=m CONFIG_PPPOE=m +CONFIG_PPTP=m +CONFIG_PPPOL2TP=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m CONFIG_SLIP=m CONFIG_SLIP_COMPRESSED=y CONFIG_SLIP_SMART=y CONFIG_SLIP_MODE_SLIP6=y -CONFIG_NETCONSOLE=m -CONFIG_NETCONSOLE_DYNAMIC=y -CONFIG_INPUT_FF_MEMLESS=m +# CONFIG_WLAN is not set +CONFIG_INPUT_EVDEV=m # CONFIG_KEYBOARD_ATKBD is not set -CONFIG_MOUSE_PS2=m +# CONFIG_MOUSE_PS2 is not set CONFIG_MOUSE_SERIAL=m CONFIG_SERIO=m -# CONFIG_SERIO_SERPORT is not set CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_LEGACY_PTYS is not set # CONFIG_DEVKMEM is not set # CONFIG_HW_RANDOM is not set -CONFIG_GEN_RTC=m -CONFIG_GEN_RTC_X=y +CONFIG_NTP_PPS=y +CONFIG_PPS_CLIENT_LDISC=m +CONFIG_PTP_1588_CLOCK=m # CONFIG_HWMON is not set CONFIG_FB=y CONFIG_FRAMEBUFFER_CONSOLE=y @@ -221,47 +294,61 @@ CONFIG_LOGO=y # CONFIG_LOGO_LINUX_CLUT224 is not set CONFIG_HID=m CONFIG_HIDRAW=y +CONFIG_UHID=m +# CONFIG_HID_GENERIC is not set # CONFIG_USB_SUPPORT is not set +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_GENERIC=m +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_HEARTBEAT=y +CONFIG_PROC_HARDWARE=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set # CONFIG_EXT3_FS_XATTR is not set +CONFIG_EXT4_FS=y CONFIG_REISERFS_FS=m CONFIG_JFS_FS=m CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m -# CONFIG_OCFS2_FS_STATS is not set # CONFIG_OCFS2_DEBUG_MASKLOG is not set +CONFIG_FANOTIFY=y CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set -CONFIG_AUTOFS_FS=m CONFIG_AUTOFS4_FS=m CONFIG_FUSE_FS=m +CONFIG_CUSE=m CONFIG_ISO9660_FS=y CONFIG_JOLIET=y CONFIG_ZISOFS=y CONFIG_UDF_FS=m -CONFIG_MSDOS_FS=y +CONFIG_MSDOS_FS=m CONFIG_VFAT_FS=m CONFIG_PROC_KCORE=y CONFIG_TMPFS=y CONFIG_AFFS_FS=m +CONFIG_ECRYPT_FS=m +CONFIG_ECRYPT_FS_MESSAGING=y CONFIG_HFS_FS=m CONFIG_HFSPLUS_FS=m CONFIG_CRAMFS=m CONFIG_SQUASHFS=m -CONFIG_MINIX_FS=y +CONFIG_SQUASHFS_LZO=y +CONFIG_MINIX_FS=m +CONFIG_OMFS_FS=m CONFIG_HPFS_FS=m +CONFIG_QNX4FS_FS=m +CONFIG_QNX6FS_FS=m CONFIG_SYSV_FS=m CONFIG_UFS_FS=m CONFIG_NFS_FS=y -CONFIG_NFS_V3=y CONFIG_NFS_V4=y +CONFIG_NFS_SWAP=y CONFIG_ROOT_NFS=y CONFIG_NFSD=m CONFIG_NFSD_V3=y -CONFIG_SMB_FS=m -CONFIG_SMB_NLS_DEFAULT=y +CONFIG_CIFS=m +# CONFIG_CIFS_DEBUG is not set CONFIG_CODA_FS=m CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_CODEPAGE_737=m @@ -300,10 +387,23 @@ CONFIG_NLS_ISO8859_14=m CONFIG_NLS_ISO8859_15=m CONFIG_NLS_KOI8_R=m CONFIG_NLS_KOI8_U=m +CONFIG_NLS_MAC_ROMAN=m +CONFIG_NLS_MAC_CELTIC=m +CONFIG_NLS_MAC_CENTEURO=m +CONFIG_NLS_MAC_CROATIAN=m +CONFIG_NLS_MAC_CYRILLIC=m +CONFIG_NLS_MAC_GAELIC=m +CONFIG_NLS_MAC_GREEK=m +CONFIG_NLS_MAC_ICELAND=m +CONFIG_NLS_MAC_INUIT=m +CONFIG_NLS_MAC_ROMANIAN=m +CONFIG_NLS_MAC_TURKISH=m CONFIG_DLM=m CONFIG_MAGIC_SYSRQ=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y +CONFIG_ASYNC_RAID6_TEST=m +CONFIG_ENCRYPTED_KEYS=m +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_USER=m CONFIG_CRYPTO_NULL=m CONFIG_CRYPTO_CRYPTD=m CONFIG_CRYPTO_TEST=m @@ -313,19 +413,16 @@ CONFIG_CRYPTO_CTS=m CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_PCBC=m CONFIG_CRYPTO_XTS=m -CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_XCBC=m -CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_VMAC=m CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_RMD128=m CONFIG_CRYPTO_RMD160=m CONFIG_CRYPTO_RMD256=m CONFIG_CRYPTO_RMD320=m -CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m CONFIG_CRYPTO_TGR192=m CONFIG_CRYPTO_WP512=m -CONFIG_CRYPTO_AES=m CONFIG_CRYPTO_ANUBIS=m CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_CAMELLIA=m @@ -341,6 +438,14 @@ CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_ZLIB=m CONFIG_CRYPTO_LZO=m # CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_USER_API_HASH=m +CONFIG_CRYPTO_USER_API_SKCIPHER=m # CONFIG_CRYPTO_HW is not set -CONFIG_CRC16=m CONFIG_CRC_T10DIF=y +CONFIG_XZ_DEC_X86=y +CONFIG_XZ_DEC_POWERPC=y +CONFIG_XZ_DEC_IA64=y +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_ARMTHUMB=y +CONFIG_XZ_DEC_SPARC=y +CONFIG_XZ_DEC_TEST=m diff --git a/arch/m68k/configs/atari_defconfig b/arch/m68k/configs/atari_defconfig index 4571d33903fe..6d5370c914b2 100644 --- a/arch/m68k/configs/atari_defconfig +++ b/arch/m68k/configs/atari_defconfig @@ -1,53 +1,75 @@ -CONFIG_EXPERIMENTAL=y CONFIG_LOCALVERSION="-atari" CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y +CONFIG_FHANDLE=y CONFIG_BSD_PROCESS_ACCT=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_RELAY=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_LOG_BUF_SHIFT=16 +# CONFIG_UTS_NS is not set +# CONFIG_IPC_NS is not set +# CONFIG_PID_NS is not set +# CONFIG_NET_NS is not set CONFIG_BLK_DEV_INITRD=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SLAB=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y -CONFIG_ATARI=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_AMIGA_PARTITION=y +CONFIG_MAC_PARTITION=y +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_SUN_PARTITION=y +# CONFIG_EFI_PARTITION is not set +CONFIG_SYSV68_PARTITION=y +CONFIG_IOSCHED_DEADLINE=m CONFIG_M68020=y CONFIG_M68030=y CONFIG_M68040=y CONFIG_M68060=y +CONFIG_ATARI=y +# CONFIG_COMPACTION is not set +CONFIG_CLEANCACHE=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_BINFMT_AOUT=m CONFIG_BINFMT_MISC=m -CONFIG_STRAM_PROC=y -CONFIG_HEARTBEAT=y -CONFIG_PROC_HARDWARE=y CONFIG_NET=y CONFIG_PACKET=y +CONFIG_PACKET_DIAG=m CONFIG_UNIX=y +CONFIG_UNIX_DIAG=m +CONFIG_XFRM_MIGRATE=y CONFIG_NET_KEY=y -CONFIG_NET_KEY_MIGRATE=y CONFIG_INET=y CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE_DEMUX=m CONFIG_NET_IPGRE=m CONFIG_SYN_COOKIES=y +CONFIG_NET_IPVTI=m CONFIG_INET_AH=m CONFIG_INET_ESP=m CONFIG_INET_IPCOMP=m CONFIG_INET_XFRM_MODE_TRANSPORT=m CONFIG_INET_XFRM_MODE_TUNNEL=m CONFIG_INET_XFRM_MODE_BEET=m +# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=m +CONFIG_INET_UDP_DIAG=m CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y -CONFIG_IPV6_ROUTE_INFO=y CONFIG_INET6_AH=m CONFIG_INET6_ESP=m CONFIG_INET6_IPCOMP=m -CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m -CONFIG_IPV6_TUNNEL=m +CONFIG_IPV6_GRE=m CONFIG_NETFILTER=y -CONFIG_NETFILTER_NETLINK_QUEUE=m CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_ZONES=y +# CONFIG_NF_CONNTRACK_PROCFS is not set # CONFIG_NF_CT_PROTO_DCCP is not set CONFIG_NF_CT_PROTO_UDPLITE=m CONFIG_NF_CONNTRACK_AMANDA=m @@ -55,25 +77,37 @@ CONFIG_NF_CONNTRACK_FTP=m CONFIG_NF_CONNTRACK_H323=m CONFIG_NF_CONNTRACK_IRC=m CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_SNMP=m CONFIG_NF_CONNTRACK_PPTP=m CONFIG_NF_CONNTRACK_SANE=m CONFIG_NF_CONNTRACK_SIP=m CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NETFILTER_XT_SET=m +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m CONFIG_NETFILTER_XT_TARGET_CONNMARK=m CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HMARK=m +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m +CONFIG_NETFILTER_XT_TARGET_LOG=m CONFIG_NETFILTER_XT_TARGET_MARK=m CONFIG_NETFILTER_XT_TARGET_NFLOG=m CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_TEE=m CONFIG_NETFILTER_XT_TARGET_TRACE=m CONFIG_NETFILTER_XT_TARGET_TCPMSS=m CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +CONFIG_NETFILTER_XT_MATCH_BPF=m CONFIG_NETFILTER_XT_MATCH_CLUSTER=m CONFIG_NETFILTER_XT_MATCH_COMMENT=m CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m CONFIG_NETFILTER_XT_MATCH_CONNMARK=m CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m CONFIG_NETFILTER_XT_MATCH_DSCP=m CONFIG_NETFILTER_XT_MATCH_ESP=m CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m @@ -84,6 +118,8 @@ CONFIG_NETFILTER_XT_MATCH_LIMIT=m CONFIG_NETFILTER_XT_MATCH_MAC=m CONFIG_NETFILTER_XT_MATCH_MARK=m CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_NFACCT=m +CONFIG_NETFILTER_XT_MATCH_OSF=m CONFIG_NETFILTER_XT_MATCH_OWNER=m CONFIG_NETFILTER_XT_MATCH_POLICY=m CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m @@ -97,22 +133,31 @@ CONFIG_NETFILTER_XT_MATCH_STRING=m CONFIG_NETFILTER_XT_MATCH_TCPMSS=m CONFIG_NETFILTER_XT_MATCH_TIME=m CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_IP_SET=m +CONFIG_IP_SET_BITMAP_IP=m +CONFIG_IP_SET_BITMAP_IPMAC=m +CONFIG_IP_SET_BITMAP_PORT=m +CONFIG_IP_SET_HASH_IP=m +CONFIG_IP_SET_HASH_IPPORT=m +CONFIG_IP_SET_HASH_IPPORTIP=m +CONFIG_IP_SET_HASH_IPPORTNET=m +CONFIG_IP_SET_HASH_NET=m +CONFIG_IP_SET_HASH_NETPORT=m +CONFIG_IP_SET_HASH_NETIFACE=m +CONFIG_IP_SET_LIST_SET=m CONFIG_NF_CONNTRACK_IPV4=m -CONFIG_IP_NF_QUEUE=m CONFIG_IP_NF_IPTABLES=m -CONFIG_IP_NF_MATCH_ADDRTYPE=m CONFIG_IP_NF_MATCH_AH=m CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_RPFILTER=m CONFIG_IP_NF_MATCH_TTL=m CONFIG_IP_NF_FILTER=m CONFIG_IP_NF_TARGET_REJECT=m -CONFIG_IP_NF_TARGET_LOG=m CONFIG_IP_NF_TARGET_ULOG=m -CONFIG_NF_NAT=m +CONFIG_NF_NAT_IPV4=m CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_REDIRECT=m -CONFIG_NF_NAT_SNMP_BASIC=m CONFIG_IP_NF_MANGLE=m CONFIG_IP_NF_TARGET_CLUSTERIP=m CONFIG_IP_NF_TARGET_ECN=m @@ -122,7 +167,6 @@ CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m CONFIG_NF_CONNTRACK_IPV6=m -CONFIG_IP6_NF_QUEUE=m CONFIG_IP6_NF_IPTABLES=m CONFIG_IP6_NF_MATCH_AH=m CONFIG_IP6_NF_MATCH_EUI64=m @@ -131,18 +175,30 @@ CONFIG_IP6_NF_MATCH_OPTS=m CONFIG_IP6_NF_MATCH_HL=m CONFIG_IP6_NF_MATCH_IPV6HEADER=m CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_RPFILTER=m CONFIG_IP6_NF_MATCH_RT=m CONFIG_IP6_NF_TARGET_HL=m -CONFIG_IP6_NF_TARGET_LOG=m CONFIG_IP6_NF_FILTER=m CONFIG_IP6_NF_TARGET_REJECT=m CONFIG_IP6_NF_MANGLE=m CONFIG_IP6_NF_RAW=m +CONFIG_NF_NAT_IPV6=m +CONFIG_IP6_NF_TARGET_MASQUERADE=m +CONFIG_IP6_NF_TARGET_NPT=m CONFIG_IP_DCCP=m # CONFIG_IP_DCCP_CCID3 is not set +CONFIG_SCTP_COOKIE_HMAC_SHA1=y +CONFIG_RDS=m +CONFIG_RDS_TCP=m +CONFIG_L2TP=m CONFIG_ATALK=m +CONFIG_BATMAN_ADV=m +CONFIG_BATMAN_ADV_DAT=y +# CONFIG_WIRELESS is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y # CONFIG_FIRMWARE_IN_KERNEL is not set +# CONFIG_FW_LOADER_USER_HELPER is not set CONFIG_CONNECTOR=m CONFIG_PARPORT=m CONFIG_PARPORT_ATARI=m @@ -150,11 +206,13 @@ CONFIG_PARPORT_1284=y CONFIG_ATARI_FLOPPY=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_DRBD=m CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=y CONFIG_CDROM_PKTCDVD=m CONFIG_ATA_OVER_ETH=m CONFIG_IDE=y +CONFIG_IDE_GD_ATAPI=y CONFIG_BLK_DEV_IDECD=y CONFIG_BLK_DEV_FALCON_IDE=y CONFIG_RAID_ATTRS=m @@ -167,63 +225,81 @@ CONFIG_BLK_DEV_SR=y CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y -CONFIG_SCSI_SAS_LIBSAS=m -# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set -CONFIG_SCSI_SRP_ATTRS=m -CONFIG_SCSI_SRP_TGT_ATTRS=y +CONFIG_SCSI_SAS_ATTRS=m CONFIG_ISCSI_TCP=m +CONFIG_ISCSI_BOOT_SYSFS=m CONFIG_ATARI_SCSI=y CONFIG_MD=y -CONFIG_BLK_DEV_MD=m CONFIG_MD_LINEAR=m CONFIG_MD_RAID0=m -CONFIG_MD_RAID1=m -CONFIG_MD_RAID456=m CONFIG_BLK_DEV_DM=m CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m +CONFIG_DM_THIN_PROVISIONING=m +CONFIG_DM_CACHE=m CONFIG_DM_MIRROR=m +CONFIG_DM_RAID=m CONFIG_DM_ZERO=m CONFIG_DM_MULTIPATH=m CONFIG_DM_UEVENT=y +CONFIG_TARGET_CORE=m +CONFIG_TCM_IBLOCK=m +CONFIG_TCM_FILEIO=m +CONFIG_TCM_PSCSI=m CONFIG_NETDEVICES=y CONFIG_DUMMY=m -CONFIG_MACVLAN=m CONFIG_EQUALIZER=m -CONFIG_VETH=m -CONFIG_NET_ETHERNET=y CONFIG_MII=y +CONFIG_NET_TEAM=m +CONFIG_NET_TEAM_MODE_BROADCAST=m +CONFIG_NET_TEAM_MODE_ROUNDROBIN=m +CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m +CONFIG_NET_TEAM_MODE_LOADBALANCE=m +CONFIG_VXLAN=m +CONFIG_NETCONSOLE=m +CONFIG_NETCONSOLE_DYNAMIC=y +CONFIG_VETH=m CONFIG_ATARILANCE=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set +# CONFIG_NET_CADENCE is not set +# CONFIG_NET_VENDOR_BROADCOM is not set +# CONFIG_NET_VENDOR_INTEL is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_STMICRO is not set +# CONFIG_NET_VENDOR_WIZNET is not set CONFIG_PPP=m -CONFIG_PPP_FILTER=y -CONFIG_PPP_ASYNC=m -CONFIG_PPP_SYNC_TTY=m -CONFIG_PPP_DEFLATE=m CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_FILTER=y CONFIG_PPP_MPPE=m CONFIG_PPPOE=m +CONFIG_PPTP=m +CONFIG_PPPOL2TP=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m CONFIG_SLIP=m CONFIG_SLIP_COMPRESSED=y CONFIG_SLIP_SMART=y CONFIG_SLIP_MODE_SLIP6=y -CONFIG_NETCONSOLE=m -CONFIG_NETCONSOLE_DYNAMIC=y -CONFIG_INPUT_FF_MEMLESS=m +# CONFIG_WLAN is not set +CONFIG_INPUT_EVDEV=m CONFIG_KEYBOARD_ATARI=y # CONFIG_KEYBOARD_ATKBD is not set -CONFIG_MOUSE_PS2=m +# CONFIG_MOUSE_PS2 is not set CONFIG_MOUSE_ATARI=m CONFIG_INPUT_MISC=y CONFIG_INPUT_M68K_BEEP=m -# CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO is not set CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_LEGACY_PTYS is not set # CONFIG_DEVKMEM is not set CONFIG_PRINTER=m # CONFIG_HW_RANDOM is not set -CONFIG_GEN_RTC=m -CONFIG_GEN_RTC_X=y +CONFIG_NTP_PPS=y +CONFIG_PPS_CLIENT_LDISC=m +CONFIG_PPS_CLIENT_PARPORT=m +CONFIG_PTP_1588_CLOCK=m # CONFIG_HWMON is not set CONFIG_FB=y CONFIG_FB_ATARI=y @@ -233,47 +309,64 @@ CONFIG_SOUND=m CONFIG_DMASOUND_ATARI=m CONFIG_HID=m CONFIG_HIDRAW=y -# CONFIG_USB_SUPPORT is not set +CONFIG_UHID=m +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_GENERIC=m +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_HEARTBEAT=y +CONFIG_PROC_HARDWARE=y +CONFIG_NATFEAT=y +CONFIG_NFBLOCK=y +CONFIG_NFCON=y +CONFIG_NFETH=y CONFIG_ATARI_DSP56K=m CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set # CONFIG_EXT3_FS_XATTR is not set +CONFIG_EXT4_FS=y CONFIG_REISERFS_FS=m CONFIG_JFS_FS=m CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m -# CONFIG_OCFS2_FS_STATS is not set # CONFIG_OCFS2_DEBUG_MASKLOG is not set +CONFIG_FANOTIFY=y CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set -CONFIG_AUTOFS_FS=m CONFIG_AUTOFS4_FS=m CONFIG_FUSE_FS=m +CONFIG_CUSE=m CONFIG_ISO9660_FS=y CONFIG_JOLIET=y CONFIG_ZISOFS=y CONFIG_UDF_FS=m -CONFIG_MSDOS_FS=y +CONFIG_MSDOS_FS=m CONFIG_VFAT_FS=m CONFIG_PROC_KCORE=y CONFIG_TMPFS=y CONFIG_AFFS_FS=m +CONFIG_ECRYPT_FS=m +CONFIG_ECRYPT_FS_MESSAGING=y CONFIG_HFS_FS=m CONFIG_HFSPLUS_FS=m CONFIG_CRAMFS=m CONFIG_SQUASHFS=m -CONFIG_MINIX_FS=y +CONFIG_SQUASHFS_LZO=y +CONFIG_MINIX_FS=m +CONFIG_OMFS_FS=m CONFIG_HPFS_FS=m +CONFIG_QNX4FS_FS=m +CONFIG_QNX6FS_FS=m CONFIG_SYSV_FS=m CONFIG_UFS_FS=m CONFIG_NFS_FS=y -CONFIG_NFS_V3=y CONFIG_NFS_V4=y +CONFIG_NFS_SWAP=y +CONFIG_ROOT_NFS=y CONFIG_NFSD=m CONFIG_NFSD_V3=y -CONFIG_SMB_FS=m -CONFIG_SMB_NLS_DEFAULT=y +CONFIG_CIFS=m +# CONFIG_CIFS_DEBUG is not set CONFIG_CODA_FS=m CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_CODEPAGE_737=m @@ -312,10 +405,23 @@ CONFIG_NLS_ISO8859_14=m CONFIG_NLS_ISO8859_15=m CONFIG_NLS_KOI8_R=m CONFIG_NLS_KOI8_U=m +CONFIG_NLS_MAC_ROMAN=m +CONFIG_NLS_MAC_CELTIC=m +CONFIG_NLS_MAC_CENTEURO=m +CONFIG_NLS_MAC_CROATIAN=m +CONFIG_NLS_MAC_CYRILLIC=m +CONFIG_NLS_MAC_GAELIC=m +CONFIG_NLS_MAC_GREEK=m +CONFIG_NLS_MAC_ICELAND=m +CONFIG_NLS_MAC_INUIT=m +CONFIG_NLS_MAC_ROMANIAN=m +CONFIG_NLS_MAC_TURKISH=m CONFIG_DLM=m CONFIG_MAGIC_SYSRQ=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y +CONFIG_ASYNC_RAID6_TEST=m +CONFIG_ENCRYPTED_KEYS=m +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_USER=m CONFIG_CRYPTO_NULL=m CONFIG_CRYPTO_CRYPTD=m CONFIG_CRYPTO_TEST=m @@ -325,19 +431,16 @@ CONFIG_CRYPTO_CTS=m CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_PCBC=m CONFIG_CRYPTO_XTS=m -CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_XCBC=m -CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_VMAC=m CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_RMD128=m CONFIG_CRYPTO_RMD160=m CONFIG_CRYPTO_RMD256=m CONFIG_CRYPTO_RMD320=m -CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m CONFIG_CRYPTO_TGR192=m CONFIG_CRYPTO_WP512=m -CONFIG_CRYPTO_AES=m CONFIG_CRYPTO_ANUBIS=m CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_CAMELLIA=m @@ -353,6 +456,14 @@ CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_ZLIB=m CONFIG_CRYPTO_LZO=m # CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_USER_API_HASH=m +CONFIG_CRYPTO_USER_API_SKCIPHER=m # CONFIG_CRYPTO_HW is not set -CONFIG_CRC16=y CONFIG_CRC_T10DIF=y +CONFIG_XZ_DEC_X86=y +CONFIG_XZ_DEC_POWERPC=y +CONFIG_XZ_DEC_IA64=y +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_ARMTHUMB=y +CONFIG_XZ_DEC_SPARC=y +CONFIG_XZ_DEC_TEST=m diff --git a/arch/m68k/configs/bvme6000_defconfig b/arch/m68k/configs/bvme6000_defconfig index 12f211733ba0..c015ddb6fd80 100644 --- a/arch/m68k/configs/bvme6000_defconfig +++ b/arch/m68k/configs/bvme6000_defconfig @@ -1,53 +1,74 @@ -CONFIG_EXPERIMENTAL=y CONFIG_LOCALVERSION="-bvme6000" CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y +CONFIG_FHANDLE=y CONFIG_BSD_PROCESS_ACCT=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_RELAY=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_LOG_BUF_SHIFT=16 +# CONFIG_UTS_NS is not set +# CONFIG_IPC_NS is not set +# CONFIG_PID_NS is not set +# CONFIG_NET_NS is not set CONFIG_BLK_DEV_INITRD=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SLAB=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y -CONFIG_VME=y -CONFIG_BVME6000=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_AMIGA_PARTITION=y +CONFIG_ATARI_PARTITION=y +CONFIG_MAC_PARTITION=y +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_SUN_PARTITION=y +# CONFIG_EFI_PARTITION is not set +CONFIG_IOSCHED_DEADLINE=m CONFIG_M68040=y CONFIG_M68060=y +CONFIG_VME=y +CONFIG_BVME6000=y +# CONFIG_COMPACTION is not set +CONFIG_CLEANCACHE=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_BINFMT_AOUT=m CONFIG_BINFMT_MISC=m -CONFIG_PROC_HARDWARE=y CONFIG_NET=y CONFIG_PACKET=y +CONFIG_PACKET_DIAG=m CONFIG_UNIX=y +CONFIG_UNIX_DIAG=m +CONFIG_XFRM_MIGRATE=y CONFIG_NET_KEY=y -CONFIG_NET_KEY_MIGRATE=y CONFIG_INET=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_IP_PNP_RARP=y CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE_DEMUX=m CONFIG_NET_IPGRE=m CONFIG_SYN_COOKIES=y +CONFIG_NET_IPVTI=m CONFIG_INET_AH=m CONFIG_INET_ESP=m CONFIG_INET_IPCOMP=m CONFIG_INET_XFRM_MODE_TRANSPORT=m CONFIG_INET_XFRM_MODE_TUNNEL=m CONFIG_INET_XFRM_MODE_BEET=m +# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=m +CONFIG_INET_UDP_DIAG=m CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y -CONFIG_IPV6_ROUTE_INFO=y CONFIG_INET6_AH=m CONFIG_INET6_ESP=m CONFIG_INET6_IPCOMP=m -CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m -CONFIG_IPV6_TUNNEL=m +CONFIG_IPV6_GRE=m CONFIG_NETFILTER=y -CONFIG_NETFILTER_NETLINK_QUEUE=m CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_ZONES=y +# CONFIG_NF_CONNTRACK_PROCFS is not set # CONFIG_NF_CT_PROTO_DCCP is not set CONFIG_NF_CT_PROTO_UDPLITE=m CONFIG_NF_CONNTRACK_AMANDA=m @@ -55,25 +76,37 @@ CONFIG_NF_CONNTRACK_FTP=m CONFIG_NF_CONNTRACK_H323=m CONFIG_NF_CONNTRACK_IRC=m CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_SNMP=m CONFIG_NF_CONNTRACK_PPTP=m CONFIG_NF_CONNTRACK_SANE=m CONFIG_NF_CONNTRACK_SIP=m CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NETFILTER_XT_SET=m +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m CONFIG_NETFILTER_XT_TARGET_CONNMARK=m CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HMARK=m +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m +CONFIG_NETFILTER_XT_TARGET_LOG=m CONFIG_NETFILTER_XT_TARGET_MARK=m CONFIG_NETFILTER_XT_TARGET_NFLOG=m CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_TEE=m CONFIG_NETFILTER_XT_TARGET_TRACE=m CONFIG_NETFILTER_XT_TARGET_TCPMSS=m CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +CONFIG_NETFILTER_XT_MATCH_BPF=m CONFIG_NETFILTER_XT_MATCH_CLUSTER=m CONFIG_NETFILTER_XT_MATCH_COMMENT=m CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m CONFIG_NETFILTER_XT_MATCH_CONNMARK=m CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m CONFIG_NETFILTER_XT_MATCH_DSCP=m CONFIG_NETFILTER_XT_MATCH_ESP=m CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m @@ -84,6 +117,8 @@ CONFIG_NETFILTER_XT_MATCH_LIMIT=m CONFIG_NETFILTER_XT_MATCH_MAC=m CONFIG_NETFILTER_XT_MATCH_MARK=m CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_NFACCT=m +CONFIG_NETFILTER_XT_MATCH_OSF=m CONFIG_NETFILTER_XT_MATCH_OWNER=m CONFIG_NETFILTER_XT_MATCH_POLICY=m CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m @@ -97,22 +132,31 @@ CONFIG_NETFILTER_XT_MATCH_STRING=m CONFIG_NETFILTER_XT_MATCH_TCPMSS=m CONFIG_NETFILTER_XT_MATCH_TIME=m CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_IP_SET=m +CONFIG_IP_SET_BITMAP_IP=m +CONFIG_IP_SET_BITMAP_IPMAC=m +CONFIG_IP_SET_BITMAP_PORT=m +CONFIG_IP_SET_HASH_IP=m +CONFIG_IP_SET_HASH_IPPORT=m +CONFIG_IP_SET_HASH_IPPORTIP=m +CONFIG_IP_SET_HASH_IPPORTNET=m +CONFIG_IP_SET_HASH_NET=m +CONFIG_IP_SET_HASH_NETPORT=m +CONFIG_IP_SET_HASH_NETIFACE=m +CONFIG_IP_SET_LIST_SET=m CONFIG_NF_CONNTRACK_IPV4=m -CONFIG_IP_NF_QUEUE=m CONFIG_IP_NF_IPTABLES=m -CONFIG_IP_NF_MATCH_ADDRTYPE=m CONFIG_IP_NF_MATCH_AH=m CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_RPFILTER=m CONFIG_IP_NF_MATCH_TTL=m CONFIG_IP_NF_FILTER=m CONFIG_IP_NF_TARGET_REJECT=m -CONFIG_IP_NF_TARGET_LOG=m CONFIG_IP_NF_TARGET_ULOG=m -CONFIG_NF_NAT=m +CONFIG_NF_NAT_IPV4=m CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_REDIRECT=m -CONFIG_NF_NAT_SNMP_BASIC=m CONFIG_IP_NF_MANGLE=m CONFIG_IP_NF_TARGET_CLUSTERIP=m CONFIG_IP_NF_TARGET_ECN=m @@ -122,7 +166,6 @@ CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m CONFIG_NF_CONNTRACK_IPV6=m -CONFIG_IP6_NF_QUEUE=m CONFIG_IP6_NF_IPTABLES=m CONFIG_IP6_NF_MATCH_AH=m CONFIG_IP6_NF_MATCH_EUI64=m @@ -131,21 +174,34 @@ CONFIG_IP6_NF_MATCH_OPTS=m CONFIG_IP6_NF_MATCH_HL=m CONFIG_IP6_NF_MATCH_IPV6HEADER=m CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_RPFILTER=m CONFIG_IP6_NF_MATCH_RT=m CONFIG_IP6_NF_TARGET_HL=m -CONFIG_IP6_NF_TARGET_LOG=m CONFIG_IP6_NF_FILTER=m CONFIG_IP6_NF_TARGET_REJECT=m CONFIG_IP6_NF_MANGLE=m CONFIG_IP6_NF_RAW=m +CONFIG_NF_NAT_IPV6=m +CONFIG_IP6_NF_TARGET_MASQUERADE=m +CONFIG_IP6_NF_TARGET_NPT=m CONFIG_IP_DCCP=m # CONFIG_IP_DCCP_CCID3 is not set +CONFIG_SCTP_COOKIE_HMAC_SHA1=y +CONFIG_RDS=m +CONFIG_RDS_TCP=m +CONFIG_L2TP=m CONFIG_ATALK=m +CONFIG_BATMAN_ADV=m +CONFIG_BATMAN_ADV_DAT=y +# CONFIG_WIRELESS is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y # CONFIG_FIRMWARE_IN_KERNEL is not set +# CONFIG_FW_LOADER_USER_HELPER is not set CONFIG_CONNECTOR=m CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_DRBD=m CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=y CONFIG_CDROM_PKTCDVD=m @@ -160,103 +216,131 @@ CONFIG_BLK_DEV_SR=y CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y -CONFIG_SCSI_SAS_LIBSAS=m -# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set -CONFIG_SCSI_SRP_ATTRS=m -CONFIG_SCSI_SRP_TGT_ATTRS=y +CONFIG_SCSI_SAS_ATTRS=m CONFIG_ISCSI_TCP=m +CONFIG_ISCSI_BOOT_SYSFS=m CONFIG_BVME6000_SCSI=y CONFIG_MD=y -CONFIG_BLK_DEV_MD=m CONFIG_MD_LINEAR=m CONFIG_MD_RAID0=m -CONFIG_MD_RAID1=m -CONFIG_MD_RAID456=m CONFIG_BLK_DEV_DM=m CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m +CONFIG_DM_THIN_PROVISIONING=m +CONFIG_DM_CACHE=m CONFIG_DM_MIRROR=m +CONFIG_DM_RAID=m CONFIG_DM_ZERO=m CONFIG_DM_MULTIPATH=m CONFIG_DM_UEVENT=y +CONFIG_TARGET_CORE=m +CONFIG_TCM_IBLOCK=m +CONFIG_TCM_FILEIO=m +CONFIG_TCM_PSCSI=m CONFIG_NETDEVICES=y CONFIG_DUMMY=m -CONFIG_MACVLAN=m CONFIG_EQUALIZER=m +CONFIG_NET_TEAM=m +CONFIG_NET_TEAM_MODE_BROADCAST=m +CONFIG_NET_TEAM_MODE_ROUNDROBIN=m +CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m +CONFIG_NET_TEAM_MODE_LOADBALANCE=m +CONFIG_VXLAN=m +CONFIG_NETCONSOLE=m +CONFIG_NETCONSOLE_DYNAMIC=y CONFIG_VETH=m -CONFIG_NET_ETHERNET=y +# CONFIG_NET_CADENCE is not set +# CONFIG_NET_VENDOR_BROADCOM is not set CONFIG_BVME6000_NET=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_STMICRO is not set +# CONFIG_NET_VENDOR_WIZNET is not set CONFIG_PPP=m -CONFIG_PPP_FILTER=y -CONFIG_PPP_ASYNC=m -CONFIG_PPP_SYNC_TTY=m -CONFIG_PPP_DEFLATE=m CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_FILTER=y CONFIG_PPP_MPPE=m CONFIG_PPPOE=m +CONFIG_PPTP=m +CONFIG_PPPOL2TP=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m CONFIG_SLIP=m CONFIG_SLIP_COMPRESSED=y CONFIG_SLIP_SMART=y CONFIG_SLIP_MODE_SLIP6=y -CONFIG_NETCONSOLE=m -CONFIG_NETCONSOLE_DYNAMIC=y -CONFIG_INPUT_FF_MEMLESS=m +# CONFIG_WLAN is not set +CONFIG_INPUT_EVDEV=m # CONFIG_KEYBOARD_ATKBD is not set -CONFIG_MOUSE_PS2=m -CONFIG_MOUSE_SERIAL=m -CONFIG_SERIO=m -# CONFIG_SERIO_SERPORT is not set +# CONFIG_MOUSE_PS2 is not set +# CONFIG_SERIO is not set CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_LEGACY_PTYS is not set # CONFIG_DEVKMEM is not set # CONFIG_HW_RANDOM is not set -CONFIG_GEN_RTC=m -CONFIG_GEN_RTC_X=y +CONFIG_NTP_PPS=y +CONFIG_PPS_CLIENT_LDISC=m +CONFIG_PTP_1588_CLOCK=m # CONFIG_HWMON is not set CONFIG_HID=m CONFIG_HIDRAW=y +CONFIG_UHID=m +# CONFIG_HID_GENERIC is not set # CONFIG_USB_SUPPORT is not set +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_GENERIC=m +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_PROC_HARDWARE=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set # CONFIG_EXT3_FS_XATTR is not set +CONFIG_EXT4_FS=y CONFIG_REISERFS_FS=m CONFIG_JFS_FS=m CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m -# CONFIG_OCFS2_FS_STATS is not set # CONFIG_OCFS2_DEBUG_MASKLOG is not set +CONFIG_FANOTIFY=y CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set -CONFIG_AUTOFS_FS=m CONFIG_AUTOFS4_FS=m CONFIG_FUSE_FS=m +CONFIG_CUSE=m CONFIG_ISO9660_FS=y CONFIG_JOLIET=y CONFIG_ZISOFS=y CONFIG_UDF_FS=m -CONFIG_MSDOS_FS=y +CONFIG_MSDOS_FS=m CONFIG_VFAT_FS=m CONFIG_PROC_KCORE=y CONFIG_TMPFS=y CONFIG_AFFS_FS=m +CONFIG_ECRYPT_FS=m +CONFIG_ECRYPT_FS_MESSAGING=y CONFIG_HFS_FS=m CONFIG_HFSPLUS_FS=m CONFIG_CRAMFS=m CONFIG_SQUASHFS=m -CONFIG_MINIX_FS=y +CONFIG_SQUASHFS_LZO=y +CONFIG_MINIX_FS=m +CONFIG_OMFS_FS=m CONFIG_HPFS_FS=m +CONFIG_QNX4FS_FS=m +CONFIG_QNX6FS_FS=m CONFIG_SYSV_FS=m CONFIG_UFS_FS=m CONFIG_NFS_FS=y -CONFIG_NFS_V3=y CONFIG_NFS_V4=y +CONFIG_NFS_SWAP=y CONFIG_ROOT_NFS=y CONFIG_NFSD=m CONFIG_NFSD_V3=y -CONFIG_SMB_FS=m -CONFIG_SMB_NLS_DEFAULT=y +CONFIG_CIFS=m +# CONFIG_CIFS_DEBUG is not set CONFIG_CODA_FS=m CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_CODEPAGE_737=m @@ -295,10 +379,23 @@ CONFIG_NLS_ISO8859_14=m CONFIG_NLS_ISO8859_15=m CONFIG_NLS_KOI8_R=m CONFIG_NLS_KOI8_U=m +CONFIG_NLS_MAC_ROMAN=m +CONFIG_NLS_MAC_CELTIC=m +CONFIG_NLS_MAC_CENTEURO=m +CONFIG_NLS_MAC_CROATIAN=m +CONFIG_NLS_MAC_CYRILLIC=m +CONFIG_NLS_MAC_GAELIC=m +CONFIG_NLS_MAC_GREEK=m +CONFIG_NLS_MAC_ICELAND=m +CONFIG_NLS_MAC_INUIT=m +CONFIG_NLS_MAC_ROMANIAN=m +CONFIG_NLS_MAC_TURKISH=m CONFIG_DLM=m CONFIG_MAGIC_SYSRQ=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y +CONFIG_ASYNC_RAID6_TEST=m +CONFIG_ENCRYPTED_KEYS=m +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_USER=m CONFIG_CRYPTO_NULL=m CONFIG_CRYPTO_CRYPTD=m CONFIG_CRYPTO_TEST=m @@ -308,19 +405,16 @@ CONFIG_CRYPTO_CTS=m CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_PCBC=m CONFIG_CRYPTO_XTS=m -CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_XCBC=m -CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_VMAC=m CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_RMD128=m CONFIG_CRYPTO_RMD160=m CONFIG_CRYPTO_RMD256=m CONFIG_CRYPTO_RMD320=m -CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m CONFIG_CRYPTO_TGR192=m CONFIG_CRYPTO_WP512=m -CONFIG_CRYPTO_AES=m CONFIG_CRYPTO_ANUBIS=m CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_CAMELLIA=m @@ -336,7 +430,14 @@ CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_ZLIB=m CONFIG_CRYPTO_LZO=m # CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_USER_API_HASH=m +CONFIG_CRYPTO_USER_API_SKCIPHER=m # CONFIG_CRYPTO_HW is not set -CONFIG_CRC16=m CONFIG_CRC_T10DIF=y -CONFIG_CRC32=m +CONFIG_XZ_DEC_X86=y +CONFIG_XZ_DEC_POWERPC=y +CONFIG_XZ_DEC_IA64=y +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_ARMTHUMB=y +CONFIG_XZ_DEC_SPARC=y +CONFIG_XZ_DEC_TEST=m diff --git a/arch/m68k/configs/hp300_defconfig b/arch/m68k/configs/hp300_defconfig index 215389a5407f..ec7382d8afff 100644 --- a/arch/m68k/configs/hp300_defconfig +++ b/arch/m68k/configs/hp300_defconfig @@ -1,54 +1,76 @@ -CONFIG_EXPERIMENTAL=y CONFIG_LOCALVERSION="-hp300" CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y +CONFIG_FHANDLE=y CONFIG_BSD_PROCESS_ACCT=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_RELAY=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_LOG_BUF_SHIFT=16 +# CONFIG_UTS_NS is not set +# CONFIG_IPC_NS is not set +# CONFIG_PID_NS is not set +# CONFIG_NET_NS is not set CONFIG_BLK_DEV_INITRD=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SLAB=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y -CONFIG_HP300=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_AMIGA_PARTITION=y +CONFIG_ATARI_PARTITION=y +CONFIG_MAC_PARTITION=y +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_SUN_PARTITION=y +# CONFIG_EFI_PARTITION is not set +CONFIG_SYSV68_PARTITION=y +CONFIG_IOSCHED_DEADLINE=m CONFIG_M68020=y CONFIG_M68030=y CONFIG_M68040=y CONFIG_M68060=y +CONFIG_HP300=y +# CONFIG_COMPACTION is not set +CONFIG_CLEANCACHE=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_BINFMT_AOUT=m CONFIG_BINFMT_MISC=m -CONFIG_PROC_HARDWARE=y CONFIG_NET=y CONFIG_PACKET=y +CONFIG_PACKET_DIAG=m CONFIG_UNIX=y +CONFIG_UNIX_DIAG=m +CONFIG_XFRM_MIGRATE=y CONFIG_NET_KEY=y -CONFIG_NET_KEY_MIGRATE=y CONFIG_INET=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_IP_PNP_RARP=y CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE_DEMUX=m CONFIG_NET_IPGRE=m CONFIG_SYN_COOKIES=y +CONFIG_NET_IPVTI=m CONFIG_INET_AH=m CONFIG_INET_ESP=m CONFIG_INET_IPCOMP=m CONFIG_INET_XFRM_MODE_TRANSPORT=m CONFIG_INET_XFRM_MODE_TUNNEL=m CONFIG_INET_XFRM_MODE_BEET=m +# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=m +CONFIG_INET_UDP_DIAG=m CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y -CONFIG_IPV6_ROUTE_INFO=y CONFIG_INET6_AH=m CONFIG_INET6_ESP=m CONFIG_INET6_IPCOMP=m -CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m -CONFIG_IPV6_TUNNEL=m +CONFIG_IPV6_GRE=m CONFIG_NETFILTER=y -CONFIG_NETFILTER_NETLINK_QUEUE=m CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_ZONES=y +# CONFIG_NF_CONNTRACK_PROCFS is not set # CONFIG_NF_CT_PROTO_DCCP is not set CONFIG_NF_CT_PROTO_UDPLITE=m CONFIG_NF_CONNTRACK_AMANDA=m @@ -56,25 +78,37 @@ CONFIG_NF_CONNTRACK_FTP=m CONFIG_NF_CONNTRACK_H323=m CONFIG_NF_CONNTRACK_IRC=m CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_SNMP=m CONFIG_NF_CONNTRACK_PPTP=m CONFIG_NF_CONNTRACK_SANE=m CONFIG_NF_CONNTRACK_SIP=m CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NETFILTER_XT_SET=m +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m CONFIG_NETFILTER_XT_TARGET_CONNMARK=m CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HMARK=m +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m +CONFIG_NETFILTER_XT_TARGET_LOG=m CONFIG_NETFILTER_XT_TARGET_MARK=m CONFIG_NETFILTER_XT_TARGET_NFLOG=m CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_TEE=m CONFIG_NETFILTER_XT_TARGET_TRACE=m CONFIG_NETFILTER_XT_TARGET_TCPMSS=m CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +CONFIG_NETFILTER_XT_MATCH_BPF=m CONFIG_NETFILTER_XT_MATCH_CLUSTER=m CONFIG_NETFILTER_XT_MATCH_COMMENT=m CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m CONFIG_NETFILTER_XT_MATCH_CONNMARK=m CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m CONFIG_NETFILTER_XT_MATCH_DSCP=m CONFIG_NETFILTER_XT_MATCH_ESP=m CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m @@ -85,6 +119,8 @@ CONFIG_NETFILTER_XT_MATCH_LIMIT=m CONFIG_NETFILTER_XT_MATCH_MAC=m CONFIG_NETFILTER_XT_MATCH_MARK=m CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_NFACCT=m +CONFIG_NETFILTER_XT_MATCH_OSF=m CONFIG_NETFILTER_XT_MATCH_OWNER=m CONFIG_NETFILTER_XT_MATCH_POLICY=m CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m @@ -98,22 +134,31 @@ CONFIG_NETFILTER_XT_MATCH_STRING=m CONFIG_NETFILTER_XT_MATCH_TCPMSS=m CONFIG_NETFILTER_XT_MATCH_TIME=m CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_IP_SET=m +CONFIG_IP_SET_BITMAP_IP=m +CONFIG_IP_SET_BITMAP_IPMAC=m +CONFIG_IP_SET_BITMAP_PORT=m +CONFIG_IP_SET_HASH_IP=m +CONFIG_IP_SET_HASH_IPPORT=m +CONFIG_IP_SET_HASH_IPPORTIP=m +CONFIG_IP_SET_HASH_IPPORTNET=m +CONFIG_IP_SET_HASH_NET=m +CONFIG_IP_SET_HASH_NETPORT=m +CONFIG_IP_SET_HASH_NETIFACE=m +CONFIG_IP_SET_LIST_SET=m CONFIG_NF_CONNTRACK_IPV4=m -CONFIG_IP_NF_QUEUE=m CONFIG_IP_NF_IPTABLES=m -CONFIG_IP_NF_MATCH_ADDRTYPE=m CONFIG_IP_NF_MATCH_AH=m CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_RPFILTER=m CONFIG_IP_NF_MATCH_TTL=m CONFIG_IP_NF_FILTER=m CONFIG_IP_NF_TARGET_REJECT=m -CONFIG_IP_NF_TARGET_LOG=m CONFIG_IP_NF_TARGET_ULOG=m -CONFIG_NF_NAT=m +CONFIG_NF_NAT_IPV4=m CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_REDIRECT=m -CONFIG_NF_NAT_SNMP_BASIC=m CONFIG_IP_NF_MANGLE=m CONFIG_IP_NF_TARGET_CLUSTERIP=m CONFIG_IP_NF_TARGET_ECN=m @@ -123,7 +168,6 @@ CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m CONFIG_NF_CONNTRACK_IPV6=m -CONFIG_IP6_NF_QUEUE=m CONFIG_IP6_NF_IPTABLES=m CONFIG_IP6_NF_MATCH_AH=m CONFIG_IP6_NF_MATCH_EUI64=m @@ -132,21 +176,34 @@ CONFIG_IP6_NF_MATCH_OPTS=m CONFIG_IP6_NF_MATCH_HL=m CONFIG_IP6_NF_MATCH_IPV6HEADER=m CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_RPFILTER=m CONFIG_IP6_NF_MATCH_RT=m CONFIG_IP6_NF_TARGET_HL=m -CONFIG_IP6_NF_TARGET_LOG=m CONFIG_IP6_NF_FILTER=m CONFIG_IP6_NF_TARGET_REJECT=m CONFIG_IP6_NF_MANGLE=m CONFIG_IP6_NF_RAW=m +CONFIG_NF_NAT_IPV6=m +CONFIG_IP6_NF_TARGET_MASQUERADE=m +CONFIG_IP6_NF_TARGET_NPT=m CONFIG_IP_DCCP=m # CONFIG_IP_DCCP_CCID3 is not set +CONFIG_SCTP_COOKIE_HMAC_SHA1=y +CONFIG_RDS=m +CONFIG_RDS_TCP=m +CONFIG_L2TP=m CONFIG_ATALK=m +CONFIG_BATMAN_ADV=m +CONFIG_BATMAN_ADV_DAT=y +# CONFIG_WIRELESS is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y # CONFIG_FIRMWARE_IN_KERNEL is not set +# CONFIG_FW_LOADER_USER_HELPER is not set CONFIG_CONNECTOR=m CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_DRBD=m CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=y CONFIG_CDROM_PKTCDVD=m @@ -161,59 +218,77 @@ CONFIG_BLK_DEV_SR=y CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y -CONFIG_SCSI_SAS_LIBSAS=m -# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set -CONFIG_SCSI_SRP_ATTRS=m -CONFIG_SCSI_SRP_TGT_ATTRS=y +CONFIG_SCSI_SAS_ATTRS=m CONFIG_ISCSI_TCP=m +CONFIG_ISCSI_BOOT_SYSFS=m CONFIG_MD=y -CONFIG_BLK_DEV_MD=m CONFIG_MD_LINEAR=m CONFIG_MD_RAID0=m -CONFIG_MD_RAID1=m -CONFIG_MD_RAID456=m CONFIG_BLK_DEV_DM=m CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m +CONFIG_DM_THIN_PROVISIONING=m +CONFIG_DM_CACHE=m CONFIG_DM_MIRROR=m +CONFIG_DM_RAID=m CONFIG_DM_ZERO=m CONFIG_DM_MULTIPATH=m CONFIG_DM_UEVENT=y +CONFIG_TARGET_CORE=m +CONFIG_TCM_IBLOCK=m +CONFIG_TCM_FILEIO=m +CONFIG_TCM_PSCSI=m CONFIG_NETDEVICES=y CONFIG_DUMMY=m -CONFIG_MACVLAN=m CONFIG_EQUALIZER=m +CONFIG_NET_TEAM=m +CONFIG_NET_TEAM_MODE_BROADCAST=m +CONFIG_NET_TEAM_MODE_ROUNDROBIN=m +CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m +CONFIG_NET_TEAM_MODE_LOADBALANCE=m +CONFIG_VXLAN=m +CONFIG_NETCONSOLE=m +CONFIG_NETCONSOLE_DYNAMIC=y CONFIG_VETH=m -CONFIG_NET_ETHERNET=y CONFIG_HPLANCE=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set +# CONFIG_NET_CADENCE is not set +# CONFIG_NET_VENDOR_BROADCOM is not set +# CONFIG_NET_VENDOR_INTEL is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_STMICRO is not set +# CONFIG_NET_VENDOR_WIZNET is not set CONFIG_PPP=m -CONFIG_PPP_FILTER=y -CONFIG_PPP_ASYNC=m -CONFIG_PPP_SYNC_TTY=m -CONFIG_PPP_DEFLATE=m CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_FILTER=y CONFIG_PPP_MPPE=m CONFIG_PPPOE=m +CONFIG_PPTP=m +CONFIG_PPPOL2TP=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m CONFIG_SLIP=m CONFIG_SLIP_COMPRESSED=y CONFIG_SLIP_SMART=y CONFIG_SLIP_MODE_SLIP6=y -CONFIG_NETCONSOLE=m -CONFIG_NETCONSOLE_DYNAMIC=y -CONFIG_INPUT_FF_MEMLESS=m +# CONFIG_WLAN is not set +CONFIG_INPUT_EVDEV=m # CONFIG_KEYBOARD_ATKBD is not set -CONFIG_MOUSE_PS2=m +# CONFIG_MOUSE_PS2 is not set CONFIG_MOUSE_SERIAL=m CONFIG_INPUT_MISC=y CONFIG_HP_SDC_RTC=m -# CONFIG_SERIO_SERPORT is not set +CONFIG_SERIO_SERPORT=m CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_LEGACY_PTYS is not set # CONFIG_DEVKMEM is not set # CONFIG_HW_RANDOM is not set -CONFIG_GEN_RTC=m -CONFIG_GEN_RTC_X=y +CONFIG_NTP_PPS=y +CONFIG_PPS_CLIENT_LDISC=m +CONFIG_PTP_1588_CLOCK=m # CONFIG_HWMON is not set CONFIG_FB=y CONFIG_FRAMEBUFFER_CONSOLE=y @@ -222,47 +297,60 @@ CONFIG_LOGO=y # CONFIG_LOGO_LINUX_VGA16 is not set CONFIG_HID=m CONFIG_HIDRAW=y +CONFIG_UHID=m +# CONFIG_HID_GENERIC is not set # CONFIG_USB_SUPPORT is not set +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_GENERIC=m +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_PROC_HARDWARE=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set # CONFIG_EXT3_FS_XATTR is not set +CONFIG_EXT4_FS=y CONFIG_REISERFS_FS=m CONFIG_JFS_FS=m CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m -# CONFIG_OCFS2_FS_STATS is not set # CONFIG_OCFS2_DEBUG_MASKLOG is not set +CONFIG_FANOTIFY=y CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set -CONFIG_AUTOFS_FS=m CONFIG_AUTOFS4_FS=m CONFIG_FUSE_FS=m +CONFIG_CUSE=m CONFIG_ISO9660_FS=y CONFIG_JOLIET=y CONFIG_ZISOFS=y CONFIG_UDF_FS=m -CONFIG_MSDOS_FS=y +CONFIG_MSDOS_FS=m CONFIG_VFAT_FS=m CONFIG_PROC_KCORE=y CONFIG_TMPFS=y CONFIG_AFFS_FS=m +CONFIG_ECRYPT_FS=m +CONFIG_ECRYPT_FS_MESSAGING=y CONFIG_HFS_FS=m CONFIG_HFSPLUS_FS=m CONFIG_CRAMFS=m CONFIG_SQUASHFS=m -CONFIG_MINIX_FS=y +CONFIG_SQUASHFS_LZO=y +CONFIG_MINIX_FS=m +CONFIG_OMFS_FS=m CONFIG_HPFS_FS=m +CONFIG_QNX4FS_FS=m +CONFIG_QNX6FS_FS=m CONFIG_SYSV_FS=m CONFIG_UFS_FS=m CONFIG_NFS_FS=y -CONFIG_NFS_V3=y CONFIG_NFS_V4=y +CONFIG_NFS_SWAP=y CONFIG_ROOT_NFS=y CONFIG_NFSD=m CONFIG_NFSD_V3=y -CONFIG_SMB_FS=m -CONFIG_SMB_NLS_DEFAULT=y +CONFIG_CIFS=m +# CONFIG_CIFS_DEBUG is not set CONFIG_CODA_FS=m CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_CODEPAGE_737=m @@ -301,10 +389,23 @@ CONFIG_NLS_ISO8859_14=m CONFIG_NLS_ISO8859_15=m CONFIG_NLS_KOI8_R=m CONFIG_NLS_KOI8_U=m +CONFIG_NLS_MAC_ROMAN=m +CONFIG_NLS_MAC_CELTIC=m +CONFIG_NLS_MAC_CENTEURO=m +CONFIG_NLS_MAC_CROATIAN=m +CONFIG_NLS_MAC_CYRILLIC=m +CONFIG_NLS_MAC_GAELIC=m +CONFIG_NLS_MAC_GREEK=m +CONFIG_NLS_MAC_ICELAND=m +CONFIG_NLS_MAC_INUIT=m +CONFIG_NLS_MAC_ROMANIAN=m +CONFIG_NLS_MAC_TURKISH=m CONFIG_DLM=m CONFIG_MAGIC_SYSRQ=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y +CONFIG_ASYNC_RAID6_TEST=m +CONFIG_ENCRYPTED_KEYS=m +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_USER=m CONFIG_CRYPTO_NULL=m CONFIG_CRYPTO_CRYPTD=m CONFIG_CRYPTO_TEST=m @@ -314,19 +415,16 @@ CONFIG_CRYPTO_CTS=m CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_PCBC=m CONFIG_CRYPTO_XTS=m -CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_XCBC=m -CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_VMAC=m CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_RMD128=m CONFIG_CRYPTO_RMD160=m CONFIG_CRYPTO_RMD256=m CONFIG_CRYPTO_RMD320=m -CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m CONFIG_CRYPTO_TGR192=m CONFIG_CRYPTO_WP512=m -CONFIG_CRYPTO_AES=m CONFIG_CRYPTO_ANUBIS=m CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_CAMELLIA=m @@ -342,6 +440,14 @@ CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_ZLIB=m CONFIG_CRYPTO_LZO=m # CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_USER_API_HASH=m +CONFIG_CRYPTO_USER_API_SKCIPHER=m # CONFIG_CRYPTO_HW is not set -CONFIG_CRC16=m CONFIG_CRC_T10DIF=y +CONFIG_XZ_DEC_X86=y +CONFIG_XZ_DEC_POWERPC=y +CONFIG_XZ_DEC_IA64=y +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_ARMTHUMB=y +CONFIG_XZ_DEC_SPARC=y +CONFIG_XZ_DEC_TEST=m diff --git a/arch/m68k/configs/mac_defconfig b/arch/m68k/configs/mac_defconfig index cb9dfb30b674..7d46fbec7042 100644 --- a/arch/m68k/configs/mac_defconfig +++ b/arch/m68k/configs/mac_defconfig @@ -1,49 +1,75 @@ -CONFIG_EXPERIMENTAL=y CONFIG_LOCALVERSION="-mac" CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y +CONFIG_FHANDLE=y CONFIG_BSD_PROCESS_ACCT=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_RELAY=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_LOG_BUF_SHIFT=16 +# CONFIG_UTS_NS is not set +# CONFIG_IPC_NS is not set +# CONFIG_PID_NS is not set +# CONFIG_NET_NS is not set CONFIG_BLK_DEV_INITRD=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SLAB=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y -CONFIG_MAC=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_AMIGA_PARTITION=y +CONFIG_ATARI_PARTITION=y +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_SUN_PARTITION=y +# CONFIG_EFI_PARTITION is not set +CONFIG_SYSV68_PARTITION=y +CONFIG_IOSCHED_DEADLINE=m CONFIG_M68020=y CONFIG_M68030=y CONFIG_M68040=y +CONFIG_M68KFPU_EMU=y +CONFIG_MAC=y +# CONFIG_COMPACTION is not set +CONFIG_CLEANCACHE=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_BINFMT_AOUT=m CONFIG_BINFMT_MISC=m -CONFIG_PROC_HARDWARE=y CONFIG_NET=y CONFIG_PACKET=y +CONFIG_PACKET_DIAG=m CONFIG_UNIX=y +CONFIG_UNIX_DIAG=m +CONFIG_XFRM_MIGRATE=y CONFIG_NET_KEY=y -CONFIG_NET_KEY_MIGRATE=y CONFIG_INET=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE_DEMUX=m CONFIG_NET_IPGRE=m CONFIG_SYN_COOKIES=y +CONFIG_NET_IPVTI=m CONFIG_INET_AH=m CONFIG_INET_ESP=m CONFIG_INET_IPCOMP=m CONFIG_INET_XFRM_MODE_TRANSPORT=m CONFIG_INET_XFRM_MODE_TUNNEL=m CONFIG_INET_XFRM_MODE_BEET=m +# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=m +CONFIG_INET_UDP_DIAG=m CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y -CONFIG_IPV6_ROUTE_INFO=y CONFIG_INET6_AH=m CONFIG_INET6_ESP=m CONFIG_INET6_IPCOMP=m -CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m -CONFIG_IPV6_TUNNEL=m +CONFIG_IPV6_GRE=m CONFIG_NETFILTER=y -CONFIG_NETFILTER_NETLINK_QUEUE=m CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_ZONES=y +# CONFIG_NF_CONNTRACK_PROCFS is not set # CONFIG_NF_CT_PROTO_DCCP is not set CONFIG_NF_CT_PROTO_UDPLITE=m CONFIG_NF_CONNTRACK_AMANDA=m @@ -51,25 +77,37 @@ CONFIG_NF_CONNTRACK_FTP=m CONFIG_NF_CONNTRACK_H323=m CONFIG_NF_CONNTRACK_IRC=m CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_SNMP=m CONFIG_NF_CONNTRACK_PPTP=m CONFIG_NF_CONNTRACK_SANE=m CONFIG_NF_CONNTRACK_SIP=m CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NETFILTER_XT_SET=m +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m CONFIG_NETFILTER_XT_TARGET_CONNMARK=m CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HMARK=m +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m +CONFIG_NETFILTER_XT_TARGET_LOG=m CONFIG_NETFILTER_XT_TARGET_MARK=m CONFIG_NETFILTER_XT_TARGET_NFLOG=m CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_TEE=m CONFIG_NETFILTER_XT_TARGET_TRACE=m CONFIG_NETFILTER_XT_TARGET_TCPMSS=m CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +CONFIG_NETFILTER_XT_MATCH_BPF=m CONFIG_NETFILTER_XT_MATCH_CLUSTER=m CONFIG_NETFILTER_XT_MATCH_COMMENT=m CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m CONFIG_NETFILTER_XT_MATCH_CONNMARK=m CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m CONFIG_NETFILTER_XT_MATCH_DSCP=m CONFIG_NETFILTER_XT_MATCH_ESP=m CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m @@ -80,6 +118,8 @@ CONFIG_NETFILTER_XT_MATCH_LIMIT=m CONFIG_NETFILTER_XT_MATCH_MAC=m CONFIG_NETFILTER_XT_MATCH_MARK=m CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_NFACCT=m +CONFIG_NETFILTER_XT_MATCH_OSF=m CONFIG_NETFILTER_XT_MATCH_OWNER=m CONFIG_NETFILTER_XT_MATCH_POLICY=m CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m @@ -93,22 +133,31 @@ CONFIG_NETFILTER_XT_MATCH_STRING=m CONFIG_NETFILTER_XT_MATCH_TCPMSS=m CONFIG_NETFILTER_XT_MATCH_TIME=m CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_IP_SET=m +CONFIG_IP_SET_BITMAP_IP=m +CONFIG_IP_SET_BITMAP_IPMAC=m +CONFIG_IP_SET_BITMAP_PORT=m +CONFIG_IP_SET_HASH_IP=m +CONFIG_IP_SET_HASH_IPPORT=m +CONFIG_IP_SET_HASH_IPPORTIP=m +CONFIG_IP_SET_HASH_IPPORTNET=m +CONFIG_IP_SET_HASH_NET=m +CONFIG_IP_SET_HASH_NETPORT=m +CONFIG_IP_SET_HASH_NETIFACE=m +CONFIG_IP_SET_LIST_SET=m CONFIG_NF_CONNTRACK_IPV4=m -CONFIG_IP_NF_QUEUE=m CONFIG_IP_NF_IPTABLES=m -CONFIG_IP_NF_MATCH_ADDRTYPE=m CONFIG_IP_NF_MATCH_AH=m CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_RPFILTER=m CONFIG_IP_NF_MATCH_TTL=m CONFIG_IP_NF_FILTER=m CONFIG_IP_NF_TARGET_REJECT=m -CONFIG_IP_NF_TARGET_LOG=m CONFIG_IP_NF_TARGET_ULOG=m -CONFIG_NF_NAT=m +CONFIG_NF_NAT_IPV4=m CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_REDIRECT=m -CONFIG_NF_NAT_SNMP_BASIC=m CONFIG_IP_NF_MANGLE=m CONFIG_IP_NF_TARGET_CLUSTERIP=m CONFIG_IP_NF_TARGET_ECN=m @@ -118,7 +167,6 @@ CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m CONFIG_NF_CONNTRACK_IPV6=m -CONFIG_IP6_NF_QUEUE=m CONFIG_IP6_NF_IPTABLES=m CONFIG_IP6_NF_MATCH_AH=m CONFIG_IP6_NF_MATCH_EUI64=m @@ -127,31 +175,45 @@ CONFIG_IP6_NF_MATCH_OPTS=m CONFIG_IP6_NF_MATCH_HL=m CONFIG_IP6_NF_MATCH_IPV6HEADER=m CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_RPFILTER=m CONFIG_IP6_NF_MATCH_RT=m CONFIG_IP6_NF_TARGET_HL=m -CONFIG_IP6_NF_TARGET_LOG=m CONFIG_IP6_NF_FILTER=m CONFIG_IP6_NF_TARGET_REJECT=m CONFIG_IP6_NF_MANGLE=m CONFIG_IP6_NF_RAW=m +CONFIG_NF_NAT_IPV6=m +CONFIG_IP6_NF_TARGET_MASQUERADE=m +CONFIG_IP6_NF_TARGET_NPT=m CONFIG_IP_DCCP=m # CONFIG_IP_DCCP_CCID3 is not set +CONFIG_SCTP_COOKIE_HMAC_SHA1=y +CONFIG_RDS=m +CONFIG_RDS_TCP=m +CONFIG_L2TP=m CONFIG_ATALK=m CONFIG_DEV_APPLETALK=m CONFIG_IPDDP=m CONFIG_IPDDP_ENCAP=y CONFIG_IPDDP_DECAP=y +CONFIG_BATMAN_ADV=m +CONFIG_BATMAN_ADV_DAT=y +# CONFIG_WIRELESS is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y # CONFIG_FIRMWARE_IN_KERNEL is not set +# CONFIG_FW_LOADER_USER_HELPER is not set CONFIG_CONNECTOR=m -CONFIG_BLK_DEV_SWIM=y +CONFIG_BLK_DEV_SWIM=m CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_DRBD=m CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=y CONFIG_CDROM_PKTCDVD=m CONFIG_ATA_OVER_ETH=m CONFIG_IDE=y +CONFIG_IDE_GD_ATAPI=y CONFIG_BLK_DEV_IDECD=y CONFIG_BLK_DEV_MAC_IDE=y CONFIG_RAID_ATTRS=m @@ -164,29 +226,30 @@ CONFIG_BLK_DEV_SR=y CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y -CONFIG_SCSI_SAS_LIBSAS=m -# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set -CONFIG_SCSI_SRP_ATTRS=m -CONFIG_SCSI_SRP_TGT_ATTRS=y +CONFIG_SCSI_SAS_ATTRS=m CONFIG_ISCSI_TCP=m +CONFIG_ISCSI_BOOT_SYSFS=m CONFIG_MAC_SCSI=y CONFIG_SCSI_MAC_ESP=y CONFIG_MD=y -CONFIG_BLK_DEV_MD=m CONFIG_MD_LINEAR=m CONFIG_MD_RAID0=m -CONFIG_MD_RAID1=m -CONFIG_MD_RAID456=m CONFIG_BLK_DEV_DM=m CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m +CONFIG_DM_THIN_PROVISIONING=m +CONFIG_DM_CACHE=m CONFIG_DM_MIRROR=m +CONFIG_DM_RAID=m CONFIG_DM_ZERO=m CONFIG_DM_MULTIPATH=m CONFIG_DM_UEVENT=y +CONFIG_TARGET_CORE=m +CONFIG_TCM_IBLOCK=m +CONFIG_TCM_FILEIO=m +CONFIG_TCM_PSCSI=m CONFIG_ADB=y CONFIG_ADB_MACII=y -CONFIG_ADB_MACIISI=y CONFIG_ADB_IOP=y CONFIG_ADB_PMU68K=y CONFIG_ADB_CUDA=y @@ -194,46 +257,61 @@ CONFIG_INPUT_ADBHID=y CONFIG_MAC_EMUMOUSEBTN=y CONFIG_NETDEVICES=y CONFIG_DUMMY=m -CONFIG_MACVLAN=m CONFIG_EQUALIZER=m +CONFIG_NET_TEAM=m +CONFIG_NET_TEAM_MODE_BROADCAST=m +CONFIG_NET_TEAM_MODE_ROUNDROBIN=m +CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m +CONFIG_NET_TEAM_MODE_LOADBALANCE=m +CONFIG_VXLAN=m +CONFIG_NETCONSOLE=m +CONFIG_NETCONSOLE_DYNAMIC=y CONFIG_VETH=m -CONFIG_NET_ETHERNET=y -CONFIG_MAC8390=y -CONFIG_MAC89x0=m -CONFIG_MACSONIC=m CONFIG_MACMACE=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set +# CONFIG_NET_CADENCE is not set +# CONFIG_NET_VENDOR_BROADCOM is not set +CONFIG_MAC89x0=y +# CONFIG_NET_VENDOR_INTEL is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MICREL is not set +CONFIG_MACSONIC=y +CONFIG_MAC8390=y +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_SMSC is not set +# CONFIG_NET_VENDOR_STMICRO is not set +# CONFIG_NET_VENDOR_WIZNET is not set CONFIG_PPP=m -CONFIG_PPP_FILTER=y -CONFIG_PPP_ASYNC=m -CONFIG_PPP_SYNC_TTY=m -CONFIG_PPP_DEFLATE=m CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_FILTER=y CONFIG_PPP_MPPE=m CONFIG_PPPOE=m +CONFIG_PPTP=m +CONFIG_PPPOL2TP=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m CONFIG_SLIP=m CONFIG_SLIP_COMPRESSED=y CONFIG_SLIP_SMART=y CONFIG_SLIP_MODE_SLIP6=y -CONFIG_NETCONSOLE=m -CONFIG_NETCONSOLE_DYNAMIC=y -CONFIG_INPUT_FF_MEMLESS=m +# CONFIG_WLAN is not set +CONFIG_INPUT_EVDEV=m # CONFIG_KEYBOARD_ATKBD is not set -CONFIG_MOUSE_PS2=m +# CONFIG_MOUSE_PS2 is not set CONFIG_MOUSE_SERIAL=m CONFIG_INPUT_MISC=y CONFIG_INPUT_M68K_BEEP=m CONFIG_SERIO=m -# CONFIG_SERIO_SERPORT is not set CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_LEGACY_PTYS is not set # CONFIG_DEVKMEM is not set CONFIG_SERIAL_PMACZILOG=y CONFIG_SERIAL_PMACZILOG_TTYS=y CONFIG_SERIAL_PMACZILOG_CONSOLE=y # CONFIG_HW_RANDOM is not set -CONFIG_GEN_RTC=m -CONFIG_GEN_RTC_X=y +CONFIG_NTP_PPS=y +CONFIG_PPS_CLIENT_LDISC=m +CONFIG_PTP_1588_CLOCK=m # CONFIG_HWMON is not set CONFIG_FB=y CONFIG_FB_VALKYRIE=y @@ -242,46 +320,60 @@ CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_LOGO=y CONFIG_HID=m CONFIG_HIDRAW=y +CONFIG_UHID=m +# CONFIG_HID_GENERIC is not set # CONFIG_USB_SUPPORT is not set +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_GENERIC=m +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_PROC_HARDWARE=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set # CONFIG_EXT3_FS_XATTR is not set +CONFIG_EXT4_FS=y CONFIG_REISERFS_FS=m CONFIG_JFS_FS=m CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m -# CONFIG_OCFS2_FS_STATS is not set # CONFIG_OCFS2_DEBUG_MASKLOG is not set +CONFIG_FANOTIFY=y CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set -CONFIG_AUTOFS_FS=m CONFIG_AUTOFS4_FS=m CONFIG_FUSE_FS=m +CONFIG_CUSE=m CONFIG_ISO9660_FS=y CONFIG_JOLIET=y CONFIG_ZISOFS=y CONFIG_UDF_FS=m -CONFIG_MSDOS_FS=y +CONFIG_MSDOS_FS=m CONFIG_VFAT_FS=m CONFIG_PROC_KCORE=y CONFIG_TMPFS=y CONFIG_AFFS_FS=m -CONFIG_HFS_FS=y -CONFIG_HFSPLUS_FS=y +CONFIG_ECRYPT_FS=m +CONFIG_ECRYPT_FS_MESSAGING=y +CONFIG_HFS_FS=m +CONFIG_HFSPLUS_FS=m CONFIG_CRAMFS=m CONFIG_SQUASHFS=m -CONFIG_MINIX_FS=y +CONFIG_SQUASHFS_LZO=y +CONFIG_MINIX_FS=m +CONFIG_OMFS_FS=m CONFIG_HPFS_FS=m +CONFIG_QNX4FS_FS=m +CONFIG_QNX6FS_FS=m CONFIG_SYSV_FS=m CONFIG_UFS_FS=m -CONFIG_NFS_FS=m -CONFIG_NFS_V3=y +CONFIG_NFS_FS=y CONFIG_NFS_V4=y +CONFIG_NFS_SWAP=y +CONFIG_ROOT_NFS=y CONFIG_NFSD=m CONFIG_NFSD_V3=y -CONFIG_SMB_FS=m -CONFIG_SMB_NLS_DEFAULT=y +CONFIG_CIFS=m +# CONFIG_CIFS_DEBUG is not set CONFIG_CODA_FS=m CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_CODEPAGE_737=m @@ -320,10 +412,23 @@ CONFIG_NLS_ISO8859_14=m CONFIG_NLS_ISO8859_15=m CONFIG_NLS_KOI8_R=m CONFIG_NLS_KOI8_U=m +CONFIG_NLS_MAC_ROMAN=m +CONFIG_NLS_MAC_CELTIC=m +CONFIG_NLS_MAC_CENTEURO=m +CONFIG_NLS_MAC_CROATIAN=m +CONFIG_NLS_MAC_CYRILLIC=m +CONFIG_NLS_MAC_GAELIC=m +CONFIG_NLS_MAC_GREEK=m +CONFIG_NLS_MAC_ICELAND=m +CONFIG_NLS_MAC_INUIT=m +CONFIG_NLS_MAC_ROMANIAN=m +CONFIG_NLS_MAC_TURKISH=m CONFIG_DLM=m CONFIG_MAGIC_SYSRQ=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y +CONFIG_ASYNC_RAID6_TEST=m +CONFIG_ENCRYPTED_KEYS=m +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_USER=m CONFIG_CRYPTO_NULL=m CONFIG_CRYPTO_CRYPTD=m CONFIG_CRYPTO_TEST=m @@ -333,19 +438,16 @@ CONFIG_CRYPTO_CTS=m CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_PCBC=m CONFIG_CRYPTO_XTS=m -CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_XCBC=m -CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_VMAC=m CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_RMD128=m CONFIG_CRYPTO_RMD160=m CONFIG_CRYPTO_RMD256=m CONFIG_CRYPTO_RMD320=m -CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m CONFIG_CRYPTO_TGR192=m CONFIG_CRYPTO_WP512=m -CONFIG_CRYPTO_AES=m CONFIG_CRYPTO_ANUBIS=m CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_CAMELLIA=m @@ -361,6 +463,14 @@ CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_ZLIB=m CONFIG_CRYPTO_LZO=m # CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_USER_API_HASH=m +CONFIG_CRYPTO_USER_API_SKCIPHER=m # CONFIG_CRYPTO_HW is not set -CONFIG_CRC16=m CONFIG_CRC_T10DIF=y +CONFIG_XZ_DEC_X86=y +CONFIG_XZ_DEC_POWERPC=y +CONFIG_XZ_DEC_IA64=y +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_ARMTHUMB=y +CONFIG_XZ_DEC_SPARC=y +CONFIG_XZ_DEC_TEST=m diff --git a/arch/m68k/configs/multi_defconfig b/arch/m68k/configs/multi_defconfig index 8d5def4a31e0..0f795d8e65fa 100644 --- a/arch/m68k/configs/multi_defconfig +++ b/arch/m68k/configs/multi_defconfig @@ -1,15 +1,29 @@ -CONFIG_EXPERIMENTAL=y CONFIG_LOCALVERSION="-multi" CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y +CONFIG_FHANDLE=y CONFIG_BSD_PROCESS_ACCT=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_RELAY=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_LOG_BUF_SHIFT=16 +# CONFIG_UTS_NS is not set +# CONFIG_IPC_NS is not set +# CONFIG_PID_NS is not set +# CONFIG_NET_NS is not set CONFIG_BLK_DEV_INITRD=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SLAB=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +# CONFIG_EFI_PARTITION is not set +CONFIG_IOSCHED_DEADLINE=m +CONFIG_M68020=y +CONFIG_M68040=y +CONFIG_M68060=y +CONFIG_M68KFPU_EMU=y CONFIG_AMIGA=y CONFIG_ATARI=y CONFIG_MAC=y @@ -21,48 +35,50 @@ CONFIG_BVME6000=y CONFIG_HP300=y CONFIG_SUN3X=y CONFIG_Q40=y -CONFIG_M68020=y -CONFIG_M68040=y -CONFIG_M68060=y -CONFIG_BINFMT_AOUT=m -CONFIG_BINFMT_MISC=m CONFIG_ZORRO=y CONFIG_AMIGA_PCMCIA=y -CONFIG_STRAM_PROC=y -CONFIG_HEARTBEAT=y -CONFIG_PROC_HARDWARE=y CONFIG_ZORRO_NAMES=y +# CONFIG_COMPACTION is not set +CONFIG_CLEANCACHE=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_BINFMT_AOUT=m +CONFIG_BINFMT_MISC=m CONFIG_NET=y CONFIG_PACKET=y +CONFIG_PACKET_DIAG=m CONFIG_UNIX=y +CONFIG_UNIX_DIAG=m +CONFIG_XFRM_MIGRATE=y CONFIG_NET_KEY=y -CONFIG_NET_KEY_MIGRATE=y CONFIG_INET=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_IP_PNP_RARP=y CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE_DEMUX=m CONFIG_NET_IPGRE=m CONFIG_SYN_COOKIES=y +CONFIG_NET_IPVTI=m CONFIG_INET_AH=m CONFIG_INET_ESP=m CONFIG_INET_IPCOMP=m CONFIG_INET_XFRM_MODE_TRANSPORT=m CONFIG_INET_XFRM_MODE_TUNNEL=m CONFIG_INET_XFRM_MODE_BEET=m +# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=m +CONFIG_INET_UDP_DIAG=m CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y -CONFIG_IPV6_ROUTE_INFO=y CONFIG_INET6_AH=m CONFIG_INET6_ESP=m CONFIG_INET6_IPCOMP=m -CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m -CONFIG_IPV6_TUNNEL=m +CONFIG_IPV6_GRE=m CONFIG_NETFILTER=y -CONFIG_NETFILTER_NETLINK_QUEUE=m CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_ZONES=y +# CONFIG_NF_CONNTRACK_PROCFS is not set # CONFIG_NF_CT_PROTO_DCCP is not set CONFIG_NF_CT_PROTO_UDPLITE=m CONFIG_NF_CONNTRACK_AMANDA=m @@ -70,25 +86,37 @@ CONFIG_NF_CONNTRACK_FTP=m CONFIG_NF_CONNTRACK_H323=m CONFIG_NF_CONNTRACK_IRC=m CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_SNMP=m CONFIG_NF_CONNTRACK_PPTP=m CONFIG_NF_CONNTRACK_SANE=m CONFIG_NF_CONNTRACK_SIP=m CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NETFILTER_XT_SET=m +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m CONFIG_NETFILTER_XT_TARGET_CONNMARK=m CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HMARK=m +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m +CONFIG_NETFILTER_XT_TARGET_LOG=m CONFIG_NETFILTER_XT_TARGET_MARK=m CONFIG_NETFILTER_XT_TARGET_NFLOG=m CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_TEE=m CONFIG_NETFILTER_XT_TARGET_TRACE=m CONFIG_NETFILTER_XT_TARGET_TCPMSS=m CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +CONFIG_NETFILTER_XT_MATCH_BPF=m CONFIG_NETFILTER_XT_MATCH_CLUSTER=m CONFIG_NETFILTER_XT_MATCH_COMMENT=m CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m CONFIG_NETFILTER_XT_MATCH_CONNMARK=m CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m CONFIG_NETFILTER_XT_MATCH_DSCP=m CONFIG_NETFILTER_XT_MATCH_ESP=m CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m @@ -99,6 +127,8 @@ CONFIG_NETFILTER_XT_MATCH_LIMIT=m CONFIG_NETFILTER_XT_MATCH_MAC=m CONFIG_NETFILTER_XT_MATCH_MARK=m CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_NFACCT=m +CONFIG_NETFILTER_XT_MATCH_OSF=m CONFIG_NETFILTER_XT_MATCH_OWNER=m CONFIG_NETFILTER_XT_MATCH_POLICY=m CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m @@ -112,22 +142,31 @@ CONFIG_NETFILTER_XT_MATCH_STRING=m CONFIG_NETFILTER_XT_MATCH_TCPMSS=m CONFIG_NETFILTER_XT_MATCH_TIME=m CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_IP_SET=m +CONFIG_IP_SET_BITMAP_IP=m +CONFIG_IP_SET_BITMAP_IPMAC=m +CONFIG_IP_SET_BITMAP_PORT=m +CONFIG_IP_SET_HASH_IP=m +CONFIG_IP_SET_HASH_IPPORT=m +CONFIG_IP_SET_HASH_IPPORTIP=m +CONFIG_IP_SET_HASH_IPPORTNET=m +CONFIG_IP_SET_HASH_NET=m +CONFIG_IP_SET_HASH_NETPORT=m +CONFIG_IP_SET_HASH_NETIFACE=m +CONFIG_IP_SET_LIST_SET=m CONFIG_NF_CONNTRACK_IPV4=m -CONFIG_IP_NF_QUEUE=m CONFIG_IP_NF_IPTABLES=m -CONFIG_IP_NF_MATCH_ADDRTYPE=m CONFIG_IP_NF_MATCH_AH=m CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_RPFILTER=m CONFIG_IP_NF_MATCH_TTL=m CONFIG_IP_NF_FILTER=m CONFIG_IP_NF_TARGET_REJECT=m -CONFIG_IP_NF_TARGET_LOG=m CONFIG_IP_NF_TARGET_ULOG=m -CONFIG_NF_NAT=m +CONFIG_NF_NAT_IPV4=m CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_REDIRECT=m -CONFIG_NF_NAT_SNMP_BASIC=m CONFIG_IP_NF_MANGLE=m CONFIG_IP_NF_TARGET_CLUSTERIP=m CONFIG_IP_NF_TARGET_ECN=m @@ -137,7 +176,6 @@ CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m CONFIG_NF_CONNTRACK_IPV6=m -CONFIG_IP6_NF_QUEUE=m CONFIG_IP6_NF_IPTABLES=m CONFIG_IP6_NF_MATCH_AH=m CONFIG_IP6_NF_MATCH_EUI64=m @@ -146,22 +184,34 @@ CONFIG_IP6_NF_MATCH_OPTS=m CONFIG_IP6_NF_MATCH_HL=m CONFIG_IP6_NF_MATCH_IPV6HEADER=m CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_RPFILTER=m CONFIG_IP6_NF_MATCH_RT=m CONFIG_IP6_NF_TARGET_HL=m -CONFIG_IP6_NF_TARGET_LOG=m CONFIG_IP6_NF_FILTER=m CONFIG_IP6_NF_TARGET_REJECT=m CONFIG_IP6_NF_MANGLE=m CONFIG_IP6_NF_RAW=m +CONFIG_NF_NAT_IPV6=m +CONFIG_IP6_NF_TARGET_MASQUERADE=m +CONFIG_IP6_NF_TARGET_NPT=m CONFIG_IP_DCCP=m # CONFIG_IP_DCCP_CCID3 is not set +CONFIG_SCTP_COOKIE_HMAC_SHA1=y +CONFIG_RDS=m +CONFIG_RDS_TCP=m +CONFIG_L2TP=m CONFIG_ATALK=m CONFIG_DEV_APPLETALK=m CONFIG_IPDDP=m CONFIG_IPDDP_ENCAP=y CONFIG_IPDDP_DECAP=y +CONFIG_BATMAN_ADV=m +CONFIG_BATMAN_ADV_DAT=y +# CONFIG_WIRELESS is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y # CONFIG_FIRMWARE_IN_KERNEL is not set +# CONFIG_FW_LOADER_USER_HELPER is not set CONFIG_CONNECTOR=m CONFIG_PARPORT=m CONFIG_PARPORT_AMIGA=m @@ -170,15 +220,17 @@ CONFIG_PARPORT_ATARI=m CONFIG_PARPORT_1284=y CONFIG_AMIGA_FLOPPY=y CONFIG_ATARI_FLOPPY=y -CONFIG_BLK_DEV_SWIM=y +CONFIG_BLK_DEV_SWIM=m CONFIG_AMIGA_Z2RAM=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_DRBD=m CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=y CONFIG_CDROM_PKTCDVD=m CONFIG_ATA_OVER_ETH=m CONFIG_IDE=y +CONFIG_IDE_GD_ATAPI=y CONFIG_BLK_DEV_IDECD=y CONFIG_BLK_DEV_GAYLE=y CONFIG_BLK_DEV_BUDDHA=y @@ -195,11 +247,9 @@ CONFIG_BLK_DEV_SR=y CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y -CONFIG_SCSI_SAS_LIBSAS=m -# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set -CONFIG_SCSI_SRP_ATTRS=m -CONFIG_SCSI_SRP_TGT_ATTRS=y +CONFIG_SCSI_SAS_ATTRS=m CONFIG_ISCSI_TCP=m +CONFIG_ISCSI_BOOT_SYSFS=m CONFIG_A3000_SCSI=y CONFIG_A2091_SCSI=y CONFIG_GVP11_SCSI=y @@ -213,21 +263,24 @@ CONFIG_MVME16x_SCSI=y CONFIG_BVME6000_SCSI=y CONFIG_SUN3X_ESP=y CONFIG_MD=y -CONFIG_BLK_DEV_MD=m CONFIG_MD_LINEAR=m CONFIG_MD_RAID0=m -CONFIG_MD_RAID1=m -CONFIG_MD_RAID456=m CONFIG_BLK_DEV_DM=m CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m +CONFIG_DM_THIN_PROVISIONING=m +CONFIG_DM_CACHE=m CONFIG_DM_MIRROR=m +CONFIG_DM_RAID=m CONFIG_DM_ZERO=m CONFIG_DM_MULTIPATH=m CONFIG_DM_UEVENT=y +CONFIG_TARGET_CORE=m +CONFIG_TCM_IBLOCK=m +CONFIG_TCM_FILEIO=m +CONFIG_TCM_PSCSI=m CONFIG_ADB=y CONFIG_ADB_MACII=y -CONFIG_ADB_MACIISI=y CONFIG_ADB_IOP=y CONFIG_ADB_PMU68K=y CONFIG_ADB_CUDA=y @@ -235,49 +288,64 @@ CONFIG_INPUT_ADBHID=y CONFIG_MAC_EMUMOUSEBTN=y CONFIG_NETDEVICES=y CONFIG_DUMMY=m -CONFIG_MACVLAN=m CONFIG_EQUALIZER=m -CONFIG_VETH=m -CONFIG_NET_ETHERNET=y CONFIG_MII=y -CONFIG_ARIADNE=y +CONFIG_NET_TEAM=m +CONFIG_NET_TEAM_MODE_BROADCAST=m +CONFIG_NET_TEAM_MODE_ROUNDROBIN=m +CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m +CONFIG_NET_TEAM_MODE_LOADBALANCE=m +CONFIG_VXLAN=m +CONFIG_NETCONSOLE=m +CONFIG_NETCONSOLE_DYNAMIC=y +CONFIG_VETH=m +# CONFIG_NET_VENDOR_3COM is not set CONFIG_A2065=y -CONFIG_HYDRA=y -CONFIG_ZORRO8390=y -CONFIG_APNE=y -CONFIG_MAC8390=y -CONFIG_MAC89x0=y -CONFIG_MACSONIC=y -CONFIG_MACMACE=y -CONFIG_MVME147_NET=y -CONFIG_MVME16x_NET=y -CONFIG_BVME6000_NET=y +CONFIG_ARIADNE=y CONFIG_ATARILANCE=y -CONFIG_SUN3LANCE=y CONFIG_HPLANCE=y +CONFIG_MVME147_NET=y +CONFIG_SUN3LANCE=y +CONFIG_MACMACE=y +# CONFIG_NET_CADENCE is not set +# CONFIG_NET_VENDOR_BROADCOM is not set +CONFIG_MAC89x0=y +# CONFIG_NET_VENDOR_FUJITSU is not set +# CONFIG_NET_VENDOR_HP is not set +CONFIG_BVME6000_NET=y +CONFIG_MVME16x_NET=y +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MICREL is not set +CONFIG_MACSONIC=y +CONFIG_HYDRA=y +CONFIG_MAC8390=y CONFIG_NE2000=m -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set +CONFIG_APNE=y +CONFIG_ZORRO8390=y +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_STMICRO is not set +# CONFIG_NET_VENDOR_WIZNET is not set CONFIG_PPP=m -CONFIG_PPP_FILTER=y -CONFIG_PPP_ASYNC=m -CONFIG_PPP_SYNC_TTY=m -CONFIG_PPP_DEFLATE=m CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_FILTER=y CONFIG_PPP_MPPE=m CONFIG_PPPOE=m +CONFIG_PPTP=m +CONFIG_PPPOL2TP=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m CONFIG_SLIP=m CONFIG_SLIP_COMPRESSED=y CONFIG_SLIP_SMART=y CONFIG_SLIP_MODE_SLIP6=y -CONFIG_NETCONSOLE=m -CONFIG_NETCONSOLE_DYNAMIC=y -CONFIG_INPUT_FF_MEMLESS=m +# CONFIG_WLAN is not set +CONFIG_INPUT_EVDEV=m CONFIG_KEYBOARD_AMIGA=y CONFIG_KEYBOARD_ATARI=y # CONFIG_KEYBOARD_ATKBD is not set CONFIG_KEYBOARD_SUNKBD=y -CONFIG_MOUSE_PS2=m +# CONFIG_MOUSE_PS2 is not set CONFIG_MOUSE_SERIAL=m CONFIG_MOUSE_AMIGA=m CONFIG_MOUSE_ATARI=m @@ -285,18 +353,20 @@ CONFIG_INPUT_JOYSTICK=y CONFIG_JOYSTICK_AMIGA=m CONFIG_INPUT_MISC=y CONFIG_INPUT_M68K_BEEP=m -CONFIG_HP_SDC_RTC=y -# CONFIG_SERIO_SERPORT is not set +CONFIG_HP_SDC_RTC=m CONFIG_SERIO_Q40KBD=y CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_LEGACY_PTYS is not set # CONFIG_DEVKMEM is not set CONFIG_SERIAL_PMACZILOG=y CONFIG_SERIAL_PMACZILOG_TTYS=y CONFIG_SERIAL_PMACZILOG_CONSOLE=y CONFIG_PRINTER=m # CONFIG_HW_RANDOM is not set -CONFIG_GEN_RTC=y -CONFIG_GEN_RTC_X=y +CONFIG_NTP_PPS=y +CONFIG_PPS_CLIENT_LDISC=m +CONFIG_PPS_CLIENT_PARPORT=m +CONFIG_PTP_1588_CLOCK=m # CONFIG_HWMON is not set CONFIG_FB=y CONFIG_FB_CIRRUS=y @@ -316,7 +386,20 @@ CONFIG_DMASOUND_PAULA=m CONFIG_DMASOUND_Q40=m CONFIG_HID=m CONFIG_HIDRAW=y +CONFIG_UHID=m +# CONFIG_HID_GENERIC is not set # CONFIG_USB_SUPPORT is not set +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_MSM6242=m +CONFIG_RTC_DRV_RP5C01=m +CONFIG_RTC_DRV_GENERIC=m +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_HEARTBEAT=y +CONFIG_PROC_HARDWARE=y +CONFIG_NATFEAT=y +CONFIG_NFBLOCK=y +CONFIG_NFCON=y +CONFIG_NFETH=y CONFIG_ATARI_DSP56K=m CONFIG_AMIGA_BUILTIN_SERIAL=y CONFIG_SERIAL_CONSOLE=y @@ -324,42 +407,49 @@ CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set # CONFIG_EXT3_FS_XATTR is not set +CONFIG_EXT4_FS=y CONFIG_REISERFS_FS=m CONFIG_JFS_FS=m CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m -# CONFIG_OCFS2_FS_STATS is not set # CONFIG_OCFS2_DEBUG_MASKLOG is not set +CONFIG_FANOTIFY=y CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set -CONFIG_AUTOFS_FS=m CONFIG_AUTOFS4_FS=m CONFIG_FUSE_FS=m +CONFIG_CUSE=m CONFIG_ISO9660_FS=y CONFIG_JOLIET=y CONFIG_ZISOFS=y CONFIG_UDF_FS=m -CONFIG_MSDOS_FS=y +CONFIG_MSDOS_FS=m CONFIG_VFAT_FS=m CONFIG_PROC_KCORE=y CONFIG_TMPFS=y CONFIG_AFFS_FS=m -CONFIG_HFS_FS=y -CONFIG_HFSPLUS_FS=y +CONFIG_ECRYPT_FS=m +CONFIG_ECRYPT_FS_MESSAGING=y +CONFIG_HFS_FS=m +CONFIG_HFSPLUS_FS=m CONFIG_CRAMFS=m CONFIG_SQUASHFS=m -CONFIG_MINIX_FS=y +CONFIG_SQUASHFS_LZO=y +CONFIG_MINIX_FS=m +CONFIG_OMFS_FS=m CONFIG_HPFS_FS=m +CONFIG_QNX4FS_FS=m +CONFIG_QNX6FS_FS=m CONFIG_SYSV_FS=m CONFIG_UFS_FS=m CONFIG_NFS_FS=y -CONFIG_NFS_V3=y CONFIG_NFS_V4=y +CONFIG_NFS_SWAP=y CONFIG_ROOT_NFS=y CONFIG_NFSD=m CONFIG_NFSD_V3=y -CONFIG_SMB_FS=m -CONFIG_SMB_NLS_DEFAULT=y +CONFIG_CIFS=m +# CONFIG_CIFS_DEBUG is not set CONFIG_CODA_FS=m CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_CODEPAGE_737=m @@ -398,10 +488,23 @@ CONFIG_NLS_ISO8859_14=m CONFIG_NLS_ISO8859_15=m CONFIG_NLS_KOI8_R=m CONFIG_NLS_KOI8_U=m +CONFIG_NLS_MAC_ROMAN=m +CONFIG_NLS_MAC_CELTIC=m +CONFIG_NLS_MAC_CENTEURO=m +CONFIG_NLS_MAC_CROATIAN=m +CONFIG_NLS_MAC_CYRILLIC=m +CONFIG_NLS_MAC_GAELIC=m +CONFIG_NLS_MAC_GREEK=m +CONFIG_NLS_MAC_ICELAND=m +CONFIG_NLS_MAC_INUIT=m +CONFIG_NLS_MAC_ROMANIAN=m +CONFIG_NLS_MAC_TURKISH=m CONFIG_DLM=m CONFIG_MAGIC_SYSRQ=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y +CONFIG_ASYNC_RAID6_TEST=m +CONFIG_ENCRYPTED_KEYS=m +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_USER=m CONFIG_CRYPTO_NULL=m CONFIG_CRYPTO_CRYPTD=m CONFIG_CRYPTO_TEST=m @@ -411,19 +514,16 @@ CONFIG_CRYPTO_CTS=m CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_PCBC=m CONFIG_CRYPTO_XTS=m -CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_XCBC=m -CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_VMAC=m CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_RMD128=m CONFIG_CRYPTO_RMD160=m CONFIG_CRYPTO_RMD256=m CONFIG_CRYPTO_RMD320=m -CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m CONFIG_CRYPTO_TGR192=m CONFIG_CRYPTO_WP512=m -CONFIG_CRYPTO_AES=m CONFIG_CRYPTO_ANUBIS=m CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_CAMELLIA=m @@ -439,6 +539,14 @@ CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_ZLIB=m CONFIG_CRYPTO_LZO=m # CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_USER_API_HASH=m +CONFIG_CRYPTO_USER_API_SKCIPHER=m # CONFIG_CRYPTO_HW is not set -CONFIG_CRC16=y CONFIG_CRC_T10DIF=y +CONFIG_XZ_DEC_X86=y +CONFIG_XZ_DEC_POWERPC=y +CONFIG_XZ_DEC_IA64=y +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_ARMTHUMB=y +CONFIG_XZ_DEC_SPARC=y +CONFIG_XZ_DEC_TEST=m diff --git a/arch/m68k/configs/mvme147_defconfig b/arch/m68k/configs/mvme147_defconfig index e2af46f530c1..5586c6529fce 100644 --- a/arch/m68k/configs/mvme147_defconfig +++ b/arch/m68k/configs/mvme147_defconfig @@ -1,52 +1,73 @@ -CONFIG_EXPERIMENTAL=y CONFIG_LOCALVERSION="-mvme147" CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y +CONFIG_FHANDLE=y CONFIG_BSD_PROCESS_ACCT=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_RELAY=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_LOG_BUF_SHIFT=16 +# CONFIG_UTS_NS is not set +# CONFIG_IPC_NS is not set +# CONFIG_PID_NS is not set +# CONFIG_NET_NS is not set CONFIG_BLK_DEV_INITRD=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SLAB=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_AMIGA_PARTITION=y +CONFIG_ATARI_PARTITION=y +CONFIG_MAC_PARTITION=y +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_SUN_PARTITION=y +# CONFIG_EFI_PARTITION is not set +CONFIG_IOSCHED_DEADLINE=m +CONFIG_M68030=y CONFIG_VME=y CONFIG_MVME147=y -CONFIG_M68030=y +# CONFIG_COMPACTION is not set +CONFIG_CLEANCACHE=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_BINFMT_AOUT=m CONFIG_BINFMT_MISC=m -CONFIG_PROC_HARDWARE=y CONFIG_NET=y CONFIG_PACKET=y +CONFIG_PACKET_DIAG=m CONFIG_UNIX=y +CONFIG_UNIX_DIAG=m +CONFIG_XFRM_MIGRATE=y CONFIG_NET_KEY=y -CONFIG_NET_KEY_MIGRATE=y CONFIG_INET=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_IP_PNP_RARP=y CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE_DEMUX=m CONFIG_NET_IPGRE=m CONFIG_SYN_COOKIES=y +CONFIG_NET_IPVTI=m CONFIG_INET_AH=m CONFIG_INET_ESP=m CONFIG_INET_IPCOMP=m CONFIG_INET_XFRM_MODE_TRANSPORT=m CONFIG_INET_XFRM_MODE_TUNNEL=m CONFIG_INET_XFRM_MODE_BEET=m +# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=m +CONFIG_INET_UDP_DIAG=m CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y -CONFIG_IPV6_ROUTE_INFO=y CONFIG_INET6_AH=m CONFIG_INET6_ESP=m CONFIG_INET6_IPCOMP=m -CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m -CONFIG_IPV6_TUNNEL=m +CONFIG_IPV6_GRE=m CONFIG_NETFILTER=y -CONFIG_NETFILTER_NETLINK_QUEUE=m CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_ZONES=y +# CONFIG_NF_CONNTRACK_PROCFS is not set # CONFIG_NF_CT_PROTO_DCCP is not set CONFIG_NF_CT_PROTO_UDPLITE=m CONFIG_NF_CONNTRACK_AMANDA=m @@ -54,25 +75,37 @@ CONFIG_NF_CONNTRACK_FTP=m CONFIG_NF_CONNTRACK_H323=m CONFIG_NF_CONNTRACK_IRC=m CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_SNMP=m CONFIG_NF_CONNTRACK_PPTP=m CONFIG_NF_CONNTRACK_SANE=m CONFIG_NF_CONNTRACK_SIP=m CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NETFILTER_XT_SET=m +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m CONFIG_NETFILTER_XT_TARGET_CONNMARK=m CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HMARK=m +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m +CONFIG_NETFILTER_XT_TARGET_LOG=m CONFIG_NETFILTER_XT_TARGET_MARK=m CONFIG_NETFILTER_XT_TARGET_NFLOG=m CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_TEE=m CONFIG_NETFILTER_XT_TARGET_TRACE=m CONFIG_NETFILTER_XT_TARGET_TCPMSS=m CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +CONFIG_NETFILTER_XT_MATCH_BPF=m CONFIG_NETFILTER_XT_MATCH_CLUSTER=m CONFIG_NETFILTER_XT_MATCH_COMMENT=m CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m CONFIG_NETFILTER_XT_MATCH_CONNMARK=m CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m CONFIG_NETFILTER_XT_MATCH_DSCP=m CONFIG_NETFILTER_XT_MATCH_ESP=m CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m @@ -83,6 +116,8 @@ CONFIG_NETFILTER_XT_MATCH_LIMIT=m CONFIG_NETFILTER_XT_MATCH_MAC=m CONFIG_NETFILTER_XT_MATCH_MARK=m CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_NFACCT=m +CONFIG_NETFILTER_XT_MATCH_OSF=m CONFIG_NETFILTER_XT_MATCH_OWNER=m CONFIG_NETFILTER_XT_MATCH_POLICY=m CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m @@ -96,22 +131,31 @@ CONFIG_NETFILTER_XT_MATCH_STRING=m CONFIG_NETFILTER_XT_MATCH_TCPMSS=m CONFIG_NETFILTER_XT_MATCH_TIME=m CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_IP_SET=m +CONFIG_IP_SET_BITMAP_IP=m +CONFIG_IP_SET_BITMAP_IPMAC=m +CONFIG_IP_SET_BITMAP_PORT=m +CONFIG_IP_SET_HASH_IP=m +CONFIG_IP_SET_HASH_IPPORT=m +CONFIG_IP_SET_HASH_IPPORTIP=m +CONFIG_IP_SET_HASH_IPPORTNET=m +CONFIG_IP_SET_HASH_NET=m +CONFIG_IP_SET_HASH_NETPORT=m +CONFIG_IP_SET_HASH_NETIFACE=m +CONFIG_IP_SET_LIST_SET=m CONFIG_NF_CONNTRACK_IPV4=m -CONFIG_IP_NF_QUEUE=m CONFIG_IP_NF_IPTABLES=m -CONFIG_IP_NF_MATCH_ADDRTYPE=m CONFIG_IP_NF_MATCH_AH=m CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_RPFILTER=m CONFIG_IP_NF_MATCH_TTL=m CONFIG_IP_NF_FILTER=m CONFIG_IP_NF_TARGET_REJECT=m -CONFIG_IP_NF_TARGET_LOG=m CONFIG_IP_NF_TARGET_ULOG=m -CONFIG_NF_NAT=m +CONFIG_NF_NAT_IPV4=m CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_REDIRECT=m -CONFIG_NF_NAT_SNMP_BASIC=m CONFIG_IP_NF_MANGLE=m CONFIG_IP_NF_TARGET_CLUSTERIP=m CONFIG_IP_NF_TARGET_ECN=m @@ -121,7 +165,6 @@ CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m CONFIG_NF_CONNTRACK_IPV6=m -CONFIG_IP6_NF_QUEUE=m CONFIG_IP6_NF_IPTABLES=m CONFIG_IP6_NF_MATCH_AH=m CONFIG_IP6_NF_MATCH_EUI64=m @@ -130,21 +173,34 @@ CONFIG_IP6_NF_MATCH_OPTS=m CONFIG_IP6_NF_MATCH_HL=m CONFIG_IP6_NF_MATCH_IPV6HEADER=m CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_RPFILTER=m CONFIG_IP6_NF_MATCH_RT=m CONFIG_IP6_NF_TARGET_HL=m -CONFIG_IP6_NF_TARGET_LOG=m CONFIG_IP6_NF_FILTER=m CONFIG_IP6_NF_TARGET_REJECT=m CONFIG_IP6_NF_MANGLE=m CONFIG_IP6_NF_RAW=m +CONFIG_NF_NAT_IPV6=m +CONFIG_IP6_NF_TARGET_MASQUERADE=m +CONFIG_IP6_NF_TARGET_NPT=m CONFIG_IP_DCCP=m # CONFIG_IP_DCCP_CCID3 is not set +CONFIG_SCTP_COOKIE_HMAC_SHA1=y +CONFIG_RDS=m +CONFIG_RDS_TCP=m +CONFIG_L2TP=m CONFIG_ATALK=m +CONFIG_BATMAN_ADV=m +CONFIG_BATMAN_ADV_DAT=y +# CONFIG_WIRELESS is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y # CONFIG_FIRMWARE_IN_KERNEL is not set +# CONFIG_FW_LOADER_USER_HELPER is not set CONFIG_CONNECTOR=m CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_DRBD=m CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=y CONFIG_CDROM_PKTCDVD=m @@ -159,103 +215,132 @@ CONFIG_BLK_DEV_SR=y CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y -CONFIG_SCSI_SAS_LIBSAS=m -# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set -CONFIG_SCSI_SRP_ATTRS=m -CONFIG_SCSI_SRP_TGT_ATTRS=y +CONFIG_SCSI_SAS_ATTRS=m CONFIG_ISCSI_TCP=m +CONFIG_ISCSI_BOOT_SYSFS=m CONFIG_MVME147_SCSI=y CONFIG_MD=y -CONFIG_BLK_DEV_MD=m CONFIG_MD_LINEAR=m CONFIG_MD_RAID0=m -CONFIG_MD_RAID1=m -CONFIG_MD_RAID456=m CONFIG_BLK_DEV_DM=m CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m +CONFIG_DM_THIN_PROVISIONING=m +CONFIG_DM_CACHE=m CONFIG_DM_MIRROR=m +CONFIG_DM_RAID=m CONFIG_DM_ZERO=m CONFIG_DM_MULTIPATH=m CONFIG_DM_UEVENT=y +CONFIG_TARGET_CORE=m +CONFIG_TCM_IBLOCK=m +CONFIG_TCM_FILEIO=m +CONFIG_TCM_PSCSI=m CONFIG_NETDEVICES=y CONFIG_DUMMY=m -CONFIG_MACVLAN=m CONFIG_EQUALIZER=m +CONFIG_NET_TEAM=m +CONFIG_NET_TEAM_MODE_BROADCAST=m +CONFIG_NET_TEAM_MODE_ROUNDROBIN=m +CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m +CONFIG_NET_TEAM_MODE_LOADBALANCE=m +CONFIG_VXLAN=m +CONFIG_NETCONSOLE=m +CONFIG_NETCONSOLE_DYNAMIC=y CONFIG_VETH=m -CONFIG_NET_ETHERNET=y CONFIG_MVME147_NET=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set +# CONFIG_NET_CADENCE is not set +# CONFIG_NET_VENDOR_BROADCOM is not set +# CONFIG_NET_VENDOR_INTEL is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_STMICRO is not set +# CONFIG_NET_VENDOR_WIZNET is not set CONFIG_PPP=m -CONFIG_PPP_FILTER=y -CONFIG_PPP_ASYNC=m -CONFIG_PPP_SYNC_TTY=m -CONFIG_PPP_DEFLATE=m CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_FILTER=y CONFIG_PPP_MPPE=m CONFIG_PPPOE=m +CONFIG_PPTP=m +CONFIG_PPPOL2TP=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m CONFIG_SLIP=m CONFIG_SLIP_COMPRESSED=y CONFIG_SLIP_SMART=y CONFIG_SLIP_MODE_SLIP6=y -CONFIG_NETCONSOLE=m -CONFIG_NETCONSOLE_DYNAMIC=y -CONFIG_INPUT_FF_MEMLESS=m +# CONFIG_WLAN is not set +CONFIG_INPUT_EVDEV=m # CONFIG_KEYBOARD_ATKBD is not set -CONFIG_MOUSE_PS2=m -CONFIG_MOUSE_SERIAL=m -CONFIG_SERIO=m -# CONFIG_SERIO_SERPORT is not set +# CONFIG_MOUSE_PS2 is not set +# CONFIG_SERIO is not set CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_LEGACY_PTYS is not set # CONFIG_DEVKMEM is not set # CONFIG_HW_RANDOM is not set -CONFIG_GEN_RTC=m -CONFIG_GEN_RTC_X=y +CONFIG_NTP_PPS=y +CONFIG_PPS_CLIENT_LDISC=m +CONFIG_PTP_1588_CLOCK=m # CONFIG_HWMON is not set CONFIG_HID=m CONFIG_HIDRAW=y +CONFIG_UHID=m +# CONFIG_HID_GENERIC is not set # CONFIG_USB_SUPPORT is not set +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_GENERIC=m +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_PROC_HARDWARE=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set # CONFIG_EXT3_FS_XATTR is not set +CONFIG_EXT4_FS=y CONFIG_REISERFS_FS=m CONFIG_JFS_FS=m CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m -# CONFIG_OCFS2_FS_STATS is not set # CONFIG_OCFS2_DEBUG_MASKLOG is not set +CONFIG_FANOTIFY=y CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set -CONFIG_AUTOFS_FS=m CONFIG_AUTOFS4_FS=m CONFIG_FUSE_FS=m +CONFIG_CUSE=m CONFIG_ISO9660_FS=y CONFIG_JOLIET=y CONFIG_ZISOFS=y CONFIG_UDF_FS=m -CONFIG_MSDOS_FS=y +CONFIG_MSDOS_FS=m CONFIG_VFAT_FS=m CONFIG_PROC_KCORE=y CONFIG_TMPFS=y CONFIG_AFFS_FS=m +CONFIG_ECRYPT_FS=m +CONFIG_ECRYPT_FS_MESSAGING=y CONFIG_HFS_FS=m CONFIG_HFSPLUS_FS=m CONFIG_CRAMFS=m CONFIG_SQUASHFS=m -CONFIG_MINIX_FS=y +CONFIG_SQUASHFS_LZO=y +CONFIG_MINIX_FS=m +CONFIG_OMFS_FS=m CONFIG_HPFS_FS=m +CONFIG_QNX4FS_FS=m +CONFIG_QNX6FS_FS=m CONFIG_SYSV_FS=m CONFIG_UFS_FS=m CONFIG_NFS_FS=y -CONFIG_NFS_V3=y CONFIG_NFS_V4=y +CONFIG_NFS_SWAP=y CONFIG_ROOT_NFS=y CONFIG_NFSD=m CONFIG_NFSD_V3=y -CONFIG_SMB_FS=m -CONFIG_SMB_NLS_DEFAULT=y +CONFIG_CIFS=m +# CONFIG_CIFS_DEBUG is not set CONFIG_CODA_FS=m CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_CODEPAGE_737=m @@ -294,10 +379,23 @@ CONFIG_NLS_ISO8859_14=m CONFIG_NLS_ISO8859_15=m CONFIG_NLS_KOI8_R=m CONFIG_NLS_KOI8_U=m +CONFIG_NLS_MAC_ROMAN=m +CONFIG_NLS_MAC_CELTIC=m +CONFIG_NLS_MAC_CENTEURO=m +CONFIG_NLS_MAC_CROATIAN=m +CONFIG_NLS_MAC_CYRILLIC=m +CONFIG_NLS_MAC_GAELIC=m +CONFIG_NLS_MAC_GREEK=m +CONFIG_NLS_MAC_ICELAND=m +CONFIG_NLS_MAC_INUIT=m +CONFIG_NLS_MAC_ROMANIAN=m +CONFIG_NLS_MAC_TURKISH=m CONFIG_DLM=m CONFIG_MAGIC_SYSRQ=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y +CONFIG_ASYNC_RAID6_TEST=m +CONFIG_ENCRYPTED_KEYS=m +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_USER=m CONFIG_CRYPTO_NULL=m CONFIG_CRYPTO_CRYPTD=m CONFIG_CRYPTO_TEST=m @@ -307,19 +405,16 @@ CONFIG_CRYPTO_CTS=m CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_PCBC=m CONFIG_CRYPTO_XTS=m -CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_XCBC=m -CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_VMAC=m CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_RMD128=m CONFIG_CRYPTO_RMD160=m CONFIG_CRYPTO_RMD256=m CONFIG_CRYPTO_RMD320=m -CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m CONFIG_CRYPTO_TGR192=m CONFIG_CRYPTO_WP512=m -CONFIG_CRYPTO_AES=m CONFIG_CRYPTO_ANUBIS=m CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_CAMELLIA=m @@ -335,6 +430,14 @@ CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_ZLIB=m CONFIG_CRYPTO_LZO=m # CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_USER_API_HASH=m +CONFIG_CRYPTO_USER_API_SKCIPHER=m # CONFIG_CRYPTO_HW is not set -CONFIG_CRC16=m CONFIG_CRC_T10DIF=y +CONFIG_XZ_DEC_X86=y +CONFIG_XZ_DEC_POWERPC=y +CONFIG_XZ_DEC_IA64=y +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_ARMTHUMB=y +CONFIG_XZ_DEC_SPARC=y +CONFIG_XZ_DEC_TEST=m diff --git a/arch/m68k/configs/mvme16x_defconfig b/arch/m68k/configs/mvme16x_defconfig index 7c9402b2097f..e5e8262bbacd 100644 --- a/arch/m68k/configs/mvme16x_defconfig +++ b/arch/m68k/configs/mvme16x_defconfig @@ -1,53 +1,74 @@ -CONFIG_EXPERIMENTAL=y CONFIG_LOCALVERSION="-mvme16x" CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y +CONFIG_FHANDLE=y CONFIG_BSD_PROCESS_ACCT=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_RELAY=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_LOG_BUF_SHIFT=16 +# CONFIG_UTS_NS is not set +# CONFIG_IPC_NS is not set +# CONFIG_PID_NS is not set +# CONFIG_NET_NS is not set CONFIG_BLK_DEV_INITRD=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SLAB=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y -CONFIG_VME=y -CONFIG_MVME16x=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_AMIGA_PARTITION=y +CONFIG_ATARI_PARTITION=y +CONFIG_MAC_PARTITION=y +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_SUN_PARTITION=y +# CONFIG_EFI_PARTITION is not set +CONFIG_IOSCHED_DEADLINE=m CONFIG_M68040=y CONFIG_M68060=y +CONFIG_VME=y +CONFIG_MVME16x=y +# CONFIG_COMPACTION is not set +CONFIG_CLEANCACHE=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_BINFMT_AOUT=m CONFIG_BINFMT_MISC=m -CONFIG_PROC_HARDWARE=y CONFIG_NET=y CONFIG_PACKET=y +CONFIG_PACKET_DIAG=m CONFIG_UNIX=y +CONFIG_UNIX_DIAG=m +CONFIG_XFRM_MIGRATE=y CONFIG_NET_KEY=y -CONFIG_NET_KEY_MIGRATE=y CONFIG_INET=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_IP_PNP_RARP=y CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE_DEMUX=m CONFIG_NET_IPGRE=m CONFIG_SYN_COOKIES=y +CONFIG_NET_IPVTI=m CONFIG_INET_AH=m CONFIG_INET_ESP=m CONFIG_INET_IPCOMP=m CONFIG_INET_XFRM_MODE_TRANSPORT=m CONFIG_INET_XFRM_MODE_TUNNEL=m CONFIG_INET_XFRM_MODE_BEET=m +# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=m +CONFIG_INET_UDP_DIAG=m CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y -CONFIG_IPV6_ROUTE_INFO=y CONFIG_INET6_AH=m CONFIG_INET6_ESP=m CONFIG_INET6_IPCOMP=m -CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m -CONFIG_IPV6_TUNNEL=m +CONFIG_IPV6_GRE=m CONFIG_NETFILTER=y -CONFIG_NETFILTER_NETLINK_QUEUE=m CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_ZONES=y +# CONFIG_NF_CONNTRACK_PROCFS is not set # CONFIG_NF_CT_PROTO_DCCP is not set CONFIG_NF_CT_PROTO_UDPLITE=m CONFIG_NF_CONNTRACK_AMANDA=m @@ -55,25 +76,37 @@ CONFIG_NF_CONNTRACK_FTP=m CONFIG_NF_CONNTRACK_H323=m CONFIG_NF_CONNTRACK_IRC=m CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_SNMP=m CONFIG_NF_CONNTRACK_PPTP=m CONFIG_NF_CONNTRACK_SANE=m CONFIG_NF_CONNTRACK_SIP=m CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NETFILTER_XT_SET=m +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m CONFIG_NETFILTER_XT_TARGET_CONNMARK=m CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HMARK=m +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m +CONFIG_NETFILTER_XT_TARGET_LOG=m CONFIG_NETFILTER_XT_TARGET_MARK=m CONFIG_NETFILTER_XT_TARGET_NFLOG=m CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_TEE=m CONFIG_NETFILTER_XT_TARGET_TRACE=m CONFIG_NETFILTER_XT_TARGET_TCPMSS=m CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +CONFIG_NETFILTER_XT_MATCH_BPF=m CONFIG_NETFILTER_XT_MATCH_CLUSTER=m CONFIG_NETFILTER_XT_MATCH_COMMENT=m CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m CONFIG_NETFILTER_XT_MATCH_CONNMARK=m CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m CONFIG_NETFILTER_XT_MATCH_DSCP=m CONFIG_NETFILTER_XT_MATCH_ESP=m CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m @@ -84,6 +117,8 @@ CONFIG_NETFILTER_XT_MATCH_LIMIT=m CONFIG_NETFILTER_XT_MATCH_MAC=m CONFIG_NETFILTER_XT_MATCH_MARK=m CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_NFACCT=m +CONFIG_NETFILTER_XT_MATCH_OSF=m CONFIG_NETFILTER_XT_MATCH_OWNER=m CONFIG_NETFILTER_XT_MATCH_POLICY=m CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m @@ -97,22 +132,31 @@ CONFIG_NETFILTER_XT_MATCH_STRING=m CONFIG_NETFILTER_XT_MATCH_TCPMSS=m CONFIG_NETFILTER_XT_MATCH_TIME=m CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_IP_SET=m +CONFIG_IP_SET_BITMAP_IP=m +CONFIG_IP_SET_BITMAP_IPMAC=m +CONFIG_IP_SET_BITMAP_PORT=m +CONFIG_IP_SET_HASH_IP=m +CONFIG_IP_SET_HASH_IPPORT=m +CONFIG_IP_SET_HASH_IPPORTIP=m +CONFIG_IP_SET_HASH_IPPORTNET=m +CONFIG_IP_SET_HASH_NET=m +CONFIG_IP_SET_HASH_NETPORT=m +CONFIG_IP_SET_HASH_NETIFACE=m +CONFIG_IP_SET_LIST_SET=m CONFIG_NF_CONNTRACK_IPV4=m -CONFIG_IP_NF_QUEUE=m CONFIG_IP_NF_IPTABLES=m -CONFIG_IP_NF_MATCH_ADDRTYPE=m CONFIG_IP_NF_MATCH_AH=m CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_RPFILTER=m CONFIG_IP_NF_MATCH_TTL=m CONFIG_IP_NF_FILTER=m CONFIG_IP_NF_TARGET_REJECT=m -CONFIG_IP_NF_TARGET_LOG=m CONFIG_IP_NF_TARGET_ULOG=m -CONFIG_NF_NAT=m +CONFIG_NF_NAT_IPV4=m CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_REDIRECT=m -CONFIG_NF_NAT_SNMP_BASIC=m CONFIG_IP_NF_MANGLE=m CONFIG_IP_NF_TARGET_CLUSTERIP=m CONFIG_IP_NF_TARGET_ECN=m @@ -122,7 +166,6 @@ CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m CONFIG_NF_CONNTRACK_IPV6=m -CONFIG_IP6_NF_QUEUE=m CONFIG_IP6_NF_IPTABLES=m CONFIG_IP6_NF_MATCH_AH=m CONFIG_IP6_NF_MATCH_EUI64=m @@ -131,21 +174,34 @@ CONFIG_IP6_NF_MATCH_OPTS=m CONFIG_IP6_NF_MATCH_HL=m CONFIG_IP6_NF_MATCH_IPV6HEADER=m CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_RPFILTER=m CONFIG_IP6_NF_MATCH_RT=m CONFIG_IP6_NF_TARGET_HL=m -CONFIG_IP6_NF_TARGET_LOG=m CONFIG_IP6_NF_FILTER=m CONFIG_IP6_NF_TARGET_REJECT=m CONFIG_IP6_NF_MANGLE=m CONFIG_IP6_NF_RAW=m +CONFIG_NF_NAT_IPV6=m +CONFIG_IP6_NF_TARGET_MASQUERADE=m +CONFIG_IP6_NF_TARGET_NPT=m CONFIG_IP_DCCP=m # CONFIG_IP_DCCP_CCID3 is not set +CONFIG_SCTP_COOKIE_HMAC_SHA1=y +CONFIG_RDS=m +CONFIG_RDS_TCP=m +CONFIG_L2TP=m CONFIG_ATALK=m +CONFIG_BATMAN_ADV=m +CONFIG_BATMAN_ADV_DAT=y +# CONFIG_WIRELESS is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y # CONFIG_FIRMWARE_IN_KERNEL is not set +# CONFIG_FW_LOADER_USER_HELPER is not set CONFIG_CONNECTOR=m CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_DRBD=m CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=y CONFIG_CDROM_PKTCDVD=m @@ -160,103 +216,131 @@ CONFIG_BLK_DEV_SR=y CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y -CONFIG_SCSI_SAS_LIBSAS=m -# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set -CONFIG_SCSI_SRP_ATTRS=m -CONFIG_SCSI_SRP_TGT_ATTRS=y +CONFIG_SCSI_SAS_ATTRS=m CONFIG_ISCSI_TCP=m +CONFIG_ISCSI_BOOT_SYSFS=m CONFIG_MVME16x_SCSI=y CONFIG_MD=y -CONFIG_BLK_DEV_MD=m CONFIG_MD_LINEAR=m CONFIG_MD_RAID0=m -CONFIG_MD_RAID1=m -CONFIG_MD_RAID456=m CONFIG_BLK_DEV_DM=m CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m +CONFIG_DM_THIN_PROVISIONING=m +CONFIG_DM_CACHE=m CONFIG_DM_MIRROR=m +CONFIG_DM_RAID=m CONFIG_DM_ZERO=m CONFIG_DM_MULTIPATH=m CONFIG_DM_UEVENT=y +CONFIG_TARGET_CORE=m +CONFIG_TCM_IBLOCK=m +CONFIG_TCM_FILEIO=m +CONFIG_TCM_PSCSI=m CONFIG_NETDEVICES=y CONFIG_DUMMY=m -CONFIG_MACVLAN=m CONFIG_EQUALIZER=m +CONFIG_NET_TEAM=m +CONFIG_NET_TEAM_MODE_BROADCAST=m +CONFIG_NET_TEAM_MODE_ROUNDROBIN=m +CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m +CONFIG_NET_TEAM_MODE_LOADBALANCE=m +CONFIG_VXLAN=m +CONFIG_NETCONSOLE=m +CONFIG_NETCONSOLE_DYNAMIC=y CONFIG_VETH=m -CONFIG_NET_ETHERNET=y +# CONFIG_NET_CADENCE is not set +# CONFIG_NET_VENDOR_BROADCOM is not set CONFIG_MVME16x_NET=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_STMICRO is not set +# CONFIG_NET_VENDOR_WIZNET is not set CONFIG_PPP=m -CONFIG_PPP_FILTER=y -CONFIG_PPP_ASYNC=m -CONFIG_PPP_SYNC_TTY=m -CONFIG_PPP_DEFLATE=m CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_FILTER=y CONFIG_PPP_MPPE=m CONFIG_PPPOE=m +CONFIG_PPTP=m +CONFIG_PPPOL2TP=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m CONFIG_SLIP=m CONFIG_SLIP_COMPRESSED=y CONFIG_SLIP_SMART=y CONFIG_SLIP_MODE_SLIP6=y -CONFIG_NETCONSOLE=m -CONFIG_NETCONSOLE_DYNAMIC=y -CONFIG_INPUT_FF_MEMLESS=m +# CONFIG_WLAN is not set +CONFIG_INPUT_EVDEV=m # CONFIG_KEYBOARD_ATKBD is not set -CONFIG_MOUSE_PS2=m -CONFIG_MOUSE_SERIAL=m -CONFIG_SERIO=m -# CONFIG_SERIO_SERPORT is not set +# CONFIG_MOUSE_PS2 is not set +# CONFIG_SERIO is not set CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_LEGACY_PTYS is not set # CONFIG_DEVKMEM is not set # CONFIG_HW_RANDOM is not set -CONFIG_GEN_RTC=m -CONFIG_GEN_RTC_X=y +CONFIG_NTP_PPS=y +CONFIG_PPS_CLIENT_LDISC=m +CONFIG_PTP_1588_CLOCK=m # CONFIG_HWMON is not set CONFIG_HID=m CONFIG_HIDRAW=y +CONFIG_UHID=m +# CONFIG_HID_GENERIC is not set # CONFIG_USB_SUPPORT is not set +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_GENERIC=m +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_PROC_HARDWARE=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set # CONFIG_EXT3_FS_XATTR is not set +CONFIG_EXT4_FS=y CONFIG_REISERFS_FS=m CONFIG_JFS_FS=m CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m -# CONFIG_OCFS2_FS_STATS is not set # CONFIG_OCFS2_DEBUG_MASKLOG is not set +CONFIG_FANOTIFY=y CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set -CONFIG_AUTOFS_FS=m CONFIG_AUTOFS4_FS=m CONFIG_FUSE_FS=m +CONFIG_CUSE=m CONFIG_ISO9660_FS=y CONFIG_JOLIET=y CONFIG_ZISOFS=y CONFIG_UDF_FS=m -CONFIG_MSDOS_FS=y +CONFIG_MSDOS_FS=m CONFIG_VFAT_FS=m CONFIG_PROC_KCORE=y CONFIG_TMPFS=y CONFIG_AFFS_FS=m +CONFIG_ECRYPT_FS=m +CONFIG_ECRYPT_FS_MESSAGING=y CONFIG_HFS_FS=m CONFIG_HFSPLUS_FS=m CONFIG_CRAMFS=m CONFIG_SQUASHFS=m -CONFIG_MINIX_FS=y +CONFIG_SQUASHFS_LZO=y +CONFIG_MINIX_FS=m +CONFIG_OMFS_FS=m CONFIG_HPFS_FS=m +CONFIG_QNX4FS_FS=m +CONFIG_QNX6FS_FS=m CONFIG_SYSV_FS=m CONFIG_UFS_FS=m CONFIG_NFS_FS=y -CONFIG_NFS_V3=y CONFIG_NFS_V4=y +CONFIG_NFS_SWAP=y CONFIG_ROOT_NFS=y CONFIG_NFSD=m CONFIG_NFSD_V3=y -CONFIG_SMB_FS=m -CONFIG_SMB_NLS_DEFAULT=y +CONFIG_CIFS=m +# CONFIG_CIFS_DEBUG is not set CONFIG_CODA_FS=m CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_CODEPAGE_737=m @@ -295,10 +379,23 @@ CONFIG_NLS_ISO8859_14=m CONFIG_NLS_ISO8859_15=m CONFIG_NLS_KOI8_R=m CONFIG_NLS_KOI8_U=m +CONFIG_NLS_MAC_ROMAN=m +CONFIG_NLS_MAC_CELTIC=m +CONFIG_NLS_MAC_CENTEURO=m +CONFIG_NLS_MAC_CROATIAN=m +CONFIG_NLS_MAC_CYRILLIC=m +CONFIG_NLS_MAC_GAELIC=m +CONFIG_NLS_MAC_GREEK=m +CONFIG_NLS_MAC_ICELAND=m +CONFIG_NLS_MAC_INUIT=m +CONFIG_NLS_MAC_ROMANIAN=m +CONFIG_NLS_MAC_TURKISH=m CONFIG_DLM=m CONFIG_MAGIC_SYSRQ=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y +CONFIG_ASYNC_RAID6_TEST=m +CONFIG_ENCRYPTED_KEYS=m +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_USER=m CONFIG_CRYPTO_NULL=m CONFIG_CRYPTO_CRYPTD=m CONFIG_CRYPTO_TEST=m @@ -308,19 +405,16 @@ CONFIG_CRYPTO_CTS=m CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_PCBC=m CONFIG_CRYPTO_XTS=m -CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_XCBC=m -CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_VMAC=m CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_RMD128=m CONFIG_CRYPTO_RMD160=m CONFIG_CRYPTO_RMD256=m CONFIG_CRYPTO_RMD320=m -CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m CONFIG_CRYPTO_TGR192=m CONFIG_CRYPTO_WP512=m -CONFIG_CRYPTO_AES=m CONFIG_CRYPTO_ANUBIS=m CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_CAMELLIA=m @@ -336,6 +430,14 @@ CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_ZLIB=m CONFIG_CRYPTO_LZO=m # CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_USER_API_HASH=m +CONFIG_CRYPTO_USER_API_SKCIPHER=m # CONFIG_CRYPTO_HW is not set -CONFIG_CRC16=m CONFIG_CRC_T10DIF=y +CONFIG_XZ_DEC_X86=y +CONFIG_XZ_DEC_POWERPC=y +CONFIG_XZ_DEC_IA64=y +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_ARMTHUMB=y +CONFIG_XZ_DEC_SPARC=y +CONFIG_XZ_DEC_TEST=m diff --git a/arch/m68k/configs/q40_defconfig b/arch/m68k/configs/q40_defconfig index 19d23db690a4..8982370e8b42 100644 --- a/arch/m68k/configs/q40_defconfig +++ b/arch/m68k/configs/q40_defconfig @@ -1,49 +1,74 @@ -CONFIG_EXPERIMENTAL=y CONFIG_LOCALVERSION="-q40" CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y +CONFIG_FHANDLE=y CONFIG_BSD_PROCESS_ACCT=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_RELAY=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_LOG_BUF_SHIFT=16 +# CONFIG_UTS_NS is not set +# CONFIG_IPC_NS is not set +# CONFIG_PID_NS is not set +# CONFIG_NET_NS is not set CONFIG_BLK_DEV_INITRD=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SLAB=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y -CONFIG_Q40=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_AMIGA_PARTITION=y +CONFIG_ATARI_PARTITION=y +CONFIG_MAC_PARTITION=y +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_SUN_PARTITION=y +# CONFIG_EFI_PARTITION is not set +CONFIG_SYSV68_PARTITION=y +CONFIG_IOSCHED_DEADLINE=m CONFIG_M68040=y CONFIG_M68060=y +CONFIG_Q40=y +# CONFIG_COMPACTION is not set +CONFIG_CLEANCACHE=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_BINFMT_AOUT=m CONFIG_BINFMT_MISC=m -CONFIG_HEARTBEAT=y -CONFIG_PROC_HARDWARE=y CONFIG_NET=y CONFIG_PACKET=y +CONFIG_PACKET_DIAG=m CONFIG_UNIX=y +CONFIG_UNIX_DIAG=m +CONFIG_XFRM_MIGRATE=y CONFIG_NET_KEY=y -CONFIG_NET_KEY_MIGRATE=y CONFIG_INET=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE_DEMUX=m CONFIG_NET_IPGRE=m CONFIG_SYN_COOKIES=y +CONFIG_NET_IPVTI=m CONFIG_INET_AH=m CONFIG_INET_ESP=m CONFIG_INET_IPCOMP=m CONFIG_INET_XFRM_MODE_TRANSPORT=m CONFIG_INET_XFRM_MODE_TUNNEL=m CONFIG_INET_XFRM_MODE_BEET=m +# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=m +CONFIG_INET_UDP_DIAG=m CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y -CONFIG_IPV6_ROUTE_INFO=y CONFIG_INET6_AH=m CONFIG_INET6_ESP=m CONFIG_INET6_IPCOMP=m -CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m -CONFIG_IPV6_TUNNEL=m +CONFIG_IPV6_GRE=m CONFIG_NETFILTER=y -CONFIG_NETFILTER_NETLINK_QUEUE=m CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_ZONES=y +# CONFIG_NF_CONNTRACK_PROCFS is not set # CONFIG_NF_CT_PROTO_DCCP is not set CONFIG_NF_CT_PROTO_UDPLITE=m CONFIG_NF_CONNTRACK_AMANDA=m @@ -51,25 +76,37 @@ CONFIG_NF_CONNTRACK_FTP=m CONFIG_NF_CONNTRACK_H323=m CONFIG_NF_CONNTRACK_IRC=m CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_SNMP=m CONFIG_NF_CONNTRACK_PPTP=m CONFIG_NF_CONNTRACK_SANE=m CONFIG_NF_CONNTRACK_SIP=m CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NETFILTER_XT_SET=m +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m CONFIG_NETFILTER_XT_TARGET_CONNMARK=m CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HMARK=m +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m +CONFIG_NETFILTER_XT_TARGET_LOG=m CONFIG_NETFILTER_XT_TARGET_MARK=m CONFIG_NETFILTER_XT_TARGET_NFLOG=m CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_TEE=m CONFIG_NETFILTER_XT_TARGET_TRACE=m CONFIG_NETFILTER_XT_TARGET_TCPMSS=m CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +CONFIG_NETFILTER_XT_MATCH_BPF=m CONFIG_NETFILTER_XT_MATCH_CLUSTER=m CONFIG_NETFILTER_XT_MATCH_COMMENT=m CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m CONFIG_NETFILTER_XT_MATCH_CONNMARK=m CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m CONFIG_NETFILTER_XT_MATCH_DSCP=m CONFIG_NETFILTER_XT_MATCH_ESP=m CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m @@ -80,6 +117,8 @@ CONFIG_NETFILTER_XT_MATCH_LIMIT=m CONFIG_NETFILTER_XT_MATCH_MAC=m CONFIG_NETFILTER_XT_MATCH_MARK=m CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_NFACCT=m +CONFIG_NETFILTER_XT_MATCH_OSF=m CONFIG_NETFILTER_XT_MATCH_OWNER=m CONFIG_NETFILTER_XT_MATCH_POLICY=m CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m @@ -93,22 +132,31 @@ CONFIG_NETFILTER_XT_MATCH_STRING=m CONFIG_NETFILTER_XT_MATCH_TCPMSS=m CONFIG_NETFILTER_XT_MATCH_TIME=m CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_IP_SET=m +CONFIG_IP_SET_BITMAP_IP=m +CONFIG_IP_SET_BITMAP_IPMAC=m +CONFIG_IP_SET_BITMAP_PORT=m +CONFIG_IP_SET_HASH_IP=m +CONFIG_IP_SET_HASH_IPPORT=m +CONFIG_IP_SET_HASH_IPPORTIP=m +CONFIG_IP_SET_HASH_IPPORTNET=m +CONFIG_IP_SET_HASH_NET=m +CONFIG_IP_SET_HASH_NETPORT=m +CONFIG_IP_SET_HASH_NETIFACE=m +CONFIG_IP_SET_LIST_SET=m CONFIG_NF_CONNTRACK_IPV4=m -CONFIG_IP_NF_QUEUE=m CONFIG_IP_NF_IPTABLES=m -CONFIG_IP_NF_MATCH_ADDRTYPE=m CONFIG_IP_NF_MATCH_AH=m CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_RPFILTER=m CONFIG_IP_NF_MATCH_TTL=m CONFIG_IP_NF_FILTER=m CONFIG_IP_NF_TARGET_REJECT=m -CONFIG_IP_NF_TARGET_LOG=m CONFIG_IP_NF_TARGET_ULOG=m -CONFIG_NF_NAT=m +CONFIG_NF_NAT_IPV4=m CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_REDIRECT=m -CONFIG_NF_NAT_SNMP_BASIC=m CONFIG_IP_NF_MANGLE=m CONFIG_IP_NF_TARGET_CLUSTERIP=m CONFIG_IP_NF_TARGET_ECN=m @@ -118,7 +166,6 @@ CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m CONFIG_NF_CONNTRACK_IPV6=m -CONFIG_IP6_NF_QUEUE=m CONFIG_IP6_NF_IPTABLES=m CONFIG_IP6_NF_MATCH_AH=m CONFIG_IP6_NF_MATCH_EUI64=m @@ -127,26 +174,40 @@ CONFIG_IP6_NF_MATCH_OPTS=m CONFIG_IP6_NF_MATCH_HL=m CONFIG_IP6_NF_MATCH_IPV6HEADER=m CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_RPFILTER=m CONFIG_IP6_NF_MATCH_RT=m CONFIG_IP6_NF_TARGET_HL=m -CONFIG_IP6_NF_TARGET_LOG=m CONFIG_IP6_NF_FILTER=m CONFIG_IP6_NF_TARGET_REJECT=m CONFIG_IP6_NF_MANGLE=m CONFIG_IP6_NF_RAW=m +CONFIG_NF_NAT_IPV6=m +CONFIG_IP6_NF_TARGET_MASQUERADE=m +CONFIG_IP6_NF_TARGET_NPT=m CONFIG_IP_DCCP=m # CONFIG_IP_DCCP_CCID3 is not set +CONFIG_SCTP_COOKIE_HMAC_SHA1=y +CONFIG_RDS=m +CONFIG_RDS_TCP=m +CONFIG_L2TP=m CONFIG_ATALK=m +CONFIG_BATMAN_ADV=m +CONFIG_BATMAN_ADV_DAT=y +# CONFIG_WIRELESS is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y # CONFIG_FIRMWARE_IN_KERNEL is not set +# CONFIG_FW_LOADER_USER_HELPER is not set CONFIG_CONNECTOR=m CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_DRBD=m CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=y CONFIG_CDROM_PKTCDVD=m CONFIG_ATA_OVER_ETH=m CONFIG_IDE=y +CONFIG_IDE_GD_ATAPI=y CONFIG_BLK_DEV_IDECD=y CONFIG_BLK_DEV_Q40IDE=y CONFIG_RAID_ATTRS=m @@ -159,61 +220,82 @@ CONFIG_BLK_DEV_SR=y CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y -CONFIG_SCSI_SAS_LIBSAS=m -# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set -CONFIG_SCSI_SRP_ATTRS=m -CONFIG_SCSI_SRP_TGT_ATTRS=y +CONFIG_SCSI_SAS_ATTRS=m CONFIG_ISCSI_TCP=m +CONFIG_ISCSI_BOOT_SYSFS=m CONFIG_MD=y -CONFIG_BLK_DEV_MD=m CONFIG_MD_LINEAR=m CONFIG_MD_RAID0=m -CONFIG_MD_RAID1=m -CONFIG_MD_RAID456=m CONFIG_BLK_DEV_DM=m CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m +CONFIG_DM_THIN_PROVISIONING=m +CONFIG_DM_CACHE=m CONFIG_DM_MIRROR=m +CONFIG_DM_RAID=m CONFIG_DM_ZERO=m CONFIG_DM_MULTIPATH=m CONFIG_DM_UEVENT=y +CONFIG_TARGET_CORE=m +CONFIG_TCM_IBLOCK=m +CONFIG_TCM_FILEIO=m +CONFIG_TCM_PSCSI=m CONFIG_NETDEVICES=y CONFIG_DUMMY=m -CONFIG_MACVLAN=m CONFIG_EQUALIZER=m +CONFIG_NET_TEAM=m +CONFIG_NET_TEAM_MODE_BROADCAST=m +CONFIG_NET_TEAM_MODE_ROUNDROBIN=m +CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m +CONFIG_NET_TEAM_MODE_LOADBALANCE=m +CONFIG_VXLAN=m +CONFIG_NETCONSOLE=m +CONFIG_NETCONSOLE_DYNAMIC=y CONFIG_VETH=m -CONFIG_NET_ETHERNET=y +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_NET_VENDOR_AMD is not set +# CONFIG_NET_CADENCE is not set +# CONFIG_NET_VENDOR_BROADCOM is not set +# CONFIG_NET_VENDOR_CIRRUS is not set +# CONFIG_NET_VENDOR_FUJITSU is not set +# CONFIG_NET_VENDOR_HP is not set +# CONFIG_NET_VENDOR_INTEL is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MICREL is not set CONFIG_NE2000=m -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_SMSC is not set +# CONFIG_NET_VENDOR_STMICRO is not set +# CONFIG_NET_VENDOR_WIZNET is not set CONFIG_PPP=m -CONFIG_PPP_FILTER=y -CONFIG_PPP_ASYNC=m -CONFIG_PPP_SYNC_TTY=m -CONFIG_PPP_DEFLATE=m CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_FILTER=y CONFIG_PPP_MPPE=m CONFIG_PPPOE=m +CONFIG_PPTP=m +CONFIG_PPPOL2TP=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m CONFIG_SLIP=m CONFIG_SLIP_COMPRESSED=y CONFIG_SLIP_SMART=y CONFIG_SLIP_MODE_SLIP6=y -CONFIG_NETCONSOLE=m -CONFIG_NETCONSOLE_DYNAMIC=y -CONFIG_INPUT_FF_MEMLESS=m +# CONFIG_WLAN is not set +CONFIG_INPUT_EVDEV=m # CONFIG_KEYBOARD_ATKBD is not set -CONFIG_MOUSE_PS2=m +# CONFIG_MOUSE_PS2 is not set CONFIG_MOUSE_SERIAL=m CONFIG_INPUT_MISC=y CONFIG_INPUT_M68K_BEEP=m -CONFIG_SERIO=m -# CONFIG_SERIO_SERPORT is not set -CONFIG_SERIO_Q40KBD=m +CONFIG_SERIO_Q40KBD=y CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_LEGACY_PTYS is not set # CONFIG_DEVKMEM is not set # CONFIG_HW_RANDOM is not set -CONFIG_GEN_RTC=m -CONFIG_GEN_RTC_X=y +CONFIG_NTP_PPS=y +CONFIG_PPS_CLIENT_LDISC=m +CONFIG_PTP_1588_CLOCK=m # CONFIG_HWMON is not set CONFIG_FB=y CONFIG_FRAMEBUFFER_CONSOLE=y @@ -222,46 +304,61 @@ CONFIG_SOUND=m CONFIG_DMASOUND_Q40=m CONFIG_HID=m CONFIG_HIDRAW=y +CONFIG_UHID=m +# CONFIG_HID_GENERIC is not set # CONFIG_USB_SUPPORT is not set +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_GENERIC=m +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_HEARTBEAT=y +CONFIG_PROC_HARDWARE=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set # CONFIG_EXT3_FS_XATTR is not set +CONFIG_EXT4_FS=y CONFIG_REISERFS_FS=m CONFIG_JFS_FS=m CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m -# CONFIG_OCFS2_FS_STATS is not set # CONFIG_OCFS2_DEBUG_MASKLOG is not set +CONFIG_FANOTIFY=y CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set -CONFIG_AUTOFS_FS=m CONFIG_AUTOFS4_FS=m CONFIG_FUSE_FS=m +CONFIG_CUSE=m CONFIG_ISO9660_FS=y CONFIG_JOLIET=y CONFIG_ZISOFS=y CONFIG_UDF_FS=m -CONFIG_MSDOS_FS=y +CONFIG_MSDOS_FS=m CONFIG_VFAT_FS=m CONFIG_PROC_KCORE=y CONFIG_TMPFS=y CONFIG_AFFS_FS=m +CONFIG_ECRYPT_FS=m +CONFIG_ECRYPT_FS_MESSAGING=y CONFIG_HFS_FS=m CONFIG_HFSPLUS_FS=m CONFIG_CRAMFS=m CONFIG_SQUASHFS=m -CONFIG_MINIX_FS=y +CONFIG_SQUASHFS_LZO=y +CONFIG_MINIX_FS=m +CONFIG_OMFS_FS=m CONFIG_HPFS_FS=m +CONFIG_QNX4FS_FS=m +CONFIG_QNX6FS_FS=m CONFIG_SYSV_FS=m CONFIG_UFS_FS=m CONFIG_NFS_FS=y -CONFIG_NFS_V3=y CONFIG_NFS_V4=y +CONFIG_NFS_SWAP=y +CONFIG_ROOT_NFS=y CONFIG_NFSD=m CONFIG_NFSD_V3=y -CONFIG_SMB_FS=m -CONFIG_SMB_NLS_DEFAULT=y +CONFIG_CIFS=m +# CONFIG_CIFS_DEBUG is not set CONFIG_CODA_FS=m CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_CODEPAGE_737=m @@ -300,10 +397,23 @@ CONFIG_NLS_ISO8859_14=m CONFIG_NLS_ISO8859_15=m CONFIG_NLS_KOI8_R=m CONFIG_NLS_KOI8_U=m +CONFIG_NLS_MAC_ROMAN=m +CONFIG_NLS_MAC_CELTIC=m +CONFIG_NLS_MAC_CENTEURO=m +CONFIG_NLS_MAC_CROATIAN=m +CONFIG_NLS_MAC_CYRILLIC=m +CONFIG_NLS_MAC_GAELIC=m +CONFIG_NLS_MAC_GREEK=m +CONFIG_NLS_MAC_ICELAND=m +CONFIG_NLS_MAC_INUIT=m +CONFIG_NLS_MAC_ROMANIAN=m +CONFIG_NLS_MAC_TURKISH=m CONFIG_DLM=m CONFIG_MAGIC_SYSRQ=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y +CONFIG_ASYNC_RAID6_TEST=m +CONFIG_ENCRYPTED_KEYS=m +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_USER=m CONFIG_CRYPTO_NULL=m CONFIG_CRYPTO_CRYPTD=m CONFIG_CRYPTO_TEST=m @@ -313,19 +423,16 @@ CONFIG_CRYPTO_CTS=m CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_PCBC=m CONFIG_CRYPTO_XTS=m -CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_XCBC=m -CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_VMAC=m CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_RMD128=m CONFIG_CRYPTO_RMD160=m CONFIG_CRYPTO_RMD256=m CONFIG_CRYPTO_RMD320=m -CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m CONFIG_CRYPTO_TGR192=m CONFIG_CRYPTO_WP512=m -CONFIG_CRYPTO_AES=m CONFIG_CRYPTO_ANUBIS=m CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_CAMELLIA=m @@ -341,6 +448,14 @@ CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_ZLIB=m CONFIG_CRYPTO_LZO=m # CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_USER_API_HASH=m +CONFIG_CRYPTO_USER_API_SKCIPHER=m # CONFIG_CRYPTO_HW is not set -CONFIG_CRC16=m CONFIG_CRC_T10DIF=y +CONFIG_XZ_DEC_X86=y +CONFIG_XZ_DEC_POWERPC=y +CONFIG_XZ_DEC_IA64=y +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_ARMTHUMB=y +CONFIG_XZ_DEC_SPARC=y +CONFIG_XZ_DEC_TEST=m diff --git a/arch/m68k/configs/sun3_defconfig b/arch/m68k/configs/sun3_defconfig index ca6c0b4cab77..54674d61e001 100644 --- a/arch/m68k/configs/sun3_defconfig +++ b/arch/m68k/configs/sun3_defconfig @@ -1,50 +1,71 @@ -CONFIG_EXPERIMENTAL=y CONFIG_LOCALVERSION="-sun3" CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y +CONFIG_FHANDLE=y CONFIG_BSD_PROCESS_ACCT=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_RELAY=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_LOG_BUF_SHIFT=16 +# CONFIG_UTS_NS is not set +# CONFIG_IPC_NS is not set +# CONFIG_PID_NS is not set +# CONFIG_NET_NS is not set CONFIG_BLK_DEV_INITRD=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SLAB=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_AMIGA_PARTITION=y +CONFIG_ATARI_PARTITION=y +CONFIG_MAC_PARTITION=y +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +# CONFIG_EFI_PARTITION is not set +CONFIG_SYSV68_PARTITION=y +CONFIG_IOSCHED_DEADLINE=m CONFIG_SUN3=y +# CONFIG_COMPACTION is not set +CONFIG_CLEANCACHE=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_BINFMT_AOUT=m CONFIG_BINFMT_MISC=m -CONFIG_PROC_HARDWARE=y CONFIG_NET=y CONFIG_PACKET=y +CONFIG_PACKET_DIAG=m CONFIG_UNIX=y +CONFIG_UNIX_DIAG=m +CONFIG_XFRM_MIGRATE=y CONFIG_NET_KEY=y -CONFIG_NET_KEY_MIGRATE=y CONFIG_INET=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_IP_PNP_RARP=y CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE_DEMUX=m CONFIG_NET_IPGRE=m CONFIG_SYN_COOKIES=y +CONFIG_NET_IPVTI=m CONFIG_INET_AH=m CONFIG_INET_ESP=m CONFIG_INET_IPCOMP=m CONFIG_INET_XFRM_MODE_TRANSPORT=m CONFIG_INET_XFRM_MODE_TUNNEL=m CONFIG_INET_XFRM_MODE_BEET=m +# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=m +CONFIG_INET_UDP_DIAG=m CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y -CONFIG_IPV6_ROUTE_INFO=y CONFIG_INET6_AH=m CONFIG_INET6_ESP=m CONFIG_INET6_IPCOMP=m -CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m -CONFIG_IPV6_TUNNEL=m +CONFIG_IPV6_GRE=m CONFIG_NETFILTER=y -CONFIG_NETFILTER_NETLINK_QUEUE=m CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_ZONES=y +# CONFIG_NF_CONNTRACK_PROCFS is not set # CONFIG_NF_CT_PROTO_DCCP is not set CONFIG_NF_CT_PROTO_UDPLITE=m CONFIG_NF_CONNTRACK_AMANDA=m @@ -52,25 +73,37 @@ CONFIG_NF_CONNTRACK_FTP=m CONFIG_NF_CONNTRACK_H323=m CONFIG_NF_CONNTRACK_IRC=m CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_SNMP=m CONFIG_NF_CONNTRACK_PPTP=m CONFIG_NF_CONNTRACK_SANE=m CONFIG_NF_CONNTRACK_SIP=m CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NETFILTER_XT_SET=m +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m CONFIG_NETFILTER_XT_TARGET_CONNMARK=m CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HMARK=m +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m +CONFIG_NETFILTER_XT_TARGET_LOG=m CONFIG_NETFILTER_XT_TARGET_MARK=m CONFIG_NETFILTER_XT_TARGET_NFLOG=m CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_TEE=m CONFIG_NETFILTER_XT_TARGET_TRACE=m CONFIG_NETFILTER_XT_TARGET_TCPMSS=m CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +CONFIG_NETFILTER_XT_MATCH_BPF=m CONFIG_NETFILTER_XT_MATCH_CLUSTER=m CONFIG_NETFILTER_XT_MATCH_COMMENT=m CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m CONFIG_NETFILTER_XT_MATCH_CONNMARK=m CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m CONFIG_NETFILTER_XT_MATCH_DSCP=m CONFIG_NETFILTER_XT_MATCH_ESP=m CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m @@ -81,6 +114,8 @@ CONFIG_NETFILTER_XT_MATCH_LIMIT=m CONFIG_NETFILTER_XT_MATCH_MAC=m CONFIG_NETFILTER_XT_MATCH_MARK=m CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_NFACCT=m +CONFIG_NETFILTER_XT_MATCH_OSF=m CONFIG_NETFILTER_XT_MATCH_OWNER=m CONFIG_NETFILTER_XT_MATCH_POLICY=m CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m @@ -94,22 +129,31 @@ CONFIG_NETFILTER_XT_MATCH_STRING=m CONFIG_NETFILTER_XT_MATCH_TCPMSS=m CONFIG_NETFILTER_XT_MATCH_TIME=m CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_IP_SET=m +CONFIG_IP_SET_BITMAP_IP=m +CONFIG_IP_SET_BITMAP_IPMAC=m +CONFIG_IP_SET_BITMAP_PORT=m +CONFIG_IP_SET_HASH_IP=m +CONFIG_IP_SET_HASH_IPPORT=m +CONFIG_IP_SET_HASH_IPPORTIP=m +CONFIG_IP_SET_HASH_IPPORTNET=m +CONFIG_IP_SET_HASH_NET=m +CONFIG_IP_SET_HASH_NETPORT=m +CONFIG_IP_SET_HASH_NETIFACE=m +CONFIG_IP_SET_LIST_SET=m CONFIG_NF_CONNTRACK_IPV4=m -CONFIG_IP_NF_QUEUE=m CONFIG_IP_NF_IPTABLES=m -CONFIG_IP_NF_MATCH_ADDRTYPE=m CONFIG_IP_NF_MATCH_AH=m CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_RPFILTER=m CONFIG_IP_NF_MATCH_TTL=m CONFIG_IP_NF_FILTER=m CONFIG_IP_NF_TARGET_REJECT=m -CONFIG_IP_NF_TARGET_LOG=m CONFIG_IP_NF_TARGET_ULOG=m -CONFIG_NF_NAT=m +CONFIG_NF_NAT_IPV4=m CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_REDIRECT=m -CONFIG_NF_NAT_SNMP_BASIC=m CONFIG_IP_NF_MANGLE=m CONFIG_IP_NF_TARGET_CLUSTERIP=m CONFIG_IP_NF_TARGET_ECN=m @@ -119,7 +163,6 @@ CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m CONFIG_NF_CONNTRACK_IPV6=m -CONFIG_IP6_NF_QUEUE=m CONFIG_IP6_NF_IPTABLES=m CONFIG_IP6_NF_MATCH_AH=m CONFIG_IP6_NF_MATCH_EUI64=m @@ -128,21 +171,34 @@ CONFIG_IP6_NF_MATCH_OPTS=m CONFIG_IP6_NF_MATCH_HL=m CONFIG_IP6_NF_MATCH_IPV6HEADER=m CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_RPFILTER=m CONFIG_IP6_NF_MATCH_RT=m CONFIG_IP6_NF_TARGET_HL=m -CONFIG_IP6_NF_TARGET_LOG=m CONFIG_IP6_NF_FILTER=m CONFIG_IP6_NF_TARGET_REJECT=m CONFIG_IP6_NF_MANGLE=m CONFIG_IP6_NF_RAW=m +CONFIG_NF_NAT_IPV6=m +CONFIG_IP6_NF_TARGET_MASQUERADE=m +CONFIG_IP6_NF_TARGET_NPT=m CONFIG_IP_DCCP=m # CONFIG_IP_DCCP_CCID3 is not set +CONFIG_SCTP_COOKIE_HMAC_SHA1=y +CONFIG_RDS=m +CONFIG_RDS_TCP=m +CONFIG_L2TP=m CONFIG_ATALK=m +CONFIG_BATMAN_ADV=m +CONFIG_BATMAN_ADV_DAT=y +# CONFIG_WIRELESS is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y # CONFIG_FIRMWARE_IN_KERNEL is not set +# CONFIG_FW_LOADER_USER_HELPER is not set CONFIG_CONNECTOR=m CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_DRBD=m CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=y CONFIG_CDROM_PKTCDVD=m @@ -157,107 +213,136 @@ CONFIG_BLK_DEV_SR=y CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y -CONFIG_SCSI_SAS_LIBSAS=m -# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set -CONFIG_SCSI_SRP_ATTRS=m -CONFIG_SCSI_SRP_TGT_ATTRS=y +CONFIG_SCSI_SAS_ATTRS=m CONFIG_ISCSI_TCP=m +CONFIG_ISCSI_BOOT_SYSFS=m CONFIG_SUN3_SCSI=y CONFIG_MD=y -CONFIG_BLK_DEV_MD=m CONFIG_MD_LINEAR=m CONFIG_MD_RAID0=m -CONFIG_MD_RAID1=m -CONFIG_MD_RAID456=m CONFIG_BLK_DEV_DM=m CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m +CONFIG_DM_THIN_PROVISIONING=m +CONFIG_DM_CACHE=m CONFIG_DM_MIRROR=m +CONFIG_DM_RAID=m CONFIG_DM_ZERO=m CONFIG_DM_MULTIPATH=m CONFIG_DM_UEVENT=y +CONFIG_TARGET_CORE=m +CONFIG_TCM_IBLOCK=m +CONFIG_TCM_FILEIO=m +CONFIG_TCM_PSCSI=m CONFIG_NETDEVICES=y CONFIG_DUMMY=m -CONFIG_MACVLAN=m CONFIG_EQUALIZER=m +CONFIG_NET_TEAM=m +CONFIG_NET_TEAM_MODE_BROADCAST=m +CONFIG_NET_TEAM_MODE_ROUNDROBIN=m +CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m +CONFIG_NET_TEAM_MODE_LOADBALANCE=m +CONFIG_VXLAN=m +CONFIG_NETCONSOLE=m +CONFIG_NETCONSOLE_DYNAMIC=y CONFIG_VETH=m -CONFIG_NET_ETHERNET=y CONFIG_SUN3LANCE=y +# CONFIG_NET_CADENCE is not set CONFIG_SUN3_82586=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_STMICRO is not set +# CONFIG_NET_VENDOR_SUN is not set +# CONFIG_NET_VENDOR_WIZNET is not set CONFIG_PPP=m -CONFIG_PPP_FILTER=y -CONFIG_PPP_ASYNC=m -CONFIG_PPP_SYNC_TTY=m -CONFIG_PPP_DEFLATE=m CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_FILTER=y CONFIG_PPP_MPPE=m CONFIG_PPPOE=m +CONFIG_PPTP=m +CONFIG_PPPOL2TP=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m CONFIG_SLIP=m CONFIG_SLIP_COMPRESSED=y CONFIG_SLIP_SMART=y CONFIG_SLIP_MODE_SLIP6=y -CONFIG_NETCONSOLE=m -CONFIG_NETCONSOLE_DYNAMIC=y -CONFIG_INPUT_FF_MEMLESS=m +# CONFIG_WLAN is not set +CONFIG_INPUT_EVDEV=m # CONFIG_KEYBOARD_ATKBD is not set CONFIG_KEYBOARD_SUNKBD=y -CONFIG_MOUSE_PS2=m +# CONFIG_MOUSE_PS2 is not set CONFIG_MOUSE_SERIAL=m -# CONFIG_SERIO_SERPORT is not set CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_LEGACY_PTYS is not set # CONFIG_DEVKMEM is not set # CONFIG_HW_RANDOM is not set -CONFIG_GEN_RTC=m -CONFIG_GEN_RTC_X=y +CONFIG_NTP_PPS=y +CONFIG_PPS_CLIENT_LDISC=m +CONFIG_PTP_1588_CLOCK=m # CONFIG_HWMON is not set CONFIG_FB=y CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_LOGO=y CONFIG_HID=m CONFIG_HIDRAW=y +CONFIG_UHID=m +# CONFIG_HID_GENERIC is not set # CONFIG_USB_SUPPORT is not set +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_GENERIC=m +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_PROC_HARDWARE=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set # CONFIG_EXT3_FS_XATTR is not set +CONFIG_EXT4_FS=y CONFIG_REISERFS_FS=m CONFIG_JFS_FS=m CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m -# CONFIG_OCFS2_FS_STATS is not set # CONFIG_OCFS2_DEBUG_MASKLOG is not set +CONFIG_FANOTIFY=y CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set -CONFIG_AUTOFS_FS=m CONFIG_AUTOFS4_FS=m CONFIG_FUSE_FS=m +CONFIG_CUSE=m CONFIG_ISO9660_FS=y CONFIG_JOLIET=y CONFIG_ZISOFS=y CONFIG_UDF_FS=m -CONFIG_MSDOS_FS=y +CONFIG_MSDOS_FS=m CONFIG_VFAT_FS=m CONFIG_PROC_KCORE=y CONFIG_TMPFS=y CONFIG_AFFS_FS=m +CONFIG_ECRYPT_FS=m +CONFIG_ECRYPT_FS_MESSAGING=y CONFIG_HFS_FS=m CONFIG_HFSPLUS_FS=m CONFIG_CRAMFS=m CONFIG_SQUASHFS=m -CONFIG_MINIX_FS=y +CONFIG_SQUASHFS_LZO=y +CONFIG_MINIX_FS=m +CONFIG_OMFS_FS=m CONFIG_HPFS_FS=m +CONFIG_QNX4FS_FS=m +CONFIG_QNX6FS_FS=m CONFIG_SYSV_FS=m CONFIG_UFS_FS=m CONFIG_NFS_FS=y -CONFIG_NFS_V3=y CONFIG_NFS_V4=y +CONFIG_NFS_SWAP=y CONFIG_ROOT_NFS=y CONFIG_NFSD=m CONFIG_NFSD_V3=y -CONFIG_SMB_FS=m -CONFIG_SMB_NLS_DEFAULT=y +CONFIG_CIFS=m +# CONFIG_CIFS_DEBUG is not set CONFIG_CODA_FS=m CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_CODEPAGE_737=m @@ -296,10 +381,23 @@ CONFIG_NLS_ISO8859_14=m CONFIG_NLS_ISO8859_15=m CONFIG_NLS_KOI8_R=m CONFIG_NLS_KOI8_U=m +CONFIG_NLS_MAC_ROMAN=m +CONFIG_NLS_MAC_CELTIC=m +CONFIG_NLS_MAC_CENTEURO=m +CONFIG_NLS_MAC_CROATIAN=m +CONFIG_NLS_MAC_CYRILLIC=m +CONFIG_NLS_MAC_GAELIC=m +CONFIG_NLS_MAC_GREEK=m +CONFIG_NLS_MAC_ICELAND=m +CONFIG_NLS_MAC_INUIT=m +CONFIG_NLS_MAC_ROMANIAN=m +CONFIG_NLS_MAC_TURKISH=m CONFIG_DLM=m CONFIG_MAGIC_SYSRQ=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y +CONFIG_ASYNC_RAID6_TEST=m +CONFIG_ENCRYPTED_KEYS=m +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_USER=m CONFIG_CRYPTO_NULL=m CONFIG_CRYPTO_CRYPTD=m CONFIG_CRYPTO_TEST=m @@ -309,19 +407,16 @@ CONFIG_CRYPTO_CTS=m CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_PCBC=m CONFIG_CRYPTO_XTS=m -CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_XCBC=m -CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_VMAC=m CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_RMD128=m CONFIG_CRYPTO_RMD160=m CONFIG_CRYPTO_RMD256=m CONFIG_CRYPTO_RMD320=m -CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m CONFIG_CRYPTO_TGR192=m CONFIG_CRYPTO_WP512=m -CONFIG_CRYPTO_AES=m CONFIG_CRYPTO_ANUBIS=m CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_CAMELLIA=m @@ -337,6 +432,14 @@ CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_ZLIB=m CONFIG_CRYPTO_LZO=m # CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_USER_API_HASH=m +CONFIG_CRYPTO_USER_API_SKCIPHER=m # CONFIG_CRYPTO_HW is not set -CONFIG_CRC16=m CONFIG_CRC_T10DIF=y +CONFIG_XZ_DEC_X86=y +CONFIG_XZ_DEC_POWERPC=y +CONFIG_XZ_DEC_IA64=y +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_ARMTHUMB=y +CONFIG_XZ_DEC_SPARC=y +CONFIG_XZ_DEC_TEST=m diff --git a/arch/m68k/configs/sun3x_defconfig b/arch/m68k/configs/sun3x_defconfig index c80941c7759e..832d9539f441 100644 --- a/arch/m68k/configs/sun3x_defconfig +++ b/arch/m68k/configs/sun3x_defconfig @@ -1,50 +1,71 @@ -CONFIG_EXPERIMENTAL=y CONFIG_LOCALVERSION="-sun3x" CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y +CONFIG_FHANDLE=y CONFIG_BSD_PROCESS_ACCT=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_RELAY=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_LOG_BUF_SHIFT=16 +# CONFIG_UTS_NS is not set +# CONFIG_IPC_NS is not set +# CONFIG_PID_NS is not set +# CONFIG_NET_NS is not set CONFIG_BLK_DEV_INITRD=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SLAB=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_AMIGA_PARTITION=y +CONFIG_ATARI_PARTITION=y +CONFIG_MAC_PARTITION=y +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +# CONFIG_EFI_PARTITION is not set +CONFIG_SYSV68_PARTITION=y +CONFIG_IOSCHED_DEADLINE=m CONFIG_SUN3X=y +# CONFIG_COMPACTION is not set +CONFIG_CLEANCACHE=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_BINFMT_AOUT=m CONFIG_BINFMT_MISC=m -CONFIG_PROC_HARDWARE=y CONFIG_NET=y CONFIG_PACKET=y +CONFIG_PACKET_DIAG=m CONFIG_UNIX=y +CONFIG_UNIX_DIAG=m +CONFIG_XFRM_MIGRATE=y CONFIG_NET_KEY=y -CONFIG_NET_KEY_MIGRATE=y CONFIG_INET=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_IP_PNP_RARP=y CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE_DEMUX=m CONFIG_NET_IPGRE=m CONFIG_SYN_COOKIES=y +CONFIG_NET_IPVTI=m CONFIG_INET_AH=m CONFIG_INET_ESP=m CONFIG_INET_IPCOMP=m CONFIG_INET_XFRM_MODE_TRANSPORT=m CONFIG_INET_XFRM_MODE_TUNNEL=m CONFIG_INET_XFRM_MODE_BEET=m +# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=m +CONFIG_INET_UDP_DIAG=m CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y -CONFIG_IPV6_ROUTE_INFO=y CONFIG_INET6_AH=m CONFIG_INET6_ESP=m CONFIG_INET6_IPCOMP=m -CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m -CONFIG_IPV6_TUNNEL=m +CONFIG_IPV6_GRE=m CONFIG_NETFILTER=y -CONFIG_NETFILTER_NETLINK_QUEUE=m CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_ZONES=y +# CONFIG_NF_CONNTRACK_PROCFS is not set # CONFIG_NF_CT_PROTO_DCCP is not set CONFIG_NF_CT_PROTO_UDPLITE=m CONFIG_NF_CONNTRACK_AMANDA=m @@ -52,25 +73,37 @@ CONFIG_NF_CONNTRACK_FTP=m CONFIG_NF_CONNTRACK_H323=m CONFIG_NF_CONNTRACK_IRC=m CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_SNMP=m CONFIG_NF_CONNTRACK_PPTP=m CONFIG_NF_CONNTRACK_SANE=m CONFIG_NF_CONNTRACK_SIP=m CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NETFILTER_XT_SET=m +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m CONFIG_NETFILTER_XT_TARGET_CONNMARK=m CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HMARK=m +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m +CONFIG_NETFILTER_XT_TARGET_LOG=m CONFIG_NETFILTER_XT_TARGET_MARK=m CONFIG_NETFILTER_XT_TARGET_NFLOG=m CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_TEE=m CONFIG_NETFILTER_XT_TARGET_TRACE=m CONFIG_NETFILTER_XT_TARGET_TCPMSS=m CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +CONFIG_NETFILTER_XT_MATCH_BPF=m CONFIG_NETFILTER_XT_MATCH_CLUSTER=m CONFIG_NETFILTER_XT_MATCH_COMMENT=m CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m CONFIG_NETFILTER_XT_MATCH_CONNMARK=m CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m CONFIG_NETFILTER_XT_MATCH_DSCP=m CONFIG_NETFILTER_XT_MATCH_ESP=m CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m @@ -81,6 +114,8 @@ CONFIG_NETFILTER_XT_MATCH_LIMIT=m CONFIG_NETFILTER_XT_MATCH_MAC=m CONFIG_NETFILTER_XT_MATCH_MARK=m CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_NFACCT=m +CONFIG_NETFILTER_XT_MATCH_OSF=m CONFIG_NETFILTER_XT_MATCH_OWNER=m CONFIG_NETFILTER_XT_MATCH_POLICY=m CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m @@ -94,22 +129,31 @@ CONFIG_NETFILTER_XT_MATCH_STRING=m CONFIG_NETFILTER_XT_MATCH_TCPMSS=m CONFIG_NETFILTER_XT_MATCH_TIME=m CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_IP_SET=m +CONFIG_IP_SET_BITMAP_IP=m +CONFIG_IP_SET_BITMAP_IPMAC=m +CONFIG_IP_SET_BITMAP_PORT=m +CONFIG_IP_SET_HASH_IP=m +CONFIG_IP_SET_HASH_IPPORT=m +CONFIG_IP_SET_HASH_IPPORTIP=m +CONFIG_IP_SET_HASH_IPPORTNET=m +CONFIG_IP_SET_HASH_NET=m +CONFIG_IP_SET_HASH_NETPORT=m +CONFIG_IP_SET_HASH_NETIFACE=m +CONFIG_IP_SET_LIST_SET=m CONFIG_NF_CONNTRACK_IPV4=m -CONFIG_IP_NF_QUEUE=m CONFIG_IP_NF_IPTABLES=m -CONFIG_IP_NF_MATCH_ADDRTYPE=m CONFIG_IP_NF_MATCH_AH=m CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_RPFILTER=m CONFIG_IP_NF_MATCH_TTL=m CONFIG_IP_NF_FILTER=m CONFIG_IP_NF_TARGET_REJECT=m -CONFIG_IP_NF_TARGET_LOG=m CONFIG_IP_NF_TARGET_ULOG=m -CONFIG_NF_NAT=m +CONFIG_NF_NAT_IPV4=m CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_REDIRECT=m -CONFIG_NF_NAT_SNMP_BASIC=m CONFIG_IP_NF_MANGLE=m CONFIG_IP_NF_TARGET_CLUSTERIP=m CONFIG_IP_NF_TARGET_ECN=m @@ -119,7 +163,6 @@ CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m CONFIG_NF_CONNTRACK_IPV6=m -CONFIG_IP6_NF_QUEUE=m CONFIG_IP6_NF_IPTABLES=m CONFIG_IP6_NF_MATCH_AH=m CONFIG_IP6_NF_MATCH_EUI64=m @@ -128,21 +171,34 @@ CONFIG_IP6_NF_MATCH_OPTS=m CONFIG_IP6_NF_MATCH_HL=m CONFIG_IP6_NF_MATCH_IPV6HEADER=m CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_RPFILTER=m CONFIG_IP6_NF_MATCH_RT=m CONFIG_IP6_NF_TARGET_HL=m -CONFIG_IP6_NF_TARGET_LOG=m CONFIG_IP6_NF_FILTER=m CONFIG_IP6_NF_TARGET_REJECT=m CONFIG_IP6_NF_MANGLE=m CONFIG_IP6_NF_RAW=m +CONFIG_NF_NAT_IPV6=m +CONFIG_IP6_NF_TARGET_MASQUERADE=m +CONFIG_IP6_NF_TARGET_NPT=m CONFIG_IP_DCCP=m # CONFIG_IP_DCCP_CCID3 is not set +CONFIG_SCTP_COOKIE_HMAC_SHA1=y +CONFIG_RDS=m +CONFIG_RDS_TCP=m +CONFIG_L2TP=m CONFIG_ATALK=m +CONFIG_BATMAN_ADV=m +CONFIG_BATMAN_ADV_DAT=y +# CONFIG_WIRELESS is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y # CONFIG_FIRMWARE_IN_KERNEL is not set +# CONFIG_FW_LOADER_USER_HELPER is not set CONFIG_CONNECTOR=m CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_DRBD=m CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=y CONFIG_CDROM_PKTCDVD=m @@ -157,106 +213,136 @@ CONFIG_BLK_DEV_SR=y CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y -CONFIG_SCSI_SAS_LIBSAS=m -# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set -CONFIG_SCSI_SRP_ATTRS=m -CONFIG_SCSI_SRP_TGT_ATTRS=y +CONFIG_SCSI_SAS_ATTRS=m CONFIG_ISCSI_TCP=m +CONFIG_ISCSI_BOOT_SYSFS=m CONFIG_SUN3X_ESP=y CONFIG_MD=y -CONFIG_BLK_DEV_MD=m CONFIG_MD_LINEAR=m CONFIG_MD_RAID0=m -CONFIG_MD_RAID1=m -CONFIG_MD_RAID456=m CONFIG_BLK_DEV_DM=m CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m +CONFIG_DM_THIN_PROVISIONING=m +CONFIG_DM_CACHE=m CONFIG_DM_MIRROR=m +CONFIG_DM_RAID=m CONFIG_DM_ZERO=m CONFIG_DM_MULTIPATH=m CONFIG_DM_UEVENT=y +CONFIG_TARGET_CORE=m +CONFIG_TCM_IBLOCK=m +CONFIG_TCM_FILEIO=m +CONFIG_TCM_PSCSI=m CONFIG_NETDEVICES=y CONFIG_DUMMY=m -CONFIG_MACVLAN=m CONFIG_EQUALIZER=m +CONFIG_NET_TEAM=m +CONFIG_NET_TEAM_MODE_BROADCAST=m +CONFIG_NET_TEAM_MODE_ROUNDROBIN=m +CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m +CONFIG_NET_TEAM_MODE_LOADBALANCE=m +CONFIG_VXLAN=m +CONFIG_NETCONSOLE=m +CONFIG_NETCONSOLE_DYNAMIC=y CONFIG_VETH=m -CONFIG_NET_ETHERNET=y CONFIG_SUN3LANCE=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set +# CONFIG_NET_CADENCE is not set +# CONFIG_NET_VENDOR_BROADCOM is not set +# CONFIG_NET_VENDOR_INTEL is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_STMICRO is not set +# CONFIG_NET_VENDOR_WIZNET is not set CONFIG_PPP=m -CONFIG_PPP_FILTER=y -CONFIG_PPP_ASYNC=m -CONFIG_PPP_SYNC_TTY=m -CONFIG_PPP_DEFLATE=m CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_FILTER=y CONFIG_PPP_MPPE=m CONFIG_PPPOE=m +CONFIG_PPTP=m +CONFIG_PPPOL2TP=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m CONFIG_SLIP=m CONFIG_SLIP_COMPRESSED=y CONFIG_SLIP_SMART=y CONFIG_SLIP_MODE_SLIP6=y -CONFIG_NETCONSOLE=m -CONFIG_NETCONSOLE_DYNAMIC=y -CONFIG_INPUT_FF_MEMLESS=m +# CONFIG_WLAN is not set +CONFIG_INPUT_EVDEV=m # CONFIG_KEYBOARD_ATKBD is not set CONFIG_KEYBOARD_SUNKBD=y -CONFIG_MOUSE_PS2=m +# CONFIG_MOUSE_PS2 is not set CONFIG_MOUSE_SERIAL=m -# CONFIG_SERIO_SERPORT is not set CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_LEGACY_PTYS is not set # CONFIG_DEVKMEM is not set # CONFIG_HW_RANDOM is not set -CONFIG_GEN_RTC=m -CONFIG_GEN_RTC_X=y +CONFIG_NTP_PPS=y +CONFIG_PPS_CLIENT_LDISC=m +CONFIG_PTP_1588_CLOCK=m # CONFIG_HWMON is not set CONFIG_FB=y CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_LOGO=y CONFIG_HID=m CONFIG_HIDRAW=y +CONFIG_UHID=m +# CONFIG_HID_GENERIC is not set # CONFIG_USB_SUPPORT is not set +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_GENERIC=m +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_PROC_HARDWARE=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set # CONFIG_EXT3_FS_XATTR is not set +CONFIG_EXT4_FS=y CONFIG_REISERFS_FS=m CONFIG_JFS_FS=m CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m -# CONFIG_OCFS2_FS_STATS is not set # CONFIG_OCFS2_DEBUG_MASKLOG is not set +CONFIG_FANOTIFY=y CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set -CONFIG_AUTOFS_FS=m CONFIG_AUTOFS4_FS=m CONFIG_FUSE_FS=m +CONFIG_CUSE=m CONFIG_ISO9660_FS=y CONFIG_JOLIET=y CONFIG_ZISOFS=y CONFIG_UDF_FS=m -CONFIG_MSDOS_FS=y +CONFIG_MSDOS_FS=m CONFIG_VFAT_FS=m CONFIG_PROC_KCORE=y CONFIG_TMPFS=y CONFIG_AFFS_FS=m +CONFIG_ECRYPT_FS=m +CONFIG_ECRYPT_FS_MESSAGING=y CONFIG_HFS_FS=m CONFIG_HFSPLUS_FS=m CONFIG_CRAMFS=m CONFIG_SQUASHFS=m -CONFIG_MINIX_FS=y +CONFIG_SQUASHFS_LZO=y +CONFIG_MINIX_FS=m +CONFIG_OMFS_FS=m CONFIG_HPFS_FS=m +CONFIG_QNX4FS_FS=m +CONFIG_QNX6FS_FS=m CONFIG_SYSV_FS=m CONFIG_UFS_FS=m CONFIG_NFS_FS=y -CONFIG_NFS_V3=y CONFIG_NFS_V4=y +CONFIG_NFS_SWAP=y CONFIG_ROOT_NFS=y CONFIG_NFSD=m CONFIG_NFSD_V3=y -CONFIG_SMB_FS=m -CONFIG_SMB_NLS_DEFAULT=y +CONFIG_CIFS=m +# CONFIG_CIFS_DEBUG is not set CONFIG_CODA_FS=m CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_CODEPAGE_737=m @@ -295,10 +381,23 @@ CONFIG_NLS_ISO8859_14=m CONFIG_NLS_ISO8859_15=m CONFIG_NLS_KOI8_R=m CONFIG_NLS_KOI8_U=m +CONFIG_NLS_MAC_ROMAN=m +CONFIG_NLS_MAC_CELTIC=m +CONFIG_NLS_MAC_CENTEURO=m +CONFIG_NLS_MAC_CROATIAN=m +CONFIG_NLS_MAC_CYRILLIC=m +CONFIG_NLS_MAC_GAELIC=m +CONFIG_NLS_MAC_GREEK=m +CONFIG_NLS_MAC_ICELAND=m +CONFIG_NLS_MAC_INUIT=m +CONFIG_NLS_MAC_ROMANIAN=m +CONFIG_NLS_MAC_TURKISH=m CONFIG_DLM=m CONFIG_MAGIC_SYSRQ=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y +CONFIG_ASYNC_RAID6_TEST=m +CONFIG_ENCRYPTED_KEYS=m +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_USER=m CONFIG_CRYPTO_NULL=m CONFIG_CRYPTO_CRYPTD=m CONFIG_CRYPTO_TEST=m @@ -308,19 +407,16 @@ CONFIG_CRYPTO_CTS=m CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_PCBC=m CONFIG_CRYPTO_XTS=m -CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_XCBC=m -CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_VMAC=m CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_RMD128=m CONFIG_CRYPTO_RMD160=m CONFIG_CRYPTO_RMD256=m CONFIG_CRYPTO_RMD320=m -CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m CONFIG_CRYPTO_TGR192=m CONFIG_CRYPTO_WP512=m -CONFIG_CRYPTO_AES=m CONFIG_CRYPTO_ANUBIS=m CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_CAMELLIA=m @@ -336,6 +432,14 @@ CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_ZLIB=m CONFIG_CRYPTO_LZO=m # CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_USER_API_HASH=m +CONFIG_CRYPTO_USER_API_SKCIPHER=m # CONFIG_CRYPTO_HW is not set -CONFIG_CRC16=m CONFIG_CRC_T10DIF=y +CONFIG_XZ_DEC_X86=y +CONFIG_XZ_DEC_POWERPC=y +CONFIG_XZ_DEC_IA64=y +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_ARMTHUMB=y +CONFIG_XZ_DEC_SPARC=y +CONFIG_XZ_DEC_TEST=m diff --git a/arch/m68k/include/asm/Kbuild b/arch/m68k/include/asm/Kbuild index c7933e41f10d..09d77a862da3 100644 --- a/arch/m68k/include/asm/Kbuild +++ b/arch/m68k/include/asm/Kbuild @@ -6,7 +6,6 @@ generic-y += device.h generic-y += emergency-restart.h generic-y += errno.h generic-y += exec.h -generic-y += futex.h generic-y += hw_irq.h generic-y += ioctl.h generic-y += ipcbuf.h diff --git a/arch/m68k/include/asm/futex.h b/arch/m68k/include/asm/futex.h new file mode 100644 index 000000000000..bc868af10c96 --- /dev/null +++ b/arch/m68k/include/asm/futex.h @@ -0,0 +1,94 @@ +#ifndef _ASM_M68K_FUTEX_H +#define _ASM_M68K_FUTEX_H + +#ifdef __KERNEL__ +#if !defined(CONFIG_MMU) +#include <asm-generic/futex.h> +#else /* CONFIG_MMU */ + +#include <linux/futex.h> +#include <linux/uaccess.h> +#include <asm/errno.h> + +static inline int +futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, + u32 oldval, u32 newval) +{ + u32 val; + + if (unlikely(get_user(val, uaddr) != 0)) + return -EFAULT; + + if (val == oldval && unlikely(put_user(newval, uaddr) != 0)) + return -EFAULT; + + *uval = val; + + return 0; +} + +static inline int +futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) +{ + int op = (encoded_op >> 28) & 7; + int cmp = (encoded_op >> 24) & 15; + int oparg = (encoded_op << 8) >> 20; + int cmparg = (encoded_op << 20) >> 20; + int oldval, ret; + u32 tmp; + + if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) + oparg = 1 << oparg; + + pagefault_disable(); /* implies preempt_disable() */ + + ret = -EFAULT; + if (unlikely(get_user(oldval, uaddr) != 0)) + goto out_pagefault_enable; + + ret = 0; + tmp = oldval; + + switch (op) { + case FUTEX_OP_SET: + tmp = oparg; + break; + case FUTEX_OP_ADD: + tmp += oparg; + break; + case FUTEX_OP_OR: + tmp |= oparg; + break; + case FUTEX_OP_ANDN: + tmp &= ~oparg; + break; + case FUTEX_OP_XOR: + tmp ^= oparg; + break; + default: + ret = -ENOSYS; + } + + if (ret == 0 && unlikely(put_user(tmp, uaddr) != 0)) + ret = -EFAULT; + +out_pagefault_enable: + pagefault_enable(); /* subsumes preempt_enable() */ + + if (ret == 0) { + switch (cmp) { + case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; + case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; + case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; + case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; + case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; + case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; + default: ret = -ENOSYS; + } + } + return ret; +} + +#endif /* CONFIG_MMU */ +#endif /* __KERNEL__ */ +#endif /* _ASM_M68K_FUTEX_H */ diff --git a/arch/m68k/include/asm/gpio.h b/arch/m68k/include/asm/gpio.h index 8cc83431805b..2f6eec1e34b4 100644 --- a/arch/m68k/include/asm/gpio.h +++ b/arch/m68k/include/asm/gpio.h @@ -86,6 +86,7 @@ static inline int gpio_cansleep(unsigned gpio) return gpio < MCFGPIO_PIN_MAX ? 0 : __gpio_cansleep(gpio); } +#ifndef CONFIG_GPIOLIB static inline int gpio_request_one(unsigned gpio, unsigned long flags, const char *label) { int err; @@ -105,5 +106,5 @@ static inline int gpio_request_one(unsigned gpio, unsigned long flags, const cha return err; } - +#endif /* !CONFIG_GPIOLIB */ #endif diff --git a/arch/m68k/kernel/head.S b/arch/m68k/kernel/head.S index d197e7ff62c5..ac85f16534af 100644 --- a/arch/m68k/kernel/head.S +++ b/arch/m68k/kernel/head.S @@ -2752,11 +2752,9 @@ func_return get_new_page #ifdef CONFIG_MAC L(scc_initable_mac): - .byte 9,12 /* Reset */ .byte 4,0x44 /* x16, 1 stopbit, no parity */ .byte 3,0xc0 /* receiver: 8 bpc */ .byte 5,0xe2 /* transmitter: 8 bpc, assert dtr/rts */ - .byte 9,0 /* no interrupts */ .byte 10,0 /* NRZ */ .byte 11,0x50 /* use baud rate generator */ .byte 12,1,13,0 /* 38400 baud */ @@ -2899,6 +2897,7 @@ func_start serial_init,%d0/%d1/%a0/%a1 is_not_mac(L(serial_init_not_mac)) #ifdef SERIAL_DEBUG + /* You may define either or both of these. */ #define MAC_USE_SCC_A /* Modem port */ #define MAC_USE_SCC_B /* Printer port */ @@ -2908,9 +2907,21 @@ func_start serial_init,%d0/%d1/%a0/%a1 #define mac_scc_cha_b_data_offset 0x4 #define mac_scc_cha_a_data_offset 0x6 +#if defined(MAC_USE_SCC_A) || defined(MAC_USE_SCC_B) + movel %pc@(L(mac_sccbase)),%a0 + /* Reset SCC device */ + moveb #9,%a0@(mac_scc_cha_a_ctrl_offset) + moveb #0xc0,%a0@(mac_scc_cha_a_ctrl_offset) + /* Wait for 5 PCLK cycles, which is about 68 CPU cycles */ + /* 5 / 3.6864 MHz = approx. 1.36 us = 68 / 50 MHz */ + movel #35,%d0 +5: + subq #1,%d0 + jne 5b +#endif + #ifdef MAC_USE_SCC_A /* Initialize channel A */ - movel %pc@(L(mac_sccbase)),%a0 lea %pc@(L(scc_initable_mac)),%a1 5: moveb %a1@+,%d0 jmi 6f @@ -2922,9 +2933,6 @@ func_start serial_init,%d0/%d1/%a0/%a1 #ifdef MAC_USE_SCC_B /* Initialize channel B */ -#ifndef MAC_USE_SCC_A /* Load mac_sccbase only if needed */ - movel %pc@(L(mac_sccbase)),%a0 -#endif /* MAC_USE_SCC_A */ lea %pc@(L(scc_initable_mac)),%a1 7: moveb %a1@+,%d0 jmi 8f @@ -2933,6 +2941,7 @@ func_start serial_init,%d0/%d1/%a0/%a1 jra 7b 8: #endif /* MAC_USE_SCC_B */ + #endif /* SERIAL_DEBUG */ jra L(serial_init_done) @@ -3006,17 +3015,17 @@ func_start serial_putc,%d0/%d1/%a0/%a1 #ifdef SERIAL_DEBUG -#ifdef MAC_USE_SCC_A +#if defined(MAC_USE_SCC_A) || defined(MAC_USE_SCC_B) movel %pc@(L(mac_sccbase)),%a1 +#endif + +#ifdef MAC_USE_SCC_A 3: btst #2,%a1@(mac_scc_cha_a_ctrl_offset) jeq 3b moveb %d0,%a1@(mac_scc_cha_a_data_offset) #endif /* MAC_USE_SCC_A */ #ifdef MAC_USE_SCC_B -#ifndef MAC_USE_SCC_A /* Load mac_sccbase only if needed */ - movel %pc@(L(mac_sccbase)),%a1 -#endif /* MAC_USE_SCC_A */ 4: btst #2,%a1@(mac_scc_cha_b_ctrl_offset) jeq 4b moveb %d0,%a1@(mac_scc_cha_b_data_offset) diff --git a/arch/metag/include/asm/hugetlb.h b/arch/metag/include/asm/hugetlb.h index f545477e61f3..471f481e67f3 100644 --- a/arch/metag/include/asm/hugetlb.h +++ b/arch/metag/include/asm/hugetlb.h @@ -2,6 +2,7 @@ #define _ASM_METAG_HUGETLB_H #include <asm/page.h> +#include <asm-generic/hugetlb.h> static inline int is_hugepage_only_range(struct mm_struct *mm, diff --git a/arch/microblaze/include/asm/cacheflush.h b/arch/microblaze/include/asm/cacheflush.h index 0f553bc009a0..ffea82a16d2c 100644 --- a/arch/microblaze/include/asm/cacheflush.h +++ b/arch/microblaze/include/asm/cacheflush.h @@ -102,21 +102,23 @@ do { \ #define flush_cache_range(vma, start, len) do { } while (0) -#define copy_to_user_page(vma, page, vaddr, dst, src, len) \ -do { \ - u32 addr = virt_to_phys(dst); \ - memcpy((dst), (src), (len)); \ - if (vma->vm_flags & VM_EXEC) { \ - invalidate_icache_range((unsigned) (addr), \ - (unsigned) (addr) + PAGE_SIZE); \ - flush_dcache_range((unsigned) (addr), \ - (unsigned) (addr) + PAGE_SIZE); \ - } \ -} while (0) - -#define copy_from_user_page(vma, page, vaddr, dst, src, len) \ -do { \ - memcpy((dst), (src), (len)); \ -} while (0) +static inline void copy_to_user_page(struct vm_area_struct *vma, + struct page *page, unsigned long vaddr, + void *dst, void *src, int len) +{ + u32 addr = virt_to_phys(dst); + memcpy(dst, src, len); + if (vma->vm_flags & VM_EXEC) { + invalidate_icache_range(addr, addr + PAGE_SIZE); + flush_dcache_range(addr, addr + PAGE_SIZE); + } +} + +static inline void copy_from_user_page(struct vm_area_struct *vma, + struct page *page, unsigned long vaddr, + void *dst, void *src, int len) +{ + memcpy(dst, src, len); +} #endif /* _ASM_MICROBLAZE_CACHEFLUSH_H */ diff --git a/arch/microblaze/include/asm/futex.h b/arch/microblaze/include/asm/futex.h index ff8cde159d9a..01848f056f43 100644 --- a/arch/microblaze/include/asm/futex.h +++ b/arch/microblaze/include/asm/futex.h @@ -105,7 +105,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, __asm__ __volatile__ ("1: lwx %1, %3, r0; \ cmp %2, %1, %4; \ - beqi %2, 3f; \ + bnei %2, 3f; \ 2: swx %5, %3, r0; \ addic %2, r0, 0; \ bnei %2, 1b; \ diff --git a/arch/microblaze/include/asm/io.h b/arch/microblaze/include/asm/io.h index 8cb8a8566ede..2565cb94f32f 100644 --- a/arch/microblaze/include/asm/io.h +++ b/arch/microblaze/include/asm/io.h @@ -123,11 +123,11 @@ static inline void writel(unsigned int v, volatile void __iomem *addr) * inb_p/inw_p/... * The macros don't do byte-swapping. */ -#define inb(port) readb((u8 *)((port))) +#define inb(port) readb((u8 *)((unsigned long)(port))) #define outb(val, port) writeb((val), (u8 *)((unsigned long)(port))) -#define inw(port) readw((u16 *)((port))) +#define inw(port) readw((u16 *)((unsigned long)(port))) #define outw(val, port) writew((val), (u16 *)((unsigned long)(port))) -#define inl(port) readl((u32 *)((port))) +#define inl(port) readl((u32 *)((unsigned long)(port))) #define outl(val, port) writel((val), (u32 *)((unsigned long)(port))) #define inb_p(port) inb((port)) diff --git a/arch/microblaze/include/asm/uaccess.h b/arch/microblaze/include/asm/uaccess.h index efe59d881789..04e49553bdf9 100644 --- a/arch/microblaze/include/asm/uaccess.h +++ b/arch/microblaze/include/asm/uaccess.h @@ -99,13 +99,13 @@ static inline int access_ok(int type, const void __user *addr, if ((get_fs().seg < ((unsigned long)addr)) || (get_fs().seg < ((unsigned long)addr + size - 1))) { pr_debug("ACCESS fail: %s at 0x%08x (size 0x%x), seg 0x%08x\n", - type ? "WRITE" : "READ ", (u32)addr, (u32)size, + type ? "WRITE" : "READ ", (__force u32)addr, (u32)size, (u32)get_fs().seg); return 0; } ok: pr_debug("ACCESS OK: %s at 0x%08x (size 0x%x), seg 0x%08x\n", - type ? "WRITE" : "READ ", (u32)addr, (u32)size, + type ? "WRITE" : "READ ", (__force u32)addr, (u32)size, (u32)get_fs().seg); return 1; } diff --git a/arch/microblaze/kernel/cpu/cache.c b/arch/microblaze/kernel/cpu/cache.c index 4254514b4c8c..a6e44410672d 100644 --- a/arch/microblaze/kernel/cpu/cache.c +++ b/arch/microblaze/kernel/cpu/cache.c @@ -140,7 +140,7 @@ do { \ /* It is used only first parameter for OP - for wic, wdc */ #define CACHE_RANGE_LOOP_1(start, end, line_length, op) \ do { \ - int volatile temp; \ + int volatile temp = 0; \ int align = ~(line_length - 1); \ end = ((end & align) == end) ? end - line_length : end & align; \ WARN_ON(end - start < 0); \ diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c index b0baa299f899..01b1b3f94feb 100644 --- a/arch/mips/cavium-octeon/setup.c +++ b/arch/mips/cavium-octeon/setup.c @@ -428,13 +428,16 @@ static void octeon_restart(char *command) */ static void octeon_kill_core(void *arg) { - mb(); - if (octeon_is_simulation()) { - /* The simulator needs the watchdog to stop for dead cores */ - cvmx_write_csr(CVMX_CIU_WDOGX(cvmx_get_core_num()), 0); + if (octeon_is_simulation()) /* A break instruction causes the simulator stop a core */ - asm volatile ("sync\nbreak"); - } + asm volatile ("break" ::: "memory"); + + local_irq_disable(); + /* Disable watchdog on this core. */ + cvmx_write_csr(CVMX_CIU_WDOGX(cvmx_get_core_num()), 0); + /* Spin in a low power mode. */ + while (true) + asm volatile ("wait" ::: "memory"); } diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h index 143875c6c95a..4d6fa0bf1305 100644 --- a/arch/mips/include/asm/kvm_host.h +++ b/arch/mips/include/asm/kvm_host.h @@ -496,10 +496,6 @@ struct kvm_mips_callbacks { uint32_t cause); int (*irq_clear) (struct kvm_vcpu *vcpu, unsigned int priority, uint32_t cause); - int (*vcpu_ioctl_get_regs) (struct kvm_vcpu *vcpu, - struct kvm_regs *regs); - int (*vcpu_ioctl_set_regs) (struct kvm_vcpu *vcpu, - struct kvm_regs *regs); }; extern struct kvm_mips_callbacks *kvm_mips_callbacks; int kvm_mips_emulation_init(struct kvm_mips_callbacks **install_callbacks); diff --git a/arch/mips/include/asm/mmu_context.h b/arch/mips/include/asm/mmu_context.h index 820116067c10..516e6e9a5594 100644 --- a/arch/mips/include/asm/mmu_context.h +++ b/arch/mips/include/asm/mmu_context.h @@ -117,7 +117,7 @@ get_new_mmu_context(struct mm_struct *mm, unsigned long cpu) if (! ((asid += ASID_INC) & ASID_MASK) ) { if (cpu_has_vtag_icache) flush_icache_all(); -#ifdef CONFIG_VIRTUALIZATION +#ifdef CONFIG_KVM kvm_local_flush_tlb_all(); /* start new asid cycle */ #else local_flush_tlb_all(); /* start new asid cycle */ diff --git a/arch/mips/include/asm/ptrace.h b/arch/mips/include/asm/ptrace.h index a3186f2bb8a0..5e6cd0947393 100644 --- a/arch/mips/include/asm/ptrace.h +++ b/arch/mips/include/asm/ptrace.h @@ -16,6 +16,38 @@ #include <asm/isadep.h> #include <uapi/asm/ptrace.h> +/* + * This struct defines the way the registers are stored on the stack during a + * system call/exception. As usual the registers k0/k1 aren't being saved. + */ +struct pt_regs { +#ifdef CONFIG_32BIT + /* Pad bytes for argument save space on the stack. */ + unsigned long pad0[6]; +#endif + + /* Saved main processor registers. */ + unsigned long regs[32]; + + /* Saved special registers. */ + unsigned long cp0_status; + unsigned long hi; + unsigned long lo; +#ifdef CONFIG_CPU_HAS_SMARTMIPS + unsigned long acx; +#endif + unsigned long cp0_badvaddr; + unsigned long cp0_cause; + unsigned long cp0_epc; +#ifdef CONFIG_MIPS_MT_SMTC + unsigned long cp0_tcstatus; +#endif /* CONFIG_MIPS_MT_SMTC */ +#ifdef CONFIG_CPU_CAVIUM_OCTEON + unsigned long long mpl[3]; /* MTM{0,1,2} */ + unsigned long long mtp[3]; /* MTP{0,1,2} */ +#endif +} __aligned(8); + struct task_struct; extern int ptrace_getregs(struct task_struct *child, __s64 __user *data); diff --git a/arch/mips/include/uapi/asm/kvm.h b/arch/mips/include/uapi/asm/kvm.h index 85789eacbf18..f09ff5ae2059 100644 --- a/arch/mips/include/uapi/asm/kvm.h +++ b/arch/mips/include/uapi/asm/kvm.h @@ -1,55 +1,135 @@ /* -* This file is subject to the terms and conditions of the GNU General Public -* License. See the file "COPYING" in the main directory of this archive -* for more details. -* -* Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. -* Authors: Sanjay Lal <sanjayl@kymasys.com> -*/ + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. + * Copyright (C) 2013 Cavium, Inc. + * Authors: Sanjay Lal <sanjayl@kymasys.com> + */ #ifndef __LINUX_KVM_MIPS_H #define __LINUX_KVM_MIPS_H #include <linux/types.h> -#define __KVM_MIPS - -#define N_MIPS_COPROC_REGS 32 -#define N_MIPS_COPROC_SEL 8 +/* + * KVM MIPS specific structures and definitions. + * + * Some parts derived from the x86 version of this file. + */ -/* for KVM_GET_REGS and KVM_SET_REGS */ +/* + * for KVM_GET_REGS and KVM_SET_REGS + * + * If Config[AT] is zero (32-bit CPU), the register contents are + * stored in the lower 32-bits of the struct kvm_regs fields and sign + * extended to 64-bits. + */ struct kvm_regs { - __u32 gprs[32]; - __u32 hi; - __u32 lo; - __u32 pc; - - __u32 cp0reg[N_MIPS_COPROC_REGS][N_MIPS_COPROC_SEL]; -}; - -/* for KVM_GET_SREGS and KVM_SET_SREGS */ -struct kvm_sregs { + /* out (KVM_GET_REGS) / in (KVM_SET_REGS) */ + __u64 gpr[32]; + __u64 hi; + __u64 lo; + __u64 pc; }; -/* for KVM_GET_FPU and KVM_SET_FPU */ +/* + * for KVM_GET_FPU and KVM_SET_FPU + * + * If Status[FR] is zero (32-bit FPU), the upper 32-bits of the FPRs + * are zero filled. + */ struct kvm_fpu { + __u64 fpr[32]; + __u32 fir; + __u32 fccr; + __u32 fexr; + __u32 fenr; + __u32 fcsr; + __u32 pad; }; + +/* + * For MIPS, we use KVM_SET_ONE_REG and KVM_GET_ONE_REG to access CP0 + * registers. The id field is broken down as follows: + * + * bits[2..0] - Register 'sel' index. + * bits[7..3] - Register 'rd' index. + * bits[15..8] - Must be zero. + * bits[31..16] - 1 -> CP0 registers. + * bits[51..32] - Must be zero. + * bits[63..52] - As per linux/kvm.h + * + * Other sets registers may be added in the future. Each set would + * have its own identifier in bits[31..16]. + * + * The registers defined in struct kvm_regs are also accessible, the + * id values for these are below. + */ + +#define KVM_REG_MIPS_R0 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 0) +#define KVM_REG_MIPS_R1 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 1) +#define KVM_REG_MIPS_R2 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 2) +#define KVM_REG_MIPS_R3 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 3) +#define KVM_REG_MIPS_R4 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 4) +#define KVM_REG_MIPS_R5 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 5) +#define KVM_REG_MIPS_R6 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 6) +#define KVM_REG_MIPS_R7 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 7) +#define KVM_REG_MIPS_R8 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 8) +#define KVM_REG_MIPS_R9 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 9) +#define KVM_REG_MIPS_R10 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 10) +#define KVM_REG_MIPS_R11 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 11) +#define KVM_REG_MIPS_R12 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 12) +#define KVM_REG_MIPS_R13 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 13) +#define KVM_REG_MIPS_R14 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 14) +#define KVM_REG_MIPS_R15 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 15) +#define KVM_REG_MIPS_R16 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 16) +#define KVM_REG_MIPS_R17 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 17) +#define KVM_REG_MIPS_R18 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 18) +#define KVM_REG_MIPS_R19 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 19) +#define KVM_REG_MIPS_R20 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 20) +#define KVM_REG_MIPS_R21 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 21) +#define KVM_REG_MIPS_R22 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 22) +#define KVM_REG_MIPS_R23 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 23) +#define KVM_REG_MIPS_R24 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 24) +#define KVM_REG_MIPS_R25 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 25) +#define KVM_REG_MIPS_R26 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 26) +#define KVM_REG_MIPS_R27 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 27) +#define KVM_REG_MIPS_R28 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 28) +#define KVM_REG_MIPS_R29 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 29) +#define KVM_REG_MIPS_R30 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 30) +#define KVM_REG_MIPS_R31 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 31) + +#define KVM_REG_MIPS_HI (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 32) +#define KVM_REG_MIPS_LO (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 33) +#define KVM_REG_MIPS_PC (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 34) + +/* + * KVM MIPS specific structures and definitions + * + */ struct kvm_debug_exit_arch { + __u64 epc; }; /* for KVM_SET_GUEST_DEBUG */ struct kvm_guest_debug_arch { }; +/* definition of registers in kvm_run */ +struct kvm_sync_regs { +}; + +/* dummy definition */ +struct kvm_sregs { +}; + struct kvm_mips_interrupt { /* in */ __u32 cpu; __u32 irq; }; -/* definition of registers in kvm_run */ -struct kvm_sync_regs { -}; - #endif /* __LINUX_KVM_MIPS_H */ diff --git a/arch/mips/include/uapi/asm/ptrace.h b/arch/mips/include/uapi/asm/ptrace.h index 4d58d8468705..b26f7e317279 100644 --- a/arch/mips/include/uapi/asm/ptrace.h +++ b/arch/mips/include/uapi/asm/ptrace.h @@ -22,16 +22,12 @@ #define DSP_CONTROL 77 #define ACX 78 +#ifndef __KERNEL__ /* * This struct defines the way the registers are stored on the stack during a * system call/exception. As usual the registers k0/k1 aren't being saved. */ struct pt_regs { -#ifdef CONFIG_32BIT - /* Pad bytes for argument save space on the stack. */ - unsigned long pad0[6]; -#endif - /* Saved main processor registers. */ unsigned long regs[32]; @@ -39,20 +35,11 @@ struct pt_regs { unsigned long cp0_status; unsigned long hi; unsigned long lo; -#ifdef CONFIG_CPU_HAS_SMARTMIPS - unsigned long acx; -#endif unsigned long cp0_badvaddr; unsigned long cp0_cause; unsigned long cp0_epc; -#ifdef CONFIG_MIPS_MT_SMTC - unsigned long cp0_tcstatus; -#endif /* CONFIG_MIPS_MT_SMTC */ -#ifdef CONFIG_CPU_CAVIUM_OCTEON - unsigned long long mpl[3]; /* MTM{0,1,2} */ - unsigned long long mtp[3]; /* MTP{0,1,2} */ -#endif } __attribute__ ((aligned (8))); +#endif /* __KERNEL__ */ /* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */ #define PTRACE_GETREGS 12 diff --git a/arch/mips/kernel/binfmt_elfn32.c b/arch/mips/kernel/binfmt_elfn32.c index e06f777e9c49..1188e00bb120 100644 --- a/arch/mips/kernel/binfmt_elfn32.c +++ b/arch/mips/kernel/binfmt_elfn32.c @@ -119,4 +119,15 @@ MODULE_AUTHOR("Ralf Baechle (ralf@linux-mips.org)"); #undef TASK_SIZE #define TASK_SIZE TASK_SIZE32 +#undef cputime_to_timeval +#define cputime_to_timeval cputime_to_compat_timeval +static __inline__ void +cputime_to_compat_timeval(const cputime_t cputime, struct compat_timeval *value) +{ + unsigned long jiffies = cputime_to_jiffies(cputime); + + value->tv_usec = (jiffies % HZ) * (1000000L / HZ); + value->tv_sec = jiffies / HZ; +} + #include "../../../fs/binfmt_elf.c" diff --git a/arch/mips/kernel/binfmt_elfo32.c b/arch/mips/kernel/binfmt_elfo32.c index 97c5a1668e53..202e581e6096 100644 --- a/arch/mips/kernel/binfmt_elfo32.c +++ b/arch/mips/kernel/binfmt_elfo32.c @@ -162,4 +162,15 @@ MODULE_AUTHOR("Ralf Baechle (ralf@linux-mips.org)"); #undef TASK_SIZE #define TASK_SIZE TASK_SIZE32 +#undef cputime_to_timeval +#define cputime_to_timeval cputime_to_compat_timeval +static __inline__ void +cputime_to_compat_timeval(const cputime_t cputime, struct compat_timeval *value) +{ + unsigned long jiffies = cputime_to_jiffies(cputime); + + value->tv_usec = (jiffies % HZ) * (1000000L / HZ); + value->tv_sec = jiffies / HZ; +} + #include "../../../fs/binfmt_elf.c" diff --git a/arch/mips/kernel/ftrace.c b/arch/mips/kernel/ftrace.c index cf5509f13dd5..dba90ec0dc38 100644 --- a/arch/mips/kernel/ftrace.c +++ b/arch/mips/kernel/ftrace.c @@ -25,12 +25,16 @@ #define MCOUNT_OFFSET_INSNS 4 #endif +#ifdef CONFIG_DYNAMIC_FTRACE + /* Arch override because MIPS doesn't need to run this from stop_machine() */ void arch_ftrace_update_code(int command) { ftrace_modify_all_code(command); } +#endif + /* * Check if the address is in kernel space * diff --git a/arch/mips/kernel/idle.c b/arch/mips/kernel/idle.c index 3b09b888afa9..0c655deeea4a 100644 --- a/arch/mips/kernel/idle.c +++ b/arch/mips/kernel/idle.c @@ -93,26 +93,27 @@ static void rm7k_wait_irqoff(void) } /* - * The Au1xxx wait is available only if using 32khz counter or - * external timer source, but specifically not CP0 Counter. - * alchemy/common/time.c may override cpu_wait! + * Au1 'wait' is only useful when the 32kHz counter is used as timer, + * since coreclock (and the cp0 counter) stops upon executing it. Only an + * interrupt can wake it, so they must be enabled before entering idle modes. */ static void au1k_wait(void) { + unsigned long c0status = read_c0_status() | 1; /* irqs on */ + __asm__( " .set mips3 \n" " cache 0x14, 0(%0) \n" " cache 0x14, 32(%0) \n" " sync \n" - " nop \n" + " mtc0 %1, $12 \n" /* wr c0status */ " wait \n" " nop \n" " nop \n" " nop \n" " nop \n" " .set mips0 \n" - : : "r" (au1k_wait)); - local_irq_enable(); + : : "r" (au1k_wait), "r" (c0status)); } static int __initdata nowait; diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c index 93c070b41b0d..6fa198db8999 100644 --- a/arch/mips/kernel/rtlx.c +++ b/arch/mips/kernel/rtlx.c @@ -40,6 +40,7 @@ #include <asm/processor.h> #include <asm/vpe.h> #include <asm/rtlx.h> +#include <asm/setup.h> static struct rtlx_info *rtlx; static int major; diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index e3be67012d78..a75ae40184aa 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -897,22 +897,24 @@ out_sigsegv: asmlinkage void do_tr(struct pt_regs *regs) { - unsigned int opcode, tcode = 0; + u32 opcode, tcode = 0; u16 instr[2]; - unsigned long epc = exception_epc(regs); + unsigned long epc = msk_isa16_mode(exception_epc(regs)); - if ((__get_user(instr[0], (u16 __user *)msk_isa16_mode(epc))) || - (__get_user(instr[1], (u16 __user *)msk_isa16_mode(epc + 2)))) + if (get_isa16_mode(regs->cp0_epc)) { + if (__get_user(instr[0], (u16 __user *)(epc + 0)) || + __get_user(instr[1], (u16 __user *)(epc + 2))) goto out_sigsegv; - opcode = (instr[0] << 16) | instr[1]; - - /* Immediate versions don't provide a code. */ - if (!(opcode & OPCODE)) { - if (get_isa16_mode(regs->cp0_epc)) - /* microMIPS */ - tcode = (opcode >> 12) & 0x1f; - else - tcode = ((opcode >> 6) & ((1 << 10) - 1)); + opcode = (instr[0] << 16) | instr[1]; + /* Immediate versions don't provide a code. */ + if (!(opcode & OPCODE)) + tcode = (opcode >> 12) & ((1 << 4) - 1); + } else { + if (__get_user(opcode, (u32 __user *)epc)) + goto out_sigsegv; + /* Immediate versions don't provide a code. */ + if (!(opcode & OPCODE)) + tcode = (opcode >> 6) & ((1 << 10) - 1); } do_trap_or_bp(regs, tcode, "Trap"); diff --git a/arch/mips/kvm/kvm_mips.c b/arch/mips/kvm/kvm_mips.c index e0dad0289797..dd203e59e6fd 100644 --- a/arch/mips/kvm/kvm_mips.c +++ b/arch/mips/kvm/kvm_mips.c @@ -195,7 +195,7 @@ void kvm_arch_destroy_vm(struct kvm *kvm) long kvm_arch_dev_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) { - return -EINVAL; + return -ENOIOCTLCMD; } void kvm_arch_free_memslot(struct kvm_memory_slot *free, @@ -401,7 +401,7 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, struct kvm_guest_debug *dbg) { - return -EINVAL; + return -ENOIOCTLCMD; } int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) @@ -475,14 +475,248 @@ int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu, struct kvm_mp_state *mp_state) { - return -EINVAL; + return -ENOIOCTLCMD; } int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu, struct kvm_mp_state *mp_state) { - return -EINVAL; + return -ENOIOCTLCMD; +} + +#define MIPS_CP0_32(_R, _S) \ + (KVM_REG_MIPS | KVM_REG_SIZE_U32 | 0x10000 | (8 * (_R) + (_S))) + +#define MIPS_CP0_64(_R, _S) \ + (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 0x10000 | (8 * (_R) + (_S))) + +#define KVM_REG_MIPS_CP0_INDEX MIPS_CP0_32(0, 0) +#define KVM_REG_MIPS_CP0_ENTRYLO0 MIPS_CP0_64(2, 0) +#define KVM_REG_MIPS_CP0_ENTRYLO1 MIPS_CP0_64(3, 0) +#define KVM_REG_MIPS_CP0_CONTEXT MIPS_CP0_64(4, 0) +#define KVM_REG_MIPS_CP0_USERLOCAL MIPS_CP0_64(4, 2) +#define KVM_REG_MIPS_CP0_PAGEMASK MIPS_CP0_32(5, 0) +#define KVM_REG_MIPS_CP0_PAGEGRAIN MIPS_CP0_32(5, 1) +#define KVM_REG_MIPS_CP0_WIRED MIPS_CP0_32(6, 0) +#define KVM_REG_MIPS_CP0_HWRENA MIPS_CP0_32(7, 0) +#define KVM_REG_MIPS_CP0_BADVADDR MIPS_CP0_64(8, 0) +#define KVM_REG_MIPS_CP0_COUNT MIPS_CP0_32(9, 0) +#define KVM_REG_MIPS_CP0_ENTRYHI MIPS_CP0_64(10, 0) +#define KVM_REG_MIPS_CP0_COMPARE MIPS_CP0_32(11, 0) +#define KVM_REG_MIPS_CP0_STATUS MIPS_CP0_32(12, 0) +#define KVM_REG_MIPS_CP0_CAUSE MIPS_CP0_32(13, 0) +#define KVM_REG_MIPS_CP0_EBASE MIPS_CP0_64(15, 1) +#define KVM_REG_MIPS_CP0_CONFIG MIPS_CP0_32(16, 0) +#define KVM_REG_MIPS_CP0_CONFIG1 MIPS_CP0_32(16, 1) +#define KVM_REG_MIPS_CP0_CONFIG2 MIPS_CP0_32(16, 2) +#define KVM_REG_MIPS_CP0_CONFIG3 MIPS_CP0_32(16, 3) +#define KVM_REG_MIPS_CP0_CONFIG7 MIPS_CP0_32(16, 7) +#define KVM_REG_MIPS_CP0_XCONTEXT MIPS_CP0_64(20, 0) +#define KVM_REG_MIPS_CP0_ERROREPC MIPS_CP0_64(30, 0) + +static u64 kvm_mips_get_one_regs[] = { + KVM_REG_MIPS_R0, + KVM_REG_MIPS_R1, + KVM_REG_MIPS_R2, + KVM_REG_MIPS_R3, + KVM_REG_MIPS_R4, + KVM_REG_MIPS_R5, + KVM_REG_MIPS_R6, + KVM_REG_MIPS_R7, + KVM_REG_MIPS_R8, + KVM_REG_MIPS_R9, + KVM_REG_MIPS_R10, + KVM_REG_MIPS_R11, + KVM_REG_MIPS_R12, + KVM_REG_MIPS_R13, + KVM_REG_MIPS_R14, + KVM_REG_MIPS_R15, + KVM_REG_MIPS_R16, + KVM_REG_MIPS_R17, + KVM_REG_MIPS_R18, + KVM_REG_MIPS_R19, + KVM_REG_MIPS_R20, + KVM_REG_MIPS_R21, + KVM_REG_MIPS_R22, + KVM_REG_MIPS_R23, + KVM_REG_MIPS_R24, + KVM_REG_MIPS_R25, + KVM_REG_MIPS_R26, + KVM_REG_MIPS_R27, + KVM_REG_MIPS_R28, + KVM_REG_MIPS_R29, + KVM_REG_MIPS_R30, + KVM_REG_MIPS_R31, + + KVM_REG_MIPS_HI, + KVM_REG_MIPS_LO, + KVM_REG_MIPS_PC, + + KVM_REG_MIPS_CP0_INDEX, + KVM_REG_MIPS_CP0_CONTEXT, + KVM_REG_MIPS_CP0_PAGEMASK, + KVM_REG_MIPS_CP0_WIRED, + KVM_REG_MIPS_CP0_BADVADDR, + KVM_REG_MIPS_CP0_ENTRYHI, + KVM_REG_MIPS_CP0_STATUS, + KVM_REG_MIPS_CP0_CAUSE, + /* EPC set via kvm_regs, et al. */ + KVM_REG_MIPS_CP0_CONFIG, + KVM_REG_MIPS_CP0_CONFIG1, + KVM_REG_MIPS_CP0_CONFIG2, + KVM_REG_MIPS_CP0_CONFIG3, + KVM_REG_MIPS_CP0_CONFIG7, + KVM_REG_MIPS_CP0_ERROREPC +}; + +static int kvm_mips_get_reg(struct kvm_vcpu *vcpu, + const struct kvm_one_reg *reg) +{ + struct mips_coproc *cop0 = vcpu->arch.cop0; + s64 v; + + switch (reg->id) { + case KVM_REG_MIPS_R0 ... KVM_REG_MIPS_R31: + v = (long)vcpu->arch.gprs[reg->id - KVM_REG_MIPS_R0]; + break; + case KVM_REG_MIPS_HI: + v = (long)vcpu->arch.hi; + break; + case KVM_REG_MIPS_LO: + v = (long)vcpu->arch.lo; + break; + case KVM_REG_MIPS_PC: + v = (long)vcpu->arch.pc; + break; + + case KVM_REG_MIPS_CP0_INDEX: + v = (long)kvm_read_c0_guest_index(cop0); + break; + case KVM_REG_MIPS_CP0_CONTEXT: + v = (long)kvm_read_c0_guest_context(cop0); + break; + case KVM_REG_MIPS_CP0_PAGEMASK: + v = (long)kvm_read_c0_guest_pagemask(cop0); + break; + case KVM_REG_MIPS_CP0_WIRED: + v = (long)kvm_read_c0_guest_wired(cop0); + break; + case KVM_REG_MIPS_CP0_BADVADDR: + v = (long)kvm_read_c0_guest_badvaddr(cop0); + break; + case KVM_REG_MIPS_CP0_ENTRYHI: + v = (long)kvm_read_c0_guest_entryhi(cop0); + break; + case KVM_REG_MIPS_CP0_STATUS: + v = (long)kvm_read_c0_guest_status(cop0); + break; + case KVM_REG_MIPS_CP0_CAUSE: + v = (long)kvm_read_c0_guest_cause(cop0); + break; + case KVM_REG_MIPS_CP0_ERROREPC: + v = (long)kvm_read_c0_guest_errorepc(cop0); + break; + case KVM_REG_MIPS_CP0_CONFIG: + v = (long)kvm_read_c0_guest_config(cop0); + break; + case KVM_REG_MIPS_CP0_CONFIG1: + v = (long)kvm_read_c0_guest_config1(cop0); + break; + case KVM_REG_MIPS_CP0_CONFIG2: + v = (long)kvm_read_c0_guest_config2(cop0); + break; + case KVM_REG_MIPS_CP0_CONFIG3: + v = (long)kvm_read_c0_guest_config3(cop0); + break; + case KVM_REG_MIPS_CP0_CONFIG7: + v = (long)kvm_read_c0_guest_config7(cop0); + break; + default: + return -EINVAL; + } + if ((reg->id & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U64) { + u64 __user *uaddr64 = (u64 __user *)(long)reg->addr; + return put_user(v, uaddr64); + } else if ((reg->id & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U32) { + u32 __user *uaddr32 = (u32 __user *)(long)reg->addr; + u32 v32 = (u32)v; + return put_user(v32, uaddr32); + } else { + return -EINVAL; + } +} + +static int kvm_mips_set_reg(struct kvm_vcpu *vcpu, + const struct kvm_one_reg *reg) +{ + struct mips_coproc *cop0 = vcpu->arch.cop0; + u64 v; + + if ((reg->id & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U64) { + u64 __user *uaddr64 = (u64 __user *)(long)reg->addr; + + if (get_user(v, uaddr64) != 0) + return -EFAULT; + } else if ((reg->id & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U32) { + u32 __user *uaddr32 = (u32 __user *)(long)reg->addr; + s32 v32; + + if (get_user(v32, uaddr32) != 0) + return -EFAULT; + v = (s64)v32; + } else { + return -EINVAL; + } + + switch (reg->id) { + case KVM_REG_MIPS_R0: + /* Silently ignore requests to set $0 */ + break; + case KVM_REG_MIPS_R1 ... KVM_REG_MIPS_R31: + vcpu->arch.gprs[reg->id - KVM_REG_MIPS_R0] = v; + break; + case KVM_REG_MIPS_HI: + vcpu->arch.hi = v; + break; + case KVM_REG_MIPS_LO: + vcpu->arch.lo = v; + break; + case KVM_REG_MIPS_PC: + vcpu->arch.pc = v; + break; + + case KVM_REG_MIPS_CP0_INDEX: + kvm_write_c0_guest_index(cop0, v); + break; + case KVM_REG_MIPS_CP0_CONTEXT: + kvm_write_c0_guest_context(cop0, v); + break; + case KVM_REG_MIPS_CP0_PAGEMASK: + kvm_write_c0_guest_pagemask(cop0, v); + break; + case KVM_REG_MIPS_CP0_WIRED: + kvm_write_c0_guest_wired(cop0, v); + break; + case KVM_REG_MIPS_CP0_BADVADDR: + kvm_write_c0_guest_badvaddr(cop0, v); + break; + case KVM_REG_MIPS_CP0_ENTRYHI: + kvm_write_c0_guest_entryhi(cop0, v); + break; + case KVM_REG_MIPS_CP0_STATUS: + kvm_write_c0_guest_status(cop0, v); + break; + case KVM_REG_MIPS_CP0_CAUSE: + kvm_write_c0_guest_cause(cop0, v); + break; + case KVM_REG_MIPS_CP0_ERROREPC: + kvm_write_c0_guest_errorepc(cop0, v); + break; + default: + return -EINVAL; + } + return 0; } long @@ -491,9 +725,38 @@ kvm_arch_vcpu_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) struct kvm_vcpu *vcpu = filp->private_data; void __user *argp = (void __user *)arg; long r; - int intr; switch (ioctl) { + case KVM_SET_ONE_REG: + case KVM_GET_ONE_REG: { + struct kvm_one_reg reg; + if (copy_from_user(®, argp, sizeof(reg))) + return -EFAULT; + if (ioctl == KVM_SET_ONE_REG) + return kvm_mips_set_reg(vcpu, ®); + else + return kvm_mips_get_reg(vcpu, ®); + } + case KVM_GET_REG_LIST: { + struct kvm_reg_list __user *user_list = argp; + u64 __user *reg_dest; + struct kvm_reg_list reg_list; + unsigned n; + + if (copy_from_user(®_list, user_list, sizeof(reg_list))) + return -EFAULT; + n = reg_list.n; + reg_list.n = ARRAY_SIZE(kvm_mips_get_one_regs); + if (copy_to_user(user_list, ®_list, sizeof(reg_list))) + return -EFAULT; + if (n < reg_list.n) + return -E2BIG; + reg_dest = user_list->reg; + if (copy_to_user(reg_dest, kvm_mips_get_one_regs, + sizeof(kvm_mips_get_one_regs))) + return -EFAULT; + return 0; + } case KVM_NMI: /* Treat the NMI as a CPU reset */ r = kvm_mips_reset_vcpu(vcpu); @@ -505,8 +768,6 @@ kvm_arch_vcpu_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) if (copy_from_user(&irq, argp, sizeof(irq))) goto out; - intr = (int)irq.irq; - kvm_debug("[%d] %s: irq: %d\n", vcpu->vcpu_id, __func__, irq.irq); @@ -514,7 +775,7 @@ kvm_arch_vcpu_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) break; } default: - r = -EINVAL; + r = -ENOIOCTLCMD; } out: @@ -565,7 +826,7 @@ long kvm_arch_vm_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) switch (ioctl) { default: - r = -EINVAL; + r = -ENOIOCTLCMD; } return r; @@ -593,13 +854,13 @@ void kvm_arch_exit(void) int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) { - return -ENOTSUPP; + return -ENOIOCTLCMD; } int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) { - return -ENOTSUPP; + return -ENOIOCTLCMD; } int kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu) @@ -609,12 +870,12 @@ int kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu) int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) { - return -ENOTSUPP; + return -ENOIOCTLCMD; } int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) { - return -ENOTSUPP; + return -ENOIOCTLCMD; } int kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf) @@ -627,6 +888,9 @@ int kvm_dev_ioctl_check_extension(long ext) int r; switch (ext) { + case KVM_CAP_ONE_REG: + r = 1; + break; case KVM_CAP_COALESCED_MMIO: r = KVM_COALESCED_MMIO_PAGE_OFFSET; break; @@ -635,7 +899,6 @@ int kvm_dev_ioctl_check_extension(long ext) break; } return r; - } int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu) @@ -677,28 +940,28 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) { int i; - for (i = 0; i < 32; i++) - vcpu->arch.gprs[i] = regs->gprs[i]; - + for (i = 1; i < ARRAY_SIZE(vcpu->arch.gprs); i++) + vcpu->arch.gprs[i] = regs->gpr[i]; + vcpu->arch.gprs[0] = 0; /* zero is special, and cannot be set. */ vcpu->arch.hi = regs->hi; vcpu->arch.lo = regs->lo; vcpu->arch.pc = regs->pc; - return kvm_mips_callbacks->vcpu_ioctl_set_regs(vcpu, regs); + return 0; } int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) { int i; - for (i = 0; i < 32; i++) - regs->gprs[i] = vcpu->arch.gprs[i]; + for (i = 0; i < ARRAY_SIZE(vcpu->arch.gprs); i++) + regs->gpr[i] = vcpu->arch.gprs[i]; regs->hi = vcpu->arch.hi; regs->lo = vcpu->arch.lo; regs->pc = vcpu->arch.pc; - return kvm_mips_callbacks->vcpu_ioctl_get_regs(vcpu, regs); + return 0; } void kvm_mips_comparecount_func(unsigned long data) diff --git a/arch/mips/kvm/kvm_trap_emul.c b/arch/mips/kvm/kvm_trap_emul.c index 466aeef044bd..30d725321db1 100644 --- a/arch/mips/kvm/kvm_trap_emul.c +++ b/arch/mips/kvm/kvm_trap_emul.c @@ -345,54 +345,6 @@ static int kvm_trap_emul_handle_break(struct kvm_vcpu *vcpu) return ret; } -static int -kvm_trap_emul_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) -{ - struct mips_coproc *cop0 = vcpu->arch.cop0; - - kvm_write_c0_guest_index(cop0, regs->cp0reg[MIPS_CP0_TLB_INDEX][0]); - kvm_write_c0_guest_context(cop0, regs->cp0reg[MIPS_CP0_TLB_CONTEXT][0]); - kvm_write_c0_guest_badvaddr(cop0, regs->cp0reg[MIPS_CP0_BAD_VADDR][0]); - kvm_write_c0_guest_entryhi(cop0, regs->cp0reg[MIPS_CP0_TLB_HI][0]); - kvm_write_c0_guest_epc(cop0, regs->cp0reg[MIPS_CP0_EXC_PC][0]); - - kvm_write_c0_guest_status(cop0, regs->cp0reg[MIPS_CP0_STATUS][0]); - kvm_write_c0_guest_cause(cop0, regs->cp0reg[MIPS_CP0_CAUSE][0]); - kvm_write_c0_guest_pagemask(cop0, - regs->cp0reg[MIPS_CP0_TLB_PG_MASK][0]); - kvm_write_c0_guest_wired(cop0, regs->cp0reg[MIPS_CP0_TLB_WIRED][0]); - kvm_write_c0_guest_errorepc(cop0, regs->cp0reg[MIPS_CP0_ERROR_PC][0]); - - return 0; -} - -static int -kvm_trap_emul_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) -{ - struct mips_coproc *cop0 = vcpu->arch.cop0; - - regs->cp0reg[MIPS_CP0_TLB_INDEX][0] = kvm_read_c0_guest_index(cop0); - regs->cp0reg[MIPS_CP0_TLB_CONTEXT][0] = kvm_read_c0_guest_context(cop0); - regs->cp0reg[MIPS_CP0_BAD_VADDR][0] = kvm_read_c0_guest_badvaddr(cop0); - regs->cp0reg[MIPS_CP0_TLB_HI][0] = kvm_read_c0_guest_entryhi(cop0); - regs->cp0reg[MIPS_CP0_EXC_PC][0] = kvm_read_c0_guest_epc(cop0); - - regs->cp0reg[MIPS_CP0_STATUS][0] = kvm_read_c0_guest_status(cop0); - regs->cp0reg[MIPS_CP0_CAUSE][0] = kvm_read_c0_guest_cause(cop0); - regs->cp0reg[MIPS_CP0_TLB_PG_MASK][0] = - kvm_read_c0_guest_pagemask(cop0); - regs->cp0reg[MIPS_CP0_TLB_WIRED][0] = kvm_read_c0_guest_wired(cop0); - regs->cp0reg[MIPS_CP0_ERROR_PC][0] = kvm_read_c0_guest_errorepc(cop0); - - regs->cp0reg[MIPS_CP0_CONFIG][0] = kvm_read_c0_guest_config(cop0); - regs->cp0reg[MIPS_CP0_CONFIG][1] = kvm_read_c0_guest_config1(cop0); - regs->cp0reg[MIPS_CP0_CONFIG][2] = kvm_read_c0_guest_config2(cop0); - regs->cp0reg[MIPS_CP0_CONFIG][3] = kvm_read_c0_guest_config3(cop0); - regs->cp0reg[MIPS_CP0_CONFIG][7] = kvm_read_c0_guest_config7(cop0); - - return 0; -} - static int kvm_trap_emul_vm_init(struct kvm *kvm) { return 0; @@ -471,8 +423,6 @@ static struct kvm_mips_callbacks kvm_trap_emul_callbacks = { .dequeue_io_int = kvm_mips_dequeue_io_int_cb, .irq_deliver = kvm_mips_irq_deliver_cb, .irq_clear = kvm_mips_irq_clear_cb, - .vcpu_ioctl_get_regs = kvm_trap_emul_ioctl_get_regs, - .vcpu_ioctl_set_regs = kvm_trap_emul_ioctl_set_regs, }; int kvm_mips_emulation_init(struct kvm_mips_callbacks **install_callbacks) diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index ce9818eef7d3..afeef93f81a7 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -301,10 +301,6 @@ static u32 tlb_handler[128] __cpuinitdata; static struct uasm_label labels[128] __cpuinitdata; static struct uasm_reloc relocs[128] __cpuinitdata; -#ifdef CONFIG_64BIT -static int check_for_high_segbits __cpuinitdata; -#endif - static int check_for_high_segbits __cpuinitdata; static unsigned int kscratch_used_mask __cpuinitdata; diff --git a/arch/mips/ralink/of.c b/arch/mips/ralink/of.c index fb1569580def..6b5f3406f414 100644 --- a/arch/mips/ralink/of.c +++ b/arch/mips/ralink/of.c @@ -88,7 +88,7 @@ void __init plat_mem_setup(void) __dt_setup_arch(&__dtb_start); if (soc_info.mem_size) - add_memory_region(soc_info.mem_base, soc_info.mem_size, + add_memory_region(soc_info.mem_base, soc_info.mem_size * SZ_1M, BOOT_MEM_RAM); else detect_memory_region(soc_info.mem_base, diff --git a/arch/mn10300/include/asm/irqflags.h b/arch/mn10300/include/asm/irqflags.h index 678f68d5f37b..8730c0a3c37d 100644 --- a/arch/mn10300/include/asm/irqflags.h +++ b/arch/mn10300/include/asm/irqflags.h @@ -13,9 +13,8 @@ #define _ASM_IRQFLAGS_H #include <asm/cpu-regs.h> -#ifndef __ASSEMBLY__ -#include <linux/smp.h> -#endif +/* linux/smp.h <- linux/irqflags.h needs asm/smp.h first */ +#include <asm/smp.h> /* * interrupt control diff --git a/arch/mn10300/include/asm/pci.h b/arch/mn10300/include/asm/pci.h index 8137c25c4e15..6f31cc0f1a87 100644 --- a/arch/mn10300/include/asm/pci.h +++ b/arch/mn10300/include/asm/pci.h @@ -103,4 +103,6 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) return channel ? 15 : 14; } +#include <asm-generic/pci_iomap.h> + #endif /* _ASM_PCI_H */ diff --git a/arch/mn10300/include/asm/smp.h b/arch/mn10300/include/asm/smp.h index 6745dbe64944..56c42417d428 100644 --- a/arch/mn10300/include/asm/smp.h +++ b/arch/mn10300/include/asm/smp.h @@ -24,6 +24,7 @@ #ifndef __ASSEMBLY__ #include <linux/threads.h> #include <linux/cpumask.h> +#include <linux/thread_info.h> #endif #ifdef CONFIG_SMP @@ -85,7 +86,7 @@ extern cpumask_t cpu_boot_map; extern void smp_init_cpus(void); extern void smp_cache_interrupt(void); extern void send_IPI_allbutself(int irq); -extern int smp_nmi_call_function(smp_call_func_t func, void *info, int wait); +extern int smp_nmi_call_function(void (*func)(void *), void *info, int wait); extern void arch_send_call_function_single_ipi(int cpu); extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); @@ -100,6 +101,7 @@ extern void __cpu_die(unsigned int cpu); #ifndef __ASSEMBLY__ static inline void smp_init_cpus(void) {} +#define raw_smp_processor_id() 0 #endif /* __ASSEMBLY__ */ #endif /* CONFIG_SMP */ diff --git a/arch/mn10300/kernel/entry.S b/arch/mn10300/kernel/entry.S index 68fcab8f8f6f..222152a3f751 100644 --- a/arch/mn10300/kernel/entry.S +++ b/arch/mn10300/kernel/entry.S @@ -60,6 +60,7 @@ ENTRY(ret_from_kernel_thread) mov (REG_D0,fp),d0 mov (REG_A0,fp),a0 calls (a0) + GET_THREAD_INFO a2 # A2 must be set on return from sys_exit() clr d0 mov d0,(REG_D0,fp) jmp syscall_exit @@ -107,10 +108,10 @@ syscall_exit_work: and EPSW_nSL,d0 beq resume_kernel # returning to supervisor mode - btst _TIF_SYSCALL_TRACE,d2 - beq work_pending LOCAL_IRQ_ENABLE # could let syscall_trace_exit() call # schedule() instead + btst _TIF_SYSCALL_TRACE,d2 + beq work_pending mov fp,d0 call syscall_trace_exit[],0 # do_syscall_trace(regs) jmp resume_userspace @@ -123,6 +124,7 @@ work_pending: work_resched: call schedule[],0 +resume_userspace: # make sure we don't miss an interrupt setting need_resched or # sigpending between sampling and the rti LOCAL_IRQ_DISABLE @@ -131,6 +133,8 @@ work_resched: mov (TI_flags,a2),d2 btst _TIF_WORK_MASK,d2 beq restore_all + + LOCAL_IRQ_ENABLE btst _TIF_NEED_RESCHED,d2 bne work_resched @@ -169,17 +173,6 @@ ret_from_intr: and EPSW_nSL,d0 beq resume_kernel # returning to supervisor mode -ENTRY(resume_userspace) - # make sure we don't miss an interrupt setting need_resched or - # sigpending between sampling and the rti - LOCAL_IRQ_DISABLE - - # is there any work to be done on int/exception return? - mov (TI_flags,a2),d2 - btst _TIF_WORK_MASK,d2 - bne work_pending - jmp restore_all - #ifdef CONFIG_PREEMPT ENTRY(resume_kernel) LOCAL_IRQ_DISABLE diff --git a/arch/mn10300/unit-asb2305/pci.c b/arch/mn10300/unit-asb2305/pci.c index 1adcf024bb9a..e37fac0461f3 100644 --- a/arch/mn10300/unit-asb2305/pci.c +++ b/arch/mn10300/unit-asb2305/pci.c @@ -19,6 +19,7 @@ #include <linux/delay.h> #include <linux/irq.h> #include <asm/io.h> +#include <asm/irq.h> #include "pci-asb2305.h" unsigned int pci_probe = 1; diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile index 197690068f88..96ec3982be8d 100644 --- a/arch/parisc/Makefile +++ b/arch/parisc/Makefile @@ -66,7 +66,7 @@ KBUILD_CFLAGS_KERNEL += -mlong-calls endif # select which processor to optimise for -cflags-$(CONFIG_PA7100) += -march=1.1 -mschedule=7100 +cflags-$(CONFIG_PA7000) += -march=1.1 -mschedule=7100 cflags-$(CONFIG_PA7200) += -march=1.1 -mschedule=7200 cflags-$(CONFIG_PA7100LC) += -march=1.1 -mschedule=7100LC cflags-$(CONFIG_PA7300LC) += -march=1.1 -mschedule=7300 diff --git a/arch/parisc/include/asm/assembly.h b/arch/parisc/include/asm/assembly.h index 89fb40005e3f..0da848232344 100644 --- a/arch/parisc/include/asm/assembly.h +++ b/arch/parisc/include/asm/assembly.h @@ -438,7 +438,6 @@ SAVE_SP (%sr4, PT_SR4 (\regs)) SAVE_SP (%sr5, PT_SR5 (\regs)) SAVE_SP (%sr6, PT_SR6 (\regs)) - SAVE_SP (%sr7, PT_SR7 (\regs)) SAVE_CR (%cr17, PT_IASQ0(\regs)) mtctl %r0, %cr17 diff --git a/arch/parisc/include/asm/hardirq.h b/arch/parisc/include/asm/hardirq.h index c19f7138ba48..241c34518465 100644 --- a/arch/parisc/include/asm/hardirq.h +++ b/arch/parisc/include/asm/hardirq.h @@ -17,17 +17,14 @@ typedef struct { unsigned int __softirq_pending; -#ifdef CONFIG_DEBUG_STACKOVERFLOW unsigned int kernel_stack_usage; -#ifdef CONFIG_IRQSTACKS unsigned int irq_stack_usage; - unsigned int irq_stack_counter; -#endif -#endif #ifdef CONFIG_SMP unsigned int irq_resched_count; unsigned int irq_call_count; #endif + unsigned int irq_unaligned_count; + unsigned int irq_fpassist_count; unsigned int irq_tlb_count; } ____cacheline_aligned irq_cpustat_t; diff --git a/arch/parisc/include/asm/mmzone.h b/arch/parisc/include/asm/mmzone.h index 0e625ab9aaec..b6b34a0987e7 100644 --- a/arch/parisc/include/asm/mmzone.h +++ b/arch/parisc/include/asm/mmzone.h @@ -27,7 +27,7 @@ extern struct node_map_data node_data[]; #define PFNNID_SHIFT (30 - PAGE_SHIFT) #define PFNNID_MAP_MAX 512 /* support 512GB */ -extern unsigned char pfnnid_map[PFNNID_MAP_MAX]; +extern signed char pfnnid_map[PFNNID_MAP_MAX]; #ifndef CONFIG_64BIT #define pfn_is_io(pfn) ((pfn & (0xf0000000UL >> PAGE_SHIFT)) == (0xf0000000UL >> PAGE_SHIFT)) @@ -39,17 +39,14 @@ extern unsigned char pfnnid_map[PFNNID_MAP_MAX]; static inline int pfn_to_nid(unsigned long pfn) { unsigned int i; - unsigned char r; if (unlikely(pfn_is_io(pfn))) return 0; i = pfn >> PFNNID_SHIFT; BUG_ON(i >= ARRAY_SIZE(pfnnid_map)); - r = pfnnid_map[i]; - BUG_ON(r == 0xff); - return (int)r; + return pfnnid_map[i]; } static inline int pfn_valid(int pfn) diff --git a/arch/parisc/include/asm/pci.h b/arch/parisc/include/asm/pci.h index 3234f492d575..465154076d23 100644 --- a/arch/parisc/include/asm/pci.h +++ b/arch/parisc/include/asm/pci.h @@ -225,4 +225,9 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) return channel ? 15 : 14; } +#define HAVE_PCI_MMAP + +extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, + enum pci_mmap_state mmap_state, int write_combine); + #endif /* __ASM_PARISC_PCI_H */ diff --git a/arch/parisc/include/asm/processor.h b/arch/parisc/include/asm/processor.h index cfbc43929cf6..cc2290a3cace 100644 --- a/arch/parisc/include/asm/processor.h +++ b/arch/parisc/include/asm/processor.h @@ -17,7 +17,6 @@ #include <asm/ptrace.h> #include <asm/types.h> #include <asm/percpu.h> - #endif /* __ASSEMBLY__ */ /* @@ -59,26 +58,6 @@ #ifndef __ASSEMBLY__ /* - * IRQ STACK - used for irq handler - */ -#ifdef __KERNEL__ - -#include <linux/spinlock_types.h> - -#define IRQ_STACK_SIZE (4096 << 2) /* 16k irq stack size */ - -union irq_stack_union { - unsigned long stack[IRQ_STACK_SIZE/sizeof(unsigned long)]; - raw_spinlock_t lock; -}; - -DECLARE_PER_CPU(union irq_stack_union, irq_stack_union); - -void call_on_stack(unsigned long p1, void *func, unsigned long new_stack); - -#endif /* __KERNEL__ */ - -/* * Data detected about CPUs at boot time which is the same for all CPU's. * HP boxes are SMP - ie identical processors. * diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c index 5709c5e59be8..14285caec71a 100644 --- a/arch/parisc/kernel/drivers.c +++ b/arch/parisc/kernel/drivers.c @@ -394,7 +394,7 @@ EXPORT_SYMBOL(print_pci_hwpath); static void setup_bus_id(struct parisc_device *padev) { struct hardware_path path; - char name[20]; + char name[28]; char *output = name; int i; diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index ae27cb6ce19a..e8f07dd28401 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S @@ -65,15 +65,11 @@ rsm PSW_SM_I, %r0 /* barrier for "Relied upon Translation */ mtsp %r0, %sr4 mtsp %r0, %sr5 - mfsp %sr7, %r1 - or,= %r0,%r1,%r0 /* Only save sr7 in sr3 if sr7 != 0 */ - mtsp %r1, %sr3 + mtsp %r0, %sr6 tovirt_r1 %r29 load32 KERNEL_PSW, %r1 rsm PSW_SM_QUIET,%r0 /* second "heavy weight" ctl op */ - mtsp %r0, %sr6 - mtsp %r0, %sr7 mtctl %r0, %cr17 /* Clear IIASQ tail */ mtctl %r0, %cr17 /* Clear IIASQ head */ mtctl %r1, %ipsw @@ -119,17 +115,20 @@ /* we save the registers in the task struct */ + copy %r30, %r17 mfctl %cr30, %r1 + ldo THREAD_SZ_ALGN(%r1), %r30 + mtsp %r0,%sr7 + mtsp %r16,%sr3 tophys %r1,%r9 LDREG TI_TASK(%r9), %r1 /* thread_info -> task_struct */ tophys %r1,%r9 ldo TASK_REGS(%r9),%r9 - STREG %r30, PT_GR30(%r9) + STREG %r17,PT_GR30(%r9) STREG %r29,PT_GR29(%r9) STREG %r26,PT_GR26(%r9) + STREG %r16,PT_SR7(%r9) copy %r9,%r29 - mfctl %cr30, %r1 - ldo THREAD_SZ_ALGN(%r1), %r30 .endm .macro get_stack_use_r30 @@ -137,10 +136,12 @@ /* we put a struct pt_regs on the stack and save the registers there */ tophys %r30,%r9 - STREG %r30,PT_GR30(%r9) + copy %r30,%r1 ldo PT_SZ_ALGN(%r30),%r30 + STREG %r1,PT_GR30(%r9) STREG %r29,PT_GR29(%r9) STREG %r26,PT_GR26(%r9) + STREG %r16,PT_SR7(%r9) copy %r9,%r29 .endm diff --git a/arch/parisc/kernel/hardware.c b/arch/parisc/kernel/hardware.c index f7752f6af29e..872275659d98 100644 --- a/arch/parisc/kernel/hardware.c +++ b/arch/parisc/kernel/hardware.c @@ -222,6 +222,7 @@ static struct hp_hardware hp_hardware_list[] = { {HPHW_NPROC,0x5DD,0x4,0x81,"Duet W2"}, {HPHW_NPROC,0x5DE,0x4,0x81,"Piccolo W+"}, {HPHW_NPROC,0x5DF,0x4,0x81,"Cantata W2"}, + {HPHW_NPROC,0x5DF,0x0,0x00,"Marcato W+? (rp5470)"}, {HPHW_NPROC,0x5E0,0x4,0x91,"Cantata DC- W2"}, {HPHW_NPROC,0x5E1,0x4,0x91,"Crescendo DC- W2"}, {HPHW_NPROC,0x5E2,0x4,0x91,"Crescendo 650 W2"}, @@ -1204,6 +1205,7 @@ static struct hp_hardware hp_hardware_list[] = { {HPHW_FIO, 0x004, 0x00320, 0x0, "Metheus Frame Buffer"}, {HPHW_FIO, 0x004, 0x00340, 0x0, "BARCO CX4500 VME Grphx Cnsl"}, {HPHW_FIO, 0x004, 0x00360, 0x0, "Hughes TOG VME FDDI"}, + {HPHW_FIO, 0x076, 0x000AD, 0x00, "Crestone Peak RS-232"}, {HPHW_IOA, 0x185, 0x0000B, 0x00, "Java BC Summit Port"}, {HPHW_IOA, 0x1FF, 0x0000B, 0x00, "Hitachi Ghostview Summit Port"}, {HPHW_IOA, 0x580, 0x0000B, 0x10, "U2-IOA BC Runway Port"}, diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c index 55237a70e197..2e6443b1e922 100644 --- a/arch/parisc/kernel/irq.c +++ b/arch/parisc/kernel/irq.c @@ -27,11 +27,11 @@ #include <linux/interrupt.h> #include <linux/kernel_stat.h> #include <linux/seq_file.h> -#include <linux/spinlock.h> #include <linux/types.h> #include <asm/io.h> #include <asm/smp.h> +#include <asm/ldcw.h> #undef PARISC_IRQ_CR16_COUNTS @@ -172,10 +172,6 @@ int arch_show_interrupts(struct seq_file *p, int prec) for_each_online_cpu(j) seq_printf(p, "%10u ", irq_stats(j)->irq_stack_usage); seq_puts(p, " Interrupt stack usage\n"); - seq_printf(p, "%*s: ", prec, "ISC"); - for_each_online_cpu(j) - seq_printf(p, "%10u ", irq_stats(j)->irq_stack_counter); - seq_puts(p, " Interrupt stack usage counter\n"); # endif #endif #ifdef CONFIG_SMP @@ -188,6 +184,14 @@ int arch_show_interrupts(struct seq_file *p, int prec) seq_printf(p, "%10u ", irq_stats(j)->irq_call_count); seq_puts(p, " Function call interrupts\n"); #endif + seq_printf(p, "%*s: ", prec, "UAH"); + for_each_online_cpu(j) + seq_printf(p, "%10u ", irq_stats(j)->irq_unaligned_count); + seq_puts(p, " Unaligned access handler traps\n"); + seq_printf(p, "%*s: ", prec, "FPA"); + for_each_online_cpu(j) + seq_printf(p, "%10u ", irq_stats(j)->irq_fpassist_count); + seq_puts(p, " Floating point assist traps\n"); seq_printf(p, "%*s: ", prec, "TLB"); for_each_online_cpu(j) seq_printf(p, "%10u ", irq_stats(j)->irq_tlb_count); @@ -376,6 +380,24 @@ static inline int eirr_to_irq(unsigned long eirr) return (BITS_PER_LONG - bit) + TIMER_IRQ; } +#ifdef CONFIG_IRQSTACKS +/* + * IRQ STACK - used for irq handler + */ +#define IRQ_STACK_SIZE (4096 << 2) /* 16k irq stack size */ + +union irq_stack_union { + unsigned long stack[IRQ_STACK_SIZE/sizeof(unsigned long)]; + volatile unsigned int slock[4]; + volatile unsigned int lock[1]; +}; + +DEFINE_PER_CPU(union irq_stack_union, irq_stack_union) = { + .slock = { 1,1,1,1 }, + }; +#endif + + int sysctl_panic_on_stackoverflow = 1; static inline void stack_overflow_check(struct pt_regs *regs) @@ -442,27 +464,26 @@ panic_check: } #ifdef CONFIG_IRQSTACKS -DEFINE_PER_CPU(union irq_stack_union, irq_stack_union) = { - .lock = __RAW_SPIN_LOCK_UNLOCKED((irq_stack_union).lock) - }; +/* in entry.S: */ +void call_on_stack(unsigned long p1, void *func, unsigned long new_stack); static void execute_on_irq_stack(void *func, unsigned long param1) { union irq_stack_union *union_ptr; unsigned long irq_stack; - raw_spinlock_t *irq_stack_in_use; + volatile unsigned int *irq_stack_in_use; union_ptr = &per_cpu(irq_stack_union, smp_processor_id()); irq_stack = (unsigned long) &union_ptr->stack; - irq_stack = ALIGN(irq_stack + sizeof(irq_stack_union.lock), + irq_stack = ALIGN(irq_stack + sizeof(irq_stack_union.slock), 64); /* align for stack frame usage */ /* We may be called recursive. If we are already using the irq stack, * just continue to use it. Use spinlocks to serialize * the irq stack usage. */ - irq_stack_in_use = &union_ptr->lock; - if (!raw_spin_trylock(irq_stack_in_use)) { + irq_stack_in_use = (volatile unsigned int *)__ldcw_align(union_ptr); + if (!__ldcw(irq_stack_in_use)) { void (*direct_call)(unsigned long p1) = func; /* We are using the IRQ stack already. @@ -474,10 +495,8 @@ static void execute_on_irq_stack(void *func, unsigned long param1) /* This is where we switch to the IRQ stack. */ call_on_stack(param1, func, irq_stack); - __inc_irq_stat(irq_stack_counter); - /* free up irq stack usage. */ - do_raw_spin_unlock(irq_stack_in_use); + *irq_stack_in_use = 1; } asmlinkage void do_softirq(void) diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S index 5e1de6072be5..b743a80eaba0 100644 --- a/arch/parisc/kernel/pacache.S +++ b/arch/parisc/kernel/pacache.S @@ -605,14 +605,14 @@ ENTRY(copy_user_page_asm) convert_phys_for_tlb_insert20 %r26 /* convert phys addr to tlb insert format */ convert_phys_for_tlb_insert20 %r23 /* convert phys addr to tlb insert format */ depd %r24,63,22, %r28 /* Form aliased virtual address 'to' */ - depdi 0, 63,PAGE_SHIFT, %r28 /* Clear any offset bits */ + depdi 0, 63,PAGE_SHIFT, %r28 /* Clear any offset bits */ copy %r28, %r29 depdi 1, 41,1, %r29 /* Form aliased virtual address 'from' */ #else extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */ extrw,u %r23, 24,25, %r23 /* convert phys addr to tlb insert format */ depw %r24, 31,22, %r28 /* Form aliased virtual address 'to' */ - depwi 0, 31,12, %r28 /* Clear any offset bits */ + depwi 0, 31,PAGE_SHIFT, %r28 /* Clear any offset bits */ copy %r28, %r29 depwi 1, 9,1, %r29 /* Form aliased virtual address 'from' */ #endif @@ -762,7 +762,7 @@ ENTRY(clear_user_page_asm) #else extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */ depw %r25, 31,22, %r28 /* Form aliased virtual address 'to' */ - depwi 0, 31,12, %r28 /* Clear any offset bits */ + depwi 0, 31,PAGE_SHIFT, %r28 /* Clear any offset bits */ #endif /* Purge any old translation */ @@ -846,7 +846,7 @@ ENTRY(flush_dcache_page_asm) #else extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */ depw %r25, 31,22, %r28 /* Form aliased virtual address 'to' */ - depwi 0, 31,12, %r28 /* Clear any offset bits */ + depwi 0, 31,PAGE_SHIFT, %r28 /* Clear any offset bits */ #endif /* Purge any old translation */ @@ -860,7 +860,7 @@ ENTRY(flush_dcache_page_asm) #endif ldil L%dcache_stride, %r1 - ldw R%dcache_stride(%r1), %r1 + ldw R%dcache_stride(%r1), r31 #ifdef CONFIG_64BIT depdi,z 1, 63-PAGE_SHIFT,1, %r25 @@ -868,26 +868,26 @@ ENTRY(flush_dcache_page_asm) depwi,z 1, 31-PAGE_SHIFT,1, %r25 #endif add %r28, %r25, %r25 - sub %r25, %r1, %r25 - - -1: fdc,m %r1(%r28) - fdc,m %r1(%r28) - fdc,m %r1(%r28) - fdc,m %r1(%r28) - fdc,m %r1(%r28) - fdc,m %r1(%r28) - fdc,m %r1(%r28) - fdc,m %r1(%r28) - fdc,m %r1(%r28) - fdc,m %r1(%r28) - fdc,m %r1(%r28) - fdc,m %r1(%r28) - fdc,m %r1(%r28) - fdc,m %r1(%r28) - fdc,m %r1(%r28) + sub %r25, r31, %r25 + + +1: fdc,m r31(%r28) + fdc,m r31(%r28) + fdc,m r31(%r28) + fdc,m r31(%r28) + fdc,m r31(%r28) + fdc,m r31(%r28) + fdc,m r31(%r28) + fdc,m r31(%r28) + fdc,m r31(%r28) + fdc,m r31(%r28) + fdc,m r31(%r28) + fdc,m r31(%r28) + fdc,m r31(%r28) + fdc,m r31(%r28) + fdc,m r31(%r28) cmpb,COND(<<) %r28, %r25,1b - fdc,m %r1(%r28) + fdc,m r31(%r28) sync @@ -918,11 +918,11 @@ ENTRY(flush_icache_page_asm) #endif convert_phys_for_tlb_insert20 %r26 /* convert phys addr to tlb insert format */ depd %r25, 63,22, %r28 /* Form aliased virtual address 'to' */ - depdi 0, 63,PAGE_SHIFT, %r28 /* Clear any offset bits */ + depdi 0, 63,PAGE_SHIFT, %r28 /* Clear any offset bits */ #else extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */ depw %r25, 31,22, %r28 /* Form aliased virtual address 'to' */ - depwi 0, 31,12, %r28 /* Clear any offset bits */ + depwi 0, 31,PAGE_SHIFT, %r28 /* Clear any offset bits */ #endif /* Purge any old translation */ @@ -936,7 +936,7 @@ ENTRY(flush_icache_page_asm) #endif ldil L%icache_stride, %r1 - ldw R%icache_stride(%r1), %r1 + ldw R%icache_stride(%r1), %r31 #ifdef CONFIG_64BIT depdi,z 1, 63-PAGE_SHIFT,1, %r25 @@ -944,28 +944,28 @@ ENTRY(flush_icache_page_asm) depwi,z 1, 31-PAGE_SHIFT,1, %r25 #endif add %r28, %r25, %r25 - sub %r25, %r1, %r25 + sub %r25, %r31, %r25 /* fic only has the type 26 form on PA1.1, requiring an * explicit space specification, so use %sr4 */ -1: fic,m %r1(%sr4,%r28) - fic,m %r1(%sr4,%r28) - fic,m %r1(%sr4,%r28) - fic,m %r1(%sr4,%r28) - fic,m %r1(%sr4,%r28) - fic,m %r1(%sr4,%r28) - fic,m %r1(%sr4,%r28) - fic,m %r1(%sr4,%r28) - fic,m %r1(%sr4,%r28) - fic,m %r1(%sr4,%r28) - fic,m %r1(%sr4,%r28) - fic,m %r1(%sr4,%r28) - fic,m %r1(%sr4,%r28) - fic,m %r1(%sr4,%r28) - fic,m %r1(%sr4,%r28) +1: fic,m %r31(%sr4,%r28) + fic,m %r31(%sr4,%r28) + fic,m %r31(%sr4,%r28) + fic,m %r31(%sr4,%r28) + fic,m %r31(%sr4,%r28) + fic,m %r31(%sr4,%r28) + fic,m %r31(%sr4,%r28) + fic,m %r31(%sr4,%r28) + fic,m %r31(%sr4,%r28) + fic,m %r31(%sr4,%r28) + fic,m %r31(%sr4,%r28) + fic,m %r31(%sr4,%r28) + fic,m %r31(%sr4,%r28) + fic,m %r31(%sr4,%r28) + fic,m %r31(%sr4,%r28) cmpb,COND(<<) %r28, %r25,1b - fic,m %r1(%sr4,%r28) + fic,m %r31(%sr4,%r28) sync diff --git a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c index 60309051875e..64f2764a8cef 100644 --- a/arch/parisc/kernel/pci.c +++ b/arch/parisc/kernel/pci.c @@ -220,6 +220,33 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res, } +int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, + enum pci_mmap_state mmap_state, int write_combine) +{ + unsigned long prot; + + /* + * I/O space can be accessed via normal processor loads and stores on + * this platform but for now we elect not to do this and portable + * drivers should not do this anyway. + */ + if (mmap_state == pci_mmap_io) + return -EINVAL; + + if (write_combine) + return -EINVAL; + + /* + * Ignore write-combine; for now only return uncached mappings. + */ + prot = pgprot_val(vma->vm_page_prot); + prot |= _PAGE_NO_CACHE; + vma->vm_page_prot = __pgprot(prot); + + return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, + vma->vm_end - vma->vm_start, vma->vm_page_prot); +} + /* * A driver is enabling the device. We make sure that all the appropriate * bits are set to allow the device to operate as the driver is expecting. diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c index 76b63e726a53..1e95b2000ce8 100644 --- a/arch/parisc/kernel/setup.c +++ b/arch/parisc/kernel/setup.c @@ -69,7 +69,8 @@ void __init setup_cmdline(char **cmdline_p) /* called from hpux boot loader */ boot_command_line[0] = '\0'; } else { - strcpy(boot_command_line, (char *)__va(boot_args[1])); + strlcpy(boot_command_line, (char *)__va(boot_args[1]), + COMMAND_LINE_SIZE); #ifdef CONFIG_BLK_DEV_INITRD if (boot_args[2] != 0) /* did palo pass us a ramdisk? */ diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c index fe41a98043bb..04e47c6a4562 100644 --- a/arch/parisc/kernel/traps.c +++ b/arch/parisc/kernel/traps.c @@ -646,6 +646,7 @@ void notrace handle_interruption(int code, struct pt_regs *regs) case 14: /* Assist Exception Trap, i.e. floating point exception. */ die_if_kernel("Floating point exception", regs, 0); /* quiet */ + __inc_irq_stat(irq_fpassist_count); handle_fpe(regs); return; diff --git a/arch/parisc/kernel/unaligned.c b/arch/parisc/kernel/unaligned.c index 234e3682cf09..d7c0acb35ec2 100644 --- a/arch/parisc/kernel/unaligned.c +++ b/arch/parisc/kernel/unaligned.c @@ -27,6 +27,7 @@ #include <linux/signal.h> #include <linux/ratelimit.h> #include <asm/uaccess.h> +#include <asm/hardirq.h> /* #define DEBUG_UNALIGNED 1 */ @@ -454,6 +455,8 @@ void handle_unaligned(struct pt_regs *regs) struct siginfo si; register int flop=0; /* true if this is a flop */ + __inc_irq_stat(irq_unaligned_count); + /* log a message with pacing */ if (user_mode(regs)) { if (current->thread.flags & PARISC_UAC_SIGBUS) { diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c index 1c965642068b..505b56c6b9b9 100644 --- a/arch/parisc/mm/init.c +++ b/arch/parisc/mm/init.c @@ -47,7 +47,7 @@ pte_t pg0[PT_INITIAL * PTRS_PER_PTE] __attribute__ ((__section__ (".data..vm0.pt #ifdef CONFIG_DISCONTIGMEM struct node_map_data node_data[MAX_NUMNODES] __read_mostly; -unsigned char pfnnid_map[PFNNID_MAP_MAX] __read_mostly; +signed char pfnnid_map[PFNNID_MAP_MAX] __read_mostly; #endif static struct resource data_resource = { diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h index 26807e5aff51..6f3887d884d2 100644 --- a/arch/powerpc/include/asm/cputable.h +++ b/arch/powerpc/include/asm/cputable.h @@ -176,6 +176,7 @@ extern const char *powerpc_base_platform; #define CPU_FTR_CFAR LONG_ASM_CONST(0x0100000000000000) #define CPU_FTR_HAS_PPR LONG_ASM_CONST(0x0200000000000000) #define CPU_FTR_DAWR LONG_ASM_CONST(0x0400000000000000) +#define CPU_FTR_DABRX LONG_ASM_CONST(0x0800000000000000) #ifndef __ASSEMBLY__ @@ -394,19 +395,20 @@ extern const char *powerpc_base_platform; CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | CPU_FTR_ARCH_201 | \ CPU_FTR_ALTIVEC_COMP | CPU_FTR_CAN_NAP | CPU_FTR_MMCRA | \ CPU_FTR_CP_USE_DCBTZ | CPU_FTR_STCX_CHECKS_ADDRESS | \ - CPU_FTR_HVMODE) + CPU_FTR_HVMODE | CPU_FTR_DABRX) #define CPU_FTRS_POWER5 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ CPU_FTR_MMCRA | CPU_FTR_SMT | \ CPU_FTR_COHERENT_ICACHE | CPU_FTR_PURR | \ - CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB) + CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_DABRX) #define CPU_FTRS_POWER6 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ CPU_FTR_MMCRA | CPU_FTR_SMT | \ CPU_FTR_COHERENT_ICACHE | \ CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \ CPU_FTR_DSCR | CPU_FTR_UNALIGNED_LD_STD | \ - CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_CFAR) + CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_CFAR | \ + CPU_FTR_DABRX) #define CPU_FTRS_POWER7 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | CPU_FTR_ARCH_206 |\ CPU_FTR_MMCRA | CPU_FTR_SMT | \ @@ -415,7 +417,7 @@ extern const char *powerpc_base_platform; CPU_FTR_DSCR | CPU_FTR_SAO | CPU_FTR_ASYM_SMT | \ CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | \ - CPU_FTR_VMX_COPY | CPU_FTR_HAS_PPR) + CPU_FTR_VMX_COPY | CPU_FTR_HAS_PPR | CPU_FTR_DABRX) #define CPU_FTRS_POWER8 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | CPU_FTR_ARCH_206 |\ CPU_FTR_MMCRA | CPU_FTR_SMT | \ @@ -430,14 +432,15 @@ extern const char *powerpc_base_platform; CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \ CPU_FTR_PAUSE_ZERO | CPU_FTR_CELL_TB_BUG | CPU_FTR_CP_USE_DCBTZ | \ - CPU_FTR_UNALIGNED_LD_STD) + CPU_FTR_UNALIGNED_LD_STD | CPU_FTR_DABRX) #define CPU_FTRS_PA6T (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP | \ - CPU_FTR_PURR | CPU_FTR_REAL_LE) + CPU_FTR_PURR | CPU_FTR_REAL_LE | CPU_FTR_DABRX) #define CPU_FTRS_COMPATIBLE (CPU_FTR_USE_TB | CPU_FTR_PPCAS_ARCH_V2) #define CPU_FTRS_A2 (CPU_FTR_USE_TB | CPU_FTR_SMT | CPU_FTR_DBELL | \ - CPU_FTR_NOEXECUTE | CPU_FTR_NODSISRALIGN | CPU_FTR_ICSWX) + CPU_FTR_NOEXECUTE | CPU_FTR_NODSISRALIGN | \ + CPU_FTR_ICSWX | CPU_FTR_DABRX ) #ifdef __powerpc64__ #ifdef CONFIG_PPC_BOOK3E diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h index 8e5fae8beaf6..46793b58a761 100644 --- a/arch/powerpc/include/asm/exception-64s.h +++ b/arch/powerpc/include/asm/exception-64s.h @@ -513,7 +513,7 @@ label##_common: \ */ #define STD_EXCEPTION_COMMON_ASYNC(trap, label, hdlr) \ EXCEPTION_COMMON(trap, label, hdlr, ret_from_except_lite, \ - FINISH_NAP;RUNLATCH_ON;DISABLE_INTS) + FINISH_NAP;DISABLE_INTS;RUNLATCH_ON) /* * When the idle code in power4_idle puts the CPU into NAP mode, diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h index cf4df8e2139a..0c7f2bfcf134 100644 --- a/arch/powerpc/include/asm/hvcall.h +++ b/arch/powerpc/include/asm/hvcall.h @@ -264,6 +264,7 @@ #define H_GET_MPP 0x2D4 #define H_HOME_NODE_ASSOCIATIVITY 0x2EC #define H_BEST_ENERGY 0x2F4 +#define H_XIRR_X 0x2FC #define H_RANDOM 0x300 #define H_COP 0x304 #define H_GET_MPP_X 0x314 diff --git a/arch/powerpc/include/asm/kvm_asm.h b/arch/powerpc/include/asm/kvm_asm.h index b9dd382cb349..851bac7afa4b 100644 --- a/arch/powerpc/include/asm/kvm_asm.h +++ b/arch/powerpc/include/asm/kvm_asm.h @@ -54,8 +54,16 @@ #define BOOKE_INTERRUPT_DEBUG 15 /* E500 */ -#define BOOKE_INTERRUPT_SPE_UNAVAIL 32 -#define BOOKE_INTERRUPT_SPE_FP_DATA 33 +#define BOOKE_INTERRUPT_SPE_ALTIVEC_UNAVAIL 32 +#define BOOKE_INTERRUPT_SPE_FP_DATA_ALTIVEC_ASSIST 33 +/* + * TODO: Unify 32-bit and 64-bit kernel exception handlers to use same defines + */ +#define BOOKE_INTERRUPT_SPE_UNAVAIL BOOKE_INTERRUPT_SPE_ALTIVEC_UNAVAIL +#define BOOKE_INTERRUPT_SPE_FP_DATA BOOKE_INTERRUPT_SPE_FP_DATA_ALTIVEC_ASSIST +#define BOOKE_INTERRUPT_ALTIVEC_UNAVAIL BOOKE_INTERRUPT_SPE_ALTIVEC_UNAVAIL +#define BOOKE_INTERRUPT_ALTIVEC_ASSIST \ + BOOKE_INTERRUPT_SPE_FP_DATA_ALTIVEC_ASSIST #define BOOKE_INTERRUPT_SPE_FP_ROUND 34 #define BOOKE_INTERRUPT_PERFORMANCE_MONITOR 35 #define BOOKE_INTERRUPT_DOORBELL 36 @@ -67,10 +75,6 @@ #define BOOKE_INTERRUPT_HV_SYSCALL 40 #define BOOKE_INTERRUPT_HV_PRIV 41 -/* altivec */ -#define BOOKE_INTERRUPT_ALTIVEC_UNAVAIL 42 -#define BOOKE_INTERRUPT_ALTIVEC_ASSIST 43 - /* book3s */ #define BOOK3S_INTERRUPT_SYSTEM_RESET 0x100 diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h index 8b11b5bd9938..2c1d8cb9b265 100644 --- a/arch/powerpc/include/asm/pci-bridge.h +++ b/arch/powerpc/include/asm/pci-bridge.h @@ -174,6 +174,8 @@ struct pci_dn { /* Get the pointer to a device_node's pci_dn */ #define PCI_DN(dn) ((struct pci_dn *) (dn)->data) +extern struct pci_dn *pci_get_pdn(struct pci_dev *pdev); + extern void * update_dn_pci_info(struct device_node *dn, void *data); static inline int pci_device_from_OF_node(struct device_node *np, diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h index cea8496091ff..2f1b6c5f8174 100644 --- a/arch/powerpc/include/asm/ppc_asm.h +++ b/arch/powerpc/include/asm/ppc_asm.h @@ -523,6 +523,17 @@ END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,946) #define PPC440EP_ERR42 #endif +/* The following stops all load and store data streams associated with stream + * ID (ie. streams created explicitly). The embedded and server mnemonics for + * dcbt are different so we use machine "power4" here explicitly. + */ +#define DCBT_STOP_ALL_STREAM_IDS(scratch) \ +.machine push ; \ +.machine "power4" ; \ + lis scratch,0x60000000@h; \ + dcbt r0,scratch,0b01010; \ +.machine pop + /* * toreal/fromreal/tophys/tovirt macros. 32-bit BookE makes them * keep the address intact to be compatible with code shared with diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index d7e67ca8b4a6..14a658363698 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h @@ -284,6 +284,12 @@ struct thread_struct { unsigned long ebbrr; unsigned long ebbhr; unsigned long bescr; + unsigned long siar; + unsigned long sdar; + unsigned long sier; + unsigned long mmcr0; + unsigned long mmcr2; + unsigned long mmcra; #endif }; @@ -403,21 +409,16 @@ static inline void prefetchw(const void *x) #endif #ifdef CONFIG_PPC64 -static inline unsigned long get_clean_sp(struct pt_regs *regs, int is_32) +static inline unsigned long get_clean_sp(unsigned long sp, int is_32) { - unsigned long sp; - if (is_32) - sp = regs->gpr[1] & 0x0ffffffffUL; - else - sp = regs->gpr[1]; - + return sp & 0x0ffffffffUL; return sp; } #else -static inline unsigned long get_clean_sp(struct pt_regs *regs, int is_32) +static inline unsigned long get_clean_sp(unsigned long sp, int is_32) { - return regs->gpr[1]; + return sp; } #endif diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index a6136515c7f2..4a9e408644fe 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h @@ -111,17 +111,6 @@ #define MSR_TM_TRANSACTIONAL(x) (((x) & MSR_TS_MASK) == MSR_TS_T) #define MSR_TM_SUSPENDED(x) (((x) & MSR_TS_MASK) == MSR_TS_S) -/* Reason codes describing kernel causes for transaction aborts. By - convention, bit0 is copied to TEXASR[56] (IBM bit 7) which is set if - the failure is persistent. -*/ -#define TM_CAUSE_RESCHED 0xfe -#define TM_CAUSE_TLBI 0xfc -#define TM_CAUSE_FAC_UNAV 0xfa -#define TM_CAUSE_SYSCALL 0xf9 /* Persistent */ -#define TM_CAUSE_MISC 0xf6 -#define TM_CAUSE_SIGNAL 0xf4 - #if defined(CONFIG_PPC_BOOK3S_64) #define MSR_64BIT MSR_SF diff --git a/arch/powerpc/include/asm/signal.h b/arch/powerpc/include/asm/signal.h index fbe66c463891..9322c28aebd2 100644 --- a/arch/powerpc/include/asm/signal.h +++ b/arch/powerpc/include/asm/signal.h @@ -3,5 +3,8 @@ #define __ARCH_HAS_SA_RESTORER #include <uapi/asm/signal.h> +#include <uapi/asm/ptrace.h> + +extern unsigned long get_tm_stackpointer(struct pt_regs *regs); #endif /* _ASM_POWERPC_SIGNAL_H */ diff --git a/arch/powerpc/include/asm/tm.h b/arch/powerpc/include/asm/tm.h index 4b4449abf3f8..9dfbc34bdbf5 100644 --- a/arch/powerpc/include/asm/tm.h +++ b/arch/powerpc/include/asm/tm.h @@ -5,6 +5,8 @@ * Copyright 2012 Matt Evans & Michael Neuling, IBM Corporation. */ +#include <uapi/asm/tm.h> + #ifdef CONFIG_PPC_TRANSACTIONAL_MEM extern void do_load_up_transact_fpu(struct thread_struct *thread); extern void do_load_up_transact_altivec(struct thread_struct *thread); diff --git a/arch/powerpc/include/uapi/asm/Kbuild b/arch/powerpc/include/uapi/asm/Kbuild index f7bca6370745..5182c8622b54 100644 --- a/arch/powerpc/include/uapi/asm/Kbuild +++ b/arch/powerpc/include/uapi/asm/Kbuild @@ -40,6 +40,7 @@ header-y += statfs.h header-y += swab.h header-y += termbits.h header-y += termios.h +header-y += tm.h header-y += types.h header-y += ucontext.h header-y += unistd.h diff --git a/arch/powerpc/include/uapi/asm/tm.h b/arch/powerpc/include/uapi/asm/tm.h new file mode 100644 index 000000000000..85059a00f560 --- /dev/null +++ b/arch/powerpc/include/uapi/asm/tm.h @@ -0,0 +1,18 @@ +#ifndef _ASM_POWERPC_TM_H +#define _ASM_POWERPC_TM_H + +/* Reason codes describing kernel causes for transaction aborts. By + * convention, bit0 is copied to TEXASR[56] (IBM bit 7) which is set if + * the failure is persistent. PAPR saves 0xff-0xe0 for the hypervisor. + */ +#define TM_CAUSE_PERSISTENT 0x01 +#define TM_CAUSE_RESCHED 0xde +#define TM_CAUSE_TLBI 0xdc +#define TM_CAUSE_FAC_UNAV 0xda +#define TM_CAUSE_SYSCALL 0xd8 /* future use */ +#define TM_CAUSE_MISC 0xd6 /* future use */ +#define TM_CAUSE_SIGNAL 0xd4 +#define TM_CAUSE_ALIGNMENT 0xd2 +#define TM_CAUSE_EMULATE 0xd0 + +#endif diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index b51a97cfedf8..6f16ffafa6f0 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -127,6 +127,12 @@ int main(void) DEFINE(THREAD_BESCR, offsetof(struct thread_struct, bescr)); DEFINE(THREAD_EBBHR, offsetof(struct thread_struct, ebbhr)); DEFINE(THREAD_EBBRR, offsetof(struct thread_struct, ebbrr)); + DEFINE(THREAD_SIAR, offsetof(struct thread_struct, siar)); + DEFINE(THREAD_SDAR, offsetof(struct thread_struct, sdar)); + DEFINE(THREAD_SIER, offsetof(struct thread_struct, sier)); + DEFINE(THREAD_MMCR0, offsetof(struct thread_struct, mmcr0)); + DEFINE(THREAD_MMCR2, offsetof(struct thread_struct, mmcr2)); + DEFINE(THREAD_MMCRA, offsetof(struct thread_struct, mmcra)); #endif #ifdef CONFIG_PPC_TRANSACTIONAL_MEM DEFINE(PACATMSCRATCH, offsetof(struct paca_struct, tm_scratch)); diff --git a/arch/powerpc/kernel/cpu_setup_power.S b/arch/powerpc/kernel/cpu_setup_power.S index a283b6442b26..18b5b9cf8e37 100644 --- a/arch/powerpc/kernel/cpu_setup_power.S +++ b/arch/powerpc/kernel/cpu_setup_power.S @@ -135,8 +135,12 @@ __init_HFSCR: blr __init_TLB: - /* Clear the TLB */ - li r6,128 + /* + * Clear the TLB using the "IS 3" form of tlbiel instruction + * (invalidate by congruence class). P7 has 128 CCs, P8 has 512 + * so we just always do 512 + */ + li r6,512 mtctr r6 li r7,0xc00 /* IS field = 0b11 */ ptesync diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index c60bbec25c1f..2a45d0f04385 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -452,7 +452,7 @@ static struct cpu_spec __initdata cpu_specs[] = { .mmu_features = MMU_FTRS_POWER8, .icache_bsize = 128, .dcache_bsize = 128, - .oprofile_type = PPC_OPROFILE_POWER4, + .oprofile_type = PPC_OPROFILE_INVALID, .oprofile_cpu_type = "ppc64/ibm-compat-v1", .cpu_setup = __setup_cpu_power8, .cpu_restore = __restore_cpu_power8, @@ -482,7 +482,7 @@ static struct cpu_spec __initdata cpu_specs[] = { .cpu_name = "POWER7+ (raw)", .cpu_features = CPU_FTRS_POWER7, .cpu_user_features = COMMON_USER_POWER7, - .cpu_user_features = COMMON_USER2_POWER7, + .cpu_user_features2 = COMMON_USER2_POWER7, .mmu_features = MMU_FTRS_POWER7, .icache_bsize = 128, .dcache_bsize = 128, @@ -507,7 +507,7 @@ static struct cpu_spec __initdata cpu_specs[] = { .num_pmcs = 6, .pmc_type = PPC_PMC_IBM, .oprofile_cpu_type = "ppc64/power8", - .oprofile_type = PPC_OPROFILE_POWER4, + .oprofile_type = PPC_OPROFILE_INVALID, .cpu_setup = __setup_cpu_power8, .cpu_restore = __restore_cpu_power8, .platform = "power8", diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index d22e73e4618b..22b45a4955cd 100644 --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S @@ -849,7 +849,7 @@ resume_kernel: /* check current_thread_info, _TIF_EMULATE_STACK_STORE */ CURRENT_THREAD_INFO(r9, r1) lwz r8,TI_FLAGS(r9) - andis. r8,r8,_TIF_EMULATE_STACK_STORE@h + andis. r0,r8,_TIF_EMULATE_STACK_STORE@h beq+ 1f addi r8,r1,INT_FRAME_SIZE /* Get the kprobed function entry */ diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 51cfb8fc301f..8741c854e03d 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -487,6 +487,13 @@ BEGIN_FTR_SECTION ldarx r6,0,r1 END_FTR_SECTION_IFSET(CPU_FTR_STCX_CHECKS_ADDRESS) +#ifdef CONFIG_PPC_BOOK3S +/* Cancel all explict user streams as they will have no use after context + * switch and will stop the HW from creating streams itself + */ + DCBT_STOP_ALL_STREAM_IDS(r6) +#endif + addi r6,r4,-THREAD /* Convert THREAD to 'current' */ std r6,PACACURRENT(r13) /* Set new 'current' */ diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index e6eba1bf61ad..40e4a17c8ba0 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -454,38 +454,14 @@ BEGIN_FTR_SECTION xori r10,r10,(MSR_FE0|MSR_FE1) mtmsrd r10 sync - fmr 0,0 - fmr 1,1 - fmr 2,2 - fmr 3,3 - fmr 4,4 - fmr 5,5 - fmr 6,6 - fmr 7,7 - fmr 8,8 - fmr 9,9 - fmr 10,10 - fmr 11,11 - fmr 12,12 - fmr 13,13 - fmr 14,14 - fmr 15,15 - fmr 16,16 - fmr 17,17 - fmr 18,18 - fmr 19,19 - fmr 20,20 - fmr 21,21 - fmr 22,22 - fmr 23,23 - fmr 24,24 - fmr 25,25 - fmr 26,26 - fmr 27,27 - fmr 28,28 - fmr 29,29 - fmr 30,30 - fmr 31,31 + +#define FMR2(n) fmr (n), (n) ; fmr n+1, n+1 +#define FMR4(n) FMR2(n) ; FMR2(n+2) +#define FMR8(n) FMR4(n) ; FMR4(n+4) +#define FMR16(n) FMR8(n) ; FMR8(n+8) +#define FMR32(n) FMR16(n) ; FMR16(n+16) + FMR32(0) + FTR_SECTION_ELSE /* * To denormalise we need to move a copy of the register to itself. @@ -495,39 +471,25 @@ FTR_SECTION_ELSE oris r10,r10,MSR_VSX@h mtmsrd r10 sync - XVCPSGNDP(0,0,0) - XVCPSGNDP(1,1,1) - XVCPSGNDP(2,2,2) - XVCPSGNDP(3,3,3) - XVCPSGNDP(4,4,4) - XVCPSGNDP(5,5,5) - XVCPSGNDP(6,6,6) - XVCPSGNDP(7,7,7) - XVCPSGNDP(8,8,8) - XVCPSGNDP(9,9,9) - XVCPSGNDP(10,10,10) - XVCPSGNDP(11,11,11) - XVCPSGNDP(12,12,12) - XVCPSGNDP(13,13,13) - XVCPSGNDP(14,14,14) - XVCPSGNDP(15,15,15) - XVCPSGNDP(16,16,16) - XVCPSGNDP(17,17,17) - XVCPSGNDP(18,18,18) - XVCPSGNDP(19,19,19) - XVCPSGNDP(20,20,20) - XVCPSGNDP(21,21,21) - XVCPSGNDP(22,22,22) - XVCPSGNDP(23,23,23) - XVCPSGNDP(24,24,24) - XVCPSGNDP(25,25,25) - XVCPSGNDP(26,26,26) - XVCPSGNDP(27,27,27) - XVCPSGNDP(28,28,28) - XVCPSGNDP(29,29,29) - XVCPSGNDP(30,30,30) - XVCPSGNDP(31,31,31) + +#define XVCPSGNDP2(n) XVCPSGNDP(n,n,n) ; XVCPSGNDP(n+1,n+1,n+1) +#define XVCPSGNDP4(n) XVCPSGNDP2(n) ; XVCPSGNDP2(n+2) +#define XVCPSGNDP8(n) XVCPSGNDP4(n) ; XVCPSGNDP4(n+4) +#define XVCPSGNDP16(n) XVCPSGNDP8(n) ; XVCPSGNDP8(n+8) +#define XVCPSGNDP32(n) XVCPSGNDP16(n) ; XVCPSGNDP16(n+16) + XVCPSGNDP32(0) + ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_206) + +BEGIN_FTR_SECTION + b denorm_done +END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S) +/* + * To denormalise we need to move a copy of the register to itself. + * For POWER8 we need to do that for all 64 VSX registers + */ + XVCPSGNDP32(32) +denorm_done: mtspr SPRN_HSRR0,r11 mtcrf 0x80,r9 ld r9,PACA_EXGEN+EX_R9(r13) @@ -721,7 +683,7 @@ machine_check_common: STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception) STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception) STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception) - STD_EXCEPTION_COMMON(0xe40, emulation_assist, .program_check_exception) + STD_EXCEPTION_COMMON(0xe40, emulation_assist, .emulation_assist_interrupt) STD_EXCEPTION_COMMON(0xe60, hmi_exception, .unknown_exception) #ifdef CONFIG_PPC_DOORBELL STD_EXCEPTION_COMMON_ASYNC(0xe80, h_doorbell, .doorbell_exception) diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 5cbcf4d5a808..ea185e0b3cae 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -162,7 +162,7 @@ notrace unsigned int __check_irq_replay(void) * in case we also had a rollover while hard disabled */ local_paca->irq_happened &= ~PACA_IRQ_DEC; - if (decrementer_check_overflow()) + if ((happened & PACA_IRQ_DEC) || decrementer_check_overflow()) return 0x900; /* Finally check if an external interrupt happened */ diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index 6053f037ef0a..eabeec991016 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -657,15 +657,6 @@ void pci_resource_to_user(const struct pci_dev *dev, int bar, * ranges. However, some machines (thanks Apple !) tend to split their * space into lots of small contiguous ranges. So we have to coalesce. * - * - We can only cope with all memory ranges having the same offset - * between CPU addresses and PCI addresses. Unfortunately, some bridges - * are setup for a large 1:1 mapping along with a small "window" which - * maps PCI address 0 to some arbitrary high address of the CPU space in - * order to give access to the ISA memory hole. - * The way out of here that I've chosen for now is to always set the - * offset based on the first resource found, then override it if we - * have a different offset and the previous was set by an ISA hole. - * * - Some busses have IO space not starting at 0, which causes trouble with * the way we do our IO resource renumbering. The code somewhat deals with * it for 64 bits but I would expect problems on 32 bits. @@ -680,10 +671,9 @@ void pci_process_bridge_OF_ranges(struct pci_controller *hose, int rlen; int pna = of_n_addr_cells(dev); int np = pna + 5; - int memno = 0, isa_hole = -1; + int memno = 0; u32 pci_space; unsigned long long pci_addr, cpu_addr, pci_next, cpu_next, size; - unsigned long long isa_mb = 0; struct resource *res; printk(KERN_INFO "PCI host bridge %s %s ranges:\n", @@ -777,8 +767,6 @@ void pci_process_bridge_OF_ranges(struct pci_controller *hose, } /* Handles ISA memory hole space here */ if (pci_addr == 0) { - isa_mb = cpu_addr; - isa_hole = memno; if (primary || isa_mem_base == 0) isa_mem_base = cpu_addr; hose->isa_mem_phys = cpu_addr; @@ -839,6 +827,7 @@ static void pcibios_fixup_resources(struct pci_dev *dev) } for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { struct resource *res = dev->resource + i; + struct pci_bus_region reg; if (!res->flags) continue; @@ -847,8 +836,9 @@ static void pcibios_fixup_resources(struct pci_dev *dev) * at 0 as unset as well, except if PCI_PROBE_ONLY is also set * since in that case, we don't want to re-assign anything */ + pcibios_resource_to_bus(dev, ®, res); if (pci_has_flag(PCI_REASSIGN_ALL_RSRC) || - (res->start == 0 && !pci_has_flag(PCI_PROBE_ONLY))) { + (reg.start == 0 && !pci_has_flag(PCI_PROBE_ONLY))) { /* Only print message if not re-assigning */ if (!pci_has_flag(PCI_REASSIGN_ALL_RSRC)) pr_debug("PCI:%s Resource %d %016llx-%016llx [%x] " @@ -1520,9 +1510,10 @@ static void pcibios_setup_phb_resources(struct pci_controller *hose, for (i = 0; i < 3; ++i) { res = &hose->mem_resources[i]; if (!res->flags) { - printk(KERN_ERR "PCI: Memory resource 0 not set for " - "host bridge %s (domain %d)\n", - hose->dn->full_name, hose->global_number); + if (i == 0) + printk(KERN_ERR "PCI: Memory resource 0 not set for " + "host bridge %s (domain %d)\n", + hose->dn->full_name, hose->global_number); continue; } offset = hose->mem_offset[i]; diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index 873050d26840..2e8629654ca8 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c @@ -266,3 +266,13 @@ int pcibus_to_node(struct pci_bus *bus) } EXPORT_SYMBOL(pcibus_to_node); #endif + +static void quirk_radeon_32bit_msi(struct pci_dev *dev) +{ + struct pci_dn *pdn = pci_get_pdn(dev); + + if (pdn) + pdn->force_32bit_msi = 1; +} +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x68f2, quirk_radeon_32bit_msi); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0xaa68, quirk_radeon_32bit_msi); diff --git a/arch/powerpc/kernel/pci_dn.c b/arch/powerpc/kernel/pci_dn.c index e7af165f8b9d..df038442548a 100644 --- a/arch/powerpc/kernel/pci_dn.c +++ b/arch/powerpc/kernel/pci_dn.c @@ -32,6 +32,14 @@ #include <asm/ppc-pci.h> #include <asm/firmware.h> +struct pci_dn *pci_get_pdn(struct pci_dev *pdev) +{ + struct device_node *dn = pci_device_to_OF_node(pdev); + if (!dn) + return NULL; + return PCI_DN(dn); +} + /* * Traverse_func that inits the PCI fields of the device node. * NOTE: this *must* be done before read/write config to the device. diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index a902723fdc69..076d1242507a 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -399,7 +399,8 @@ static inline int __set_dabr(unsigned long dabr, unsigned long dabrx) static inline int __set_dabr(unsigned long dabr, unsigned long dabrx) { mtspr(SPRN_DABR, dabr); - mtspr(SPRN_DABRX, dabrx); + if (cpu_has_feature(CPU_FTR_DABRX)) + mtspr(SPRN_DABRX, dabrx); return 0; } #else @@ -1368,7 +1369,7 @@ void show_stack(struct task_struct *tsk, unsigned long *stack) #ifdef CONFIG_PPC64 /* Called with hard IRQs off */ -void __ppc64_runlatch_on(void) +void notrace __ppc64_runlatch_on(void) { struct thread_info *ti = current_thread_info(); unsigned long ctrl; @@ -1381,7 +1382,7 @@ void __ppc64_runlatch_on(void) } /* Called with hard IRQs off */ -void __ppc64_runlatch_off(void) +void notrace __ppc64_runlatch_off(void) { struct thread_info *ti = current_thread_info(); unsigned long ctrl; diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c index 577a8aa69c6e..457e97aa2945 100644 --- a/arch/powerpc/kernel/signal.c +++ b/arch/powerpc/kernel/signal.c @@ -18,6 +18,7 @@ #include <asm/uaccess.h> #include <asm/unistd.h> #include <asm/debug.h> +#include <asm/tm.h> #include "signal.h" @@ -30,13 +31,13 @@ int show_unhandled_signals = 1; /* * Allocate space for the signal frame */ -void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, +void __user * get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size, int is_32) { unsigned long oldsp, newsp; /* Default to using normal stack */ - oldsp = get_clean_sp(regs, is_32); + oldsp = get_clean_sp(sp, is_32); /* Check for alt stack */ if ((ka->sa.sa_flags & SA_ONSTACK) && @@ -175,3 +176,38 @@ void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags) user_enter(); } + +unsigned long get_tm_stackpointer(struct pt_regs *regs) +{ + /* When in an active transaction that takes a signal, we need to be + * careful with the stack. It's possible that the stack has moved back + * up after the tbegin. The obvious case here is when the tbegin is + * called inside a function that returns before a tend. In this case, + * the stack is part of the checkpointed transactional memory state. + * If we write over this non transactionally or in suspend, we are in + * trouble because if we get a tm abort, the program counter and stack + * pointer will be back at the tbegin but our in memory stack won't be + * valid anymore. + * + * To avoid this, when taking a signal in an active transaction, we + * need to use the stack pointer from the checkpointed state, rather + * than the speculated state. This ensures that the signal context + * (written tm suspended) will be written below the stack required for + * the rollback. The transaction is aborted becuase of the treclaim, + * so any memory written between the tbegin and the signal will be + * rolled back anyway. + * + * For signals taken in non-TM or suspended mode, we use the + * normal/non-checkpointed stack pointer. + */ + +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM + if (MSR_TM_ACTIVE(regs->msr)) { + tm_enable(); + tm_reclaim(¤t->thread, regs->msr, TM_CAUSE_SIGNAL); + if (MSR_TM_TRANSACTIONAL(regs->msr)) + return current->thread.ckpt_regs.gpr[1]; + } +#endif + return regs->gpr[1]; +} diff --git a/arch/powerpc/kernel/signal.h b/arch/powerpc/kernel/signal.h index ec84c901ceab..c69b9aeb9f23 100644 --- a/arch/powerpc/kernel/signal.h +++ b/arch/powerpc/kernel/signal.h @@ -12,7 +12,7 @@ extern void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags); -extern void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, +extern void __user * get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size, int is_32); extern int handle_signal32(unsigned long sig, struct k_sigaction *ka, diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 95068bf569ad..201385c3a1ae 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -503,12 +503,6 @@ static int save_tm_user_regs(struct pt_regs *regs, { unsigned long msr = regs->msr; - /* tm_reclaim rolls back all reg states, updating thread.ckpt_regs, - * thread.transact_fpr[], thread.transact_vr[], etc. - */ - tm_enable(); - tm_reclaim(¤t->thread, msr, TM_CAUSE_SIGNAL); - /* Make sure floating point registers are stored in regs */ flush_fp_to_thread(current); @@ -965,7 +959,7 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka, /* Set up Signal Frame */ /* Put a Real Time Context onto stack */ - rt_sf = get_sigframe(ka, regs, sizeof(*rt_sf), 1); + rt_sf = get_sigframe(ka, get_tm_stackpointer(regs), sizeof(*rt_sf), 1); addr = rt_sf; if (unlikely(rt_sf == NULL)) goto badframe; @@ -1403,7 +1397,7 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka, unsigned long tramp; /* Set up Signal Frame */ - frame = get_sigframe(ka, regs, sizeof(*frame), 1); + frame = get_sigframe(ka, get_tm_stackpointer(regs), sizeof(*frame), 1); if (unlikely(frame == NULL)) goto badframe; sc = (struct sigcontext __user *) &frame->sctx; diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index c1794286098c..345947367ec0 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -154,11 +154,12 @@ static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, * As above, but Transactional Memory is in use, so deliver sigcontexts * containing checkpointed and transactional register states. * - * To do this, we treclaim to gather both sets of registers and set up the - * 'normal' sigcontext registers with rolled-back register values such that a - * simple signal handler sees a correct checkpointed register state. - * If interested, a TM-aware sighandler can examine the transactional registers - * in the 2nd sigcontext to determine the real origin of the signal. + * To do this, we treclaim (done before entering here) to gather both sets of + * registers and set up the 'normal' sigcontext registers with rolled-back + * register values such that a simple signal handler sees a correct + * checkpointed register state. If interested, a TM-aware sighandler can + * examine the transactional registers in the 2nd sigcontext to determine the + * real origin of the signal. */ static long setup_tm_sigcontexts(struct sigcontext __user *sc, struct sigcontext __user *tm_sc, @@ -184,16 +185,6 @@ static long setup_tm_sigcontexts(struct sigcontext __user *sc, BUG_ON(!MSR_TM_ACTIVE(regs->msr)); - /* tm_reclaim rolls back all reg states, saving checkpointed (older) - * GPRs to thread.ckpt_regs and (if used) FPRs to (newer) - * thread.transact_fp and/or VRs to (newer) thread.transact_vr. - * THEN we save out FP/VRs, if necessary, to the checkpointed (older) - * thread.fr[]/vr[]s. The transactional (newer) GPRs are on the - * stack, in *regs. - */ - tm_enable(); - tm_reclaim(¤t->thread, msr, TM_CAUSE_SIGNAL); - flush_fp_to_thread(current); #ifdef CONFIG_ALTIVEC @@ -711,7 +702,7 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info, unsigned long newsp = 0; long err = 0; - frame = get_sigframe(ka, regs, sizeof(*frame), 0); + frame = get_sigframe(ka, get_tm_stackpointer(regs), sizeof(*frame), 0); if (unlikely(frame == NULL)) goto badframe; diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index a7a648f6b750..c0e5caf8ccc7 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -53,6 +53,7 @@ #ifdef CONFIG_PPC64 #include <asm/firmware.h> #include <asm/processor.h> +#include <asm/tm.h> #endif #include <asm/kexec.h> #include <asm/ppc-opcode.h> @@ -932,6 +933,28 @@ static int emulate_isel(struct pt_regs *regs, u32 instword) return 0; } +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM +static inline bool tm_abort_check(struct pt_regs *regs, int cause) +{ + /* If we're emulating a load/store in an active transaction, we cannot + * emulate it as the kernel operates in transaction suspended context. + * We need to abort the transaction. This creates a persistent TM + * abort so tell the user what caused it with a new code. + */ + if (MSR_TM_TRANSACTIONAL(regs->msr)) { + tm_enable(); + tm_abort(cause); + return true; + } + return false; +} +#else +static inline bool tm_abort_check(struct pt_regs *regs, int reason) +{ + return false; +} +#endif + static int emulate_instruction(struct pt_regs *regs) { u32 instword; @@ -971,6 +994,9 @@ static int emulate_instruction(struct pt_regs *regs) /* Emulate load/store string insn. */ if ((instword & PPC_INST_STRING_GEN_MASK) == PPC_INST_STRING) { + if (tm_abort_check(regs, + TM_CAUSE_EMULATE | TM_CAUSE_PERSISTENT)) + return -EINVAL; PPC_WARN_EMULATED(string, regs); return emulate_string_inst(regs, instword); } @@ -1139,6 +1165,16 @@ bail: exception_exit(prev_state); } +/* + * This occurs when running in hypervisor mode on POWER6 or later + * and an illegal instruction is encountered. + */ +void __kprobes emulation_assist_interrupt(struct pt_regs *regs) +{ + regs->msr |= REASON_ILLEGAL; + program_check_exception(regs); +} + void alignment_exception(struct pt_regs *regs) { enum ctx_state prev_state = exception_enter(); @@ -1148,6 +1184,9 @@ void alignment_exception(struct pt_regs *regs) if (!arch_irq_disabled_regs(regs)) local_irq_enable(); + if (tm_abort_check(regs, TM_CAUSE_ALIGNMENT | TM_CAUSE_PERSISTENT)) + goto bail; + /* we don't implement logging of alignment exceptions */ if (!(current->thread.align_ctl & PR_UNALIGN_SIGBUS)) fixed = fix_alignment(regs); diff --git a/arch/powerpc/kvm/44x_tlb.c b/arch/powerpc/kvm/44x_tlb.c index 5dd3ab469976..ed0385448148 100644 --- a/arch/powerpc/kvm/44x_tlb.c +++ b/arch/powerpc/kvm/44x_tlb.c @@ -441,6 +441,7 @@ int kvmppc_44x_emul_tlbwe(struct kvm_vcpu *vcpu, u8 ra, u8 rs, u8 ws) struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu); struct kvmppc_44x_tlbe *tlbe; unsigned int gtlb_index; + int idx; gtlb_index = kvmppc_get_gpr(vcpu, ra); if (gtlb_index >= KVM44x_GUEST_TLB_SIZE) { @@ -473,6 +474,8 @@ int kvmppc_44x_emul_tlbwe(struct kvm_vcpu *vcpu, u8 ra, u8 rs, u8 ws) return EMULATE_FAIL; } + idx = srcu_read_lock(&vcpu->kvm->srcu); + if (tlbe_is_host_safe(vcpu, tlbe)) { gva_t eaddr; gpa_t gpaddr; @@ -489,6 +492,8 @@ int kvmppc_44x_emul_tlbwe(struct kvm_vcpu *vcpu, u8 ra, u8 rs, u8 ws) kvmppc_mmu_map(vcpu, eaddr, gpaddr, gtlb_index); } + srcu_read_unlock(&vcpu->kvm->srcu, idx); + trace_kvm_gtlb_write(gtlb_index, tlbe->tid, tlbe->word0, tlbe->word1, tlbe->word2); diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 9de24f8e03c7..550f5928b394 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -562,6 +562,8 @@ int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu) case H_CPPR: case H_EOI: case H_IPI: + case H_IPOLL: + case H_XIRR_X: if (kvmppc_xics_enabled(vcpu)) { ret = kvmppc_xics_hcall(vcpu, req); break; diff --git a/arch/powerpc/kvm/book3s_pr_papr.c b/arch/powerpc/kvm/book3s_pr_papr.c index b24309c6c2d5..da0e0bc268bd 100644 --- a/arch/powerpc/kvm/book3s_pr_papr.c +++ b/arch/powerpc/kvm/book3s_pr_papr.c @@ -257,6 +257,8 @@ int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd) case H_CPPR: case H_EOI: case H_IPI: + case H_IPOLL: + case H_XIRR_X: if (kvmppc_xics_enabled(vcpu)) return kvmppc_h_pr_xics_hcall(vcpu, cmd); break; diff --git a/arch/powerpc/kvm/book3s_xics.c b/arch/powerpc/kvm/book3s_xics.c index f7a103756618..94c1dd46b83d 100644 --- a/arch/powerpc/kvm/book3s_xics.c +++ b/arch/powerpc/kvm/book3s_xics.c @@ -650,6 +650,23 @@ static noinline int kvmppc_h_ipi(struct kvm_vcpu *vcpu, unsigned long server, return H_SUCCESS; } +static int kvmppc_h_ipoll(struct kvm_vcpu *vcpu, unsigned long server) +{ + union kvmppc_icp_state state; + struct kvmppc_icp *icp; + + icp = vcpu->arch.icp; + if (icp->server_num != server) { + icp = kvmppc_xics_find_server(vcpu->kvm, server); + if (!icp) + return H_PARAMETER; + } + state = ACCESS_ONCE(icp->state); + kvmppc_set_gpr(vcpu, 4, ((u32)state.cppr << 24) | state.xisr); + kvmppc_set_gpr(vcpu, 5, state.mfrr); + return H_SUCCESS; +} + static noinline void kvmppc_h_cppr(struct kvm_vcpu *vcpu, unsigned long cppr) { union kvmppc_icp_state old_state, new_state; @@ -787,6 +804,18 @@ int kvmppc_xics_hcall(struct kvm_vcpu *vcpu, u32 req) if (!xics || !vcpu->arch.icp) return H_HARDWARE; + /* These requests don't have real-mode implementations at present */ + switch (req) { + case H_XIRR_X: + res = kvmppc_h_xirr(vcpu); + kvmppc_set_gpr(vcpu, 4, res); + kvmppc_set_gpr(vcpu, 5, get_tb()); + return rc; + case H_IPOLL: + rc = kvmppc_h_ipoll(vcpu, kvmppc_get_gpr(vcpu, 4)); + return rc; + } + /* Check for real mode returning too hard */ if (xics->real_mode) return kvmppc_xics_rm_complete(vcpu, req); diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index 1020119226db..1a1b51189773 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c @@ -673,7 +673,6 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) ret = s; goto out; } - kvmppc_lazy_ee_enable(); kvm_guest_enter(); @@ -699,6 +698,8 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) kvmppc_load_guest_fp(vcpu); #endif + kvmppc_lazy_ee_enable(); + ret = __kvmppc_vcpu_run(kvm_run, vcpu); /* No need for kvm_guest_exit. It's done in handle_exit. @@ -832,6 +833,18 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, { int r = RESUME_HOST; int s; + int idx; + +#ifdef CONFIG_PPC64 + WARN_ON(local_paca->irq_happened != 0); +#endif + + /* + * We enter with interrupts disabled in hardware, but + * we need to call hard_irq_disable anyway to ensure that + * the software state is kept in sync. + */ + hard_irq_disable(); /* update before a new last_exit_type is rewritten */ kvmppc_update_timing_stats(vcpu); @@ -1053,6 +1066,8 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, break; } + idx = srcu_read_lock(&vcpu->kvm->srcu); + gpaddr = kvmppc_mmu_xlate(vcpu, gtlb_index, eaddr); gfn = gpaddr >> PAGE_SHIFT; @@ -1075,6 +1090,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, kvmppc_account_exit(vcpu, MMIO_EXITS); } + srcu_read_unlock(&vcpu->kvm->srcu, idx); break; } @@ -1098,6 +1114,8 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, kvmppc_account_exit(vcpu, ITLB_VIRT_MISS_EXITS); + idx = srcu_read_lock(&vcpu->kvm->srcu); + gpaddr = kvmppc_mmu_xlate(vcpu, gtlb_index, eaddr); gfn = gpaddr >> PAGE_SHIFT; @@ -1114,6 +1132,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_MACHINE_CHECK); } + srcu_read_unlock(&vcpu->kvm->srcu, idx); break; } diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c index c41a5a96b558..6d6f153b6c1d 100644 --- a/arch/powerpc/kvm/e500_mmu.c +++ b/arch/powerpc/kvm/e500_mmu.c @@ -396,6 +396,7 @@ int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *vcpu) struct kvm_book3e_206_tlb_entry *gtlbe; int tlbsel, esel; int recal = 0; + int idx; tlbsel = get_tlb_tlbsel(vcpu); esel = get_tlb_esel(vcpu, tlbsel); @@ -430,6 +431,8 @@ int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *vcpu) kvmppc_set_tlb1map_range(vcpu, gtlbe); } + idx = srcu_read_lock(&vcpu->kvm->srcu); + /* Invalidate shadow mappings for the about-to-be-clobbered TLBE. */ if (tlbe_is_host_safe(vcpu, gtlbe)) { u64 eaddr = get_tlb_eaddr(gtlbe); @@ -444,6 +447,8 @@ int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *vcpu) kvmppc_mmu_map(vcpu, eaddr, raddr, index_of(tlbsel, esel)); } + srcu_read_unlock(&vcpu->kvm->srcu, idx); + kvmppc_set_exit_type(vcpu, EMULATED_TLBWE_EXITS); return EMULATE_DONE; } diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c index 753cc99eff2b..19c8379575f7 100644 --- a/arch/powerpc/kvm/e500mc.c +++ b/arch/powerpc/kvm/e500mc.c @@ -177,8 +177,6 @@ int kvmppc_core_check_processor_compat(void) r = 0; else if (strcmp(cur_cpu_spec->cpu_name, "e5500") == 0) r = 0; - else if (strcmp(cur_cpu_spec->cpu_name, "e6500") == 0) - r = 0; else r = -ENOTSUPP; diff --git a/arch/powerpc/lib/copypage_power7.S b/arch/powerpc/lib/copypage_power7.S index 0ef75bf0695c..395c594722a2 100644 --- a/arch/powerpc/lib/copypage_power7.S +++ b/arch/powerpc/lib/copypage_power7.S @@ -28,13 +28,14 @@ _GLOBAL(copypage_power7) * aligned we don't need to clear the bottom 7 bits of either * address. */ - ori r9,r3,1 /* stream=1 */ + ori r9,r3,1 /* stream=1 => to */ #ifdef CONFIG_PPC_64K_PAGES - lis r7,0x0E01 /* depth=7, units=512 */ + lis r7,0x0E01 /* depth=7 + * units/cachelines=512 */ #else lis r7,0x0E00 /* depth=7 */ - ori r7,r7,0x1000 /* units=32 */ + ori r7,r7,0x1000 /* units/cachelines=32 */ #endif ori r10,r7,1 /* stream=1 */ @@ -43,12 +44,14 @@ _GLOBAL(copypage_power7) .machine push .machine "power4" - dcbt r0,r4,0b01000 - dcbt r0,r7,0b01010 - dcbtst r0,r9,0b01000 - dcbtst r0,r10,0b01010 + /* setup read stream 0 */ + dcbt r0,r4,0b01000 /* addr from */ + dcbt r0,r7,0b01010 /* length and depth from */ + /* setup write stream 1 */ + dcbtst r0,r9,0b01000 /* addr to */ + dcbtst r0,r10,0b01010 /* length and depth to */ eieio - dcbt r0,r8,0b01010 /* GO */ + dcbt r0,r8,0b01010 /* all streams GO */ .machine pop #ifdef CONFIG_ALTIVEC diff --git a/arch/powerpc/lib/copyuser_power7.S b/arch/powerpc/lib/copyuser_power7.S index 0d24ff15f5f6..d1f11795a7ad 100644 --- a/arch/powerpc/lib/copyuser_power7.S +++ b/arch/powerpc/lib/copyuser_power7.S @@ -318,12 +318,14 @@ err1; stb r0,0(r3) .machine push .machine "power4" - dcbt r0,r6,0b01000 - dcbt r0,r7,0b01010 - dcbtst r0,r9,0b01000 - dcbtst r0,r10,0b01010 + /* setup read stream 0 */ + dcbt r0,r6,0b01000 /* addr from */ + dcbt r0,r7,0b01010 /* length and depth from */ + /* setup write stream 1 */ + dcbtst r0,r9,0b01000 /* addr to */ + dcbtst r0,r10,0b01010 /* length and depth to */ eieio - dcbt r0,r8,0b01010 /* GO */ + dcbt r0,r8,0b01010 /* all streams GO */ .machine pop beq cr1,.Lunwind_stack_nonvmx_copy diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c index 6a2aead5b0e5..4c122c3f1623 100644 --- a/arch/powerpc/mm/hash_native_64.c +++ b/arch/powerpc/mm/hash_native_64.c @@ -336,11 +336,18 @@ static long native_hpte_updatepp(unsigned long slot, unsigned long newpp, hpte_v = hptep->v; actual_psize = hpte_actual_psize(hptep, psize); + /* + * We need to invalidate the TLB always because hpte_remove doesn't do + * a tlb invalidate. If a hash bucket gets full, we "evict" a more/less + * random entry from it. When we do that we don't invalidate the TLB + * (hpte_remove) because we assume the old translation is still + * technically "valid". + */ if (actual_psize < 0) { - native_unlock_hpte(hptep); - return -1; + actual_psize = psize; + ret = -1; + goto err_out; } - /* Even if we miss, we need to invalidate the TLB */ if (!HPTE_V_COMPARE(hpte_v, want_v)) { DBG_LOW(" -> miss\n"); ret = -1; @@ -350,6 +357,7 @@ static long native_hpte_updatepp(unsigned long slot, unsigned long newpp, hptep->r = (hptep->r & ~(HPTE_R_PP | HPTE_R_N)) | (newpp & (HPTE_R_PP | HPTE_R_N | HPTE_R_C)); } +err_out: native_unlock_hpte(hptep); /* Ensure it is out of the tlb too. */ @@ -409,7 +417,7 @@ static void native_hpte_updateboltedpp(unsigned long newpp, unsigned long ea, hptep = htab_address + slot; actual_psize = hpte_actual_psize(hptep, psize); if (actual_psize < 0) - return; + actual_psize = psize; /* Update the HPTE */ hptep->r = (hptep->r & ~(HPTE_R_PP | HPTE_R_N)) | @@ -437,21 +445,27 @@ static void native_hpte_invalidate(unsigned long slot, unsigned long vpn, hpte_v = hptep->v; actual_psize = hpte_actual_psize(hptep, psize); + /* + * We need to invalidate the TLB always because hpte_remove doesn't do + * a tlb invalidate. If a hash bucket gets full, we "evict" a more/less + * random entry from it. When we do that we don't invalidate the TLB + * (hpte_remove) because we assume the old translation is still + * technically "valid". + */ if (actual_psize < 0) { + actual_psize = psize; native_unlock_hpte(hptep); - local_irq_restore(flags); - return; + goto err_out; } - /* Even if we miss, we need to invalidate the TLB */ if (!HPTE_V_COMPARE(hpte_v, want_v)) native_unlock_hpte(hptep); else /* Invalidate the hpte. NOTE: this also unlocks it */ hptep->v = 0; +err_out: /* Invalidate the TLB */ tlbie(vpn, psize, actual_psize, ssize, local); - local_irq_restore(flags); } diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index 237c8e5f2640..77fdd2cef33b 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -592,8 +592,14 @@ static void hugetlb_free_pmd_range(struct mmu_gather *tlb, pud_t *pud, do { pmd = pmd_offset(pud, addr); next = pmd_addr_end(addr, end); - if (pmd_none_or_clear_bad(pmd)) + if (!is_hugepd(pmd)) { + /* + * if it is not hugepd pointer, we should already find + * it cleared. + */ + WARN_ON(!pmd_none_or_clear_bad(pmd)); continue; + } #ifdef CONFIG_PPC_FSL_BOOK3E /* * Increment next by the size of the huge mapping since diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c index 426180b84978..29c6482890c8 100644 --- a/arch/powerpc/perf/core-book3s.c +++ b/arch/powerpc/perf/core-book3s.c @@ -110,7 +110,7 @@ static inline void power_pmu_bhrb_read(struct cpu_hw_events *cpuhw) {} static bool regs_use_siar(struct pt_regs *regs) { - return !!(regs->result & 1); + return !!regs->result; } /* @@ -136,22 +136,30 @@ static inline unsigned long perf_ip_adjust(struct pt_regs *regs) * If we're not doing instruction sampling, give them the SDAR * (sampled data address). If we are doing instruction sampling, then * only give them the SDAR if it corresponds to the instruction - * pointed to by SIAR; this is indicated by the [POWER6_]MMCRA_SDSYNC or - * the [POWER7P_]MMCRA_SDAR_VALID bit in MMCRA. + * pointed to by SIAR; this is indicated by the [POWER6_]MMCRA_SDSYNC, the + * [POWER7P_]MMCRA_SDAR_VALID bit in MMCRA, or the SDAR_VALID bit in SIER. */ static inline void perf_get_data_addr(struct pt_regs *regs, u64 *addrp) { unsigned long mmcra = regs->dsisr; - unsigned long sdsync; + bool sdar_valid; - if (ppmu->flags & PPMU_SIAR_VALID) - sdsync = POWER7P_MMCRA_SDAR_VALID; - else if (ppmu->flags & PPMU_ALT_SIPR) - sdsync = POWER6_MMCRA_SDSYNC; - else - sdsync = MMCRA_SDSYNC; + if (ppmu->flags & PPMU_HAS_SIER) + sdar_valid = regs->dar & SIER_SDAR_VALID; + else { + unsigned long sdsync; + + if (ppmu->flags & PPMU_SIAR_VALID) + sdsync = POWER7P_MMCRA_SDAR_VALID; + else if (ppmu->flags & PPMU_ALT_SIPR) + sdsync = POWER6_MMCRA_SDSYNC; + else + sdsync = MMCRA_SDSYNC; + + sdar_valid = mmcra & sdsync; + } - if (!(mmcra & MMCRA_SAMPLE_ENABLE) || (mmcra & sdsync)) + if (!(mmcra & MMCRA_SAMPLE_ENABLE) || sdar_valid) *addrp = mfspr(SPRN_SDAR); } @@ -181,11 +189,6 @@ static bool regs_sipr(struct pt_regs *regs) return !!(regs->dsisr & sipr); } -static bool regs_no_sipr(struct pt_regs *regs) -{ - return !!(regs->result & 2); -} - static inline u32 perf_flags_from_msr(struct pt_regs *regs) { if (regs->msr & MSR_PR) @@ -208,7 +211,7 @@ static inline u32 perf_get_misc_flags(struct pt_regs *regs) * SIAR which should give slightly more reliable * results */ - if (regs_no_sipr(regs)) { + if (ppmu->flags & PPMU_NO_SIPR) { unsigned long siar = mfspr(SPRN_SIAR); if (siar >= PAGE_OFFSET) return PERF_RECORD_MISC_KERNEL; @@ -239,22 +242,9 @@ static inline void perf_read_regs(struct pt_regs *regs) int use_siar; regs->dsisr = mmcra; - regs->result = 0; - - if (ppmu->flags & PPMU_NO_SIPR) - regs->result |= 2; - - /* - * On power8 if we're in random sampling mode, the SIER is updated. - * If we're in continuous sampling mode, we don't have SIPR. - */ - if (ppmu->flags & PPMU_HAS_SIER) { - if (marked) - regs->dar = mfspr(SPRN_SIER); - else - regs->result |= 2; - } + if (ppmu->flags & PPMU_HAS_SIER) + regs->dar = mfspr(SPRN_SIER); /* * If this isn't a PMU exception (eg a software event) the SIAR is @@ -279,12 +269,12 @@ static inline void perf_read_regs(struct pt_regs *regs) use_siar = 1; else if ((ppmu->flags & PPMU_NO_CONT_SAMPLING)) use_siar = 0; - else if (!regs_no_sipr(regs) && regs_sipr(regs)) + else if (!(ppmu->flags & PPMU_NO_SIPR) && regs_sipr(regs)) use_siar = 0; else use_siar = 1; - regs->result |= use_siar; + regs->result = use_siar; } /* @@ -308,8 +298,13 @@ static inline int siar_valid(struct pt_regs *regs) unsigned long mmcra = regs->dsisr; int marked = mmcra & MMCRA_SAMPLE_ENABLE; - if ((ppmu->flags & PPMU_SIAR_VALID) && marked) - return mmcra & POWER7P_MMCRA_SIAR_VALID; + if (marked) { + if (ppmu->flags & PPMU_HAS_SIER) + return regs->dar & SIER_SIAR_VALID; + + if (ppmu->flags & PPMU_SIAR_VALID) + return mmcra & POWER7P_MMCRA_SIAR_VALID; + } return 1; } @@ -1763,7 +1758,7 @@ static void perf_event_interrupt(struct pt_regs *regs) } } } - if ((!found) && printk_ratelimit()) + if (!found && !nmi && printk_ratelimit()) printk(KERN_WARNING "Can't find PMC that caused IRQ\n"); /* diff --git a/arch/powerpc/platforms/powernv/Kconfig b/arch/powerpc/platforms/powernv/Kconfig index d3e840d643af..c24684c818ab 100644 --- a/arch/powerpc/platforms/powernv/Kconfig +++ b/arch/powerpc/platforms/powernv/Kconfig @@ -6,6 +6,7 @@ config PPC_POWERNV select PPC_ICP_NATIVE select PPC_P7_NAP select PPC_PCI_CHOICE if EMBEDDED + select EPAPR_BOOT default y config POWERNV_MSI diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 3937aaae5bc4..9c9d15e4cdf2 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -68,16 +68,6 @@ define_pe_printk_level(pe_err, KERN_ERR); define_pe_printk_level(pe_warn, KERN_WARNING); define_pe_printk_level(pe_info, KERN_INFO); -static struct pci_dn *pnv_ioda_get_pdn(struct pci_dev *dev) -{ - struct device_node *np; - - np = pci_device_to_OF_node(dev); - if (!np) - return NULL; - return PCI_DN(np); -} - static int pnv_ioda_alloc_pe(struct pnv_phb *phb) { unsigned long pe; @@ -110,7 +100,7 @@ static struct pnv_ioda_pe *pnv_ioda_get_pe(struct pci_dev *dev) { struct pci_controller *hose = pci_bus_to_host(dev->bus); struct pnv_phb *phb = hose->private_data; - struct pci_dn *pdn = pnv_ioda_get_pdn(dev); + struct pci_dn *pdn = pci_get_pdn(dev); if (!pdn) return NULL; @@ -173,7 +163,7 @@ static int pnv_ioda_configure_pe(struct pnv_phb *phb, struct pnv_ioda_pe *pe) /* Add to all parents PELT-V */ while (parent) { - struct pci_dn *pdn = pnv_ioda_get_pdn(parent); + struct pci_dn *pdn = pci_get_pdn(parent); if (pdn && pdn->pe_number != IODA_INVALID_PE) { rc = opal_pci_set_peltv(phb->opal_id, pdn->pe_number, pe->pe_number, OPAL_ADD_PE_TO_DOMAIN); @@ -252,7 +242,7 @@ static struct pnv_ioda_pe *pnv_ioda_setup_dev_PE(struct pci_dev *dev) { struct pci_controller *hose = pci_bus_to_host(dev->bus); struct pnv_phb *phb = hose->private_data; - struct pci_dn *pdn = pnv_ioda_get_pdn(dev); + struct pci_dn *pdn = pci_get_pdn(dev); struct pnv_ioda_pe *pe; int pe_num; @@ -323,7 +313,7 @@ static void pnv_ioda_setup_same_PE(struct pci_bus *bus, struct pnv_ioda_pe *pe) struct pci_dev *dev; list_for_each_entry(dev, &bus->devices, bus_list) { - struct pci_dn *pdn = pnv_ioda_get_pdn(dev); + struct pci_dn *pdn = pci_get_pdn(dev); if (pdn == NULL) { pr_warn("%s: No device node associated with device !\n", @@ -436,7 +426,7 @@ static void pnv_pci_ioda_setup_PEs(void) static void pnv_pci_ioda_dma_dev_setup(struct pnv_phb *phb, struct pci_dev *pdev) { - struct pci_dn *pdn = pnv_ioda_get_pdn(pdev); + struct pci_dn *pdn = pci_get_pdn(pdev); struct pnv_ioda_pe *pe; /* @@ -768,6 +758,7 @@ static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, unsigned int is_64, struct msi_msg *msg) { struct pnv_ioda_pe *pe = pnv_ioda_get_pe(dev); + struct pci_dn *pdn = pci_get_pdn(dev); struct irq_data *idata; struct irq_chip *ichip; unsigned int xive_num = hwirq - phb->msi_base; @@ -783,6 +774,10 @@ static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, if (pe->mve_number < 0) return -ENXIO; + /* Force 32-bit MSI on some broken devices */ + if (pdn && pdn->force_32bit_msi) + is_64 = 0; + /* Assign XIVE to PE */ rc = opal_pci_set_xive_pe(phb->opal_id, pe->pe_number, xive_num); if (rc) { @@ -1035,7 +1030,7 @@ static int pnv_pci_enable_device_hook(struct pci_dev *dev) if (!phb->initialized) return 0; - pdn = pnv_ioda_get_pdn(dev); + pdn = pci_get_pdn(dev); if (!pdn || pdn->pe_number == IODA_INVALID_PE) return -EINVAL; diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index 163bd7422f1c..277343cc6a3d 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c @@ -47,6 +47,10 @@ static int pnv_msi_check_device(struct pci_dev* pdev, int nvec, int type) { struct pci_controller *hose = pci_bus_to_host(pdev->bus); struct pnv_phb *phb = hose->private_data; + struct pci_dn *pdn = pci_get_pdn(pdev); + + if (pdn && pdn->force_32bit_msi && !phb->msi32_support) + return -ENODEV; return (phb && phb->msi_bmp.bitmap) ? 0 : -ENODEV; } @@ -367,7 +371,7 @@ static void pnv_tce_free(struct iommu_table *tbl, long index, long npages) while (npages--) *(tcep++) = 0; - if (tbl->it_type & TCE_PCI_SWINV_CREATE) + if (tbl->it_type & TCE_PCI_SWINV_FREE) pnv_pci_ioda_tce_invalidate(tbl, tces, tcep - 1); } diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig index 023b288f895b..4459eff7a75a 100644 --- a/arch/powerpc/platforms/pseries/Kconfig +++ b/arch/powerpc/platforms/pseries/Kconfig @@ -19,6 +19,8 @@ config PPC_PSERIES select ZLIB_DEFLATE select PPC_DOORBELL select HAVE_CONTEXT_TRACKING + select HOTPLUG if SMP + select HOTPLUG_CPU if SMP default y config PPC_SPLPAR diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c index 19506f935737..b456b157d33d 100644 --- a/arch/powerpc/platforms/pseries/eeh_pseries.c +++ b/arch/powerpc/platforms/pseries/eeh_pseries.c @@ -83,7 +83,11 @@ static int pseries_eeh_init(void) ibm_configure_pe = rtas_token("ibm,configure-pe"); ibm_configure_bridge = rtas_token("ibm,configure-bridge"); - /* necessary sanity check */ + /* + * Necessary sanity check. We needn't check "get-config-addr-info" + * and its variant since the old firmware probably support address + * of domain/bus/slot/function for EEH RTAS operations. + */ if (ibm_set_eeh_option == RTAS_UNKNOWN_SERVICE) { pr_warning("%s: RTAS service <ibm,set-eeh-option> invalid\n", __func__); @@ -102,12 +106,6 @@ static int pseries_eeh_init(void) pr_warning("%s: RTAS service <ibm,slot-error-detail> invalid\n", __func__); return -EINVAL; - } else if (ibm_get_config_addr_info2 == RTAS_UNKNOWN_SERVICE && - ibm_get_config_addr_info == RTAS_UNKNOWN_SERVICE) { - pr_warning("%s: RTAS service <ibm,get-config-addr-info2> and " - "<ibm,get-config-addr-info> invalid\n", - __func__); - return -EINVAL; } else if (ibm_configure_pe == RTAS_UNKNOWN_SERVICE && ibm_configure_bridge == RTAS_UNKNOWN_SERVICE) { pr_warning("%s: RTAS service <ibm,configure-pe> and " diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c index 420524e6f8c9..6d2f0abce6fa 100644 --- a/arch/powerpc/platforms/pseries/msi.c +++ b/arch/powerpc/platforms/pseries/msi.c @@ -26,26 +26,6 @@ static int query_token, change_token; #define RTAS_CHANGE_MSIX_FN 4 #define RTAS_CHANGE_32MSI_FN 5 -static struct pci_dn *get_pdn(struct pci_dev *pdev) -{ - struct device_node *dn; - struct pci_dn *pdn; - - dn = pci_device_to_OF_node(pdev); - if (!dn) { - dev_dbg(&pdev->dev, "rtas_msi: No OF device node\n"); - return NULL; - } - - pdn = PCI_DN(dn); - if (!pdn) { - dev_dbg(&pdev->dev, "rtas_msi: No PCI DN\n"); - return NULL; - } - - return pdn; -} - /* RTAS Helpers */ static int rtas_change_msi(struct pci_dn *pdn, u32 func, u32 num_irqs) @@ -91,7 +71,7 @@ static void rtas_disable_msi(struct pci_dev *pdev) { struct pci_dn *pdn; - pdn = get_pdn(pdev); + pdn = pci_get_pdn(pdev); if (!pdn) return; @@ -152,7 +132,7 @@ static int check_req(struct pci_dev *pdev, int nvec, char *prop_name) struct pci_dn *pdn; const u32 *req_msi; - pdn = get_pdn(pdev); + pdn = pci_get_pdn(pdev); if (!pdn) return -ENODEV; @@ -394,6 +374,23 @@ static int check_msix_entries(struct pci_dev *pdev) return 0; } +static void rtas_hack_32bit_msi_gen2(struct pci_dev *pdev) +{ + u32 addr_hi, addr_lo; + + /* + * We should only get in here for IODA1 configs. This is based on the + * fact that we using RTAS for MSIs, we don't have the 32 bit MSI RTAS + * support, and we are in a PCIe Gen2 slot. + */ + dev_info(&pdev->dev, + "rtas_msi: No 32 bit MSI firmware support, forcing 32 bit MSI\n"); + pci_read_config_dword(pdev, pdev->msi_cap + PCI_MSI_ADDRESS_HI, &addr_hi); + addr_lo = 0xffff0000 | ((addr_hi >> (48 - 32)) << 4); + pci_write_config_dword(pdev, pdev->msi_cap + PCI_MSI_ADDRESS_LO, addr_lo); + pci_write_config_dword(pdev, pdev->msi_cap + PCI_MSI_ADDRESS_HI, 0); +} + static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec_in, int type) { struct pci_dn *pdn; @@ -401,8 +398,9 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec_in, int type) struct msi_desc *entry; struct msi_msg msg; int nvec = nvec_in; + int use_32bit_msi_hack = 0; - pdn = get_pdn(pdev); + pdn = pci_get_pdn(pdev); if (!pdn) return -ENODEV; @@ -428,15 +426,31 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec_in, int type) */ again: if (type == PCI_CAP_ID_MSI) { - if (pdn->force_32bit_msi) + if (pdn->force_32bit_msi) { rc = rtas_change_msi(pdn, RTAS_CHANGE_32MSI_FN, nvec); - else + if (rc < 0) { + /* + * We only want to run the 32 bit MSI hack below if + * the max bus speed is Gen2 speed + */ + if (pdev->bus->max_bus_speed != PCIE_SPEED_5_0GT) + return rc; + + use_32bit_msi_hack = 1; + } + } else + rc = -1; + + if (rc < 0) rc = rtas_change_msi(pdn, RTAS_CHANGE_MSI_FN, nvec); - if (rc < 0 && !pdn->force_32bit_msi) { + if (rc < 0) { pr_debug("rtas_msi: trying the old firmware call.\n"); rc = rtas_change_msi(pdn, RTAS_CHANGE_FN, nvec); } + + if (use_32bit_msi_hack && rc > 0) + rtas_hack_32bit_msi_gen2(pdev); } else rc = rtas_change_msi(pdn, RTAS_CHANGE_MSIX_FN, nvec); @@ -518,12 +532,3 @@ static int rtas_msi_init(void) } arch_initcall(rtas_msi_init); -static void quirk_radeon(struct pci_dev *dev) -{ - struct pci_dn *pdn = get_pdn(dev); - - if (pdn) - pdn->force_32bit_msi = 1; -} -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x68f2, quirk_radeon); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0xaa68, quirk_radeon); diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 0a13ecb270c7..3cc2f9159ab1 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -54,7 +54,7 @@ static DEFINE_RAW_SPINLOCK(mpic_lock); #ifdef CONFIG_PPC32 /* XXX for now */ #ifdef CONFIG_IRQ_ALL_CPUS -#define distribute_irqs (!(mpic->flags & MPIC_SINGLE_DEST_CPU)) +#define distribute_irqs (1) #else #define distribute_irqs (0) #endif @@ -1703,7 +1703,7 @@ void mpic_setup_this_cpu(void) * it differently, then we should make sure we also change the default * values of irq_desc[].affinity in irq.c. */ - if (distribute_irqs) { + if (distribute_irqs && !(mpic->flags & MPIC_SINGLE_DEST_CPU)) { for (i = 0; i < mpic->num_sources ; i++) mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION), mpic_irq_read(i, MPIC_INFO(IRQ_DESTINATION)) | msk); diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c index bae0f402bf2a..87a22092b68f 100644 --- a/arch/s390/appldata/appldata_base.c +++ b/arch/s390/appldata/appldata_base.c @@ -212,7 +212,9 @@ appldata_timer_handler(ctl_table *ctl, int write, return 0; } if (!write) { - len = sprintf(buf, appldata_timer_active ? "1\n" : "0\n"); + strncpy(buf, appldata_timer_active ? "1\n" : "0\n", + ARRAY_SIZE(buf)); + len = strnlen(buf, ARRAY_SIZE(buf)); if (len > *lenp) len = *lenp; if (copy_to_user(buffer, buf, len)) @@ -317,7 +319,8 @@ appldata_generic_handler(ctl_table *ctl, int write, return 0; } if (!write) { - len = sprintf(buf, ops->active ? "1\n" : "0\n"); + strncpy(buf, ops->active ? "1\n" : "0\n", ARRAY_SIZE(buf)); + len = strnlen(buf, ARRAY_SIZE(buf)); if (len > *lenp) len = *lenp; if (copy_to_user(buffer, buf, len)) { diff --git a/arch/s390/include/asm/dma-mapping.h b/arch/s390/include/asm/dma-mapping.h index 9411db653bac..886ac7d4937a 100644 --- a/arch/s390/include/asm/dma-mapping.h +++ b/arch/s390/include/asm/dma-mapping.h @@ -71,8 +71,8 @@ static inline void dma_free_coherent(struct device *dev, size_t size, { struct dma_map_ops *dma_ops = get_dma_ops(dev); - dma_ops->free(dev, size, cpu_addr, dma_handle, NULL); debug_dma_free_coherent(dev, size, cpu_addr, dma_handle); + dma_ops->free(dev, size, cpu_addr, dma_handle, NULL); } #endif /* _ASM_S390_DMA_MAPPING_H */ diff --git a/arch/s390/include/asm/io.h b/arch/s390/include/asm/io.h index 379d96e2105e..fd9be010f9b2 100644 --- a/arch/s390/include/asm/io.h +++ b/arch/s390/include/asm/io.h @@ -36,6 +36,7 @@ static inline void * phys_to_virt(unsigned long address) } void *xlate_dev_mem_ptr(unsigned long phys); +#define xlate_dev_mem_ptr xlate_dev_mem_ptr void unxlate_dev_mem_ptr(unsigned long phys, void *addr); /* diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index 0f0de30e3e3f..e8b6e5b8932c 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h @@ -623,7 +623,7 @@ static inline pgste_t pgste_get_lock(pte_t *ptep) " csg %0,%1,%2\n" " jl 0b\n" : "=&d" (old), "=&d" (new), "=Q" (ptep[PTRS_PER_PTE]) - : "Q" (ptep[PTRS_PER_PTE]) : "cc"); + : "Q" (ptep[PTRS_PER_PTE]) : "cc", "memory"); #endif return __pgste(new); } @@ -635,18 +635,26 @@ static inline void pgste_set_unlock(pte_t *ptep, pgste_t pgste) " nihh %1,0xff7f\n" /* clear RCP_PCL_BIT */ " stg %1,%0\n" : "=Q" (ptep[PTRS_PER_PTE]) - : "d" (pgste_val(pgste)), "Q" (ptep[PTRS_PER_PTE]) : "cc"); + : "d" (pgste_val(pgste)), "Q" (ptep[PTRS_PER_PTE]) + : "cc", "memory"); preempt_enable(); #endif } +static inline void pgste_set(pte_t *ptep, pgste_t pgste) +{ +#ifdef CONFIG_PGSTE + *(pgste_t *)(ptep + PTRS_PER_PTE) = pgste; +#endif +} + static inline pgste_t pgste_update_all(pte_t *ptep, pgste_t pgste) { #ifdef CONFIG_PGSTE unsigned long address, bits; unsigned char skey; - if (!pte_present(*ptep)) + if (pte_val(*ptep) & _PAGE_INVALID) return pgste; address = pte_val(*ptep) & PAGE_MASK; skey = page_get_storage_key(address); @@ -680,7 +688,7 @@ static inline pgste_t pgste_update_young(pte_t *ptep, pgste_t pgste) #ifdef CONFIG_PGSTE int young; - if (!pte_present(*ptep)) + if (pte_val(*ptep) & _PAGE_INVALID) return pgste; /* Get referenced bit from storage key */ young = page_reset_referenced(pte_val(*ptep) & PAGE_MASK); @@ -704,17 +712,19 @@ static inline void pgste_set_key(pte_t *ptep, pgste_t pgste, pte_t entry) { #ifdef CONFIG_PGSTE unsigned long address; - unsigned long okey, nkey; + unsigned long nkey; - if (!pte_present(entry)) + if (pte_val(entry) & _PAGE_INVALID) return; + VM_BUG_ON(!(pte_val(*ptep) & _PAGE_INVALID)); address = pte_val(entry) & PAGE_MASK; - okey = nkey = page_get_storage_key(address); - nkey &= ~(_PAGE_ACC_BITS | _PAGE_FP_BIT); - /* Set page access key and fetch protection bit from pgste */ - nkey |= (pgste_val(pgste) & (RCP_ACC_BITS | RCP_FP_BIT)) >> 56; - if (okey != nkey) - page_set_storage_key(address, nkey, 0); + /* + * Set page access key and fetch protection bit from pgste. + * The guest C/R information is still in the PGSTE, set real + * key C/R to 0. + */ + nkey = (pgste_val(pgste) & (RCP_ACC_BITS | RCP_FP_BIT)) >> 56; + page_set_storage_key(address, nkey, 0); #endif } @@ -1098,6 +1108,11 @@ static inline pte_t ptep_modify_prot_start(struct mm_struct *mm, pte = *ptep; if (!mm_exclusive(mm)) __ptep_ipte(address, ptep); + + if (mm_has_pgste(mm)) { + pgste = pgste_update_all(&pte, pgste); + pgste_set(ptep, pgste); + } return pte; } @@ -1105,9 +1120,13 @@ static inline void ptep_modify_prot_commit(struct mm_struct *mm, unsigned long address, pte_t *ptep, pte_t pte) { + pgste_t pgste; + if (mm_has_pgste(mm)) { + pgste = *(pgste_t *)(ptep + PTRS_PER_PTE); + pgste_set_key(ptep, pgste, pte); pgste_set_pte(ptep, pte); - pgste_set_unlock(ptep, *(pgste_t *)(ptep + PTRS_PER_PTE)); + pgste_set_unlock(ptep, pgste); } else *ptep = pte; } diff --git a/arch/s390/kernel/dumpstack.c b/arch/s390/kernel/dumpstack.c index 298297477257..87acc38f73c6 100644 --- a/arch/s390/kernel/dumpstack.c +++ b/arch/s390/kernel/dumpstack.c @@ -74,6 +74,8 @@ __show_trace(unsigned long sp, unsigned long low, unsigned long high) static void show_trace(struct task_struct *task, unsigned long *stack) { + const unsigned long frame_size = + STACK_FRAME_OVERHEAD + sizeof(struct pt_regs); register unsigned long __r15 asm ("15"); unsigned long sp; @@ -82,11 +84,13 @@ static void show_trace(struct task_struct *task, unsigned long *stack) sp = task ? task->thread.ksp : __r15; printk("Call Trace:\n"); #ifdef CONFIG_CHECK_STACK - sp = __show_trace(sp, S390_lowcore.panic_stack - 4096, - S390_lowcore.panic_stack); + sp = __show_trace(sp, + S390_lowcore.panic_stack + frame_size - 4096, + S390_lowcore.panic_stack + frame_size); #endif - sp = __show_trace(sp, S390_lowcore.async_stack - ASYNC_SIZE, - S390_lowcore.async_stack); + sp = __show_trace(sp, + S390_lowcore.async_stack + frame_size - ASYNC_SIZE, + S390_lowcore.async_stack + frame_size); if (task) __show_trace(sp, (unsigned long) task_stack_page(task), (unsigned long) task_stack_page(task) + THREAD_SIZE); diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c index f7fb58903f6a..408e866ae548 100644 --- a/arch/s390/kernel/irq.c +++ b/arch/s390/kernel/irq.c @@ -311,3 +311,67 @@ void measurement_alert_subclass_unregister(void) spin_unlock(&ma_subclass_lock); } EXPORT_SYMBOL(measurement_alert_subclass_unregister); + +void synchronize_irq(unsigned int irq) +{ + /* + * Not needed, the handler is protected by a lock and IRQs that occur + * after the handler is deleted are just NOPs. + */ +} +EXPORT_SYMBOL_GPL(synchronize_irq); + +#ifndef CONFIG_PCI + +/* Only PCI devices have dynamically-defined IRQ handlers */ + +int request_irq(unsigned int irq, irq_handler_t handler, + unsigned long irqflags, const char *devname, void *dev_id) +{ + return -EINVAL; +} +EXPORT_SYMBOL_GPL(request_irq); + +void free_irq(unsigned int irq, void *dev_id) +{ + WARN_ON(1); +} +EXPORT_SYMBOL_GPL(free_irq); + +void enable_irq(unsigned int irq) +{ + WARN_ON(1); +} +EXPORT_SYMBOL_GPL(enable_irq); + +void disable_irq(unsigned int irq) +{ + WARN_ON(1); +} +EXPORT_SYMBOL_GPL(disable_irq); + +#endif /* !CONFIG_PCI */ + +void disable_irq_nosync(unsigned int irq) +{ + disable_irq(irq); +} +EXPORT_SYMBOL_GPL(disable_irq_nosync); + +unsigned long probe_irq_on(void) +{ + return 0; +} +EXPORT_SYMBOL_GPL(probe_irq_on); + +int probe_irq_off(unsigned long val) +{ + return 0; +} +EXPORT_SYMBOL_GPL(probe_irq_off); + +unsigned int probe_irq_mask(unsigned long val) +{ + return val; +} +EXPORT_SYMBOL_GPL(probe_irq_mask); diff --git a/arch/s390/kernel/sclp.S b/arch/s390/kernel/sclp.S index b6506ee32a36..29bd7bec4176 100644 --- a/arch/s390/kernel/sclp.S +++ b/arch/s390/kernel/sclp.S @@ -225,7 +225,7 @@ _sclp_print: ahi %r2,1 ltr %r0,%r0 # end of string? jz .LfinalizemtoS4 - chi %r0,0x15 # end of line (NL)? + chi %r0,0x0a # end of line (NL)? jz .LfinalizemtoS4 stc %r0,0(%r6,%r7) # copy to mto la %r11,0(%r6,%r7) diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 05674b669001..4f977d0d25c2 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -428,34 +428,27 @@ void smp_stop_cpu(void) * This is the main routine where commands issued by other * cpus are handled. */ -static void do_ext_call_interrupt(struct ext_code ext_code, - unsigned int param32, unsigned long param64) +static void smp_handle_ext_call(void) { unsigned long bits; - int cpu; - - cpu = smp_processor_id(); - if (ext_code.code == 0x1202) - inc_irq_stat(IRQEXT_EXC); - else - inc_irq_stat(IRQEXT_EMS); - /* - * handle bit signal external calls - */ - bits = xchg(&pcpu_devices[cpu].ec_mask, 0); + /* handle bit signal external calls */ + bits = xchg(&pcpu_devices[smp_processor_id()].ec_mask, 0); if (test_bit(ec_stop_cpu, &bits)) smp_stop_cpu(); - if (test_bit(ec_schedule, &bits)) scheduler_ipi(); - if (test_bit(ec_call_function, &bits)) generic_smp_call_function_interrupt(); - if (test_bit(ec_call_function_single, &bits)) generic_smp_call_function_single_interrupt(); +} +static void do_ext_call_interrupt(struct ext_code ext_code, + unsigned int param32, unsigned long param64) +{ + inc_irq_stat(ext_code.code == 0x1202 ? IRQEXT_EXC : IRQEXT_EMS); + smp_handle_ext_call(); } void arch_send_call_function_ipi_mask(const struct cpumask *mask) @@ -760,6 +753,8 @@ int __cpu_disable(void) { unsigned long cregs[16]; + /* Handle possible pending IPIs */ + smp_handle_ext_call(); set_cpu_online(smp_processor_id(), false); /* Disable pseudo page faults on this cpu. */ pfault_fini(); diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 18dc417aaf79..a938b548f07e 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c @@ -492,7 +492,7 @@ static int gmap_connect_pgtable(unsigned long address, unsigned long segment, mp = (struct gmap_pgtable *) page->index; rmap->gmap = gmap; rmap->entry = segment_ptr; - rmap->vmaddr = address; + rmap->vmaddr = address & PMD_MASK; spin_lock(&mm->page_table_lock); if (*segment_ptr == segment) { list_add(&rmap->list, &mp->mapper); diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index e6f15b5d8b7d..f1e5be85d592 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c @@ -302,15 +302,6 @@ static int zpci_cfg_store(struct zpci_dev *zdev, int offset, u32 val, u8 len) return rc; } -void synchronize_irq(unsigned int irq) -{ - /* - * Not needed, the handler is protected by a lock and IRQs that occur - * after the handler is deleted are just NOPs. - */ -} -EXPORT_SYMBOL_GPL(synchronize_irq); - void enable_irq(unsigned int irq) { struct msi_desc *msi = irq_get_msi_desc(irq); @@ -327,30 +318,6 @@ void disable_irq(unsigned int irq) } EXPORT_SYMBOL_GPL(disable_irq); -void disable_irq_nosync(unsigned int irq) -{ - disable_irq(irq); -} -EXPORT_SYMBOL_GPL(disable_irq_nosync); - -unsigned long probe_irq_on(void) -{ - return 0; -} -EXPORT_SYMBOL_GPL(probe_irq_on); - -int probe_irq_off(unsigned long val) -{ - return 0; -} -EXPORT_SYMBOL_GPL(probe_irq_off); - -unsigned int probe_irq_mask(unsigned long val) -{ - return val; -} -EXPORT_SYMBOL_GPL(probe_irq_mask); - void pcibios_fixup_bus(struct pci_bus *bus) { } diff --git a/arch/score/mm/init.c b/arch/score/mm/init.c index d8f988a37d16..0940682ab38b 100644 --- a/arch/score/mm/init.c +++ b/arch/score/mm/init.c @@ -41,8 +41,6 @@ unsigned long empty_zero_page; EXPORT_SYMBOL_GPL(empty_zero_page); -static struct kcore_list kcore_mem, kcore_vmalloc; - static void setup_zero_page(void) { struct page *page; diff --git a/arch/sparc/include/asm/Kbuild b/arch/sparc/include/asm/Kbuild index ff18e3cfb6b1..7e4a97fbded4 100644 --- a/arch/sparc/include/asm/Kbuild +++ b/arch/sparc/include/asm/Kbuild @@ -6,6 +6,7 @@ generic-y += cputime.h generic-y += div64.h generic-y += emergency-restart.h generic-y += exec.h +generic-y += linkage.h generic-y += local64.h generic-y += mutex.h generic-y += irq_regs.h diff --git a/arch/sparc/include/asm/leon.h b/arch/sparc/include/asm/leon.h index 15a716934e4d..b836e9297f2a 100644 --- a/arch/sparc/include/asm/leon.h +++ b/arch/sparc/include/asm/leon.h @@ -135,7 +135,7 @@ static inline int sparc_leon3_cpuid(void) #ifdef CONFIG_SMP # define LEON3_IRQ_IPI_DEFAULT 13 -# define LEON3_IRQ_TICKER (leon3_ticker_irq) +# define LEON3_IRQ_TICKER (leon3_gptimer_irq) # define LEON3_IRQ_CROSS_CALL 15 #endif diff --git a/arch/sparc/include/asm/leon_amba.h b/arch/sparc/include/asm/leon_amba.h index f3034eddf468..24ec48c3ff90 100644 --- a/arch/sparc/include/asm/leon_amba.h +++ b/arch/sparc/include/asm/leon_amba.h @@ -47,6 +47,7 @@ struct amba_prom_registers { #define LEON3_GPTIMER_LD 4 #define LEON3_GPTIMER_IRQEN 8 #define LEON3_GPTIMER_SEPIRQ 8 +#define LEON3_GPTIMER_TIMERS 0x7 #define LEON23_REG_TIMER_CONTROL_EN 0x00000001 /* 1 = enable counting */ /* 0 = hold scalar and counter */ diff --git a/arch/sparc/include/asm/linkage.h b/arch/sparc/include/asm/linkage.h deleted file mode 100644 index 291c2d01c44f..000000000000 --- a/arch/sparc/include/asm/linkage.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ASM_LINKAGE_H -#define __ASM_LINKAGE_H - -/* Nothing to see here... */ - -#endif diff --git a/arch/sparc/kernel/ds.c b/arch/sparc/kernel/ds.c index 75bb608c423e..5ef48dab5636 100644 --- a/arch/sparc/kernel/ds.c +++ b/arch/sparc/kernel/ds.c @@ -843,7 +843,8 @@ void ldom_reboot(const char *boot_command) unsigned long len; strcpy(full_boot_str, "boot "); - strcpy(full_boot_str + strlen("boot "), boot_command); + strlcpy(full_boot_str + strlen("boot "), boot_command, + sizeof(full_boot_str + strlen("boot "))); len = strlen(full_boot_str); if (reboot_data_supported) { diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c index 7c0231dabe44..b7c68976cbc7 100644 --- a/arch/sparc/kernel/leon_kernel.c +++ b/arch/sparc/kernel/leon_kernel.c @@ -38,7 +38,6 @@ static DEFINE_SPINLOCK(leon_irq_lock); unsigned long leon3_gptimer_irq; /* interrupt controller irq number */ unsigned long leon3_gptimer_idx; /* Timer Index (0..6) within Timer Core */ -int leon3_ticker_irq; /* Timer ticker IRQ */ unsigned int sparc_leon_eirq; #define LEON_IMASK(cpu) (&leon3_irqctrl_regs->mask[cpu]) #define LEON_IACK (&leon3_irqctrl_regs->iclear) @@ -278,6 +277,9 @@ irqreturn_t leon_percpu_timer_ce_interrupt(int irq, void *unused) leon_clear_profile_irq(cpu); + if (cpu == boot_cpu_id) + timer_interrupt(irq, NULL); + ce = &per_cpu(sparc32_clockevent, cpu); irq_enter(); @@ -299,6 +301,7 @@ void __init leon_init_timers(void) int icsel; int ampopts; int err; + u32 config; sparc_config.get_cycles_offset = leon_cycles_offset; sparc_config.cs_period = 1000000 / HZ; @@ -377,23 +380,6 @@ void __init leon_init_timers(void) LEON3_BYPASS_STORE_PA( &leon3_gptimer_regs->e[leon3_gptimer_idx].ctrl, 0); -#ifdef CONFIG_SMP - leon3_ticker_irq = leon3_gptimer_irq + 1 + leon3_gptimer_idx; - - if (!(LEON3_BYPASS_LOAD_PA(&leon3_gptimer_regs->config) & - (1<<LEON3_GPTIMER_SEPIRQ))) { - printk(KERN_ERR "timer not configured with separate irqs\n"); - BUG(); - } - - LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx+1].val, - 0); - LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx+1].rld, - (((1000000/HZ) - 1))); - LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx+1].ctrl, - 0); -#endif - /* * The IRQ controller may (if implemented) consist of multiple * IRQ controllers, each mapped on a 4Kb boundary. @@ -416,13 +402,6 @@ void __init leon_init_timers(void) if (eirq != 0) leon_eirq_setup(eirq); - irq = _leon_build_device_irq(NULL, leon3_gptimer_irq+leon3_gptimer_idx); - err = request_irq(irq, timer_interrupt, IRQF_TIMER, "timer", NULL); - if (err) { - printk(KERN_ERR "unable to attach timer IRQ%d\n", irq); - prom_halt(); - } - #ifdef CONFIG_SMP { unsigned long flags; @@ -439,30 +418,31 @@ void __init leon_init_timers(void) } #endif - LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx].ctrl, - LEON3_GPTIMER_EN | - LEON3_GPTIMER_RL | - LEON3_GPTIMER_LD | - LEON3_GPTIMER_IRQEN); + config = LEON3_BYPASS_LOAD_PA(&leon3_gptimer_regs->config); + if (config & (1 << LEON3_GPTIMER_SEPIRQ)) + leon3_gptimer_irq += leon3_gptimer_idx; + else if ((config & LEON3_GPTIMER_TIMERS) > 1) + pr_warn("GPTIMER uses shared irqs, using other timers of the same core will fail.\n"); #ifdef CONFIG_SMP /* Install per-cpu IRQ handler for broadcasted ticker */ - irq = leon_build_device_irq(leon3_ticker_irq, handle_percpu_irq, + irq = leon_build_device_irq(leon3_gptimer_irq, handle_percpu_irq, "per-cpu", 0); err = request_irq(irq, leon_percpu_timer_ce_interrupt, - IRQF_PERCPU | IRQF_TIMER, "ticker", - NULL); + IRQF_PERCPU | IRQF_TIMER, "timer", NULL); +#else + irq = _leon_build_device_irq(NULL, leon3_gptimer_irq); + err = request_irq(irq, timer_interrupt, IRQF_TIMER, "timer", NULL); +#endif if (err) { - printk(KERN_ERR "unable to attach ticker IRQ%d\n", irq); + pr_err("Unable to attach timer IRQ%d\n", irq); prom_halt(); } - - LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx+1].ctrl, + LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx].ctrl, LEON3_GPTIMER_EN | LEON3_GPTIMER_RL | LEON3_GPTIMER_LD | LEON3_GPTIMER_IRQEN); -#endif return; bad: printk(KERN_ERR "No Timer/irqctrl found\n"); diff --git a/arch/sparc/kernel/leon_pci_grpci1.c b/arch/sparc/kernel/leon_pci_grpci1.c index 7739a54315e2..6df26e37f879 100644 --- a/arch/sparc/kernel/leon_pci_grpci1.c +++ b/arch/sparc/kernel/leon_pci_grpci1.c @@ -536,11 +536,9 @@ static int grpci1_of_probe(struct platform_device *ofdev) /* find device register base address */ res = platform_get_resource(ofdev, IORESOURCE_MEM, 0); - regs = devm_request_and_ioremap(&ofdev->dev, res); - if (!regs) { - dev_err(&ofdev->dev, "io-regs mapping failed\n"); - return -EADDRNOTAVAIL; - } + regs = devm_ioremap_resource(&ofdev->dev, res); + if (IS_ERR(regs)) + return PTR_ERR(regs); /* * check that we're in Host Slot and that we can act as a Host Bridge diff --git a/arch/sparc/kernel/leon_pmc.c b/arch/sparc/kernel/leon_pmc.c index bdf53d9a8d46..b0b3967a2dd2 100644 --- a/arch/sparc/kernel/leon_pmc.c +++ b/arch/sparc/kernel/leon_pmc.c @@ -47,6 +47,10 @@ void pmc_leon_idle_fixup(void) * MMU does not get a TLB miss here by using the MMU BYPASS ASI. */ register unsigned int address = (unsigned int)leon3_irqctrl_regs; + + /* Interrupts need to be enabled to not hang the CPU */ + local_irq_enable(); + __asm__ __volatile__ ( "wr %%g0, %%asr19\n" "lda [%0] %1, %%g0\n" @@ -60,6 +64,9 @@ void pmc_leon_idle_fixup(void) */ void pmc_leon_idle(void) { + /* Interrupts need to be enabled to not hang the CPU */ + local_irq_enable(); + /* For systems without power-down, this will be no-op */ __asm__ __volatile__ ("wr %g0, %asr19\n\t"); } diff --git a/arch/sparc/kernel/prom_common.c b/arch/sparc/kernel/prom_common.c index 9f20566b0773..79cc0d1a477d 100644 --- a/arch/sparc/kernel/prom_common.c +++ b/arch/sparc/kernel/prom_common.c @@ -54,6 +54,7 @@ EXPORT_SYMBOL(of_set_property_mutex); int of_set_property(struct device_node *dp, const char *name, void *val, int len) { struct property **prevp; + unsigned long flags; void *new_val; int err; @@ -64,7 +65,7 @@ int of_set_property(struct device_node *dp, const char *name, void *val, int len err = -ENODEV; mutex_lock(&of_set_property_mutex); - raw_spin_lock(&devtree_lock); + raw_spin_lock_irqsave(&devtree_lock, flags); prevp = &dp->properties; while (*prevp) { struct property *prop = *prevp; @@ -91,7 +92,7 @@ int of_set_property(struct device_node *dp, const char *name, void *val, int len } prevp = &(*prevp)->next; } - raw_spin_unlock(&devtree_lock); + raw_spin_unlock_irqrestore(&devtree_lock, flags); mutex_unlock(&of_set_property_mutex); /* XXX Upate procfs if necessary... */ diff --git a/arch/sparc/kernel/setup_32.c b/arch/sparc/kernel/setup_32.c index 38bf80a22f02..1434526970a6 100644 --- a/arch/sparc/kernel/setup_32.c +++ b/arch/sparc/kernel/setup_32.c @@ -304,7 +304,7 @@ void __init setup_arch(char **cmdline_p) /* Initialize PROM console and command line. */ *cmdline_p = prom_getbootargs(); - strcpy(boot_command_line, *cmdline_p); + strlcpy(boot_command_line, *cmdline_p, COMMAND_LINE_SIZE); parse_early_param(); boot_flags_init(*cmdline_p); diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c index 88a127b9c69e..13785547e435 100644 --- a/arch/sparc/kernel/setup_64.c +++ b/arch/sparc/kernel/setup_64.c @@ -555,7 +555,7 @@ void __init setup_arch(char **cmdline_p) { /* Initialize PROM console and command line. */ *cmdline_p = prom_getbootargs(); - strcpy(boot_command_line, *cmdline_p); + strlcpy(boot_command_line, *cmdline_p, COMMAND_LINE_SIZE); parse_early_param(); boot_flags_init(*cmdline_p); diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c index a7171997adfd..04fd55a6e461 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c @@ -1098,7 +1098,14 @@ static int __init grab_mblocks(struct mdesc_handle *md) m->size = *val; val = mdesc_get_property(md, node, "address-congruence-offset", NULL); - m->offset = *val; + + /* The address-congruence-offset property is optional. + * Explicity zero it be identifty this. + */ + if (val) + m->offset = *val; + else + m->offset = 0UL; numadbg("MBLOCK[%d]: base[%llx] size[%llx] offset[%llx]\n", count - 1, m->base, m->size, m->offset); diff --git a/arch/sparc/mm/tlb.c b/arch/sparc/mm/tlb.c index 83d89bcb44af..37e7bc4c95b3 100644 --- a/arch/sparc/mm/tlb.c +++ b/arch/sparc/mm/tlb.c @@ -85,8 +85,8 @@ static void tlb_batch_add_one(struct mm_struct *mm, unsigned long vaddr, } if (!tb->active) { - global_flush_tlb_page(mm, vaddr); flush_tsb_user_page(mm, vaddr); + global_flush_tlb_page(mm, vaddr); goto out; } diff --git a/arch/sparc/prom/bootstr_32.c b/arch/sparc/prom/bootstr_32.c index f5ec32e0d419..d2b49d2365e7 100644 --- a/arch/sparc/prom/bootstr_32.c +++ b/arch/sparc/prom/bootstr_32.c @@ -23,23 +23,25 @@ prom_getbootargs(void) return barg_buf; } - switch(prom_vers) { + switch (prom_vers) { case PROM_V0: cp = barg_buf; /* Start from 1 and go over fd(0,0,0)kernel */ - for(iter = 1; iter < 8; iter++) { + for (iter = 1; iter < 8; iter++) { arg = (*(romvec->pv_v0bootargs))->argv[iter]; if (arg == NULL) break; - while(*arg != 0) { + while (*arg != 0) { /* Leave place for space and null. */ - if(cp >= barg_buf + BARG_LEN-2){ + if (cp >= barg_buf + BARG_LEN - 2) /* We might issue a warning here. */ break; - } *cp++ = *arg++; } *cp++ = ' '; + if (cp >= barg_buf + BARG_LEN - 1) + /* We might issue a warning here. */ + break; } *cp = 0; break; diff --git a/arch/sparc/prom/tree_64.c b/arch/sparc/prom/tree_64.c index 92204c3800b5..bd1b2a3ac34e 100644 --- a/arch/sparc/prom/tree_64.c +++ b/arch/sparc/prom/tree_64.c @@ -39,7 +39,7 @@ inline phandle __prom_getchild(phandle node) return prom_node_to_node("child", node); } -inline phandle prom_getchild(phandle node) +phandle prom_getchild(phandle node) { phandle cnode; @@ -72,7 +72,7 @@ inline phandle __prom_getsibling(phandle node) return prom_node_to_node(prom_peer_name, node); } -inline phandle prom_getsibling(phandle node) +phandle prom_getsibling(phandle node) { phandle sibnode; @@ -89,7 +89,7 @@ EXPORT_SYMBOL(prom_getsibling); /* Return the length in bytes of property 'prop' at node 'node'. * Return -1 on error. */ -inline int prom_getproplen(phandle node, const char *prop) +int prom_getproplen(phandle node, const char *prop) { unsigned long args[6]; @@ -113,8 +113,8 @@ EXPORT_SYMBOL(prom_getproplen); * 'buffer' which has a size of 'bufsize'. If the acquisition * was successful the length will be returned, else -1 is returned. */ -inline int prom_getproperty(phandle node, const char *prop, - char *buffer, int bufsize) +int prom_getproperty(phandle node, const char *prop, + char *buffer, int bufsize) { unsigned long args[8]; int plen; @@ -141,7 +141,7 @@ EXPORT_SYMBOL(prom_getproperty); /* Acquire an integer property and return its value. Returns -1 * on failure. */ -inline int prom_getint(phandle node, const char *prop) +int prom_getint(phandle node, const char *prop) { int intprop; @@ -235,7 +235,7 @@ static const char *prom_nextprop_name = "nextprop"; /* Return the first property type for node 'node'. * buffer should be at least 32B in length */ -inline char *prom_firstprop(phandle node, char *buffer) +char *prom_firstprop(phandle node, char *buffer) { unsigned long args[7]; @@ -261,7 +261,7 @@ EXPORT_SYMBOL(prom_firstprop); * at node 'node' . Returns NULL string if no more * property types for this node. */ -inline char *prom_nextprop(phandle node, const char *oprop, char *buffer) +char *prom_nextprop(phandle node, const char *oprop, char *buffer) { unsigned long args[7]; char buf[32]; diff --git a/arch/tile/lib/exports.c b/arch/tile/lib/exports.c index 4385cb6fa00a..a93b02a25222 100644 --- a/arch/tile/lib/exports.c +++ b/arch/tile/lib/exports.c @@ -84,4 +84,6 @@ uint64_t __ashrdi3(uint64_t, unsigned int); EXPORT_SYMBOL(__ashrdi3); uint64_t __ashldi3(uint64_t, unsigned int); EXPORT_SYMBOL(__ashldi3); +int __ffsdi2(uint64_t); +EXPORT_SYMBOL(__ffsdi2); #endif diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index d7d21851e60c..3df3bd544492 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c @@ -147,7 +147,7 @@ void mconsole_proc(struct mc_request *req) } do { - loff_t pos; + loff_t pos = file->f_pos; mm_segment_t old_fs = get_fs(); set_fs(KERNEL_DS); len = vfs_read(file, buf, PAGE_SIZE - 1, &pos); diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 685692c94f05..fe120da25625 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -2265,6 +2265,7 @@ source "fs/Kconfig.binfmt" config IA32_EMULATION bool "IA32 Emulation" depends on X86_64 + select BINFMT_ELF select COMPAT_BINFMT_ELF select HAVE_UID16 ---help--- diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c index 35ee62fccf98..c205035a6b96 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c @@ -251,51 +251,6 @@ static void find_bits(unsigned long mask, u8 *pos, u8 *size) *size = len; } -static efi_status_t setup_efi_vars(struct boot_params *params) -{ - struct setup_data *data; - struct efi_var_bootdata *efidata; - u64 store_size, remaining_size, var_size; - efi_status_t status; - - if (sys_table->runtime->hdr.revision < EFI_2_00_SYSTEM_TABLE_REVISION) - return EFI_UNSUPPORTED; - - data = (struct setup_data *)(unsigned long)params->hdr.setup_data; - - while (data && data->next) - data = (struct setup_data *)(unsigned long)data->next; - - status = efi_call_phys4((void *)sys_table->runtime->query_variable_info, - EFI_VARIABLE_NON_VOLATILE | - EFI_VARIABLE_BOOTSERVICE_ACCESS | - EFI_VARIABLE_RUNTIME_ACCESS, &store_size, - &remaining_size, &var_size); - - if (status != EFI_SUCCESS) - return status; - - status = efi_call_phys3(sys_table->boottime->allocate_pool, - EFI_LOADER_DATA, sizeof(*efidata), &efidata); - - if (status != EFI_SUCCESS) - return status; - - efidata->data.type = SETUP_EFI_VARS; - efidata->data.len = sizeof(struct efi_var_bootdata) - - sizeof(struct setup_data); - efidata->data.next = 0; - efidata->store_size = store_size; - efidata->remaining_size = remaining_size; - efidata->max_var_size = var_size; - - if (data) - data->next = (unsigned long)efidata; - else - params->hdr.setup_data = (unsigned long)efidata; - -} - static efi_status_t setup_efi_pci(struct boot_params *params) { efi_pci_io_protocol *pci; @@ -1202,8 +1157,6 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table, setup_graphics(boot_params); - setup_efi_vars(boot_params); - setup_efi_pci(boot_params); status = efi_call_phys3(sys_table->boottime->allocate_pool, diff --git a/arch/x86/crypto/aesni-intel_asm.S b/arch/x86/crypto/aesni-intel_asm.S index 62fe22cd4cba..477e9d75149b 100644 --- a/arch/x86/crypto/aesni-intel_asm.S +++ b/arch/x86/crypto/aesni-intel_asm.S @@ -2681,56 +2681,68 @@ ENTRY(aesni_xts_crypt8) addq %rcx, KEYP movdqa IV, STATE1 - pxor 0x00(INP), STATE1 + movdqu 0x00(INP), INC + pxor INC, STATE1 movdqu IV, 0x00(OUTP) _aesni_gf128mul_x_ble() movdqa IV, STATE2 - pxor 0x10(INP), STATE2 + movdqu 0x10(INP), INC + pxor INC, STATE2 movdqu IV, 0x10(OUTP) _aesni_gf128mul_x_ble() movdqa IV, STATE3 - pxor 0x20(INP), STATE3 + movdqu 0x20(INP), INC + pxor INC, STATE3 movdqu IV, 0x20(OUTP) _aesni_gf128mul_x_ble() movdqa IV, STATE4 - pxor 0x30(INP), STATE4 + movdqu 0x30(INP), INC + pxor INC, STATE4 movdqu IV, 0x30(OUTP) call *%r11 - pxor 0x00(OUTP), STATE1 + movdqu 0x00(OUTP), INC + pxor INC, STATE1 movdqu STATE1, 0x00(OUTP) _aesni_gf128mul_x_ble() movdqa IV, STATE1 - pxor 0x40(INP), STATE1 + movdqu 0x40(INP), INC + pxor INC, STATE1 movdqu IV, 0x40(OUTP) - pxor 0x10(OUTP), STATE2 + movdqu 0x10(OUTP), INC + pxor INC, STATE2 movdqu STATE2, 0x10(OUTP) _aesni_gf128mul_x_ble() movdqa IV, STATE2 - pxor 0x50(INP), STATE2 + movdqu 0x50(INP), INC + pxor INC, STATE2 movdqu IV, 0x50(OUTP) - pxor 0x20(OUTP), STATE3 + movdqu 0x20(OUTP), INC + pxor INC, STATE3 movdqu STATE3, 0x20(OUTP) _aesni_gf128mul_x_ble() movdqa IV, STATE3 - pxor 0x60(INP), STATE3 + movdqu 0x60(INP), INC + pxor INC, STATE3 movdqu IV, 0x60(OUTP) - pxor 0x30(OUTP), STATE4 + movdqu 0x30(OUTP), INC + pxor INC, STATE4 movdqu STATE4, 0x30(OUTP) _aesni_gf128mul_x_ble() movdqa IV, STATE4 - pxor 0x70(INP), STATE4 + movdqu 0x70(INP), INC + pxor INC, STATE4 movdqu IV, 0x70(OUTP) _aesni_gf128mul_x_ble() @@ -2738,16 +2750,20 @@ ENTRY(aesni_xts_crypt8) call *%r11 - pxor 0x40(OUTP), STATE1 + movdqu 0x40(OUTP), INC + pxor INC, STATE1 movdqu STATE1, 0x40(OUTP) - pxor 0x50(OUTP), STATE2 + movdqu 0x50(OUTP), INC + pxor INC, STATE2 movdqu STATE2, 0x50(OUTP) - pxor 0x60(OUTP), STATE3 + movdqu 0x60(OUTP), INC + pxor INC, STATE3 movdqu STATE3, 0x60(OUTP) - pxor 0x70(OUTP), STATE4 + movdqu 0x70(OUTP), INC + pxor INC, STATE4 movdqu STATE4, 0x70(OUTP) ret diff --git a/arch/x86/crypto/crc32-pclmul_asm.S b/arch/x86/crypto/crc32-pclmul_asm.S index 94c27df8a549..f247304299a2 100644 --- a/arch/x86/crypto/crc32-pclmul_asm.S +++ b/arch/x86/crypto/crc32-pclmul_asm.S @@ -240,7 +240,7 @@ fold_64: pand %xmm3, %xmm1 PCLMULQDQ 0x00, CONSTANT, %xmm1 pxor %xmm2, %xmm1 - pextrd $0x01, %xmm1, %eax + PEXTRD 0x01, %xmm1, %eax ret ENDPROC(crc32_pclmul_le_16) diff --git a/arch/x86/crypto/sha256-avx-asm.S b/arch/x86/crypto/sha256-avx-asm.S index 56610c4bf31b..642f15687a0a 100644 --- a/arch/x86/crypto/sha256-avx-asm.S +++ b/arch/x86/crypto/sha256-avx-asm.S @@ -118,7 +118,7 @@ y2 = %r15d _INP_END_SIZE = 8 _INP_SIZE = 8 -_XFER_SIZE = 8 +_XFER_SIZE = 16 _XMM_SAVE_SIZE = 0 _INP_END = 0 diff --git a/arch/x86/crypto/sha256-ssse3-asm.S b/arch/x86/crypto/sha256-ssse3-asm.S index 98d3c391da81..f833b74d902b 100644 --- a/arch/x86/crypto/sha256-ssse3-asm.S +++ b/arch/x86/crypto/sha256-ssse3-asm.S @@ -111,7 +111,7 @@ y2 = %r15d _INP_END_SIZE = 8 _INP_SIZE = 8 -_XFER_SIZE = 8 +_XFER_SIZE = 16 _XMM_SAVE_SIZE = 0 _INP_END = 0 diff --git a/arch/x86/ia32/ia32_aout.c b/arch/x86/ia32/ia32_aout.c index 805078e08013..52ff81cce008 100644 --- a/arch/x86/ia32/ia32_aout.c +++ b/arch/x86/ia32/ia32_aout.c @@ -192,7 +192,7 @@ static int aout_core_dump(long signr, struct pt_regs *regs, struct file *file, /* struct user */ DUMP_WRITE(&dump, sizeof(dump)); /* Now dump all of the user data. Include malloced stuff as well */ - DUMP_SEEK(PAGE_SIZE); + DUMP_SEEK(PAGE_SIZE - sizeof(dump)); /* now we start writing out the user space info */ set_fs(USER_DS); /* Dump the data area */ diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index 2fb5d5884e23..60c89f30c727 100644 --- a/arch/x86/include/asm/efi.h +++ b/arch/x86/include/asm/efi.h @@ -102,13 +102,6 @@ extern void efi_call_phys_epilog(void); extern void efi_unmap_memmap(void); extern void efi_memory_uc(u64 addr, unsigned long size); -struct efi_var_bootdata { - struct setup_data data; - u64 store_size; - u64 remaining_size; - u64 max_var_size; -}; - #ifdef CONFIG_EFI static inline bool efi_is_native(void) diff --git a/arch/x86/include/asm/inst.h b/arch/x86/include/asm/inst.h index 280bf7fb6aba..3e115273ed88 100644 --- a/arch/x86/include/asm/inst.h +++ b/arch/x86/include/asm/inst.h @@ -9,12 +9,68 @@ #define REG_NUM_INVALID 100 -#define REG_TYPE_R64 0 -#define REG_TYPE_XMM 1 +#define REG_TYPE_R32 0 +#define REG_TYPE_R64 1 +#define REG_TYPE_XMM 2 #define REG_TYPE_INVALID 100 + .macro R32_NUM opd r32 + \opd = REG_NUM_INVALID + .ifc \r32,%eax + \opd = 0 + .endif + .ifc \r32,%ecx + \opd = 1 + .endif + .ifc \r32,%edx + \opd = 2 + .endif + .ifc \r32,%ebx + \opd = 3 + .endif + .ifc \r32,%esp + \opd = 4 + .endif + .ifc \r32,%ebp + \opd = 5 + .endif + .ifc \r32,%esi + \opd = 6 + .endif + .ifc \r32,%edi + \opd = 7 + .endif +#ifdef CONFIG_X86_64 + .ifc \r32,%r8d + \opd = 8 + .endif + .ifc \r32,%r9d + \opd = 9 + .endif + .ifc \r32,%r10d + \opd = 10 + .endif + .ifc \r32,%r11d + \opd = 11 + .endif + .ifc \r32,%r12d + \opd = 12 + .endif + .ifc \r32,%r13d + \opd = 13 + .endif + .ifc \r32,%r14d + \opd = 14 + .endif + .ifc \r32,%r15d + \opd = 15 + .endif +#endif + .endm + .macro R64_NUM opd r64 \opd = REG_NUM_INVALID +#ifdef CONFIG_X86_64 .ifc \r64,%rax \opd = 0 .endif @@ -63,6 +119,7 @@ .ifc \r64,%r15 \opd = 15 .endif +#endif .endm .macro XMM_NUM opd xmm @@ -118,10 +175,13 @@ .endm .macro REG_TYPE type reg + R32_NUM reg_type_r32 \reg R64_NUM reg_type_r64 \reg XMM_NUM reg_type_xmm \reg .if reg_type_r64 <> REG_NUM_INVALID \type = REG_TYPE_R64 + .elseif reg_type_r32 <> REG_NUM_INVALID + \type = REG_TYPE_R32 .elseif reg_type_xmm <> REG_NUM_INVALID \type = REG_TYPE_XMM .else @@ -162,6 +222,16 @@ .byte \imm8 .endm + .macro PEXTRD imm8 xmm gpr + R32_NUM extrd_opd1 \gpr + XMM_NUM extrd_opd2 \xmm + PFX_OPD_SIZE + PFX_REX extrd_opd1 extrd_opd2 + .byte 0x0f, 0x3a, 0x16 + MODRM 0xc0 extrd_opd1 extrd_opd2 + .byte \imm8 + .endm + .macro AESKEYGENASSIST rcon xmm1 xmm2 XMM_NUM aeskeygen_opd1 \xmm1 XMM_NUM aeskeygen_opd2 \xmm2 diff --git a/arch/x86/include/asm/irq.h b/arch/x86/include/asm/irq.h index ba870bb6dd8e..57873beb3292 100644 --- a/arch/x86/include/asm/irq.h +++ b/arch/x86/include/asm/irq.h @@ -41,4 +41,9 @@ extern int vector_used_by_percpu_irq(unsigned int vector); extern void init_ISA_irqs(void); +#ifdef CONFIG_X86_LOCAL_APIC +void arch_trigger_all_cpu_backtrace(void); +#define arch_trigger_all_cpu_backtrace arch_trigger_all_cpu_backtrace +#endif + #endif /* _ASM_X86_IRQ_H */ diff --git a/arch/x86/include/asm/microcode.h b/arch/x86/include/asm/microcode.h index 6825e2efd1b4..6bc3985ee473 100644 --- a/arch/x86/include/asm/microcode.h +++ b/arch/x86/include/asm/microcode.h @@ -60,11 +60,11 @@ static inline void __exit exit_amd_microcode(void) {} #ifdef CONFIG_MICROCODE_EARLY #define MAX_UCODE_COUNT 128 extern void __init load_ucode_bsp(void); -extern __init void load_ucode_ap(void); +extern void __cpuinit load_ucode_ap(void); extern int __init save_microcode_in_initrd(void); #else static inline void __init load_ucode_bsp(void) {} -static inline __init void load_ucode_ap(void) {} +static inline void __cpuinit load_ucode_ap(void) {} static inline int __init save_microcode_in_initrd(void) { return 0; diff --git a/arch/x86/include/asm/nmi.h b/arch/x86/include/asm/nmi.h index c0fa356e90de..86f9301903c8 100644 --- a/arch/x86/include/asm/nmi.h +++ b/arch/x86/include/asm/nmi.h @@ -18,9 +18,7 @@ extern int proc_nmi_enabled(struct ctl_table *, int , void __user *, size_t *, loff_t *); extern int unknown_nmi_panic; -void arch_trigger_all_cpu_backtrace(void); -#define arch_trigger_all_cpu_backtrace arch_trigger_all_cpu_backtrace -#endif +#endif /* CONFIG_X86_LOCAL_APIC */ #define NMI_FLAG_FIRST 1 diff --git a/arch/x86/include/uapi/asm/bootparam.h b/arch/x86/include/uapi/asm/bootparam.h index 08744242b8d2..c15ddaf90710 100644 --- a/arch/x86/include/uapi/asm/bootparam.h +++ b/arch/x86/include/uapi/asm/bootparam.h @@ -6,7 +6,6 @@ #define SETUP_E820_EXT 1 #define SETUP_DTB 2 #define SETUP_PCI 3 -#define SETUP_EFI_VARS 4 /* ram_size flags */ #define RAMDISK_IMAGE_START_MASK 0x07FF diff --git a/arch/x86/kernel/apic/hw_nmi.c b/arch/x86/kernel/apic/hw_nmi.c index 31cb9ae992b7..a698d7165c96 100644 --- a/arch/x86/kernel/apic/hw_nmi.c +++ b/arch/x86/kernel/apic/hw_nmi.c @@ -9,6 +9,7 @@ * */ #include <asm/apic.h> +#include <asm/nmi.h> #include <linux/cpumask.h> #include <linux/kdebug.h> diff --git a/arch/x86/kernel/cpu/mtrr/cleanup.c b/arch/x86/kernel/cpu/mtrr/cleanup.c index 35ffda5d0727..5f90b85ff22e 100644 --- a/arch/x86/kernel/cpu/mtrr/cleanup.c +++ b/arch/x86/kernel/cpu/mtrr/cleanup.c @@ -714,15 +714,15 @@ int __init mtrr_cleanup(unsigned address_bits) if (mtrr_tom2) x_remove_size = (mtrr_tom2 >> PAGE_SHIFT) - x_remove_base; - nr_range = x86_get_mtrr_mem_range(range, 0, x_remove_base, x_remove_size); /* * [0, 1M) should always be covered by var mtrr with WB * and fixed mtrrs should take effect before var mtrr for it: */ - nr_range = add_range_with_merge(range, RANGE_NUM, nr_range, 0, + nr_range = add_range_with_merge(range, RANGE_NUM, 0, 0, 1ULL<<(20 - PAGE_SHIFT)); - /* Sort the ranges: */ - sort_range(range, nr_range); + /* add from var mtrr at last */ + nr_range = x86_get_mtrr_mem_range(range, nr_range, + x_remove_base, x_remove_size); range_sums = sum_ranges(range, nr_range); printk(KERN_INFO "total RAM covered: %ldM\n", diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index f60d41ff9a97..a9e22073bd56 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -165,13 +165,13 @@ static struct extra_reg intel_snb_extra_regs[] __read_mostly = { INTEL_EVENT_EXTRA_REG(0xb7, MSR_OFFCORE_RSP_0, 0x3f807f8fffull, RSP_0), INTEL_EVENT_EXTRA_REG(0xbb, MSR_OFFCORE_RSP_1, 0x3f807f8fffull, RSP_1), INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x01cd), - INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x01cd), EVENT_EXTRA_END }; static struct extra_reg intel_snbep_extra_regs[] __read_mostly = { INTEL_EVENT_EXTRA_REG(0xb7, MSR_OFFCORE_RSP_0, 0x3fffff8fffull, RSP_0), INTEL_EVENT_EXTRA_REG(0xbb, MSR_OFFCORE_RSP_1, 0x3fffff8fffull, RSP_1), + INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x01cd), EVENT_EXTRA_END }; diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index 08f7e8039099..321d65ebaffe 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S @@ -115,8 +115,10 @@ startup_64: movq %rdi, %rax shrq $PUD_SHIFT, %rax andl $(PTRS_PER_PUD-1), %eax - movq %rdx, (4096+0)(%rbx,%rax,8) - movq %rdx, (4096+8)(%rbx,%rax,8) + movq %rdx, 4096(%rbx,%rax,8) + incl %eax + andl $(PTRS_PER_PUD-1), %eax + movq %rdx, 4096(%rbx,%rax,8) addq $8192, %rbx movq %rdi, %rax diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c index 245a71db401a..cb339097b9ea 100644 --- a/arch/x86/kernel/i387.c +++ b/arch/x86/kernel/i387.c @@ -22,23 +22,19 @@ /* * Were we in an interrupt that interrupted kernel mode? * - * For now, with eagerfpu we will return interrupted kernel FPU - * state as not-idle. TBD: Ideally we can change the return value - * to something like __thread_has_fpu(current). But we need to - * be careful of doing __thread_clear_has_fpu() before saving - * the FPU etc for supporting nested uses etc. For now, take - * the simple route! - * * On others, we can do a kernel_fpu_begin/end() pair *ONLY* if that * pair does nothing at all: the thread must not have fpu (so * that we don't try to save the FPU state), and TS must * be set (so that the clts/stts pair does nothing that is * visible in the interrupted kernel thread). + * + * Except for the eagerfpu case when we return 1 unless we've already + * been eager and saved the state in kernel_fpu_begin(). */ static inline bool interrupted_kernel_fpu_idle(void) { if (use_eager_fpu()) - return 0; + return __thread_has_fpu(current); return !__thread_has_fpu(current) && (read_cr0() & X86_CR0_TS); @@ -78,8 +74,8 @@ void __kernel_fpu_begin(void) struct task_struct *me = current; if (__thread_has_fpu(me)) { - __save_init_fpu(me); __thread_clear_has_fpu(me); + __save_init_fpu(me); /* We do 'stts()' in __kernel_fpu_end() */ } else if (!use_eager_fpu()) { this_cpu_write(fpu_owner_task, NULL); diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c index d2c381280e3c..3dd37ebd591b 100644 --- a/arch/x86/kernel/kvmclock.c +++ b/arch/x86/kernel/kvmclock.c @@ -242,6 +242,7 @@ void __init kvmclock_init(void) if (!mem) return; hv_clock = __va(mem); + memset(hv_clock, 0, size); if (kvm_register_clock("boot clock")) { hv_clock = NULL; diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 4e7a37ff03ab..81a5f5e8f142 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -277,18 +277,6 @@ void exit_idle(void) } #endif -void arch_cpu_idle_prepare(void) -{ - /* - * If we're the non-boot CPU, nothing set the stack canary up - * for us. CPU0 already has it initialized but no harm in - * doing it again. This is a good place for updating it, as - * we wont ever return from this function (so the invalid - * canaries already on the stack wont ever trigger). - */ - boot_init_stack_canary(); -} - void arch_cpu_idle_enter(void) { local_touch_nmi(); diff --git a/arch/x86/kernel/relocate_kernel_64.S b/arch/x86/kernel/relocate_kernel_64.S index 7a6f3b3be3cf..f2bb9c96720a 100644 --- a/arch/x86/kernel/relocate_kernel_64.S +++ b/arch/x86/kernel/relocate_kernel_64.S @@ -160,7 +160,7 @@ identity_mapped: xorq %rbp, %rbp xorq %r8, %r8 xorq %r9, %r9 - xorq %r10, %r9 + xorq %r10, %r10 xorq %r11, %r11 xorq %r12, %r12 xorq %r13, %r13 diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 9c73b51817e4..bfd348e99369 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -372,15 +372,15 @@ static bool __cpuinit match_mc(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o) void __cpuinit set_cpu_sibling_map(int cpu) { - bool has_mc = boot_cpu_data.x86_max_cores > 1; bool has_smt = smp_num_siblings > 1; + bool has_mp = has_smt || boot_cpu_data.x86_max_cores > 1; struct cpuinfo_x86 *c = &cpu_data(cpu); struct cpuinfo_x86 *o; int i; cpumask_set_cpu(cpu, cpu_sibling_setup_mask); - if (!has_smt && !has_mc) { + if (!has_mp) { cpumask_set_cpu(cpu, cpu_sibling_mask(cpu)); cpumask_set_cpu(cpu, cpu_llc_shared_mask(cpu)); cpumask_set_cpu(cpu, cpu_core_mask(cpu)); @@ -394,7 +394,7 @@ void __cpuinit set_cpu_sibling_map(int cpu) if ((i == cpu) || (has_smt && match_smt(c, o))) link_mask(sibling, cpu, i); - if ((i == cpu) || (has_mc && match_llc(c, o))) + if ((i == cpu) || (has_mp && match_llc(c, o))) link_mask(llc_shared, cpu, i); } @@ -406,7 +406,7 @@ void __cpuinit set_cpu_sibling_map(int cpu) for_each_cpu(i, cpu_sibling_setup_mask) { o = &cpu_data(i); - if ((i == cpu) || (has_mc && match_mc(c, o))) { + if ((i == cpu) || (has_mp && match_mc(c, o))) { link_mask(core, cpu, i); /* diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 8db0010ed150..5953dcea752d 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -1240,9 +1240,12 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt, ctxt->modrm_seg = VCPU_SREG_DS; if (ctxt->modrm_mod == 3) { + int highbyte_regs = ctxt->rex_prefix == 0; + op->type = OP_REG; op->bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes; - op->addr.reg = decode_register(ctxt, ctxt->modrm_rm, ctxt->d & ByteOp); + op->addr.reg = decode_register(ctxt, ctxt->modrm_rm, + highbyte_regs && (ctxt->d & ByteOp)); if (ctxt->d & Sse) { op->type = OP_XMM; op->bytes = 16; @@ -3997,7 +4000,8 @@ static const struct opcode twobyte_table[256] = { DI(ImplicitOps | Priv, invd), DI(ImplicitOps | Priv, wbinvd), N, N, N, D(ImplicitOps | ModRM), N, N, /* 0x10 - 0x1F */ - N, N, N, N, N, N, N, N, D(ImplicitOps | ModRM), N, N, N, N, N, N, N, + N, N, N, N, N, N, N, N, + D(ImplicitOps | ModRM), N, N, N, N, N, N, D(ImplicitOps | ModRM), /* 0x20 - 0x2F */ DIP(ModRM | DstMem | Priv | Op3264, cr_read, check_cr_read), DIP(ModRM | DstMem | Priv | Op3264, dr_read, check_dr_read), @@ -4836,6 +4840,7 @@ twobyte_insn: case 0x08: /* invd */ case 0x0d: /* GrpP (prefetch) */ case 0x18: /* Grp16 (prefetch/nop) */ + case 0x1f: /* nop */ break; case 0x20: /* mov cr, reg */ ctxt->dst.val = ops->get_cr(ctxt, ctxt->modrm_reg); diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index e1adbb4aca75..0eee2c8b64d1 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -1861,11 +1861,14 @@ void kvm_apic_accept_events(struct kvm_vcpu *vcpu) { struct kvm_lapic *apic = vcpu->arch.apic; unsigned int sipi_vector; + unsigned long pe; - if (!kvm_vcpu_has_lapic(vcpu)) + if (!kvm_vcpu_has_lapic(vcpu) || !apic->pending_events) return; - if (test_and_clear_bit(KVM_APIC_INIT, &apic->pending_events)) { + pe = xchg(&apic->pending_events, 0); + + if (test_bit(KVM_APIC_INIT, &pe)) { kvm_lapic_reset(vcpu); kvm_vcpu_reset(vcpu); if (kvm_vcpu_is_bsp(apic->vcpu)) @@ -1873,7 +1876,7 @@ void kvm_apic_accept_events(struct kvm_vcpu *vcpu) else vcpu->arch.mp_state = KVM_MP_STATE_INIT_RECEIVED; } - if (test_and_clear_bit(KVM_APIC_SIPI, &apic->pending_events) && + if (test_bit(KVM_APIC_SIPI, &pe) && vcpu->arch.mp_state == KVM_MP_STATE_INIT_RECEIVED) { /* evaluate pending_events before reading the vector */ smp_rmb(); diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 094b5d96ab14..e8ba99c34180 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -582,8 +582,6 @@ int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr) if (index != XCR_XFEATURE_ENABLED_MASK) return 1; xcr0 = xcr; - if (kvm_x86_ops->get_cpl(vcpu) != 0) - return 1; if (!(xcr0 & XSTATE_FP)) return 1; if ((xcr0 & XSTATE_YMM) && !(xcr0 & XSTATE_SSE)) @@ -597,7 +595,8 @@ int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr) int kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr) { - if (__kvm_set_xcr(vcpu, index, xcr)) { + if (kvm_x86_ops->get_cpl(vcpu) != 0 || + __kvm_set_xcr(vcpu, index, xcr)) { kvm_inject_gp(vcpu, 0); return 1; } diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c index eaac1743def7..1f34e9219775 100644 --- a/arch/x86/mm/init.c +++ b/arch/x86/mm/init.c @@ -277,6 +277,9 @@ static int __meminit split_mem_range(struct map_range *mr, int nr_range, end_pfn = limit_pfn; nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, 0); + if (!after_bootmem) + adjust_range_page_size_mask(mr, nr_range); + /* try to merge same page size and continuous */ for (i = 0; nr_range > 1 && i < nr_range - 1; i++) { unsigned long old_start; @@ -291,9 +294,6 @@ static int __meminit split_mem_range(struct map_range *mr, int nr_range, nr_range--; } - if (!after_bootmem) - adjust_range_page_size_mask(mr, nr_range); - for (i = 0; i < nr_range; i++) printk(KERN_DEBUG " [mem %#010lx-%#010lx] page %s\n", mr[i].start, mr[i].end - 1, diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c index 305c68b8d538..981c2dbd72cc 100644 --- a/arch/x86/pci/common.c +++ b/arch/x86/pci/common.c @@ -628,7 +628,9 @@ int pcibios_add_device(struct pci_dev *dev) pa_data = boot_params.hdr.setup_data; while (pa_data) { - data = phys_to_virt(pa_data); + data = ioremap(pa_data, sizeof(*rom)); + if (!data) + return -ENOMEM; if (data->type == SETUP_PCI) { rom = (struct pci_setup_rom *)data; @@ -645,6 +647,7 @@ int pcibios_add_device(struct pci_dev *dev) } } pa_data = data->next; + iounmap(data); } return 0; } diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index 55856b2310d3..d2fbcedcf6ea 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c @@ -42,7 +42,6 @@ #include <linux/io.h> #include <linux/reboot.h> #include <linux/bcd.h> -#include <linux/ucs2_string.h> #include <asm/setup.h> #include <asm/efi.h> @@ -54,12 +53,12 @@ #define EFI_DEBUG 1 -/* - * There's some additional metadata associated with each - * variable. Intel's reference implementation is 60 bytes - bump that - * to account for potential alignment constraints - */ -#define VAR_METADATA_SIZE 64 +#define EFI_MIN_RESERVE 5120 + +#define EFI_DUMMY_GUID \ + EFI_GUID(0x4424ac57, 0xbe4b, 0x47dd, 0x9e, 0x97, 0xed, 0x50, 0xf0, 0x9f, 0x92, 0xa9) + +static efi_char16_t efi_dummy_name[6] = { 'D', 'U', 'M', 'M', 'Y', 0 }; struct efi __read_mostly efi = { .mps = EFI_INVALID_TABLE_ADDR, @@ -79,13 +78,6 @@ struct efi_memory_map memmap; static struct efi efi_phys __initdata; static efi_system_table_t efi_systab __initdata; -static u64 efi_var_store_size; -static u64 efi_var_remaining_size; -static u64 efi_var_max_var_size; -static u64 boot_used_size; -static u64 boot_var_size; -static u64 active_size; - unsigned long x86_efi_facility; /* @@ -188,53 +180,8 @@ static efi_status_t virt_efi_get_next_variable(unsigned long *name_size, efi_char16_t *name, efi_guid_t *vendor) { - efi_status_t status; - static bool finished = false; - static u64 var_size; - - status = efi_call_virt3(get_next_variable, - name_size, name, vendor); - - if (status == EFI_NOT_FOUND) { - finished = true; - if (var_size < boot_used_size) { - boot_var_size = boot_used_size - var_size; - active_size += boot_var_size; - } else { - printk(KERN_WARNING FW_BUG "efi: Inconsistent initial sizes\n"); - } - } - - if (boot_used_size && !finished) { - unsigned long size; - u32 attr; - efi_status_t s; - void *tmp; - - s = virt_efi_get_variable(name, vendor, &attr, &size, NULL); - - if (s != EFI_BUFFER_TOO_SMALL || !size) - return status; - - tmp = kmalloc(size, GFP_ATOMIC); - - if (!tmp) - return status; - - s = virt_efi_get_variable(name, vendor, &attr, &size, tmp); - - if (s == EFI_SUCCESS && (attr & EFI_VARIABLE_NON_VOLATILE)) { - var_size += size; - var_size += ucs2_strsize(name, 1024); - active_size += size; - active_size += VAR_METADATA_SIZE; - active_size += ucs2_strsize(name, 1024); - } - - kfree(tmp); - } - - return status; + return efi_call_virt3(get_next_variable, + name_size, name, vendor); } static efi_status_t virt_efi_set_variable(efi_char16_t *name, @@ -243,34 +190,9 @@ static efi_status_t virt_efi_set_variable(efi_char16_t *name, unsigned long data_size, void *data) { - efi_status_t status; - u32 orig_attr = 0; - unsigned long orig_size = 0; - - status = virt_efi_get_variable(name, vendor, &orig_attr, &orig_size, - NULL); - - if (status != EFI_BUFFER_TOO_SMALL) - orig_size = 0; - - status = efi_call_virt5(set_variable, - name, vendor, attr, - data_size, data); - - if (status == EFI_SUCCESS) { - if (orig_size) { - active_size -= orig_size; - active_size -= ucs2_strsize(name, 1024); - active_size -= VAR_METADATA_SIZE; - } - if (data_size) { - active_size += data_size; - active_size += ucs2_strsize(name, 1024); - active_size += VAR_METADATA_SIZE; - } - } - - return status; + return efi_call_virt5(set_variable, + name, vendor, attr, + data_size, data); } static efi_status_t virt_efi_query_variable_info(u32 attr, @@ -786,9 +708,6 @@ void __init efi_init(void) char vendor[100] = "unknown"; int i = 0; void *tmp; - struct setup_data *data; - struct efi_var_bootdata *efi_var_data; - u64 pa_data; #ifdef CONFIG_X86_32 if (boot_params.efi_info.efi_systab_hi || @@ -806,22 +725,6 @@ void __init efi_init(void) if (efi_systab_init(efi_phys.systab)) return; - pa_data = boot_params.hdr.setup_data; - while (pa_data) { - data = early_ioremap(pa_data, sizeof(*efi_var_data)); - if (data->type == SETUP_EFI_VARS) { - efi_var_data = (struct efi_var_bootdata *)data; - - efi_var_store_size = efi_var_data->store_size; - efi_var_remaining_size = efi_var_data->remaining_size; - efi_var_max_var_size = efi_var_data->max_var_size; - } - pa_data = data->next; - early_iounmap(data, sizeof(*efi_var_data)); - } - - boot_used_size = efi_var_store_size - efi_var_remaining_size; - set_bit(EFI_SYSTEM_TABLES, &x86_efi_facility); /* @@ -1085,6 +988,13 @@ void __init efi_enter_virtual_mode(void) runtime_code_page_mkexec(); kfree(new_memmap); + + /* clean DUMMY object */ + efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + 0, NULL); } /* @@ -1136,33 +1046,70 @@ efi_status_t efi_query_variable_store(u32 attributes, unsigned long size) efi_status_t status; u64 storage_size, remaining_size, max_size; + if (!(attributes & EFI_VARIABLE_NON_VOLATILE)) + return 0; + status = efi.query_variable_info(attributes, &storage_size, &remaining_size, &max_size); if (status != EFI_SUCCESS) return status; - if (!max_size && remaining_size > size) - printk_once(KERN_ERR FW_BUG "Broken EFI implementation" - " is returning MaxVariableSize=0\n"); /* * Some firmware implementations refuse to boot if there's insufficient * space in the variable store. We account for that by refusing the * write if permitting it would reduce the available space to under - * 50%. However, some firmware won't reclaim variable space until - * after the used (not merely the actively used) space drops below - * a threshold. We can approximate that case with the value calculated - * above. If both the firmware and our calculations indicate that the - * available space would drop below 50%, refuse the write. + * 5KB. This figure was provided by Samsung, so should be safe. */ + if ((remaining_size - size < EFI_MIN_RESERVE) && + !efi_no_storage_paranoia) { + + /* + * Triggering garbage collection may require that the firmware + * generate a real EFI_OUT_OF_RESOURCES error. We can force + * that by attempting to use more space than is available. + */ + unsigned long dummy_size = remaining_size + 1024; + void *dummy = kzalloc(dummy_size, GFP_ATOMIC); + + if (!dummy) + return EFI_OUT_OF_RESOURCES; + + status = efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + dummy_size, dummy); + + if (status == EFI_SUCCESS) { + /* + * This should have failed, so if it didn't make sure + * that we delete it... + */ + efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + 0, dummy); + } + + kfree(dummy); - if (!storage_size || size > remaining_size || - (max_size && size > max_size)) - return EFI_OUT_OF_RESOURCES; + /* + * The runtime code may now have triggered a garbage collection + * run, so check the variable info again + */ + status = efi.query_variable_info(attributes, &storage_size, + &remaining_size, &max_size); - if (!efi_no_storage_paranoia && - ((active_size + size + VAR_METADATA_SIZE > storage_size / 2) && - (remaining_size - size < storage_size / 2))) - return EFI_OUT_OF_RESOURCES; + if (status != EFI_SUCCESS) + return status; + + /* + * There still isn't enough room, so return an error + */ + if (remaining_size - size < EFI_MIN_RESERVE) + return EFI_OUT_OF_RESOURCES; + } return EFI_SUCCESS; } diff --git a/arch/x86/tools/relocs.c b/arch/x86/tools/relocs.c index 590be1090892..f7bab68a4b83 100644 --- a/arch/x86/tools/relocs.c +++ b/arch/x86/tools/relocs.c @@ -42,9 +42,6 @@ static const char * const sym_regex_kernel[S_NSYMTYPES] = { "^(xen_irq_disable_direct_reloc$|" "xen_save_fl_direct_reloc$|" "VDSO|" -#if ELF_BITS == 64 - "__vvar_page|" -#endif "__crc_)", /* @@ -72,6 +69,7 @@ static const char * const sym_regex_kernel[S_NSYMTYPES] = { "__per_cpu_load|" "init_per_cpu__.*|" "__end_rodata_hpage_align|" + "__vvar_page|" #endif "_end)$" }; diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index 8ff37995d54e..d99cae8147d1 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c @@ -17,6 +17,7 @@ #include <linux/slab.h> #include <linux/smp.h> #include <linux/irq_work.h> +#include <linux/tick.h> #include <asm/paravirt.h> #include <asm/desc.h> @@ -447,6 +448,13 @@ static void __cpuinit xen_play_dead(void) /* used only with HOTPLUG_CPU */ play_dead_common(); HYPERVISOR_vcpu_op(VCPUOP_down, smp_processor_id(), NULL); cpu_bringup(); + /* + * commit 4b0c0f294 (tick: Cleanup NOHZ per cpu data on cpu down) + * clears certain data that the cpu_idle loop (which called us + * and that we return from) expects. The only way to get that + * data back is to call: + */ + tick_nohz_idle_enter(); } #else /* !CONFIG_HOTPLUG_CPU */ @@ -576,24 +584,22 @@ void xen_send_IPI_mask_allbutself(const struct cpumask *mask, { unsigned cpu; unsigned int this_cpu = smp_processor_id(); + int xen_vector = xen_map_vector(vector); - if (!(num_online_cpus() > 1)) + if (!(num_online_cpus() > 1) || (xen_vector < 0)) return; for_each_cpu_and(cpu, mask, cpu_online_mask) { if (this_cpu == cpu) continue; - xen_smp_send_call_function_single_ipi(cpu); + xen_send_IPI_one(cpu, xen_vector); } } void xen_send_IPI_allbutself(int vector) { - int xen_vector = xen_map_vector(vector); - - if (xen_vector >= 0) - xen_send_IPI_mask_allbutself(cpu_online_mask, xen_vector); + xen_send_IPI_mask_allbutself(cpu_online_mask, vector); } static irqreturn_t xen_call_function_interrupt(int irq, void *dev_id) diff --git a/arch/x86/xen/smp.h b/arch/x86/xen/smp.h index 8981a76d081a..c7c2d89efd76 100644 --- a/arch/x86/xen/smp.h +++ b/arch/x86/xen/smp.h @@ -5,7 +5,6 @@ extern void xen_send_IPI_mask(const struct cpumask *mask, extern void xen_send_IPI_mask_allbutself(const struct cpumask *mask, int vector); extern void xen_send_IPI_allbutself(int vector); -extern void physflat_send_IPI_allbutself(int vector); extern void xen_send_IPI_all(int vector); extern void xen_send_IPI_self(int vector); diff --git a/block/blk-core.c b/block/blk-core.c index 33c33bc99ddd..d5745b5833c9 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -3164,7 +3164,7 @@ void blk_post_runtime_resume(struct request_queue *q, int err) q->rpm_status = RPM_ACTIVE; __blk_run_queue(q); pm_runtime_mark_last_busy(q->dev); - pm_runtime_autosuspend(q->dev); + pm_request_autosuspend(q->dev); } else { q->rpm_status = RPM_SUSPENDED; } diff --git a/crypto/Kconfig b/crypto/Kconfig index 622d8a48cbe9..bf8148e74e73 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -823,6 +823,7 @@ config CRYPTO_BLOWFISH_X86_64 config CRYPTO_BLOWFISH_AVX2_X86_64 tristate "Blowfish cipher algorithm (x86_64/AVX2)" depends on X86 && 64BIT + depends on BROKEN select CRYPTO_ALGAPI select CRYPTO_CRYPTD select CRYPTO_ABLK_HELPER_X86 @@ -1299,6 +1300,7 @@ config CRYPTO_TWOFISH_AVX_X86_64 config CRYPTO_TWOFISH_AVX2_X86_64 tristate "Twofish cipher algorithm (x86_64/AVX2)" depends on X86 && 64BIT + depends on BROKEN select CRYPTO_ALGAPI select CRYPTO_CRYPTD select CRYPTO_ABLK_HELPER_X86 diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index ecb743bf05a5..536562c626a2 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -24,7 +24,7 @@ acpi-y += nvs.o # Power management related files acpi-y += wakeup.o acpi-y += sleep.o -acpi-$(CONFIG_PM) += device_pm.o +acpi-y += device_pm.o acpi-$(CONFIG_ACPI_SLEEP) += proc.o @@ -38,7 +38,6 @@ acpi-y += processor_core.o acpi-y += ec.o acpi-$(CONFIG_ACPI_DOCK) += dock.o acpi-y += pci_root.o pci_link.o pci_irq.o -acpi-y += csrt.o acpi-$(CONFIG_X86_INTEL_LPSS) += acpi_lpss.o acpi-y += acpi_platform.o acpi-y += power.o diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c index b1c95422ce74..cab13f2fc28e 100644 --- a/drivers/acpi/acpi_lpss.c +++ b/drivers/acpi/acpi_lpss.c @@ -35,11 +35,16 @@ ACPI_MODULE_NAME("acpi_lpss"); struct lpss_device_desc { bool clk_required; - const char *clk_parent; + const char *clkdev_name; bool ltr_required; unsigned int prv_offset; }; +static struct lpss_device_desc lpss_dma_desc = { + .clk_required = true, + .clkdev_name = "hclk", +}; + struct lpss_private_data { void __iomem *mmio_base; resource_size_t mmio_size; @@ -49,7 +54,6 @@ struct lpss_private_data { static struct lpss_device_desc lpt_dev_desc = { .clk_required = true, - .clk_parent = "lpss_clk", .prv_offset = 0x800, .ltr_required = true, }; @@ -60,6 +64,9 @@ static struct lpss_device_desc lpt_sdio_dev_desc = { }; static const struct acpi_device_id acpi_lpss_device_ids[] = { + /* Generic LPSS devices */ + { "INTL9C60", (unsigned long)&lpss_dma_desc }, + /* Lynxpoint LPSS devices */ { "INT33C0", (unsigned long)&lpt_dev_desc }, { "INT33C1", (unsigned long)&lpt_dev_desc }, @@ -91,16 +98,27 @@ static int register_device_clock(struct acpi_device *adev, struct lpss_private_data *pdata) { const struct lpss_device_desc *dev_desc = pdata->dev_desc; + struct lpss_clk_data *clk_data; if (!lpss_clk_dev) lpt_register_clock_device(); - if (!dev_desc->clk_parent || !pdata->mmio_base + clk_data = platform_get_drvdata(lpss_clk_dev); + if (!clk_data) + return -ENODEV; + + if (dev_desc->clkdev_name) { + clk_register_clkdev(clk_data->clk, dev_desc->clkdev_name, + dev_name(&adev->dev)); + return 0; + } + + if (!pdata->mmio_base || pdata->mmio_size < dev_desc->prv_offset + LPSS_CLK_SIZE) return -ENODATA; pdata->clk = clk_register_gate(NULL, dev_name(&adev->dev), - dev_desc->clk_parent, 0, + clk_data->name, 0, pdata->mmio_base + dev_desc->prv_offset, 0, 0, NULL); if (IS_ERR(pdata->clk)) @@ -146,15 +164,24 @@ static int acpi_lpss_create_device(struct acpi_device *adev, if (dev_desc->clk_required) { ret = register_device_clock(adev, pdata); if (ret) { - /* - * Skip the device, but don't terminate the namespace - * scan. - */ - kfree(pdata); - return 0; + /* Skip the device, but continue the namespace scan. */ + ret = 0; + goto err_out; } } + /* + * This works around a known issue in ACPI tables where LPSS devices + * have _PS0 and _PS3 without _PSC (and no power resources), so + * acpi_bus_init_power() will assume that the BIOS has put them into D0. + */ + ret = acpi_device_fix_up_power(adev); + if (ret) { + /* Skip the device, but continue the namespace scan. */ + ret = 0; + goto err_out; + } + adev->driver_data = pdata; ret = acpi_create_platform_device(adev, id); if (ret > 0) diff --git a/drivers/acpi/apei/cper.c b/drivers/acpi/apei/cper.c index fefc2ca7cc3e..33dc6a004802 100644 --- a/drivers/acpi/apei/cper.c +++ b/drivers/acpi/apei/cper.c @@ -250,10 +250,6 @@ static const char *cper_pcie_port_type_strs[] = { static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie, const struct acpi_hest_generic_data *gdata) { -#ifdef CONFIG_ACPI_APEI_PCIEAER - struct pci_dev *dev; -#endif - if (pcie->validation_bits & CPER_PCIE_VALID_PORT_TYPE) printk("%s""port_type: %d, %s\n", pfx, pcie->port_type, pcie->port_type < ARRAY_SIZE(cper_pcie_port_type_strs) ? @@ -285,20 +281,6 @@ static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie, printk( "%s""bridge: secondary_status: 0x%04x, control: 0x%04x\n", pfx, pcie->bridge.secondary_status, pcie->bridge.control); -#ifdef CONFIG_ACPI_APEI_PCIEAER - dev = pci_get_domain_bus_and_slot(pcie->device_id.segment, - pcie->device_id.bus, pcie->device_id.function); - if (!dev) { - pr_err("PCI AER Cannot get PCI device %04x:%02x:%02x.%d\n", - pcie->device_id.segment, pcie->device_id.bus, - pcie->device_id.slot, pcie->device_id.function); - return; - } - if (pcie->validation_bits & CPER_PCIE_VALID_AER_INFO) - cper_print_aer(pfx, dev, gdata->error_severity, - (struct aer_capability_regs *) pcie->aer_info); - pci_dev_put(dev); -#endif } static const char *apei_estatus_section_flag_strs[] = { diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index d668a8ae602b..fcd7d91cec34 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -454,7 +454,9 @@ static void ghes_do_proc(struct ghes *ghes, aer_severity = cper_severity_to_aer(sev); aer_recover_queue(pcie_err->device_id.segment, pcie_err->device_id.bus, - devfn, aer_severity); + devfn, aer_severity, + (struct aer_capability_regs *) + pcie_err->aer_info); } } @@ -917,13 +919,14 @@ static int ghes_probe(struct platform_device *ghes_dev) break; case ACPI_HEST_NOTIFY_EXTERNAL: /* External interrupt vector is GSI */ - if (acpi_gsi_to_irq(generic->notify.vector, &ghes->irq)) { + rc = acpi_gsi_to_irq(generic->notify.vector, &ghes->irq); + if (rc) { pr_err(GHES_PFX "Failed to map GSI to IRQ for generic hardware error source: %d\n", generic->header.source_id); goto err_edac_unreg; } - if (request_irq(ghes->irq, ghes_irq_func, - 0, "GHES IRQ", ghes)) { + rc = request_irq(ghes->irq, ghes_irq_func, 0, "GHES IRQ", ghes); + if (rc) { pr_err(GHES_PFX "Failed to register IRQ for generic hardware error source: %d\n", generic->header.source_id); goto err_edac_unreg; diff --git a/drivers/acpi/csrt.c b/drivers/acpi/csrt.c deleted file mode 100644 index 5c15a91faf0b..000000000000 --- a/drivers/acpi/csrt.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Support for Core System Resources Table (CSRT) - * - * Copyright (C) 2013, Intel Corporation - * Authors: Mika Westerberg <mika.westerberg@linux.intel.com> - * Andy Shevchenko <andriy.shevchenko@linux.intel.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#define pr_fmt(fmt) "ACPI: CSRT: " fmt - -#include <linux/acpi.h> -#include <linux/device.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/sizes.h> - -ACPI_MODULE_NAME("CSRT"); - -static int __init acpi_csrt_parse_shared_info(struct platform_device *pdev, - const struct acpi_csrt_group *grp) -{ - const struct acpi_csrt_shared_info *si; - struct resource res[3]; - size_t nres; - int ret; - - memset(res, 0, sizeof(res)); - nres = 0; - - si = (const struct acpi_csrt_shared_info *)&grp[1]; - /* - * The peripherals that are listed on CSRT typically support only - * 32-bit addresses so we only use the low part of MMIO base for - * now. - */ - if (!si->mmio_base_high && si->mmio_base_low) { - /* - * There is no size of the memory resource in shared_info - * so we assume that it is 4k here. - */ - res[nres].start = si->mmio_base_low; - res[nres].end = res[0].start + SZ_4K - 1; - res[nres++].flags = IORESOURCE_MEM; - } - - if (si->gsi_interrupt) { - int irq = acpi_register_gsi(NULL, si->gsi_interrupt, - si->interrupt_mode, - si->interrupt_polarity); - res[nres].start = irq; - res[nres].end = irq; - res[nres++].flags = IORESOURCE_IRQ; - } - - if (si->base_request_line || si->num_handshake_signals) { - /* - * We pass the driver a DMA resource describing the range - * of request lines the device supports. - */ - res[nres].start = si->base_request_line; - res[nres].end = res[nres].start + si->num_handshake_signals - 1; - res[nres++].flags = IORESOURCE_DMA; - } - - ret = platform_device_add_resources(pdev, res, nres); - if (ret) { - if (si->gsi_interrupt) - acpi_unregister_gsi(si->gsi_interrupt); - return ret; - } - - return 0; -} - -static int __init -acpi_csrt_parse_resource_group(const struct acpi_csrt_group *grp) -{ - struct platform_device *pdev; - char vendor[5], name[16]; - int ret, i; - - vendor[0] = grp->vendor_id; - vendor[1] = grp->vendor_id >> 8; - vendor[2] = grp->vendor_id >> 16; - vendor[3] = grp->vendor_id >> 24; - vendor[4] = '\0'; - - if (grp->shared_info_length != sizeof(struct acpi_csrt_shared_info)) - return -ENODEV; - - snprintf(name, sizeof(name), "%s%04X", vendor, grp->device_id); - pdev = platform_device_alloc(name, PLATFORM_DEVID_AUTO); - if (!pdev) - return -ENOMEM; - - /* Add resources based on the shared info */ - ret = acpi_csrt_parse_shared_info(pdev, grp); - if (ret) - goto fail; - - ret = platform_device_add(pdev); - if (ret) - goto fail; - - for (i = 0; i < pdev->num_resources; i++) - dev_dbg(&pdev->dev, "%pR\n", &pdev->resource[i]); - - return 0; - -fail: - platform_device_put(pdev); - return ret; -} - -/* - * CSRT or Core System Resources Table is a proprietary ACPI table - * introduced by Microsoft. This table can contain devices that are not in - * the system DSDT table. In particular DMA controllers might be described - * here. - * - * We present these devices as normal platform devices that don't have ACPI - * IDs or handle. The platform device name will be something like - * <VENDOR><DEVID>.<n>.auto for example: INTL9C06.0.auto. - */ -void __init acpi_csrt_init(void) -{ - struct acpi_csrt_group *grp, *end; - struct acpi_table_csrt *csrt; - acpi_status status; - int ret; - - status = acpi_get_table(ACPI_SIG_CSRT, 0, - (struct acpi_table_header **)&csrt); - if (ACPI_FAILURE(status)) { - if (status != AE_NOT_FOUND) - pr_warn("failed to get the CSRT table\n"); - return; - } - - pr_debug("parsing CSRT table for devices\n"); - - grp = (struct acpi_csrt_group *)(csrt + 1); - end = (struct acpi_csrt_group *)((void *)csrt + csrt->header.length); - - while (grp < end) { - ret = acpi_csrt_parse_resource_group(grp); - if (ret) { - pr_warn("error in parsing resource group: %d\n", ret); - return; - } - - grp = (struct acpi_csrt_group *)((void *)grp + grp->length); - } -} diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index 96de787e6104..31c217a42839 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c @@ -37,68 +37,6 @@ #define _COMPONENT ACPI_POWER_COMPONENT ACPI_MODULE_NAME("device_pm"); -static DEFINE_MUTEX(acpi_pm_notifier_lock); - -/** - * acpi_add_pm_notifier - Register PM notifier for given ACPI device. - * @adev: ACPI device to add the notifier for. - * @context: Context information to pass to the notifier routine. - * - * NOTE: @adev need not be a run-wake or wakeup device to be a valid source of - * PM wakeup events. For example, wakeup events may be generated for bridges - * if one of the devices below the bridge is signaling wakeup, even if the - * bridge itself doesn't have a wakeup GPE associated with it. - */ -acpi_status acpi_add_pm_notifier(struct acpi_device *adev, - acpi_notify_handler handler, void *context) -{ - acpi_status status = AE_ALREADY_EXISTS; - - mutex_lock(&acpi_pm_notifier_lock); - - if (adev->wakeup.flags.notifier_present) - goto out; - - status = acpi_install_notify_handler(adev->handle, - ACPI_SYSTEM_NOTIFY, - handler, context); - if (ACPI_FAILURE(status)) - goto out; - - adev->wakeup.flags.notifier_present = true; - - out: - mutex_unlock(&acpi_pm_notifier_lock); - return status; -} - -/** - * acpi_remove_pm_notifier - Unregister PM notifier from given ACPI device. - * @adev: ACPI device to remove the notifier from. - */ -acpi_status acpi_remove_pm_notifier(struct acpi_device *adev, - acpi_notify_handler handler) -{ - acpi_status status = AE_BAD_PARAMETER; - - mutex_lock(&acpi_pm_notifier_lock); - - if (!adev->wakeup.flags.notifier_present) - goto out; - - status = acpi_remove_notify_handler(adev->handle, - ACPI_SYSTEM_NOTIFY, - handler); - if (ACPI_FAILURE(status)) - goto out; - - adev->wakeup.flags.notifier_present = false; - - out: - mutex_unlock(&acpi_pm_notifier_lock); - return status; -} - /** * acpi_power_state_string - String representation of ACPI device power state. * @state: ACPI device power state to return the string representation of. @@ -340,16 +278,38 @@ int acpi_bus_init_power(struct acpi_device *device) if (result) return result; } else if (state == ACPI_STATE_UNKNOWN) { - /* No power resources and missing _PSC? Try to force D0. */ + /* + * No power resources and missing _PSC? Cross fingers and make + * it D0 in hope that this is what the BIOS put the device into. + * [We tried to force D0 here by executing _PS0, but that broke + * Toshiba P870-303 in a nasty way.] + */ state = ACPI_STATE_D0; - result = acpi_dev_pm_explicit_set(device, state); - if (result) - return result; } device->power.state = state; return 0; } +/** + * acpi_device_fix_up_power - Force device with missing _PSC into D0. + * @device: Device object whose power state is to be fixed up. + * + * Devices without power resources and _PSC, but having _PS0 and _PS3 defined, + * are assumed to be put into D0 by the BIOS. However, in some cases that may + * not be the case and this function should be used then. + */ +int acpi_device_fix_up_power(struct acpi_device *device) +{ + int ret = 0; + + if (!device->power.flags.power_resources + && !device->power.flags.explicit_get + && device->power.state == ACPI_STATE_D0) + ret = acpi_dev_pm_explicit_set(device, ACPI_STATE_D0); + + return ret; +} + int acpi_bus_update_power(acpi_handle handle, int *state_p) { struct acpi_device *device; @@ -385,6 +345,69 @@ bool acpi_bus_power_manageable(acpi_handle handle) } EXPORT_SYMBOL(acpi_bus_power_manageable); +#ifdef CONFIG_PM +static DEFINE_MUTEX(acpi_pm_notifier_lock); + +/** + * acpi_add_pm_notifier - Register PM notifier for given ACPI device. + * @adev: ACPI device to add the notifier for. + * @context: Context information to pass to the notifier routine. + * + * NOTE: @adev need not be a run-wake or wakeup device to be a valid source of + * PM wakeup events. For example, wakeup events may be generated for bridges + * if one of the devices below the bridge is signaling wakeup, even if the + * bridge itself doesn't have a wakeup GPE associated with it. + */ +acpi_status acpi_add_pm_notifier(struct acpi_device *adev, + acpi_notify_handler handler, void *context) +{ + acpi_status status = AE_ALREADY_EXISTS; + + mutex_lock(&acpi_pm_notifier_lock); + + if (adev->wakeup.flags.notifier_present) + goto out; + + status = acpi_install_notify_handler(adev->handle, + ACPI_SYSTEM_NOTIFY, + handler, context); + if (ACPI_FAILURE(status)) + goto out; + + adev->wakeup.flags.notifier_present = true; + + out: + mutex_unlock(&acpi_pm_notifier_lock); + return status; +} + +/** + * acpi_remove_pm_notifier - Unregister PM notifier from given ACPI device. + * @adev: ACPI device to remove the notifier from. + */ +acpi_status acpi_remove_pm_notifier(struct acpi_device *adev, + acpi_notify_handler handler) +{ + acpi_status status = AE_BAD_PARAMETER; + + mutex_lock(&acpi_pm_notifier_lock); + + if (!adev->wakeup.flags.notifier_present) + goto out; + + status = acpi_remove_notify_handler(adev->handle, + ACPI_SYSTEM_NOTIFY, + handler); + if (ACPI_FAILURE(status)) + goto out; + + adev->wakeup.flags.notifier_present = false; + + out: + mutex_unlock(&acpi_pm_notifier_lock); + return status; +} + bool acpi_bus_can_wakeup(acpi_handle handle) { struct acpi_device *device; @@ -1023,3 +1046,4 @@ void acpi_dev_pm_remove_dependent(acpi_handle handle, struct device *depdev) mutex_unlock(&adev->physical_node_lock); } EXPORT_SYMBOL_GPL(acpi_dev_pm_remove_dependent); +#endif /* CONFIG_PM */ diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 4fdea381ef21..ec117c6c996c 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -868,8 +868,10 @@ static ssize_t write_undock(struct device *dev, struct device_attribute *attr, if (!count) return -EINVAL; + acpi_scan_lock_acquire(); begin_undock(dock_station); ret = handle_eject_request(dock_station, ACPI_NOTIFY_EJECT_REQUEST); + acpi_scan_lock_release(); return ret ? ret: count; } static DEVICE_ATTR(undock, S_IWUSR, NULL, write_undock); diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 6f1afd9118c8..297cbf456f86 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -35,7 +35,6 @@ void acpi_pci_link_init(void); void acpi_pci_root_hp_init(void); void acpi_platform_init(void); int acpi_sysfs_init(void); -void acpi_csrt_init(void); #ifdef CONFIG_ACPI_CONTAINER void acpi_container_init(void); #else diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index f962047c6c85..288bb270f8ed 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c @@ -885,6 +885,7 @@ int acpi_add_power_resource(acpi_handle handle) ACPI_STA_DEFAULT); mutex_init(&resource->resource_lock); INIT_LIST_HEAD(&resource->dependent); + INIT_LIST_HEAD(&resource->list_node); resource->name = device->pnp.bus_id; strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME); strcpy(acpi_device_class(device), ACPI_POWER_CLASS); diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index a3868f6c222a..3322b47ab7ca 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c @@ -304,7 +304,8 @@ static void acpi_dev_irqresource_disabled(struct resource *res, u32 gsi) } static void acpi_dev_get_irqresource(struct resource *res, u32 gsi, - u8 triggering, u8 polarity, u8 shareable) + u8 triggering, u8 polarity, u8 shareable, + bool legacy) { int irq, p, t; @@ -317,14 +318,19 @@ static void acpi_dev_get_irqresource(struct resource *res, u32 gsi, * In IO-APIC mode, use overrided attribute. Two reasons: * 1. BIOS bug in DSDT * 2. BIOS uses IO-APIC mode Interrupt Source Override + * + * We do this only if we are dealing with IRQ() or IRQNoFlags() + * resource (the legacy ISA resources). With modern ACPI 5 devices + * using extended IRQ descriptors we take the IRQ configuration + * from _CRS directly. */ - if (!acpi_get_override_irq(gsi, &t, &p)) { + if (legacy && !acpi_get_override_irq(gsi, &t, &p)) { u8 trig = t ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE; u8 pol = p ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH; if (triggering != trig || polarity != pol) { pr_warning("ACPI: IRQ %d override to %s, %s\n", gsi, - t ? "edge" : "level", p ? "low" : "high"); + t ? "level" : "edge", p ? "low" : "high"); triggering = trig; polarity = pol; } @@ -373,7 +379,7 @@ bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index, } acpi_dev_get_irqresource(res, irq->interrupts[index], irq->triggering, irq->polarity, - irq->sharable); + irq->sharable, true); break; case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: ext_irq = &ares->data.extended_irq; @@ -383,7 +389,7 @@ bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index, } acpi_dev_get_irqresource(res, ext_irq->interrupts[index], ext_irq->triggering, ext_irq->polarity, - ext_irq->sharable); + ext_irq->sharable, false); break; default: return false; diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index c1bc608339a6..b14ac46948c9 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -1017,11 +1017,8 @@ acpi_bus_driver_init(struct acpi_device *device, struct acpi_driver *driver) return -ENOSYS; result = driver->ops.add(device); - if (result) { - device->driver = NULL; - device->driver_data = NULL; + if (result) return result; - } device->driver = driver; @@ -2043,7 +2040,6 @@ int __init acpi_scan_init(void) acpi_pci_link_init(); acpi_platform_init(); acpi_lpss_init(); - acpi_csrt_init(); acpi_container_init(); acpi_memory_hotplug_init(); diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 5b32e15a65ce..440eadf2d32c 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -458,12 +458,28 @@ static struct dmi_system_id video_dmi_table[] __initdata = { }, { .callback = video_ignore_initial_backlight, + .ident = "HP Pavilion g6 Notebook PC", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion g6 Notebook PC"), + }, + }, + { + .callback = video_ignore_initial_backlight, .ident = "HP 1000 Notebook PC", .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), DMI_MATCH(DMI_PRODUCT_NAME, "HP 1000 Notebook PC"), }, }, + { + .callback = video_ignore_initial_backlight, + .ident = "HP Pavilion m4", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion m4 Notebook PC"), + }, + }, {} }; @@ -1706,6 +1722,9 @@ static int acpi_video_bus_add(struct acpi_device *device) int error; acpi_status status; + if (device->handler) + return -EINVAL; + status = acpi_walk_namespace(ACPI_TYPE_DEVICE, device->parent->handle, 1, acpi_video_bus_match, NULL, diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index 66f67626f02e..e6bd910bc6ed 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -161,6 +161,14 @@ static struct dmi_system_id video_detect_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "UL30VT"), }, }, + { + .callback = video_detect_force_vendor, + .ident = "Asus UL30A", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "UL30A"), + }, + }, { }, }; diff --git a/drivers/ata/acard-ahci.c b/drivers/ata/acard-ahci.c index 4e94ba29cb8d..9d0cf019ce59 100644 --- a/drivers/ata/acard-ahci.c +++ b/drivers/ata/acard-ahci.c @@ -2,7 +2,7 @@ /* * acard-ahci.c - ACard AHCI SATA support * - * Maintained by: Jeff Garzik <jgarzik@pobox.com> + * Maintained by: Tejun Heo <tj@kernel.org> * Please ALWAYS copy linux-ide@vger.kernel.org * on emails. * diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 251e57d38942..2b50dfdf1cfc 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -1,7 +1,7 @@ /* * ahci.c - AHCI SATA support * - * Maintained by: Jeff Garzik <jgarzik@pobox.com> + * Maintained by: Tejun Heo <tj@kernel.org> * Please ALWAYS copy linux-ide@vger.kernel.org * on emails. * @@ -423,6 +423,8 @@ static const struct pci_device_id ahci_pci_tbl[] = { .driver_data = board_ahci_yes_fbs }, /* 88se9125 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x917a), .driver_data = board_ahci_yes_fbs }, /* 88se9172 */ + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9172), + .driver_data = board_ahci_yes_fbs }, /* 88se9172 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9192), .driver_data = board_ahci_yes_fbs }, /* 88se9172 on some Gigabyte */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x91a3), diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index b830e6c9fe49..10b14d45cfd2 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h @@ -1,7 +1,7 @@ /* * ahci.h - Common AHCI SATA definitions and declarations * - * Maintained by: Jeff Garzik <jgarzik@pobox.com> + * Maintained by: Tejun Heo <tj@kernel.org> * Please ALWAYS copy linux-ide@vger.kernel.org * on emails. * diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 2f48123d74c4..9a8a674e8fac 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -1,7 +1,7 @@ /* * ata_piix.c - Intel PATA/SATA controllers * - * Maintained by: Jeff Garzik <jgarzik@pobox.com> + * Maintained by: Tejun Heo <tj@kernel.org> * Please ALWAYS copy linux-ide@vger.kernel.org * on emails. * @@ -151,6 +151,7 @@ enum piix_controller_ids { piix_pata_vmw, /* PIIX4 for VMware, spurious DMA_ERR */ ich8_sata_snb, ich8_2port_sata_snb, + ich8_2port_sata_byt, }; struct piix_map_db { @@ -334,6 +335,9 @@ static const struct pci_device_id piix_pci_tbl[] = { { 0x8086, 0x8d60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb }, /* SATA Controller IDE (Wellsburg) */ { 0x8086, 0x8d68, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, + /* SATA Controller IDE (BayTrail) */ + { 0x8086, 0x0F20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata_byt }, + { 0x8086, 0x0F21, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata_byt }, { } /* terminate list */ }; @@ -441,6 +445,7 @@ static const struct piix_map_db *piix_map_db_table[] = { [tolapai_sata] = &tolapai_map_db, [ich8_sata_snb] = &ich8_map_db, [ich8_2port_sata_snb] = &ich8_2port_map_db, + [ich8_2port_sata_byt] = &ich8_2port_map_db, }; static struct pci_bits piix_enable_bits[] = { @@ -1254,6 +1259,16 @@ static struct ata_port_info piix_port_info[] = { .udma_mask = ATA_UDMA6, .port_ops = &piix_sata_ops, }, + + [ich8_2port_sata_byt] = + { + .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SIDPR | PIIX_FLAG_PIO16, + .pio_mask = ATA_PIO4, + .mwdma_mask = ATA_MWDMA2, + .udma_mask = ATA_UDMA6, + .port_ops = &piix_sata_ops, + }, + }; #define AHCI_PCI_BAR 5 diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 34c82167b962..a70ff154f586 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c @@ -1,7 +1,7 @@ /* * libahci.c - Common AHCI SATA low-level routines * - * Maintained by: Jeff Garzik <jgarzik@pobox.com> + * Maintained by: Tejun Heo <tj@kernel.org> * Please ALWAYS copy linux-ide@vger.kernel.org * on emails. * diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 63c743baf920..f2184276539d 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -1,7 +1,7 @@ /* * libata-core.c - helper library for ATA * - * Maintained by: Jeff Garzik <jgarzik@pobox.com> + * Maintained by: Tejun Heo <tj@kernel.org> * Please ALWAYS copy linux-ide@vger.kernel.org * on emails. * @@ -1602,6 +1602,12 @@ unsigned ata_exec_internal_sg(struct ata_device *dev, qc->tf = *tf; if (cdb) memcpy(qc->cdb, cdb, ATAPI_CDB_LEN); + + /* some SATA bridges need us to indicate data xfer direction */ + if (tf->protocol == ATAPI_PROT_DMA && (dev->flags & ATA_DFLAG_DMADIR) && + dma_dir == DMA_FROM_DEVICE) + qc->tf.feature |= ATAPI_DMADIR; + qc->flags |= ATA_QCFLAG_RESULT_TF; qc->dma_dir = dma_dir; if (dma_dir != DMA_NONE) { diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index f9476fb3ac43..c69fcce505c0 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -1,7 +1,7 @@ /* * libata-eh.c - libata error handling * - * Maintained by: Jeff Garzik <jgarzik@pobox.com> + * Maintained by: Tejun Heo <tj@kernel.org> * Please ALWAYS copy linux-ide@vger.kernel.org * on emails. * diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index dd310b27b24c..0101af541436 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -1,7 +1,7 @@ /* * libata-scsi.c - helper library for ATA * - * Maintained by: Jeff Garzik <jgarzik@pobox.com> + * Maintained by: Tejun Heo <tj@kernel.org> * Please ALWAYS copy linux-ide@vger.kernel.org * on emails. * diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index d8af325a6bda..b603720b877d 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -1,7 +1,7 @@ /* * libata-sff.c - helper library for PCI IDE BMDMA * - * Maintained by: Jeff Garzik <jgarzik@pobox.com> + * Maintained by: Tejun Heo <tj@kernel.org> * Please ALWAYS copy linux-ide@vger.kernel.org * on emails. * diff --git a/drivers/ata/pdc_adma.c b/drivers/ata/pdc_adma.c index 505333340ad5..8ea6e6afd041 100644 --- a/drivers/ata/pdc_adma.c +++ b/drivers/ata/pdc_adma.c @@ -1,7 +1,7 @@ /* * pdc_adma.c - Pacific Digital Corporation ADMA * - * Maintained by: Mark Lord <mlord@pobox.com> + * Maintained by: Tejun Heo <tj@kernel.org> * * Copyright 2005 Mark Lord * diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c index fb0dd87f8893..958ba2a420c3 100644 --- a/drivers/ata/sata_promise.c +++ b/drivers/ata/sata_promise.c @@ -1,7 +1,7 @@ /* * sata_promise.c - Promise SATA * - * Maintained by: Jeff Garzik <jgarzik@pobox.com> + * Maintained by: Tejun Heo <tj@kernel.org> * Mikael Pettersson <mikpe@it.uu.se> * Please ALWAYS copy linux-ide@vger.kernel.org * on emails. diff --git a/drivers/ata/sata_rcar.c b/drivers/ata/sata_rcar.c index 4799868bd733..249c8a289bfd 100644 --- a/drivers/ata/sata_rcar.c +++ b/drivers/ata/sata_rcar.c @@ -549,6 +549,7 @@ static void sata_rcar_bmdma_start(struct ata_queued_cmd *qc) /* start host DMA transaction */ dmactl = ioread32(priv->base + ATAPI_CONTROL1_REG); + dmactl &= ~ATAPI_CONTROL1_STOP; dmactl |= ATAPI_CONTROL1_START; iowrite32(dmactl, priv->base + ATAPI_CONTROL1_REG); } @@ -618,17 +619,16 @@ static struct ata_port_operations sata_rcar_port_ops = { .bmdma_status = sata_rcar_bmdma_status, }; -static int sata_rcar_serr_interrupt(struct ata_port *ap) +static void sata_rcar_serr_interrupt(struct ata_port *ap) { struct sata_rcar_priv *priv = ap->host->private_data; struct ata_eh_info *ehi = &ap->link.eh_info; int freeze = 0; - int handled = 0; u32 serror; serror = ioread32(priv->base + SCRSERR_REG); if (!serror) - return 0; + return; DPRINTK("SError @host_intr: 0x%x\n", serror); @@ -641,7 +641,6 @@ static int sata_rcar_serr_interrupt(struct ata_port *ap) ata_ehi_push_desc(ehi, "%s", "hotplug"); freeze = serror & SERR_COMM_WAKE ? 0 : 1; - handled = 1; } /* freeze or abort */ @@ -649,11 +648,9 @@ static int sata_rcar_serr_interrupt(struct ata_port *ap) ata_port_freeze(ap); else ata_port_abort(ap); - - return handled; } -static int sata_rcar_ata_interrupt(struct ata_port *ap) +static void sata_rcar_ata_interrupt(struct ata_port *ap) { struct ata_queued_cmd *qc; int handled = 0; @@ -662,7 +659,9 @@ static int sata_rcar_ata_interrupt(struct ata_port *ap) if (qc) handled |= ata_bmdma_port_intr(ap, qc); - return handled; + /* be sure to clear ATA interrupt */ + if (!handled) + sata_rcar_check_status(ap); } static irqreturn_t sata_rcar_interrupt(int irq, void *dev_instance) @@ -677,20 +676,21 @@ static irqreturn_t sata_rcar_interrupt(int irq, void *dev_instance) spin_lock_irqsave(&host->lock, flags); sataintstat = ioread32(priv->base + SATAINTSTAT_REG); + sataintstat &= SATA_RCAR_INT_MASK; if (!sataintstat) goto done; /* ack */ - iowrite32(sataintstat & ~SATA_RCAR_INT_MASK, - priv->base + SATAINTSTAT_REG); + iowrite32(~sataintstat & 0x7ff, priv->base + SATAINTSTAT_REG); ap = host->ports[0]; if (sataintstat & SATAINTSTAT_ATA) - handled |= sata_rcar_ata_interrupt(ap); + sata_rcar_ata_interrupt(ap); if (sataintstat & SATAINTSTAT_SERR) - handled |= sata_rcar_serr_interrupt(ap); + sata_rcar_serr_interrupt(ap); + handled = 1; done: spin_unlock_irqrestore(&host->lock, flags); diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c index a7b31672c4b7..0ae3ca4bf5c0 100644 --- a/drivers/ata/sata_sil.c +++ b/drivers/ata/sata_sil.c @@ -1,7 +1,7 @@ /* * sata_sil.c - Silicon Image SATA * - * Maintained by: Jeff Garzik <jgarzik@pobox.com> + * Maintained by: Tejun Heo <tj@kernel.org> * Please ALWAYS copy linux-ide@vger.kernel.org * on emails. * diff --git a/drivers/ata/sata_sx4.c b/drivers/ata/sata_sx4.c index 7b7127a58f51..9947010afc0f 100644 --- a/drivers/ata/sata_sx4.c +++ b/drivers/ata/sata_sx4.c @@ -1,7 +1,7 @@ /* * sata_sx4.c - Promise SATA * - * Maintained by: Jeff Garzik <jgarzik@pobox.com> + * Maintained by: Tejun Heo <tj@kernel.org> * Please ALWAYS copy linux-ide@vger.kernel.org * on emails. * diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c index 5913ea9d57b2..87f056e54a9d 100644 --- a/drivers/ata/sata_via.c +++ b/drivers/ata/sata_via.c @@ -1,7 +1,7 @@ /* * sata_via.c - VIA Serial ATA controllers * - * Maintained by: Jeff Garzik <jgarzik@pobox.com> + * Maintained by: Tejun Heo <tj@kernel.org> * Please ALWAYS copy linux-ide@vger.kernel.org * on emails. * diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 4b1f9265887f..01e21037d8fe 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -450,8 +450,18 @@ static void fw_load_abort(struct firmware_priv *fw_priv) { struct firmware_buf *buf = fw_priv->buf; + /* + * There is a small window in which user can write to 'loading' + * between loading done and disappearance of 'loading' + */ + if (test_bit(FW_STATUS_DONE, &buf->status)) + return; + set_bit(FW_STATUS_ABORT, &buf->status); complete_all(&buf->completion); + + /* avoid user action after loading abort */ + fw_priv->buf = NULL; } #define is_fw_load_aborted(buf) \ @@ -528,7 +538,12 @@ static ssize_t firmware_loading_show(struct device *dev, struct device_attribute *attr, char *buf) { struct firmware_priv *fw_priv = to_firmware_priv(dev); - int loading = test_bit(FW_STATUS_LOADING, &fw_priv->buf->status); + int loading = 0; + + mutex_lock(&fw_lock); + if (fw_priv->buf) + loading = test_bit(FW_STATUS_LOADING, &fw_priv->buf->status); + mutex_unlock(&fw_lock); return sprintf(buf, "%d\n", loading); } @@ -570,12 +585,12 @@ static ssize_t firmware_loading_store(struct device *dev, const char *buf, size_t count) { struct firmware_priv *fw_priv = to_firmware_priv(dev); - struct firmware_buf *fw_buf = fw_priv->buf; + struct firmware_buf *fw_buf; int loading = simple_strtol(buf, NULL, 10); int i; mutex_lock(&fw_lock); - + fw_buf = fw_priv->buf; if (!fw_buf) goto out; @@ -777,10 +792,6 @@ static void firmware_class_timeout_work(struct work_struct *work) struct firmware_priv, timeout_work.work); mutex_lock(&fw_lock); - if (test_bit(FW_STATUS_DONE, &(fw_priv->buf->status))) { - mutex_unlock(&fw_lock); - return; - } fw_load_abort(fw_priv); mutex_unlock(&fw_lock); } @@ -861,8 +872,6 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent, cancel_delayed_work_sync(&fw_priv->timeout_work); - fw_priv->buf = NULL; - device_remove_file(f_dev, &dev_attr_loading); err_del_bin_attr: device_remove_bin_file(f_dev, &firmware_attr_data); diff --git a/drivers/base/regmap/regcache-rbtree.c b/drivers/base/regmap/regcache-rbtree.c index aa0875f6f1b7..02f490bad30f 100644 --- a/drivers/base/regmap/regcache-rbtree.c +++ b/drivers/base/regmap/regcache-rbtree.c @@ -143,7 +143,7 @@ static int rbtree_show(struct seq_file *s, void *ignored) int registers = 0; int this_registers, average; - map->lock(map); + map->lock(map->lock_arg); mem_size = sizeof(*rbtree_ctx); mem_size += BITS_TO_LONGS(map->cache_present_nbits) * sizeof(long); @@ -170,7 +170,7 @@ static int rbtree_show(struct seq_file *s, void *ignored) seq_printf(s, "%d nodes, %d registers, average %d registers, used %zu bytes\n", nodes, registers, average, mem_size); - map->unlock(map); + map->unlock(map->lock_arg); return 0; } @@ -391,8 +391,6 @@ static int regcache_rbtree_sync(struct regmap *map, unsigned int min, for (node = rb_first(&rbtree_ctx->root); node; node = rb_next(node)) { rbnode = rb_entry(node, struct regcache_rbtree_node, node); - if (rbnode->base_reg < min) - continue; if (rbnode->base_reg > max) break; if (rbnode->base_reg + rbnode->blklen < min) diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c index 75923f2396bd..507ee2da0f6e 100644 --- a/drivers/base/regmap/regcache.c +++ b/drivers/base/regmap/regcache.c @@ -270,7 +270,7 @@ int regcache_sync(struct regmap *map) BUG_ON(!map->cache_ops || !map->cache_ops->sync); - map->lock(map); + map->lock(map->lock_arg); /* Remember the initial bypass state */ bypass = map->cache_bypass; dev_dbg(map->dev, "Syncing %s cache\n", @@ -306,7 +306,7 @@ out: trace_regcache_sync(map->dev, name, "stop"); /* Restore the bypass state */ map->cache_bypass = bypass; - map->unlock(map); + map->unlock(map->lock_arg); return ret; } @@ -333,7 +333,7 @@ int regcache_sync_region(struct regmap *map, unsigned int min, BUG_ON(!map->cache_ops || !map->cache_ops->sync); - map->lock(map); + map->lock(map->lock_arg); /* Remember the initial bypass state */ bypass = map->cache_bypass; @@ -352,7 +352,7 @@ out: trace_regcache_sync(map->dev, name, "stop region"); /* Restore the bypass state */ map->cache_bypass = bypass; - map->unlock(map); + map->unlock(map->lock_arg); return ret; } @@ -372,11 +372,11 @@ EXPORT_SYMBOL_GPL(regcache_sync_region); */ void regcache_cache_only(struct regmap *map, bool enable) { - map->lock(map); + map->lock(map->lock_arg); WARN_ON(map->cache_bypass && enable); map->cache_only = enable; trace_regmap_cache_only(map->dev, enable); - map->unlock(map); + map->unlock(map->lock_arg); } EXPORT_SYMBOL_GPL(regcache_cache_only); @@ -391,9 +391,9 @@ EXPORT_SYMBOL_GPL(regcache_cache_only); */ void regcache_mark_dirty(struct regmap *map) { - map->lock(map); + map->lock(map->lock_arg); map->cache_dirty = true; - map->unlock(map); + map->unlock(map->lock_arg); } EXPORT_SYMBOL_GPL(regcache_mark_dirty); @@ -410,11 +410,11 @@ EXPORT_SYMBOL_GPL(regcache_mark_dirty); */ void regcache_cache_bypass(struct regmap *map, bool enable) { - map->lock(map); + map->lock(map->lock_arg); WARN_ON(map->cache_only && enable); map->cache_bypass = enable; trace_regmap_cache_bypass(map->dev, enable); - map->unlock(map); + map->unlock(map->lock_arg); } EXPORT_SYMBOL_GPL(regcache_cache_bypass); diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c index 23b701f5fd2f..975719bc3450 100644 --- a/drivers/base/regmap/regmap-debugfs.c +++ b/drivers/base/regmap/regmap-debugfs.c @@ -265,6 +265,7 @@ static ssize_t regmap_map_write_file(struct file *file, char *start = buf; unsigned long reg, value; struct regmap *map = file->private_data; + int ret; buf_size = min(count, (sizeof(buf)-1)); if (copy_from_user(buf, user_buf, buf_size)) @@ -282,7 +283,9 @@ static ssize_t regmap_map_write_file(struct file *file, /* Userspace has been fiddling around behind the kernel's back */ add_taint(TAINT_USER, LOCKDEP_NOW_UNRELIABLE); - regmap_write(map, reg, value); + ret = regmap_write(map, reg, value); + if (ret < 0) + return ret; return buf_size; } #else diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c index bca9c80056fe..8bffa5c9818c 100644 --- a/drivers/bcma/scan.c +++ b/drivers/bcma/scan.c @@ -84,6 +84,8 @@ static const struct bcma_device_id_name bcma_bcm_device_names[] = { { BCMA_CORE_I2S, "I2S" }, { BCMA_CORE_SDR_DDR1_MEM_CTL, "SDR/DDR1 Memory Controller" }, { BCMA_CORE_SHIM, "SHIM" }, + { BCMA_CORE_PCIE2, "PCIe Gen2" }, + { BCMA_CORE_ARM_CR4, "ARM CR4" }, { BCMA_CORE_DEFAULT, "Default" }, }; diff --git a/drivers/block/brd.c b/drivers/block/brd.c index f1a29f8e9d33..9bf4371755f2 100644 --- a/drivers/block/brd.c +++ b/drivers/block/brd.c @@ -117,13 +117,13 @@ static struct page *brd_insert_page(struct brd_device *brd, sector_t sector) spin_lock(&brd->brd_lock); idx = sector >> PAGE_SECTORS_SHIFT; + page->index = idx; if (radix_tree_insert(&brd->brd_pages, idx, page)) { __free_page(page); page = radix_tree_lookup(&brd->brd_pages, idx); BUG_ON(!page); BUG_ON(page->index != idx); - } else - page->index = idx; + } spin_unlock(&brd->brd_lock); radix_tree_preload_end(); diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 6374dc103521..62b6c2cc80b5 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -168,8 +168,6 @@ static irqreturn_t do_cciss_msix_intr(int irq, void *dev_id); static int cciss_open(struct block_device *bdev, fmode_t mode); static int cciss_unlocked_open(struct block_device *bdev, fmode_t mode); static void cciss_release(struct gendisk *disk, fmode_t mode); -static int do_ioctl(struct block_device *bdev, fmode_t mode, - unsigned int cmd, unsigned long arg); static int cciss_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg); static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo); @@ -235,7 +233,7 @@ static const struct block_device_operations cciss_fops = { .owner = THIS_MODULE, .open = cciss_unlocked_open, .release = cciss_release, - .ioctl = do_ioctl, + .ioctl = cciss_ioctl, .getgeo = cciss_getgeo, #ifdef CONFIG_COMPAT .compat_ioctl = cciss_compat_ioctl, @@ -1143,16 +1141,6 @@ static void cciss_release(struct gendisk *disk, fmode_t mode) mutex_unlock(&cciss_mutex); } -static int do_ioctl(struct block_device *bdev, fmode_t mode, - unsigned cmd, unsigned long arg) -{ - int ret; - mutex_lock(&cciss_mutex); - ret = cciss_ioctl(bdev, mode, cmd, arg); - mutex_unlock(&cciss_mutex); - return ret; -} - #ifdef CONFIG_COMPAT static int cciss_ioctl32_passthru(struct block_device *bdev, fmode_t mode, @@ -1179,7 +1167,7 @@ static int cciss_compat_ioctl(struct block_device *bdev, fmode_t mode, case CCISS_REGNEWD: case CCISS_RESCANDISK: case CCISS_GETLUNINFO: - return do_ioctl(bdev, mode, cmd, arg); + return cciss_ioctl(bdev, mode, cmd, arg); case CCISS_PASSTHRU32: return cciss_ioctl32_passthru(bdev, mode, cmd, arg); @@ -1219,7 +1207,7 @@ static int cciss_ioctl32_passthru(struct block_device *bdev, fmode_t mode, if (err) return -EFAULT; - err = do_ioctl(bdev, mode, CCISS_PASSTHRU, (unsigned long)p); + err = cciss_ioctl(bdev, mode, CCISS_PASSTHRU, (unsigned long)p); if (err) return err; err |= @@ -1261,7 +1249,7 @@ static int cciss_ioctl32_big_passthru(struct block_device *bdev, fmode_t mode, if (err) return -EFAULT; - err = do_ioctl(bdev, mode, CCISS_BIG_PASSTHRU, (unsigned long)p); + err = cciss_ioctl(bdev, mode, CCISS_BIG_PASSTHRU, (unsigned long)p); if (err) return err; err |= @@ -1311,11 +1299,14 @@ static int cciss_getpciinfo(ctlr_info_t *h, void __user *argp) static int cciss_getintinfo(ctlr_info_t *h, void __user *argp) { cciss_coalint_struct intinfo; + unsigned long flags; if (!argp) return -EINVAL; + spin_lock_irqsave(&h->lock, flags); intinfo.delay = readl(&h->cfgtable->HostWrite.CoalIntDelay); intinfo.count = readl(&h->cfgtable->HostWrite.CoalIntCount); + spin_unlock_irqrestore(&h->lock, flags); if (copy_to_user (argp, &intinfo, sizeof(cciss_coalint_struct))) return -EFAULT; @@ -1356,12 +1347,15 @@ static int cciss_setintinfo(ctlr_info_t *h, void __user *argp) static int cciss_getnodename(ctlr_info_t *h, void __user *argp) { NodeName_type NodeName; + unsigned long flags; int i; if (!argp) return -EINVAL; + spin_lock_irqsave(&h->lock, flags); for (i = 0; i < 16; i++) NodeName[i] = readb(&h->cfgtable->ServerName[i]); + spin_unlock_irqrestore(&h->lock, flags); if (copy_to_user(argp, NodeName, sizeof(NodeName_type))) return -EFAULT; return 0; @@ -1398,10 +1392,13 @@ static int cciss_setnodename(ctlr_info_t *h, void __user *argp) static int cciss_getheartbeat(ctlr_info_t *h, void __user *argp) { Heartbeat_type heartbeat; + unsigned long flags; if (!argp) return -EINVAL; + spin_lock_irqsave(&h->lock, flags); heartbeat = readl(&h->cfgtable->HeartBeat); + spin_unlock_irqrestore(&h->lock, flags); if (copy_to_user(argp, &heartbeat, sizeof(Heartbeat_type))) return -EFAULT; return 0; @@ -1410,10 +1407,13 @@ static int cciss_getheartbeat(ctlr_info_t *h, void __user *argp) static int cciss_getbustypes(ctlr_info_t *h, void __user *argp) { BusTypes_type BusTypes; + unsigned long flags; if (!argp) return -EINVAL; + spin_lock_irqsave(&h->lock, flags); BusTypes = readl(&h->cfgtable->BusTypes); + spin_unlock_irqrestore(&h->lock, flags); if (copy_to_user(argp, &BusTypes, sizeof(BusTypes_type))) return -EFAULT; return 0; diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index 847107ef0cce..20dd52a2f92f 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c @@ -3002,7 +3002,8 @@ static int mtip_hw_debugfs_init(struct driver_data *dd) static void mtip_hw_debugfs_exit(struct driver_data *dd) { - debugfs_remove_recursive(dd->dfs_node); + if (dd->dfs_node) + debugfs_remove_recursive(dd->dfs_node); } @@ -3863,7 +3864,7 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio) struct driver_data *dd = queue->queuedata; struct scatterlist *sg; struct bio_vec *bvec; - int nents = 0; + int i, nents = 0; int tag = 0, unaligned = 0; if (unlikely(dd->dd_flag & MTIP_DDF_STOP_IO)) { @@ -3921,11 +3922,12 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio) } /* Create the scatter list for this bio. */ - bio_for_each_segment(bvec, bio, nents) { + bio_for_each_segment(bvec, bio, i) { sg_set_page(&sg[nents], bvec->bv_page, bvec->bv_len, bvec->bv_offset); + nents++; } /* Issue the read/write. */ diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index 8efdfaa44a59..ce79a590b45b 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -629,7 +629,7 @@ static int nvme_submit_bio_queue(struct nvme_queue *nvmeq, struct nvme_ns *ns, struct nvme_command *cmnd; struct nvme_iod *iod; enum dma_data_direction dma_dir; - int cmdid, length, result = -ENOMEM; + int cmdid, length, result; u16 control; u32 dsmgmt; int psegs = bio_phys_segments(ns->queue, bio); @@ -640,6 +640,7 @@ static int nvme_submit_bio_queue(struct nvme_queue *nvmeq, struct nvme_ns *ns, return result; } + result = -ENOMEM; iod = nvme_alloc_iod(psegs, bio->bi_size, GFP_ATOMIC); if (!iod) goto nomem; @@ -977,6 +978,8 @@ static void nvme_cancel_ios(struct nvme_queue *nvmeq, bool timeout) if (timeout && !time_after(now, info[cmdid].timeout)) continue; + if (info[cmdid].ctx == CMD_CTX_CANCELLED) + continue; dev_warn(nvmeq->q_dmadev, "Cancelling I/O %d\n", cmdid); ctx = cancel_cmdid(nvmeq, cmdid, &fn); fn(nvmeq->dev, ctx, &cqe); @@ -1206,7 +1209,7 @@ struct nvme_iod *nvme_map_user_pages(struct nvme_dev *dev, int write, if (addr & 3) return ERR_PTR(-EINVAL); - if (!length) + if (!length || length > INT_MAX - PAGE_SIZE) return ERR_PTR(-EINVAL); offset = offset_in_page(addr); @@ -1227,7 +1230,8 @@ struct nvme_iod *nvme_map_user_pages(struct nvme_dev *dev, int write, sg_init_table(sg, count); for (i = 0; i < count; i++) { sg_set_page(&sg[i], pages[i], - min_t(int, length, PAGE_SIZE - offset), offset); + min_t(unsigned, length, PAGE_SIZE - offset), + offset); length -= (PAGE_SIZE - offset); offset = 0; } @@ -1435,7 +1439,7 @@ static int nvme_user_admin_cmd(struct nvme_dev *dev, nvme_free_iod(dev, iod); } - if (!status && copy_to_user(&ucmd->result, &cmd.result, + if ((status >= 0) && copy_to_user(&ucmd->result, &cmd.result, sizeof(cmd.result))) status = -EFAULT; @@ -1633,7 +1637,8 @@ static int set_queue_count(struct nvme_dev *dev, int count) static int nvme_setup_io_queues(struct nvme_dev *dev) { - int result, cpu, i, nr_io_queues, db_bar_size, q_depth; + struct pci_dev *pdev = dev->pci_dev; + int result, cpu, i, nr_io_queues, db_bar_size, q_depth, q_count; nr_io_queues = num_online_cpus(); result = set_queue_count(dev, nr_io_queues); @@ -1642,14 +1647,14 @@ static int nvme_setup_io_queues(struct nvme_dev *dev) if (result < nr_io_queues) nr_io_queues = result; + q_count = nr_io_queues; /* Deregister the admin queue's interrupt */ free_irq(dev->entry[0].vector, dev->queues[0]); db_bar_size = 4096 + ((nr_io_queues + 1) << (dev->db_stride + 3)); if (db_bar_size > 8192) { iounmap(dev->bar); - dev->bar = ioremap(pci_resource_start(dev->pci_dev, 0), - db_bar_size); + dev->bar = ioremap(pci_resource_start(pdev, 0), db_bar_size); dev->dbs = ((void __iomem *)dev->bar) + 4096; dev->queues[0]->q_db = dev->dbs; } @@ -1657,19 +1662,36 @@ static int nvme_setup_io_queues(struct nvme_dev *dev) for (i = 0; i < nr_io_queues; i++) dev->entry[i].entry = i; for (;;) { - result = pci_enable_msix(dev->pci_dev, dev->entry, - nr_io_queues); + result = pci_enable_msix(pdev, dev->entry, nr_io_queues); if (result == 0) { break; } else if (result > 0) { nr_io_queues = result; continue; } else { - nr_io_queues = 1; + nr_io_queues = 0; break; } } + if (nr_io_queues == 0) { + nr_io_queues = q_count; + for (;;) { + result = pci_enable_msi_block(pdev, nr_io_queues); + if (result == 0) { + for (i = 0; i < nr_io_queues; i++) + dev->entry[i].vector = i + pdev->irq; + break; + } else if (result > 0) { + nr_io_queues = result; + continue; + } else { + nr_io_queues = 1; + break; + } + } + } + result = queue_request_irq(dev, dev->queues[0], "nvme admin"); /* XXX: handle failure here */ @@ -1850,7 +1872,10 @@ static void nvme_free_dev(struct kref *kref) { struct nvme_dev *dev = container_of(kref, struct nvme_dev, kref); nvme_dev_remove(dev); - pci_disable_msix(dev->pci_dev); + if (dev->pci_dev->msi_enabled) + pci_disable_msi(dev->pci_dev); + else if (dev->pci_dev->msix_enabled) + pci_disable_msix(dev->pci_dev); iounmap(dev->bar); nvme_release_instance(dev); nvme_release_prp_pools(dev); @@ -1923,8 +1948,14 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) INIT_LIST_HEAD(&dev->namespaces); dev->pci_dev = pdev; pci_set_drvdata(pdev, dev); - dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)); - dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64)); + + if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(64))) + dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64)); + else if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))) + dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); + else + goto disable; + result = nvme_set_instance(dev); if (result) goto disable; @@ -1977,7 +2008,10 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) unmap: iounmap(dev->bar); disable_msix: - pci_disable_msix(pdev); + if (dev->pci_dev->msi_enabled) + pci_disable_msi(dev->pci_dev); + else if (dev->pci_dev->msix_enabled) + pci_disable_msix(dev->pci_dev); nvme_release_instance(dev); nvme_release_prp_pools(dev); disable: diff --git a/drivers/block/nvme-scsi.c b/drivers/block/nvme-scsi.c index fed54b039893..102de2f52b5c 100644 --- a/drivers/block/nvme-scsi.c +++ b/drivers/block/nvme-scsi.c @@ -44,7 +44,6 @@ #include <linux/sched.h> #include <linux/slab.h> #include <linux/types.h> -#include <linux/version.h> #include <scsi/sg.h> #include <scsi/scsi.h> @@ -1654,7 +1653,7 @@ static void nvme_trans_modesel_save_bd(struct nvme_ns *ns, u8 *parm_list, } } -static u16 nvme_trans_modesel_get_mp(struct nvme_ns *ns, struct sg_io_hdr *hdr, +static int nvme_trans_modesel_get_mp(struct nvme_ns *ns, struct sg_io_hdr *hdr, u8 *mode_page, u8 page_code) { int res = SNTI_TRANSLATION_SUCCESS; diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 3c08983e600a..f5d0ea11d9fd 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c @@ -83,7 +83,8 @@ #define MAX_SPEED 0xffff -#define ZONE(sector, pd) (((sector) + (pd)->offset) & ~((pd)->settings.size - 1)) +#define ZONE(sector, pd) (((sector) + (pd)->offset) & \ + ~(sector_t)((pd)->settings.size - 1)) static DEFINE_MUTEX(pktcdvd_mutex); static struct pktcdvd_device *pkt_devs[MAX_WRITERS]; diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index d6d314027b5d..49394e3f31bc 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -519,8 +519,8 @@ static const struct block_device_operations rbd_bd_ops = { }; /* - * Initialize an rbd client instance. - * We own *ceph_opts. + * Initialize an rbd client instance. Success or not, this function + * consumes ceph_opts. */ static struct rbd_client *rbd_client_create(struct ceph_options *ceph_opts) { @@ -675,7 +675,8 @@ static int parse_rbd_opts_token(char *c, void *private) /* * Get a ceph client with specific addr and configuration, if one does - * not exist create it. + * not exist create it. Either way, ceph_opts is consumed by this + * function. */ static struct rbd_client *rbd_get_client(struct ceph_options *ceph_opts) { @@ -1035,12 +1036,16 @@ static const char *rbd_segment_name(struct rbd_device *rbd_dev, u64 offset) char *name; u64 segment; int ret; + char *name_format; name = kmem_cache_alloc(rbd_segment_name_cache, GFP_NOIO); if (!name) return NULL; segment = offset >> rbd_dev->header.obj_order; - ret = snprintf(name, MAX_OBJ_NAME_SIZE + 1, "%s.%012llx", + name_format = "%s.%012llx"; + if (rbd_dev->image_format == 2) + name_format = "%s.%016llx"; + ret = snprintf(name, MAX_OBJ_NAME_SIZE + 1, name_format, rbd_dev->header.object_prefix, segment); if (ret < 0 || ret > MAX_OBJ_NAME_SIZE) { pr_err("error formatting segment name for #%llu (%d)\n", @@ -4697,8 +4702,10 @@ out: return ret; } -/* Undo whatever state changes are made by v1 or v2 image probe */ - +/* + * Undo whatever state changes are made by v1 or v2 header info + * call. + */ static void rbd_dev_unprobe(struct rbd_device *rbd_dev) { struct rbd_image_header *header; @@ -4902,9 +4909,10 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, bool mapping) int tmp; /* - * Get the id from the image id object. If it's not a - * format 2 image, we'll get ENOENT back, and we'll assume - * it's a format 1 image. + * Get the id from the image id object. Unless there's an + * error, rbd_dev->spec->image_id will be filled in with + * a dynamically-allocated string, and rbd_dev->image_format + * will be set to either 1 or 2. */ ret = rbd_dev_image_id(rbd_dev); if (ret) @@ -4992,7 +5000,6 @@ static ssize_t rbd_add(struct bus_type *bus, rc = PTR_ERR(rbdc); goto err_out_args; } - ceph_opts = NULL; /* rbd_dev client now owns this */ /* pick the pool */ osdc = &rbdc->client->osdc; @@ -5027,18 +5034,18 @@ static ssize_t rbd_add(struct bus_type *bus, rbd_dev->mapping.read_only = read_only; rc = rbd_dev_device_setup(rbd_dev); - if (!rc) - return count; + if (rc) { + rbd_dev_image_release(rbd_dev); + goto err_out_module; + } + + return count; - rbd_dev_image_release(rbd_dev); err_out_rbd_dev: rbd_dev_destroy(rbd_dev); err_out_client: rbd_put_client(rbdc); err_out_args: - if (ceph_opts) - ceph_destroy_options(ceph_opts); - kfree(rbd_opts); rbd_spec_put(spec); err_out_module: module_put(THIS_MODULE); diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c index f8ef15f37c5e..3fd130fdfbc1 100644 --- a/drivers/block/xsysace.c +++ b/drivers/block/xsysace.c @@ -1160,8 +1160,7 @@ static int ace_probe(struct platform_device *dev) dev_dbg(&dev->dev, "ace_probe(%p)\n", dev); /* device id and bus width */ - of_property_read_u32(dev->dev.of_node, "port-number", &id); - if (id < 0) + if (of_property_read_u32(dev->dev.of_node, "port-number", &id)) id = 0; if (of_find_property(dev->dev.of_node, "8-bit", NULL)) bus_width = ACE_BUS_WIDTH_8; diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig index fdfd61a2d523..11a6104a1e4f 100644 --- a/drivers/bluetooth/Kconfig +++ b/drivers/bluetooth/Kconfig @@ -201,7 +201,7 @@ config BT_MRVL The core driver to support Marvell Bluetooth devices. This driver is required if you want to support - Marvell Bluetooth devices, such as 8688/8787/8797. + Marvell Bluetooth devices, such as 8688/8787/8797/8897. Say Y here to compile Marvell Bluetooth driver into the kernel or say M to compile it as module. @@ -214,7 +214,7 @@ config BT_MRVL_SDIO The driver for Marvell Bluetooth chipsets with SDIO interface. This driver is required if you want to use Marvell Bluetooth - devices with SDIO interface. Currently SD8688/SD8787/SD8797 + devices with SDIO interface. Currently SD8688/SD8787/SD8797/SD8897 chipsets are supported. Say Y here to compile support for Marvell BT-over-SDIO driver diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c index c63488c54f4a..13693b7a0d5c 100644 --- a/drivers/bluetooth/btmrvl_sdio.c +++ b/drivers/bluetooth/btmrvl_sdio.c @@ -82,6 +82,23 @@ static const struct btmrvl_sdio_card_reg btmrvl_reg_87xx = { .io_port_2 = 0x7a, }; +static const struct btmrvl_sdio_card_reg btmrvl_reg_88xx = { + .cfg = 0x00, + .host_int_mask = 0x02, + .host_intstatus = 0x03, + .card_status = 0x50, + .sq_read_base_addr_a0 = 0x60, + .sq_read_base_addr_a1 = 0x61, + .card_revision = 0xbc, + .card_fw_status0 = 0xc0, + .card_fw_status1 = 0xc1, + .card_rx_len = 0xc2, + .card_rx_unit = 0xc3, + .io_port_0 = 0xd8, + .io_port_1 = 0xd9, + .io_port_2 = 0xda, +}; + static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = { .helper = "mrvl/sd8688_helper.bin", .firmware = "mrvl/sd8688.bin", @@ -103,6 +120,13 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8797 = { .sd_blksz_fw_dl = 256, }; +static const struct btmrvl_sdio_device btmrvl_sdio_sd8897 = { + .helper = NULL, + .firmware = "mrvl/sd8897_uapsta.bin", + .reg = &btmrvl_reg_88xx, + .sd_blksz_fw_dl = 256, +}; + static const struct sdio_device_id btmrvl_sdio_ids[] = { /* Marvell SD8688 Bluetooth device */ { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x9105), @@ -116,6 +140,9 @@ static const struct sdio_device_id btmrvl_sdio_ids[] = { /* Marvell SD8797 Bluetooth device */ { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x912A), .driver_data = (unsigned long) &btmrvl_sdio_sd8797 }, + /* Marvell SD8897 Bluetooth device */ + { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x912E), + .driver_data = (unsigned long) &btmrvl_sdio_sd8897 }, { } /* Terminating entry */ }; @@ -1194,3 +1221,4 @@ MODULE_FIRMWARE("mrvl/sd8688_helper.bin"); MODULE_FIRMWARE("mrvl/sd8688.bin"); MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin"); MODULE_FIRMWARE("mrvl/sd8797_uapsta.bin"); +MODULE_FIRMWARE("mrvl/sd8897_uapsta.bin"); diff --git a/drivers/char/random.c b/drivers/char/random.c index cd9a6211dcad..35487e8ded59 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -865,16 +865,24 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min, if (r->entropy_count / 8 < min + reserved) { nbytes = 0; } else { + int entropy_count, orig; +retry: + entropy_count = orig = ACCESS_ONCE(r->entropy_count); /* If limited, never pull more than available */ - if (r->limit && nbytes + reserved >= r->entropy_count / 8) - nbytes = r->entropy_count/8 - reserved; - - if (r->entropy_count / 8 >= nbytes + reserved) - r->entropy_count -= nbytes*8; - else - r->entropy_count = reserved; + if (r->limit && nbytes + reserved >= entropy_count / 8) + nbytes = entropy_count/8 - reserved; + + if (entropy_count / 8 >= nbytes + reserved) { + entropy_count -= nbytes*8; + if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig) + goto retry; + } else { + entropy_count = reserved; + if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig) + goto retry; + } - if (r->entropy_count < random_write_wakeup_thresh) + if (entropy_count < random_write_wakeup_thresh) wakeup_write = 1; } @@ -957,10 +965,23 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf, { ssize_t ret = 0, i; __u8 tmp[EXTRACT_SIZE]; + unsigned long flags; /* if last_data isn't primed, we need EXTRACT_SIZE extra bytes */ - if (fips_enabled && !r->last_data_init) - nbytes += EXTRACT_SIZE; + if (fips_enabled) { + spin_lock_irqsave(&r->lock, flags); + if (!r->last_data_init) { + r->last_data_init = true; + spin_unlock_irqrestore(&r->lock, flags); + trace_extract_entropy(r->name, EXTRACT_SIZE, + r->entropy_count, _RET_IP_); + xfer_secondary_pool(r, EXTRACT_SIZE); + extract_buf(r, tmp); + spin_lock_irqsave(&r->lock, flags); + memcpy(r->last_data, tmp, EXTRACT_SIZE); + } + spin_unlock_irqrestore(&r->lock, flags); + } trace_extract_entropy(r->name, nbytes, r->entropy_count, _RET_IP_); xfer_secondary_pool(r, nbytes); @@ -970,19 +991,6 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf, extract_buf(r, tmp); if (fips_enabled) { - unsigned long flags; - - - /* prime last_data value if need be, per fips 140-2 */ - if (!r->last_data_init) { - spin_lock_irqsave(&r->lock, flags); - memcpy(r->last_data, tmp, EXTRACT_SIZE); - r->last_data_init = true; - nbytes -= EXTRACT_SIZE; - spin_unlock_irqrestore(&r->lock, flags); - extract_buf(r, tmp); - } - spin_lock_irqsave(&r->lock, flags); if (!memcmp(tmp, r->last_data, EXTRACT_SIZE)) panic("Hardware RNG duplicated output!\n"); diff --git a/drivers/clk/clk-si5351.c b/drivers/clk/clk-si5351.c index 892728412e9d..24f553673b72 100644 --- a/drivers/clk/clk-si5351.c +++ b/drivers/clk/clk-si5351.c @@ -932,7 +932,7 @@ static unsigned long si5351_clkout_recalc_rate(struct clk_hw *hw, unsigned char reg; unsigned char rdiv; - if (hwdata->num > 5) + if (hwdata->num <= 5) reg = si5351_msynth_params_address(hwdata->num) + 2; else reg = SI5351_CLK6_7_OUTPUT_DIVIDER; @@ -1477,6 +1477,16 @@ static int si5351_i2c_probe(struct i2c_client *client, return -EINVAL; } drvdata->onecell.clks[n] = clk; + + /* set initial clkout rate */ + if (pdata->clkout[n].rate != 0) { + int ret; + ret = clk_set_rate(clk, pdata->clkout[n].rate); + if (ret != 0) { + dev_err(&client->dev, "Cannot set rate : %d\n", + ret); + } + } } ret = of_clk_add_provider(client->dev.of_node, of_clk_src_onecell_get, diff --git a/drivers/clk/clk-vt8500.c b/drivers/clk/clk-vt8500.c index debf688afa8e..553ac35bcc91 100644 --- a/drivers/clk/clk-vt8500.c +++ b/drivers/clk/clk-vt8500.c @@ -183,7 +183,7 @@ static int vt8500_dclk_set_rate(struct clk_hw *hw, unsigned long rate, writel(divisor, cdev->div_reg); vt8500_pmc_wait_busy(); - spin_lock_irqsave(cdev->lock, flags); + spin_unlock_irqrestore(cdev->lock, flags); return 0; } diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 934cfd18f72d..1144e8c7579d 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -1955,6 +1955,7 @@ int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb) /* XXX the notifier code should handle this better */ if (!cn->notifier_head.head) { srcu_cleanup_notifier_head(&cn->notifier_head); + list_del(&cn->node); kfree(cn); } diff --git a/drivers/clk/mxs/clk-imx28.c b/drivers/clk/mxs/clk-imx28.c index d0e5eed146de..4faf0afc44cd 100644 --- a/drivers/clk/mxs/clk-imx28.c +++ b/drivers/clk/mxs/clk-imx28.c @@ -10,6 +10,7 @@ */ #include <linux/clk.h> +#include <linux/clk/mxs.h> #include <linux/clkdev.h> #include <linux/err.h> #include <linux/init.h> diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c index d0940e69d034..3c1f88868f29 100644 --- a/drivers/clk/samsung/clk-exynos4.c +++ b/drivers/clk/samsung/clk-exynos4.c @@ -791,7 +791,8 @@ struct samsung_gate_clock exynos4210_gate_clks[] __initdata = { GATE(smmu_pcie, "smmu_pcie", "aclk133", GATE_IP_FSYS, 18, 0, 0), GATE(modemif, "modemif", "aclk100", GATE_IP_PERIL, 28, 0, 0), GATE(chipid, "chipid", "aclk100", E4210_GATE_IP_PERIR, 0, 0, 0), - GATE(sysreg, "sysreg", "aclk100", E4210_GATE_IP_PERIR, 0, 0, 0), + GATE(sysreg, "sysreg", "aclk100", E4210_GATE_IP_PERIR, 0, + CLK_IGNORE_UNUSED, 0), GATE(hdmi_cec, "hdmi_cec", "aclk100", E4210_GATE_IP_PERIR, 11, 0, 0), GATE(smmu_rotator, "smmu_rotator", "aclk200", E4210_GATE_IP_IMAGE, 4, 0, 0), @@ -819,7 +820,8 @@ struct samsung_gate_clock exynos4x12_gate_clks[] __initdata = { GATE(smmu_mdma, "smmu_mdma", "aclk200", E4X12_GATE_IP_IMAGE, 5, 0, 0), GATE(mipi_hsi, "mipi_hsi", "aclk133", GATE_IP_FSYS, 10, 0, 0), GATE(chipid, "chipid", "aclk100", E4X12_GATE_IP_PERIR, 0, 0, 0), - GATE(sysreg, "sysreg", "aclk100", E4X12_GATE_IP_PERIR, 1, 0, 0), + GATE(sysreg, "sysreg", "aclk100", E4X12_GATE_IP_PERIR, 1, + CLK_IGNORE_UNUSED, 0), GATE(hdmi_cec, "hdmi_cec", "aclk100", E4X12_GATE_IP_PERIR, 11, 0, 0), GATE(sclk_mdnie0, "sclk_mdnie0", "div_mdnie0", SRC_MASK_LCD0, 4, CLK_SET_RATE_PARENT, 0), diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c index 5c97e75924a8..22d7699e7ced 100644 --- a/drivers/clk/samsung/clk-exynos5250.c +++ b/drivers/clk/samsung/clk-exynos5250.c @@ -155,7 +155,7 @@ static __initdata unsigned long exynos5250_clk_regs[] = { /* list of all parent clock list */ PNAME(mout_apll_p) = { "fin_pll", "fout_apll", }; -PNAME(mout_cpu_p) = { "mout_apll", "mout_mpll", }; +PNAME(mout_cpu_p) = { "mout_apll", "sclk_mpll", }; PNAME(mout_mpll_fout_p) = { "fout_mplldiv2", "fout_mpll" }; PNAME(mout_mpll_p) = { "fin_pll", "mout_mpll_fout" }; PNAME(mout_bpll_fout_p) = { "fout_bplldiv2", "fout_bpll" }; @@ -208,10 +208,10 @@ struct samsung_fixed_factor_clock exynos5250_fixed_factor_clks[] __initdata = { }; struct samsung_mux_clock exynos5250_mux_clks[] __initdata = { - MUX(none, "mout_apll", mout_apll_p, SRC_CPU, 0, 1), - MUX(none, "mout_cpu", mout_cpu_p, SRC_CPU, 16, 1), + MUX_A(none, "mout_apll", mout_apll_p, SRC_CPU, 0, 1, "mout_apll"), + MUX_A(none, "mout_cpu", mout_cpu_p, SRC_CPU, 16, 1, "mout_cpu"), MUX(none, "mout_mpll_fout", mout_mpll_fout_p, PLL_DIV2_SEL, 4, 1), - MUX(none, "sclk_mpll", mout_mpll_p, SRC_CORE1, 8, 1), + MUX_A(none, "sclk_mpll", mout_mpll_p, SRC_CORE1, 8, 1, "mout_mpll"), MUX(none, "mout_bpll_fout", mout_bpll_fout_p, PLL_DIV2_SEL, 0, 1), MUX(none, "sclk_bpll", mout_bpll_p, SRC_CDREX, 0, 1), MUX(none, "mout_vpllsrc", mout_vpllsrc_p, SRC_TOP2, 0, 1), @@ -378,7 +378,7 @@ struct samsung_gate_clock exynos5250_gate_clks[] __initdata = { GATE(hsi2c3, "hsi2c3", "aclk66", GATE_IP_PERIC, 31, 0, 0), GATE(chipid, "chipid", "aclk66", GATE_IP_PERIS, 0, 0, 0), GATE(sysreg, "sysreg", "aclk66", GATE_IP_PERIS, 1, 0, 0), - GATE(pmu, "pmu", "aclk66", GATE_IP_PERIS, 2, 0, 0), + GATE(pmu, "pmu", "aclk66", GATE_IP_PERIS, 2, CLK_IGNORE_UNUSED, 0), GATE(tzpc0, "tzpc0", "aclk66", GATE_IP_PERIS, 6, 0, 0), GATE(tzpc1, "tzpc1", "aclk66", GATE_IP_PERIS, 7, 0, 0), GATE(tzpc2, "tzpc2", "aclk66", GATE_IP_PERIS, 8, 0, 0), diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c index 89135f6be116..362f12dcd944 100644 --- a/drivers/clk/samsung/clk-pll.c +++ b/drivers/clk/samsung/clk-pll.c @@ -111,7 +111,8 @@ static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { struct samsung_clk_pll36xx *pll = to_clk_pll36xx(hw); - u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1; + u32 mdiv, pdiv, sdiv, pll_con0, pll_con1; + s16 kdiv; u64 fvco = parent_rate; pll_con0 = __raw_readl(pll->con_reg); @@ -119,7 +120,7 @@ static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw, mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK; pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK; sdiv = (pll_con0 >> PLL36XX_SDIV_SHIFT) & PLL36XX_SDIV_MASK; - kdiv = pll_con1 & PLL36XX_KDIV_MASK; + kdiv = (s16)(pll_con1 & PLL36XX_KDIV_MASK); fvco *= (mdiv << 16) + kdiv; do_div(fvco, (pdiv << sdiv)); diff --git a/drivers/clk/spear/spear3xx_clock.c b/drivers/clk/spear/spear3xx_clock.c index f9ec43fd1320..080c3c5e33f6 100644 --- a/drivers/clk/spear/spear3xx_clock.c +++ b/drivers/clk/spear/spear3xx_clock.c @@ -369,7 +369,7 @@ static void __init spear320_clk_init(void __iomem *soc_config_base) clk_register_clkdev(clk, NULL, "60100000.serial"); } #else -static inline void spear320_clk_init(void) { } +static inline void spear320_clk_init(void __iomem *soc_config_base) { } #endif void __init spear3xx_clk_init(void __iomem *misc_base, void __iomem *soc_config_base) diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c index 8292a00c3de9..075db0c99edb 100644 --- a/drivers/clk/tegra/clk-tegra20.c +++ b/drivers/clk/tegra/clk-tegra20.c @@ -872,6 +872,14 @@ static void __init tegra20_periph_clk_init(void) struct clk *clk; int i; + /* ac97 */ + clk = tegra_clk_register_periph_gate("ac97", "pll_a_out0", + TEGRA_PERIPH_ON_APB, + clk_base, 0, 3, &periph_l_regs, + periph_clk_enb_refcnt); + clk_register_clkdev(clk, NULL, "tegra20-ac97"); + clks[ac97] = clk; + /* apbdma */ clk = tegra_clk_register_periph_gate("apbdma", "pclk", 0, clk_base, 0, 34, &periph_h_regs, @@ -1234,9 +1242,6 @@ static __initdata struct tegra_clk_init_table init_table[] = { {uartc, pll_p, 0, 0}, {uartd, pll_p, 0, 0}, {uarte, pll_p, 0, 0}, - {usbd, clk_max, 12000000, 0}, - {usb2, clk_max, 12000000, 0}, - {usb3, clk_max, 12000000, 0}, {pll_a, clk_max, 56448000, 1}, {pll_a_out0, clk_max, 11289600, 1}, {cdev1, clk_max, 0, 1}, diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c index c6921f538e28..ba99e3844106 100644 --- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c @@ -1598,6 +1598,12 @@ static void __init tegra30_periph_clk_init(void) clk_register_clkdev(clk, "afi", "tegra-pcie"); clks[afi] = clk; + /* pciex */ + clk = tegra_clk_register_periph_gate("pciex", "pll_e", 0, clk_base, 0, + 74, &periph_u_regs, periph_clk_enb_refcnt); + clk_register_clkdev(clk, "pciex", "tegra-pcie"); + clks[pciex] = clk; + /* kfuse */ clk = tegra_clk_register_periph_gate("kfuse", "clk_m", TEGRA_PERIPH_ON_APB, @@ -1716,11 +1722,6 @@ static void __init tegra30_fixed_clk_init(void) 1, 0, &cml_lock); clk_register_clkdev(clk, "cml1", NULL); clks[cml1] = clk; - - /* pciex */ - clk = clk_register_fixed_rate(NULL, "pciex", "pll_e", 0, 100000000); - clk_register_clkdev(clk, "pciex", NULL); - clks[pciex] = clk; } static void __init tegra30_osc_clk_init(void) diff --git a/drivers/clk/ux500/clk-sysctrl.c b/drivers/clk/ux500/clk-sysctrl.c index bc7e9bde792b..e364c9d4aa60 100644 --- a/drivers/clk/ux500/clk-sysctrl.c +++ b/drivers/clk/ux500/clk-sysctrl.c @@ -145,7 +145,13 @@ static struct clk *clk_reg_sysctrl(struct device *dev, return ERR_PTR(-ENOMEM); } - for (i = 0; i < num_parents; i++) { + /* set main clock registers */ + clk->reg_sel[0] = reg_sel[0]; + clk->reg_bits[0] = reg_bits[0]; + clk->reg_mask[0] = reg_mask[0]; + + /* handle clocks with more than one parent */ + for (i = 1; i < num_parents; i++) { clk->reg_sel[i] = reg_sel[i]; clk->reg_bits[i] = reg_bits[i]; clk->reg_mask[i] = reg_mask[i]; diff --git a/drivers/clk/ux500/u8500_clk.c b/drivers/clk/ux500/u8500_clk.c index 0b4f35a5ffc2..80069c370a47 100644 --- a/drivers/clk/ux500/u8500_clk.c +++ b/drivers/clk/ux500/u8500_clk.c @@ -325,7 +325,7 @@ void u8500_clk_init(u32 clkrst1_base, u32 clkrst2_base, u32 clkrst3_base, clk = clk_reg_prcc_pclk("p3_pclk0", "per3clk", clkrst3_base, BIT(0), 0); clk_register_clkdev(clk, "fsmc", NULL); - clk_register_clkdev(clk, NULL, "smsc911x"); + clk_register_clkdev(clk, NULL, "smsc911x.0"); clk = clk_reg_prcc_pclk("p3_pclk1", "per3clk", clkrst3_base, BIT(1), 0); diff --git a/drivers/clk/x86/clk-lpt.c b/drivers/clk/x86/clk-lpt.c index 5cf4f4686406..4f45eee9e33b 100644 --- a/drivers/clk/x86/clk-lpt.c +++ b/drivers/clk/x86/clk-lpt.c @@ -15,22 +15,29 @@ #include <linux/clk-provider.h> #include <linux/err.h> #include <linux/module.h> +#include <linux/platform_data/clk-lpss.h> #include <linux/platform_device.h> #define PRV_CLOCK_PARAMS 0x800 static int lpt_clk_probe(struct platform_device *pdev) { + struct lpss_clk_data *drvdata; struct clk *clk; + drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); + if (!drvdata) + return -ENOMEM; + /* LPSS free running clock */ - clk = clk_register_fixed_rate(&pdev->dev, "lpss_clk", NULL, CLK_IS_ROOT, - 100000000); + drvdata->name = "lpss_clk"; + clk = clk_register_fixed_rate(&pdev->dev, drvdata->name, NULL, + CLK_IS_ROOT, 100000000); if (IS_ERR(clk)) return PTR_ERR(clk); - /* Shared DMA clock */ - clk_register_clkdev(clk, "hclk", "INTL9C60.0.auto"); + drvdata->clk = clk; + platform_set_drvdata(pdev, drvdata); return 0; } diff --git a/drivers/cpufreq/Kconfig.x86 b/drivers/cpufreq/Kconfig.x86 index 2b8a8c374548..6bd63d63d356 100644 --- a/drivers/cpufreq/Kconfig.x86 +++ b/drivers/cpufreq/Kconfig.x86 @@ -272,7 +272,7 @@ config X86_LONGHAUL config X86_E_POWERSAVER tristate "VIA C7 Enhanced PowerSaver (DANGEROUS)" select CPU_FREQ_TABLE - depends on X86_32 + depends on X86_32 && ACPI_PROCESSOR help This adds the CPUFreq driver for VIA C7 processors. However, this driver does not have any safeguards to prevent operating the CPU out of spec diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c index 11b8b4b54ceb..edc089e9d0c4 100644 --- a/drivers/cpufreq/acpi-cpufreq.c +++ b/drivers/cpufreq/acpi-cpufreq.c @@ -347,11 +347,11 @@ static u32 get_cur_val(const struct cpumask *mask) switch (per_cpu(acfreq_data, cpumask_first(mask))->cpu_feature) { case SYSTEM_INTEL_MSR_CAPABLE: cmd.type = SYSTEM_INTEL_MSR_CAPABLE; - cmd.addr.msr.reg = MSR_IA32_PERF_STATUS; + cmd.addr.msr.reg = MSR_IA32_PERF_CTL; break; case SYSTEM_AMD_MSR_CAPABLE: cmd.type = SYSTEM_AMD_MSR_CAPABLE; - cmd.addr.msr.reg = MSR_AMD_PERF_STATUS; + cmd.addr.msr.reg = MSR_AMD_PERF_CTL; break; case SYSTEM_IO_CAPABLE: cmd.type = SYSTEM_IO_CAPABLE; diff --git a/drivers/cpufreq/arm_big_little_dt.c b/drivers/cpufreq/arm_big_little_dt.c index 173ed059d95f..fd9e3ea6a480 100644 --- a/drivers/cpufreq/arm_big_little_dt.c +++ b/drivers/cpufreq/arm_big_little_dt.c @@ -19,70 +19,75 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include <linux/cpu.h> #include <linux/cpufreq.h> #include <linux/device.h> #include <linux/export.h> #include <linux/module.h> #include <linux/of.h> #include <linux/opp.h> +#include <linux/platform_device.h> #include <linux/slab.h> #include <linux/types.h> #include "arm_big_little.h" -static int dt_init_opp_table(struct device *cpu_dev) +/* get cpu node with valid operating-points */ +static struct device_node *get_cpu_node_with_valid_op(int cpu) { - struct device_node *np, *parent; - int count = 0, ret; + struct device_node *np = NULL, *parent; + int count = 0; parent = of_find_node_by_path("/cpus"); if (!parent) { pr_err("failed to find OF /cpus\n"); - return -ENOENT; + return NULL; } for_each_child_of_node(parent, np) { - if (count++ != cpu_dev->id) + if (count++ != cpu) continue; if (!of_get_property(np, "operating-points", NULL)) { - ret = -ENODATA; - } else { - cpu_dev->of_node = np; - ret = of_init_opp_table(cpu_dev); + of_node_put(np); + np = NULL; } - of_node_put(np); - of_node_put(parent); - return ret; + break; } - return -ENODEV; + of_node_put(parent); + return np; +} + +static int dt_init_opp_table(struct device *cpu_dev) +{ + struct device_node *np; + int ret; + + np = get_cpu_node_with_valid_op(cpu_dev->id); + if (!np) + return -ENODATA; + + cpu_dev->of_node = np; + ret = of_init_opp_table(cpu_dev); + of_node_put(np); + + return ret; } static int dt_get_transition_latency(struct device *cpu_dev) { - struct device_node *np, *parent; + struct device_node *np; u32 transition_latency = CPUFREQ_ETERNAL; - int count = 0; - parent = of_find_node_by_path("/cpus"); - if (!parent) { - pr_info("Failed to find OF /cpus. Use CPUFREQ_ETERNAL transition latency\n"); + np = get_cpu_node_with_valid_op(cpu_dev->id); + if (!np) return CPUFREQ_ETERNAL; - } - - for_each_child_of_node(parent, np) { - if (count++ != cpu_dev->id) - continue; - of_property_read_u32(np, "clock-latency", &transition_latency); - of_node_put(np); - of_node_put(parent); + of_property_read_u32(np, "clock-latency", &transition_latency); + of_node_put(np); - return transition_latency; - } - - pr_info("clock-latency isn't found, use CPUFREQ_ETERNAL transition latency\n"); - return CPUFREQ_ETERNAL; + pr_debug("%s: clock-latency: %d\n", __func__, transition_latency); + return transition_latency; } static struct cpufreq_arm_bL_ops dt_bL_ops = { @@ -91,17 +96,33 @@ static struct cpufreq_arm_bL_ops dt_bL_ops = { .init_opp_table = dt_init_opp_table, }; -static int generic_bL_init(void) +static int generic_bL_probe(struct platform_device *pdev) { + struct device_node *np; + + np = get_cpu_node_with_valid_op(0); + if (!np) + return -ENODEV; + + of_node_put(np); return bL_cpufreq_register(&dt_bL_ops); } -module_init(generic_bL_init); -static void generic_bL_exit(void) +static int generic_bL_remove(struct platform_device *pdev) { - return bL_cpufreq_unregister(&dt_bL_ops); + bL_cpufreq_unregister(&dt_bL_ops); + return 0; } -module_exit(generic_bL_exit); + +static struct platform_driver generic_bL_platdrv = { + .driver = { + .name = "arm-bL-cpufreq-dt", + .owner = THIS_MODULE, + }, + .probe = generic_bL_probe, + .remove = generic_bL_remove, +}; +module_platform_driver(generic_bL_platdrv); MODULE_AUTHOR("Viresh Kumar <viresh.kumar@linaro.org>"); MODULE_DESCRIPTION("Generic ARM big LITTLE cpufreq driver via DT"); diff --git a/drivers/cpufreq/cpufreq-cpu0.c b/drivers/cpufreq/cpufreq-cpu0.c index a64eb8b70444..ad1fde277661 100644 --- a/drivers/cpufreq/cpufreq-cpu0.c +++ b/drivers/cpufreq/cpufreq-cpu0.c @@ -45,7 +45,7 @@ static int cpu0_set_target(struct cpufreq_policy *policy, struct cpufreq_freqs freqs; struct opp *opp; unsigned long volt = 0, volt_old = 0, tol = 0; - long freq_Hz; + long freq_Hz, freq_exact; unsigned int index; int ret; @@ -60,6 +60,7 @@ static int cpu0_set_target(struct cpufreq_policy *policy, freq_Hz = clk_round_rate(cpu_clk, freq_table[index].frequency * 1000); if (freq_Hz < 0) freq_Hz = freq_table[index].frequency * 1000; + freq_exact = freq_Hz; freqs.new = freq_Hz / 1000; freqs.old = clk_get_rate(cpu_clk) / 1000; @@ -98,7 +99,7 @@ static int cpu0_set_target(struct cpufreq_policy *policy, } } - ret = clk_set_rate(cpu_clk, freqs.new * 1000); + ret = clk_set_rate(cpu_clk, freq_exact); if (ret) { pr_err("failed to set clock rate: %d\n", ret); if (cpu_reg) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 4b8c7f297d74..2d53f47d1747 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1729,18 +1729,23 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data, /* end old governor */ if (data->governor) { __cpufreq_governor(data, CPUFREQ_GOV_STOP); + unlock_policy_rwsem_write(policy->cpu); __cpufreq_governor(data, CPUFREQ_GOV_POLICY_EXIT); + lock_policy_rwsem_write(policy->cpu); } /* start new governor */ data->governor = policy->governor; if (!__cpufreq_governor(data, CPUFREQ_GOV_POLICY_INIT)) { - if (!__cpufreq_governor(data, CPUFREQ_GOV_START)) + if (!__cpufreq_governor(data, CPUFREQ_GOV_START)) { failed = 0; - else + } else { + unlock_policy_rwsem_write(policy->cpu); __cpufreq_governor(data, CPUFREQ_GOV_POLICY_EXIT); + lock_policy_rwsem_write(policy->cpu); + } } if (failed) { diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c index 5af40ad82d23..dc9b72e25c1a 100644 --- a/drivers/cpufreq/cpufreq_governor.c +++ b/drivers/cpufreq/cpufreq_governor.c @@ -26,6 +26,7 @@ #include <linux/tick.h> #include <linux/types.h> #include <linux/workqueue.h> +#include <linux/cpu.h> #include "cpufreq_governor.h" @@ -180,8 +181,10 @@ void gov_queue_work(struct dbs_data *dbs_data, struct cpufreq_policy *policy, if (!all_cpus) { __gov_queue_work(smp_processor_id(), dbs_data, delay); } else { + get_online_cpus(); for_each_cpu(i, policy->cpus) __gov_queue_work(i, dbs_data, delay); + put_online_cpus(); } } EXPORT_SYMBOL_GPL(gov_queue_work); diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 9c36ace92a39..07f2840ad805 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -521,6 +521,7 @@ static void intel_pstate_timer_func(unsigned long __data) static const struct x86_cpu_id intel_pstate_cpu_ids[] = { ICPU(0x2a, default_policy), ICPU(0x2d, default_policy), + ICPU(0x3a, default_policy), {} }; MODULE_DEVICE_TABLE(x86cpu, intel_pstate_cpu_ids); diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c index 765fdf5ce579..bf416a8391a7 100644 --- a/drivers/crypto/caam/caamalg.c +++ b/drivers/crypto/caam/caamalg.c @@ -1154,7 +1154,7 @@ static struct aead_edesc *aead_edesc_alloc(struct aead_request *req, dst_nents = sg_count(req->dst, req->cryptlen, &dst_chained); sgc = dma_map_sg_chained(jrdev, req->assoc, assoc_nents ? : 1, - DMA_BIDIRECTIONAL, assoc_chained); + DMA_TO_DEVICE, assoc_chained); if (likely(req->src == req->dst)) { sgc = dma_map_sg_chained(jrdev, req->src, src_nents ? : 1, DMA_BIDIRECTIONAL, src_chained); @@ -1336,7 +1336,7 @@ static struct aead_edesc *aead_giv_edesc_alloc(struct aead_givcrypt_request dst_nents = sg_count(req->dst, req->cryptlen, &dst_chained); sgc = dma_map_sg_chained(jrdev, req->assoc, assoc_nents ? : 1, - DMA_BIDIRECTIONAL, assoc_chained); + DMA_TO_DEVICE, assoc_chained); if (likely(req->src == req->dst)) { sgc = dma_map_sg_chained(jrdev, req->src, src_nents ? : 1, DMA_BIDIRECTIONAL, src_chained); diff --git a/drivers/crypto/nx/nx-aes-cbc.c b/drivers/crypto/nx/nx-aes-cbc.c index a76d4c4f29f5..35d483f8db66 100644 --- a/drivers/crypto/nx/nx-aes-cbc.c +++ b/drivers/crypto/nx/nx-aes-cbc.c @@ -126,6 +126,7 @@ struct crypto_alg nx_cbc_aes_alg = { .cra_blocksize = AES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct nx_crypto_ctx), .cra_type = &crypto_blkcipher_type, + .cra_alignmask = 0xf, .cra_module = THIS_MODULE, .cra_init = nx_crypto_ctx_aes_cbc_init, .cra_exit = nx_crypto_ctx_exit, diff --git a/drivers/crypto/nx/nx-aes-ecb.c b/drivers/crypto/nx/nx-aes-ecb.c index ba5f1611336f..7bbc9a81da21 100644 --- a/drivers/crypto/nx/nx-aes-ecb.c +++ b/drivers/crypto/nx/nx-aes-ecb.c @@ -123,6 +123,7 @@ struct crypto_alg nx_ecb_aes_alg = { .cra_priority = 300, .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, .cra_blocksize = AES_BLOCK_SIZE, + .cra_alignmask = 0xf, .cra_ctxsize = sizeof(struct nx_crypto_ctx), .cra_type = &crypto_blkcipher_type, .cra_module = THIS_MODULE, diff --git a/drivers/crypto/nx/nx-aes-gcm.c b/drivers/crypto/nx/nx-aes-gcm.c index c8109edc5cfb..6cca6c392b00 100644 --- a/drivers/crypto/nx/nx-aes-gcm.c +++ b/drivers/crypto/nx/nx-aes-gcm.c @@ -219,7 +219,7 @@ static int gcm_aes_nx_crypt(struct aead_request *req, int enc) if (enc) NX_CPB_FDM(csbcpb) |= NX_FDM_ENDE_ENCRYPT; else - nbytes -= AES_BLOCK_SIZE; + nbytes -= crypto_aead_authsize(crypto_aead_reqtfm(req)); csbcpb->cpb.aes_gcm.bit_length_data = nbytes * 8; diff --git a/drivers/crypto/nx/nx-sha256.c b/drivers/crypto/nx/nx-sha256.c index 9767315f8c0b..67024f2f0b78 100644 --- a/drivers/crypto/nx/nx-sha256.c +++ b/drivers/crypto/nx/nx-sha256.c @@ -69,7 +69,7 @@ static int nx_sha256_update(struct shash_desc *desc, const u8 *data, * 1: <= SHA256_BLOCK_SIZE: copy into state, return 0 * 2: > SHA256_BLOCK_SIZE: process X blocks, copy in leftover */ - if (len + sctx->count <= SHA256_BLOCK_SIZE) { + if (len + sctx->count < SHA256_BLOCK_SIZE) { memcpy(sctx->buf + sctx->count, data, len); sctx->count += len; goto out; @@ -110,7 +110,8 @@ static int nx_sha256_update(struct shash_desc *desc, const u8 *data, atomic_inc(&(nx_ctx->stats->sha256_ops)); /* copy the leftover back into the state struct */ - memcpy(sctx->buf, data + len - leftover, leftover); + if (leftover) + memcpy(sctx->buf, data + len - leftover, leftover); sctx->count = leftover; csbcpb->cpb.sha256.message_bit_length += (u64) @@ -130,6 +131,7 @@ static int nx_sha256_final(struct shash_desc *desc, u8 *out) struct nx_sg *in_sg, *out_sg; int rc; + if (NX_CPB_FDM(csbcpb) & NX_FDM_CONTINUATION) { /* we've hit the nx chip previously, now we're finalizing, * so copy over the partial digest */ @@ -162,7 +164,7 @@ static int nx_sha256_final(struct shash_desc *desc, u8 *out) atomic_inc(&(nx_ctx->stats->sha256_ops)); - atomic64_add(csbcpb->cpb.sha256.message_bit_length, + atomic64_add(csbcpb->cpb.sha256.message_bit_length / 8, &(nx_ctx->stats->sha256_bytes)); memcpy(out, csbcpb->cpb.sha256.message_digest, SHA256_DIGEST_SIZE); out: diff --git a/drivers/crypto/nx/nx-sha512.c b/drivers/crypto/nx/nx-sha512.c index 3177b8c3d5f1..08eee1122349 100644 --- a/drivers/crypto/nx/nx-sha512.c +++ b/drivers/crypto/nx/nx-sha512.c @@ -69,7 +69,7 @@ static int nx_sha512_update(struct shash_desc *desc, const u8 *data, * 1: <= SHA512_BLOCK_SIZE: copy into state, return 0 * 2: > SHA512_BLOCK_SIZE: process X blocks, copy in leftover */ - if ((u64)len + sctx->count[0] <= SHA512_BLOCK_SIZE) { + if ((u64)len + sctx->count[0] < SHA512_BLOCK_SIZE) { memcpy(sctx->buf + sctx->count[0], data, len); sctx->count[0] += len; goto out; @@ -110,7 +110,8 @@ static int nx_sha512_update(struct shash_desc *desc, const u8 *data, atomic_inc(&(nx_ctx->stats->sha512_ops)); /* copy the leftover back into the state struct */ - memcpy(sctx->buf, data + len - leftover, leftover); + if (leftover) + memcpy(sctx->buf, data + len - leftover, leftover); sctx->count[0] = leftover; spbc_bits = csbcpb->cpb.sha512.spbc * 8; @@ -168,7 +169,7 @@ static int nx_sha512_final(struct shash_desc *desc, u8 *out) goto out; atomic_inc(&(nx_ctx->stats->sha512_ops)); - atomic64_add(csbcpb->cpb.sha512.message_bit_length_lo, + atomic64_add(csbcpb->cpb.sha512.message_bit_length_lo / 8, &(nx_ctx->stats->sha512_bytes)); memcpy(out, csbcpb->cpb.sha512.message_digest, SHA512_DIGEST_SIZE); diff --git a/drivers/crypto/nx/nx.c b/drivers/crypto/nx/nx.c index c767f232e693..bbdab6e5ccf0 100644 --- a/drivers/crypto/nx/nx.c +++ b/drivers/crypto/nx/nx.c @@ -211,44 +211,20 @@ int nx_build_sg_lists(struct nx_crypto_ctx *nx_ctx, { struct nx_sg *nx_insg = nx_ctx->in_sg; struct nx_sg *nx_outsg = nx_ctx->out_sg; - struct blkcipher_walk walk; - int rc; - - blkcipher_walk_init(&walk, dst, src, nbytes); - rc = blkcipher_walk_virt_block(desc, &walk, AES_BLOCK_SIZE); - if (rc) - goto out; if (iv) - memcpy(iv, walk.iv, AES_BLOCK_SIZE); + memcpy(iv, desc->info, AES_BLOCK_SIZE); - while (walk.nbytes) { - nx_insg = nx_build_sg_list(nx_insg, walk.src.virt.addr, - walk.nbytes, nx_ctx->ap->sglen); - nx_outsg = nx_build_sg_list(nx_outsg, walk.dst.virt.addr, - walk.nbytes, nx_ctx->ap->sglen); - - rc = blkcipher_walk_done(desc, &walk, 0); - if (rc) - break; - } - - if (walk.nbytes) { - nx_insg = nx_build_sg_list(nx_insg, walk.src.virt.addr, - walk.nbytes, nx_ctx->ap->sglen); - nx_outsg = nx_build_sg_list(nx_outsg, walk.dst.virt.addr, - walk.nbytes, nx_ctx->ap->sglen); - - rc = 0; - } + nx_insg = nx_walk_and_build(nx_insg, nx_ctx->ap->sglen, src, 0, nbytes); + nx_outsg = nx_walk_and_build(nx_outsg, nx_ctx->ap->sglen, dst, 0, nbytes); /* these lengths should be negative, which will indicate to phyp that * the input and output parameters are scatterlists, not linear * buffers */ nx_ctx->op.inlen = (nx_ctx->in_sg - nx_insg) * sizeof(struct nx_sg); nx_ctx->op.outlen = (nx_ctx->out_sg - nx_outsg) * sizeof(struct nx_sg); -out: - return rc; + + return 0; } /** @@ -454,6 +430,8 @@ static int nx_register_algs(void) if (rc) goto out; + nx_driver.of.status = NX_OKAY; + rc = crypto_register_alg(&nx_ecb_aes_alg); if (rc) goto out; @@ -498,8 +476,6 @@ static int nx_register_algs(void) if (rc) goto out_unreg_s512; - nx_driver.of.status = NX_OKAY; - goto out; out_unreg_s512: diff --git a/drivers/crypto/sahara.c b/drivers/crypto/sahara.c index a97bb6c1596c..c3dc1c04a5df 100644 --- a/drivers/crypto/sahara.c +++ b/drivers/crypto/sahara.c @@ -863,7 +863,7 @@ static struct of_device_id sahara_dt_ids[] = { { .compatible = "fsl,imx27-sahara" }, { /* sentinel */ } }; -MODULE_DEVICE_TABLE(platform, sahara_dt_ids); +MODULE_DEVICE_TABLE(of, sahara_dt_ids); static int sahara_probe(struct platform_device *pdev) { diff --git a/drivers/dma/acpi-dma.c b/drivers/dma/acpi-dma.c index ba6fc62e9651..5a18f82f732a 100644 --- a/drivers/dma/acpi-dma.c +++ b/drivers/dma/acpi-dma.c @@ -4,7 +4,8 @@ * Based on of-dma.c * * Copyright (C) 2013, Intel Corporation - * Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com> + * Authors: Andy Shevchenko <andriy.shevchenko@linux.intel.com> + * Mika Westerberg <mika.westerberg@linux.intel.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -16,6 +17,7 @@ #include <linux/list.h> #include <linux/mutex.h> #include <linux/slab.h> +#include <linux/ioport.h> #include <linux/acpi.h> #include <linux/acpi_dma.h> @@ -23,6 +25,117 @@ static LIST_HEAD(acpi_dma_list); static DEFINE_MUTEX(acpi_dma_lock); /** + * acpi_dma_parse_resource_group - match device and parse resource group + * @grp: CSRT resource group + * @adev: ACPI device to match with + * @adma: struct acpi_dma of the given DMA controller + * + * Returns 1 on success, 0 when no information is available, or appropriate + * errno value on error. + * + * In order to match a device from DSDT table to the corresponding CSRT device + * we use MMIO address and IRQ. + */ +static int acpi_dma_parse_resource_group(const struct acpi_csrt_group *grp, + struct acpi_device *adev, struct acpi_dma *adma) +{ + const struct acpi_csrt_shared_info *si; + struct list_head resource_list; + struct resource_list_entry *rentry; + resource_size_t mem = 0, irq = 0; + u32 vendor_id; + int ret; + + if (grp->shared_info_length != sizeof(struct acpi_csrt_shared_info)) + return -ENODEV; + + INIT_LIST_HEAD(&resource_list); + ret = acpi_dev_get_resources(adev, &resource_list, NULL, NULL); + if (ret <= 0) + return 0; + + list_for_each_entry(rentry, &resource_list, node) { + if (resource_type(&rentry->res) == IORESOURCE_MEM) + mem = rentry->res.start; + else if (resource_type(&rentry->res) == IORESOURCE_IRQ) + irq = rentry->res.start; + } + + acpi_dev_free_resource_list(&resource_list); + + /* Consider initial zero values as resource not found */ + if (mem == 0 && irq == 0) + return 0; + + si = (const struct acpi_csrt_shared_info *)&grp[1]; + + /* Match device by MMIO and IRQ */ + if (si->mmio_base_low != mem || si->gsi_interrupt != irq) + return 0; + + vendor_id = le32_to_cpu(grp->vendor_id); + dev_dbg(&adev->dev, "matches with %.4s%04X (rev %u)\n", + (char *)&vendor_id, grp->device_id, grp->revision); + + /* Check if the request line range is available */ + if (si->base_request_line == 0 && si->num_handshake_signals == 0) + return 0; + + adma->base_request_line = si->base_request_line; + adma->end_request_line = si->base_request_line + + si->num_handshake_signals - 1; + + dev_dbg(&adev->dev, "request line base: 0x%04x end: 0x%04x\n", + adma->base_request_line, adma->end_request_line); + + return 1; +} + +/** + * acpi_dma_parse_csrt - parse CSRT to exctract additional DMA resources + * @adev: ACPI device to match with + * @adma: struct acpi_dma of the given DMA controller + * + * CSRT or Core System Resources Table is a proprietary ACPI table + * introduced by Microsoft. This table can contain devices that are not in + * the system DSDT table. In particular DMA controllers might be described + * here. + * + * We are using this table to get the request line range of the specific DMA + * controller to be used later. + * + */ +static void acpi_dma_parse_csrt(struct acpi_device *adev, struct acpi_dma *adma) +{ + struct acpi_csrt_group *grp, *end; + struct acpi_table_csrt *csrt; + acpi_status status; + int ret; + + status = acpi_get_table(ACPI_SIG_CSRT, 0, + (struct acpi_table_header **)&csrt); + if (ACPI_FAILURE(status)) { + if (status != AE_NOT_FOUND) + dev_warn(&adev->dev, "failed to get the CSRT table\n"); + return; + } + + grp = (struct acpi_csrt_group *)(csrt + 1); + end = (struct acpi_csrt_group *)((void *)csrt + csrt->header.length); + + while (grp < end) { + ret = acpi_dma_parse_resource_group(grp, adev, adma); + if (ret < 0) { + dev_warn(&adev->dev, + "error in parsing resource group\n"); + return; + } + + grp = (struct acpi_csrt_group *)((void *)grp + grp->length); + } +} + +/** * acpi_dma_controller_register - Register a DMA controller to ACPI DMA helpers * @dev: struct device of DMA controller * @acpi_dma_xlate: translation function which converts a dma specifier @@ -61,6 +174,8 @@ int acpi_dma_controller_register(struct device *dev, adma->acpi_dma_xlate = acpi_dma_xlate; adma->data = data; + acpi_dma_parse_csrt(adev, adma); + /* Now queue acpi_dma controller structure in list */ mutex_lock(&acpi_dma_lock); list_add_tail(&adma->dma_controllers, &acpi_dma_list); @@ -149,6 +264,45 @@ void devm_acpi_dma_controller_free(struct device *dev) } EXPORT_SYMBOL_GPL(devm_acpi_dma_controller_free); +/** + * acpi_dma_update_dma_spec - prepare dma specifier to pass to translation function + * @adma: struct acpi_dma of DMA controller + * @dma_spec: dma specifier to update + * + * Returns 0, if no information is avaiable, -1 on mismatch, and 1 otherwise. + * + * Accordingly to ACPI 5.0 Specification Table 6-170 "Fixed DMA Resource + * Descriptor": + * DMA Request Line bits is a platform-relative number uniquely + * identifying the request line assigned. Request line-to-Controller + * mapping is done in a controller-specific OS driver. + * That's why we can safely adjust slave_id when the appropriate controller is + * found. + */ +static int acpi_dma_update_dma_spec(struct acpi_dma *adma, + struct acpi_dma_spec *dma_spec) +{ + /* Set link to the DMA controller device */ + dma_spec->dev = adma->dev; + + /* Check if the request line range is available */ + if (adma->base_request_line == 0 && adma->end_request_line == 0) + return 0; + + /* Check if slave_id falls to the range */ + if (dma_spec->slave_id < adma->base_request_line || + dma_spec->slave_id > adma->end_request_line) + return -1; + + /* + * Here we adjust slave_id. It should be a relative number to the base + * request line. + */ + dma_spec->slave_id -= adma->base_request_line; + + return 1; +} + struct acpi_dma_parser_data { struct acpi_dma_spec dma_spec; size_t index; @@ -193,6 +347,7 @@ struct dma_chan *acpi_dma_request_slave_chan_by_index(struct device *dev, struct acpi_device *adev; struct acpi_dma *adma; struct dma_chan *chan = NULL; + int found; /* Check if the device was enumerated by ACPI */ if (!dev || !ACPI_HANDLE(dev)) @@ -219,9 +374,20 @@ struct dma_chan *acpi_dma_request_slave_chan_by_index(struct device *dev, mutex_lock(&acpi_dma_lock); list_for_each_entry(adma, &acpi_dma_list, dma_controllers) { - dma_spec->dev = adma->dev; + /* + * We are not going to call translation function if slave_id + * doesn't fall to the request range. + */ + found = acpi_dma_update_dma_spec(adma, dma_spec); + if (found < 0) + continue; chan = adma->acpi_dma_xlate(dma_spec, adma); - if (chan) + /* + * Try to get a channel only from the DMA controller that + * matches the slave_id. See acpi_dma_update_dma_spec() + * description for the details. + */ + if (found > 0 || chan) break; } diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c index d8ce4ecfef18..e88ded2c8d2f 100644 --- a/drivers/dma/dmatest.c +++ b/drivers/dma/dmatest.c @@ -716,8 +716,7 @@ static int dmatest_func(void *data) } dma_async_issue_pending(chan); - wait_event_freezable_timeout(done_wait, - done.done || kthread_should_stop(), + wait_event_freezable_timeout(done_wait, done.done, msecs_to_jiffies(params->timeout)); status = dma_async_is_tx_complete(chan, cookie, NULL, NULL); @@ -997,7 +996,6 @@ static void stop_threaded_test(struct dmatest_info *info) static int __restart_threaded_test(struct dmatest_info *info, bool run) { struct dmatest_params *params = &info->params; - int ret; /* Stop any running test first */ __stop_threaded_test(info); @@ -1012,13 +1010,23 @@ static int __restart_threaded_test(struct dmatest_info *info, bool run) memcpy(params, &info->dbgfs_params, sizeof(*params)); /* Run test with new parameters */ - ret = __run_threaded_test(info); - if (ret) { - __stop_threaded_test(info); - pr_err("dmatest: Can't run test\n"); + return __run_threaded_test(info); +} + +static bool __is_threaded_test_run(struct dmatest_info *info) +{ + struct dmatest_chan *dtc; + + list_for_each_entry(dtc, &info->channels, node) { + struct dmatest_thread *thread; + + list_for_each_entry(thread, &dtc->threads, node) { + if (!thread->done) + return true; + } } - return ret; + return false; } static ssize_t dtf_write_string(void *to, size_t available, loff_t *ppos, @@ -1091,22 +1099,10 @@ static ssize_t dtf_read_run(struct file *file, char __user *user_buf, { struct dmatest_info *info = file->private_data; char buf[3]; - struct dmatest_chan *dtc; - bool alive = false; mutex_lock(&info->lock); - list_for_each_entry(dtc, &info->channels, node) { - struct dmatest_thread *thread; - - list_for_each_entry(thread, &dtc->threads, node) { - if (!thread->done) { - alive = true; - break; - } - } - } - if (alive) { + if (__is_threaded_test_run(info)) { buf[0] = 'Y'; } else { __stop_threaded_test(info); @@ -1132,7 +1128,12 @@ static ssize_t dtf_write_run(struct file *file, const char __user *user_buf, if (strtobool(buf, &bv) == 0) { mutex_lock(&info->lock); - ret = __restart_threaded_test(info, bv); + + if (__is_threaded_test_run(info)) + ret = -EBUSY; + else + ret = __restart_threaded_test(info, bv); + mutex_unlock(&info->lock); } diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 1734feec47b1..71bf4ec300ea 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -1566,10 +1566,12 @@ static void dma_tc_handle(struct d40_chan *d40c) return; } - if (d40_queue_start(d40c) == NULL) + if (d40_queue_start(d40c) == NULL) { d40c->busy = false; - pm_runtime_mark_last_busy(d40c->base->dev); - pm_runtime_put_autosuspend(d40c->base->dev); + + pm_runtime_mark_last_busy(d40c->base->dev); + pm_runtime_put_autosuspend(d40c->base->dev); + } d40_desc_remove(d40d); d40_desc_done(d40c, d40d); diff --git a/drivers/edac/amd64_edac_inj.c b/drivers/edac/amd64_edac_inj.c index 8c171fa1cb9b..845f04786c2d 100644 --- a/drivers/edac/amd64_edac_inj.c +++ b/drivers/edac/amd64_edac_inj.c @@ -202,9 +202,9 @@ static DEVICE_ATTR(inject_word, S_IRUGO | S_IWUSR, amd64_inject_word_show, amd64_inject_word_store); static DEVICE_ATTR(inject_ecc_vector, S_IRUGO | S_IWUSR, amd64_inject_ecc_vector_show, amd64_inject_ecc_vector_store); -static DEVICE_ATTR(inject_write, S_IRUGO | S_IWUSR, +static DEVICE_ATTR(inject_write, S_IWUSR, NULL, amd64_inject_write_store); -static DEVICE_ATTR(inject_read, S_IRUGO | S_IWUSR, +static DEVICE_ATTR(inject_read, S_IWUSR, NULL, amd64_inject_read_store); diff --git a/drivers/firmware/efi/efivars.c b/drivers/firmware/efi/efivars.c index b623c599e572..8bd1bb6dbe47 100644 --- a/drivers/firmware/efi/efivars.c +++ b/drivers/firmware/efi/efivars.c @@ -523,13 +523,11 @@ static void efivar_update_sysfs_entries(struct work_struct *work) struct efivar_entry *entry; int err; - entry = kzalloc(sizeof(*entry), GFP_KERNEL); - if (!entry) - return; - /* Add new sysfs entries */ while (1) { - memset(entry, 0, sizeof(*entry)); + entry = kzalloc(sizeof(*entry), GFP_KERNEL); + if (!entry) + return; err = efivar_init(efivar_update_sysfs_entry, entry, true, false, &efivar_sysfs_list); diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 87d567089f13..573c449c49b9 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -636,7 +636,7 @@ config GPIO_MAX7301 config GPIO_MCP23S08 tristate "Microchip MCP23xxx I/O expander" - depends on SPI_MASTER || I2C + depends on (SPI_MASTER && !I2C) || I2C help SPI/I2C driver for Microchip MCP23S08/MCP23S17/MCP23008/MCP23017 I/O expanders. diff --git a/drivers/gpio/gpio-langwell.c b/drivers/gpio/gpio-langwell.c index 634c3d37f7b5..62ef10a641c4 100644 --- a/drivers/gpio/gpio-langwell.c +++ b/drivers/gpio/gpio-langwell.c @@ -324,6 +324,7 @@ static int lnw_gpio_probe(struct pci_dev *pdev, resource_size_t start, len; struct lnw_gpio *lnw; u32 gpio_base; + u32 irq_base; int retval; int ngpio = id->driver_data; @@ -345,6 +346,7 @@ static int lnw_gpio_probe(struct pci_dev *pdev, retval = -EFAULT; goto err_ioremap; } + irq_base = *(u32 *)base; gpio_base = *((u32 *)base + 1); /* release the IO mapping, since we already get the info from bar1 */ iounmap(base); @@ -365,13 +367,6 @@ static int lnw_gpio_probe(struct pci_dev *pdev, goto err_ioremap; } - lnw->domain = irq_domain_add_linear(pdev->dev.of_node, ngpio, - &lnw_gpio_irq_ops, lnw); - if (!lnw->domain) { - retval = -ENOMEM; - goto err_ioremap; - } - lnw->reg_base = base; lnw->chip.label = dev_name(&pdev->dev); lnw->chip.request = lnw_gpio_request; @@ -384,6 +379,14 @@ static int lnw_gpio_probe(struct pci_dev *pdev, lnw->chip.ngpio = ngpio; lnw->chip.can_sleep = 0; lnw->pdev = pdev; + + lnw->domain = irq_domain_add_simple(pdev->dev.of_node, ngpio, irq_base, + &lnw_gpio_irq_ops, lnw); + if (!lnw->domain) { + retval = -ENOMEM; + goto err_ioremap; + } + pci_set_drvdata(pdev, lnw); retval = gpiochip_add(&lnw->chip); if (retval) { diff --git a/drivers/gpio/gpio-ml-ioh.c b/drivers/gpio/gpio-ml-ioh.c index b73366523fae..0966f2637ad2 100644 --- a/drivers/gpio/gpio-ml-ioh.c +++ b/drivers/gpio/gpio-ml-ioh.c @@ -496,8 +496,7 @@ err_irq_alloc_descs: err_gpiochip_add: while (--i >= 0) { chip--; - ret = gpiochip_remove(&chip->gpio); - if (ret) + if (gpiochip_remove(&chip->gpio)) dev_err(&pdev->dev, "Failed gpiochip_remove(%d)\n", i); } kfree(chip_save); diff --git a/drivers/gpio/gpio-mxs.c b/drivers/gpio/gpio-mxs.c index 25000b0f8453..f8e6af20dfbf 100644 --- a/drivers/gpio/gpio-mxs.c +++ b/drivers/gpio/gpio-mxs.c @@ -326,7 +326,8 @@ static int mxs_gpio_probe(struct platform_device *pdev) err = bgpio_init(&port->bgc, &pdev->dev, 4, port->base + PINCTRL_DIN(port), - port->base + PINCTRL_DOUT(port), NULL, + port->base + PINCTRL_DOUT(port) + MXS_SET, + port->base + PINCTRL_DOUT(port) + MXS_CLR, port->base + PINCTRL_DOE(port), NULL, 0); if (err) goto out_irqdesc_free; diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 2050891d9c65..d3f7d2db870f 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -69,6 +69,7 @@ struct gpio_bank { bool is_mpuio; bool dbck_flag; bool loses_context; + bool context_valid; int stride; u32 width; int context_loss_count; @@ -1128,6 +1129,10 @@ static int omap_gpio_probe(struct platform_device *pdev) bank->loses_context = true; } else { bank->loses_context = pdata->loses_context; + + if (bank->loses_context) + bank->get_context_loss_count = + pdata->get_context_loss_count; } @@ -1178,9 +1183,6 @@ static int omap_gpio_probe(struct platform_device *pdev) omap_gpio_chip_init(bank); omap_gpio_show_rev(bank); - if (bank->loses_context) - bank->get_context_loss_count = pdata->get_context_loss_count; - pm_runtime_put(bank->dev); list_add_tail(&bank->node, &omap_gpio_list); @@ -1259,6 +1261,8 @@ update_gpio_context_count: return 0; } +static void omap_gpio_init_context(struct gpio_bank *p); + static int omap_gpio_runtime_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); @@ -1268,6 +1272,20 @@ static int omap_gpio_runtime_resume(struct device *dev) int c; spin_lock_irqsave(&bank->lock, flags); + + /* + * On the first resume during the probe, the context has not + * been initialised and so initialise it now. Also initialise + * the context loss count. + */ + if (bank->loses_context && !bank->context_valid) { + omap_gpio_init_context(bank); + + if (bank->get_context_loss_count) + bank->context_loss_count = + bank->get_context_loss_count(bank->dev); + } + _gpio_dbck_enable(bank); /* @@ -1384,6 +1402,29 @@ void omap2_gpio_resume_after_idle(void) } #if defined(CONFIG_PM_RUNTIME) +static void omap_gpio_init_context(struct gpio_bank *p) +{ + struct omap_gpio_reg_offs *regs = p->regs; + void __iomem *base = p->base; + + p->context.ctrl = __raw_readl(base + regs->ctrl); + p->context.oe = __raw_readl(base + regs->direction); + p->context.wake_en = __raw_readl(base + regs->wkup_en); + p->context.leveldetect0 = __raw_readl(base + regs->leveldetect0); + p->context.leveldetect1 = __raw_readl(base + regs->leveldetect1); + p->context.risingdetect = __raw_readl(base + regs->risingdetect); + p->context.fallingdetect = __raw_readl(base + regs->fallingdetect); + p->context.irqenable1 = __raw_readl(base + regs->irqenable); + p->context.irqenable2 = __raw_readl(base + regs->irqenable2); + + if (regs->set_dataout && p->regs->clr_dataout) + p->context.dataout = __raw_readl(base + regs->set_dataout); + else + p->context.dataout = __raw_readl(base + regs->dataout); + + p->context_valid = true; +} + static void omap_gpio_restore_context(struct gpio_bank *bank) { __raw_writel(bank->context.wake_en, @@ -1421,6 +1462,7 @@ static void omap_gpio_restore_context(struct gpio_bank *bank) #else #define omap_gpio_runtime_suspend NULL #define omap_gpio_runtime_resume NULL +static void omap_gpio_init_context(struct gpio_bank *p) {} #endif static const struct dev_pm_ops gpio_pm_ops = { diff --git a/drivers/gpio/gpio-pch.c b/drivers/gpio/gpio-pch.c index cdf599687cf7..0fec097e838d 100644 --- a/drivers/gpio/gpio-pch.c +++ b/drivers/gpio/gpio-pch.c @@ -424,8 +424,7 @@ end: err_request_irq: irq_free_descs(irq_base, gpio_pins[chip->ioh]); - ret = gpiochip_remove(&chip->gpio); - if (ret) + if (gpiochip_remove(&chip->gpio)) dev_err(&pdev->dev, "%s gpiochip_remove failed\n", __func__); err_gpiochip_add: diff --git a/drivers/gpio/gpio-sch.c b/drivers/gpio/gpio-sch.c index 1e4de16ceb41..5af65719b95d 100644 --- a/drivers/gpio/gpio-sch.c +++ b/drivers/gpio/gpio-sch.c @@ -272,10 +272,8 @@ static int sch_gpio_probe(struct platform_device *pdev) return 0; err_sch_gpio_resume: - err = gpiochip_remove(&sch_gpio_core); - if (err) - dev_err(&pdev->dev, "%s failed, %d\n", - "gpiochip_remove()", err); + if (gpiochip_remove(&sch_gpio_core)) + dev_err(&pdev->dev, "%s gpiochip_remove failed\n", __func__); err_sch_gpio_core: release_region(res->start, resource_size(res)); diff --git a/drivers/gpio/gpio-viperboard.c b/drivers/gpio/gpio-viperboard.c index 095ab14cea4d..5ac2919197fe 100644 --- a/drivers/gpio/gpio-viperboard.c +++ b/drivers/gpio/gpio-viperboard.c @@ -446,7 +446,8 @@ static int vprbrd_gpio_probe(struct platform_device *pdev) return ret; err_gpiob: - ret = gpiochip_remove(&vb_gpio->gpioa); + if (gpiochip_remove(&vb_gpio->gpioa)) + dev_err(&pdev->dev, "%s gpiochip_remove failed\n", __func__); err_gpioa: return ret; diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index a6a8643a6a77..8bcce7866d36 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -1054,7 +1054,7 @@ EXPORT_SYMBOL(drm_vblank_off); */ void drm_vblank_pre_modeset(struct drm_device *dev, int crtc) { - /* vblank is not initialized (IRQ not installed ?) */ + /* vblank is not initialized (IRQ not installed ?), or has been freed */ if (!dev->num_crtcs) return; /* @@ -1076,6 +1076,10 @@ void drm_vblank_post_modeset(struct drm_device *dev, int crtc) { unsigned long irqflags; + /* vblank is not initialized (IRQ not installed ?), or has been freed */ + if (!dev->num_crtcs) + return; + if (dev->vblank_inmodeset[crtc]) { spin_lock_irqsave(&dev->vbl_lock, irqflags); dev->vblank_disable_allowed = 1; diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index d92853e06dbb..e57c675db840 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c @@ -210,8 +210,7 @@ static const struct dma_buf_ops drm_gem_prime_dmabuf_ops = { struct dma_buf *drm_gem_prime_export(struct drm_device *dev, struct drm_gem_object *obj, int flags) { - return dma_buf_export(obj, &drm_gem_prime_dmabuf_ops, obj->size, - 0600); + return dma_buf_export(obj, &drm_gem_prime_dmabuf_ops, obj->size, flags); } EXPORT_SYMBOL(drm_gem_prime_export); diff --git a/drivers/gpu/drm/gma500/cdv_intel_display.c b/drivers/gpu/drm/gma500/cdv_intel_display.c index 3cfd0931fbfb..82430ad8ba62 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_display.c +++ b/drivers/gpu/drm/gma500/cdv_intel_display.c @@ -1462,7 +1462,7 @@ static int cdv_intel_crtc_cursor_set(struct drm_crtc *crtc, size_t addr = 0; struct gtt_range *gt; struct drm_gem_object *obj; - int ret; + int ret = 0; /* if we want to turn of the cursor ignore width and height */ if (!handle) { @@ -1499,7 +1499,8 @@ static int cdv_intel_crtc_cursor_set(struct drm_crtc *crtc, if (obj->size < width * height * 4) { dev_dbg(dev->dev, "buffer is to small\n"); - return -ENOMEM; + ret = -ENOMEM; + goto unref_cursor; } gt = container_of(obj, struct gtt_range, gem); @@ -1508,7 +1509,7 @@ static int cdv_intel_crtc_cursor_set(struct drm_crtc *crtc, ret = psb_gtt_pin(gt); if (ret) { dev_err(dev->dev, "Can not pin down handle 0x%x\n", handle); - return ret; + goto unref_cursor; } addr = gt->offset; /* Or resource.start ??? */ @@ -1532,9 +1533,14 @@ static int cdv_intel_crtc_cursor_set(struct drm_crtc *crtc, struct gtt_range, gem); psb_gtt_unpin(gt); drm_gem_object_unreference(psb_intel_crtc->cursor_obj); - psb_intel_crtc->cursor_obj = obj; } - return 0; + + psb_intel_crtc->cursor_obj = obj; + return ret; + +unref_cursor: + drm_gem_object_unreference(obj); + return ret; } static int cdv_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) @@ -1750,6 +1756,19 @@ static void cdv_intel_crtc_destroy(struct drm_crtc *crtc) kfree(psb_intel_crtc); } +static void cdv_intel_crtc_disable(struct drm_crtc *crtc) +{ + struct gtt_range *gt; + struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; + + crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF); + + if (crtc->fb) { + gt = to_psb_fb(crtc->fb)->gtt; + psb_gtt_unpin(gt); + } +} + const struct drm_crtc_helper_funcs cdv_intel_helper_funcs = { .dpms = cdv_intel_crtc_dpms, .mode_fixup = cdv_intel_crtc_mode_fixup, @@ -1757,6 +1776,7 @@ const struct drm_crtc_helper_funcs cdv_intel_helper_funcs = { .mode_set_base = cdv_intel_pipe_set_base, .prepare = cdv_intel_crtc_prepare, .commit = cdv_intel_crtc_commit, + .disable = cdv_intel_crtc_disable, }; const struct drm_crtc_funcs cdv_intel_crtc_funcs = { diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c index 1534e220097a..8b1b6d923abe 100644 --- a/drivers/gpu/drm/gma500/framebuffer.c +++ b/drivers/gpu/drm/gma500/framebuffer.c @@ -121,8 +121,8 @@ static int psbfb_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) unsigned long address; int ret; unsigned long pfn; - /* FIXME: assumes fb at stolen base which may not be true */ - unsigned long phys_addr = (unsigned long)dev_priv->stolen_base; + unsigned long phys_addr = (unsigned long)dev_priv->stolen_base + + psbfb->gtt->offset; page_num = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; address = (unsigned long)vmf->virtual_address - (vmf->pgoff << PAGE_SHIFT); diff --git a/drivers/gpu/drm/gma500/psb_intel_display.c b/drivers/gpu/drm/gma500/psb_intel_display.c index 6e8f42b61ff6..6666493789d1 100644 --- a/drivers/gpu/drm/gma500/psb_intel_display.c +++ b/drivers/gpu/drm/gma500/psb_intel_display.c @@ -843,7 +843,7 @@ static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc, struct gtt_range *cursor_gt = psb_intel_crtc->cursor_gt; struct drm_gem_object *obj; void *tmp_dst, *tmp_src; - int ret, i, cursor_pages; + int ret = 0, i, cursor_pages; /* if we want to turn of the cursor ignore width and height */ if (!handle) { @@ -880,7 +880,8 @@ static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc, if (obj->size < width * height * 4) { dev_dbg(dev->dev, "buffer is to small\n"); - return -ENOMEM; + ret = -ENOMEM; + goto unref_cursor; } gt = container_of(obj, struct gtt_range, gem); @@ -889,13 +890,14 @@ static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc, ret = psb_gtt_pin(gt); if (ret) { dev_err(dev->dev, "Can not pin down handle 0x%x\n", handle); - return ret; + goto unref_cursor; } if (dev_priv->ops->cursor_needs_phys) { if (cursor_gt == NULL) { dev_err(dev->dev, "No hardware cursor mem available"); - return -ENOMEM; + ret = -ENOMEM; + goto unref_cursor; } /* Prevent overflow */ @@ -936,9 +938,14 @@ static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc, struct gtt_range, gem); psb_gtt_unpin(gt); drm_gem_object_unreference(psb_intel_crtc->cursor_obj); - psb_intel_crtc->cursor_obj = obj; } - return 0; + + psb_intel_crtc->cursor_obj = obj; + return ret; + +unref_cursor: + drm_gem_object_unreference(obj); + return ret; } static int psb_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) @@ -1150,6 +1157,19 @@ static void psb_intel_crtc_destroy(struct drm_crtc *crtc) kfree(psb_intel_crtc); } +static void psb_intel_crtc_disable(struct drm_crtc *crtc) +{ + struct gtt_range *gt; + struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; + + crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF); + + if (crtc->fb) { + gt = to_psb_fb(crtc->fb)->gtt; + psb_gtt_unpin(gt); + } +} + const struct drm_crtc_helper_funcs psb_intel_helper_funcs = { .dpms = psb_intel_crtc_dpms, .mode_fixup = psb_intel_crtc_mode_fixup, @@ -1157,6 +1177,7 @@ const struct drm_crtc_helper_funcs psb_intel_helper_funcs = { .mode_set_base = psb_intel_pipe_set_base, .prepare = psb_intel_crtc_prepare, .commit = psb_intel_crtc_commit, + .disable = psb_intel_crtc_disable, }; const struct drm_crtc_funcs psb_intel_crtc_funcs = { diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index c605097bf598..e5b6a92e7102 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -91,14 +91,11 @@ i915_gem_wait_for_error(struct i915_gpu_error *error) { int ret; -#define EXIT_COND (!i915_reset_in_progress(error)) +#define EXIT_COND (!i915_reset_in_progress(error) || \ + i915_terminally_wedged(error)) if (EXIT_COND) return 0; - /* GPU is already declared terminally dead, give up. */ - if (i915_terminally_wedged(error)) - return -EIO; - /* * Only wait 10 seconds for the gpu reset to complete to avoid hanging * userspace. If it takes that long something really bad is going on and diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index dff9d4e5b92b..6eb99e13c37d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -8177,6 +8177,11 @@ intel_modeset_check_state(struct drm_device *dev) active = dev_priv->display.get_pipe_config(crtc, &pipe_config); + + /* hw state is inconsistent with the pipe A quirk */ + if (crtc->pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) + active = crtc->active; + WARN(crtc->active != active, "crtc active state doesn't match with hw state " "(expected %i, found %i)\n", crtc->active, active); diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 655486099b76..0ef8b4dc835f 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -639,10 +639,10 @@ static const struct dmi_system_id intel_no_lvds[] = { }, { .callback = intel_no_lvds_dmi_callback, - .ident = "Hewlett-Packard HP t5740e Thin Client", + .ident = "Hewlett-Packard HP t5740", .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP t5740e Thin Client"), + DMI_MATCH(DMI_PRODUCT_NAME, " t5740"), }, }, { diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 7068195376ef..c55841937705 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -1844,15 +1844,9 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) struct drm_display_mode *newmode; /* - * Attempt to get the mode list from DDC. - * Assume that the preferred modes are - * arranged in priority order. + * Fetch modes from VBT. For SDVO prefer the VBT mode since some + * SDVO->LVDS transcoders can't cope with the EDID mode. */ - intel_ddc_get_modes(connector, intel_sdvo->i2c); - if (list_empty(&connector->probed_modes) == false) - goto end; - - /* Fetch modes from VBT */ if (dev_priv->vbt.sdvo_lvds_vbt_mode != NULL) { newmode = drm_mode_duplicate(connector->dev, dev_priv->vbt.sdvo_lvds_vbt_mode); @@ -1864,7 +1858,13 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) } } -end: + /* + * Attempt to get the mode list from DDC. + * Assume that the preferred modes are + * arranged in priority order. + */ + intel_ddc_get_modes(connector, &intel_sdvo->ddc); + list_for_each_entry(newmode, &connector->probed_modes, head) { if (newmode->type & DRM_MODE_TYPE_PREFERRED) { intel_sdvo->sdvo_lvds_fixed_mode = @@ -2860,12 +2860,6 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) SDVOB_HOTPLUG_INT_STATUS_I915 : SDVOC_HOTPLUG_INT_STATUS_I915; } - /* Only enable the hotplug irq if we need it, to work around noisy - * hotplug lines. - */ - if (intel_sdvo->hotplug_active) - intel_encoder->hpd_pin = HPD_SDVO_B ? HPD_SDVO_B : HPD_SDVO_C; - intel_encoder->compute_config = intel_sdvo_compute_config; intel_encoder->disable = intel_disable_sdvo; intel_encoder->mode_set = intel_sdvo_mode_set; @@ -2885,6 +2879,14 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) goto err_output; } + /* Only enable the hotplug irq if we need it, to work around noisy + * hotplug lines. + */ + if (intel_sdvo->hotplug_active) { + intel_encoder->hpd_pin = + intel_sdvo->is_sdvob ? HPD_SDVO_B : HPD_SDVO_C; + } + /* * Cloning SDVO with anything is often impossible, since the SDVO * encoder can request a special input timing mode. And even if that's diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index deed0bda3528..5b1a9e73fe58 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -1034,13 +1034,14 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, else hi_pri_lvl = 5; - WREG8(0x1fde, 0x06); - WREG8(0x1fdf, hi_pri_lvl); + WREG8(MGAREG_CRTCEXT_INDEX, 0x06); + WREG8(MGAREG_CRTCEXT_DATA, hi_pri_lvl); } else { + WREG8(MGAREG_CRTCEXT_INDEX, 0x06); if (mdev->reg_1e24 >= 0x01) - WREG8(0x1fdf, 0x03); + WREG8(MGAREG_CRTCEXT_DATA, 0x03); else - WREG8(0x1fdf, 0x04); + WREG8(MGAREG_CRTCEXT_DATA, 0x04); } } return 0; diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/dacnv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/dacnv50.c index d0817d94454c..f02fd9f443ff 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/dacnv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/dacnv50.c @@ -50,11 +50,16 @@ nv50_dac_sense(struct nv50_disp_priv *priv, int or, u32 loadval) { const u32 doff = (or * 0x800); int load = -EINVAL; + nv_mask(priv, 0x61a004 + doff, 0x807f0000, 0x80150000); + nv_wait(priv, 0x61a004 + doff, 0x80000000, 0x00000000); nv_wr32(priv, 0x61a00c + doff, 0x00100000 | loadval); - udelay(9500); + mdelay(9); + udelay(500); nv_wr32(priv, 0x61a00c + doff, 0x80000000); load = (nv_rd32(priv, 0x61a00c + doff) & 0x38000000) >> 27; nv_wr32(priv, 0x61a00c + doff, 0x00000000); + nv_mask(priv, 0x61a004 + doff, 0x807f0000, 0x80550000); + nv_wait(priv, 0x61a004 + doff, 0x80000000, 0x00000000); return load; } diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/hdminv84.c b/drivers/gpu/drm/nouveau/core/engine/disp/hdminv84.c index 0d36bdc51417..7fdade6e604d 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/hdminv84.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/hdminv84.c @@ -55,6 +55,10 @@ nv84_hdmi_ctrl(struct nv50_disp_priv *priv, int head, int or, u32 data) nv_wr32(priv, 0x616510 + hoff, 0x00000000); nv_mask(priv, 0x616500 + hoff, 0x00000001, 0x00000001); + nv_mask(priv, 0x6165d0 + hoff, 0x00070001, 0x00010001); /* SPARE, HW_CTS */ + nv_mask(priv, 0x616568 + hoff, 0x00010101, 0x00000000); /* ACR_CTRL, ?? */ + nv_mask(priv, 0x616578 + hoff, 0x80000000, 0x80000000); /* ACR_0441_ENABLE */ + /* ??? */ nv_mask(priv, 0x61733c, 0x00100000, 0x00100000); /* RESETF */ nv_mask(priv, 0x61733c, 0x10000000, 0x10000000); /* LOOKUP_EN */ diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c index 89bf459d584b..e9b8217d0075 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c @@ -40,14 +40,13 @@ * FIFO channel objects ******************************************************************************/ -void -nv50_fifo_playlist_update(struct nv50_fifo_priv *priv) +static void +nv50_fifo_playlist_update_locked(struct nv50_fifo_priv *priv) { struct nouveau_bar *bar = nouveau_bar(priv); struct nouveau_gpuobj *cur; int i, p; - mutex_lock(&nv_subdev(priv)->mutex); cur = priv->playlist[priv->cur_playlist]; priv->cur_playlist = !priv->cur_playlist; @@ -61,6 +60,13 @@ nv50_fifo_playlist_update(struct nv50_fifo_priv *priv) nv_wr32(priv, 0x0032f4, cur->addr >> 12); nv_wr32(priv, 0x0032ec, p); nv_wr32(priv, 0x002500, 0x00000101); +} + +void +nv50_fifo_playlist_update(struct nv50_fifo_priv *priv) +{ + mutex_lock(&nv_subdev(priv)->mutex); + nv50_fifo_playlist_update_locked(priv); mutex_unlock(&nv_subdev(priv)->mutex); } @@ -489,7 +495,7 @@ nv50_fifo_init(struct nouveau_object *object) for (i = 0; i < 128; i++) nv_wr32(priv, 0x002600 + (i * 4), 0x00000000); - nv50_fifo_playlist_update(priv); + nv50_fifo_playlist_update_locked(priv); nv_wr32(priv, 0x003200, 0x00000001); nv_wr32(priv, 0x003250, 0x00000001); diff --git a/drivers/gpu/drm/nouveau/core/include/core/class.h b/drivers/gpu/drm/nouveau/core/include/core/class.h index 0a393f7f055f..5a5961b6a6a3 100644 --- a/drivers/gpu/drm/nouveau/core/include/core/class.h +++ b/drivers/gpu/drm/nouveau/core/include/core/class.h @@ -218,7 +218,7 @@ struct nv04_display_class { #define NV50_DISP_DAC_PWR_STATE 0x00000040 #define NV50_DISP_DAC_PWR_STATE_ON 0x00000000 #define NV50_DISP_DAC_PWR_STATE_OFF 0x00000040 -#define NV50_DISP_DAC_LOAD 0x0002000c +#define NV50_DISP_DAC_LOAD 0x00020100 #define NV50_DISP_DAC_LOAD_VALUE 0x00000007 #define NV50_DISP_PIOR_MTHD 0x00030000 diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index ebf0a683305e..dd5e01f89f28 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -1554,7 +1554,9 @@ nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) { struct nv50_disp *disp = nv50_disp(encoder->dev); int ret, or = nouveau_encoder(encoder)->or; - u32 load = 0; + u32 load = nouveau_drm(encoder->dev)->vbios.dactestval; + if (load == 0) + load = 340; ret = nv_exec(disp->core, NV50_DISP_DAC_LOAD + or, &load, sizeof(load)); if (ret || load != 7) diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index 9c53c25e5201..826586ffbe83 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -649,6 +649,9 @@ static void pdev_shutdown(struct platform_device *device) static int pdev_probe(struct platform_device *device) { + if (omapdss_is_initialized() == false) + return -EPROBE_DEFER; + DBG("%s", device->name); return drm_platform_init(&omap_drm_driver, device); } diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c index 44a7da66e081..8406c8251fbf 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c @@ -667,6 +667,8 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) int atombios_get_encoder_mode(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_connector *connector; struct radeon_connector *radeon_connector; @@ -693,7 +695,8 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) case DRM_MODE_CONNECTOR_DVII: case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */ if (drm_detect_hdmi_monitor(radeon_connector->edid) && - radeon_audio) + radeon_audio && + !ASIC_IS_DCE6(rdev)) /* remove once we support DCE6 */ return ATOM_ENCODER_MODE_HDMI; else if (radeon_connector->use_digital) return ATOM_ENCODER_MODE_DVI; @@ -704,7 +707,8 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) case DRM_MODE_CONNECTOR_HDMIA: default: if (drm_detect_hdmi_monitor(radeon_connector->edid) && - radeon_audio) + radeon_audio && + !ASIC_IS_DCE6(rdev)) /* remove once we support DCE6 */ return ATOM_ENCODER_MODE_HDMI; else return ATOM_ENCODER_MODE_DVI; @@ -718,7 +722,8 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) return ATOM_ENCODER_MODE_DP; else if (drm_detect_hdmi_monitor(radeon_connector->edid) && - radeon_audio) + radeon_audio && + !ASIC_IS_DCE6(rdev)) /* remove once we support DCE6 */ return ATOM_ENCODER_MODE_HDMI; else return ATOM_ENCODER_MODE_DVI; diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 8546e3b333b4..0f89ce3d02b9 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -4754,6 +4754,12 @@ static int evergreen_startup(struct radeon_device *rdev) rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0; /* Enable IRQ */ + if (!rdev->irq.installed) { + r = radeon_irq_kms_init(rdev); + if (r) + return r; + } + r = r600_irq_init(rdev); if (r) { DRM_ERROR("radeon: IH init failed (%d).\n", r); @@ -4923,10 +4929,6 @@ int evergreen_init(struct radeon_device *rdev) if (r) return r; - r = radeon_irq_kms_init(rdev); - if (r) - return r; - rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL; r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024); diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 7969c0c8ec20..84583302b081 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -2025,6 +2025,12 @@ static int cayman_startup(struct radeon_device *rdev) } /* Enable IRQ */ + if (!rdev->irq.installed) { + r = radeon_irq_kms_init(rdev); + if (r) + return r; + } + r = r600_irq_init(rdev); if (r) { DRM_ERROR("radeon: IH init failed (%d).\n", r); @@ -2190,10 +2196,6 @@ int cayman_init(struct radeon_device *rdev) if (r) return r; - r = radeon_irq_kms_init(rdev); - if (r) - return r; - ring->ring_obj = NULL; r600_ring_init(rdev, ring, 1024 * 1024); diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 4973bff37fec..d0314ecbd7c1 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -3869,6 +3869,12 @@ static int r100_startup(struct radeon_device *rdev) } /* Enable IRQ */ + if (!rdev->irq.installed) { + r = radeon_irq_kms_init(rdev); + if (r) + return r; + } + r100_irq_set(rdev); rdev->config.r100.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); /* 1M ring buffer */ @@ -4024,9 +4030,6 @@ int r100_init(struct radeon_device *rdev) r = radeon_fence_driver_init(rdev); if (r) return r; - r = radeon_irq_kms_init(rdev); - if (r) - return r; /* Memory manager */ r = radeon_bo_init(rdev); if (r) diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index c60350e6872d..b9b776f1e582 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c @@ -1382,6 +1382,12 @@ static int r300_startup(struct radeon_device *rdev) } /* Enable IRQ */ + if (!rdev->irq.installed) { + r = radeon_irq_kms_init(rdev); + if (r) + return r; + } + r100_irq_set(rdev); rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); /* 1M ring buffer */ @@ -1516,9 +1522,6 @@ int r300_init(struct radeon_device *rdev) r = radeon_fence_driver_init(rdev); if (r) return r; - r = radeon_irq_kms_init(rdev); - if (r) - return r; /* Memory manager */ r = radeon_bo_init(rdev); if (r) diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c index 6fce2eb4dd16..4e796ecf9ea4 100644 --- a/drivers/gpu/drm/radeon/r420.c +++ b/drivers/gpu/drm/radeon/r420.c @@ -265,6 +265,12 @@ static int r420_startup(struct radeon_device *rdev) } /* Enable IRQ */ + if (!rdev->irq.installed) { + r = radeon_irq_kms_init(rdev); + if (r) + return r; + } + r100_irq_set(rdev); rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); /* 1M ring buffer */ @@ -411,10 +417,6 @@ int r420_init(struct radeon_device *rdev) if (r) { return r; } - r = radeon_irq_kms_init(rdev); - if (r) { - return r; - } /* Memory manager */ r = radeon_bo_init(rdev); if (r) { diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c index f795a4e092cb..e1aece73b370 100644 --- a/drivers/gpu/drm/radeon/r520.c +++ b/drivers/gpu/drm/radeon/r520.c @@ -194,6 +194,12 @@ static int r520_startup(struct radeon_device *rdev) } /* Enable IRQ */ + if (!rdev->irq.installed) { + r = radeon_irq_kms_init(rdev); + if (r) + return r; + } + rs600_irq_set(rdev); rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); /* 1M ring buffer */ @@ -297,9 +303,6 @@ int r520_init(struct radeon_device *rdev) r = radeon_fence_driver_init(rdev); if (r) return r; - r = radeon_irq_kms_init(rdev); - if (r) - return r; /* Memory manager */ r = radeon_bo_init(rdev); if (r) diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index b45e64848677..6948eb88c2b7 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -1046,6 +1046,24 @@ int r600_mc_wait_for_idle(struct radeon_device *rdev) return -1; } +uint32_t rs780_mc_rreg(struct radeon_device *rdev, uint32_t reg) +{ + uint32_t r; + + WREG32(R_0028F8_MC_INDEX, S_0028F8_MC_IND_ADDR(reg)); + r = RREG32(R_0028FC_MC_DATA); + WREG32(R_0028F8_MC_INDEX, ~C_0028F8_MC_IND_ADDR); + return r; +} + +void rs780_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) +{ + WREG32(R_0028F8_MC_INDEX, S_0028F8_MC_IND_ADDR(reg) | + S_0028F8_MC_IND_WR_EN(1)); + WREG32(R_0028FC_MC_DATA, v); + WREG32(R_0028F8_MC_INDEX, 0x7F); +} + static void r600_mc_program(struct radeon_device *rdev) { struct rv515_mc_save save; @@ -1181,6 +1199,8 @@ static int r600_mc_init(struct radeon_device *rdev) { u32 tmp; int chansize, numchan; + uint32_t h_addr, l_addr; + unsigned long long k8_addr; /* Get VRAM informations */ rdev->mc.vram_is_ddr = true; @@ -1221,7 +1241,30 @@ static int r600_mc_init(struct radeon_device *rdev) if (rdev->flags & RADEON_IS_IGP) { rs690_pm_info(rdev); rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); + + if (rdev->family == CHIP_RS780 || rdev->family == CHIP_RS880) { + /* Use K8 direct mapping for fast fb access. */ + rdev->fastfb_working = false; + h_addr = G_000012_K8_ADDR_EXT(RREG32_MC(R_000012_MC_MISC_UMA_CNTL)); + l_addr = RREG32_MC(R_000011_K8_FB_LOCATION); + k8_addr = ((unsigned long long)h_addr) << 32 | l_addr; +#if defined(CONFIG_X86_32) && !defined(CONFIG_X86_PAE) + if (k8_addr + rdev->mc.visible_vram_size < 0x100000000ULL) +#endif + { + /* FastFB shall be used with UMA memory. Here it is simply disabled when sideport + * memory is present. + */ + if (rdev->mc.igp_sideport_enabled == false && radeon_fastfb == 1) { + DRM_INFO("Direct mapping: aper base at 0x%llx, replaced by direct mapping base 0x%llx.\n", + (unsigned long long)rdev->mc.aper_base, k8_addr); + rdev->mc.aper_base = (resource_size_t)k8_addr; + rdev->fastfb_working = true; + } + } + } } + radeon_update_bandwidth_info(rdev); return 0; } @@ -2644,6 +2687,9 @@ void r600_uvd_rbc_stop(struct radeon_device *rdev) int r600_uvd_init(struct radeon_device *rdev) { int i, j, r; + /* disable byte swapping */ + u32 lmi_swap_cntl = 0; + u32 mp_swap_cntl = 0; /* raise clocks while booting up the VCPU */ radeon_set_uvd_clocks(rdev, 53300, 40000); @@ -2668,9 +2714,13 @@ int r600_uvd_init(struct radeon_device *rdev) WREG32(UVD_LMI_CTRL, 0x40 | (1 << 8) | (1 << 13) | (1 << 21) | (1 << 9) | (1 << 20)); - /* disable byte swapping */ - WREG32(UVD_LMI_SWAP_CNTL, 0); - WREG32(UVD_MP_SWAP_CNTL, 0); +#ifdef __BIG_ENDIAN + /* swap (8 in 32) RB and IB */ + lmi_swap_cntl = 0xa; + mp_swap_cntl = 0; +#endif + WREG32(UVD_LMI_SWAP_CNTL, lmi_swap_cntl); + WREG32(UVD_MP_SWAP_CNTL, mp_swap_cntl); WREG32(UVD_MPC_SET_MUXA0, 0x40c2040); WREG32(UVD_MPC_SET_MUXA1, 0x0); @@ -3202,6 +3252,12 @@ static int r600_startup(struct radeon_device *rdev) } /* Enable IRQ */ + if (!rdev->irq.installed) { + r = radeon_irq_kms_init(rdev); + if (r) + return r; + } + r = r600_irq_init(rdev); if (r) { DRM_ERROR("radeon: IH init failed (%d).\n", r); @@ -3356,10 +3412,6 @@ int r600_init(struct radeon_device *rdev) if (r) return r; - r = radeon_irq_kms_init(rdev); - if (r) - return r; - rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL; r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024); diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index acb146c06973..79df558f8c40 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h @@ -1342,6 +1342,14 @@ #define PACKET3_STRMOUT_BASE_UPDATE 0x72 /* r7xx */ #define PACKET3_SURFACE_BASE_UPDATE 0x73 +#define R_000011_K8_FB_LOCATION 0x11 +#define R_000012_MC_MISC_UMA_CNTL 0x12 +#define G_000012_K8_ADDR_EXT(x) (((x) >> 0) & 0xFF) +#define R_0028F8_MC_INDEX 0x28F8 +#define S_0028F8_MC_IND_ADDR(x) (((x) & 0x1FF) << 0) +#define C_0028F8_MC_IND_ADDR 0xFFFFFE00 +#define S_0028F8_MC_IND_WR_EN(x) (((x) & 0x1) << 9) +#define R_0028FC_MC_DATA 0x28FC #define R_008020_GRBM_SOFT_RESET 0x8020 #define S_008020_SOFT_RESET_CP(x) (((x) & 1) << 0) diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 06b8c19ab19e..a2802b47ee95 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c @@ -122,6 +122,10 @@ static void radeon_register_accessor_init(struct radeon_device *rdev) rdev->mc_rreg = &rs600_mc_rreg; rdev->mc_wreg = &rs600_mc_wreg; } + if (rdev->family == CHIP_RS780 || rdev->family == CHIP_RS880) { + rdev->mc_rreg = &rs780_mc_rreg; + rdev->mc_wreg = &rs780_mc_wreg; + } if (rdev->family >= CHIP_R600) { rdev->pciep_rreg = &r600_pciep_rreg; rdev->pciep_wreg = &r600_pciep_wreg; diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 2c87365d345f..a72759ede753 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h @@ -347,6 +347,8 @@ extern bool r600_gui_idle(struct radeon_device *rdev); extern void r600_pm_misc(struct radeon_device *rdev); extern void r600_pm_init_profile(struct radeon_device *rdev); extern void rs780_pm_init_profile(struct radeon_device *rdev); +extern uint32_t rs780_mc_rreg(struct radeon_device *rdev, uint32_t reg); +extern void rs780_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); extern void r600_pm_get_dynpm_state(struct radeon_device *rdev); extern void r600_set_pcie_lanes(struct radeon_device *rdev, int lanes); extern int r600_get_pcie_lanes(struct radeon_device *rdev); diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 189973836cff..b0dc0b6cb4e0 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -244,16 +244,6 @@ void radeon_scratch_free(struct radeon_device *rdev, uint32_t reg) */ void radeon_wb_disable(struct radeon_device *rdev) { - int r; - - if (rdev->wb.wb_obj) { - r = radeon_bo_reserve(rdev->wb.wb_obj, false); - if (unlikely(r != 0)) - return; - radeon_bo_kunmap(rdev->wb.wb_obj); - radeon_bo_unpin(rdev->wb.wb_obj); - radeon_bo_unreserve(rdev->wb.wb_obj); - } rdev->wb.enabled = false; } @@ -269,6 +259,11 @@ void radeon_wb_fini(struct radeon_device *rdev) { radeon_wb_disable(rdev); if (rdev->wb.wb_obj) { + if (!radeon_bo_reserve(rdev->wb.wb_obj, false)) { + radeon_bo_kunmap(rdev->wb.wb_obj); + radeon_bo_unpin(rdev->wb.wb_obj); + radeon_bo_unreserve(rdev->wb.wb_obj); + } radeon_bo_unref(&rdev->wb.wb_obj); rdev->wb.wb = NULL; rdev->wb.wb_obj = NULL; @@ -295,26 +290,26 @@ int radeon_wb_init(struct radeon_device *rdev) dev_warn(rdev->dev, "(%d) create WB bo failed\n", r); return r; } - } - r = radeon_bo_reserve(rdev->wb.wb_obj, false); - if (unlikely(r != 0)) { - radeon_wb_fini(rdev); - return r; - } - r = radeon_bo_pin(rdev->wb.wb_obj, RADEON_GEM_DOMAIN_GTT, - &rdev->wb.gpu_addr); - if (r) { + r = radeon_bo_reserve(rdev->wb.wb_obj, false); + if (unlikely(r != 0)) { + radeon_wb_fini(rdev); + return r; + } + r = radeon_bo_pin(rdev->wb.wb_obj, RADEON_GEM_DOMAIN_GTT, + &rdev->wb.gpu_addr); + if (r) { + radeon_bo_unreserve(rdev->wb.wb_obj); + dev_warn(rdev->dev, "(%d) pin WB bo failed\n", r); + radeon_wb_fini(rdev); + return r; + } + r = radeon_bo_kmap(rdev->wb.wb_obj, (void **)&rdev->wb.wb); radeon_bo_unreserve(rdev->wb.wb_obj); - dev_warn(rdev->dev, "(%d) pin WB bo failed\n", r); - radeon_wb_fini(rdev); - return r; - } - r = radeon_bo_kmap(rdev->wb.wb_obj, (void **)&rdev->wb.wb); - radeon_bo_unreserve(rdev->wb.wb_obj); - if (r) { - dev_warn(rdev->dev, "(%d) map WB bo failed\n", r); - radeon_wb_fini(rdev); - return r; + if (r) { + dev_warn(rdev->dev, "(%d) map WB bo failed\n", r); + radeon_wb_fini(rdev); + return r; + } } /* clear wb memory */ diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index 5b937dfe6f65..ddb8f8e04eb5 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c @@ -63,7 +63,9 @@ static void radeon_fence_write(struct radeon_device *rdev, u32 seq, int ring) { struct radeon_fence_driver *drv = &rdev->fence_drv[ring]; if (likely(rdev->wb.enabled || !drv->scratch_reg)) { - *drv->cpu_addr = cpu_to_le32(seq); + if (drv->cpu_addr) { + *drv->cpu_addr = cpu_to_le32(seq); + } } else { WREG32(drv->scratch_reg, seq); } @@ -84,7 +86,11 @@ static u32 radeon_fence_read(struct radeon_device *rdev, int ring) u32 seq = 0; if (likely(rdev->wb.enabled || !drv->scratch_reg)) { - seq = le32_to_cpu(*drv->cpu_addr); + if (drv->cpu_addr) { + seq = le32_to_cpu(*drv->cpu_addr); + } else { + seq = lower_32_bits(atomic64_read(&drv->last_seq)); + } } else { seq = RREG32(drv->scratch_reg); } diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index 2c1341f63dc5..43ec4a401f07 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c @@ -1197,11 +1197,13 @@ int radeon_vm_bo_update_pte(struct radeon_device *rdev, int radeon_vm_bo_rmv(struct radeon_device *rdev, struct radeon_bo_va *bo_va) { - int r; + int r = 0; mutex_lock(&rdev->vm_manager.lock); mutex_lock(&bo_va->vm->mutex); - r = radeon_vm_bo_update_pte(rdev, bo_va->vm, bo_va->bo, NULL); + if (bo_va->soffset) { + r = radeon_vm_bo_update_pte(rdev, bo_va->vm, bo_va->bo, NULL); + } mutex_unlock(&rdev->vm_manager.lock); list_del(&bo_va->vm_list); mutex_unlock(&bo_va->vm->mutex); diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index e17faa7cf732..82434018cbe8 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c @@ -402,6 +402,13 @@ int radeon_ring_alloc(struct radeon_device *rdev, struct radeon_ring *ring, unsi return -ENOMEM; /* Align requested size with padding so unlock_commit can * pad safely */ + radeon_ring_free_size(rdev, ring); + if (ring->ring_free_dw == (ring->ring_size / 4)) { + /* This is an empty ring update lockup info to avoid + * false positive. + */ + radeon_ring_lockup_update(ring); + } ndw = (ndw + ring->align_mask) & ~ring->align_mask; while (ndw > (ring->ring_free_dw - 1)) { radeon_ring_free_size(rdev, ring); diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c index 906e5c0ca3b9..cad735dd02c6 100644 --- a/drivers/gpu/drm/radeon/radeon_uvd.c +++ b/drivers/gpu/drm/radeon/radeon_uvd.c @@ -159,7 +159,17 @@ int radeon_uvd_suspend(struct radeon_device *rdev) if (!r) { radeon_bo_kunmap(rdev->uvd.vcpu_bo); radeon_bo_unpin(rdev->uvd.vcpu_bo); + rdev->uvd.cpu_addr = NULL; + if (!radeon_bo_pin(rdev->uvd.vcpu_bo, RADEON_GEM_DOMAIN_CPU, NULL)) { + radeon_bo_kmap(rdev->uvd.vcpu_bo, &rdev->uvd.cpu_addr); + } radeon_bo_unreserve(rdev->uvd.vcpu_bo); + + if (rdev->uvd.cpu_addr) { + radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_UVD_INDEX); + } else { + rdev->fence_drv[R600_RING_TYPE_UVD_INDEX].cpu_addr = NULL; + } } return r; } @@ -178,6 +188,10 @@ int radeon_uvd_resume(struct radeon_device *rdev) return r; } + /* Have been pin in cpu unmap unpin */ + radeon_bo_kunmap(rdev->uvd.vcpu_bo); + radeon_bo_unpin(rdev->uvd.vcpu_bo); + r = radeon_bo_pin(rdev->uvd.vcpu_bo, RADEON_GEM_DOMAIN_VRAM, &rdev->uvd.gpu_addr); if (r) { @@ -613,19 +627,19 @@ int radeon_uvd_get_create_msg(struct radeon_device *rdev, int ring, } /* stitch together an UVD create msg */ - msg[0] = 0x00000de4; - msg[1] = 0x00000000; - msg[2] = handle; - msg[3] = 0x00000000; - msg[4] = 0x00000000; - msg[5] = 0x00000000; - msg[6] = 0x00000000; - msg[7] = 0x00000780; - msg[8] = 0x00000440; - msg[9] = 0x00000000; - msg[10] = 0x01b37000; + msg[0] = cpu_to_le32(0x00000de4); + msg[1] = cpu_to_le32(0x00000000); + msg[2] = cpu_to_le32(handle); + msg[3] = cpu_to_le32(0x00000000); + msg[4] = cpu_to_le32(0x00000000); + msg[5] = cpu_to_le32(0x00000000); + msg[6] = cpu_to_le32(0x00000000); + msg[7] = cpu_to_le32(0x00000780); + msg[8] = cpu_to_le32(0x00000440); + msg[9] = cpu_to_le32(0x00000000); + msg[10] = cpu_to_le32(0x01b37000); for (i = 11; i < 1024; ++i) - msg[i] = 0x0; + msg[i] = cpu_to_le32(0x0); radeon_bo_kunmap(bo); radeon_bo_unreserve(bo); @@ -659,12 +673,12 @@ int radeon_uvd_get_destroy_msg(struct radeon_device *rdev, int ring, } /* stitch together an UVD destroy msg */ - msg[0] = 0x00000de4; - msg[1] = 0x00000002; - msg[2] = handle; - msg[3] = 0x00000000; + msg[0] = cpu_to_le32(0x00000de4); + msg[1] = cpu_to_le32(0x00000002); + msg[2] = cpu_to_le32(handle); + msg[3] = cpu_to_le32(0x00000000); for (i = 4; i < 1024; ++i) - msg[i] = 0x0; + msg[i] = cpu_to_le32(0x0); radeon_bo_kunmap(bo); radeon_bo_unreserve(bo); diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c index 73051ce3121e..233a9b9fa1f7 100644 --- a/drivers/gpu/drm/radeon/rs400.c +++ b/drivers/gpu/drm/radeon/rs400.c @@ -417,6 +417,12 @@ static int rs400_startup(struct radeon_device *rdev) } /* Enable IRQ */ + if (!rdev->irq.installed) { + r = radeon_irq_kms_init(rdev); + if (r) + return r; + } + r100_irq_set(rdev); rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); /* 1M ring buffer */ @@ -535,9 +541,6 @@ int rs400_init(struct radeon_device *rdev) r = radeon_fence_driver_init(rdev); if (r) return r; - r = radeon_irq_kms_init(rdev); - if (r) - return r; /* Memory manager */ r = radeon_bo_init(rdev); if (r) diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 46fa1b07c560..670b555d2ca2 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c @@ -923,6 +923,12 @@ static int rs600_startup(struct radeon_device *rdev) } /* Enable IRQ */ + if (!rdev->irq.installed) { + r = radeon_irq_kms_init(rdev); + if (r) + return r; + } + rs600_irq_set(rdev); rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); /* 1M ring buffer */ @@ -1047,9 +1053,6 @@ int rs600_init(struct radeon_device *rdev) r = radeon_fence_driver_init(rdev); if (r) return r; - r = radeon_irq_kms_init(rdev); - if (r) - return r; /* Memory manager */ r = radeon_bo_init(rdev); if (r) diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index ab4c86cfd552..55880d5962c3 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c @@ -651,6 +651,12 @@ static int rs690_startup(struct radeon_device *rdev) } /* Enable IRQ */ + if (!rdev->irq.installed) { + r = radeon_irq_kms_init(rdev); + if (r) + return r; + } + rs600_irq_set(rdev); rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); /* 1M ring buffer */ @@ -776,9 +782,6 @@ int rs690_init(struct radeon_device *rdev) r = radeon_fence_driver_init(rdev); if (r) return r; - r = radeon_irq_kms_init(rdev); - if (r) - return r; /* Memory manager */ r = radeon_bo_init(rdev); if (r) diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index ffcba730c57c..21c7d7b26e55 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c @@ -532,6 +532,12 @@ static int rv515_startup(struct radeon_device *rdev) } /* Enable IRQ */ + if (!rdev->irq.installed) { + r = radeon_irq_kms_init(rdev); + if (r) + return r; + } + rs600_irq_set(rdev); rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); /* 1M ring buffer */ @@ -662,9 +668,6 @@ int rv515_init(struct radeon_device *rdev) r = radeon_fence_driver_init(rdev); if (r) return r; - r = radeon_irq_kms_init(rdev); - if (r) - return r; /* Memory manager */ r = radeon_bo_init(rdev); if (r) diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 08aef24afe40..4a62ad2e5399 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -1887,6 +1887,12 @@ static int rv770_startup(struct radeon_device *rdev) rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0; /* Enable IRQ */ + if (!rdev->irq.installed) { + r = radeon_irq_kms_init(rdev); + if (r) + return r; + } + r = r600_irq_init(rdev); if (r) { DRM_ERROR("radeon: IH init failed (%d).\n", r); @@ -2045,10 +2051,6 @@ int rv770_init(struct radeon_device *rdev) if (r) return r; - r = radeon_irq_kms_init(rdev); - if (r) - return r; - rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL; r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024); diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index d1ba9d88f311..a1b0da6b5808 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -5350,6 +5350,12 @@ static int si_startup(struct radeon_device *rdev) } /* Enable IRQ */ + if (!rdev->irq.installed) { + r = radeon_irq_kms_init(rdev); + if (r) + return r; + } + r = si_irq_init(rdev); if (r) { DRM_ERROR("radeon: IH init failed (%d).\n", r); @@ -5533,10 +5539,6 @@ int si_init(struct radeon_device *rdev) if (r) return r; - r = radeon_irq_kms_init(rdev); - if (r) - return r; - ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; ring->ring_obj = NULL; r600_ring_init(rdev, ring, 1024 * 1024); diff --git a/drivers/gpu/drm/tilcdc/Kconfig b/drivers/gpu/drm/tilcdc/Kconfig index e461e9972455..7a4d10106906 100644 --- a/drivers/gpu/drm/tilcdc/Kconfig +++ b/drivers/gpu/drm/tilcdc/Kconfig @@ -6,6 +6,7 @@ config DRM_TILCDC select DRM_GEM_CMA_HELPER select VIDEOMODE_HELPERS select BACKLIGHT_CLASS_DEVICE + select BACKLIGHT_LCD_SUPPORT help Choose this option if you have an TI SoC with LCDC display controller, for example AM33xx in beagle-bone, DA8xx, or diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index dc3ae5c56f56..d39a5cede0b0 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -264,9 +264,12 @@ static struct mt_class mt_classes[] = { static void mt_free_input_name(struct hid_input *hi) { struct hid_device *hdev = hi->report->device; + const char *name = hi->input->name; - if (hi->input->name != hdev->name) - kfree(hi->input->name); + if (name != hdev->name) { + hi->input->name = hdev->name; + kfree(name); + } } static ssize_t mt_show_quirks(struct device *dev, @@ -1040,11 +1043,11 @@ static void mt_remove(struct hid_device *hdev) struct hid_input *hi; sysfs_remove_group(&hdev->dev.kobj, &mt_attribute_group); - hid_hw_stop(hdev); - list_for_each_entry(hi, &hdev->inputs, list) mt_free_input_name(hi); + hid_hw_stop(hdev); + kfree(td); hid_set_drvdata(hdev, NULL); } diff --git a/drivers/hwmon/adm1021.c b/drivers/hwmon/adm1021.c index 7e76922a4ba9..f920619cd6da 100644 --- a/drivers/hwmon/adm1021.c +++ b/drivers/hwmon/adm1021.c @@ -331,26 +331,68 @@ static int adm1021_detect(struct i2c_client *client, man_id = i2c_smbus_read_byte_data(client, ADM1021_REG_MAN_ID); dev_id = i2c_smbus_read_byte_data(client, ADM1021_REG_DEV_ID); + if (man_id < 0 || dev_id < 0) + return -ENODEV; + if (man_id == 0x4d && dev_id == 0x01) type_name = "max1617a"; else if (man_id == 0x41) { if ((dev_id & 0xF0) == 0x30) type_name = "adm1023"; - else + else if ((dev_id & 0xF0) == 0x00) type_name = "adm1021"; + else + return -ENODEV; } else if (man_id == 0x49) type_name = "thmc10"; else if (man_id == 0x23) type_name = "gl523sm"; else if (man_id == 0x54) type_name = "mc1066"; - /* LM84 Mfr ID in a different place, and it has more unused bits */ - else if (conv_rate == 0x00 - && (config & 0x7F) == 0x00 - && (status & 0xAB) == 0x00) - type_name = "lm84"; - else - type_name = "max1617"; + else { + int lte, rte, lhi, rhi, llo, rlo; + + /* extra checks for LM84 and MAX1617 to avoid misdetections */ + + llo = i2c_smbus_read_byte_data(client, ADM1021_REG_THYST_R(0)); + rlo = i2c_smbus_read_byte_data(client, ADM1021_REG_THYST_R(1)); + + /* fail if any of the additional register reads failed */ + if (llo < 0 || rlo < 0) + return -ENODEV; + + lte = i2c_smbus_read_byte_data(client, ADM1021_REG_TEMP(0)); + rte = i2c_smbus_read_byte_data(client, ADM1021_REG_TEMP(1)); + lhi = i2c_smbus_read_byte_data(client, ADM1021_REG_TOS_R(0)); + rhi = i2c_smbus_read_byte_data(client, ADM1021_REG_TOS_R(1)); + + /* + * Fail for negative temperatures and negative high limits. + * This check also catches read errors on the tested registers. + */ + if ((s8)lte < 0 || (s8)rte < 0 || (s8)lhi < 0 || (s8)rhi < 0) + return -ENODEV; + + /* fail if all registers hold the same value */ + if (lte == rte && lte == lhi && lte == rhi && lte == llo + && lte == rlo) + return -ENODEV; + + /* + * LM84 Mfr ID is in a different place, + * and it has more unused bits. + */ + if (conv_rate == 0x00 + && (config & 0x7F) == 0x00 + && (status & 0xAB) == 0x00) { + type_name = "lm84"; + } else { + /* fail if low limits are larger than high limits */ + if ((s8)llo > lhi || (s8)rlo > rhi) + return -ENODEV; + type_name = "max1617"; + } + } pr_debug("Detected chip %s at adapter %d, address 0x%02x.\n", type_name, i2c_adapter_id(adapter), client->addr); diff --git a/drivers/iio/buffer_cb.c b/drivers/iio/buffer_cb.c index 9201022945e9..9d19ba74f22b 100644 --- a/drivers/iio/buffer_cb.c +++ b/drivers/iio/buffer_cb.c @@ -64,7 +64,7 @@ struct iio_cb_buffer *iio_channel_get_all_cb(struct device *dev, while (chan->indio_dev) { if (chan->indio_dev != indio_dev) { ret = -EINVAL; - goto error_release_channels; + goto error_free_scan_mask; } set_bit(chan->channel->scan_index, cb_buff->buffer.scan_mask); @@ -73,6 +73,8 @@ struct iio_cb_buffer *iio_channel_get_all_cb(struct device *dev, return cb_buff; +error_free_scan_mask: + kfree(cb_buff->buffer.scan_mask); error_release_channels: iio_channel_release_all(cb_buff->channels); error_free_cb_buff: @@ -100,6 +102,7 @@ EXPORT_SYMBOL_GPL(iio_channel_stop_all_cb); void iio_channel_release_all_cb(struct iio_cb_buffer *cb_buff) { + kfree(cb_buff->buffer.scan_mask); iio_channel_release_all(cb_buff->channels); kfree(cb_buff); } diff --git a/drivers/iio/frequency/adf4350.c b/drivers/iio/frequency/adf4350.c index a884252ac66b..e76d4ace53ff 100644 --- a/drivers/iio/frequency/adf4350.c +++ b/drivers/iio/frequency/adf4350.c @@ -212,7 +212,7 @@ static int adf4350_set_freq(struct adf4350_state *st, unsigned long long freq) (pdata->r2_user_settings & (ADF4350_REG2_PD_POLARITY_POS | ADF4350_REG2_LDP_6ns | ADF4350_REG2_LDF_INT_N | ADF4350_REG2_CHARGE_PUMP_CURR_uA(5000) | - ADF4350_REG2_MUXOUT(0x7) | ADF4350_REG2_NOISE_MODE(0x9))); + ADF4350_REG2_MUXOUT(0x7) | ADF4350_REG2_NOISE_MODE(0x3))); st->regs[ADF4350_REG3] = pdata->r3_user_settings & (ADF4350_REG3_12BIT_CLKDIV(0xFFF) | diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c index 795d100b4c36..98ddc323add0 100644 --- a/drivers/iio/inkern.c +++ b/drivers/iio/inkern.c @@ -124,7 +124,7 @@ static int __of_iio_channel_get(struct iio_channel *channel, channel->indio_dev = indio_dev; index = iiospec.args_count ? iiospec.args[0] : 0; if (index >= indio_dev->num_channels) { - return -EINVAL; + err = -EINVAL; goto err_put; } channel->channel = &indio_dev->channels[index]; @@ -450,7 +450,7 @@ static int iio_convert_raw_to_processed_unlocked(struct iio_channel *chan, s64 raw64 = raw; int ret; - ret = iio_channel_read(chan, &offset, NULL, IIO_CHAN_INFO_SCALE); + ret = iio_channel_read(chan, &offset, NULL, IIO_CHAN_INFO_OFFSET); if (ret == 0) raw64 += offset; diff --git a/drivers/infiniband/hw/qib/qib_keys.c b/drivers/infiniband/hw/qib/qib_keys.c index 81c7b73695d2..3b9afccaaade 100644 --- a/drivers/infiniband/hw/qib/qib_keys.c +++ b/drivers/infiniband/hw/qib/qib_keys.c @@ -61,7 +61,7 @@ int qib_alloc_lkey(struct qib_mregion *mr, int dma_region) if (dma_region) { struct qib_mregion *tmr; - tmr = rcu_dereference(dev->dma_mr); + tmr = rcu_access_pointer(dev->dma_mr); if (!tmr) { qib_get_mr(mr); rcu_assign_pointer(dev->dma_mr, mr); diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index f19b0998a53c..2e84ef859c5b 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/drivers/infiniband/ulp/iser/iscsi_iser.c @@ -5,6 +5,7 @@ * Copyright (C) 2004 Alex Aizman * Copyright (C) 2005 Mike Christie * Copyright (c) 2005, 2006 Voltaire, Inc. All rights reserved. + * Copyright (c) 2013 Mellanox Technologies. All rights reserved. * maintained by openib-general@openib.org * * This software is available to you under a choice of one of two diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h index 06f578cde75b..4f069c0d4c04 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.h +++ b/drivers/infiniband/ulp/iser/iscsi_iser.h @@ -8,6 +8,7 @@ * * Copyright (c) 2004, 2005, 2006 Voltaire, Inc. All rights reserved. * Copyright (c) 2005, 2006 Cisco Systems. All rights reserved. + * Copyright (c) 2013 Mellanox Technologies. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/drivers/infiniband/ulp/iser/iser_initiator.c b/drivers/infiniband/ulp/iser/iser_initiator.c index a00ccd1ca333..b6d81a86c976 100644 --- a/drivers/infiniband/ulp/iser/iser_initiator.c +++ b/drivers/infiniband/ulp/iser/iser_initiator.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2004, 2005, 2006 Voltaire, Inc. All rights reserved. + * Copyright (c) 2013 Mellanox Technologies. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/drivers/infiniband/ulp/iser/iser_memory.c b/drivers/infiniband/ulp/iser/iser_memory.c index 68ebb7fe072a..7827baf455a1 100644 --- a/drivers/infiniband/ulp/iser/iser_memory.c +++ b/drivers/infiniband/ulp/iser/iser_memory.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2004, 2005, 2006 Voltaire, Inc. All rights reserved. + * Copyright (c) 2013 Mellanox Technologies. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c index 5278916c3103..2c4941d0656b 100644 --- a/drivers/infiniband/ulp/iser/iser_verbs.c +++ b/drivers/infiniband/ulp/iser/iser_verbs.c @@ -1,6 +1,7 @@ /* * Copyright (c) 2004, 2005, 2006 Voltaire, Inc. All rights reserved. * Copyright (c) 2005, 2006 Cisco Systems. All rights reserved. + * Copyright (c) 2013 Mellanox Technologies. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU @@ -292,10 +293,10 @@ out_err: } /** - * releases the FMR pool, QP and CMA ID objects, returns 0 on success, + * releases the FMR pool and QP objects, returns 0 on success, * -1 on failure */ -static int iser_free_ib_conn_res(struct iser_conn *ib_conn, int can_destroy_id) +static int iser_free_ib_conn_res(struct iser_conn *ib_conn) { int cq_index; BUG_ON(ib_conn == NULL); @@ -314,13 +315,9 @@ static int iser_free_ib_conn_res(struct iser_conn *ib_conn, int can_destroy_id) rdma_destroy_qp(ib_conn->cma_id); } - /* if cma handler context, the caller acts s.t the cma destroy the id */ - if (ib_conn->cma_id != NULL && can_destroy_id) - rdma_destroy_id(ib_conn->cma_id); ib_conn->fmr_pool = NULL; ib_conn->qp = NULL; - ib_conn->cma_id = NULL; kfree(ib_conn->page_vec); if (ib_conn->login_buf) { @@ -415,11 +412,16 @@ static void iser_conn_release(struct iser_conn *ib_conn, int can_destroy_id) list_del(&ib_conn->conn_list); mutex_unlock(&ig.connlist_mutex); iser_free_rx_descriptors(ib_conn); - iser_free_ib_conn_res(ib_conn, can_destroy_id); + iser_free_ib_conn_res(ib_conn); ib_conn->device = NULL; /* on EVENT_ADDR_ERROR there's no device yet for this conn */ if (device != NULL) iser_device_try_release(device); + /* if cma handler context, the caller actually destroy the id */ + if (ib_conn->cma_id != NULL && can_destroy_id) { + rdma_destroy_id(ib_conn->cma_id); + ib_conn->cma_id = NULL; + } iscsi_destroy_endpoint(ib_conn->ep); } diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index b08ca7a9f76b..3f3f0416fbdd 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -2227,6 +2227,27 @@ static void srpt_close_ch(struct srpt_rdma_ch *ch) } /** + * srpt_shutdown_session() - Whether or not a session may be shut down. + */ +static int srpt_shutdown_session(struct se_session *se_sess) +{ + struct srpt_rdma_ch *ch = se_sess->fabric_sess_ptr; + unsigned long flags; + + spin_lock_irqsave(&ch->spinlock, flags); + if (ch->in_shutdown) { + spin_unlock_irqrestore(&ch->spinlock, flags); + return true; + } + + ch->in_shutdown = true; + target_sess_cmd_list_set_waiting(se_sess); + spin_unlock_irqrestore(&ch->spinlock, flags); + + return true; +} + +/** * srpt_drain_channel() - Drain a channel by resetting the IB queue pair. * @cm_id: Pointer to the CM ID of the channel to be drained. * @@ -2264,6 +2285,9 @@ static void srpt_drain_channel(struct ib_cm_id *cm_id) spin_unlock_irq(&sdev->spinlock); if (do_reset) { + if (ch->sess) + srpt_shutdown_session(ch->sess); + ret = srpt_ch_qp_err(ch); if (ret < 0) printk(KERN_ERR "Setting queue pair in error state" @@ -2328,7 +2352,7 @@ static void srpt_release_channel_work(struct work_struct *w) se_sess = ch->sess; BUG_ON(!se_sess); - target_wait_for_sess_cmds(se_sess, 0); + target_wait_for_sess_cmds(se_sess); transport_deregister_session_configfs(se_sess); transport_deregister_session(se_sess); @@ -3467,14 +3491,6 @@ static void srpt_release_cmd(struct se_cmd *se_cmd) } /** - * srpt_shutdown_session() - Whether or not a session may be shut down. - */ -static int srpt_shutdown_session(struct se_session *se_sess) -{ - return true; -} - -/** * srpt_close_session() - Forcibly close a session. * * Callback function invoked by the TCM core to clean up sessions associated diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.h b/drivers/infiniband/ulp/srpt/ib_srpt.h index 4caf55cda7b1..3dae156905de 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.h +++ b/drivers/infiniband/ulp/srpt/ib_srpt.h @@ -325,6 +325,7 @@ struct srpt_rdma_ch { u8 sess_name[36]; struct work_struct release_work; struct completion *release_done; + bool in_shutdown; }; /** diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 2f78538e09d0..b2420ae19e14 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -1379,6 +1379,7 @@ static int synaptics_reconnect(struct psmouse *psmouse) { struct synaptics_data *priv = psmouse->private; struct synaptics_data old_priv = *priv; + unsigned char param[2]; int retry = 0; int error; @@ -1394,6 +1395,7 @@ static int synaptics_reconnect(struct psmouse *psmouse) */ ssleep(1); } + ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_GETID); error = synaptics_detect(psmouse, 0); } while (error && ++retry < 3); diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 5c68e4486845..518282da6d85 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c @@ -1966,7 +1966,8 @@ static const struct wacom_features wacom_features_0xF4 = 63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; static const struct wacom_features wacom_features_0xF8 = { "Wacom Cintiq 24HD touch", WACOM_PKGLEN_INTUOS, 104480, 65600, 2047, /* Pen */ - 63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf6 }; + 63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, + .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf6 }; static const struct wacom_features wacom_features_0xF6 = { "Wacom Cintiq 24HD touch", .type = WACOM_24HDT, /* Touch */ .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf8, .touch_max = 10 }; @@ -2009,7 +2010,8 @@ static const struct wacom_features wacom_features_0xFA = 63, WACOM_22HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; static const struct wacom_features wacom_features_0x5B = { "Wacom Cintiq 22HDT", WACOM_PKGLEN_INTUOS, 95840, 54260, 2047, - 63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x5e }; + 63, WACOM_22HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, + .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x5e }; static const struct wacom_features wacom_features_0x5E = { "Wacom Cintiq 22HDT", .type = WACOM_24HDT, .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x5b, .touch_max = 10 }; @@ -2042,7 +2044,7 @@ static const struct wacom_features wacom_features_0xE5 = static const struct wacom_features wacom_features_0xE6 = { "Wacom ISDv4 E6", WACOM_PKGLEN_TPC2FG, 27760, 15694, 255, 0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES, - .touch_max = 2 }; + .touch_max = 2 }; static const struct wacom_features wacom_features_0xEC = { "Wacom ISDv4 EC", WACOM_PKGLEN_GRAPHIRE, 25710, 14500, 255, 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 1760ceb68b7b..19ceaa60e0f4 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -705,7 +705,7 @@ static int gic_irq_domain_xlate(struct irq_domain *d, static int __cpuinit gic_secondary_init(struct notifier_block *nfb, unsigned long action, void *hcpu) { - if (action == CPU_STARTING) + if (action == CPU_STARTING || action == CPU_STARTING_FROZEN) gic_cpu_init(&gic_data[0]); return NOTIFY_OK; } diff --git a/drivers/irqchip/irq-mxs.c b/drivers/irqchip/irq-mxs.c index 29889bbdcc6d..63b3d4eb0ef7 100644 --- a/drivers/irqchip/irq-mxs.c +++ b/drivers/irqchip/irq-mxs.c @@ -76,16 +76,10 @@ asmlinkage void __exception_irq_entry icoll_handle_irq(struct pt_regs *regs) { u32 irqnr; - do { - irqnr = __raw_readl(icoll_base + HW_ICOLL_STAT_OFFSET); - if (irqnr != 0x7f) { - __raw_writel(irqnr, icoll_base + HW_ICOLL_VECTOR); - irqnr = irq_find_mapping(icoll_domain, irqnr); - handle_IRQ(irqnr, regs); - continue; - } - break; - } while (1); + irqnr = __raw_readl(icoll_base + HW_ICOLL_STAT_OFFSET); + __raw_writel(irqnr, icoll_base + HW_ICOLL_VECTOR); + irqnr = irq_find_mapping(icoll_domain, irqnr); + handle_IRQ(irqnr, regs); } static int icoll_irq_domain_map(struct irq_domain *d, unsigned int virq, diff --git a/drivers/irqchip/irq-versatile-fpga.c b/drivers/irqchip/irq-versatile-fpga.c index 065b7a31a478..47a52ab580d8 100644 --- a/drivers/irqchip/irq-versatile-fpga.c +++ b/drivers/irqchip/irq-versatile-fpga.c @@ -119,7 +119,7 @@ static int fpga_irqdomain_map(struct irq_domain *d, unsigned int irq, /* Skip invalid IRQs, only register handlers for the real ones */ if (!(f->valid & BIT(hwirq))) - return -ENOTSUPP; + return -EPERM; irq_set_chip_data(irq, f); irq_set_chip_and_handler(irq, &f->chip, handle_level_irq); diff --git a/drivers/irqchip/irq-vic.c b/drivers/irqchip/irq-vic.c index 884d11c7355f..2bbb00404cf5 100644 --- a/drivers/irqchip/irq-vic.c +++ b/drivers/irqchip/irq-vic.c @@ -197,7 +197,7 @@ static int vic_irqdomain_map(struct irq_domain *d, unsigned int irq, /* Skip invalid IRQs, only register handlers for the real ones */ if (!(v->valid_sources & (1 << hwirq))) - return -ENOTSUPP; + return -EPERM; irq_set_chip_and_handler(irq, &vic_chip, handle_level_irq); irq_set_chip_data(irq, v->base); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); diff --git a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c index 9b1b274c7d25..c123709acf82 100644 --- a/drivers/isdn/capi/kcapi.c +++ b/drivers/isdn/capi/kcapi.c @@ -93,7 +93,7 @@ capi_ctr_put(struct capi_ctr *ctr) static inline struct capi_ctr *get_capi_ctr_by_nr(u16 contr) { - if (contr - 1 >= CAPI_MAXCONTR) + if (contr < 1 || contr - 1 >= CAPI_MAXCONTR) return NULL; return capi_controller[contr - 1]; @@ -103,7 +103,7 @@ static inline struct capi20_appl *__get_capi_appl_by_nr(u16 applid) { lockdep_assert_held(&capi_controller_lock); - if (applid - 1 >= CAPI_MAXAPPL) + if (applid < 1 || applid - 1 >= CAPI_MAXAPPL) return NULL; return capi_applications[applid - 1]; @@ -111,7 +111,7 @@ static inline struct capi20_appl *__get_capi_appl_by_nr(u16 applid) static inline struct capi20_appl *get_capi_appl_by_nr(u16 applid) { - if (applid - 1 >= CAPI_MAXAPPL) + if (applid < 1 || applid - 1 >= CAPI_MAXAPPL) return NULL; return rcu_dereference(capi_applications[applid - 1]); diff --git a/drivers/leds/leds-ot200.c b/drivers/leds/leds-ot200.c index ee14662ed5ce..98cae529373f 100644 --- a/drivers/leds/leds-ot200.c +++ b/drivers/leds/leds-ot200.c @@ -47,37 +47,37 @@ static struct ot200_led leds[] = { { .name = "led_1", .port = 0x49, - .mask = BIT(7), + .mask = BIT(6), }, { .name = "led_2", .port = 0x49, - .mask = BIT(6), + .mask = BIT(5), }, { .name = "led_3", .port = 0x49, - .mask = BIT(5), + .mask = BIT(4), }, { .name = "led_4", .port = 0x49, - .mask = BIT(4), + .mask = BIT(3), }, { .name = "led_5", .port = 0x49, - .mask = BIT(3), + .mask = BIT(2), }, { .name = "led_6", .port = 0x49, - .mask = BIT(2), + .mask = BIT(1), }, { .name = "led_7", .port = 0x49, - .mask = BIT(1), + .mask = BIT(0), } }; diff --git a/drivers/md/bcache/Kconfig b/drivers/md/bcache/Kconfig index 05c220d05e23..f950c9d29f3e 100644 --- a/drivers/md/bcache/Kconfig +++ b/drivers/md/bcache/Kconfig @@ -1,7 +1,6 @@ config BCACHE tristate "Block device as cache" - select CLOSURES ---help--- Allows a block device to be used as cache for other devices; uses a btree for indexing and the layout is optimized for SSDs. diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h index 340146d7c17f..d3e15b42a4ab 100644 --- a/drivers/md/bcache/bcache.h +++ b/drivers/md/bcache/bcache.h @@ -1241,7 +1241,7 @@ void bch_cache_set_stop(struct cache_set *); struct cache_set *bch_cache_set_alloc(struct cache_sb *); void bch_btree_cache_free(struct cache_set *); int bch_btree_cache_alloc(struct cache_set *); -void bch_writeback_init_cached_dev(struct cached_dev *); +void bch_cached_dev_writeback_init(struct cached_dev *); void bch_moving_init_cache_set(struct cache_set *); void bch_cache_allocator_exit(struct cache *ca); diff --git a/drivers/md/bcache/stats.c b/drivers/md/bcache/stats.c index 64e679449c2a..b8730e714d69 100644 --- a/drivers/md/bcache/stats.c +++ b/drivers/md/bcache/stats.c @@ -93,24 +93,6 @@ static struct attribute *bch_stats_files[] = { }; static KTYPE(bch_stats); -static void scale_accounting(unsigned long data); - -void bch_cache_accounting_init(struct cache_accounting *acc, - struct closure *parent) -{ - kobject_init(&acc->total.kobj, &bch_stats_ktype); - kobject_init(&acc->five_minute.kobj, &bch_stats_ktype); - kobject_init(&acc->hour.kobj, &bch_stats_ktype); - kobject_init(&acc->day.kobj, &bch_stats_ktype); - - closure_init(&acc->cl, parent); - init_timer(&acc->timer); - acc->timer.expires = jiffies + accounting_delay; - acc->timer.data = (unsigned long) acc; - acc->timer.function = scale_accounting; - add_timer(&acc->timer); -} - int bch_cache_accounting_add_kobjs(struct cache_accounting *acc, struct kobject *parent) { @@ -244,3 +226,19 @@ void bch_mark_sectors_bypassed(struct search *s, int sectors) atomic_add(sectors, &dc->accounting.collector.sectors_bypassed); atomic_add(sectors, &s->op.c->accounting.collector.sectors_bypassed); } + +void bch_cache_accounting_init(struct cache_accounting *acc, + struct closure *parent) +{ + kobject_init(&acc->total.kobj, &bch_stats_ktype); + kobject_init(&acc->five_minute.kobj, &bch_stats_ktype); + kobject_init(&acc->hour.kobj, &bch_stats_ktype); + kobject_init(&acc->day.kobj, &bch_stats_ktype); + + closure_init(&acc->cl, parent); + init_timer(&acc->timer); + acc->timer.expires = jiffies + accounting_delay; + acc->timer.data = (unsigned long) acc; + acc->timer.function = scale_accounting; + add_timer(&acc->timer); +} diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c index c8046bc4aa57..f88e2b653a3f 100644 --- a/drivers/md/bcache/super.c +++ b/drivers/md/bcache/super.c @@ -634,11 +634,10 @@ static int open_dev(struct block_device *b, fmode_t mode) return 0; } -static int release_dev(struct gendisk *b, fmode_t mode) +static void release_dev(struct gendisk *b, fmode_t mode) { struct bcache_device *d = b->private_data; closure_put(&d->cl); - return 0; } static int ioctl_dev(struct block_device *b, fmode_t mode, @@ -732,8 +731,7 @@ static void bcache_device_free(struct bcache_device *d) if (d->c) bcache_device_detach(d); - - if (d->disk) + if (d->disk && d->disk->flags & GENHD_FL_UP) del_gendisk(d->disk); if (d->disk && d->disk->queue) blk_cleanup_queue(d->disk->queue); @@ -756,12 +754,9 @@ static int bcache_device_init(struct bcache_device *d, unsigned block_size) if (!(d->bio_split = bioset_create(4, offsetof(struct bbio, bio))) || !(d->unaligned_bvec = mempool_create_kmalloc_pool(1, sizeof(struct bio_vec) * BIO_MAX_PAGES)) || - bio_split_pool_init(&d->bio_split_hook)) - - return -ENOMEM; - - d->disk = alloc_disk(1); - if (!d->disk) + bio_split_pool_init(&d->bio_split_hook) || + !(d->disk = alloc_disk(1)) || + !(q = blk_alloc_queue(GFP_KERNEL))) return -ENOMEM; snprintf(d->disk->disk_name, DISK_NAME_LEN, "bcache%i", bcache_minor); @@ -771,10 +766,6 @@ static int bcache_device_init(struct bcache_device *d, unsigned block_size) d->disk->fops = &bcache_ops; d->disk->private_data = d; - q = blk_alloc_queue(GFP_KERNEL); - if (!q) - return -ENOMEM; - blk_queue_make_request(q, NULL); d->disk->queue = q; q->queuedata = d; @@ -999,14 +990,17 @@ static void cached_dev_free(struct closure *cl) mutex_lock(&bch_register_lock); - bd_unlink_disk_holder(dc->bdev, dc->disk.disk); + if (atomic_read(&dc->running)) + bd_unlink_disk_holder(dc->bdev, dc->disk.disk); bcache_device_free(&dc->disk); list_del(&dc->list); mutex_unlock(&bch_register_lock); if (!IS_ERR_OR_NULL(dc->bdev)) { - blk_sync_queue(bdev_get_queue(dc->bdev)); + if (dc->bdev->bd_disk) + blk_sync_queue(bdev_get_queue(dc->bdev)); + blkdev_put(dc->bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL); } @@ -1028,73 +1022,67 @@ static void cached_dev_flush(struct closure *cl) static int cached_dev_init(struct cached_dev *dc, unsigned block_size) { - int err; + int ret; struct io *io; - - closure_init(&dc->disk.cl, NULL); - set_closure_fn(&dc->disk.cl, cached_dev_flush, system_wq); + struct request_queue *q = bdev_get_queue(dc->bdev); __module_get(THIS_MODULE); INIT_LIST_HEAD(&dc->list); + closure_init(&dc->disk.cl, NULL); + set_closure_fn(&dc->disk.cl, cached_dev_flush, system_wq); kobject_init(&dc->disk.kobj, &bch_cached_dev_ktype); - - bch_cache_accounting_init(&dc->accounting, &dc->disk.cl); - - err = bcache_device_init(&dc->disk, block_size); - if (err) - goto err; - - spin_lock_init(&dc->io_lock); - closure_init_unlocked(&dc->sb_write); INIT_WORK(&dc->detach, cached_dev_detach_finish); + closure_init_unlocked(&dc->sb_write); + INIT_LIST_HEAD(&dc->io_lru); + spin_lock_init(&dc->io_lock); + bch_cache_accounting_init(&dc->accounting, &dc->disk.cl); dc->sequential_merge = true; dc->sequential_cutoff = 4 << 20; - INIT_LIST_HEAD(&dc->io_lru); - dc->sb_bio.bi_max_vecs = 1; - dc->sb_bio.bi_io_vec = dc->sb_bio.bi_inline_vecs; - for (io = dc->io; io < dc->io + RECENT_IO; io++) { list_add(&io->lru, &dc->io_lru); hlist_add_head(&io->hash, dc->io_hash + RECENT_IO); } - bch_writeback_init_cached_dev(dc); + ret = bcache_device_init(&dc->disk, block_size); + if (ret) + return ret; + + set_capacity(dc->disk.disk, + dc->bdev->bd_part->nr_sects - dc->sb.data_offset); + + dc->disk.disk->queue->backing_dev_info.ra_pages = + max(dc->disk.disk->queue->backing_dev_info.ra_pages, + q->backing_dev_info.ra_pages); + + bch_cached_dev_request_init(dc); + bch_cached_dev_writeback_init(dc); return 0; -err: - bcache_device_stop(&dc->disk); - return err; } /* Cached device - bcache superblock */ -static const char *register_bdev(struct cache_sb *sb, struct page *sb_page, +static void register_bdev(struct cache_sb *sb, struct page *sb_page, struct block_device *bdev, struct cached_dev *dc) { char name[BDEVNAME_SIZE]; const char *err = "cannot allocate memory"; - struct gendisk *g; struct cache_set *c; - if (!dc || cached_dev_init(dc, sb->block_size << 9) != 0) - return err; - memcpy(&dc->sb, sb, sizeof(struct cache_sb)); - dc->sb_bio.bi_io_vec[0].bv_page = sb_page; dc->bdev = bdev; dc->bdev->bd_holder = dc; - g = dc->disk.disk; - - set_capacity(g, dc->bdev->bd_part->nr_sects - dc->sb.data_offset); - - g->queue->backing_dev_info.ra_pages = - max(g->queue->backing_dev_info.ra_pages, - bdev->bd_queue->backing_dev_info.ra_pages); + bio_init(&dc->sb_bio); + dc->sb_bio.bi_max_vecs = 1; + dc->sb_bio.bi_io_vec = dc->sb_bio.bi_inline_vecs; + dc->sb_bio.bi_io_vec[0].bv_page = sb_page; + get_page(sb_page); - bch_cached_dev_request_init(dc); + if (cached_dev_init(dc, sb->block_size << 9)) + goto err; err = "error creating kobject"; if (kobject_add(&dc->disk.kobj, &part_to_dev(bdev->bd_part)->kobj, @@ -1103,6 +1091,8 @@ static const char *register_bdev(struct cache_sb *sb, struct page *sb_page, if (bch_cache_accounting_add_kobjs(&dc->accounting, &dc->disk.kobj)) goto err; + pr_info("registered backing device %s", bdevname(bdev, name)); + list_add(&dc->list, &uncached_devices); list_for_each_entry(c, &bch_cache_sets, list) bch_cached_dev_attach(dc, c); @@ -1111,15 +1101,10 @@ static const char *register_bdev(struct cache_sb *sb, struct page *sb_page, BDEV_STATE(&dc->sb) == BDEV_STATE_STALE) bch_cached_dev_run(dc); - return NULL; + return; err: - kobject_put(&dc->disk.kobj); pr_notice("error opening %s: %s", bdevname(bdev, name), err); - /* - * Return NULL instead of an error because kobject_put() cleans - * everything up - */ - return NULL; + bcache_device_stop(&dc->disk); } /* Flash only volumes */ @@ -1717,20 +1702,11 @@ static int cache_alloc(struct cache_sb *sb, struct cache *ca) size_t free; struct bucket *b; - if (!ca) - return -ENOMEM; - __module_get(THIS_MODULE); kobject_init(&ca->kobj, &bch_cache_ktype); - memcpy(&ca->sb, sb, sizeof(struct cache_sb)); - INIT_LIST_HEAD(&ca->discards); - bio_init(&ca->sb_bio); - ca->sb_bio.bi_max_vecs = 1; - ca->sb_bio.bi_io_vec = ca->sb_bio.bi_inline_vecs; - bio_init(&ca->journal.bio); ca->journal.bio.bi_max_vecs = 8; ca->journal.bio.bi_io_vec = ca->journal.bio.bi_inline_vecs; @@ -1742,18 +1718,17 @@ static int cache_alloc(struct cache_sb *sb, struct cache *ca) !init_fifo(&ca->free_inc, free << 2, GFP_KERNEL) || !init_fifo(&ca->unused, free << 2, GFP_KERNEL) || !init_heap(&ca->heap, free << 3, GFP_KERNEL) || - !(ca->buckets = vmalloc(sizeof(struct bucket) * + !(ca->buckets = vzalloc(sizeof(struct bucket) * ca->sb.nbuckets)) || !(ca->prio_buckets = kzalloc(sizeof(uint64_t) * prio_buckets(ca) * 2, GFP_KERNEL)) || !(ca->disk_buckets = alloc_bucket_pages(GFP_KERNEL, ca)) || !(ca->alloc_workqueue = alloc_workqueue("bch_allocator", 0, 1)) || bio_split_pool_init(&ca->bio_split_hook)) - goto err; + return -ENOMEM; ca->prio_last_buckets = ca->prio_buckets + prio_buckets(ca); - memset(ca->buckets, 0, ca->sb.nbuckets * sizeof(struct bucket)); for_each_bucket(b, ca) atomic_set(&b->pin, 0); @@ -1766,22 +1741,28 @@ err: return -ENOMEM; } -static const char *register_cache(struct cache_sb *sb, struct page *sb_page, +static void register_cache(struct cache_sb *sb, struct page *sb_page, struct block_device *bdev, struct cache *ca) { char name[BDEVNAME_SIZE]; const char *err = "cannot allocate memory"; - if (cache_alloc(sb, ca) != 0) - return err; - - ca->sb_bio.bi_io_vec[0].bv_page = sb_page; + memcpy(&ca->sb, sb, sizeof(struct cache_sb)); ca->bdev = bdev; ca->bdev->bd_holder = ca; + bio_init(&ca->sb_bio); + ca->sb_bio.bi_max_vecs = 1; + ca->sb_bio.bi_io_vec = ca->sb_bio.bi_inline_vecs; + ca->sb_bio.bi_io_vec[0].bv_page = sb_page; + get_page(sb_page); + if (blk_queue_discard(bdev_get_queue(ca->bdev))) ca->discard = CACHE_DISCARD(&ca->sb); + if (cache_alloc(sb, ca) != 0) + goto err; + err = "error creating kobject"; if (kobject_add(&ca->kobj, &part_to_dev(bdev->bd_part)->kobj, "bcache")) goto err; @@ -1791,15 +1772,10 @@ static const char *register_cache(struct cache_sb *sb, struct page *sb_page, goto err; pr_info("registered cache device %s", bdevname(bdev, name)); - - return NULL; + return; err: + pr_notice("error opening %s: %s", bdevname(bdev, name), err); kobject_put(&ca->kobj); - pr_info("error opening %s: %s", bdevname(bdev, name), err); - /* Return NULL instead of an error because kobject_put() cleans - * everything up - */ - return NULL; } /* Global interfaces/init */ @@ -1833,12 +1809,15 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr, bdev = blkdev_get_by_path(strim(path), FMODE_READ|FMODE_WRITE|FMODE_EXCL, sb); - if (bdev == ERR_PTR(-EBUSY)) - err = "device busy"; - - if (IS_ERR(bdev) || - set_blocksize(bdev, 4096)) + if (IS_ERR(bdev)) { + if (bdev == ERR_PTR(-EBUSY)) + err = "device busy"; goto err; + } + + err = "failed to set blocksize"; + if (set_blocksize(bdev, 4096)) + goto err_close; err = read_super(sb, bdev, &sb_page); if (err) @@ -1846,33 +1825,33 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr, if (SB_IS_BDEV(sb)) { struct cached_dev *dc = kzalloc(sizeof(*dc), GFP_KERNEL); + if (!dc) + goto err_close; - err = register_bdev(sb, sb_page, bdev, dc); + register_bdev(sb, sb_page, bdev, dc); } else { struct cache *ca = kzalloc(sizeof(*ca), GFP_KERNEL); + if (!ca) + goto err_close; - err = register_cache(sb, sb_page, bdev, ca); + register_cache(sb, sb_page, bdev, ca); } - - if (err) { - /* register_(bdev|cache) will only return an error if they - * didn't get far enough to create the kobject - if they did, - * the kobject destructor will do this cleanup. - */ +out: + if (sb_page) put_page(sb_page); -err_close: - blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL); -err: - if (attr != &ksysfs_register_quiet) - pr_info("error opening %s: %s", path, err); - ret = -EINVAL; - } - kfree(sb); kfree(path); mutex_unlock(&bch_register_lock); module_put(THIS_MODULE); return ret; + +err_close: + blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL); +err: + if (attr != &ksysfs_register_quiet) + pr_info("error opening %s: %s", path, err); + ret = -EINVAL; + goto out; } static int bcache_reboot(struct notifier_block *n, unsigned long code, void *x) diff --git a/drivers/md/bcache/writeback.c b/drivers/md/bcache/writeback.c index 93e7e31a4bd3..2714ed3991d1 100644 --- a/drivers/md/bcache/writeback.c +++ b/drivers/md/bcache/writeback.c @@ -375,7 +375,7 @@ err: refill_dirty(cl); } -void bch_writeback_init_cached_dev(struct cached_dev *dc) +void bch_cached_dev_writeback_init(struct cached_dev *dc) { closure_init_unlocked(&dc->writeback); init_rwsem(&dc->writeback_lock); diff --git a/drivers/md/md.c b/drivers/md/md.c index 681d1099a2d5..9b82377a833b 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -5268,8 +5268,8 @@ static void md_clean(struct mddev *mddev) static void __md_stop_writes(struct mddev *mddev) { + set_bit(MD_RECOVERY_FROZEN, &mddev->recovery); if (mddev->sync_thread) { - set_bit(MD_RECOVERY_FROZEN, &mddev->recovery); set_bit(MD_RECOVERY_INTR, &mddev->recovery); md_reap_sync_thread(mddev); } diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 55951182af73..6e17f8181c4b 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -417,7 +417,17 @@ static void raid1_end_write_request(struct bio *bio, int error) r1_bio->bios[mirror] = NULL; to_put = bio; - set_bit(R1BIO_Uptodate, &r1_bio->state); + /* + * Do not set R1BIO_Uptodate if the current device is + * rebuilding or Faulty. This is because we cannot use + * such device for properly reading the data back (we could + * potentially use it, if the current write would have felt + * before rdev->recovery_offset, but for simplicity we don't + * check this here. + */ + if (test_bit(In_sync, &conf->mirrors[mirror].rdev->flags) && + !test_bit(Faulty, &conf->mirrors[mirror].rdev->flags)) + set_bit(R1BIO_Uptodate, &r1_bio->state); /* Maybe we can clear some bad blocks. */ if (is_badblock(conf->mirrors[mirror].rdev, @@ -870,17 +880,17 @@ static void allow_barrier(struct r1conf *conf) wake_up(&conf->wait_barrier); } -static void freeze_array(struct r1conf *conf) +static void freeze_array(struct r1conf *conf, int extra) { /* stop syncio and normal IO and wait for everything to * go quite. * We increment barrier and nr_waiting, and then - * wait until nr_pending match nr_queued+1 + * wait until nr_pending match nr_queued+extra * This is called in the context of one normal IO request * that has failed. Thus any sync request that might be pending * will be blocked by nr_pending, and we need to wait for * pending IO requests to complete or be queued for re-try. - * Thus the number queued (nr_queued) plus this request (1) + * Thus the number queued (nr_queued) plus this request (extra) * must match the number of pending IOs (nr_pending) before * we continue. */ @@ -888,7 +898,7 @@ static void freeze_array(struct r1conf *conf) conf->barrier++; conf->nr_waiting++; wait_event_lock_irq_cmd(conf->wait_barrier, - conf->nr_pending == conf->nr_queued+1, + conf->nr_pending == conf->nr_queued+extra, conf->resync_lock, flush_pending_writes(conf)); spin_unlock_irq(&conf->resync_lock); @@ -1544,8 +1554,8 @@ static int raid1_add_disk(struct mddev *mddev, struct md_rdev *rdev) * we wait for all outstanding requests to complete. */ synchronize_sched(); - raise_barrier(conf); - lower_barrier(conf); + freeze_array(conf, 0); + unfreeze_array(conf); clear_bit(Unmerged, &rdev->flags); } md_integrity_add_rdev(rdev, mddev); @@ -1595,11 +1605,11 @@ static int raid1_remove_disk(struct mddev *mddev, struct md_rdev *rdev) */ struct md_rdev *repl = conf->mirrors[conf->raid_disks + number].rdev; - raise_barrier(conf); + freeze_array(conf, 0); clear_bit(Replacement, &repl->flags); p->rdev = repl; conf->mirrors[conf->raid_disks + number].rdev = NULL; - lower_barrier(conf); + unfreeze_array(conf); clear_bit(WantReplacement, &rdev->flags); } else clear_bit(WantReplacement, &rdev->flags); @@ -2195,7 +2205,7 @@ static void handle_read_error(struct r1conf *conf, struct r1bio *r1_bio) * frozen */ if (mddev->ro == 0) { - freeze_array(conf); + freeze_array(conf, 1); fix_read_error(conf, r1_bio->read_disk, r1_bio->sector, r1_bio->sectors); unfreeze_array(conf); @@ -2780,8 +2790,8 @@ static int run(struct mddev *mddev) return PTR_ERR(conf); if (mddev->queue) - blk_queue_max_write_same_sectors(mddev->queue, - mddev->chunk_sectors); + blk_queue_max_write_same_sectors(mddev->queue, 0); + rdev_for_each(rdev, mddev) { if (!mddev->gendisk) continue; @@ -2963,7 +2973,7 @@ static int raid1_reshape(struct mddev *mddev) return -ENOMEM; } - raise_barrier(conf); + freeze_array(conf, 0); /* ok, everything is stopped */ oldpool = conf->r1bio_pool; @@ -2994,7 +3004,7 @@ static int raid1_reshape(struct mddev *mddev) conf->raid_disks = mddev->raid_disks = raid_disks; mddev->delta_disks = 0; - lower_barrier(conf); + unfreeze_array(conf); set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); md_wakeup_thread(mddev->thread); diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 59d4daa5f4c7..6ddae2501b9a 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -490,7 +490,17 @@ static void raid10_end_write_request(struct bio *bio, int error) sector_t first_bad; int bad_sectors; - set_bit(R10BIO_Uptodate, &r10_bio->state); + /* + * Do not set R10BIO_Uptodate if the current device is + * rebuilding or Faulty. This is because we cannot use + * such device for properly reading the data back (we could + * potentially use it, if the current write would have felt + * before rdev->recovery_offset, but for simplicity we don't + * check this here. + */ + if (test_bit(In_sync, &rdev->flags) && + !test_bit(Faulty, &rdev->flags)) + set_bit(R10BIO_Uptodate, &r10_bio->state); /* Maybe we can clear some bad blocks. */ if (is_badblock(rdev, @@ -1055,17 +1065,17 @@ static void allow_barrier(struct r10conf *conf) wake_up(&conf->wait_barrier); } -static void freeze_array(struct r10conf *conf) +static void freeze_array(struct r10conf *conf, int extra) { /* stop syncio and normal IO and wait for everything to * go quiet. * We increment barrier and nr_waiting, and then - * wait until nr_pending match nr_queued+1 + * wait until nr_pending match nr_queued+extra * This is called in the context of one normal IO request * that has failed. Thus any sync request that might be pending * will be blocked by nr_pending, and we need to wait for * pending IO requests to complete or be queued for re-try. - * Thus the number queued (nr_queued) plus this request (1) + * Thus the number queued (nr_queued) plus this request (extra) * must match the number of pending IOs (nr_pending) before * we continue. */ @@ -1073,7 +1083,7 @@ static void freeze_array(struct r10conf *conf) conf->barrier++; conf->nr_waiting++; wait_event_lock_irq_cmd(conf->wait_barrier, - conf->nr_pending == conf->nr_queued+1, + conf->nr_pending == conf->nr_queued+extra, conf->resync_lock, flush_pending_writes(conf)); @@ -1837,8 +1847,8 @@ static int raid10_add_disk(struct mddev *mddev, struct md_rdev *rdev) * we wait for all outstanding requests to complete. */ synchronize_sched(); - raise_barrier(conf, 0); - lower_barrier(conf); + freeze_array(conf, 0); + unfreeze_array(conf); clear_bit(Unmerged, &rdev->flags); } md_integrity_add_rdev(rdev, mddev); @@ -2612,7 +2622,7 @@ static void handle_read_error(struct mddev *mddev, struct r10bio *r10_bio) r10_bio->devs[slot].bio = NULL; if (mddev->ro == 0) { - freeze_array(conf); + freeze_array(conf, 1); fix_read_error(conf, mddev, r10_bio); unfreeze_array(conf); } else @@ -3609,8 +3619,7 @@ static int run(struct mddev *mddev) if (mddev->queue) { blk_queue_max_discard_sectors(mddev->queue, mddev->chunk_sectors); - blk_queue_max_write_same_sectors(mddev->queue, - mddev->chunk_sectors); + blk_queue_max_write_same_sectors(mddev->queue, 0); blk_queue_io_min(mddev->queue, chunk_size); if (conf->geo.raid_disks % conf->geo.near_copies) blk_queue_io_opt(mddev->queue, chunk_size * conf->geo.raid_disks); diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 9359828ffe26..05e4a105b9c7 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -664,6 +664,7 @@ static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s) if (test_bit(R5_ReadNoMerge, &sh->dev[i].flags)) bi->bi_rw |= REQ_FLUSH; + bi->bi_vcnt = 1; bi->bi_io_vec[0].bv_len = STRIPE_SIZE; bi->bi_io_vec[0].bv_offset = 0; bi->bi_size = STRIPE_SIZE; @@ -701,6 +702,7 @@ static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s) else rbi->bi_sector = (sh->sector + rrdev->data_offset); + rbi->bi_vcnt = 1; rbi->bi_io_vec[0].bv_len = STRIPE_SIZE; rbi->bi_io_vec[0].bv_offset = 0; rbi->bi_size = STRIPE_SIZE; @@ -5464,7 +5466,7 @@ static int run(struct mddev *mddev) if (mddev->major_version == 0 && mddev->minor_version > 90) rdev->recovery_offset = reshape_offset; - + if (rdev->recovery_offset < reshape_offset) { /* We need to check old and new layout */ if (!only_parity(rdev->raid_disk, @@ -5587,6 +5589,8 @@ static int run(struct mddev *mddev) */ mddev->queue->limits.discard_zeroes_data = 0; + blk_queue_max_write_same_sectors(mddev->queue, 0); + rdev_for_each(rdev, mddev) { disk_stack_limits(mddev->gendisk, rdev->bdev, rdev->data_offset << 9); diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig index 7f5a7cac6dc7..8270388e2a0d 100644 --- a/drivers/media/Kconfig +++ b/drivers/media/Kconfig @@ -136,9 +136,9 @@ config DVB_NET # This Kconfig option is used by both PCI and USB drivers config TTPCI_EEPROM - tristate - depends on I2C - default n + tristate + depends on I2C + default n source "drivers/media/dvb-core/Kconfig" @@ -189,6 +189,12 @@ config MEDIA_SUBDRV_AUTOSELECT If unsure say Y. +config MEDIA_ATTACH + bool + depends on MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT || MEDIA_RADIO_SUPPORT + depends on MODULES + default MODULES + source "drivers/media/i2c/Kconfig" source "drivers/media/tuners/Kconfig" source "drivers/media/dvb-frontends/Kconfig" diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c index cb52438e53ac..9eac5310942f 100644 --- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c +++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c @@ -956,7 +956,7 @@ static int s5c73m3_oif_enum_frame_interval(struct v4l2_subdev *sd, if (fie->pad != OIF_SOURCE_PAD) return -EINVAL; - if (fie->index > ARRAY_SIZE(s5c73m3_intervals)) + if (fie->index >= ARRAY_SIZE(s5c73m3_intervals)) return -EINVAL; mutex_lock(&state->lock); diff --git a/drivers/media/pci/cx88/cx88-alsa.c b/drivers/media/pci/cx88/cx88-alsa.c index 27d62623274b..aba5b1c649e6 100644 --- a/drivers/media/pci/cx88/cx88-alsa.c +++ b/drivers/media/pci/cx88/cx88-alsa.c @@ -615,7 +615,7 @@ static int snd_cx88_volume_put(struct snd_kcontrol *kcontrol, int changed = 0; u32 old; - if (core->board.audio_chip == V4L2_IDENT_WM8775) + if (core->sd_wm8775) snd_cx88_wm8775_volume_put(kcontrol, value); left = value->value.integer.value[0] & 0x3f; @@ -682,8 +682,7 @@ static int snd_cx88_switch_put(struct snd_kcontrol *kcontrol, vol ^= bit; cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, vol); /* Pass mute onto any WM8775 */ - if ((core->board.audio_chip == V4L2_IDENT_WM8775) && - ((1<<6) == bit)) + if (core->sd_wm8775 && ((1<<6) == bit)) wm8775_s_ctrl(core, V4L2_CID_AUDIO_MUTE, 0 != (vol & bit)); ret = 1; } @@ -903,7 +902,7 @@ static int cx88_audio_initdev(struct pci_dev *pci, goto error; /* If there's a wm8775 then add a Line-In ALC switch */ - if (core->board.audio_chip == V4L2_IDENT_WM8775) + if (core->sd_wm8775) snd_ctl_add(card, snd_ctl_new1(&snd_cx88_alc_switch, chip)); strcpy (card->driver, "CX88x"); diff --git a/drivers/media/pci/cx88/cx88-video.c b/drivers/media/pci/cx88/cx88-video.c index 1b00615fd395..c7a9be1065c0 100644 --- a/drivers/media/pci/cx88/cx88-video.c +++ b/drivers/media/pci/cx88/cx88-video.c @@ -385,8 +385,7 @@ int cx88_video_mux(struct cx88_core *core, unsigned int input) /* The wm8775 module has the "2" route hardwired into the initialization. Some boards may use different routes for different inputs. HVR-1300 surely does */ - if (core->board.audio_chip && - core->board.audio_chip == V4L2_IDENT_WM8775) { + if (core->sd_wm8775) { call_all(core, audio, s_routing, INPUT(input).audioroute, 0, 0); } @@ -771,8 +770,7 @@ static int video_open(struct file *file) cx_write(MO_GP1_IO, core->board.radio.gpio1); cx_write(MO_GP2_IO, core->board.radio.gpio2); if (core->board.radio.audioroute) { - if(core->board.audio_chip && - core->board.audio_chip == V4L2_IDENT_WM8775) { + if (core->sd_wm8775) { call_all(core, audio, s_routing, core->board.radio.audioroute, 0, 0); } @@ -959,7 +957,7 @@ static int cx8800_s_aud_ctrl(struct v4l2_ctrl *ctrl) u32 value,mask; /* Pass changes onto any WM8775 */ - if (core->board.audio_chip == V4L2_IDENT_WM8775) { + if (core->sd_wm8775) { switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: wm8775_s_ctrl(core, ctrl->id, ctrl->val); diff --git a/drivers/media/pci/zoran/zoran.h b/drivers/media/pci/zoran/zoran.h index ca2754a3cd63..5e040085c2ff 100644 --- a/drivers/media/pci/zoran/zoran.h +++ b/drivers/media/pci/zoran/zoran.h @@ -176,7 +176,7 @@ struct zoran_fh; struct zoran_mapping { struct zoran_fh *fh; - int count; + atomic_t count; }; struct zoran_buffer { diff --git a/drivers/media/pci/zoran/zoran_driver.c b/drivers/media/pci/zoran/zoran_driver.c index 1168a84a737d..d133c30c3fdc 100644 --- a/drivers/media/pci/zoran/zoran_driver.c +++ b/drivers/media/pci/zoran/zoran_driver.c @@ -2803,8 +2803,7 @@ static void zoran_vm_open (struct vm_area_struct *vma) { struct zoran_mapping *map = vma->vm_private_data; - - map->count++; + atomic_inc(&map->count); } static void @@ -2815,7 +2814,7 @@ zoran_vm_close (struct vm_area_struct *vma) struct zoran *zr = fh->zr; int i; - if (--map->count > 0) + if (!atomic_dec_and_mutex_lock(&map->count, &zr->resource_lock)) return; dprintk(3, KERN_INFO "%s: %s - munmap(%s)\n", ZR_DEVNAME(zr), @@ -2828,14 +2827,16 @@ zoran_vm_close (struct vm_area_struct *vma) kfree(map); /* Any buffers still mapped? */ - for (i = 0; i < fh->buffers.num_buffers; i++) - if (fh->buffers.buffer[i].map) + for (i = 0; i < fh->buffers.num_buffers; i++) { + if (fh->buffers.buffer[i].map) { + mutex_unlock(&zr->resource_lock); return; + } + } dprintk(3, KERN_INFO "%s: %s - free %s buffers\n", ZR_DEVNAME(zr), __func__, mode_name(fh->map_mode)); - mutex_lock(&zr->resource_lock); if (fh->map_mode == ZORAN_MAP_MODE_RAW) { if (fh->buffers.active != ZORAN_FREE) { @@ -2939,7 +2940,7 @@ zoran_mmap (struct file *file, goto mmap_unlock_and_return; } map->fh = fh; - map->count = 1; + atomic_set(&map->count, 1); vma->vm_ops = &zoran_vm_ops; vma->vm_flags |= VM_DONTEXPAND; diff --git a/drivers/media/platform/coda.c b/drivers/media/platform/coda.c index 48b8d7af386d..9d1481a60bd9 100644 --- a/drivers/media/platform/coda.c +++ b/drivers/media/platform/coda.c @@ -576,6 +576,14 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf) return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf); } +static int vidioc_create_bufs(struct file *file, void *priv, + struct v4l2_create_buffers *create) +{ + struct coda_ctx *ctx = fh_to_ctx(priv); + + return v4l2_m2m_create_bufs(file, ctx->m2m_ctx, create); +} + static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type type) { @@ -610,6 +618,7 @@ static const struct v4l2_ioctl_ops coda_ioctl_ops = { .vidioc_qbuf = vidioc_qbuf, .vidioc_dqbuf = vidioc_dqbuf, + .vidioc_create_bufs = vidioc_create_bufs, .vidioc_streamon = vidioc_streamon, .vidioc_streamoff = vidioc_streamoff, diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c index 1802f11e939f..d0b375cf565f 100644 --- a/drivers/media/platform/davinci/vpbe_display.c +++ b/drivers/media/platform/davinci/vpbe_display.c @@ -916,6 +916,21 @@ static int vpbe_display_s_fmt(struct file *file, void *priv, other video window */ layer->pix_fmt = *pixfmt; + if (pixfmt->pixelformat == V4L2_PIX_FMT_NV12) { + struct vpbe_layer *otherlayer; + + otherlayer = _vpbe_display_get_other_win_layer(disp_dev, layer); + /* if other layer is available, only + * claim it, do not configure it + */ + ret = osd_device->ops.request_layer(osd_device, + otherlayer->layer_info.id); + if (ret < 0) { + v4l2_err(&vpbe_dev->v4l2_dev, + "Display Manager failed to allocate layer\n"); + return -EBUSY; + } + } /* Get osd layer config */ osd_device->ops.get_layer_config(osd_device, diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c index 8c50d3074866..93609091cb23 100644 --- a/drivers/media/platform/davinci/vpfe_capture.c +++ b/drivers/media/platform/davinci/vpfe_capture.c @@ -1837,7 +1837,7 @@ static int vpfe_probe(struct platform_device *pdev) if (NULL == ccdc_cfg) { v4l2_err(pdev->dev.driver, "Memory allocation failed for ccdc_cfg\n"); - goto probe_free_lock; + goto probe_free_dev_mem; } mutex_lock(&ccdc_lock); @@ -1991,7 +1991,6 @@ probe_out_release_irq: free_irq(vpfe_dev->ccdc_irq0, vpfe_dev); probe_free_ccdc_cfg_mem: kfree(ccdc_cfg); -probe_free_lock: mutex_unlock(&ccdc_lock); probe_free_dev_mem: kfree(vpfe_dev); diff --git a/drivers/media/platform/exynos4-is/fimc-is-regs.c b/drivers/media/platform/exynos4-is/fimc-is-regs.c index b0ff67bc1b05..d05eaa2c8490 100644 --- a/drivers/media/platform/exynos4-is/fimc-is-regs.c +++ b/drivers/media/platform/exynos4-is/fimc-is-regs.c @@ -174,7 +174,7 @@ int fimc_is_hw_change_mode(struct fimc_is *is) HIC_CAPTURE_STILL, HIC_CAPTURE_VIDEO, }; - if (WARN_ON(is->config_index > ARRAY_SIZE(cmd))) + if (WARN_ON(is->config_index >= ARRAY_SIZE(cmd))) return -EINVAL; mcuctl_write(cmd[is->config_index], is, MCUCTL_REG_ISSR(0)); diff --git a/drivers/media/platform/exynos4-is/fimc-is.c b/drivers/media/platform/exynos4-is/fimc-is.c index 47c6363d04e2..0741945b79ed 100644 --- a/drivers/media/platform/exynos4-is/fimc-is.c +++ b/drivers/media/platform/exynos4-is/fimc-is.c @@ -48,7 +48,6 @@ static char *fimc_is_clocks[ISS_CLKS_MAX] = { [ISS_CLK_LITE0] = "lite0", [ISS_CLK_LITE1] = "lite1", [ISS_CLK_MPLL] = "mpll", - [ISS_CLK_SYSREG] = "sysreg", [ISS_CLK_ISP] = "isp", [ISS_CLK_DRC] = "drc", [ISS_CLK_FD] = "fd", @@ -71,7 +70,6 @@ static void fimc_is_put_clocks(struct fimc_is *is) for (i = 0; i < ISS_CLKS_MAX; i++) { if (IS_ERR(is->clocks[i])) continue; - clk_unprepare(is->clocks[i]); clk_put(is->clocks[i]); is->clocks[i] = ERR_PTR(-EINVAL); } @@ -90,12 +88,6 @@ static int fimc_is_get_clocks(struct fimc_is *is) ret = PTR_ERR(is->clocks[i]); goto err; } - ret = clk_prepare(is->clocks[i]); - if (ret < 0) { - clk_put(is->clocks[i]); - is->clocks[i] = ERR_PTR(-EINVAL); - goto err; - } } return 0; @@ -103,7 +95,7 @@ err: fimc_is_put_clocks(is); dev_err(&is->pdev->dev, "failed to get clock: %s\n", fimc_is_clocks[i]); - return -ENXIO; + return ret; } static int fimc_is_setup_clocks(struct fimc_is *is) @@ -144,7 +136,7 @@ int fimc_is_enable_clocks(struct fimc_is *is) for (i = 0; i < ISS_GATE_CLKS_MAX; i++) { if (IS_ERR(is->clocks[i])) continue; - ret = clk_enable(is->clocks[i]); + ret = clk_prepare_enable(is->clocks[i]); if (ret < 0) { dev_err(&is->pdev->dev, "clock %s enable failed\n", fimc_is_clocks[i]); @@ -163,7 +155,7 @@ void fimc_is_disable_clocks(struct fimc_is *is) for (i = 0; i < ISS_GATE_CLKS_MAX; i++) { if (!IS_ERR(is->clocks[i])) { - clk_disable(is->clocks[i]); + clk_disable_unprepare(is->clocks[i]); pr_debug("disabled clock: %s\n", fimc_is_clocks[i]); } } @@ -326,6 +318,11 @@ int fimc_is_start_firmware(struct fimc_is *is) struct device *dev = &is->pdev->dev; int ret; + if (is->fw.f_w == NULL) { + dev_err(dev, "firmware is not loaded\n"); + return -EINVAL; + } + memcpy(is->memory.vaddr, is->fw.f_w->data, is->fw.f_w->size); wmb(); @@ -837,23 +834,11 @@ static int fimc_is_probe(struct platform_device *pdev) goto err_clk; } pm_runtime_enable(dev); - /* - * Enable only the ISP power domain, keep FIMC-IS clocks off until - * the whole clock tree is configured. The ISP power domain needs - * be active in order to acces any CMU_ISP clock registers. - */ - ret = pm_runtime_get_sync(dev); - if (ret < 0) - goto err_irq; - - ret = fimc_is_setup_clocks(is); - pm_runtime_put_sync(dev); + ret = pm_runtime_get_sync(dev); if (ret < 0) goto err_irq; - is->clk_init = true; - is->alloc_ctx = vb2_dma_contig_init_ctx(dev); if (IS_ERR(is->alloc_ctx)) { ret = PTR_ERR(is->alloc_ctx); @@ -875,6 +860,8 @@ static int fimc_is_probe(struct platform_device *pdev) if (ret < 0) goto err_dfs; + pm_runtime_put_sync(dev); + dev_dbg(dev, "FIMC-IS registered successfully\n"); return 0; @@ -894,9 +881,11 @@ err_clk: static int fimc_is_runtime_resume(struct device *dev) { struct fimc_is *is = dev_get_drvdata(dev); + int ret; - if (!is->clk_init) - return 0; + ret = fimc_is_setup_clocks(is); + if (ret) + return ret; return fimc_is_enable_clocks(is); } @@ -905,9 +894,7 @@ static int fimc_is_runtime_suspend(struct device *dev) { struct fimc_is *is = dev_get_drvdata(dev); - if (is->clk_init) - fimc_is_disable_clocks(is); - + fimc_is_disable_clocks(is); return 0; } @@ -941,7 +928,8 @@ static int fimc_is_remove(struct platform_device *pdev) vb2_dma_contig_cleanup_ctx(is->alloc_ctx); fimc_is_put_clocks(is); fimc_is_debugfs_remove(is); - release_firmware(is->fw.f_w); + if (is->fw.f_w) + release_firmware(is->fw.f_w); fimc_is_free_cpu_memory(is); return 0; diff --git a/drivers/media/platform/exynos4-is/fimc-is.h b/drivers/media/platform/exynos4-is/fimc-is.h index f5275a5b0156..d7db133b493f 100644 --- a/drivers/media/platform/exynos4-is/fimc-is.h +++ b/drivers/media/platform/exynos4-is/fimc-is.h @@ -73,7 +73,6 @@ enum { ISS_CLK_LITE0, ISS_CLK_LITE1, ISS_CLK_MPLL, - ISS_CLK_SYSREG, ISS_CLK_ISP, ISS_CLK_DRC, ISS_CLK_FD, @@ -265,7 +264,6 @@ struct fimc_is { spinlock_t slock; struct clk *clocks[ISS_CLKS_MAX]; - bool clk_init; void __iomem *regs; void __iomem *pmu_regs; int irq; diff --git a/drivers/media/platform/exynos4-is/fimc-isp.c b/drivers/media/platform/exynos4-is/fimc-isp.c index d63947f7b302..7ede30b5910f 100644 --- a/drivers/media/platform/exynos4-is/fimc-isp.c +++ b/drivers/media/platform/exynos4-is/fimc-isp.c @@ -138,7 +138,7 @@ static int fimc_isp_subdev_get_fmt(struct v4l2_subdev *sd, return 0; } - mf->colorspace = V4L2_COLORSPACE_JPEG; + mf->colorspace = V4L2_COLORSPACE_SRGB; mutex_lock(&isp->subdev_lock); __is_get_frame_size(is, &cur_fmt); @@ -194,7 +194,7 @@ static int fimc_isp_subdev_set_fmt(struct v4l2_subdev *sd, v4l2_dbg(1, debug, sd, "%s: pad%d: code: 0x%x, %dx%d\n", __func__, fmt->pad, mf->code, mf->width, mf->height); - mf->colorspace = V4L2_COLORSPACE_JPEG; + mf->colorspace = V4L2_COLORSPACE_SRGB; mutex_lock(&isp->subdev_lock); __isp_subdev_try_format(isp, fmt); diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c index a2eda9d5ac87..254d70fe762a 100644 --- a/drivers/media/platform/exynos4-is/mipi-csis.c +++ b/drivers/media/platform/exynos4-is/mipi-csis.c @@ -746,7 +746,7 @@ static int s5pcsis_parse_dt(struct platform_device *pdev, node = v4l2_of_get_next_endpoint(node, NULL); if (!node) { dev_err(&pdev->dev, "No port node at %s\n", - node->full_name); + pdev->dev.of_node->full_name); return -EINVAL; } /* Get port node and validate MIPI-CSI channel id. */ diff --git a/drivers/media/platform/omap/omap_vout.c b/drivers/media/platform/omap/omap_vout.c index 477268a2415f..d338b19da544 100644 --- a/drivers/media/platform/omap/omap_vout.c +++ b/drivers/media/platform/omap/omap_vout.c @@ -2150,6 +2150,9 @@ static int __init omap_vout_probe(struct platform_device *pdev) struct omap_dss_device *def_display; struct omap2video_device *vid_dev = NULL; + if (omapdss_is_initialized() == false) + return -EPROBE_DEFER; + ret = omapdss_compat_init(); if (ret) { dev_err(&pdev->dev, "failed to init dss\n"); diff --git a/drivers/media/platform/s3c-camif/camif-core.h b/drivers/media/platform/s3c-camif/camif-core.h index 261134baa655..35d2fcdc0036 100644 --- a/drivers/media/platform/s3c-camif/camif-core.h +++ b/drivers/media/platform/s3c-camif/camif-core.h @@ -229,7 +229,7 @@ struct camif_vp { unsigned int state; u16 fmt_flags; u8 id; - u8 rotation; + u16 rotation; u8 hflip; u8 vflip; unsigned int offset; diff --git a/drivers/media/platform/s5p-jpeg/Makefile b/drivers/media/platform/s5p-jpeg/Makefile index ddc2900d88a2..d18cb5edd2d5 100644 --- a/drivers/media/platform/s5p-jpeg/Makefile +++ b/drivers/media/platform/s5p-jpeg/Makefile @@ -1,2 +1,2 @@ s5p-jpeg-objs := jpeg-core.o -obj-$(CONFIG_VIDEO_SAMSUNG_S5P_JPEG) := s5p-jpeg.o +obj-$(CONFIG_VIDEO_SAMSUNG_S5P_JPEG) += s5p-jpeg.o diff --git a/drivers/media/platform/s5p-mfc/Makefile b/drivers/media/platform/s5p-mfc/Makefile index 379008c6d09a..15f59b324fef 100644 --- a/drivers/media/platform/s5p-mfc/Makefile +++ b/drivers/media/platform/s5p-mfc/Makefile @@ -1,4 +1,4 @@ -obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MFC) := s5p-mfc.o +obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MFC) += s5p-mfc.o s5p-mfc-y += s5p_mfc.o s5p_mfc_intr.o s5p-mfc-y += s5p_mfc_dec.o s5p_mfc_enc.o s5p-mfc-y += s5p_mfc_ctrl.o s5p_mfc_pm.o diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c index 01f9ae0dadb0..d12faa691af8 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c @@ -397,7 +397,7 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx, leave_handle_frame: spin_unlock_irqrestore(&dev->irqlock, flags); if ((ctx->src_queue_cnt == 0 && ctx->state != MFCINST_FINISHING) - || ctx->dst_queue_cnt < ctx->dpb_count) + || ctx->dst_queue_cnt < ctx->pb_count) clear_work_bit(ctx); s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev); wake_up_ctx(ctx, reason, err); @@ -473,7 +473,7 @@ static void s5p_mfc_handle_seq_done(struct s5p_mfc_ctx *ctx, s5p_mfc_hw_call(dev->mfc_ops, dec_calc_dpb_size, ctx); - ctx->dpb_count = s5p_mfc_hw_call(dev->mfc_ops, get_dpb_count, + ctx->pb_count = s5p_mfc_hw_call(dev->mfc_ops, get_dpb_count, dev); ctx->mv_count = s5p_mfc_hw_call(dev->mfc_ops, get_mv_count, dev); @@ -562,7 +562,7 @@ static void s5p_mfc_handle_stream_complete(struct s5p_mfc_ctx *ctx, struct s5p_mfc_dev *dev = ctx->dev; struct s5p_mfc_buf *mb_entry; - mfc_debug(2, "Stream completed"); + mfc_debug(2, "Stream completed\n"); s5p_mfc_clear_int_flags(dev); ctx->int_type = reason; @@ -1362,7 +1362,6 @@ static struct s5p_mfc_variant mfc_drvdata_v5 = { .port_num = MFC_NUM_PORTS, .buf_size = &buf_size_v5, .buf_align = &mfc_buf_align_v5, - .mclk_name = "sclk_mfc", .fw_name = "s5p-mfc.fw", }; @@ -1389,7 +1388,6 @@ static struct s5p_mfc_variant mfc_drvdata_v6 = { .port_num = MFC_NUM_PORTS_V6, .buf_size = &buf_size_v6, .buf_align = &mfc_buf_align_v6, - .mclk_name = "aclk_333", .fw_name = "s5p-mfc-v6.fw", }; diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h index 202d1d7a37a8..ef4074cd5316 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h @@ -138,6 +138,7 @@ enum s5p_mfc_inst_state { MFCINST_INIT = 100, MFCINST_GOT_INST, MFCINST_HEAD_PARSED, + MFCINST_HEAD_PRODUCED, MFCINST_BUFS_SET, MFCINST_RUNNING, MFCINST_FINISHING, @@ -231,7 +232,6 @@ struct s5p_mfc_variant { unsigned int port_num; struct s5p_mfc_buf_size *buf_size; struct s5p_mfc_buf_align *buf_align; - char *mclk_name; char *fw_name; }; @@ -438,7 +438,7 @@ struct s5p_mfc_enc_params { u32 rc_framerate_num; u32 rc_framerate_denom; - union { + struct { struct s5p_mfc_h264_enc_params h264; struct s5p_mfc_mpeg4_enc_params mpeg4; } codec; @@ -602,7 +602,7 @@ struct s5p_mfc_ctx { int after_packed_pb; int sei_fp_parse; - int dpb_count; + int pb_count; int total_dpb_count; int mv_count; /* Buffers */ diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c index 2e5f30b40dea..dc1fc94a488d 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c @@ -38,7 +38,7 @@ int s5p_mfc_alloc_firmware(struct s5p_mfc_dev *dev) dev->fw_virt_addr = dma_alloc_coherent(dev->mem_dev_l, dev->fw_size, &dev->bank1, GFP_KERNEL); - if (IS_ERR(dev->fw_virt_addr)) { + if (IS_ERR_OR_NULL(dev->fw_virt_addr)) { dev->fw_virt_addr = NULL; mfc_err("Allocating bitprocessor buffer failed\n"); return -ENOMEM; diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_debug.h b/drivers/media/platform/s5p-mfc/s5p_mfc_debug.h index bd5cd4ae993c..8e608f5aa0d7 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_debug.h +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_debug.h @@ -30,8 +30,8 @@ extern int debug; #define mfc_debug(level, fmt, args...) #endif -#define mfc_debug_enter() mfc_debug(5, "enter") -#define mfc_debug_leave() mfc_debug(5, "leave") +#define mfc_debug_enter() mfc_debug(5, "enter\n") +#define mfc_debug_leave() mfc_debug(5, "leave\n") #define mfc_err(fmt, args...) \ do { \ diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c index 4af53bd2f182..00b07032f4f0 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c @@ -210,11 +210,11 @@ static int s5p_mfc_ctx_ready(struct s5p_mfc_ctx *ctx) /* Context is to decode a frame */ if (ctx->src_queue_cnt >= 1 && ctx->state == MFCINST_RUNNING && - ctx->dst_queue_cnt >= ctx->dpb_count) + ctx->dst_queue_cnt >= ctx->pb_count) return 1; /* Context is to return last frame */ if (ctx->state == MFCINST_FINISHING && - ctx->dst_queue_cnt >= ctx->dpb_count) + ctx->dst_queue_cnt >= ctx->pb_count) return 1; /* Context is to set buffers */ if (ctx->src_queue_cnt >= 1 && @@ -224,7 +224,7 @@ static int s5p_mfc_ctx_ready(struct s5p_mfc_ctx *ctx) /* Resolution change */ if ((ctx->state == MFCINST_RES_CHANGE_INIT || ctx->state == MFCINST_RES_CHANGE_FLUSH) && - ctx->dst_queue_cnt >= ctx->dpb_count) + ctx->dst_queue_cnt >= ctx->pb_count) return 1; if (ctx->state == MFCINST_RES_CHANGE_END && ctx->src_queue_cnt >= 1) @@ -537,7 +537,7 @@ static int vidioc_reqbufs(struct file *file, void *priv, mfc_err("vb2_reqbufs on capture failed\n"); return ret; } - if (reqbufs->count < ctx->dpb_count) { + if (reqbufs->count < ctx->pb_count) { mfc_err("Not enough buffers allocated\n"); reqbufs->count = 0; s5p_mfc_clock_on(); @@ -751,7 +751,7 @@ static int s5p_mfc_dec_g_v_ctrl(struct v4l2_ctrl *ctrl) case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: if (ctx->state >= MFCINST_HEAD_PARSED && ctx->state < MFCINST_ABORT) { - ctrl->val = ctx->dpb_count; + ctrl->val = ctx->pb_count; break; } else if (ctx->state != MFCINST_INIT) { v4l2_err(&dev->v4l2_dev, "Decoding not initialised\n"); @@ -763,7 +763,7 @@ static int s5p_mfc_dec_g_v_ctrl(struct v4l2_ctrl *ctrl) S5P_MFC_R2H_CMD_SEQ_DONE_RET, 0); if (ctx->state >= MFCINST_HEAD_PARSED && ctx->state < MFCINST_ABORT) { - ctrl->val = ctx->dpb_count; + ctrl->val = ctx->pb_count; } else { v4l2_err(&dev->v4l2_dev, "Decoding not initialised\n"); return -EINVAL; @@ -924,10 +924,10 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq, /* Output plane count is 2 - one for Y and one for CbCr */ *plane_count = 2; /* Setup buffer count */ - if (*buf_count < ctx->dpb_count) - *buf_count = ctx->dpb_count; - if (*buf_count > ctx->dpb_count + MFC_MAX_EXTRA_DPB) - *buf_count = ctx->dpb_count + MFC_MAX_EXTRA_DPB; + if (*buf_count < ctx->pb_count) + *buf_count = ctx->pb_count; + if (*buf_count > ctx->pb_count + MFC_MAX_EXTRA_DPB) + *buf_count = ctx->pb_count + MFC_MAX_EXTRA_DPB; if (*buf_count > MFC_MAX_BUFFERS) *buf_count = MFC_MAX_BUFFERS; } else { diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c index 4f6b553c4b2d..2549967b2f85 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c @@ -592,7 +592,7 @@ static int s5p_mfc_ctx_ready(struct s5p_mfc_ctx *ctx) return 1; /* context is ready to encode a frame */ if ((ctx->state == MFCINST_RUNNING || - ctx->state == MFCINST_HEAD_PARSED) && + ctx->state == MFCINST_HEAD_PRODUCED) && ctx->src_queue_cnt >= 1 && ctx->dst_queue_cnt >= 1) return 1; /* context is ready to encode remaining frames */ @@ -649,6 +649,7 @@ static int enc_post_seq_start(struct s5p_mfc_ctx *ctx) struct s5p_mfc_enc_params *p = &ctx->enc_params; struct s5p_mfc_buf *dst_mb; unsigned long flags; + unsigned int enc_pb_count; if (p->seq_hdr_mode == V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE) { spin_lock_irqsave(&dev->irqlock, flags); @@ -661,18 +662,19 @@ static int enc_post_seq_start(struct s5p_mfc_ctx *ctx) vb2_buffer_done(dst_mb->b, VB2_BUF_STATE_DONE); spin_unlock_irqrestore(&dev->irqlock, flags); } - if (IS_MFCV6(dev)) { - ctx->state = MFCINST_HEAD_PARSED; /* for INIT_BUFFER cmd */ - } else { + + if (!IS_MFCV6(dev)) { ctx->state = MFCINST_RUNNING; if (s5p_mfc_ctx_ready(ctx)) set_work_bit_irqsave(ctx); s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); - } - - if (IS_MFCV6(dev)) - ctx->dpb_count = s5p_mfc_hw_call(dev->mfc_ops, + } else { + enc_pb_count = s5p_mfc_hw_call(dev->mfc_ops, get_enc_dpb_count, dev); + if (ctx->pb_count < enc_pb_count) + ctx->pb_count = enc_pb_count; + ctx->state = MFCINST_HEAD_PRODUCED; + } return 0; } @@ -717,9 +719,9 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx) slice_type = s5p_mfc_hw_call(dev->mfc_ops, get_enc_slice_type, dev); strm_size = s5p_mfc_hw_call(dev->mfc_ops, get_enc_strm_size, dev); - mfc_debug(2, "Encoded slice type: %d", slice_type); - mfc_debug(2, "Encoded stream size: %d", strm_size); - mfc_debug(2, "Display order: %d", + mfc_debug(2, "Encoded slice type: %d\n", slice_type); + mfc_debug(2, "Encoded stream size: %d\n", strm_size); + mfc_debug(2, "Display order: %d\n", mfc_read(dev, S5P_FIMV_ENC_SI_PIC_CNT)); spin_lock_irqsave(&dev->irqlock, flags); if (slice_type >= 0) { @@ -1055,15 +1057,13 @@ static int vidioc_reqbufs(struct file *file, void *priv, } ctx->capture_state = QUEUE_BUFS_REQUESTED; - if (!IS_MFCV6(dev)) { - ret = s5p_mfc_hw_call(ctx->dev->mfc_ops, - alloc_codec_buffers, ctx); - if (ret) { - mfc_err("Failed to allocate encoding buffers\n"); - reqbufs->count = 0; - ret = vb2_reqbufs(&ctx->vq_dst, reqbufs); - return -ENOMEM; - } + ret = s5p_mfc_hw_call(ctx->dev->mfc_ops, + alloc_codec_buffers, ctx); + if (ret) { + mfc_err("Failed to allocate encoding buffers\n"); + reqbufs->count = 0; + ret = vb2_reqbufs(&ctx->vq_dst, reqbufs); + return -ENOMEM; } } else if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { if (ctx->output_state != QUEUE_FREE) { @@ -1071,6 +1071,19 @@ static int vidioc_reqbufs(struct file *file, void *priv, ctx->output_state); return -EINVAL; } + + if (IS_MFCV6(dev)) { + /* Check for min encoder buffers */ + if (ctx->pb_count && + (reqbufs->count < ctx->pb_count)) { + reqbufs->count = ctx->pb_count; + mfc_debug(2, "Minimum %d output buffers needed\n", + ctx->pb_count); + } else { + ctx->pb_count = reqbufs->count; + } + } + ret = vb2_reqbufs(&ctx->vq_src, reqbufs); if (ret != 0) { mfc_err("error in vb2_reqbufs() for E(S)\n"); @@ -1533,14 +1546,14 @@ int vidioc_encoder_cmd(struct file *file, void *priv, spin_lock_irqsave(&dev->irqlock, flags); if (list_empty(&ctx->src_queue)) { - mfc_debug(2, "EOS: empty src queue, entering finishing state"); + mfc_debug(2, "EOS: empty src queue, entering finishing state\n"); ctx->state = MFCINST_FINISHING; if (s5p_mfc_ctx_ready(ctx)) set_work_bit_irqsave(ctx); spin_unlock_irqrestore(&dev->irqlock, flags); s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); } else { - mfc_debug(2, "EOS: marking last buffer of stream"); + mfc_debug(2, "EOS: marking last buffer of stream\n"); buf = list_entry(ctx->src_queue.prev, struct s5p_mfc_buf, list); if (buf->flags & MFC_BUF_FLAG_USED) @@ -1609,9 +1622,9 @@ static int check_vb_with_fmt(struct s5p_mfc_fmt *fmt, struct vb2_buffer *vb) mfc_err("failed to get plane cookie\n"); return -EINVAL; } - mfc_debug(2, "index: %d, plane[%d] cookie: 0x%08zx", - vb->v4l2_buf.index, i, - vb2_dma_contig_plane_dma_addr(vb, i)); + mfc_debug(2, "index: %d, plane[%d] cookie: 0x%08zx\n", + vb->v4l2_buf.index, i, + vb2_dma_contig_plane_dma_addr(vb, i)); } return 0; } @@ -1760,11 +1773,27 @@ static int s5p_mfc_start_streaming(struct vb2_queue *q, unsigned int count) struct s5p_mfc_ctx *ctx = fh_to_ctx(q->drv_priv); struct s5p_mfc_dev *dev = ctx->dev; - v4l2_ctrl_handler_setup(&ctx->ctrl_handler); + if (IS_MFCV6(dev) && (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)) { + + if ((ctx->state == MFCINST_GOT_INST) && + (dev->curr_ctx == ctx->num) && dev->hw_lock) { + s5p_mfc_wait_for_done_ctx(ctx, + S5P_MFC_R2H_CMD_SEQ_DONE_RET, + 0); + } + + if (ctx->src_bufs_cnt < ctx->pb_count) { + mfc_err("Need minimum %d OUTPUT buffers\n", + ctx->pb_count); + return -EINVAL; + } + } + /* If context is ready then dev = work->data;schedule it to run */ if (s5p_mfc_ctx_ready(ctx)) set_work_bit_irqsave(ctx); s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); + return 0; } @@ -1920,6 +1949,7 @@ int s5p_mfc_enc_ctrls_setup(struct s5p_mfc_ctx *ctx) if (controls[i].is_volatile && ctx->ctrls[i]) ctx->ctrls[i]->flags |= V4L2_CTRL_FLAG_VOLATILE; } + v4l2_ctrl_handler_setup(&ctx->ctrl_handler); return 0; } diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c index 0af05a2d1cd4..368582b091bf 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c @@ -1275,8 +1275,8 @@ static int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx) spin_unlock_irqrestore(&dev->irqlock, flags); dev->curr_ctx = ctx->num; s5p_mfc_clean_ctx_int_flags(ctx); - mfc_debug(2, "encoding buffer with index=%d state=%d", - src_mb ? src_mb->b->v4l2_buf.index : -1, ctx->state); + mfc_debug(2, "encoding buffer with index=%d state=%d\n", + src_mb ? src_mb->b->v4l2_buf.index : -1, ctx->state); s5p_mfc_encode_one_frame_v5(ctx); return 0; } diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c index 7e76fce2e524..66f0d042357f 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c @@ -62,12 +62,6 @@ static void s5p_mfc_release_dec_desc_buffer_v6(struct s5p_mfc_ctx *ctx) /* NOP */ } -static int s5p_mfc_get_dec_status_v6(struct s5p_mfc_dev *dev) -{ - /* NOP */ - return -1; -} - /* Allocate codec buffers */ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx) { @@ -167,7 +161,7 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx) S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6); ctx->bank1.size = ctx->scratch_buf_size + ctx->tmv_buffer_size + - (ctx->dpb_count * (ctx->luma_dpb_size + + (ctx->pb_count * (ctx->luma_dpb_size + ctx->chroma_dpb_size + ctx->me_buffer_size)); ctx->bank2.size = 0; break; @@ -181,7 +175,7 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx) S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6); ctx->bank1.size = ctx->scratch_buf_size + ctx->tmv_buffer_size + - (ctx->dpb_count * (ctx->luma_dpb_size + + (ctx->pb_count * (ctx->luma_dpb_size + ctx->chroma_dpb_size + ctx->me_buffer_size)); ctx->bank2.size = 0; break; @@ -198,7 +192,6 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx) } BUG_ON(ctx->bank1.dma & ((1 << MFC_BANK1_ALIGN_ORDER) - 1)); } - return 0; } @@ -449,8 +442,8 @@ static int s5p_mfc_set_enc_stream_buffer_v6(struct s5p_mfc_ctx *ctx, WRITEL(addr, S5P_FIMV_E_STREAM_BUFFER_ADDR_V6); /* 16B align */ WRITEL(size, S5P_FIMV_E_STREAM_BUFFER_SIZE_V6); - mfc_debug(2, "stream buf addr: 0x%08lx, size: 0x%d", - addr, size); + mfc_debug(2, "stream buf addr: 0x%08lx, size: 0x%d\n", + addr, size); return 0; } @@ -463,8 +456,8 @@ static void s5p_mfc_set_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx, WRITEL(y_addr, S5P_FIMV_E_SOURCE_LUMA_ADDR_V6); /* 256B align */ WRITEL(c_addr, S5P_FIMV_E_SOURCE_CHROMA_ADDR_V6); - mfc_debug(2, "enc src y buf addr: 0x%08lx", y_addr); - mfc_debug(2, "enc src c buf addr: 0x%08lx", c_addr); + mfc_debug(2, "enc src y buf addr: 0x%08lx\n", y_addr); + mfc_debug(2, "enc src c buf addr: 0x%08lx\n", c_addr); } static void s5p_mfc_get_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx, @@ -479,8 +472,8 @@ static void s5p_mfc_get_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx, enc_recon_y_addr = READL(S5P_FIMV_E_RECON_LUMA_DPB_ADDR_V6); enc_recon_c_addr = READL(S5P_FIMV_E_RECON_CHROMA_DPB_ADDR_V6); - mfc_debug(2, "recon y addr: 0x%08lx", enc_recon_y_addr); - mfc_debug(2, "recon c addr: 0x%08lx", enc_recon_c_addr); + mfc_debug(2, "recon y addr: 0x%08lx\n", enc_recon_y_addr); + mfc_debug(2, "recon c addr: 0x%08lx\n", enc_recon_c_addr); } /* Set encoding ref & codec buffer */ @@ -497,7 +490,7 @@ static int s5p_mfc_set_enc_ref_buffer_v6(struct s5p_mfc_ctx *ctx) mfc_debug(2, "Buf1: %p (%d)\n", (void *)buf_addr1, buf_size1); - for (i = 0; i < ctx->dpb_count; i++) { + for (i = 0; i < ctx->pb_count; i++) { WRITEL(buf_addr1, S5P_FIMV_E_LUMA_DPB_V6 + (4 * i)); buf_addr1 += ctx->luma_dpb_size; WRITEL(buf_addr1, S5P_FIMV_E_CHROMA_DPB_V6 + (4 * i)); @@ -520,7 +513,7 @@ static int s5p_mfc_set_enc_ref_buffer_v6(struct s5p_mfc_ctx *ctx) buf_size1 -= ctx->tmv_buffer_size; mfc_debug(2, "Buf1: %u, buf_size1: %d (ref frames %d)\n", - buf_addr1, buf_size1, ctx->dpb_count); + buf_addr1, buf_size1, ctx->pb_count); if (buf_size1 < 0) { mfc_debug(2, "Not enough memory has been allocated.\n"); return -ENOMEM; @@ -1431,8 +1424,8 @@ static inline int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx) src_y_addr = vb2_dma_contig_plane_dma_addr(src_mb->b, 0); src_c_addr = vb2_dma_contig_plane_dma_addr(src_mb->b, 1); - mfc_debug(2, "enc src y addr: 0x%08lx", src_y_addr); - mfc_debug(2, "enc src c addr: 0x%08lx", src_c_addr); + mfc_debug(2, "enc src y addr: 0x%08lx\n", src_y_addr); + mfc_debug(2, "enc src c addr: 0x%08lx\n", src_c_addr); s5p_mfc_set_enc_frame_buffer_v6(ctx, src_y_addr, src_c_addr); @@ -1522,22 +1515,6 @@ static inline int s5p_mfc_run_init_enc_buffers(struct s5p_mfc_ctx *ctx) struct s5p_mfc_dev *dev = ctx->dev; int ret; - ret = s5p_mfc_alloc_codec_buffers_v6(ctx); - if (ret) { - mfc_err("Failed to allocate encoding buffers.\n"); - return -ENOMEM; - } - - /* Header was generated now starting processing - * First set the reference frame buffers - */ - if (ctx->capture_state != QUEUE_BUFS_REQUESTED) { - mfc_err("It seems that destionation buffers were not\n" - "requested.MFC requires that header should be generated\n" - "before allocating codec buffer.\n"); - return -EAGAIN; - } - dev->curr_ctx = ctx->num; s5p_mfc_clean_ctx_int_flags(ctx); ret = s5p_mfc_set_enc_ref_buffer_v6(ctx); @@ -1582,7 +1559,7 @@ static void s5p_mfc_try_run_v6(struct s5p_mfc_dev *dev) mfc_debug(1, "Seting new context to %p\n", ctx); /* Got context to run in ctx */ mfc_debug(1, "ctx->dst_queue_cnt=%d ctx->dpb_count=%d ctx->src_queue_cnt=%d\n", - ctx->dst_queue_cnt, ctx->dpb_count, ctx->src_queue_cnt); + ctx->dst_queue_cnt, ctx->pb_count, ctx->src_queue_cnt); mfc_debug(1, "ctx->state=%d\n", ctx->state); /* Last frame has already been sent to MFC * Now obtaining frames from MFC buffer */ @@ -1647,7 +1624,7 @@ static void s5p_mfc_try_run_v6(struct s5p_mfc_dev *dev) case MFCINST_GOT_INST: s5p_mfc_run_init_enc(ctx); break; - case MFCINST_HEAD_PARSED: /* Only for MFC6.x */ + case MFCINST_HEAD_PRODUCED: ret = s5p_mfc_run_init_enc_buffers(ctx); break; default: @@ -1730,7 +1707,7 @@ static int s5p_mfc_get_dspl_status_v6(struct s5p_mfc_dev *dev) return mfc_read(dev, S5P_FIMV_D_DISPLAY_STATUS_V6); } -static int s5p_mfc_get_decoded_status_v6(struct s5p_mfc_dev *dev) +static int s5p_mfc_get_dec_status_v6(struct s5p_mfc_dev *dev) { return mfc_read(dev, S5P_FIMV_D_DECODED_STATUS_V6); } diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c b/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c index 6aa38a56aaf2..11d5f1dada32 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c @@ -50,19 +50,6 @@ int s5p_mfc_init_pm(struct s5p_mfc_dev *dev) goto err_p_ip_clk; } - pm->clock = clk_get(&dev->plat_dev->dev, dev->variant->mclk_name); - if (IS_ERR(pm->clock)) { - mfc_err("Failed to get MFC clock\n"); - ret = PTR_ERR(pm->clock); - goto err_g_ip_clk_2; - } - - ret = clk_prepare(pm->clock); - if (ret) { - mfc_err("Failed to prepare MFC clock\n"); - goto err_p_ip_clk_2; - } - atomic_set(&pm->power, 0); #ifdef CONFIG_PM_RUNTIME pm->device = &dev->plat_dev->dev; @@ -72,10 +59,6 @@ int s5p_mfc_init_pm(struct s5p_mfc_dev *dev) atomic_set(&clk_ref, 0); #endif return 0; -err_p_ip_clk_2: - clk_put(pm->clock); -err_g_ip_clk_2: - clk_unprepare(pm->clock_gate); err_p_ip_clk: clk_put(pm->clock_gate); err_g_ip_clk: @@ -86,8 +69,6 @@ void s5p_mfc_final_pm(struct s5p_mfc_dev *dev) { clk_unprepare(pm->clock_gate); clk_put(pm->clock_gate); - clk_unprepare(pm->clock); - clk_put(pm->clock); #ifdef CONFIG_PM_RUNTIME pm_runtime_disable(pm->device); #endif @@ -98,7 +79,7 @@ int s5p_mfc_clock_on(void) int ret; #ifdef CLK_DEBUG atomic_inc(&clk_ref); - mfc_debug(3, "+ %d", atomic_read(&clk_ref)); + mfc_debug(3, "+ %d\n", atomic_read(&clk_ref)); #endif ret = clk_enable(pm->clock_gate); return ret; @@ -108,7 +89,7 @@ void s5p_mfc_clock_off(void) { #ifdef CLK_DEBUG atomic_dec(&clk_ref); - mfc_debug(3, "- %d", atomic_read(&clk_ref)); + mfc_debug(3, "- %d\n", atomic_read(&clk_ref)); #endif clk_disable(pm->clock_gate); } diff --git a/drivers/media/platform/sh_veu.c b/drivers/media/platform/sh_veu.c index 0b32cc3f6a47..59a9deefb242 100644 --- a/drivers/media/platform/sh_veu.c +++ b/drivers/media/platform/sh_veu.c @@ -905,11 +905,11 @@ static int sh_veu_queue_setup(struct vb2_queue *vq, if (ftmp.fmt.pix.width != pix->width || ftmp.fmt.pix.height != pix->height) return -EINVAL; - size = pix->bytesperline ? pix->bytesperline * pix->height : - pix->width * pix->height * fmt->depth >> 3; + size = pix->bytesperline ? pix->bytesperline * pix->height * fmt->depth / fmt->ydepth : + pix->width * pix->height * fmt->depth / fmt->ydepth; } else { vfmt = sh_veu_get_vfmt(veu, vq->type); - size = vfmt->bytesperline * vfmt->frame.height; + size = vfmt->bytesperline * vfmt->frame.height * vfmt->fmt->depth / vfmt->fmt->ydepth; } if (count < 2) @@ -1033,8 +1033,6 @@ static int sh_veu_release(struct file *file) dev_dbg(veu->dev, "Releasing instance %p\n", veu_file); - pm_runtime_put(veu->dev); - if (veu_file == veu->capture) { veu->capture = NULL; vb2_queue_release(v4l2_m2m_get_vq(veu->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE)); @@ -1050,6 +1048,8 @@ static int sh_veu_release(struct file *file) veu->m2m_ctx = NULL; } + pm_runtime_put(veu->dev); + kfree(veu_file); return 0; @@ -1138,10 +1138,7 @@ static irqreturn_t sh_veu_isr(int irq, void *dev_id) veu->xaction++; - if (!veu->aborting) - return IRQ_WAKE_THREAD; - - return IRQ_HANDLED; + return IRQ_WAKE_THREAD; } static int sh_veu_probe(struct platform_device *pdev) diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c index eea832c5fd01..3a4efbdc7668 100644 --- a/drivers/media/platform/soc_camera/soc_camera.c +++ b/drivers/media/platform/soc_camera/soc_camera.c @@ -643,9 +643,9 @@ static int soc_camera_close(struct file *file) if (ici->ops->init_videobuf2) vb2_queue_release(&icd->vb2_vidq); - ici->ops->remove(icd); - __soc_camera_power_off(icd); + + ici->ops->remove(icd); } if (icd->streamer == file) diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig index c0beee2fa37c..d529ba788f41 100644 --- a/drivers/media/radio/Kconfig +++ b/drivers/media/radio/Kconfig @@ -22,6 +22,7 @@ config RADIO_SI476X tristate "Silicon Laboratories Si476x I2C FM Radio" depends on I2C && VIDEO_V4L2 depends on MFD_SI476X_CORE + depends on SND_SOC select SND_SOC_SI476X ---help--- Choose Y here if you have this FM radio chip. diff --git a/drivers/media/radio/radio-si476x.c b/drivers/media/radio/radio-si476x.c index 9430c6a29937..9dc8bafe6486 100644 --- a/drivers/media/radio/radio-si476x.c +++ b/drivers/media/radio/radio-si476x.c @@ -44,7 +44,7 @@ #define FREQ_MUL (10000000 / 625) -#define SI476X_PHDIV_STATUS_LINK_LOCKED(status) (0b10000000 & (status)) +#define SI476X_PHDIV_STATUS_LINK_LOCKED(status) (0x80 & (status)) #define DRIVER_NAME "si476x-radio" #define DRIVER_CARD "SI476x AM/FM Receiver" diff --git a/drivers/media/tuners/Kconfig b/drivers/media/tuners/Kconfig index f6768cad001a..15665debc572 100644 --- a/drivers/media/tuners/Kconfig +++ b/drivers/media/tuners/Kconfig @@ -1,23 +1,3 @@ -config MEDIA_ATTACH - bool "Load and attach frontend and tuner driver modules as needed" - depends on MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT || MEDIA_RADIO_SUPPORT - depends on MODULES - default y if !EXPERT - help - Remove the static dependency of DVB card drivers on all - frontend modules for all possible card variants. Instead, - allow the card drivers to only load the frontend modules - they require. - - Also, tuner module will automatically load a tuner driver - when needed, for analog mode. - - This saves several KBytes of memory. - - Note: You will need module-init-tools v3.2 or later for this feature. - - If unsure say Y. - # Analog TV tuners, auto-loaded via tuner.ko config MEDIA_TUNER tristate diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c index 22015fe1a0f3..2cc8ec70e3b6 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c @@ -376,7 +376,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d) struct rtl28xxu_req req_mxl5007t = {0xd9c0, CMD_I2C_RD, 1, buf}; struct rtl28xxu_req req_e4000 = {0x02c8, CMD_I2C_RD, 1, buf}; struct rtl28xxu_req req_tda18272 = {0x00c0, CMD_I2C_RD, 2, buf}; - struct rtl28xxu_req req_r820t = {0x0034, CMD_I2C_RD, 5, buf}; + struct rtl28xxu_req req_r820t = {0x0034, CMD_I2C_RD, 1, buf}; dev_dbg(&d->udev->dev, "%s:\n", __func__); @@ -481,9 +481,9 @@ static int rtl2832u_read_config(struct dvb_usb_device *d) goto found; } - /* check R820T by reading tuner stats at I2C addr 0x1a */ + /* check R820T ID register; reg=00 val=69 */ ret = rtl28xxu_ctrl_msg(d, &req_r820t); - if (ret == 0) { + if (ret == 0 && buf[0] == 0x69) { priv->tuner = TUNER_RTL2832_R820T; priv->tuner_name = "R820T"; goto found; diff --git a/drivers/media/usb/gspca/sonixb.c b/drivers/media/usb/gspca/sonixb.c index 3fe207e038c7..d7ff3b9687c5 100644 --- a/drivers/media/usb/gspca/sonixb.c +++ b/drivers/media/usb/gspca/sonixb.c @@ -1159,6 +1159,13 @@ static int sd_start(struct gspca_dev *gspca_dev) regs[0x01] = 0x44; /* Select 24 Mhz clock */ regs[0x12] = 0x02; /* Set hstart to 2 */ } + break; + case SENSOR_PAS202: + /* For some unknown reason we need to increase hstart by 1 on + the sn9c103, otherwise we get wrong colors (bayer shift). */ + if (sd->bridge == BRIDGE_103) + regs[0x12] += 1; + break; } /* Disable compression when the raw bayer format has been selected */ if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) diff --git a/drivers/media/usb/pwc/pwc.h b/drivers/media/usb/pwc/pwc.h index 7a6a0d39c2c6..81b017a554bc 100644 --- a/drivers/media/usb/pwc/pwc.h +++ b/drivers/media/usb/pwc/pwc.h @@ -226,7 +226,7 @@ struct pwc_device struct list_head queued_bufs; spinlock_t queued_bufs_lock; /* Protects queued_bufs */ - /* Note if taking both locks v4l2_lock must always be locked first! */ + /* If taking both locks vb_queue_lock must always be locked first! */ struct mutex v4l2_lock; /* Protects everything else */ struct mutex vb_queue_lock; /* Protects vb_queue and capt_file */ diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c index ebb8e48619a2..fccd08b66d1a 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls.c +++ b/drivers/media/v4l2-core/v4l2-ctrls.c @@ -1835,6 +1835,8 @@ bool v4l2_ctrl_radio_filter(const struct v4l2_ctrl *ctrl) { if (V4L2_CTRL_ID2CLASS(ctrl->id) == V4L2_CTRL_CLASS_FM_TX) return true; + if (V4L2_CTRL_ID2CLASS(ctrl->id) == V4L2_CTRL_CLASS_FM_RX) + return true; switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: case V4L2_CID_AUDIO_VOLUME: diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index f81bda1a48ec..7658586fe5f4 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -243,7 +243,6 @@ static void v4l_print_format(const void *arg, bool write_only) const struct v4l2_vbi_format *vbi; const struct v4l2_sliced_vbi_format *sliced; const struct v4l2_window *win; - const struct v4l2_clip *clip; unsigned i; pr_cont("type=%s", prt_names(p->type, v4l2_type_names)); @@ -253,7 +252,7 @@ static void v4l_print_format(const void *arg, bool write_only) pix = &p->fmt.pix; pr_cont(", width=%u, height=%u, " "pixelformat=%c%c%c%c, field=%s, " - "bytesperline=%u sizeimage=%u, colorspace=%d\n", + "bytesperline=%u, sizeimage=%u, colorspace=%d\n", pix->width, pix->height, (pix->pixelformat & 0xff), (pix->pixelformat >> 8) & 0xff, @@ -284,20 +283,14 @@ static void v4l_print_format(const void *arg, bool write_only) case V4L2_BUF_TYPE_VIDEO_OVERLAY: case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: win = &p->fmt.win; - pr_cont(", wxh=%dx%d, x,y=%d,%d, field=%s, " - "chromakey=0x%08x, bitmap=%p, " - "global_alpha=0x%02x\n", - win->w.width, win->w.height, - win->w.left, win->w.top, + /* Note: we can't print the clip list here since the clips + * pointer is a userspace pointer, not a kernelspace + * pointer. */ + pr_cont(", wxh=%dx%d, x,y=%d,%d, field=%s, chromakey=0x%08x, clipcount=%u, clips=%p, bitmap=%p, global_alpha=0x%02x\n", + win->w.width, win->w.height, win->w.left, win->w.top, prt_names(win->field, v4l2_field_names), - win->chromakey, win->bitmap, win->global_alpha); - clip = win->clips; - for (i = 0; i < win->clipcount; i++) { - printk(KERN_DEBUG "clip %u: wxh=%dx%d, x,y=%d,%d\n", - i, clip->c.width, clip->c.height, - clip->c.left, clip->c.top); - clip = clip->next; - } + win->chromakey, win->clipcount, win->clips, + win->bitmap, win->global_alpha); break; case V4L2_BUF_TYPE_VBI_CAPTURE: case V4L2_BUF_TYPE_VBI_OUTPUT: @@ -332,7 +325,7 @@ static void v4l_print_framebuffer(const void *arg, bool write_only) pr_cont("capability=0x%x, flags=0x%x, base=0x%p, width=%u, " "height=%u, pixelformat=%c%c%c%c, " - "bytesperline=%u sizeimage=%u, colorspace=%d\n", + "bytesperline=%u, sizeimage=%u, colorspace=%d\n", p->capability, p->flags, p->base, p->fmt.width, p->fmt.height, (p->fmt.pixelformat & 0xff), @@ -353,7 +346,7 @@ static void v4l_print_modulator(const void *arg, bool write_only) const struct v4l2_modulator *p = arg; if (write_only) - pr_cont("index=%u, txsubchans=0x%x", p->index, p->txsubchans); + pr_cont("index=%u, txsubchans=0x%x\n", p->index, p->txsubchans); else pr_cont("index=%u, name=%.*s, capability=0x%x, " "rangelow=%u, rangehigh=%u, txsubchans=0x%x\n", @@ -445,13 +438,13 @@ static void v4l_print_buffer(const void *arg, bool write_only) for (i = 0; i < p->length; ++i) { plane = &p->m.planes[i]; printk(KERN_DEBUG - "plane %d: bytesused=%d, data_offset=0x%08x " + "plane %d: bytesused=%d, data_offset=0x%08x, " "offset/userptr=0x%lx, length=%d\n", i, plane->bytesused, plane->data_offset, plane->m.userptr, plane->length); } } else { - pr_cont("bytesused=%d, offset/userptr=0x%lx, length=%d\n", + pr_cont(", bytesused=%d, offset/userptr=0x%lx, length=%d\n", p->bytesused, p->m.userptr, p->length); } @@ -504,6 +497,8 @@ static void v4l_print_streamparm(const void *arg, bool write_only) c->capability, c->outputmode, c->timeperframe.numerator, c->timeperframe.denominator, c->extendedmode, c->writebuffers); + } else { + pr_cont("\n"); } } @@ -734,11 +729,11 @@ static void v4l_print_frmsizeenum(const void *arg, bool write_only) p->type); switch (p->type) { case V4L2_FRMSIZE_TYPE_DISCRETE: - pr_cont(" wxh=%ux%u\n", + pr_cont(", wxh=%ux%u\n", p->discrete.width, p->discrete.height); break; case V4L2_FRMSIZE_TYPE_STEPWISE: - pr_cont(" min=%ux%u, max=%ux%u, step=%ux%u\n", + pr_cont(", min=%ux%u, max=%ux%u, step=%ux%u\n", p->stepwise.min_width, p->stepwise.min_height, p->stepwise.step_width, p->stepwise.step_height, p->stepwise.max_width, p->stepwise.max_height); @@ -764,12 +759,12 @@ static void v4l_print_frmivalenum(const void *arg, bool write_only) p->width, p->height, p->type); switch (p->type) { case V4L2_FRMIVAL_TYPE_DISCRETE: - pr_cont(" fps=%d/%d\n", + pr_cont(", fps=%d/%d\n", p->discrete.numerator, p->discrete.denominator); break; case V4L2_FRMIVAL_TYPE_STEPWISE: - pr_cont(" min=%d/%d, max=%d/%d, step=%d/%d\n", + pr_cont(", min=%d/%d, max=%d/%d, step=%d/%d\n", p->stepwise.min.numerator, p->stepwise.min.denominator, p->stepwise.max.numerator, @@ -807,8 +802,8 @@ static void v4l_print_event(const void *arg, bool write_only) pr_cont("value64=%lld, ", c->value64); else pr_cont("value=%d, ", c->value); - pr_cont("flags=0x%x, minimum=%d, maximum=%d, step=%d," - " default_value=%d\n", + pr_cont("flags=0x%x, minimum=%d, maximum=%d, step=%d, " + "default_value=%d\n", c->flags, c->minimum, c->maximum, c->step, c->default_value); break; @@ -845,7 +840,7 @@ static void v4l_print_freq_band(const void *arg, bool write_only) const struct v4l2_frequency_band *p = arg; pr_cont("tuner=%u, type=%u, index=%u, capability=0x%x, " - "rangelow=%u, rangehigh=%u, modulation=0x%x\n", + "rangelow=%u, rangehigh=%u, modulation=0x%x\n", p->tuner, p->type, p->index, p->capability, p->rangelow, p->rangehigh, p->modulation); diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c index 66f599fcb829..e96497f7c3ed 100644 --- a/drivers/media/v4l2-core/v4l2-mem2mem.c +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c @@ -205,7 +205,7 @@ static void v4l2_m2m_try_run(struct v4l2_m2m_dev *m2m_dev) static void v4l2_m2m_try_schedule(struct v4l2_m2m_ctx *m2m_ctx) { struct v4l2_m2m_dev *m2m_dev; - unsigned long flags_job, flags; + unsigned long flags_job, flags_out, flags_cap; m2m_dev = m2m_ctx->m2m_dev; dprintk("Trying to schedule a job for m2m_ctx: %p\n", m2m_ctx); @@ -223,23 +223,26 @@ static void v4l2_m2m_try_schedule(struct v4l2_m2m_ctx *m2m_ctx) return; } - spin_lock_irqsave(&m2m_ctx->out_q_ctx.rdy_spinlock, flags); + spin_lock_irqsave(&m2m_ctx->out_q_ctx.rdy_spinlock, flags_out); if (list_empty(&m2m_ctx->out_q_ctx.rdy_queue)) { - spin_unlock_irqrestore(&m2m_ctx->out_q_ctx.rdy_spinlock, flags); + spin_unlock_irqrestore(&m2m_ctx->out_q_ctx.rdy_spinlock, + flags_out); spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags_job); dprintk("No input buffers available\n"); return; } - spin_lock_irqsave(&m2m_ctx->cap_q_ctx.rdy_spinlock, flags); + spin_lock_irqsave(&m2m_ctx->cap_q_ctx.rdy_spinlock, flags_cap); if (list_empty(&m2m_ctx->cap_q_ctx.rdy_queue)) { - spin_unlock_irqrestore(&m2m_ctx->cap_q_ctx.rdy_spinlock, flags); - spin_unlock_irqrestore(&m2m_ctx->out_q_ctx.rdy_spinlock, flags); + spin_unlock_irqrestore(&m2m_ctx->cap_q_ctx.rdy_spinlock, + flags_cap); + spin_unlock_irqrestore(&m2m_ctx->out_q_ctx.rdy_spinlock, + flags_out); spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags_job); dprintk("No output buffers available\n"); return; } - spin_unlock_irqrestore(&m2m_ctx->cap_q_ctx.rdy_spinlock, flags); - spin_unlock_irqrestore(&m2m_ctx->out_q_ctx.rdy_spinlock, flags); + spin_unlock_irqrestore(&m2m_ctx->cap_q_ctx.rdy_spinlock, flags_cap); + spin_unlock_irqrestore(&m2m_ctx->out_q_ctx.rdy_spinlock, flags_out); if (m2m_dev->m2m_ops->job_ready && (!m2m_dev->m2m_ops->job_ready(m2m_ctx->priv))) { @@ -372,6 +375,20 @@ int v4l2_m2m_dqbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, EXPORT_SYMBOL_GPL(v4l2_m2m_dqbuf); /** + * v4l2_m2m_create_bufs() - create a source or destination buffer, depending + * on the type + */ +int v4l2_m2m_create_bufs(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, + struct v4l2_create_buffers *create) +{ + struct vb2_queue *vq; + + vq = v4l2_m2m_get_vq(m2m_ctx, create->format.type); + return vb2_create_bufs(vq, create); +} +EXPORT_SYMBOL_GPL(v4l2_m2m_create_bufs); + +/** * v4l2_m2m_expbuf() - export a source or destination buffer, depending on * the type */ @@ -486,8 +503,10 @@ unsigned int v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, if (m2m_ctx->m2m_dev->m2m_ops->unlock) m2m_ctx->m2m_dev->m2m_ops->unlock(m2m_ctx->priv); - poll_wait(file, &src_q->done_wq, wait); - poll_wait(file, &dst_q->done_wq, wait); + if (list_empty(&src_q->done_list)) + poll_wait(file, &src_q->done_wq, wait); + if (list_empty(&dst_q->done_list)) + poll_wait(file, &dst_q->done_wq, wait); if (m2m_ctx->m2m_dev->m2m_ops->lock) m2m_ctx->m2m_dev->m2m_ops->lock(m2m_ctx->priv); diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index 7d833eefaf4e..e3bdc3be91e1 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -2014,7 +2014,8 @@ unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait) if (list_empty(&q->queued_list)) return res | POLLERR; - poll_wait(file, &q->done_wq, wait); + if (list_empty(&q->done_list)) + poll_wait(file, &q->done_wq, wait); /* * Take first buffer available for dequeuing. diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index 713d89fedc46..f580d30bb784 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -197,6 +197,8 @@ void mei_stop(struct mei_device *dev) { dev_dbg(&dev->pdev->dev, "stopping the device.\n"); + flush_scheduled_work(); + mutex_lock(&dev->device_lock); cancel_delayed_work(&dev->timer_work); @@ -210,8 +212,6 @@ void mei_stop(struct mei_device *dev) mutex_unlock(&dev->device_lock); - flush_scheduled_work(); - mei_watchdog_unregister(dev); } EXPORT_SYMBOL_GPL(mei_stop); diff --git a/drivers/misc/mei/nfc.c b/drivers/misc/mei/nfc.c index 3adf8a70f26e..d0c6907dfd92 100644 --- a/drivers/misc/mei/nfc.c +++ b/drivers/misc/mei/nfc.c @@ -142,6 +142,8 @@ static void mei_nfc_free(struct mei_nfc_dev *ndev) mei_cl_unlink(ndev->cl_info); kfree(ndev->cl_info); } + + memset(ndev, 0, sizeof(struct mei_nfc_dev)); } static int mei_nfc_build_bus_name(struct mei_nfc_dev *ndev) diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c index a727464e9c3f..0f268329bd3a 100644 --- a/drivers/misc/mei/pci-me.c +++ b/drivers/misc/mei/pci-me.c @@ -325,6 +325,7 @@ static int mei_me_pci_resume(struct device *device) mutex_lock(&dev->device_lock); dev->dev_state = MEI_DEV_POWER_UP; + mei_clear_interrupts(dev); mei_reset(dev, 1); mutex_unlock(&dev->device_lock); diff --git a/drivers/misc/sgi-gru/grufile.c b/drivers/misc/sgi-gru/grufile.c index 44d273c5e19d..0535d1e0bc78 100644 --- a/drivers/misc/sgi-gru/grufile.c +++ b/drivers/misc/sgi-gru/grufile.c @@ -172,6 +172,7 @@ static long gru_get_config_info(unsigned long arg) nodesperblade = 2; else nodesperblade = 1; + memset(&info, 0, sizeof(info)); info.cpus = num_online_cpus(); info.nodes = num_online_nodes(); info.blades = info.nodes / nodesperblade; diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index e75774f72606..aca59d93d5a9 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c @@ -2230,10 +2230,15 @@ static void __exit atmci_cleanup_slot(struct atmel_mci_slot *slot, mmc_free_host(slot->mmc); } -static bool atmci_filter(struct dma_chan *chan, void *slave) +static bool atmci_filter(struct dma_chan *chan, void *pdata) { - struct mci_dma_data *sl = slave; + struct mci_platform_data *sl_pdata = pdata; + struct mci_dma_data *sl; + if (!sl_pdata) + return false; + + sl = sl_pdata->dma_slave; if (sl && find_slave_dev(sl) == chan->device->dev) { chan->private = slave_data_ptr(sl); return true; @@ -2245,24 +2250,18 @@ static bool atmci_filter(struct dma_chan *chan, void *slave) static bool atmci_configure_dma(struct atmel_mci *host) { struct mci_platform_data *pdata; + dma_cap_mask_t mask; if (host == NULL) return false; pdata = host->pdev->dev.platform_data; - if (!pdata) - return false; + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE, mask); - if (pdata->dma_slave && find_slave_dev(pdata->dma_slave)) { - dma_cap_mask_t mask; - - /* Try to grab a DMA channel */ - dma_cap_zero(mask); - dma_cap_set(DMA_SLAVE, mask); - host->dma.chan = - dma_request_channel(mask, atmci_filter, pdata->dma_slave); - } + host->dma.chan = dma_request_slave_channel_compat(mask, atmci_filter, pdata, + &host->pdev->dev, "rxtx"); if (!host->dma.chan) { dev_warn(&host->pdev->dev, "no DMA channel available\n"); return false; diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 6e44025acf01..eccedc7d06a4 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -161,6 +161,7 @@ struct omap_hsmmc_host { */ struct regulator *vcc; struct regulator *vcc_aux; + int pbias_disable; void __iomem *base; resource_size_t mapbase; spinlock_t irq_lock; /* Prevent races with irq handler */ @@ -255,11 +256,11 @@ static int omap_hsmmc_set_power(struct device *dev, int slot, int power_on, if (!host->vcc) return 0; /* - * With DT, never turn OFF the regulator. This is because + * With DT, never turn OFF the regulator for MMC1. This is because * the pbias cell programming support is still missing when * booting with Device tree */ - if (dev->of_node && !vdd) + if (host->pbias_disable && !vdd) return 0; if (mmc_slot(host).before_set_reg) @@ -1520,10 +1521,10 @@ static void omap_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) (ios->vdd == DUAL_VOLT_OCR_BIT) && /* * With pbias cell programming missing, this - * can't be allowed when booting with device + * can't be allowed on MMC1 when booting with device * tree. */ - !host->dev->of_node) { + !host->pbias_disable) { /* * The mmc_select_voltage fn of the core does * not seem to set the power_mode to @@ -1871,6 +1872,10 @@ static int omap_hsmmc_probe(struct platform_device *pdev) omap_hsmmc_context_save(host); + /* This can be removed once we support PBIAS with DT */ + if (host->dev->of_node && host->mapbase == 0x4809c000) + host->pbias_disable = 1; + host->dbclk = clk_get(&pdev->dev, "mmchsdb_fck"); /* * MMC can still work without debounce clock. @@ -1906,33 +1911,41 @@ static int omap_hsmmc_probe(struct platform_device *pdev) omap_hsmmc_conf_bus_power(host); - res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx"); - if (!res) { - dev_err(mmc_dev(host->mmc), "cannot get DMA TX channel\n"); - ret = -ENXIO; - goto err_irq; - } - tx_req = res->start; + if (!pdev->dev.of_node) { + res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx"); + if (!res) { + dev_err(mmc_dev(host->mmc), "cannot get DMA TX channel\n"); + ret = -ENXIO; + goto err_irq; + } + tx_req = res->start; - res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx"); - if (!res) { - dev_err(mmc_dev(host->mmc), "cannot get DMA RX channel\n"); - ret = -ENXIO; - goto err_irq; + res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx"); + if (!res) { + dev_err(mmc_dev(host->mmc), "cannot get DMA RX channel\n"); + ret = -ENXIO; + goto err_irq; + } + rx_req = res->start; } - rx_req = res->start; dma_cap_zero(mask); dma_cap_set(DMA_SLAVE, mask); - host->rx_chan = dma_request_channel(mask, omap_dma_filter_fn, &rx_req); + host->rx_chan = + dma_request_slave_channel_compat(mask, omap_dma_filter_fn, + &rx_req, &pdev->dev, "rx"); + if (!host->rx_chan) { dev_err(mmc_dev(host->mmc), "unable to obtain RX DMA engine channel %u\n", rx_req); ret = -ENXIO; goto err_irq; } - host->tx_chan = dma_request_channel(mask, omap_dma_filter_fn, &tx_req); + host->tx_chan = + dma_request_slave_channel_compat(mask, omap_dma_filter_fn, + &tx_req, &pdev->dev, "tx"); + if (!host->tx_chan) { dev_err(mmc_dev(host->mmc), "unable to obtain TX DMA engine channel %u\n", tx_req); ret = -ENXIO; diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c index 7bcf74b1a5cd..706d9cb1a49e 100644 --- a/drivers/mmc/host/sdhci-acpi.c +++ b/drivers/mmc/host/sdhci-acpi.c @@ -87,6 +87,12 @@ static const struct sdhci_ops sdhci_acpi_ops_dflt = { .enable_dma = sdhci_acpi_enable_dma, }; +static const struct sdhci_acpi_slot sdhci_acpi_slot_int_emmc = { + .caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE, + .caps2 = MMC_CAP2_HC_ERASE_SZ, + .flags = SDHCI_ACPI_RUNTIME_PM, +}; + static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sdio = { .quirks2 = SDHCI_QUIRK2_HOST_OFF_CARD_ON, .caps = MMC_CAP_NONREMOVABLE | MMC_CAP_POWER_OFF_CARD, @@ -94,23 +100,67 @@ static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sdio = { .pm_caps = MMC_PM_KEEP_POWER, }; +static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sd = { +}; + +struct sdhci_acpi_uid_slot { + const char *hid; + const char *uid; + const struct sdhci_acpi_slot *slot; +}; + +static const struct sdhci_acpi_uid_slot sdhci_acpi_uids[] = { + { "80860F14" , "1" , &sdhci_acpi_slot_int_emmc }, + { "80860F14" , "3" , &sdhci_acpi_slot_int_sd }, + { "INT33BB" , "2" , &sdhci_acpi_slot_int_sdio }, + { "INT33C6" , NULL, &sdhci_acpi_slot_int_sdio }, + { "PNP0D40" }, + { }, +}; + static const struct acpi_device_id sdhci_acpi_ids[] = { - { "INT33C6", (kernel_ulong_t)&sdhci_acpi_slot_int_sdio }, - { "PNP0D40" }, + { "80860F14" }, + { "INT33BB" }, + { "INT33C6" }, + { "PNP0D40" }, { }, }; MODULE_DEVICE_TABLE(acpi, sdhci_acpi_ids); -static const struct sdhci_acpi_slot *sdhci_acpi_get_slot(const char *hid) +static const struct sdhci_acpi_slot *sdhci_acpi_get_slot_by_ids(const char *hid, + const char *uid) { - const struct acpi_device_id *id; - - for (id = sdhci_acpi_ids; id->id[0]; id++) - if (!strcmp(id->id, hid)) - return (const struct sdhci_acpi_slot *)id->driver_data; + const struct sdhci_acpi_uid_slot *u; + + for (u = sdhci_acpi_uids; u->hid; u++) { + if (strcmp(u->hid, hid)) + continue; + if (!u->uid) + return u->slot; + if (uid && !strcmp(u->uid, uid)) + return u->slot; + } return NULL; } +static const struct sdhci_acpi_slot *sdhci_acpi_get_slot(acpi_handle handle, + const char *hid) +{ + const struct sdhci_acpi_slot *slot; + struct acpi_device_info *info; + const char *uid = NULL; + acpi_status status; + + status = acpi_get_object_info(handle, &info); + if (!ACPI_FAILURE(status) && (info->valid & ACPI_VALID_UID)) + uid = info->unique_id.string; + + slot = sdhci_acpi_get_slot_by_ids(hid, uid); + + kfree(info); + return slot; +} + static int sdhci_acpi_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -148,7 +198,7 @@ static int sdhci_acpi_probe(struct platform_device *pdev) c = sdhci_priv(host); c->host = host; - c->slot = sdhci_acpi_get_slot(hid); + c->slot = sdhci_acpi_get_slot(handle, hid); c->pdev = pdev; c->use_runtime_pm = sdhci_acpi_flag(c, SDHCI_ACPI_RUNTIME_PM); @@ -202,6 +252,7 @@ static int sdhci_acpi_probe(struct platform_device *pdev) goto err_free; if (c->use_runtime_pm) { + pm_runtime_set_active(dev); pm_suspend_ignore_children(dev, 1); pm_runtime_set_autosuspend_delay(dev, 50); pm_runtime_use_autosuspend(dev); diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 67d6dde2ff19..d5f0d59e1310 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -85,6 +85,12 @@ struct pltfm_imx_data { struct clk *clk_ipg; struct clk *clk_ahb; struct clk *clk_per; + enum { + NO_CMD_PENDING, /* no multiblock command pending*/ + MULTIBLK_IN_PROCESS, /* exact multiblock cmd in process */ + WAIT_FOR_INT, /* sent CMD12, waiting for response INT */ + } multiblock_status; + }; static struct platform_device_id imx_esdhc_devtype[] = { @@ -154,6 +160,8 @@ static inline void esdhc_clrset_le(struct sdhci_host *host, u32 mask, u32 val, i static u32 esdhc_readl_le(struct sdhci_host *host, int reg) { + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct pltfm_imx_data *imx_data = pltfm_host->priv; u32 val = readl(host->ioaddr + reg); if (unlikely(reg == SDHCI_CAPABILITIES)) { @@ -175,6 +183,18 @@ static u32 esdhc_readl_le(struct sdhci_host *host, int reg) val &= ~ESDHC_INT_VENDOR_SPEC_DMA_ERR; val |= SDHCI_INT_ADMA_ERROR; } + + /* + * mask off the interrupt we get in response to the manually + * sent CMD12 + */ + if ((imx_data->multiblock_status == WAIT_FOR_INT) && + ((val & SDHCI_INT_RESPONSE) == SDHCI_INT_RESPONSE)) { + val &= ~SDHCI_INT_RESPONSE; + writel(SDHCI_INT_RESPONSE, host->ioaddr + + SDHCI_INT_STATUS); + imx_data->multiblock_status = NO_CMD_PENDING; + } } return val; @@ -211,6 +231,15 @@ static void esdhc_writel_le(struct sdhci_host *host, u32 val, int reg) v = readl(host->ioaddr + ESDHC_VENDOR_SPEC); v &= ~ESDHC_VENDOR_SPEC_SDIO_QUIRK; writel(v, host->ioaddr + ESDHC_VENDOR_SPEC); + + if (imx_data->multiblock_status == MULTIBLK_IN_PROCESS) + { + /* send a manual CMD12 with RESPTYP=none */ + data = MMC_STOP_TRANSMISSION << 24 | + SDHCI_CMD_ABORTCMD << 16; + writel(data, host->ioaddr + SDHCI_TRANSFER_MODE); + imx_data->multiblock_status = WAIT_FOR_INT; + } } if (unlikely(reg == SDHCI_INT_ENABLE || reg == SDHCI_SIGNAL_ENABLE)) { @@ -277,11 +306,13 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg) } return; case SDHCI_COMMAND: - if ((host->cmd->opcode == MMC_STOP_TRANSMISSION || - host->cmd->opcode == MMC_SET_BLOCK_COUNT) && - (imx_data->flags & ESDHC_FLAG_MULTIBLK_NO_INT)) + if (host->cmd->opcode == MMC_STOP_TRANSMISSION) val |= SDHCI_CMD_ABORTCMD; + if ((host->cmd->opcode == MMC_SET_BLOCK_COUNT) && + (imx_data->flags & ESDHC_FLAG_MULTIBLK_NO_INT)) + imx_data->multiblock_status = MULTIBLK_IN_PROCESS; + if (is_imx6q_usdhc(imx_data)) writel(val << 16, host->ioaddr + SDHCI_TRANSFER_MODE); @@ -324,8 +355,10 @@ static void esdhc_writeb_le(struct sdhci_host *host, u8 val, int reg) /* * Do not touch buswidth bits here. This is done in * esdhc_pltfm_bus_width. + * Do not touch the D3CD bit either which is used for the + * SDIO interrupt errata workaround. */ - mask = 0xffff & ~ESDHC_CTRL_BUSWIDTH_MASK; + mask = 0xffff & ~(ESDHC_CTRL_BUSWIDTH_MASK | ESDHC_CTRL_D3CD); esdhc_clrset_le(host, mask, new_val, reg); return; diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index 0012d3fdc999..701d06d0e1fb 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c @@ -33,6 +33,9 @@ */ #define PCI_DEVICE_ID_INTEL_PCH_SDIO0 0x8809 #define PCI_DEVICE_ID_INTEL_PCH_SDIO1 0x880a +#define PCI_DEVICE_ID_INTEL_BYT_EMMC 0x0f14 +#define PCI_DEVICE_ID_INTEL_BYT_SDIO 0x0f15 +#define PCI_DEVICE_ID_INTEL_BYT_SD 0x0f16 /* * PCI registers @@ -304,6 +307,33 @@ static const struct sdhci_pci_fixes sdhci_intel_pch_sdio = { .probe_slot = pch_hc_probe_slot, }; +static int byt_emmc_probe_slot(struct sdhci_pci_slot *slot) +{ + slot->host->mmc->caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE; + slot->host->mmc->caps2 |= MMC_CAP2_HC_ERASE_SZ; + return 0; +} + +static int byt_sdio_probe_slot(struct sdhci_pci_slot *slot) +{ + slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD | MMC_CAP_NONREMOVABLE; + return 0; +} + +static const struct sdhci_pci_fixes sdhci_intel_byt_emmc = { + .allow_runtime_pm = true, + .probe_slot = byt_emmc_probe_slot, +}; + +static const struct sdhci_pci_fixes sdhci_intel_byt_sdio = { + .quirks2 = SDHCI_QUIRK2_HOST_OFF_CARD_ON, + .allow_runtime_pm = true, + .probe_slot = byt_sdio_probe_slot, +}; + +static const struct sdhci_pci_fixes sdhci_intel_byt_sd = { +}; + /* O2Micro extra registers */ #define O2_SD_LOCK_WP 0xD3 #define O2_SD_MULTI_VCC3V 0xEE @@ -856,6 +886,30 @@ static const struct pci_device_id pci_ids[] = { }, { + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_BYT_EMMC, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = (kernel_ulong_t)&sdhci_intel_byt_emmc, + }, + + { + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_BYT_SDIO, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = (kernel_ulong_t)&sdhci_intel_byt_sdio, + }, + + { + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_BYT_SD, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = (kernel_ulong_t)&sdhci_intel_byt_sd, + }, + + { .vendor = PCI_VENDOR_ID_O2, .device = PCI_DEVICE_ID_O2_8120, .subvendor = PCI_ANY_ID, diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index fc58d118d844..390061d09693 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c @@ -2360,14 +2360,15 @@ int bond_3ad_set_carrier(struct bonding *bond) } /** - * bond_3ad_get_active_agg_info - get information of the active aggregator + * __bond_3ad_get_active_agg_info - get information of the active aggregator * @bond: bonding struct to work on * @ad_info: ad_info struct to fill with the bond's info * * Returns: 0 on success * < 0 on error */ -int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info) +int __bond_3ad_get_active_agg_info(struct bonding *bond, + struct ad_info *ad_info) { struct aggregator *aggregator = NULL; struct port *port; @@ -2391,6 +2392,18 @@ int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info) return -1; } +/* Wrapper used to hold bond->lock so no slave manipulation can occur */ +int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info) +{ + int ret; + + read_lock(&bond->lock); + ret = __bond_3ad_get_active_agg_info(bond, ad_info); + read_unlock(&bond->lock); + + return ret; +} + int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev) { struct slave *slave, *start_at; @@ -2402,8 +2415,8 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev) struct ad_info ad_info; int res = 1; - if (bond_3ad_get_active_agg_info(bond, &ad_info)) { - pr_debug("%s: Error: bond_3ad_get_active_agg_info failed\n", + if (__bond_3ad_get_active_agg_info(bond, &ad_info)) { + pr_debug("%s: Error: __bond_3ad_get_active_agg_info failed\n", dev->name); goto out; } diff --git a/drivers/net/bonding/bond_3ad.h b/drivers/net/bonding/bond_3ad.h index 0cfaa4afdece..5d91ad0cc041 100644 --- a/drivers/net/bonding/bond_3ad.h +++ b/drivers/net/bonding/bond_3ad.h @@ -273,6 +273,8 @@ void bond_3ad_adapter_speed_changed(struct slave *slave); void bond_3ad_adapter_duplex_changed(struct slave *slave); void bond_3ad_handle_link_change(struct slave *slave, char link); int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info); +int __bond_3ad_get_active_agg_info(struct bonding *bond, + struct ad_info *ad_info); int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev); int bond_3ad_lacpdu_recv(const struct sk_buff *skb, struct bonding *bond, struct slave *slave); diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index d0aade04e49a..02d9ae7d527e 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -764,8 +764,8 @@ static void bond_resend_igmp_join_requests(struct bonding *bond) struct net_device *bond_dev, *vlan_dev, *upper_dev; struct vlan_entry *vlan; - rcu_read_lock(); read_lock(&bond->lock); + rcu_read_lock(); bond_dev = bond->dev; @@ -787,12 +787,19 @@ static void bond_resend_igmp_join_requests(struct bonding *bond) if (vlan_dev) __bond_resend_igmp_join_requests(vlan_dev); } + rcu_read_unlock(); - if (--bond->igmp_retrans > 0) + /* We use curr_slave_lock to protect against concurrent access to + * igmp_retrans from multiple running instances of this function and + * bond_change_active_slave + */ + write_lock_bh(&bond->curr_slave_lock); + if (bond->igmp_retrans > 1) { + bond->igmp_retrans--; queue_delayed_work(bond->wq, &bond->mcast_work, HZ/5); - + } + write_unlock_bh(&bond->curr_slave_lock); read_unlock(&bond->lock); - rcu_read_unlock(); } static void bond_resend_igmp_join_requests_delayed(struct work_struct *work) @@ -1362,6 +1369,7 @@ static netdev_features_t bond_fix_features(struct net_device *dev, slave->dev->features, mask); } + features = netdev_add_tso_features(features, mask); out: read_unlock(&bond->lock); @@ -1956,6 +1964,10 @@ err_free: err_undo_flags: bond_compute_features(bond); + /* Enslave of first slave has failed and we need to fix master's mac */ + if (bond->slave_cnt == 0 && + ether_addr_equal(bond_dev->dev_addr, slave_dev->dev_addr)) + eth_hw_addr_random(bond_dev); return res; } @@ -2555,8 +2567,8 @@ static void bond_arp_send(struct net_device *slave_dev, int arp_op, __be32 dest_ { struct sk_buff *skb; - pr_debug("arp %d on slave %s: dst %x src %x vid %d\n", arp_op, - slave_dev->name, dest_ip, src_ip, vlan_id); + pr_debug("arp %d on slave %s: dst %pI4 src %pI4 vid %d\n", arp_op, + slave_dev->name, &dest_ip, &src_ip, vlan_id); skb = arp_create(arp_op, ETH_P_ARP, dest_ip, slave_dev, src_ip, NULL, slave_dev->dev_addr, NULL); @@ -2588,7 +2600,7 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave) __be32 addr; if (!targets[i]) break; - pr_debug("basa: target %x\n", targets[i]); + pr_debug("basa: target %pI4\n", &targets[i]); if (!bond_vlan_used(bond)) { pr_debug("basa: empty vlan: arp_send\n"); addr = bond_confirm_addr(bond->dev, targets[i], 0); @@ -4470,7 +4482,7 @@ int bond_parse_parm(const char *buf, const struct bond_parm_tbl *tbl) static int bond_check_params(struct bond_params *params) { - int arp_validate_value, fail_over_mac_value, primary_reselect_value; + int arp_validate_value, fail_over_mac_value, primary_reselect_value, i; /* * Convert string parameters. @@ -4650,19 +4662,18 @@ static int bond_check_params(struct bond_params *params) arp_interval = BOND_LINK_ARP_INTERV; } - for (arp_ip_count = 0; - (arp_ip_count < BOND_MAX_ARP_TARGETS) && arp_ip_target[arp_ip_count]; - arp_ip_count++) { + for (arp_ip_count = 0, i = 0; + (arp_ip_count < BOND_MAX_ARP_TARGETS) && arp_ip_target[i]; i++) { /* not complete check, but should be good enough to catch mistakes */ - __be32 ip = in_aton(arp_ip_target[arp_ip_count]); - if (!isdigit(arp_ip_target[arp_ip_count][0]) || - ip == 0 || ip == htonl(INADDR_BROADCAST)) { + __be32 ip = in_aton(arp_ip_target[i]); + if (!isdigit(arp_ip_target[i][0]) || ip == 0 || + ip == htonl(INADDR_BROADCAST)) { pr_warning("Warning: bad arp_ip_target module parameter (%s), ARP monitoring will not be performed\n", - arp_ip_target[arp_ip_count]); + arp_ip_target[i]); arp_interval = 0; } else { - arp_target[arp_ip_count] = ip; + arp_target[arp_ip_count++] = ip; } } @@ -4696,8 +4707,6 @@ static int bond_check_params(struct bond_params *params) if (miimon) { pr_info("MII link monitoring set to %d ms\n", miimon); } else if (arp_interval) { - int i; - pr_info("ARP monitoring set to %d ms, validate %s, with %d target(s):", arp_interval, arp_validate_tbl[arp_validate_value].modename, diff --git a/drivers/net/bonding/bond_procfs.c b/drivers/net/bonding/bond_procfs.c index 94d06f1307b8..4060d41f0ee7 100644 --- a/drivers/net/bonding/bond_procfs.c +++ b/drivers/net/bonding/bond_procfs.c @@ -130,7 +130,7 @@ static void bond_info_show_master(struct seq_file *seq) seq_printf(seq, "Aggregator selection policy (ad_select): %s\n", ad_select_tbl[bond->params.ad_select].modename); - if (bond_3ad_get_active_agg_info(bond, &ad_info)) { + if (__bond_3ad_get_active_agg_info(bond, &ad_info)) { seq_printf(seq, "bond %s has no active aggregator\n", bond->dev->name); } else { diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index ea7a388f4843..d7434e0a610e 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c @@ -316,6 +316,9 @@ static ssize_t bonding_store_mode(struct device *d, int new_value, ret = count; struct bonding *bond = to_bond(d); + if (!rtnl_trylock()) + return restart_syscall(); + if (bond->dev->flags & IFF_UP) { pr_err("unable to update mode of %s because interface is up.\n", bond->dev->name); @@ -352,6 +355,7 @@ static ssize_t bonding_store_mode(struct device *d, bond->dev->name, bond_mode_tbl[new_value].modename, new_value); out: + rtnl_unlock(); return ret; } static DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, @@ -1315,7 +1319,6 @@ static ssize_t bonding_show_mii_status(struct device *d, } static DEVICE_ATTR(mii_status, S_IRUGO, bonding_show_mii_status, NULL); - /* * Show current 802.3ad aggregator ID. */ @@ -1329,7 +1332,7 @@ static ssize_t bonding_show_ad_aggregator(struct device *d, if (bond->params.mode == BOND_MODE_8023AD) { struct ad_info ad_info; count = sprintf(buf, "%d\n", - (bond_3ad_get_active_agg_info(bond, &ad_info)) + bond_3ad_get_active_agg_info(bond, &ad_info) ? 0 : ad_info.aggregator_id); } @@ -1351,7 +1354,7 @@ static ssize_t bonding_show_ad_num_ports(struct device *d, if (bond->params.mode == BOND_MODE_8023AD) { struct ad_info ad_info; count = sprintf(buf, "%d\n", - (bond_3ad_get_active_agg_info(bond, &ad_info)) + bond_3ad_get_active_agg_info(bond, &ad_info) ? 0 : ad_info.ports); } @@ -1373,7 +1376,7 @@ static ssize_t bonding_show_ad_actor_key(struct device *d, if (bond->params.mode == BOND_MODE_8023AD) { struct ad_info ad_info; count = sprintf(buf, "%d\n", - (bond_3ad_get_active_agg_info(bond, &ad_info)) + bond_3ad_get_active_agg_info(bond, &ad_info) ? 0 : ad_info.actor_key); } @@ -1395,7 +1398,7 @@ static ssize_t bonding_show_ad_partner_key(struct device *d, if (bond->params.mode == BOND_MODE_8023AD) { struct ad_info ad_info; count = sprintf(buf, "%d\n", - (bond_3ad_get_active_agg_info(bond, &ad_info)) + bond_3ad_get_active_agg_info(bond, &ad_info) ? 0 : ad_info.partner_key); } diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 2baec24388b1..f989e1529a29 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h @@ -225,7 +225,7 @@ struct bonding { rwlock_t curr_slave_lock; u8 send_peer_notif; s8 setup_by_slave; - s8 igmp_retrans; + u8 igmp_retrans; #ifdef CONFIG_PROC_FS struct proc_dir_entry *proc_entry; char proc_file_name[IFNAMSIZ]; diff --git a/drivers/net/can/usb/esd_usb2.c b/drivers/net/can/usb/esd_usb2.c index 9b74d1e3ad44..6aa7b3266c80 100644 --- a/drivers/net/can/usb/esd_usb2.c +++ b/drivers/net/can/usb/esd_usb2.c @@ -612,9 +612,15 @@ static int esd_usb2_start(struct esd_usb2_net_priv *priv) { struct esd_usb2 *dev = priv->usb2; struct net_device *netdev = priv->netdev; - struct esd_usb2_msg msg; + struct esd_usb2_msg *msg; int err, i; + msg = kmalloc(sizeof(*msg), GFP_KERNEL); + if (!msg) { + err = -ENOMEM; + goto out; + } + /* * Enable all IDs * The IDADD message takes up to 64 32 bit bitmasks (2048 bits). @@ -628,33 +634,32 @@ static int esd_usb2_start(struct esd_usb2_net_priv *priv) * the number of the starting bitmask (0..64) to the filter.option * field followed by only some bitmasks. */ - msg.msg.hdr.cmd = CMD_IDADD; - msg.msg.hdr.len = 2 + ESD_MAX_ID_SEGMENT; - msg.msg.filter.net = priv->index; - msg.msg.filter.option = ESD_ID_ENABLE; /* start with segment 0 */ + msg->msg.hdr.cmd = CMD_IDADD; + msg->msg.hdr.len = 2 + ESD_MAX_ID_SEGMENT; + msg->msg.filter.net = priv->index; + msg->msg.filter.option = ESD_ID_ENABLE; /* start with segment 0 */ for (i = 0; i < ESD_MAX_ID_SEGMENT; i++) - msg.msg.filter.mask[i] = cpu_to_le32(0xffffffff); + msg->msg.filter.mask[i] = cpu_to_le32(0xffffffff); /* enable 29bit extended IDs */ - msg.msg.filter.mask[ESD_MAX_ID_SEGMENT] = cpu_to_le32(0x00000001); + msg->msg.filter.mask[ESD_MAX_ID_SEGMENT] = cpu_to_le32(0x00000001); - err = esd_usb2_send_msg(dev, &msg); + err = esd_usb2_send_msg(dev, msg); if (err) - goto failed; + goto out; err = esd_usb2_setup_rx_urbs(dev); if (err) - goto failed; + goto out; priv->can.state = CAN_STATE_ERROR_ACTIVE; - return 0; - -failed: +out: if (err == -ENODEV) netif_device_detach(netdev); + if (err) + netdev_err(netdev, "couldn't start device: %d\n", err); - netdev_err(netdev, "couldn't start device: %d\n", err); - + kfree(msg); return err; } @@ -833,26 +838,30 @@ nourbmem: static int esd_usb2_close(struct net_device *netdev) { struct esd_usb2_net_priv *priv = netdev_priv(netdev); - struct esd_usb2_msg msg; + struct esd_usb2_msg *msg; int i; + msg = kmalloc(sizeof(*msg), GFP_KERNEL); + if (!msg) + return -ENOMEM; + /* Disable all IDs (see esd_usb2_start()) */ - msg.msg.hdr.cmd = CMD_IDADD; - msg.msg.hdr.len = 2 + ESD_MAX_ID_SEGMENT; - msg.msg.filter.net = priv->index; - msg.msg.filter.option = ESD_ID_ENABLE; /* start with segment 0 */ + msg->msg.hdr.cmd = CMD_IDADD; + msg->msg.hdr.len = 2 + ESD_MAX_ID_SEGMENT; + msg->msg.filter.net = priv->index; + msg->msg.filter.option = ESD_ID_ENABLE; /* start with segment 0 */ for (i = 0; i <= ESD_MAX_ID_SEGMENT; i++) - msg.msg.filter.mask[i] = 0; - if (esd_usb2_send_msg(priv->usb2, &msg) < 0) + msg->msg.filter.mask[i] = 0; + if (esd_usb2_send_msg(priv->usb2, msg) < 0) netdev_err(netdev, "sending idadd message failed\n"); /* set CAN controller to reset mode */ - msg.msg.hdr.len = 2; - msg.msg.hdr.cmd = CMD_SETBAUD; - msg.msg.setbaud.net = priv->index; - msg.msg.setbaud.rsvd = 0; - msg.msg.setbaud.baud = cpu_to_le32(ESD_USB2_NO_BAUDRATE); - if (esd_usb2_send_msg(priv->usb2, &msg) < 0) + msg->msg.hdr.len = 2; + msg->msg.hdr.cmd = CMD_SETBAUD; + msg->msg.setbaud.net = priv->index; + msg->msg.setbaud.rsvd = 0; + msg->msg.setbaud.baud = cpu_to_le32(ESD_USB2_NO_BAUDRATE); + if (esd_usb2_send_msg(priv->usb2, msg) < 0) netdev_err(netdev, "sending setbaud message failed\n"); priv->can.state = CAN_STATE_STOPPED; @@ -861,6 +870,8 @@ static int esd_usb2_close(struct net_device *netdev) close_candev(netdev); + kfree(msg); + return 0; } @@ -886,7 +897,8 @@ static int esd_usb2_set_bittiming(struct net_device *netdev) { struct esd_usb2_net_priv *priv = netdev_priv(netdev); struct can_bittiming *bt = &priv->can.bittiming; - struct esd_usb2_msg msg; + struct esd_usb2_msg *msg; + int err; u32 canbtr; int sjw_shift; @@ -912,15 +924,22 @@ static int esd_usb2_set_bittiming(struct net_device *netdev) if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) canbtr |= ESD_USB2_3_SAMPLES; - msg.msg.hdr.len = 2; - msg.msg.hdr.cmd = CMD_SETBAUD; - msg.msg.setbaud.net = priv->index; - msg.msg.setbaud.rsvd = 0; - msg.msg.setbaud.baud = cpu_to_le32(canbtr); + msg = kmalloc(sizeof(*msg), GFP_KERNEL); + if (!msg) + return -ENOMEM; + + msg->msg.hdr.len = 2; + msg->msg.hdr.cmd = CMD_SETBAUD; + msg->msg.setbaud.net = priv->index; + msg->msg.setbaud.rsvd = 0; + msg->msg.setbaud.baud = cpu_to_le32(canbtr); netdev_info(netdev, "setting BTR=%#x\n", canbtr); - return esd_usb2_send_msg(priv->usb2, &msg); + err = esd_usb2_send_msg(priv->usb2, msg); + + kfree(msg); + return err; } static int esd_usb2_get_berr_counter(const struct net_device *netdev, @@ -1022,7 +1041,7 @@ static int esd_usb2_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct esd_usb2 *dev; - struct esd_usb2_msg msg; + struct esd_usb2_msg *msg; int i, err; dev = kzalloc(sizeof(*dev), GFP_KERNEL); @@ -1037,27 +1056,33 @@ static int esd_usb2_probe(struct usb_interface *intf, usb_set_intfdata(intf, dev); + msg = kmalloc(sizeof(*msg), GFP_KERNEL); + if (!msg) { + err = -ENOMEM; + goto free_msg; + } + /* query number of CAN interfaces (nets) */ - msg.msg.hdr.cmd = CMD_VERSION; - msg.msg.hdr.len = 2; - msg.msg.version.rsvd = 0; - msg.msg.version.flags = 0; - msg.msg.version.drv_version = 0; + msg->msg.hdr.cmd = CMD_VERSION; + msg->msg.hdr.len = 2; + msg->msg.version.rsvd = 0; + msg->msg.version.flags = 0; + msg->msg.version.drv_version = 0; - err = esd_usb2_send_msg(dev, &msg); + err = esd_usb2_send_msg(dev, msg); if (err < 0) { dev_err(&intf->dev, "sending version message failed\n"); - goto free_dev; + goto free_msg; } - err = esd_usb2_wait_msg(dev, &msg); + err = esd_usb2_wait_msg(dev, msg); if (err < 0) { dev_err(&intf->dev, "no version message answer\n"); - goto free_dev; + goto free_msg; } - dev->net_count = (int)msg.msg.version_reply.nets; - dev->version = le32_to_cpu(msg.msg.version_reply.version); + dev->net_count = (int)msg->msg.version_reply.nets; + dev->version = le32_to_cpu(msg->msg.version_reply.version); if (device_create_file(&intf->dev, &dev_attr_firmware)) dev_err(&intf->dev, @@ -1075,10 +1100,10 @@ static int esd_usb2_probe(struct usb_interface *intf, for (i = 0; i < dev->net_count; i++) esd_usb2_probe_one_net(intf, i); - return 0; - -free_dev: - kfree(dev); +free_msg: + kfree(msg); + if (err) + kfree(dev); done: return err; } diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c index 45cb9f3c1324..3b9546588240 100644 --- a/drivers/net/can/usb/kvaser_usb.c +++ b/drivers/net/can/usb/kvaser_usb.c @@ -136,6 +136,9 @@ #define KVASER_CTRL_MODE_SELFRECEPTION 3 #define KVASER_CTRL_MODE_OFF 4 +/* log message */ +#define KVASER_EXTENDED_FRAME BIT(31) + struct kvaser_msg_simple { u8 tid; u8 channel; @@ -817,8 +820,13 @@ static void kvaser_usb_rx_can_msg(const struct kvaser_usb *dev, priv = dev->nets[channel]; stats = &priv->netdev->stats; - if (msg->u.rx_can.flag & (MSG_FLAG_ERROR_FRAME | MSG_FLAG_NERR | - MSG_FLAG_OVERRUN)) { + if ((msg->u.rx_can.flag & MSG_FLAG_ERROR_FRAME) && + (msg->id == CMD_LOG_MESSAGE)) { + kvaser_usb_rx_error(dev, msg); + return; + } else if (msg->u.rx_can.flag & (MSG_FLAG_ERROR_FRAME | + MSG_FLAG_NERR | + MSG_FLAG_OVERRUN)) { kvaser_usb_rx_can_err(priv, msg); return; } else if (msg->u.rx_can.flag & ~MSG_FLAG_REMOTE_FRAME) { @@ -834,22 +842,40 @@ static void kvaser_usb_rx_can_msg(const struct kvaser_usb *dev, return; } - cf->can_id = ((msg->u.rx_can.msg[0] & 0x1f) << 6) | - (msg->u.rx_can.msg[1] & 0x3f); - cf->can_dlc = get_can_dlc(msg->u.rx_can.msg[5]); + if (msg->id == CMD_LOG_MESSAGE) { + cf->can_id = le32_to_cpu(msg->u.log_message.id); + if (cf->can_id & KVASER_EXTENDED_FRAME) + cf->can_id &= CAN_EFF_MASK | CAN_EFF_FLAG; + else + cf->can_id &= CAN_SFF_MASK; - if (msg->id == CMD_RX_EXT_MESSAGE) { - cf->can_id <<= 18; - cf->can_id |= ((msg->u.rx_can.msg[2] & 0x0f) << 14) | - ((msg->u.rx_can.msg[3] & 0xff) << 6) | - (msg->u.rx_can.msg[4] & 0x3f); - cf->can_id |= CAN_EFF_FLAG; - } + cf->can_dlc = get_can_dlc(msg->u.log_message.dlc); - if (msg->u.rx_can.flag & MSG_FLAG_REMOTE_FRAME) - cf->can_id |= CAN_RTR_FLAG; - else - memcpy(cf->data, &msg->u.rx_can.msg[6], cf->can_dlc); + if (msg->u.log_message.flags & MSG_FLAG_REMOTE_FRAME) + cf->can_id |= CAN_RTR_FLAG; + else + memcpy(cf->data, &msg->u.log_message.data, + cf->can_dlc); + } else { + cf->can_id = ((msg->u.rx_can.msg[0] & 0x1f) << 6) | + (msg->u.rx_can.msg[1] & 0x3f); + + if (msg->id == CMD_RX_EXT_MESSAGE) { + cf->can_id <<= 18; + cf->can_id |= ((msg->u.rx_can.msg[2] & 0x0f) << 14) | + ((msg->u.rx_can.msg[3] & 0xff) << 6) | + (msg->u.rx_can.msg[4] & 0x3f); + cf->can_id |= CAN_EFF_FLAG; + } + + cf->can_dlc = get_can_dlc(msg->u.rx_can.msg[5]); + + if (msg->u.rx_can.flag & MSG_FLAG_REMOTE_FRAME) + cf->can_id |= CAN_RTR_FLAG; + else + memcpy(cf->data, &msg->u.rx_can.msg[6], + cf->can_dlc); + } netif_rx(skb); @@ -911,6 +937,7 @@ static void kvaser_usb_handle_message(const struct kvaser_usb *dev, case CMD_RX_STD_MESSAGE: case CMD_RX_EXT_MESSAGE: + case CMD_LOG_MESSAGE: kvaser_usb_rx_can_msg(dev, msg); break; @@ -919,11 +946,6 @@ static void kvaser_usb_handle_message(const struct kvaser_usb *dev, kvaser_usb_rx_error(dev, msg); break; - case CMD_LOG_MESSAGE: - if (msg->u.log_message.flags & MSG_FLAG_ERROR_FRAME) - kvaser_usb_rx_error(dev, msg); - break; - case CMD_TX_ACKNOWLEDGE: kvaser_usb_tx_acknowledge(dev, msg); break; diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c index 30d79bfa5b10..8ee9d1556e6e 100644 --- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c +++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c @@ -504,15 +504,24 @@ static int pcan_usb_pro_restart_async(struct peak_usb_device *dev, return usb_submit_urb(urb, GFP_ATOMIC); } -static void pcan_usb_pro_drv_loaded(struct peak_usb_device *dev, int loaded) +static int pcan_usb_pro_drv_loaded(struct peak_usb_device *dev, int loaded) { - u8 buffer[16]; + u8 *buffer; + int err; + + buffer = kmalloc(PCAN_USBPRO_FCT_DRVLD_REQ_LEN, GFP_KERNEL); + if (!buffer) + return -ENOMEM; buffer[0] = 0; buffer[1] = !!loaded; - pcan_usb_pro_send_req(dev, PCAN_USBPRO_REQ_FCT, - PCAN_USBPRO_FCT_DRVLD, buffer, sizeof(buffer)); + err = pcan_usb_pro_send_req(dev, PCAN_USBPRO_REQ_FCT, + PCAN_USBPRO_FCT_DRVLD, buffer, + PCAN_USBPRO_FCT_DRVLD_REQ_LEN); + kfree(buffer); + + return err; } static inline @@ -851,21 +860,24 @@ static int pcan_usb_pro_stop(struct peak_usb_device *dev) */ static int pcan_usb_pro_init(struct peak_usb_device *dev) { - struct pcan_usb_pro_interface *usb_if; struct pcan_usb_pro_device *pdev = container_of(dev, struct pcan_usb_pro_device, dev); + struct pcan_usb_pro_interface *usb_if = NULL; + struct pcan_usb_pro_fwinfo *fi = NULL; + struct pcan_usb_pro_blinfo *bi = NULL; + int err; /* do this for 1st channel only */ if (!dev->prev_siblings) { - struct pcan_usb_pro_fwinfo fi; - struct pcan_usb_pro_blinfo bi; - int err; - /* allocate netdevices common structure attached to first one */ usb_if = kzalloc(sizeof(struct pcan_usb_pro_interface), GFP_KERNEL); - if (!usb_if) - return -ENOMEM; + fi = kmalloc(sizeof(struct pcan_usb_pro_fwinfo), GFP_KERNEL); + bi = kmalloc(sizeof(struct pcan_usb_pro_blinfo), GFP_KERNEL); + if (!usb_if || !fi || !bi) { + err = -ENOMEM; + goto err_out; + } /* number of ts msgs to ignore before taking one into account */ usb_if->cm_ignore_count = 5; @@ -877,34 +889,34 @@ static int pcan_usb_pro_init(struct peak_usb_device *dev) */ err = pcan_usb_pro_send_req(dev, PCAN_USBPRO_REQ_INFO, PCAN_USBPRO_INFO_FW, - &fi, sizeof(fi)); + fi, sizeof(*fi)); if (err) { - kfree(usb_if); dev_err(dev->netdev->dev.parent, "unable to read %s firmware info (err %d)\n", pcan_usb_pro.name, err); - return err; + goto err_out; } err = pcan_usb_pro_send_req(dev, PCAN_USBPRO_REQ_INFO, PCAN_USBPRO_INFO_BL, - &bi, sizeof(bi)); + bi, sizeof(*bi)); if (err) { - kfree(usb_if); dev_err(dev->netdev->dev.parent, "unable to read %s bootloader info (err %d)\n", pcan_usb_pro.name, err); - return err; + goto err_out; } + /* tell the device the can driver is running */ + err = pcan_usb_pro_drv_loaded(dev, 1); + if (err) + goto err_out; + dev_info(dev->netdev->dev.parent, "PEAK-System %s hwrev %u serial %08X.%08X (%u channels)\n", pcan_usb_pro.name, - bi.hw_rev, bi.serial_num_hi, bi.serial_num_lo, + bi->hw_rev, bi->serial_num_hi, bi->serial_num_lo, pcan_usb_pro.ctrl_count); - - /* tell the device the can driver is running */ - pcan_usb_pro_drv_loaded(dev, 1); } else { usb_if = pcan_usb_pro_dev_if(dev->prev_siblings); } @@ -916,6 +928,13 @@ static int pcan_usb_pro_init(struct peak_usb_device *dev) pcan_usb_pro_set_led(dev, 0, 1); return 0; + + err_out: + kfree(bi); + kfree(fi); + kfree(usb_if); + + return err; } static void pcan_usb_pro_exit(struct peak_usb_device *dev) diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.h b/drivers/net/can/usb/peak_usb/pcan_usb_pro.h index a869918c5620..32275af547e0 100644 --- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.h +++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.h @@ -29,6 +29,7 @@ /* Vendor Request value for XXX_FCT */ #define PCAN_USBPRO_FCT_DRVLD 5 /* tell device driver is loaded */ +#define PCAN_USBPRO_FCT_DRVLD_REQ_LEN 16 /* PCAN_USBPRO_INFO_BL vendor request record type */ struct __packed pcan_usb_pro_blinfo { diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index b8fbe266ab68..638e55435b04 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -3192,11 +3192,11 @@ static u32 bnx2x_xmit_type(struct bnx2x *bp, struct sk_buff *skb) rc |= XMIT_CSUM_TCP; if (skb_is_gso_v6(skb)) { - rc |= (XMIT_GSO_V6 | XMIT_CSUM_TCP | XMIT_CSUM_V6); + rc |= (XMIT_GSO_V6 | XMIT_CSUM_TCP); if (rc & XMIT_CSUM_ENC) rc |= XMIT_GSO_ENC_V6; } else if (skb_is_gso(skb)) { - rc |= (XMIT_GSO_V4 | XMIT_CSUM_V4 | XMIT_CSUM_TCP); + rc |= (XMIT_GSO_V4 | XMIT_CSUM_TCP); if (rc & XMIT_CSUM_ENC) rc |= XMIT_GSO_ENC_V4; } @@ -3313,6 +3313,7 @@ static void bnx2x_set_pbd_gso_e2(struct sk_buff *skb, u32 *parsing_data, */ static void bnx2x_set_pbd_gso(struct sk_buff *skb, struct eth_tx_parse_bd_e1x *pbd, + struct eth_tx_start_bd *tx_start_bd, u32 xmit_type) { pbd->lso_mss = cpu_to_le16(skb_shinfo(skb)->gso_size); @@ -3326,11 +3327,14 @@ static void bnx2x_set_pbd_gso(struct sk_buff *skb, ip_hdr(skb)->daddr, 0, IPPROTO_TCP, 0)); - } else + /* GSO on 57710/57711 needs FW to calculate IP checksum */ + tx_start_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_IP_CSUM; + } else { pbd->tcp_pseudo_csum = bswab16(~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, 0, IPPROTO_TCP, 0)); + } pbd->global_data |= cpu_to_le16(ETH_TX_PARSE_BD_E1X_PSEUDO_CS_WITHOUT_LEN); @@ -3479,19 +3483,18 @@ static void bnx2x_update_pbds_gso_enc(struct sk_buff *skb, { u16 hlen_w = 0; u8 outerip_off, outerip_len = 0; + /* from outer IP to transport */ hlen_w = (skb_inner_transport_header(skb) - skb_network_header(skb)) >> 1; /* transport len */ - if (xmit_type & XMIT_CSUM_TCP) - hlen_w += inner_tcp_hdrlen(skb) >> 1; - else - hlen_w += sizeof(struct udphdr) >> 1; + hlen_w += inner_tcp_hdrlen(skb) >> 1; pbd2->fw_ip_hdr_to_payload_w = hlen_w; - if (xmit_type & XMIT_CSUM_ENC_V4) { + /* outer IP header info */ + if (xmit_type & XMIT_CSUM_V4) { struct iphdr *iph = ip_hdr(skb); pbd2->fw_ip_csum_wo_len_flags_frag = bswab16(csum_fold((~iph->check) - @@ -3814,7 +3817,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) bnx2x_set_pbd_gso_e2(skb, &pbd_e2_parsing_data, xmit_type); else - bnx2x_set_pbd_gso(skb, pbd_e1x, xmit_type); + bnx2x_set_pbd_gso(skb, pbd_e1x, first_bd, xmit_type); } /* Set the PBD's parsing_data field if not zero diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 728d42ab2a76..c777b9013164 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -94,10 +94,10 @@ static inline void _tg3_flag_clear(enum TG3_FLAGS flag, unsigned long *bits) #define DRV_MODULE_NAME "tg3" #define TG3_MAJ_NUM 3 -#define TG3_MIN_NUM 131 +#define TG3_MIN_NUM 132 #define DRV_MODULE_VERSION \ __stringify(TG3_MAJ_NUM) "." __stringify(TG3_MIN_NUM) -#define DRV_MODULE_RELDATE "April 09, 2013" +#define DRV_MODULE_RELDATE "May 21, 2013" #define RESET_KIND_SHUTDOWN 0 #define RESET_KIND_INIT 1 @@ -1800,6 +1800,9 @@ static int tg3_poll_fw(struct tg3 *tp) int i; u32 val; + if (tg3_flag(tp, NO_FWARE_REPORTED)) + return 0; + if (tg3_flag(tp, IS_SSB_CORE)) { /* We don't use firmware. */ return 0; @@ -2957,6 +2960,31 @@ static int tg3_5700_link_polarity(struct tg3 *tp, u32 speed) return 0; } +static bool tg3_phy_power_bug(struct tg3 *tp) +{ + switch (tg3_asic_rev(tp)) { + case ASIC_REV_5700: + case ASIC_REV_5704: + return true; + case ASIC_REV_5780: + if (tp->phy_flags & TG3_PHYFLG_MII_SERDES) + return true; + return false; + case ASIC_REV_5717: + if (!tp->pci_fn) + return true; + return false; + case ASIC_REV_5719: + case ASIC_REV_5720: + if ((tp->phy_flags & TG3_PHYFLG_PHY_SERDES) && + !tp->pci_fn) + return true; + return false; + } + + return false; +} + static void tg3_power_down_phy(struct tg3 *tp, bool do_low_power) { u32 val; @@ -3016,12 +3044,7 @@ static void tg3_power_down_phy(struct tg3 *tp, bool do_low_power) /* The PHY should not be powered down on some chips because * of bugs. */ - if (tg3_asic_rev(tp) == ASIC_REV_5700 || - tg3_asic_rev(tp) == ASIC_REV_5704 || - (tg3_asic_rev(tp) == ASIC_REV_5780 && - (tp->phy_flags & TG3_PHYFLG_MII_SERDES)) || - (tg3_asic_rev(tp) == ASIC_REV_5717 && - !tp->pci_fn)) + if (tg3_phy_power_bug(tp)) return; if (tg3_chip_rev(tp) == CHIPREV_5784_AX || @@ -7428,6 +7451,20 @@ static inline int tg3_4g_overflow_test(dma_addr_t mapping, int len) return (base > 0xffffdcc0) && (base + len + 8 < base); } +/* Test for TSO DMA buffers that cross into regions which are within MSS bytes + * of any 4GB boundaries: 4G, 8G, etc + */ +static inline int tg3_4g_tso_overflow_test(struct tg3 *tp, dma_addr_t mapping, + u32 len, u32 mss) +{ + if (tg3_asic_rev(tp) == ASIC_REV_5762 && mss) { + u32 base = (u32) mapping & 0xffffffff; + + return ((base + len + (mss & 0x3fff)) < base); + } + return 0; +} + /* Test for DMA addresses > 40-bit */ static inline int tg3_40bit_overflow_test(struct tg3 *tp, dma_addr_t mapping, int len) @@ -7464,6 +7501,9 @@ static bool tg3_tx_frag_set(struct tg3_napi *tnapi, u32 *entry, u32 *budget, if (tg3_4g_overflow_test(map, len)) hwbug = true; + if (tg3_4g_tso_overflow_test(tp, map, len, mss)) + hwbug = true; + if (tg3_40bit_overflow_test(tp, map, len)) hwbug = true; @@ -8874,6 +8914,10 @@ static int tg3_chip_reset(struct tg3 *tp) tg3_halt_cpu(tp, RX_CPU_BASE); } + err = tg3_poll_fw(tp); + if (err) + return err; + tw32(GRC_MODE, tp->grc_mode); if (tg3_chip_rev_id(tp) == CHIPREV_ID_5705_A0) { @@ -8904,10 +8948,6 @@ static int tg3_chip_reset(struct tg3 *tp) tg3_ape_unlock(tp, TG3_APE_LOCK_GRC); - err = tg3_poll_fw(tp); - if (err) - return err; - tg3_mdio_start(tp); if (tg3_flag(tp, PCI_EXPRESS) && @@ -9431,6 +9471,14 @@ static void tg3_rss_write_indir_tbl(struct tg3 *tp) } } +static inline u32 tg3_lso_rd_dma_workaround_bit(struct tg3 *tp) +{ + if (tg3_asic_rev(tp) == ASIC_REV_5719) + return TG3_LSO_RD_DMA_TX_LENGTH_WA_5719; + else + return TG3_LSO_RD_DMA_TX_LENGTH_WA_5720; +} + /* tp->lock is held. */ static int tg3_reset_hw(struct tg3 *tp, bool reset_phy) { @@ -10116,16 +10164,17 @@ static int tg3_reset_hw(struct tg3 *tp, bool reset_phy) tw32_f(RDMAC_MODE, rdmac_mode); udelay(40); - if (tg3_asic_rev(tp) == ASIC_REV_5719) { + if (tg3_asic_rev(tp) == ASIC_REV_5719 || + tg3_asic_rev(tp) == ASIC_REV_5720) { for (i = 0; i < TG3_NUM_RDMA_CHANNELS; i++) { if (tr32(TG3_RDMA_LENGTH + (i << 2)) > TG3_MAX_MTU(tp)) break; } if (i < TG3_NUM_RDMA_CHANNELS) { val = tr32(TG3_LSO_RD_DMA_CRPTEN_CTRL); - val |= TG3_LSO_RD_DMA_TX_LENGTH_WA; + val |= tg3_lso_rd_dma_workaround_bit(tp); tw32(TG3_LSO_RD_DMA_CRPTEN_CTRL, val); - tg3_flag_set(tp, 5719_RDMA_BUG); + tg3_flag_set(tp, 5719_5720_RDMA_BUG); } } @@ -10358,6 +10407,13 @@ static int tg3_reset_hw(struct tg3 *tp, bool reset_phy) */ static int tg3_init_hw(struct tg3 *tp, bool reset_phy) { + /* Chip may have been just powered on. If so, the boot code may still + * be running initialization. Wait for it to finish to avoid races in + * accessing the hardware. + */ + tg3_enable_register_access(tp); + tg3_poll_fw(tp); + tg3_switch_clocks(tp); tw32(TG3PCI_MEM_WIN_BASE_ADDR, 0); @@ -10489,15 +10545,15 @@ static void tg3_periodic_fetch_stats(struct tg3 *tp) TG3_STAT_ADD32(&sp->tx_ucast_packets, MAC_TX_STATS_UCAST); TG3_STAT_ADD32(&sp->tx_mcast_packets, MAC_TX_STATS_MCAST); TG3_STAT_ADD32(&sp->tx_bcast_packets, MAC_TX_STATS_BCAST); - if (unlikely(tg3_flag(tp, 5719_RDMA_BUG) && + if (unlikely(tg3_flag(tp, 5719_5720_RDMA_BUG) && (sp->tx_ucast_packets.low + sp->tx_mcast_packets.low + sp->tx_bcast_packets.low) > TG3_NUM_RDMA_CHANNELS)) { u32 val; val = tr32(TG3_LSO_RD_DMA_CRPTEN_CTRL); - val &= ~TG3_LSO_RD_DMA_TX_LENGTH_WA; + val &= ~tg3_lso_rd_dma_workaround_bit(tp); tw32(TG3_LSO_RD_DMA_CRPTEN_CTRL, val); - tg3_flag_clear(tp, 5719_RDMA_BUG); + tg3_flag_clear(tp, 5719_5720_RDMA_BUG); } TG3_STAT_ADD32(&sp->rx_octets, MAC_RX_STATS_OCTETS); diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h index 9b2d3ac2474a..ff6e30eeae35 100644 --- a/drivers/net/ethernet/broadcom/tg3.h +++ b/drivers/net/ethernet/broadcom/tg3.h @@ -1422,7 +1422,8 @@ #define TG3_LSO_RD_DMA_CRPTEN_CTRL 0x00004910 #define TG3_LSO_RD_DMA_CRPTEN_CTRL_BLEN_BD_4K 0x00030000 #define TG3_LSO_RD_DMA_CRPTEN_CTRL_BLEN_LSO_4K 0x000c0000 -#define TG3_LSO_RD_DMA_TX_LENGTH_WA 0x02000000 +#define TG3_LSO_RD_DMA_TX_LENGTH_WA_5719 0x02000000 +#define TG3_LSO_RD_DMA_TX_LENGTH_WA_5720 0x00200000 /* 0x4914 --> 0x4be0 unused */ #define TG3_NUM_RDMA_CHANNELS 4 @@ -3059,7 +3060,7 @@ enum TG3_FLAGS { TG3_FLAG_APE_HAS_NCSI, TG3_FLAG_TX_TSTAMP_EN, TG3_FLAG_4K_FIFO_LIMIT, - TG3_FLAG_5719_RDMA_BUG, + TG3_FLAG_5719_5720_RDMA_BUG, TG3_FLAG_RESET_TASK_PENDING, TG3_FLAG_PTP_CAPABLE, TG3_FLAG_5705_PLUS, diff --git a/drivers/net/ethernet/brocade/bna/bnad_debugfs.c b/drivers/net/ethernet/brocade/bna/bnad_debugfs.c index 6e8bc9d88c41..94d957d203a6 100644 --- a/drivers/net/ethernet/brocade/bna/bnad_debugfs.c +++ b/drivers/net/ethernet/brocade/bna/bnad_debugfs.c @@ -244,7 +244,7 @@ bnad_debugfs_lseek(struct file *file, loff_t offset, int orig) file->f_pos += offset; break; case 2: - file->f_pos = debug->buffer_len - offset; + file->f_pos = debug->buffer_len + offset; break; default: return -EINVAL; diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c index 6be513deb17f..c89aa41dd448 100644 --- a/drivers/net/ethernet/cadence/macb.c +++ b/drivers/net/ethernet/cadence/macb.c @@ -485,7 +485,8 @@ static void macb_tx_interrupt(struct macb *bp) status = macb_readl(bp, TSR); macb_writel(bp, TSR, status); - macb_writel(bp, ISR, MACB_BIT(TCOMP)); + if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) + macb_writel(bp, ISR, MACB_BIT(TCOMP)); netdev_vdbg(bp->dev, "macb_tx_interrupt status = 0x%03lx\n", (unsigned long)status); @@ -738,7 +739,8 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id) * now. */ macb_writel(bp, IDR, MACB_RX_INT_FLAGS); - macb_writel(bp, ISR, MACB_BIT(RCOMP)); + if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) + macb_writel(bp, ISR, MACB_BIT(RCOMP)); if (napi_schedule_prep(&bp->napi)) { netdev_vdbg(bp->dev, "scheduling RX softirq\n"); @@ -1062,6 +1064,17 @@ static void macb_configure_dma(struct macb *bp) } } +/* + * Configure peripheral capacities according to integration options used + */ +static void macb_configure_caps(struct macb *bp) +{ + if (macb_is_gem(bp)) { + if (GEM_BF(IRQCOR, gem_readl(bp, DCFG1)) == 0) + bp->caps |= MACB_CAPS_ISR_CLEAR_ON_WRITE; + } +} + static void macb_init_hw(struct macb *bp) { u32 config; @@ -1084,6 +1097,7 @@ static void macb_init_hw(struct macb *bp) bp->duplex = DUPLEX_HALF; macb_configure_dma(bp); + macb_configure_caps(bp); /* Initialize TX and RX buffers */ macb_writel(bp, RBQP, bp->rx_ring_dma); diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h index 993d70380688..548c0ecae869 100644 --- a/drivers/net/ethernet/cadence/macb.h +++ b/drivers/net/ethernet/cadence/macb.h @@ -300,6 +300,8 @@ #define MACB_REV_SIZE 16 /* Bitfields in DCFG1. */ +#define GEM_IRQCOR_OFFSET 23 +#define GEM_IRQCOR_SIZE 1 #define GEM_DBWDEF_OFFSET 25 #define GEM_DBWDEF_SIZE 3 @@ -323,6 +325,9 @@ #define MACB_MAN_READ 2 #define MACB_MAN_CODE 2 +/* Capability mask bits */ +#define MACB_CAPS_ISR_CLEAR_ON_WRITE 0x1 + /* Bit manipulation macros */ #define MACB_BIT(name) \ (1 << MACB_##name##_OFFSET) @@ -574,6 +579,8 @@ struct macb { unsigned int speed; unsigned int duplex; + u32 caps; + phy_interface_t phy_interface; /* AT91RM9200 transmit */ diff --git a/drivers/net/ethernet/dec/tulip/interrupt.c b/drivers/net/ethernet/dec/tulip/interrupt.c index 28a5e425fecf..92306b320840 100644 --- a/drivers/net/ethernet/dec/tulip/interrupt.c +++ b/drivers/net/ethernet/dec/tulip/interrupt.c @@ -76,6 +76,12 @@ int tulip_refill_rx(struct net_device *dev) mapping = pci_map_single(tp->pdev, skb->data, PKT_BUF_SZ, PCI_DMA_FROMDEVICE); + if (dma_mapping_error(&tp->pdev->dev, mapping)) { + dev_kfree_skb(skb); + tp->rx_buffers[entry].skb = NULL; + break; + } + tp->rx_buffers[entry].mapping = mapping; tp->rx_ring[entry].buffer1 = cpu_to_le32(mapping); diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h index f544b297c9ab..0a510684e468 100644 --- a/drivers/net/ethernet/emulex/benet/be.h +++ b/drivers/net/ethernet/emulex/benet/be.h @@ -262,6 +262,7 @@ struct be_rx_compl_info { u8 ipv6; u8 vtm; u8 pkt_type; + u8 ip_frag; }; struct be_rx_obj { diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index fd7b547698ab..1db2df61b8af 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c @@ -562,7 +562,7 @@ int lancer_test_and_set_rdy_state(struct be_adapter *adapter) resource_error = lancer_provisioning_error(adapter); if (resource_error) - return -1; + return -EAGAIN; status = lancer_wait_ready(adapter); if (!status) { @@ -590,8 +590,8 @@ int lancer_test_and_set_rdy_state(struct be_adapter *adapter) * when PF provisions resources. */ resource_error = lancer_provisioning_error(adapter); - if (status == -1 && !resource_error) - adapter->eeh_error = true; + if (resource_error) + status = -EAGAIN; return status; } @@ -2976,22 +2976,17 @@ static struct be_nic_resource_desc *be_get_nic_desc(u8 *buf, u32 desc_count, for (i = 0; i < desc_count; i++) { desc->desc_len = desc->desc_len ? : RESOURCE_DESC_SIZE; if (((void *)desc + desc->desc_len) > - (void *)(buf + max_buf_size)) { - desc = NULL; - break; - } + (void *)(buf + max_buf_size)) + return NULL; if (desc->desc_type == NIC_RESOURCE_DESC_TYPE_V0 || desc->desc_type == NIC_RESOURCE_DESC_TYPE_V1) - break; + return desc; desc = (void *)desc + desc->desc_len; } - if (!desc || i == MAX_RESOURCE_DESC) - return NULL; - - return desc; + return NULL; } /* Uses Mbox */ diff --git a/drivers/net/ethernet/emulex/benet/be_hw.h b/drivers/net/ethernet/emulex/benet/be_hw.h index 3c1099b47f2a..8780183c6d1c 100644 --- a/drivers/net/ethernet/emulex/benet/be_hw.h +++ b/drivers/net/ethernet/emulex/benet/be_hw.h @@ -356,7 +356,7 @@ struct amap_eth_rx_compl_v0 { u8 ip_version; /* dword 1 */ u8 macdst[6]; /* dword 1 */ u8 vtp; /* dword 1 */ - u8 rsvd0; /* dword 1 */ + u8 ip_frag; /* dword 1 */ u8 fragndx[10]; /* dword 1 */ u8 ct[2]; /* dword 1 */ u8 sw; /* dword 1 */ diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index a444110b060f..a0b4be51f0d1 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -780,26 +780,18 @@ static struct sk_buff *be_insert_vlan_in_pkt(struct be_adapter *adapter, if (unlikely(!skb)) return skb; - if (vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) vlan_tag = be_get_tx_vlan_tag(adapter, skb); - skb = __vlan_put_tag(skb, htons(ETH_P_8021Q), vlan_tag); - if (skb) - skb->vlan_tci = 0; - } - - if (qnq_async_evt_rcvd(adapter) && adapter->pvid) { - if (!vlan_tag) - vlan_tag = adapter->pvid; - if (skip_hw_vlan) - *skip_hw_vlan = true; - } + else if (qnq_async_evt_rcvd(adapter) && adapter->pvid) + vlan_tag = adapter->pvid; if (vlan_tag) { skb = __vlan_put_tag(skb, htons(ETH_P_8021Q), vlan_tag); if (unlikely(!skb)) return skb; - skb->vlan_tci = 0; + if (skip_hw_vlan) + *skip_hw_vlan = true; } /* Insert the outer VLAN, if any */ @@ -1607,6 +1599,8 @@ static void be_parse_rx_compl_v0(struct be_eth_rx_compl *compl, compl); } rxcp->port = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, port, compl); + rxcp->ip_frag = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, + ip_frag, compl); } static struct be_rx_compl_info *be_rx_compl_get(struct be_rx_obj *rxo) @@ -1628,6 +1622,9 @@ static struct be_rx_compl_info *be_rx_compl_get(struct be_rx_obj *rxo) else be_parse_rx_compl_v0(compl, rxcp); + if (rxcp->ip_frag) + rxcp->l4_csum = 0; + if (rxcp->vlanf) { /* vlanf could be wrongly set in some cards. * ignore if vtm is not set */ @@ -2176,7 +2173,7 @@ static irqreturn_t be_msix(int irq, void *dev) static inline bool do_gro(struct be_rx_compl_info *rxcp) { - return (rxcp->tcpf && !rxcp->err) ? true : false; + return (rxcp->tcpf && !rxcp->err && rxcp->l4_csum) ? true : false; } static int be_process_rx(struct be_rx_obj *rxo, struct napi_struct *napi, @@ -4101,6 +4098,7 @@ static int be_get_initial_config(struct be_adapter *adapter) static int lancer_recover_func(struct be_adapter *adapter) { + struct device *dev = &adapter->pdev->dev; int status; status = lancer_test_and_set_rdy_state(adapter); @@ -4112,8 +4110,7 @@ static int lancer_recover_func(struct be_adapter *adapter) be_clear(adapter); - adapter->hw_error = false; - adapter->fw_timeout = false; + be_clear_all_error(adapter); status = be_setup(adapter); if (status) @@ -4125,13 +4122,13 @@ static int lancer_recover_func(struct be_adapter *adapter) goto err; } - dev_err(&adapter->pdev->dev, - "Adapter SLIPORT recovery succeeded\n"); + dev_err(dev, "Error recovery successful\n"); return 0; err: - if (adapter->eeh_error) - dev_err(&adapter->pdev->dev, - "Adapter SLIPORT recovery failed\n"); + if (status == -EAGAIN) + dev_err(dev, "Waiting for resource provisioning\n"); + else + dev_err(dev, "Error recovery failed\n"); return status; } @@ -4140,28 +4137,27 @@ static void be_func_recovery_task(struct work_struct *work) { struct be_adapter *adapter = container_of(work, struct be_adapter, func_recovery_work.work); - int status; + int status = 0; be_detect_error(adapter); if (adapter->hw_error && lancer_chip(adapter)) { - if (adapter->eeh_error) - goto out; - rtnl_lock(); netif_device_detach(adapter->netdev); rtnl_unlock(); status = lancer_recover_func(adapter); - if (!status) netif_device_attach(adapter->netdev); } -out: - schedule_delayed_work(&adapter->func_recovery_work, - msecs_to_jiffies(1000)); + /* In Lancer, for all errors other than provisioning error (-EAGAIN), + * no need to attempt further recovery. + */ + if (!status || status == -EAGAIN) + schedule_delayed_work(&adapter->func_recovery_work, + msecs_to_jiffies(1000)); } static void be_worker(struct work_struct *work) @@ -4266,6 +4262,9 @@ static int be_probe(struct pci_dev *pdev, const struct pci_device_id *pdev_id) netdev->features |= NETIF_F_HIGHDMA; } else { status = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); + if (!status) + status = dma_set_coherent_mask(&pdev->dev, + DMA_BIT_MASK(32)); if (status) { dev_err(&pdev->dev, "Could not set PCI DMA Mask\n"); goto free_netdev; @@ -4444,20 +4443,19 @@ static pci_ers_result_t be_eeh_err_detected(struct pci_dev *pdev, dev_err(&adapter->pdev->dev, "EEH error detected\n"); - adapter->eeh_error = true; + if (!adapter->eeh_error) { + adapter->eeh_error = true; - cancel_delayed_work_sync(&adapter->func_recovery_work); + cancel_delayed_work_sync(&adapter->func_recovery_work); - rtnl_lock(); - netif_device_detach(netdev); - rtnl_unlock(); - - if (netif_running(netdev)) { rtnl_lock(); - be_close(netdev); + netif_device_detach(netdev); + if (netif_running(netdev)) + be_close(netdev); rtnl_unlock(); + + be_clear(adapter); } - be_clear(adapter); if (state == pci_channel_io_perm_failure) return PCI_ERS_RESULT_DISCONNECT; @@ -4482,7 +4480,6 @@ static pci_ers_result_t be_eeh_reset(struct pci_dev *pdev) int status; dev_info(&adapter->pdev->dev, "EEH reset\n"); - be_clear_all_error(adapter); status = pci_enable_device(pdev); if (status) @@ -4500,6 +4497,7 @@ static pci_ers_result_t be_eeh_reset(struct pci_dev *pdev) return PCI_ERS_RESULT_DISCONNECT; pci_cleanup_aer_uncorrect_error_status(pdev); + be_clear_all_error(adapter); return PCI_ERS_RESULT_RECOVERED; } diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index ca9825ca88c9..a667015be22a 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -109,7 +109,7 @@ static struct platform_device_id fec_devtype[] = { .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT | FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM, }, { - .name = "mvf-fec", + .name = "mvf600-fec", .driver_data = FEC_QUIRK_ENET_MAC, }, { /* sentinel */ @@ -122,7 +122,7 @@ enum imx_fec_type { IMX27_FEC, /* runs on i.mx27/35/51 */ IMX28_FEC, IMX6Q_FEC, - MVF_FEC, + MVF600_FEC, }; static const struct of_device_id fec_dt_ids[] = { @@ -130,7 +130,7 @@ static const struct of_device_id fec_dt_ids[] = { { .compatible = "fsl,imx27-fec", .data = &fec_devtype[IMX27_FEC], }, { .compatible = "fsl,imx28-fec", .data = &fec_devtype[IMX28_FEC], }, { .compatible = "fsl,imx6q-fec", .data = &fec_devtype[IMX6Q_FEC], }, - { .compatible = "fsl,mvf-fec", .data = &fec_devtype[MVF_FEC], }, + { .compatible = "fsl,mvf600-fec", .data = &fec_devtype[MVF600_FEC], }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, fec_dt_ids); @@ -451,7 +451,7 @@ fec_restart(struct net_device *ndev, int duplex) netif_device_detach(ndev); napi_disable(&fep->napi); netif_stop_queue(ndev); - netif_tx_lock(ndev); + netif_tx_lock_bh(ndev); } /* Whack a reset. We should wait for this. */ @@ -616,10 +616,10 @@ fec_restart(struct net_device *ndev, int duplex) writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK); if (netif_running(ndev)) { - netif_device_attach(ndev); - napi_enable(&fep->napi); + netif_tx_unlock_bh(ndev); netif_wake_queue(ndev); - netif_tx_unlock(ndev); + napi_enable(&fep->napi); + netif_device_attach(ndev); } } @@ -1038,6 +1038,18 @@ static void fec_get_mac(struct net_device *ndev) iap = &tmpaddr[0]; } + /* + * 5) random mac address + */ + if (!is_valid_ether_addr(iap)) { + /* Report it and use a random ethernet address instead */ + netdev_err(ndev, "Invalid MAC address: %pM\n", iap); + eth_hw_addr_random(ndev); + netdev_info(ndev, "Using random MAC address: %pM\n", + ndev->dev_addr); + return; + } + memcpy(ndev->dev_addr, iap, ETH_ALEN); /* Adjust MAC if using macaddr */ diff --git a/drivers/net/ethernet/freescale/gianfar_ptp.c b/drivers/net/ethernet/freescale/gianfar_ptp.c index 576e4b858fce..083ea2b4d20a 100644 --- a/drivers/net/ethernet/freescale/gianfar_ptp.c +++ b/drivers/net/ethernet/freescale/gianfar_ptp.c @@ -524,6 +524,7 @@ static int gianfar_ptp_probe(struct platform_device *dev) return 0; no_clock: + iounmap(etsects->regs); no_ioremap: release_resource(etsects->rsrc); no_resource: diff --git a/drivers/net/ethernet/icplus/ipg.h b/drivers/net/ethernet/icplus/ipg.h index 6ce027355fcf..abb300a31912 100644 --- a/drivers/net/ethernet/icplus/ipg.h +++ b/drivers/net/ethernet/icplus/ipg.h @@ -195,57 +195,57 @@ enum ipg_regs { /* TFD data structure masks. */ /* TFDList, TFC */ -#define IPG_TFC_RSVD_MASK 0x0000FFFF9FFFFFFF -#define IPG_TFC_FRAMEID 0x000000000000FFFF -#define IPG_TFC_WORDALIGN 0x0000000000030000 -#define IPG_TFC_WORDALIGNTODWORD 0x0000000000000000 -#define IPG_TFC_WORDALIGNTOWORD 0x0000000000020000 -#define IPG_TFC_WORDALIGNDISABLED 0x0000000000030000 -#define IPG_TFC_TCPCHECKSUMENABLE 0x0000000000040000 -#define IPG_TFC_UDPCHECKSUMENABLE 0x0000000000080000 -#define IPG_TFC_IPCHECKSUMENABLE 0x0000000000100000 -#define IPG_TFC_FCSAPPENDDISABLE 0x0000000000200000 -#define IPG_TFC_TXINDICATE 0x0000000000400000 -#define IPG_TFC_TXDMAINDICATE 0x0000000000800000 -#define IPG_TFC_FRAGCOUNT 0x000000000F000000 -#define IPG_TFC_VLANTAGINSERT 0x0000000010000000 -#define IPG_TFC_TFDDONE 0x0000000080000000 -#define IPG_TFC_VID 0x00000FFF00000000 -#define IPG_TFC_CFI 0x0000100000000000 -#define IPG_TFC_USERPRIORITY 0x0000E00000000000 +#define IPG_TFC_RSVD_MASK 0x0000FFFF9FFFFFFFULL +#define IPG_TFC_FRAMEID 0x000000000000FFFFULL +#define IPG_TFC_WORDALIGN 0x0000000000030000ULL +#define IPG_TFC_WORDALIGNTODWORD 0x0000000000000000ULL +#define IPG_TFC_WORDALIGNTOWORD 0x0000000000020000ULL +#define IPG_TFC_WORDALIGNDISABLED 0x0000000000030000ULL +#define IPG_TFC_TCPCHECKSUMENABLE 0x0000000000040000ULL +#define IPG_TFC_UDPCHECKSUMENABLE 0x0000000000080000ULL +#define IPG_TFC_IPCHECKSUMENABLE 0x0000000000100000ULL +#define IPG_TFC_FCSAPPENDDISABLE 0x0000000000200000ULL +#define IPG_TFC_TXINDICATE 0x0000000000400000ULL +#define IPG_TFC_TXDMAINDICATE 0x0000000000800000ULL +#define IPG_TFC_FRAGCOUNT 0x000000000F000000ULL +#define IPG_TFC_VLANTAGINSERT 0x0000000010000000ULL +#define IPG_TFC_TFDDONE 0x0000000080000000ULL +#define IPG_TFC_VID 0x00000FFF00000000ULL +#define IPG_TFC_CFI 0x0000100000000000ULL +#define IPG_TFC_USERPRIORITY 0x0000E00000000000ULL /* TFDList, FragInfo */ -#define IPG_TFI_RSVD_MASK 0xFFFF00FFFFFFFFFF -#define IPG_TFI_FRAGADDR 0x000000FFFFFFFFFF -#define IPG_TFI_FRAGLEN 0xFFFF000000000000LL +#define IPG_TFI_RSVD_MASK 0xFFFF00FFFFFFFFFFULL +#define IPG_TFI_FRAGADDR 0x000000FFFFFFFFFFULL +#define IPG_TFI_FRAGLEN 0xFFFF000000000000ULL /* RFD data structure masks. */ /* RFDList, RFS */ -#define IPG_RFS_RSVD_MASK 0x0000FFFFFFFFFFFF -#define IPG_RFS_RXFRAMELEN 0x000000000000FFFF -#define IPG_RFS_RXFIFOOVERRUN 0x0000000000010000 -#define IPG_RFS_RXRUNTFRAME 0x0000000000020000 -#define IPG_RFS_RXALIGNMENTERROR 0x0000000000040000 -#define IPG_RFS_RXFCSERROR 0x0000000000080000 -#define IPG_RFS_RXOVERSIZEDFRAME 0x0000000000100000 -#define IPG_RFS_RXLENGTHERROR 0x0000000000200000 -#define IPG_RFS_VLANDETECTED 0x0000000000400000 -#define IPG_RFS_TCPDETECTED 0x0000000000800000 -#define IPG_RFS_TCPERROR 0x0000000001000000 -#define IPG_RFS_UDPDETECTED 0x0000000002000000 -#define IPG_RFS_UDPERROR 0x0000000004000000 -#define IPG_RFS_IPDETECTED 0x0000000008000000 -#define IPG_RFS_IPERROR 0x0000000010000000 -#define IPG_RFS_FRAMESTART 0x0000000020000000 -#define IPG_RFS_FRAMEEND 0x0000000040000000 -#define IPG_RFS_RFDDONE 0x0000000080000000 -#define IPG_RFS_TCI 0x0000FFFF00000000 +#define IPG_RFS_RSVD_MASK 0x0000FFFFFFFFFFFFULL +#define IPG_RFS_RXFRAMELEN 0x000000000000FFFFULL +#define IPG_RFS_RXFIFOOVERRUN 0x0000000000010000ULL +#define IPG_RFS_RXRUNTFRAME 0x0000000000020000ULL +#define IPG_RFS_RXALIGNMENTERROR 0x0000000000040000ULL +#define IPG_RFS_RXFCSERROR 0x0000000000080000ULL +#define IPG_RFS_RXOVERSIZEDFRAME 0x0000000000100000ULL +#define IPG_RFS_RXLENGTHERROR 0x0000000000200000ULL +#define IPG_RFS_VLANDETECTED 0x0000000000400000ULL +#define IPG_RFS_TCPDETECTED 0x0000000000800000ULL +#define IPG_RFS_TCPERROR 0x0000000001000000ULL +#define IPG_RFS_UDPDETECTED 0x0000000002000000ULL +#define IPG_RFS_UDPERROR 0x0000000004000000ULL +#define IPG_RFS_IPDETECTED 0x0000000008000000ULL +#define IPG_RFS_IPERROR 0x0000000010000000ULL +#define IPG_RFS_FRAMESTART 0x0000000020000000ULL +#define IPG_RFS_FRAMEEND 0x0000000040000000ULL +#define IPG_RFS_RFDDONE 0x0000000080000000ULL +#define IPG_RFS_TCI 0x0000FFFF00000000ULL /* RFDList, FragInfo */ -#define IPG_RFI_RSVD_MASK 0xFFFF00FFFFFFFFFF -#define IPG_RFI_FRAGADDR 0x000000FFFFFFFFFF -#define IPG_RFI_FRAGLEN 0xFFFF000000000000LL +#define IPG_RFI_RSVD_MASK 0xFFFF00FFFFFFFFFFULL +#define IPG_RFI_FRAGADDR 0x000000FFFFFFFFFFULL +#define IPG_RFI_FRAGLEN 0xFFFF000000000000ULL /* I/O Register masks. */ diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c index d0afeea181fb..2ad1494efbb3 100644 --- a/drivers/net/ethernet/marvell/mv643xx_eth.c +++ b/drivers/net/ethernet/marvell/mv643xx_eth.c @@ -867,7 +867,7 @@ static int txq_reclaim(struct tx_queue *txq, int budget, int force) struct netdev_queue *nq = netdev_get_tx_queue(mp->dev, txq->index); int reclaimed; - __netif_tx_lock(nq, smp_processor_id()); + __netif_tx_lock_bh(nq); reclaimed = 0; while (reclaimed < budget && txq->tx_desc_count > 0) { @@ -913,7 +913,7 @@ static int txq_reclaim(struct tx_queue *txq, int budget, int force) dev_kfree_skb(skb); } - __netif_tx_unlock(nq); + __netif_tx_unlock_bh(nq); if (reclaimed < budget) mp->work_tx &= ~(1 << txq->index); @@ -2745,7 +2745,7 @@ static int mv643xx_eth_probe(struct platform_device *pdev) INIT_WORK(&mp->tx_timeout_task, tx_timeout_task); - netif_napi_add(dev, &mp->napi, mv643xx_eth_poll, 128); + netif_napi_add(dev, &mp->napi, mv643xx_eth_poll, NAPI_POLL_WEIGHT); init_timer(&mp->rx_oom); mp->rx_oom.data = (unsigned long)mp; diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c index 1df56cc50ee9..0e572a527154 100644 --- a/drivers/net/ethernet/mellanox/mlx4/cmd.c +++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c @@ -222,8 +222,6 @@ static int mlx4_comm_cmd_poll(struct mlx4_dev *dev, u8 cmd, u16 param, * FLR process. The only non-zero result in the RESET command * is MLX4_DELAY_RESET_SLAVE*/ if ((MLX4_COMM_CMD_RESET == cmd)) { - mlx4_warn(dev, "Got slave FLRed from Communication" - " channel (ret:0x%x)\n", ret_from_pending); err = MLX4_DELAY_RESET_SLAVE; } else { mlx4_warn(dev, "Communication channel timed out\n"); diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index b35f94700093..89c47ea84b50 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -1323,6 +1323,7 @@ static void mlx4_en_auto_moderation(struct mlx4_en_priv *priv) priv->last_moder_time[ring] = moder_time; cq = &priv->rx_cq[ring]; cq->moder_time = moder_time; + cq->moder_cnt = priv->rx_frames; err = mlx4_en_set_cq_moder(priv, cq); if (err) en_err(priv, "Failed modifying moderation for cq:%d\n", @@ -2118,6 +2119,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, struct mlx4_en_priv *priv; int i; int err; + u64 mac_u64; dev = alloc_etherdev_mqs(sizeof(struct mlx4_en_priv), MAX_TX_RINGS, MAX_RX_RINGS); @@ -2191,10 +2193,17 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, dev->addr_len = ETH_ALEN; mlx4_en_u64_to_mac(dev->dev_addr, mdev->dev->caps.def_mac[priv->port]); if (!is_valid_ether_addr(dev->dev_addr)) { - en_err(priv, "Port: %d, invalid mac burned: %pM, quiting\n", - priv->port, dev->dev_addr); - err = -EINVAL; - goto out; + if (mlx4_is_slave(priv->mdev->dev)) { + eth_hw_addr_random(dev); + en_warn(priv, "Assigned random MAC address %pM\n", dev->dev_addr); + mac_u64 = mlx4_en_mac_to_u64(dev->dev_addr); + mdev->dev->caps.def_mac[priv->port] = mac_u64; + } else { + en_err(priv, "Port: %d, invalid mac burned: %pM, quiting\n", + priv->port, dev->dev_addr); + err = -EINVAL; + goto out; + } } memcpy(priv->prev_mac, dev->dev_addr, sizeof(priv->prev_mac)); diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c index 58a8e535d698..2c97901c6a6d 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.c +++ b/drivers/net/ethernet/mellanox/mlx4/fw.c @@ -840,12 +840,16 @@ int mlx4_QUERY_PORT_wrapper(struct mlx4_dev *dev, int slave, MLX4_CMD_NATIVE); if (!err && dev->caps.function != slave) { - /* set slave default_mac address */ - MLX4_GET(def_mac, outbox->buf, QUERY_PORT_MAC_OFFSET); - def_mac += slave << 8; /* if config MAC in DB use it */ if (priv->mfunc.master.vf_oper[slave].vport[vhcr->in_modifier].state.mac) def_mac = priv->mfunc.master.vf_oper[slave].vport[vhcr->in_modifier].state.mac; + else { + /* set slave default_mac address */ + MLX4_GET(def_mac, outbox->buf, QUERY_PORT_MAC_OFFSET); + def_mac += slave << 8; + priv->mfunc.master.vf_admin[slave].vport[vhcr->in_modifier].mac = def_mac; + } + MLX4_PUT(outbox->buf, def_mac, QUERY_PORT_MAC_OFFSET); /* get port type - currently only eth is enabled */ diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 0d32a82458bf..2f4a26039e80 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c @@ -1290,7 +1290,6 @@ static int mlx4_init_slave(struct mlx4_dev *dev) { struct mlx4_priv *priv = mlx4_priv(dev); u64 dma = (u64) priv->mfunc.vhcr_dma; - int num_of_reset_retries = NUM_OF_RESET_RETRIES; int ret_from_reset = 0; u32 slave_read; u32 cmd_channel_ver; @@ -1304,18 +1303,10 @@ static int mlx4_init_slave(struct mlx4_dev *dev) * NUM_OF_RESET_RETRIES times before leaving.*/ if (ret_from_reset) { if (MLX4_DELAY_RESET_SLAVE == ret_from_reset) { - msleep(SLEEP_TIME_IN_RESET); - while (ret_from_reset && num_of_reset_retries) { - mlx4_warn(dev, "slave is currently in the" - "middle of FLR. retrying..." - "(try num:%d)\n", - (NUM_OF_RESET_RETRIES - - num_of_reset_retries + 1)); - ret_from_reset = - mlx4_comm_cmd(dev, MLX4_COMM_CMD_RESET, - 0, MLX4_COMM_TIME); - num_of_reset_retries = num_of_reset_retries - 1; - } + mlx4_warn(dev, "slave is currently in the " + "middle of FLR. Deferring probe.\n"); + mutex_unlock(&priv->cmd.slave_cmd_mutex); + return -EPROBE_DEFER; } else goto err; } @@ -1526,7 +1517,8 @@ static int mlx4_init_hca(struct mlx4_dev *dev) } else { err = mlx4_init_slave(dev); if (err) { - mlx4_err(dev, "Failed to initialize slave\n"); + if (err != -EPROBE_DEFER) + mlx4_err(dev, "Failed to initialize slave\n"); return err; } diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h index 019c5f78732e..c1b693cb3df3 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h @@ -907,8 +907,11 @@ struct qlcnic_ipaddr { #define QLCNIC_FW_HANG 0x4000 #define QLCNIC_FW_LRO_MSS_CAP 0x8000 #define QLCNIC_TX_INTR_SHARED 0x10000 +#define QLCNIC_APP_CHANGED_FLAGS 0x20000 #define QLCNIC_IS_MSI_FAMILY(adapter) \ ((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED)) +#define QLCNIC_IS_TSO_CAPABLE(adapter) \ + ((adapter)->ahw->capabilities & QLCNIC_FW_CAPABILITY_TSO) #define QLCNIC_DEF_NUM_STS_DESC_RINGS 4 #define QLCNIC_MSIX_TBL_SPACE 8192 @@ -1034,6 +1037,7 @@ struct qlcnic_adapter { spinlock_t rx_mac_learn_lock; u32 file_prd_off; /*File fw product offset*/ u32 fw_version; + u32 offload_flags; const struct firmware *fw; }; @@ -1542,6 +1546,8 @@ void qlcnic_add_lb_filter(struct qlcnic_adapter *, struct sk_buff *, int, u16); int qlcnic_83xx_configure_opmode(struct qlcnic_adapter *adapter); int qlcnic_read_mac_addr(struct qlcnic_adapter *); int qlcnic_setup_netdev(struct qlcnic_adapter *, struct net_device *, int); +void qlcnic_set_netdev_features(struct qlcnic_adapter *, + struct qlcnic_esw_func_cfg *); void qlcnic_sriov_vf_schedule_multi(struct net_device *); void qlcnic_vf_add_mc_list(struct net_device *, u16); diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c index c67d1eb35e8f..5e7fb1dfb97b 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c @@ -382,8 +382,6 @@ static int qlcnic_83xx_idc_tx_soft_reset(struct qlcnic_adapter *adapter) clear_bit(__QLCNIC_RESETTING, &adapter->state); dev_err(&adapter->pdev->dev, "%s:\n", __func__); - adapter->netdev->trans_start = jiffies; - return 0; } diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c index 6a6512ba9f38..106a12f2a02f 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c @@ -973,16 +973,57 @@ int qlcnic_change_mtu(struct net_device *netdev, int mtu) return rc; } +static netdev_features_t qlcnic_process_flags(struct qlcnic_adapter *adapter, + netdev_features_t features) +{ + u32 offload_flags = adapter->offload_flags; + + if (offload_flags & BIT_0) { + features |= NETIF_F_RXCSUM | NETIF_F_IP_CSUM | + NETIF_F_IPV6_CSUM; + adapter->rx_csum = 1; + if (QLCNIC_IS_TSO_CAPABLE(adapter)) { + if (!(offload_flags & BIT_1)) + features &= ~NETIF_F_TSO; + else + features |= NETIF_F_TSO; + + if (!(offload_flags & BIT_2)) + features &= ~NETIF_F_TSO6; + else + features |= NETIF_F_TSO6; + } + } else { + features &= ~(NETIF_F_RXCSUM | + NETIF_F_IP_CSUM | + NETIF_F_IPV6_CSUM); + + if (QLCNIC_IS_TSO_CAPABLE(adapter)) + features &= ~(NETIF_F_TSO | NETIF_F_TSO6); + adapter->rx_csum = 0; + } + + return features; +} netdev_features_t qlcnic_fix_features(struct net_device *netdev, netdev_features_t features) { struct qlcnic_adapter *adapter = netdev_priv(netdev); + netdev_features_t changed; - if ((adapter->flags & QLCNIC_ESWITCH_ENABLED) && - qlcnic_82xx_check(adapter)) { - netdev_features_t changed = features ^ netdev->features; - features ^= changed & (NETIF_F_ALL_CSUM | NETIF_F_RXCSUM); + if (qlcnic_82xx_check(adapter) && + (adapter->flags & QLCNIC_ESWITCH_ENABLED)) { + if (adapter->flags & QLCNIC_APP_CHANGED_FLAGS) { + features = qlcnic_process_flags(adapter, features); + } else { + changed = features ^ netdev->features; + features ^= changed & (NETIF_F_RXCSUM | + NETIF_F_IP_CSUM | + NETIF_F_IPV6_CSUM | + NETIF_F_TSO | + NETIF_F_TSO6); + } } if (!(features & NETIF_F_RXCSUM)) diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 8fb836d4129f..aeb26a850679 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -84,14 +84,9 @@ static int qlcnic_start_firmware(struct qlcnic_adapter *); static void qlcnic_free_lb_filters_mem(struct qlcnic_adapter *adapter); static void qlcnic_dev_set_npar_ready(struct qlcnic_adapter *); static int qlcnicvf_start_firmware(struct qlcnic_adapter *); -static void qlcnic_set_netdev_features(struct qlcnic_adapter *, - struct qlcnic_esw_func_cfg *); static int qlcnic_vlan_rx_add(struct net_device *, __be16, u16); static int qlcnic_vlan_rx_del(struct net_device *, __be16, u16); -#define QLCNIC_IS_TSO_CAPABLE(adapter) \ - ((adapter)->ahw->capabilities & QLCNIC_FW_CAPABILITY_TSO) - static u32 qlcnic_vlan_tx_check(struct qlcnic_adapter *adapter) { struct qlcnic_hardware_context *ahw = adapter->ahw; @@ -1074,8 +1069,6 @@ void qlcnic_set_eswitch_port_features(struct qlcnic_adapter *adapter, if (!esw_cfg->promisc_mode) adapter->flags |= QLCNIC_PROMISC_DISABLED; - - qlcnic_set_netdev_features(adapter, esw_cfg); } int qlcnic_set_eswitch_port_config(struct qlcnic_adapter *adapter) @@ -1090,51 +1083,23 @@ int qlcnic_set_eswitch_port_config(struct qlcnic_adapter *adapter) return -EIO; qlcnic_set_vlan_config(adapter, &esw_cfg); qlcnic_set_eswitch_port_features(adapter, &esw_cfg); + qlcnic_set_netdev_features(adapter, &esw_cfg); return 0; } -static void -qlcnic_set_netdev_features(struct qlcnic_adapter *adapter, - struct qlcnic_esw_func_cfg *esw_cfg) +void qlcnic_set_netdev_features(struct qlcnic_adapter *adapter, + struct qlcnic_esw_func_cfg *esw_cfg) { struct net_device *netdev = adapter->netdev; - unsigned long features, vlan_features; if (qlcnic_83xx_check(adapter)) return; - features = (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_RXCSUM | - NETIF_F_IPV6_CSUM | NETIF_F_GRO); - vlan_features = (NETIF_F_SG | NETIF_F_IP_CSUM | - NETIF_F_IPV6_CSUM); - - if (QLCNIC_IS_TSO_CAPABLE(adapter)) { - features |= (NETIF_F_TSO | NETIF_F_TSO6); - vlan_features |= (NETIF_F_TSO | NETIF_F_TSO6); - } - - if (netdev->features & NETIF_F_LRO) - features |= NETIF_F_LRO; - - if (esw_cfg->offload_flags & BIT_0) { - netdev->features |= features; - adapter->rx_csum = 1; - if (!(esw_cfg->offload_flags & BIT_1)) { - netdev->features &= ~NETIF_F_TSO; - features &= ~NETIF_F_TSO; - } - if (!(esw_cfg->offload_flags & BIT_2)) { - netdev->features &= ~NETIF_F_TSO6; - features &= ~NETIF_F_TSO6; - } - } else { - netdev->features &= ~features; - features &= ~features; - adapter->rx_csum = 0; - } - - netdev->vlan_features = (features & vlan_features); + adapter->offload_flags = esw_cfg->offload_flags; + adapter->flags |= QLCNIC_APP_CHANGED_FLAGS; + netdev_update_features(netdev); + adapter->flags &= ~QLCNIC_APP_CHANGED_FLAGS; } static int @@ -2016,8 +1981,10 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pci_enable_pcie_error_reporting(pdev); ahw = kzalloc(sizeof(struct qlcnic_hardware_context), GFP_KERNEL); - if (!ahw) + if (!ahw) { + err = -ENOMEM; goto err_out_free_res; + } switch (ent->device) { case PCI_DEVICE_ID_QLOGIC_QLE824X: @@ -2053,6 +2020,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) adapter->qlcnic_wq = create_singlethread_workqueue("qlcnic"); if (adapter->qlcnic_wq == NULL) { + err = -ENOMEM; dev_err(&pdev->dev, "Failed to create workqueue\n"); goto err_out_free_netdev; } @@ -2133,6 +2101,10 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto err_out_disable_msi; } + err = qlcnic_get_act_pci_func(adapter); + if (err) + goto err_out_disable_mbx_intr; + err = qlcnic_setup_netdev(adapter, netdev, pci_using_dac); if (err) goto err_out_disable_mbx_intr; @@ -2162,9 +2134,6 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) break; } - if (qlcnic_get_act_pci_func(adapter)) - goto err_out_disable_mbx_intr; - if (adapter->drv_mac_learn) qlcnic_alloc_lb_filters_mem(adapter); @@ -3149,10 +3118,8 @@ qlcnic_check_health(struct qlcnic_adapter *adapter) if (adapter->need_fw_reset) goto detach; - if (adapter->ahw->reset_context && qlcnic_auto_fw_reset) { + if (adapter->ahw->reset_context && qlcnic_auto_fw_reset) qlcnic_reset_hw_context(adapter); - adapter->netdev->trans_start = jiffies; - } return 0; } diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c index 3869c3864deb..196b2d100407 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c @@ -1734,7 +1734,6 @@ static int qlcnic_sriov_vf_handle_context_reset(struct qlcnic_adapter *adapter) if (!qlcnic_sriov_vf_reinit_driver(adapter)) { qlcnic_sriov_vf_attach(adapter); - adapter->netdev->trans_start = jiffies; adapter->tx_timeo_cnt = 0; adapter->reset_ctx_cnt = 0; adapter->fw_fail_cnt = 0; diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c index 4e22e794a186..e7a2fe21b649 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c @@ -544,6 +544,9 @@ static ssize_t qlcnic_sysfs_write_esw_config(struct file *file, switch (esw_cfg[i].op_mode) { case QLCNIC_PORT_DEFAULTS: qlcnic_set_eswitch_port_features(adapter, &esw_cfg[i]); + rtnl_lock(); + qlcnic_set_netdev_features(adapter, &esw_cfg[i]); + rtnl_unlock(); break; case QLCNIC_ADD_VLAN: qlcnic_set_vlan_config(adapter, &esw_cfg[i]); diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_main.c b/drivers/net/ethernet/qlogic/qlge/qlge_main.c index 50235d201592..f87cc216045b 100644 --- a/drivers/net/ethernet/qlogic/qlge/qlge_main.c +++ b/drivers/net/ethernet/qlogic/qlge/qlge_main.c @@ -4717,6 +4717,7 @@ static int qlge_probe(struct pci_dev *pdev, dev_err(&pdev->dev, "net device registration failed.\n"); ql_release_all(pdev); pci_disable_device(pdev); + free_netdev(ndev); return err; } /* Start up the timer to trigger EEH if diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c index 7d1fb9ad1296..03523459c406 100644 --- a/drivers/net/ethernet/realtek/8139cp.c +++ b/drivers/net/ethernet/realtek/8139cp.c @@ -1136,6 +1136,7 @@ static void cp_clean_rings (struct cp_private *cp) cp->dev->stats.tx_dropped++; } } + netdev_reset_queue(cp->dev); memset(cp->rx_ring, 0, sizeof(struct cp_desc) * CP_RX_RING_SIZE); memset(cp->tx_ring, 0, sizeof(struct cp_desc) * CP_TX_RING_SIZE); diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 79c520b64fdd..393f961a013c 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -5856,7 +5856,20 @@ err_out: return -EIO; } -static inline void rtl8169_tso_csum(struct rtl8169_private *tp, +static bool rtl_skb_pad(struct sk_buff *skb) +{ + if (skb_padto(skb, ETH_ZLEN)) + return false; + skb_put(skb, ETH_ZLEN - skb->len); + return true; +} + +static bool rtl_test_hw_pad_bug(struct rtl8169_private *tp, struct sk_buff *skb) +{ + return skb->len < ETH_ZLEN && tp->mac_version == RTL_GIGA_MAC_VER_34; +} + +static inline bool rtl8169_tso_csum(struct rtl8169_private *tp, struct sk_buff *skb, u32 *opts) { const struct rtl_tx_desc_info *info = tx_desc_info + tp->txd_version; @@ -5869,13 +5882,20 @@ static inline void rtl8169_tso_csum(struct rtl8169_private *tp, } else if (skb->ip_summed == CHECKSUM_PARTIAL) { const struct iphdr *ip = ip_hdr(skb); + if (unlikely(rtl_test_hw_pad_bug(tp, skb))) + return skb_checksum_help(skb) == 0 && rtl_skb_pad(skb); + if (ip->protocol == IPPROTO_TCP) opts[offset] |= info->checksum.tcp; else if (ip->protocol == IPPROTO_UDP) opts[offset] |= info->checksum.udp; else WARN_ON_ONCE(1); + } else { + if (unlikely(rtl_test_hw_pad_bug(tp, skb))) + return rtl_skb_pad(skb); } + return true; } static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, @@ -5896,17 +5916,15 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, goto err_stop_0; } - /* 8168evl does not automatically pad to minimum length. */ - if (unlikely(tp->mac_version == RTL_GIGA_MAC_VER_34 && - skb->len < ETH_ZLEN)) { - if (skb_padto(skb, ETH_ZLEN)) - goto err_update_stats; - skb_put(skb, ETH_ZLEN - skb->len); - } - if (unlikely(le32_to_cpu(txd->opts1) & DescOwn)) goto err_stop_0; + opts[1] = cpu_to_le32(rtl8169_tx_vlan_tag(skb)); + opts[0] = DescOwn; + + if (!rtl8169_tso_csum(tp, skb, opts)) + goto err_update_stats; + len = skb_headlen(skb); mapping = dma_map_single(d, skb->data, len, DMA_TO_DEVICE); if (unlikely(dma_mapping_error(d, mapping))) { @@ -5918,11 +5936,6 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, tp->tx_skb[entry].len = len; txd->addr = cpu_to_le64(mapping); - opts[1] = cpu_to_le32(rtl8169_tx_vlan_tag(skb)); - opts[0] = DescOwn; - - rtl8169_tso_csum(tp, skb, opts); - frags = rtl8169_xmit_frags(tp, skb, opts); if (frags < 0) goto err_dma_1; diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 42e9dd05c936..5e3982fc5398 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -897,8 +897,8 @@ static int sh_eth_check_reset(struct net_device *ndev) mdelay(1); cnt--; } - if (cnt < 0) { - pr_err("Device reset fail\n"); + if (cnt <= 0) { + pr_err("Device reset failed\n"); ret = -ETIMEDOUT; } return ret; @@ -1401,16 +1401,23 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status) desc_status = edmac_to_cpu(mdp, rxdesc->status); pkt_len = rxdesc->frame_length; -#if defined(CONFIG_ARCH_R8A7740) - desc_status >>= 16; -#endif - if (--boguscnt < 0) break; if (!(desc_status & RDFEND)) ndev->stats.rx_length_errors++; +#if defined(CONFIG_ARCH_R8A7740) + /* + * In case of almost all GETHER/ETHERs, the Receive Frame State + * (RFS) bits in the Receive Descriptor 0 are from bit 9 to + * bit 0. However, in case of the R8A7740's GETHER, the RFS + * bits are from bit 25 to bit 16. So, the driver needs right + * shifting by 16. + */ + desc_status >>= 16; +#endif + if (desc_status & (RD_RFS1 | RD_RFS2 | RD_RFS3 | RD_RFS4 | RD_RFS5 | RD_RFS6 | RD_RFS10)) { ndev->stats.rx_errors++; diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 01b99206139a..39e4cb39de29 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -638,14 +638,16 @@ static void efx_start_datapath(struct efx_nic *efx) EFX_MAX_FRAME_LEN(efx->net_dev->mtu) + efx->type->rx_buffer_padding); rx_buf_len = (sizeof(struct efx_rx_page_state) + - EFX_PAGE_IP_ALIGN + efx->rx_dma_len); + NET_IP_ALIGN + efx->rx_dma_len); if (rx_buf_len <= PAGE_SIZE) { efx->rx_scatter = false; efx->rx_buffer_order = 0; } else if (efx->type->can_rx_scatter) { + BUILD_BUG_ON(EFX_RX_USR_BUF_SIZE % L1_CACHE_BYTES); BUILD_BUG_ON(sizeof(struct efx_rx_page_state) + - EFX_PAGE_IP_ALIGN + EFX_RX_USR_BUF_SIZE > - PAGE_SIZE / 2); + 2 * ALIGN(NET_IP_ALIGN + EFX_RX_USR_BUF_SIZE, + EFX_RX_BUF_ALIGNMENT) > + PAGE_SIZE); efx->rx_scatter = true; efx->rx_dma_len = EFX_RX_USR_BUF_SIZE; efx->rx_buffer_order = 0; diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index 9bd433a095c5..39d6bd77f015 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -72,8 +72,20 @@ /* Maximum possible MTU the driver supports */ #define EFX_MAX_MTU (9 * 1024) -/* Size of an RX scatter buffer. Small enough to pack 2 into a 4K page. */ -#define EFX_RX_USR_BUF_SIZE 1824 +/* Size of an RX scatter buffer. Small enough to pack 2 into a 4K page, + * and should be a multiple of the cache line size. + */ +#define EFX_RX_USR_BUF_SIZE (2048 - 256) + +/* If possible, we should ensure cache line alignment at start and end + * of every buffer. Otherwise, we just need to ensure 4-byte + * alignment of the network header. + */ +#if NET_IP_ALIGN == 0 +#define EFX_RX_BUF_ALIGNMENT L1_CACHE_BYTES +#else +#define EFX_RX_BUF_ALIGNMENT 4 +#endif /* Forward declare Precision Time Protocol (PTP) support structure. */ struct efx_ptp_data; @@ -468,24 +480,11 @@ enum nic_state { }; /* - * Alignment of page-allocated RX buffers - * - * Controls the number of bytes inserted at the start of an RX buffer. - * This is the equivalent of NET_IP_ALIGN [which controls the alignment - * of the skb->head for hardware DMA]. - */ -#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS -#define EFX_PAGE_IP_ALIGN 0 -#else -#define EFX_PAGE_IP_ALIGN NET_IP_ALIGN -#endif - -/* * Alignment of the skb->head which wraps a page-allocated RX buffer * * The skb allocated to wrap an rx_buffer can have this alignment. Since * the data is memcpy'd from the rx_buf, it does not need to be equal to - * EFX_PAGE_IP_ALIGN. + * NET_IP_ALIGN. */ #define EFX_PAGE_SKB_ALIGN 2 diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c index e73e30bac10e..a7dfe36cabf4 100644 --- a/drivers/net/ethernet/sfc/rx.c +++ b/drivers/net/ethernet/sfc/rx.c @@ -93,8 +93,8 @@ static inline void efx_sync_rx_buffer(struct efx_nic *efx, void efx_rx_config_page_split(struct efx_nic *efx) { - efx->rx_page_buf_step = ALIGN(efx->rx_dma_len + EFX_PAGE_IP_ALIGN, - L1_CACHE_BYTES); + efx->rx_page_buf_step = ALIGN(efx->rx_dma_len + NET_IP_ALIGN, + EFX_RX_BUF_ALIGNMENT); efx->rx_bufs_per_page = efx->rx_buffer_order ? 1 : ((PAGE_SIZE - sizeof(struct efx_rx_page_state)) / efx->rx_page_buf_step); @@ -188,9 +188,9 @@ static int efx_init_rx_buffers(struct efx_rx_queue *rx_queue) do { index = rx_queue->added_count & rx_queue->ptr_mask; rx_buf = efx_rx_buffer(rx_queue, index); - rx_buf->dma_addr = dma_addr + EFX_PAGE_IP_ALIGN; + rx_buf->dma_addr = dma_addr + NET_IP_ALIGN; rx_buf->page = page; - rx_buf->page_offset = page_offset + EFX_PAGE_IP_ALIGN; + rx_buf->page_offset = page_offset + NET_IP_ALIGN; rx_buf->len = efx->rx_dma_len; rx_buf->flags = 0; ++rx_queue->added_count; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 618446ae1ec1..ee919ca8b8a0 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -1899,7 +1899,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) #ifdef STMMAC_XMIT_DEBUG if (netif_msg_pktdata(priv)) { - pr_info("%s: curr %d dirty=%d entry=%d, first=%p, nfrags=%d" + pr_info("%s: curr %d dirty=%d entry=%d, first=%p, nfrags=%d", __func__, (priv->cur_tx % txsize), (priv->dirty_tx % txsize), entry, first, nfrags); if (priv->extend_desc) diff --git a/drivers/net/ethernet/ti/davinci_mdio.c b/drivers/net/ethernet/ti/davinci_mdio.c index 12aec173564c..c47f0dbcebb5 100644 --- a/drivers/net/ethernet/ti/davinci_mdio.c +++ b/drivers/net/ethernet/ti/davinci_mdio.c @@ -449,10 +449,9 @@ static int davinci_mdio_suspend(struct device *dev) __raw_writel(ctrl, &data->regs->control); wait_for_idle(data); - pm_runtime_put_sync(data->dev); - data->suspended = true; spin_unlock(&data->lock); + pm_runtime_put_sync(data->dev); return 0; } @@ -460,15 +459,12 @@ static int davinci_mdio_suspend(struct device *dev) static int davinci_mdio_resume(struct device *dev) { struct davinci_mdio_data *data = dev_get_drvdata(dev); - u32 ctrl; - spin_lock(&data->lock); pm_runtime_get_sync(data->dev); + spin_lock(&data->lock); /* restart the scan state machine */ - ctrl = __raw_readl(&data->regs->control); - ctrl |= CONTROL_ENABLE; - __raw_writel(ctrl, &data->regs->control); + __davinci_mdio_reset(data); data->suspended = false; spin_unlock(&data->lock); @@ -477,8 +473,8 @@ static int davinci_mdio_resume(struct device *dev) } static const struct dev_pm_ops davinci_mdio_pm_ops = { - .suspend = davinci_mdio_suspend, - .resume = davinci_mdio_resume, + .suspend_late = davinci_mdio_suspend, + .resume_early = davinci_mdio_resume, }; static const struct of_device_id davinci_mdio_of_mtable[] = { diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c index 919b983114e9..b7268b3dae77 100644 --- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c +++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c @@ -946,7 +946,8 @@ static int xemaclite_open(struct net_device *dev) phy_write(lp->phy_dev, MII_CTRL1000, 0); /* Advertise only 10 and 100mbps full/half duplex speeds */ - phy_write(lp->phy_dev, MII_ADVERTISE, ADVERTISE_ALL); + phy_write(lp->phy_dev, MII_ADVERTISE, ADVERTISE_ALL | + ADVERTISE_CSMA); /* Restart auto negotiation */ bmcr = phy_read(lp->phy_dev, MII_BMCR); diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index 088c55496191..ab2307b5d9a7 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -31,6 +31,7 @@ #include <linux/inetdevice.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> +#include <linux/if_vlan.h> #include <linux/in.h> #include <linux/slab.h> #include <net/arp.h> @@ -284,7 +285,7 @@ int netvsc_recv_callback(struct hv_device *device_obj, skb->protocol = eth_type_trans(skb, net); skb->ip_summed = CHECKSUM_NONE; - skb->vlan_tci = packet->vlan_tci; + __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), packet->vlan_tci); net->stats.rx_packets++; net->stats.rx_bytes += packet->total_data_buflen; diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 1c502bb0c916..6e91931a1c2c 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -853,18 +853,24 @@ static int macvlan_changelink(struct net_device *dev, struct nlattr *tb[], struct nlattr *data[]) { struct macvlan_dev *vlan = netdev_priv(dev); - if (data && data[IFLA_MACVLAN_MODE]) - vlan->mode = nla_get_u32(data[IFLA_MACVLAN_MODE]); + if (data && data[IFLA_MACVLAN_FLAGS]) { __u16 flags = nla_get_u16(data[IFLA_MACVLAN_FLAGS]); bool promisc = (flags ^ vlan->flags) & MACVLAN_FLAG_NOPROMISC; - - if (promisc && (flags & MACVLAN_FLAG_NOPROMISC)) - dev_set_promiscuity(vlan->lowerdev, -1); - else if (promisc && !(flags & MACVLAN_FLAG_NOPROMISC)) - dev_set_promiscuity(vlan->lowerdev, 1); + if (vlan->port->passthru && promisc) { + int err; + + if (flags & MACVLAN_FLAG_NOPROMISC) + err = dev_set_promiscuity(vlan->lowerdev, -1); + else + err = dev_set_promiscuity(vlan->lowerdev, 1); + if (err < 0) + return err; + } vlan->flags = flags; } + if (data && data[IFLA_MACVLAN_MODE]) + vlan->mode = nla_get_u32(data[IFLA_MACVLAN_MODE]); return 0; } diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index c14f14741b3f..38f0b312ff85 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -1044,7 +1044,7 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable) adv = mmd_eee_adv_to_ethtool_adv_t(eee_adv); lp = mmd_eee_adv_to_ethtool_adv_t(eee_lp); idx = phy_find_setting(phydev->speed, phydev->duplex); - if ((lp & adv & settings[idx].setting)) + if (!(lp & adv & settings[idx].setting)) goto eee_exit; if (clk_stop_enable) { diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index 7c43261975bd..b3051052f3ad 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -1092,8 +1092,8 @@ static int team_port_add(struct team *team, struct net_device *port_dev) } port->index = -1; - team_port_enable(team, port); list_add_tail_rcu(&port->list, &team->port_list); + team_port_enable(team, port); __team_compute_features(team); __team_port_change_port_added(port, !!netif_carrier_ok(port_dev)); __team_options_change_check(team); @@ -2374,7 +2374,8 @@ static int team_nl_send_port_list_get(struct team *team, u32 portid, u32 seq, bool incomplete; int i; - port = list_first_entry(&team->port_list, struct team_port, list); + port = list_first_entry_or_null(&team->port_list, + struct team_port, list); start_again: err = __send_and_alloc_skb(&skb, team, portid, send_func); @@ -2402,8 +2403,8 @@ start_again: err = team_nl_fill_one_port_get(skb, one_port); if (err) goto errout; - } else { - list_for_each_entry(port, &team->port_list, list) { + } else if (port) { + list_for_each_entry_from(port, &team->port_list, list) { err = team_nl_fill_one_port_get(skb, port); if (err) { if (err == -EMSGSIZE) { diff --git a/drivers/net/team/team_mode_random.c b/drivers/net/team/team_mode_random.c index 5ca14d463ba7..7f032e211343 100644 --- a/drivers/net/team/team_mode_random.c +++ b/drivers/net/team/team_mode_random.c @@ -28,6 +28,8 @@ static bool rnd_transmit(struct team *team, struct sk_buff *skb) port_index = random_N(team->en_port_count); port = team_get_port_by_index_rcu(team, port_index); + if (unlikely(!port)) + goto drop; port = team_get_first_port_txable_rcu(team, port); if (unlikely(!port)) goto drop; diff --git a/drivers/net/team/team_mode_roundrobin.c b/drivers/net/team/team_mode_roundrobin.c index d268e4de781b..472623f8ce3d 100644 --- a/drivers/net/team/team_mode_roundrobin.c +++ b/drivers/net/team/team_mode_roundrobin.c @@ -32,6 +32,8 @@ static bool rr_transmit(struct team *team, struct sk_buff *skb) port_index = rr_priv(team)->sent_packets++ % team->en_port_count; port = team_get_port_by_index_rcu(team, port_index); + if (unlikely(!port)) + goto drop; port = team_get_first_port_txable_rcu(team, port); if (unlikely(!port)) goto drop; diff --git a/drivers/net/tun.c b/drivers/net/tun.c index f042b0373e5d..bfa9bb48e42d 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -352,7 +352,7 @@ static u16 tun_select_queue(struct net_device *dev, struct sk_buff *skb) u32 numqueues = 0; rcu_read_lock(); - numqueues = tun->numqueues; + numqueues = ACCESS_ONCE(tun->numqueues); txq = skb_get_rxhash(skb); if (txq) { @@ -1585,6 +1585,10 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) else return -EINVAL; + if (!!(ifr->ifr_flags & IFF_MULTI_QUEUE) != + !!(tun->flags & TUN_TAP_MQ)) + return -EINVAL; + if (tun_not_capable(tun)) return -EPERM; err = security_tun_dev_open(tun->security); @@ -2155,6 +2159,8 @@ static int tun_chr_open(struct inode *inode, struct file * file) set_bit(SOCK_EXTERNALLY_ALLOCATED, &tfile->socket.flags); INIT_LIST_HEAD(&tfile->next); + sock_set_flag(&tfile->sk, SOCK_ZEROCOPY); + return 0; } diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 078795fe6e31..04ee044dde51 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c @@ -627,6 +627,12 @@ static const struct usb_device_id products [] = { .driver_info = 0, }, +/* Huawei E1820 - handled by qmi_wwan */ +{ + USB_DEVICE_INTERFACE_NUMBER(HUAWEI_VENDOR_ID, 0x14ac, 1), + .driver_info = 0, +}, + /* Realtek RTL8152 Based USB 2.0 Ethernet Adapters */ #if defined(CONFIG_USB_RTL8152) || defined(CONFIG_USB_RTL8152_MODULE) { diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index cf887c2384e9..d095d0d3056b 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -519,6 +519,7 @@ static const struct usb_device_id products[] = { /* 3. Combined interface devices matching on interface number */ {QMI_FIXED_INTF(0x0408, 0xea42, 4)}, /* Yota / Megafon M100-1 */ {QMI_FIXED_INTF(0x12d1, 0x140c, 1)}, /* Huawei E173 */ + {QMI_FIXED_INTF(0x12d1, 0x14ac, 1)}, /* Huawei E1820 */ {QMI_FIXED_INTF(0x19d2, 0x0002, 1)}, {QMI_FIXED_INTF(0x19d2, 0x0012, 1)}, {QMI_FIXED_INTF(0x19d2, 0x0017, 3)}, @@ -582,6 +583,7 @@ static const struct usb_device_id products[] = { {QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */ {QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */ {QMI_FIXED_INTF(0x1bc7, 0x1200, 5)}, /* Telit LE920 */ + {QMI_FIXED_INTF(0x1e2d, 0x12d1, 4)}, /* Cinterion PLxx */ /* 4. Gobi 1000 devices */ {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c index a491d3a95393..6cbdac67f3a0 100644 --- a/drivers/net/usb/rtl8150.c +++ b/drivers/net/usb/rtl8150.c @@ -130,19 +130,23 @@ struct rtl8150 { struct usb_device *udev; struct tasklet_struct tl; struct net_device *netdev; - struct urb *rx_urb, *tx_urb, *intr_urb, *ctrl_urb; + struct urb *rx_urb, *tx_urb, *intr_urb; struct sk_buff *tx_skb, *rx_skb; struct sk_buff *rx_skb_pool[RX_SKB_POOL_SIZE]; spinlock_t rx_pool_lock; struct usb_ctrlrequest dr; int intr_interval; - __le16 rx_creg; u8 *intr_buff; u8 phy; }; typedef struct rtl8150 rtl8150_t; +struct async_req { + struct usb_ctrlrequest dr; + u16 rx_creg; +}; + static const char driver_name [] = "rtl8150"; /* @@ -164,51 +168,47 @@ static int set_registers(rtl8150_t * dev, u16 indx, u16 size, void *data) indx, 0, data, size, 500); } -static void ctrl_callback(struct urb *urb) +static void async_set_reg_cb(struct urb *urb) { - rtl8150_t *dev; + struct async_req *req = (struct async_req *)urb->context; int status = urb->status; - switch (status) { - case 0: - break; - case -EINPROGRESS: - break; - case -ENOENT: - break; - default: - if (printk_ratelimit()) - dev_warn(&urb->dev->dev, "ctrl urb status %d\n", status); - } - dev = urb->context; - clear_bit(RX_REG_SET, &dev->flags); + if (status < 0) + dev_dbg(&urb->dev->dev, "%s failed with %d", __func__, status); + kfree(req); + usb_free_urb(urb); } -static int async_set_registers(rtl8150_t * dev, u16 indx, u16 size) +static int async_set_registers(rtl8150_t *dev, u16 indx, u16 size, u16 reg) { - int ret; - - if (test_bit(RX_REG_SET, &dev->flags)) - return -EAGAIN; + int res = -ENOMEM; + struct urb *async_urb; + struct async_req *req; - dev->dr.bRequestType = RTL8150_REQT_WRITE; - dev->dr.bRequest = RTL8150_REQ_SET_REGS; - dev->dr.wValue = cpu_to_le16(indx); - dev->dr.wIndex = 0; - dev->dr.wLength = cpu_to_le16(size); - dev->ctrl_urb->transfer_buffer_length = size; - usb_fill_control_urb(dev->ctrl_urb, dev->udev, - usb_sndctrlpipe(dev->udev, 0), (char *) &dev->dr, - &dev->rx_creg, size, ctrl_callback, dev); - if ((ret = usb_submit_urb(dev->ctrl_urb, GFP_ATOMIC))) { - if (ret == -ENODEV) + req = kmalloc(sizeof(struct async_req), GFP_ATOMIC); + if (req == NULL) + return res; + async_urb = usb_alloc_urb(0, GFP_ATOMIC); + if (async_urb == NULL) { + kfree(req); + return res; + } + req->rx_creg = cpu_to_le16(reg); + req->dr.bRequestType = RTL8150_REQT_WRITE; + req->dr.bRequest = RTL8150_REQ_SET_REGS; + req->dr.wIndex = 0; + req->dr.wValue = cpu_to_le16(indx); + req->dr.wLength = cpu_to_le16(size); + usb_fill_control_urb(async_urb, dev->udev, + usb_sndctrlpipe(dev->udev, 0), (void *)&req->dr, + &req->rx_creg, size, async_set_reg_cb, req); + res = usb_submit_urb(async_urb, GFP_ATOMIC); + if (res) { + if (res == -ENODEV) netif_device_detach(dev->netdev); - dev_err(&dev->udev->dev, - "control request submission failed: %d\n", ret); - } else - set_bit(RX_REG_SET, &dev->flags); - - return ret; + dev_err(&dev->udev->dev, "%s failed with %d\n", __func__, res); + } + return res; } static int read_mii_word(rtl8150_t * dev, u8 phy, __u8 indx, u16 * reg) @@ -330,13 +330,6 @@ static int alloc_all_urbs(rtl8150_t * dev) usb_free_urb(dev->tx_urb); return 0; } - dev->ctrl_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!dev->ctrl_urb) { - usb_free_urb(dev->rx_urb); - usb_free_urb(dev->tx_urb); - usb_free_urb(dev->intr_urb); - return 0; - } return 1; } @@ -346,7 +339,6 @@ static void free_all_urbs(rtl8150_t * dev) usb_free_urb(dev->rx_urb); usb_free_urb(dev->tx_urb); usb_free_urb(dev->intr_urb); - usb_free_urb(dev->ctrl_urb); } static void unlink_all_urbs(rtl8150_t * dev) @@ -354,7 +346,6 @@ static void unlink_all_urbs(rtl8150_t * dev) usb_kill_urb(dev->rx_urb); usb_kill_urb(dev->tx_urb); usb_kill_urb(dev->intr_urb); - usb_kill_urb(dev->ctrl_urb); } static inline struct sk_buff *pull_skb(rtl8150_t *dev) @@ -629,7 +620,6 @@ static int enable_net_traffic(rtl8150_t * dev) } /* RCR bit7=1 attach Rx info at the end; =0 HW CRC (which is broken) */ rcr = 0x9e; - dev->rx_creg = cpu_to_le16(rcr); tcr = 0xd8; cr = 0x0c; if (!(rcr & 0x80)) @@ -662,20 +652,22 @@ static void rtl8150_tx_timeout(struct net_device *netdev) static void rtl8150_set_multicast(struct net_device *netdev) { rtl8150_t *dev = netdev_priv(netdev); + u16 rx_creg = 0x9e; + netif_stop_queue(netdev); if (netdev->flags & IFF_PROMISC) { - dev->rx_creg |= cpu_to_le16(0x0001); + rx_creg |= 0x0001; dev_info(&netdev->dev, "%s: promiscuous mode\n", netdev->name); } else if (!netdev_mc_empty(netdev) || (netdev->flags & IFF_ALLMULTI)) { - dev->rx_creg &= cpu_to_le16(0xfffe); - dev->rx_creg |= cpu_to_le16(0x0002); + rx_creg &= 0xfffe; + rx_creg |= 0x0002; dev_info(&netdev->dev, "%s: allmulti set\n", netdev->name); } else { /* ~RX_MULTICAST, ~RX_PROMISCUOUS */ - dev->rx_creg &= cpu_to_le16(0x00fc); + rx_creg &= 0x00fc; } - async_set_registers(dev, RCR, 2); + async_set_registers(dev, RCR, sizeof(rx_creg), rx_creg); netif_wake_queue(netdev); } diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 655bb25eed2b..c9e00387d999 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -636,10 +636,11 @@ static int virtnet_open(struct net_device *dev) struct virtnet_info *vi = netdev_priv(dev); int i; - for (i = 0; i < vi->curr_queue_pairs; i++) { - /* Make sure we have some buffers: if oom use wq. */ - if (!try_fill_recv(&vi->rq[i], GFP_KERNEL)) - schedule_delayed_work(&vi->refill, 0); + for (i = 0; i < vi->max_queue_pairs; i++) { + if (i < vi->curr_queue_pairs) + /* Make sure we have some buffers: if oom use wq. */ + if (!try_fill_recv(&vi->rq[i], GFP_KERNEL)) + schedule_delayed_work(&vi->refill, 0); virtnet_napi_enable(&vi->rq[i]); } diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index ba81f3c39a83..3b1d2ee7156b 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -301,7 +301,7 @@ static inline struct hlist_head *vxlan_fdb_head(struct vxlan_dev *vxlan, } /* Look up Ethernet address in forwarding table */ -static struct vxlan_fdb *vxlan_find_mac(struct vxlan_dev *vxlan, +static struct vxlan_fdb *__vxlan_find_mac(struct vxlan_dev *vxlan, const u8 *mac) { @@ -316,6 +316,18 @@ static struct vxlan_fdb *vxlan_find_mac(struct vxlan_dev *vxlan, return NULL; } +static struct vxlan_fdb *vxlan_find_mac(struct vxlan_dev *vxlan, + const u8 *mac) +{ + struct vxlan_fdb *f; + + f = __vxlan_find_mac(vxlan, mac); + if (f) + f->used = jiffies; + + return f; +} + /* Add/update destinations for multicast */ static int vxlan_fdb_append(struct vxlan_fdb *f, __be32 ip, __be16 port, __u32 vni, __u32 ifindex) @@ -353,7 +365,7 @@ static int vxlan_fdb_create(struct vxlan_dev *vxlan, struct vxlan_fdb *f; int notify = 0; - f = vxlan_find_mac(vxlan, mac); + f = __vxlan_find_mac(vxlan, mac); if (f) { if (flags & NLM_F_EXCL) { netdev_dbg(vxlan->dev, @@ -563,7 +575,6 @@ static void vxlan_snoop(struct net_device *dev, f = vxlan_find_mac(vxlan, src_mac); if (likely(f)) { - f->used = jiffies; if (likely(f->remote.remote_ip == src_ip)) return; diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig index f3dc124c60c7..3c2cbc9d6295 100644 --- a/drivers/net/wireless/ath/ath9k/Kconfig +++ b/drivers/net/wireless/ath/ath9k/Kconfig @@ -92,13 +92,17 @@ config ATH9K_MAC_DEBUG This option enables collection of statistics for Rx/Tx status data and some other MAC related statistics -config ATH9K_RATE_CONTROL +config ATH9K_LEGACY_RATE_CONTROL bool "Atheros ath9k rate control" depends on ATH9K - default y + default n ---help--- Say Y, if you want to use the ath9k specific rate control - module instead of minstrel_ht. + module instead of minstrel_ht. Be warned that there are various + issues with the ath9k RC and minstrel is a more robust algorithm. + Note that even if this option is selected, "ath9k_rate_control" + has to be passed to mac80211 using the module parameter, + ieee80211_default_rc_algo. config ATH9K_HTC tristate "Atheros HTC based wireless cards support" diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile index 2ad8f9474ba1..75ee9e7704ce 100644 --- a/drivers/net/wireless/ath/ath9k/Makefile +++ b/drivers/net/wireless/ath/ath9k/Makefile @@ -8,7 +8,7 @@ ath9k-y += beacon.o \ antenna.o ath9k-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += mci.o -ath9k-$(CONFIG_ATH9K_RATE_CONTROL) += rc.o +ath9k-$(CONFIG_ATH9K_LEGACY_RATE_CONTROL) += rc.o ath9k-$(CONFIG_ATH9K_PCI) += pci.o ath9k-$(CONFIG_ATH9K_AHB) += ahb.o ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h index db5ffada2217..7546b9a7dcbf 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h @@ -958,11 +958,11 @@ static const u32 ar9300Common_rx_gain_table_2p2[][2] = { {0x0000a074, 0x00000000}, {0x0000a078, 0x00000000}, {0x0000a07c, 0x00000000}, - {0x0000a080, 0x1a1a1a1a}, - {0x0000a084, 0x1a1a1a1a}, - {0x0000a088, 0x1a1a1a1a}, - {0x0000a08c, 0x1a1a1a1a}, - {0x0000a090, 0x171a1a1a}, + {0x0000a080, 0x22222229}, + {0x0000a084, 0x1d1d1d1d}, + {0x0000a088, 0x1d1d1d1d}, + {0x0000a08c, 0x1d1d1d1d}, + {0x0000a090, 0x171d1d1d}, {0x0000a094, 0x11111717}, {0x0000a098, 0x00030311}, {0x0000a09c, 0x00000000}, diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index 639ba7d18ea4..6988e1d081f2 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c @@ -965,7 +965,7 @@ static void ar9003_hw_do_manual_peak_cal(struct ath_hw *ah, { int i; - if (!AR_SREV_9462(ah) && !AR_SREV_9565(ah)) + if (!AR_SREV_9462(ah) && !AR_SREV_9565(ah) && !AR_SREV_9485(ah)) return; for (i = 0; i < AR9300_MAX_CHAINS; i++) { diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h index 54ba42f4108a..874f6570bd1c 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h @@ -68,13 +68,16 @@ #define AR9300_BASE_ADDR 0x3ff #define AR9300_BASE_ADDR_512 0x1ff -#define AR9300_OTP_BASE (AR_SREV_9340(ah) ? 0x30000 : 0x14000) -#define AR9300_OTP_STATUS (AR_SREV_9340(ah) ? 0x30018 : 0x15f18) +#define AR9300_OTP_BASE \ + ((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x30000 : 0x14000) +#define AR9300_OTP_STATUS \ + ((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x30018 : 0x15f18) #define AR9300_OTP_STATUS_TYPE 0x7 #define AR9300_OTP_STATUS_VALID 0x4 #define AR9300_OTP_STATUS_ACCESS_BUSY 0x2 #define AR9300_OTP_STATUS_SM_BUSY 0x1 -#define AR9300_OTP_READ_DATA (AR_SREV_9340(ah) ? 0x3001c : 0x15f1c) +#define AR9300_OTP_READ_DATA \ + ((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x3001c : 0x15f1c) enum targetPowerHTRates { HT_TARGET_RATE_0_8_16, diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 2bf6548dd143..e1714d7c9eeb 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -334,7 +334,8 @@ static void ar9003_hw_spur_ofdm(struct ath_hw *ah, REG_RMW_FIELD(ah, AR_PHY_SPUR_REG, AR_PHY_SPUR_REG_EN_VIT_SPUR_RSSI, 1); - if (REG_READ_FIELD(ah, AR_PHY_MODE, + if (!AR_SREV_9340(ah) && + REG_READ_FIELD(ah, AR_PHY_MODE, AR_PHY_MODE_DYNAMIC) == 0x1) REG_RMW_FIELD(ah, AR_PHY_SPUR_REG, AR_PHY_SPUR_REG_ENABLE_NF_RSSI_SPUR_MIT, 1); diff --git a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h index 712f415b8c08..88ff1d7b53ab 100644 --- a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h @@ -1020,7 +1020,7 @@ static const u32 ar9485_1_1_baseband_postamble[][5] = { {0x0000a284, 0x00000000, 0x00000000, 0x000002a0, 0x000002a0}, {0x0000a288, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a28c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, + {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00058d18, 0x00058d18}, {0x0000a2d0, 0x00071981, 0x00071981, 0x00071982, 0x00071982}, {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a}, {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 8a1888d02070..42b03dc39d14 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -251,9 +251,9 @@ struct ath_atx_tid { int tidno; int baw_head; /* first un-acked tx buffer */ int baw_tail; /* next unused tx buffer slot */ - int sched; - int paused; - u8 state; + bool sched; + bool paused; + bool active; }; struct ath_node { @@ -274,10 +274,6 @@ struct ath_node { #endif }; -#define AGGR_CLEANUP BIT(1) -#define AGGR_ADDBA_COMPLETE BIT(2) -#define AGGR_ADDBA_PROGRESS BIT(3) - struct ath_tx_control { struct ath_txq *txq; struct ath_node *an; diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index e6307b86363a..b37eb8d38811 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -2008,6 +2008,14 @@ void ath9k_get_et_stats(struct ieee80211_hw *hw, WARN_ON(i != ATH9K_SSTATS_LEN); } +void ath9k_deinit_debug(struct ath_softc *sc) +{ + if (config_enabled(CONFIG_ATH9K_DEBUGFS) && sc->rfs_chan_spec_scan) { + relay_close(sc->rfs_chan_spec_scan); + sc->rfs_chan_spec_scan = NULL; + } +} + int ath9k_init_debug(struct ath_hw *ah) { struct ath_common *common = ath9k_hw_common(ah); diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index 794a7ec83a24..9d49aab8b989 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h @@ -304,6 +304,7 @@ struct ath9k_debug { }; int ath9k_init_debug(struct ath_hw *ah); +void ath9k_deinit_debug(struct ath_softc *sc); void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status); void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, @@ -339,6 +340,10 @@ static inline int ath9k_init_debug(struct ath_hw *ah) return 0; } +static inline void ath9k_deinit_debug(struct ath_softc *sc) +{ +} + static inline void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status) { diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 7f25da8444fe..15dfefcf2d0f 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1172,6 +1172,7 @@ u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan) static inline void ath9k_hw_set_dma(struct ath_hw *ah) { struct ath_common *common = ath9k_hw_common(ah); + int txbuf_size; ENABLE_REGWRITE_BUFFER(ah); @@ -1225,13 +1226,17 @@ static inline void ath9k_hw_set_dma(struct ath_hw *ah) * So set the usable tx buf size also to half to * avoid data/delimiter underruns */ - REG_WRITE(ah, AR_PCU_TXBUF_CTRL, - AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE); - } else if (!AR_SREV_9271(ah)) { - REG_WRITE(ah, AR_PCU_TXBUF_CTRL, - AR_PCU_TXBUF_CTRL_USABLE_SIZE); + txbuf_size = AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE; + } else if (AR_SREV_9340_13_OR_LATER(ah)) { + /* Uses fewer entries for AR934x v1.3+ to prevent rx overruns */ + txbuf_size = AR_9340_PCU_TXBUF_CTRL_USABLE_SIZE; + } else { + txbuf_size = AR_PCU_TXBUF_CTRL_USABLE_SIZE; } + if (!AR_SREV_9271(ah)) + REG_WRITE(ah, AR_PCU_TXBUF_CTRL, txbuf_size); + REGWRITE_BUFFER_FLUSH(ah); if (AR_SREV_9300_20_OR_LATER(ah)) @@ -1306,9 +1311,13 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type) AR_RTC_RC_COLD_RESET | AR_RTC_RC_WARM_RESET; } else { tmpReg = REG_READ(ah, AR_INTR_SYNC_CAUSE); - if (tmpReg & - (AR_INTR_SYNC_LOCAL_TIMEOUT | - AR_INTR_SYNC_RADM_CPL_TIMEOUT)) { + if (AR_SREV_9340(ah)) + tmpReg &= AR9340_INTR_SYNC_LOCAL_TIMEOUT; + else + tmpReg &= AR_INTR_SYNC_LOCAL_TIMEOUT | + AR_INTR_SYNC_RADM_CPL_TIMEOUT; + + if (tmpReg) { u32 val; REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0); diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 0237b2868961..2ba494567777 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -787,8 +787,7 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) hw->wiphy->iface_combinations = if_comb; hw->wiphy->n_iface_combinations = ARRAY_SIZE(if_comb); - if (AR_SREV_5416(sc->sc_ah)) - hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; + hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS; @@ -830,10 +829,6 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) sc->ant_rx = hw->wiphy->available_antennas_rx; sc->ant_tx = hw->wiphy->available_antennas_tx; -#ifdef CONFIG_ATH9K_RATE_CONTROL - hw->rate_control_algorithm = "ath9k_rate_control"; -#endif - if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &sc->sbands[IEEE80211_BAND_2GHZ]; @@ -906,7 +901,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, if (!ath_is_world_regd(reg)) { error = regulatory_hint(hw->wiphy, reg->alpha2); if (error) - goto unregister; + goto debug_cleanup; } ath_init_leds(sc); @@ -914,6 +909,8 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, return 0; +debug_cleanup: + ath9k_deinit_debug(sc); unregister: ieee80211_unregister_hw(hw); rx_cleanup: @@ -942,11 +939,6 @@ static void ath9k_deinit_softc(struct ath_softc *sc) sc->dfs_detector->exit(sc->dfs_detector); ath9k_eeprom_release(sc); - - if (config_enabled(CONFIG_ATH9K_DEBUGFS) && sc->rfs_chan_spec_scan) { - relay_close(sc->rfs_chan_spec_scan); - sc->rfs_chan_spec_scan = NULL; - } } void ath9k_deinit_device(struct ath_softc *sc) @@ -960,6 +952,7 @@ void ath9k_deinit_device(struct ath_softc *sc) ath9k_ps_restore(sc); + ath9k_deinit_debug(sc); ieee80211_unregister_hw(hw); ath_rx_cleanup(sc); ath9k_deinit_softc(sc); diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index 498fee04afa0..566109a40fb3 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c @@ -410,7 +410,7 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q) REG_WRITE(ah, AR_QMISC(q), AR_Q_MISC_DCU_EARLY_TERM_REQ); - if (AR_SREV_9340(ah)) + if (AR_SREV_9340(ah) && !AR_SREV_9340_13_OR_LATER(ah)) REG_WRITE(ah, AR_DMISC(q), AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x1); else diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index a18414b5948b..5092ecae7706 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1687,6 +1687,7 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, u16 tid, u16 *ssn, u8 buf_size) { struct ath_softc *sc = hw->priv; + bool flush = false; int ret = 0; local_bh_disable(); @@ -1703,12 +1704,14 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); ath9k_ps_restore(sc); break; - case IEEE80211_AMPDU_TX_STOP_CONT: case IEEE80211_AMPDU_TX_STOP_FLUSH: case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: + flush = true; + case IEEE80211_AMPDU_TX_STOP_CONT: ath9k_ps_wakeup(sc); ath_tx_aggr_stop(sc, sta, tid); - ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); + if (!flush) + ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); ath9k_ps_restore(sc); break; case IEEE80211_AMPDU_TX_OPERATIONAL: diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index aa4d368d8d3d..7eb1f4b458e4 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -1227,10 +1227,7 @@ static bool ath_tx_aggr_check(struct ath_softc *sc, struct ieee80211_sta *sta, return false; txtid = ATH_AN_2_TID(an, tidno); - - if (!(txtid->state & (AGGR_ADDBA_COMPLETE | AGGR_ADDBA_PROGRESS))) - return true; - return false; + return !txtid->active; } diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h index 267dbfcfaa96..b9a87383cb43 100644 --- a/drivers/net/wireless/ath/ath9k/rc.h +++ b/drivers/net/wireless/ath/ath9k/rc.h @@ -231,7 +231,7 @@ static inline void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix, } #endif -#ifdef CONFIG_ATH9K_RATE_CONTROL +#ifdef CONFIG_ATH9K_LEGACY_RATE_CONTROL int ath_rate_control_register(void); void ath_rate_control_unregister(void); #else diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 5c4ab5026dca..f7c90cc58d56 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -798,6 +798,10 @@ #define AR_SREV_REVISION_9485_10 0 #define AR_SREV_REVISION_9485_11 1 #define AR_SREV_VERSION_9340 0x300 +#define AR_SREV_REVISION_9340_10 0 +#define AR_SREV_REVISION_9340_11 1 +#define AR_SREV_REVISION_9340_12 2 +#define AR_SREV_REVISION_9340_13 3 #define AR_SREV_VERSION_9580 0x1C0 #define AR_SREV_REVISION_9580_10 4 /* AR9580 1.0 */ #define AR_SREV_VERSION_9462 0x280 @@ -897,6 +901,10 @@ #define AR_SREV_9340(_ah) \ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9340)) +#define AR_SREV_9340_13_OR_LATER(_ah) \ + (AR_SREV_9340((_ah)) && \ + ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9340_13)) + #define AR_SREV_9285E_20(_ah) \ (AR_SREV_9285_12_OR_LATER(_ah) && \ ((REG_READ(_ah, AR_AN_SYNTH9) & 0x7) == 0x1)) @@ -1007,6 +1015,8 @@ enum { AR_INTR_SYNC_LOCAL_TIMEOUT | AR_INTR_SYNC_MAC_SLEEP_ACCESS), + AR9340_INTR_SYNC_LOCAL_TIMEOUT = 0x00000010, + AR_INTR_SYNC_SPURIOUS = 0xFFFFFFFF, }; @@ -1881,6 +1891,7 @@ enum { #define AR_PCU_TXBUF_CTRL_SIZE_MASK 0x7FF #define AR_PCU_TXBUF_CTRL_USABLE_SIZE 0x700 #define AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE 0x380 +#define AR_9340_PCU_TXBUF_CTRL_USABLE_SIZE 0x500 #define AR_PCU_MISC_MODE2 0x8344 #define AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE 0x00000002 diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index eab0fcb7ded6..1c9b1bac8b0d 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -125,24 +125,6 @@ static void ath_tx_queue_tid(struct ath_txq *txq, struct ath_atx_tid *tid) list_add_tail(&ac->list, &txq->axq_acq); } -static void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid) -{ - struct ath_txq *txq = tid->ac->txq; - - WARN_ON(!tid->paused); - - ath_txq_lock(sc, txq); - tid->paused = false; - - if (skb_queue_empty(&tid->buf_q)) - goto unlock; - - ath_tx_queue_tid(txq, tid); - ath_txq_schedule(sc, txq); -unlock: - ath_txq_unlock_complete(sc, txq); -} - static struct ath_frame_info *get_frame_info(struct sk_buff *skb) { struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); @@ -201,11 +183,6 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) } } - if (tid->baw_head == tid->baw_tail) { - tid->state &= ~AGGR_ADDBA_COMPLETE; - tid->state &= ~AGGR_CLEANUP; - } - if (sendbar) { ath_txq_unlock(sc, txq); ath_send_bar(tid, tid->seq_start); @@ -277,9 +254,7 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq, list_add_tail(&bf->list, &bf_head); - if (fi->retries) - ath_tx_update_baw(sc, tid, bf->bf_state.seqno); - + ath_tx_update_baw(sc, tid, bf->bf_state.seqno); ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0); } @@ -491,19 +466,19 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, tx_info = IEEE80211_SKB_CB(skb); fi = get_frame_info(skb); - if (ATH_BA_ISSET(ba, ATH_BA_INDEX(seq_st, seqno))) { + if (!BAW_WITHIN(tid->seq_start, tid->baw_size, seqno)) { + /* + * Outside of the current BlockAck window, + * maybe part of a previous session + */ + txfail = 1; + } else if (ATH_BA_ISSET(ba, ATH_BA_INDEX(seq_st, seqno))) { /* transmit completion, subframe is * acked by block ack */ acked_cnt++; } else if (!isaggr && txok) { /* transmit completion */ acked_cnt++; - } else if (tid->state & AGGR_CLEANUP) { - /* - * cleanup in progress, just fail - * the un-acked sub-frames - */ - txfail = 1; } else if (flush) { txpending = 1; } else if (fi->retries < ATH_MAX_SW_RETRIES) { @@ -527,7 +502,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, if (bf_next != NULL || !bf_last->bf_stale) list_move_tail(&bf->list, &bf_head); - if (!txpending || (tid->state & AGGR_CLEANUP)) { + if (!txpending) { /* * complete the acked-ones/xretried ones; update * block-ack window @@ -601,9 +576,6 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, ath_txq_lock(sc, txq); } - if (tid->state & AGGR_CLEANUP) - ath_tx_flush_tid(sc, tid); - rcu_read_unlock(); if (needreset) @@ -620,6 +592,7 @@ static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq, struct ath_tx_status *ts, struct ath_buf *bf, struct list_head *bf_head) { + struct ieee80211_tx_info *info; bool txok, flush; txok = !(ts->ts_status & ATH9K_TXERR_MASK); @@ -631,8 +604,12 @@ static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq, txq->axq_ampdu_depth--; if (!bf_isampdu(bf)) { - if (!flush) + if (!flush) { + info = IEEE80211_SKB_CB(bf->bf_mpdu); + memcpy(info->control.rates, bf->rates, + sizeof(info->control.rates)); ath_tx_rc_status(sc, bf, ts, 1, txok ? 0 : 1, txok); + } ath_tx_complete_buf(sc, bf, txq, bf_head, ts, txok); } else ath_tx_complete_aggr(sc, txq, bf, bf_head, ts, txok); @@ -676,7 +653,7 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf, skb = bf->bf_mpdu; tx_info = IEEE80211_SKB_CB(skb); - rates = tx_info->control.rates; + rates = bf->rates; /* * Find the lowest frame length among the rate series that will have a @@ -1231,9 +1208,6 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, an = (struct ath_node *)sta->drv_priv; txtid = ATH_AN_2_TID(an, tid); - if (txtid->state & (AGGR_CLEANUP | AGGR_ADDBA_COMPLETE)) - return -EAGAIN; - /* update ampdu factor/density, they may have changed. This may happen * in HT IBSS when a beacon with HT-info is received after the station * has already been added. @@ -1245,7 +1219,7 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, an->mpdudensity = density; } - txtid->state |= AGGR_ADDBA_PROGRESS; + txtid->active = true; txtid->paused = true; *ssn = txtid->seq_start = txtid->seq_next; txtid->bar_index = -1; @@ -1262,28 +1236,9 @@ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid); struct ath_txq *txq = txtid->ac->txq; - if (txtid->state & AGGR_CLEANUP) - return; - - if (!(txtid->state & AGGR_ADDBA_COMPLETE)) { - txtid->state &= ~AGGR_ADDBA_PROGRESS; - return; - } - ath_txq_lock(sc, txq); + txtid->active = false; txtid->paused = true; - - /* - * If frames are still being transmitted for this TID, they will be - * cleaned up during tx completion. To prevent race conditions, this - * TID can only be reused after all in-progress subframes have been - * completed. - */ - if (txtid->baw_head != txtid->baw_tail) - txtid->state |= AGGR_CLEANUP; - else - txtid->state &= ~AGGR_ADDBA_COMPLETE; - ath_tx_flush_tid(sc, txtid); ath_txq_unlock_complete(sc, txq); } @@ -1349,18 +1304,28 @@ void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an) } } -void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) +void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, + u16 tidno) { - struct ath_atx_tid *txtid; + struct ath_atx_tid *tid; struct ath_node *an; + struct ath_txq *txq; an = (struct ath_node *)sta->drv_priv; + tid = ATH_AN_2_TID(an, tidno); + txq = tid->ac->txq; - txtid = ATH_AN_2_TID(an, tid); - txtid->baw_size = IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor; - txtid->state |= AGGR_ADDBA_COMPLETE; - txtid->state &= ~AGGR_ADDBA_PROGRESS; - ath_tx_resume_tid(sc, txtid); + ath_txq_lock(sc, txq); + + tid->baw_size = IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor; + tid->paused = false; + + if (!skb_queue_empty(&tid->buf_q)) { + ath_tx_queue_tid(txq, tid); + ath_txq_schedule(sc, txq); + } + + ath_txq_unlock_complete(sc, txq); } /********************/ @@ -2409,12 +2374,10 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an) tid->baw_head = tid->baw_tail = 0; tid->sched = false; tid->paused = false; - tid->state &= ~AGGR_CLEANUP; + tid->active = false; __skb_queue_head_init(&tid->buf_q); acno = TID_TO_WME_AC(tidno); tid->ac = &an->ac[acno]; - tid->state &= ~AGGR_ADDBA_COMPLETE; - tid->state &= ~AGGR_ADDBA_PROGRESS; } for (acno = 0, ac = &an->ac[acno]; @@ -2451,8 +2414,7 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an) } ath_tid_drain(sc, txq, tid); - tid->state &= ~AGGR_ADDBA_COMPLETE; - tid->state &= ~AGGR_CLEANUP; + tid->active = false; ath_txq_unlock(sc, txq); } diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c index 830bb1d1f957..b827d51c30a3 100644 --- a/drivers/net/wireless/atmel.c +++ b/drivers/net/wireless/atmel.c @@ -1624,7 +1624,7 @@ struct net_device *init_atmel_card(unsigned short irq, unsigned long port, netif_carrier_off(dev); - if (!proc_create_data("driver/atmel", 0, NULL, &atmel_proc_fops, priv)); + if (!proc_create_data("driver/atmel", 0, NULL, &atmel_proc_fops, priv)) printk(KERN_WARNING "atmel: unable to create /proc entry.\n"); printk(KERN_INFO "%s: Atmel at76c50x. Version %d.%d. MAC %pM\n", diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 6dd07e2ec595..a95b77ab360e 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -2458,7 +2458,7 @@ static void b43_request_firmware(struct work_struct *work) for (i = 0; i < B43_NR_FWTYPES; i++) { errmsg = ctx->errors[i]; if (strlen(errmsg)) - b43err(dev->wl, errmsg); + b43err(dev->wl, "%s", errmsg); } b43_print_fw_helptext(dev->wl, 1); goto out; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c index be0787cab24f..9431af2465f3 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c @@ -27,7 +27,6 @@ #include "tracepoint.h" #define PKTFILTER_BUF_SIZE 128 -#define BRCMF_ARPOL_MODE 0xb /* agent|snoop|peer_autoreply */ #define BRCMF_DEFAULT_BCN_TIMEOUT 3 #define BRCMF_DEFAULT_SCAN_CHANNEL_TIME 40 #define BRCMF_DEFAULT_SCAN_UNASSOC_TIME 40 @@ -338,23 +337,6 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp) goto done; } - /* Try to set and enable ARP offload feature, this may fail */ - err = brcmf_fil_iovar_int_set(ifp, "arp_ol", BRCMF_ARPOL_MODE); - if (err) { - brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, err = %d\n", - BRCMF_ARPOL_MODE, err); - err = 0; - } else { - err = brcmf_fil_iovar_int_set(ifp, "arpoe", 1); - if (err) { - brcmf_dbg(TRACE, "failed to enable ARP offload err = %d\n", - err); - err = 0; - } else - brcmf_dbg(TRACE, "successfully enabled ARP offload to 0x%x\n", - BRCMF_ARPOL_MODE); - } - /* Setup packet filter */ brcmf_c_pktfilter_offload_set(ifp, BRCMF_DEFAULT_PACKET_FILTER); brcmf_c_pktfilter_offload_enable(ifp, BRCMF_DEFAULT_PACKET_FILTER, diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index 59c25463e428..b98f2235978e 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -653,10 +653,13 @@ int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked) brcmf_dbg(INFO, "%s: Broadcom Dongle Host Driver\n", ndev->name); + ndev->destructor = free_netdev; return 0; fail: + drvr->iflist[ifp->bssidx] = NULL; ndev->netdev_ops = NULL; + free_netdev(ndev); return -EBADE; } @@ -720,6 +723,9 @@ static int brcmf_net_p2p_attach(struct brcmf_if *ifp) return 0; fail: + ifp->drvr->iflist[ifp->bssidx] = NULL; + ndev->netdev_ops = NULL; + free_netdev(ndev); return -EBADE; } @@ -788,6 +794,7 @@ void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx) struct brcmf_if *ifp; ifp = drvr->iflist[bssidx]; + drvr->iflist[bssidx] = NULL; if (!ifp) { brcmf_err("Null interface, idx=%d\n", bssidx); return; @@ -808,15 +815,13 @@ void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx) cancel_work_sync(&ifp->setmacaddr_work); cancel_work_sync(&ifp->multicast_work); } - + /* unregister will take care of freeing it */ unregister_netdev(ifp->ndev); if (bssidx == 0) brcmf_cfg80211_detach(drvr->config); - free_netdev(ifp->ndev); } else { kfree(ifp); } - drvr->iflist[bssidx] = NULL; } int brcmf_attach(uint bus_hdrlen, struct device *dev) @@ -925,8 +930,6 @@ fail: brcmf_fws_del_interface(ifp); brcmf_fws_deinit(drvr); } - free_netdev(ifp->ndev); - drvr->iflist[0] = NULL; if (p2p_ifp) { free_netdev(p2p_ifp->ndev); drvr->iflist[1] = NULL; @@ -934,7 +937,8 @@ fail: return ret; } if ((brcmf_p2p_enable) && (p2p_ifp)) - brcmf_net_p2p_attach(p2p_ifp); + if (brcmf_net_p2p_attach(p2p_ifp) < 0) + brcmf_p2p_enable = 0; return 0; } diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c index 5a64280e6485..83ee53a7c76e 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c @@ -202,7 +202,8 @@ static void brcmf_fweh_handle_if_event(struct brcmf_pub *drvr, return; brcmf_fws_add_interface(ifp); if (!drvr->fweh.evt_handler[BRCMF_E_IF]) - err = brcmf_net_attach(ifp, false); + if (brcmf_net_attach(ifp, false) < 0) + return; } if (ifevent->action == BRCMF_E_IF_CHANGE) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h b/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h index 0f2c83bc95dc..665ef69e974b 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h @@ -23,6 +23,12 @@ #define BRCMF_FIL_ACTION_FRAME_SIZE 1800 +/* ARP Offload feature flags for arp_ol iovar */ +#define BRCMF_ARP_OL_AGENT 0x00000001 +#define BRCMF_ARP_OL_SNOOP 0x00000002 +#define BRCMF_ARP_OL_HOST_AUTO_REPLY 0x00000004 +#define BRCMF_ARP_OL_PEER_AUTO_REPLY 0x00000008 + enum brcmf_fil_p2p_if_types { BRCMF_FIL_P2P_IF_CLIENT, diff --git a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c index e7a1a4770996..79555f006d53 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c @@ -47,6 +47,7 @@ #define IS_P2P_SOCIAL_CHANNEL(channel) ((channel == SOCIAL_CHAN_1) || \ (channel == SOCIAL_CHAN_2) || \ (channel == SOCIAL_CHAN_3)) +#define BRCMF_P2P_TEMP_CHAN SOCIAL_CHAN_3 #define SOCIAL_CHAN_CNT 3 #define AF_PEER_SEARCH_CNT 2 @@ -1954,21 +1955,21 @@ s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg) err = brcmf_fil_iovar_int_set(pri_ifp, "p2p_disc", 1); if (err < 0) { brcmf_err("set p2p_disc error\n"); - brcmf_free_vif(p2p_vif); + brcmf_free_vif(cfg, p2p_vif); goto exit; } /* obtain bsscfg index for P2P discovery */ err = brcmf_fil_iovar_int_get(pri_ifp, "p2p_dev", &bssidx); if (err < 0) { brcmf_err("retrieving discover bsscfg index failed\n"); - brcmf_free_vif(p2p_vif); + brcmf_free_vif(cfg, p2p_vif); goto exit; } /* Verify that firmware uses same bssidx as driver !! */ if (p2p_ifp->bssidx != bssidx) { brcmf_err("Incorrect bssidx=%d, compared to p2p_ifp->bssidx=%d\n", bssidx, p2p_ifp->bssidx); - brcmf_free_vif(p2p_vif); + brcmf_free_vif(cfg, p2p_vif); goto exit; } @@ -1996,7 +1997,7 @@ void brcmf_p2p_detach(struct brcmf_p2p_info *p2p) brcmf_p2p_cancel_remain_on_channel(vif->ifp); brcmf_p2p_deinit_discovery(p2p); /* remove discovery interface */ - brcmf_free_vif(vif); + brcmf_free_vif(p2p->cfg, vif); p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL; } /* just set it all to zero */ @@ -2013,17 +2014,30 @@ static void brcmf_p2p_get_current_chanspec(struct brcmf_p2p_info *p2p, u16 *chanspec) { struct brcmf_if *ifp; - struct brcmf_fil_chan_info_le ci; + u8 mac_addr[ETH_ALEN]; struct brcmu_chan ch; - s32 err; + struct brcmf_bss_info_le *bi; + u8 *buf; ifp = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp; - ch.chnum = 11; - - err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_CHANNEL, &ci, sizeof(ci)); - if (!err) - ch.chnum = le32_to_cpu(ci.hw_channel); + if (brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSSID, mac_addr, + ETH_ALEN) == 0) { + buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL); + if (buf != NULL) { + *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX); + if (brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO, + buf, WL_BSS_INFO_MAX) == 0) { + bi = (struct brcmf_bss_info_le *)(buf + 4); + *chanspec = le16_to_cpu(bi->chanspec); + kfree(buf); + return; + } + kfree(buf); + } + } + /* Use default channel for P2P */ + ch.chnum = BRCMF_P2P_TEMP_CHAN; ch.bw = BRCMU_CHAN_BW_20; p2p->cfg->d11inf.encchspec(&ch); *chanspec = ch.chspec; @@ -2208,7 +2222,7 @@ static struct wireless_dev *brcmf_p2p_create_p2pdev(struct brcmf_p2p_info *p2p, return &p2p_vif->wdev; fail: - brcmf_free_vif(p2p_vif); + brcmf_free_vif(p2p->cfg, p2p_vif); return ERR_PTR(err); } @@ -2217,13 +2231,31 @@ fail: * * @vif: virtual interface object to delete. */ -static void brcmf_p2p_delete_p2pdev(struct brcmf_cfg80211_vif *vif) +static void brcmf_p2p_delete_p2pdev(struct brcmf_cfg80211_info *cfg, + struct brcmf_cfg80211_vif *vif) { - struct brcmf_p2p_info *p2p = &vif->ifp->drvr->config->p2p; - cfg80211_unregister_wdev(&vif->wdev); - p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL; - brcmf_free_vif(vif); + cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL; + brcmf_free_vif(cfg, vif); +} + +/** + * brcmf_p2p_free_p2p_if() - free up net device related data. + * + * @ndev: net device that needs to be freed. + */ +static void brcmf_p2p_free_p2p_if(struct net_device *ndev) +{ + struct brcmf_cfg80211_info *cfg; + struct brcmf_cfg80211_vif *vif; + struct brcmf_if *ifp; + + ifp = netdev_priv(ndev); + cfg = ifp->drvr->config; + vif = ifp->vif; + + brcmf_free_vif(cfg, vif); + free_netdev(ifp->ndev); } /** @@ -2303,6 +2335,9 @@ struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name, brcmf_err("Registering netdevice failed\n"); goto fail; } + /* override destructor */ + ifp->ndev->destructor = brcmf_p2p_free_p2p_if; + cfg->p2p.bss_idx[P2PAPI_BSSCFG_CONNECTION].vif = vif; /* Disable firmware roaming for P2P interface */ brcmf_fil_iovar_int_set(ifp, "roam_off", 1); @@ -2314,7 +2349,7 @@ struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name, return &ifp->vif->wdev; fail: - brcmf_free_vif(vif); + brcmf_free_vif(cfg, vif); return ERR_PTR(err); } @@ -2350,7 +2385,7 @@ int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev) break; case NL80211_IFTYPE_P2P_DEVICE: - brcmf_p2p_delete_p2pdev(vif); + brcmf_p2p_delete_p2pdev(cfg, vif); return 0; default: return -ENOTSUPP; @@ -2378,7 +2413,6 @@ int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev) err = 0; } brcmf_cfg80211_arm_vif_event(cfg, NULL); - brcmf_free_vif(vif); p2p->bss_idx[P2PAPI_BSSCFG_CONNECTION].vif = NULL; return err; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 6d758f285352..301e572e8923 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c @@ -459,6 +459,38 @@ send_key_to_dongle(struct net_device *ndev, struct brcmf_wsec_key *key) return err; } +static s32 +brcmf_configure_arp_offload(struct brcmf_if *ifp, bool enable) +{ + s32 err; + u32 mode; + + if (enable) + mode = BRCMF_ARP_OL_AGENT | BRCMF_ARP_OL_PEER_AUTO_REPLY; + else + mode = 0; + + /* Try to set and enable ARP offload feature, this may fail, then it */ + /* is simply not supported and err 0 will be returned */ + err = brcmf_fil_iovar_int_set(ifp, "arp_ol", mode); + if (err) { + brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, err = %d\n", + mode, err); + err = 0; + } else { + err = brcmf_fil_iovar_int_set(ifp, "arpoe", enable); + if (err) { + brcmf_dbg(TRACE, "failed to configure (%d) ARP offload err = %d\n", + enable, err); + err = 0; + } else + brcmf_dbg(TRACE, "successfully configured (%d) ARP offload to 0x%x\n", + enable, mode); + } + + return err; +} + static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy, const char *name, enum nl80211_iftype type, @@ -2216,6 +2248,11 @@ brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev, } pm = enabled ? PM_FAST : PM_OFF; + /* Do not enable the power save after assoc if it is a p2p interface */ + if (ifp->vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) { + brcmf_dbg(INFO, "Do not enable power save for P2P clients\n"); + pm = PM_OFF; + } brcmf_dbg(INFO, "power save %s\n", (pm ? "enabled" : "disabled")); err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, pm); @@ -3640,10 +3677,28 @@ brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif *vif, } static s32 +brcmf_cfg80211_set_channel(struct brcmf_cfg80211_info *cfg, + struct brcmf_if *ifp, + struct ieee80211_channel *channel) +{ + u16 chanspec; + s32 err; + + brcmf_dbg(TRACE, "band=%d, center_freq=%d\n", channel->band, + channel->center_freq); + + chanspec = channel_to_chanspec(&cfg->d11inf, channel); + err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec); + + return err; +} + +static s32 brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_ap_settings *settings) { s32 ie_offset; + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); struct brcmf_if *ifp = netdev_priv(ndev); struct brcmf_tlv *ssid_ie; struct brcmf_ssid_le ssid_le; @@ -3683,6 +3738,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, } brcmf_set_mpc(ifp, 0); + brcmf_configure_arp_offload(ifp, false); /* find the RSN_IE */ rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail, @@ -3713,6 +3769,12 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon); + err = brcmf_cfg80211_set_channel(cfg, ifp, settings->chandef.chan); + if (err < 0) { + brcmf_err("Set Channel failed, %d\n", err); + goto exit; + } + if (settings->beacon_interval) { err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD, settings->beacon_interval); @@ -3789,8 +3851,10 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state); exit: - if (err) + if (err) { brcmf_set_mpc(ifp, 1); + brcmf_configure_arp_offload(ifp, true); + } return err; } @@ -3831,6 +3895,7 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev) brcmf_err("bss_enable config failed %d\n", err); } brcmf_set_mpc(ifp, 1); + brcmf_configure_arp_offload(ifp, true); set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state); clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state); @@ -4140,11 +4205,15 @@ static const struct ieee80211_iface_limit brcmf_iface_limits[] = { .types = BIT(NL80211_IFTYPE_P2P_CLIENT) | BIT(NL80211_IFTYPE_P2P_GO) }, + { + .max = 1, + .types = BIT(NL80211_IFTYPE_P2P_DEVICE) + } }; static const struct ieee80211_iface_combination brcmf_iface_combos[] = { { .max_interfaces = BRCMF_IFACE_MAX_CNT, - .num_different_channels = 1, /* no multi-channel for now */ + .num_different_channels = 2, .n_limits = ARRAY_SIZE(brcmf_iface_limits), .limits = brcmf_iface_limits } @@ -4197,7 +4266,8 @@ static struct wiphy *brcmf_setup_wiphy(struct device *phydev) BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_P2P_CLIENT) | - BIT(NL80211_IFTYPE_P2P_GO); + BIT(NL80211_IFTYPE_P2P_GO) | + BIT(NL80211_IFTYPE_P2P_DEVICE); wiphy->iface_combinations = brcmf_iface_combos; wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos); wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz; @@ -4251,20 +4321,16 @@ struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg, return vif; } -void brcmf_free_vif(struct brcmf_cfg80211_vif *vif) +void brcmf_free_vif(struct brcmf_cfg80211_info *cfg, + struct brcmf_cfg80211_vif *vif) { - struct brcmf_cfg80211_info *cfg; - struct wiphy *wiphy; - - wiphy = vif->wdev.wiphy; - cfg = wiphy_priv(wiphy); list_del(&vif->list); cfg->vif_cnt--; kfree(vif); if (!cfg->vif_cnt) { - wiphy_unregister(wiphy); - wiphy_free(wiphy); + wiphy_unregister(cfg->wiphy); + wiphy_free(cfg->wiphy); } } @@ -4641,7 +4707,6 @@ static s32 brcmf_notify_vif_event(struct brcmf_if *ifp, return 0; case BRCMF_E_IF_DEL: - ifp->vif = NULL; mutex_unlock(&event->vif_event_lock); /* event may not be upon user request */ if (brcmf_cfg80211_vif_event_armed(cfg)) @@ -4847,8 +4912,7 @@ cfg80211_p2p_attach_out: wl_deinit_priv(cfg); cfg80211_attach_out: - brcmf_free_vif(vif); - wiphy_free(wiphy); + brcmf_free_vif(cfg, vif); return NULL; } @@ -4860,7 +4924,7 @@ void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg) wl_deinit_priv(cfg); brcmf_btcoex_detach(cfg); list_for_each_entry_safe(vif, tmp, &cfg->vif_list, list) { - brcmf_free_vif(vif); + brcmf_free_vif(cfg, vif); } } @@ -5224,6 +5288,8 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg) if (err) goto default_conf_out; + brcmf_configure_arp_offload(ifp, true); + cfg->dongle_up = true; default_conf_out: diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h index a71cff84cdcf..d9bdaf9a72d0 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h @@ -487,7 +487,8 @@ enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp); struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg, enum nl80211_iftype type, bool pm_block); -void brcmf_free_vif(struct brcmf_cfg80211_vif *vif); +void brcmf_free_vif(struct brcmf_cfg80211_info *cfg, + struct brcmf_cfg80211_vif *vif); s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag, const u8 *vndr_ie_buf, u32 vndr_ie_len); diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c index 592d0aa634a8..e9a3cbc409ae 100644 --- a/drivers/net/wireless/iwlegacy/common.c +++ b/drivers/net/wireless/iwlegacy/common.c @@ -1423,7 +1423,7 @@ il_setup_rx_scan_handlers(struct il_priv *il) } EXPORT_SYMBOL(il_setup_rx_scan_handlers); -inline u16 +u16 il_get_active_dwell_time(struct il_priv *il, enum ieee80211_band band, u8 n_probes) { diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h index f8246f2d88f9..4caaf52986a4 100644 --- a/drivers/net/wireless/iwlegacy/common.h +++ b/drivers/net/wireless/iwlegacy/common.h @@ -1832,16 +1832,16 @@ u32 il_usecs_to_beacons(struct il_priv *il, u32 usec, u32 beacon_interval); __le32 il_add_beacon_time(struct il_priv *il, u32 base, u32 addon, u32 beacon_interval); -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP extern const struct dev_pm_ops il_pm_ops; #define IL_LEGACY_PM_OPS (&il_pm_ops) -#else /* !CONFIG_PM */ +#else /* !CONFIG_PM_SLEEP */ #define IL_LEGACY_PM_OPS NULL -#endif /* !CONFIG_PM */ +#endif /* !CONFIG_PM_SLEEP */ /***************************************************** * Error Handling Debugging diff --git a/drivers/net/wireless/iwlwifi/dvm/sta.c b/drivers/net/wireless/iwlwifi/dvm/sta.c index db183b44e038..c3c13ce96eb0 100644 --- a/drivers/net/wireless/iwlwifi/dvm/sta.c +++ b/drivers/net/wireless/iwlwifi/dvm/sta.c @@ -735,7 +735,7 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx) memcpy(&lq, priv->stations[i].lq, sizeof(struct iwl_link_quality_cmd)); - if (!memcmp(&lq, &zero_lq, sizeof(lq))) + if (memcmp(&lq, &zero_lq, sizeof(lq))) send_lq = true; } spin_unlock_bh(&priv->sta_lock); diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h index 191dcae8ba47..c6384555aab4 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h @@ -173,6 +173,8 @@ enum { REPLY_DEBUG_CMD = 0xf0, DEBUG_LOG_MSG = 0xf7, + MCAST_FILTER_CMD = 0xd0, + /* D3 commands/notifications */ D3_CONFIG_CMD = 0xd3, PROT_OFFLOAD_CONFIG_CMD = 0xd4, @@ -948,4 +950,29 @@ struct iwl_set_calib_default_cmd { u8 data[0]; } __packed; /* PHY_CALIB_OVERRIDE_VALUES_S */ +#define MAX_PORT_ID_NUM 2 + +/** + * struct iwl_mcast_filter_cmd - configure multicast filter. + * @filter_own: Set 1 to filter out multicast packets sent by station itself + * @port_id: Multicast MAC addresses array specifier. This is a strange way + * to identify network interface adopted in host-device IF. + * It is used by FW as index in array of addresses. This array has + * MAX_PORT_ID_NUM members. + * @count: Number of MAC addresses in the array + * @pass_all: Set 1 to pass all multicast packets. + * @bssid: current association BSSID. + * @addr_list: Place holder for array of MAC addresses. + * IMPORTANT: add padding if necessary to ensure DWORD alignment. + */ +struct iwl_mcast_filter_cmd { + u8 filter_own; + u8 port_id; + u8 count; + u8 pass_all; + u8 bssid[6]; + u8 reserved[2]; + u8 addr_list[0]; +} __packed; /* MCAST_FILTERING_CMD_API_S_VER_1 */ + #endif /* __fw_api_h__ */ diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c index e6eca4d66f6c..b2cc3d98e0f7 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c @@ -586,10 +586,12 @@ static int iwl_mvm_mac_ctxt_send_cmd(struct iwl_mvm *mvm, */ static void iwl_mvm_mac_ctxt_cmd_fill_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, - struct iwl_mac_data_sta *ctxt_sta) + struct iwl_mac_data_sta *ctxt_sta, + bool force_assoc_off) { /* We need the dtim_period to set the MAC as associated */ - if (vif->bss_conf.assoc && vif->bss_conf.dtim_period) { + if (vif->bss_conf.assoc && vif->bss_conf.dtim_period && + !force_assoc_off) { u32 dtim_offs; /* @@ -659,7 +661,8 @@ static int iwl_mvm_mac_ctxt_cmd_station(struct iwl_mvm *mvm, cmd.filter_flags &= ~cpu_to_le32(MAC_FILTER_IN_BEACON); /* Fill the data specific for station mode */ - iwl_mvm_mac_ctxt_cmd_fill_sta(mvm, vif, &cmd.sta); + iwl_mvm_mac_ctxt_cmd_fill_sta(mvm, vif, &cmd.sta, + action == FW_CTXT_ACTION_ADD); return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd); } @@ -677,7 +680,8 @@ static int iwl_mvm_mac_ctxt_cmd_p2p_client(struct iwl_mvm *mvm, iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); /* Fill the data specific for station mode */ - iwl_mvm_mac_ctxt_cmd_fill_sta(mvm, vif, &cmd.p2p_sta.sta); + iwl_mvm_mac_ctxt_cmd_fill_sta(mvm, vif, &cmd.p2p_sta.sta, + action == FW_CTXT_ACTION_ADD); cmd.p2p_sta.ctwin = cpu_to_le32(noa->oppps_ctwindow & IEEE80211_P2P_OPPPS_CTWINDOW_MASK); diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index dd158ec571fb..a5eb8c82f16a 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -701,6 +701,20 @@ static void iwl_mvm_configure_filter(struct ieee80211_hw *hw, *total_flags = 0; } +static int iwl_mvm_configure_mcast_filter(struct iwl_mvm *mvm, + struct ieee80211_vif *vif) +{ + struct iwl_mcast_filter_cmd mcast_filter_cmd = { + .pass_all = 1, + }; + + memcpy(mcast_filter_cmd.bssid, vif->bss_conf.bssid, ETH_ALEN); + + return iwl_mvm_send_cmd_pdu(mvm, MCAST_FILTER_CMD, CMD_SYNC, + sizeof(mcast_filter_cmd), + &mcast_filter_cmd); +} + static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct ieee80211_bss_conf *bss_conf, @@ -722,6 +736,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm, return; } iwl_mvm_bt_coex_vif_assoc(mvm, vif); + iwl_mvm_configure_mcast_filter(mvm, vif); } else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) { /* remove AP station now that the MAC is unassoc */ ret = iwl_mvm_rm_sta_id(mvm, vif, mvmvif->ap_sta_id); @@ -931,7 +946,7 @@ static void iwl_mvm_mac_sta_notify(struct ieee80211_hw *hw, switch (cmd) { case STA_NOTIFY_SLEEP: - if (atomic_read(&mvmsta->pending_frames) > 0) + if (atomic_read(&mvm->pending_frames[mvmsta->sta_id]) > 0) ieee80211_sta_block_awake(hw, sta, true); /* * The fw updates the STA to be asleep. Tx packets on the Tx diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 8269bc562951..9f46b23801bc 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -292,6 +292,7 @@ struct iwl_mvm { struct ieee80211_sta __rcu *fw_id_to_mac_id[IWL_MVM_STATION_COUNT]; struct work_struct sta_drained_wk; unsigned long sta_drained[BITS_TO_LONGS(IWL_MVM_STATION_COUNT)]; + atomic_t pending_frames[IWL_MVM_STATION_COUNT]; /* configured by mac80211 */ u32 rts_threshold; diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index fe031d304d1e..b29c31a41594 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c @@ -292,6 +292,7 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = { CMD(BT_COEX_PROT_ENV), CMD(BT_PROFILE_NOTIFICATION), CMD(BT_CONFIG), + CMD(MCAST_FILTER_CMD), }; #undef CMD diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c index 2157b0f8ced5..2476e43799d5 100644 --- a/drivers/net/wireless/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/iwlwifi/mvm/scan.c @@ -298,6 +298,12 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm, else cmd->type = cpu_to_le32(SCAN_TYPE_FORCED); + /* + * TODO: This is a WA due to a bug in the FW AUX framework that does not + * properly handle time events that fail to be scheduled + */ + cmd->type = cpu_to_le32(SCAN_TYPE_FORCED); + cmd->repeats = cpu_to_le32(1); /* diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c index 0fd96e4da461..5c664ed54400 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/iwlwifi/mvm/sta.c @@ -219,7 +219,7 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm, mvm_sta->max_agg_bufsize = LINK_QUAL_AGG_FRAME_LIMIT_DEF; /* HW restart, don't assume the memory has been zeroed */ - atomic_set(&mvm_sta->pending_frames, 0); + atomic_set(&mvm->pending_frames[sta_id], 0); mvm_sta->tid_disable_agg = 0; mvm_sta->tfd_queue_msk = 0; for (i = 0; i < IEEE80211_NUM_ACS; i++) @@ -407,14 +407,21 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm, } /* + * Make sure that the tx response code sees the station as -EBUSY and + * calls the drain worker. + */ + spin_lock_bh(&mvm_sta->lock); + /* * There are frames pending on the AC queues for this station. * We need to wait until all the frames are drained... */ - if (atomic_read(&mvm_sta->pending_frames)) { - ret = iwl_mvm_drain_sta(mvm, mvm_sta, true); + if (atomic_read(&mvm->pending_frames[mvm_sta->sta_id])) { rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id], ERR_PTR(-EBUSY)); + spin_unlock_bh(&mvm_sta->lock); + ret = iwl_mvm_drain_sta(mvm, mvm_sta, true); } else { + spin_unlock_bh(&mvm_sta->lock); ret = iwl_mvm_rm_sta_common(mvm, mvm_sta->sta_id); rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id], NULL); } diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.h b/drivers/net/wireless/iwlwifi/mvm/sta.h index 12abd2d71835..a4ddce77aaae 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.h +++ b/drivers/net/wireless/iwlwifi/mvm/sta.h @@ -274,7 +274,6 @@ struct iwl_mvm_tid_data { * @bt_reduced_txpower: is reduced tx power enabled for this station * @lock: lock to protect the whole struct. Since %tid_data is access from Tx * and from Tx response flow, it needs a spinlock. - * @pending_frames: number of frames for this STA on the shared Tx queues. * @tid_data: per tid data. Look at %iwl_mvm_tid_data. * * When mac80211 creates a station it reserves some space (hw->sta_data_size) @@ -290,7 +289,6 @@ struct iwl_mvm_sta { u8 max_agg_bufsize; bool bt_reduced_txpower; spinlock_t lock; - atomic_t pending_frames; struct iwl_mvm_tid_data tid_data[IWL_MAX_TID_COUNT]; struct iwl_lq_sta lq_sta; struct ieee80211_vif *vif; diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c index 479074303bd7..f212f16502ff 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/iwlwifi/mvm/tx.c @@ -416,9 +416,8 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb, spin_unlock(&mvmsta->lock); - if (mvmsta->vif->type == NL80211_IFTYPE_AP && - txq_id < IWL_MVM_FIRST_AGG_QUEUE) - atomic_inc(&mvmsta->pending_frames); + if (txq_id < IWL_MVM_FIRST_AGG_QUEUE) + atomic_inc(&mvm->pending_frames[mvmsta->sta_id]); return 0; @@ -680,16 +679,41 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, /* * If the txq is not an AMPDU queue, there is no chance we freed * several skbs. Check that out... - * If there are no pending frames for this STA, notify mac80211 that - * this station can go to sleep in its STA table. */ - if (txq_id < IWL_MVM_FIRST_AGG_QUEUE && mvmsta && - !WARN_ON(skb_freed > 1) && - mvmsta->vif->type == NL80211_IFTYPE_AP && - atomic_sub_and_test(skb_freed, &mvmsta->pending_frames)) { - ieee80211_sta_block_awake(mvm->hw, sta, false); - set_bit(sta_id, mvm->sta_drained); - schedule_work(&mvm->sta_drained_wk); + if (txq_id < IWL_MVM_FIRST_AGG_QUEUE && !WARN_ON(skb_freed > 1) && + atomic_sub_and_test(skb_freed, &mvm->pending_frames[sta_id])) { + if (mvmsta) { + /* + * If there are no pending frames for this STA, notify + * mac80211 that this station can go to sleep in its + * STA table. + */ + if (mvmsta->vif->type == NL80211_IFTYPE_AP) + ieee80211_sta_block_awake(mvm->hw, sta, false); + /* + * We might very well have taken mvmsta pointer while + * the station was being removed. The remove flow might + * have seen a pending_frame (because we didn't take + * the lock) even if now the queues are drained. So make + * really sure now that this the station is not being + * removed. If it is, run the drain worker to remove it. + */ + spin_lock_bh(&mvmsta->lock); + sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]); + if (IS_ERR_OR_NULL(sta)) { + /* + * Station disappeared in the meantime: + * so we are draining. + */ + set_bit(sta_id, mvm->sta_drained); + schedule_work(&mvm->sta_drained_wk); + } + spin_unlock_bh(&mvmsta->lock); + } else if (!mvmsta) { + /* Tx response without STA, so we are draining */ + set_bit(sta_id, mvm->sta_drained); + schedule_work(&mvm->sta_drained_wk); + } } rcu_read_unlock(); diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index b878a32e7a98..cb34c7895f2a 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -1723,11 +1723,11 @@ static void mac80211_hwsim_free(void) class_destroy(hwsim_class); } - -static struct device_driver mac80211_hwsim_driver = { - .name = "mac80211_hwsim", - .bus = &platform_bus_type, - .owner = THIS_MODULE, +static struct platform_driver mac80211_hwsim_driver = { + .driver = { + .name = "mac80211_hwsim", + .owner = THIS_MODULE, + }, }; static const struct net_device_ops hwsim_netdev_ops = { @@ -2219,7 +2219,7 @@ static int __init init_mac80211_hwsim(void) spin_lock_init(&hwsim_radio_lock); INIT_LIST_HEAD(&hwsim_radios); - err = driver_register(&mac80211_hwsim_driver); + err = platform_driver_register(&mac80211_hwsim_driver); if (err) return err; @@ -2254,7 +2254,7 @@ static int __init init_mac80211_hwsim(void) err = -ENOMEM; goto failed_drvdata; } - data->dev->driver = &mac80211_hwsim_driver; + data->dev->driver = &mac80211_hwsim_driver.driver; err = device_bind_driver(data->dev); if (err != 0) { printk(KERN_DEBUG @@ -2564,7 +2564,7 @@ failed_drvdata: failed: mac80211_hwsim_free(); failed_unregister_driver: - driver_unregister(&mac80211_hwsim_driver); + platform_driver_unregister(&mac80211_hwsim_driver); return err; } module_init(init_mac80211_hwsim); @@ -2577,6 +2577,6 @@ static void __exit exit_mac80211_hwsim(void) mac80211_hwsim_free(); unregister_netdev(hwsim_mon); - driver_unregister(&mac80211_hwsim_driver); + platform_driver_unregister(&mac80211_hwsim_driver); } module_exit(exit_mac80211_hwsim); diff --git a/drivers/net/wireless/mwifiex/debugfs.c b/drivers/net/wireless/mwifiex/debugfs.c index 753b5682d53f..a5f9875cfd6e 100644 --- a/drivers/net/wireless/mwifiex/debugfs.c +++ b/drivers/net/wireless/mwifiex/debugfs.c @@ -26,10 +26,17 @@ static struct dentry *mwifiex_dfs_dir; static char *bss_modes[] = { - "Unknown", - "Ad-hoc", - "Managed", - "Auto" + "UNSPECIFIED", + "ADHOC", + "STATION", + "AP", + "AP_VLAN", + "WDS", + "MONITOR", + "MESH_POINT", + "P2P_CLIENT", + "P2P_GO", + "P2P_DEVICE", }; /* size/addr for mwifiex_debug_info */ @@ -200,7 +207,12 @@ mwifiex_info_read(struct file *file, char __user *ubuf, p += sprintf(p, "driver_version = %s", fmt); p += sprintf(p, "\nverext = %s", priv->version_str); p += sprintf(p, "\ninterface_name=\"%s\"\n", netdev->name); - p += sprintf(p, "bss_mode=\"%s\"\n", bss_modes[info.bss_mode]); + + if (info.bss_mode >= ARRAY_SIZE(bss_modes)) + p += sprintf(p, "bss_mode=\"%d\"\n", info.bss_mode); + else + p += sprintf(p, "bss_mode=\"%s\"\n", bss_modes[info.bss_mode]); + p += sprintf(p, "media_state=\"%s\"\n", (!priv->media_connected ? "Disconnected" : "Connected")); p += sprintf(p, "mac_address=\"%pM\"\n", netdev->dev_addr); diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 999ffc12578b..c97e9d327331 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -764,6 +764,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) "can't alloc skb for rx\n"); goto done; } + kmemleak_not_leak(new_skb); pci_unmap_single(rtlpci->pdev, *((dma_addr_t *) skb->cb), diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/trx.h b/drivers/net/wireless/rtlwifi/rtl8188ee/trx.h index d3a02e73f53a..21ca33a7c770 100644 --- a/drivers/net/wireless/rtlwifi/rtl8188ee/trx.h +++ b/drivers/net/wireless/rtlwifi/rtl8188ee/trx.h @@ -550,7 +550,7 @@ do { \ rxmcs == DESC92C_RATE11M) struct phy_rx_agc_info_t { - #if __LITTLE_ENDIAN + #ifdef __LITTLE_ENDIAN u8 gain:7, trsw:1; #else u8 trsw:1, gain:7; @@ -574,7 +574,7 @@ struct phy_status_rpt { u8 stream_target_csi[2]; u8 sig_evm; u8 rsvd_3; -#if __LITTLE_ENDIAN +#ifdef __LITTLE_ENDIAN u8 antsel_rx_keep_2:1; /*ex_intf_flg:1;*/ u8 sgi_en:1; u8 rxsc:2; diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c index 3d0498e69c8c..189ba124a8c6 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c @@ -1973,26 +1973,35 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) } } -void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw, - struct ieee80211_sta *sta, - u8 rssi_level) +static void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw, + struct ieee80211_sta *sta) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_phy *rtlphy = &(rtlpriv->phy); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - u32 ratr_value = (u32) mac->basic_rates; - u8 *mcsrate = mac->mcs; + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u32 ratr_value; u8 ratr_index = 0; u8 nmode = mac->ht_enable; - u8 mimo_ps = 1; - u16 shortgi_rate = 0; - u32 tmp_ratr_value = 0; + u8 mimo_ps = IEEE80211_SMPS_OFF; + u16 shortgi_rate; + u32 tmp_ratr_value; u8 curtxbw_40mhz = mac->bw_40; - u8 curshortgi_40mhz = mac->sgi_40; - u8 curshortgi_20mhz = mac->sgi_20; + u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? + 1 : 0; + u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? + 1 : 0; enum wireless_mode wirelessmode = mac->mode; - ratr_value |= ((*(u16 *) (mcsrate))) << 12; + if (rtlhal->current_bandtype == BAND_ON_5G) + ratr_value = sta->supp_rates[1] << 4; + else + ratr_value = sta->supp_rates[0]; + if (mac->opmode == NL80211_IFTYPE_ADHOC) + ratr_value = 0xfff; + + ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 | + sta->ht_cap.mcs.rx_mask[0] << 12); switch (wirelessmode) { case WIRELESS_MODE_B: if (ratr_value & 0x0000000c) @@ -2006,7 +2015,7 @@ void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw, case WIRELESS_MODE_N_24G: case WIRELESS_MODE_N_5G: nmode = 1; - if (mimo_ps == 0) { + if (mimo_ps == IEEE80211_SMPS_STATIC) { ratr_value &= 0x0007F005; } else { u32 ratr_mask; @@ -2016,8 +2025,7 @@ void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw, ratr_mask = 0x000ff005; else ratr_mask = 0x0f0ff005; - if (curtxbw_40mhz) - ratr_mask |= 0x00000010; + ratr_value &= ratr_mask; } break; @@ -2026,41 +2034,74 @@ void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw, ratr_value &= 0x000ff0ff; else ratr_value &= 0x0f0ff0ff; + break; } + ratr_value &= 0x0FFFFFFF; - if (nmode && ((curtxbw_40mhz && curshortgi_40mhz) || - (!curtxbw_40mhz && curshortgi_20mhz))) { + + if (nmode && ((curtxbw_40mhz && + curshortgi_40mhz) || (!curtxbw_40mhz && + curshortgi_20mhz))) { + ratr_value |= 0x10000000; tmp_ratr_value = (ratr_value >> 12); + for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) { if ((1 << shortgi_rate) & tmp_ratr_value) break; } + shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) | - (shortgi_rate << 4) | (shortgi_rate); + (shortgi_rate << 4) | (shortgi_rate); } + rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value); + + RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n", + rtl_read_dword(rtlpriv, REG_ARFR0)); } -void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level) +static void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, + u8 rssi_level) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_phy *rtlphy = &(rtlpriv->phy); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - u32 ratr_bitmap = (u32) mac->basic_rates; - u8 *p_mcsrate = mac->mcs; - u8 ratr_index = 0; - u8 curtxbw_40mhz = mac->bw_40; - u8 curshortgi_40mhz = mac->sgi_40; - u8 curshortgi_20mhz = mac->sgi_20; - enum wireless_mode wirelessmode = mac->mode; + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_sta_info *sta_entry = NULL; + u32 ratr_bitmap; + u8 ratr_index; + u8 curtxbw_40mhz = (sta->bandwidth >= IEEE80211_STA_RX_BW_40) ? 1 : 0; + u8 curshortgi_40mhz = curtxbw_40mhz && + (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? + 1 : 0; + u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? + 1 : 0; + enum wireless_mode wirelessmode = 0; bool shortgi = false; u8 rate_mask[5]; u8 macid = 0; - u8 mimops = 1; - - ratr_bitmap |= (p_mcsrate[1] << 20) | (p_mcsrate[0] << 12); + u8 mimo_ps = IEEE80211_SMPS_OFF; + + sta_entry = (struct rtl_sta_info *) sta->drv_priv; + wirelessmode = sta_entry->wireless_mode; + if (mac->opmode == NL80211_IFTYPE_STATION || + mac->opmode == NL80211_IFTYPE_MESH_POINT) + curtxbw_40mhz = mac->bw_40; + else if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_ADHOC) + macid = sta->aid + 1; + + if (rtlhal->current_bandtype == BAND_ON_5G) + ratr_bitmap = sta->supp_rates[1] << 4; + else + ratr_bitmap = sta->supp_rates[0]; + if (mac->opmode == NL80211_IFTYPE_ADHOC) + ratr_bitmap = 0xfff; + ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 | + sta->ht_cap.mcs.rx_mask[0] << 12); switch (wirelessmode) { case WIRELESS_MODE_B: ratr_index = RATR_INX_WIRELESS_B; @@ -2071,6 +2112,7 @@ void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level) break; case WIRELESS_MODE_G: ratr_index = RATR_INX_WIRELESS_GB; + if (rssi_level == 1) ratr_bitmap &= 0x00000f00; else if (rssi_level == 2) @@ -2085,7 +2127,8 @@ void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level) case WIRELESS_MODE_N_24G: case WIRELESS_MODE_N_5G: ratr_index = RATR_INX_WIRELESS_NGB; - if (mimops == 0) { + + if (mimo_ps == IEEE80211_SMPS_STATIC) { if (rssi_level == 1) ratr_bitmap &= 0x00070000; else if (rssi_level == 2) @@ -2128,8 +2171,10 @@ void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level) } } } + if ((curtxbw_40mhz && curshortgi_40mhz) || (!curtxbw_40mhz && curshortgi_20mhz)) { + if (macid == 0) shortgi = true; else if (macid == 1) @@ -2138,21 +2183,42 @@ void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level) break; default: ratr_index = RATR_INX_WIRELESS_NGB; + if (rtlphy->rf_type == RF_1T2R) ratr_bitmap &= 0x000ff0ff; else ratr_bitmap &= 0x0f0ff0ff; break; } - RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "ratr_bitmap :%x\n", - ratr_bitmap); - *(u32 *)&rate_mask = ((ratr_bitmap & 0x0fffffff) | - ratr_index << 28); + sta_entry->ratr_index = ratr_index; + + RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, + "ratr_bitmap :%x\n", ratr_bitmap); + *(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) | + (ratr_index << 28); rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80; RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "Rate_index:%x, ratr_val:%x, %5phC\n", ratr_index, ratr_bitmap, rate_mask); - rtl92c_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask); + memcpy(rtlpriv->rate_mask, rate_mask, 5); + /* rtl92c_fill_h2c_cmd() does USB I/O and will result in a + * "scheduled while atomic" if called directly */ + schedule_work(&rtlpriv->works.fill_h2c_cmd); + + if (macid != 0) + sta_entry->ratr_index = ratr_index; +} + +void rtl92cu_update_hal_rate_tbl(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, + u8 rssi_level) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->dm.useramask) + rtl92cu_update_hal_rate_mask(hw, sta, rssi_level); + else + rtl92cu_update_hal_rate_table(hw, sta); } void rtl92cu_update_channel_access_setting(struct ieee80211_hw *hw) diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h index f41a3aa4a26f..8e3ec1e25644 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h @@ -98,10 +98,6 @@ void rtl92cu_update_interrupt_mask(struct ieee80211_hw *hw, u32 add_msr, u32 rm_msr); void rtl92cu_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); -void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw, - struct ieee80211_sta *sta, - u8 rssi_level); -void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level); void rtl92cu_update_channel_access_setting(struct ieee80211_hw *hw); bool rtl92cu_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid); diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c index 85b6bdb163c0..da4f587199ee 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c @@ -289,14 +289,30 @@ void rtl92c_set_key(struct ieee80211_hw *hw, u32 key_index, macaddr = cam_const_broad; entry_id = key_index; } else { + if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_MESH_POINT) { + entry_id = rtl_cam_get_free_entry(hw, + p_macaddr); + if (entry_id >= TOTAL_CAM_ENTRY) { + RT_TRACE(rtlpriv, COMP_SEC, + DBG_EMERG, + "Can not find free hw security cam entry\n"); + return; + } + } else { + entry_id = CAM_PAIRWISE_KEY_POSITION; + } + key_index = PAIRWISE_KEYIDX; - entry_id = CAM_PAIRWISE_KEY_POSITION; is_pairwise = true; } } if (rtlpriv->sec.key_len[key_index] == 0) { RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "delete one entry\n"); + if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_MESH_POINT) + rtl_cam_del_entry(hw, p_macaddr); rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); } else { RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c index 23d640a4debd..826f085c29dd 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c @@ -106,8 +106,7 @@ static struct rtl_hal_ops rtl8192cu_hal_ops = { .update_interrupt_mask = rtl92cu_update_interrupt_mask, .get_hw_reg = rtl92cu_get_hw_reg, .set_hw_reg = rtl92cu_set_hw_reg, - .update_rate_tbl = rtl92cu_update_hal_rate_table, - .update_rate_mask = rtl92cu_update_hal_rate_mask, + .update_rate_tbl = rtl92cu_update_hal_rate_tbl, .fill_tx_desc = rtl92cu_tx_fill_desc, .fill_fake_txdesc = rtl92cu_fill_fake_txdesc, .fill_tx_cmddesc = rtl92cu_tx_fill_cmddesc, @@ -137,6 +136,7 @@ static struct rtl_hal_ops rtl8192cu_hal_ops = { .phy_lc_calibrate = _rtl92cu_phy_lc_calibrate, .phy_set_bw_mode_callback = rtl92cu_phy_set_bw_mode_callback, .dm_dynamic_txpower = rtl92cu_dm_dynamic_txpower, + .fill_h2c_cmd = rtl92c_fill_h2c_cmd, }; static struct rtl_mod_params rtl92cu_mod_params = { @@ -349,6 +349,7 @@ static struct usb_device_id rtl8192c_usb_ids[] = { {RTL_USB_DEVICE(0x07aa, 0x0056, rtl92cu_hal_cfg)}, /*ATKK-Gemtek*/ {RTL_USB_DEVICE(0x07b8, 0x8178, rtl92cu_hal_cfg)}, /*Funai -Abocom*/ {RTL_USB_DEVICE(0x0846, 0x9021, rtl92cu_hal_cfg)}, /*Netgear-Sercomm*/ + {RTL_USB_DEVICE(0x0846, 0xf001, rtl92cu_hal_cfg)}, /*On Netwrks N300MA*/ {RTL_USB_DEVICE(0x0b05, 0x17ab, rtl92cu_hal_cfg)}, /*ASUS-Edimax*/ {RTL_USB_DEVICE(0x0bda, 0x8186, rtl92cu_hal_cfg)}, /*Realtek 92CE-VAU*/ {RTL_USB_DEVICE(0x0df6, 0x0061, rtl92cu_hal_cfg)}, /*Sitecom-Edimax*/ diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h index a1310abd0d54..262e1e4c6e5b 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h @@ -49,5 +49,8 @@ bool rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw, u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, u32 regaddr, u32 bitmask); void rtl92cu_phy_set_bw_mode_callback(struct ieee80211_hw *hw); +void rtl92cu_update_hal_rate_tbl(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, + u8 rssi_level); #endif diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index 76732b0cd221..a3532e077871 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c @@ -824,6 +824,7 @@ static void rtl_usb_stop(struct ieee80211_hw *hw) /* should after adapter start and interrupt enable. */ set_hal_stop(rtlhal); + cancel_work_sync(&rtlpriv->works.fill_h2c_cmd); /* Enable software */ SET_USB_STOP(rtlusb); rtl_usb_deinit(hw); @@ -1026,6 +1027,16 @@ static bool rtl_usb_tx_chk_waitq_insert(struct ieee80211_hw *hw, return false; } +static void rtl_fill_h2c_cmd_work_callback(struct work_struct *work) +{ + struct rtl_works *rtlworks = + container_of(work, struct rtl_works, fill_h2c_cmd); + struct ieee80211_hw *hw = rtlworks->hw; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->cfg->ops->fill_h2c_cmd(hw, H2C_RA_MASK, 5, rtlpriv->rate_mask); +} + static struct rtl_intf_ops rtl_usb_ops = { .adapter_start = rtl_usb_start, .adapter_stop = rtl_usb_stop, @@ -1057,6 +1068,8 @@ int rtl_usb_probe(struct usb_interface *intf, /* this spin lock must be initialized early */ spin_lock_init(&rtlpriv->locks.usb_lock); + INIT_WORK(&rtlpriv->works.fill_h2c_cmd, + rtl_fill_h2c_cmd_work_callback); rtlpriv->usb_data_index = 0; init_completion(&rtlpriv->firmware_loading_complete); diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index 44328baa6389..cc03e7c87cbe 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h @@ -1736,6 +1736,8 @@ struct rtl_hal_ops { void (*bt_wifi_media_status_notify) (struct ieee80211_hw *hw, bool mstate); void (*bt_coex_off_before_lps) (struct ieee80211_hw *hw); + void (*fill_h2c_cmd) (struct ieee80211_hw *hw, u8 element_id, + u32 cmd_len, u8 *p_cmdbuffer); }; struct rtl_intf_ops { @@ -1869,6 +1871,7 @@ struct rtl_works { struct delayed_work fwevt_wq; struct work_struct lps_change_work; + struct work_struct fill_h2c_cmd; }; struct rtl_debug { @@ -2048,6 +2051,7 @@ struct rtl_priv { }; }; bool enter_ps; /* true when entering PS */ + u8 rate_mask[5]; /*This must be the last item so that it points to the data allocated diff --git a/drivers/net/wireless/ti/wl12xx/scan.c b/drivers/net/wireless/ti/wl12xx/scan.c index affdb3ec6225..4a0bbb13806b 100644 --- a/drivers/net/wireless/ti/wl12xx/scan.c +++ b/drivers/net/wireless/ti/wl12xx/scan.c @@ -310,7 +310,7 @@ static void wl12xx_adjust_channels(struct wl1271_cmd_sched_scan_config *cmd, memcpy(cmd->channels_2, cmd_channels->channels_2, sizeof(cmd->channels_2)); memcpy(cmd->channels_5, cmd_channels->channels_5, - sizeof(cmd->channels_2)); + sizeof(cmd->channels_5)); /* channels_4 are not supported, so no need to copy them */ } diff --git a/drivers/net/wireless/ti/wl12xx/wl12xx.h b/drivers/net/wireless/ti/wl12xx/wl12xx.h index 222d03540200..9e5484a73667 100644 --- a/drivers/net/wireless/ti/wl12xx/wl12xx.h +++ b/drivers/net/wireless/ti/wl12xx/wl12xx.h @@ -36,12 +36,12 @@ #define WL127X_IFTYPE_SR_VER 3 #define WL127X_MAJOR_SR_VER 10 #define WL127X_SUBTYPE_SR_VER WLCORE_FW_VER_IGNORE -#define WL127X_MINOR_SR_VER 115 +#define WL127X_MINOR_SR_VER 133 /* minimum multi-role FW version for wl127x */ #define WL127X_IFTYPE_MR_VER 5 #define WL127X_MAJOR_MR_VER 7 #define WL127X_SUBTYPE_MR_VER WLCORE_FW_VER_IGNORE -#define WL127X_MINOR_MR_VER 115 +#define WL127X_MINOR_MR_VER 42 /* FW chip version for wl128x */ #define WL128X_CHIP_VER 7 @@ -49,7 +49,7 @@ #define WL128X_IFTYPE_SR_VER 3 #define WL128X_MAJOR_SR_VER 10 #define WL128X_SUBTYPE_SR_VER WLCORE_FW_VER_IGNORE -#define WL128X_MINOR_SR_VER 115 +#define WL128X_MINOR_SR_VER 133 /* minimum multi-role FW version for wl128x */ #define WL128X_IFTYPE_MR_VER 5 #define WL128X_MAJOR_MR_VER 7 diff --git a/drivers/net/wireless/ti/wl18xx/scan.c b/drivers/net/wireless/ti/wl18xx/scan.c index 09d944505ac0..2b642f8c9266 100644 --- a/drivers/net/wireless/ti/wl18xx/scan.c +++ b/drivers/net/wireless/ti/wl18xx/scan.c @@ -34,7 +34,7 @@ static void wl18xx_adjust_channels(struct wl18xx_cmd_scan_params *cmd, memcpy(cmd->channels_2, cmd_channels->channels_2, sizeof(cmd->channels_2)); memcpy(cmd->channels_5, cmd_channels->channels_5, - sizeof(cmd->channels_2)); + sizeof(cmd->channels_5)); /* channels_4 are not supported, so no need to copy them */ } diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index 37984e6d4e99..8c20935d72c9 100644 --- a/drivers/net/xen-netback/netback.c +++ b/drivers/net/xen-netback/netback.c @@ -662,7 +662,7 @@ static void xen_netbk_rx_action(struct xen_netbk *netbk) { struct xenvif *vif = NULL, *tmp; s8 status; - u16 irq, flags; + u16 flags; struct xen_netif_rx_response *resp; struct sk_buff_head rxq; struct sk_buff *skb; @@ -771,13 +771,13 @@ static void xen_netbk_rx_action(struct xen_netbk *netbk) sco->meta_slots_used); RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&vif->rx, ret); - irq = vif->irq; - if (ret && list_empty(&vif->notify_list)) - list_add_tail(&vif->notify_list, ¬ify); xenvif_notify_tx_completion(vif); - xenvif_put(vif); + if (ret && list_empty(&vif->notify_list)) + list_add_tail(&vif->notify_list, ¬ify); + else + xenvif_put(vif); npo.meta_cons += sco->meta_slots_used; dev_kfree_skb(skb); } @@ -785,6 +785,7 @@ static void xen_netbk_rx_action(struct xen_netbk *netbk) list_for_each_entry_safe(vif, tmp, ¬ify, notify_list) { notify_remote_via_irq(vif->irq); list_del_init(&vif->notify_list); + xenvif_put(vif); } /* More work to do? */ diff --git a/drivers/nfc/Kconfig b/drivers/nfc/Kconfig index 4775d4e61b88..74a852e4e41f 100644 --- a/drivers/nfc/Kconfig +++ b/drivers/nfc/Kconfig @@ -28,7 +28,7 @@ config NFC_WILINK config NFC_MEI_PHY tristate "MEI bus NFC device support" - depends on INTEL_MEI_BUS_NFC && NFC_HCI + depends on INTEL_MEI && NFC_HCI help This adds support to use an mei bus nfc device. Select this if you will use an HCI NFC driver for an NFC chip connected behind an diff --git a/drivers/nfc/mei_phy.c b/drivers/nfc/mei_phy.c index b8f8abc422f0..1201bdbfb791 100644 --- a/drivers/nfc/mei_phy.c +++ b/drivers/nfc/mei_phy.c @@ -64,6 +64,15 @@ int nfc_mei_phy_enable(void *phy_id) return r; } + r = mei_cl_register_event_cb(phy->device, nfc_mei_event_cb, phy); + if (r) { + pr_err("MEY_PHY: Event cb registration failed\n"); + mei_cl_disable_device(phy->device); + phy->powered = 0; + + return r; + } + phy->powered = 1; return 0; diff --git a/drivers/nfc/microread/mei.c b/drivers/nfc/microread/mei.c index 1ad044dce7b6..cdf1bc53b257 100644 --- a/drivers/nfc/microread/mei.c +++ b/drivers/nfc/microread/mei.c @@ -43,24 +43,16 @@ static int microread_mei_probe(struct mei_cl_device *device, return -ENOMEM; } - r = mei_cl_register_event_cb(device, nfc_mei_event_cb, phy); - if (r) { - pr_err(MICROREAD_DRIVER_NAME ": event cb registration failed\n"); - goto err_out; - } - r = microread_probe(phy, &mei_phy_ops, LLC_NOP_NAME, MEI_NFC_HEADER_SIZE, 0, MEI_NFC_MAX_HCI_PAYLOAD, &phy->hdev); - if (r < 0) - goto err_out; - - return 0; + if (r < 0) { + nfc_mei_phy_free(phy); -err_out: - nfc_mei_phy_free(phy); + return r; + } - return r; + return 0; } static int microread_mei_remove(struct mei_cl_device *device) @@ -71,8 +63,6 @@ static int microread_mei_remove(struct mei_cl_device *device) microread_remove(phy->hdev); - nfc_mei_phy_disable(phy); - nfc_mei_phy_free(phy); return 0; diff --git a/drivers/nfc/pn544/mei.c b/drivers/nfc/pn544/mei.c index 1eb48848a35a..b5d3d18179eb 100644 --- a/drivers/nfc/pn544/mei.c +++ b/drivers/nfc/pn544/mei.c @@ -43,24 +43,16 @@ static int pn544_mei_probe(struct mei_cl_device *device, return -ENOMEM; } - r = mei_cl_register_event_cb(device, nfc_mei_event_cb, phy); - if (r) { - pr_err(PN544_DRIVER_NAME ": event cb registration failed\n"); - goto err_out; - } - r = pn544_hci_probe(phy, &mei_phy_ops, LLC_NOP_NAME, MEI_NFC_HEADER_SIZE, 0, MEI_NFC_MAX_HCI_PAYLOAD, &phy->hdev); - if (r < 0) - goto err_out; - - return 0; + if (r < 0) { + nfc_mei_phy_free(phy); -err_out: - nfc_mei_phy_free(phy); + return r; + } - return r; + return 0; } static int pn544_mei_remove(struct mei_cl_device *device) @@ -71,8 +63,6 @@ static int pn544_mei_remove(struct mei_cl_device *device) pn544_hci_remove(phy->hdev); - nfc_mei_phy_disable(phy); - nfc_mei_phy_free(phy); return 0; diff --git a/drivers/of/base.c b/drivers/of/base.c index f53b992f060a..a6f584a7f4a1 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -192,14 +192,15 @@ EXPORT_SYMBOL(of_find_property); struct device_node *of_find_all_nodes(struct device_node *prev) { struct device_node *np; + unsigned long flags; - raw_spin_lock(&devtree_lock); + raw_spin_lock_irqsave(&devtree_lock, flags); np = prev ? prev->allnext : of_allnodes; for (; np != NULL; np = np->allnext) if (of_node_get(np)) break; of_node_put(prev); - raw_spin_unlock(&devtree_lock); + raw_spin_unlock_irqrestore(&devtree_lock, flags); return np; } EXPORT_SYMBOL(of_find_all_nodes); @@ -421,8 +422,9 @@ struct device_node *of_get_next_available_child(const struct device_node *node, struct device_node *prev) { struct device_node *next; + unsigned long flags; - raw_spin_lock(&devtree_lock); + raw_spin_lock_irqsave(&devtree_lock, flags); next = prev ? prev->sibling : node->child; for (; next; next = next->sibling) { if (!__of_device_is_available(next)) @@ -431,7 +433,7 @@ struct device_node *of_get_next_available_child(const struct device_node *node, break; } of_node_put(prev); - raw_spin_unlock(&devtree_lock); + raw_spin_unlock_irqrestore(&devtree_lock, flags); return next; } EXPORT_SYMBOL(of_get_next_available_child); @@ -735,13 +737,14 @@ EXPORT_SYMBOL_GPL(of_modalias_node); struct device_node *of_find_node_by_phandle(phandle handle) { struct device_node *np; + unsigned long flags; - raw_spin_lock(&devtree_lock); + raw_spin_lock_irqsave(&devtree_lock, flags); for (np = of_allnodes; np; np = np->allnext) if (np->phandle == handle) break; of_node_get(np); - raw_spin_unlock(&devtree_lock); + raw_spin_unlock_irqrestore(&devtree_lock, flags); return np; } EXPORT_SYMBOL(of_find_node_by_phandle); diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c index 9544cdc0d1af..e79e006eb9ab 100644 --- a/drivers/parisc/iosapic.c +++ b/drivers/parisc/iosapic.c @@ -811,6 +811,70 @@ int iosapic_fixup_irq(void *isi_obj, struct pci_dev *pcidev) return pcidev->irq; } +static struct iosapic_info *first_isi = NULL; + +#ifdef CONFIG_64BIT +int iosapic_serial_irq(int num) +{ + struct iosapic_info *isi = first_isi; + struct irt_entry *irte = NULL; /* only used if PAT PDC */ + struct vector_info *vi; + int isi_line; /* line used by device */ + + /* lookup IRT entry for isi/slot/pin set */ + irte = &irt_cell[num]; + + DBG_IRT("iosapic_serial_irq(): irte %p %x %x %x %x %x %x %x %x\n", + irte, + irte->entry_type, + irte->entry_length, + irte->polarity_trigger, + irte->src_bus_irq_devno, + irte->src_bus_id, + irte->src_seg_id, + irte->dest_iosapic_intin, + (u32) irte->dest_iosapic_addr); + isi_line = irte->dest_iosapic_intin; + + /* get vector info for this input line */ + vi = isi->isi_vector + isi_line; + DBG_IRT("iosapic_serial_irq: line %d vi 0x%p\n", isi_line, vi); + + /* If this IRQ line has already been setup, skip it */ + if (vi->irte) + goto out; + + vi->irte = irte; + + /* + * Allocate processor IRQ + * + * XXX/FIXME The txn_alloc_irq() code and related code should be + * moved to enable_irq(). That way we only allocate processor IRQ + * bits for devices that actually have drivers claiming them. + * Right now we assign an IRQ to every PCI device present, + * regardless of whether it's used or not. + */ + vi->txn_irq = txn_alloc_irq(8); + + if (vi->txn_irq < 0) + panic("I/O sapic: couldn't get TXN IRQ\n"); + + /* enable_irq() will use txn_* to program IRdT */ + vi->txn_addr = txn_alloc_addr(vi->txn_irq); + vi->txn_data = txn_alloc_data(vi->txn_irq); + + vi->eoi_addr = isi->addr + IOSAPIC_REG_EOI; + vi->eoi_data = cpu_to_le32(vi->txn_data); + + cpu_claim_irq(vi->txn_irq, &iosapic_interrupt_type, vi); + + out: + + return vi->txn_irq; +} +#endif + /* ** squirrel away the I/O Sapic Version @@ -877,6 +941,8 @@ void *iosapic_register(unsigned long hpa) vip->irqline = (unsigned char) cnt; vip->iosapic = isi; } + if (!first_isi) + first_isi = isi; return isi; } diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c index 2ef7103270bb..1f05913ae677 100644 --- a/drivers/parisc/lba_pci.c +++ b/drivers/parisc/lba_pci.c @@ -668,7 +668,7 @@ lba_fixup_bus(struct pci_bus *bus) BUG(); } - if (ldev->hba.elmmio_space.start) { + if (ldev->hba.elmmio_space.flags) { err = request_resource(&iomem_resource, &(ldev->hba.elmmio_space)); if (err < 0) { @@ -993,7 +993,7 @@ lba_pat_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev) case PAT_LMMIO: /* used to fix up pre-initialized MEM BARs */ - if (!lba_dev->hba.lmmio_space.start) { + if (!lba_dev->hba.lmmio_space.flags) { sprintf(lba_dev->hba.lmmio_name, "PCI%02x LMMIO", (int)lba_dev->hba.bus_num.start); @@ -1001,7 +1001,7 @@ lba_pat_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev) io->start; r = &lba_dev->hba.lmmio_space; r->name = lba_dev->hba.lmmio_name; - } else if (!lba_dev->hba.elmmio_space.start) { + } else if (!lba_dev->hba.elmmio_space.flags) { sprintf(lba_dev->hba.elmmio_name, "PCI%02x ELMMIO", (int)lba_dev->hba.bus_num.start); @@ -1096,6 +1096,7 @@ lba_legacy_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev) r->name = "LBA PCI Busses"; r->start = lba_num & 0xff; r->end = (lba_num>>8) & 0xff; + r->flags = IORESOURCE_BUS; /* Set up local PCI Bus resources - we don't need them for ** Legacy boxes but it's nice to see in /proc/iomem. @@ -1494,7 +1495,7 @@ lba_driver_probe(struct parisc_device *dev) pci_add_resource_offset(&resources, &lba_dev->hba.io_space, HBA_PORT_BASE(lba_dev->hba.hba_num)); - if (lba_dev->hba.elmmio_space.start) + if (lba_dev->hba.elmmio_space.flags) pci_add_resource_offset(&resources, &lba_dev->hba.elmmio_space, lba_dev->hba.lmmio_space_offset); if (lba_dev->hba.lmmio_space.flags) diff --git a/drivers/parisc/superio.c b/drivers/parisc/superio.c index ac6e8e7a02df..a042d065a0c7 100644 --- a/drivers/parisc/superio.c +++ b/drivers/parisc/superio.c @@ -494,15 +494,4 @@ static struct pci_driver superio_driver = { .probe = superio_probe, }; -static int __init superio_modinit(void) -{ - return pci_register_driver(&superio_driver); -} - -static void __exit superio_exit(void) -{ - pci_unregister_driver(&superio_driver); -} - -module_init(superio_modinit); -module_exit(superio_exit); +module_pci_driver(superio_driver); diff --git a/drivers/parport/Kconfig b/drivers/parport/Kconfig index 24e12d4d1769..a50576081b34 100644 --- a/drivers/parport/Kconfig +++ b/drivers/parport/Kconfig @@ -71,7 +71,7 @@ config PARPORT_PC_FIFO config PARPORT_PC_SUPERIO bool "SuperIO chipset support" - depends on PARPORT_PC + depends on PARPORT_PC && !PARISC help Saying Y here enables some probes for Super-IO chipsets in order to find out things like base addresses, IRQ lines and DMA channels. It diff --git a/drivers/parport/parport_gsc.c b/drivers/parport/parport_gsc.c index a5251cb5fb0c..6e3a60c78873 100644 --- a/drivers/parport/parport_gsc.c +++ b/drivers/parport/parport_gsc.c @@ -234,7 +234,7 @@ static int parport_PS2_supported(struct parport *pb) struct parport *parport_gsc_probe_port(unsigned long base, unsigned long base_hi, int irq, - int dma, struct pci_dev *dev) + int dma, struct parisc_device *padev) { struct parport_gsc_private *priv; struct parport_operations *ops; @@ -258,7 +258,6 @@ struct parport *parport_gsc_probe_port(unsigned long base, priv->ctr_writable = 0xff; priv->dma_buf = 0; priv->dma_handle = 0; - priv->dev = dev; p->base = base; p->base_hi = base_hi; p->irq = irq; @@ -282,6 +281,7 @@ struct parport *parport_gsc_probe_port(unsigned long base, return NULL; } + p->dev = &padev->dev; p->base_hi = base_hi; p->modes = tmp.modes; p->size = (p->modes & PARPORT_MODE_EPP)?8:3; @@ -373,7 +373,7 @@ static int parport_init_chip(struct parisc_device *dev) } p = parport_gsc_probe_port(port, 0, dev->irq, - /* PARPORT_IRQ_NONE */ PARPORT_DMA_NONE, NULL); + /* PARPORT_IRQ_NONE */ PARPORT_DMA_NONE, dev); if (p) parport_count++; dev_set_drvdata(&dev->dev, p); diff --git a/drivers/parport/parport_gsc.h b/drivers/parport/parport_gsc.h index fc9c37c54022..812214768d27 100644 --- a/drivers/parport/parport_gsc.h +++ b/drivers/parport/parport_gsc.h @@ -217,6 +217,6 @@ extern void parport_gsc_dec_use_count(void); extern struct parport *parport_gsc_probe_port(unsigned long base, unsigned long base_hi, int irq, int dma, - struct pci_dev *dev); + struct parisc_device *padev); #endif /* __DRIVERS_PARPORT_PARPORT_GSC_H */ diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index 8ec8b4f48560..0f4554e48cc5 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c @@ -580,6 +580,7 @@ struct aer_recover_entry u8 devfn; u16 domain; int severity; + struct aer_capability_regs *regs; }; static DEFINE_KFIFO(aer_recover_ring, struct aer_recover_entry, @@ -593,7 +594,7 @@ static DEFINE_SPINLOCK(aer_recover_ring_lock); static DECLARE_WORK(aer_recover_work, aer_recover_work_func); void aer_recover_queue(int domain, unsigned int bus, unsigned int devfn, - int severity) + int severity, struct aer_capability_regs *aer_regs) { unsigned long flags; struct aer_recover_entry entry = { @@ -601,6 +602,7 @@ void aer_recover_queue(int domain, unsigned int bus, unsigned int devfn, .devfn = devfn, .domain = domain, .severity = severity, + .regs = aer_regs, }; spin_lock_irqsave(&aer_recover_ring_lock, flags); @@ -627,6 +629,7 @@ static void aer_recover_work_func(struct work_struct *work) PCI_SLOT(entry.devfn), PCI_FUNC(entry.devfn)); continue; } + cper_print_aer(pdev, entry.severity, entry.regs); do_recovery(pdev, entry.severity); pci_dev_put(pdev); } diff --git a/drivers/pci/pcie/aer/aerdrv_errprint.c b/drivers/pci/pcie/aer/aerdrv_errprint.c index 5ab14251839d..2c7c9f5f592c 100644 --- a/drivers/pci/pcie/aer/aerdrv_errprint.c +++ b/drivers/pci/pcie/aer/aerdrv_errprint.c @@ -220,7 +220,7 @@ int cper_severity_to_aer(int cper_severity) } EXPORT_SYMBOL_GPL(cper_severity_to_aer); -void cper_print_aer(const char *prefix, struct pci_dev *dev, int cper_severity, +void cper_print_aer(struct pci_dev *dev, int cper_severity, struct aer_capability_regs *aer) { int aer_severity, layer, agent, status_strs_size, tlp_header_valid = 0; @@ -244,7 +244,7 @@ void cper_print_aer(const char *prefix, struct pci_dev *dev, int cper_severity, agent = AER_GET_AGENT(aer_severity, status); dev_err(&dev->dev, "aer_status: 0x%08x, aer_mask: 0x%08x\n", status, mask); - cper_print_bits(prefix, status, status_strs, status_strs_size); + cper_print_bits("", status, status_strs, status_strs_size); dev_err(&dev->dev, "aer_layer=%s, aer_agent=%s\n", aer_error_layer[layer], aer_agent_string[agent]); if (aer_severity != AER_CORRECTABLE) diff --git a/drivers/pinctrl/pinconf.c b/drivers/pinctrl/pinconf.c index c67c37e23dd7..694c3ace4520 100644 --- a/drivers/pinctrl/pinconf.c +++ b/drivers/pinctrl/pinconf.c @@ -610,7 +610,7 @@ static int pinconf_dbg_config_print(struct seq_file *s, void *d) bool found = false; unsigned long config; - mutex_lock(&pctldev->mutex); + mutex_lock(&pinctrl_maps_mutex); /* Parse the pinctrl map and look for the elected pin/state */ for_each_maps(maps_node, i, map) { @@ -659,7 +659,7 @@ static int pinconf_dbg_config_print(struct seq_file *s, void *d) confops->pin_config_config_dbg_show(pctldev, s, config); exit: - mutex_unlock(&pctldev->mutex); + mutex_unlock(&pinctrl_maps_mutex); return 0; } diff --git a/drivers/pinctrl/pinctrl-coh901.c b/drivers/pinctrl/pinctrl-coh901.c index a67af419f531..d6b41747d687 100644 --- a/drivers/pinctrl/pinctrl-coh901.c +++ b/drivers/pinctrl/pinctrl-coh901.c @@ -830,7 +830,8 @@ static int __init u300_gpio_probe(struct platform_device *pdev) return 0; err_no_range: - err = gpiochip_remove(&gpio->chip); + if (gpiochip_remove(&gpio->chip)) + dev_err(&pdev->dev, "failed to remove gpio chip\n"); err_no_chip: err_no_domain: err_no_port: diff --git a/drivers/pinctrl/pinctrl-exynos.c b/drivers/pinctrl/pinctrl-exynos.c index ac742817ebce..2d76f66a2e0b 100644 --- a/drivers/pinctrl/pinctrl-exynos.c +++ b/drivers/pinctrl/pinctrl-exynos.c @@ -196,6 +196,12 @@ static irqreturn_t exynos_eint_gpio_irq(int irq, void *data) return IRQ_HANDLED; } +struct exynos_eint_gpio_save { + u32 eint_con; + u32 eint_fltcon0; + u32 eint_fltcon1; +}; + /* * exynos_eint_gpio_init() - setup handling of external gpio interrupts. * @d: driver data of samsung pinctrl driver. @@ -204,8 +210,8 @@ static int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d) { struct samsung_pin_bank *bank; struct device *dev = d->dev; - unsigned int ret; - unsigned int i; + int ret; + int i; if (!d->irq) { dev_err(dev, "irq number not available\n"); @@ -227,11 +233,29 @@ static int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d) bank->nr_pins, &exynos_gpio_irqd_ops, bank); if (!bank->irq_domain) { dev_err(dev, "gpio irq domain add failed\n"); - return -ENXIO; + ret = -ENXIO; + goto err_domains; + } + + bank->soc_priv = devm_kzalloc(d->dev, + sizeof(struct exynos_eint_gpio_save), GFP_KERNEL); + if (!bank->soc_priv) { + irq_domain_remove(bank->irq_domain); + ret = -ENOMEM; + goto err_domains; } } return 0; + +err_domains: + for (--i, --bank; i >= 0; --i, --bank) { + if (bank->eint_type != EINT_TYPE_GPIO) + continue; + irq_domain_remove(bank->irq_domain); + } + + return ret; } static void exynos_wkup_irq_unmask(struct irq_data *irqd) @@ -326,6 +350,28 @@ static int exynos_wkup_irq_set_type(struct irq_data *irqd, unsigned int type) return 0; } +static u32 exynos_eint_wake_mask = 0xffffffff; + +u32 exynos_get_eint_wake_mask(void) +{ + return exynos_eint_wake_mask; +} + +static int exynos_wkup_irq_set_wake(struct irq_data *irqd, unsigned int on) +{ + struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); + unsigned long bit = 1UL << (2 * bank->eint_offset + irqd->hwirq); + + pr_info("wake %s for irq %d\n", on ? "enabled" : "disabled", irqd->irq); + + if (!on) + exynos_eint_wake_mask |= bit; + else + exynos_eint_wake_mask &= ~bit; + + return 0; +} + /* * irq_chip for wakeup interrupts */ @@ -335,6 +381,7 @@ static struct irq_chip exynos_wkup_irq_chip = { .irq_mask = exynos_wkup_irq_mask, .irq_ack = exynos_wkup_irq_ack, .irq_set_type = exynos_wkup_irq_set_type, + .irq_set_wake = exynos_wkup_irq_set_wake, }; /* interrupt handler for wakeup interrupts 0..15 */ @@ -505,6 +552,72 @@ static int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d) return 0; } +static void exynos_pinctrl_suspend_bank( + struct samsung_pinctrl_drv_data *drvdata, + struct samsung_pin_bank *bank) +{ + struct exynos_eint_gpio_save *save = bank->soc_priv; + void __iomem *regs = drvdata->virt_base; + + save->eint_con = readl(regs + EXYNOS_GPIO_ECON_OFFSET + + bank->eint_offset); + save->eint_fltcon0 = readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET + + 2 * bank->eint_offset); + save->eint_fltcon1 = readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET + + 2 * bank->eint_offset + 4); + + pr_debug("%s: save con %#010x\n", bank->name, save->eint_con); + pr_debug("%s: save fltcon0 %#010x\n", bank->name, save->eint_fltcon0); + pr_debug("%s: save fltcon1 %#010x\n", bank->name, save->eint_fltcon1); +} + +static void exynos_pinctrl_suspend(struct samsung_pinctrl_drv_data *drvdata) +{ + struct samsung_pin_ctrl *ctrl = drvdata->ctrl; + struct samsung_pin_bank *bank = ctrl->pin_banks; + int i; + + for (i = 0; i < ctrl->nr_banks; ++i, ++bank) + if (bank->eint_type == EINT_TYPE_GPIO) + exynos_pinctrl_suspend_bank(drvdata, bank); +} + +static void exynos_pinctrl_resume_bank( + struct samsung_pinctrl_drv_data *drvdata, + struct samsung_pin_bank *bank) +{ + struct exynos_eint_gpio_save *save = bank->soc_priv; + void __iomem *regs = drvdata->virt_base; + + pr_debug("%s: con %#010x => %#010x\n", bank->name, + readl(regs + EXYNOS_GPIO_ECON_OFFSET + + bank->eint_offset), save->eint_con); + pr_debug("%s: fltcon0 %#010x => %#010x\n", bank->name, + readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET + + 2 * bank->eint_offset), save->eint_fltcon0); + pr_debug("%s: fltcon1 %#010x => %#010x\n", bank->name, + readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET + + 2 * bank->eint_offset + 4), save->eint_fltcon1); + + writel(save->eint_con, regs + EXYNOS_GPIO_ECON_OFFSET + + bank->eint_offset); + writel(save->eint_fltcon0, regs + EXYNOS_GPIO_EFLTCON_OFFSET + + 2 * bank->eint_offset); + writel(save->eint_fltcon1, regs + EXYNOS_GPIO_EFLTCON_OFFSET + + 2 * bank->eint_offset + 4); +} + +static void exynos_pinctrl_resume(struct samsung_pinctrl_drv_data *drvdata) +{ + struct samsung_pin_ctrl *ctrl = drvdata->ctrl; + struct samsung_pin_bank *bank = ctrl->pin_banks; + int i; + + for (i = 0; i < ctrl->nr_banks; ++i, ++bank) + if (bank->eint_type == EINT_TYPE_GPIO) + exynos_pinctrl_resume_bank(drvdata, bank); +} + /* pin banks of exynos4210 pin-controller 0 */ static struct samsung_pin_bank exynos4210_pin_banks0[] = { EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00), @@ -568,6 +681,8 @@ struct samsung_pin_ctrl exynos4210_pin_ctrl[] = { .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, .svc = EXYNOS_SVC_OFFSET, .eint_gpio_init = exynos_eint_gpio_init, + .suspend = exynos_pinctrl_suspend, + .resume = exynos_pinctrl_resume, .label = "exynos4210-gpio-ctrl0", }, { /* pin-controller instance 1 data */ @@ -582,6 +697,8 @@ struct samsung_pin_ctrl exynos4210_pin_ctrl[] = { .svc = EXYNOS_SVC_OFFSET, .eint_gpio_init = exynos_eint_gpio_init, .eint_wkup_init = exynos_eint_wkup_init, + .suspend = exynos_pinctrl_suspend, + .resume = exynos_pinctrl_resume, .label = "exynos4210-gpio-ctrl1", }, { /* pin-controller instance 2 data */ @@ -663,6 +780,8 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = { .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, .svc = EXYNOS_SVC_OFFSET, .eint_gpio_init = exynos_eint_gpio_init, + .suspend = exynos_pinctrl_suspend, + .resume = exynos_pinctrl_resume, .label = "exynos4x12-gpio-ctrl0", }, { /* pin-controller instance 1 data */ @@ -677,6 +796,8 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = { .svc = EXYNOS_SVC_OFFSET, .eint_gpio_init = exynos_eint_gpio_init, .eint_wkup_init = exynos_eint_wkup_init, + .suspend = exynos_pinctrl_suspend, + .resume = exynos_pinctrl_resume, .label = "exynos4x12-gpio-ctrl1", }, { /* pin-controller instance 2 data */ @@ -687,6 +808,8 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = { .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, .svc = EXYNOS_SVC_OFFSET, .eint_gpio_init = exynos_eint_gpio_init, + .suspend = exynos_pinctrl_suspend, + .resume = exynos_pinctrl_resume, .label = "exynos4x12-gpio-ctrl2", }, { /* pin-controller instance 3 data */ @@ -697,6 +820,8 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = { .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, .svc = EXYNOS_SVC_OFFSET, .eint_gpio_init = exynos_eint_gpio_init, + .suspend = exynos_pinctrl_suspend, + .resume = exynos_pinctrl_resume, .label = "exynos4x12-gpio-ctrl3", }, }; @@ -775,6 +900,8 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = { .svc = EXYNOS_SVC_OFFSET, .eint_gpio_init = exynos_eint_gpio_init, .eint_wkup_init = exynos_eint_wkup_init, + .suspend = exynos_pinctrl_suspend, + .resume = exynos_pinctrl_resume, .label = "exynos5250-gpio-ctrl0", }, { /* pin-controller instance 1 data */ @@ -785,6 +912,8 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = { .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, .svc = EXYNOS_SVC_OFFSET, .eint_gpio_init = exynos_eint_gpio_init, + .suspend = exynos_pinctrl_suspend, + .resume = exynos_pinctrl_resume, .label = "exynos5250-gpio-ctrl1", }, { /* pin-controller instance 2 data */ @@ -795,6 +924,8 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = { .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, .svc = EXYNOS_SVC_OFFSET, .eint_gpio_init = exynos_eint_gpio_init, + .suspend = exynos_pinctrl_suspend, + .resume = exynos_pinctrl_resume, .label = "exynos5250-gpio-ctrl2", }, { /* pin-controller instance 3 data */ @@ -805,6 +936,8 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = { .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, .svc = EXYNOS_SVC_OFFSET, .eint_gpio_init = exynos_eint_gpio_init, + .suspend = exynos_pinctrl_suspend, + .resume = exynos_pinctrl_resume, .label = "exynos5250-gpio-ctrl3", }, }; diff --git a/drivers/pinctrl/pinctrl-exynos.h b/drivers/pinctrl/pinctrl-exynos.h index 9b1f77a5bf0f..3c91c357792f 100644 --- a/drivers/pinctrl/pinctrl-exynos.h +++ b/drivers/pinctrl/pinctrl-exynos.h @@ -19,6 +19,7 @@ /* External GPIO and wakeup interrupt related definitions */ #define EXYNOS_GPIO_ECON_OFFSET 0x700 +#define EXYNOS_GPIO_EFLTCON_OFFSET 0x800 #define EXYNOS_GPIO_EMASK_OFFSET 0x900 #define EXYNOS_GPIO_EPEND_OFFSET 0xA00 #define EXYNOS_WKUP_ECON_OFFSET 0xE00 diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c index 055d0162098b..63ac22e89678 100644 --- a/drivers/pinctrl/pinctrl-samsung.c +++ b/drivers/pinctrl/pinctrl-samsung.c @@ -28,6 +28,7 @@ #include <linux/gpio.h> #include <linux/irqdomain.h> #include <linux/spinlock.h> +#include <linux/syscore_ops.h> #include "core.h" #include "pinctrl-samsung.h" @@ -48,6 +49,9 @@ static struct pin_config { { "samsung,pin-pud-pdn", PINCFG_TYPE_PUD_PDN }, }; +/* Global list of devices (struct samsung_pinctrl_drv_data) */ +LIST_HEAD(drvdata_list); + static unsigned int pin_base; static inline struct samsung_pin_bank *gc_to_pin_bank(struct gpio_chip *gc) @@ -956,9 +960,151 @@ static int samsung_pinctrl_probe(struct platform_device *pdev) ctrl->eint_wkup_init(drvdata); platform_set_drvdata(pdev, drvdata); + + /* Add to the global list */ + list_add_tail(&drvdata->node, &drvdata_list); + return 0; } +#ifdef CONFIG_PM + +/** + * samsung_pinctrl_suspend_dev - save pinctrl state for suspend for a device + * + * Save data for all banks handled by this device. + */ +static void samsung_pinctrl_suspend_dev( + struct samsung_pinctrl_drv_data *drvdata) +{ + struct samsung_pin_ctrl *ctrl = drvdata->ctrl; + void __iomem *virt_base = drvdata->virt_base; + int i; + + for (i = 0; i < ctrl->nr_banks; i++) { + struct samsung_pin_bank *bank = &ctrl->pin_banks[i]; + void __iomem *reg = virt_base + bank->pctl_offset; + + u8 *offs = bank->type->reg_offset; + u8 *widths = bank->type->fld_width; + enum pincfg_type type; + + /* Registers without a powerdown config aren't lost */ + if (!widths[PINCFG_TYPE_CON_PDN]) + continue; + + for (type = 0; type < PINCFG_TYPE_NUM; type++) + if (widths[type]) + bank->pm_save[type] = readl(reg + offs[type]); + + if (widths[PINCFG_TYPE_FUNC] * bank->nr_pins > 32) { + /* Some banks have two config registers */ + bank->pm_save[PINCFG_TYPE_NUM] = + readl(reg + offs[PINCFG_TYPE_FUNC] + 4); + pr_debug("Save %s @ %p (con %#010x %08x)\n", + bank->name, reg, + bank->pm_save[PINCFG_TYPE_FUNC], + bank->pm_save[PINCFG_TYPE_NUM]); + } else { + pr_debug("Save %s @ %p (con %#010x)\n", bank->name, + reg, bank->pm_save[PINCFG_TYPE_FUNC]); + } + } + + if (ctrl->suspend) + ctrl->suspend(drvdata); +} + +/** + * samsung_pinctrl_resume_dev - restore pinctrl state from suspend for a device + * + * Restore one of the banks that was saved during suspend. + * + * We don't bother doing anything complicated to avoid glitching lines since + * we're called before pad retention is turned off. + */ +static void samsung_pinctrl_resume_dev(struct samsung_pinctrl_drv_data *drvdata) +{ + struct samsung_pin_ctrl *ctrl = drvdata->ctrl; + void __iomem *virt_base = drvdata->virt_base; + int i; + + if (ctrl->resume) + ctrl->resume(drvdata); + + for (i = 0; i < ctrl->nr_banks; i++) { + struct samsung_pin_bank *bank = &ctrl->pin_banks[i]; + void __iomem *reg = virt_base + bank->pctl_offset; + + u8 *offs = bank->type->reg_offset; + u8 *widths = bank->type->fld_width; + enum pincfg_type type; + + /* Registers without a powerdown config aren't lost */ + if (!widths[PINCFG_TYPE_CON_PDN]) + continue; + + if (widths[PINCFG_TYPE_FUNC] * bank->nr_pins > 32) { + /* Some banks have two config registers */ + pr_debug("%s @ %p (con %#010x %08x => %#010x %08x)\n", + bank->name, reg, + readl(reg + offs[PINCFG_TYPE_FUNC]), + readl(reg + offs[PINCFG_TYPE_FUNC] + 4), + bank->pm_save[PINCFG_TYPE_FUNC], + bank->pm_save[PINCFG_TYPE_NUM]); + writel(bank->pm_save[PINCFG_TYPE_NUM], + reg + offs[PINCFG_TYPE_FUNC] + 4); + } else { + pr_debug("%s @ %p (con %#010x => %#010x)\n", bank->name, + reg, readl(reg + offs[PINCFG_TYPE_FUNC]), + bank->pm_save[PINCFG_TYPE_FUNC]); + } + for (type = 0; type < PINCFG_TYPE_NUM; type++) + if (widths[type]) + writel(bank->pm_save[type], reg + offs[type]); + } +} + +/** + * samsung_pinctrl_suspend - save pinctrl state for suspend + * + * Save data for all banks across all devices. + */ +static int samsung_pinctrl_suspend(void) +{ + struct samsung_pinctrl_drv_data *drvdata; + + list_for_each_entry(drvdata, &drvdata_list, node) { + samsung_pinctrl_suspend_dev(drvdata); + } + + return 0; +} + +/** + * samsung_pinctrl_resume - restore pinctrl state for suspend + * + * Restore data for all banks across all devices. + */ +static void samsung_pinctrl_resume(void) +{ + struct samsung_pinctrl_drv_data *drvdata; + + list_for_each_entry_reverse(drvdata, &drvdata_list, node) { + samsung_pinctrl_resume_dev(drvdata); + } +} + +#else +#define samsung_pinctrl_suspend NULL +#define samsung_pinctrl_resume NULL +#endif + +static struct syscore_ops samsung_pinctrl_syscore_ops = { + .suspend = samsung_pinctrl_suspend, + .resume = samsung_pinctrl_resume, +}; + static const struct of_device_id samsung_pinctrl_dt_match[] = { #ifdef CONFIG_PINCTRL_EXYNOS { .compatible = "samsung,exynos4210-pinctrl", @@ -987,6 +1133,14 @@ static struct platform_driver samsung_pinctrl_driver = { static int __init samsung_pinctrl_drv_register(void) { + /* + * Register syscore ops for save/restore of registers across suspend. + * It's important to ensure that this driver is running at an earlier + * initcall level than any arch-specific init calls that install syscore + * ops that turn off pad retention (like exynos_pm_resume). + */ + register_syscore_ops(&samsung_pinctrl_syscore_ops); + return platform_driver_register(&samsung_pinctrl_driver); } postcore_initcall(samsung_pinctrl_drv_register); diff --git a/drivers/pinctrl/pinctrl-samsung.h b/drivers/pinctrl/pinctrl-samsung.h index 7c7f9ebcd05b..26d3519240c9 100644 --- a/drivers/pinctrl/pinctrl-samsung.h +++ b/drivers/pinctrl/pinctrl-samsung.h @@ -127,6 +127,7 @@ struct samsung_pin_bank_type { * @gpio_chip: GPIO chip of the bank. * @grange: linux gpio pin range supported by this bank. * @slock: spinlock protecting bank registers + * @pm_save: saved register values during suspend */ struct samsung_pin_bank { struct samsung_pin_bank_type *type; @@ -138,12 +139,15 @@ struct samsung_pin_bank { u32 eint_mask; u32 eint_offset; char *name; + void *soc_priv; struct device_node *of_node; struct samsung_pinctrl_drv_data *drvdata; struct irq_domain *irq_domain; struct gpio_chip gpio_chip; struct pinctrl_gpio_range grange; spinlock_t slock; + + u32 pm_save[PINCFG_TYPE_NUM + 1]; /* +1 to handle double CON registers*/ }; /** @@ -184,11 +188,15 @@ struct samsung_pin_ctrl { int (*eint_gpio_init)(struct samsung_pinctrl_drv_data *); int (*eint_wkup_init)(struct samsung_pinctrl_drv_data *); + void (*suspend)(struct samsung_pinctrl_drv_data *); + void (*resume)(struct samsung_pinctrl_drv_data *); + char *label; }; /** * struct samsung_pinctrl_drv_data: wrapper for holding driver data together. + * @node: global list node * @virt_base: register base address of the controller. * @dev: device instance representing the controller. * @irq: interrpt number used by the controller to notify gpio interrupts. @@ -201,6 +209,7 @@ struct samsung_pin_ctrl { * @nr_function: number of such pin functions. */ struct samsung_pinctrl_drv_data { + struct list_head node; void __iomem *virt_base; struct device *dev; int irq; diff --git a/drivers/pinctrl/pinctrl-sunxi.c b/drivers/pinctrl/pinctrl-sunxi.c index c52fc2c08732..b7d8c890514c 100644 --- a/drivers/pinctrl/pinctrl-sunxi.c +++ b/drivers/pinctrl/pinctrl-sunxi.c @@ -1990,8 +1990,10 @@ static int sunxi_pinctrl_probe(struct platform_device *pdev) } clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(clk)) + if (IS_ERR(clk)) { + ret = PTR_ERR(clk); goto gpiochip_error; + } clk_prepare_enable(clk); @@ -2000,7 +2002,8 @@ static int sunxi_pinctrl_probe(struct platform_device *pdev) return 0; gpiochip_error: - ret = gpiochip_remove(pctl->chip); + if (gpiochip_remove(pctl->chip)) + dev_err(&pdev->dev, "failed to remove gpio chip\n"); pinctrl_error: pinctrl_unregister(pctl->pctl_dev); return ret; diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c index 791a6719d8a9..8cd90e7e945a 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c @@ -2357,27 +2357,48 @@ static const unsigned int sdhi3_wp_mux[] = { }; /* - USB0 ------------------------------------------------------------------- */ static const unsigned int usb0_pins[] = { - /* OVC */ - 150, 154, + /* PENC */ + 154, }; static const unsigned int usb0_mux[] = { - USB_OVC0_MARK, USB_PENC0_MARK, + USB_PENC0_MARK, +}; +static const unsigned int usb0_ovc_pins[] = { + /* USB_OVC */ + 150 +}; +static const unsigned int usb0_ovc_mux[] = { + USB_OVC0_MARK, }; /* - USB1 ------------------------------------------------------------------- */ static const unsigned int usb1_pins[] = { - /* OVC */ - 152, 155, + /* PENC */ + 155, }; static const unsigned int usb1_mux[] = { - USB_OVC1_MARK, USB_PENC1_MARK, + USB_PENC1_MARK, +}; +static const unsigned int usb1_ovc_pins[] = { + /* USB_OVC */ + 152, +}; +static const unsigned int usb1_ovc_mux[] = { + USB_OVC1_MARK, }; /* - USB2 ------------------------------------------------------------------- */ static const unsigned int usb2_pins[] = { - /* OVC, PENC */ - 125, 156, + /* PENC */ + 156, }; static const unsigned int usb2_mux[] = { - USB_OVC2_MARK, USB_PENC2_MARK, + USB_PENC2_MARK, +}; +static const unsigned int usb2_ovc_pins[] = { + /* USB_OVC */ + 125, +}; +static const unsigned int usb2_ovc_mux[] = { + USB_OVC2_MARK, }; static const struct sh_pfc_pin_group pinmux_groups[] = { @@ -2501,8 +2522,11 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { SH_PFC_PIN_GROUP(sdhi3_cd), SH_PFC_PIN_GROUP(sdhi3_wp), SH_PFC_PIN_GROUP(usb0), + SH_PFC_PIN_GROUP(usb0_ovc), SH_PFC_PIN_GROUP(usb1), + SH_PFC_PIN_GROUP(usb1_ovc), SH_PFC_PIN_GROUP(usb2), + SH_PFC_PIN_GROUP(usb2_ovc), }; static const char * const du0_groups[] = { @@ -2683,14 +2707,17 @@ static const char * const sdhi3_groups[] = { static const char * const usb0_groups[] = { "usb0", + "usb0_ovc", }; static const char * const usb1_groups[] = { "usb1", + "usb1_ovc", }; static const char * const usb2_groups[] = { "usb2", + "usb2_ovc", }; static const struct sh_pfc_function pinmux_functions[] = { diff --git a/drivers/pinctrl/vt8500/pinctrl-wmt.c b/drivers/pinctrl/vt8500/pinctrl-wmt.c index ab63104e8dc9..70d986e04afb 100644 --- a/drivers/pinctrl/vt8500/pinctrl-wmt.c +++ b/drivers/pinctrl/vt8500/pinctrl-wmt.c @@ -609,8 +609,7 @@ int wmt_pinctrl_probe(struct platform_device *pdev, return 0; fail_range: - err = gpiochip_remove(&data->gpio_chip); - if (err) + if (gpiochip_remove(&data->gpio_chip)) dev_err(&pdev->dev, "failed to remove gpio chip\n"); fail_gpio: pinctrl_unregister(data->pctl_dev); diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index 8df0c5a21be2..d111c8687f9b 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c @@ -703,7 +703,7 @@ static int hp_wmi_rfkill_setup(struct platform_device *device) } rfkill_init_sw_state(gps_rfkill, hp_wmi_get_sw_state(HPWMI_GPS)); - rfkill_set_hw_state(bluetooth_rfkill, + rfkill_set_hw_state(gps_rfkill, hp_wmi_get_hw_state(HPWMI_GPS)); err = rfkill_register(gps_rfkill); if (err) diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 0d0b5d7d19d0..7b8979c63f48 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -152,6 +152,7 @@ config BATTERY_SBS config BATTERY_BQ27x00 tristate "BQ27x00 battery driver" + depends on I2C || I2C=n help Say Y here to enable support for batteries with BQ27x00 (I2C/HDQ) chips. @@ -284,6 +285,7 @@ config CHARGER_LP8788 tristate "TI LP8788 charger driver" depends on MFD_LP8788 depends on LP8788_ADC + depends on IIO help Say Y to enable support for the LP8788 linear charger. diff --git a/drivers/power/pm2301_charger.c b/drivers/power/pm2301_charger.c index a44175139bbf..fef56e2041b3 100644 --- a/drivers/power/pm2301_charger.c +++ b/drivers/power/pm2301_charger.c @@ -1269,5 +1269,5 @@ module_exit(pm2xxx_charger_exit); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Rajkumar kasirajan, Olivier Launay"); -MODULE_ALIAS("platform:pm2xxx-charger"); +MODULE_ALIAS("i2c:pm2xxx-charger"); MODULE_DESCRIPTION("PM2xxx charger management driver"); diff --git a/drivers/power/wm831x_backup.c b/drivers/power/wm831x_backup.c index 58cbb009b74f..56fb509f4be0 100644 --- a/drivers/power/wm831x_backup.c +++ b/drivers/power/wm831x_backup.c @@ -207,7 +207,6 @@ static int wm831x_backup_remove(struct platform_device *pdev) struct wm831x_backup *devdata = platform_get_drvdata(pdev); power_supply_unregister(&devdata->backup); - kfree(devdata->backup.name); return 0; } diff --git a/drivers/ptp/ptp_pch.c b/drivers/ptp/ptp_pch.c index bea94510ad2d..71a2559278d7 100644 --- a/drivers/ptp/ptp_pch.c +++ b/drivers/ptp/ptp_pch.c @@ -628,9 +628,10 @@ pch_probe(struct pci_dev *pdev, const struct pci_device_id *id) chip->caps = ptp_pch_caps; chip->ptp_clock = ptp_clock_register(&chip->caps, &pdev->dev); - - if (IS_ERR(chip->ptp_clock)) - return PTR_ERR(chip->ptp_clock); + if (IS_ERR(chip->ptp_clock)) { + ret = PTR_ERR(chip->ptp_clock); + goto err_ptp_clock_reg; + } spin_lock_init(&chip->register_lock); @@ -669,6 +670,7 @@ pch_probe(struct pci_dev *pdev, const struct pci_device_id *id) err_req_irq: ptp_clock_unregister(chip->ptp_clock); +err_ptp_clock_reg: iounmap(chip->regs); chip->regs = NULL; diff --git a/drivers/rapidio/Kconfig b/drivers/rapidio/Kconfig index 6194d35ebb97..5ab056494bbe 100644 --- a/drivers/rapidio/Kconfig +++ b/drivers/rapidio/Kconfig @@ -47,4 +47,24 @@ config RAPIDIO_DEBUG If you are unsure about this, say N here. +choice + prompt "Enumeration method" + depends on RAPIDIO + default RAPIDIO_ENUM_BASIC + help + There are different enumeration and discovery mechanisms offered + for RapidIO subsystem. You may select single built-in method or + or any number of methods to be built as modules. + Selecting a built-in method disables use of loadable methods. + + If unsure, select Basic built-in. + +config RAPIDIO_ENUM_BASIC + tristate "Basic" + help + This option includes basic RapidIO fabric enumeration and discovery + mechanism similar to one described in RapidIO specification Annex 1. + +endchoice + source "drivers/rapidio/switches/Kconfig" diff --git a/drivers/rapidio/Makefile b/drivers/rapidio/Makefile index ec3fb8121004..3036702ffe8b 100644 --- a/drivers/rapidio/Makefile +++ b/drivers/rapidio/Makefile @@ -1,7 +1,8 @@ # # Makefile for RapidIO interconnect services # -obj-y += rio.o rio-access.o rio-driver.o rio-scan.o rio-sysfs.o +obj-y += rio.o rio-access.o rio-driver.o rio-sysfs.o +obj-$(CONFIG_RAPIDIO_ENUM_BASIC) += rio-scan.o obj-$(CONFIG_RAPIDIO) += switches/ obj-$(CONFIG_RAPIDIO) += devices/ diff --git a/drivers/rapidio/devices/tsi721.c b/drivers/rapidio/devices/tsi721.c index 6faba406b6e9..a8b2c23a7ef4 100644 --- a/drivers/rapidio/devices/tsi721.c +++ b/drivers/rapidio/devices/tsi721.c @@ -471,6 +471,10 @@ static irqreturn_t tsi721_irqhandler(int irq, void *ptr) u32 intval; u32 ch_inte; + /* For MSI mode disable all device-level interrupts */ + if (priv->flags & TSI721_USING_MSI) + iowrite32(0, priv->regs + TSI721_DEV_INTE); + dev_int = ioread32(priv->regs + TSI721_DEV_INT); if (!dev_int) return IRQ_NONE; @@ -560,6 +564,14 @@ static irqreturn_t tsi721_irqhandler(int irq, void *ptr) } } #endif + + /* For MSI mode re-enable device-level interrupts */ + if (priv->flags & TSI721_USING_MSI) { + dev_int = TSI721_DEV_INT_SR2PC_CH | TSI721_DEV_INT_SRIO | + TSI721_DEV_INT_SMSG_CH | TSI721_DEV_INT_BDMA_CH; + iowrite32(dev_int, priv->regs + TSI721_DEV_INTE); + } + return IRQ_HANDLED; } diff --git a/drivers/rapidio/rio-driver.c b/drivers/rapidio/rio-driver.c index 0f4a53bdaa3c..a0c875563d76 100644 --- a/drivers/rapidio/rio-driver.c +++ b/drivers/rapidio/rio-driver.c @@ -164,6 +164,13 @@ void rio_unregister_driver(struct rio_driver *rdrv) driver_unregister(&rdrv->driver); } +void rio_attach_device(struct rio_dev *rdev) +{ + rdev->dev.bus = &rio_bus_type; + rdev->dev.parent = &rio_bus; +} +EXPORT_SYMBOL_GPL(rio_attach_device); + /** * rio_match_bus - Tell if a RIO device structure has a matching RIO driver device id structure * @dev: the standard device structure to match against @@ -200,6 +207,7 @@ struct bus_type rio_bus_type = { .name = "rapidio", .match = rio_match_bus, .dev_attrs = rio_dev_attrs, + .bus_attrs = rio_bus_attrs, .probe = rio_device_probe, .remove = rio_device_remove, }; diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c index a965acd3c0e4..4c15dbf81087 100644 --- a/drivers/rapidio/rio-scan.c +++ b/drivers/rapidio/rio-scan.c @@ -37,12 +37,8 @@ #include "rio.h" -LIST_HEAD(rio_devices); - static void rio_init_em(struct rio_dev *rdev); -DEFINE_SPINLOCK(rio_global_list_lock); - static int next_destid = 0; static int next_comptag = 1; @@ -327,127 +323,6 @@ static int rio_is_switch(struct rio_dev *rdev) } /** - * rio_switch_init - Sets switch operations for a particular vendor switch - * @rdev: RIO device - * @do_enum: Enumeration/Discovery mode flag - * - * Searches the RIO switch ops table for known switch types. If the vid - * and did match a switch table entry, then call switch initialization - * routine to setup switch-specific routines. - */ -static void rio_switch_init(struct rio_dev *rdev, int do_enum) -{ - struct rio_switch_ops *cur = __start_rio_switch_ops; - struct rio_switch_ops *end = __end_rio_switch_ops; - - while (cur < end) { - if ((cur->vid == rdev->vid) && (cur->did == rdev->did)) { - pr_debug("RIO: calling init routine for %s\n", - rio_name(rdev)); - cur->init_hook(rdev, do_enum); - break; - } - cur++; - } - - if ((cur >= end) && (rdev->pef & RIO_PEF_STD_RT)) { - pr_debug("RIO: adding STD routing ops for %s\n", - rio_name(rdev)); - rdev->rswitch->add_entry = rio_std_route_add_entry; - rdev->rswitch->get_entry = rio_std_route_get_entry; - rdev->rswitch->clr_table = rio_std_route_clr_table; - } - - if (!rdev->rswitch->add_entry || !rdev->rswitch->get_entry) - printk(KERN_ERR "RIO: missing routing ops for %s\n", - rio_name(rdev)); -} - -/** - * rio_add_device- Adds a RIO device to the device model - * @rdev: RIO device - * - * Adds the RIO device to the global device list and adds the RIO - * device to the RIO device list. Creates the generic sysfs nodes - * for an RIO device. - */ -static int rio_add_device(struct rio_dev *rdev) -{ - int err; - - err = device_add(&rdev->dev); - if (err) - return err; - - spin_lock(&rio_global_list_lock); - list_add_tail(&rdev->global_list, &rio_devices); - spin_unlock(&rio_global_list_lock); - - rio_create_sysfs_dev_files(rdev); - - return 0; -} - -/** - * rio_enable_rx_tx_port - enable input receiver and output transmitter of - * given port - * @port: Master port associated with the RIO network - * @local: local=1 select local port otherwise a far device is reached - * @destid: Destination ID of the device to check host bit - * @hopcount: Number of hops to reach the target - * @port_num: Port (-number on switch) to enable on a far end device - * - * Returns 0 or 1 from on General Control Command and Status Register - * (EXT_PTR+0x3C) - */ -inline int rio_enable_rx_tx_port(struct rio_mport *port, - int local, u16 destid, - u8 hopcount, u8 port_num) { -#ifdef CONFIG_RAPIDIO_ENABLE_RX_TX_PORTS - u32 regval; - u32 ext_ftr_ptr; - - /* - * enable rx input tx output port - */ - pr_debug("rio_enable_rx_tx_port(local = %d, destid = %d, hopcount = " - "%d, port_num = %d)\n", local, destid, hopcount, port_num); - - ext_ftr_ptr = rio_mport_get_physefb(port, local, destid, hopcount); - - if (local) { - rio_local_read_config_32(port, ext_ftr_ptr + - RIO_PORT_N_CTL_CSR(0), - ®val); - } else { - if (rio_mport_read_config_32(port, destid, hopcount, - ext_ftr_ptr + RIO_PORT_N_CTL_CSR(port_num), ®val) < 0) - return -EIO; - } - - if (regval & RIO_PORT_N_CTL_P_TYP_SER) { - /* serial */ - regval = regval | RIO_PORT_N_CTL_EN_RX_SER - | RIO_PORT_N_CTL_EN_TX_SER; - } else { - /* parallel */ - regval = regval | RIO_PORT_N_CTL_EN_RX_PAR - | RIO_PORT_N_CTL_EN_TX_PAR; - } - - if (local) { - rio_local_write_config_32(port, ext_ftr_ptr + - RIO_PORT_N_CTL_CSR(0), regval); - } else { - if (rio_mport_write_config_32(port, destid, hopcount, - ext_ftr_ptr + RIO_PORT_N_CTL_CSR(port_num), regval) < 0) - return -EIO; - } -#endif - return 0; -} - -/** * rio_setup_device- Allocates and sets up a RIO device * @net: RIO network * @port: Master port to send transactions @@ -587,8 +462,7 @@ static struct rio_dev *rio_setup_device(struct rio_net *net, rdev->destid); } - rdev->dev.bus = &rio_bus_type; - rdev->dev.parent = &rio_bus; + rio_attach_device(rdev); device_initialize(&rdev->dev); rdev->dev.release = rio_release_dev; @@ -1260,19 +1134,30 @@ static void rio_pw_enable(struct rio_mport *port, int enable) /** * rio_enum_mport- Start enumeration through a master port * @mport: Master port to send transactions + * @flags: Enumeration control flags * * Starts the enumeration process. If somebody has enumerated our * master port device, then give up. If not and we have an active * link, then start recursive peer enumeration. Returns %0 if * enumeration succeeds or %-EBUSY if enumeration fails. */ -int rio_enum_mport(struct rio_mport *mport) +int rio_enum_mport(struct rio_mport *mport, u32 flags) { struct rio_net *net = NULL; int rc = 0; printk(KERN_INFO "RIO: enumerate master port %d, %s\n", mport->id, mport->name); + + /* + * To avoid multiple start requests (repeat enumeration is not supported + * by this method) check if enumeration/discovery was performed for this + * mport: if mport was added into the list of mports for a net exit + * with error. + */ + if (mport->nnode.next || mport->nnode.prev) + return -EBUSY; + /* If somebody else enumerated our master port device, bail. */ if (rio_enum_host(mport) < 0) { printk(KERN_INFO @@ -1362,14 +1247,16 @@ static void rio_build_route_tables(struct rio_net *net) /** * rio_disc_mport- Start discovery through a master port * @mport: Master port to send transactions + * @flags: discovery control flags * * Starts the discovery process. If we have an active link, - * then wait for the signal that enumeration is complete. + * then wait for the signal that enumeration is complete (if wait + * is allowed). * When enumeration completion is signaled, start recursive * peer discovery. Returns %0 if discovery succeeds or %-EBUSY * on failure. */ -int rio_disc_mport(struct rio_mport *mport) +int rio_disc_mport(struct rio_mport *mport, u32 flags) { struct rio_net *net = NULL; unsigned long to_end; @@ -1379,6 +1266,11 @@ int rio_disc_mport(struct rio_mport *mport) /* If master port has an active link, allocate net and discover peers */ if (rio_mport_is_active(mport)) { + if (rio_enum_complete(mport)) + goto enum_done; + else if (flags & RIO_SCAN_ENUM_NO_WAIT) + return -EAGAIN; + pr_debug("RIO: wait for enumeration to complete...\n"); to_end = jiffies + CONFIG_RAPIDIO_DISC_TIMEOUT * HZ; @@ -1421,3 +1313,41 @@ enum_done: bail: return -EBUSY; } + +static struct rio_scan rio_scan_ops = { + .enumerate = rio_enum_mport, + .discover = rio_disc_mport, +}; + +static bool scan; +module_param(scan, bool, 0); +MODULE_PARM_DESC(scan, "Start RapidIO network enumeration/discovery " + "(default = 0)"); + +/** + * rio_basic_attach: + * + * When this enumeration/discovery method is loaded as a module this function + * registers its specific enumeration and discover routines for all available + * RapidIO mport devices. The "scan" command line parameter controls ability of + * the module to start RapidIO enumeration/discovery automatically. + * + * Returns 0 for success or -EIO if unable to register itself. + * + * This enumeration/discovery method cannot be unloaded and therefore does not + * provide a matching cleanup_module routine. + */ + +static int __init rio_basic_attach(void) +{ + if (rio_register_scan(RIO_MPORT_ANY, &rio_scan_ops)) + return -EIO; + if (scan) + rio_init_mports(); + return 0; +} + +late_initcall(rio_basic_attach); + +MODULE_DESCRIPTION("Basic RapidIO enumeration/discovery"); +MODULE_LICENSE("GPL"); diff --git a/drivers/rapidio/rio-sysfs.c b/drivers/rapidio/rio-sysfs.c index 4dbe360989be..66d4acd5e18f 100644 --- a/drivers/rapidio/rio-sysfs.c +++ b/drivers/rapidio/rio-sysfs.c @@ -285,3 +285,48 @@ void rio_remove_sysfs_dev_files(struct rio_dev *rdev) rdev->rswitch->sw_sysfs(rdev, RIO_SW_SYSFS_REMOVE); } } + +static ssize_t bus_scan_store(struct bus_type *bus, const char *buf, + size_t count) +{ + long val; + struct rio_mport *port = NULL; + int rc; + + if (kstrtol(buf, 0, &val) < 0) + return -EINVAL; + + if (val == RIO_MPORT_ANY) { + rc = rio_init_mports(); + goto exit; + } + + if (val < 0 || val >= RIO_MAX_MPORTS) + return -EINVAL; + + port = rio_find_mport((int)val); + + if (!port) { + pr_debug("RIO: %s: mport_%d not available\n", + __func__, (int)val); + return -EINVAL; + } + + if (!port->nscan) + return -EINVAL; + + if (port->host_deviceid >= 0) + rc = port->nscan->enumerate(port, 0); + else + rc = port->nscan->discover(port, RIO_SCAN_ENUM_NO_WAIT); +exit: + if (!rc) + rc = count; + + return rc; +} + +struct bus_attribute rio_bus_attrs[] = { + __ATTR(scan, (S_IWUSR|S_IWGRP), NULL, bus_scan_store), + __ATTR_NULL +}; diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c index d553b5d13722..cb1c08996fbb 100644 --- a/drivers/rapidio/rio.c +++ b/drivers/rapidio/rio.c @@ -31,7 +31,11 @@ #include "rio.h" +static LIST_HEAD(rio_devices); +static DEFINE_SPINLOCK(rio_global_list_lock); + static LIST_HEAD(rio_mports); +static DEFINE_MUTEX(rio_mport_list_lock); static unsigned char next_portid; static DEFINE_SPINLOCK(rio_mmap_lock); @@ -53,6 +57,32 @@ u16 rio_local_get_device_id(struct rio_mport *port) } /** + * rio_add_device- Adds a RIO device to the device model + * @rdev: RIO device + * + * Adds the RIO device to the global device list and adds the RIO + * device to the RIO device list. Creates the generic sysfs nodes + * for an RIO device. + */ +int rio_add_device(struct rio_dev *rdev) +{ + int err; + + err = device_add(&rdev->dev); + if (err) + return err; + + spin_lock(&rio_global_list_lock); + list_add_tail(&rdev->global_list, &rio_devices); + spin_unlock(&rio_global_list_lock); + + rio_create_sysfs_dev_files(rdev); + + return 0; +} +EXPORT_SYMBOL_GPL(rio_add_device); + +/** * rio_request_inb_mbox - request inbound mailbox service * @mport: RIO master port from which to allocate the mailbox resource * @dev_id: Device specific pointer to pass on event @@ -489,6 +519,7 @@ rio_mport_get_physefb(struct rio_mport *port, int local, return ext_ftr_ptr; } +EXPORT_SYMBOL_GPL(rio_mport_get_physefb); /** * rio_get_comptag - Begin or continue searching for a RIO device by component tag @@ -521,6 +552,7 @@ exit: spin_unlock(&rio_global_list_lock); return rdev; } +EXPORT_SYMBOL_GPL(rio_get_comptag); /** * rio_set_port_lockout - Sets/clears LOCKOUT bit (RIO EM 1.3) for a switch port. @@ -545,6 +577,107 @@ int rio_set_port_lockout(struct rio_dev *rdev, u32 pnum, int lock) regval); return 0; } +EXPORT_SYMBOL_GPL(rio_set_port_lockout); + +/** + * rio_switch_init - Sets switch operations for a particular vendor switch + * @rdev: RIO device + * @do_enum: Enumeration/Discovery mode flag + * + * Searches the RIO switch ops table for known switch types. If the vid + * and did match a switch table entry, then call switch initialization + * routine to setup switch-specific routines. + */ +void rio_switch_init(struct rio_dev *rdev, int do_enum) +{ + struct rio_switch_ops *cur = __start_rio_switch_ops; + struct rio_switch_ops *end = __end_rio_switch_ops; + + while (cur < end) { + if ((cur->vid == rdev->vid) && (cur->did == rdev->did)) { + pr_debug("RIO: calling init routine for %s\n", + rio_name(rdev)); + cur->init_hook(rdev, do_enum); + break; + } + cur++; + } + + if ((cur >= end) && (rdev->pef & RIO_PEF_STD_RT)) { + pr_debug("RIO: adding STD routing ops for %s\n", + rio_name(rdev)); + rdev->rswitch->add_entry = rio_std_route_add_entry; + rdev->rswitch->get_entry = rio_std_route_get_entry; + rdev->rswitch->clr_table = rio_std_route_clr_table; + } + + if (!rdev->rswitch->add_entry || !rdev->rswitch->get_entry) + printk(KERN_ERR "RIO: missing routing ops for %s\n", + rio_name(rdev)); +} +EXPORT_SYMBOL_GPL(rio_switch_init); + +/** + * rio_enable_rx_tx_port - enable input receiver and output transmitter of + * given port + * @port: Master port associated with the RIO network + * @local: local=1 select local port otherwise a far device is reached + * @destid: Destination ID of the device to check host bit + * @hopcount: Number of hops to reach the target + * @port_num: Port (-number on switch) to enable on a far end device + * + * Returns 0 or 1 from on General Control Command and Status Register + * (EXT_PTR+0x3C) + */ +int rio_enable_rx_tx_port(struct rio_mport *port, + int local, u16 destid, + u8 hopcount, u8 port_num) +{ +#ifdef CONFIG_RAPIDIO_ENABLE_RX_TX_PORTS + u32 regval; + u32 ext_ftr_ptr; + + /* + * enable rx input tx output port + */ + pr_debug("rio_enable_rx_tx_port(local = %d, destid = %d, hopcount = " + "%d, port_num = %d)\n", local, destid, hopcount, port_num); + + ext_ftr_ptr = rio_mport_get_physefb(port, local, destid, hopcount); + + if (local) { + rio_local_read_config_32(port, ext_ftr_ptr + + RIO_PORT_N_CTL_CSR(0), + ®val); + } else { + if (rio_mport_read_config_32(port, destid, hopcount, + ext_ftr_ptr + RIO_PORT_N_CTL_CSR(port_num), ®val) < 0) + return -EIO; + } + + if (regval & RIO_PORT_N_CTL_P_TYP_SER) { + /* serial */ + regval = regval | RIO_PORT_N_CTL_EN_RX_SER + | RIO_PORT_N_CTL_EN_TX_SER; + } else { + /* parallel */ + regval = regval | RIO_PORT_N_CTL_EN_RX_PAR + | RIO_PORT_N_CTL_EN_TX_PAR; + } + + if (local) { + rio_local_write_config_32(port, ext_ftr_ptr + + RIO_PORT_N_CTL_CSR(0), regval); + } else { + if (rio_mport_write_config_32(port, destid, hopcount, + ext_ftr_ptr + RIO_PORT_N_CTL_CSR(port_num), regval) < 0) + return -EIO; + } +#endif + return 0; +} +EXPORT_SYMBOL_GPL(rio_enable_rx_tx_port); + /** * rio_chk_dev_route - Validate route to the specified device. @@ -610,6 +743,7 @@ rio_mport_chk_dev_access(struct rio_mport *mport, u16 destid, u8 hopcount) return 0; } +EXPORT_SYMBOL_GPL(rio_mport_chk_dev_access); /** * rio_chk_dev_access - Validate access to the specified device. @@ -941,6 +1075,7 @@ rio_mport_get_efb(struct rio_mport *port, int local, u16 destid, return RIO_GET_BLOCK_ID(reg_val); } } +EXPORT_SYMBOL_GPL(rio_mport_get_efb); /** * rio_mport_get_feature - query for devices' extended features @@ -997,6 +1132,7 @@ rio_mport_get_feature(struct rio_mport * port, int local, u16 destid, return 0; } +EXPORT_SYMBOL_GPL(rio_mport_get_feature); /** * rio_get_asm - Begin or continue searching for a RIO device by vid/did/asm_vid/asm_did @@ -1246,6 +1382,95 @@ EXPORT_SYMBOL_GPL(rio_dma_prep_slave_sg); #endif /* CONFIG_RAPIDIO_DMA_ENGINE */ +/** + * rio_find_mport - find RIO mport by its ID + * @mport_id: number (ID) of mport device + * + * Given a RIO mport number, the desired mport is located + * in the global list of mports. If the mport is found, a pointer to its + * data structure is returned. If no mport is found, %NULL is returned. + */ +struct rio_mport *rio_find_mport(int mport_id) +{ + struct rio_mport *port; + + mutex_lock(&rio_mport_list_lock); + list_for_each_entry(port, &rio_mports, node) { + if (port->id == mport_id) + goto found; + } + port = NULL; +found: + mutex_unlock(&rio_mport_list_lock); + + return port; +} + +/** + * rio_register_scan - enumeration/discovery method registration interface + * @mport_id: mport device ID for which fabric scan routine has to be set + * (RIO_MPORT_ANY = set for all available mports) + * @scan_ops: enumeration/discovery control structure + * + * Assigns enumeration or discovery method to the specified mport device (or all + * available mports if RIO_MPORT_ANY is specified). + * Returns error if the mport already has an enumerator attached to it. + * In case of RIO_MPORT_ANY ignores ports with valid scan routines and returns + * an error if was unable to find at least one available mport. + */ +int rio_register_scan(int mport_id, struct rio_scan *scan_ops) +{ + struct rio_mport *port; + int rc = -EBUSY; + + mutex_lock(&rio_mport_list_lock); + list_for_each_entry(port, &rio_mports, node) { + if (port->id == mport_id || mport_id == RIO_MPORT_ANY) { + if (port->nscan && mport_id == RIO_MPORT_ANY) + continue; + else if (port->nscan) + break; + + port->nscan = scan_ops; + rc = 0; + + if (mport_id != RIO_MPORT_ANY) + break; + } + } + mutex_unlock(&rio_mport_list_lock); + + return rc; +} +EXPORT_SYMBOL_GPL(rio_register_scan); + +/** + * rio_unregister_scan - removes enumeration/discovery method from mport + * @mport_id: mport device ID for which fabric scan routine has to be + * unregistered (RIO_MPORT_ANY = set for all available mports) + * + * Removes enumeration or discovery method assigned to the specified mport + * device (or all available mports if RIO_MPORT_ANY is specified). + */ +int rio_unregister_scan(int mport_id) +{ + struct rio_mport *port; + + mutex_lock(&rio_mport_list_lock); + list_for_each_entry(port, &rio_mports, node) { + if (port->id == mport_id || mport_id == RIO_MPORT_ANY) { + if (port->nscan) + port->nscan = NULL; + if (mport_id != RIO_MPORT_ANY) + break; + } + } + mutex_unlock(&rio_mport_list_lock); + + return 0; +} +EXPORT_SYMBOL_GPL(rio_unregister_scan); + static void rio_fixup_device(struct rio_dev *dev) { } @@ -1274,7 +1499,7 @@ static void disc_work_handler(struct work_struct *_work) work = container_of(_work, struct rio_disc_work, work); pr_debug("RIO: discovery work for mport %d %s\n", work->mport->id, work->mport->name); - rio_disc_mport(work->mport); + work->mport->nscan->discover(work->mport, 0); } int rio_init_mports(void) @@ -1290,12 +1515,15 @@ int rio_init_mports(void) * First, run enumerations and check if we need to perform discovery * on any of the registered mports. */ + mutex_lock(&rio_mport_list_lock); list_for_each_entry(port, &rio_mports, node) { - if (port->host_deviceid >= 0) - rio_enum_mport(port); - else + if (port->host_deviceid >= 0) { + if (port->nscan) + port->nscan->enumerate(port, 0); + } else n++; } + mutex_unlock(&rio_mport_list_lock); if (!n) goto no_disc; @@ -1322,14 +1550,16 @@ int rio_init_mports(void) } n = 0; + mutex_lock(&rio_mport_list_lock); list_for_each_entry(port, &rio_mports, node) { - if (port->host_deviceid < 0) { + if (port->host_deviceid < 0 && port->nscan) { work[n].mport = port; INIT_WORK(&work[n].work, disc_work_handler); queue_work(rio_wq, &work[n].work); n++; } } + mutex_unlock(&rio_mport_list_lock); flush_workqueue(rio_wq); pr_debug("RIO: destroy discovery workqueue\n"); @@ -1342,8 +1572,6 @@ no_disc: return 0; } -device_initcall_sync(rio_init_mports); - static int hdids[RIO_MAX_MPORTS + 1]; static int rio_get_hdid(int index) @@ -1371,7 +1599,10 @@ int rio_register_mport(struct rio_mport *port) port->id = next_portid++; port->host_deviceid = rio_get_hdid(port->id); + port->nscan = NULL; + mutex_lock(&rio_mport_list_lock); list_add_tail(&port->node, &rio_mports); + mutex_unlock(&rio_mport_list_lock); return 0; } @@ -1386,3 +1617,4 @@ EXPORT_SYMBOL_GPL(rio_request_inb_mbox); EXPORT_SYMBOL_GPL(rio_release_inb_mbox); EXPORT_SYMBOL_GPL(rio_request_outb_mbox); EXPORT_SYMBOL_GPL(rio_release_outb_mbox); +EXPORT_SYMBOL_GPL(rio_init_mports); diff --git a/drivers/rapidio/rio.h b/drivers/rapidio/rio.h index b1af414f15e6..c14f864dea5c 100644 --- a/drivers/rapidio/rio.h +++ b/drivers/rapidio/rio.h @@ -15,6 +15,7 @@ #include <linux/rio.h> #define RIO_MAX_CHK_RETRY 3 +#define RIO_MPORT_ANY (-1) /* Functions internal to the RIO core code */ @@ -27,8 +28,6 @@ extern u32 rio_mport_get_efb(struct rio_mport *port, int local, u16 destid, extern int rio_mport_chk_dev_access(struct rio_mport *mport, u16 destid, u8 hopcount); extern int rio_create_sysfs_dev_files(struct rio_dev *rdev); -extern int rio_enum_mport(struct rio_mport *mport); -extern int rio_disc_mport(struct rio_mport *mport); extern int rio_std_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount, u16 table, u16 route_destid, u8 route_port); @@ -39,10 +38,18 @@ extern int rio_std_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount, u16 table); extern int rio_set_port_lockout(struct rio_dev *rdev, u32 pnum, int lock); extern struct rio_dev *rio_get_comptag(u32 comp_tag, struct rio_dev *from); +extern int rio_add_device(struct rio_dev *rdev); +extern void rio_switch_init(struct rio_dev *rdev, int do_enum); +extern int rio_enable_rx_tx_port(struct rio_mport *port, int local, u16 destid, + u8 hopcount, u8 port_num); +extern int rio_register_scan(int mport_id, struct rio_scan *scan_ops); +extern int rio_unregister_scan(int mport_id); +extern void rio_attach_device(struct rio_dev *rdev); +extern struct rio_mport *rio_find_mport(int mport_id); /* Structures internal to the RIO core code */ extern struct device_attribute rio_dev_attrs[]; -extern spinlock_t rio_global_list_lock; +extern struct bus_attribute rio_bus_attrs[]; extern struct rio_switch_ops __start_rio_switch_ops[]; extern struct rio_switch_ops __end_rio_switch_ops[]; diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 6e5017841582..815d6df8bd5f 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1539,7 +1539,10 @@ static void regulator_ena_gpio_free(struct regulator_dev *rdev) } /** - * Balance enable_count of each GPIO and actual GPIO pin control. + * regulator_ena_gpio_ctrl - balance enable_count of each GPIO and actual GPIO pin control + * @rdev: regulator_dev structure + * @enable: enable GPIO at initial use? + * * GPIO is enabled in case of initial use. (enable_count is 0) * GPIO is disabled when it is not shared any more. (enable_count <= 1) */ @@ -2702,7 +2705,7 @@ EXPORT_SYMBOL_GPL(regulator_get_voltage); /** * regulator_set_current_limit - set regulator output current limit * @regulator: regulator source - * @min_uA: Minimuum supported current in uA + * @min_uA: Minimum supported current in uA * @max_uA: Maximum supported current in uA * * Sets current sink to the desired output current. This can be set during diff --git a/drivers/regulator/dbx500-prcmu.c b/drivers/regulator/dbx500-prcmu.c index 89bd2faaef8c..ce89f7848a57 100644 --- a/drivers/regulator/dbx500-prcmu.c +++ b/drivers/regulator/dbx500-prcmu.c @@ -24,18 +24,6 @@ static int power_state_active_cnt; /* will initialize to zero */ static DEFINE_SPINLOCK(power_state_active_lock); -int power_state_active_get(void) -{ - unsigned long flags; - int cnt; - - spin_lock_irqsave(&power_state_active_lock, flags); - cnt = power_state_active_cnt; - spin_unlock_irqrestore(&power_state_active_lock, flags); - - return cnt; -} - void power_state_active_enable(void) { unsigned long flags; @@ -65,6 +53,18 @@ out: #ifdef CONFIG_REGULATOR_DEBUG +static int power_state_active_get(void) +{ + unsigned long flags; + int cnt; + + spin_lock_irqsave(&power_state_active_lock, flags); + cnt = power_state_active_cnt; + spin_unlock_irqrestore(&power_state_active_lock, flags); + + return cnt; +} + static struct ux500_regulator_debug { struct dentry *dir; struct dentry *status_file; diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index 92ceed0fc65e..3ae44ac12a94 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c @@ -840,7 +840,7 @@ static int palmas_regulators_probe(struct platform_device *pdev) break; } - if ((id == PALMAS_REG_SMPS6) && (id == PALMAS_REG_SMPS8)) + if ((id == PALMAS_REG_SMPS6) || (id == PALMAS_REG_SMPS8)) ramp_delay_support = true; if (ramp_delay_support) { @@ -878,7 +878,7 @@ static int palmas_regulators_probe(struct platform_device *pdev) pmic->desc[id].vsel_mask = SMPS10_VSEL; pmic->desc[id].enable_reg = PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, - PALMAS_SMPS10_STATUS); + PALMAS_SMPS10_CTRL); pmic->desc[id].enable_mask = SMPS10_BOOST_EN; pmic->desc[id].min_uV = 3750000; pmic->desc[id].uV_step = 1250000; diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c index 0eab77b22340..f296f3f7db9b 100644 --- a/drivers/rtc/rtc-at91rm9200.c +++ b/drivers/rtc/rtc-at91rm9200.c @@ -25,6 +25,7 @@ #include <linux/rtc.h> #include <linux/bcd.h> #include <linux/interrupt.h> +#include <linux/spinlock.h> #include <linux/ioctl.h> #include <linux/completion.h> #include <linux/io.h> @@ -42,10 +43,65 @@ #define AT91_RTC_EPOCH 1900UL /* just like arch/arm/common/rtctime.c */ +struct at91_rtc_config { + bool use_shadow_imr; +}; + +static const struct at91_rtc_config *at91_rtc_config; static DECLARE_COMPLETION(at91_rtc_updated); static unsigned int at91_alarm_year = AT91_RTC_EPOCH; static void __iomem *at91_rtc_regs; static int irq; +static DEFINE_SPINLOCK(at91_rtc_lock); +static u32 at91_rtc_shadow_imr; + +static void at91_rtc_write_ier(u32 mask) +{ + unsigned long flags; + + spin_lock_irqsave(&at91_rtc_lock, flags); + at91_rtc_shadow_imr |= mask; + at91_rtc_write(AT91_RTC_IER, mask); + spin_unlock_irqrestore(&at91_rtc_lock, flags); +} + +static void at91_rtc_write_idr(u32 mask) +{ + unsigned long flags; + + spin_lock_irqsave(&at91_rtc_lock, flags); + at91_rtc_write(AT91_RTC_IDR, mask); + /* + * Register read back (of any RTC-register) needed to make sure + * IDR-register write has reached the peripheral before updating + * shadow mask. + * + * Note that there is still a possibility that the mask is updated + * before interrupts have actually been disabled in hardware. The only + * way to be certain would be to poll the IMR-register, which is is + * the very register we are trying to emulate. The register read back + * is a reasonable heuristic. + */ + at91_rtc_read(AT91_RTC_SR); + at91_rtc_shadow_imr &= ~mask; + spin_unlock_irqrestore(&at91_rtc_lock, flags); +} + +static u32 at91_rtc_read_imr(void) +{ + unsigned long flags; + u32 mask; + + if (at91_rtc_config->use_shadow_imr) { + spin_lock_irqsave(&at91_rtc_lock, flags); + mask = at91_rtc_shadow_imr; + spin_unlock_irqrestore(&at91_rtc_lock, flags); + } else { + mask = at91_rtc_read(AT91_RTC_IMR); + } + + return mask; +} /* * Decode time/date into rtc_time structure @@ -110,9 +166,9 @@ static int at91_rtc_settime(struct device *dev, struct rtc_time *tm) cr = at91_rtc_read(AT91_RTC_CR); at91_rtc_write(AT91_RTC_CR, cr | AT91_RTC_UPDCAL | AT91_RTC_UPDTIM); - at91_rtc_write(AT91_RTC_IER, AT91_RTC_ACKUPD); + at91_rtc_write_ier(AT91_RTC_ACKUPD); wait_for_completion(&at91_rtc_updated); /* wait for ACKUPD interrupt */ - at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ACKUPD); + at91_rtc_write_idr(AT91_RTC_ACKUPD); at91_rtc_write(AT91_RTC_TIMR, bin2bcd(tm->tm_sec) << 0 @@ -144,7 +200,7 @@ static int at91_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year); tm->tm_year = at91_alarm_year - 1900; - alrm->enabled = (at91_rtc_read(AT91_RTC_IMR) & AT91_RTC_ALARM) + alrm->enabled = (at91_rtc_read_imr() & AT91_RTC_ALARM) ? 1 : 0; dev_dbg(dev, "%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__, @@ -169,7 +225,7 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) tm.tm_min = alrm->time.tm_min; tm.tm_sec = alrm->time.tm_sec; - at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ALARM); + at91_rtc_write_idr(AT91_RTC_ALARM); at91_rtc_write(AT91_RTC_TIMALR, bin2bcd(tm.tm_sec) << 0 | bin2bcd(tm.tm_min) << 8 @@ -182,7 +238,7 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) if (alrm->enabled) { at91_rtc_write(AT91_RTC_SCCR, AT91_RTC_ALARM); - at91_rtc_write(AT91_RTC_IER, AT91_RTC_ALARM); + at91_rtc_write_ier(AT91_RTC_ALARM); } dev_dbg(dev, "%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__, @@ -198,9 +254,9 @@ static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) if (enabled) { at91_rtc_write(AT91_RTC_SCCR, AT91_RTC_ALARM); - at91_rtc_write(AT91_RTC_IER, AT91_RTC_ALARM); + at91_rtc_write_ier(AT91_RTC_ALARM); } else - at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ALARM); + at91_rtc_write_idr(AT91_RTC_ALARM); return 0; } @@ -209,7 +265,7 @@ static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) */ static int at91_rtc_proc(struct device *dev, struct seq_file *seq) { - unsigned long imr = at91_rtc_read(AT91_RTC_IMR); + unsigned long imr = at91_rtc_read_imr(); seq_printf(seq, "update_IRQ\t: %s\n", (imr & AT91_RTC_ACKUPD) ? "yes" : "no"); @@ -229,7 +285,7 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id) unsigned int rtsr; unsigned long events = 0; - rtsr = at91_rtc_read(AT91_RTC_SR) & at91_rtc_read(AT91_RTC_IMR); + rtsr = at91_rtc_read(AT91_RTC_SR) & at91_rtc_read_imr(); if (rtsr) { /* this interrupt is shared! Is it ours? */ if (rtsr & AT91_RTC_ALARM) events |= (RTC_AF | RTC_IRQF); @@ -250,6 +306,43 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id) return IRQ_NONE; /* not handled */ } +static const struct at91_rtc_config at91rm9200_config = { +}; + +static const struct at91_rtc_config at91sam9x5_config = { + .use_shadow_imr = true, +}; + +#ifdef CONFIG_OF +static const struct of_device_id at91_rtc_dt_ids[] = { + { + .compatible = "atmel,at91rm9200-rtc", + .data = &at91rm9200_config, + }, { + .compatible = "atmel,at91sam9x5-rtc", + .data = &at91sam9x5_config, + }, { + /* sentinel */ + } +}; +MODULE_DEVICE_TABLE(of, at91_rtc_dt_ids); +#endif + +static const struct at91_rtc_config * +at91_rtc_get_config(struct platform_device *pdev) +{ + const struct of_device_id *match; + + if (pdev->dev.of_node) { + match = of_match_node(at91_rtc_dt_ids, pdev->dev.of_node); + if (!match) + return NULL; + return (const struct at91_rtc_config *)match->data; + } + + return &at91rm9200_config; +} + static const struct rtc_class_ops at91_rtc_ops = { .read_time = at91_rtc_readtime, .set_time = at91_rtc_settime, @@ -268,6 +361,10 @@ static int __init at91_rtc_probe(struct platform_device *pdev) struct resource *regs; int ret = 0; + at91_rtc_config = at91_rtc_get_config(pdev); + if (!at91_rtc_config) + return -ENODEV; + regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!regs) { dev_err(&pdev->dev, "no mmio resource defined\n"); @@ -290,7 +387,7 @@ static int __init at91_rtc_probe(struct platform_device *pdev) at91_rtc_write(AT91_RTC_MR, 0); /* 24 hour mode */ /* Disable all interrupts */ - at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ACKUPD | AT91_RTC_ALARM | + at91_rtc_write_idr(AT91_RTC_ACKUPD | AT91_RTC_ALARM | AT91_RTC_SECEV | AT91_RTC_TIMEV | AT91_RTC_CALEV); @@ -335,7 +432,7 @@ static int __exit at91_rtc_remove(struct platform_device *pdev) struct rtc_device *rtc = platform_get_drvdata(pdev); /* Disable all interrupts */ - at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ACKUPD | AT91_RTC_ALARM | + at91_rtc_write_idr(AT91_RTC_ACKUPD | AT91_RTC_ALARM | AT91_RTC_SECEV | AT91_RTC_TIMEV | AT91_RTC_CALEV); free_irq(irq, pdev); @@ -358,13 +455,13 @@ static int at91_rtc_suspend(struct device *dev) /* this IRQ is shared with DBGU and other hardware which isn't * necessarily doing PM like we are... */ - at91_rtc_imr = at91_rtc_read(AT91_RTC_IMR) + at91_rtc_imr = at91_rtc_read_imr() & (AT91_RTC_ALARM|AT91_RTC_SECEV); if (at91_rtc_imr) { if (device_may_wakeup(dev)) enable_irq_wake(irq); else - at91_rtc_write(AT91_RTC_IDR, at91_rtc_imr); + at91_rtc_write_idr(at91_rtc_imr); } return 0; } @@ -375,7 +472,7 @@ static int at91_rtc_resume(struct device *dev) if (device_may_wakeup(dev)) disable_irq_wake(irq); else - at91_rtc_write(AT91_RTC_IER, at91_rtc_imr); + at91_rtc_write_ier(at91_rtc_imr); } return 0; } @@ -383,12 +480,6 @@ static int at91_rtc_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(at91_rtc_pm_ops, at91_rtc_suspend, at91_rtc_resume); -static const struct of_device_id at91_rtc_dt_ids[] = { - { .compatible = "atmel,at91rm9200-rtc" }, - { /* sentinel */ } -}; -MODULE_DEVICE_TABLE(of, at91_rtc_dt_ids); - static struct platform_driver at91_rtc_driver = { .remove = __exit_p(at91_rtc_remove), .driver = { diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index cc5bea9c4b1c..f1cb706445c7 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -854,6 +854,9 @@ static int cmos_resume(struct device *dev) } spin_lock_irq(&rtc_lock); + if (device_may_wakeup(dev)) + hpet_rtc_timer_init(); + do { CMOS_WRITE(tmp, RTC_CONTROL); hpet_set_rtc_irq_bit(tmp & RTC_IRQMASK); @@ -869,7 +872,6 @@ static int cmos_resume(struct device *dev) rtc_update_irq(cmos->rtc, 1, mask); tmp &= ~RTC_AIE; hpet_mask_rtc_irq_bit(RTC_AIE); - hpet_rtc_timer_init(); } while (mask & RTC_AIE); spin_unlock_irq(&rtc_lock); } diff --git a/drivers/rtc/rtc-max8998.c b/drivers/rtc/rtc-max8998.c index 48b6612fae7f..d5af7baa48b5 100644 --- a/drivers/rtc/rtc-max8998.c +++ b/drivers/rtc/rtc-max8998.c @@ -285,7 +285,7 @@ static int max8998_rtc_probe(struct platform_device *pdev) info->irq, ret); dev_info(&pdev->dev, "RTC CHIP NAME: %s\n", pdev->id_entry->name); - if (pdata->rtc_delay) { + if (pdata && pdata->rtc_delay) { info->lp3974_bug_workaround = true; dev_warn(&pdev->dev, "LP3974 with RTC REGERR option." " RTC updates will be extremely slow.\n"); diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c index 8900ea784817..0f0609b1aa2c 100644 --- a/drivers/rtc/rtc-pl031.c +++ b/drivers/rtc/rtc-pl031.c @@ -306,7 +306,7 @@ static int pl031_remove(struct amba_device *adev) struct pl031_local *ldata = dev_get_drvdata(&adev->dev); amba_set_drvdata(adev, NULL); - free_irq(adev->irq[0], ldata->rtc); + free_irq(adev->irq[0], ldata); rtc_device_unregister(ldata->rtc); iounmap(ldata->base); kfree(ldata); diff --git a/drivers/rtc/rtc-tps6586x.c b/drivers/rtc/rtc-tps6586x.c index 459c2ffc95a6..426901cef14f 100644 --- a/drivers/rtc/rtc-tps6586x.c +++ b/drivers/rtc/rtc-tps6586x.c @@ -273,6 +273,8 @@ static int tps6586x_rtc_probe(struct platform_device *pdev) return ret; } + device_init_wakeup(&pdev->dev, 1); + platform_set_drvdata(pdev, rtc); rtc->rtc = devm_rtc_device_register(&pdev->dev, dev_name(&pdev->dev), &tps6586x_rtc_ops, THIS_MODULE); @@ -292,7 +294,6 @@ static int tps6586x_rtc_probe(struct platform_device *pdev) goto fail_rtc_register; } disable_irq(rtc->irq); - device_set_wakeup_capable(&pdev->dev, 1); return 0; fail_rtc_register: diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c index 8751a5240c99..b2eab34f38d9 100644 --- a/drivers/rtc/rtc-twl.c +++ b/drivers/rtc/rtc-twl.c @@ -524,6 +524,7 @@ static int twl_rtc_probe(struct platform_device *pdev) } platform_set_drvdata(pdev, rtc); + device_init_wakeup(&pdev->dev, 1); return 0; out2: diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 4361d9772c42..d72a9216ee2e 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c @@ -3440,8 +3440,16 @@ void dasd_generic_path_event(struct ccw_device *cdev, int *path_event) device->path_data.opm &= ~eventlpm; device->path_data.ppm &= ~eventlpm; device->path_data.npm &= ~eventlpm; - if (oldopm && !device->path_data.opm) - dasd_generic_last_path_gone(device); + if (oldopm && !device->path_data.opm) { + dev_warn(&device->cdev->dev, + "No verified channel paths remain " + "for the device\n"); + DBF_DEV_EVENT(DBF_WARNING, device, + "%s", "last verified path gone"); + dasd_eer_write(device, NULL, DASD_EER_NOPATH); + dasd_device_set_stop_bits(device, + DASD_STOPPED_DC_WAIT); + } } if (path_event[chp] & PE_PATH_AVAILABLE) { device->path_data.opm &= ~eventlpm; diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c index 4ffa66c87ea5..9ca3996f65b2 100644 --- a/drivers/s390/net/netiucv.c +++ b/drivers/s390/net/netiucv.c @@ -2040,6 +2040,7 @@ static struct net_device *netiucv_init_netdevice(char *username, char *userdata) netiucv_setup_netdevice); if (!dev) return NULL; + rtnl_lock(); if (dev_alloc_name(dev, dev->name) < 0) goto out_netdev; @@ -2061,6 +2062,7 @@ static struct net_device *netiucv_init_netdevice(char *username, char *userdata) out_fsm: kfree_fsm(privptr->fsm); out_netdev: + rtnl_unlock(); free_netdev(dev); return NULL; } @@ -2100,6 +2102,7 @@ static ssize_t conn_write(struct device_driver *drv, rc = netiucv_register_device(dev); if (rc) { + rtnl_unlock(); IUCV_DBF_TEXT_(setup, 2, "ret %d from netiucv_register_device\n", rc); goto out_free_ndev; @@ -2109,7 +2112,8 @@ static ssize_t conn_write(struct device_driver *drv, priv = netdev_priv(dev); SET_NETDEV_DEV(dev, priv->dev); - rc = register_netdev(dev); + rc = register_netdevice(dev); + rtnl_unlock(); if (rc) goto out_unreg; diff --git a/drivers/scsi/bfa/bfad_debugfs.c b/drivers/scsi/bfa/bfad_debugfs.c index 439c012be763..b63d534192e3 100644 --- a/drivers/scsi/bfa/bfad_debugfs.c +++ b/drivers/scsi/bfa/bfad_debugfs.c @@ -186,7 +186,7 @@ bfad_debugfs_lseek(struct file *file, loff_t offset, int orig) file->f_pos += offset; break; case 2: - file->f_pos = debug->buffer_len - offset; + file->f_pos = debug->buffer_len + offset; break; default: return -EINVAL; diff --git a/drivers/scsi/fnic/fnic_debugfs.c b/drivers/scsi/fnic/fnic_debugfs.c index adc1f7f471f5..85e1ffd0e5c5 100644 --- a/drivers/scsi/fnic/fnic_debugfs.c +++ b/drivers/scsi/fnic/fnic_debugfs.c @@ -174,7 +174,7 @@ static loff_t fnic_trace_debugfs_lseek(struct file *file, pos = file->f_pos + offset; break; case 2: - pos = fnic_dbg_prt->buffer_len - offset; + pos = fnic_dbg_prt->buffer_len + offset; } return (pos < 0 || pos > fnic_dbg_prt->buffer_len) ? -EINVAL : (file->f_pos = pos); diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c index f63f5ff7f274..f525ecb7a9c6 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/drivers/scsi/lpfc/lpfc_debugfs.c @@ -1178,7 +1178,7 @@ lpfc_debugfs_lseek(struct file *file, loff_t off, int whence) pos = file->f_pos + off; break; case 2: - pos = debug->len - off; + pos = debug->len + off; } return (pos < 0 || pos > debug->len) ? -EINVAL : (file->f_pos = pos); } diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c index d182c96e17ea..66b0b26a1381 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c @@ -688,8 +688,12 @@ static int tcm_qla2xxx_queue_status(struct se_cmd *se_cmd) * For FCP_READ with CHECK_CONDITION status, clear cmd->bufflen * for qla_tgt_xmit_response LLD code */ + if (se_cmd->se_cmd_flags & SCF_OVERFLOW_BIT) { + se_cmd->se_cmd_flags &= ~SCF_OVERFLOW_BIT; + se_cmd->residual_count = 0; + } se_cmd->se_cmd_flags |= SCF_UNDERFLOW_BIT; - se_cmd->residual_count = se_cmd->data_length; + se_cmd->residual_count += se_cmd->data_length; cmd->bufflen = 0; } @@ -1370,7 +1374,7 @@ static void tcm_qla2xxx_free_session(struct qla_tgt_sess *sess) dump_stack(); return; } - target_wait_for_sess_cmds(se_sess, 0); + target_wait_for_sess_cmds(se_sess); transport_deregister_session_configfs(sess->se_sess); transport_deregister_session(sess->se_sess); diff --git a/drivers/scsi/scsi_proc.c b/drivers/scsi/scsi_proc.c index db66357211ed..86f0c5d5c116 100644 --- a/drivers/scsi/scsi_proc.c +++ b/drivers/scsi/scsi_proc.c @@ -84,6 +84,7 @@ static int proc_scsi_host_open(struct inode *inode, struct file *file) static const struct file_operations proc_scsi_fops = { .open = proc_scsi_host_open, + .release = single_release, .read = seq_read, .llseek = seq_lseek, .write = proc_scsi_host_write diff --git a/drivers/spi/spi-sh-hspi.c b/drivers/spi/spi-sh-hspi.c index 60cfae51c713..eab593eaaafa 100644 --- a/drivers/spi/spi-sh-hspi.c +++ b/drivers/spi/spi-sh-hspi.c @@ -89,7 +89,7 @@ static int hspi_status_check_timeout(struct hspi_priv *hspi, u32 mask, u32 val) if ((mask & hspi_read(hspi, SPSR)) == val) return 0; - msleep(20); + udelay(10); } dev_err(hspi->dev, "timeout\n"); diff --git a/drivers/spi/spi-topcliff-pch.c b/drivers/spi/spi-topcliff-pch.c index 35f60bd252dd..637d728fbeb5 100644 --- a/drivers/spi/spi-topcliff-pch.c +++ b/drivers/spi/spi-topcliff-pch.c @@ -1487,7 +1487,7 @@ static int pch_spi_pd_probe(struct platform_device *plat_dev) return 0; err_spi_register_master: - free_irq(board_dat->pdev->irq, board_dat); + free_irq(board_dat->pdev->irq, data); err_request_irq: pch_spi_free_resources(board_dat, data); err_spi_get_resources: @@ -1667,6 +1667,7 @@ static int pch_spi_probe(struct pci_dev *pdev, pd_dev = platform_device_alloc("pch-spi", i); if (!pd_dev) { dev_err(&pdev->dev, "platform_device_alloc failed\n"); + retval = -ENOMEM; goto err_platform_device; } pd_dev_save->pd_save[i] = pd_dev; diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c index e1d769607425..34d18dcfa0db 100644 --- a/drivers/spi/spi-xilinx.c +++ b/drivers/spi/spi-xilinx.c @@ -267,7 +267,6 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) { struct xilinx_spi *xspi = spi_master_get_devdata(spi->master); u32 ipif_ier; - u16 cr; /* We get here with transmitter inhibited */ @@ -276,7 +275,6 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) xspi->remaining_bytes = t->len; INIT_COMPLETION(xspi->done); - xilinx_spi_fill_tx_fifo(xspi); /* Enable the transmit empty interrupt, which we use to determine * progress on the transmission. @@ -285,12 +283,41 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) xspi->write_fn(ipif_ier | XSPI_INTR_TX_EMPTY, xspi->regs + XIPIF_V123B_IIER_OFFSET); - /* Start the transfer by not inhibiting the transmitter any longer */ - cr = xspi->read_fn(xspi->regs + XSPI_CR_OFFSET) & - ~XSPI_CR_TRANS_INHIBIT; - xspi->write_fn(cr, xspi->regs + XSPI_CR_OFFSET); + for (;;) { + u16 cr; + u8 sr; + + xilinx_spi_fill_tx_fifo(xspi); + + /* Start the transfer by not inhibiting the transmitter any + * longer + */ + cr = xspi->read_fn(xspi->regs + XSPI_CR_OFFSET) & + ~XSPI_CR_TRANS_INHIBIT; + xspi->write_fn(cr, xspi->regs + XSPI_CR_OFFSET); + + wait_for_completion(&xspi->done); + + /* A transmit has just completed. Process received data and + * check for more data to transmit. Always inhibit the + * transmitter while the Isr refills the transmit register/FIFO, + * or make sure it is stopped if we're done. + */ + cr = xspi->read_fn(xspi->regs + XSPI_CR_OFFSET); + xspi->write_fn(cr | XSPI_CR_TRANS_INHIBIT, + xspi->regs + XSPI_CR_OFFSET); + + /* Read out all the data from the Rx FIFO */ + sr = xspi->read_fn(xspi->regs + XSPI_SR_OFFSET); + while ((sr & XSPI_SR_RX_EMPTY_MASK) == 0) { + xspi->rx_fn(xspi); + sr = xspi->read_fn(xspi->regs + XSPI_SR_OFFSET); + } - wait_for_completion(&xspi->done); + /* See if there is more data to send */ + if (!xspi->remaining_bytes > 0) + break; + } /* Disable the transmit empty interrupt */ xspi->write_fn(ipif_ier, xspi->regs + XIPIF_V123B_IIER_OFFSET); @@ -314,38 +341,7 @@ static irqreturn_t xilinx_spi_irq(int irq, void *dev_id) xspi->write_fn(ipif_isr, xspi->regs + XIPIF_V123B_IISR_OFFSET); if (ipif_isr & XSPI_INTR_TX_EMPTY) { /* Transmission completed */ - u16 cr; - u8 sr; - - /* A transmit has just completed. Process received data and - * check for more data to transmit. Always inhibit the - * transmitter while the Isr refills the transmit register/FIFO, - * or make sure it is stopped if we're done. - */ - cr = xspi->read_fn(xspi->regs + XSPI_CR_OFFSET); - xspi->write_fn(cr | XSPI_CR_TRANS_INHIBIT, - xspi->regs + XSPI_CR_OFFSET); - - /* Read out all the data from the Rx FIFO */ - sr = xspi->read_fn(xspi->regs + XSPI_SR_OFFSET); - while ((sr & XSPI_SR_RX_EMPTY_MASK) == 0) { - xspi->rx_fn(xspi); - sr = xspi->read_fn(xspi->regs + XSPI_SR_OFFSET); - } - - /* See if there is more data to send */ - if (xspi->remaining_bytes > 0) { - xilinx_spi_fill_tx_fifo(xspi); - /* Start the transfer by not inhibiting the - * transmitter any longer - */ - xspi->write_fn(cr, xspi->regs + XSPI_CR_OFFSET); - } else { - /* No more data to send. - * Indicate the transfer is completed. - */ - complete(&xspi->done); - } + complete(&xspi->done); } return IRQ_HANDLED; diff --git a/drivers/staging/android/alarm-dev.c b/drivers/staging/android/alarm-dev.c index ceb1c643753d..6dc27dac679d 100644 --- a/drivers/staging/android/alarm-dev.c +++ b/drivers/staging/android/alarm-dev.c @@ -264,6 +264,8 @@ static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) } rv = alarm_do_ioctl(file, cmd, &ts); + if (rv) + return rv; switch (ANDROID_ALARM_BASE_CMD(cmd)) { case ANDROID_ALARM_GET_TIME(0): @@ -272,7 +274,7 @@ static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) break; } - return rv; + return 0; } #ifdef CONFIG_COMPAT static long alarm_compat_ioctl(struct file *file, unsigned int cmd, @@ -295,6 +297,8 @@ static long alarm_compat_ioctl(struct file *file, unsigned int cmd, } rv = alarm_do_ioctl(file, cmd, &ts); + if (rv) + return rv; switch (ANDROID_ALARM_BASE_CMD(cmd)) { case ANDROID_ALARM_GET_TIME(0): /* NOTE: we modified cmd above */ @@ -303,7 +307,7 @@ static long alarm_compat_ioctl(struct file *file, unsigned int cmd, break; } - return rv; + return 0; } #endif diff --git a/drivers/staging/dwc2/hcd.c b/drivers/staging/dwc2/hcd.c index 827ab781ae9b..8551ccedf037 100644 --- a/drivers/staging/dwc2/hcd.c +++ b/drivers/staging/dwc2/hcd.c @@ -2804,9 +2804,8 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq, /* Set device flags indicating whether the HCD supports DMA */ if (hsotg->core_params->dma_enable > 0) { - if (dma_set_mask(hsotg->dev, DMA_BIT_MASK(31)) < 0) - dev_warn(hsotg->dev, - "can't enable workaround for >2GB RAM\n"); + if (dma_set_mask(hsotg->dev, DMA_BIT_MASK(32)) < 0) + dev_warn(hsotg->dev, "can't set DMA mask\n"); if (dma_set_coherent_mask(hsotg->dev, DMA_BIT_MASK(31)) < 0) dev_warn(hsotg->dev, "can't enable workaround for >2GB RAM\n"); diff --git a/drivers/staging/media/davinci_vpfe/Kconfig b/drivers/staging/media/davinci_vpfe/Kconfig index 2e4a28b018e8..12f321dd2399 100644 --- a/drivers/staging/media/davinci_vpfe/Kconfig +++ b/drivers/staging/media/davinci_vpfe/Kconfig @@ -1,6 +1,6 @@ config VIDEO_DM365_VPFE tristate "DM365 VPFE Media Controller Capture Driver" - depends on VIDEO_V4L2 && ARCH_DAVINCI_DM365 && !VIDEO_VPFE_CAPTURE + depends on VIDEO_V4L2 && ARCH_DAVINCI_DM365 && !VIDEO_DM365_ISIF select VIDEOBUF2_DMA_CONTIG help Support for DM365 VPFE based Media Controller Capture driver. diff --git a/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c b/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c index b88e1ddce229..d8ce20d2fbda 100644 --- a/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c +++ b/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c @@ -639,7 +639,8 @@ static int vpfe_probe(struct platform_device *pdev) if (ret) goto probe_free_dev_mem; - if (vpfe_initialize_modules(vpfe_dev, pdev)) + ret = vpfe_initialize_modules(vpfe_dev, pdev); + if (ret) goto probe_disable_clock; vpfe_dev->media_dev.dev = vpfe_dev->pdev; @@ -663,7 +664,8 @@ static int vpfe_probe(struct platform_device *pdev) /* set the driver data in platform device */ platform_set_drvdata(pdev, vpfe_dev); /* register subdevs/entities */ - if (vpfe_register_entities(vpfe_dev)) + ret = vpfe_register_entities(vpfe_dev); + if (ret) goto probe_out_v4l2_unregister; ret = vpfe_attach_irq(vpfe_dev); diff --git a/drivers/staging/media/solo6x10/Kconfig b/drivers/staging/media/solo6x10/Kconfig index df6569b997b8..34f3b6d02d2a 100644 --- a/drivers/staging/media/solo6x10/Kconfig +++ b/drivers/staging/media/solo6x10/Kconfig @@ -5,6 +5,7 @@ config SOLO6X10 select VIDEOBUF2_DMA_SG select VIDEOBUF2_DMA_CONTIG select SND_PCM + select FONT_8x16 ---help--- This driver supports the Softlogic based MPEG-4 and h.264 codec cards. diff --git a/drivers/staging/zcache/ramster.h b/drivers/staging/zcache/ramster.h index e1f91d5a0f6a..a858666eae68 100644 --- a/drivers/staging/zcache/ramster.h +++ b/drivers/staging/zcache/ramster.h @@ -11,10 +11,6 @@ #ifndef _ZCACHE_RAMSTER_H_ #define _ZCACHE_RAMSTER_H_ -#ifdef CONFIG_RAMSTER_MODULE -#define CONFIG_RAMSTER -#endif - #ifdef CONFIG_RAMSTER #include "ramster/ramster.h" #else diff --git a/drivers/staging/zcache/ramster/debug.c b/drivers/staging/zcache/ramster/debug.c index 327e4f0d98e1..5b26ee977c2f 100644 --- a/drivers/staging/zcache/ramster/debug.c +++ b/drivers/staging/zcache/ramster/debug.c @@ -1,6 +1,8 @@ #include <linux/atomic.h> #include "debug.h" +ssize_t ramster_foreign_eph_pages; +ssize_t ramster_foreign_pers_pages; #ifdef CONFIG_DEBUG_FS #include <linux/debugfs.h> diff --git a/drivers/staging/zcache/ramster/ramster.c b/drivers/staging/zcache/ramster/ramster.c index b18b887db79f..a937ce1fa27a 100644 --- a/drivers/staging/zcache/ramster/ramster.c +++ b/drivers/staging/zcache/ramster/ramster.c @@ -66,8 +66,6 @@ static int ramster_remote_target_nodenum __read_mostly = -1; /* Used by this code. */ long ramster_flnodes; -ssize_t ramster_foreign_eph_pages; -ssize_t ramster_foreign_pers_pages; /* FIXME frontswap selfshrinking knobs in debugfs? */ static LIST_HEAD(ramster_rem_op_list); @@ -399,14 +397,18 @@ void ramster_count_foreign_pages(bool eph, int count) inc_ramster_foreign_eph_pages(); } else { dec_ramster_foreign_eph_pages(); +#ifdef CONFIG_RAMSTER_DEBUG WARN_ON_ONCE(ramster_foreign_eph_pages < 0); +#endif } } else { if (count > 0) { inc_ramster_foreign_pers_pages(); } else { dec_ramster_foreign_pers_pages(); +#ifdef CONFIG_RAMSTER_DEBUG WARN_ON_ONCE(ramster_foreign_pers_pages < 0); +#endif } } } diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 262ef1f23b38..d7705e5824fb 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -651,7 +651,7 @@ static int iscsit_add_reject( cmd->buf_ptr = kmemdup(buf, ISCSI_HDR_LEN, GFP_KERNEL); if (!cmd->buf_ptr) { pr_err("Unable to allocate memory for cmd->buf_ptr\n"); - iscsit_release_cmd(cmd); + iscsit_free_cmd(cmd, false); return -1; } @@ -697,7 +697,7 @@ int iscsit_add_reject_from_cmd( cmd->buf_ptr = kmemdup(buf, ISCSI_HDR_LEN, GFP_KERNEL); if (!cmd->buf_ptr) { pr_err("Unable to allocate memory for cmd->buf_ptr\n"); - iscsit_release_cmd(cmd); + iscsit_free_cmd(cmd, false); return -1; } @@ -1743,7 +1743,7 @@ int iscsit_handle_nop_out(struct iscsi_conn *conn, struct iscsi_cmd *cmd, return 0; out: if (cmd) - iscsit_release_cmd(cmd); + iscsit_free_cmd(cmd, false); ping_out: kfree(ping_data); return ret; @@ -2251,7 +2251,7 @@ iscsit_handle_logout_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, if (conn->conn_state != TARG_CONN_STATE_LOGGED_IN) { pr_err("Received logout request on connection that" " is not in logged in state, ignoring request.\n"); - iscsit_release_cmd(cmd); + iscsit_free_cmd(cmd, false); return 0; } @@ -3665,7 +3665,7 @@ iscsit_immediate_queue(struct iscsi_conn *conn, struct iscsi_cmd *cmd, int state list_del(&cmd->i_conn_node); spin_unlock_bh(&conn->cmd_lock); - iscsit_free_cmd(cmd); + iscsit_free_cmd(cmd, false); break; case ISTATE_SEND_NOPIN_WANT_RESPONSE: iscsit_mod_nopin_response_timer(conn); @@ -4122,7 +4122,7 @@ static void iscsit_release_commands_from_conn(struct iscsi_conn *conn) iscsit_increment_maxcmdsn(cmd, sess); - iscsit_free_cmd(cmd); + iscsit_free_cmd(cmd, true); spin_lock_bh(&conn->cmd_lock); } diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c index 13e9e715ad2e..8d8b3ff68490 100644 --- a/drivers/target/iscsi/iscsi_target_configfs.c +++ b/drivers/target/iscsi/iscsi_target_configfs.c @@ -155,7 +155,7 @@ static ssize_t lio_target_np_store_iser( struct iscsi_tpg_np *tpg_np_iser = NULL; char *endptr; u32 op; - int rc; + int rc = 0; op = simple_strtoul(page, &endptr, 0); if ((op != 1) && (op != 0)) { @@ -174,31 +174,32 @@ static ssize_t lio_target_np_store_iser( return -EINVAL; if (op) { - int rc = request_module("ib_isert"); - if (rc != 0) + rc = request_module("ib_isert"); + if (rc != 0) { pr_warn("Unable to request_module for ib_isert\n"); + rc = 0; + } tpg_np_iser = iscsit_tpg_add_network_portal(tpg, &np->np_sockaddr, np->np_ip, tpg_np, ISCSI_INFINIBAND); - if (!tpg_np_iser || IS_ERR(tpg_np_iser)) + if (IS_ERR(tpg_np_iser)) { + rc = PTR_ERR(tpg_np_iser); goto out; + } } else { tpg_np_iser = iscsit_tpg_locate_child_np(tpg_np, ISCSI_INFINIBAND); - if (!tpg_np_iser) - goto out; - - rc = iscsit_tpg_del_network_portal(tpg, tpg_np_iser); - if (rc < 0) - goto out; + if (tpg_np_iser) { + rc = iscsit_tpg_del_network_portal(tpg, tpg_np_iser); + if (rc < 0) + goto out; + } } - printk("lio_target_np_store_iser() done, op: %d\n", op); - iscsit_put_tpg(tpg); return count; out: iscsit_put_tpg(tpg); - return -EINVAL; + return rc; } TF_NP_BASE_ATTR(lio_target, iser, S_IRUGO | S_IWUSR); diff --git a/drivers/target/iscsi/iscsi_target_erl0.c b/drivers/target/iscsi/iscsi_target_erl0.c index 8e6298cc8839..dcb199da06b9 100644 --- a/drivers/target/iscsi/iscsi_target_erl0.c +++ b/drivers/target/iscsi/iscsi_target_erl0.c @@ -842,11 +842,11 @@ int iscsit_stop_time2retain_timer(struct iscsi_session *sess) return 0; sess->time2retain_timer_flags |= ISCSI_TF_STOP; - spin_unlock_bh(&se_tpg->session_lock); + spin_unlock(&se_tpg->session_lock); del_timer_sync(&sess->time2retain_timer); - spin_lock_bh(&se_tpg->session_lock); + spin_lock(&se_tpg->session_lock); sess->time2retain_timer_flags &= ~ISCSI_TF_RUNNING; pr_debug("Stopped Time2Retain Timer for SID: %u\n", sess->sid); diff --git a/drivers/target/iscsi/iscsi_target_erl2.c b/drivers/target/iscsi/iscsi_target_erl2.c index ba6091bf93fc..45a5afd5ea13 100644 --- a/drivers/target/iscsi/iscsi_target_erl2.c +++ b/drivers/target/iscsi/iscsi_target_erl2.c @@ -143,7 +143,7 @@ void iscsit_free_connection_recovery_entires(struct iscsi_session *sess) list_del(&cmd->i_conn_node); cmd->conn = NULL; spin_unlock(&cr->conn_recovery_cmd_lock); - iscsit_free_cmd(cmd); + iscsit_free_cmd(cmd, true); spin_lock(&cr->conn_recovery_cmd_lock); } spin_unlock(&cr->conn_recovery_cmd_lock); @@ -165,7 +165,7 @@ void iscsit_free_connection_recovery_entires(struct iscsi_session *sess) list_del(&cmd->i_conn_node); cmd->conn = NULL; spin_unlock(&cr->conn_recovery_cmd_lock); - iscsit_free_cmd(cmd); + iscsit_free_cmd(cmd, true); spin_lock(&cr->conn_recovery_cmd_lock); } spin_unlock(&cr->conn_recovery_cmd_lock); @@ -248,7 +248,7 @@ void iscsit_discard_cr_cmds_by_expstatsn( iscsit_remove_cmd_from_connection_recovery(cmd, sess); spin_unlock(&cr->conn_recovery_cmd_lock); - iscsit_free_cmd(cmd); + iscsit_free_cmd(cmd, true); spin_lock(&cr->conn_recovery_cmd_lock); } spin_unlock(&cr->conn_recovery_cmd_lock); @@ -302,7 +302,7 @@ int iscsit_discard_unacknowledged_ooo_cmdsns_for_conn(struct iscsi_conn *conn) list_del(&cmd->i_conn_node); spin_unlock_bh(&conn->cmd_lock); - iscsit_free_cmd(cmd); + iscsit_free_cmd(cmd, true); spin_lock_bh(&conn->cmd_lock); } spin_unlock_bh(&conn->cmd_lock); @@ -355,7 +355,7 @@ int iscsit_prepare_cmds_for_realligance(struct iscsi_conn *conn) list_del(&cmd->i_conn_node); spin_unlock_bh(&conn->cmd_lock); - iscsit_free_cmd(cmd); + iscsit_free_cmd(cmd, true); spin_lock_bh(&conn->cmd_lock); continue; } @@ -375,7 +375,7 @@ int iscsit_prepare_cmds_for_realligance(struct iscsi_conn *conn) iscsi_sna_gte(cmd->cmd_sn, conn->sess->exp_cmd_sn)) { list_del(&cmd->i_conn_node); spin_unlock_bh(&conn->cmd_lock); - iscsit_free_cmd(cmd); + iscsit_free_cmd(cmd, true); spin_lock_bh(&conn->cmd_lock); continue; } diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c index bb5d5c5bce65..3402241be87c 100644 --- a/drivers/target/iscsi/iscsi_target_login.c +++ b/drivers/target/iscsi/iscsi_target_login.c @@ -984,8 +984,6 @@ int iscsi_target_setup_login_socket( } np->np_transport = t; - printk("Set np->np_transport to %p -> %s\n", np->np_transport, - np->np_transport->name); return 0; } @@ -1002,7 +1000,6 @@ int iscsit_accept_np(struct iscsi_np *np, struct iscsi_conn *conn) conn->sock = new_sock; conn->login_family = np->np_sockaddr.ss_family; - printk("iSCSI/TCP: Setup conn->sock from new_sock: %p\n", new_sock); if (np->np_sockaddr.ss_family == AF_INET6) { memset(&sock_in6, 0, sizeof(struct sockaddr_in6)); diff --git a/drivers/target/iscsi/iscsi_target_nego.c b/drivers/target/iscsi/iscsi_target_nego.c index 7ad912060e21..cd5018ff9cd7 100644 --- a/drivers/target/iscsi/iscsi_target_nego.c +++ b/drivers/target/iscsi/iscsi_target_nego.c @@ -721,9 +721,6 @@ int iscsi_target_locate_portal( start += strlen(key) + strlen(value) + 2; } - - printk("i_buf: %s, s_buf: %s, t_buf: %s\n", i_buf, s_buf, t_buf); - /* * See 5.3. Login Phase. */ diff --git a/drivers/target/iscsi/iscsi_target_parameters.c b/drivers/target/iscsi/iscsi_target_parameters.c index c2185fc31136..e38222191a33 100644 --- a/drivers/target/iscsi/iscsi_target_parameters.c +++ b/drivers/target/iscsi/iscsi_target_parameters.c @@ -758,9 +758,9 @@ static int iscsi_add_notunderstood_response( } INIT_LIST_HEAD(&extra_response->er_list); - strncpy(extra_response->key, key, strlen(key) + 1); - strncpy(extra_response->value, NOTUNDERSTOOD, - strlen(NOTUNDERSTOOD) + 1); + strlcpy(extra_response->key, key, sizeof(extra_response->key)); + strlcpy(extra_response->value, NOTUNDERSTOOD, + sizeof(extra_response->value)); list_add_tail(&extra_response->er_list, ¶m_list->extra_response_list); @@ -1629,8 +1629,6 @@ int iscsi_decode_text_input( if (phase & PHASE_SECURITY) { if (iscsi_check_for_auth_key(key) > 0) { - char *tmpptr = key + strlen(key); - *tmpptr = '='; kfree(tmpbuf); return 1; } diff --git a/drivers/target/iscsi/iscsi_target_parameters.h b/drivers/target/iscsi/iscsi_target_parameters.h index 915b06798505..a47046a752aa 100644 --- a/drivers/target/iscsi/iscsi_target_parameters.h +++ b/drivers/target/iscsi/iscsi_target_parameters.h @@ -1,8 +1,10 @@ #ifndef ISCSI_PARAMETERS_H #define ISCSI_PARAMETERS_H +#include <scsi/iscsi_proto.h> + struct iscsi_extra_response { - char key[64]; + char key[KEY_MAXLEN]; char value[32]; struct list_head er_list; } ____cacheline_aligned; diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c index 2cc6c9a3ffb8..08a3bacef0c5 100644 --- a/drivers/target/iscsi/iscsi_target_util.c +++ b/drivers/target/iscsi/iscsi_target_util.c @@ -676,40 +676,56 @@ void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *conn) void iscsit_release_cmd(struct iscsi_cmd *cmd) { - struct iscsi_conn *conn = cmd->conn; - - iscsit_free_r2ts_from_list(cmd); - iscsit_free_all_datain_reqs(cmd); - kfree(cmd->buf_ptr); kfree(cmd->pdu_list); kfree(cmd->seq_list); kfree(cmd->tmr_req); kfree(cmd->iov_data); - if (conn) { + kmem_cache_free(lio_cmd_cache, cmd); +} + +static void __iscsit_free_cmd(struct iscsi_cmd *cmd, bool scsi_cmd, + bool check_queues) +{ + struct iscsi_conn *conn = cmd->conn; + + if (scsi_cmd) { + if (cmd->data_direction == DMA_TO_DEVICE) { + iscsit_stop_dataout_timer(cmd); + iscsit_free_r2ts_from_list(cmd); + } + if (cmd->data_direction == DMA_FROM_DEVICE) + iscsit_free_all_datain_reqs(cmd); + } + + if (conn && check_queues) { iscsit_remove_cmd_from_immediate_queue(cmd, conn); iscsit_remove_cmd_from_response_queue(cmd, conn); } - - kmem_cache_free(lio_cmd_cache, cmd); } -void iscsit_free_cmd(struct iscsi_cmd *cmd) +void iscsit_free_cmd(struct iscsi_cmd *cmd, bool shutdown) { + struct se_cmd *se_cmd = NULL; + int rc; /* * Determine if a struct se_cmd is associated with * this struct iscsi_cmd. */ switch (cmd->iscsi_opcode) { case ISCSI_OP_SCSI_CMD: - if (cmd->data_direction == DMA_TO_DEVICE) - iscsit_stop_dataout_timer(cmd); + se_cmd = &cmd->se_cmd; + __iscsit_free_cmd(cmd, true, shutdown); /* * Fallthrough */ case ISCSI_OP_SCSI_TMFUNC: - transport_generic_free_cmd(&cmd->se_cmd, 1); + rc = transport_generic_free_cmd(&cmd->se_cmd, 1); + if (!rc && shutdown && se_cmd && se_cmd->se_sess) { + __iscsit_free_cmd(cmd, true, shutdown); + target_put_sess_cmd(se_cmd->se_sess, se_cmd); + } break; case ISCSI_OP_REJECT: /* @@ -718,11 +734,19 @@ void iscsit_free_cmd(struct iscsi_cmd *cmd) * associated cmd->se_cmd needs to be released. */ if (cmd->se_cmd.se_tfo != NULL) { - transport_generic_free_cmd(&cmd->se_cmd, 1); + se_cmd = &cmd->se_cmd; + __iscsit_free_cmd(cmd, true, shutdown); + + rc = transport_generic_free_cmd(&cmd->se_cmd, 1); + if (!rc && shutdown && se_cmd->se_sess) { + __iscsit_free_cmd(cmd, true, shutdown); + target_put_sess_cmd(se_cmd->se_sess, se_cmd); + } break; } /* Fall-through */ default: + __iscsit_free_cmd(cmd, false, shutdown); cmd->release_cmd(cmd); break; } diff --git a/drivers/target/iscsi/iscsi_target_util.h b/drivers/target/iscsi/iscsi_target_util.h index 4f8e01a47081..a4422659d049 100644 --- a/drivers/target/iscsi/iscsi_target_util.h +++ b/drivers/target/iscsi/iscsi_target_util.h @@ -29,7 +29,7 @@ extern void iscsit_remove_cmd_from_tx_queues(struct iscsi_cmd *, struct iscsi_co extern bool iscsit_conn_all_queues_empty(struct iscsi_conn *); extern void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *); extern void iscsit_release_cmd(struct iscsi_cmd *); -extern void iscsit_free_cmd(struct iscsi_cmd *); +extern void iscsit_free_cmd(struct iscsi_cmd *, bool); extern int iscsit_check_session_usage_count(struct iscsi_session *); extern void iscsit_dec_session_usage_count(struct iscsi_session *); extern void iscsit_inc_session_usage_count(struct iscsi_session *); diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c index 1b1d544e927a..b11890d85120 100644 --- a/drivers/target/target_core_file.c +++ b/drivers/target/target_core_file.c @@ -153,6 +153,7 @@ static int fd_configure_device(struct se_device *dev) struct request_queue *q = bdev_get_queue(inode->i_bdev); unsigned long long dev_size; + fd_dev->fd_block_size = bdev_logical_block_size(inode->i_bdev); /* * Determine the number of bytes from i_size_read() minus * one (1) logical sector from underlying struct block_device @@ -199,6 +200,7 @@ static int fd_configure_device(struct se_device *dev) goto fail; } + fd_dev->fd_block_size = FD_BLOCKSIZE; /* * Limit UNMAP emulation to 8k Number of LBAs (NoLB) */ @@ -217,9 +219,7 @@ static int fd_configure_device(struct se_device *dev) dev->dev_attrib.max_write_same_len = 0x1000; } - fd_dev->fd_block_size = dev->dev_attrib.hw_block_size; - - dev->dev_attrib.hw_block_size = FD_BLOCKSIZE; + dev->dev_attrib.hw_block_size = fd_dev->fd_block_size; dev->dev_attrib.hw_max_sectors = FD_MAX_SECTORS; dev->dev_attrib.hw_queue_depth = FD_MAX_DEVICE_QUEUE_DEPTH; @@ -694,11 +694,12 @@ static sector_t fd_get_blocks(struct se_device *dev) * to handle underlying block_device resize operations. */ if (S_ISBLK(i->i_mode)) - dev_size = (i_size_read(i) - fd_dev->fd_block_size); + dev_size = i_size_read(i); else dev_size = fd_dev->fd_dev_size; - return div_u64(dev_size, dev->dev_attrib.block_size); + return div_u64(dev_size - dev->dev_attrib.block_size, + dev->dev_attrib.block_size); } static struct sbc_ops fd_sbc_ops = { diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 4a793362309d..21e315874a54 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -65,7 +65,7 @@ static void transport_complete_task_attr(struct se_cmd *cmd); static void transport_handle_queue_full(struct se_cmd *cmd, struct se_device *dev); static int transport_generic_get_mem(struct se_cmd *cmd); -static void transport_put_cmd(struct se_cmd *cmd); +static int transport_put_cmd(struct se_cmd *cmd); static void target_complete_ok_work(struct work_struct *work); int init_se_kmem_caches(void) @@ -221,6 +221,7 @@ struct se_session *transport_init_session(void) INIT_LIST_HEAD(&se_sess->sess_list); INIT_LIST_HEAD(&se_sess->sess_acl_list); INIT_LIST_HEAD(&se_sess->sess_cmd_list); + INIT_LIST_HEAD(&se_sess->sess_wait_list); spin_lock_init(&se_sess->sess_cmd_lock); kref_init(&se_sess->sess_kref); @@ -1943,7 +1944,7 @@ static inline void transport_free_pages(struct se_cmd *cmd) * This routine unconditionally frees a command, and reference counting * or list removal must be done in the caller. */ -static void transport_release_cmd(struct se_cmd *cmd) +static int transport_release_cmd(struct se_cmd *cmd) { BUG_ON(!cmd->se_tfo); @@ -1955,11 +1956,11 @@ static void transport_release_cmd(struct se_cmd *cmd) * If this cmd has been setup with target_get_sess_cmd(), drop * the kref and call ->release_cmd() in kref callback. */ - if (cmd->check_release != 0) { - target_put_sess_cmd(cmd->se_sess, cmd); - return; - } + if (cmd->check_release != 0) + return target_put_sess_cmd(cmd->se_sess, cmd); + cmd->se_tfo->release_cmd(cmd); + return 1; } /** @@ -1968,7 +1969,7 @@ static void transport_release_cmd(struct se_cmd *cmd) * * This routine releases our reference to the command and frees it if possible. */ -static void transport_put_cmd(struct se_cmd *cmd) +static int transport_put_cmd(struct se_cmd *cmd) { unsigned long flags; @@ -1976,7 +1977,7 @@ static void transport_put_cmd(struct se_cmd *cmd) if (atomic_read(&cmd->t_fe_count) && !atomic_dec_and_test(&cmd->t_fe_count)) { spin_unlock_irqrestore(&cmd->t_state_lock, flags); - return; + return 0; } if (cmd->transport_state & CMD_T_DEV_ACTIVE) { @@ -1986,8 +1987,7 @@ static void transport_put_cmd(struct se_cmd *cmd) spin_unlock_irqrestore(&cmd->t_state_lock, flags); transport_free_pages(cmd); - transport_release_cmd(cmd); - return; + return transport_release_cmd(cmd); } void *transport_kmap_data_sg(struct se_cmd *cmd) @@ -2152,13 +2152,15 @@ static void transport_write_pending_qf(struct se_cmd *cmd) } } -void transport_generic_free_cmd(struct se_cmd *cmd, int wait_for_tasks) +int transport_generic_free_cmd(struct se_cmd *cmd, int wait_for_tasks) { + int ret = 0; + if (!(cmd->se_cmd_flags & SCF_SE_LUN_CMD)) { if (wait_for_tasks && (cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)) transport_wait_for_tasks(cmd); - transport_release_cmd(cmd); + ret = transport_release_cmd(cmd); } else { if (wait_for_tasks) transport_wait_for_tasks(cmd); @@ -2166,8 +2168,9 @@ void transport_generic_free_cmd(struct se_cmd *cmd, int wait_for_tasks) if (cmd->se_lun) transport_lun_remove_cmd(cmd); - transport_put_cmd(cmd); + ret = transport_put_cmd(cmd); } + return ret; } EXPORT_SYMBOL(transport_generic_free_cmd); @@ -2250,11 +2253,14 @@ void target_sess_cmd_list_set_waiting(struct se_session *se_sess) unsigned long flags; spin_lock_irqsave(&se_sess->sess_cmd_lock, flags); - - WARN_ON(se_sess->sess_tearing_down); + if (se_sess->sess_tearing_down) { + spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags); + return; + } se_sess->sess_tearing_down = 1; + list_splice_init(&se_sess->sess_cmd_list, &se_sess->sess_wait_list); - list_for_each_entry(se_cmd, &se_sess->sess_cmd_list, se_cmd_list) + list_for_each_entry(se_cmd, &se_sess->sess_wait_list, se_cmd_list) se_cmd->cmd_wait_set = 1; spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags); @@ -2263,44 +2269,32 @@ EXPORT_SYMBOL(target_sess_cmd_list_set_waiting); /* target_wait_for_sess_cmds - Wait for outstanding descriptors * @se_sess: session to wait for active I/O - * @wait_for_tasks: Make extra transport_wait_for_tasks call */ -void target_wait_for_sess_cmds( - struct se_session *se_sess, - int wait_for_tasks) +void target_wait_for_sess_cmds(struct se_session *se_sess) { struct se_cmd *se_cmd, *tmp_cmd; - bool rc = false; + unsigned long flags; list_for_each_entry_safe(se_cmd, tmp_cmd, - &se_sess->sess_cmd_list, se_cmd_list) { + &se_sess->sess_wait_list, se_cmd_list) { list_del(&se_cmd->se_cmd_list); pr_debug("Waiting for se_cmd: %p t_state: %d, fabric state:" " %d\n", se_cmd, se_cmd->t_state, se_cmd->se_tfo->get_cmd_state(se_cmd)); - if (wait_for_tasks) { - pr_debug("Calling transport_wait_for_tasks se_cmd: %p t_state: %d," - " fabric state: %d\n", se_cmd, se_cmd->t_state, - se_cmd->se_tfo->get_cmd_state(se_cmd)); - - rc = transport_wait_for_tasks(se_cmd); - - pr_debug("After transport_wait_for_tasks se_cmd: %p t_state: %d," - " fabric state: %d\n", se_cmd, se_cmd->t_state, - se_cmd->se_tfo->get_cmd_state(se_cmd)); - } - - if (!rc) { - wait_for_completion(&se_cmd->cmd_wait_comp); - pr_debug("After cmd_wait_comp: se_cmd: %p t_state: %d" - " fabric state: %d\n", se_cmd, se_cmd->t_state, - se_cmd->se_tfo->get_cmd_state(se_cmd)); - } + wait_for_completion(&se_cmd->cmd_wait_comp); + pr_debug("After cmd_wait_comp: se_cmd: %p t_state: %d" + " fabric state: %d\n", se_cmd, se_cmd->t_state, + se_cmd->se_tfo->get_cmd_state(se_cmd)); se_cmd->se_tfo->release_cmd(se_cmd); } + + spin_lock_irqsave(&se_sess->sess_cmd_lock, flags); + WARN_ON(!list_empty(&se_sess->sess_cmd_list)); + spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags); + } EXPORT_SYMBOL(target_wait_for_sess_cmds); diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 59bfaecc4e14..abfd99089781 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -244,14 +244,9 @@ static void pty_flush_buffer(struct tty_struct *tty) static int pty_open(struct tty_struct *tty, struct file *filp) { - int retval = -ENODEV; - if (!tty || !tty->link) - goto out; - - set_bit(TTY_IO_ERROR, &tty->flags); + return -ENODEV; - retval = -EIO; if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) goto out; if (test_bit(TTY_PTY_LOCK, &tty->link->flags)) @@ -262,9 +257,11 @@ static int pty_open(struct tty_struct *tty, struct file *filp) clear_bit(TTY_IO_ERROR, &tty->flags); clear_bit(TTY_OTHER_CLOSED, &tty->link->flags); set_bit(TTY_THROTTLED, &tty->flags); - retval = 0; + return 0; + out: - return retval; + set_bit(TTY_IO_ERROR, &tty->flags); + return -EIO; } static void pty_set_termios(struct tty_struct *tty, diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 46528d57be72..86c00b1c5583 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -2755,7 +2755,7 @@ static void __init serial8250_isa_init_ports(void) if (nr_uarts > UART_NR) nr_uarts = UART_NR; - for (i = 0; i < UART_NR; i++) { + for (i = 0; i < nr_uarts; i++) { struct uart_8250_port *up = &serial8250_ports[i]; struct uart_port *port = &up->port; @@ -2916,7 +2916,7 @@ static int __init serial8250_console_setup(struct console *co, char *options) * if so, search for the first available port that does have * console support. */ - if (co->index >= UART_NR) + if (co->index >= nr_uarts) co->index = 0; port = &serial8250_ports[co->index].port; if (!port->iobase && !port->membase) @@ -2957,7 +2957,7 @@ int serial8250_find_port(struct uart_port *p) int line; struct uart_port *port; - for (line = 0; line < UART_NR; line++) { + for (line = 0; line < nr_uarts; line++) { port = &serial8250_ports[line].port; if (uart_match_port(p, port)) return line; @@ -3110,7 +3110,7 @@ static int serial8250_remove(struct platform_device *dev) { int i; - for (i = 0; i < UART_NR; i++) { + for (i = 0; i < nr_uarts; i++) { struct uart_8250_port *up = &serial8250_ports[i]; if (up->port.dev == &dev->dev) @@ -3178,7 +3178,7 @@ static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port * /* * First, find a port entry which matches. */ - for (i = 0; i < UART_NR; i++) + for (i = 0; i < nr_uarts; i++) if (uart_match_port(&serial8250_ports[i].port, port)) return &serial8250_ports[i]; @@ -3187,7 +3187,7 @@ static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port * * free entry. We look for one which hasn't been previously * used (indicated by zero iobase). */ - for (i = 0; i < UART_NR; i++) + for (i = 0; i < nr_uarts; i++) if (serial8250_ports[i].port.type == PORT_UNKNOWN && serial8250_ports[i].port.iobase == 0) return &serial8250_ports[i]; @@ -3196,7 +3196,7 @@ static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port * * That also failed. Last resort is to find any entry which * doesn't have a real port associated with it. */ - for (i = 0; i < UART_NR; i++) + for (i = 0; i < nr_uarts; i++) if (serial8250_ports[i].port.type == PORT_UNKNOWN) return &serial8250_ports[i]; diff --git a/drivers/tty/serial/8250/8250_gsc.c b/drivers/tty/serial/8250/8250_gsc.c index 097dff9c08ad..bb91b4713ebd 100644 --- a/drivers/tty/serial/8250/8250_gsc.c +++ b/drivers/tty/serial/8250/8250_gsc.c @@ -30,6 +30,12 @@ static int __init serial_init_chip(struct parisc_device *dev) unsigned long address; int err; +#ifdef CONFIG_64BIT + extern int iosapic_serial_irq(int cellnum); + if (!dev->irq && (dev->id.sversion == 0xad)) + dev->irq = iosapic_serial_irq(dev->mod_index-1); +#endif + if (!dev->irq) { /* We find some unattached serial ports by walking native * busses. These should be silently ignored. Otherwise, @@ -51,7 +57,8 @@ static int __init serial_init_chip(struct parisc_device *dev) memset(&uart, 0, sizeof(uart)); uart.port.iotype = UPIO_MEM; /* 7.272727MHz on Lasi. Assumed the same for Dino, Wax and Timi. */ - uart.port.uartclk = 7272727; + uart.port.uartclk = (dev->id.sversion != 0xad) ? + 7272727 : 1843200; uart.port.mapbase = address; uart.port.membase = ioremap_nocache(address, 16); uart.port.irq = dev->irq; @@ -73,6 +80,7 @@ static struct parisc_device_id serial_tbl[] = { { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00075 }, { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008c }, { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008d }, + { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x000ad }, { 0 } }; diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 147c9e193595..8cdfbd365892 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -761,6 +761,8 @@ static int imx_startup(struct uart_port *port) temp = readl(sport->port.membase + UCR2); temp |= (UCR2_RXEN | UCR2_TXEN); + if (!sport->have_rtscts) + temp |= UCR2_IRTS; writel(temp, sport->port.membase + UCR2); if (USE_IRDA(sport)) { diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 30d4f7a783cd..f0b9f6b52b32 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -202,26 +202,6 @@ static int serial_omap_get_context_loss_count(struct uart_omap_port *up) return pdata->get_context_loss_count(up->dev); } -static void serial_omap_set_forceidle(struct uart_omap_port *up) -{ - struct omap_uart_port_info *pdata = up->dev->platform_data; - - if (!pdata || !pdata->set_forceidle) - return; - - pdata->set_forceidle(up->dev); -} - -static void serial_omap_set_noidle(struct uart_omap_port *up) -{ - struct omap_uart_port_info *pdata = up->dev->platform_data; - - if (!pdata || !pdata->set_noidle) - return; - - pdata->set_noidle(up->dev); -} - static void serial_omap_enable_wakeup(struct uart_omap_port *up, bool enable) { struct omap_uart_port_info *pdata = up->dev->platform_data; @@ -298,8 +278,6 @@ static void serial_omap_stop_tx(struct uart_port *port) serial_out(up, UART_IER, up->ier); } - serial_omap_set_forceidle(up); - pm_runtime_mark_last_busy(up->dev); pm_runtime_put_autosuspend(up->dev); } @@ -364,7 +342,6 @@ static void serial_omap_start_tx(struct uart_port *port) pm_runtime_get_sync(up->dev); serial_omap_enable_ier_thri(up); - serial_omap_set_noidle(up); pm_runtime_mark_last_busy(up->dev); pm_runtime_put_autosuspend(up->dev); } diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index 89429410a245..0c8a9fa2be6c 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c @@ -1166,6 +1166,18 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, ourport->tx_irq = ret; ourport->clk = clk_get(&platdev->dev, "uart"); + if (IS_ERR(ourport->clk)) { + pr_err("%s: Controller clock not found\n", + dev_name(&platdev->dev)); + return PTR_ERR(ourport->clk); + } + + ret = clk_prepare_enable(ourport->clk); + if (ret) { + pr_err("uart: clock failed to prepare+enable: %d\n", ret); + clk_put(ourport->clk); + return ret; + } /* Keep all interrupts masked and cleared */ if (s3c24xx_serial_has_interrupt_mask(port)) { @@ -1180,6 +1192,7 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, /* reset the fifos (and setup the uart) */ s3c24xx_serial_resetport(port, cfg); + clk_disable_unprepare(ourport->clk); return 0; } diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c index fc2c06c66e89..2bd78e2ac8ec 100644 --- a/drivers/tty/vt/vt_ioctl.c +++ b/drivers/tty/vt/vt_ioctl.c @@ -289,13 +289,10 @@ static int vt_disallocate(unsigned int vc_num) struct vc_data *vc = NULL; int ret = 0; - if (!vc_num) - return 0; - console_lock(); if (VT_BUSY(vc_num)) ret = -EBUSY; - else + else if (vc_num) vc = vc_deallocate(vc_num); console_unlock(); diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 49b098bedf9b..475c9c114689 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -276,8 +276,9 @@ static void ci_role_work(struct work_struct *work) ci_role_stop(ci); ci_role_start(ci, role); - enable_irq(ci->irq); } + + enable_irq(ci->irq); } static irqreturn_t ci_irq(int irq, void *data) diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 519ead2443c5..b501346484ae 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -1678,8 +1678,11 @@ static int udc_start(struct ci13xxx *ci) ci->gadget.ep0 = &ci->ep0in->ep; - if (ci->global_phy) + if (ci->global_phy) { ci->transceiver = usb_get_phy(USB_PHY_TYPE_USB2); + if (IS_ERR(ci->transceiver)) + ci->transceiver = NULL; + } if (ci->platdata->flags & CI13XXX_REQUIRE_TRANSCEIVER) { if (ci->transceiver == NULL) { @@ -1694,7 +1697,7 @@ static int udc_start(struct ci13xxx *ci) goto put_transceiver; } - if (!IS_ERR_OR_NULL(ci->transceiver)) { + if (ci->transceiver) { retval = otg_set_peripheral(ci->transceiver->otg, &ci->gadget); if (retval) @@ -1711,7 +1714,7 @@ static int udc_start(struct ci13xxx *ci) return retval; remove_trans: - if (!IS_ERR_OR_NULL(ci->transceiver)) { + if (ci->transceiver) { otg_set_peripheral(ci->transceiver->otg, NULL); if (ci->global_phy) usb_put_phy(ci->transceiver); @@ -1719,7 +1722,7 @@ remove_trans: dev_err(dev, "error = %i\n", retval); put_transceiver: - if (!IS_ERR_OR_NULL(ci->transceiver) && ci->global_phy) + if (ci->transceiver && ci->global_phy) usb_put_phy(ci->transceiver); destroy_eps: destroy_eps(ci); @@ -1747,7 +1750,7 @@ static void udc_stop(struct ci13xxx *ci) dma_pool_destroy(ci->td_pool); dma_pool_destroy(ci->qh_pool); - if (!IS_ERR_OR_NULL(ci->transceiver)) { + if (ci->transceiver) { otg_set_peripheral(ci->transceiver->otg, NULL); if (ci->global_phy) usb_put_phy(ci->transceiver); diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index caefc800f298..c88c4fb9459d 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -1287,9 +1287,13 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, goto error; } for (totlen = u = 0; u < uurb->number_of_packets; u++) { - /* arbitrary limit, - * sufficient for USB 2.0 high-bandwidth iso */ - if (isopkt[u].length > 8192) { + /* + * arbitrary limit need for USB 3.0 + * bMaxBurst (0~15 allowed, 1~16 packets) + * bmAttributes (bit 1:0, mult 0~2, 1~3 packets) + * sizemax: 1024 * 16 * 3 = 49152 + */ + if (isopkt[u].length > 49152) { ret = -EINVAL; goto error; } diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c index 929e7dd6e58b..8ce9d7fd6cfc 100644 --- a/drivers/usb/dwc3/dwc3-exynos.c +++ b/drivers/usb/dwc3/dwc3-exynos.c @@ -164,9 +164,9 @@ static int dwc3_exynos_remove(struct platform_device *pdev) { struct dwc3_exynos *exynos = platform_get_drvdata(pdev); + device_for_each_child(&pdev->dev, NULL, dwc3_exynos_remove_child); platform_device_unregister(exynos->usb2_phy); platform_device_unregister(exynos->usb3_phy); - device_for_each_child(&pdev->dev, NULL, dwc3_exynos_remove_child); clk_disable_unprepare(exynos->clk); diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index 227d4a7acad7..eba9e2baf32b 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -196,9 +196,9 @@ static void dwc3_pci_remove(struct pci_dev *pci) { struct dwc3_pci *glue = pci_get_drvdata(pci); + platform_device_unregister(glue->dwc3); platform_device_unregister(glue->usb2_phy); platform_device_unregister(glue->usb3_phy); - platform_device_unregister(glue->dwc3); pci_set_drvdata(pci, NULL); pci_disable_device(pci); } diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 2b6e7e001207..b5e5b35df49c 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1706,11 +1706,19 @@ static void dwc3_gadget_free_endpoints(struct dwc3 *dwc) dep = dwc->eps[epnum]; if (!dep) continue; - - dwc3_free_trb_pool(dep); - - if (epnum != 0 && epnum != 1) + /* + * Physical endpoints 0 and 1 are special; they form the + * bi-directional USB endpoint 0. + * + * For those two physical endpoints, we don't allocate a TRB + * pool nor do we add them the endpoints list. Due to that, we + * shouldn't do these two operations otherwise we would end up + * with all sorts of bugs when removing dwc3.ko. + */ + if (epnum != 0 && epnum != 1) { + dwc3_free_trb_pool(dep); list_del(&dep->endpoint.ep_list); + } kfree(dep); } diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index acff5b8f6e89..f80d0330d548 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -213,7 +213,7 @@ static inline unsigned char tt_start_uframe(struct ehci_hcd *ehci, __hc32 mask) } static const unsigned char -max_tt_usecs[] = { 125, 125, 125, 125, 125, 125, 125, 25 }; +max_tt_usecs[] = { 125, 125, 125, 125, 125, 125, 30, 0 }; /* carryover low/fullspeed bandwidth that crosses uframe boundries */ static inline void carryover_tt_bandwidth(unsigned short tt_usecs[8]) @@ -646,6 +646,10 @@ static void end_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh) /* reschedule QH iff another request is queued */ if (!list_empty(&qh->qtd_list) && ehci->rh_state == EHCI_RH_RUNNING) { rc = qh_schedule(ehci, qh); + if (rc == 0) { + qh_refresh(ehci, qh); + qh_link_periodic(ehci, qh); + } /* An error here likely indicates handshake failure * or no space left in the schedule. Neither fault @@ -653,9 +657,10 @@ static void end_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh) * * FIXME kill the now-dysfunctional queued urbs */ - if (rc != 0) + else { ehci_err(ehci, "can't reschedule qh %p, err %d\n", qh, rc); + } } /* maybe turn off periodic schedule */ diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 2cfc465925bd..fbf75e57628b 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -1827,6 +1827,9 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) } spin_unlock_irqrestore(&xhci->lock, flags); + if (!xhci->rh_bw) + goto no_bw; + num_ports = HCS_MAX_PORTS(xhci->hcs_params1); for (i = 0; i < num_ports; i++) { struct xhci_interval_bw_table *bwt = &xhci->rh_bw[i].bw_table; @@ -1845,6 +1848,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) } } +no_bw: xhci->num_usb2_ports = 0; xhci->num_usb3_ports = 0; xhci->num_active_eps = 0; @@ -2256,6 +2260,9 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) u32 page_size, temp; int i; + INIT_LIST_HEAD(&xhci->lpm_failed_devs); + INIT_LIST_HEAD(&xhci->cancel_cmd_list); + page_size = xhci_readl(xhci, &xhci->op_regs->page_size); xhci_dbg(xhci, "Supported page size register = 0x%x\n", page_size); for (i = 0; i < 16; i++) { @@ -2334,7 +2341,6 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) xhci->cmd_ring = xhci_ring_alloc(xhci, 1, 1, TYPE_COMMAND, flags); if (!xhci->cmd_ring) goto fail; - INIT_LIST_HEAD(&xhci->cancel_cmd_list); xhci_dbg(xhci, "Allocated command ring at %p\n", xhci->cmd_ring); xhci_dbg(xhci, "First segment DMA is 0x%llx\n", (unsigned long long)xhci->cmd_ring->first_seg->dma); @@ -2445,8 +2451,6 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) if (xhci_setup_port_arrays(xhci, flags)) goto fail; - INIT_LIST_HEAD(&xhci->lpm_failed_devs); - /* Enable USB 3.0 device notifications for function remote wake, which * is necessary for allowing USB 3.0 devices to do remote wakeup from * U3 (device suspend). diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 1a30c380043c..cc24e39b97d5 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -221,6 +221,14 @@ static void xhci_pci_remove(struct pci_dev *dev) static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup) { struct xhci_hcd *xhci = hcd_to_xhci(hcd); + struct pci_dev *pdev = to_pci_dev(hcd->self.controller); + + /* + * Systems with the TI redriver that loses port status change events + * need to have the registers polled during D3, so avoid D3cold. + */ + if (xhci_compliance_mode_recovery_timer_quirk_check()) + pdev->no_d3cold = true; return xhci_suspend(xhci); } diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index b4aa79d154b2..d8f640b12dd9 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -466,7 +466,7 @@ static void compliance_mode_recovery_timer_init(struct xhci_hcd *xhci) * Systems: * Vendor: Hewlett-Packard -> System Models: Z420, Z620 and Z820 */ -static bool compliance_mode_recovery_timer_quirk_check(void) +bool xhci_compliance_mode_recovery_timer_quirk_check(void) { const char *dmi_product_name, *dmi_sys_vendor; @@ -517,7 +517,7 @@ int xhci_init(struct usb_hcd *hcd) xhci_dbg(xhci, "Finished xhci_init\n"); /* Initializing Compliance Mode Recovery Data If Needed */ - if (compliance_mode_recovery_timer_quirk_check()) { + if (xhci_compliance_mode_recovery_timer_quirk_check()) { xhci->quirks |= XHCI_COMP_MODE_QUIRK; compliance_mode_recovery_timer_init(xhci); } @@ -956,6 +956,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) struct usb_hcd *hcd = xhci_to_hcd(xhci); struct usb_hcd *secondary_hcd; int retval = 0; + bool comp_timer_running = false; /* Wait a bit if either of the roothubs need to settle from the * transition into bus suspend. @@ -993,6 +994,13 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) /* If restore operation fails, re-initialize the HC during resume */ if ((temp & STS_SRE) || hibernated) { + + if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) && + !(xhci_all_ports_seen_u0(xhci))) { + del_timer_sync(&xhci->comp_mode_recovery_timer); + xhci_dbg(xhci, "Compliance Mode Recovery Timer deleted!\n"); + } + /* Let the USB core know _both_ roothubs lost power. */ usb_root_hub_lost_power(xhci->main_hcd->self.root_hub); usb_root_hub_lost_power(xhci->shared_hcd->self.root_hub); @@ -1035,6 +1043,8 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) retval = xhci_init(hcd->primary_hcd); if (retval) return retval; + comp_timer_running = true; + xhci_dbg(xhci, "Start the primary HCD\n"); retval = xhci_run(hcd->primary_hcd); if (!retval) { @@ -1076,7 +1086,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) * to suffer the Compliance Mode issue again. It doesn't matter if * ports have entered previously to U0 before system's suspension. */ - if (xhci->quirks & XHCI_COMP_MODE_QUIRK) + if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) && !comp_timer_running) compliance_mode_recovery_timer_init(xhci); /* Re-enable port polling. */ diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 29c978e37135..77600cefcaf1 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1853,4 +1853,7 @@ struct xhci_input_control_ctx *xhci_get_input_control_ctx(struct xhci_hcd *xhci, struct xhci_slot_ctx *xhci_get_slot_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx); struct xhci_ep_ctx *xhci_get_ep_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx, unsigned int ep_index); +/* xHCI quirks */ +bool xhci_compliance_mode_recovery_timer_quirk_check(void); + #endif /* __LINUX_XHCI_HCD_H */ diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 8914dec49f01..9d3044bdebe5 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -1232,7 +1232,6 @@ void musb_host_tx(struct musb *musb, u8 epnum) void __iomem *mbase = musb->mregs; struct dma_channel *dma; bool transfer_pending = false; - static bool use_sg; musb_ep_select(mbase, epnum); tx_csr = musb_readw(epio, MUSB_TXCSR); @@ -1463,9 +1462,9 @@ done: * NULL. */ if (!urb->transfer_buffer) - use_sg = true; + qh->use_sg = true; - if (use_sg) { + if (qh->use_sg) { /* sg_miter_start is already done in musb_ep_program */ if (!sg_miter_next(&qh->sg_miter)) { dev_err(musb->controller, "error: sg list empty\n"); @@ -1484,9 +1483,9 @@ done: qh->segsize = length; - if (use_sg) { + if (qh->use_sg) { if (offset + length >= urb->transfer_buffer_length) - use_sg = false; + qh->use_sg = false; } musb_ep_select(mbase, epnum); @@ -1552,7 +1551,6 @@ void musb_host_rx(struct musb *musb, u8 epnum) bool done = false; u32 status; struct dma_channel *dma; - static bool use_sg; unsigned int sg_flags = SG_MITER_ATOMIC | SG_MITER_TO_SG; musb_ep_select(mbase, epnum); @@ -1878,12 +1876,12 @@ void musb_host_rx(struct musb *musb, u8 epnum) * NULL. */ if (!urb->transfer_buffer) { - use_sg = true; + qh->use_sg = true; sg_miter_start(&qh->sg_miter, urb->sg, 1, sg_flags); } - if (use_sg) { + if (qh->use_sg) { if (!sg_miter_next(&qh->sg_miter)) { dev_err(musb->controller, "error: sg list empty\n"); sg_miter_stop(&qh->sg_miter); @@ -1913,8 +1911,8 @@ finish: urb->actual_length += xfer_len; qh->offset += xfer_len; if (done) { - if (use_sg) - use_sg = false; + if (qh->use_sg) + qh->use_sg = false; if (urb->status == -EINPROGRESS) urb->status = status; diff --git a/drivers/usb/musb/musb_host.h b/drivers/usb/musb/musb_host.h index 5a9c8feec10c..738f7eb60df9 100644 --- a/drivers/usb/musb/musb_host.h +++ b/drivers/usb/musb/musb_host.h @@ -74,6 +74,7 @@ struct musb_qh { u16 frame; /* for periodic schedule */ unsigned iso_idx; /* in urb->iso_frame_desc[] */ struct sg_mapping_iter sg_miter; /* for highmem in PIO mode */ + bool use_sg; /* to track urb using sglist */ }; /* map from control or bulk queue head to the first qh on that ring */ diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig index 7ef3eb8617a6..2311b1e4e43c 100644 --- a/drivers/usb/phy/Kconfig +++ b/drivers/usb/phy/Kconfig @@ -4,11 +4,17 @@ menuconfig USB_PHY bool "USB Physical Layer drivers" help - USB controllers (those which are host, device or DRD) need a - device to handle the physical layer signalling, commonly called - a PHY. + Most USB controllers have the physical layer signalling part + (commonly called a PHY) built in. However, dual-role devices + (a.k.a. USB on-the-go) which support being USB master or slave + with the same connector often use an external PHY. - The following drivers add support for such PHY devices. + The drivers in this submenu add support for such PHY devices. + They are not needed for standard master-only (or the vast + majority of slave-only) USB interfaces. + + If you're not sure if this applies to you, it probably doesn't; + say N here. if USB_PHY diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c index 3b16118cbf62..40e7fd94646f 100644 --- a/drivers/usb/serial/ark3116.c +++ b/drivers/usb/serial/ark3116.c @@ -43,7 +43,7 @@ #define DRIVER_NAME "ark3116" /* usb timeout of 1 second */ -#define ARK_TIMEOUT (1*HZ) +#define ARK_TIMEOUT 1000 static const struct usb_device_id id_table[] = { { USB_DEVICE(0x6547, 0x0232) }, diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index d341555d37d8..082120198f87 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c @@ -65,6 +65,7 @@ static const struct usb_device_id id_table_earthmate[] = { static const struct usb_device_id id_table_cyphidcomrs232[] = { { USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) }, { USB_DEVICE(VENDOR_ID_POWERCOM, PRODUCT_ID_UPS) }, + { USB_DEVICE(VENDOR_ID_FRWD, PRODUCT_ID_CYPHIDCOM_FRWD) }, { } /* Terminating entry */ }; @@ -78,6 +79,7 @@ static const struct usb_device_id id_table_combined[] = { { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB_LT20) }, { USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) }, { USB_DEVICE(VENDOR_ID_POWERCOM, PRODUCT_ID_UPS) }, + { USB_DEVICE(VENDOR_ID_FRWD, PRODUCT_ID_CYPHIDCOM_FRWD) }, { USB_DEVICE(VENDOR_ID_DAZZLE, PRODUCT_ID_CA42) }, { } /* Terminating entry */ }; @@ -229,6 +231,12 @@ static struct usb_serial_driver * const serial_drivers[] = { * Cypress serial helper functions *****************************************************************************/ +/* FRWD Dongle hidcom needs to skip reset and speed checks */ +static inline bool is_frwd(struct usb_device *dev) +{ + return ((le16_to_cpu(dev->descriptor.idVendor) == VENDOR_ID_FRWD) && + (le16_to_cpu(dev->descriptor.idProduct) == PRODUCT_ID_CYPHIDCOM_FRWD)); +} static int analyze_baud_rate(struct usb_serial_port *port, speed_t new_rate) { @@ -238,6 +246,10 @@ static int analyze_baud_rate(struct usb_serial_port *port, speed_t new_rate) if (unstable_bauds) return new_rate; + /* FRWD Dongle uses 115200 bps */ + if (is_frwd(port->serial->dev)) + return new_rate; + /* * The general purpose firmware for the Cypress M8 allows for * a maximum speed of 57600bps (I have no idea whether DeLorme @@ -448,7 +460,11 @@ static int cypress_generic_port_probe(struct usb_serial_port *port) return -ENOMEM; } - usb_reset_configuration(serial->dev); + /* Skip reset for FRWD device. It is a workaound: + device hangs if it receives SET_CONFIGURE in Configured + state. */ + if (!is_frwd(serial->dev)) + usb_reset_configuration(serial->dev); priv->cmd_ctrl = 0; priv->line_control = 0; diff --git a/drivers/usb/serial/cypress_m8.h b/drivers/usb/serial/cypress_m8.h index 67cf60826884..b461311a2ae7 100644 --- a/drivers/usb/serial/cypress_m8.h +++ b/drivers/usb/serial/cypress_m8.h @@ -24,6 +24,10 @@ #define VENDOR_ID_CYPRESS 0x04b4 #define PRODUCT_ID_CYPHIDCOM 0x5500 +/* FRWD Dongle - a GPS sports watch */ +#define VENDOR_ID_FRWD 0x6737 +#define PRODUCT_ID_CYPHIDCOM_FRWD 0x0001 + /* Powercom UPS, chip CY7C63723 */ #define VENDOR_ID_POWERCOM 0x0d9f #define PRODUCT_ID_UPS 0x0002 diff --git a/drivers/usb/serial/f81232.c b/drivers/usb/serial/f81232.c index 090b411d893f..7d8dd5aad236 100644 --- a/drivers/usb/serial/f81232.c +++ b/drivers/usb/serial/f81232.c @@ -165,11 +165,12 @@ static void f81232_set_termios(struct tty_struct *tty, /* FIXME - Stubbed out for now */ /* Don't change anything if nothing has changed */ - if (!tty_termios_hw_change(&tty->termios, old_termios)) + if (old_termios && !tty_termios_hw_change(&tty->termios, old_termios)) return; /* Do the real work here... */ - tty_termios_copy_hw(&tty->termios, old_termios); + if (old_termios) + tty_termios_copy_hw(&tty->termios, old_termios); } static int f81232_tiocmget(struct tty_struct *tty) @@ -187,12 +188,11 @@ static int f81232_tiocmset(struct tty_struct *tty, static int f81232_open(struct tty_struct *tty, struct usb_serial_port *port) { - struct ktermios tmp_termios; int result; /* Setup termios */ if (tty) - f81232_set_termios(tty, port, &tmp_termios); + f81232_set_termios(tty, port, NULL); result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); if (result) { diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c index 9d74c278b7b5..790673e5faa7 100644 --- a/drivers/usb/serial/iuu_phoenix.c +++ b/drivers/usb/serial/iuu_phoenix.c @@ -287,7 +287,7 @@ static int bulk_immediate(struct usb_serial_port *port, u8 *buf, u8 count) usb_bulk_msg(serial->dev, usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress), buf, - count, &actual, HZ * 1); + count, &actual, 1000); if (status != IUU_OPERATION_OK) dev_dbg(&port->dev, "%s - error = %2x\n", __func__, status); @@ -307,7 +307,7 @@ static int read_immediate(struct usb_serial_port *port, u8 *buf, u8 count) usb_bulk_msg(serial->dev, usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress), buf, - count, &actual, HZ * 1); + count, &actual, 1000); if (status != IUU_OPERATION_OK) dev_dbg(&port->dev, "%s - error = %2x\n", __func__, status); diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index eb30d7b01f36..3549d073df22 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c @@ -1548,7 +1548,6 @@ static int keyspan_usa26_send_setup(struct usb_serial *serial, struct keyspan_serial_private *s_priv; struct keyspan_port_private *p_priv; const struct keyspan_device_details *d_details; - int outcont_urb; struct urb *this_urb; int device_port, err; @@ -1559,7 +1558,6 @@ static int keyspan_usa26_send_setup(struct usb_serial *serial, d_details = s_priv->device_details; device_port = port->number - port->serial->minor; - outcont_urb = d_details->outcont_endpoints[port->number]; this_urb = p_priv->outcont_urb; dev_dbg(&port->dev, "%s - endpoint %d\n", __func__, usb_pipeendpoint(this_urb->pipe)); @@ -1685,14 +1683,6 @@ static int keyspan_usa26_send_setup(struct usb_serial *serial, err = usb_submit_urb(this_urb, GFP_ATOMIC); if (err != 0) dev_dbg(&port->dev, "%s - usb_submit_urb(setup) failed (%d)\n", __func__, err); -#if 0 - else { - dev_dbg(&port->dev, "%s - usb_submit_urb(%d) OK %d bytes (end %d)\n", __func__ - outcont_urb, this_urb->transfer_buffer_length, - usb_pipeendpoint(this_urb->pipe)); - } -#endif - return 0; } diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index cc0e54345df9..f27c621a9297 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c @@ -40,7 +40,7 @@ #define DRIVER_DESC "Moschip USB Serial Driver" /* default urb timeout */ -#define MOS_WDR_TIMEOUT (HZ * 5) +#define MOS_WDR_TIMEOUT 5000 #define MOS_MAX_PORT 0x02 #define MOS_WRITE 0x0E @@ -227,11 +227,22 @@ static int read_mos_reg(struct usb_serial *serial, unsigned int serial_portnum, __u8 requesttype = (__u8)0xc0; __u16 index = get_reg_index(reg); __u16 value = get_reg_value(reg, serial_portnum); - int status = usb_control_msg(usbdev, pipe, request, requesttype, value, - index, data, 1, MOS_WDR_TIMEOUT); - if (status < 0) + u8 *buf; + int status; + + buf = kmalloc(1, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + status = usb_control_msg(usbdev, pipe, request, requesttype, value, + index, buf, 1, MOS_WDR_TIMEOUT); + if (status == 1) + *data = *buf; + else if (status < 0) dev_err(&usbdev->dev, "mos7720: usb_control_msg() failed: %d", status); + kfree(buf); + return status; } @@ -1618,7 +1629,7 @@ static void change_port_settings(struct tty_struct *tty, mos7720_port->shadowMCR |= (UART_MCR_XONANY); /* To set hardware flow control to the specified * * serial port, in SP1/2_CONTROL_REG */ - if (port->number) + if (port_number) write_mos_reg(serial, dummy, SP_CONTROL_REG, 0x01); else write_mos_reg(serial, dummy, SP_CONTROL_REG, 0x02); @@ -1927,7 +1938,7 @@ static int mos7720_startup(struct usb_serial *serial) /* setting configuration feature to one */ usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), - (__u8)0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5*HZ); + (__u8)0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5000); /* start the interrupt urb */ ret_val = usb_submit_urb(serial->port[0]->interrupt_in_urb, GFP_KERNEL); @@ -1970,7 +1981,7 @@ static void mos7720_release(struct usb_serial *serial) /* wait for synchronous usb calls to return */ if (mos_parport->msg_pending) wait_for_completion_timeout(&mos_parport->syncmsg_compl, - MOS_WDR_TIMEOUT); + msecs_to_jiffies(MOS_WDR_TIMEOUT)); parport_remove_port(mos_parport->pp); usb_set_serial_data(serial, NULL); diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index a0d5ea545982..7e998081e1cd 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -2142,13 +2142,21 @@ static int mos7840_ioctl(struct tty_struct *tty, static int mos7810_check(struct usb_serial *serial) { int i, pass_count = 0; + u8 *buf; __u16 data = 0, mcr_data = 0; __u16 test_pattern = 0x55AA; + int res; + + buf = kmalloc(VENDOR_READ_LENGTH, GFP_KERNEL); + if (!buf) + return 0; /* failed to identify 7810 */ /* Store MCR setting */ - usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), + res = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), MCS_RDREQ, MCS_RD_RTYPE, 0x0300, MODEM_CONTROL_REGISTER, - &mcr_data, VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT); + buf, VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT); + if (res == VENDOR_READ_LENGTH) + mcr_data = *buf; for (i = 0; i < 16; i++) { /* Send the 1-bit test pattern out to MCS7810 test pin */ @@ -2158,9 +2166,12 @@ static int mos7810_check(struct usb_serial *serial) MODEM_CONTROL_REGISTER, NULL, 0, MOS_WDR_TIMEOUT); /* Read the test pattern back */ - usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), - MCS_RDREQ, MCS_RD_RTYPE, 0, GPIO_REGISTER, &data, - VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT); + res = usb_control_msg(serial->dev, + usb_rcvctrlpipe(serial->dev, 0), MCS_RDREQ, + MCS_RD_RTYPE, 0, GPIO_REGISTER, buf, + VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT); + if (res == VENDOR_READ_LENGTH) + data = *buf; /* If this is a MCS7810 device, both test patterns must match */ if (((test_pattern >> i) ^ (~data >> 1)) & 0x0001) @@ -2174,6 +2185,8 @@ static int mos7810_check(struct usb_serial *serial) MCS_WR_RTYPE, 0x0300 | mcr_data, MODEM_CONTROL_REGISTER, NULL, 0, MOS_WDR_TIMEOUT); + kfree(buf); + if (pass_count == 16) return 1; @@ -2183,11 +2196,17 @@ static int mos7810_check(struct usb_serial *serial) static int mos7840_calc_num_ports(struct usb_serial *serial) { __u16 data = 0x00; + u8 *buf; int mos7840_num_ports; - usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), - MCS_RDREQ, MCS_RD_RTYPE, 0, GPIO_REGISTER, &data, - VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT); + buf = kzalloc(VENDOR_READ_LENGTH, GFP_KERNEL); + if (buf) { + usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), + MCS_RDREQ, MCS_RD_RTYPE, 0, GPIO_REGISTER, buf, + VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT); + data = *buf; + kfree(buf); + } if (serial->dev->descriptor.idProduct == MOSCHIP_DEVICE_ID_7810 || serial->dev->descriptor.idProduct == MOSCHIP_DEVICE_ID_7820) { diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 93d02bc4eb52..bd4323ddae1a 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -250,13 +250,7 @@ static void option_instat_callback(struct urb *urb); #define ZTE_PRODUCT_MF622 0x0001 #define ZTE_PRODUCT_MF628 0x0015 #define ZTE_PRODUCT_MF626 0x0031 -#define ZTE_PRODUCT_CDMA_TECH 0xfffe -#define ZTE_PRODUCT_AC8710 0xfff1 -#define ZTE_PRODUCT_AC2726 0xfff5 -#define ZTE_PRODUCT_AC8710T 0xffff #define ZTE_PRODUCT_MC2718 0xffe8 -#define ZTE_PRODUCT_AD3812 0xffeb -#define ZTE_PRODUCT_MC2716 0xffed #define BENQ_VENDOR_ID 0x04a5 #define BENQ_PRODUCT_H10 0x4068 @@ -495,18 +489,10 @@ static const struct option_blacklist_info zte_k3765_z_blacklist = { .reserved = BIT(4), }; -static const struct option_blacklist_info zte_ad3812_z_blacklist = { - .sendsetup = BIT(0) | BIT(1) | BIT(2), -}; - static const struct option_blacklist_info zte_mc2718_z_blacklist = { .sendsetup = BIT(1) | BIT(2) | BIT(3) | BIT(4), }; -static const struct option_blacklist_info zte_mc2716_z_blacklist = { - .sendsetup = BIT(1) | BIT(2) | BIT(3), -}; - static const struct option_blacklist_info huawei_cdc12_blacklist = { .reserved = BIT(1) | BIT(2), }; @@ -593,6 +579,8 @@ static const struct usb_device_id option_ids[] = { .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x14ac, 0xff, 0xff, 0xff), /* Huawei E1820 */ + .driver_info = (kernel_ulong_t) &net_intf1_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0xff, 0xff) }, @@ -797,7 +785,6 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_INTERFACE_CLASS(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1012, 0xff) }, { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC650) }, { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) }, - { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */ { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */ { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6280) }, /* BP3-USB & BP3-EXT HSDPA */ @@ -1199,16 +1186,9 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0178, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710T, 0xff, 0xff, 0xff) }, + /* NOTE: most ZTE CDMA devices should be driven by zte_ev, not option */ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2718, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&zte_mc2718_z_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AD3812, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&zte_ad3812_z_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2716, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&zte_mc2716_z_blacklist }, { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x01) }, { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x05) }, { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x86, 0x10) }, diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 7151659367a0..048cd44d51b1 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -284,7 +284,7 @@ static void pl2303_set_termios(struct tty_struct *tty, serial settings even to the same values as before. Thus we actually need to filter in this specific case */ - if (!tty_termios_hw_change(&tty->termios, old_termios)) + if (old_termios && !tty_termios_hw_change(&tty->termios, old_termios)) return; cflag = tty->termios.c_cflag; @@ -293,7 +293,8 @@ static void pl2303_set_termios(struct tty_struct *tty, if (!buf) { dev_err(&port->dev, "%s - out of memory.\n", __func__); /* Report back no change occurred */ - tty->termios = *old_termios; + if (old_termios) + tty->termios = *old_termios; return; } @@ -433,7 +434,7 @@ static void pl2303_set_termios(struct tty_struct *tty, control = priv->line_control; if ((cflag & CBAUD) == B0) priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS); - else if ((old_termios->c_cflag & CBAUD) == B0) + else if (old_termios && (old_termios->c_cflag & CBAUD) == B0) priv->line_control |= (CONTROL_DTR | CONTROL_RTS); if (control != priv->line_control) { control = priv->line_control; @@ -492,7 +493,6 @@ static void pl2303_close(struct usb_serial_port *port) static int pl2303_open(struct tty_struct *tty, struct usb_serial_port *port) { - struct ktermios tmp_termios; struct usb_serial *serial = port->serial; struct pl2303_serial_private *spriv = usb_get_serial_data(serial); int result; @@ -508,7 +508,7 @@ static int pl2303_open(struct tty_struct *tty, struct usb_serial_port *port) /* Setup termios */ if (tty) - pl2303_set_termios(tty, port, &tmp_termios); + pl2303_set_termios(tty, port, NULL); result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); if (result) { diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index 59b32b782126..bd794b43898c 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c @@ -118,6 +118,7 @@ static const struct usb_device_id id_table[] = { {USB_DEVICE(0x1199, 0x901b)}, /* Sierra Wireless MC7770 */ {USB_DEVICE(0x12D1, 0x14F0)}, /* Sony Gobi 3000 QDL */ {USB_DEVICE(0x12D1, 0x14F1)}, /* Sony Gobi 3000 Composite */ + {USB_DEVICE(0x0AF0, 0x8120)}, /* Option GTM681W */ /* non Gobi Qualcomm serial devices */ {USB_DEVICE_INTERFACE_NUMBER(0x0f3d, 0x68a2, 0)}, /* Sierra Wireless MC7700 Device Management */ diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c index cf3df793c2b7..ddf6c47137dc 100644 --- a/drivers/usb/serial/spcp8x5.c +++ b/drivers/usb/serial/spcp8x5.c @@ -291,7 +291,6 @@ static void spcp8x5_set_termios(struct tty_struct *tty, struct spcp8x5_private *priv = usb_get_serial_port_data(port); unsigned long flags; unsigned int cflag = tty->termios.c_cflag; - unsigned int old_cflag = old_termios->c_cflag; unsigned short uartdata; unsigned char buf[2] = {0, 0}; int baud; @@ -299,15 +298,15 @@ static void spcp8x5_set_termios(struct tty_struct *tty, u8 control; /* check that they really want us to change something */ - if (!tty_termios_hw_change(&tty->termios, old_termios)) + if (old_termios && !tty_termios_hw_change(&tty->termios, old_termios)) return; /* set DTR/RTS active */ spin_lock_irqsave(&priv->lock, flags); control = priv->line_control; - if ((old_cflag & CBAUD) == B0) { + if (old_termios && (old_termios->c_cflag & CBAUD) == B0) { priv->line_control |= MCR_DTR; - if (!(old_cflag & CRTSCTS)) + if (!(old_termios->c_cflag & CRTSCTS)) priv->line_control |= MCR_RTS; } if (control != priv->line_control) { @@ -394,7 +393,6 @@ static void spcp8x5_set_termios(struct tty_struct *tty, static int spcp8x5_open(struct tty_struct *tty, struct usb_serial_port *port) { - struct ktermios tmp_termios; struct usb_serial *serial = port->serial; struct spcp8x5_private *priv = usb_get_serial_port_data(port); int ret; @@ -411,7 +409,7 @@ static int spcp8x5_open(struct tty_struct *tty, struct usb_serial_port *port) spcp8x5_set_ctrl_line(port, priv->line_control); if (tty) - spcp8x5_set_termios(tty, port, &tmp_termios); + spcp8x5_set_termios(tty, port, NULL); port->port.drain_delay = 256; diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index c92c5ed4e580..e581c2549a57 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c @@ -172,7 +172,8 @@ static struct usb_device_id ti_id_table_3410[15+TI_EXTRA_VID_PID_COUNT+1] = { { USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) }, { USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) }, { USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) }, - { USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_PRODUCT_ID) }, + { USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_STEREO_PLUG_ID) }, + { USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_STRIP_PORT_ID) }, { USB_DEVICE(TI_VENDOR_ID, FRI2_PRODUCT_ID) }, }; diff --git a/drivers/usb/serial/ti_usb_3410_5052.h b/drivers/usb/serial/ti_usb_3410_5052.h index b353e7e3d480..4a2423e84d55 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.h +++ b/drivers/usb/serial/ti_usb_3410_5052.h @@ -52,7 +52,9 @@ /* Abbott Diabetics vendor and product ids */ #define ABBOTT_VENDOR_ID 0x1a61 -#define ABBOTT_PRODUCT_ID 0x3410 +#define ABBOTT_STEREO_PLUG_ID 0x3410 +#define ABBOTT_PRODUCT_ID ABBOTT_STEREO_PLUG_ID +#define ABBOTT_STRIP_PORT_ID 0x3420 /* Commands */ #define TI_GET_VERSION 0x01 diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 4753c005cfb6..5f6b1ff9d29e 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -408,7 +408,7 @@ static int serial_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct usb_serial_port *port = tty->driver_data; - int retval = -ENODEV; + int retval = -ENOIOCTLCMD; dev_dbg(tty->dev, "%s - cmd 0x%.4x\n", __func__, cmd); @@ -420,8 +420,6 @@ static int serial_ioctl(struct tty_struct *tty, default: if (port->serial->type->ioctl) retval = port->serial->type->ioctl(tty, cmd, arg); - else - retval = -ENOIOCTLCMD; } return retval; diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index 7573ec8a084f..9910aa2edf4b 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c @@ -560,10 +560,19 @@ static int treo_attach(struct usb_serial *serial) */ #define COPY_PORT(dest, src) \ do { \ + int i; \ + \ + for (i = 0; i < ARRAY_SIZE(src->read_urbs); ++i) { \ + dest->read_urbs[i] = src->read_urbs[i]; \ + dest->read_urbs[i]->context = dest; \ + dest->bulk_in_buffers[i] = src->bulk_in_buffers[i]; \ + } \ dest->read_urb = src->read_urb; \ dest->bulk_in_endpointAddress = src->bulk_in_endpointAddress;\ dest->bulk_in_buffer = src->bulk_in_buffer; \ + dest->bulk_in_size = src->bulk_in_size; \ dest->interrupt_in_urb = src->interrupt_in_urb; \ + dest->interrupt_in_urb->context = dest; \ dest->interrupt_in_endpointAddress = \ src->interrupt_in_endpointAddress;\ dest->interrupt_in_buffer = src->interrupt_in_buffer; \ diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index b9fca3586d74..347caad47a12 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c @@ -649,7 +649,7 @@ static void firm_setup_port(struct tty_struct *tty) struct whiteheat_port_settings port_settings; unsigned int cflag = tty->termios.c_cflag; - port_settings.port = port->number + 1; + port_settings.port = port->number - port->serial->minor + 1; /* get the byte size */ switch (cflag & CSIZE) { diff --git a/drivers/usb/serial/zte_ev.c b/drivers/usb/serial/zte_ev.c index 39ee7373b4ee..fca4c752a4ed 100644 --- a/drivers/usb/serial/zte_ev.c +++ b/drivers/usb/serial/zte_ev.c @@ -41,9 +41,6 @@ static int zte_ev_usb_serial_open(struct tty_struct *tty, int len; unsigned char *buf; - if (port->number != 0) - return -ENODEV; - buf = kmalloc(MAX_SETUP_DATA_SIZE, GFP_KERNEL); if (!buf) return -ENOMEM; @@ -53,7 +50,7 @@ static int zte_ev_usb_serial_open(struct tty_struct *tty, result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x22, 0x21, 0x0001, 0x0000, NULL, len, - HZ * USB_CTRL_GET_TIMEOUT); + USB_CTRL_GET_TIMEOUT); dev_dbg(dev, "result = %d\n", result); /* send 2st cmd and recieve data */ @@ -65,7 +62,7 @@ static int zte_ev_usb_serial_open(struct tty_struct *tty, result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x21, 0xa1, 0x0000, 0x0000, buf, len, - HZ * USB_CTRL_GET_TIMEOUT); + USB_CTRL_GET_TIMEOUT); debug_data(dev, __func__, len, buf, result); /* send 3 cmd */ @@ -84,7 +81,7 @@ static int zte_ev_usb_serial_open(struct tty_struct *tty, result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x20, 0x21, 0x0000, 0x0000, buf, len, - HZ * USB_CTRL_GET_TIMEOUT); + USB_CTRL_GET_TIMEOUT); debug_data(dev, __func__, len, buf, result); /* send 4 cmd */ @@ -95,7 +92,7 @@ static int zte_ev_usb_serial_open(struct tty_struct *tty, result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x22, 0x21, 0x0003, 0x0000, NULL, len, - HZ * USB_CTRL_GET_TIMEOUT); + USB_CTRL_GET_TIMEOUT); dev_dbg(dev, "result = %d\n", result); /* send 5 cmd */ @@ -107,7 +104,7 @@ static int zte_ev_usb_serial_open(struct tty_struct *tty, result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x21, 0xa1, 0x0000, 0x0000, buf, len, - HZ * USB_CTRL_GET_TIMEOUT); + USB_CTRL_GET_TIMEOUT); debug_data(dev, __func__, len, buf, result); /* send 6 cmd */ @@ -126,7 +123,7 @@ static int zte_ev_usb_serial_open(struct tty_struct *tty, result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x20, 0x21, 0x0000, 0x0000, buf, len, - HZ * USB_CTRL_GET_TIMEOUT); + USB_CTRL_GET_TIMEOUT); debug_data(dev, __func__, len, buf, result); kfree(buf); @@ -166,9 +163,6 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port) int len; unsigned char *buf; - if (port->number != 0) - return; - buf = kmalloc(MAX_SETUP_DATA_SIZE, GFP_KERNEL); if (!buf) return; @@ -178,7 +172,7 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port) result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x22, 0x21, 0x0002, 0x0000, NULL, len, - HZ * USB_CTRL_GET_TIMEOUT); + USB_CTRL_GET_TIMEOUT); dev_dbg(dev, "result = %d\n", result); /* send 2st ctl cmd(CTL 21 22 03 00 00 00 00 00 ) */ @@ -186,7 +180,7 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port) result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x22, 0x21, 0x0003, 0x0000, NULL, len, - HZ * USB_CTRL_GET_TIMEOUT); + USB_CTRL_GET_TIMEOUT); dev_dbg(dev, "result = %d\n", result); /* send 3st cmd and recieve data */ @@ -198,7 +192,7 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port) result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x21, 0xa1, 0x0000, 0x0000, buf, len, - HZ * USB_CTRL_GET_TIMEOUT); + USB_CTRL_GET_TIMEOUT); debug_data(dev, __func__, len, buf, result); /* send 4 cmd */ @@ -217,7 +211,7 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port) result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x20, 0x21, 0x0000, 0x0000, buf, len, - HZ * USB_CTRL_GET_TIMEOUT); + USB_CTRL_GET_TIMEOUT); debug_data(dev, __func__, len, buf, result); /* send 5 cmd */ @@ -228,7 +222,7 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port) result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x22, 0x21, 0x0003, 0x0000, NULL, len, - HZ * USB_CTRL_GET_TIMEOUT); + USB_CTRL_GET_TIMEOUT); dev_dbg(dev, "result = %d\n", result); /* send 6 cmd */ @@ -240,7 +234,7 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port) result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x21, 0xa1, 0x0000, 0x0000, buf, len, - HZ * USB_CTRL_GET_TIMEOUT); + USB_CTRL_GET_TIMEOUT); debug_data(dev, __func__, len, buf, result); /* send 7 cmd */ @@ -259,7 +253,7 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port) result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x20, 0x21, 0x0000, 0x0000, buf, len, - HZ * USB_CTRL_GET_TIMEOUT); + USB_CTRL_GET_TIMEOUT); debug_data(dev, __func__, len, buf, result); /* send 8 cmd */ @@ -270,7 +264,7 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port) result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x22, 0x21, 0x0003, 0x0000, NULL, len, - HZ * USB_CTRL_GET_TIMEOUT); + USB_CTRL_GET_TIMEOUT); dev_dbg(dev, "result = %d\n", result); kfree(buf); @@ -279,11 +273,29 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port) } static const struct usb_device_id id_table[] = { - { USB_DEVICE(0x19d2, 0xffff) }, /* AC8700 */ - { USB_DEVICE(0x19d2, 0xfffe) }, - { USB_DEVICE(0x19d2, 0xfffd) }, /* MG880 */ + /* AC8710, AC8710T */ + { USB_DEVICE_AND_INTERFACE_INFO(0x19d2, 0xffff, 0xff, 0xff, 0xff) }, + /* AC8700 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x19d2, 0xfffe, 0xff, 0xff, 0xff) }, + /* MG880 */ + { USB_DEVICE(0x19d2, 0xfffd) }, + { USB_DEVICE(0x19d2, 0xfffc) }, + { USB_DEVICE(0x19d2, 0xfffb) }, + /* AC2726, AC8710_V3 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x19d2, 0xfff1, 0xff, 0xff, 0xff) }, + { USB_DEVICE(0x19d2, 0xfff6) }, + { USB_DEVICE(0x19d2, 0xfff7) }, + { USB_DEVICE(0x19d2, 0xfff8) }, + { USB_DEVICE(0x19d2, 0xfff9) }, + { USB_DEVICE(0x19d2, 0xffee) }, + /* AC2716, MC2716 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x19d2, 0xffed, 0xff, 0xff, 0xff) }, + /* AD3812 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x19d2, 0xffeb, 0xff, 0xff, 0xff) }, + { USB_DEVICE(0x19d2, 0xffec) }, { USB_DEVICE(0x05C6, 0x3197) }, { USB_DEVICE(0x05C6, 0x6000) }, + { USB_DEVICE(0x05C6, 0x9008) }, { }, }; MODULE_DEVICE_TABLE(usb, id_table); diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c index acb7121a9316..6d78736563de 100644 --- a/drivers/vfio/vfio.c +++ b/drivers/vfio/vfio.c @@ -1360,7 +1360,7 @@ static const struct file_operations vfio_device_fops = { */ static char *vfio_devnode(struct device *dev, umode_t *mode) { - if (MINOR(dev->devt) == 0) + if (mode && (MINOR(dev->devt) == 0)) *mode = S_IRUGO | S_IWUGO; return kasprintf(GFP_KERNEL, "vfio/%s", dev_name(dev)); diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index 2b51e2336aa2..f80d3dd41d8c 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c @@ -155,14 +155,11 @@ static void vhost_net_ubuf_put_and_wait(struct vhost_net_ubuf_ref *ubufs) static void vhost_net_clear_ubuf_info(struct vhost_net *n) { - - bool zcopy; int i; - for (i = 0; i < n->dev.nvqs; ++i) { - zcopy = vhost_net_zcopy_mask & (0x1 << i); - if (zcopy) - kfree(n->vqs[i].ubuf_info); + for (i = 0; i < VHOST_NET_VQ_MAX; ++i) { + kfree(n->vqs[i].ubuf_info); + n->vqs[i].ubuf_info = NULL; } } @@ -171,7 +168,7 @@ int vhost_net_set_ubuf_info(struct vhost_net *n) bool zcopy; int i; - for (i = 0; i < n->dev.nvqs; ++i) { + for (i = 0; i < VHOST_NET_VQ_MAX; ++i) { zcopy = vhost_net_zcopy_mask & (0x1 << i); if (!zcopy) continue; @@ -183,12 +180,7 @@ int vhost_net_set_ubuf_info(struct vhost_net *n) return 0; err: - while (i--) { - zcopy = vhost_net_zcopy_mask & (0x1 << i); - if (!zcopy) - continue; - kfree(n->vqs[i].ubuf_info); - } + vhost_net_clear_ubuf_info(n); return -ENOMEM; } @@ -196,12 +188,12 @@ void vhost_net_vq_reset(struct vhost_net *n) { int i; + vhost_net_clear_ubuf_info(n); + for (i = 0; i < VHOST_NET_VQ_MAX; i++) { n->vqs[i].done_idx = 0; n->vqs[i].upend_idx = 0; n->vqs[i].ubufs = NULL; - kfree(n->vqs[i].ubuf_info); - n->vqs[i].ubuf_info = NULL; n->vqs[i].vhost_hlen = 0; n->vqs[i].sock_hlen = 0; } @@ -436,7 +428,8 @@ static void handle_tx(struct vhost_net *net) kref_get(&ubufs->kref); } nvq->upend_idx = (nvq->upend_idx + 1) % UIO_MAXIOV; - } + } else + msg.msg_control = NULL; /* TODO: Check specific error and bomb out unless ENOBUFS? */ err = sock->ops->sendmsg(NULL, sock, &msg, len); if (unlikely(err < 0)) { @@ -1053,6 +1046,10 @@ static long vhost_net_set_owner(struct vhost_net *n) int r; mutex_lock(&n->dev.mutex); + if (vhost_dev_has_owner(&n->dev)) { + r = -EBUSY; + goto out; + } r = vhost_net_set_ubuf_info(n); if (r) goto out; diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index beee7f5787e6..60aa5ad09a2f 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -344,13 +344,19 @@ static int vhost_attach_cgroups(struct vhost_dev *dev) } /* Caller should have device mutex */ +bool vhost_dev_has_owner(struct vhost_dev *dev) +{ + return dev->mm; +} + +/* Caller should have device mutex */ long vhost_dev_set_owner(struct vhost_dev *dev) { struct task_struct *worker; int err; /* Is there an owner already? */ - if (dev->mm) { + if (vhost_dev_has_owner(dev)) { err = -EBUSY; goto err_mm; } diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h index a7ad63592987..64adcf99ff33 100644 --- a/drivers/vhost/vhost.h +++ b/drivers/vhost/vhost.h @@ -133,6 +133,7 @@ struct vhost_dev { long vhost_dev_init(struct vhost_dev *, struct vhost_virtqueue **vqs, int nvqs); long vhost_dev_set_owner(struct vhost_dev *dev); +bool vhost_dev_has_owner(struct vhost_dev *dev); long vhost_dev_check_owner(struct vhost_dev *); struct vhost_memory *vhost_dev_reset_owner_prepare(void); void vhost_dev_reset_owner(struct vhost_dev *, struct vhost_memory *); diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index d71d60f94fc1..2e937bdace6f 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -2199,7 +2199,7 @@ config FB_XILINX config FB_GOLDFISH tristate "Goldfish Framebuffer" - depends on FB + depends on FB && HAS_DMA select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT @@ -2453,6 +2453,23 @@ config FB_HYPERV help This framebuffer driver supports Microsoft Hyper-V Synthetic Video. +config FB_SIMPLE + bool "Simple framebuffer support" + depends on (FB = y) && OF + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + Say Y if you want support for a simple frame-buffer. + + This driver assumes that the display hardware has been initialized + before the kernel boots, and the kernel will simply render to the + pre-allocated frame buffer surface. + + Configuration re: surface address, size, and format must be provided + through device tree, or potentially plain old platform data in the + future. + source "drivers/video/omap/Kconfig" source "drivers/video/omap2/Kconfig" source "drivers/video/exynos/Kconfig" diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 7234e4a959e8..e8bae8dd4804 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -166,6 +166,7 @@ obj-$(CONFIG_FB_MX3) += mx3fb.o obj-$(CONFIG_FB_DA8XX) += da8xx-fb.o obj-$(CONFIG_FB_MXS) += mxsfb.o obj-$(CONFIG_FB_SSD1307) += ssd1307fb.o +obj-$(CONFIG_FB_SIMPLE) += simplefb.o # the test framebuffer is last obj-$(CONFIG_FB_VIRTUAL) += vfb.o diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index 540909de6247..effdb373b8db 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c @@ -223,8 +223,14 @@ static void init_backlight(struct atmel_lcdfb_info *sinfo) static void exit_backlight(struct atmel_lcdfb_info *sinfo) { - if (sinfo->backlight) - backlight_device_unregister(sinfo->backlight); + if (!sinfo->backlight) + return; + + if (sinfo->backlight->ops) { + sinfo->backlight->props.power = FB_BLANK_POWERDOWN; + sinfo->backlight->ops->update_status(sinfo->backlight); + } + backlight_device_unregister(sinfo->backlight); } #else @@ -461,8 +467,11 @@ static int atmel_lcdfb_check_var(struct fb_var_screeninfo *var, if (info->fix.smem_len) { unsigned int smem_len = (var->xres_virtual * var->yres_virtual * ((var->bits_per_pixel + 7) / 8)); - if (smem_len > info->fix.smem_len) + if (smem_len > info->fix.smem_len) { + dev_err(dev, "Frame buffer is too small (%u) for screen size (need at least %u)\n", + info->fix.smem_len, smem_len); return -EINVAL; + } } /* Saturate vertical and horizontal timings at maximum values */ diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index 60cc6fee6548..c9c2252e3719 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c @@ -53,6 +53,8 @@ static char *def_disp_name; module_param_named(def_disp, def_disp_name, charp, 0); MODULE_PARM_DESC(def_disp, "default display name"); +static bool dss_initialized; + const char *omapdss_get_default_display_name(void) { return core.default_display_name; @@ -66,6 +68,12 @@ enum omapdss_version omapdss_get_version(void) } EXPORT_SYMBOL(omapdss_get_version); +bool omapdss_is_initialized(void) +{ + return dss_initialized; +} +EXPORT_SYMBOL(omapdss_is_initialized); + struct platform_device *dss_get_core_pdev(void) { return core.pdev; @@ -603,6 +611,8 @@ static int __init omap_dss_init(void) return r; } + dss_initialized = true; + return 0; } @@ -633,7 +643,15 @@ static int __init omap_dss_init(void) static int __init omap_dss_init2(void) { - return omap_dss_register_drivers(); + int r; + + r = omap_dss_register_drivers(); + if (r) + return r; + + dss_initialized = true; + + return 0; } core_initcall(omap_dss_init); diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c index c84bb8a4d0c4..856917b33616 100644 --- a/drivers/video/omap2/omapfb/omapfb-main.c +++ b/drivers/video/omap2/omapfb/omapfb-main.c @@ -2416,6 +2416,9 @@ static int omapfb_probe(struct platform_device *pdev) DBG("omapfb_probe\n"); + if (omapdss_is_initialized() == false) + return -EPROBE_DEFER; + if (pdev->num_resources != 0) { dev_err(&pdev->dev, "probed for an unknown device\n"); r = -ENODEV; diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c index d9f08c653d62..dbfe2c18a434 100644 --- a/drivers/video/ps3fb.c +++ b/drivers/video/ps3fb.c @@ -710,7 +710,7 @@ static int ps3fb_mmap(struct fb_info *info, struct vm_area_struct *vma) r = vm_iomap_memory(vma, info->fix.smem_start, info->fix.smem_len); dev_dbg(info->device, "ps3fb: mmap framebuffer P(%lx)->V(%lx)\n", - info->fix.smem_start + vma->vm_pgoff << PAGE_SHIFT, + info->fix.smem_start + (vma->vm_pgoff << PAGE_SHIFT), vma->vm_start); return r; diff --git a/drivers/video/simplefb.c b/drivers/video/simplefb.c new file mode 100644 index 000000000000..e2e9e3e61b72 --- /dev/null +++ b/drivers/video/simplefb.c @@ -0,0 +1,234 @@ +/* + * Simplest possible simple frame-buffer driver, as a platform device + * + * Copyright (c) 2013, Stephen Warren + * + * Based on q40fb.c, which was: + * Copyright (C) 2001 Richard Zidlicky <rz@linux-m68k.org> + * + * Also based on offb.c, which was: + * Copyright (C) 1997 Geert Uytterhoeven + * Copyright (C) 1996 Paul Mackerras + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include <linux/errno.h> +#include <linux/fb.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/platform_device.h> + +static struct fb_fix_screeninfo simplefb_fix = { + .id = "simple", + .type = FB_TYPE_PACKED_PIXELS, + .visual = FB_VISUAL_TRUECOLOR, + .accel = FB_ACCEL_NONE, +}; + +static struct fb_var_screeninfo simplefb_var = { + .height = -1, + .width = -1, + .activate = FB_ACTIVATE_NOW, + .vmode = FB_VMODE_NONINTERLACED, +}; + +static int simplefb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, + u_int transp, struct fb_info *info) +{ + u32 *pal = info->pseudo_palette; + u32 cr = red >> (16 - info->var.red.length); + u32 cg = green >> (16 - info->var.green.length); + u32 cb = blue >> (16 - info->var.blue.length); + u32 value; + + if (regno >= 16) + return -EINVAL; + + value = (cr << info->var.red.offset) | + (cg << info->var.green.offset) | + (cb << info->var.blue.offset); + if (info->var.transp.length > 0) { + u32 mask = (1 << info->var.transp.length) - 1; + mask <<= info->var.transp.offset; + value |= mask; + } + pal[regno] = value; + + return 0; +} + +static struct fb_ops simplefb_ops = { + .owner = THIS_MODULE, + .fb_setcolreg = simplefb_setcolreg, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, +}; + +struct simplefb_format { + const char *name; + u32 bits_per_pixel; + struct fb_bitfield red; + struct fb_bitfield green; + struct fb_bitfield blue; + struct fb_bitfield transp; +}; + +static struct simplefb_format simplefb_formats[] = { + { "r5g6b5", 16, {11, 5}, {5, 6}, {0, 5}, {0, 0} }, +}; + +struct simplefb_params { + u32 width; + u32 height; + u32 stride; + struct simplefb_format *format; +}; + +static int simplefb_parse_dt(struct platform_device *pdev, + struct simplefb_params *params) +{ + struct device_node *np = pdev->dev.of_node; + int ret; + const char *format; + int i; + + ret = of_property_read_u32(np, "width", ¶ms->width); + if (ret) { + dev_err(&pdev->dev, "Can't parse width property\n"); + return ret; + } + + ret = of_property_read_u32(np, "height", ¶ms->height); + if (ret) { + dev_err(&pdev->dev, "Can't parse height property\n"); + return ret; + } + + ret = of_property_read_u32(np, "stride", ¶ms->stride); + if (ret) { + dev_err(&pdev->dev, "Can't parse stride property\n"); + return ret; + } + + ret = of_property_read_string(np, "format", &format); + if (ret) { + dev_err(&pdev->dev, "Can't parse format property\n"); + return ret; + } + params->format = NULL; + for (i = 0; i < ARRAY_SIZE(simplefb_formats); i++) { + if (strcmp(format, simplefb_formats[i].name)) + continue; + params->format = &simplefb_formats[i]; + break; + } + if (!params->format) { + dev_err(&pdev->dev, "Invalid format value\n"); + return -EINVAL; + } + + return 0; +} + +static int simplefb_probe(struct platform_device *pdev) +{ + int ret; + struct simplefb_params params; + struct fb_info *info; + struct resource *mem; + + if (fb_get_options("simplefb", NULL)) + return -ENODEV; + + ret = simplefb_parse_dt(pdev, ¶ms); + if (ret) + return ret; + + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!mem) { + dev_err(&pdev->dev, "No memory resource\n"); + return -EINVAL; + } + + info = framebuffer_alloc(sizeof(u32) * 16, &pdev->dev); + if (!info) + return -ENOMEM; + platform_set_drvdata(pdev, info); + + info->fix = simplefb_fix; + info->fix.smem_start = mem->start; + info->fix.smem_len = resource_size(mem); + info->fix.line_length = params.stride; + + info->var = simplefb_var; + info->var.xres = params.width; + info->var.yres = params.height; + info->var.xres_virtual = params.width; + info->var.yres_virtual = params.height; + info->var.bits_per_pixel = params.format->bits_per_pixel; + info->var.red = params.format->red; + info->var.green = params.format->green; + info->var.blue = params.format->blue; + info->var.transp = params.format->transp; + + info->fbops = &simplefb_ops; + info->flags = FBINFO_DEFAULT; + info->screen_base = devm_ioremap(&pdev->dev, info->fix.smem_start, + info->fix.smem_len); + if (!info->screen_base) { + framebuffer_release(info); + return -ENODEV; + } + info->pseudo_palette = (void *)(info + 1); + + ret = register_framebuffer(info); + if (ret < 0) { + dev_err(&pdev->dev, "Unable to register simplefb: %d\n", ret); + framebuffer_release(info); + return ret; + } + + dev_info(&pdev->dev, "fb%d: simplefb registered!\n", info->node); + + return 0; +} + +static int simplefb_remove(struct platform_device *pdev) +{ + struct fb_info *info = platform_get_drvdata(pdev); + + unregister_framebuffer(info); + framebuffer_release(info); + + return 0; +} + +static const struct of_device_id simplefb_of_match[] = { + { .compatible = "simple-framebuffer", }, + { }, +}; +MODULE_DEVICE_TABLE(of, simplefb_of_match); + +static struct platform_driver simplefb_driver = { + .driver = { + .name = "simple-framebuffer", + .owner = THIS_MODULE, + .of_match_table = simplefb_of_match, + }, + .probe = simplefb_probe, + .remove = simplefb_remove, +}; +module_platform_driver(simplefb_driver); + +MODULE_AUTHOR("Stephen Warren <swarren@wwwdotorg.org>"); +MODULE_DESCRIPTION("Simple framebuffer driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/xen/tmem.c b/drivers/xen/tmem.c index 18e8bd8fa947..0f0493c63371 100644 --- a/drivers/xen/tmem.c +++ b/drivers/xen/tmem.c @@ -41,6 +41,8 @@ module_param(selfballooning, bool, S_IRUGO); #ifdef CONFIG_FRONTSWAP static bool frontswap __read_mostly = true; module_param(frontswap, bool, S_IRUGO); +#else /* CONFIG_FRONTSWAP */ +#define frontswap (0) #endif /* CONFIG_FRONTSWAP */ #ifdef CONFIG_XEN_SELFBALLOONING @@ -377,10 +379,10 @@ static int xen_tmem_init(void) #ifdef CONFIG_FRONTSWAP if (tmem_enabled && frontswap) { char *s = ""; - struct frontswap_ops *old_ops = - frontswap_register_ops(&tmem_frontswap_ops); + struct frontswap_ops *old_ops; tmem_frontswap_poolid = -1; + old_ops = frontswap_register_ops(&tmem_frontswap_ops); if (IS_ERR(old_ops) || old_ops) { if (IS_ERR(old_ops)) return PTR_ERR(old_ops); diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c index a2278ba7fb27..4e8ba38aa0c9 100644 --- a/drivers/xen/xen-pciback/pci_stub.c +++ b/drivers/xen/xen-pciback/pci_stub.c @@ -106,7 +106,7 @@ static void pcistub_device_release(struct kref *kref) else pci_restore_state(dev); - if (pci_find_capability(dev, PCI_CAP_ID_MSIX)) { + if (dev->msix_cap) { struct physdev_pci_device ppdev = { .seg = pci_domain_nr(dev->bus), .bus = dev->bus->number, @@ -371,7 +371,7 @@ static int pcistub_init_device(struct pci_dev *dev) if (err) goto config_release; - if (pci_find_capability(dev, PCI_CAP_ID_MSIX)) { + if (dev->msix_cap) { struct physdev_pci_device ppdev = { .seg = pci_domain_nr(dev->bus), .bus = dev->bus->number, diff --git a/drivers/xen/xenbus/xenbus_client.c b/drivers/xen/xenbus/xenbus_client.c index 61786be9138b..ec097d6f964d 100644 --- a/drivers/xen/xenbus/xenbus_client.c +++ b/drivers/xen/xenbus/xenbus_client.c @@ -534,7 +534,7 @@ static int xenbus_map_ring_valloc_hvm(struct xenbus_device *dev, err = xenbus_map_ring(dev, gnt_ref, &node->handle, addr); if (err) - goto out_err; + goto out_err_free_ballooned_pages; spin_lock(&xenbus_valloc_lock); list_add(&node->next, &xenbus_valloc_pages); @@ -543,8 +543,9 @@ static int xenbus_map_ring_valloc_hvm(struct xenbus_device *dev, *vaddr = addr; return 0; - out_err: + out_err_free_ballooned_pages: free_xenballooned_pages(1, &node->page); + out_err: kfree(node); return err; } diff --git a/drivers/xen/xenbus/xenbus_comms.h b/drivers/xen/xenbus/xenbus_comms.h index c8abd3b8a6c4..e74f9c1fbd80 100644 --- a/drivers/xen/xenbus/xenbus_comms.h +++ b/drivers/xen/xenbus/xenbus_comms.h @@ -45,6 +45,7 @@ int xb_wait_for_data_to_read(void); int xs_input_avail(void); extern struct xenstore_domain_interface *xen_store_interface; extern int xen_store_evtchn; +extern enum xenstore_init xen_store_domain_type; extern const struct file_operations xen_xenbus_fops; diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c index 3325884c693f..56cfaaa9d006 100644 --- a/drivers/xen/xenbus/xenbus_probe.c +++ b/drivers/xen/xenbus/xenbus_probe.c @@ -69,6 +69,9 @@ EXPORT_SYMBOL_GPL(xen_store_evtchn); struct xenstore_domain_interface *xen_store_interface; EXPORT_SYMBOL_GPL(xen_store_interface); +enum xenstore_init xen_store_domain_type; +EXPORT_SYMBOL_GPL(xen_store_domain_type); + static unsigned long xen_store_mfn; static BLOCKING_NOTIFIER_HEAD(xenstore_chain); @@ -719,17 +722,11 @@ static int __init xenstored_local_init(void) return err; } -enum xenstore_init { - UNKNOWN, - PV, - HVM, - LOCAL, -}; static int __init xenbus_init(void) { int err = 0; - enum xenstore_init usage = UNKNOWN; uint64_t v = 0; + xen_store_domain_type = XS_UNKNOWN; if (!xen_domain()) return -ENODEV; @@ -737,29 +734,29 @@ static int __init xenbus_init(void) xenbus_ring_ops_init(); if (xen_pv_domain()) - usage = PV; + xen_store_domain_type = XS_PV; if (xen_hvm_domain()) - usage = HVM; + xen_store_domain_type = XS_HVM; if (xen_hvm_domain() && xen_initial_domain()) - usage = LOCAL; + xen_store_domain_type = XS_LOCAL; if (xen_pv_domain() && !xen_start_info->store_evtchn) - usage = LOCAL; + xen_store_domain_type = XS_LOCAL; if (xen_pv_domain() && xen_start_info->store_evtchn) xenstored_ready = 1; - switch (usage) { - case LOCAL: + switch (xen_store_domain_type) { + case XS_LOCAL: err = xenstored_local_init(); if (err) goto out_error; xen_store_interface = mfn_to_virt(xen_store_mfn); break; - case PV: + case XS_PV: xen_store_evtchn = xen_start_info->store_evtchn; xen_store_mfn = xen_start_info->store_mfn; xen_store_interface = mfn_to_virt(xen_store_mfn); break; - case HVM: + case XS_HVM: err = hvm_get_parameter(HVM_PARAM_STORE_EVTCHN, &v); if (err) goto out_error; diff --git a/drivers/xen/xenbus/xenbus_probe.h b/drivers/xen/xenbus/xenbus_probe.h index bb4f92ed8730..146f857a36f8 100644 --- a/drivers/xen/xenbus/xenbus_probe.h +++ b/drivers/xen/xenbus/xenbus_probe.h @@ -47,6 +47,13 @@ struct xen_bus_type { struct bus_type bus; }; +enum xenstore_init { + XS_UNKNOWN, + XS_PV, + XS_HVM, + XS_LOCAL, +}; + extern struct device_attribute xenbus_dev_attrs[]; extern int xenbus_match(struct device *_dev, struct device_driver *_drv); diff --git a/drivers/xen/xenbus/xenbus_probe_frontend.c b/drivers/xen/xenbus/xenbus_probe_frontend.c index 3159a37d966d..a7e25073de19 100644 --- a/drivers/xen/xenbus/xenbus_probe_frontend.c +++ b/drivers/xen/xenbus/xenbus_probe_frontend.c @@ -29,6 +29,8 @@ #include "xenbus_probe.h" +static struct workqueue_struct *xenbus_frontend_wq; + /* device/<type>/<id> => <type>-<id> */ static int frontend_bus_id(char bus_id[XEN_BUS_ID_SIZE], const char *nodename) { @@ -89,9 +91,40 @@ static void backend_changed(struct xenbus_watch *watch, xenbus_otherend_changed(watch, vec, len, 1); } +static void xenbus_frontend_delayed_resume(struct work_struct *w) +{ + struct xenbus_device *xdev = container_of(w, struct xenbus_device, work); + + xenbus_dev_resume(&xdev->dev); +} + +static int xenbus_frontend_dev_resume(struct device *dev) +{ + /* + * If xenstored is running in this domain, we cannot access the backend + * state at the moment, so we need to defer xenbus_dev_resume + */ + if (xen_store_domain_type == XS_LOCAL) { + struct xenbus_device *xdev = to_xenbus_device(dev); + + if (!xenbus_frontend_wq) { + pr_err("%s: no workqueue to process delayed resume\n", + xdev->nodename); + return -EFAULT; + } + + INIT_WORK(&xdev->work, xenbus_frontend_delayed_resume); + queue_work(xenbus_frontend_wq, &xdev->work); + + return 0; + } + + return xenbus_dev_resume(dev); +} + static const struct dev_pm_ops xenbus_pm_ops = { .suspend = xenbus_dev_suspend, - .resume = xenbus_dev_resume, + .resume = xenbus_frontend_dev_resume, .freeze = xenbus_dev_suspend, .thaw = xenbus_dev_cancel, .restore = xenbus_dev_resume, @@ -440,6 +473,8 @@ static int __init xenbus_probe_frontend_init(void) register_xenstore_notifier(&xenstore_notifier); + xenbus_frontend_wq = create_workqueue("xenbus_frontend"); + return 0; } subsys_initcall(xenbus_probe_frontend_init); @@ -141,9 +141,6 @@ static void aio_free_ring(struct kioctx *ctx) for (i = 0; i < ctx->nr_pages; i++) put_page(ctx->ring_pages[i]); - if (ctx->mmap_size) - vm_munmap(ctx->mmap_base, ctx->mmap_size); - if (ctx->ring_pages && ctx->ring_pages != ctx->internal_pages) kfree(ctx->ring_pages); } @@ -307,7 +304,9 @@ static void free_ioctx(struct kioctx *ctx) kunmap_atomic(ring); while (atomic_read(&ctx->reqs_active) > 0) { - wait_event(ctx->wait, head != ctx->tail); + wait_event(ctx->wait, + head != ctx->tail || + atomic_read(&ctx->reqs_active) <= 0); avail = (head <= ctx->tail ? ctx->tail : ctx->nr_events) - head; @@ -320,11 +319,6 @@ static void free_ioctx(struct kioctx *ctx) aio_free_ring(ctx); - spin_lock(&aio_nr_lock); - BUG_ON(aio_nr - ctx->max_reqs > aio_nr); - aio_nr -= ctx->max_reqs; - spin_unlock(&aio_nr_lock); - pr_debug("freeing %p\n", ctx); /* @@ -433,17 +427,24 @@ static void kill_ioctx(struct kioctx *ctx) { if (!atomic_xchg(&ctx->dead, 1)) { hlist_del_rcu(&ctx->list); - /* Between hlist_del_rcu() and dropping the initial ref */ - synchronize_rcu(); /* - * We can't punt to workqueue here because put_ioctx() -> - * free_ioctx() will unmap the ringbuffer, and that has to be - * done in the original process's context. kill_ioctx_rcu/work() - * exist for exit_aio(), as in that path free_ioctx() won't do - * the unmap. + * It'd be more correct to do this in free_ioctx(), after all + * the outstanding kiocbs have finished - but by then io_destroy + * has already returned, so io_setup() could potentially return + * -EAGAIN with no ioctxs actually in use (as far as userspace + * could tell). */ - kill_ioctx_work(&ctx->rcu_work); + spin_lock(&aio_nr_lock); + BUG_ON(aio_nr - ctx->max_reqs > aio_nr); + aio_nr -= ctx->max_reqs; + spin_unlock(&aio_nr_lock); + + if (ctx->mmap_size) + vm_munmap(ctx->mmap_base, ctx->mmap_size); + + /* Between hlist_del_rcu() and dropping the initial ref */ + call_rcu(&ctx->rcu_head, kill_ioctx_rcu); } } @@ -493,10 +494,7 @@ void exit_aio(struct mm_struct *mm) */ ctx->mmap_size = 0; - if (!atomic_xchg(&ctx->dead, 1)) { - hlist_del_rcu(&ctx->list); - call_rcu(&ctx->rcu_head, kill_ioctx_rcu); - } + kill_ioctx(ctx); } } @@ -1299,8 +1297,7 @@ SYSCALL_DEFINE3(io_cancel, aio_context_t, ctx_id, struct iocb __user *, iocb, * < min_nr if the timeout specified by timeout has elapsed * before sufficient events are available, where timeout == NULL * specifies an infinite timeout. Note that the timeout pointed to by - * timeout is relative and will be updated if not NULL and the - * operation blocks. Will fail with -ENOSYS if not implemented. + * timeout is relative. Will fail with -ENOSYS if not implemented. */ SYSCALL_DEFINE5(io_getevents, aio_context_t, ctx_id, long, min_nr, diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c index 8615ee89ab55..f95dddced968 100644 --- a/fs/befs/linuxvfs.c +++ b/fs/befs/linuxvfs.c @@ -265,8 +265,8 @@ befs_readdir(struct file *filp, void *dirent, filldir_t filldir) result = filldir(dirent, keybuf, keysize, filp->f_pos, (ino_t) value, d_type); } - - filp->f_pos++; + if (!result) + filp->f_pos++; befs_debug(sb, "<--- befs_readdir() filp->f_pos %Ld", filp->f_pos); diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index e7b3cb5286a5..b8b60b660c8f 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -2859,8 +2859,8 @@ fail_qgroup: btrfs_free_qgroup_config(fs_info); fail_trans_kthread: kthread_stop(fs_info->transaction_kthread); - del_fs_roots(fs_info); btrfs_cleanup_transaction(fs_info->tree_root); + del_fs_roots(fs_info); fail_cleaner: kthread_stop(fs_info->cleaner_kthread); @@ -3512,15 +3512,15 @@ int close_ctree(struct btrfs_root *root) percpu_counter_sum(&fs_info->delalloc_bytes)); } - free_root_pointers(fs_info, 1); - btrfs_free_block_groups(fs_info); + btrfs_stop_all_workers(fs_info); + del_fs_roots(fs_info); - iput(fs_info->btree_inode); + free_root_pointers(fs_info, 1); - btrfs_stop_all_workers(fs_info); + iput(fs_info->btree_inode); #ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY if (btrfs_test_opt(root, CHECK_INTEGRITY)) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index af978f7682b3..17f3064b4a3e 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -8012,6 +8012,9 @@ int btrfs_drop_inode(struct inode *inode) { struct btrfs_root *root = BTRFS_I(inode)->root; + if (root == NULL) + return 1; + /* the snap/subvol tree is on deleting */ if (btrfs_root_refs(&root->root_item) == 0 && root != root->fs_info->tree_root) diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index 395b82031a42..4febca4fc2de 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c @@ -4082,7 +4082,7 @@ out: return inode; } -static struct reloc_control *alloc_reloc_control(void) +static struct reloc_control *alloc_reloc_control(struct btrfs_fs_info *fs_info) { struct reloc_control *rc; @@ -4093,7 +4093,8 @@ static struct reloc_control *alloc_reloc_control(void) INIT_LIST_HEAD(&rc->reloc_roots); backref_cache_init(&rc->backref_cache); mapping_tree_init(&rc->reloc_root_tree); - extent_io_tree_init(&rc->processed_blocks, NULL); + extent_io_tree_init(&rc->processed_blocks, + fs_info->btree_inode->i_mapping); return rc; } @@ -4110,7 +4111,7 @@ int btrfs_relocate_block_group(struct btrfs_root *extent_root, u64 group_start) int rw = 0; int err = 0; - rc = alloc_reloc_control(); + rc = alloc_reloc_control(fs_info); if (!rc) return -ENOMEM; @@ -4311,7 +4312,7 @@ int btrfs_recover_relocation(struct btrfs_root *root) if (list_empty(&reloc_roots)) goto out; - rc = alloc_reloc_control(); + rc = alloc_reloc_control(root->fs_info); if (!rc) { err = -ENOMEM; goto out; diff --git a/fs/ceph/locks.c b/fs/ceph/locks.c index 202dd3d68be0..ebbf680378e2 100644 --- a/fs/ceph/locks.c +++ b/fs/ceph/locks.c @@ -191,27 +191,23 @@ void ceph_count_locks(struct inode *inode, int *fcntl_count, int *flock_count) } /** - * Encode the flock and fcntl locks for the given inode into the pagelist. - * Format is: #fcntl locks, sequential fcntl locks, #flock locks, - * sequential flock locks. - * Must be called with lock_flocks() already held. - * If we encounter more of a specific lock type than expected, - * we return the value 1. + * Encode the flock and fcntl locks for the given inode into the ceph_filelock + * array. Must be called with lock_flocks() already held. + * If we encounter more of a specific lock type than expected, return -ENOSPC. */ -int ceph_encode_locks(struct inode *inode, struct ceph_pagelist *pagelist, - int num_fcntl_locks, int num_flock_locks) +int ceph_encode_locks_to_buffer(struct inode *inode, + struct ceph_filelock *flocks, + int num_fcntl_locks, int num_flock_locks) { struct file_lock *lock; - struct ceph_filelock cephlock; int err = 0; int seen_fcntl = 0; int seen_flock = 0; + int l = 0; dout("encoding %d flock and %d fcntl locks", num_flock_locks, num_fcntl_locks); - err = ceph_pagelist_append(pagelist, &num_fcntl_locks, sizeof(u32)); - if (err) - goto fail; + for (lock = inode->i_flock; lock != NULL; lock = lock->fl_next) { if (lock->fl_flags & FL_POSIX) { ++seen_fcntl; @@ -219,19 +215,12 @@ int ceph_encode_locks(struct inode *inode, struct ceph_pagelist *pagelist, err = -ENOSPC; goto fail; } - err = lock_to_ceph_filelock(lock, &cephlock); + err = lock_to_ceph_filelock(lock, &flocks[l]); if (err) goto fail; - err = ceph_pagelist_append(pagelist, &cephlock, - sizeof(struct ceph_filelock)); + ++l; } - if (err) - goto fail; } - - err = ceph_pagelist_append(pagelist, &num_flock_locks, sizeof(u32)); - if (err) - goto fail; for (lock = inode->i_flock; lock != NULL; lock = lock->fl_next) { if (lock->fl_flags & FL_FLOCK) { ++seen_flock; @@ -239,19 +228,51 @@ int ceph_encode_locks(struct inode *inode, struct ceph_pagelist *pagelist, err = -ENOSPC; goto fail; } - err = lock_to_ceph_filelock(lock, &cephlock); + err = lock_to_ceph_filelock(lock, &flocks[l]); if (err) goto fail; - err = ceph_pagelist_append(pagelist, &cephlock, - sizeof(struct ceph_filelock)); + ++l; } - if (err) - goto fail; } fail: return err; } +/** + * Copy the encoded flock and fcntl locks into the pagelist. + * Format is: #fcntl locks, sequential fcntl locks, #flock locks, + * sequential flock locks. + * Returns zero on success. + */ +int ceph_locks_to_pagelist(struct ceph_filelock *flocks, + struct ceph_pagelist *pagelist, + int num_fcntl_locks, int num_flock_locks) +{ + int err = 0; + __le32 nlocks; + + nlocks = cpu_to_le32(num_fcntl_locks); + err = ceph_pagelist_append(pagelist, &nlocks, sizeof(nlocks)); + if (err) + goto out_fail; + + err = ceph_pagelist_append(pagelist, flocks, + num_fcntl_locks * sizeof(*flocks)); + if (err) + goto out_fail; + + nlocks = cpu_to_le32(num_flock_locks); + err = ceph_pagelist_append(pagelist, &nlocks, sizeof(nlocks)); + if (err) + goto out_fail; + + err = ceph_pagelist_append(pagelist, + &flocks[num_fcntl_locks], + num_flock_locks * sizeof(*flocks)); +out_fail: + return err; +} + /* * Given a pointer to a lock, convert it to a ceph filelock */ diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 4f22671a5bd4..4d2920304be8 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -2478,39 +2478,44 @@ static int encode_caps_cb(struct inode *inode, struct ceph_cap *cap, if (recon_state->flock) { int num_fcntl_locks, num_flock_locks; - struct ceph_pagelist_cursor trunc_point; - - ceph_pagelist_set_cursor(pagelist, &trunc_point); - do { - lock_flocks(); - ceph_count_locks(inode, &num_fcntl_locks, - &num_flock_locks); - rec.v2.flock_len = (2*sizeof(u32) + - (num_fcntl_locks+num_flock_locks) * - sizeof(struct ceph_filelock)); - unlock_flocks(); - - /* pre-alloc pagelist */ - ceph_pagelist_truncate(pagelist, &trunc_point); - err = ceph_pagelist_append(pagelist, &rec, reclen); - if (!err) - err = ceph_pagelist_reserve(pagelist, - rec.v2.flock_len); - - /* encode locks */ - if (!err) { - lock_flocks(); - err = ceph_encode_locks(inode, - pagelist, - num_fcntl_locks, - num_flock_locks); - unlock_flocks(); - } - } while (err == -ENOSPC); + struct ceph_filelock *flocks; + +encode_again: + lock_flocks(); + ceph_count_locks(inode, &num_fcntl_locks, &num_flock_locks); + unlock_flocks(); + flocks = kmalloc((num_fcntl_locks+num_flock_locks) * + sizeof(struct ceph_filelock), GFP_NOFS); + if (!flocks) { + err = -ENOMEM; + goto out_free; + } + lock_flocks(); + err = ceph_encode_locks_to_buffer(inode, flocks, + num_fcntl_locks, + num_flock_locks); + unlock_flocks(); + if (err) { + kfree(flocks); + if (err == -ENOSPC) + goto encode_again; + goto out_free; + } + /* + * number of encoded locks is stable, so copy to pagelist + */ + rec.v2.flock_len = cpu_to_le32(2*sizeof(u32) + + (num_fcntl_locks+num_flock_locks) * + sizeof(struct ceph_filelock)); + err = ceph_pagelist_append(pagelist, &rec, reclen); + if (!err) + err = ceph_locks_to_pagelist(flocks, pagelist, + num_fcntl_locks, + num_flock_locks); + kfree(flocks); } else { err = ceph_pagelist_append(pagelist, &rec, reclen); } - out_free: kfree(path); out_dput: diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 8696be2ff679..7ccfdb4aea2e 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -822,8 +822,13 @@ extern const struct export_operations ceph_export_ops; extern int ceph_lock(struct file *file, int cmd, struct file_lock *fl); extern int ceph_flock(struct file *file, int cmd, struct file_lock *fl); extern void ceph_count_locks(struct inode *inode, int *p_num, int *f_num); -extern int ceph_encode_locks(struct inode *i, struct ceph_pagelist *p, - int p_locks, int f_locks); +extern int ceph_encode_locks_to_buffer(struct inode *inode, + struct ceph_filelock *flocks, + int num_fcntl_locks, + int num_flock_locks); +extern int ceph_locks_to_pagelist(struct ceph_filelock *flocks, + struct ceph_pagelist *pagelist, + int num_fcntl_locks, int num_flock_locks); extern int lock_to_ceph_filelock(struct file_lock *fl, struct ceph_filelock *c); /* debugfs.c */ diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c index 8e33ec65847b..58df174deb10 100644 --- a/fs/cifs/cifs_dfs_ref.c +++ b/fs/cifs/cifs_dfs_ref.c @@ -18,6 +18,7 @@ #include <linux/slab.h> #include <linux/vfs.h> #include <linux/fs.h> +#include <linux/inet.h> #include "cifsglob.h" #include "cifsproto.h" #include "cifsfs.h" @@ -48,58 +49,74 @@ void cifs_dfs_release_automount_timer(void) } /** - * cifs_get_share_name - extracts share name from UNC - * @node_name: pointer to UNC string + * cifs_build_devname - build a devicename from a UNC and optional prepath + * @nodename: pointer to UNC string + * @prepath: pointer to prefixpath (or NULL if there isn't one) * - * Extracts sharename form full UNC. - * i.e. strips from UNC trailing path that is not part of share - * name and fixup missing '\' in the beginning of DFS node refferal - * if necessary. - * Returns pointer to share name on success or ERR_PTR on error. - * Caller is responsible for freeing returned string. + * Build a new cifs devicename after chasing a DFS referral. Allocate a buffer + * big enough to hold the final thing. Copy the UNC from the nodename, and + * concatenate the prepath onto the end of it if there is one. + * + * Returns pointer to the built string, or a ERR_PTR. Caller is responsible + * for freeing the returned string. */ -static char *cifs_get_share_name(const char *node_name) +static char * +cifs_build_devname(char *nodename, const char *prepath) { - int len; - char *UNC; - char *pSep; - - len = strlen(node_name); - UNC = kmalloc(len+2 /*for term null and additional \ if it's missed */, - GFP_KERNEL); - if (!UNC) - return ERR_PTR(-ENOMEM); + size_t pplen; + size_t unclen; + char *dev; + char *pos; + + /* skip over any preceding delimiters */ + nodename += strspn(nodename, "\\"); + if (!*nodename) + return ERR_PTR(-EINVAL); - /* get share name and server name */ - if (node_name[1] != '\\') { - UNC[0] = '\\'; - strncpy(UNC+1, node_name, len); - len++; - UNC[len] = 0; - } else { - strncpy(UNC, node_name, len); - UNC[len] = 0; - } + /* get length of UNC and set pos to last char */ + unclen = strlen(nodename); + pos = nodename + unclen - 1; - /* find server name end */ - pSep = memchr(UNC+2, '\\', len-2); - if (!pSep) { - cifs_dbg(VFS, "%s: no server name end in node name: %s\n", - __func__, node_name); - kfree(UNC); - return ERR_PTR(-EINVAL); + /* trim off any trailing delimiters */ + while (*pos == '\\') { + --pos; + --unclen; } - /* find sharename end */ - pSep++; - pSep = memchr(UNC+(pSep-UNC), '\\', len-(pSep-UNC)); - if (pSep) { - /* trim path up to sharename end - * now we have share name in UNC */ - *pSep = 0; + /* allocate a buffer: + * +2 for preceding "//" + * +1 for delimiter between UNC and prepath + * +1 for trailing NULL + */ + pplen = prepath ? strlen(prepath) : 0; + dev = kmalloc(2 + unclen + 1 + pplen + 1, GFP_KERNEL); + if (!dev) + return ERR_PTR(-ENOMEM); + + pos = dev; + /* add the initial "//" */ + *pos = '/'; + ++pos; + *pos = '/'; + ++pos; + + /* copy in the UNC portion from referral */ + memcpy(pos, nodename, unclen); + pos += unclen; + + /* copy the prefixpath remainder (if there is one) */ + if (pplen) { + *pos = '/'; + ++pos; + memcpy(pos, prepath, pplen); + pos += pplen; } - return UNC; + /* NULL terminator */ + *pos = '\0'; + + convert_delimiter(dev, '/'); + return dev; } @@ -123,6 +140,7 @@ char *cifs_compose_mount_options(const char *sb_mountdata, { int rc; char *mountdata = NULL; + const char *prepath = NULL; int md_len; char *tkn_e; char *srvIP = NULL; @@ -132,7 +150,10 @@ char *cifs_compose_mount_options(const char *sb_mountdata, if (sb_mountdata == NULL) return ERR_PTR(-EINVAL); - *devname = cifs_get_share_name(ref->node_name); + if (strlen(fullpath) - ref->path_consumed) + prepath = fullpath + ref->path_consumed; + + *devname = cifs_build_devname(ref->node_name, prepath); if (IS_ERR(*devname)) { rc = PTR_ERR(*devname); *devname = NULL; @@ -146,12 +167,14 @@ char *cifs_compose_mount_options(const char *sb_mountdata, goto compose_mount_options_err; } - /* md_len = strlen(...) + 12 for 'sep+prefixpath=' - * assuming that we have 'unc=' and 'ip=' in - * the original sb_mountdata + /* + * In most cases, we'll be building a shorter string than the original, + * but we do have to assume that the address in the ip= option may be + * much longer than the original. Add the max length of an address + * string to the length of the original string to allow for worst case. */ - md_len = strlen(sb_mountdata) + rc + strlen(ref->node_name) + 12; - mountdata = kzalloc(md_len+1, GFP_KERNEL); + md_len = strlen(sb_mountdata) + INET6_ADDRSTRLEN; + mountdata = kzalloc(md_len + 1, GFP_KERNEL); if (mountdata == NULL) { rc = -ENOMEM; goto compose_mount_options_err; @@ -195,26 +218,6 @@ char *cifs_compose_mount_options(const char *sb_mountdata, strncat(mountdata, &sep, 1); strcat(mountdata, "ip="); strcat(mountdata, srvIP); - strncat(mountdata, &sep, 1); - strcat(mountdata, "unc="); - strcat(mountdata, *devname); - - /* find & copy prefixpath */ - tkn_e = strchr(ref->node_name + 2, '\\'); - if (tkn_e == NULL) { - /* invalid unc, missing share name*/ - rc = -EINVAL; - goto compose_mount_options_err; - } - - tkn_e = strchr(tkn_e + 1, '\\'); - if (tkn_e || (strlen(fullpath) - ref->path_consumed)) { - strncat(mountdata, &sep, 1); - strcat(mountdata, "prefixpath="); - if (tkn_e) - strcat(mountdata, tkn_e + 1); - strcat(mountdata, fullpath + ref->path_consumed); - } /*cifs_dbg(FYI, "%s: parent mountdata: %s\n", __func__, sb_mountdata);*/ /*cifs_dbg(FYI, "%s: submount mountdata: %s\n", __func__, mountdata );*/ diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 72e4efee1389..3752b9f6d9e4 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -372,9 +372,6 @@ cifs_show_options(struct seq_file *s, struct dentry *root) cifs_show_security(s, tcon->ses->server); cifs_show_cache_flavor(s, cifs_sb); - seq_printf(s, ",unc="); - seq_escape(s, tcon->treeName, " \t\n\\"); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER) seq_printf(s, ",multiuser"); else if (tcon->ses->user_name) diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 99eeaa17ee00..e3bc39bb9d12 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -1061,6 +1061,7 @@ static int cifs_parse_security_flavors(char *value, #endif case Opt_sec_none: vol->nullauth = 1; + vol->secFlg |= CIFSSEC_MAY_NTLM; break; default: cifs_dbg(VFS, "bad security option: %s\n", value); @@ -1257,14 +1258,18 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, vol->backupuid_specified = false; /* no backup intent for a user */ vol->backupgid_specified = false; /* no backup intent for a group */ - /* - * For now, we ignore -EINVAL errors under the assumption that the - * unc= and prefixpath= options will be usable. - */ - if (cifs_parse_devname(devname, vol) == -ENOMEM) { - printk(KERN_ERR "CIFS: Unable to allocate memory to parse " - "device string.\n"); - goto out_nomem; + switch (cifs_parse_devname(devname, vol)) { + case 0: + break; + case -ENOMEM: + cifs_dbg(VFS, "Unable to allocate memory for devname.\n"); + goto cifs_parse_mount_err; + case -EINVAL: + cifs_dbg(VFS, "Malformed UNC in devname.\n"); + goto cifs_parse_mount_err; + default: + cifs_dbg(VFS, "Unknown error parsing devname.\n"); + goto cifs_parse_mount_err; } while ((data = strsep(&options, separator)) != NULL) { @@ -1826,7 +1831,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, } #endif if (!vol->UNC) { - cifs_dbg(VFS, "CIFS mount error: No usable UNC path provided in device string or in unc= option!\n"); + cifs_dbg(VFS, "CIFS mount error: No usable UNC path provided in device string!\n"); goto cifs_parse_mount_err; } @@ -3274,8 +3279,8 @@ build_unc_path_to_root(const struct smb_vol *vol, pos = full_path + unc_len; if (pplen) { - *pos++ = CIFS_DIR_SEP(cifs_sb); - strncpy(pos, vol->prepath, pplen); + *pos = CIFS_DIR_SEP(cifs_sb); + strncpy(pos + 1, vol->prepath, pplen); pos += pplen; } diff --git a/fs/cifs/dns_resolve.c b/fs/cifs/dns_resolve.c index e7512e497611..7ede7306599f 100644 --- a/fs/cifs/dns_resolve.c +++ b/fs/cifs/dns_resolve.c @@ -34,7 +34,7 @@ /** * dns_resolve_server_name_to_ip - Resolve UNC server name to ip address. - * @unc: UNC path specifying the server + * @unc: UNC path specifying the server (with '/' as delimiter) * @ip_addr: Where to return the IP address. * * The IP address will be returned in string form, and the caller is @@ -64,7 +64,7 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr) hostname = unc + 2; /* Search for server name delimiter */ - sep = memchr(hostname, '\\', len); + sep = memchr(hostname, '/', len); if (sep) len = sep - hostname; else diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index fc3025199cb3..20efd81266c6 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -171,7 +171,8 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr) if (fattr->cf_flags & CIFS_FATTR_DFS_REFERRAL) inode->i_flags |= S_AUTOMOUNT; - cifs_set_ops(inode); + if (inode->i_state & I_NEW) + cifs_set_ops(inode); } void diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index 201f0a0d6b0a..a7abbea2c096 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c @@ -295,6 +295,12 @@ static int ecryptfs_release(struct inode *inode, struct file *file) static int ecryptfs_fsync(struct file *file, loff_t start, loff_t end, int datasync) { + int rc; + + rc = filemap_write_and_wait(file->f_mapping); + if (rc) + return rc; + return vfs_fsync(ecryptfs_file_to_lower(file), datasync); } diff --git a/fs/efivarfs/file.c b/fs/efivarfs/file.c index bfb531564319..8dd524f32284 100644 --- a/fs/efivarfs/file.c +++ b/fs/efivarfs/file.c @@ -44,8 +44,11 @@ static ssize_t efivarfs_file_write(struct file *file, bytes = efivar_entry_set_get_size(var, attributes, &datasize, data, &set); - if (!set && bytes) + if (!set && bytes) { + if (bytes == -ENOENT) + bytes = -EIO; goto out; + } if (bytes == -ENOENT) { drop_nlink(inode); @@ -76,7 +79,14 @@ static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf, int err; err = efivar_entry_size(var, &datasize); - if (err) + + /* + * efivarfs represents uncommitted variables with + * zero-length files. Reading them should return EOF. + */ + if (err == -ENOENT) + return 0; + else if (err) return err; data = kmalloc(datasize + sizeof(attributes), GFP_KERNEL); diff --git a/fs/fat/inode.c b/fs/fat/inode.c index dfce656ddb33..5d4513cb1b3c 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -1229,6 +1229,19 @@ static int fat_read_root(struct inode *inode) return 0; } +static unsigned long calc_fat_clusters(struct super_block *sb) +{ + struct msdos_sb_info *sbi = MSDOS_SB(sb); + + /* Divide first to avoid overflow */ + if (sbi->fat_bits != 12) { + unsigned long ent_per_sec = sb->s_blocksize * 8 / sbi->fat_bits; + return ent_per_sec * sbi->fat_length; + } + + return sbi->fat_length * sb->s_blocksize * 8 / sbi->fat_bits; +} + /* * Read the super block of an MS-DOS FS. */ @@ -1434,7 +1447,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, sbi->dirty = b->fat16.state & FAT_STATE_DIRTY; /* check that FAT table does not overflow */ - fat_clusters = sbi->fat_length * sb->s_blocksize * 8 / sbi->fat_bits; + fat_clusters = calc_fat_clusters(sb); total_clusters = min(total_clusters, fat_clusters - FAT_START_ENT); if (total_clusters > MAX_FAT(sb)) { if (!silent) diff --git a/fs/file_table.c b/fs/file_table.c index cd4d87a82951..485dc0eddd67 100644 --- a/fs/file_table.c +++ b/fs/file_table.c @@ -306,17 +306,18 @@ void fput(struct file *file) { if (atomic_long_dec_and_test(&file->f_count)) { struct task_struct *task = current; + unsigned long flags; + file_sb_list_del(file); - if (unlikely(in_interrupt() || task->flags & PF_KTHREAD)) { - unsigned long flags; - spin_lock_irqsave(&delayed_fput_lock, flags); - list_add(&file->f_u.fu_list, &delayed_fput_list); - schedule_work(&delayed_fput_work); - spin_unlock_irqrestore(&delayed_fput_lock, flags); - return; + if (likely(!in_interrupt() && !(task->flags & PF_KTHREAD))) { + init_task_work(&file->f_u.fu_rcuhead, ____fput); + if (!task_work_add(task, &file->f_u.fu_rcuhead, true)) + return; } - init_task_work(&file->f_u.fu_rcuhead, ____fput); - task_work_add(task, &file->f_u.fu_rcuhead, true); + spin_lock_irqsave(&delayed_fput_lock, flags); + list_add(&file->f_u.fu_list, &delayed_fput_list); + schedule_work(&delayed_fput_work); + spin_unlock_irqrestore(&delayed_fput_lock, flags); } } diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 254df56b847b..f3f783dc4f75 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -180,6 +180,8 @@ u64 fuse_get_attr_version(struct fuse_conn *fc) static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags) { struct inode *inode; + struct dentry *parent; + struct fuse_conn *fc; inode = ACCESS_ONCE(entry->d_inode); if (inode && is_bad_inode(inode)) @@ -187,10 +189,8 @@ static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags) else if (fuse_dentry_time(entry) < get_jiffies_64()) { int err; struct fuse_entry_out outarg; - struct fuse_conn *fc; struct fuse_req *req; struct fuse_forget_link *forget; - struct dentry *parent; u64 attr_version; /* For negative dentries, always do a fresh lookup */ @@ -241,8 +241,14 @@ static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags) entry_attr_timeout(&outarg), attr_version); fuse_change_entry_timeout(entry, &outarg); + } else if (inode) { + fc = get_fuse_conn(inode); + if (fc->readdirplus_auto) { + parent = dget_parent(entry); + fuse_advise_use_readdirplus(parent->d_inode); + dput(parent); + } } - fuse_advise_use_readdirplus(inode); return 1; } diff --git a/fs/fuse/file.c b/fs/fuse/file.c index d1c9b85b3f58..e570081f9f76 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -16,6 +16,7 @@ #include <linux/compat.h> #include <linux/swap.h> #include <linux/aio.h> +#include <linux/falloc.h> static const struct file_operations fuse_direct_io_file_operations; @@ -1278,7 +1279,10 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, const struct iovec *iov, iov_iter_init(&ii, iov, nr_segs, count, 0); - req = fuse_get_req(fc, fuse_iter_npages(&ii)); + if (io->async) + req = fuse_get_req_for_background(fc, fuse_iter_npages(&ii)); + else + req = fuse_get_req(fc, fuse_iter_npages(&ii)); if (IS_ERR(req)) return PTR_ERR(req); @@ -1314,7 +1318,11 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, const struct iovec *iov, break; if (count) { fuse_put_request(fc, req); - req = fuse_get_req(fc, fuse_iter_npages(&ii)); + if (io->async) + req = fuse_get_req_for_background(fc, + fuse_iter_npages(&ii)); + else + req = fuse_get_req(fc, fuse_iter_npages(&ii)); if (IS_ERR(req)) break; } @@ -2365,6 +2373,11 @@ static void fuse_do_truncate(struct file *file) fuse_do_setattr(inode, &attr, file); } +static inline loff_t fuse_round_up(loff_t off) +{ + return round_up(off, FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT); +} + static ssize_t fuse_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, loff_t offset, unsigned long nr_segs) @@ -2372,6 +2385,7 @@ fuse_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, ssize_t ret = 0; struct file *file = iocb->ki_filp; struct fuse_file *ff = file->private_data; + bool async_dio = ff->fc->async_dio; loff_t pos = 0; struct inode *inode; loff_t i_size; @@ -2383,10 +2397,10 @@ fuse_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, i_size = i_size_read(inode); /* optimization for short read */ - if (rw != WRITE && offset + count > i_size) { + if (async_dio && rw != WRITE && offset + count > i_size) { if (offset >= i_size) return 0; - count = i_size - offset; + count = min_t(loff_t, count, fuse_round_up(i_size - offset)); } io = kmalloc(sizeof(struct fuse_io_priv), GFP_KERNEL); @@ -2404,7 +2418,7 @@ fuse_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, * By default, we want to optimize all I/Os with async request * submission to the client filesystem if supported. */ - io->async = ff->fc->async_dio; + io->async = async_dio; io->iocb = iocb; /* @@ -2412,7 +2426,7 @@ fuse_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, * to wait on real async I/O requests, so we must submit this request * synchronously. */ - if (!is_sync_kiocb(iocb) && (offset + count > i_size)) + if (!is_sync_kiocb(iocb) && (offset + count > i_size) && rw == WRITE) io->async = false; if (rw == WRITE) @@ -2424,7 +2438,7 @@ fuse_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, fuse_aio_complete(io, ret < 0 ? ret : 0, -1); /* we have a non-extending, async request, so return */ - if (ret > 0 && !is_sync_kiocb(iocb)) + if (!is_sync_kiocb(iocb)) return -EIOCBQUEUED; ret = wait_on_sync_kiocb(iocb); @@ -2446,6 +2460,7 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset, loff_t length) { struct fuse_file *ff = file->private_data; + struct inode *inode = file->f_inode; struct fuse_conn *fc = ff->fc; struct fuse_req *req; struct fuse_fallocate_in inarg = { @@ -2459,9 +2474,16 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset, if (fc->no_fallocate) return -EOPNOTSUPP; + if (mode & FALLOC_FL_PUNCH_HOLE) { + mutex_lock(&inode->i_mutex); + fuse_set_nowrite(inode); + } + req = fuse_get_req_nopages(fc); - if (IS_ERR(req)) - return PTR_ERR(req); + if (IS_ERR(req)) { + err = PTR_ERR(req); + goto out; + } req->in.h.opcode = FUSE_FALLOCATE; req->in.h.nodeid = ff->nodeid; @@ -2476,6 +2498,24 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset, } fuse_put_request(fc, req); + if (err) + goto out; + + /* we could have extended the file */ + if (!(mode & FALLOC_FL_KEEP_SIZE)) + fuse_write_update_size(inode, offset + length); + + if (mode & FALLOC_FL_PUNCH_HOLE) + truncate_pagecache_range(inode, offset, offset + length - 1); + + fuse_invalidate_attr(inode); + +out: + if (mode & FALLOC_FL_PUNCH_HOLE) { + fuse_release_nowrite(inode); + mutex_unlock(&inode->i_mutex); + } + return err; } diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 6201f81e4d3a..9a0cdde14a08 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -867,10 +867,11 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req) fc->dont_mask = 1; if (arg->flags & FUSE_AUTO_INVAL_DATA) fc->auto_inval_data = 1; - if (arg->flags & FUSE_DO_READDIRPLUS) + if (arg->flags & FUSE_DO_READDIRPLUS) { fc->do_readdirplus = 1; - if (arg->flags & FUSE_READDIRPLUS_AUTO) - fc->readdirplus_auto = 1; + if (arg->flags & FUSE_READDIRPLUS_AUTO) + fc->readdirplus_auto = 1; + } if (arg->flags & FUSE_ASYNC_DIO) fc->async_dio = 1; } else { diff --git a/fs/gfs2/Kconfig b/fs/gfs2/Kconfig index eb08c9e43c2a..5a376ab81feb 100644 --- a/fs/gfs2/Kconfig +++ b/fs/gfs2/Kconfig @@ -26,7 +26,7 @@ config GFS2_FS config GFS2_FS_LOCKING_DLM bool "GFS2 DLM locking" depends on (GFS2_FS!=n) && NET && INET && (IPV6 || IPV6=n) && \ - HOTPLUG && DLM && CONFIGFS_FS && SYSFS + HOTPLUG && CONFIGFS_FS && SYSFS && (DLM=y || DLM=GFS2_FS) help Multiple node locking module for GFS2 diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index 1dc9a13ce6bb..93b5809c20bb 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c @@ -1286,17 +1286,26 @@ int gfs2_setattr_size(struct inode *inode, u64 newsize) if (ret) return ret; + ret = get_write_access(inode); + if (ret) + return ret; + inode_dio_wait(inode); ret = gfs2_rs_alloc(GFS2_I(inode)); if (ret) - return ret; + goto out; oldsize = inode->i_size; - if (newsize >= oldsize) - return do_grow(inode, newsize); + if (newsize >= oldsize) { + ret = do_grow(inode, newsize); + goto out; + } - return do_shrink(inode, oldsize, newsize); + ret = do_shrink(inode, oldsize, newsize); +out: + put_write_access(inode); + return ret; } int gfs2_truncatei_resume(struct gfs2_inode *ip) diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c index c3e82bd23179..b631c9043460 100644 --- a/fs/gfs2/dir.c +++ b/fs/gfs2/dir.c @@ -354,22 +354,31 @@ static __be64 *gfs2_dir_get_hash_table(struct gfs2_inode *ip) return ERR_PTR(-EIO); } - hc = kmalloc(hsize, GFP_NOFS); - ret = -ENOMEM; + hc = kmalloc(hsize, GFP_NOFS | __GFP_NOWARN); + if (hc == NULL) + hc = __vmalloc(hsize, GFP_NOFS, PAGE_KERNEL); + if (hc == NULL) return ERR_PTR(-ENOMEM); ret = gfs2_dir_read_data(ip, hc, hsize); if (ret < 0) { - kfree(hc); + if (is_vmalloc_addr(hc)) + vfree(hc); + else + kfree(hc); return ERR_PTR(ret); } spin_lock(&inode->i_lock); - if (ip->i_hash_cache) - kfree(hc); - else + if (ip->i_hash_cache) { + if (is_vmalloc_addr(hc)) + vfree(hc); + else + kfree(hc); + } else { ip->i_hash_cache = hc; + } spin_unlock(&inode->i_lock); return ip->i_hash_cache; @@ -385,7 +394,10 @@ void gfs2_dir_hash_inval(struct gfs2_inode *ip) { __be64 *hc = ip->i_hash_cache; ip->i_hash_cache = NULL; - kfree(hc); + if (is_vmalloc_addr(hc)) + vfree(hc); + else + kfree(hc); } static inline int gfs2_dirent_sentinel(const struct gfs2_dirent *dent) @@ -1113,7 +1125,10 @@ static int dir_double_exhash(struct gfs2_inode *dip) if (IS_ERR(hc)) return PTR_ERR(hc); - h = hc2 = kmalloc(hsize_bytes * 2, GFP_NOFS); + h = hc2 = kmalloc(hsize_bytes * 2, GFP_NOFS | __GFP_NOWARN); + if (hc2 == NULL) + hc2 = __vmalloc(hsize_bytes * 2, GFP_NOFS, PAGE_KERNEL); + if (!hc2) return -ENOMEM; @@ -1145,7 +1160,10 @@ fail: gfs2_dinode_out(dip, dibh->b_data); brelse(dibh); out_kfree: - kfree(hc2); + if (is_vmalloc_addr(hc2)) + vfree(hc2); + else + kfree(hc2); return error; } @@ -1846,6 +1864,8 @@ static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len, memset(&rlist, 0, sizeof(struct gfs2_rgrp_list)); ht = kzalloc(size, GFP_NOFS); + if (ht == NULL) + ht = vzalloc(size); if (!ht) return -ENOMEM; @@ -1933,7 +1953,10 @@ out_rlist: gfs2_rlist_free(&rlist); gfs2_quota_unhold(dip); out: - kfree(ht); + if (is_vmalloc_addr(ht)) + vfree(ht); + else + kfree(ht); return error; } diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index acd16764b133..ad0dc38d87ab 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c @@ -402,16 +402,20 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) /* Update file times before taking page lock */ file_update_time(vma->vm_file); + ret = get_write_access(inode); + if (ret) + goto out; + ret = gfs2_rs_alloc(ip); if (ret) - return ret; + goto out_write_access; gfs2_size_hint(vma->vm_file, pos, PAGE_CACHE_SIZE); gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); ret = gfs2_glock_nq(&gh); if (ret) - goto out; + goto out_uninit; set_bit(GLF_DIRTY, &ip->i_gl->gl_flags); set_bit(GIF_SW_PAGED, &ip->i_flags); @@ -480,12 +484,15 @@ out_quota_unlock: gfs2_quota_unlock(ip); out_unlock: gfs2_glock_dq(&gh); -out: +out_uninit: gfs2_holder_uninit(&gh); if (ret == 0) { set_page_dirty(page); wait_for_stable_page(page); } +out_write_access: + put_write_access(inode); +out: sb_end_pagefault(inode->i_sb); return block_page_mkwrite_return(ret); } @@ -594,10 +601,10 @@ static int gfs2_release(struct inode *inode, struct file *file) kfree(file->private_data); file->private_data = NULL; - if ((file->f_mode & FMODE_WRITE) && - (atomic_read(&inode->i_writecount) == 1)) - gfs2_rs_delete(ip); + if (!(file->f_mode & FMODE_WRITE)) + return 0; + gfs2_rs_delete(ip); return 0; } diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 8833a4f264e3..62b484e4a9e4 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -189,6 +189,7 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type, return inode; fail_refresh: + ip->i_iopen_gh.gh_flags |= GL_NOCACHE; ip->i_iopen_gh.gh_gl->gl_object = NULL; gfs2_glock_dq_uninit(&ip->i_iopen_gh); fail_iopen: diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c index c5fa758fd844..6c33d7b6e0c4 100644 --- a/fs/gfs2/lops.c +++ b/fs/gfs2/lops.c @@ -212,7 +212,7 @@ static void gfs2_end_log_write(struct bio *bio, int error) fs_err(sdp, "Error %d writing to log\n", error); } - bio_for_each_segment(bvec, bio, i) { + bio_for_each_segment_all(bvec, bio, i) { page = bvec->bv_page; if (page_has_buffers(page)) gfs2_end_log_write_bh(sdp, bvec, error); @@ -419,7 +419,9 @@ static void gfs2_before_commit(struct gfs2_sbd *sdp, unsigned int limit, if (total > limit) num = limit; gfs2_log_unlock(sdp); - page = gfs2_get_log_desc(sdp, GFS2_LOG_DESC_METADATA, num + 1, num); + page = gfs2_get_log_desc(sdp, + is_databuf ? GFS2_LOG_DESC_JDATA : + GFS2_LOG_DESC_METADATA, num + 1, num); ld = page_address(page); gfs2_log_lock(sdp); ptr = (__be64 *)(ld + 1); diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index c7c840e916f8..c253b13722e8 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c @@ -121,7 +121,7 @@ static u64 qd2index(struct gfs2_quota_data *qd) { struct kqid qid = qd->qd_id; return (2 * (u64)from_kqid(&init_user_ns, qid)) + - (qid.type == USRQUOTA) ? 0 : 1; + ((qid.type == USRQUOTA) ? 0 : 1); } static u64 qd2offset(struct gfs2_quota_data *qd) @@ -721,7 +721,7 @@ get_a_page: goto unlock_out; } - gfs2_trans_add_meta(ip->i_gl, bh); + gfs2_trans_add_data(ip->i_gl, bh); kaddr = kmap_atomic(page); if (offset + sizeof(struct gfs2_quota) > PAGE_CACHE_SIZE) diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 0c5a575b513e..9809156e3d04 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c @@ -638,8 +638,10 @@ void gfs2_rs_deltree(struct gfs2_blkreserv *rs) */ void gfs2_rs_delete(struct gfs2_inode *ip) { + struct inode *inode = &ip->i_inode; + down_write(&ip->i_rw_mutex); - if (ip->i_res) { + if (ip->i_res && atomic_read(&inode->i_writecount) <= 1) { gfs2_rs_deltree(ip->i_res); BUG_ON(ip->i_res->rs_free); kmem_cache_free(gfs2_rsrv_cachep, ip->i_res); @@ -1401,9 +1403,14 @@ static void rg_mblk_search(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip, u32 extlen; u32 free_blocks = rgd->rd_free_clone - rgd->rd_reserved; int ret; + struct inode *inode = &ip->i_inode; - extlen = max_t(u32, atomic_read(&rs->rs_sizehint), requested); - extlen = clamp(extlen, RGRP_RSRV_MINBLKS, free_blocks); + if (S_ISDIR(inode->i_mode)) + extlen = 1; + else { + extlen = max_t(u32, atomic_read(&rs->rs_sizehint), requested); + extlen = clamp(extlen, RGRP_RSRV_MINBLKS, free_blocks); + } if ((rgd->rd_free_clone < rgd->rd_reserved) || (free_blocks < extlen)) return; diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index 917c8e1eb4ae..e5639dec66c4 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c @@ -1444,6 +1444,7 @@ static void gfs2_evict_inode(struct inode *inode) /* Must not read inode block until block type has been verified */ error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_SKIP, &gh); if (unlikely(error)) { + ip->i_iopen_gh.gh_flags |= GL_NOCACHE; gfs2_glock_dq_uninit(&ip->i_iopen_gh); goto out; } @@ -1514,8 +1515,10 @@ out_unlock: if (gfs2_rs_active(ip->i_res)) gfs2_rs_deltree(ip->i_res); - if (test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags)) + if (test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags)) { + ip->i_iopen_gh.gh_flags |= GL_NOCACHE; gfs2_glock_dq(&ip->i_iopen_gh); + } gfs2_holder_uninit(&ip->i_iopen_gh); gfs2_glock_dq_uninit(&gh); if (error && error != GLR_TRYFAILED && error != -EROFS) @@ -1534,6 +1537,7 @@ out: ip->i_gl = NULL; if (ip->i_iopen_gh.gh_gl) { ip->i_iopen_gh.gh_gl->gl_object = NULL; + ip->i_iopen_gh.gh_flags |= GL_NOCACHE; gfs2_glock_dq_uninit(&ip->i_iopen_gh); } } diff --git a/fs/hfs/bnode.c b/fs/hfs/bnode.c index f3b1a15ccd59..d3fa6bd9503e 100644 --- a/fs/hfs/bnode.c +++ b/fs/hfs/bnode.c @@ -415,7 +415,11 @@ struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num) spin_lock(&tree->hash_lock); node = hfs_bnode_findhash(tree, num); spin_unlock(&tree->hash_lock); - BUG_ON(node); + if (node) { + pr_crit("new node %u already hashed?\n", num); + WARN_ON(1); + return node; + } node = __hfs_bnode_create(tree, num); if (!node) return ERR_PTR(-ENOMEM); diff --git a/fs/hpfs/dir.c b/fs/hpfs/dir.c index 546f6d39713a..834ac13c04b7 100644 --- a/fs/hpfs/dir.c +++ b/fs/hpfs/dir.c @@ -33,25 +33,27 @@ static loff_t hpfs_dir_lseek(struct file *filp, loff_t off, int whence) if (whence == SEEK_DATA || whence == SEEK_HOLE) return -EINVAL; + mutex_lock(&i->i_mutex); hpfs_lock(s); /*printk("dir lseek\n");*/ if (new_off == 0 || new_off == 1 || new_off == 11 || new_off == 12 || new_off == 13) goto ok; - mutex_lock(&i->i_mutex); pos = ((loff_t) hpfs_de_as_down_as_possible(s, hpfs_inode->i_dno) << 4) + 1; while (pos != new_off) { if (map_pos_dirent(i, &pos, &qbh)) hpfs_brelse4(&qbh); else goto fail; if (pos == 12) goto fail; } - mutex_unlock(&i->i_mutex); + hpfs_add_pos(i, &filp->f_pos); ok: + filp->f_pos = new_off; hpfs_unlock(s); - return filp->f_pos = new_off; -fail: mutex_unlock(&i->i_mutex); + return new_off; +fail: /*printk("illegal lseek: %016llx\n", new_off);*/ hpfs_unlock(s); + mutex_unlock(&i->i_mutex); return -ESPIPE; } diff --git a/fs/hpfs/file.c b/fs/hpfs/file.c index 3027f4dbbab5..e4ba5fe4c3b5 100644 --- a/fs/hpfs/file.c +++ b/fs/hpfs/file.c @@ -109,10 +109,14 @@ static void hpfs_write_failed(struct address_space *mapping, loff_t to) { struct inode *inode = mapping->host; + hpfs_lock(inode->i_sb); + if (to > inode->i_size) { truncate_pagecache(inode, to, inode->i_size); hpfs_truncate(inode); } + + hpfs_unlock(inode->i_sb); } static int hpfs_write_begin(struct file *file, struct address_space *mapping, diff --git a/fs/internal.h b/fs/internal.h index eaa75f75b625..68121584ae37 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -132,6 +132,12 @@ extern struct dentry *__d_alloc(struct super_block *, const struct qstr *); extern ssize_t __kernel_write(struct file *, const char *, size_t, loff_t *); /* + * splice.c + */ +extern long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, + loff_t *opos, size_t len, unsigned int flags); + +/* * pipe.c */ extern const struct file_operations pipefifo_fops; diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c index c57499dca89c..360d27c48887 100644 --- a/fs/jfs/jfs_logmgr.c +++ b/fs/jfs/jfs_logmgr.c @@ -2009,7 +2009,13 @@ static int lbmRead(struct jfs_log * log, int pn, struct lbuf ** bpp) bio->bi_end_io = lbmIODone; bio->bi_private = bp; - submit_bio(READ_SYNC, bio); + /*check if journaling to disk has been disabled*/ + if (log->no_integrity) { + bio->bi_size = 0; + lbmIODone(bio, 0); + } else { + submit_bio(READ_SYNC, bio); + } wait_event(bp->l_ioevent, (bp->l_flag != lbmREAD)); diff --git a/fs/jfs/super.c b/fs/jfs/super.c index 2003e830ed1c..788e0a9c1fb0 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c @@ -611,11 +611,28 @@ static int jfs_freeze(struct super_block *sb) { struct jfs_sb_info *sbi = JFS_SBI(sb); struct jfs_log *log = sbi->log; + int rc = 0; if (!(sb->s_flags & MS_RDONLY)) { txQuiesce(sb); - lmLogShutdown(log); - updateSuper(sb, FM_CLEAN); + rc = lmLogShutdown(log); + if (rc) { + jfs_error(sb, "jfs_freeze: lmLogShutdown failed"); + + /* let operations fail rather than hang */ + txResume(sb); + + return rc; + } + rc = updateSuper(sb, FM_CLEAN); + if (rc) { + jfs_err("jfs_freeze: updateSuper failed\n"); + /* + * Don't fail here. Everything succeeded except + * marking the superblock clean, so there's really + * no harm in leaving it frozen for now. + */ + } } return 0; } @@ -627,13 +644,18 @@ static int jfs_unfreeze(struct super_block *sb) int rc = 0; if (!(sb->s_flags & MS_RDONLY)) { - updateSuper(sb, FM_MOUNT); - if ((rc = lmLogInit(log))) - jfs_err("jfs_unlock failed with return code %d", rc); - else - txResume(sb); + rc = updateSuper(sb, FM_MOUNT); + if (rc) { + jfs_error(sb, "jfs_unfreeze: updateSuper failed"); + goto out; + } + rc = lmLogInit(log); + if (rc) + jfs_error(sb, "jfs_unfreeze: lmLogInit failed"); +out: + txResume(sb); } - return 0; + return rc; } static struct dentry *jfs_do_mount(struct file_system_type *fs_type, diff --git a/fs/namei.c b/fs/namei.c index 85e40d1c0a8f..9ed9361223c0 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -1976,7 +1976,7 @@ static int path_lookupat(int dfd, const char *name, err = complete_walk(nd); if (!err && nd->flags & LOOKUP_DIRECTORY) { - if (!nd->inode->i_op->lookup) { + if (!can_lookup(nd->inode)) { path_put(&nd->path); err = -ENOTDIR; } @@ -2850,7 +2850,7 @@ finish_lookup: if ((open_flag & O_CREAT) && S_ISDIR(nd->inode->i_mode)) goto out; error = -ENOTDIR; - if ((nd->flags & LOOKUP_DIRECTORY) && !nd->inode->i_op->lookup) + if ((nd->flags & LOOKUP_DIRECTORY) && !can_lookup(nd->inode)) goto out; audit_inode(name, nd->path.dentry, 0); finish_open: diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c index 816326093656..6792ce11f2bf 100644 --- a/fs/ncpfs/dir.c +++ b/fs/ncpfs/dir.c @@ -1029,15 +1029,6 @@ static int ncp_rmdir(struct inode *dir, struct dentry *dentry) DPRINTK("ncp_rmdir: removing %s/%s\n", dentry->d_parent->d_name.name, dentry->d_name.name); - /* - * fail with EBUSY if there are still references to this - * directory. - */ - dentry_unhash(dentry); - error = -EBUSY; - if (!d_unhashed(dentry)) - goto out; - len = sizeof(__name); error = ncp_io2vol(server, __name, &len, dentry->d_name.name, dentry->d_name.len, !ncp_preserve_case(dir)); diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index a13d26ede254..0bc27684ebfa 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c @@ -414,7 +414,7 @@ __be32 nfs4_callback_sequence(struct cb_sequenceargs *args, spin_lock(&tbl->slot_tbl_lock); /* state manager is resetting the session */ - if (test_bit(NFS4_SESSION_DRAINING, &clp->cl_session->session_state)) { + if (test_bit(NFS4_SLOT_TBL_DRAINING, &tbl->slot_tbl_state)) { spin_unlock(&tbl->slot_tbl_lock); status = htonl(NFS4ERR_DELAY); /* Return NFS4ERR_BADSESSION if we're draining the session diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c index 59461c957d9d..a35582c9d444 100644 --- a/fs/nfs/callback_xdr.c +++ b/fs/nfs/callback_xdr.c @@ -763,7 +763,7 @@ static void nfs4_callback_free_slot(struct nfs4_session *session) * A single slot, so highest used slotid is either 0 or -1 */ tbl->highest_used_slotid = NFS4_NO_SLOT; - nfs4_session_drain_complete(session, tbl); + nfs4_slot_tbl_drain_complete(tbl); spin_unlock(&tbl->slot_tbl_lock); } diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c index 947b0c908aa9..4cbad5d6b276 100644 --- a/fs/nfs/nfs4client.c +++ b/fs/nfs/nfs4client.c @@ -203,7 +203,7 @@ struct nfs_client *nfs4_init_client(struct nfs_client *clp, __set_bit(NFS_CS_DISCRTRY, &clp->cl_flags); error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_GSS_KRB5I); if (error == -EINVAL) - error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_NULL); + error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_UNIX); if (error < 0) goto error; diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 8fbc10054115..d7ba5616989c 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -572,7 +572,7 @@ int nfs41_setup_sequence(struct nfs4_session *session, task->tk_timeout = 0; spin_lock(&tbl->slot_tbl_lock); - if (test_bit(NFS4_SESSION_DRAINING, &session->session_state) && + if (test_bit(NFS4_SLOT_TBL_DRAINING, &tbl->slot_tbl_state) && !args->sa_privileged) { /* The state manager will wait until the slot table is empty */ dprintk("%s session is draining\n", __func__); @@ -1078,7 +1078,7 @@ static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata) struct nfs4_state *state = opendata->state; struct nfs_inode *nfsi = NFS_I(state->inode); struct nfs_delegation *delegation; - int open_mode = opendata->o_arg.open_flags & (O_EXCL|O_TRUNC); + int open_mode = opendata->o_arg.open_flags; fmode_t fmode = opendata->o_arg.fmode; nfs4_stateid stateid; int ret = -EAGAIN; diff --git a/fs/nfs/nfs4session.c b/fs/nfs/nfs4session.c index ebda5f4a031b..c4e225e4a9af 100644 --- a/fs/nfs/nfs4session.c +++ b/fs/nfs/nfs4session.c @@ -73,7 +73,7 @@ void nfs4_free_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *slot) tbl->highest_used_slotid = new_max; else { tbl->highest_used_slotid = NFS4_NO_SLOT; - nfs4_session_drain_complete(tbl->session, tbl); + nfs4_slot_tbl_drain_complete(tbl); } } dprintk("%s: slotid %u highest_used_slotid %d\n", __func__, @@ -226,7 +226,7 @@ static bool nfs41_assign_slot(struct rpc_task *task, void *pslot) struct nfs4_slot *slot = pslot; struct nfs4_slot_table *tbl = slot->table; - if (nfs4_session_draining(tbl->session) && !args->sa_privileged) + if (nfs4_slot_tbl_draining(tbl) && !args->sa_privileged) return false; slot->generation = tbl->generation; args->sa_slot = slot; diff --git a/fs/nfs/nfs4session.h b/fs/nfs/nfs4session.h index 6f3cb39386d4..ff7d9f0f8a65 100644 --- a/fs/nfs/nfs4session.h +++ b/fs/nfs/nfs4session.h @@ -25,6 +25,10 @@ struct nfs4_slot { }; /* Sessions */ +enum nfs4_slot_tbl_state { + NFS4_SLOT_TBL_DRAINING, +}; + #define SLOT_TABLE_SZ DIV_ROUND_UP(NFS4_MAX_SLOT_TABLE, 8*sizeof(long)) struct nfs4_slot_table { struct nfs4_session *session; /* Parent session */ @@ -43,6 +47,7 @@ struct nfs4_slot_table { unsigned long generation; /* Generation counter for target_highest_slotid */ struct completion complete; + unsigned long slot_tbl_state; }; /* @@ -68,7 +73,6 @@ struct nfs4_session { enum nfs4_session_state { NFS4_SESSION_INITING, - NFS4_SESSION_DRAINING, }; #if defined(CONFIG_NFS_V4_1) @@ -88,12 +92,11 @@ extern void nfs4_destroy_session(struct nfs4_session *session); extern int nfs4_init_session(struct nfs_server *server); extern int nfs4_init_ds_session(struct nfs_client *, unsigned long); -extern void nfs4_session_drain_complete(struct nfs4_session *session, - struct nfs4_slot_table *tbl); +extern void nfs4_slot_tbl_drain_complete(struct nfs4_slot_table *tbl); -static inline bool nfs4_session_draining(struct nfs4_session *session) +static inline bool nfs4_slot_tbl_draining(struct nfs4_slot_table *tbl) { - return !!test_bit(NFS4_SESSION_DRAINING, &session->session_state); + return !!test_bit(NFS4_SLOT_TBL_DRAINING, &tbl->slot_tbl_state); } bool nfs41_wake_and_assign_slot(struct nfs4_slot_table *tbl, diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 300d17d85c0e..1fab140764c4 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -241,7 +241,7 @@ static void nfs4_end_drain_session(struct nfs_client *clp) if (ses == NULL) return; tbl = &ses->fc_slot_table; - if (test_and_clear_bit(NFS4_SESSION_DRAINING, &ses->session_state)) { + if (test_and_clear_bit(NFS4_SLOT_TBL_DRAINING, &tbl->slot_tbl_state)) { spin_lock(&tbl->slot_tbl_lock); nfs41_wake_slot_table(tbl); spin_unlock(&tbl->slot_tbl_lock); @@ -251,15 +251,15 @@ static void nfs4_end_drain_session(struct nfs_client *clp) /* * Signal state manager thread if session fore channel is drained */ -void nfs4_session_drain_complete(struct nfs4_session *session, - struct nfs4_slot_table *tbl) +void nfs4_slot_tbl_drain_complete(struct nfs4_slot_table *tbl) { - if (nfs4_session_draining(session)) + if (nfs4_slot_tbl_draining(tbl)) complete(&tbl->complete); } -static int nfs4_wait_on_slot_tbl(struct nfs4_slot_table *tbl) +static int nfs4_drain_slot_tbl(struct nfs4_slot_table *tbl) { + set_bit(NFS4_SLOT_TBL_DRAINING, &tbl->slot_tbl_state); spin_lock(&tbl->slot_tbl_lock); if (tbl->highest_used_slotid != NFS4_NO_SLOT) { INIT_COMPLETION(tbl->complete); @@ -275,13 +275,12 @@ static int nfs4_begin_drain_session(struct nfs_client *clp) struct nfs4_session *ses = clp->cl_session; int ret = 0; - set_bit(NFS4_SESSION_DRAINING, &ses->session_state); /* back channel */ - ret = nfs4_wait_on_slot_tbl(&ses->bc_slot_table); + ret = nfs4_drain_slot_tbl(&ses->bc_slot_table); if (ret) return ret; /* fore channel */ - return nfs4_wait_on_slot_tbl(&ses->fc_slot_table); + return nfs4_drain_slot_tbl(&ses->fc_slot_table); } static void nfs41_finish_session_reset(struct nfs_client *clp) diff --git a/fs/nfs/super.c b/fs/nfs/super.c index a366107a7331..2d7525fbcf25 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -1942,6 +1942,7 @@ static int nfs23_validate_mount_data(void *options, args->namlen = data->namlen; args->bsize = data->bsize; + args->auth_flavors[0] = RPC_AUTH_UNIX; if (data->flags & NFS_MOUNT_SECFLAVOUR) args->auth_flavors[0] = data->pseudoflavor; if (!args->nfs_server.hostname) @@ -2637,6 +2638,7 @@ static int nfs4_validate_mount_data(void *options, goto out_no_address; args->nfs_server.port = ntohs(((struct sockaddr_in *)sap)->sin_port); + args->auth_flavors[0] = RPC_AUTH_UNIX; if (data->auth_flavourlen) { if (data->auth_flavourlen > 1) goto out_inval_auth; diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c index 689fb608648e..bccfec8343c5 100644 --- a/fs/nilfs2/inode.c +++ b/fs/nilfs2/inode.c @@ -219,13 +219,32 @@ static int nilfs_writepage(struct page *page, struct writeback_control *wbc) static int nilfs_set_page_dirty(struct page *page) { - int ret = __set_page_dirty_buffers(page); + int ret = __set_page_dirty_nobuffers(page); - if (ret) { + if (page_has_buffers(page)) { struct inode *inode = page->mapping->host; - unsigned nr_dirty = 1 << (PAGE_SHIFT - inode->i_blkbits); + unsigned nr_dirty = 0; + struct buffer_head *bh, *head; - nilfs_set_file_dirty(inode, nr_dirty); + /* + * This page is locked by callers, and no other thread + * concurrently marks its buffers dirty since they are + * only dirtied through routines in fs/buffer.c in + * which call sites of mark_buffer_dirty are protected + * by page lock. + */ + bh = head = page_buffers(page); + do { + /* Do not mark hole blocks dirty */ + if (buffer_dirty(bh) || !buffer_mapped(bh)) + continue; + + set_buffer_dirty(bh); + nr_dirty++; + } while (bh = bh->b_this_page, bh != head); + + if (nr_dirty) + nilfs_set_file_dirty(inode, nr_dirty); } return ret; } diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c index b3fdd1a323d6..e68588e6b1e8 100644 --- a/fs/ocfs2/dlm/dlmrecovery.c +++ b/fs/ocfs2/dlm/dlmrecovery.c @@ -1408,6 +1408,7 @@ int dlm_mig_lockres_handler(struct o2net_msg *msg, u32 len, void *data, mres->lockname_len, mres->lockname); ret = -EFAULT; spin_unlock(&res->spinlock); + dlm_lockres_put(res); goto leave; } res->state |= DLM_LOCK_RES_MIGRATING; diff --git a/fs/ocfs2/extent_map.c b/fs/ocfs2/extent_map.c index 1c39efb71bab..2487116d0d33 100644 --- a/fs/ocfs2/extent_map.c +++ b/fs/ocfs2/extent_map.c @@ -790,7 +790,7 @@ int ocfs2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, &hole_size, &rec, &is_last); if (ret) { mlog_errno(ret); - goto out; + goto out_unlock; } if (rec.e_blkno == 0ULL) { diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 8a7509f9e6f5..ff54014a24ec 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -2288,7 +2288,7 @@ relock: ret = ocfs2_inode_lock(inode, NULL, 1); if (ret < 0) { mlog_errno(ret); - goto out_sems; + goto out; } ocfs2_inode_unlock(inode, 1); diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index 04ee1b57c243..b4a5cdf9dbc5 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c @@ -947,7 +947,7 @@ leave: ocfs2_free_dir_lookup_result(&orphan_insert); ocfs2_free_dir_lookup_result(&lookup); - if (status) + if (status && (status != -ENOTEMPTY)) mlog_errno(status); return status; @@ -2216,7 +2216,7 @@ out: brelse(orphan_dir_bh); - return 0; + return ret; } int ocfs2_create_inode_in_orphan(struct inode *dir, diff --git a/fs/pnode.c b/fs/pnode.c index 3d2a7141b87a..9af0df15256e 100644 --- a/fs/pnode.c +++ b/fs/pnode.c @@ -83,7 +83,8 @@ static int do_make_slave(struct mount *mnt) if (peer_mnt == mnt) peer_mnt = NULL; } - if (IS_MNT_SHARED(mnt) && list_empty(&mnt->mnt_share)) + if (mnt->mnt_group_id && IS_MNT_SHARED(mnt) && + list_empty(&mnt->mnt_share)) mnt_release_group_id(mnt); list_del_init(&mnt->mnt_share); diff --git a/fs/proc/base.c b/fs/proc/base.c index dd51e50001fe..c3834dad09b3 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -2118,6 +2118,7 @@ static int show_timer(struct seq_file *m, void *v) nstr[notify & ~SIGEV_THREAD_ID], (notify & SIGEV_THREAD_ID) ? "tid" : "pid", pid_nr_ns(timer->it_pid, tp->ns)); + seq_printf(m, "ClockID: %d\n", timer->it_clock); return 0; } diff --git a/fs/proc/kmsg.c b/fs/proc/kmsg.c index bd4b5a740ff1..bdfabdaefdce 100644 --- a/fs/proc/kmsg.c +++ b/fs/proc/kmsg.c @@ -21,12 +21,12 @@ extern wait_queue_head_t log_wait; static int kmsg_open(struct inode * inode, struct file * file) { - return do_syslog(SYSLOG_ACTION_OPEN, NULL, 0, SYSLOG_FROM_FILE); + return do_syslog(SYSLOG_ACTION_OPEN, NULL, 0, SYSLOG_FROM_PROC); } static int kmsg_release(struct inode * inode, struct file * file) { - (void) do_syslog(SYSLOG_ACTION_CLOSE, NULL, 0, SYSLOG_FROM_FILE); + (void) do_syslog(SYSLOG_ACTION_CLOSE, NULL, 0, SYSLOG_FROM_PROC); return 0; } @@ -34,15 +34,15 @@ static ssize_t kmsg_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { if ((file->f_flags & O_NONBLOCK) && - !do_syslog(SYSLOG_ACTION_SIZE_UNREAD, NULL, 0, SYSLOG_FROM_FILE)) + !do_syslog(SYSLOG_ACTION_SIZE_UNREAD, NULL, 0, SYSLOG_FROM_PROC)) return -EAGAIN; - return do_syslog(SYSLOG_ACTION_READ, buf, count, SYSLOG_FROM_FILE); + return do_syslog(SYSLOG_ACTION_READ, buf, count, SYSLOG_FROM_PROC); } static unsigned int kmsg_poll(struct file *file, poll_table *wait) { poll_wait(file, &log_wait, wait); - if (do_syslog(SYSLOG_ACTION_SIZE_UNREAD, NULL, 0, SYSLOG_FROM_FILE)) + if (do_syslog(SYSLOG_ACTION_SIZE_UNREAD, NULL, 0, SYSLOG_FROM_PROC)) return POLLIN | POLLRDNORM; return 0; } diff --git a/fs/qnx6/dir.c b/fs/qnx6/dir.c index 8798d065e400..afa6be6fc397 100644 --- a/fs/qnx6/dir.c +++ b/fs/qnx6/dir.c @@ -120,7 +120,7 @@ static int qnx6_readdir(struct file *filp, void *dirent, filldir_t filldir) struct inode *inode = file_inode(filp); struct super_block *s = inode->i_sb; struct qnx6_sb_info *sbi = QNX6_SB(s); - loff_t pos = filp->f_pos & (QNX6_DIR_ENTRY_SIZE - 1); + loff_t pos = filp->f_pos & ~(QNX6_DIR_ENTRY_SIZE - 1); unsigned long npages = dir_pages(inode); unsigned long n = pos >> PAGE_CACHE_SHIFT; unsigned start = (pos & ~PAGE_CACHE_MASK) / QNX6_DIR_ENTRY_SIZE; diff --git a/fs/read_write.c b/fs/read_write.c index 03430008704e..2cefa417be34 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -1064,6 +1064,7 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, struct fd in, out; struct inode *in_inode, *out_inode; loff_t pos; + loff_t out_pos; ssize_t retval; int fl; @@ -1077,12 +1078,14 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, if (!(in.file->f_mode & FMODE_READ)) goto fput_in; retval = -ESPIPE; - if (!ppos) - ppos = &in.file->f_pos; - else + if (!ppos) { + pos = in.file->f_pos; + } else { + pos = *ppos; if (!(in.file->f_mode & FMODE_PREAD)) goto fput_in; - retval = rw_verify_area(READ, in.file, ppos, count); + } + retval = rw_verify_area(READ, in.file, &pos, count); if (retval < 0) goto fput_in; count = retval; @@ -1099,7 +1102,8 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, retval = -EINVAL; in_inode = file_inode(in.file); out_inode = file_inode(out.file); - retval = rw_verify_area(WRITE, out.file, &out.file->f_pos, count); + out_pos = out.file->f_pos; + retval = rw_verify_area(WRITE, out.file, &out_pos, count); if (retval < 0) goto fput_out; count = retval; @@ -1107,7 +1111,6 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, if (!max) max = min(in_inode->i_sb->s_maxbytes, out_inode->i_sb->s_maxbytes); - pos = *ppos; if (unlikely(pos + count > max)) { retval = -EOVERFLOW; if (pos >= max) @@ -1126,18 +1129,23 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, if (in.file->f_flags & O_NONBLOCK) fl = SPLICE_F_NONBLOCK; #endif - retval = do_splice_direct(in.file, ppos, out.file, count, fl); + retval = do_splice_direct(in.file, &pos, out.file, &out_pos, count, fl); if (retval > 0) { add_rchar(current, retval); add_wchar(current, retval); fsnotify_access(in.file); fsnotify_modify(out.file); + out.file->f_pos = out_pos; + if (ppos) + *ppos = pos; + else + in.file->f_pos = pos; } inc_syscr(current); inc_syscw(current); - if (*ppos > max) + if (pos > max) retval = -EOVERFLOW; fput_out: diff --git a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c index 66c53b642a88..6c2d136561cb 100644 --- a/fs/reiserfs/dir.c +++ b/fs/reiserfs/dir.c @@ -204,6 +204,8 @@ int reiserfs_readdir_dentry(struct dentry *dentry, void *dirent, next_pos = deh_offset(deh) + 1; if (item_moved(&tmp_ih, &path_to_entry)) { + set_cpu_key_k_offset(&pos_key, + next_pos); goto research; } } /* for */ diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 77d6d47abc83..f844533792ee 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c @@ -1811,11 +1811,16 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, TYPE_STAT_DATA, SD_SIZE, MAX_US_INT); memcpy(INODE_PKEY(inode), &(ih.ih_key), KEY_SIZE); args.dirid = le32_to_cpu(ih.ih_key.k_dir_id); - if (insert_inode_locked4(inode, args.objectid, - reiserfs_find_actor, &args) < 0) { + + reiserfs_write_unlock(inode->i_sb); + err = insert_inode_locked4(inode, args.objectid, + reiserfs_find_actor, &args); + reiserfs_write_lock(inode->i_sb); + if (err) { err = -EINVAL; goto out_bad_inode; } + if (old_format_only(sb)) /* not a perfect generation count, as object ids can be reused, but ** this is as good as reiserfs can do right now. diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index 4cce1d9552fb..821bcf70e467 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c @@ -318,7 +318,19 @@ static int delete_one_xattr(struct dentry *dentry, void *data) static int chown_one_xattr(struct dentry *dentry, void *data) { struct iattr *attrs = data; - return reiserfs_setattr(dentry, attrs); + int ia_valid = attrs->ia_valid; + int err; + + /* + * We only want the ownership bits. Otherwise, we'll do + * things like change a directory to a regular file if + * ATTR_MODE is set. + */ + attrs->ia_valid &= (ATTR_UID|ATTR_GID); + err = reiserfs_setattr(dentry, attrs); + attrs->ia_valid = ia_valid; + + return err; } /* No i_mutex, but the inode is unconnected. */ diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c index d7c01ef64eda..6c8767fdfc6a 100644 --- a/fs/reiserfs/xattr_acl.c +++ b/fs/reiserfs/xattr_acl.c @@ -443,6 +443,9 @@ int reiserfs_acl_chmod(struct inode *inode) int depth; int error; + if (IS_PRIVATE(inode)) + return 0; + if (S_ISLNK(inode->i_mode)) return -EOPNOTSUPP; diff --git a/fs/splice.c b/fs/splice.c index e6b25598c8c4..9eca476227d5 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -1274,7 +1274,7 @@ static int direct_splice_actor(struct pipe_inode_info *pipe, { struct file *file = sd->u.file; - return do_splice_from(pipe, file, &file->f_pos, sd->total_len, + return do_splice_from(pipe, file, sd->opos, sd->total_len, sd->flags); } @@ -1294,7 +1294,7 @@ static int direct_splice_actor(struct pipe_inode_info *pipe, * */ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, - size_t len, unsigned int flags) + loff_t *opos, size_t len, unsigned int flags) { struct splice_desc sd = { .len = len, @@ -1302,6 +1302,7 @@ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, .flags = flags, .pos = *ppos, .u.file = out, + .opos = opos, }; long ret; @@ -1325,7 +1326,7 @@ static long do_splice(struct file *in, loff_t __user *off_in, { struct pipe_inode_info *ipipe; struct pipe_inode_info *opipe; - loff_t offset, *off; + loff_t offset; long ret; ipipe = get_pipe_info(in); @@ -1356,13 +1357,15 @@ static long do_splice(struct file *in, loff_t __user *off_in, return -EINVAL; if (copy_from_user(&offset, off_out, sizeof(loff_t))) return -EFAULT; - off = &offset; - } else - off = &out->f_pos; + } else { + offset = out->f_pos; + } - ret = do_splice_from(ipipe, out, off, len, flags); + ret = do_splice_from(ipipe, out, &offset, len, flags); - if (off_out && copy_to_user(off_out, off, sizeof(loff_t))) + if (!off_out) + out->f_pos = offset; + else if (copy_to_user(off_out, &offset, sizeof(loff_t))) ret = -EFAULT; return ret; @@ -1376,13 +1379,15 @@ static long do_splice(struct file *in, loff_t __user *off_in, return -EINVAL; if (copy_from_user(&offset, off_in, sizeof(loff_t))) return -EFAULT; - off = &offset; - } else - off = &in->f_pos; + } else { + offset = in->f_pos; + } - ret = do_splice_to(in, off, opipe, len, flags); + ret = do_splice_to(in, &offset, opipe, len, flags); - if (off_in && copy_to_user(off_in, off, sizeof(loff_t))) + if (!off_in) + in->f_pos = offset; + else if (copy_to_user(off_in, &offset, sizeof(loff_t))) ret = -EFAULT; return ret; diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c index 1d32f1d52763..306d883d89bc 100644 --- a/fs/xfs/xfs_acl.c +++ b/fs/xfs/xfs_acl.c @@ -21,6 +21,8 @@ #include "xfs_bmap_btree.h" #include "xfs_inode.h" #include "xfs_vnodeops.h" +#include "xfs_sb.h" +#include "xfs_mount.h" #include "xfs_trace.h" #include <linux/slab.h> #include <linux/xattr.h> @@ -34,7 +36,9 @@ */ STATIC struct posix_acl * -xfs_acl_from_disk(struct xfs_acl *aclp) +xfs_acl_from_disk( + struct xfs_acl *aclp, + int max_entries) { struct posix_acl_entry *acl_e; struct posix_acl *acl; @@ -42,7 +46,7 @@ xfs_acl_from_disk(struct xfs_acl *aclp) unsigned int count, i; count = be32_to_cpu(aclp->acl_cnt); - if (count > XFS_ACL_MAX_ENTRIES) + if (count > max_entries) return ERR_PTR(-EFSCORRUPTED); acl = posix_acl_alloc(count, GFP_KERNEL); @@ -108,9 +112,9 @@ xfs_get_acl(struct inode *inode, int type) struct xfs_inode *ip = XFS_I(inode); struct posix_acl *acl; struct xfs_acl *xfs_acl; - int len = sizeof(struct xfs_acl); unsigned char *ea_name; int error; + int len; acl = get_cached_acl(inode, type); if (acl != ACL_NOT_CACHED) @@ -133,8 +137,8 @@ xfs_get_acl(struct inode *inode, int type) * If we have a cached ACLs value just return it, not need to * go out to the disk. */ - - xfs_acl = kzalloc(sizeof(struct xfs_acl), GFP_KERNEL); + len = XFS_ACL_MAX_SIZE(ip->i_mount); + xfs_acl = kzalloc(len, GFP_KERNEL); if (!xfs_acl) return ERR_PTR(-ENOMEM); @@ -153,7 +157,7 @@ xfs_get_acl(struct inode *inode, int type) goto out; } - acl = xfs_acl_from_disk(xfs_acl); + acl = xfs_acl_from_disk(xfs_acl, XFS_ACL_MAX_ENTRIES(ip->i_mount)); if (IS_ERR(acl)) goto out; @@ -189,16 +193,17 @@ xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl) if (acl) { struct xfs_acl *xfs_acl; - int len; + int len = XFS_ACL_MAX_SIZE(ip->i_mount); - xfs_acl = kzalloc(sizeof(struct xfs_acl), GFP_KERNEL); + xfs_acl = kzalloc(len, GFP_KERNEL); if (!xfs_acl) return -ENOMEM; xfs_acl_to_disk(xfs_acl, acl); - len = sizeof(struct xfs_acl) - - (sizeof(struct xfs_acl_entry) * - (XFS_ACL_MAX_ENTRIES - acl->a_count)); + + /* subtract away the unused acl entries */ + len -= sizeof(struct xfs_acl_entry) * + (XFS_ACL_MAX_ENTRIES(ip->i_mount) - acl->a_count); error = -xfs_attr_set(ip, ea_name, (unsigned char *)xfs_acl, len, ATTR_ROOT); @@ -243,7 +248,7 @@ xfs_set_mode(struct inode *inode, umode_t mode) static int xfs_acl_exists(struct inode *inode, unsigned char *name) { - int len = sizeof(struct xfs_acl); + int len = XFS_ACL_MAX_SIZE(XFS_M(inode->i_sb)); return (xfs_attr_get(XFS_I(inode), name, NULL, &len, ATTR_ROOT|ATTR_KERNOVAL) == 0); @@ -379,7 +384,7 @@ xfs_xattr_acl_set(struct dentry *dentry, const char *name, goto out_release; error = -EINVAL; - if (acl->a_count > XFS_ACL_MAX_ENTRIES) + if (acl->a_count > XFS_ACL_MAX_ENTRIES(XFS_M(inode->i_sb))) goto out_release; if (type == ACL_TYPE_ACCESS) { diff --git a/fs/xfs/xfs_acl.h b/fs/xfs/xfs_acl.h index 39632d941354..4016a567b83c 100644 --- a/fs/xfs/xfs_acl.h +++ b/fs/xfs/xfs_acl.h @@ -22,19 +22,36 @@ struct inode; struct posix_acl; struct xfs_inode; -#define XFS_ACL_MAX_ENTRIES 25 #define XFS_ACL_NOT_PRESENT (-1) /* On-disk XFS access control list structure */ +struct xfs_acl_entry { + __be32 ae_tag; + __be32 ae_id; + __be16 ae_perm; + __be16 ae_pad; /* fill the implicit hole in the structure */ +}; + struct xfs_acl { - __be32 acl_cnt; - struct xfs_acl_entry { - __be32 ae_tag; - __be32 ae_id; - __be16 ae_perm; - } acl_entry[XFS_ACL_MAX_ENTRIES]; + __be32 acl_cnt; + struct xfs_acl_entry acl_entry[0]; }; +/* + * The number of ACL entries allowed is defined by the on-disk format. + * For v4 superblocks, that is limited to 25 entries. For v5 superblocks, it is + * limited only by the maximum size of the xattr that stores the information. + */ +#define XFS_ACL_MAX_ENTRIES(mp) \ + (xfs_sb_version_hascrc(&mp->m_sb) \ + ? (XATTR_SIZE_MAX - sizeof(struct xfs_acl)) / \ + sizeof(struct xfs_acl_entry) \ + : 25) + +#define XFS_ACL_MAX_SIZE(mp) \ + (sizeof(struct xfs_acl) + \ + sizeof(struct xfs_acl_entry) * XFS_ACL_MAX_ENTRIES((mp))) + /* On-disk XFS extended attribute names */ #define SGI_ACL_FILE (unsigned char *)"SGI_ACL_FILE" #define SGI_ACL_DEFAULT (unsigned char *)"SGI_ACL_DEFAULT" diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 2b2691b73428..41a695048be7 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -725,6 +725,25 @@ xfs_convert_page( (xfs_off_t)(page->index + 1) << PAGE_CACHE_SHIFT, i_size_read(inode)); + /* + * If the current map does not span the entire page we are about to try + * to write, then give up. The only way we can write a page that spans + * multiple mappings in a single writeback iteration is via the + * xfs_vm_writepage() function. Data integrity writeback requires the + * entire page to be written in a single attempt, otherwise the part of + * the page we don't write here doesn't get written as part of the data + * integrity sync. + * + * For normal writeback, we also don't attempt to write partial pages + * here as it simply means that write_cache_pages() will see it under + * writeback and ignore the page until some point in the future, at + * which time this will be the only page in the file that needs + * writeback. Hence for more optimal IO patterns, we should always + * avoid partial page writeback due to multiple mappings on a page here. + */ + if (!xfs_imap_valid(inode, imap, end_offset)) + goto fail_unlock_page; + len = 1 << inode->i_blkbits; p_offset = min_t(unsigned long, end_offset & (PAGE_CACHE_SIZE - 1), PAGE_CACHE_SIZE); diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c index 08d5457c948e..31d3cd129269 100644 --- a/fs/xfs/xfs_attr_leaf.c +++ b/fs/xfs/xfs_attr_leaf.c @@ -931,20 +931,22 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context) */ int xfs_attr_shortform_allfit( - struct xfs_buf *bp, - struct xfs_inode *dp) + struct xfs_buf *bp, + struct xfs_inode *dp) { - xfs_attr_leafblock_t *leaf; - xfs_attr_leaf_entry_t *entry; + struct xfs_attr_leafblock *leaf; + struct xfs_attr_leaf_entry *entry; xfs_attr_leaf_name_local_t *name_loc; - int bytes, i; + struct xfs_attr3_icleaf_hdr leafhdr; + int bytes; + int i; leaf = bp->b_addr; - ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); + xfs_attr3_leaf_hdr_from_disk(&leafhdr, leaf); + entry = xfs_attr3_leaf_entryp(leaf); - entry = &leaf->entries[0]; bytes = sizeof(struct xfs_attr_sf_hdr); - for (i = 0; i < be16_to_cpu(leaf->hdr.count); entry++, i++) { + for (i = 0; i < leafhdr.count; entry++, i++) { if (entry->flags & XFS_ATTR_INCOMPLETE) continue; /* don't copy partial entries */ if (!(entry->flags & XFS_ATTR_LOCAL)) @@ -954,15 +956,15 @@ xfs_attr_shortform_allfit( return(0); if (be16_to_cpu(name_loc->valuelen) >= XFS_ATTR_SF_ENTSIZE_MAX) return(0); - bytes += sizeof(struct xfs_attr_sf_entry)-1 + bytes += sizeof(struct xfs_attr_sf_entry) - 1 + name_loc->namelen + be16_to_cpu(name_loc->valuelen); } if ((dp->i_mount->m_flags & XFS_MOUNT_ATTR2) && (dp->i_d.di_format != XFS_DINODE_FMT_BTREE) && (bytes == sizeof(struct xfs_attr_sf_hdr))) - return(-1); - return(xfs_attr_shortform_bytesfit(dp, bytes)); + return -1; + return xfs_attr_shortform_bytesfit(dp, bytes); } /* @@ -1410,7 +1412,7 @@ xfs_attr3_leaf_add_work( name_rmt->valuelen = 0; name_rmt->valueblk = 0; args->rmtblkno = 1; - args->rmtblkcnt = XFS_B_TO_FSB(mp, args->valuelen); + args->rmtblkcnt = xfs_attr3_rmt_blocks(mp, args->valuelen); } xfs_trans_log_buf(args->trans, bp, XFS_DA_LOGRANGE(leaf, xfs_attr3_leaf_name(leaf, args->index), @@ -1443,11 +1445,12 @@ xfs_attr3_leaf_add_work( STATIC void xfs_attr3_leaf_compact( struct xfs_da_args *args, - struct xfs_attr3_icleaf_hdr *ichdr_d, + struct xfs_attr3_icleaf_hdr *ichdr_dst, struct xfs_buf *bp) { - xfs_attr_leafblock_t *leaf_s, *leaf_d; - struct xfs_attr3_icleaf_hdr ichdr_s; + struct xfs_attr_leafblock *leaf_src; + struct xfs_attr_leafblock *leaf_dst; + struct xfs_attr3_icleaf_hdr ichdr_src; struct xfs_trans *trans = args->trans; struct xfs_mount *mp = trans->t_mountp; char *tmpbuffer; @@ -1455,29 +1458,38 @@ xfs_attr3_leaf_compact( trace_xfs_attr_leaf_compact(args); tmpbuffer = kmem_alloc(XFS_LBSIZE(mp), KM_SLEEP); - ASSERT(tmpbuffer != NULL); memcpy(tmpbuffer, bp->b_addr, XFS_LBSIZE(mp)); memset(bp->b_addr, 0, XFS_LBSIZE(mp)); + leaf_src = (xfs_attr_leafblock_t *)tmpbuffer; + leaf_dst = bp->b_addr; /* - * Copy basic information + * Copy the on-disk header back into the destination buffer to ensure + * all the information in the header that is not part of the incore + * header structure is preserved. */ - leaf_s = (xfs_attr_leafblock_t *)tmpbuffer; - leaf_d = bp->b_addr; - ichdr_s = *ichdr_d; /* struct copy */ - ichdr_d->firstused = XFS_LBSIZE(mp); - ichdr_d->usedbytes = 0; - ichdr_d->count = 0; - ichdr_d->holes = 0; - ichdr_d->freemap[0].base = xfs_attr3_leaf_hdr_size(leaf_s); - ichdr_d->freemap[0].size = ichdr_d->firstused - ichdr_d->freemap[0].base; + memcpy(bp->b_addr, tmpbuffer, xfs_attr3_leaf_hdr_size(leaf_src)); + + /* Initialise the incore headers */ + ichdr_src = *ichdr_dst; /* struct copy */ + ichdr_dst->firstused = XFS_LBSIZE(mp); + ichdr_dst->usedbytes = 0; + ichdr_dst->count = 0; + ichdr_dst->holes = 0; + ichdr_dst->freemap[0].base = xfs_attr3_leaf_hdr_size(leaf_src); + ichdr_dst->freemap[0].size = ichdr_dst->firstused - + ichdr_dst->freemap[0].base; + + + /* write the header back to initialise the underlying buffer */ + xfs_attr3_leaf_hdr_to_disk(leaf_dst, ichdr_dst); /* * Copy all entry's in the same (sorted) order, * but allocate name/value pairs packed and in sequence. */ - xfs_attr3_leaf_moveents(leaf_s, &ichdr_s, 0, leaf_d, ichdr_d, 0, - ichdr_s.count, mp); + xfs_attr3_leaf_moveents(leaf_src, &ichdr_src, 0, leaf_dst, ichdr_dst, 0, + ichdr_src.count, mp); /* * this logs the entire buffer, but the caller must write the header * back to the buffer when it is finished modifying it. @@ -2179,14 +2191,24 @@ xfs_attr3_leaf_unbalance( struct xfs_attr_leafblock *tmp_leaf; struct xfs_attr3_icleaf_hdr tmphdr; - tmp_leaf = kmem_alloc(state->blocksize, KM_SLEEP); - memset(tmp_leaf, 0, state->blocksize); - memset(&tmphdr, 0, sizeof(tmphdr)); + tmp_leaf = kmem_zalloc(state->blocksize, KM_SLEEP); + + /* + * Copy the header into the temp leaf so that all the stuff + * not in the incore header is present and gets copied back in + * once we've moved all the entries. + */ + memcpy(tmp_leaf, save_leaf, xfs_attr3_leaf_hdr_size(save_leaf)); + memset(&tmphdr, 0, sizeof(tmphdr)); tmphdr.magic = savehdr.magic; tmphdr.forw = savehdr.forw; tmphdr.back = savehdr.back; tmphdr.firstused = state->blocksize; + + /* write the header to the temp buffer to initialise it */ + xfs_attr3_leaf_hdr_to_disk(tmp_leaf, &tmphdr); + if (xfs_attr3_leaf_order(save_blk->bp, &savehdr, drop_blk->bp, &drophdr)) { xfs_attr3_leaf_moveents(drop_leaf, &drophdr, 0, @@ -2330,9 +2352,11 @@ xfs_attr3_leaf_lookup_int( if (!xfs_attr_namesp_match(args->flags, entry->flags)) continue; args->index = probe; + args->valuelen = be32_to_cpu(name_rmt->valuelen); args->rmtblkno = be32_to_cpu(name_rmt->valueblk); - args->rmtblkcnt = XFS_B_TO_FSB(args->dp->i_mount, - be32_to_cpu(name_rmt->valuelen)); + args->rmtblkcnt = xfs_attr3_rmt_blocks( + args->dp->i_mount, + args->valuelen); return XFS_ERROR(EEXIST); } } @@ -2383,7 +2407,8 @@ xfs_attr3_leaf_getvalue( ASSERT(memcmp(args->name, name_rmt->name, args->namelen) == 0); valuelen = be32_to_cpu(name_rmt->valuelen); args->rmtblkno = be32_to_cpu(name_rmt->valueblk); - args->rmtblkcnt = XFS_B_TO_FSB(args->dp->i_mount, valuelen); + args->rmtblkcnt = xfs_attr3_rmt_blocks(args->dp->i_mount, + valuelen); if (args->flags & ATTR_KERNOVAL) { args->valuelen = valuelen; return 0; @@ -2709,7 +2734,8 @@ xfs_attr3_leaf_list_int( args.valuelen = valuelen; args.value = kmem_alloc(valuelen, KM_SLEEP | KM_NOFS); args.rmtblkno = be32_to_cpu(name_rmt->valueblk); - args.rmtblkcnt = XFS_B_TO_FSB(args.dp->i_mount, valuelen); + args.rmtblkcnt = xfs_attr3_rmt_blocks( + args.dp->i_mount, valuelen); retval = xfs_attr_rmtval_get(&args); if (retval) return retval; @@ -3232,7 +3258,7 @@ xfs_attr3_leaf_inactive( name_rmt = xfs_attr3_leaf_name_remote(leaf, i); if (name_rmt->valueblk) { lp->valueblk = be32_to_cpu(name_rmt->valueblk); - lp->valuelen = XFS_B_TO_FSB(dp->i_mount, + lp->valuelen = xfs_attr3_rmt_blocks(dp->i_mount, be32_to_cpu(name_rmt->valuelen)); lp++; } diff --git a/fs/xfs/xfs_attr_leaf.h b/fs/xfs/xfs_attr_leaf.h index f9d7846097e2..444a7704596c 100644 --- a/fs/xfs/xfs_attr_leaf.h +++ b/fs/xfs/xfs_attr_leaf.h @@ -128,6 +128,7 @@ struct xfs_attr3_leaf_hdr { __u8 holes; __u8 pad1; struct xfs_attr_leaf_map freemap[XFS_ATTR_LEAF_MAPSIZE]; + __be32 pad2; /* 64 bit alignment */ }; #define XFS_ATTR3_LEAF_CRC_OFF (offsetof(struct xfs_attr3_leaf_hdr, info.crc)) diff --git a/fs/xfs/xfs_attr_remote.c b/fs/xfs/xfs_attr_remote.c index dee84466dcc9..ef6b0c124528 100644 --- a/fs/xfs/xfs_attr_remote.c +++ b/fs/xfs/xfs_attr_remote.c @@ -47,22 +47,55 @@ * Each contiguous block has a header, so it is not just a simple attribute * length to FSB conversion. */ -static int +int xfs_attr3_rmt_blocks( struct xfs_mount *mp, int attrlen) { - int buflen = XFS_ATTR3_RMT_BUF_SPACE(mp, - mp->m_sb.sb_blocksize); - return (attrlen + buflen - 1) / buflen; + if (xfs_sb_version_hascrc(&mp->m_sb)) { + int buflen = XFS_ATTR3_RMT_BUF_SPACE(mp, mp->m_sb.sb_blocksize); + return (attrlen + buflen - 1) / buflen; + } + return XFS_B_TO_FSB(mp, attrlen); +} + +/* + * Checking of the remote attribute header is split into two parts. The verifier + * does CRC, location and bounds checking, the unpacking function checks the + * attribute parameters and owner. + */ +static bool +xfs_attr3_rmt_hdr_ok( + struct xfs_mount *mp, + void *ptr, + xfs_ino_t ino, + uint32_t offset, + uint32_t size, + xfs_daddr_t bno) +{ + struct xfs_attr3_rmt_hdr *rmt = ptr; + + if (bno != be64_to_cpu(rmt->rm_blkno)) + return false; + if (offset != be32_to_cpu(rmt->rm_offset)) + return false; + if (size != be32_to_cpu(rmt->rm_bytes)) + return false; + if (ino != be64_to_cpu(rmt->rm_owner)) + return false; + + /* ok */ + return true; } static bool xfs_attr3_rmt_verify( - struct xfs_buf *bp) + struct xfs_mount *mp, + void *ptr, + int fsbsize, + xfs_daddr_t bno) { - struct xfs_mount *mp = bp->b_target->bt_mount; - struct xfs_attr3_rmt_hdr *rmt = bp->b_addr; + struct xfs_attr3_rmt_hdr *rmt = ptr; if (!xfs_sb_version_hascrc(&mp->m_sb)) return false; @@ -70,7 +103,9 @@ xfs_attr3_rmt_verify( return false; if (!uuid_equal(&rmt->rm_uuid, &mp->m_sb.sb_uuid)) return false; - if (bp->b_bn != be64_to_cpu(rmt->rm_blkno)) + if (be64_to_cpu(rmt->rm_blkno) != bno) + return false; + if (be32_to_cpu(rmt->rm_bytes) > fsbsize - sizeof(*rmt)) return false; if (be32_to_cpu(rmt->rm_offset) + be32_to_cpu(rmt->rm_bytes) >= XATTR_SIZE_MAX) @@ -86,17 +121,40 @@ xfs_attr3_rmt_read_verify( struct xfs_buf *bp) { struct xfs_mount *mp = bp->b_target->bt_mount; + char *ptr; + int len; + bool corrupt = false; + xfs_daddr_t bno; /* no verification of non-crc buffers */ if (!xfs_sb_version_hascrc(&mp->m_sb)) return; - if (!xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length), - XFS_ATTR3_RMT_CRC_OFF) || - !xfs_attr3_rmt_verify(bp)) { + ptr = bp->b_addr; + bno = bp->b_bn; + len = BBTOB(bp->b_length); + ASSERT(len >= XFS_LBSIZE(mp)); + + while (len > 0) { + if (!xfs_verify_cksum(ptr, XFS_LBSIZE(mp), + XFS_ATTR3_RMT_CRC_OFF)) { + corrupt = true; + break; + } + if (!xfs_attr3_rmt_verify(mp, ptr, XFS_LBSIZE(mp), bno)) { + corrupt = true; + break; + } + len -= XFS_LBSIZE(mp); + ptr += XFS_LBSIZE(mp); + bno += mp->m_bsize; + } + + if (corrupt) { XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr); xfs_buf_ioerror(bp, EFSCORRUPTED); - } + } else + ASSERT(len == 0); } static void @@ -105,23 +163,39 @@ xfs_attr3_rmt_write_verify( { struct xfs_mount *mp = bp->b_target->bt_mount; struct xfs_buf_log_item *bip = bp->b_fspriv; + char *ptr; + int len; + xfs_daddr_t bno; /* no verification of non-crc buffers */ if (!xfs_sb_version_hascrc(&mp->m_sb)) return; - if (!xfs_attr3_rmt_verify(bp)) { - XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr); - xfs_buf_ioerror(bp, EFSCORRUPTED); - return; - } + ptr = bp->b_addr; + bno = bp->b_bn; + len = BBTOB(bp->b_length); + ASSERT(len >= XFS_LBSIZE(mp)); + + while (len > 0) { + if (!xfs_attr3_rmt_verify(mp, ptr, XFS_LBSIZE(mp), bno)) { + XFS_CORRUPTION_ERROR(__func__, + XFS_ERRLEVEL_LOW, mp, bp->b_addr); + xfs_buf_ioerror(bp, EFSCORRUPTED); + return; + } + if (bip) { + struct xfs_attr3_rmt_hdr *rmt; + + rmt = (struct xfs_attr3_rmt_hdr *)ptr; + rmt->rm_lsn = cpu_to_be64(bip->bli_item.li_lsn); + } + xfs_update_cksum(ptr, XFS_LBSIZE(mp), XFS_ATTR3_RMT_CRC_OFF); - if (bip) { - struct xfs_attr3_rmt_hdr *rmt = bp->b_addr; - rmt->rm_lsn = cpu_to_be64(bip->bli_item.li_lsn); + len -= XFS_LBSIZE(mp); + ptr += XFS_LBSIZE(mp); + bno += mp->m_bsize; } - xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length), - XFS_ATTR3_RMT_CRC_OFF); + ASSERT(len == 0); } const struct xfs_buf_ops xfs_attr3_rmt_buf_ops = { @@ -129,15 +203,16 @@ const struct xfs_buf_ops xfs_attr3_rmt_buf_ops = { .verify_write = xfs_attr3_rmt_write_verify, }; -static int +STATIC int xfs_attr3_rmt_hdr_set( struct xfs_mount *mp, + void *ptr, xfs_ino_t ino, uint32_t offset, uint32_t size, - struct xfs_buf *bp) + xfs_daddr_t bno) { - struct xfs_attr3_rmt_hdr *rmt = bp->b_addr; + struct xfs_attr3_rmt_hdr *rmt = ptr; if (!xfs_sb_version_hascrc(&mp->m_sb)) return 0; @@ -147,36 +222,107 @@ xfs_attr3_rmt_hdr_set( rmt->rm_bytes = cpu_to_be32(size); uuid_copy(&rmt->rm_uuid, &mp->m_sb.sb_uuid); rmt->rm_owner = cpu_to_be64(ino); - rmt->rm_blkno = cpu_to_be64(bp->b_bn); - bp->b_ops = &xfs_attr3_rmt_buf_ops; + rmt->rm_blkno = cpu_to_be64(bno); return sizeof(struct xfs_attr3_rmt_hdr); } /* - * Checking of the remote attribute header is split into two parts. the verifier - * does CRC, location and bounds checking, the unpacking function checks the - * attribute parameters and owner. + * Helper functions to copy attribute data in and out of the one disk extents */ -static bool -xfs_attr3_rmt_hdr_ok( - struct xfs_mount *mp, - xfs_ino_t ino, - uint32_t offset, - uint32_t size, - struct xfs_buf *bp) +STATIC int +xfs_attr_rmtval_copyout( + struct xfs_mount *mp, + struct xfs_buf *bp, + xfs_ino_t ino, + int *offset, + int *valuelen, + char **dst) { - struct xfs_attr3_rmt_hdr *rmt = bp->b_addr; + char *src = bp->b_addr; + xfs_daddr_t bno = bp->b_bn; + int len = BBTOB(bp->b_length); - if (offset != be32_to_cpu(rmt->rm_offset)) - return false; - if (size != be32_to_cpu(rmt->rm_bytes)) - return false; - if (ino != be64_to_cpu(rmt->rm_owner)) - return false; + ASSERT(len >= XFS_LBSIZE(mp)); - /* ok */ - return true; + while (len > 0 && *valuelen > 0) { + int hdr_size = 0; + int byte_cnt = XFS_ATTR3_RMT_BUF_SPACE(mp, XFS_LBSIZE(mp)); + + byte_cnt = min_t(int, *valuelen, byte_cnt); + + if (xfs_sb_version_hascrc(&mp->m_sb)) { + if (!xfs_attr3_rmt_hdr_ok(mp, src, ino, *offset, + byte_cnt, bno)) { + xfs_alert(mp, +"remote attribute header mismatch bno/off/len/owner (0x%llx/0x%x/Ox%x/0x%llx)", + bno, *offset, byte_cnt, ino); + return EFSCORRUPTED; + } + hdr_size = sizeof(struct xfs_attr3_rmt_hdr); + } + + memcpy(*dst, src + hdr_size, byte_cnt); + + /* roll buffer forwards */ + len -= XFS_LBSIZE(mp); + src += XFS_LBSIZE(mp); + bno += mp->m_bsize; + + /* roll attribute data forwards */ + *valuelen -= byte_cnt; + *dst += byte_cnt; + *offset += byte_cnt; + } + return 0; +} + +STATIC void +xfs_attr_rmtval_copyin( + struct xfs_mount *mp, + struct xfs_buf *bp, + xfs_ino_t ino, + int *offset, + int *valuelen, + char **src) +{ + char *dst = bp->b_addr; + xfs_daddr_t bno = bp->b_bn; + int len = BBTOB(bp->b_length); + + ASSERT(len >= XFS_LBSIZE(mp)); + + while (len > 0 && *valuelen > 0) { + int hdr_size; + int byte_cnt = XFS_ATTR3_RMT_BUF_SPACE(mp, XFS_LBSIZE(mp)); + + byte_cnt = min(*valuelen, byte_cnt); + hdr_size = xfs_attr3_rmt_hdr_set(mp, dst, ino, *offset, + byte_cnt, bno); + + memcpy(dst + hdr_size, *src, byte_cnt); + + /* + * If this is the last block, zero the remainder of it. + * Check that we are actually the last block, too. + */ + if (byte_cnt + hdr_size < XFS_LBSIZE(mp)) { + ASSERT(*valuelen - byte_cnt == 0); + ASSERT(len == XFS_LBSIZE(mp)); + memset(dst + hdr_size + byte_cnt, 0, + XFS_LBSIZE(mp) - hdr_size - byte_cnt); + } + + /* roll buffer forwards */ + len -= XFS_LBSIZE(mp); + dst += XFS_LBSIZE(mp); + bno += mp->m_bsize; + + /* roll attribute data forwards */ + *valuelen -= byte_cnt; + *src += byte_cnt; + *offset += byte_cnt; + } } /* @@ -190,13 +336,12 @@ xfs_attr_rmtval_get( struct xfs_bmbt_irec map[ATTR_RMTVALUE_MAPSIZE]; struct xfs_mount *mp = args->dp->i_mount; struct xfs_buf *bp; - xfs_daddr_t dblkno; xfs_dablk_t lblkno = args->rmtblkno; - void *dst = args->value; + char *dst = args->value; int valuelen = args->valuelen; int nmap; int error; - int blkcnt; + int blkcnt = args->rmtblkcnt; int i; int offset = 0; @@ -207,52 +352,36 @@ xfs_attr_rmtval_get( while (valuelen > 0) { nmap = ATTR_RMTVALUE_MAPSIZE; error = xfs_bmapi_read(args->dp, (xfs_fileoff_t)lblkno, - args->rmtblkcnt, map, &nmap, + blkcnt, map, &nmap, XFS_BMAPI_ATTRFORK); if (error) return error; ASSERT(nmap >= 1); for (i = 0; (i < nmap) && (valuelen > 0); i++) { - int byte_cnt; - char *src; + xfs_daddr_t dblkno; + int dblkcnt; ASSERT((map[i].br_startblock != DELAYSTARTBLOCK) && (map[i].br_startblock != HOLESTARTBLOCK)); dblkno = XFS_FSB_TO_DADDR(mp, map[i].br_startblock); - blkcnt = XFS_FSB_TO_BB(mp, map[i].br_blockcount); + dblkcnt = XFS_FSB_TO_BB(mp, map[i].br_blockcount); error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp, - dblkno, blkcnt, 0, &bp, + dblkno, dblkcnt, 0, &bp, &xfs_attr3_rmt_buf_ops); if (error) return error; - byte_cnt = min_t(int, valuelen, BBTOB(bp->b_length)); - byte_cnt = XFS_ATTR3_RMT_BUF_SPACE(mp, byte_cnt); - - src = bp->b_addr; - if (xfs_sb_version_hascrc(&mp->m_sb)) { - if (!xfs_attr3_rmt_hdr_ok(mp, args->dp->i_ino, - offset, byte_cnt, bp)) { - xfs_alert(mp, -"remote attribute header does not match required off/len/owner (0x%x/Ox%x,0x%llx)", - offset, byte_cnt, args->dp->i_ino); - xfs_buf_relse(bp); - return EFSCORRUPTED; - - } - - src += sizeof(struct xfs_attr3_rmt_hdr); - } - - memcpy(dst, src, byte_cnt); + error = xfs_attr_rmtval_copyout(mp, bp, args->dp->i_ino, + &offset, &valuelen, + &dst); xfs_buf_relse(bp); + if (error) + return error; - offset += byte_cnt; - dst += byte_cnt; - valuelen -= byte_cnt; - + /* roll attribute extent map forwards */ lblkno += map[i].br_blockcount; + blkcnt -= map[i].br_blockcount; } } ASSERT(valuelen == 0); @@ -270,17 +399,13 @@ xfs_attr_rmtval_set( struct xfs_inode *dp = args->dp; struct xfs_mount *mp = dp->i_mount; struct xfs_bmbt_irec map; - struct xfs_buf *bp; - xfs_daddr_t dblkno; xfs_dablk_t lblkno; xfs_fileoff_t lfileoff = 0; - void *src = args->value; + char *src = args->value; int blkcnt; int valuelen; int nmap; int error; - int hdrcnt = 0; - bool crcs = xfs_sb_version_hascrc(&mp->m_sb); int offset = 0; trace_xfs_attr_rmtval_set(args); @@ -289,24 +414,14 @@ xfs_attr_rmtval_set( * Find a "hole" in the attribute address space large enough for * us to drop the new attribute's value into. Because CRC enable * attributes have headers, we can't just do a straight byte to FSB - * conversion. We calculate the worst case block count in this case - * and we may not need that many, so we have to handle this when - * allocating the blocks below. + * conversion and have to take the header space into account. */ - if (!crcs) - blkcnt = XFS_B_TO_FSB(mp, args->valuelen); - else - blkcnt = xfs_attr3_rmt_blocks(mp, args->valuelen); - + blkcnt = xfs_attr3_rmt_blocks(mp, args->valuelen); error = xfs_bmap_first_unused(args->trans, args->dp, blkcnt, &lfileoff, XFS_ATTR_FORK); if (error) return error; - /* Start with the attribute data. We'll allocate the rest afterwards. */ - if (crcs) - blkcnt = XFS_B_TO_FSB(mp, args->valuelen); - args->rmtblkno = lblkno = (xfs_dablk_t)lfileoff; args->rmtblkcnt = blkcnt; @@ -349,26 +464,6 @@ xfs_attr_rmtval_set( (map.br_startblock != HOLESTARTBLOCK)); lblkno += map.br_blockcount; blkcnt -= map.br_blockcount; - hdrcnt++; - - /* - * If we have enough blocks for the attribute data, calculate - * how many extra blocks we need for headers. We might run - * through this multiple times in the case that the additional - * headers in the blocks needed for the data fragments spills - * into requiring more blocks. e.g. for 512 byte blocks, we'll - * spill for another block every 9 headers we require in this - * loop. - */ - if (crcs && blkcnt == 0) { - int total_len; - - total_len = args->valuelen + - hdrcnt * sizeof(struct xfs_attr3_rmt_hdr); - blkcnt = XFS_B_TO_FSB(mp, total_len); - blkcnt -= args->rmtblkcnt; - args->rmtblkcnt += blkcnt; - } /* * Start the next trans in the chain. @@ -385,18 +480,19 @@ xfs_attr_rmtval_set( * the INCOMPLETE flag. */ lblkno = args->rmtblkno; + blkcnt = args->rmtblkcnt; valuelen = args->valuelen; while (valuelen > 0) { - int byte_cnt; - char *buf; + struct xfs_buf *bp; + xfs_daddr_t dblkno; + int dblkcnt; + + ASSERT(blkcnt > 0); - /* - * Try to remember where we decided to put the value. - */ xfs_bmap_init(args->flist, args->firstblock); nmap = 1; error = xfs_bmapi_read(dp, (xfs_fileoff_t)lblkno, - args->rmtblkcnt, &map, &nmap, + blkcnt, &map, &nmap, XFS_BMAPI_ATTRFORK); if (error) return(error); @@ -405,41 +501,27 @@ xfs_attr_rmtval_set( (map.br_startblock != HOLESTARTBLOCK)); dblkno = XFS_FSB_TO_DADDR(mp, map.br_startblock), - blkcnt = XFS_FSB_TO_BB(mp, map.br_blockcount); + dblkcnt = XFS_FSB_TO_BB(mp, map.br_blockcount); - bp = xfs_buf_get(mp->m_ddev_targp, dblkno, blkcnt, 0); + bp = xfs_buf_get(mp->m_ddev_targp, dblkno, dblkcnt, 0); if (!bp) return ENOMEM; bp->b_ops = &xfs_attr3_rmt_buf_ops; - byte_cnt = BBTOB(bp->b_length); - byte_cnt = XFS_ATTR3_RMT_BUF_SPACE(mp, byte_cnt); - if (valuelen < byte_cnt) - byte_cnt = valuelen; - - buf = bp->b_addr; - buf += xfs_attr3_rmt_hdr_set(mp, dp->i_ino, offset, - byte_cnt, bp); - memcpy(buf, src, byte_cnt); - - if (byte_cnt < BBTOB(bp->b_length)) - xfs_buf_zero(bp, byte_cnt, - BBTOB(bp->b_length) - byte_cnt); + xfs_attr_rmtval_copyin(mp, bp, args->dp->i_ino, &offset, + &valuelen, &src); error = xfs_bwrite(bp); /* GROT: NOTE: synchronous write */ xfs_buf_relse(bp); if (error) return error; - src += byte_cnt; - valuelen -= byte_cnt; - offset += byte_cnt; - hdrcnt--; + /* roll attribute extent map forwards */ lblkno += map.br_blockcount; + blkcnt -= map.br_blockcount; } ASSERT(valuelen == 0); - ASSERT(hdrcnt == 0); return 0; } @@ -448,33 +530,40 @@ xfs_attr_rmtval_set( * out-of-line buffer that it is stored on. */ int -xfs_attr_rmtval_remove(xfs_da_args_t *args) +xfs_attr_rmtval_remove( + struct xfs_da_args *args) { - xfs_mount_t *mp; - xfs_bmbt_irec_t map; - xfs_buf_t *bp; - xfs_daddr_t dblkno; - xfs_dablk_t lblkno; - int valuelen, blkcnt, nmap, error, done, committed; + struct xfs_mount *mp = args->dp->i_mount; + xfs_dablk_t lblkno; + int blkcnt; + int error; + int done; trace_xfs_attr_rmtval_remove(args); - mp = args->dp->i_mount; - /* - * Roll through the "value", invalidating the attribute value's - * blocks. + * Roll through the "value", invalidating the attribute value's blocks. + * Note that args->rmtblkcnt is the minimum number of data blocks we'll + * see for a CRC enabled remote attribute. Each extent will have a + * header, and so we may have more blocks than we realise here. If we + * fail to map the blocks correctly, we'll have problems with the buffer + * lookups. */ lblkno = args->rmtblkno; - valuelen = args->rmtblkcnt; - while (valuelen > 0) { + blkcnt = args->rmtblkcnt; + while (blkcnt > 0) { + struct xfs_bmbt_irec map; + struct xfs_buf *bp; + xfs_daddr_t dblkno; + int dblkcnt; + int nmap; + /* * Try to remember where we decided to put the value. */ nmap = 1; error = xfs_bmapi_read(args->dp, (xfs_fileoff_t)lblkno, - args->rmtblkcnt, &map, &nmap, - XFS_BMAPI_ATTRFORK); + blkcnt, &map, &nmap, XFS_BMAPI_ATTRFORK); if (error) return(error); ASSERT(nmap == 1); @@ -482,21 +571,20 @@ xfs_attr_rmtval_remove(xfs_da_args_t *args) (map.br_startblock != HOLESTARTBLOCK)); dblkno = XFS_FSB_TO_DADDR(mp, map.br_startblock), - blkcnt = XFS_FSB_TO_BB(mp, map.br_blockcount); + dblkcnt = XFS_FSB_TO_BB(mp, map.br_blockcount); /* * If the "remote" value is in the cache, remove it. */ - bp = xfs_incore(mp->m_ddev_targp, dblkno, blkcnt, XBF_TRYLOCK); + bp = xfs_incore(mp->m_ddev_targp, dblkno, dblkcnt, XBF_TRYLOCK); if (bp) { xfs_buf_stale(bp); xfs_buf_relse(bp); bp = NULL; } - valuelen -= map.br_blockcount; - lblkno += map.br_blockcount; + blkcnt -= map.br_blockcount; } /* @@ -506,6 +594,8 @@ xfs_attr_rmtval_remove(xfs_da_args_t *args) blkcnt = args->rmtblkcnt; done = 0; while (!done) { + int committed; + xfs_bmap_init(args->flist, args->firstblock); error = xfs_bunmapi(args->trans, args->dp, lblkno, blkcnt, XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, diff --git a/fs/xfs/xfs_attr_remote.h b/fs/xfs/xfs_attr_remote.h index c7cca60a062a..92a8fd7977cc 100644 --- a/fs/xfs/xfs_attr_remote.h +++ b/fs/xfs/xfs_attr_remote.h @@ -20,6 +20,14 @@ #define XFS_ATTR3_RMT_MAGIC 0x5841524d /* XARM */ +/* + * There is one of these headers per filesystem block in a remote attribute. + * This is done to ensure there is a 1:1 mapping between the attribute value + * length and the number of blocks needed to store the attribute. This makes the + * verification of a buffer a little more complex, but greatly simplifies the + * allocation, reading and writing of these attributes as we don't have to guess + * the number of blocks needed to store the attribute data. + */ struct xfs_attr3_rmt_hdr { __be32 rm_magic; __be32 rm_offset; @@ -39,6 +47,8 @@ struct xfs_attr3_rmt_hdr { extern const struct xfs_buf_ops xfs_attr3_rmt_buf_ops; +int xfs_attr3_rmt_blocks(struct xfs_mount *mp, int attrlen); + int xfs_attr_rmtval_get(struct xfs_da_args *args); int xfs_attr_rmtval_set(struct xfs_da_args *args); int xfs_attr_rmtval_remove(struct xfs_da_args *args); diff --git a/fs/xfs/xfs_btree.c b/fs/xfs/xfs_btree.c index 8804b8a3c310..0903960410a2 100644 --- a/fs/xfs/xfs_btree.c +++ b/fs/xfs/xfs_btree.c @@ -2544,7 +2544,17 @@ xfs_btree_new_iroot( if (error) goto error0; + /* + * we can't just memcpy() the root in for CRC enabled btree blocks. + * In that case have to also ensure the blkno remains correct + */ memcpy(cblock, block, xfs_btree_block_len(cur)); + if (cur->bc_flags & XFS_BTREE_CRC_BLOCKS) { + if (cur->bc_flags & XFS_BTREE_LONG_PTRS) + cblock->bb_u.l.bb_blkno = cpu_to_be64(cbp->b_bn); + else + cblock->bb_u.s.bb_blkno = cpu_to_be64(cbp->b_bn); + } be16_add_cpu(&block->bb_level, 1); xfs_btree_set_numrecs(block, 1); diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 82b70bda9f47..1b2472a46e46 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c @@ -513,6 +513,7 @@ _xfs_buf_find( xfs_alert(btp->bt_mount, "%s: Block out of range: block 0x%llx, EOFS 0x%llx ", __func__, blkno, eofs); + WARN_ON(1); return NULL; } @@ -1649,7 +1650,7 @@ xfs_alloc_buftarg( { xfs_buftarg_t *btp; - btp = kmem_zalloc(sizeof(*btp), KM_SLEEP); + btp = kmem_zalloc(sizeof(*btp), KM_SLEEP | KM_NOFS); btp->bt_mount = mp; btp->bt_dev = bdev->bd_dev; diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index cf263476d6b4..4ec431777048 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c @@ -262,12 +262,7 @@ xfs_buf_item_format_segment( vecp->i_addr = xfs_buf_offset(bp, buffer_offset); vecp->i_len = nbits * XFS_BLF_CHUNK; vecp->i_type = XLOG_REG_TYPE_BCHUNK; -/* - * You would think we need to bump the nvecs here too, but we do not - * this number is used by recovery, and it gets confused by the boundary - * split here - * nvecs++; - */ + nvecs++; vecp++; first_bit = next_bit; last_bit = next_bit; diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c index 9b26a99ebfe9..0b8b2a13cd24 100644 --- a/fs/xfs/xfs_da_btree.c +++ b/fs/xfs/xfs_da_btree.c @@ -270,6 +270,7 @@ xfs_da3_node_read_verify( break; return; case XFS_ATTR_LEAF_MAGIC: + case XFS_ATTR3_LEAF_MAGIC: bp->b_ops = &xfs_attr3_leaf_buf_ops; bp->b_ops->verify_read(bp); return; @@ -2464,7 +2465,8 @@ xfs_buf_map_from_irec( ASSERT(nirecs >= 1); if (nirecs > 1) { - map = kmem_zalloc(nirecs * sizeof(struct xfs_buf_map), KM_SLEEP); + map = kmem_zalloc(nirecs * sizeof(struct xfs_buf_map), + KM_SLEEP | KM_NOFS); if (!map) return ENOMEM; *mapp = map; @@ -2520,7 +2522,8 @@ xfs_dabuf_map( * Optimize the one-block case. */ if (nfsb != 1) - irecs = kmem_zalloc(sizeof(irec) * nfsb, KM_SLEEP); + irecs = kmem_zalloc(sizeof(irec) * nfsb, + KM_SLEEP | KM_NOFS); nirecs = nfsb; error = xfs_bmapi_read(dp, (xfs_fileoff_t)bno, nfsb, irecs, diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c index f852b082a084..c407e1ccff43 100644 --- a/fs/xfs/xfs_dfrag.c +++ b/fs/xfs/xfs_dfrag.c @@ -219,6 +219,14 @@ xfs_swap_extents( int taforkblks = 0; __uint64_t tmp; + /* + * We have no way of updating owner information in the BMBT blocks for + * each inode on CRC enabled filesystems, so to avoid corrupting the + * this metadata we simply don't allow extent swaps to occur. + */ + if (xfs_sb_version_hascrc(&mp->m_sb)) + return XFS_ERROR(EINVAL); + tempifp = kmem_alloc(sizeof(xfs_ifork_t), KM_MAYFAIL); if (!tempifp) { error = XFS_ERROR(ENOMEM); diff --git a/fs/xfs/xfs_dir2_format.h b/fs/xfs/xfs_dir2_format.h index a3b1bd841a80..7826782b8d78 100644 --- a/fs/xfs/xfs_dir2_format.h +++ b/fs/xfs/xfs_dir2_format.h @@ -266,6 +266,7 @@ struct xfs_dir3_blk_hdr { struct xfs_dir3_data_hdr { struct xfs_dir3_blk_hdr hdr; xfs_dir2_data_free_t best_free[XFS_DIR2_DATA_FD_COUNT]; + __be32 pad; /* 64 bit alignment */ }; #define XFS_DIR3_DATA_CRC_OFF offsetof(struct xfs_dir3_data_hdr, hdr.crc) @@ -477,7 +478,7 @@ struct xfs_dir3_leaf_hdr { struct xfs_da3_blkinfo info; /* header for da routines */ __be16 count; /* count of entries */ __be16 stale; /* count of stale entries */ - __be32 pad; + __be32 pad; /* 64 bit alignment */ }; struct xfs_dir3_icleaf_hdr { @@ -715,6 +716,7 @@ struct xfs_dir3_free_hdr { __be32 firstdb; /* db of first entry */ __be32 nvalid; /* count of valid entries */ __be32 nused; /* count of used entries */ + __be32 pad; /* 64 bit alignment */ }; struct xfs_dir3_free { diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c index 721ba2fe8e54..da71a1819d78 100644 --- a/fs/xfs/xfs_dir2_leaf.c +++ b/fs/xfs/xfs_dir2_leaf.c @@ -1336,7 +1336,7 @@ xfs_dir2_leaf_getdents( mp->m_sb.sb_blocksize); map_info = kmem_zalloc(offsetof(struct xfs_dir2_leaf_map_info, map) + (length * sizeof(struct xfs_bmbt_irec)), - KM_SLEEP); + KM_SLEEP | KM_NOFS); map_info->map_size = length; /* diff --git a/fs/xfs/xfs_dir2_node.c b/fs/xfs/xfs_dir2_node.c index 5246de4912d4..2226a00acd15 100644 --- a/fs/xfs/xfs_dir2_node.c +++ b/fs/xfs/xfs_dir2_node.c @@ -263,18 +263,19 @@ xfs_dir3_free_get_buf( * Initialize the new block to be empty, and remember * its first slot as our empty slot. */ - hdr.magic = XFS_DIR2_FREE_MAGIC; - hdr.firstdb = 0; - hdr.nused = 0; - hdr.nvalid = 0; + memset(bp->b_addr, 0, sizeof(struct xfs_dir3_free_hdr)); + memset(&hdr, 0, sizeof(hdr)); + if (xfs_sb_version_hascrc(&mp->m_sb)) { struct xfs_dir3_free_hdr *hdr3 = bp->b_addr; hdr.magic = XFS_DIR3_FREE_MAGIC; + hdr3->hdr.blkno = cpu_to_be64(bp->b_bn); hdr3->hdr.owner = cpu_to_be64(dp->i_ino); uuid_copy(&hdr3->hdr.uuid, &mp->m_sb.sb_uuid); - } + } else + hdr.magic = XFS_DIR2_FREE_MAGIC; xfs_dir3_free_hdr_to_disk(bp->b_addr, &hdr); *bpp = bp; return 0; @@ -1921,8 +1922,6 @@ xfs_dir2_node_addname_int( */ freehdr.firstdb = (fbno - XFS_DIR2_FREE_FIRSTDB(mp)) * xfs_dir3_free_max_bests(mp); - free->hdr.nvalid = 0; - free->hdr.nused = 0; } else { free = fbp->b_addr; bests = xfs_dir3_free_bests_p(mp, free); diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index a41f8bf1da37..044e97a33c8d 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c @@ -249,8 +249,11 @@ xfs_qm_init_dquot_blk( d->dd_diskdq.d_version = XFS_DQUOT_VERSION; d->dd_diskdq.d_id = cpu_to_be32(curid); d->dd_diskdq.d_flags = type; - if (xfs_sb_version_hascrc(&mp->m_sb)) + if (xfs_sb_version_hascrc(&mp->m_sb)) { uuid_copy(&d->dd_uuid, &mp->m_sb.sb_uuid); + xfs_update_cksum((char *)d, sizeof(struct xfs_dqblk), + XFS_DQUOT_CRC_OFF); + } } xfs_trans_dquot_buf(tp, bp, @@ -286,23 +289,6 @@ xfs_dquot_set_prealloc_limits(struct xfs_dquot *dqp) dqp->q_low_space[XFS_QLOWSP_5_PCNT] = space * 5; } -STATIC void -xfs_dquot_buf_calc_crc( - struct xfs_mount *mp, - struct xfs_buf *bp) -{ - struct xfs_dqblk *d = (struct xfs_dqblk *)bp->b_addr; - int i; - - if (!xfs_sb_version_hascrc(&mp->m_sb)) - return; - - for (i = 0; i < mp->m_quotainfo->qi_dqperchunk; i++, d++) { - xfs_update_cksum((char *)d, sizeof(struct xfs_dqblk), - offsetof(struct xfs_dqblk, dd_crc)); - } -} - STATIC bool xfs_dquot_buf_verify_crc( struct xfs_mount *mp, @@ -328,12 +314,11 @@ xfs_dquot_buf_verify_crc( for (i = 0; i < ndquots; i++, d++) { if (!xfs_verify_cksum((char *)d, sizeof(struct xfs_dqblk), - offsetof(struct xfs_dqblk, dd_crc))) + XFS_DQUOT_CRC_OFF)) return false; if (!uuid_equal(&d->dd_uuid, &mp->m_sb.sb_uuid)) return false; } - return true; } @@ -393,6 +378,11 @@ xfs_dquot_buf_read_verify( } } +/* + * we don't calculate the CRC here as that is done when the dquot is flushed to + * the buffer after the update is done. This ensures that the dquot in the + * buffer always has an up-to-date CRC value. + */ void xfs_dquot_buf_write_verify( struct xfs_buf *bp) @@ -404,7 +394,6 @@ xfs_dquot_buf_write_verify( xfs_buf_ioerror(bp, EFSCORRUPTED); return; } - xfs_dquot_buf_calc_crc(mp, bp); } const struct xfs_buf_ops xfs_dquot_buf_ops = { @@ -1151,11 +1140,17 @@ xfs_qm_dqflush( * copy the lsn into the on-disk dquot now while we have the in memory * dquot here. This can't be done later in the write verifier as we * can't get access to the log item at that point in time. + * + * We also calculate the CRC here so that the on-disk dquot in the + * buffer always has a valid CRC. This ensures there is no possibility + * of a dquot without an up-to-date CRC getting to disk. */ if (xfs_sb_version_hascrc(&mp->m_sb)) { struct xfs_dqblk *dqb = (struct xfs_dqblk *)ddqp; dqb->dd_lsn = cpu_to_be64(dqp->q_logitem.qli_item.li_lsn); + xfs_update_cksum((char *)dqb, sizeof(struct xfs_dqblk), + XFS_DQUOT_CRC_OFF); } /* diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c index c0f375087efc..452920a3f03f 100644 --- a/fs/xfs/xfs_extfree_item.c +++ b/fs/xfs/xfs_extfree_item.c @@ -305,11 +305,12 @@ xfs_efi_release(xfs_efi_log_item_t *efip, { ASSERT(atomic_read(&efip->efi_next_extent) >= nextents); if (atomic_sub_and_test(nextents, &efip->efi_next_extent)) { - __xfs_efi_release(efip); - /* recovery needs us to drop the EFI reference, too */ if (test_bit(XFS_EFI_RECOVERED, &efip->efi_flags)) __xfs_efi_release(efip); + + __xfs_efi_release(efip); + /* efip may now have been freed, do not reference it again. */ } } diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h index 6dda3f949b04..d04695545397 100644 --- a/fs/xfs/xfs_fs.h +++ b/fs/xfs/xfs_fs.h @@ -236,6 +236,7 @@ typedef struct xfs_fsop_resblks { #define XFS_FSOP_GEOM_FLAGS_PROJID32 0x0800 /* 32-bit project IDs */ #define XFS_FSOP_GEOM_FLAGS_DIRV2CI 0x1000 /* ASCII only CI names */ #define XFS_FSOP_GEOM_FLAGS_LAZYSB 0x4000 /* lazy superblock counters */ +#define XFS_FSOP_GEOM_FLAGS_V5SB 0x8000 /* version 5 superblock */ /* diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index 87595b211da1..3c3644ea825b 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c @@ -99,7 +99,9 @@ xfs_fs_geometry( (xfs_sb_version_hasattr2(&mp->m_sb) ? XFS_FSOP_GEOM_FLAGS_ATTR2 : 0) | (xfs_sb_version_hasprojid32bit(&mp->m_sb) ? - XFS_FSOP_GEOM_FLAGS_PROJID32 : 0); + XFS_FSOP_GEOM_FLAGS_PROJID32 : 0) | + (xfs_sb_version_hascrc(&mp->m_sb) ? + XFS_FSOP_GEOM_FLAGS_V5SB : 0); geo->logsectsize = xfs_sb_version_hassector(&mp->m_sb) ? mp->m_sb.sb_logsectsize : BBSIZE; geo->rtsectsize = mp->m_sb.sb_blocksize; diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index efbe1accb6ca..7f7be5f98f52 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1638,6 +1638,10 @@ xfs_iunlink( dip->di_next_unlinked = agi->agi_unlinked[bucket_index]; offset = ip->i_imap.im_boffset + offsetof(xfs_dinode_t, di_next_unlinked); + + /* need to recalc the inode CRC if appropriate */ + xfs_dinode_calc_crc(mp, dip); + xfs_trans_inode_buf(tp, ibp); xfs_trans_log_buf(tp, ibp, offset, (offset + sizeof(xfs_agino_t) - 1)); @@ -1723,6 +1727,10 @@ xfs_iunlink_remove( dip->di_next_unlinked = cpu_to_be32(NULLAGINO); offset = ip->i_imap.im_boffset + offsetof(xfs_dinode_t, di_next_unlinked); + + /* need to recalc the inode CRC if appropriate */ + xfs_dinode_calc_crc(mp, dip); + xfs_trans_inode_buf(tp, ibp); xfs_trans_log_buf(tp, ibp, offset, (offset + sizeof(xfs_agino_t) - 1)); @@ -1796,6 +1804,10 @@ xfs_iunlink_remove( dip->di_next_unlinked = cpu_to_be32(NULLAGINO); offset = ip->i_imap.im_boffset + offsetof(xfs_dinode_t, di_next_unlinked); + + /* need to recalc the inode CRC if appropriate */ + xfs_dinode_calc_crc(mp, dip); + xfs_trans_inode_buf(tp, ibp); xfs_trans_log_buf(tp, ibp, offset, (offset + sizeof(xfs_agino_t) - 1)); @@ -1809,6 +1821,10 @@ xfs_iunlink_remove( last_dip->di_next_unlinked = cpu_to_be32(next_agino); ASSERT(next_agino != 0); offset = last_offset + offsetof(xfs_dinode_t, di_next_unlinked); + + /* need to recalc the inode CRC if appropriate */ + xfs_dinode_calc_crc(mp, last_dip); + xfs_trans_inode_buf(tp, last_ibp); xfs_trans_log_buf(tp, last_ibp, offset, (offset + sizeof(xfs_agino_t) - 1)); diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index d82efaa2ac73..ca9ecaa81112 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -455,6 +455,28 @@ xfs_vn_getattr( return 0; } +static void +xfs_setattr_mode( + struct xfs_trans *tp, + struct xfs_inode *ip, + struct iattr *iattr) +{ + struct inode *inode = VFS_I(ip); + umode_t mode = iattr->ia_mode; + + ASSERT(tp); + ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); + + if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID)) + mode &= ~S_ISGID; + + ip->i_d.di_mode &= S_IFMT; + ip->i_d.di_mode |= mode & ~S_IFMT; + + inode->i_mode &= S_IFMT; + inode->i_mode |= mode & ~S_IFMT; +} + int xfs_setattr_nonsize( struct xfs_inode *ip, @@ -606,18 +628,8 @@ xfs_setattr_nonsize( /* * Change file access modes. */ - if (mask & ATTR_MODE) { - umode_t mode = iattr->ia_mode; - - if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID)) - mode &= ~S_ISGID; - - ip->i_d.di_mode &= S_IFMT; - ip->i_d.di_mode |= mode & ~S_IFMT; - - inode->i_mode &= S_IFMT; - inode->i_mode |= mode & ~S_IFMT; - } + if (mask & ATTR_MODE) + xfs_setattr_mode(tp, ip, iattr); /* * Change file access or modified times. @@ -714,9 +726,8 @@ xfs_setattr_size( return XFS_ERROR(error); ASSERT(S_ISREG(ip->i_d.di_mode)); - ASSERT((mask & (ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_ATIME_SET| - ATTR_MTIME_SET|ATTR_KILL_SUID|ATTR_KILL_SGID| - ATTR_KILL_PRIV|ATTR_TIMES_SET)) == 0); + ASSERT((mask & (ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_ATIME_SET| + ATTR_MTIME_SET|ATTR_KILL_PRIV|ATTR_TIMES_SET)) == 0); if (!(flags & XFS_ATTR_NOLOCK)) { lock_flags |= XFS_IOLOCK_EXCL; @@ -860,6 +871,12 @@ xfs_setattr_size( xfs_inode_clear_eofblocks_tag(ip); } + /* + * Change file access modes. + */ + if (mask & ATTR_MODE) + xfs_setattr_mode(tp, ip, iattr); + if (mask & ATTR_CTIME) { inode->i_ctime = iattr->ia_ctime; ip->i_d.di_ctime.t_sec = iattr->ia_ctime.tv_sec; diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c index e3d0b85d852b..d0833b54e55d 100644 --- a/fs/xfs/xfs_log_cil.c +++ b/fs/xfs/xfs_log_cil.c @@ -139,7 +139,7 @@ xlog_cil_prepare_log_vecs( new_lv = kmem_zalloc(sizeof(*new_lv) + niovecs * sizeof(struct xfs_log_iovec), - KM_SLEEP); + KM_SLEEP|KM_NOFS); /* The allocated iovec region lies beyond the log vector. */ new_lv->lv_iovecp = (struct xfs_log_iovec *)&new_lv[1]; diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 93f03ec17eec..7cf5e4eafe28 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -1599,10 +1599,43 @@ xlog_recover_add_to_trans( } /* - * Sort the log items in the transaction. Cancelled buffers need - * to be put first so they are processed before any items that might - * modify the buffers. If they are cancelled, then the modifications - * don't need to be replayed. + * Sort the log items in the transaction. + * + * The ordering constraints are defined by the inode allocation and unlink + * behaviour. The rules are: + * + * 1. Every item is only logged once in a given transaction. Hence it + * represents the last logged state of the item. Hence ordering is + * dependent on the order in which operations need to be performed so + * required initial conditions are always met. + * + * 2. Cancelled buffers are recorded in pass 1 in a separate table and + * there's nothing to replay from them so we can simply cull them + * from the transaction. However, we can't do that until after we've + * replayed all the other items because they may be dependent on the + * cancelled buffer and replaying the cancelled buffer can remove it + * form the cancelled buffer table. Hence they have tobe done last. + * + * 3. Inode allocation buffers must be replayed before inode items that + * read the buffer and replay changes into it. + * + * 4. Inode unlink buffers must be replayed after inode items are replayed. + * This ensures that inodes are completely flushed to the inode buffer + * in a "free" state before we remove the unlinked inode list pointer. + * + * Hence the ordering needs to be inode allocation buffers first, inode items + * second, inode unlink buffers third and cancelled buffers last. + * + * But there's a problem with that - we can't tell an inode allocation buffer + * apart from a regular buffer, so we can't separate them. We can, however, + * tell an inode unlink buffer from the others, and so we can separate them out + * from all the other buffers and move them to last. + * + * Hence, 4 lists, in order from head to tail: + * - buffer_list for all buffers except cancelled/inode unlink buffers + * - item_list for all non-buffer items + * - inode_buffer_list for inode unlink buffers + * - cancel_list for the cancelled buffers */ STATIC int xlog_recover_reorder_trans( @@ -1612,6 +1645,10 @@ xlog_recover_reorder_trans( { xlog_recover_item_t *item, *n; LIST_HEAD(sort_list); + LIST_HEAD(cancel_list); + LIST_HEAD(buffer_list); + LIST_HEAD(inode_buffer_list); + LIST_HEAD(inode_list); list_splice_init(&trans->r_itemq, &sort_list); list_for_each_entry_safe(item, n, &sort_list, ri_list) { @@ -1619,12 +1656,18 @@ xlog_recover_reorder_trans( switch (ITEM_TYPE(item)) { case XFS_LI_BUF: - if (!(buf_f->blf_flags & XFS_BLF_CANCEL)) { + if (buf_f->blf_flags & XFS_BLF_CANCEL) { trace_xfs_log_recover_item_reorder_head(log, trans, item, pass); - list_move(&item->ri_list, &trans->r_itemq); + list_move(&item->ri_list, &cancel_list); + break; + } + if (buf_f->blf_flags & XFS_BLF_INODE_BUF) { + list_move(&item->ri_list, &inode_buffer_list); break; } + list_move_tail(&item->ri_list, &buffer_list); + break; case XFS_LI_INODE: case XFS_LI_DQUOT: case XFS_LI_QUOTAOFF: @@ -1632,7 +1675,7 @@ xlog_recover_reorder_trans( case XFS_LI_EFI: trace_xfs_log_recover_item_reorder_tail(log, trans, item, pass); - list_move_tail(&item->ri_list, &trans->r_itemq); + list_move_tail(&item->ri_list, &inode_list); break; default: xfs_warn(log->l_mp, @@ -1643,6 +1686,14 @@ xlog_recover_reorder_trans( } } ASSERT(list_empty(&sort_list)); + if (!list_empty(&buffer_list)) + list_splice(&buffer_list, &trans->r_itemq); + if (!list_empty(&inode_list)) + list_splice_tail(&inode_list, &trans->r_itemq); + if (!list_empty(&inode_buffer_list)) + list_splice_tail(&inode_buffer_list, &trans->r_itemq); + if (!list_empty(&cancel_list)) + list_splice_tail(&cancel_list, &trans->r_itemq); return 0; } @@ -1794,7 +1845,13 @@ xlog_recover_do_inode_buffer( xfs_agino_t *buffer_nextp; trace_xfs_log_recover_buf_inode_buf(mp->m_log, buf_f); - bp->b_ops = &xfs_inode_buf_ops; + + /* + * Post recovery validation only works properly on CRC enabled + * filesystems. + */ + if (xfs_sb_version_hascrc(&mp->m_sb)) + bp->b_ops = &xfs_inode_buf_ops; inodes_per_buf = BBTOB(bp->b_io_length) >> mp->m_sb.sb_inodelog; for (i = 0; i < inodes_per_buf; i++) { @@ -1861,6 +1918,15 @@ xlog_recover_do_inode_buffer( buffer_nextp = (xfs_agino_t *)xfs_buf_offset(bp, next_unlinked_offset); *buffer_nextp = *logged_nextp; + + /* + * If necessary, recalculate the CRC in the on-disk inode. We + * have to leave the inode in a consistent state for whoever + * reads it next.... + */ + xfs_dinode_calc_crc(mp, (struct xfs_dinode *) + xfs_buf_offset(bp, i * mp->m_sb.sb_inodesize)); + } return 0; @@ -2097,6 +2163,17 @@ xlog_recover_do_reg_buffer( ((uint)bit << XFS_BLF_SHIFT) + (nbits << XFS_BLF_SHIFT)); /* + * The dirty regions logged in the buffer, even though + * contiguous, may span multiple chunks. This is because the + * dirty region may span a physical page boundary in a buffer + * and hence be split into two separate vectors for writing into + * the log. Hence we need to trim nbits back to the length of + * the current region being copied out of the log. + */ + if (item->ri_buf[i].i_len < (nbits << XFS_BLF_SHIFT)) + nbits = item->ri_buf[i].i_len >> XFS_BLF_SHIFT; + + /* * Do a sanity check if this is a dquot buffer. Just checking * the first dquot in the buffer should do. XXXThis is * probably a good thing to do for other buf types also. @@ -2134,7 +2211,16 @@ xlog_recover_do_reg_buffer( /* Shouldn't be any more regions */ ASSERT(i == item->ri_total); - xlog_recovery_validate_buf_type(mp, bp, buf_f); + /* + * We can only do post recovery validation on items on CRC enabled + * fielsystems as we need to know when the buffer was written to be able + * to determine if we should have replayed the item. If we replay old + * metadata over a newer buffer, then it will enter a temporarily + * inconsistent state resulting in verification failures. Hence for now + * just avoid the verification stage for non-crc filesystems + */ + if (xfs_sb_version_hascrc(&mp->m_sb)) + xlog_recovery_validate_buf_type(mp, bp, buf_f); } /* @@ -2255,6 +2341,12 @@ xfs_qm_dqcheck( d->dd_diskdq.d_flags = type; d->dd_diskdq.d_id = cpu_to_be32(id); + if (xfs_sb_version_hascrc(&mp->m_sb)) { + uuid_copy(&d->dd_uuid, &mp->m_sb.sb_uuid); + xfs_update_cksum((char *)d, sizeof(struct xfs_dqblk), + XFS_DQUOT_CRC_OFF); + } + return errs; } @@ -2782,6 +2874,10 @@ xlog_recover_dquot_pass2( } memcpy(ddq, recddq, item->ri_buf[1].i_len); + if (xfs_sb_version_hascrc(&mp->m_sb)) { + xfs_update_cksum((char *)ddq, sizeof(struct xfs_dqblk), + XFS_DQUOT_CRC_OFF); + } ASSERT(dq_f->qlf_size == 2); ASSERT(bp->b_target->bt_mount == mp); diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index f6bfbd734669..e8e310c05097 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -314,7 +314,8 @@ STATIC int xfs_mount_validate_sb( xfs_mount_t *mp, xfs_sb_t *sbp, - bool check_inprogress) + bool check_inprogress, + bool check_version) { /* @@ -337,9 +338,10 @@ xfs_mount_validate_sb( /* * Version 5 superblock feature mask validation. Reject combinations the - * kernel cannot support up front before checking anything else. + * kernel cannot support up front before checking anything else. For + * write validation, we don't need to check feature masks. */ - if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) { + if (check_version && XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) { xfs_alert(mp, "Version 5 superblock detected. This kernel has EXPERIMENTAL support enabled!\n" "Use of these features in this kernel is at your own risk!"); @@ -675,7 +677,8 @@ xfs_sb_to_disk( static int xfs_sb_verify( - struct xfs_buf *bp) + struct xfs_buf *bp, + bool check_version) { struct xfs_mount *mp = bp->b_target->bt_mount; struct xfs_sb sb; @@ -686,7 +689,8 @@ xfs_sb_verify( * Only check the in progress field for the primary superblock as * mkfs.xfs doesn't clear it from secondary superblocks. */ - return xfs_mount_validate_sb(mp, &sb, bp->b_bn == XFS_SB_DADDR); + return xfs_mount_validate_sb(mp, &sb, bp->b_bn == XFS_SB_DADDR, + check_version); } /* @@ -719,7 +723,7 @@ xfs_sb_read_verify( goto out_error; } } - error = xfs_sb_verify(bp); + error = xfs_sb_verify(bp, true); out_error: if (error) { @@ -758,7 +762,7 @@ xfs_sb_write_verify( struct xfs_buf_log_item *bip = bp->b_fspriv; int error; - error = xfs_sb_verify(bp); + error = xfs_sb_verify(bp, false); if (error) { XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr); xfs_buf_ioerror(bp, error); diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index f41702b43003..b75c9bb6e71e 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c @@ -41,6 +41,7 @@ #include "xfs_qm.h" #include "xfs_trace.h" #include "xfs_icache.h" +#include "xfs_cksum.h" /* * The global quota manager. There is only one of these for the entire @@ -839,7 +840,7 @@ xfs_qm_reset_dqcounts( xfs_dqid_t id, uint type) { - xfs_disk_dquot_t *ddq; + struct xfs_dqblk *dqb; int j; trace_xfs_reset_dqcounts(bp, _RET_IP_); @@ -853,8 +854,12 @@ xfs_qm_reset_dqcounts( do_div(j, sizeof(xfs_dqblk_t)); ASSERT(mp->m_quotainfo->qi_dqperchunk == j); #endif - ddq = bp->b_addr; + dqb = bp->b_addr; for (j = 0; j < mp->m_quotainfo->qi_dqperchunk; j++) { + struct xfs_disk_dquot *ddq; + + ddq = (struct xfs_disk_dquot *)&dqb[j]; + /* * Do a sanity check, and if needed, repair the dqblk. Don't * output any warnings because it's perfectly possible to @@ -871,7 +876,12 @@ xfs_qm_reset_dqcounts( ddq->d_bwarns = 0; ddq->d_iwarns = 0; ddq->d_rtbwarns = 0; - ddq = (xfs_disk_dquot_t *) ((xfs_dqblk_t *)ddq + 1); + + if (xfs_sb_version_hascrc(&mp->m_sb)) { + xfs_update_cksum((char *)&dqb[j], + sizeof(struct xfs_dqblk), + XFS_DQUOT_CRC_OFF); + } } } @@ -907,19 +917,29 @@ xfs_qm_dqiter_bufs( XFS_FSB_TO_DADDR(mp, bno), mp->m_quotainfo->qi_dqchunklen, 0, &bp, &xfs_dquot_buf_ops); - if (error) - break; /* - * XXX(hch): need to figure out if it makes sense to validate - * the CRC here. + * CRC and validation errors will return a EFSCORRUPTED here. If + * this occurs, re-read without CRC validation so that we can + * repair the damage via xfs_qm_reset_dqcounts(). This process + * will leave a trace in the log indicating corruption has + * been detected. */ + if (error == EFSCORRUPTED) { + error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp, + XFS_FSB_TO_DADDR(mp, bno), + mp->m_quotainfo->qi_dqchunklen, 0, &bp, + NULL); + } + + if (error) + break; + xfs_qm_reset_dqcounts(mp, bp, firstid, type); xfs_buf_delwri_queue(bp, buffer_list); xfs_buf_relse(bp); - /* - * goto the next block. - */ + + /* goto the next block. */ bno++; firstid += mp->m_quotainfo->qi_dqperchunk; } diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c index c41190cad6e9..6cdf6ffc36a1 100644 --- a/fs/xfs/xfs_qm_syscalls.c +++ b/fs/xfs/xfs_qm_syscalls.c @@ -489,31 +489,36 @@ xfs_qm_scall_setqlim( if ((newlim->d_fieldmask & XFS_DQ_MASK) == 0) return 0; - tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SETQLIM); - error = xfs_trans_reserve(tp, 0, XFS_QM_SETQLIM_LOG_RES(mp), - 0, 0, XFS_DEFAULT_LOG_COUNT); - if (error) { - xfs_trans_cancel(tp, 0); - return (error); - } - /* * We don't want to race with a quotaoff so take the quotaoff lock. - * (We don't hold an inode lock, so there's nothing else to stop - * a quotaoff from happening). (XXXThis doesn't currently happen - * because we take the vfslock before calling xfs_qm_sysent). + * We don't hold an inode lock, so there's nothing else to stop + * a quotaoff from happening. */ mutex_lock(&q->qi_quotaofflock); /* - * Get the dquot (locked), and join it to the transaction. - * Allocate the dquot if this doesn't exist. + * Get the dquot (locked) before we start, as we need to do a + * transaction to allocate it if it doesn't exist. Once we have the + * dquot, unlock it so we can start the next transaction safely. We hold + * a reference to the dquot, so it's safe to do this unlock/lock without + * it being reclaimed in the mean time. */ - if ((error = xfs_qm_dqget(mp, NULL, id, type, XFS_QMOPT_DQALLOC, &dqp))) { - xfs_trans_cancel(tp, XFS_TRANS_ABORT); + error = xfs_qm_dqget(mp, NULL, id, type, XFS_QMOPT_DQALLOC, &dqp); + if (error) { ASSERT(error != ENOENT); goto out_unlock; } + xfs_dqunlock(dqp); + + tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SETQLIM); + error = xfs_trans_reserve(tp, 0, XFS_QM_SETQLIM_LOG_RES(mp), + 0, 0, XFS_DEFAULT_LOG_COUNT); + if (error) { + xfs_trans_cancel(tp, 0); + goto out_rele; + } + + xfs_dqlock(dqp); xfs_trans_dqjoin(tp, dqp); ddq = &dqp->q_core; @@ -621,9 +626,10 @@ xfs_qm_scall_setqlim( xfs_trans_log_dquot(tp, dqp); error = xfs_trans_commit(tp, 0); - xfs_qm_dqrele(dqp); - out_unlock: +out_rele: + xfs_qm_dqrele(dqp); +out_unlock: mutex_unlock(&q->qi_quotaofflock); return error; } diff --git a/fs/xfs/xfs_quota.h b/fs/xfs/xfs_quota.h index c61e31c7d997..c38068f26c55 100644 --- a/fs/xfs/xfs_quota.h +++ b/fs/xfs/xfs_quota.h @@ -87,6 +87,8 @@ typedef struct xfs_dqblk { uuid_t dd_uuid; /* location information */ } xfs_dqblk_t; +#define XFS_DQUOT_CRC_OFF offsetof(struct xfs_dqblk, dd_crc) + /* * flags for q_flags field in the dquot. */ diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index ea341cea68cb..3033ba5e9762 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -1373,6 +1373,17 @@ xfs_finish_flags( } /* + * V5 filesystems always use attr2 format for attributes. + */ + if (xfs_sb_version_hascrc(&mp->m_sb) && + (mp->m_flags & XFS_MOUNT_NOATTR2)) { + xfs_warn(mp, +"Cannot mount a V5 filesystem as %s. %s is always enabled for V5 filesystems.", + MNTOPT_NOATTR2, MNTOPT_ATTR2); + return XFS_ERROR(EINVAL); + } + + /* * mkfs'ed attr2 will turn on attr2 mount unless explicitly * told by noattr2 to turn it off */ diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c index 5f234389327c..195a403e1522 100644 --- a/fs/xfs/xfs_symlink.c +++ b/fs/xfs/xfs_symlink.c @@ -56,16 +56,9 @@ xfs_symlink_blocks( struct xfs_mount *mp, int pathlen) { - int fsblocks = 0; - int len = pathlen; + int buflen = XFS_SYMLINK_BUF_SPACE(mp, mp->m_sb.sb_blocksize); - do { - fsblocks++; - len -= XFS_SYMLINK_BUF_SPACE(mp, mp->m_sb.sb_blocksize); - } while (len > 0); - - ASSERT(fsblocks <= XFS_SYMLINK_MAPS); - return fsblocks; + return (pathlen + buflen - 1) / buflen; } static int @@ -405,7 +398,7 @@ xfs_symlink( if (pathlen <= XFS_LITINO(mp, dp->i_d.di_version)) fs_blocks = 0; else - fs_blocks = XFS_B_TO_FSB(mp, pathlen); + fs_blocks = xfs_symlink_blocks(mp, pathlen); resblks = XFS_SYMLINK_SPACE_RES(mp, link_name->len, fs_blocks); error = xfs_trans_reserve(tp, resblks, XFS_SYMLINK_LOG_RES(mp), 0, XFS_TRANS_PERM_LOG_RES, XFS_SYMLINK_LOG_COUNT); @@ -512,7 +505,7 @@ xfs_symlink( cur_chunk = target_path; offset = 0; for (n = 0; n < nmaps; n++) { - char *buf; + char *buf; d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock); byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount); @@ -525,9 +518,7 @@ xfs_symlink( bp->b_ops = &xfs_symlink_buf_ops; byte_cnt = XFS_SYMLINK_BUF_SPACE(mp, byte_cnt); - if (pathlen < byte_cnt) { - byte_cnt = pathlen; - } + byte_cnt = min(byte_cnt, pathlen); buf = bp->b_addr; buf += xfs_symlink_hdr_set(mp, ip->i_ino, offset, @@ -542,6 +533,7 @@ xfs_symlink( xfs_trans_log_buf(tp, bp, 0, (buf + byte_cnt - 1) - (char *)bp->b_addr); } + ASSERT(pathlen == 0); } /* diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 1501f4fa51a6..0176bb21f09a 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -1453,7 +1453,7 @@ xfs_free_file_space( xfs_mount_t *mp; int nimap; uint resblks; - uint rounding; + xfs_off_t rounding; int rt; xfs_fileoff_t startoffset_fsb; xfs_trans_t *tp; @@ -1482,7 +1482,7 @@ xfs_free_file_space( inode_dio_wait(VFS_I(ip)); } - rounding = max_t(uint, 1 << mp->m_sb.sb_blocklog, PAGE_CACHE_SIZE); + rounding = max_t(xfs_off_t, 1 << mp->m_sb.sb_blocklog, PAGE_CACHE_SIZE); ioffset = offset & ~(rounding - 1); error = -filemap_write_and_wait_range(VFS_I(ip)->i_mapping, ioffset, -1); diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 98db31d9f9b4..c13c919ab99e 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -377,49 +377,20 @@ acpi_status acpi_bus_get_status_handle(acpi_handle handle, unsigned long long *sta); int acpi_bus_get_status(struct acpi_device *device); -#ifdef CONFIG_PM int acpi_bus_set_power(acpi_handle handle, int state); const char *acpi_power_state_string(int state); int acpi_device_get_power(struct acpi_device *device, int *state); int acpi_device_set_power(struct acpi_device *device, int state); int acpi_bus_init_power(struct acpi_device *device); +int acpi_device_fix_up_power(struct acpi_device *device); int acpi_bus_update_power(acpi_handle handle, int *state_p); bool acpi_bus_power_manageable(acpi_handle handle); + +#ifdef CONFIG_PM bool acpi_bus_can_wakeup(acpi_handle handle); -#else /* !CONFIG_PM */ -static inline int acpi_bus_set_power(acpi_handle handle, int state) -{ - return 0; -} -static inline const char *acpi_power_state_string(int state) -{ - return "D0"; -} -static inline int acpi_device_get_power(struct acpi_device *device, int *state) -{ - return 0; -} -static inline int acpi_device_set_power(struct acpi_device *device, int state) -{ - return 0; -} -static inline int acpi_bus_init_power(struct acpi_device *device) -{ - return 0; -} -static inline int acpi_bus_update_power(acpi_handle handle, int *state_p) -{ - return 0; -} -static inline bool acpi_bus_power_manageable(acpi_handle handle) -{ - return false; -} -static inline bool acpi_bus_can_wakeup(acpi_handle handle) -{ - return false; -} -#endif /* !CONFIG_PM */ +#else +static inline bool acpi_bus_can_wakeup(acpi_handle handle) { return false; } +#endif #ifdef CONFIG_ACPI_PROC_EVENT int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data); diff --git a/include/asm-generic/io.h b/include/asm-generic/io.h index ac9da00e9f2c..d5afe96adba6 100644 --- a/include/asm-generic/io.h +++ b/include/asm-generic/io.h @@ -343,8 +343,12 @@ extern void ioport_unmap(void __iomem *p); #endif /* CONFIG_GENERIC_IOMAP */ #endif /* CONFIG_HAS_IOPORT */ +#ifndef xlate_dev_kmem_ptr #define xlate_dev_kmem_ptr(p) p +#endif +#ifndef xlate_dev_mem_ptr #define xlate_dev_mem_ptr(p) __va(p) +#endif #ifdef CONFIG_VIRT_TO_BUS #ifndef virt_to_bus diff --git a/include/asm-generic/kvm_para.h b/include/asm-generic/kvm_para.h index 9d96605f160a..fa25becbdcaf 100644 --- a/include/asm-generic/kvm_para.h +++ b/include/asm-generic/kvm_para.h @@ -18,4 +18,9 @@ static inline unsigned int kvm_arch_para_features(void) return 0; } +static inline bool kvm_para_available(void) +{ + return false; +} + #endif diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h index b1b1fa6ffffe..13821c339a41 100644 --- a/include/asm-generic/tlb.h +++ b/include/asm-generic/tlb.h @@ -97,11 +97,9 @@ struct mmu_gather { unsigned long start; unsigned long end; unsigned int need_flush : 1, /* Did free PTEs */ - fast_mode : 1; /* No batching */ - /* we are in the middle of an operation to clear * a full mm and can make some optimizations */ - unsigned int fullmm : 1, + fullmm : 1, /* we have performed an operation which * requires a complete flush of the tlb */ need_flush_all : 1; @@ -114,19 +112,6 @@ struct mmu_gather { #define HAVE_GENERIC_MMU_GATHER -static inline int tlb_fast_mode(struct mmu_gather *tlb) -{ -#ifdef CONFIG_SMP - return tlb->fast_mode; -#else - /* - * For UP we don't need to worry about TLB flush - * and page free order so much.. - */ - return 1; -#endif -} - void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, bool fullmm); void tlb_flush_mmu(struct mmu_gather *tlb); void tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, diff --git a/include/linux/acpi_dma.h b/include/linux/acpi_dma.h index d09deabc7bf6..fb0298082916 100644 --- a/include/linux/acpi_dma.h +++ b/include/linux/acpi_dma.h @@ -37,6 +37,8 @@ struct acpi_dma_spec { * @dev: struct device of this controller * @acpi_dma_xlate: callback function to find a suitable channel * @data: private data used by a callback function + * @base_request_line: first supported request line (CSRT) + * @end_request_line: last supported request line (CSRT) */ struct acpi_dma { struct list_head dma_controllers; @@ -44,6 +46,8 @@ struct acpi_dma { struct dma_chan *(*acpi_dma_xlate) (struct acpi_dma_spec *, struct acpi_dma *); void *data; + unsigned short base_request_line; + unsigned short end_request_line; }; /* Used with acpi_dma_simple_xlate() */ diff --git a/include/linux/aer.h b/include/linux/aer.h index ec10e1b24c1c..737f90ab4b62 100644 --- a/include/linux/aer.h +++ b/include/linux/aer.h @@ -49,10 +49,11 @@ static inline int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev) } #endif -extern void cper_print_aer(const char *prefix, struct pci_dev *dev, +extern void cper_print_aer(struct pci_dev *dev, int cper_severity, struct aer_capability_regs *aer); extern int cper_severity_to_aer(int cper_severity); extern void aer_recover_queue(int domain, unsigned int bus, unsigned int devfn, - int severity); + int severity, + struct aer_capability_regs *aer_regs); #endif //_AER_H_ diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h index f14a98a79c9d..2e34db82a643 100644 --- a/include/linux/bcma/bcma.h +++ b/include/linux/bcma/bcma.h @@ -134,7 +134,10 @@ struct bcma_host_ops { #define BCMA_CORE_I2S 0x834 #define BCMA_CORE_SDR_DDR1_MEM_CTL 0x835 /* SDR/DDR1 memory controller core */ #define BCMA_CORE_SHIM 0x837 /* SHIM component in ubus/6362 */ -#define BCMA_CORE_ARM_CR4 0x83e +#define BCMA_CORE_PHY_AC 0x83B +#define BCMA_CORE_PCIE2 0x83C /* PCI Express Gen2 */ +#define BCMA_CORE_USB30_DEV 0x83D +#define BCMA_CORE_ARM_CR4 0x83E #define BCMA_CORE_DEFAULT 0xFFF #define BCMA_MAX_NR_CORES 16 diff --git a/include/linux/brcmphy.h b/include/linux/brcmphy.h index b840a4960282..677b4f01b2d0 100644 --- a/include/linux/brcmphy.h +++ b/include/linux/brcmphy.h @@ -1,3 +1,6 @@ +#ifndef _LINUX_BRCMPHY_H +#define _LINUX_BRCMPHY_H + #define PHY_ID_BCM50610 0x0143bd60 #define PHY_ID_BCM50610M 0x0143bd70 #define PHY_ID_BCM5241 0x0143bc30 @@ -29,3 +32,5 @@ #define PHY_BRCM_CLEAR_RGMII_MODE 0x00004000 #define PHY_BRCM_DIS_TXCRXC_NOENRGY 0x00008000 #define PHY_BCM_FLAGS_VALID 0x80000000 + +#endif /* _LINUX_BRCMPHY_H */ diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 5047355b9a0f..8bda1294c035 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -707,7 +707,7 @@ struct cgroup *cgroup_rightmost_descendant(struct cgroup *pos); * * If a subsystem synchronizes against the parent in its ->css_online() and * before starting iterating, and synchronizes against @pos on each - * iteration, any descendant cgroup which finished ->css_offline() is + * iteration, any descendant cgroup which finished ->css_online() is * guaranteed to be visible in the future iterations. * * In other words, the following guarantees that a descendant can't escape diff --git a/include/linux/context_tracking.h b/include/linux/context_tracking.h index 365f4a61bf04..fc09d7b0dacf 100644 --- a/include/linux/context_tracking.h +++ b/include/linux/context_tracking.h @@ -3,6 +3,7 @@ #include <linux/sched.h> #include <linux/percpu.h> +#include <linux/vtime.h> #include <asm/ptrace.h> struct context_tracking { @@ -19,6 +20,26 @@ struct context_tracking { } state; }; +static inline void __guest_enter(void) +{ + /* + * This is running in ioctl context so we can avoid + * the call to vtime_account() with its unnecessary idle check. + */ + vtime_account_system(current); + current->flags |= PF_VCPU; +} + +static inline void __guest_exit(void) +{ + /* + * This is running in ioctl context so we can avoid + * the call to vtime_account() with its unnecessary idle check. + */ + vtime_account_system(current); + current->flags &= ~PF_VCPU; +} + #ifdef CONFIG_CONTEXT_TRACKING DECLARE_PER_CPU(struct context_tracking, context_tracking); @@ -35,6 +56,9 @@ static inline bool context_tracking_active(void) extern void user_enter(void); extern void user_exit(void); +extern void guest_enter(void); +extern void guest_exit(void); + static inline enum ctx_state exception_enter(void) { enum ctx_state prev_ctx; @@ -57,6 +81,17 @@ extern void context_tracking_task_switch(struct task_struct *prev, static inline bool context_tracking_in_user(void) { return false; } static inline void user_enter(void) { } static inline void user_exit(void) { } + +static inline void guest_enter(void) +{ + __guest_enter(); +} + +static inline void guest_exit(void) +{ + __guest_exit(); +} + static inline enum ctx_state exception_enter(void) { return 0; } static inline void exception_exit(enum ctx_state prev_ctx) { } static inline void context_tracking_task_switch(struct task_struct *prev, diff --git a/include/linux/cpu.h b/include/linux/cpu.h index c6f6e0839b61..9f3c7e81270a 100644 --- a/include/linux/cpu.h +++ b/include/linux/cpu.h @@ -175,6 +175,8 @@ extern struct bus_type cpu_subsys; extern void get_online_cpus(void); extern void put_online_cpus(void); +extern void cpu_hotplug_disable(void); +extern void cpu_hotplug_enable(void); #define hotcpu_notifier(fn, pri) cpu_notifier(fn, pri) #define register_hotcpu_notifier(nb) register_cpu_notifier(nb) #define unregister_hotcpu_notifier(nb) unregister_cpu_notifier(nb) @@ -198,6 +200,8 @@ static inline void cpu_hotplug_driver_unlock(void) #define get_online_cpus() do { } while (0) #define put_online_cpus() do { } while (0) +#define cpu_hotplug_disable() do { } while (0) +#define cpu_hotplug_enable() do { } while (0) #define hotcpu_notifier(fn, pri) do { (void)(fn); } while (0) /* These aren't inline functions due to a GCC bug. */ #define register_hotcpu_notifier(nb) ({ (void)(nb); 0; }) diff --git a/include/linux/filter.h b/include/linux/filter.h index c050dcc322a4..f65f5a69db8f 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -46,6 +46,7 @@ extern int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk); extern int sk_detach_filter(struct sock *sk); extern int sk_chk_filter(struct sock_filter *filter, unsigned int flen); extern int sk_get_filter(struct sock *sk, struct sock_filter __user *filter, unsigned len); +extern void sk_decode_filter(struct sock_filter *filt, struct sock_filter *to); #ifdef CONFIG_BPF_JIT #include <stdarg.h> diff --git a/include/linux/fs.h b/include/linux/fs.h index 43db02e9c9fa..65c2be22b601 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2414,8 +2414,6 @@ extern ssize_t generic_file_splice_write(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int); extern ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe, struct file *out, loff_t *, size_t len, unsigned int flags); -extern long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, - size_t len, unsigned int flags); extern void file_ra_state_init(struct file_ra_state *ra, struct address_space *mapping); diff --git a/include/linux/if_team.h b/include/linux/if_team.h index 4474557904f6..16fae6436d0e 100644 --- a/include/linux/if_team.h +++ b/include/linux/if_team.h @@ -249,12 +249,12 @@ team_get_first_port_txable_rcu(struct team *team, struct team_port *port) return port; cur = port; list_for_each_entry_continue_rcu(cur, &team->port_list, list) - if (team_port_txable(port)) + if (team_port_txable(cur)) return cur; list_for_each_entry_rcu(cur, &team->port_list, list) { if (cur == port) break; - if (team_port_txable(port)) + if (team_port_txable(cur)) return cur; } return NULL; diff --git a/include/linux/kernel.h b/include/linux/kernel.h index e96329ceb28c..e9ef6d6b51d5 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -562,6 +562,9 @@ int __trace_bprintk(unsigned long ip, const char *fmt, ...); extern __printf(2, 3) int __trace_printk(unsigned long ip, const char *fmt, ...); +extern int __trace_bputs(unsigned long ip, const char *str); +extern int __trace_puts(unsigned long ip, const char *str, int size); + /** * trace_puts - write a string into the ftrace buffer * @str: the string to record @@ -587,8 +590,6 @@ int __trace_printk(unsigned long ip, const char *fmt, ...); * (1 when __trace_bputs is used, strlen(str) when __trace_puts is used) */ -extern int __trace_bputs(unsigned long ip, const char *str); -extern int __trace_puts(unsigned long ip, const char *str, int size); #define trace_puts(str) ({ \ static const char *trace_printk_fmt \ __attribute__((section("__trace_printk_fmt"))) = \ diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index f0eea07d2c2b..8db53cfaccdb 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -23,6 +23,7 @@ #include <linux/ratelimit.h> #include <linux/err.h> #include <linux/irqflags.h> +#include <linux/context_tracking.h> #include <asm/signal.h> #include <linux/kvm.h> @@ -760,42 +761,6 @@ static inline int kvm_iommu_unmap_guest(struct kvm *kvm) } #endif -static inline void __guest_enter(void) -{ - /* - * This is running in ioctl context so we can avoid - * the call to vtime_account() with its unnecessary idle check. - */ - vtime_account_system(current); - current->flags |= PF_VCPU; -} - -static inline void __guest_exit(void) -{ - /* - * This is running in ioctl context so we can avoid - * the call to vtime_account() with its unnecessary idle check. - */ - vtime_account_system(current); - current->flags &= ~PF_VCPU; -} - -#ifdef CONFIG_CONTEXT_TRACKING -extern void guest_enter(void); -extern void guest_exit(void); - -#else /* !CONFIG_CONTEXT_TRACKING */ -static inline void guest_enter(void) -{ - __guest_enter(); -} - -static inline void guest_exit(void) -{ - __guest_exit(); -} -#endif /* !CONFIG_CONTEXT_TRACKING */ - static inline void kvm_guest_enter(void) { unsigned long flags; diff --git a/include/linux/list.h b/include/linux/list.h index 6a1f8df9144b..b83e5657365a 100644 --- a/include/linux/list.h +++ b/include/linux/list.h @@ -362,6 +362,17 @@ static inline void list_splice_tail_init(struct list_head *list, list_entry((ptr)->next, type, member) /** + * list_first_entry_or_null - get the first element from a list + * @ptr: the list head to take the element from. + * @type: the type of the struct this is embedded in. + * @member: the name of the list_struct within the struct. + * + * Note that if the list is empty, it returns NULL. + */ +#define list_first_entry_or_null(ptr, type, member) \ + (!list_empty(ptr) ? list_first_entry(ptr, type, member) : NULL) + +/** * list_for_each - iterate over a list * @pos: the &struct list_head to use as a loop cursor. * @head: the head for your list. diff --git a/include/linux/math64.h b/include/linux/math64.h index b8ba85544721..2913b86eb12a 100644 --- a/include/linux/math64.h +++ b/include/linux/math64.h @@ -6,7 +6,8 @@ #if BITS_PER_LONG == 64 -#define div64_long(x,y) div64_s64((x),(y)) +#define div64_long(x, y) div64_s64((x), (y)) +#define div64_ul(x, y) div64_u64((x), (y)) /** * div_u64_rem - unsigned 64bit divide with 32bit divisor with remainder @@ -47,7 +48,8 @@ static inline s64 div64_s64(s64 dividend, s64 divisor) #elif BITS_PER_LONG == 32 -#define div64_long(x,y) div_s64((x),(y)) +#define div64_long(x, y) div_s64((x), (y)) +#define div64_ul(x, y) div_u64((x), (y)) #ifndef div_u64_rem static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index a94a5a0ab122..60584b185a0c 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -2733,6 +2733,17 @@ static inline netdev_features_t netdev_get_wanted_features( } netdev_features_t netdev_increment_features(netdev_features_t all, netdev_features_t one, netdev_features_t mask); + +/* Allow TSO being used on stacked device : + * Performing the GSO segmentation before last device + * is a performance improvement. + */ +static inline netdev_features_t netdev_add_tso_features(netdev_features_t features, + netdev_features_t mask) +{ + return netdev_increment_features(features, NETIF_F_ALL_TSO, mask); +} + int __netdev_update_features(struct net_device *dev); void netdev_update_features(struct net_device *dev); void netdev_change_features(struct net_device *dev); diff --git a/include/linux/netfilter_ipv6.h b/include/linux/netfilter_ipv6.h index 98ffb54988b6..2d4df6ce043e 100644 --- a/include/linux/netfilter_ipv6.h +++ b/include/linux/netfilter_ipv6.h @@ -17,6 +17,22 @@ extern __sum16 nf_ip6_checksum(struct sk_buff *skb, unsigned int hook, extern int ipv6_netfilter_init(void); extern void ipv6_netfilter_fini(void); + +/* + * Hook functions for ipv6 to allow xt_* modules to be built-in even + * if IPv6 is a module. + */ +struct nf_ipv6_ops { + int (*chk_addr)(struct net *net, const struct in6_addr *addr, + const struct net_device *dev, int strict); +}; + +extern const struct nf_ipv6_ops __rcu *nf_ipv6_ops; +static inline const struct nf_ipv6_ops *nf_get_ipv6_ops(void) +{ + return rcu_dereference(nf_ipv6_ops); +} + #else /* CONFIG_NETFILTER */ static inline int ipv6_netfilter_init(void) { return 0; } static inline void ipv6_netfilter_fini(void) { return; } diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index f463a46424e2..c5b6dbf9c2fc 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -389,8 +389,7 @@ struct perf_event { /* mmap bits */ struct mutex mmap_mutex; atomic_t mmap_count; - int mmap_locked; - struct user_struct *mmap_user; + struct ring_buffer *rb; struct list_head rb_entry; diff --git a/include/linux/platform_data/clk-lpss.h b/include/linux/platform_data/clk-lpss.h index 528e73ce46d2..23901992b9dd 100644 --- a/include/linux/platform_data/clk-lpss.h +++ b/include/linux/platform_data/clk-lpss.h @@ -13,6 +13,11 @@ #ifndef __CLK_LPSS_H #define __CLK_LPSS_H +struct lpss_clk_data { + const char *name; + struct clk *clk; +}; + extern int lpt_clk_init(void); #endif /* __CLK_LPSS_H */ diff --git a/include/linux/platform_data/serial-omap.h b/include/linux/platform_data/serial-omap.h index ff9b0aab5281..c860c1b314c0 100644 --- a/include/linux/platform_data/serial-omap.h +++ b/include/linux/platform_data/serial-omap.h @@ -43,8 +43,6 @@ struct omap_uart_port_info { int DTR_present; int (*get_context_loss_count)(struct device *); - void (*set_forceidle)(struct device *); - void (*set_noidle)(struct device *); void (*enable_wakeup)(struct device *, bool); }; diff --git a/include/linux/preempt.h b/include/linux/preempt.h index 87a03c746f17..f5d4723cdb3d 100644 --- a/include/linux/preempt.h +++ b/include/linux/preempt.h @@ -33,9 +33,25 @@ do { \ preempt_schedule(); \ } while (0) +#ifdef CONFIG_CONTEXT_TRACKING + +void preempt_schedule_context(void); + +#define preempt_check_resched_context() \ +do { \ + if (unlikely(test_thread_flag(TIF_NEED_RESCHED))) \ + preempt_schedule_context(); \ +} while (0) +#else + +#define preempt_check_resched_context() preempt_check_resched() + +#endif /* CONFIG_CONTEXT_TRACKING */ + #else /* !CONFIG_PREEMPT */ #define preempt_check_resched() do { } while (0) +#define preempt_check_resched_context() do { } while (0) #endif /* CONFIG_PREEMPT */ @@ -88,7 +104,7 @@ do { \ do { \ preempt_enable_no_resched_notrace(); \ barrier(); \ - preempt_check_resched(); \ + preempt_check_resched_context(); \ } while (0) #else /* !CONFIG_PREEMPT_COUNT */ diff --git a/include/linux/rculist.h b/include/linux/rculist.h index 8089e35d47ac..f4b1001a4676 100644 --- a/include/linux/rculist.h +++ b/include/linux/rculist.h @@ -461,6 +461,26 @@ static inline void hlist_add_after_rcu(struct hlist_node *prev, &(pos)->member)), typeof(*(pos)), member)) /** + * hlist_for_each_entry_rcu_notrace - iterate over rcu list of given type (for tracing) + * @pos: the type * to use as a loop cursor. + * @head: the head for your list. + * @member: the name of the hlist_node within the struct. + * + * This list-traversal primitive may safely run concurrently with + * the _rcu list-mutation primitives such as hlist_add_head_rcu() + * as long as the traversal is guarded by rcu_read_lock(). + * + * This is the same as hlist_for_each_entry_rcu() except that it does + * not do any RCU debugging or tracing. + */ +#define hlist_for_each_entry_rcu_notrace(pos, head, member) \ + for (pos = hlist_entry_safe (rcu_dereference_raw_notrace(hlist_first_rcu(head)),\ + typeof(*(pos)), member); \ + pos; \ + pos = hlist_entry_safe(rcu_dereference_raw_notrace(hlist_next_rcu(\ + &(pos)->member)), typeof(*(pos)), member)) + +/** * hlist_for_each_entry_rcu_bh - iterate over rcu list of given type * @pos: the type * to use as a loop cursor. * @head: the head for your list. diff --git a/include/linux/rculist_nulls.h b/include/linux/rculist_nulls.h index 2ae13714828b..1c33dd7da4a7 100644 --- a/include/linux/rculist_nulls.h +++ b/include/linux/rculist_nulls.h @@ -105,9 +105,14 @@ static inline void hlist_nulls_add_head_rcu(struct hlist_nulls_node *n, * @head: the head for your list. * @member: the name of the hlist_nulls_node within the struct. * + * The barrier() is needed to make sure compiler doesn't cache first element [1], + * as this loop can be restarted [2] + * [1] Documentation/atomic_ops.txt around line 114 + * [2] Documentation/RCU/rculist_nulls.txt around line 146 */ #define hlist_nulls_for_each_entry_rcu(tpos, pos, head, member) \ - for (pos = rcu_dereference_raw(hlist_nulls_first_rcu(head)); \ + for (({barrier();}), \ + pos = rcu_dereference_raw(hlist_nulls_first_rcu(head)); \ (!is_a_nulls(pos)) && \ ({ tpos = hlist_nulls_entry(pos, typeof(*tpos), member); 1; }); \ pos = rcu_dereference_raw(hlist_nulls_next_rcu(pos))) diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index 4ccd68e49b00..ddcc7826d907 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -640,6 +640,15 @@ static inline void rcu_preempt_sleep_check(void) #define rcu_dereference_raw(p) rcu_dereference_check(p, 1) /*@@@ needed? @@@*/ +/* + * The tracing infrastructure traces RCU (we want that), but unfortunately + * some of the RCU checks causes tracing to lock up the system. + * + * The tracing version of rcu_dereference_raw() must not call + * rcu_read_lock_held(). + */ +#define rcu_dereference_raw_notrace(p) __rcu_dereference_check((p), 1, __rcu) + /** * rcu_access_index() - fetch RCU index with no dereferencing * @p: The index to read diff --git a/include/linux/rio.h b/include/linux/rio.h index a3e784278667..18e099342e6f 100644 --- a/include/linux/rio.h +++ b/include/linux/rio.h @@ -83,7 +83,6 @@ extern struct bus_type rio_bus_type; extern struct device rio_bus; -extern struct list_head rio_devices; /* list of all devices */ struct rio_mport; struct rio_dev; @@ -237,6 +236,7 @@ enum rio_phy_type { * @name: Port name string * @priv: Master port private data * @dma: DMA device associated with mport + * @nscan: RapidIO network enumeration/discovery operations */ struct rio_mport { struct list_head dbells; /* list of doorbell events */ @@ -262,8 +262,14 @@ struct rio_mport { #ifdef CONFIG_RAPIDIO_DMA_ENGINE struct dma_device dma; #endif + struct rio_scan *nscan; }; +/* + * Enumeration/discovery control flags + */ +#define RIO_SCAN_ENUM_NO_WAIT 0x00000001 /* Do not wait for enum completed */ + struct rio_id_table { u16 start; /* logical minimal id */ u32 max; /* max number of IDs in table */ @@ -460,6 +466,16 @@ static inline struct rio_mport *dma_to_mport(struct dma_device *ddev) } #endif /* CONFIG_RAPIDIO_DMA_ENGINE */ +/** + * struct rio_scan - RIO enumeration and discovery operations + * @enumerate: Callback to perform RapidIO fabric enumeration. + * @discover: Callback to perform RapidIO fabric discovery. + */ +struct rio_scan { + int (*enumerate)(struct rio_mport *mport, u32 flags); + int (*discover)(struct rio_mport *mport, u32 flags); +}; + /* Architecture and hardware-specific functions */ extern int rio_register_mport(struct rio_mport *); extern int rio_open_inb_mbox(struct rio_mport *, void *, int, int); diff --git a/include/linux/rio_drv.h b/include/linux/rio_drv.h index b75c05920ab5..5059994fe297 100644 --- a/include/linux/rio_drv.h +++ b/include/linux/rio_drv.h @@ -433,5 +433,6 @@ extern u16 rio_local_get_device_id(struct rio_mport *port); extern struct rio_dev *rio_get_device(u16 vid, u16 did, struct rio_dev *from); extern struct rio_dev *rio_get_asm(u16 vid, u16 did, u16 asm_vid, u16 asm_did, struct rio_dev *from); +extern int rio_init_mports(void); #endif /* LINUX_RIO_DRV_H */ diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h index 5951e3f38878..26806775b11b 100644 --- a/include/linux/scatterlist.h +++ b/include/linux/scatterlist.h @@ -111,6 +111,9 @@ static inline struct page *sg_page(struct scatterlist *sg) static inline void sg_set_buf(struct scatterlist *sg, const void *buf, unsigned int buflen) { +#ifdef CONFIG_DEBUG_SG + BUG_ON(!virt_addr_valid(buf)); +#endif sg_set_page(sg, virt_to_page(buf), buflen, offset_in_page(buf)); } diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 2e0ced1af3b1..9c676eae3968 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -2852,6 +2852,21 @@ static inline int skb_tnl_header_len(const struct sk_buff *inner_skb) SKB_GSO_CB(inner_skb)->mac_offset; } +static inline int gso_pskb_expand_head(struct sk_buff *skb, int extra) +{ + int new_headroom, headroom; + int ret; + + headroom = skb_headroom(skb); + ret = pskb_expand_head(skb, extra, 0, GFP_ATOMIC); + if (ret) + return ret; + + new_headroom = skb_headroom(skb); + SKB_GSO_CB(skb)->mac_offset += (new_headroom - headroom); + return 0; +} + static inline bool skb_is_gso(const struct sk_buff *skb) { return skb_shinfo(skb)->gso_size; diff --git a/include/linux/smp.h b/include/linux/smp.h index e6564c1dc552..c8488763277f 100644 --- a/include/linux/smp.h +++ b/include/linux/smp.h @@ -11,6 +11,7 @@ #include <linux/list.h> #include <linux/cpumask.h> #include <linux/init.h> +#include <linux/irqflags.h> extern void cpu_idle(void); @@ -139,13 +140,17 @@ static inline int up_smp_call_function(smp_call_func_t func, void *info) } #define smp_call_function(func, info, wait) \ (up_smp_call_function(func, info)) -#define on_each_cpu(func,info,wait) \ - ({ \ - local_irq_disable(); \ - func(info); \ - local_irq_enable(); \ - 0; \ - }) + +static inline int on_each_cpu(smp_call_func_t func, void *info, int wait) +{ + unsigned long flags; + + local_irq_save(flags); + func(info); + local_irq_restore(flags); + return 0; +} + /* * Note we still need to test the mask even for UP * because we actually can get an empty mask from diff --git a/include/linux/socket.h b/include/linux/socket.h index 33bf2dfab19d..b10ce4b341ea 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -320,6 +320,9 @@ extern int put_cmsg(struct msghdr*, int level, int type, int len, void *data); struct timespec; +/* The __sys_...msg variants allow MSG_CMSG_COMPAT */ +extern long __sys_recvmsg(int fd, struct msghdr __user *msg, unsigned flags); +extern long __sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags); extern int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, unsigned int flags, struct timespec *timeout); extern int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, diff --git a/include/linux/splice.h b/include/linux/splice.h index 09a545a7dfa3..74575cbf2d6f 100644 --- a/include/linux/splice.h +++ b/include/linux/splice.h @@ -35,6 +35,7 @@ struct splice_desc { void *data; /* cookie */ } u; loff_t pos; /* file position */ + loff_t *opos; /* sendfile: output position */ size_t num_spliced; /* number of bytes already spliced */ bool need_wakeup; /* need to wake up writer */ }; diff --git a/include/linux/swapops.h b/include/linux/swapops.h index 47ead515c811..c5fd30d2a415 100644 --- a/include/linux/swapops.h +++ b/include/linux/swapops.h @@ -137,6 +137,7 @@ static inline void make_migration_entry_read(swp_entry_t *entry) extern void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd, unsigned long address); +extern void migration_entry_wait_huge(struct mm_struct *mm, pte_t *pte); #else #define make_migration_entry(page, write) swp_entry(0, 0) @@ -148,6 +149,8 @@ static inline int is_migration_entry(swp_entry_t swp) static inline void make_migration_entry_read(swp_entry_t *entryp) { } static inline void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd, unsigned long address) { } +static inline void migration_entry_wait_huge(struct mm_struct *mm, + pte_t *pte) { } static inline int is_write_migration_entry(swp_entry_t entry) { return 0; diff --git a/include/linux/syslog.h b/include/linux/syslog.h index 38911391a139..98a3153c0f96 100644 --- a/include/linux/syslog.h +++ b/include/linux/syslog.h @@ -44,8 +44,8 @@ /* Return size of the log buffer */ #define SYSLOG_ACTION_SIZE_BUFFER 10 -#define SYSLOG_FROM_CALL 0 -#define SYSLOG_FROM_FILE 1 +#define SYSLOG_FROM_READER 0 +#define SYSLOG_FROM_PROC 1 int do_syslog(int type, char __user *buf, int count, bool from_file); diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h index 2f322c38bd4d..f8e084d0fc77 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h @@ -145,8 +145,8 @@ static inline void tracepoint_synchronize_unregister(void) TP_PROTO(data_proto), \ TP_ARGS(data_args), \ TP_CONDITION(cond), \ - rcu_idle_exit(), \ - rcu_idle_enter()); \ + rcu_irq_enter(), \ + rcu_irq_exit()); \ } #else #define __DECLARE_TRACE_RCU(name, proto, args, cond, data_proto, data_args) diff --git a/include/linux/vtime.h b/include/linux/vtime.h index 71a5782d8c59..b1dd2db80076 100644 --- a/include/linux/vtime.h +++ b/include/linux/vtime.h @@ -34,7 +34,7 @@ static inline void vtime_user_exit(struct task_struct *tsk) } extern void vtime_guest_enter(struct task_struct *tsk); extern void vtime_guest_exit(struct task_struct *tsk); -extern void vtime_init_idle(struct task_struct *tsk); +extern void vtime_init_idle(struct task_struct *tsk, int cpu); #else static inline void vtime_account_irq_exit(struct task_struct *tsk) { @@ -45,7 +45,7 @@ static inline void vtime_user_enter(struct task_struct *tsk) { } static inline void vtime_user_exit(struct task_struct *tsk) { } static inline void vtime_guest_enter(struct task_struct *tsk) { } static inline void vtime_guest_exit(struct task_struct *tsk) { } -static inline void vtime_init_idle(struct task_struct *tsk) { } +static inline void vtime_init_idle(struct task_struct *tsk, int cpu) { } #endif #ifdef CONFIG_IRQ_TIME_ACCOUNTING diff --git a/include/linux/wait.h b/include/linux/wait.h index ac38be2692d8..1133695eb067 100644 --- a/include/linux/wait.h +++ b/include/linux/wait.h @@ -217,6 +217,8 @@ do { \ if (!ret) \ break; \ } \ + if (!ret && (condition)) \ + ret = 1; \ finish_wait(&wq, &__wait); \ } while (0) @@ -233,8 +235,9 @@ do { \ * wake_up() has to be called after changing any variable that could * change the result of the wait condition. * - * The function returns 0 if the @timeout elapsed, and the remaining - * jiffies if the condition evaluated to true before the timeout elapsed. + * The function returns 0 if the @timeout elapsed, or the remaining + * jiffies (at least 1) if the @condition evaluated to %true before + * the @timeout elapsed. */ #define wait_event_timeout(wq, condition, timeout) \ ({ \ @@ -302,6 +305,8 @@ do { \ ret = -ERESTARTSYS; \ break; \ } \ + if (!ret && (condition)) \ + ret = 1; \ finish_wait(&wq, &__wait); \ } while (0) @@ -318,9 +323,10 @@ do { \ * wake_up() has to be called after changing any variable that could * change the result of the wait condition. * - * The function returns 0 if the @timeout elapsed, -ERESTARTSYS if it - * was interrupted by a signal, and the remaining jiffies otherwise - * if the condition evaluated to true before the timeout elapsed. + * Returns: + * 0 if the @timeout elapsed, -%ERESTARTSYS if it was interrupted by + * a signal, or the remaining jiffies (at least 1) if the @condition + * evaluated to %true before the @timeout elapsed. */ #define wait_event_interruptible_timeout(wq, condition, timeout) \ ({ \ diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h index d3eef01da648..0f4555b2a31b 100644 --- a/include/media/v4l2-mem2mem.h +++ b/include/media/v4l2-mem2mem.h @@ -110,6 +110,8 @@ int v4l2_m2m_qbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, struct v4l2_buffer *buf); int v4l2_m2m_dqbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, struct v4l2_buffer *buf); +int v4l2_m2m_create_bufs(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, + struct v4l2_create_buffers *create); int v4l2_m2m_expbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, struct v4l2_exportbuffer *eb); diff --git a/include/net/addrconf.h b/include/net/addrconf.h index 84a6440f1f19..21f702704f24 100644 --- a/include/net/addrconf.h +++ b/include/net/addrconf.h @@ -65,7 +65,7 @@ extern int addrconf_set_dstaddr(struct net *net, extern int ipv6_chk_addr(struct net *net, const struct in6_addr *addr, - struct net_device *dev, + const struct net_device *dev, int strict); #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 35a57cd1704c..7cb6d360d147 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -1117,6 +1117,7 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event); int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len); int mgmt_index_added(struct hci_dev *hdev); int mgmt_index_removed(struct hci_dev *hdev); +int mgmt_set_powered_failed(struct hci_dev *hdev, int err); int mgmt_powered(struct hci_dev *hdev, u8 powered); int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable); int mgmt_connectable(struct hci_dev *hdev, u8 connectable); diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h index 22980a7c3873..9944c3e68c5d 100644 --- a/include/net/bluetooth/mgmt.h +++ b/include/net/bluetooth/mgmt.h @@ -42,6 +42,7 @@ #define MGMT_STATUS_NOT_POWERED 0x0f #define MGMT_STATUS_CANCELLED 0x10 #define MGMT_STATUS_INVALID_INDEX 0x11 +#define MGMT_STATUS_RFKILLED 0x12 struct mgmt_hdr { __le16 opcode; diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h index 4b6f0b28f41f..09b1360e10bf 100644 --- a/include/net/ip_tunnels.h +++ b/include/net/ip_tunnels.h @@ -95,10 +95,10 @@ struct ip_tunnel_net { int ip_tunnel_init(struct net_device *dev); void ip_tunnel_uninit(struct net_device *dev); void ip_tunnel_dellink(struct net_device *dev, struct list_head *head); -int __net_init ip_tunnel_init_net(struct net *net, int ip_tnl_net_id, - struct rtnl_link_ops *ops, char *devname); +int ip_tunnel_init_net(struct net *net, int ip_tnl_net_id, + struct rtnl_link_ops *ops, char *devname); -void __net_exit ip_tunnel_delete_net(struct ip_tunnel_net *itn); +void ip_tunnel_delete_net(struct ip_tunnel_net *itn); void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, const struct iphdr *tnl_params); diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 04c2d4670dc6..885898a40d13 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -3043,7 +3043,8 @@ void ieee80211_napi_complete(struct ieee80211_hw *hw); * This function may not be called in IRQ context. Calls to this function * for a single hardware must be synchronized against each other. Calls to * this function, ieee80211_rx_ni() and ieee80211_rx_irqsafe() may not be - * mixed for a single hardware. + * mixed for a single hardware. Must not run concurrently with + * ieee80211_tx_status() or ieee80211_tx_status_ni(). * * In process context use instead ieee80211_rx_ni(). * @@ -3059,7 +3060,8 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb); * (internally defers to a tasklet.) * * Calls to this function, ieee80211_rx() or ieee80211_rx_ni() may not - * be mixed for a single hardware. + * be mixed for a single hardware.Must not run concurrently with + * ieee80211_tx_status() or ieee80211_tx_status_ni(). * * @hw: the hardware this frame came in on * @skb: the buffer to receive, owned by mac80211 after this call @@ -3073,7 +3075,8 @@ void ieee80211_rx_irqsafe(struct ieee80211_hw *hw, struct sk_buff *skb); * (internally disables bottom halves). * * Calls to this function, ieee80211_rx() and ieee80211_rx_irqsafe() may - * not be mixed for a single hardware. + * not be mixed for a single hardware. Must not run concurrently with + * ieee80211_tx_status() or ieee80211_tx_status_ni(). * * @hw: the hardware this frame came in on * @skb: the buffer to receive, owned by mac80211 after this call @@ -3196,7 +3199,8 @@ void ieee80211_get_tx_rates(struct ieee80211_vif *vif, * This function may not be called in IRQ context. Calls to this function * for a single hardware must be synchronized against each other. Calls * to this function, ieee80211_tx_status_ni() and ieee80211_tx_status_irqsafe() - * may not be mixed for a single hardware. + * may not be mixed for a single hardware. Must not run concurrently with + * ieee80211_rx() or ieee80211_rx_ni(). * * @hw: the hardware the frame was transmitted by * @skb: the frame that was transmitted, owned by mac80211 after this call diff --git a/include/net/netfilter/nf_log.h b/include/net/netfilter/nf_log.h index 31f1fb9eb784..99eac12d040b 100644 --- a/include/net/netfilter/nf_log.h +++ b/include/net/netfilter/nf_log.h @@ -30,7 +30,8 @@ struct nf_loginfo { } u; }; -typedef void nf_logfn(u_int8_t pf, +typedef void nf_logfn(struct net *net, + u_int8_t pf, unsigned int hooknum, const struct sk_buff *skb, const struct net_device *in, diff --git a/include/net/netfilter/nfnetlink_log.h b/include/net/netfilter/nfnetlink_log.h index e2dec42c2db2..5ca3f14f0998 100644 --- a/include/net/netfilter/nfnetlink_log.h +++ b/include/net/netfilter/nfnetlink_log.h @@ -2,7 +2,8 @@ #define _KER_NFNETLINK_LOG_H void -nfulnl_log_packet(u_int8_t pf, +nfulnl_log_packet(struct net *net, + u_int8_t pf, unsigned int hooknum, const struct sk_buff *skb, const struct net_device *in, diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index f10818fc8804..e7f4e21cc3e1 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -679,22 +679,26 @@ static inline struct sk_buff *skb_act_clone(struct sk_buff *skb, gfp_t gfp_mask, #endif struct psched_ratecfg { - u64 rate_bps; - u32 mult; - u32 shift; + u64 rate_bps; + u32 mult; + u16 overhead; + u8 shift; }; static inline u64 psched_l2t_ns(const struct psched_ratecfg *r, unsigned int len) { - return ((u64)len * r->mult) >> r->shift; + return ((u64)(len + r->overhead) * r->mult) >> r->shift; } -extern void psched_ratecfg_precompute(struct psched_ratecfg *r, u32 rate); +extern void psched_ratecfg_precompute(struct psched_ratecfg *r, const struct tc_ratespec *conf); -static inline u32 psched_ratecfg_getrate(const struct psched_ratecfg *r) +static inline void psched_ratecfg_getrate(struct tc_ratespec *res, + const struct psched_ratecfg *r) { - return r->rate_bps >> 3; + memset(res, 0, sizeof(*res)); + res->rate = r->rate_bps >> 3; + res->overhead = r->overhead; } #endif diff --git a/include/net/xfrm.h b/include/net/xfrm.h index ae16531d0d35..94ce082b29dc 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -1160,6 +1160,8 @@ static inline void xfrm_sk_free_policy(struct sock *sk) } } +extern void xfrm_garbage_collect(struct net *net); + #else static inline void xfrm_sk_free_policy(struct sock *sk) {} @@ -1194,6 +1196,9 @@ static inline int xfrm6_policy_check_reverse(struct sock *sk, int dir, { return 1; } +static inline void xfrm_garbage_collect(struct net *net) +{ +} #endif static __inline__ diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index d4609029f014..385c6329a967 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h @@ -450,7 +450,8 @@ enum snd_soc_dapm_type { snd_soc_dapm_aif_in, /* audio interface input */ snd_soc_dapm_aif_out, /* audio interface output */ snd_soc_dapm_siggen, /* signal generator */ - snd_soc_dapm_dai, /* link to DAI structure */ + snd_soc_dapm_dai_in, /* link to DAI structure */ + snd_soc_dapm_dai_out, snd_soc_dapm_dai_link, /* link between two DAI structures */ }; diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index e773dfa5f98f..4ea4f985f394 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h @@ -543,6 +543,7 @@ struct se_session { struct list_head sess_list; struct list_head sess_acl_list; struct list_head sess_cmd_list; + struct list_head sess_wait_list; spinlock_t sess_cmd_lock; struct kref sess_kref; }; diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h index ba3471b73c07..1dcce9cc99b9 100644 --- a/include/target/target_core_fabric.h +++ b/include/target/target_core_fabric.h @@ -114,7 +114,7 @@ sense_reason_t transport_generic_new_cmd(struct se_cmd *); void target_execute_cmd(struct se_cmd *cmd); -void transport_generic_free_cmd(struct se_cmd *, int); +int transport_generic_free_cmd(struct se_cmd *, int); bool transport_wait_for_tasks(struct se_cmd *); int transport_check_aborted_status(struct se_cmd *, int); @@ -123,7 +123,7 @@ int transport_send_check_condition_and_sense(struct se_cmd *, int target_get_sess_cmd(struct se_session *, struct se_cmd *, bool); int target_put_sess_cmd(struct se_session *, struct se_cmd *); void target_sess_cmd_list_set_waiting(struct se_session *); -void target_wait_for_sess_cmds(struct se_session *, int); +void target_wait_for_sess_cmds(struct se_session *); int core_alua_check_nonop_delay(struct se_cmd *); diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index a5c86fc34a37..d88c8ee00c8b 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -783,6 +783,7 @@ struct kvm_dirty_tlb { #define KVM_REG_IA64 0x3000000000000000ULL #define KVM_REG_ARM 0x4000000000000000ULL #define KVM_REG_S390 0x5000000000000000ULL +#define KVM_REG_MIPS 0x7000000000000000ULL #define KVM_REG_SIZE_SHIFT 52 #define KVM_REG_SIZE_MASK 0x00f0000000000000ULL diff --git a/include/video/omapdss.h b/include/video/omapdss.h index 62ca9a77c1d6..aeb4e9a0c5d1 100644 --- a/include/video/omapdss.h +++ b/include/video/omapdss.h @@ -748,6 +748,7 @@ struct omap_dss_driver { }; enum omapdss_version omapdss_get_version(void); +bool omapdss_is_initialized(void); int omap_dss_register_driver(struct omap_dss_driver *); void omap_dss_unregister_driver(struct omap_dss_driver *); diff --git a/include/xen/xenbus.h b/include/xen/xenbus.h index 0a7515c1e3a4..569c07f2e344 100644 --- a/include/xen/xenbus.h +++ b/include/xen/xenbus.h @@ -70,6 +70,7 @@ struct xenbus_device { struct device dev; enum xenbus_state state; struct completion down; + struct work_struct work; }; static inline struct xenbus_device *to_xenbus_device(struct device *dev) diff --git a/init/Kconfig b/init/Kconfig index 9d3a7887a6d3..2d9b83104dcf 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -431,6 +431,7 @@ choice config TREE_RCU bool "Tree-based hierarchical RCU" depends on !PREEMPT && SMP + select IRQ_WORK help This option selects the RCU implementation that is designed for very large SMP system with hundreds or diff --git a/ipc/sem.c b/ipc/sem.c index a7e40ed8a076..70480a3aa698 100644 --- a/ipc/sem.c +++ b/ipc/sem.c @@ -752,19 +752,29 @@ static void do_smart_update(struct sem_array *sma, struct sembuf *sops, int nsop int otime, struct list_head *pt) { int i; + int progress; - if (sma->complex_count || sops == NULL) { - if (update_queue(sma, -1, pt)) + progress = 1; +retry_global: + if (sma->complex_count) { + if (update_queue(sma, -1, pt)) { + progress = 1; otime = 1; + sops = NULL; + } } + if (!progress) + goto done; if (!sops) { /* No semops; something special is going on. */ for (i = 0; i < sma->sem_nsems; i++) { - if (update_queue(sma, i, pt)) + if (update_queue(sma, i, pt)) { otime = 1; + progress = 1; + } } - goto done; + goto done_checkretry; } /* Check the semaphores that were modified. */ @@ -772,8 +782,15 @@ static void do_smart_update(struct sem_array *sma, struct sembuf *sops, int nsop if (sops[i].sem_op > 0 || (sops[i].sem_op < 0 && sma->sem_base[sops[i].sem_num].semval == 0)) - if (update_queue(sma, sops[i].sem_num, pt)) + if (update_queue(sma, sops[i].sem_num, pt)) { otime = 1; + progress = 1; + } + } +done_checkretry: + if (progress) { + progress = 0; + goto retry_global; } done: if (otime) diff --git a/kernel/audit.c b/kernel/audit.c index 21c7fa615bd3..91e53d04b6a9 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -1056,7 +1056,7 @@ static inline void audit_get_stamp(struct audit_context *ctx, static void wait_for_auditd(unsigned long sleep_time) { DECLARE_WAITQUEUE(wait, current); - set_current_state(TASK_INTERRUPTIBLE); + set_current_state(TASK_UNINTERRUPTIBLE); add_wait_queue(&audit_backlog_wait, &wait); if (audit_backlog_limit && diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c index a291aa23fb3f..43c307dc9453 100644 --- a/kernel/audit_tree.c +++ b/kernel/audit_tree.c @@ -658,6 +658,7 @@ int audit_add_tree_rule(struct audit_krule *rule) struct vfsmount *mnt; int err; + rule->tree = NULL; list_for_each_entry(tree, &tree_list, list) { if (!strcmp(seed->pathname, tree->pathname)) { put_tree(seed); diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 83a2970295d1..6bd4a90d1991 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c @@ -1021,9 +1021,6 @@ static void audit_log_rule_change(char *action, struct audit_krule *rule, int re * @seq: netlink audit message sequence (serial) number * @data: payload data * @datasz: size of payload data - * @loginuid: loginuid of sender - * @sessionid: sessionid for netlink audit message - * @sid: SE Linux Security ID of sender */ int audit_receive_filter(int type, int pid, int seq, void *data, size_t datasz) { diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 2a9926275f80..a7c9e6ddb979 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -1686,11 +1686,14 @@ static struct dentry *cgroup_mount(struct file_system_type *fs_type, */ cgroup_drop_root(opts.new_root); - if (((root->flags | opts.flags) & CGRP_ROOT_SANE_BEHAVIOR) && - root->flags != opts.flags) { - pr_err("cgroup: sane_behavior: new mount options should match the existing superblock\n"); - ret = -EINVAL; - goto drop_new_super; + if (root->flags != opts.flags) { + if ((root->flags | opts.flags) & CGRP_ROOT_SANE_BEHAVIOR) { + pr_err("cgroup: sane_behavior: new mount options should match the existing superblock\n"); + ret = -EINVAL; + goto drop_new_super; + } else { + pr_warning("cgroup: new mount options do not match the existing superblock, will be ignored\n"); + } } /* no subsys rebinding, so refcounts don't change */ @@ -2699,13 +2702,14 @@ static int cgroup_add_file(struct cgroup *cgrp, struct cgroup_subsys *subsys, goto out; } + cfe->type = (void *)cft; + cfe->dentry = dentry; + dentry->d_fsdata = cfe; + simple_xattrs_init(&cfe->xattrs); + mode = cgroup_file_mode(cft); error = cgroup_create_file(dentry, mode | S_IFREG, cgrp->root->sb); if (!error) { - cfe->type = (void *)cft; - cfe->dentry = dentry; - dentry->d_fsdata = cfe; - simple_xattrs_init(&cfe->xattrs); list_add_tail(&cfe->node, &parent->files); cfe = NULL; } @@ -2953,11 +2957,8 @@ struct cgroup *cgroup_next_descendant_pre(struct cgroup *pos, WARN_ON_ONCE(!rcu_read_lock_held()); /* if first iteration, pretend we just visited @cgroup */ - if (!pos) { - if (list_empty(&cgroup->children)) - return NULL; + if (!pos) pos = cgroup; - } /* visit the first child if exists */ next = list_first_or_null_rcu(&pos->children, struct cgroup, sibling); @@ -2965,14 +2966,14 @@ struct cgroup *cgroup_next_descendant_pre(struct cgroup *pos, return next; /* no child, visit my or the closest ancestor's next sibling */ - do { + while (pos != cgroup) { next = list_entry_rcu(pos->sibling.next, struct cgroup, sibling); if (&next->sibling != &pos->parent->children) return next; pos = pos->parent; - } while (pos != cgroup); + } return NULL; } diff --git a/kernel/context_tracking.c b/kernel/context_tracking.c index 65349f07b878..383f8231e436 100644 --- a/kernel/context_tracking.c +++ b/kernel/context_tracking.c @@ -15,7 +15,6 @@ */ #include <linux/context_tracking.h> -#include <linux/kvm_host.h> #include <linux/rcupdate.h> #include <linux/sched.h> #include <linux/hardirq.h> @@ -71,6 +70,46 @@ void user_enter(void) local_irq_restore(flags); } +#ifdef CONFIG_PREEMPT +/** + * preempt_schedule_context - preempt_schedule called by tracing + * + * The tracing infrastructure uses preempt_enable_notrace to prevent + * recursion and tracing preempt enabling caused by the tracing + * infrastructure itself. But as tracing can happen in areas coming + * from userspace or just about to enter userspace, a preempt enable + * can occur before user_exit() is called. This will cause the scheduler + * to be called when the system is still in usermode. + * + * To prevent this, the preempt_enable_notrace will use this function + * instead of preempt_schedule() to exit user context if needed before + * calling the scheduler. + */ +void __sched notrace preempt_schedule_context(void) +{ + struct thread_info *ti = current_thread_info(); + enum ctx_state prev_ctx; + + if (likely(ti->preempt_count || irqs_disabled())) + return; + + /* + * Need to disable preemption in case user_exit() is traced + * and the tracer calls preempt_enable_notrace() causing + * an infinite recursion. + */ + preempt_disable_notrace(); + prev_ctx = exception_enter(); + preempt_enable_no_resched_notrace(); + + preempt_schedule(); + + preempt_disable_notrace(); + exception_exit(prev_ctx); + preempt_enable_notrace(); +} +EXPORT_SYMBOL_GPL(preempt_schedule_context); +#endif /* CONFIG_PREEMPT */ /** * user_exit - Inform the context tracking that the CPU is diff --git a/kernel/cpu.c b/kernel/cpu.c index b5e4ab2d427e..198a38883e64 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c @@ -133,6 +133,27 @@ static void cpu_hotplug_done(void) mutex_unlock(&cpu_hotplug.lock); } +/* + * Wait for currently running CPU hotplug operations to complete (if any) and + * disable future CPU hotplug (from sysfs). The 'cpu_add_remove_lock' protects + * the 'cpu_hotplug_disabled' flag. The same lock is also acquired by the + * hotplug path before performing hotplug operations. So acquiring that lock + * guarantees mutual exclusion from any currently running hotplug operations. + */ +void cpu_hotplug_disable(void) +{ + cpu_maps_update_begin(); + cpu_hotplug_disabled = 1; + cpu_maps_update_done(); +} + +void cpu_hotplug_enable(void) +{ + cpu_maps_update_begin(); + cpu_hotplug_disabled = 0; + cpu_maps_update_done(); +} + #else /* #if CONFIG_HOTPLUG_CPU */ static void cpu_hotplug_begin(void) {} static void cpu_hotplug_done(void) {} @@ -541,36 +562,6 @@ static int __init alloc_frozen_cpus(void) core_initcall(alloc_frozen_cpus); /* - * Prevent regular CPU hotplug from racing with the freezer, by disabling CPU - * hotplug when tasks are about to be frozen. Also, don't allow the freezer - * to continue until any currently running CPU hotplug operation gets - * completed. - * To modify the 'cpu_hotplug_disabled' flag, we need to acquire the - * 'cpu_add_remove_lock'. And this same lock is also taken by the regular - * CPU hotplug path and released only after it is complete. Thus, we - * (and hence the freezer) will block here until any currently running CPU - * hotplug operation gets completed. - */ -void cpu_hotplug_disable_before_freeze(void) -{ - cpu_maps_update_begin(); - cpu_hotplug_disabled = 1; - cpu_maps_update_done(); -} - - -/* - * When tasks have been thawed, re-enable regular CPU hotplug (which had been - * disabled while beginning to freeze tasks). - */ -void cpu_hotplug_enable_after_thaw(void) -{ - cpu_maps_update_begin(); - cpu_hotplug_disabled = 0; - cpu_maps_update_done(); -} - -/* * When callbacks for CPU hotplug notifications are being executed, we must * ensure that the state of the system with respect to the tasks being frozen * or not, as reported by the notification, remains unchanged *throughout the @@ -589,12 +580,12 @@ cpu_hotplug_pm_callback(struct notifier_block *nb, case PM_SUSPEND_PREPARE: case PM_HIBERNATION_PREPARE: - cpu_hotplug_disable_before_freeze(); + cpu_hotplug_disable(); break; case PM_POST_SUSPEND: case PM_POST_HIBERNATION: - cpu_hotplug_enable_after_thaw(); + cpu_hotplug_enable(); break; default: diff --git a/kernel/cpu/idle.c b/kernel/cpu/idle.c index d5585f5e038e..e695c0a0bcb5 100644 --- a/kernel/cpu/idle.c +++ b/kernel/cpu/idle.c @@ -5,6 +5,7 @@ #include <linux/cpu.h> #include <linux/tick.h> #include <linux/mm.h> +#include <linux/stackprotector.h> #include <asm/tlb.h> @@ -58,6 +59,7 @@ void __weak arch_cpu_idle_dead(void) { } void __weak arch_cpu_idle(void) { cpu_idle_force_poll = 1; + local_irq_enable(); } /* @@ -112,6 +114,21 @@ static void cpu_idle_loop(void) void cpu_startup_entry(enum cpuhp_state state) { + /* + * This #ifdef needs to die, but it's too late in the cycle to + * make this generic (arm and sh have never invoked the canary + * init for the non boot cpus!). Will be fixed in 3.11 + */ +#ifdef CONFIG_X86 + /* + * If we're the non-boot CPU, nothing set the stack canary up + * for us. The boot CPU already has it initialized but no harm + * in doing it again. This is a good place for updating it, as + * we wont ever return from this function (so the invalid + * canaries already on the stack wont ever trigger). + */ + boot_init_stack_canary(); +#endif current_set_polling(); arch_cpu_idle_prepare(); cpu_idle_loop(); diff --git a/kernel/events/core.c b/kernel/events/core.c index 9dc297faf7c0..b391907d5352 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -196,9 +196,6 @@ static void cpu_ctx_sched_in(struct perf_cpu_context *cpuctx, static void update_context_time(struct perf_event_context *ctx); static u64 perf_event_time(struct perf_event *event); -static void ring_buffer_attach(struct perf_event *event, - struct ring_buffer *rb); - void __weak perf_event_print_debug(void) { } extern __weak const char *perf_pmu_name(void) @@ -2918,6 +2915,7 @@ static void free_event_rcu(struct rcu_head *head) } static void ring_buffer_put(struct ring_buffer *rb); +static void ring_buffer_detach(struct perf_event *event, struct ring_buffer *rb); static void free_event(struct perf_event *event) { @@ -2942,15 +2940,30 @@ static void free_event(struct perf_event *event) if (has_branch_stack(event)) { static_key_slow_dec_deferred(&perf_sched_events); /* is system-wide event */ - if (!(event->attach_state & PERF_ATTACH_TASK)) + if (!(event->attach_state & PERF_ATTACH_TASK)) { atomic_dec(&per_cpu(perf_branch_stack_events, event->cpu)); + } } } if (event->rb) { - ring_buffer_put(event->rb); - event->rb = NULL; + struct ring_buffer *rb; + + /* + * Can happen when we close an event with re-directed output. + * + * Since we have a 0 refcount, perf_mmap_close() will skip + * over us; possibly making our ring_buffer_put() the last. + */ + mutex_lock(&event->mmap_mutex); + rb = event->rb; + if (rb) { + rcu_assign_pointer(event->rb, NULL); + ring_buffer_detach(event, rb); + ring_buffer_put(rb); /* could be last */ + } + mutex_unlock(&event->mmap_mutex); } if (is_cgroup_event(event)) @@ -3188,30 +3201,13 @@ static unsigned int perf_poll(struct file *file, poll_table *wait) unsigned int events = POLL_HUP; /* - * Race between perf_event_set_output() and perf_poll(): perf_poll() - * grabs the rb reference but perf_event_set_output() overrides it. - * Here is the timeline for two threads T1, T2: - * t0: T1, rb = rcu_dereference(event->rb) - * t1: T2, old_rb = event->rb - * t2: T2, event->rb = new rb - * t3: T2, ring_buffer_detach(old_rb) - * t4: T1, ring_buffer_attach(rb1) - * t5: T1, poll_wait(event->waitq) - * - * To avoid this problem, we grab mmap_mutex in perf_poll() - * thereby ensuring that the assignment of the new ring buffer - * and the detachment of the old buffer appear atomic to perf_poll() + * Pin the event->rb by taking event->mmap_mutex; otherwise + * perf_event_set_output() can swizzle our rb and make us miss wakeups. */ mutex_lock(&event->mmap_mutex); - - rcu_read_lock(); - rb = rcu_dereference(event->rb); - if (rb) { - ring_buffer_attach(event, rb); + rb = event->rb; + if (rb) events = atomic_xchg(&rb->poll, 0); - } - rcu_read_unlock(); - mutex_unlock(&event->mmap_mutex); poll_wait(file, &event->waitq, wait); @@ -3521,16 +3517,12 @@ static void ring_buffer_attach(struct perf_event *event, return; spin_lock_irqsave(&rb->event_lock, flags); - if (!list_empty(&event->rb_entry)) - goto unlock; - - list_add(&event->rb_entry, &rb->event_list); -unlock: + if (list_empty(&event->rb_entry)) + list_add(&event->rb_entry, &rb->event_list); spin_unlock_irqrestore(&rb->event_lock, flags); } -static void ring_buffer_detach(struct perf_event *event, - struct ring_buffer *rb) +static void ring_buffer_detach(struct perf_event *event, struct ring_buffer *rb) { unsigned long flags; @@ -3549,13 +3541,10 @@ static void ring_buffer_wakeup(struct perf_event *event) rcu_read_lock(); rb = rcu_dereference(event->rb); - if (!rb) - goto unlock; - - list_for_each_entry_rcu(event, &rb->event_list, rb_entry) - wake_up_all(&event->waitq); - -unlock: + if (rb) { + list_for_each_entry_rcu(event, &rb->event_list, rb_entry) + wake_up_all(&event->waitq); + } rcu_read_unlock(); } @@ -3584,18 +3573,10 @@ static struct ring_buffer *ring_buffer_get(struct perf_event *event) static void ring_buffer_put(struct ring_buffer *rb) { - struct perf_event *event, *n; - unsigned long flags; - if (!atomic_dec_and_test(&rb->refcount)) return; - spin_lock_irqsave(&rb->event_lock, flags); - list_for_each_entry_safe(event, n, &rb->event_list, rb_entry) { - list_del_init(&event->rb_entry); - wake_up_all(&event->waitq); - } - spin_unlock_irqrestore(&rb->event_lock, flags); + WARN_ON_ONCE(!list_empty(&rb->event_list)); call_rcu(&rb->rcu_head, rb_free_rcu); } @@ -3605,26 +3586,100 @@ static void perf_mmap_open(struct vm_area_struct *vma) struct perf_event *event = vma->vm_file->private_data; atomic_inc(&event->mmap_count); + atomic_inc(&event->rb->mmap_count); } +/* + * A buffer can be mmap()ed multiple times; either directly through the same + * event, or through other events by use of perf_event_set_output(). + * + * In order to undo the VM accounting done by perf_mmap() we need to destroy + * the buffer here, where we still have a VM context. This means we need + * to detach all events redirecting to us. + */ static void perf_mmap_close(struct vm_area_struct *vma) { struct perf_event *event = vma->vm_file->private_data; - if (atomic_dec_and_mutex_lock(&event->mmap_count, &event->mmap_mutex)) { - unsigned long size = perf_data_size(event->rb); - struct user_struct *user = event->mmap_user; - struct ring_buffer *rb = event->rb; + struct ring_buffer *rb = event->rb; + struct user_struct *mmap_user = rb->mmap_user; + int mmap_locked = rb->mmap_locked; + unsigned long size = perf_data_size(rb); + + atomic_dec(&rb->mmap_count); + + if (!atomic_dec_and_mutex_lock(&event->mmap_count, &event->mmap_mutex)) + return; - atomic_long_sub((size >> PAGE_SHIFT) + 1, &user->locked_vm); - vma->vm_mm->pinned_vm -= event->mmap_locked; - rcu_assign_pointer(event->rb, NULL); - ring_buffer_detach(event, rb); + /* Detach current event from the buffer. */ + rcu_assign_pointer(event->rb, NULL); + ring_buffer_detach(event, rb); + mutex_unlock(&event->mmap_mutex); + + /* If there's still other mmap()s of this buffer, we're done. */ + if (atomic_read(&rb->mmap_count)) { + ring_buffer_put(rb); /* can't be last */ + return; + } + + /* + * No other mmap()s, detach from all other events that might redirect + * into the now unreachable buffer. Somewhat complicated by the + * fact that rb::event_lock otherwise nests inside mmap_mutex. + */ +again: + rcu_read_lock(); + list_for_each_entry_rcu(event, &rb->event_list, rb_entry) { + if (!atomic_long_inc_not_zero(&event->refcount)) { + /* + * This event is en-route to free_event() which will + * detach it and remove it from the list. + */ + continue; + } + rcu_read_unlock(); + + mutex_lock(&event->mmap_mutex); + /* + * Check we didn't race with perf_event_set_output() which can + * swizzle the rb from under us while we were waiting to + * acquire mmap_mutex. + * + * If we find a different rb; ignore this event, a next + * iteration will no longer find it on the list. We have to + * still restart the iteration to make sure we're not now + * iterating the wrong list. + */ + if (event->rb == rb) { + rcu_assign_pointer(event->rb, NULL); + ring_buffer_detach(event, rb); + ring_buffer_put(rb); /* can't be last, we still have one */ + } mutex_unlock(&event->mmap_mutex); + put_event(event); - ring_buffer_put(rb); - free_uid(user); + /* + * Restart the iteration; either we're on the wrong list or + * destroyed its integrity by doing a deletion. + */ + goto again; } + rcu_read_unlock(); + + /* + * It could be there's still a few 0-ref events on the list; they'll + * get cleaned up by free_event() -- they'll also still have their + * ref on the rb and will free it whenever they are done with it. + * + * Aside from that, this buffer is 'fully' detached and unmapped, + * undo the VM accounting. + */ + + atomic_long_sub((size >> PAGE_SHIFT) + 1, &mmap_user->locked_vm); + vma->vm_mm->pinned_vm -= mmap_locked; + free_uid(mmap_user); + + ring_buffer_put(rb); /* could be last */ } static const struct vm_operations_struct perf_mmap_vmops = { @@ -3674,12 +3729,24 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma) return -EINVAL; WARN_ON_ONCE(event->ctx->parent_ctx); +again: mutex_lock(&event->mmap_mutex); if (event->rb) { - if (event->rb->nr_pages == nr_pages) - atomic_inc(&event->rb->refcount); - else + if (event->rb->nr_pages != nr_pages) { ret = -EINVAL; + goto unlock; + } + + if (!atomic_inc_not_zero(&event->rb->mmap_count)) { + /* + * Raced against perf_mmap_close() through + * perf_event_set_output(). Try again, hope for better + * luck. + */ + mutex_unlock(&event->mmap_mutex); + goto again; + } + goto unlock; } @@ -3720,12 +3787,16 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma) ret = -ENOMEM; goto unlock; } - rcu_assign_pointer(event->rb, rb); + + atomic_set(&rb->mmap_count, 1); + rb->mmap_locked = extra; + rb->mmap_user = get_current_user(); atomic_long_add(user_extra, &user->locked_vm); - event->mmap_locked = extra; - event->mmap_user = get_current_user(); - vma->vm_mm->pinned_vm += event->mmap_locked; + vma->vm_mm->pinned_vm += extra; + + ring_buffer_attach(event, rb); + rcu_assign_pointer(event->rb, rb); perf_event_update_userpage(event); @@ -3734,7 +3805,11 @@ unlock: atomic_inc(&event->mmap_count); mutex_unlock(&event->mmap_mutex); - vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP; + /* + * Since pinned accounting is per vm we cannot allow fork() to copy our + * vma. + */ + vma->vm_flags |= VM_DONTCOPY | VM_DONTEXPAND | VM_DONTDUMP; vma->vm_ops = &perf_mmap_vmops; return ret; @@ -6412,6 +6487,8 @@ set: if (atomic_read(&event->mmap_count)) goto unlock; + old_rb = event->rb; + if (output_event) { /* get the rb we want to redirect to */ rb = ring_buffer_get(output_event); @@ -6419,16 +6496,28 @@ set: goto unlock; } - old_rb = event->rb; - rcu_assign_pointer(event->rb, rb); if (old_rb) ring_buffer_detach(event, old_rb); + + if (rb) + ring_buffer_attach(event, rb); + + rcu_assign_pointer(event->rb, rb); + + if (old_rb) { + ring_buffer_put(old_rb); + /* + * Since we detached before setting the new rb, so that we + * could attach the new rb, we could have missed a wakeup. + * Provide it now. + */ + wake_up_all(&event->waitq); + } + ret = 0; unlock: mutex_unlock(&event->mmap_mutex); - if (old_rb) - ring_buffer_put(old_rb); out: return ret; } diff --git a/kernel/events/internal.h b/kernel/events/internal.h index eb675c4d59df..ca6599723be5 100644 --- a/kernel/events/internal.h +++ b/kernel/events/internal.h @@ -31,6 +31,10 @@ struct ring_buffer { spinlock_t event_lock; struct list_head event_list; + atomic_t mmap_count; + unsigned long mmap_locked; + struct user_struct *mmap_user; + struct perf_event_mmap_page *user_page; void *data_pages[0]; }; diff --git a/kernel/exit.c b/kernel/exit.c index af2eb3cbd499..7bb73f9d09db 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -649,7 +649,6 @@ static void exit_notify(struct task_struct *tsk, int group_dead) * jobs, send them a SIGHUP and then a SIGCONT. (POSIX 3.2.2.2) */ forget_original_parent(tsk); - exit_task_namespaces(tsk); write_lock_irq(&tasklist_lock); if (group_dead) @@ -795,6 +794,7 @@ void do_exit(long code) exit_shm(tsk); exit_files(tsk); exit_fs(tsk); + exit_task_namespaces(tsk); exit_task_work(tsk); check_stack_usage(); exit_thread(); diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index 5a83dde8ca0c..54a4d5223238 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c @@ -143,7 +143,10 @@ static unsigned int irq_domain_legacy_revmap(struct irq_domain *domain, * irq_domain_add_simple() - Allocate and register a simple irq_domain. * @of_node: pointer to interrupt controller's device tree node. * @size: total number of irqs in mapping - * @first_irq: first number of irq block assigned to the domain + * @first_irq: first number of irq block assigned to the domain, + * pass zero to assign irqs on-the-fly. This will result in a + * linear IRQ domain so it is important to use irq_create_mapping() + * for each used IRQ, especially when SPARSE_IRQ is enabled. * @ops: map/unmap domain callbacks * @host_data: Controller private data pointer * @@ -191,6 +194,7 @@ struct irq_domain *irq_domain_add_simple(struct device_node *of_node, /* A linear domain is the default */ return irq_domain_add_linear(of_node, size, ops, host_data); } +EXPORT_SYMBOL_GPL(irq_domain_add_simple); /** * irq_domain_add_legacy() - Allocate and register a legacy revmap irq_domain. @@ -397,11 +401,12 @@ static void irq_domain_disassociate_many(struct irq_domain *domain, while (count--) { int irq = irq_base + count; struct irq_data *irq_data = irq_get_irq_data(irq); - irq_hw_number_t hwirq = irq_data->hwirq; + irq_hw_number_t hwirq; if (WARN_ON(!irq_data || irq_data->domain != domain)) continue; + hwirq = irq_data->hwirq; irq_set_status_flags(irq, IRQ_NOREQUEST); /* remove chip and handler */ diff --git a/kernel/kprobes.c b/kernel/kprobes.c index 3fed7f0cbcdf..bddf3b201a48 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c @@ -467,6 +467,7 @@ static struct kprobe *__kprobes get_optimized_kprobe(unsigned long addr) /* Optimization staging list, protected by kprobe_mutex */ static LIST_HEAD(optimizing_list); static LIST_HEAD(unoptimizing_list); +static LIST_HEAD(freeing_list); static void kprobe_optimizer(struct work_struct *work); static DECLARE_DELAYED_WORK(optimizing_work, kprobe_optimizer); @@ -504,7 +505,7 @@ static __kprobes void do_optimize_kprobes(void) * Unoptimize (replace a jump with a breakpoint and remove the breakpoint * if need) kprobes listed on unoptimizing_list. */ -static __kprobes void do_unoptimize_kprobes(struct list_head *free_list) +static __kprobes void do_unoptimize_kprobes(void) { struct optimized_kprobe *op, *tmp; @@ -515,9 +516,9 @@ static __kprobes void do_unoptimize_kprobes(struct list_head *free_list) /* Ditto to do_optimize_kprobes */ get_online_cpus(); mutex_lock(&text_mutex); - arch_unoptimize_kprobes(&unoptimizing_list, free_list); + arch_unoptimize_kprobes(&unoptimizing_list, &freeing_list); /* Loop free_list for disarming */ - list_for_each_entry_safe(op, tmp, free_list, list) { + list_for_each_entry_safe(op, tmp, &freeing_list, list) { /* Disarm probes if marked disabled */ if (kprobe_disabled(&op->kp)) arch_disarm_kprobe(&op->kp); @@ -536,11 +537,11 @@ static __kprobes void do_unoptimize_kprobes(struct list_head *free_list) } /* Reclaim all kprobes on the free_list */ -static __kprobes void do_free_cleaned_kprobes(struct list_head *free_list) +static __kprobes void do_free_cleaned_kprobes(void) { struct optimized_kprobe *op, *tmp; - list_for_each_entry_safe(op, tmp, free_list, list) { + list_for_each_entry_safe(op, tmp, &freeing_list, list) { BUG_ON(!kprobe_unused(&op->kp)); list_del_init(&op->list); free_aggr_kprobe(&op->kp); @@ -556,8 +557,6 @@ static __kprobes void kick_kprobe_optimizer(void) /* Kprobe jump optimizer */ static __kprobes void kprobe_optimizer(struct work_struct *work) { - LIST_HEAD(free_list); - mutex_lock(&kprobe_mutex); /* Lock modules while optimizing kprobes */ mutex_lock(&module_mutex); @@ -566,7 +565,7 @@ static __kprobes void kprobe_optimizer(struct work_struct *work) * Step 1: Unoptimize kprobes and collect cleaned (unused and disarmed) * kprobes before waiting for quiesence period. */ - do_unoptimize_kprobes(&free_list); + do_unoptimize_kprobes(); /* * Step 2: Wait for quiesence period to ensure all running interrupts @@ -581,7 +580,7 @@ static __kprobes void kprobe_optimizer(struct work_struct *work) do_optimize_kprobes(); /* Step 4: Free cleaned kprobes after quiesence period */ - do_free_cleaned_kprobes(&free_list); + do_free_cleaned_kprobes(); mutex_unlock(&module_mutex); mutex_unlock(&kprobe_mutex); @@ -723,8 +722,19 @@ static void __kprobes kill_optimized_kprobe(struct kprobe *p) if (!list_empty(&op->list)) /* Dequeue from the (un)optimization queue */ list_del_init(&op->list); - op->kp.flags &= ~KPROBE_FLAG_OPTIMIZED; + + if (kprobe_unused(p)) { + /* Enqueue if it is unused */ + list_add(&op->list, &freeing_list); + /* + * Remove unused probes from the hash list. After waiting + * for synchronization, this probe is reclaimed. + * (reclaiming is done by do_free_cleaned_kprobes().) + */ + hlist_del_rcu(&op->kp.hlist); + } + /* Don't touch the code, because it is already freed. */ arch_remove_optimized_kprobe(op); } diff --git a/kernel/printk.c b/kernel/printk.c index fa36e1494420..8212c1aef125 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -363,6 +363,53 @@ static void log_store(int facility, int level, log_next_seq++; } +#ifdef CONFIG_SECURITY_DMESG_RESTRICT +int dmesg_restrict = 1; +#else +int dmesg_restrict; +#endif + +static int syslog_action_restricted(int type) +{ + if (dmesg_restrict) + return 1; + /* + * Unless restricted, we allow "read all" and "get buffer size" + * for everybody. + */ + return type != SYSLOG_ACTION_READ_ALL && + type != SYSLOG_ACTION_SIZE_BUFFER; +} + +static int check_syslog_permissions(int type, bool from_file) +{ + /* + * If this is from /proc/kmsg and we've already opened it, then we've + * already done the capabilities checks at open time. + */ + if (from_file && type != SYSLOG_ACTION_OPEN) + return 0; + + if (syslog_action_restricted(type)) { + if (capable(CAP_SYSLOG)) + return 0; + /* + * For historical reasons, accept CAP_SYS_ADMIN too, with + * a warning. + */ + if (capable(CAP_SYS_ADMIN)) { + pr_warn_once("%s (%d): Attempt to access syslog with " + "CAP_SYS_ADMIN but no CAP_SYSLOG " + "(deprecated).\n", + current->comm, task_pid_nr(current)); + return 0; + } + return -EPERM; + } + return security_syslog(type); +} + + /* /dev/kmsg - userspace message inject/listen interface */ struct devkmsg_user { u64 seq; @@ -620,7 +667,8 @@ static int devkmsg_open(struct inode *inode, struct file *file) if ((file->f_flags & O_ACCMODE) == O_WRONLY) return 0; - err = security_syslog(SYSLOG_ACTION_READ_ALL); + err = check_syslog_permissions(SYSLOG_ACTION_READ_ALL, + SYSLOG_FROM_READER); if (err) return err; @@ -813,45 +861,6 @@ static inline void boot_delay_msec(int level) } #endif -#ifdef CONFIG_SECURITY_DMESG_RESTRICT -int dmesg_restrict = 1; -#else -int dmesg_restrict; -#endif - -static int syslog_action_restricted(int type) -{ - if (dmesg_restrict) - return 1; - /* Unless restricted, we allow "read all" and "get buffer size" for everybody */ - return type != SYSLOG_ACTION_READ_ALL && type != SYSLOG_ACTION_SIZE_BUFFER; -} - -static int check_syslog_permissions(int type, bool from_file) -{ - /* - * If this is from /proc/kmsg and we've already opened it, then we've - * already done the capabilities checks at open time. - */ - if (from_file && type != SYSLOG_ACTION_OPEN) - return 0; - - if (syslog_action_restricted(type)) { - if (capable(CAP_SYSLOG)) - return 0; - /* For historical reasons, accept CAP_SYS_ADMIN too, with a warning */ - if (capable(CAP_SYS_ADMIN)) { - printk_once(KERN_WARNING "%s (%d): " - "Attempt to access syslog with CAP_SYS_ADMIN " - "but no CAP_SYSLOG (deprecated).\n", - current->comm, task_pid_nr(current)); - return 0; - } - return -EPERM; - } - return 0; -} - #if defined(CONFIG_PRINTK_TIME) static bool printk_time = 1; #else @@ -1249,7 +1258,7 @@ out: SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len) { - return do_syslog(type, buf, len, SYSLOG_FROM_CALL); + return do_syslog(type, buf, len, SYSLOG_FROM_READER); } /* diff --git a/kernel/range.c b/kernel/range.c index 071b0ab455cb..322ea8e93e4b 100644 --- a/kernel/range.c +++ b/kernel/range.c @@ -4,7 +4,7 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/sort.h> - +#include <linux/string.h> #include <linux/range.h> int add_range(struct range *range, int az, int nr_range, u64 start, u64 end) @@ -32,9 +32,8 @@ int add_range_with_merge(struct range *range, int az, int nr_range, if (start >= end) return nr_range; - /* Try to merge it with old one: */ + /* get new start/end: */ for (i = 0; i < nr_range; i++) { - u64 final_start, final_end; u64 common_start, common_end; if (!range[i].end) @@ -45,12 +44,16 @@ int add_range_with_merge(struct range *range, int az, int nr_range, if (common_start > common_end) continue; - final_start = min(range[i].start, start); - final_end = max(range[i].end, end); + /* new start/end, will add it back at last */ + start = min(range[i].start, start); + end = max(range[i].end, end); - range[i].start = final_start; - range[i].end = final_end; - return nr_range; + memmove(&range[i], &range[i + 1], + (nr_range - (i + 1)) * sizeof(range[i])); + range[nr_range - 1].start = 0; + range[nr_range - 1].end = 0; + nr_range--; + i--; } /* Need to add it: */ diff --git a/kernel/rcutree.c b/kernel/rcutree.c index 16ea67925015..35380019f0fc 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c @@ -1451,9 +1451,9 @@ static int rcu_gp_init(struct rcu_state *rsp) rnp->grphi, rnp->qsmask); raw_spin_unlock_irq(&rnp->lock); #ifdef CONFIG_PROVE_RCU_DELAY - if ((prandom_u32() % (rcu_num_nodes * 8)) == 0 && + if ((prandom_u32() % (rcu_num_nodes + 1)) == 0 && system_state == SYSTEM_RUNNING) - schedule_timeout_uninterruptible(2); + udelay(200); #endif /* #ifdef CONFIG_PROVE_RCU_DELAY */ cond_resched(); } @@ -1613,6 +1613,14 @@ static int __noreturn rcu_gp_kthread(void *arg) } } +static void rsp_wakeup(struct irq_work *work) +{ + struct rcu_state *rsp = container_of(work, struct rcu_state, wakeup_work); + + /* Wake up rcu_gp_kthread() to start the grace period. */ + wake_up(&rsp->gp_wq); +} + /* * Start a new RCU grace period if warranted, re-initializing the hierarchy * in preparation for detecting the next grace period. The caller must hold @@ -1637,8 +1645,12 @@ rcu_start_gp_advanced(struct rcu_state *rsp, struct rcu_node *rnp, } rsp->gp_flags = RCU_GP_FLAG_INIT; - /* Wake up rcu_gp_kthread() to start the grace period. */ - wake_up(&rsp->gp_wq); + /* + * We can't do wakeups while holding the rnp->lock, as that + * could cause possible deadlocks with the rq->lock. Deter + * the wakeup to interrupt context. + */ + irq_work_queue(&rsp->wakeup_work); } /* @@ -3235,6 +3247,7 @@ static void __init rcu_init_one(struct rcu_state *rsp, rsp->rda = rda; init_waitqueue_head(&rsp->gp_wq); + init_irq_work(&rsp->wakeup_work, rsp_wakeup); rnp = rsp->level[rcu_num_lvls - 1]; for_each_possible_cpu(i) { while (i > rnp->grphi) diff --git a/kernel/rcutree.h b/kernel/rcutree.h index da77a8f57ff9..4df503470e42 100644 --- a/kernel/rcutree.h +++ b/kernel/rcutree.h @@ -27,6 +27,7 @@ #include <linux/threads.h> #include <linux/cpumask.h> #include <linux/seqlock.h> +#include <linux/irq_work.h> /* * Define shape of hierarchy based on NR_CPUS, CONFIG_RCU_FANOUT, and @@ -442,6 +443,7 @@ struct rcu_state { char *name; /* Name of structure. */ char abbr; /* Abbreviated name. */ struct list_head flavors; /* List of RCU flavors. */ + struct irq_work wakeup_work; /* Postponed wakeups */ }; /* Values for rcu_state structure's gp_flags field. */ diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 58453b8272fd..e8b335016c52 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -633,7 +633,19 @@ void wake_up_nohz_cpu(int cpu) static inline bool got_nohz_idle_kick(void) { int cpu = smp_processor_id(); - return idle_cpu(cpu) && test_bit(NOHZ_BALANCE_KICK, nohz_flags(cpu)); + + if (!test_bit(NOHZ_BALANCE_KICK, nohz_flags(cpu))) + return false; + + if (idle_cpu(cpu) && !need_resched()) + return true; + + /* + * We can't run Idle Load Balance on this CPU for this time so we + * cancel it and clear NOHZ_BALANCE_KICK + */ + clear_bit(NOHZ_BALANCE_KICK, nohz_flags(cpu)); + return false; } #else /* CONFIG_NO_HZ_COMMON */ @@ -1393,8 +1405,9 @@ static void sched_ttwu_pending(void) void scheduler_ipi(void) { - if (llist_empty(&this_rq()->wake_list) && !got_nohz_idle_kick() - && !tick_nohz_full_cpu(smp_processor_id())) + if (llist_empty(&this_rq()->wake_list) + && !tick_nohz_full_cpu(smp_processor_id()) + && !got_nohz_idle_kick()) return; /* @@ -1417,7 +1430,7 @@ void scheduler_ipi(void) /* * Check if someone kicked us for doing the nohz idle load balance. */ - if (unlikely(got_nohz_idle_kick() && !need_resched())) { + if (unlikely(got_nohz_idle_kick())) { this_rq()->idle_balance = 1; raise_softirq_irqoff(SCHED_SOFTIRQ); } @@ -4745,7 +4758,7 @@ void __cpuinit init_idle(struct task_struct *idle, int cpu) */ idle->sched_class = &idle_sched_class; ftrace_graph_init_idle_task(idle, cpu); - vtime_init_idle(idle); + vtime_init_idle(idle, cpu); #if defined(CONFIG_SMP) sprintf(idle->comm, "%s/%d", INIT_TASK_COMM, cpu); #endif diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c index cc2dc3eea8a3..b5ccba22603b 100644 --- a/kernel/sched/cputime.c +++ b/kernel/sched/cputime.c @@ -747,17 +747,17 @@ void arch_vtime_task_switch(struct task_struct *prev) write_seqlock(¤t->vtime_seqlock); current->vtime_snap_whence = VTIME_SYS; - current->vtime_snap = sched_clock(); + current->vtime_snap = sched_clock_cpu(smp_processor_id()); write_sequnlock(¤t->vtime_seqlock); } -void vtime_init_idle(struct task_struct *t) +void vtime_init_idle(struct task_struct *t, int cpu) { unsigned long flags; write_seqlock_irqsave(&t->vtime_seqlock, flags); t->vtime_snap_whence = VTIME_SYS; - t->vtime_snap = sched_clock(); + t->vtime_snap = sched_clock_cpu(cpu); write_sequnlock_irqrestore(&t->vtime_seqlock, flags); } diff --git a/kernel/softirq.c b/kernel/softirq.c index b5197dcb0dad..3d6833f125d3 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c @@ -195,8 +195,12 @@ void local_bh_enable_ip(unsigned long ip) EXPORT_SYMBOL(local_bh_enable_ip); /* - * We restart softirq processing for at most 2 ms, - * and if need_resched() is not set. + * We restart softirq processing for at most MAX_SOFTIRQ_RESTART times, + * but break the loop if need_resched() is set or after 2 ms. + * The MAX_SOFTIRQ_TIME provides a nice upper bound in most cases, but in + * certain cases, such as stop_machine(), jiffies may cease to + * increment and so we need the MAX_SOFTIRQ_RESTART limit as + * well to make sure we eventually return from this method. * * These limits have been established via experimentation. * The two things to balance is latency against fairness - @@ -204,6 +208,7 @@ EXPORT_SYMBOL(local_bh_enable_ip); * should not be able to lock up the box. */ #define MAX_SOFTIRQ_TIME msecs_to_jiffies(2) +#define MAX_SOFTIRQ_RESTART 10 asmlinkage void __do_softirq(void) { @@ -212,6 +217,7 @@ asmlinkage void __do_softirq(void) unsigned long end = jiffies + MAX_SOFTIRQ_TIME; int cpu; unsigned long old_flags = current->flags; + int max_restart = MAX_SOFTIRQ_RESTART; /* * Mask out PF_MEMALLOC s current task context is borrowed for the @@ -265,7 +271,8 @@ restart: pending = local_softirq_pending(); if (pending) { - if (time_before(jiffies, end) && !need_resched()) + if (time_before(jiffies, end) && !need_resched() && + --max_restart) goto restart; wakeup_softirqd(); diff --git a/kernel/sys.c b/kernel/sys.c index b95d3c72ba21..2bbd9a73b54c 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -362,6 +362,29 @@ int unregister_reboot_notifier(struct notifier_block *nb) } EXPORT_SYMBOL(unregister_reboot_notifier); +/* Add backwards compatibility for stable trees. */ +#ifndef PF_NO_SETAFFINITY +#define PF_NO_SETAFFINITY PF_THREAD_BOUND +#endif + +static void migrate_to_reboot_cpu(void) +{ + /* The boot cpu is always logical cpu 0 */ + int cpu = 0; + + cpu_hotplug_disable(); + + /* Make certain the cpu I'm about to reboot on is online */ + if (!cpu_online(cpu)) + cpu = cpumask_first(cpu_online_mask); + + /* Prevent races with other tasks migrating this task */ + current->flags |= PF_NO_SETAFFINITY; + + /* Make certain I only run on the appropriate processor */ + set_cpus_allowed_ptr(current, cpumask_of(cpu)); +} + /** * kernel_restart - reboot the system * @cmd: pointer to buffer containing command to execute for restart @@ -373,7 +396,7 @@ EXPORT_SYMBOL(unregister_reboot_notifier); void kernel_restart(char *cmd) { kernel_restart_prepare(cmd); - disable_nonboot_cpus(); + migrate_to_reboot_cpu(); syscore_shutdown(); if (!cmd) printk(KERN_EMERG "Restarting system.\n"); @@ -400,7 +423,7 @@ static void kernel_shutdown_prepare(enum system_states state) void kernel_halt(void) { kernel_shutdown_prepare(SYSTEM_HALT); - disable_nonboot_cpus(); + migrate_to_reboot_cpu(); syscore_shutdown(); printk(KERN_EMERG "System halted.\n"); kmsg_dump(KMSG_DUMP_HALT); @@ -419,7 +442,7 @@ void kernel_power_off(void) kernel_shutdown_prepare(SYSTEM_POWER_OFF); if (pm_power_off_prepare) pm_power_off_prepare(); - disable_nonboot_cpus(); + migrate_to_reboot_cpu(); syscore_shutdown(); printk(KERN_EMERG "Power down.\n"); kmsg_dump(KMSG_DUMP_POWEROFF); diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c index 12ff13a838c6..8f5b3b98577b 100644 --- a/kernel/time/ntp.c +++ b/kernel/time/ntp.c @@ -874,7 +874,6 @@ static void hardpps_update_phase(long error) void __hardpps(const struct timespec *phase_ts, const struct timespec *raw_ts) { struct pps_normtime pts_norm, freq_norm; - unsigned long flags; pts_norm = pps_normalize_ts(*phase_ts); diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c index 24938d577669..b4c245580b79 100644 --- a/kernel/time/tick-broadcast.c +++ b/kernel/time/tick-broadcast.c @@ -511,6 +511,12 @@ again: } } + /* + * Remove the current cpu from the pending mask. The event is + * delivered immediately in tick_do_broadcast() ! + */ + cpumask_clear_cpu(smp_processor_id(), tick_broadcast_pending_mask); + /* Take care of enforced broadcast requests */ cpumask_or(tmpmask, tmpmask, tick_broadcast_force_mask); cpumask_clear(tick_broadcast_force_mask); @@ -575,8 +581,8 @@ void tick_broadcast_oneshot_control(unsigned long reason) raw_spin_lock_irqsave(&tick_broadcast_lock, flags); if (reason == CLOCK_EVT_NOTIFY_BROADCAST_ENTER) { - WARN_ON_ONCE(cpumask_test_cpu(cpu, tick_broadcast_pending_mask)); if (!cpumask_test_and_set_cpu(cpu, tick_broadcast_oneshot_mask)) { + WARN_ON_ONCE(cpumask_test_cpu(cpu, tick_broadcast_pending_mask)); clockevents_set_mode(dev, CLOCK_EVT_MODE_SHUTDOWN); /* * We only reprogram the broadcast timer if we @@ -692,10 +698,6 @@ void tick_broadcast_setup_oneshot(struct clock_event_device *bc) bc->event_handler = tick_handle_oneshot_broadcast; - /* Take the do_timer update */ - if (!tick_nohz_full_cpu(cpu)) - tick_do_timer_cpu = cpu; - /* * We must be careful here. There might be other CPUs * waiting for periodic broadcast. We need to set the diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index f4208138fbf4..0cf1c1453181 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -306,7 +306,7 @@ static int __cpuinit tick_nohz_cpu_down_callback(struct notifier_block *nfb, * we can't safely shutdown that CPU. */ if (have_nohz_full_mask && tick_do_timer_cpu == cpu) - return -EINVAL; + return NOTIFY_BAD; break; } return NOTIFY_OK; diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 98cd470bbe49..baeeb5c87cf1 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -975,6 +975,14 @@ static int timekeeping_suspend(void) read_persistent_clock(&timekeeping_suspend_time); + /* + * On some systems the persistent_clock can not be detected at + * timekeeping_init by its return value, so if we see a valid + * value returned, update the persistent_clock_exists flag. + */ + if (timekeeping_suspend_time.tv_sec || timekeeping_suspend_time.tv_nsec) + persistent_clock_exist = true; + raw_spin_lock_irqsave(&timekeeper_lock, flags); write_seqcount_begin(&timekeeper_seq); timekeeping_forward_now(tk); diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index b549b0f5b977..6c508ff33c62 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -120,22 +120,22 @@ static void ftrace_ops_no_ops(unsigned long ip, unsigned long parent_ip); /* * Traverse the ftrace_global_list, invoking all entries. The reason that we - * can use rcu_dereference_raw() is that elements removed from this list + * can use rcu_dereference_raw_notrace() is that elements removed from this list * are simply leaked, so there is no need to interact with a grace-period - * mechanism. The rcu_dereference_raw() calls are needed to handle + * mechanism. The rcu_dereference_raw_notrace() calls are needed to handle * concurrent insertions into the ftrace_global_list. * * Silly Alpha and silly pointer-speculation compiler optimizations! */ #define do_for_each_ftrace_op(op, list) \ - op = rcu_dereference_raw(list); \ + op = rcu_dereference_raw_notrace(list); \ do /* * Optimized for just a single item in the list (as that is the normal case). */ #define while_for_each_ftrace_op(op) \ - while (likely(op = rcu_dereference_raw((op)->next)) && \ + while (likely(op = rcu_dereference_raw_notrace((op)->next)) && \ unlikely((op) != &ftrace_list_end)) static inline void ftrace_ops_init(struct ftrace_ops *ops) @@ -779,7 +779,7 @@ ftrace_find_profiled_func(struct ftrace_profile_stat *stat, unsigned long ip) if (hlist_empty(hhd)) return NULL; - hlist_for_each_entry_rcu(rec, hhd, node) { + hlist_for_each_entry_rcu_notrace(rec, hhd, node) { if (rec->ip == ip) return rec; } @@ -1165,7 +1165,7 @@ ftrace_lookup_ip(struct ftrace_hash *hash, unsigned long ip) hhd = &hash->buckets[key]; - hlist_for_each_entry_rcu(entry, hhd, hlist) { + hlist_for_each_entry_rcu_notrace(entry, hhd, hlist) { if (entry->ip == ip) return entry; } @@ -1422,8 +1422,8 @@ ftrace_ops_test(struct ftrace_ops *ops, unsigned long ip) struct ftrace_hash *notrace_hash; int ret; - filter_hash = rcu_dereference_raw(ops->filter_hash); - notrace_hash = rcu_dereference_raw(ops->notrace_hash); + filter_hash = rcu_dereference_raw_notrace(ops->filter_hash); + notrace_hash = rcu_dereference_raw_notrace(ops->notrace_hash); if ((ftrace_hash_empty(filter_hash) || ftrace_lookup_ip(filter_hash, ip)) && @@ -2920,7 +2920,7 @@ static void function_trace_probe_call(unsigned long ip, unsigned long parent_ip, * on the hash. rcu_read_lock is too dangerous here. */ preempt_disable_notrace(); - hlist_for_each_entry_rcu(entry, hhd, node) { + hlist_for_each_entry_rcu_notrace(entry, hhd, node) { if (entry->ip == ip) entry->ops->func(ip, parent_ip, &entry->data); } diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index b59aea2c48c2..e444ff88f0a4 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -620,6 +620,9 @@ int ring_buffer_poll_wait(struct ring_buffer *buffer, int cpu, if (cpu == RING_BUFFER_ALL_CPUS) work = &buffer->irq_work; else { + if (!cpumask_test_cpu(cpu, buffer->cpumask)) + return -EINVAL; + cpu_buffer = buffer->buffers[cpu]; work = &cpu_buffer->irq_work; } diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index ae6fa2d1cdf7..e71a8be4a6ee 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -652,8 +652,6 @@ static struct { ARCH_TRACE_CLOCKS }; -int trace_clock_id; - /* * trace_parser_get_init - gets the buffer for trace parser */ @@ -843,7 +841,15 @@ __update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu) memcpy(max_data->comm, tsk->comm, TASK_COMM_LEN); max_data->pid = tsk->pid; - max_data->uid = task_uid(tsk); + /* + * If tsk == current, then use current_uid(), as that does not use + * RCU. The irq tracer can be called out of RCU scope. + */ + if (tsk == current) + max_data->uid = current_uid(); + else + max_data->uid = task_uid(tsk); + max_data->nice = tsk->static_prio - 20 - MAX_RT_PRIO; max_data->policy = tsk->policy; max_data->rt_priority = tsk->rt_priority; @@ -2818,7 +2824,7 @@ __tracing_open(struct inode *inode, struct file *file, bool snapshot) iter->iter_flags |= TRACE_FILE_ANNOTATE; /* Output in nanoseconds only if we are using a clock in nanoseconds. */ - if (trace_clocks[trace_clock_id].in_ns) + if (trace_clocks[tr->clock_id].in_ns) iter->iter_flags |= TRACE_FILE_TIME_IN_NS; /* stop the trace while dumping if we are not opening "snapshot" */ @@ -3817,7 +3823,7 @@ static int tracing_open_pipe(struct inode *inode, struct file *filp) iter->iter_flags |= TRACE_FILE_LAT_FMT; /* Output in nanoseconds only if we are using a clock in nanoseconds. */ - if (trace_clocks[trace_clock_id].in_ns) + if (trace_clocks[tr->clock_id].in_ns) iter->iter_flags |= TRACE_FILE_TIME_IN_NS; iter->cpu_file = tc->cpu; @@ -5087,7 +5093,7 @@ tracing_stats_read(struct file *filp, char __user *ubuf, cnt = ring_buffer_bytes_cpu(trace_buf->buffer, cpu); trace_seq_printf(s, "bytes: %ld\n", cnt); - if (trace_clocks[trace_clock_id].in_ns) { + if (trace_clocks[tr->clock_id].in_ns) { /* local or global for trace_clock */ t = ns2usecs(ring_buffer_oldest_event_ts(trace_buf->buffer, cpu)); usec_rem = do_div(t, USEC_PER_SEC); @@ -6216,10 +6222,15 @@ __init static int tracer_alloc_buffers(void) trace_init_cmdlines(); - register_tracer(&nop_trace); - + /* + * register_tracer() might reference current_trace, so it + * needs to be set before we register anything. This is + * just a bootstrap of current_trace anyway. + */ global_trace.current_trace = &nop_trace; + register_tracer(&nop_trace); + /* All seems OK, enable tracing */ tracing_disabled = 0; diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 711ca7d3e7f1..20572ed88c5c 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -700,8 +700,6 @@ enum print_line_t print_trace_line(struct trace_iterator *iter); extern unsigned long trace_flags; -extern int trace_clock_id; - /* Standard output formatting function used for function return traces */ #ifdef CONFIG_FUNCTION_GRAPH_TRACER diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 7a0cf68027cc..27963e2bf4bf 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -2072,8 +2072,10 @@ event_enable_func(struct ftrace_hash *hash, out_reg: /* Don't let event modules unload while probe registered */ ret = try_module_get(file->event_call->mod); - if (!ret) + if (!ret) { + ret = -EBUSY; goto out_free; + } ret = __ftrace_event_enable_disable(file, 1, 1); if (ret < 0) diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c index 55e2cf66967b..2901e3b88590 100644 --- a/kernel/trace/trace_selftest.c +++ b/kernel/trace/trace_selftest.c @@ -1159,7 +1159,7 @@ trace_selftest_startup_branch(struct tracer *trace, struct trace_array *tr) /* stop the tracing. */ tracing_stop(); /* check the trace buffer */ - ret = trace_test_buffer(tr, &count); + ret = trace_test_buffer(&tr->trace_buffer, &count); trace->reset(tr); tracing_start(); diff --git a/lib/mpi/longlong.h b/lib/mpi/longlong.h index 095ab157a521..d411355f238e 100644 --- a/lib/mpi/longlong.h +++ b/lib/mpi/longlong.h @@ -318,7 +318,8 @@ extern UDItype __udiv_qrnnd(); "rM" ((USItype)(bh)), \ "rM" ((USItype)(al)), \ "rM" ((USItype)(bl))) -#if defined(_PA_RISC1_1) +#if 0 && defined(_PA_RISC1_1) +/* xmpyu uses floating point register which is not allowed in Linux kernel. */ #define umul_ppmm(wh, wl, u, v) \ do { \ union {UDItype __ll; \ @@ -337,7 +338,7 @@ do { \ #define UMUL_TIME 40 #define UDIV_TIME 80 #endif -#ifndef LONGLONG_STANDALONE +#if 0 /* #ifndef LONGLONG_STANDALONE */ #define udiv_qrnnd(q, r, n1, n0, d) \ do { USItype __r; \ (q) = __udiv_qrnnd(&__r, (n1), (n0), (d)); \ diff --git a/lib/mpi/mpicoder.c b/lib/mpi/mpicoder.c index 5f9c44cdf1f5..4cc6442733f4 100644 --- a/lib/mpi/mpicoder.c +++ b/lib/mpi/mpicoder.c @@ -37,7 +37,7 @@ MPI mpi_read_raw_data(const void *xbuffer, size_t nbytes) mpi_limb_t a; MPI val = NULL; - while (nbytes >= 0 && buffer[0] == 0) { + while (nbytes > 0 && buffer[0] == 0) { buffer++; nbytes--; } diff --git a/mm/frontswap.c b/mm/frontswap.c index 538367ef1372..1b24bdcb3197 100644 --- a/mm/frontswap.c +++ b/mm/frontswap.c @@ -319,7 +319,7 @@ void __frontswap_invalidate_area(unsigned type) return; frontswap_ops->invalidate_area(type); atomic_set(&sis->frontswap_pages, 0); - memset(sis->frontswap_map, 0, sis->max / sizeof(long)); + bitmap_zero(sis->frontswap_map, sis->max); } clear_bit(type, need_init); } diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 03a89a2f464b..362c329b83fe 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -2325,7 +2325,12 @@ static void collapse_huge_page(struct mm_struct *mm, pte_unmap(pte); spin_lock(&mm->page_table_lock); BUG_ON(!pmd_none(*pmd)); - set_pmd_at(mm, address, pmd, _pmd); + /* + * We can only use set_pmd_at when establishing + * hugepmds and never for establishing regular pmds that + * points to regular pagetables. Use pmd_populate for that + */ + pmd_populate(mm, pmd, pmd_pgtable(_pmd)); spin_unlock(&mm->page_table_lock); anon_vma_unlock_write(vma->anon_vma); goto out; diff --git a/mm/hugetlb.c b/mm/hugetlb.c index f8feeeca6686..e2bfbf73a551 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -2839,7 +2839,7 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma, if (ptep) { entry = huge_ptep_get(ptep); if (unlikely(is_hugetlb_entry_migration(entry))) { - migration_entry_wait(mm, (pmd_t *)ptep, address); + migration_entry_wait_huge(mm, ptep); return 0; } else if (unlikely(is_hugetlb_entry_hwpoisoned(entry))) return VM_FAULT_HWPOISON_LARGE | diff --git a/mm/memcontrol.c b/mm/memcontrol.c index cb1c9dedf9b6..194721839cf5 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -1199,7 +1199,6 @@ struct mem_cgroup *mem_cgroup_iter(struct mem_cgroup *root, mz = mem_cgroup_zoneinfo(root, nid, zid); iter = &mz->reclaim_iter[reclaim->priority]; - last_visited = iter->last_visited; if (prev && reclaim->generation != iter->generation) { iter->last_visited = NULL; goto out_unlock; @@ -1218,13 +1217,12 @@ struct mem_cgroup *mem_cgroup_iter(struct mem_cgroup *root, * is alive. */ dead_count = atomic_read(&root->dead_count); - smp_rmb(); - last_visited = iter->last_visited; - if (last_visited) { - if ((dead_count != iter->last_dead_count) || - !css_tryget(&last_visited->css)) { + if (dead_count == iter->last_dead_count) { + smp_rmb(); + last_visited = iter->last_visited; + if (last_visited && + !css_tryget(&last_visited->css)) last_visited = NULL; - } } } @@ -3141,8 +3139,6 @@ int memcg_update_cache_size(struct kmem_cache *s, int num_groups) return -ENOMEM; } - INIT_WORK(&s->memcg_params->destroy, - kmem_cache_destroy_work_func); s->memcg_params->is_root_cache = true; /* @@ -4108,8 +4104,6 @@ __mem_cgroup_uncharge_common(struct page *page, enum charge_type ctype, if (mem_cgroup_disabled()) return NULL; - VM_BUG_ON(PageSwapCache(page)); - if (PageTransHuge(page)) { nr_pages <<= compound_order(page); VM_BUG_ON(!PageTransHuge(page)); @@ -4205,6 +4199,18 @@ void mem_cgroup_uncharge_page(struct page *page) if (page_mapped(page)) return; VM_BUG_ON(page->mapping && !PageAnon(page)); + /* + * If the page is in swap cache, uncharge should be deferred + * to the swap path, which also properly accounts swap usage + * and handles memcg lifetime. + * + * Note that this check is not stable and reclaim may add the + * page to swap cache at any time after this. However, if the + * page is not in swap cache by the time page->mapcount hits + * 0, there won't be any page table references to the swap + * slot, and reclaim will free it and not actually write the + * page to disk. + */ if (PageSwapCache(page)) return; __mem_cgroup_uncharge_common(page, MEM_CGROUP_CHARGE_TYPE_ANON, false); diff --git a/mm/memory.c b/mm/memory.c index 6dc1882fbd72..61a262b08e53 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -220,7 +220,6 @@ void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, bool fullmm) tlb->start = -1UL; tlb->end = 0; tlb->need_flush = 0; - tlb->fast_mode = (num_possible_cpus() == 1); tlb->local.next = NULL; tlb->local.nr = 0; tlb->local.max = ARRAY_SIZE(tlb->__pages); @@ -244,9 +243,6 @@ void tlb_flush_mmu(struct mmu_gather *tlb) tlb_table_flush(tlb); #endif - if (tlb_fast_mode(tlb)) - return; - for (batch = &tlb->local; batch; batch = batch->next) { free_pages_and_swap_cache(batch->pages, batch->nr); batch->nr = 0; @@ -288,11 +284,6 @@ int __tlb_remove_page(struct mmu_gather *tlb, struct page *page) VM_BUG_ON(!tlb->need_flush); - if (tlb_fast_mode(tlb)) { - free_page_and_swap_cache(page); - return 1; /* avoid calling tlb_flush_mmu() */ - } - batch = tlb->active; batch->pages[batch->nr++] = page; if (batch->nr == batch->max) { diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index a221fac1f47d..1ad92b46753e 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -720,9 +720,12 @@ int __remove_pages(struct zone *zone, unsigned long phys_start_pfn, start = phys_start_pfn << PAGE_SHIFT; size = nr_pages * PAGE_SIZE; ret = release_mem_region_adjustable(&iomem_resource, start, size); - if (ret) - pr_warn("Unable to release resource <%016llx-%016llx> (%d)\n", - start, start + size - 1, ret); + if (ret) { + resource_size_t endres = start + size - 1; + + pr_warn("Unable to release resource <%pa-%pa> (%d)\n", + &start, &endres, ret); + } sections_to_remove = nr_pages / PAGES_PER_SECTION; for (i = 0; i < sections_to_remove; i++) { diff --git a/mm/migrate.c b/mm/migrate.c index 27ed22579fd9..6f0c24438bba 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -165,7 +165,7 @@ static int remove_migration_pte(struct page *new, struct vm_area_struct *vma, pte = arch_make_huge_pte(pte, vma, new, 0); } #endif - flush_cache_page(vma, addr, pte_pfn(pte)); + flush_dcache_page(new); set_pte_at(mm, addr, ptep, pte); if (PageHuge(new)) { @@ -200,15 +200,14 @@ static void remove_migration_ptes(struct page *old, struct page *new) * get to the page and wait until migration is finished. * When we return from this function the fault will be retried. */ -void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd, - unsigned long address) +static void __migration_entry_wait(struct mm_struct *mm, pte_t *ptep, + spinlock_t *ptl) { - pte_t *ptep, pte; - spinlock_t *ptl; + pte_t pte; swp_entry_t entry; struct page *page; - ptep = pte_offset_map_lock(mm, pmd, address, &ptl); + spin_lock(ptl); pte = *ptep; if (!is_swap_pte(pte)) goto out; @@ -236,6 +235,20 @@ out: pte_unmap_unlock(ptep, ptl); } +void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd, + unsigned long address) +{ + spinlock_t *ptl = pte_lockptr(mm, pmd); + pte_t *ptep = pte_offset_map(pmd, address); + __migration_entry_wait(mm, ptep, ptl); +} + +void migration_entry_wait_huge(struct mm_struct *mm, pte_t *pte) +{ + spinlock_t *ptl = &(mm)->page_table_lock; + __migration_entry_wait(mm, pte, ptl); +} + #ifdef CONFIG_BLOCK /* Returns true if all buffers are successfully locked */ static bool buffer_migrate_lock_buffers(struct buffer_head *head, diff --git a/mm/mmu_notifier.c b/mm/mmu_notifier.c index be04122fb277..6725ff183374 100644 --- a/mm/mmu_notifier.c +++ b/mm/mmu_notifier.c @@ -40,48 +40,44 @@ void __mmu_notifier_release(struct mm_struct *mm) int id; /* - * srcu_read_lock() here will block synchronize_srcu() in - * mmu_notifier_unregister() until all registered - * ->release() callouts this function makes have - * returned. + * SRCU here will block mmu_notifier_unregister until + * ->release returns. */ id = srcu_read_lock(&srcu); + hlist_for_each_entry_rcu(mn, &mm->mmu_notifier_mm->list, hlist) + /* + * If ->release runs before mmu_notifier_unregister it must be + * handled, as it's the only way for the driver to flush all + * existing sptes and stop the driver from establishing any more + * sptes before all the pages in the mm are freed. + */ + if (mn->ops->release) + mn->ops->release(mn, mm); + srcu_read_unlock(&srcu, id); + spin_lock(&mm->mmu_notifier_mm->lock); while (unlikely(!hlist_empty(&mm->mmu_notifier_mm->list))) { mn = hlist_entry(mm->mmu_notifier_mm->list.first, struct mmu_notifier, hlist); - /* - * Unlink. This will prevent mmu_notifier_unregister() - * from also making the ->release() callout. + * We arrived before mmu_notifier_unregister so + * mmu_notifier_unregister will do nothing other than to wait + * for ->release to finish and for mmu_notifier_unregister to + * return. */ hlist_del_init_rcu(&mn->hlist); - spin_unlock(&mm->mmu_notifier_mm->lock); - - /* - * Clear sptes. (see 'release' description in mmu_notifier.h) - */ - if (mn->ops->release) - mn->ops->release(mn, mm); - - spin_lock(&mm->mmu_notifier_mm->lock); } spin_unlock(&mm->mmu_notifier_mm->lock); /* - * All callouts to ->release() which we have done are complete. - * Allow synchronize_srcu() in mmu_notifier_unregister() to complete - */ - srcu_read_unlock(&srcu, id); - - /* - * mmu_notifier_unregister() may have unlinked a notifier and may - * still be calling out to it. Additionally, other notifiers - * may have been active via vmtruncate() et. al. Block here - * to ensure that all notifier callouts for this mm have been - * completed and the sptes are really cleaned up before returning - * to exit_mmap(). + * synchronize_srcu here prevents mmu_notifier_release from returning to + * exit_mmap (which would proceed with freeing all pages in the mm) + * until the ->release method returns, if it was invoked by + * mmu_notifier_unregister. + * + * The mmu_notifier_mm can't go away from under us because one mm_count + * is held by exit_mmap. */ synchronize_srcu(&srcu); } @@ -292,31 +288,34 @@ void mmu_notifier_unregister(struct mmu_notifier *mn, struct mm_struct *mm) { BUG_ON(atomic_read(&mm->mm_count) <= 0); - spin_lock(&mm->mmu_notifier_mm->lock); if (!hlist_unhashed(&mn->hlist)) { + /* + * SRCU here will force exit_mmap to wait for ->release to + * finish before freeing the pages. + */ int id; + id = srcu_read_lock(&srcu); /* - * Ensure we synchronize up with __mmu_notifier_release(). + * exit_mmap will block in mmu_notifier_release to guarantee + * that ->release is called before freeing the pages. */ - id = srcu_read_lock(&srcu); - - hlist_del_rcu(&mn->hlist); - spin_unlock(&mm->mmu_notifier_mm->lock); - if (mn->ops->release) mn->ops->release(mn, mm); + srcu_read_unlock(&srcu, id); + spin_lock(&mm->mmu_notifier_mm->lock); /* - * Allow __mmu_notifier_release() to complete. + * Can not use list_del_rcu() since __mmu_notifier_release + * can delete it before we hold the lock. */ - srcu_read_unlock(&srcu, id); - } else + hlist_del_init_rcu(&mn->hlist); spin_unlock(&mm->mmu_notifier_mm->lock); + } /* - * Wait for any running method to finish, including ->release() if it - * was run by __mmu_notifier_release() instead of us. + * Wait for any running method to finish, of course including + * ->release if it was run by mmu_notifier_relase instead of us. */ synchronize_srcu(&srcu); diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 378a15bcd649..c3edb624fccf 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -1628,6 +1628,7 @@ static bool __zone_watermark_ok(struct zone *z, int order, unsigned long mark, long min = mark; long lowmem_reserve = z->lowmem_reserve[classzone_idx]; int o; + long free_cma = 0; free_pages -= (1 << order) - 1; if (alloc_flags & ALLOC_HIGH) @@ -1637,9 +1638,10 @@ static bool __zone_watermark_ok(struct zone *z, int order, unsigned long mark, #ifdef CONFIG_CMA /* If allocation can't use CMA areas don't use free CMA pages */ if (!(alloc_flags & ALLOC_CMA)) - free_pages -= zone_page_state(z, NR_FREE_CMA_PAGES); + free_cma = zone_page_state(z, NR_FREE_CMA_PAGES); #endif - if (free_pages <= min + lowmem_reserve) + + if (free_pages - free_cma <= min + lowmem_reserve) return false; for (o = 0; o < order; o++) { /* At the next order, this order's pages become unavailable */ diff --git a/mm/pagewalk.c b/mm/pagewalk.c index 35aa294656cd..5da2cbcfdbb5 100644 --- a/mm/pagewalk.c +++ b/mm/pagewalk.c @@ -127,28 +127,7 @@ static int walk_hugetlb_range(struct vm_area_struct *vma, return 0; } -static struct vm_area_struct* hugetlb_vma(unsigned long addr, struct mm_walk *walk) -{ - struct vm_area_struct *vma; - - /* We don't need vma lookup at all. */ - if (!walk->hugetlb_entry) - return NULL; - - VM_BUG_ON(!rwsem_is_locked(&walk->mm->mmap_sem)); - vma = find_vma(walk->mm, addr); - if (vma && vma->vm_start <= addr && is_vm_hugetlb_page(vma)) - return vma; - - return NULL; -} - #else /* CONFIG_HUGETLB_PAGE */ -static struct vm_area_struct* hugetlb_vma(unsigned long addr, struct mm_walk *walk) -{ - return NULL; -} - static int walk_hugetlb_range(struct vm_area_struct *vma, unsigned long addr, unsigned long end, struct mm_walk *walk) @@ -198,30 +177,53 @@ int walk_page_range(unsigned long addr, unsigned long end, if (!walk->mm) return -EINVAL; + VM_BUG_ON(!rwsem_is_locked(&walk->mm->mmap_sem)); + pgd = pgd_offset(walk->mm, addr); do { - struct vm_area_struct *vma; + struct vm_area_struct *vma = NULL; next = pgd_addr_end(addr, end); /* - * handle hugetlb vma individually because pagetable walk for - * the hugetlb page is dependent on the architecture and - * we can't handled it in the same manner as non-huge pages. + * This function was not intended to be vma based. + * But there are vma special cases to be handled: + * - hugetlb vma's + * - VM_PFNMAP vma's */ - vma = hugetlb_vma(addr, walk); + vma = find_vma(walk->mm, addr); if (vma) { - if (vma->vm_end < next) + /* + * There are no page structures backing a VM_PFNMAP + * range, so do not allow split_huge_page_pmd(). + */ + if ((vma->vm_start <= addr) && + (vma->vm_flags & VM_PFNMAP)) { next = vma->vm_end; + pgd = pgd_offset(walk->mm, next); + continue; + } /* - * Hugepage is very tightly coupled with vma, so - * walk through hugetlb entries within a given vma. + * Handle hugetlb vma individually because pagetable + * walk for the hugetlb page is dependent on the + * architecture and we can't handled it in the same + * manner as non-huge pages. */ - err = walk_hugetlb_range(vma, addr, next, walk); - if (err) - break; - pgd = pgd_offset(walk->mm, next); - continue; + if (walk->hugetlb_entry && (vma->vm_start <= addr) && + is_vm_hugetlb_page(vma)) { + if (vma->vm_end < next) + next = vma->vm_end; + /* + * Hugepage is very tightly coupled with vma, + * so walk through hugetlb entries within a + * given vma. + */ + err = walk_hugetlb_range(vma, addr, next, walk); + if (err) + break; + pgd = pgd_offset(walk->mm, next); + continue; + } } if (pgd_none_or_clear_bad(pgd)) { diff --git a/mm/slab_common.c b/mm/slab_common.c index ff3218a0f5e1..2d414508e9ec 100644 --- a/mm/slab_common.c +++ b/mm/slab_common.c @@ -373,8 +373,10 @@ struct kmem_cache *kmalloc_slab(size_t size, gfp_t flags) { int index; - if (WARN_ON_ONCE(size > KMALLOC_MAX_SIZE)) + if (size > KMALLOC_MAX_SIZE) { + WARN_ON_ONCE(!(flags & __GFP_NOWARN)); return NULL; + } if (size <= 192) { if (!size) diff --git a/mm/swap_state.c b/mm/swap_state.c index b3d40dcf3624..f24ab0dff554 100644 --- a/mm/swap_state.c +++ b/mm/swap_state.c @@ -336,8 +336,24 @@ struct page *read_swap_cache_async(swp_entry_t entry, gfp_t gfp_mask, * Swap entry may have been freed since our caller observed it. */ err = swapcache_prepare(entry); - if (err == -EEXIST) { /* seems racy */ + if (err == -EEXIST) { radix_tree_preload_end(); + /* + * We might race against get_swap_page() and stumble + * across a SWAP_HAS_CACHE swap_map entry whose page + * has not been brought into the swapcache yet, while + * the other end is scheduled away waiting on discard + * I/O completion at scan_swap_map(). + * + * In order to avoid turning this transitory state + * into a permanent loop around this -EEXIST case + * if !CONFIG_PREEMPT and the I/O completion happens + * to be waiting on the CPU waitqueue where we are now + * busy looping, we just conditionally invoke the + * scheduler here, if there are some more important + * tasks to run. + */ + cond_resched(); continue; } if (err) { /* swp entry is obsolete ? */ diff --git a/mm/swapfile.c b/mm/swapfile.c index 6c340d908b27..746af55b8455 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -2116,7 +2116,7 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) } /* frontswap enabled? set up bit-per-page map for frontswap */ if (frontswap_enabled) - frontswap_map = vzalloc(maxpages / sizeof(long)); + frontswap_map = vzalloc(BITS_TO_LONGS(maxpages) * sizeof(long)); if (p->bdev) { if (blk_queue_nonrot(bdev_get_queue(p->bdev))) { diff --git a/net/802/mrp.c b/net/802/mrp.c index e085bcc754f6..1eb05d80b07b 100644 --- a/net/802/mrp.c +++ b/net/802/mrp.c @@ -871,10 +871,10 @@ void mrp_uninit_applicant(struct net_device *dev, struct mrp_application *appl) */ del_timer_sync(&app->join_timer); - spin_lock(&app->lock); + spin_lock_bh(&app->lock); mrp_mad_event(app, MRP_EVENT_TX); mrp_pdu_queue(app); - spin_unlock(&app->lock); + spin_unlock_bh(&app->lock); mrp_queue_xmit(app); diff --git a/net/9p/client.c b/net/9p/client.c index 8eb75425e6e6..addc116cecf0 100644 --- a/net/9p/client.c +++ b/net/9p/client.c @@ -562,36 +562,19 @@ static int p9_check_zc_errors(struct p9_client *c, struct p9_req_t *req, if (!p9_is_proto_dotl(c)) { /* Error is reported in string format */ - uint16_t len; - /* 7 = header size for RERROR, 2 is the size of string len; */ - int inline_len = in_hdrlen - (7 + 2); + int len; + /* 7 = header size for RERROR; */ + int inline_len = in_hdrlen - 7; - /* Read the size of error string */ - err = p9pdu_readf(req->rc, c->proto_version, "w", &len); - if (err) - goto out_err; - - ename = kmalloc(len + 1, GFP_NOFS); - if (!ename) { - err = -ENOMEM; + len = req->rc->size - req->rc->offset; + if (len > (P9_ZC_HDR_SZ - 7)) { + err = -EFAULT; goto out_err; } - if (len <= inline_len) { - /* We have error in protocol buffer itself */ - if (pdu_read(req->rc, ename, len)) { - err = -EFAULT; - goto out_free; - } - } else { - /* - * Part of the data is in user space buffer. - */ - if (pdu_read(req->rc, ename, inline_len)) { - err = -EFAULT; - goto out_free; - - } + ename = &req->rc->sdata[req->rc->offset]; + if (len > inline_len) { + /* We have error in external buffer */ if (kern_buf) { memcpy(ename + inline_len, uidata, len - inline_len); @@ -600,19 +583,19 @@ static int p9_check_zc_errors(struct p9_client *c, struct p9_req_t *req, uidata, len - inline_len); if (err) { err = -EFAULT; - goto out_free; + goto out_err; } } } - ename[len] = 0; - if (p9_is_proto_dotu(c)) { - /* For dotu we also have error code */ - err = p9pdu_readf(req->rc, - c->proto_version, "d", &ecode); - if (err) - goto out_free; + ename = NULL; + err = p9pdu_readf(req->rc, c->proto_version, "s?d", + &ename, &ecode); + if (err) + goto out_err; + + if (p9_is_proto_dotu(c)) err = -ecode; - } + if (!err || !IS_ERR_VALUE(err)) { err = p9_errstr2errno(ename, strlen(ename)); @@ -628,8 +611,6 @@ static int p9_check_zc_errors(struct p9_client *c, struct p9_req_t *req, } return err; -out_free: - kfree(ename); out_err: p9_debug(P9_DEBUG_ERROR, "couldn't parse error%d\n", err); return err; diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index 071f288b77a8..f680ee101878 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c @@ -29,6 +29,21 @@ #include "bat_algo.h" #include "network-coding.h" +/** + * batadv_dup_status - duplicate status + * @BATADV_NO_DUP: the packet is a duplicate + * @BATADV_ORIG_DUP: OGM is a duplicate in the originator (but not for the + * neighbor) + * @BATADV_NEIGH_DUP: OGM is a duplicate for the neighbor + * @BATADV_PROTECTED: originator is currently protected (after reboot) + */ +enum batadv_dup_status { + BATADV_NO_DUP = 0, + BATADV_ORIG_DUP, + BATADV_NEIGH_DUP, + BATADV_PROTECTED, +}; + static struct batadv_neigh_node * batadv_iv_ogm_neigh_new(struct batadv_hard_iface *hard_iface, const uint8_t *neigh_addr, @@ -650,7 +665,7 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv, const struct batadv_ogm_packet *batadv_ogm_packet, struct batadv_hard_iface *if_incoming, const unsigned char *tt_buff, - int is_duplicate) + enum batadv_dup_status dup_status) { struct batadv_neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL; struct batadv_neigh_node *router = NULL; @@ -676,7 +691,7 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv, continue; } - if (is_duplicate) + if (dup_status != BATADV_NO_DUP) continue; spin_lock_bh(&tmp_neigh_node->lq_update_lock); @@ -718,7 +733,7 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv, neigh_node->tq_avg = batadv_ring_buffer_avg(neigh_node->tq_recv); spin_unlock_bh(&neigh_node->lq_update_lock); - if (!is_duplicate) { + if (dup_status == BATADV_NO_DUP) { orig_node->last_ttl = batadv_ogm_packet->header.ttl; neigh_node->last_ttl = batadv_ogm_packet->header.ttl; } @@ -902,15 +917,16 @@ out: return ret; } -/* processes a batman packet for all interfaces, adjusts the sequence number and - * finds out whether it is a duplicate. - * returns: - * 1 the packet is a duplicate - * 0 the packet has not yet been received - * -1 the packet is old and has been received while the seqno window - * was protected. Caller should drop it. +/** + * batadv_iv_ogm_update_seqnos - process a batman packet for all interfaces, + * adjust the sequence number and find out whether it is a duplicate + * @ethhdr: ethernet header of the packet + * @batadv_ogm_packet: OGM packet to be considered + * @if_incoming: interface on which the OGM packet was received + * + * Returns duplicate status as enum batadv_dup_status */ -static int +static enum batadv_dup_status batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr, const struct batadv_ogm_packet *batadv_ogm_packet, const struct batadv_hard_iface *if_incoming) @@ -918,17 +934,18 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr, struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface); struct batadv_orig_node *orig_node; struct batadv_neigh_node *tmp_neigh_node; - int is_duplicate = 0; + int is_dup; int32_t seq_diff; int need_update = 0; - int set_mark, ret = -1; + int set_mark; + enum batadv_dup_status ret = BATADV_NO_DUP; uint32_t seqno = ntohl(batadv_ogm_packet->seqno); uint8_t *neigh_addr; uint8_t packet_count; orig_node = batadv_get_orig_node(bat_priv, batadv_ogm_packet->orig); if (!orig_node) - return 0; + return BATADV_NO_DUP; spin_lock_bh(&orig_node->ogm_cnt_lock); seq_diff = seqno - orig_node->last_real_seqno; @@ -936,22 +953,29 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr, /* signalize caller that the packet is to be dropped. */ if (!hlist_empty(&orig_node->neigh_list) && batadv_window_protected(bat_priv, seq_diff, - &orig_node->batman_seqno_reset)) + &orig_node->batman_seqno_reset)) { + ret = BATADV_PROTECTED; goto out; + } rcu_read_lock(); hlist_for_each_entry_rcu(tmp_neigh_node, &orig_node->neigh_list, list) { - is_duplicate |= batadv_test_bit(tmp_neigh_node->real_bits, - orig_node->last_real_seqno, - seqno); - neigh_addr = tmp_neigh_node->addr; + is_dup = batadv_test_bit(tmp_neigh_node->real_bits, + orig_node->last_real_seqno, + seqno); + if (batadv_compare_eth(neigh_addr, ethhdr->h_source) && - tmp_neigh_node->if_incoming == if_incoming) + tmp_neigh_node->if_incoming == if_incoming) { set_mark = 1; - else + if (is_dup) + ret = BATADV_NEIGH_DUP; + } else { set_mark = 0; + if (is_dup && (ret != BATADV_NEIGH_DUP)) + ret = BATADV_ORIG_DUP; + } /* if the window moved, set the update flag. */ need_update |= batadv_bit_get_packet(bat_priv, @@ -971,8 +995,6 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr, orig_node->last_real_seqno = seqno; } - ret = is_duplicate; - out: spin_unlock_bh(&orig_node->ogm_cnt_lock); batadv_orig_node_free_ref(orig_node); @@ -994,7 +1016,8 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr, int is_broadcast = 0, is_bidirect; bool is_single_hop_neigh = false; bool is_from_best_next_hop = false; - int is_duplicate, sameseq, simlar_ttl; + int sameseq, similar_ttl; + enum batadv_dup_status dup_status; uint32_t if_incoming_seqno; uint8_t *prev_sender; @@ -1138,10 +1161,10 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr, if (!orig_node) return; - is_duplicate = batadv_iv_ogm_update_seqnos(ethhdr, batadv_ogm_packet, - if_incoming); + dup_status = batadv_iv_ogm_update_seqnos(ethhdr, batadv_ogm_packet, + if_incoming); - if (is_duplicate == -1) { + if (dup_status == BATADV_PROTECTED) { batadv_dbg(BATADV_DBG_BATMAN, bat_priv, "Drop packet: packet within seqno protection time (sender: %pM)\n", ethhdr->h_source); @@ -1211,11 +1234,12 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr, * seqno and similar ttl as the non-duplicate */ sameseq = orig_node->last_real_seqno == ntohl(batadv_ogm_packet->seqno); - simlar_ttl = orig_node->last_ttl - 3 <= batadv_ogm_packet->header.ttl; - if (is_bidirect && (!is_duplicate || (sameseq && simlar_ttl))) + similar_ttl = orig_node->last_ttl - 3 <= batadv_ogm_packet->header.ttl; + if (is_bidirect && ((dup_status == BATADV_NO_DUP) || + (sameseq && similar_ttl))) batadv_iv_ogm_orig_update(bat_priv, orig_node, ethhdr, batadv_ogm_packet, if_incoming, - tt_buff, is_duplicate); + tt_buff, dup_status); /* is single hop (direct) neighbor */ if (is_single_hop_neigh) { @@ -1236,7 +1260,7 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr, goto out_neigh; } - if (is_duplicate) { + if (dup_status == BATADV_NEIGH_DUP) { batadv_dbg(BATADV_DBG_BATMAN, bat_priv, "Drop packet: duplicate packet received\n"); goto out_neigh; diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index 379061c72549..de27b3175cfd 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c @@ -1067,6 +1067,10 @@ void batadv_bla_update_orig_address(struct batadv_priv *bat_priv, group = htons(crc16(0, primary_if->net_dev->dev_addr, ETH_ALEN)); bat_priv->bla.claim_dest.group = group; + /* purge everything when bridge loop avoidance is turned off */ + if (!atomic_read(&bat_priv->bridge_loop_avoidance)) + oldif = NULL; + if (!oldif) { batadv_bla_purge_claims(bat_priv, NULL, 1); batadv_bla_purge_backbone_gw(bat_priv, 1); diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index 1240f07ad31d..51aafd669cbb 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c @@ -181,6 +181,7 @@ void batadv_mesh_free(struct net_device *soft_iface) batadv_originator_free(bat_priv); free_percpu(bat_priv->bat_counters); + bat_priv->bat_counters = NULL; atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE); } diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index 2f3452546636..fad1a2093e15 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c @@ -156,12 +156,28 @@ static void batadv_orig_node_free_rcu(struct rcu_head *rcu) kfree(orig_node); } +/** + * batadv_orig_node_free_ref - decrement the orig node refcounter and possibly + * schedule an rcu callback for freeing it + * @orig_node: the orig node to free + */ void batadv_orig_node_free_ref(struct batadv_orig_node *orig_node) { if (atomic_dec_and_test(&orig_node->refcount)) call_rcu(&orig_node->rcu, batadv_orig_node_free_rcu); } +/** + * batadv_orig_node_free_ref_now - decrement the orig node refcounter and + * possibly free it (without rcu callback) + * @orig_node: the orig node to free + */ +void batadv_orig_node_free_ref_now(struct batadv_orig_node *orig_node) +{ + if (atomic_dec_and_test(&orig_node->refcount)) + batadv_orig_node_free_rcu(&orig_node->rcu); +} + void batadv_originator_free(struct batadv_priv *bat_priv) { struct batadv_hashtable *hash = bat_priv->orig_hash; diff --git a/net/batman-adv/originator.h b/net/batman-adv/originator.h index 7df48fa7669d..734e5a3d8a5b 100644 --- a/net/batman-adv/originator.h +++ b/net/batman-adv/originator.h @@ -26,6 +26,7 @@ int batadv_originator_init(struct batadv_priv *bat_priv); void batadv_originator_free(struct batadv_priv *bat_priv); void batadv_purge_orig_ref(struct batadv_priv *bat_priv); void batadv_orig_node_free_ref(struct batadv_orig_node *orig_node); +void batadv_orig_node_free_ref_now(struct batadv_orig_node *orig_node); struct batadv_orig_node *batadv_get_orig_node(struct batadv_priv *bat_priv, const uint8_t *addr); struct batadv_neigh_node * diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index 6f20d339e33a..819dfb006cdf 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -505,6 +505,7 @@ unreg_debugfs: batadv_debugfs_del_meshif(dev); free_bat_counters: free_percpu(bat_priv->bat_counters); + bat_priv->bat_counters = NULL; return ret; } diff --git a/net/batman-adv/sysfs.c b/net/batman-adv/sysfs.c index 15a22efa9a67..929e304dacb2 100644 --- a/net/batman-adv/sysfs.c +++ b/net/batman-adv/sysfs.c @@ -582,10 +582,7 @@ static ssize_t batadv_store_mesh_iface(struct kobject *kobj, (strncmp(hard_iface->soft_iface->name, buff, IFNAMSIZ) == 0)) goto out; - if (!rtnl_trylock()) { - ret = -ERESTARTSYS; - goto out; - } + rtnl_lock(); if (status_tmp == BATADV_IF_NOT_IN_USE) { batadv_hardif_disable_interface(hard_iface, diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index 5e89deeb9542..9e8748575845 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -144,7 +144,12 @@ static void batadv_tt_orig_list_entry_free_rcu(struct rcu_head *rcu) struct batadv_tt_orig_list_entry *orig_entry; orig_entry = container_of(rcu, struct batadv_tt_orig_list_entry, rcu); - batadv_orig_node_free_ref(orig_entry->orig_node); + + /* We are in an rcu callback here, therefore we cannot use + * batadv_orig_node_free_ref() and its call_rcu(): + * An rcu_barrier() wouldn't wait for that to finish + */ + batadv_orig_node_free_ref_now(orig_entry->orig_node); kfree(orig_entry); } diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 33843c5c4939..d817c932d634 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1555,11 +1555,15 @@ static const struct rfkill_ops hci_rfkill_ops = { static void hci_power_on(struct work_struct *work) { struct hci_dev *hdev = container_of(work, struct hci_dev, power_on); + int err; BT_DBG("%s", hdev->name); - if (hci_dev_open(hdev->id) < 0) + err = hci_dev_open(hdev->id); + if (err < 0) { + mgmt_set_powered_failed(hdev, err); return; + } if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) queue_delayed_work(hdev->req_workqueue, &hdev->power_off, diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index a76d1ac0321b..24bee07ee4ce 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -3677,10 +3677,14 @@ static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len) } static inline int l2cap_command_rej(struct l2cap_conn *conn, - struct l2cap_cmd_hdr *cmd, u8 *data) + struct l2cap_cmd_hdr *cmd, u16 cmd_len, + u8 *data) { struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data; + if (cmd_len < sizeof(*rej)) + return -EPROTO; + if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD) return 0; @@ -3829,11 +3833,14 @@ sendresp: } static int l2cap_connect_req(struct l2cap_conn *conn, - struct l2cap_cmd_hdr *cmd, u8 *data) + struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data) { struct hci_dev *hdev = conn->hcon->hdev; struct hci_conn *hcon = conn->hcon; + if (cmd_len < sizeof(struct l2cap_conn_req)) + return -EPROTO; + hci_dev_lock(hdev); if (test_bit(HCI_MGMT, &hdev->dev_flags) && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags)) @@ -3847,7 +3854,8 @@ static int l2cap_connect_req(struct l2cap_conn *conn, } static int l2cap_connect_create_rsp(struct l2cap_conn *conn, - struct l2cap_cmd_hdr *cmd, u8 *data) + struct l2cap_cmd_hdr *cmd, u16 cmd_len, + u8 *data) { struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data; u16 scid, dcid, result, status; @@ -3855,6 +3863,9 @@ static int l2cap_connect_create_rsp(struct l2cap_conn *conn, u8 req[128]; int err; + if (cmd_len < sizeof(*rsp)) + return -EPROTO; + scid = __le16_to_cpu(rsp->scid); dcid = __le16_to_cpu(rsp->dcid); result = __le16_to_cpu(rsp->result); @@ -3952,6 +3963,9 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_chan *chan; int len, err = 0; + if (cmd_len < sizeof(*req)) + return -EPROTO; + dcid = __le16_to_cpu(req->dcid); flags = __le16_to_cpu(req->flags); @@ -3975,7 +3989,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, /* Reject if config buffer is too small. */ len = cmd_len - sizeof(*req); - if (len < 0 || chan->conf_len + len > sizeof(chan->conf_req)) { + if (chan->conf_len + len > sizeof(chan->conf_req)) { l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_build_conf_rsp(chan, rsp, L2CAP_CONF_REJECT, flags), rsp); @@ -4053,14 +4067,18 @@ unlock: } static inline int l2cap_config_rsp(struct l2cap_conn *conn, - struct l2cap_cmd_hdr *cmd, u8 *data) + struct l2cap_cmd_hdr *cmd, u16 cmd_len, + u8 *data) { struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data; u16 scid, flags, result; struct l2cap_chan *chan; - int len = le16_to_cpu(cmd->len) - sizeof(*rsp); + int len = cmd_len - sizeof(*rsp); int err = 0; + if (cmd_len < sizeof(*rsp)) + return -EPROTO; + scid = __le16_to_cpu(rsp->scid); flags = __le16_to_cpu(rsp->flags); result = __le16_to_cpu(rsp->result); @@ -4161,7 +4179,8 @@ done: } static inline int l2cap_disconnect_req(struct l2cap_conn *conn, - struct l2cap_cmd_hdr *cmd, u8 *data) + struct l2cap_cmd_hdr *cmd, u16 cmd_len, + u8 *data) { struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data; struct l2cap_disconn_rsp rsp; @@ -4169,6 +4188,9 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_chan *chan; struct sock *sk; + if (cmd_len != sizeof(*req)) + return -EPROTO; + scid = __le16_to_cpu(req->scid); dcid = __le16_to_cpu(req->dcid); @@ -4208,12 +4230,16 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, } static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, - struct l2cap_cmd_hdr *cmd, u8 *data) + struct l2cap_cmd_hdr *cmd, u16 cmd_len, + u8 *data) { struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data; u16 dcid, scid; struct l2cap_chan *chan; + if (cmd_len != sizeof(*rsp)) + return -EPROTO; + scid = __le16_to_cpu(rsp->scid); dcid = __le16_to_cpu(rsp->dcid); @@ -4243,11 +4269,15 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, } static inline int l2cap_information_req(struct l2cap_conn *conn, - struct l2cap_cmd_hdr *cmd, u8 *data) + struct l2cap_cmd_hdr *cmd, u16 cmd_len, + u8 *data) { struct l2cap_info_req *req = (struct l2cap_info_req *) data; u16 type; + if (cmd_len != sizeof(*req)) + return -EPROTO; + type = __le16_to_cpu(req->type); BT_DBG("type 0x%4.4x", type); @@ -4294,11 +4324,15 @@ static inline int l2cap_information_req(struct l2cap_conn *conn, } static inline int l2cap_information_rsp(struct l2cap_conn *conn, - struct l2cap_cmd_hdr *cmd, u8 *data) + struct l2cap_cmd_hdr *cmd, u16 cmd_len, + u8 *data) { struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data; u16 type, result; + if (cmd_len != sizeof(*rsp)) + return -EPROTO; + type = __le16_to_cpu(rsp->type); result = __le16_to_cpu(rsp->result); @@ -5164,16 +5198,16 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn, switch (cmd->code) { case L2CAP_COMMAND_REJ: - l2cap_command_rej(conn, cmd, data); + l2cap_command_rej(conn, cmd, cmd_len, data); break; case L2CAP_CONN_REQ: - err = l2cap_connect_req(conn, cmd, data); + err = l2cap_connect_req(conn, cmd, cmd_len, data); break; case L2CAP_CONN_RSP: case L2CAP_CREATE_CHAN_RSP: - err = l2cap_connect_create_rsp(conn, cmd, data); + err = l2cap_connect_create_rsp(conn, cmd, cmd_len, data); break; case L2CAP_CONF_REQ: @@ -5181,15 +5215,15 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn, break; case L2CAP_CONF_RSP: - err = l2cap_config_rsp(conn, cmd, data); + err = l2cap_config_rsp(conn, cmd, cmd_len, data); break; case L2CAP_DISCONN_REQ: - err = l2cap_disconnect_req(conn, cmd, data); + err = l2cap_disconnect_req(conn, cmd, cmd_len, data); break; case L2CAP_DISCONN_RSP: - err = l2cap_disconnect_rsp(conn, cmd, data); + err = l2cap_disconnect_rsp(conn, cmd, cmd_len, data); break; case L2CAP_ECHO_REQ: @@ -5200,11 +5234,11 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn, break; case L2CAP_INFO_REQ: - err = l2cap_information_req(conn, cmd, data); + err = l2cap_information_req(conn, cmd, cmd_len, data); break; case L2CAP_INFO_RSP: - err = l2cap_information_rsp(conn, cmd, data); + err = l2cap_information_rsp(conn, cmd, cmd_len, data); break; case L2CAP_CREATE_CHAN_REQ: diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 35fef22703e9..f8ecbc70293d 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -2700,7 +2700,7 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev, break; case DISCOV_TYPE_LE: - if (!lmp_host_le_capable(hdev)) { + if (!test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) { err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY, MGMT_STATUS_NOT_SUPPORTED); mgmt_pending_remove(cmd); @@ -3418,6 +3418,27 @@ new_settings: return err; } +int mgmt_set_powered_failed(struct hci_dev *hdev, int err) +{ + struct pending_cmd *cmd; + u8 status; + + cmd = mgmt_pending_find(MGMT_OP_SET_POWERED, hdev); + if (!cmd) + return -ENOENT; + + if (err == -ERFKILL) + status = MGMT_STATUS_RFKILLED; + else + status = MGMT_STATUS_FAILED; + + err = cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_POWERED, status); + + mgmt_pending_remove(cmd); + + return err; +} + int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable) { struct cmd_lookup match = { NULL, hdev }; diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index b2296d3857a0..b5562abdd6e0 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -770,7 +770,7 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level) BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level); - if (!lmp_host_le_capable(hcon->hdev)) + if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) return 1; if (sec_level == BT_SECURITY_LOW) @@ -851,7 +851,7 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb) __u8 reason; int err = 0; - if (!lmp_host_le_capable(conn->hcon->hdev)) { + if (!test_bit(HCI_LE_ENABLED, &conn->hcon->hdev->dev_flags)) { err = -ENOTSUPP; reason = SMP_PAIRING_NOTSUPP; goto done; diff --git a/net/bridge/netfilter/ebt_log.c b/net/bridge/netfilter/ebt_log.c index 9878eb8204c5..19c37a4929bc 100644 --- a/net/bridge/netfilter/ebt_log.c +++ b/net/bridge/netfilter/ebt_log.c @@ -72,13 +72,12 @@ print_ports(const struct sk_buff *skb, uint8_t protocol, int offset) } static void -ebt_log_packet(u_int8_t pf, unsigned int hooknum, - const struct sk_buff *skb, const struct net_device *in, - const struct net_device *out, const struct nf_loginfo *loginfo, - const char *prefix) +ebt_log_packet(struct net *net, u_int8_t pf, unsigned int hooknum, + const struct sk_buff *skb, const struct net_device *in, + const struct net_device *out, const struct nf_loginfo *loginfo, + const char *prefix) { unsigned int bitmask; - struct net *net = dev_net(in ? in : out); /* FIXME: Disabled from containers until syslog ns is supported */ if (!net_eq(net, &init_net)) @@ -191,7 +190,7 @@ ebt_log_tg(struct sk_buff *skb, const struct xt_action_param *par) nf_log_packet(net, NFPROTO_BRIDGE, par->hooknum, skb, par->in, par->out, &li, "%s", info->prefix); else - ebt_log_packet(NFPROTO_BRIDGE, par->hooknum, skb, par->in, + ebt_log_packet(net, NFPROTO_BRIDGE, par->hooknum, skb, par->in, par->out, &li, info->prefix); return EBT_CONTINUE; } diff --git a/net/bridge/netfilter/ebt_ulog.c b/net/bridge/netfilter/ebt_ulog.c index fc1905c51417..df0364aa12d5 100644 --- a/net/bridge/netfilter/ebt_ulog.c +++ b/net/bridge/netfilter/ebt_ulog.c @@ -131,14 +131,16 @@ static struct sk_buff *ulog_alloc_skb(unsigned int size) return skb; } -static void ebt_ulog_packet(unsigned int hooknr, const struct sk_buff *skb, - const struct net_device *in, const struct net_device *out, - const struct ebt_ulog_info *uloginfo, const char *prefix) +static void ebt_ulog_packet(struct net *net, unsigned int hooknr, + const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const struct ebt_ulog_info *uloginfo, + const char *prefix) { ebt_ulog_packet_msg_t *pm; size_t size, copy_len; struct nlmsghdr *nlh; - struct net *net = dev_net(in ? in : out); struct ebt_ulog_net *ebt = ebt_ulog_pernet(net); unsigned int group = uloginfo->nlgroup; ebt_ulog_buff_t *ub = &ebt->ulog_buffers[group]; @@ -233,7 +235,7 @@ unlock: } /* this function is registered with the netfilter core */ -static void ebt_log_packet(u_int8_t pf, unsigned int hooknum, +static void ebt_log_packet(struct net *net, u_int8_t pf, unsigned int hooknum, const struct sk_buff *skb, const struct net_device *in, const struct net_device *out, const struct nf_loginfo *li, const char *prefix) @@ -252,13 +254,15 @@ static void ebt_log_packet(u_int8_t pf, unsigned int hooknum, strlcpy(loginfo.prefix, prefix, sizeof(loginfo.prefix)); } - ebt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix); + ebt_ulog_packet(net, hooknum, skb, in, out, &loginfo, prefix); } static unsigned int ebt_ulog_tg(struct sk_buff *skb, const struct xt_action_param *par) { - ebt_ulog_packet(par->hooknum, skb, par->in, par->out, + struct net *net = dev_net(par->in ? par->in : par->out); + + ebt_ulog_packet(net, par->hooknum, skb, par->in, par->out, par->targinfo, NULL); return EBT_CONTINUE; } diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index d5953b87918c..3a246a6cab47 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c @@ -1675,13 +1675,13 @@ static void kick_requests(struct ceph_osd_client *osdc, int force_resend) __register_request(osdc, req); __unregister_linger_request(osdc, req); } + reset_changed_osds(osdc); mutex_unlock(&osdc->request_mutex); if (needmap) { dout("%d requests for down osds, need new map\n", needmap); ceph_monc_request_next_osdmap(&osdc->client->monc); } - reset_changed_osds(osdc); } diff --git a/net/compat.c b/net/compat.c index 79ae88485001..f0a1ba6c8086 100644 --- a/net/compat.c +++ b/net/compat.c @@ -734,19 +734,25 @@ static unsigned char nas[21] = { asmlinkage long compat_sys_sendmsg(int fd, struct compat_msghdr __user *msg, unsigned int flags) { - return sys_sendmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT); + if (flags & MSG_CMSG_COMPAT) + return -EINVAL; + return __sys_sendmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT); } asmlinkage long compat_sys_sendmmsg(int fd, struct compat_mmsghdr __user *mmsg, unsigned int vlen, unsigned int flags) { + if (flags & MSG_CMSG_COMPAT) + return -EINVAL; return __sys_sendmmsg(fd, (struct mmsghdr __user *)mmsg, vlen, flags | MSG_CMSG_COMPAT); } asmlinkage long compat_sys_recvmsg(int fd, struct compat_msghdr __user *msg, unsigned int flags) { - return sys_recvmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT); + if (flags & MSG_CMSG_COMPAT) + return -EINVAL; + return __sys_recvmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT); } asmlinkage long compat_sys_recv(int fd, void __user *buf, size_t len, unsigned int flags) @@ -768,6 +774,9 @@ asmlinkage long compat_sys_recvmmsg(int fd, struct compat_mmsghdr __user *mmsg, int datagrams; struct timespec ktspec; + if (flags & MSG_CMSG_COMPAT) + return -EINVAL; + if (COMPAT_USE_64BIT_TIME) return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen, flags | MSG_CMSG_COMPAT, diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c index c013f38482a1..6cda4e2c2132 100644 --- a/net/core/dev_addr_lists.c +++ b/net/core/dev_addr_lists.c @@ -39,6 +39,7 @@ static int __hw_addr_create_ex(struct netdev_hw_addr_list *list, ha->refcount = 1; ha->global_use = global; ha->synced = sync; + ha->sync_cnt = 0; list_add_tail_rcu(&ha->list, &list->list); list->count++; @@ -66,7 +67,7 @@ static int __hw_addr_add_ex(struct netdev_hw_addr_list *list, } if (sync) { if (ha->synced) - return 0; + return -EEXIST; else ha->synced = true; } @@ -139,10 +140,13 @@ static int __hw_addr_sync_one(struct netdev_hw_addr_list *to_list, err = __hw_addr_add_ex(to_list, ha->addr, addr_len, ha->type, false, true); - if (err) + if (err && err != -EEXIST) return err; - ha->sync_cnt++; - ha->refcount++; + + if (!err) { + ha->sync_cnt++; + ha->refcount++; + } return 0; } @@ -159,7 +163,8 @@ static void __hw_addr_unsync_one(struct netdev_hw_addr_list *to_list, if (err) return; ha->sync_cnt--; - __hw_addr_del_entry(from_list, ha, false, true); + /* address on from list is not marked synced */ + __hw_addr_del_entry(from_list, ha, false, false); } static int __hw_addr_sync_multiple(struct netdev_hw_addr_list *to_list, @@ -796,7 +801,7 @@ int dev_mc_sync_multiple(struct net_device *to, struct net_device *from) return -EINVAL; netif_addr_lock_nested(to); - err = __hw_addr_sync(&to->mc, &from->mc, to->addr_len); + err = __hw_addr_sync_multiple(&to->mc, &from->mc, to->addr_len); if (!err) __dev_set_rx_mode(to); netif_addr_unlock(to); diff --git a/net/core/filter.c b/net/core/filter.c index dad2a178f9f8..6438f29ff266 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -778,7 +778,7 @@ int sk_detach_filter(struct sock *sk) } EXPORT_SYMBOL_GPL(sk_detach_filter); -static void sk_decode_filter(struct sock_filter *filt, struct sock_filter *to) +void sk_decode_filter(struct sock_filter *filt, struct sock_filter *to) { static const u16 decodes[] = { [BPF_S_ALU_ADD_K] = BPF_ALU|BPF_ADD|BPF_K, diff --git a/net/core/skbuff.c b/net/core/skbuff.c index af9185d0be6a..cfd777bd6bd0 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -195,7 +195,7 @@ struct sk_buff *__alloc_skb_head(gfp_t gfp_mask, int node) * the tail pointer in struct sk_buff! */ memset(skb, 0, offsetof(struct sk_buff, tail)); - skb->data = NULL; + skb->head = NULL; skb->truesize = sizeof(struct sk_buff); atomic_set(&skb->users, 1); @@ -611,7 +611,7 @@ static void skb_release_head_state(struct sk_buff *skb) static void skb_release_all(struct sk_buff *skb) { skb_release_head_state(skb); - if (likely(skb->data)) + if (likely(skb->head)) skb_release_data(skb); } diff --git a/net/core/sock.c b/net/core/sock.c index 6ba327da79e1..88868a9d21da 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -210,7 +210,7 @@ static const char *const af_family_key_strings[AF_MAX+1] = { "sk_lock-AF_TIPC" , "sk_lock-AF_BLUETOOTH", "sk_lock-IUCV" , "sk_lock-AF_RXRPC" , "sk_lock-AF_ISDN" , "sk_lock-AF_PHONET" , "sk_lock-AF_IEEE802154", "sk_lock-AF_CAIF" , "sk_lock-AF_ALG" , - "sk_lock-AF_NFC" , "sk_lock-AF_MAX" + "sk_lock-AF_NFC" , "sk_lock-AF_VSOCK" , "sk_lock-AF_MAX" }; static const char *const af_family_slock_key_strings[AF_MAX+1] = { "slock-AF_UNSPEC", "slock-AF_UNIX" , "slock-AF_INET" , @@ -226,7 +226,7 @@ static const char *const af_family_slock_key_strings[AF_MAX+1] = { "slock-AF_TIPC" , "slock-AF_BLUETOOTH", "slock-AF_IUCV" , "slock-AF_RXRPC" , "slock-AF_ISDN" , "slock-AF_PHONET" , "slock-AF_IEEE802154", "slock-AF_CAIF" , "slock-AF_ALG" , - "slock-AF_NFC" , "slock-AF_MAX" + "slock-AF_NFC" , "slock-AF_VSOCK" ,"slock-AF_MAX" }; static const char *const af_family_clock_key_strings[AF_MAX+1] = { "clock-AF_UNSPEC", "clock-AF_UNIX" , "clock-AF_INET" , @@ -242,7 +242,7 @@ static const char *const af_family_clock_key_strings[AF_MAX+1] = { "clock-AF_TIPC" , "clock-AF_BLUETOOTH", "clock-AF_IUCV" , "clock-AF_RXRPC" , "clock-AF_ISDN" , "clock-AF_PHONET" , "clock-AF_IEEE802154", "clock-AF_CAIF" , "clock-AF_ALG" , - "clock-AF_NFC" , "clock-AF_MAX" + "clock-AF_NFC" , "clock-AF_VSOCK" , "clock-AF_MAX" }; /* diff --git a/net/core/sock_diag.c b/net/core/sock_diag.c index d5bef0b0f639..a0e9cf6379de 100644 --- a/net/core/sock_diag.c +++ b/net/core/sock_diag.c @@ -73,8 +73,13 @@ int sock_diag_put_filterinfo(struct user_namespace *user_ns, struct sock *sk, goto out; } - if (filter) - memcpy(nla_data(attr), filter->insns, len); + if (filter) { + struct sock_filter *fb = (struct sock_filter *)nla_data(attr); + int i; + + for (i = 0; i < filter->len; i++, fb++) + sk_decode_filter(&filter->insns[i], fb); + } out: rcu_read_unlock(); diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index c625e4dad4b0..2a83591492dd 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -235,7 +235,7 @@ static void ipgre_err(struct sk_buff *skb, u32 info) */ struct net *net = dev_net(skb->dev); struct ip_tunnel_net *itn; - const struct iphdr *iph = (const struct iphdr *)skb->data; + const struct iphdr *iph; const int type = icmp_hdr(skb)->type; const int code = icmp_hdr(skb)->code; struct ip_tunnel *t; @@ -281,6 +281,7 @@ static void ipgre_err(struct sk_buff *skb, u32 info) else itn = net_generic(net, ipgre_net_id); + iph = (const struct iphdr *)skb->data; t = ip_tunnel_lookup(itn, skb->dev->ifindex, tpi.flags, iph->daddr, iph->saddr, tpi.key); diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c index e4147ec1665a..7fa8f08fa7ae 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c @@ -503,6 +503,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, inner_iph = (const struct iphdr *)skb_inner_network_header(skb); + memset(IPCB(skb), 0, sizeof(*IPCB(skb))); dst = tnl_params->daddr; if (dst == 0) { /* NBMA tunnel */ @@ -658,7 +659,6 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, skb_dst_drop(skb); skb_dst_set(skb, &rt->dst); - memset(IPCB(skb), 0, sizeof(*IPCB(skb))); /* Push down and install the IP header. */ skb_push(skb, sizeof(struct iphdr)); @@ -853,7 +853,7 @@ void ip_tunnel_dellink(struct net_device *dev, struct list_head *head) } EXPORT_SYMBOL_GPL(ip_tunnel_dellink); -int __net_init ip_tunnel_init_net(struct net *net, int ip_tnl_net_id, +int ip_tunnel_init_net(struct net *net, int ip_tnl_net_id, struct rtnl_link_ops *ops, char *devname) { struct ip_tunnel_net *itn = net_generic(net, ip_tnl_net_id); @@ -899,7 +899,7 @@ static void ip_tunnel_destroy(struct ip_tunnel_net *itn, struct list_head *head) unregister_netdevice_queue(itn->fb_tunnel_dev, head); } -void __net_exit ip_tunnel_delete_net(struct ip_tunnel_net *itn) +void ip_tunnel_delete_net(struct ip_tunnel_net *itn) { LIST_HEAD(list); diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c index 9d2bdb2c1d3f..c118f6b576bb 100644 --- a/net/ipv4/ip_vti.c +++ b/net/ipv4/ip_vti.c @@ -361,8 +361,7 @@ static netdev_tx_t vti_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) tunnel->err_count = 0; } - IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | - IPSKB_REROUTED); + memset(IPCB(skb), 0, sizeof(*IPCB(skb))); skb_dst_drop(skb); skb_dst_set(skb, &rt->dst); nf_reset(skb); diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c index f8a222cb6448..ff4b781b1056 100644 --- a/net/ipv4/netfilter/ipt_ULOG.c +++ b/net/ipv4/netfilter/ipt_ULOG.c @@ -162,7 +162,8 @@ static struct sk_buff *ulog_alloc_skb(unsigned int size) return skb; } -static void ipt_ulog_packet(unsigned int hooknum, +static void ipt_ulog_packet(struct net *net, + unsigned int hooknum, const struct sk_buff *skb, const struct net_device *in, const struct net_device *out, @@ -174,7 +175,6 @@ static void ipt_ulog_packet(unsigned int hooknum, size_t size, copy_len; struct nlmsghdr *nlh; struct timeval tv; - struct net *net = dev_net(in ? in : out); struct ulog_net *ulog = ulog_pernet(net); /* ffs == find first bit set, necessary because userspace @@ -231,8 +231,10 @@ static void ipt_ulog_packet(unsigned int hooknum, put_unaligned(tv.tv_usec, &pm->timestamp_usec); put_unaligned(skb->mark, &pm->mark); pm->hook = hooknum; - if (prefix != NULL) - strncpy(pm->prefix, prefix, sizeof(pm->prefix)); + if (prefix != NULL) { + strncpy(pm->prefix, prefix, sizeof(pm->prefix) - 1); + pm->prefix[sizeof(pm->prefix) - 1] = '\0'; + } else if (loginfo->prefix[0] != '\0') strncpy(pm->prefix, loginfo->prefix, sizeof(pm->prefix)); else @@ -291,12 +293,15 @@ alloc_failure: static unsigned int ulog_tg(struct sk_buff *skb, const struct xt_action_param *par) { - ipt_ulog_packet(par->hooknum, skb, par->in, par->out, + struct net *net = dev_net(par->in ? par->in : par->out); + + ipt_ulog_packet(net, par->hooknum, skb, par->in, par->out, par->targinfo, NULL); return XT_CONTINUE; } -static void ipt_logfn(u_int8_t pf, +static void ipt_logfn(struct net *net, + u_int8_t pf, unsigned int hooknum, const struct sk_buff *skb, const struct net_device *in, @@ -318,7 +323,7 @@ static void ipt_logfn(u_int8_t pf, strlcpy(loginfo.prefix, prefix, sizeof(loginfo.prefix)); } - ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix); + ipt_ulog_packet(net, hooknum, skb, in, out, &loginfo, prefix); } static int ulog_tg_check(const struct xt_tgchk_param *par) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 550781a17b34..d35bbf0cf404 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -737,10 +737,15 @@ static void ip_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_buf { struct rtable *rt; struct flowi4 fl4; + const struct iphdr *iph = (const struct iphdr *) skb->data; + int oif = skb->dev->ifindex; + u8 tos = RT_TOS(iph->tos); + u8 prot = iph->protocol; + u32 mark = skb->mark; rt = (struct rtable *) dst; - ip_rt_build_flow_key(&fl4, sk, skb); + __build_flow_key(&fl4, sk, iph, oif, tos, prot, mark, 0); __ip_do_redirect(rt, skb, &fl4, true); } diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index dcb116dde216..ab450c099aa4 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -2887,6 +2887,7 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb, unsigned int mss; struct sk_buff *gso_skb = skb; __sum16 newcheck; + bool ooo_okay, copy_destructor; if (!pskb_may_pull(skb, sizeof(*th))) goto out; @@ -2927,10 +2928,18 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb, goto out; } + copy_destructor = gso_skb->destructor == tcp_wfree; + ooo_okay = gso_skb->ooo_okay; + /* All segments but the first should have ooo_okay cleared */ + skb->ooo_okay = 0; + segs = skb_segment(skb, features); if (IS_ERR(segs)) goto out; + /* Only first segment might have ooo_okay set */ + segs->ooo_okay = ooo_okay; + delta = htonl(oldlen + (thlen + mss)); skb = segs; @@ -2950,6 +2959,17 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb, thlen, skb->csum)); seq += mss; + if (copy_destructor) { + skb->destructor = gso_skb->destructor; + skb->sk = gso_skb->sk; + /* {tcp|sock}_wfree() use exact truesize accounting : + * sum(skb->truesize) MUST be exactly be gso_skb->truesize + * So we account mss bytes of 'true size' for each segment. + * The last segment will contain the remaining. + */ + skb->truesize = mss; + gso_skb->truesize -= mss; + } skb = skb->next; th = tcp_hdr(skb); @@ -2962,7 +2982,7 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb, * is freed at TX completion, and not right now when gso_skb * is freed by GSO engine */ - if (gso_skb->destructor == tcp_wfree) { + if (copy_destructor) { swap(gso_skb->sk, skb->sk); swap(gso_skb->destructor, skb->destructor); swap(gso_skb->truesize, skb->truesize); @@ -3269,8 +3289,11 @@ int tcp_md5_hash_skb_data(struct tcp_md5sig_pool *hp, for (i = 0; i < shi->nr_frags; ++i) { const struct skb_frag_struct *f = &shi->frags[i]; - struct page *page = skb_frag_page(f); - sg_set_page(&sg, page, skb_frag_size(f), f->page_offset); + unsigned int offset = f->page_offset; + struct page *page = skb_frag_page(f) + (offset >> PAGE_SHIFT); + + sg_set_page(&sg, page, skb_frag_size(f), + offset_in_page(offset)); if (crypto_hash_update(desc, &sg, skb_frag_size(f))) return 1; } diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 08bbe6096528..9c6225780bd5 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -2743,8 +2743,8 @@ static void tcp_process_loss(struct sock *sk, int flag, bool is_dupack) * tcp_xmit_retransmit_queue(). */ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked, - int prior_sacked, bool is_dupack, - int flag) + int prior_sacked, int prior_packets, + bool is_dupack, int flag) { struct inet_connection_sock *icsk = inet_csk(sk); struct tcp_sock *tp = tcp_sk(sk); @@ -2804,7 +2804,8 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked, tcp_add_reno_sack(sk); } else do_lost = tcp_try_undo_partial(sk, pkts_acked); - newly_acked_sacked = pkts_acked + tp->sacked_out - prior_sacked; + newly_acked_sacked = prior_packets - tp->packets_out + + tp->sacked_out - prior_sacked; break; case TCP_CA_Loss: tcp_process_loss(sk, flag, is_dupack); @@ -2818,7 +2819,8 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked, if (is_dupack) tcp_add_reno_sack(sk); } - newly_acked_sacked = pkts_acked + tp->sacked_out - prior_sacked; + newly_acked_sacked = prior_packets - tp->packets_out + + tp->sacked_out - prior_sacked; if (icsk->icsk_ca_state <= TCP_CA_Disorder) tcp_try_undo_dsack(sk); @@ -3330,9 +3332,10 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) bool is_dupack = false; u32 prior_in_flight; u32 prior_fackets; - int prior_packets; + int prior_packets = tp->packets_out; int prior_sacked = tp->sacked_out; int pkts_acked = 0; + int previous_packets_out = 0; /* If the ack is older than previous acks * then we can probably ignore it. @@ -3403,14 +3406,14 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) sk->sk_err_soft = 0; icsk->icsk_probes_out = 0; tp->rcv_tstamp = tcp_time_stamp; - prior_packets = tp->packets_out; if (!prior_packets) goto no_queue; /* See if we can take anything off of the retransmit queue. */ + previous_packets_out = tp->packets_out; flag |= tcp_clean_rtx_queue(sk, prior_fackets, prior_snd_una); - pkts_acked = prior_packets - tp->packets_out; + pkts_acked = previous_packets_out - tp->packets_out; if (tcp_ack_is_dubious(sk, flag)) { /* Advance CWND, if state allows this. */ @@ -3418,7 +3421,7 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) tcp_cong_avoid(sk, ack, prior_in_flight); is_dupack = !(flag & (FLAG_SND_UNA_ADVANCED | FLAG_NOT_DUP)); tcp_fastretrans_alert(sk, pkts_acked, prior_sacked, - is_dupack, flag); + prior_packets, is_dupack, flag); } else { if (flag & FLAG_DATA_ACKED) tcp_cong_avoid(sk, ack, prior_in_flight); @@ -3441,7 +3444,7 @@ no_queue: /* If data was DSACKed, see if we can undo a cwnd reduction. */ if (flag & FLAG_DSACKING_ACK) tcp_fastretrans_alert(sk, pkts_acked, prior_sacked, - is_dupack, flag); + prior_packets, is_dupack, flag); /* If this ack opens up a zero window, clear backoff. It was * being used to time the probes, and is probably far higher than * it needs to be for normal retransmission. @@ -3464,7 +3467,7 @@ old_ack: if (TCP_SKB_CB(skb)->sacked) { flag |= tcp_sacktag_write_queue(sk, skb, prior_snd_una); tcp_fastretrans_alert(sk, pkts_acked, prior_sacked, - is_dupack, flag); + prior_packets, is_dupack, flag); } SOCK_DEBUG(sk, "Ack %u before %u:%u\n", ack, tp->snd_una, tp->snd_nxt); diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 536d40929ba6..ec335fabd5cc 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -874,11 +874,13 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, &md5); tcp_header_size = tcp_options_size + sizeof(struct tcphdr); - if (tcp_packets_in_flight(tp) == 0) { + if (tcp_packets_in_flight(tp) == 0) tcp_ca_event(sk, CA_EVENT_TX_START); - skb->ooo_okay = 1; - } else - skb->ooo_okay = 0; + + /* if no packet is in qdisc/device queue, then allow XPS to select + * another queue. + */ + skb->ooo_okay = sk_wmem_alloc_get(sk) == 0; skb_push(skb, tcp_header_size); skb_reset_transport_header(skb); diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index d1ab6ab29a55..1bbf744c2cc3 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -1487,7 +1487,7 @@ static int ipv6_count_addresses(struct inet6_dev *idev) } int ipv6_chk_addr(struct net *net, const struct in6_addr *addr, - struct net_device *dev, int strict) + const struct net_device *dev, int strict) { struct inet6_ifaddr *ifp; unsigned int hash = inet6_addr_hash(addr); @@ -2658,8 +2658,10 @@ static void init_loopback(struct net_device *dev) sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, 0); /* Failure cases are ignored */ - if (!IS_ERR(sp_rt)) + if (!IS_ERR(sp_rt)) { + sp_ifa->rt = sp_rt; ip6_ins_rt(sp_rt); + } } read_unlock_bh(&idev->lock); } diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index d2eedf192330..dae1949019d7 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -1147,7 +1147,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, if (WARN_ON(np->cork.opt)) return -EINVAL; - np->cork.opt = kmalloc(opt->tot_len, sk->sk_allocation); + np->cork.opt = kzalloc(opt->tot_len, sk->sk_allocation); if (unlikely(np->cork.opt == NULL)) return -ENOBUFS; diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c index 72836f40b730..95f3f1da0d7f 100644 --- a/net/ipv6/netfilter.c +++ b/net/ipv6/netfilter.c @@ -10,6 +10,7 @@ #include <linux/netfilter.h> #include <linux/netfilter_ipv6.h> #include <linux/export.h> +#include <net/addrconf.h> #include <net/dst.h> #include <net/ipv6.h> #include <net/ip6_route.h> @@ -186,6 +187,10 @@ static __sum16 nf_ip6_checksum_partial(struct sk_buff *skb, unsigned int hook, return csum; }; +static const struct nf_ipv6_ops ipv6ops = { + .chk_addr = ipv6_chk_addr, +}; + static const struct nf_afinfo nf_ip6_afinfo = { .family = AF_INET6, .checksum = nf_ip6_checksum, @@ -198,6 +203,7 @@ static const struct nf_afinfo nf_ip6_afinfo = { int __init ipv6_netfilter_init(void) { + RCU_INIT_POINTER(nf_ipv6_ops, &ipv6ops); return nf_register_afinfo(&nf_ip6_afinfo); } @@ -206,5 +212,6 @@ int __init ipv6_netfilter_init(void) */ void ipv6_netfilter_fini(void) { + RCU_INIT_POINTER(nf_ipv6_ops, NULL); nf_unregister_afinfo(&nf_ip6_afinfo); } diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c index f3c1ff4357ff..51c3285b5d9b 100644 --- a/net/ipv6/proc.c +++ b/net/ipv6/proc.c @@ -90,7 +90,7 @@ static const struct snmp_mib snmp6_ipstats_list[] = { SNMP_MIB_ITEM("Ip6OutMcastOctets", IPSTATS_MIB_OUTMCASTOCTETS), SNMP_MIB_ITEM("Ip6InBcastOctets", IPSTATS_MIB_INBCASTOCTETS), SNMP_MIB_ITEM("Ip6OutBcastOctets", IPSTATS_MIB_OUTBCASTOCTETS), - SNMP_MIB_ITEM("InCsumErrors", IPSTATS_MIB_CSUMERRORS), + /* IPSTATS_MIB_CSUMERRORS is not relevant in IPv6 (no checksum) */ SNMP_MIB_SENTINEL }; diff --git a/net/ipv6/udp_offload.c b/net/ipv6/udp_offload.c index 3bb3a891a424..d3cfaf9c7a08 100644 --- a/net/ipv6/udp_offload.c +++ b/net/ipv6/udp_offload.c @@ -46,11 +46,12 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, unsigned int mss; unsigned int unfrag_ip6hlen, unfrag_len; struct frag_hdr *fptr; - u8 *mac_start, *prevhdr; + u8 *packet_start, *prevhdr; u8 nexthdr; u8 frag_hdr_sz = sizeof(struct frag_hdr); int offset; __wsum csum; + int tnl_hlen; mss = skb_shinfo(skb)->gso_size; if (unlikely(skb->len <= mss)) @@ -83,9 +84,11 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, skb->ip_summed = CHECKSUM_NONE; /* Check if there is enough headroom to insert fragment header. */ - if ((skb_mac_header(skb) < skb->head + frag_hdr_sz) && - pskb_expand_head(skb, frag_hdr_sz, 0, GFP_ATOMIC)) - goto out; + tnl_hlen = skb_tnl_header_len(skb); + if (skb_headroom(skb) < (tnl_hlen + frag_hdr_sz)) { + if (gso_pskb_expand_head(skb, tnl_hlen + frag_hdr_sz)) + goto out; + } /* Find the unfragmentable header and shift it left by frag_hdr_sz * bytes to insert fragment header. @@ -93,11 +96,12 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, unfrag_ip6hlen = ip6_find_1stfragopt(skb, &prevhdr); nexthdr = *prevhdr; *prevhdr = NEXTHDR_FRAGMENT; - unfrag_len = skb_network_header(skb) - skb_mac_header(skb) + - unfrag_ip6hlen; - mac_start = skb_mac_header(skb); - memmove(mac_start-frag_hdr_sz, mac_start, unfrag_len); + unfrag_len = (skb_network_header(skb) - skb_mac_header(skb)) + + unfrag_ip6hlen + tnl_hlen; + packet_start = (u8 *) skb->head + SKB_GSO_CB(skb)->mac_offset; + memmove(packet_start-frag_hdr_sz, packet_start, unfrag_len); + SKB_GSO_CB(skb)->mac_offset -= frag_hdr_sz; skb->mac_header -= frag_hdr_sz; skb->network_header -= frag_hdr_sz; diff --git a/net/irda/irlap_frame.c b/net/irda/irlap_frame.c index 8c004161a843..9ea0c933b9ff 100644 --- a/net/irda/irlap_frame.c +++ b/net/irda/irlap_frame.c @@ -544,7 +544,7 @@ static void irlap_recv_discovery_xid_cmd(struct irlap_cb *self, /* * We now have some discovery info to deliver! */ - discovery = kmalloc(sizeof(discovery_t), GFP_ATOMIC); + discovery = kzalloc(sizeof(discovery_t), GFP_ATOMIC); if (!discovery) { IRDA_WARNING("%s: unable to malloc!\n", __func__); return; diff --git a/net/key/af_key.c b/net/key/af_key.c index 5b1e5af25713..c5fbd7589681 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c @@ -2366,6 +2366,8 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, const struct sa out: xfrm_pol_put(xp); + if (err == 0) + xfrm_garbage_collect(net); return err; } @@ -2615,6 +2617,8 @@ static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, const struct sadb_ out: xfrm_pol_put(xp); + if (delete && err == 0) + xfrm_garbage_collect(net); return err; } diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c index 637a341c1e2d..8dec6876dc50 100644 --- a/net/l2tp/l2tp_ppp.c +++ b/net/l2tp/l2tp_ppp.c @@ -346,19 +346,19 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh skb_put(skb, 2); /* Copy user data into skb */ - error = memcpy_fromiovec(skb->data, m->msg_iov, total_len); + error = memcpy_fromiovec(skb_put(skb, total_len), m->msg_iov, + total_len); if (error < 0) { kfree_skb(skb); goto error_put_sess_tun; } - skb_put(skb, total_len); l2tp_xmit_skb(session, skb, session->hdr_len); sock_put(ps->tunnel_sock); sock_put(sk); - return error; + return total_len; error_put_sess_tun: sock_put(ps->tunnel_sock); diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 158e6eb188d3..44be28cfc6c4 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1267,6 +1267,7 @@ void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata); void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata); void ieee80211_mgd_conn_tx_status(struct ieee80211_sub_if_data *sdata, __le16 fc, bool acked); +void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata); /* IBSS code */ void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local); diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 60f1ce5e5e52..98d20c0f6fed 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -159,9 +159,10 @@ static int ieee80211_change_mtu(struct net_device *dev, int new_mtu) return 0; } -static int ieee80211_verify_mac(struct ieee80211_local *local, u8 *addr) +static int ieee80211_verify_mac(struct ieee80211_sub_if_data *sdata, u8 *addr) { - struct ieee80211_sub_if_data *sdata; + struct ieee80211_local *local = sdata->local; + struct ieee80211_sub_if_data *iter; u64 new, mask, tmp; u8 *m; int ret = 0; @@ -181,11 +182,14 @@ static int ieee80211_verify_mac(struct ieee80211_local *local, u8 *addr) mutex_lock(&local->iflist_mtx); - list_for_each_entry(sdata, &local->interfaces, list) { - if (sdata->vif.type == NL80211_IFTYPE_MONITOR) + list_for_each_entry(iter, &local->interfaces, list) { + if (iter == sdata) + continue; + + if (iter->vif.type == NL80211_IFTYPE_MONITOR) continue; - m = sdata->vif.addr; + m = iter->vif.addr; tmp = ((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) | ((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) | ((u64)m[4] << 1*8) | ((u64)m[5] << 0*8); @@ -209,7 +213,7 @@ static int ieee80211_change_mac(struct net_device *dev, void *addr) if (ieee80211_sdata_running(sdata)) return -EBUSY; - ret = ieee80211_verify_mac(sdata->local, sa->sa_data); + ret = ieee80211_verify_mac(sdata, sa->sa_data); if (ret) return ret; @@ -474,6 +478,9 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) master->control_port_protocol; sdata->control_port_no_encrypt = master->control_port_no_encrypt; + sdata->vif.cab_queue = master->vif.cab_queue; + memcpy(sdata->vif.hw_queue, master->vif.hw_queue, + sizeof(sdata->vif.hw_queue)); break; } case NL80211_IFTYPE_AP: @@ -653,7 +660,11 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) ieee80211_recalc_ps(local, -1); - if (dev) { + if (sdata->vif.type == NL80211_IFTYPE_MONITOR || + sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { + /* XXX: for AP_VLAN, actually track AP queues */ + netif_tx_start_all_queues(dev); + } else if (dev) { unsigned long flags; int n_acs = IEEE80211_NUM_ACS; int ac; @@ -1479,7 +1490,17 @@ static void ieee80211_assign_perm_addr(struct ieee80211_local *local, break; } + /* + * Pick address of existing interface in case user changed + * MAC address manually, default to perm_addr. + */ m = local->hw.wiphy->perm_addr; + list_for_each_entry(sdata, &local->interfaces, list) { + if (sdata->vif.type == NL80211_IFTYPE_MONITOR) + continue; + m = sdata->vif.addr; + break; + } start = ((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) | ((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) | ((u64)m[4] << 1*8) | ((u64)m[5] << 0*8); @@ -1696,6 +1717,15 @@ void ieee80211_remove_interfaces(struct ieee80211_local *local) ASSERT_RTNL(); + /* + * Close all AP_VLAN interfaces first, as otherwise they + * might be closed while the AP interface they belong to + * is closed, causing unregister_netdevice_many() to crash. + */ + list_for_each_entry(sdata, &local->interfaces, list) + if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) + dev_close(sdata->dev); + mutex_lock(&local->iflist_mtx); list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) { list_del(&sdata->list); diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 29620bfc7a69..a8c2130c8ba4 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1015,7 +1015,8 @@ static void ieee80211_chswitch_timer(unsigned long data) static void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, - u64 timestamp, struct ieee802_11_elems *elems) + u64 timestamp, struct ieee802_11_elems *elems, + bool beacon) { struct ieee80211_local *local = sdata->local; struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; @@ -1032,6 +1033,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, struct cfg80211_chan_def new_vht_chandef = {}; const struct ieee80211_sec_chan_offs_ie *sec_chan_offs; const struct ieee80211_wide_bw_chansw_ie *wide_bw_chansw_ie; + const struct ieee80211_ht_operation *ht_oper; int secondary_channel_offset = -1; ASSERT_MGD_MTX(ifmgd); @@ -1048,11 +1050,14 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, sec_chan_offs = elems->sec_chan_offs; wide_bw_chansw_ie = elems->wide_bw_chansw_ie; + ht_oper = elems->ht_operation; if (ifmgd->flags & (IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_40MHZ)) { sec_chan_offs = NULL; wide_bw_chansw_ie = NULL; + /* only used for bandwidth here */ + ht_oper = NULL; } if (ifmgd->flags & IEEE80211_STA_DISABLE_VHT) @@ -1094,10 +1099,20 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, return; } - if (sec_chan_offs) { + if (!beacon && sec_chan_offs) { secondary_channel_offset = sec_chan_offs->sec_chan_offs; + } else if (beacon && ht_oper) { + secondary_channel_offset = + ht_oper->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET; } else if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) { - /* if HT is enabled and the IE not present, it's still HT */ + /* + * If it's not a beacon, HT is enabled and the IE not present, + * it's 20 MHz, 802.11-2012 8.5.2.6: + * This element [the Secondary Channel Offset Element] is + * present when switching to a 40 MHz channel. It may be + * present when switching to a 20 MHz channel (in which + * case the secondary channel offset is set to SCN). + */ secondary_channel_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE; } @@ -2796,7 +2811,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, mutex_unlock(&local->iflist_mtx); } - ieee80211_sta_process_chanswitch(sdata, rx_status->mactime, elems); + ieee80211_sta_process_chanswitch(sdata, rx_status->mactime, + elems, true); } @@ -3210,7 +3226,7 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, ieee80211_sta_process_chanswitch(sdata, rx_status->mactime, - &elems); + &elems, false); } else if (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) { ies_len = skb->len - offsetof(struct ieee80211_mgmt, @@ -3232,7 +3248,7 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, ieee80211_sta_process_chanswitch(sdata, rx_status->mactime, - &elems); + &elems, false); } break; } @@ -3305,10 +3321,6 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) if (WARN_ON_ONCE(!auth_data)) return -EINVAL; - if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) - tx_flags = IEEE80211_TX_CTL_REQ_TX_STATUS | - IEEE80211_TX_INTFL_MLME_CONN_TX; - auth_data->tries++; if (auth_data->tries > IEEE80211_AUTH_MAX_TRIES) { @@ -3342,6 +3354,10 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) auth_data->expected_transaction = trans; } + if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) + tx_flags = IEEE80211_TX_CTL_REQ_TX_STATUS | + IEEE80211_TX_INTFL_MLME_CONN_TX; + ieee80211_send_auth(sdata, trans, auth_data->algorithm, status, auth_data->data, auth_data->data_len, auth_data->bss->bssid, @@ -3365,12 +3381,12 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) * will not answer to direct packet in unassociated state. */ ieee80211_send_probe_req(sdata, NULL, ssidie + 2, ssidie[1], - NULL, 0, (u32) -1, true, tx_flags, + NULL, 0, (u32) -1, true, 0, auth_data->bss->channel, false); rcu_read_unlock(); } - if (!(local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) { + if (tx_flags == 0) { auth_data->timeout = jiffies + IEEE80211_AUTH_TIMEOUT; ifmgd->auth_data->timeout_started = true; run_again(ifmgd, auth_data->timeout); @@ -3623,6 +3639,31 @@ static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata) } } +#ifdef CONFIG_PM +void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata) +{ + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; + + mutex_lock(&ifmgd->mtx); + if (!ifmgd->associated) { + mutex_unlock(&ifmgd->mtx); + return; + } + + if (sdata->flags & IEEE80211_SDATA_DISCONNECT_RESUME) { + sdata->flags &= ~IEEE80211_SDATA_DISCONNECT_RESUME; + mlme_dbg(sdata, "driver requested disconnect after resume\n"); + ieee80211_sta_connection_lost(sdata, + ifmgd->associated->bssid, + WLAN_REASON_UNSPECIFIED, + true); + mutex_unlock(&ifmgd->mtx); + return; + } + mutex_unlock(&ifmgd->mtx); +} +#endif + /* interface setup */ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata) { @@ -4329,7 +4370,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; bool tx = !req->local_state_change; - bool sent_frame = false; + bool report_frame = false; mutex_lock(&ifmgd->mtx); @@ -4346,7 +4387,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, ieee80211_destroy_auth_data(sdata, false); mutex_unlock(&ifmgd->mtx); - sent_frame = tx; + report_frame = true; goto out; } @@ -4354,12 +4395,12 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, ether_addr_equal(ifmgd->associated->bssid, req->bssid)) { ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, req->reason_code, tx, frame_buf); - sent_frame = tx; + report_frame = true; } mutex_unlock(&ifmgd->mtx); out: - if (sent_frame) + if (report_frame) __cfg80211_send_deauth(sdata->dev, frame_buf, IEEE80211_DEAUTH_FRAME_LEN); diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c index 0d51877efdb7..d3f414fe67e0 100644 --- a/net/mac80211/rate.c +++ b/net/mac80211/rate.c @@ -688,8 +688,15 @@ int rate_control_set_rates(struct ieee80211_hw *hw, struct ieee80211_sta *pubsta, struct ieee80211_sta_rates *rates) { - struct ieee80211_sta_rates *old = rcu_dereference(pubsta->rates); + struct ieee80211_sta_rates *old; + /* + * mac80211 guarantees that this function will not be called + * concurrently, so the following RCU access is safe, even without + * extra locking. This can not be checked easily, so we just set + * the condition to true. + */ + old = rcu_dereference_protected(pubsta->rates, true); rcu_assign_pointer(pubsta->rates, rates); if (old) kfree_rcu(old, rcu_head); diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index c8447af76ead..8e2952620256 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -3036,6 +3036,9 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx, * and location updates. Note that mac80211 * itself never looks at these frames. */ + if (!multicast && + !ether_addr_equal(sdata->vif.addr, hdr->addr1)) + return 0; if (ieee80211_is_public_action(hdr, skb->len)) return 1; if (!ieee80211_is_beacon(hdr->frame_control)) diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c index 3ed801d90f1e..124b1fdc20d0 100644 --- a/net/mac80211/tkip.c +++ b/net/mac80211/tkip.c @@ -208,10 +208,10 @@ void ieee80211_get_tkip_p2k(struct ieee80211_key_conf *keyconf, u32 iv32 = get_unaligned_le32(&data[4]); u16 iv16 = data[2] | (data[0] << 8); - spin_lock_bh(&key->u.tkip.txlock); + spin_lock(&key->u.tkip.txlock); ieee80211_compute_tkip_p1k(key, iv32); tkip_mixing_phase2(tk, ctx, iv16, p2k); - spin_unlock_bh(&key->u.tkip.txlock); + spin_unlock(&key->u.tkip.txlock); } EXPORT_SYMBOL(ieee80211_get_tkip_p2k); diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 3f87fa468b1f..27e07150eb46 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -1740,6 +1740,13 @@ int ieee80211_reconfig(struct ieee80211_local *local) mb(); local->resuming = false; + list_for_each_entry(sdata, &local->interfaces, list) { + if (!ieee80211_sdata_running(sdata)) + continue; + if (sdata->vif.type == NL80211_IFTYPE_STATION) + ieee80211_sta_restart(sdata); + } + mod_timer(&local->sta_cleanup, jiffies + 1); #else WARN_ON(1); diff --git a/net/netfilter/core.c b/net/netfilter/core.c index 07c865a31a3d..857ca9f35177 100644 --- a/net/netfilter/core.c +++ b/net/netfilter/core.c @@ -30,6 +30,8 @@ static DEFINE_MUTEX(afinfo_mutex); const struct nf_afinfo __rcu *nf_afinfo[NFPROTO_NUMPROTO] __read_mostly; EXPORT_SYMBOL(nf_afinfo); +const struct nf_ipv6_ops __rcu *nf_ipv6_ops __read_mostly; +EXPORT_SYMBOL_GPL(nf_ipv6_ops); int nf_register_afinfo(const struct nf_afinfo *afinfo) { diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index 085b5880ab0d..05565d2b3a61 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c @@ -1001,6 +1001,32 @@ static inline int is_tcp_reset(const struct sk_buff *skb, int nh_len) return th->rst; } +static inline bool is_new_conn(const struct sk_buff *skb, + struct ip_vs_iphdr *iph) +{ + switch (iph->protocol) { + case IPPROTO_TCP: { + struct tcphdr _tcph, *th; + + th = skb_header_pointer(skb, iph->len, sizeof(_tcph), &_tcph); + if (th == NULL) + return false; + return th->syn; + } + case IPPROTO_SCTP: { + sctp_chunkhdr_t *sch, schunk; + + sch = skb_header_pointer(skb, iph->len + sizeof(sctp_sctphdr_t), + sizeof(schunk), &schunk); + if (sch == NULL) + return false; + return sch->type == SCTP_CID_INIT; + } + default: + return false; + } +} + /* Handle response packets: rewrite addresses and send away... */ static unsigned int @@ -1612,6 +1638,15 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af) * Check if the packet belongs to an existing connection entry */ cp = pp->conn_in_get(af, skb, &iph, 0); + + if (unlikely(sysctl_expire_nodest_conn(ipvs)) && cp && cp->dest && + unlikely(!atomic_read(&cp->dest->weight)) && !iph.fragoffs && + is_new_conn(skb, &iph)) { + ip_vs_conn_expire_now(cp); + __ip_vs_conn_put(cp); + cp = NULL; + } + if (unlikely(!cp) && !iph.fragoffs) { /* No (second) fragments need to enter here, as nf_defrag_ipv6 * replayed fragment zero will already have created the cp diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index 5b142fb16480..9e6c2a075a4c 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c @@ -2542,6 +2542,7 @@ __ip_vs_get_dest_entries(struct net *net, const struct ip_vs_get_dests *get, struct ip_vs_dest *dest; struct ip_vs_dest_entry entry; + memset(&entry, 0, sizeof(entry)); list_for_each_entry(dest, &svc->destinations, n_list) { if (count >= get->num_dests) break; diff --git a/net/netfilter/ipvs/ip_vs_sh.c b/net/netfilter/ipvs/ip_vs_sh.c index 0df269d7c99f..a65edfe4b16c 100644 --- a/net/netfilter/ipvs/ip_vs_sh.c +++ b/net/netfilter/ipvs/ip_vs_sh.c @@ -67,8 +67,8 @@ struct ip_vs_sh_bucket { #define IP_VS_SH_TAB_MASK (IP_VS_SH_TAB_SIZE - 1) struct ip_vs_sh_state { - struct ip_vs_sh_bucket buckets[IP_VS_SH_TAB_SIZE]; struct rcu_head rcu_head; + struct ip_vs_sh_bucket buckets[IP_VS_SH_TAB_SIZE]; }; /* diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c index 388656d5a9ec..3b18dd1be7d9 100644 --- a/net/netfilter/nf_log.c +++ b/net/netfilter/nf_log.c @@ -148,7 +148,7 @@ void nf_log_packet(struct net *net, va_start(args, fmt); vsnprintf(prefix, sizeof(prefix), fmt, args); va_end(args); - logger->logfn(pf, hooknum, skb, in, out, loginfo, prefix); + logger->logfn(net, pf, hooknum, skb, in, out, loginfo, prefix); } rcu_read_unlock(); } @@ -368,17 +368,20 @@ static int __net_init nf_log_net_init(struct net *net) return 0; out_sysctl: +#ifdef CONFIG_PROC_FS /* For init_net: errors will trigger panic, don't unroll on error. */ if (!net_eq(net, &init_net)) remove_proc_entry("nf_log", net->nf.proc_netfilter); - +#endif return ret; } static void __net_exit nf_log_net_exit(struct net *net) { netfilter_log_sysctl_exit(net); +#ifdef CONFIG_PROC_FS remove_proc_entry("nf_log", net->nf.proc_netfilter); +#endif } static struct pernet_operations nf_log_net_ops = { diff --git a/net/netfilter/nfnetlink_acct.c b/net/netfilter/nfnetlink_acct.c index dc3fd5d44464..c7b6d466a662 100644 --- a/net/netfilter/nfnetlink_acct.c +++ b/net/netfilter/nfnetlink_acct.c @@ -149,9 +149,12 @@ nfnl_acct_dump(struct sk_buff *skb, struct netlink_callback *cb) rcu_read_lock(); list_for_each_entry_rcu(cur, &nfnl_acct_list, head) { - if (last && cur != last) - continue; + if (last) { + if (cur != last) + continue; + last = NULL; + } if (nfnl_acct_fill_info(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, NFNL_MSG_TYPE(cb->nlh->nlmsg_type), diff --git a/net/netfilter/nfnetlink_cttimeout.c b/net/netfilter/nfnetlink_cttimeout.c index 701c88a20fea..65074dfb9383 100644 --- a/net/netfilter/nfnetlink_cttimeout.c +++ b/net/netfilter/nfnetlink_cttimeout.c @@ -220,9 +220,12 @@ ctnl_timeout_dump(struct sk_buff *skb, struct netlink_callback *cb) rcu_read_lock(); list_for_each_entry_rcu(cur, &cttimeout_list, head) { - if (last && cur != last) - continue; + if (last) { + if (cur != last) + continue; + last = NULL; + } if (ctnl_timeout_fill_info(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, NFNL_MSG_TYPE(cb->nlh->nlmsg_type), diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index faf1e9300d8a..962e9792e317 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c @@ -602,7 +602,8 @@ static struct nf_loginfo default_loginfo = { /* log handler for internal netfilter logging api */ void -nfulnl_log_packet(u_int8_t pf, +nfulnl_log_packet(struct net *net, + u_int8_t pf, unsigned int hooknum, const struct sk_buff *skb, const struct net_device *in, @@ -615,7 +616,6 @@ nfulnl_log_packet(u_int8_t pf, const struct nf_loginfo *li; unsigned int qthreshold; unsigned int plen; - struct net *net = dev_net(in ? in : out); struct nfnl_log_net *log = nfnl_log_pernet(net); if (li_user && li_user->type == NF_LOG_TYPE_ULOG) @@ -1045,7 +1045,9 @@ static int __net_init nfnl_log_net_init(struct net *net) static void __net_exit nfnl_log_net_exit(struct net *net) { +#ifdef CONFIG_PROC_FS remove_proc_entry("nfnetlink_log", net->nf.proc_netfilter); +#endif } static struct pernet_operations nfnl_log_net_ops = { diff --git a/net/netfilter/nfnetlink_queue_core.c b/net/netfilter/nfnetlink_queue_core.c index 2e0e835baf72..5352b2d2d5bf 100644 --- a/net/netfilter/nfnetlink_queue_core.c +++ b/net/netfilter/nfnetlink_queue_core.c @@ -637,9 +637,6 @@ nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum) if (queue->copy_mode == NFQNL_COPY_NONE) return -EINVAL; - if ((queue->flags & NFQA_CFG_F_GSO) || !skb_is_gso(entry->skb)) - return __nfqnl_enqueue_packet(net, queue, entry); - skb = entry->skb; switch (entry->pf) { @@ -651,6 +648,9 @@ nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum) break; } + if ((queue->flags & NFQA_CFG_F_GSO) || !skb_is_gso(skb)) + return __nfqnl_enqueue_packet(net, queue, entry); + nf_bridge_adjust_skb_data(skb); segs = skb_gso_segment(skb, 0); /* Does not use PTR_ERR to limit the number of error codes that can be @@ -1285,7 +1285,9 @@ static int __net_init nfnl_queue_net_init(struct net *net) static void __net_exit nfnl_queue_net_exit(struct net *net) { +#ifdef CONFIG_PROC_FS remove_proc_entry("nfnetlink_queue", net->nf.proc_netfilter); +#endif } static struct pernet_operations nfnl_queue_net_ops = { diff --git a/net/netfilter/xt_LOG.c b/net/netfilter/xt_LOG.c index fe573f6c9e91..5ab24843370a 100644 --- a/net/netfilter/xt_LOG.c +++ b/net/netfilter/xt_LOG.c @@ -466,7 +466,8 @@ log_packet_common(struct sbuff *m, static void -ipt_log_packet(u_int8_t pf, +ipt_log_packet(struct net *net, + u_int8_t pf, unsigned int hooknum, const struct sk_buff *skb, const struct net_device *in, @@ -475,7 +476,6 @@ ipt_log_packet(u_int8_t pf, const char *prefix) { struct sbuff *m; - struct net *net = dev_net(in ? in : out); /* FIXME: Disabled from containers until syslog ns is supported */ if (!net_eq(net, &init_net)) @@ -737,7 +737,7 @@ static void dump_ipv6_packet(struct sbuff *m, dump_sk_uid_gid(m, skb->sk); /* Max length: 16 "MARK=0xFFFFFFFF " */ - if (!recurse && skb->mark) + if (recurse && skb->mark) sb_add(m, "MARK=0x%x ", skb->mark); } @@ -797,7 +797,8 @@ fallback: } static void -ip6t_log_packet(u_int8_t pf, +ip6t_log_packet(struct net *net, + u_int8_t pf, unsigned int hooknum, const struct sk_buff *skb, const struct net_device *in, @@ -806,7 +807,6 @@ ip6t_log_packet(u_int8_t pf, const char *prefix) { struct sbuff *m; - struct net *net = dev_net(in ? in : out); /* FIXME: Disabled from containers until syslog ns is supported */ if (!net_eq(net, &init_net)) @@ -833,17 +833,18 @@ log_tg(struct sk_buff *skb, const struct xt_action_param *par) { const struct xt_log_info *loginfo = par->targinfo; struct nf_loginfo li; + struct net *net = dev_net(par->in ? par->in : par->out); li.type = NF_LOG_TYPE_LOG; li.u.log.level = loginfo->level; li.u.log.logflags = loginfo->logflags; if (par->family == NFPROTO_IPV4) - ipt_log_packet(NFPROTO_IPV4, par->hooknum, skb, par->in, + ipt_log_packet(net, NFPROTO_IPV4, par->hooknum, skb, par->in, par->out, &li, loginfo->prefix); #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES) else if (par->family == NFPROTO_IPV6) - ip6t_log_packet(NFPROTO_IPV6, par->hooknum, skb, par->in, + ip6t_log_packet(net, NFPROTO_IPV6, par->hooknum, skb, par->in, par->out, &li, loginfo->prefix); #endif else diff --git a/net/netfilter/xt_NFLOG.c b/net/netfilter/xt_NFLOG.c index a17dd0f589b2..fb7497c928a0 100644 --- a/net/netfilter/xt_NFLOG.c +++ b/net/netfilter/xt_NFLOG.c @@ -26,13 +26,14 @@ nflog_tg(struct sk_buff *skb, const struct xt_action_param *par) { const struct xt_nflog_info *info = par->targinfo; struct nf_loginfo li; + struct net *net = dev_net(par->in ? par->in : par->out); li.type = NF_LOG_TYPE_ULOG; li.u.ulog.copy_len = info->len; li.u.ulog.group = info->group; li.u.ulog.qthreshold = info->threshold; - nfulnl_log_packet(par->family, par->hooknum, skb, par->in, + nfulnl_log_packet(net, par->family, par->hooknum, skb, par->in, par->out, &li, info->prefix); return XT_CONTINUE; } diff --git a/net/netfilter/xt_TCPMSS.c b/net/netfilter/xt_TCPMSS.c index a75240f0d42b..afaebc766933 100644 --- a/net/netfilter/xt_TCPMSS.c +++ b/net/netfilter/xt_TCPMSS.c @@ -125,6 +125,12 @@ tcpmss_mangle_packet(struct sk_buff *skb, skb_put(skb, TCPOLEN_MSS); + /* RFC 879 states that the default MSS is 536 without specific + * knowledge that the destination host is prepared to accept larger. + * Since no MSS was provided, we MUST NOT set a value > 536. + */ + newmss = min(newmss, (u16)536); + opt = (u_int8_t *)tcph + sizeof(struct tcphdr); memmove(opt + TCPOLEN_MSS, opt, tcplen - sizeof(struct tcphdr)); diff --git a/net/netfilter/xt_TCPOPTSTRIP.c b/net/netfilter/xt_TCPOPTSTRIP.c index 25fd1c4e1eec..1eb1a44bfd3d 100644 --- a/net/netfilter/xt_TCPOPTSTRIP.c +++ b/net/netfilter/xt_TCPOPTSTRIP.c @@ -30,17 +30,28 @@ static inline unsigned int optlen(const u_int8_t *opt, unsigned int offset) static unsigned int tcpoptstrip_mangle_packet(struct sk_buff *skb, - const struct xt_tcpoptstrip_target_info *info, + const struct xt_action_param *par, unsigned int tcphoff, unsigned int minlen) { + const struct xt_tcpoptstrip_target_info *info = par->targinfo; unsigned int optl, i, j; struct tcphdr *tcph; u_int16_t n, o; u_int8_t *opt; + int len; + + /* This is a fragment, no TCP header is available */ + if (par->fragoff != 0) + return XT_CONTINUE; if (!skb_make_writable(skb, skb->len)) return NF_DROP; + len = skb->len - tcphoff; + if (len < (int)sizeof(struct tcphdr) || + tcp_hdr(skb)->doff * 4 > len) + return NF_DROP; + tcph = (struct tcphdr *)(skb_network_header(skb) + tcphoff); opt = (u_int8_t *)tcph; @@ -76,7 +87,7 @@ tcpoptstrip_mangle_packet(struct sk_buff *skb, static unsigned int tcpoptstrip_tg4(struct sk_buff *skb, const struct xt_action_param *par) { - return tcpoptstrip_mangle_packet(skb, par->targinfo, ip_hdrlen(skb), + return tcpoptstrip_mangle_packet(skb, par, ip_hdrlen(skb), sizeof(struct iphdr) + sizeof(struct tcphdr)); } @@ -94,7 +105,7 @@ tcpoptstrip_tg6(struct sk_buff *skb, const struct xt_action_param *par) if (tcphoff < 0) return NF_DROP; - return tcpoptstrip_mangle_packet(skb, par->targinfo, tcphoff, + return tcpoptstrip_mangle_packet(skb, par, tcphoff, sizeof(*ipv6h) + sizeof(struct tcphdr)); } #endif diff --git a/net/netfilter/xt_addrtype.c b/net/netfilter/xt_addrtype.c index 49c5ff7f6dd6..68ff29f60867 100644 --- a/net/netfilter/xt_addrtype.c +++ b/net/netfilter/xt_addrtype.c @@ -22,6 +22,7 @@ #include <net/ip6_fib.h> #endif +#include <linux/netfilter_ipv6.h> #include <linux/netfilter/xt_addrtype.h> #include <linux/netfilter/x_tables.h> @@ -33,12 +34,12 @@ MODULE_ALIAS("ip6t_addrtype"); #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES) static u32 match_lookup_rt6(struct net *net, const struct net_device *dev, - const struct in6_addr *addr) + const struct in6_addr *addr, u16 mask) { const struct nf_afinfo *afinfo; struct flowi6 flow; struct rt6_info *rt; - u32 ret; + u32 ret = 0; int route_err; memset(&flow, 0, sizeof(flow)); @@ -49,12 +50,19 @@ static u32 match_lookup_rt6(struct net *net, const struct net_device *dev, rcu_read_lock(); afinfo = nf_get_afinfo(NFPROTO_IPV6); - if (afinfo != NULL) + if (afinfo != NULL) { + const struct nf_ipv6_ops *v6ops; + + if (dev && (mask & XT_ADDRTYPE_LOCAL)) { + v6ops = nf_get_ipv6_ops(); + if (v6ops && v6ops->chk_addr(net, addr, dev, true)) + ret = XT_ADDRTYPE_LOCAL; + } route_err = afinfo->route(net, (struct dst_entry **)&rt, - flowi6_to_flowi(&flow), !!dev); - else + flowi6_to_flowi(&flow), false); + } else { route_err = 1; - + } rcu_read_unlock(); if (route_err) @@ -62,15 +70,12 @@ static u32 match_lookup_rt6(struct net *net, const struct net_device *dev, if (rt->rt6i_flags & RTF_REJECT) ret = XT_ADDRTYPE_UNREACHABLE; - else - ret = 0; - if (rt->rt6i_flags & RTF_LOCAL) + if (dev == NULL && rt->rt6i_flags & RTF_LOCAL) ret |= XT_ADDRTYPE_LOCAL; if (rt->rt6i_flags & RTF_ANYCAST) ret |= XT_ADDRTYPE_ANYCAST; - dst_release(&rt->dst); return ret; } @@ -90,7 +95,7 @@ static bool match_type6(struct net *net, const struct net_device *dev, if ((XT_ADDRTYPE_LOCAL | XT_ADDRTYPE_ANYCAST | XT_ADDRTYPE_UNREACHABLE) & mask) - return !!(mask & match_lookup_rt6(net, dev, addr)); + return !!(mask & match_lookup_rt6(net, dev, addr, mask)); return true; } diff --git a/net/netlabel/netlabel_domainhash.c b/net/netlabel/netlabel_domainhash.c index d8d424337550..6bb1d42f0fac 100644 --- a/net/netlabel/netlabel_domainhash.c +++ b/net/netlabel/netlabel_domainhash.c @@ -245,6 +245,71 @@ static void netlbl_domhsh_audit_add(struct netlbl_dom_map *entry, } } +/** + * netlbl_domhsh_validate - Validate a new domain mapping entry + * @entry: the entry to validate + * + * This function validates the new domain mapping entry to ensure that it is + * a valid entry. Returns zero on success, negative values on failure. + * + */ +static int netlbl_domhsh_validate(const struct netlbl_dom_map *entry) +{ + struct netlbl_af4list *iter4; + struct netlbl_domaddr4_map *map4; +#if IS_ENABLED(CONFIG_IPV6) + struct netlbl_af6list *iter6; + struct netlbl_domaddr6_map *map6; +#endif /* IPv6 */ + + if (entry == NULL) + return -EINVAL; + + switch (entry->type) { + case NETLBL_NLTYPE_UNLABELED: + if (entry->type_def.cipsov4 != NULL || + entry->type_def.addrsel != NULL) + return -EINVAL; + break; + case NETLBL_NLTYPE_CIPSOV4: + if (entry->type_def.cipsov4 == NULL) + return -EINVAL; + break; + case NETLBL_NLTYPE_ADDRSELECT: + netlbl_af4list_foreach(iter4, &entry->type_def.addrsel->list4) { + map4 = netlbl_domhsh_addr4_entry(iter4); + switch (map4->type) { + case NETLBL_NLTYPE_UNLABELED: + if (map4->type_def.cipsov4 != NULL) + return -EINVAL; + break; + case NETLBL_NLTYPE_CIPSOV4: + if (map4->type_def.cipsov4 == NULL) + return -EINVAL; + break; + default: + return -EINVAL; + } + } +#if IS_ENABLED(CONFIG_IPV6) + netlbl_af6list_foreach(iter6, &entry->type_def.addrsel->list6) { + map6 = netlbl_domhsh_addr6_entry(iter6); + switch (map6->type) { + case NETLBL_NLTYPE_UNLABELED: + break; + default: + return -EINVAL; + } + } +#endif /* IPv6 */ + break; + default: + return -EINVAL; + } + + return 0; +} + /* * Domain Hash Table Functions */ @@ -311,6 +376,10 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry, struct netlbl_af6list *tmp6; #endif /* IPv6 */ + ret_val = netlbl_domhsh_validate(entry); + if (ret_val != 0) + return ret_val; + /* XXX - we can remove this RCU read lock as the spinlock protects the * entire function, but before we do we need to fixup the * netlbl_af[4,6]list RCU functions to do "the right thing" with diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 12ac6b47a35c..57ee84d21470 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -371,7 +371,7 @@ static int netlink_mmap(struct file *file, struct socket *sock, err = 0; out: mutex_unlock(&nlk->pg_vec_lock); - return 0; + return err; } static void netlink_frame_flush_dcache(const struct nl_mmap_hdr *hdr) @@ -747,7 +747,7 @@ static void netlink_skb_destructor(struct sk_buff *skb) atomic_dec(&ring->pending); sock_put(sk); - skb->data = NULL; + skb->head = NULL; } #endif if (skb->sk != NULL) diff --git a/net/nfc/Makefile b/net/nfc/Makefile index fb799deaed4f..a76f4533cb6c 100644 --- a/net/nfc/Makefile +++ b/net/nfc/Makefile @@ -5,7 +5,6 @@ obj-$(CONFIG_NFC) += nfc.o obj-$(CONFIG_NFC_NCI) += nci/ obj-$(CONFIG_NFC_HCI) += hci/ -#obj-$(CONFIG_NFC_LLCP) += llcp/ nfc-objs := core.o netlink.o af_nfc.o rawsock.o llcp_core.o llcp_commands.o \ llcp_sock.o diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 8ec1bca7f859..20a1bd0e6549 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -2851,12 +2851,11 @@ static int packet_getname_spkt(struct socket *sock, struct sockaddr *uaddr, return -EOPNOTSUPP; uaddr->sa_family = AF_PACKET; + memset(uaddr->sa_data, 0, sizeof(uaddr->sa_data)); rcu_read_lock(); dev = dev_get_by_index_rcu(sock_net(sk), pkt_sk(sk)->ifindex); if (dev) - strncpy(uaddr->sa_data, dev->name, 14); - else - memset(uaddr->sa_data, 0, 14); + strlcpy(uaddr->sa_data, dev->name, sizeof(uaddr->sa_data)); rcu_read_unlock(); *uaddr_len = sizeof(*uaddr); diff --git a/net/sched/act_police.c b/net/sched/act_police.c index 823463adbd21..189e3c5b3d09 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c @@ -231,14 +231,14 @@ override: } if (R_tab) { police->rate_present = true; - psched_ratecfg_precompute(&police->rate, R_tab->rate.rate); + psched_ratecfg_precompute(&police->rate, &R_tab->rate); qdisc_put_rtab(R_tab); } else { police->rate_present = false; } if (P_tab) { police->peak_present = true; - psched_ratecfg_precompute(&police->peak, P_tab->rate.rate); + psched_ratecfg_precompute(&police->peak, &P_tab->rate); qdisc_put_rtab(P_tab); } else { police->peak_present = false; @@ -376,9 +376,9 @@ tcf_act_police_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref) }; if (police->rate_present) - opt.rate.rate = psched_ratecfg_getrate(&police->rate); + psched_ratecfg_getrate(&opt.rate, &police->rate); if (police->peak_present) - opt.peakrate.rate = psched_ratecfg_getrate(&police->peak); + psched_ratecfg_getrate(&opt.peakrate, &police->peak); if (nla_put(skb, TCA_POLICE_TBF, sizeof(opt), &opt)) goto nla_put_failure; if (police->tcfp_result && diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index 2b935e7cfe7b..281c1bded1f6 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -291,17 +291,18 @@ struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r, struct nlattr *ta { struct qdisc_rate_table *rtab; + if (tab == NULL || r->rate == 0 || r->cell_log == 0 || + nla_len(tab) != TC_RTAB_SIZE) + return NULL; + for (rtab = qdisc_rtab_list; rtab; rtab = rtab->next) { - if (memcmp(&rtab->rate, r, sizeof(struct tc_ratespec)) == 0) { + if (!memcmp(&rtab->rate, r, sizeof(struct tc_ratespec)) && + !memcmp(&rtab->data, nla_data(tab), 1024)) { rtab->refcnt++; return rtab; } } - if (tab == NULL || r->rate == 0 || r->cell_log == 0 || - nla_len(tab) != TC_RTAB_SIZE) - return NULL; - rtab = kmalloc(sizeof(*rtab), GFP_KERNEL); if (rtab) { rtab->rate = *r; diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index eac7e0ee23c1..20224086cc28 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c @@ -898,14 +898,16 @@ void dev_shutdown(struct net_device *dev) WARN_ON(timer_pending(&dev->watchdog_timer)); } -void psched_ratecfg_precompute(struct psched_ratecfg *r, u32 rate) +void psched_ratecfg_precompute(struct psched_ratecfg *r, + const struct tc_ratespec *conf) { u64 factor; u64 mult; int shift; - r->rate_bps = (u64)rate << 3; - r->shift = 0; + memset(r, 0, sizeof(*r)); + r->overhead = conf->overhead; + r->rate_bps = (u64)conf->rate << 3; r->mult = 1; /* * Calibrate mult, shift so that token counting is accurate diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index 79b1876b6cd2..adaedd79389c 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c @@ -109,7 +109,7 @@ struct htb_class { } un; struct rb_node node[TC_HTB_NUMPRIO]; /* node for self or feed tree */ struct rb_node pq_node; /* node for event queue */ - psched_time_t pq_key; + s64 pq_key; int prio_activity; /* for which prios are we active */ enum htb_cmode cmode; /* current mode of the class */ @@ -121,10 +121,10 @@ struct htb_class { /* token bucket parameters */ struct psched_ratecfg rate; struct psched_ratecfg ceil; - s64 buffer, cbuffer; /* token bucket depth/rate */ - psched_tdiff_t mbuffer; /* max wait time */ - s64 tokens, ctokens; /* current number of tokens */ - psched_time_t t_c; /* checkpoint time */ + s64 buffer, cbuffer; /* token bucket depth/rate */ + s64 mbuffer; /* max wait time */ + s64 tokens, ctokens; /* current number of tokens */ + s64 t_c; /* checkpoint time */ }; struct htb_sched { @@ -141,15 +141,15 @@ struct htb_sched { struct rb_root wait_pq[TC_HTB_MAXDEPTH]; /* time of nearest event per level (row) */ - psched_time_t near_ev_cache[TC_HTB_MAXDEPTH]; + s64 near_ev_cache[TC_HTB_MAXDEPTH]; int defcls; /* class where unclassified flows go to */ /* filters for qdisc itself */ struct tcf_proto *filter_list; - int rate2quantum; /* quant = rate / rate2quantum */ - psched_time_t now; /* cached dequeue time */ + int rate2quantum; /* quant = rate / rate2quantum */ + s64 now; /* cached dequeue time */ struct qdisc_watchdog watchdog; /* non shaped skbs; let them go directly thru */ @@ -664,8 +664,8 @@ static void htb_charge_class(struct htb_sched *q, struct htb_class *cl, * next pending event (0 for no event in pq, q->now for too many events). * Note: Applied are events whose have cl->pq_key <= q->now. */ -static psched_time_t htb_do_events(struct htb_sched *q, int level, - unsigned long start) +static s64 htb_do_events(struct htb_sched *q, int level, + unsigned long start) { /* don't run for longer than 2 jiffies; 2 is used instead of * 1 to simplify things when jiffy is going to be incremented @@ -857,7 +857,7 @@ static struct sk_buff *htb_dequeue(struct Qdisc *sch) struct sk_buff *skb; struct htb_sched *q = qdisc_priv(sch); int level; - psched_time_t next_event; + s64 next_event; unsigned long start_at; /* try to dequeue direct packets as high prio (!) to minimize cpu work */ @@ -880,7 +880,7 @@ ok: for (level = 0; level < TC_HTB_MAXDEPTH; level++) { /* common case optimization - skip event handler quickly */ int m; - psched_time_t event; + s64 event; if (q->now >= q->near_ev_cache[level]) { event = htb_do_events(q, level, start_at); @@ -1090,9 +1090,9 @@ static int htb_dump_class(struct Qdisc *sch, unsigned long arg, memset(&opt, 0, sizeof(opt)); - opt.rate.rate = psched_ratecfg_getrate(&cl->rate); + psched_ratecfg_getrate(&opt.rate, &cl->rate); opt.buffer = PSCHED_NS2TICKS(cl->buffer); - opt.ceil.rate = psched_ratecfg_getrate(&cl->ceil); + psched_ratecfg_getrate(&opt.ceil, &cl->ceil); opt.cbuffer = PSCHED_NS2TICKS(cl->cbuffer); opt.quantum = cl->quantum; opt.prio = cl->prio; @@ -1117,8 +1117,8 @@ htb_dump_class_stats(struct Qdisc *sch, unsigned long arg, struct gnet_dump *d) if (!cl->level && cl->un.leaf.q) cl->qstats.qlen = cl->un.leaf.q->q.qlen; - cl->xstats.tokens = cl->tokens; - cl->xstats.ctokens = cl->ctokens; + cl->xstats.tokens = PSCHED_NS2TICKS(cl->tokens); + cl->xstats.ctokens = PSCHED_NS2TICKS(cl->ctokens); if (gnet_stats_copy_basic(d, &cl->bstats) < 0 || gnet_stats_copy_rate_est(d, NULL, &cl->rate_est) < 0 || @@ -1200,7 +1200,7 @@ static void htb_parent_to_leaf(struct htb_sched *q, struct htb_class *cl, parent->un.leaf.q = new_q ? new_q : &noop_qdisc; parent->tokens = parent->buffer; parent->ctokens = parent->cbuffer; - parent->t_c = psched_get_time(); + parent->t_c = ktime_to_ns(ktime_get()); parent->cmode = HTB_CAN_SEND; } @@ -1417,8 +1417,8 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, /* set class to be in HTB_CAN_SEND state */ cl->tokens = PSCHED_TICKS2NS(hopt->buffer); cl->ctokens = PSCHED_TICKS2NS(hopt->cbuffer); - cl->mbuffer = 60 * PSCHED_TICKS_PER_SEC; /* 1min */ - cl->t_c = psched_get_time(); + cl->mbuffer = 60ULL * NSEC_PER_SEC; /* 1min */ + cl->t_c = ktime_to_ns(ktime_get()); cl->cmode = HTB_CAN_SEND; /* attach to the hash list and parent's family */ @@ -1459,8 +1459,8 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, cl->prio = TC_HTB_NUMPRIO - 1; } - psched_ratecfg_precompute(&cl->rate, hopt->rate.rate); - psched_ratecfg_precompute(&cl->ceil, hopt->ceil.rate); + psched_ratecfg_precompute(&cl->rate, &hopt->rate); + psched_ratecfg_precompute(&cl->ceil, &hopt->ceil); cl->buffer = PSCHED_TICKS2NS(hopt->buffer); cl->cbuffer = PSCHED_TICKS2NS(hopt->buffer); diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c index c8388f3c3426..e478d316602b 100644 --- a/net/sched/sch_tbf.c +++ b/net/sched/sch_tbf.c @@ -298,9 +298,9 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt) q->tokens = q->buffer; q->ptokens = q->mtu; - psched_ratecfg_precompute(&q->rate, rtab->rate.rate); + psched_ratecfg_precompute(&q->rate, &rtab->rate); if (ptab) { - psched_ratecfg_precompute(&q->peak, ptab->rate.rate); + psched_ratecfg_precompute(&q->peak, &ptab->rate); q->peak_present = true; } else { q->peak_present = false; @@ -350,9 +350,9 @@ static int tbf_dump(struct Qdisc *sch, struct sk_buff *skb) goto nla_put_failure; opt.limit = q->limit; - opt.rate.rate = psched_ratecfg_getrate(&q->rate); + psched_ratecfg_getrate(&opt.rate, &q->rate); if (q->peak_present) - opt.peakrate.rate = psched_ratecfg_getrate(&q->peak); + psched_ratecfg_getrate(&opt.peakrate, &q->peak); else memset(&opt.peakrate, 0, sizeof(opt.peakrate)); opt.mtu = PSCHED_NS2TICKS(q->mtu); diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index 32a4625fef77..be35e2dbcc9a 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c @@ -206,6 +206,8 @@ static inline int sctp_cacc_skip(struct sctp_transport *primary, */ void sctp_outq_init(struct sctp_association *asoc, struct sctp_outq *q) { + memset(q, 0, sizeof(struct sctp_outq)); + q->asoc = asoc; INIT_LIST_HEAD(&q->out_chunk_list); INIT_LIST_HEAD(&q->control_chunk_list); @@ -213,11 +215,7 @@ void sctp_outq_init(struct sctp_association *asoc, struct sctp_outq *q) INIT_LIST_HEAD(&q->sacked); INIT_LIST_HEAD(&q->abandoned); - q->fast_rtx = 0; - q->outstanding_bytes = 0; q->empty = 1; - q->cork = 0; - q->out_qlen = 0; } /* Free the outqueue structure and any related pending chunks. diff --git a/net/sctp/socket.c b/net/sctp/socket.c index f631c5ff4dbf..6abb1caf9836 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -4003,6 +4003,12 @@ SCTP_STATIC void sctp_destroy_sock(struct sock *sk) /* Release our hold on the endpoint. */ sp = sctp_sk(sk); + /* This could happen during socket init, thus we bail out + * early, since the rest of the below is not setup either. + */ + if (sp->ep == NULL) + return; + if (sp->do_auto_asconf) { sp->do_auto_asconf = 0; list_del(&sp->auto_asconf_list); diff --git a/net/socket.c b/net/socket.c index 6b94633ca61d..4ca1526db756 100644 --- a/net/socket.c +++ b/net/socket.c @@ -1956,7 +1956,7 @@ struct used_address { unsigned int name_len; }; -static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg, +static int ___sys_sendmsg(struct socket *sock, struct msghdr __user *msg, struct msghdr *msg_sys, unsigned int flags, struct used_address *used_address) { @@ -2071,22 +2071,30 @@ out: * BSD sendmsg interface */ -SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned int, flags) +long __sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags) { int fput_needed, err; struct msghdr msg_sys; - struct socket *sock = sockfd_lookup_light(fd, &err, &fput_needed); + struct socket *sock; + sock = sockfd_lookup_light(fd, &err, &fput_needed); if (!sock) goto out; - err = __sys_sendmsg(sock, msg, &msg_sys, flags, NULL); + err = ___sys_sendmsg(sock, msg, &msg_sys, flags, NULL); fput_light(sock->file, fput_needed); out: return err; } +SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned int, flags) +{ + if (flags & MSG_CMSG_COMPAT) + return -EINVAL; + return __sys_sendmsg(fd, msg, flags); +} + /* * Linux sendmmsg interface */ @@ -2117,15 +2125,16 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, while (datagrams < vlen) { if (MSG_CMSG_COMPAT & flags) { - err = __sys_sendmsg(sock, (struct msghdr __user *)compat_entry, - &msg_sys, flags, &used_address); + err = ___sys_sendmsg(sock, (struct msghdr __user *)compat_entry, + &msg_sys, flags, &used_address); if (err < 0) break; err = __put_user(err, &compat_entry->msg_len); ++compat_entry; } else { - err = __sys_sendmsg(sock, (struct msghdr __user *)entry, - &msg_sys, flags, &used_address); + err = ___sys_sendmsg(sock, + (struct msghdr __user *)entry, + &msg_sys, flags, &used_address); if (err < 0) break; err = put_user(err, &entry->msg_len); @@ -2149,10 +2158,12 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, SYSCALL_DEFINE4(sendmmsg, int, fd, struct mmsghdr __user *, mmsg, unsigned int, vlen, unsigned int, flags) { + if (flags & MSG_CMSG_COMPAT) + return -EINVAL; return __sys_sendmmsg(fd, mmsg, vlen, flags); } -static int __sys_recvmsg(struct socket *sock, struct msghdr __user *msg, +static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg, struct msghdr *msg_sys, unsigned int flags, int nosec) { struct compat_msghdr __user *msg_compat = @@ -2244,23 +2255,31 @@ out: * BSD recvmsg interface */ -SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg, - unsigned int, flags) +long __sys_recvmsg(int fd, struct msghdr __user *msg, unsigned flags) { int fput_needed, err; struct msghdr msg_sys; - struct socket *sock = sockfd_lookup_light(fd, &err, &fput_needed); + struct socket *sock; + sock = sockfd_lookup_light(fd, &err, &fput_needed); if (!sock) goto out; - err = __sys_recvmsg(sock, msg, &msg_sys, flags, 0); + err = ___sys_recvmsg(sock, msg, &msg_sys, flags, 0); fput_light(sock->file, fput_needed); out: return err; } +SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg, + unsigned int, flags) +{ + if (flags & MSG_CMSG_COMPAT) + return -EINVAL; + return __sys_recvmsg(fd, msg, flags); +} + /* * Linux recvmmsg interface */ @@ -2298,17 +2317,18 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, * No need to ask LSM for more than the first datagram. */ if (MSG_CMSG_COMPAT & flags) { - err = __sys_recvmsg(sock, (struct msghdr __user *)compat_entry, - &msg_sys, flags & ~MSG_WAITFORONE, - datagrams); + err = ___sys_recvmsg(sock, (struct msghdr __user *)compat_entry, + &msg_sys, flags & ~MSG_WAITFORONE, + datagrams); if (err < 0) break; err = __put_user(err, &compat_entry->msg_len); ++compat_entry; } else { - err = __sys_recvmsg(sock, (struct msghdr __user *)entry, - &msg_sys, flags & ~MSG_WAITFORONE, - datagrams); + err = ___sys_recvmsg(sock, + (struct msghdr __user *)entry, + &msg_sys, flags & ~MSG_WAITFORONE, + datagrams); if (err < 0) break; err = put_user(err, &entry->msg_len); @@ -2375,6 +2395,9 @@ SYSCALL_DEFINE5(recvmmsg, int, fd, struct mmsghdr __user *, mmsg, int datagrams; struct timespec timeout_sys; + if (flags & MSG_CMSG_COMPAT) + return -EINVAL; + if (!timeout) return __sys_recvmmsg(fd, mmsg, vlen, flags, NULL); diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 7da6b457f66a..fc2f78d6a9b4 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c @@ -52,6 +52,8 @@ #include <linux/sunrpc/gss_api.h> #include <asm/uaccess.h> +#include "../netns.h" + static const struct rpc_authops authgss_ops; static const struct rpc_credops gss_credops; @@ -85,8 +87,6 @@ struct gss_auth { }; /* pipe_version >= 0 if and only if someone has a pipe open. */ -static int pipe_version = -1; -static atomic_t pipe_users = ATOMIC_INIT(0); static DEFINE_SPINLOCK(pipe_version_lock); static struct rpc_wait_queue pipe_version_rpc_waitqueue; static DECLARE_WAIT_QUEUE_HEAD(pipe_version_waitqueue); @@ -266,24 +266,27 @@ struct gss_upcall_msg { char databuf[UPCALL_BUF_LEN]; }; -static int get_pipe_version(void) +static int get_pipe_version(struct net *net) { + struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); int ret; spin_lock(&pipe_version_lock); - if (pipe_version >= 0) { - atomic_inc(&pipe_users); - ret = pipe_version; + if (sn->pipe_version >= 0) { + atomic_inc(&sn->pipe_users); + ret = sn->pipe_version; } else ret = -EAGAIN; spin_unlock(&pipe_version_lock); return ret; } -static void put_pipe_version(void) +static void put_pipe_version(struct net *net) { - if (atomic_dec_and_lock(&pipe_users, &pipe_version_lock)) { - pipe_version = -1; + struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); + + if (atomic_dec_and_lock(&sn->pipe_users, &pipe_version_lock)) { + sn->pipe_version = -1; spin_unlock(&pipe_version_lock); } } @@ -291,9 +294,10 @@ static void put_pipe_version(void) static void gss_release_msg(struct gss_upcall_msg *gss_msg) { + struct net *net = rpc_net_ns(gss_msg->auth->client); if (!atomic_dec_and_test(&gss_msg->count)) return; - put_pipe_version(); + put_pipe_version(net); BUG_ON(!list_empty(&gss_msg->list)); if (gss_msg->ctx != NULL) gss_put_ctx(gss_msg->ctx); @@ -439,7 +443,10 @@ static void gss_encode_msg(struct gss_upcall_msg *gss_msg, struct rpc_clnt *clnt, const char *service_name) { - if (pipe_version == 0) + struct net *net = rpc_net_ns(clnt); + struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); + + if (sn->pipe_version == 0) gss_encode_v0_msg(gss_msg); else /* pipe_version == 1 */ gss_encode_v1_msg(gss_msg, clnt, service_name); @@ -455,7 +462,7 @@ gss_alloc_msg(struct gss_auth *gss_auth, struct rpc_clnt *clnt, gss_msg = kzalloc(sizeof(*gss_msg), GFP_NOFS); if (gss_msg == NULL) return ERR_PTR(-ENOMEM); - vers = get_pipe_version(); + vers = get_pipe_version(rpc_net_ns(clnt)); if (vers < 0) { kfree(gss_msg); return ERR_PTR(vers); @@ -559,24 +566,34 @@ out: static inline int gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred) { + struct net *net = rpc_net_ns(gss_auth->client); + struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); struct rpc_pipe *pipe; struct rpc_cred *cred = &gss_cred->gc_base; struct gss_upcall_msg *gss_msg; + unsigned long timeout; DEFINE_WAIT(wait); - int err = 0; + int err; dprintk("RPC: %s for uid %u\n", __func__, from_kuid(&init_user_ns, cred->cr_uid)); retry: + err = 0; + /* Default timeout is 15s unless we know that gssd is not running */ + timeout = 15 * HZ; + if (!sn->gssd_running) + timeout = HZ >> 2; gss_msg = gss_setup_upcall(gss_auth->client, gss_auth, cred); if (PTR_ERR(gss_msg) == -EAGAIN) { err = wait_event_interruptible_timeout(pipe_version_waitqueue, - pipe_version >= 0, 15*HZ); - if (pipe_version < 0) { + sn->pipe_version >= 0, timeout); + if (sn->pipe_version < 0) { + if (err == 0) + sn->gssd_running = 0; warn_gssd(); err = -EACCES; } - if (err) + if (err < 0) goto out; goto retry; } @@ -707,20 +724,22 @@ out: static int gss_pipe_open(struct inode *inode, int new_version) { + struct net *net = inode->i_sb->s_fs_info; + struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); int ret = 0; spin_lock(&pipe_version_lock); - if (pipe_version < 0) { + if (sn->pipe_version < 0) { /* First open of any gss pipe determines the version: */ - pipe_version = new_version; + sn->pipe_version = new_version; rpc_wake_up(&pipe_version_rpc_waitqueue); wake_up(&pipe_version_waitqueue); - } else if (pipe_version != new_version) { + } else if (sn->pipe_version != new_version) { /* Trying to open a pipe of a different version */ ret = -EBUSY; goto out; } - atomic_inc(&pipe_users); + atomic_inc(&sn->pipe_users); out: spin_unlock(&pipe_version_lock); return ret; @@ -740,6 +759,7 @@ static int gss_pipe_open_v1(struct inode *inode) static void gss_pipe_release(struct inode *inode) { + struct net *net = inode->i_sb->s_fs_info; struct rpc_pipe *pipe = RPC_I(inode)->pipe; struct gss_upcall_msg *gss_msg; @@ -758,7 +778,7 @@ restart: } spin_unlock(&pipe->lock); - put_pipe_version(); + put_pipe_version(net); } static void diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index 871c73c92165..29b4ba93ab3c 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c @@ -1287,7 +1287,7 @@ static bool use_gss_proxy(struct net *net) #ifdef CONFIG_PROC_FS -static bool set_gss_proxy(struct net *net, int type) +static int set_gss_proxy(struct net *net, int type) { struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); int ret = 0; @@ -1317,10 +1317,12 @@ static inline bool gssp_ready(struct sunrpc_net *sn) return false; } -static int wait_for_gss_proxy(struct net *net) +static int wait_for_gss_proxy(struct net *net, struct file *file) { struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); + if (file->f_flags & O_NONBLOCK && !gssp_ready(sn)) + return -EAGAIN; return wait_event_interruptible(sn->gssp_wq, gssp_ready(sn)); } @@ -1362,7 +1364,7 @@ static ssize_t read_gssp(struct file *file, char __user *buf, size_t len; int ret; - ret = wait_for_gss_proxy(net); + ret = wait_for_gss_proxy(net, file); if (ret) return ret; diff --git a/net/sunrpc/netns.h b/net/sunrpc/netns.h index 7111a4c9113b..74d948f5d5a1 100644 --- a/net/sunrpc/netns.h +++ b/net/sunrpc/netns.h @@ -28,7 +28,11 @@ struct sunrpc_net { wait_queue_head_t gssp_wq; struct rpc_clnt *gssp_clnt; int use_gss_proxy; + int pipe_version; + atomic_t pipe_users; struct proc_dir_entry *use_gssp_proc; + + unsigned int gssd_running; }; extern int sunrpc_net_id; diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index a9129f8d7070..e7ce4b3eb0bd 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c @@ -216,11 +216,14 @@ rpc_destroy_inode(struct inode *inode) static int rpc_pipe_open(struct inode *inode, struct file *filp) { + struct net *net = inode->i_sb->s_fs_info; + struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); struct rpc_pipe *pipe; int first_open; int res = -ENXIO; mutex_lock(&inode->i_mutex); + sn->gssd_running = 1; pipe = RPC_I(inode)->pipe; if (pipe == NULL) goto out; @@ -1069,6 +1072,8 @@ void rpc_pipefs_init_net(struct net *net) struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); mutex_init(&sn->pipefs_sb_lock); + sn->gssd_running = 1; + sn->pipe_version = -1; } /* diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index f8529fc8e542..5356b120dbf8 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c @@ -324,11 +324,17 @@ EXPORT_SYMBOL_GPL(__rpc_wait_for_completion_task); * Note: If the task is ASYNC, and is being made runnable after sitting on an * rpc_wait_queue, this must be called with the queue spinlock held to protect * the wait queue operation. + * Note the ordering of rpc_test_and_set_running() and rpc_clear_queued(), + * which is needed to ensure that __rpc_execute() doesn't loop (due to the + * lockless RPC_IS_QUEUED() test) before we've had a chance to test + * the RPC_TASK_RUNNING flag. */ static void rpc_make_runnable(struct rpc_task *task) { + bool need_wakeup = !rpc_test_and_set_running(task); + rpc_clear_queued(task); - if (rpc_test_and_set_running(task)) + if (!need_wakeup) return; if (RPC_IS_ASYNC(task)) { INIT_WORK(&task->u.tk_work, rpc_async_schedule); diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c index c3f9e1ef7f53..06bdf5a1082c 100644 --- a/net/sunrpc/svcauth_unix.c +++ b/net/sunrpc/svcauth_unix.c @@ -810,11 +810,15 @@ svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp) goto badcred; argv->iov_base = (void*)((__be32*)argv->iov_base + slen); /* skip machname */ argv->iov_len -= slen*4; - + /* + * Note: we skip uid_valid()/gid_valid() checks here for + * backwards compatibility with clients that use -1 id's. + * Instead, -1 uid or gid is later mapped to the + * (export-specific) anonymous id by nfsd_setuser. + * Supplementary gid's will be left alone. + */ cred->cr_uid = make_kuid(&init_user_ns, svc_getnl(argv)); /* uid */ cred->cr_gid = make_kgid(&init_user_ns, svc_getnl(argv)); /* gid */ - if (!uid_valid(cred->cr_uid) || !gid_valid(cred->cr_gid)) - goto badcred; slen = svc_getnl(argv); /* gids length */ if (slen > 16 || (len -= (slen + 2)*4) < 0) goto badcred; @@ -823,8 +827,6 @@ svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp) return SVC_CLOSE; for (i = 0; i < slen; i++) { kgid_t kgid = make_kgid(&init_user_ns, svc_getnl(argv)); - if (!gid_valid(kgid)) - goto badcred; GROUP_AT(cred->cr_group_info, i) = kgid; } if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) { diff --git a/net/wireless/core.c b/net/wireless/core.c index 84c9ad7e1dca..73405e00c800 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -638,17 +638,21 @@ int wiphy_register(struct wiphy *wiphy) * cfg80211_mutex lock */ res = rfkill_register(rdev->rfkill); - if (res) - goto out_rm_dev; + if (res) { + device_del(&rdev->wiphy.dev); + + mutex_lock(&cfg80211_mutex); + debugfs_remove_recursive(rdev->wiphy.debugfsdir); + list_del_rcu(&rdev->list); + wiphy_regulatory_deregister(wiphy); + mutex_unlock(&cfg80211_mutex); + return res; + } rtnl_lock(); rdev->wiphy.registered = true; rtnl_unlock(); return 0; - -out_rm_dev: - device_del(&rdev->wiphy.dev); - return res; } EXPORT_SYMBOL(wiphy_register); @@ -866,7 +870,6 @@ void cfg80211_leave(struct cfg80211_registered_device *rdev, #endif __cfg80211_disconnect(rdev, dev, WLAN_REASON_DEAUTH_LEAVING, true); - cfg80211_mlme_down(rdev, dev); wdev_unlock(wdev); break; case NL80211_IFTYPE_MESH_POINT: diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index afa283841e8c..d5aed3bb3945 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -3411,7 +3411,7 @@ static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq, (u32)sinfo->rx_bytes)) goto nla_put_failure; if ((sinfo->filled & (STATION_INFO_TX_BYTES | - NL80211_STA_INFO_TX_BYTES64)) && + STATION_INFO_TX_BYTES64)) && nla_put_u32(msg, NL80211_STA_INFO_TX_BYTES, (u32)sinfo->tx_bytes)) goto nla_put_failure; @@ -7577,6 +7577,8 @@ static int nl80211_send_wowlan_tcp(struct sk_buff *msg, &tcp->payload_tok)) return -ENOBUFS; + nla_nest_end(msg, nl_tcp); + return 0; } @@ -9970,6 +9972,7 @@ int nl80211_send_mgmt(struct cfg80211_registered_device *rdev, if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || (netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex)) || + nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)) || nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq) || (sig_dbm && nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) || @@ -10010,6 +10013,7 @@ void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie, if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || (netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex)) || + nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)) || nla_put(msg, NL80211_ATTR_FRAME, len, buf) || nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie) || (ack && nla_put_flag(msg, NL80211_ATTR_ACK))) diff --git a/net/wireless/sme.c b/net/wireless/sme.c index a9dc5c736df0..3ed35c345cae 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c @@ -231,6 +231,9 @@ void cfg80211_conn_work(struct work_struct *work) mutex_lock(&rdev->sched_scan_mtx); list_for_each_entry(wdev, &rdev->wdev_list, list) { + if (!wdev->netdev) + continue; + wdev_lock(wdev); if (!netif_running(wdev->netdev)) { wdev_unlock(wdev); @@ -961,7 +964,7 @@ int __cfg80211_disconnect(struct cfg80211_registered_device *rdev, /* was it connected by userspace SME? */ if (!wdev->conn) { cfg80211_mlme_down(rdev, dev); - return 0; + goto disconnect; } if (wdev->sme_state == CFG80211_SME_CONNECTING && @@ -987,6 +990,7 @@ int __cfg80211_disconnect(struct cfg80211_registered_device *rdev, return err; } + disconnect: if (wdev->sme_state == CFG80211_SME_CONNECTED) __cfg80211_disconnected(dev, NULL, 0, 0, false); else if (wdev->sme_state == CFG80211_SME_CONNECTING) diff --git a/net/wireless/trace.h b/net/wireless/trace.h index ecd4fcec3c94..5755bc14abbd 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h @@ -2441,6 +2441,7 @@ TRACE_EVENT(cfg80211_report_wowlan_wakeup, TP_STRUCT__entry( WIPHY_ENTRY WDEV_ENTRY + __field(bool, non_wireless) __field(bool, disconnect) __field(bool, magic_pkt) __field(bool, gtk_rekey_failure) @@ -2449,20 +2450,22 @@ TRACE_EVENT(cfg80211_report_wowlan_wakeup, __field(bool, rfkill_release) __field(s32, pattern_idx) __field(u32, packet_len) - __dynamic_array(u8, packet, wakeup->packet_present_len) + __dynamic_array(u8, packet, + wakeup ? wakeup->packet_present_len : 0) ), TP_fast_assign( WIPHY_ASSIGN; WDEV_ASSIGN; - __entry->disconnect = wakeup->disconnect; - __entry->magic_pkt = wakeup->magic_pkt; - __entry->gtk_rekey_failure = wakeup->gtk_rekey_failure; - __entry->eap_identity_req = wakeup->eap_identity_req; - __entry->four_way_handshake = wakeup->four_way_handshake; - __entry->rfkill_release = wakeup->rfkill_release; - __entry->pattern_idx = wakeup->pattern_idx; - __entry->packet_len = wakeup->packet_len; - if (wakeup->packet && wakeup->packet_present_len) + __entry->non_wireless = !wakeup; + __entry->disconnect = wakeup ? wakeup->disconnect : false; + __entry->magic_pkt = wakeup ? wakeup->magic_pkt : false; + __entry->gtk_rekey_failure = wakeup ? wakeup->gtk_rekey_failure : false; + __entry->eap_identity_req = wakeup ? wakeup->eap_identity_req : false; + __entry->four_way_handshake = wakeup ? wakeup->four_way_handshake : false; + __entry->rfkill_release = wakeup ? wakeup->rfkill_release : false; + __entry->pattern_idx = wakeup ? wakeup->pattern_idx : false; + __entry->packet_len = wakeup ? wakeup->packet_len : false; + if (wakeup && wakeup->packet && wakeup->packet_present_len) memcpy(__get_dynamic_array(packet), wakeup->packet, wakeup->packet_present_len); ), diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c index bcfda8921b5b..0cf003dfa8fc 100644 --- a/net/xfrm/xfrm_output.c +++ b/net/xfrm/xfrm_output.c @@ -64,6 +64,7 @@ static int xfrm_output_one(struct sk_buff *skb, int err) if (unlikely(x->km.state != XFRM_STATE_VALID)) { XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTSTATEINVALID); + err = -EINVAL; goto error; } diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 23cea0f74336..ea970b8002a2 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -2557,11 +2557,12 @@ static void __xfrm_garbage_collect(struct net *net) } } -static void xfrm_garbage_collect(struct net *net) +void xfrm_garbage_collect(struct net *net) { flow_cache_flush(); __xfrm_garbage_collect(net); } +EXPORT_SYMBOL(xfrm_garbage_collect); static void xfrm_garbage_collect_deferred(struct net *net) { diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index aa778748c565..3f565e495ac6 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -1681,6 +1681,8 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, out: xfrm_pol_put(xp); + if (delete && err == 0) + xfrm_garbage_collect(net); return err; } diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 51bb3de680b6..f97869f1f09b 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -149,7 +149,7 @@ cpp_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ ld_flags = $(LDFLAGS) $(ldflags-y) -dtc_cpp_flags = -Wp,-MD,$(depfile).pre -nostdinc \ +dtc_cpp_flags = -Wp,-MD,$(depfile).pre.tmp -nostdinc \ -I$(srctree)/arch/$(SRCARCH)/boot/dts \ -I$(srctree)/arch/$(SRCARCH)/boot/dts/include \ -undef -D__DTS__ @@ -264,14 +264,14 @@ $(obj)/%.dtb.S: $(obj)/%.dtb quiet_cmd_dtc = DTC $@ cmd_dtc = $(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \ $(objtree)/scripts/dtc/dtc -O dtb -o $@ -b 0 \ - -i $(srctree)/arch/$(SRCARCH)/boot/dts $(DTC_FLAGS) \ - -d $(depfile).dtc $(dtc-tmp) ; \ - cat $(depfile).pre $(depfile).dtc > $(depfile) + -i $(dir $<) $(DTC_FLAGS) \ + -d $(depfile).dtc.tmp $(dtc-tmp) ; \ + cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile) $(obj)/%.dtb: $(src)/%.dts FORCE $(call if_changed_dep,dtc) -dtc-tmp = $(subst $(comma),_,$(dot-target).dts) +dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp) # Bzip2 # --------------------------------------------------------------------------- diff --git a/scripts/config b/scripts/config index bb4d3deb6d1c..a65ecbbdd32a 100755 --- a/scripts/config +++ b/scripts/config @@ -105,7 +105,7 @@ while [ "$1" != "" ] ; do ;; --refresh) ;; - --*-after) + --*-after|-E|-D|-M) checkarg "$1" A=$ARG checkarg "$2" diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l index 254d5af88956..3b41bfca636c 100644 --- a/scripts/dtc/dtc-lexer.l +++ b/scripts/dtc/dtc-lexer.l @@ -71,7 +71,7 @@ static int pop_input_file(void); push_input_file(name); } -<*>^"#"(line)?{WS}+[0-9]+{WS}+{STRING}({WS}+[0-9]+)? { +<*>^"#"(line)?[ \t]+[0-9]+[ \t]+{STRING}([ \t]+[0-9]+)? { char *line, *tmp, *fn; /* skip text before line # */ line = yytext; diff --git a/scripts/dtc/dtc-lexer.lex.c_shipped b/scripts/dtc/dtc-lexer.lex.c_shipped index a6c5fcdfc032..2d30f41778b7 100644 --- a/scripts/dtc/dtc-lexer.lex.c_shipped +++ b/scripts/dtc/dtc-lexer.lex.c_shipped @@ -405,19 +405,19 @@ static yyconst flex_int16_t yy_accept[161] = static yyconst flex_int32_t yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, - 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, + 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 4, 5, 6, 1, 1, 7, 8, 1, - 1, 9, 10, 10, 11, 10, 12, 13, 14, 15, - 15, 15, 15, 15, 15, 15, 15, 16, 1, 17, - 18, 19, 10, 10, 20, 20, 20, 20, 20, 20, - 21, 21, 21, 21, 21, 22, 21, 21, 21, 21, - 21, 21, 21, 21, 23, 21, 21, 24, 21, 21, - 1, 25, 26, 1, 21, 1, 20, 27, 28, 29, - - 30, 20, 21, 21, 31, 21, 21, 32, 33, 34, - 35, 36, 21, 37, 38, 39, 40, 41, 21, 24, - 42, 21, 43, 44, 45, 1, 1, 1, 1, 1, + 1, 2, 5, 6, 7, 1, 1, 8, 9, 1, + 1, 10, 11, 11, 12, 11, 13, 14, 15, 16, + 16, 16, 16, 16, 16, 16, 16, 17, 1, 18, + 19, 20, 11, 11, 21, 21, 21, 21, 21, 21, + 22, 22, 22, 22, 22, 23, 22, 22, 22, 22, + 22, 22, 22, 22, 24, 22, 22, 25, 22, 22, + 1, 26, 27, 1, 22, 1, 21, 28, 29, 30, + + 31, 21, 22, 22, 32, 22, 22, 33, 34, 35, + 36, 37, 22, 38, 39, 40, 41, 42, 22, 25, + 43, 22, 44, 45, 46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -434,36 +434,36 @@ static yyconst flex_int32_t yy_ec[256] = 1, 1, 1, 1, 1 } ; -static yyconst flex_int32_t yy_meta[46] = +static yyconst flex_int32_t yy_meta[47] = { 0, - 1, 1, 1, 1, 1, 2, 3, 1, 2, 2, - 2, 4, 5, 5, 5, 6, 1, 1, 1, 7, - 8, 8, 8, 8, 1, 1, 7, 7, 7, 7, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 3, 1, 1 + 1, 1, 1, 1, 1, 1, 2, 3, 1, 2, + 2, 2, 4, 5, 5, 5, 6, 1, 1, 1, + 7, 8, 8, 8, 8, 1, 1, 7, 7, 7, + 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 3, 1, 1 } ; static yyconst flex_int16_t yy_base[175] = { 0, - 0, 388, 381, 40, 41, 386, 71, 385, 34, 44, - 390, 395, 60, 62, 371, 112, 111, 111, 111, 104, - 370, 106, 371, 342, 124, 119, 0, 144, 395, 0, - 123, 0, 159, 153, 165, 167, 395, 130, 395, 382, - 395, 0, 372, 122, 395, 157, 374, 379, 350, 21, - 346, 349, 395, 395, 395, 395, 395, 362, 395, 395, - 181, 346, 342, 395, 359, 0, 191, 343, 190, 351, - 350, 0, 0, 0, 173, 362, 177, 367, 357, 329, - 335, 328, 337, 331, 206, 329, 334, 327, 395, 338, - 170, 314, 346, 345, 318, 325, 343, 158, 316, 212, - - 322, 319, 320, 395, 340, 336, 308, 305, 314, 304, - 295, 138, 208, 220, 395, 292, 305, 265, 264, 254, - 201, 222, 285, 275, 273, 270, 236, 235, 225, 115, - 395, 395, 252, 216, 216, 217, 214, 230, 209, 220, - 213, 239, 211, 217, 216, 209, 229, 395, 240, 225, - 206, 169, 395, 395, 116, 106, 99, 54, 395, 395, - 254, 260, 268, 272, 276, 282, 289, 293, 301, 309, - 313, 319, 327, 335 + 0, 385, 378, 40, 41, 383, 72, 382, 34, 44, + 388, 393, 61, 117, 368, 116, 115, 115, 115, 48, + 367, 107, 368, 339, 127, 120, 0, 147, 393, 0, + 127, 0, 133, 156, 168, 153, 393, 125, 393, 380, + 393, 0, 369, 127, 393, 160, 371, 377, 347, 21, + 343, 346, 393, 393, 393, 393, 393, 359, 393, 393, + 183, 343, 339, 393, 356, 0, 183, 340, 187, 348, + 347, 0, 0, 0, 178, 359, 195, 365, 354, 326, + 332, 325, 334, 328, 204, 326, 331, 324, 393, 335, + 150, 311, 343, 342, 315, 322, 340, 179, 313, 207, + + 319, 316, 317, 393, 337, 333, 305, 302, 311, 301, + 310, 190, 338, 337, 393, 307, 322, 301, 305, 277, + 208, 311, 307, 278, 271, 270, 248, 246, 213, 130, + 393, 393, 263, 235, 207, 221, 218, 229, 213, 213, + 206, 234, 218, 210, 208, 193, 219, 393, 223, 204, + 176, 157, 393, 393, 120, 106, 97, 119, 393, 393, + 245, 251, 259, 263, 267, 273, 280, 284, 292, 300, + 304, 310, 318, 326 } ; static yyconst flex_int16_t yy_def[175] = @@ -489,108 +489,108 @@ static yyconst flex_int16_t yy_def[175] = 160, 160, 160, 160 } ; -static yyconst flex_int16_t yy_nxt[441] = +static yyconst flex_int16_t yy_nxt[440] = { 0, - 12, 13, 14, 15, 16, 12, 17, 18, 12, 12, - 12, 19, 12, 12, 12, 12, 20, 21, 22, 23, - 23, 23, 23, 23, 12, 12, 23, 23, 23, 23, + 12, 13, 14, 13, 15, 16, 12, 17, 18, 12, + 12, 12, 19, 12, 12, 12, 12, 20, 21, 22, + 23, 23, 23, 23, 23, 12, 12, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 12, 24, 12, 25, 34, 35, 35, 25, - 81, 26, 26, 27, 27, 27, 34, 35, 35, 82, - 28, 36, 36, 36, 36, 159, 29, 28, 28, 28, - 28, 12, 13, 14, 15, 16, 30, 17, 18, 30, - 30, 30, 26, 30, 30, 30, 12, 20, 21, 22, - 31, 31, 31, 31, 31, 32, 12, 31, 31, 31, + 23, 23, 23, 12, 24, 12, 25, 34, 35, 35, + 25, 81, 26, 26, 27, 27, 27, 34, 35, 35, + 82, 28, 36, 36, 36, 53, 54, 29, 28, 28, + 28, 28, 12, 13, 14, 13, 15, 16, 30, 17, + 18, 30, 30, 30, 26, 30, 30, 30, 12, 20, + 21, 22, 31, 31, 31, 31, 31, 32, 12, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 12, 24, 12, 39, 41, 45, 47, - 53, 54, 48, 56, 57, 61, 61, 47, 66, 45, - 48, 66, 66, 66, 39, 46, 40, 49, 59, 50, - 158, 51, 122, 52, 157, 49, 46, 50, 136, 63, - 137, 52, 156, 43, 40, 62, 65, 65, 65, 59, - 61, 61, 123, 65, 75, 69, 69, 69, 36, 36, - 65, 65, 65, 65, 70, 71, 72, 69, 69, 69, - 45, 46, 61, 61, 109, 77, 70, 71, 93, 110, - 68, 70, 71, 85, 85, 85, 66, 46, 155, 66, - - 66, 66, 69, 69, 69, 122, 59, 100, 100, 61, - 61, 70, 71, 100, 100, 148, 112, 154, 85, 85, - 85, 61, 61, 129, 129, 123, 129, 129, 135, 135, - 135, 142, 142, 148, 143, 149, 153, 135, 135, 135, - 142, 142, 160, 143, 152, 151, 150, 146, 145, 144, - 141, 140, 139, 149, 38, 38, 38, 38, 38, 38, - 38, 38, 42, 138, 134, 133, 42, 42, 44, 44, - 44, 44, 44, 44, 44, 44, 58, 58, 58, 58, - 64, 132, 64, 66, 131, 130, 66, 160, 66, 66, - 67, 128, 127, 67, 67, 67, 67, 73, 126, 73, - - 73, 76, 76, 76, 76, 76, 76, 76, 76, 78, - 78, 78, 78, 78, 78, 78, 78, 91, 125, 91, - 92, 124, 92, 92, 120, 92, 92, 121, 121, 121, - 121, 121, 121, 121, 121, 147, 147, 147, 147, 147, - 147, 147, 147, 119, 118, 117, 116, 115, 47, 114, - 110, 113, 111, 108, 107, 106, 48, 105, 104, 89, - 103, 102, 101, 99, 98, 97, 96, 95, 94, 79, - 77, 90, 89, 88, 59, 87, 86, 59, 84, 83, - 80, 79, 77, 74, 160, 60, 59, 55, 37, 160, - 33, 25, 26, 25, 11, 160, 160, 160, 160, 160, + 31, 31, 31, 31, 31, 12, 24, 12, 36, 36, + 36, 39, 41, 45, 47, 56, 57, 48, 61, 47, + 39, 159, 48, 66, 61, 45, 66, 66, 66, 158, + 46, 40, 49, 59, 50, 157, 51, 49, 52, 50, + 40, 63, 46, 52, 36, 36, 36, 156, 43, 62, + 65, 65, 65, 59, 136, 68, 137, 65, 75, 69, + 69, 69, 70, 71, 65, 65, 65, 65, 70, 71, + 72, 69, 69, 69, 61, 46, 45, 155, 154, 66, + 70, 71, 66, 66, 66, 122, 85, 85, 85, 59, + + 69, 69, 69, 46, 77, 100, 109, 93, 100, 70, + 71, 110, 112, 122, 129, 123, 153, 85, 85, 85, + 135, 135, 135, 148, 148, 160, 135, 135, 135, 152, + 142, 142, 142, 123, 143, 142, 142, 142, 151, 143, + 150, 146, 145, 149, 149, 38, 38, 38, 38, 38, + 38, 38, 38, 42, 144, 141, 140, 42, 42, 44, + 44, 44, 44, 44, 44, 44, 44, 58, 58, 58, + 58, 64, 139, 64, 66, 138, 134, 66, 133, 66, + 66, 67, 132, 131, 67, 67, 67, 67, 73, 130, + 73, 73, 76, 76, 76, 76, 76, 76, 76, 76, + + 78, 78, 78, 78, 78, 78, 78, 78, 91, 160, + 91, 92, 129, 92, 92, 128, 92, 92, 121, 121, + 121, 121, 121, 121, 121, 121, 147, 147, 147, 147, + 147, 147, 147, 147, 127, 126, 125, 124, 61, 61, + 120, 119, 118, 117, 116, 115, 47, 114, 110, 113, + 111, 108, 107, 106, 48, 105, 104, 89, 103, 102, + 101, 99, 98, 97, 96, 95, 94, 79, 77, 90, + 89, 88, 59, 87, 86, 59, 84, 83, 80, 79, + 77, 74, 160, 60, 59, 55, 37, 160, 33, 25, + 26, 25, 11, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, 160, 160 + 160, 160, 160, 160, 160, 160, 160, 160, 160 } ; -static yyconst flex_int16_t yy_chk[441] = +static yyconst flex_int16_t yy_chk[440] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 4, 9, 9, 9, 10, - 50, 4, 5, 5, 5, 5, 10, 10, 10, 50, - 5, 13, 13, 14, 14, 158, 5, 5, 5, 5, - 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 1, 1, 1, 1, 1, 1, 4, 9, 9, 9, + 10, 50, 4, 5, 5, 5, 5, 10, 10, 10, + 50, 5, 13, 13, 13, 20, 20, 5, 5, 5, + 5, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 16, 17, 18, 19, - 20, 20, 19, 22, 22, 25, 25, 26, 31, 44, - 26, 31, 31, 31, 38, 18, 16, 19, 31, 19, - 157, 19, 112, 19, 156, 26, 44, 26, 130, 26, - 130, 26, 155, 17, 38, 25, 28, 28, 28, 28, - 33, 33, 112, 28, 46, 34, 34, 34, 36, 36, - 28, 28, 28, 28, 34, 34, 34, 35, 35, 35, - 75, 46, 61, 61, 98, 77, 35, 35, 77, 98, - 33, 91, 91, 61, 61, 61, 67, 75, 152, 67, - - 67, 67, 69, 69, 69, 121, 67, 85, 85, 113, - 113, 69, 69, 100, 100, 143, 100, 151, 85, 85, - 85, 114, 114, 122, 122, 121, 129, 129, 135, 135, - 135, 138, 138, 147, 138, 143, 150, 129, 129, 129, - 142, 142, 149, 142, 146, 145, 144, 141, 140, 139, - 137, 136, 134, 147, 161, 161, 161, 161, 161, 161, - 161, 161, 162, 133, 128, 127, 162, 162, 163, 163, - 163, 163, 163, 163, 163, 163, 164, 164, 164, 164, - 165, 126, 165, 166, 125, 124, 166, 123, 166, 166, - 167, 120, 119, 167, 167, 167, 167, 168, 118, 168, - - 168, 169, 169, 169, 169, 169, 169, 169, 169, 170, - 170, 170, 170, 170, 170, 170, 170, 171, 117, 171, - 172, 116, 172, 172, 111, 172, 172, 173, 173, 173, - 173, 173, 173, 173, 173, 174, 174, 174, 174, 174, - 174, 174, 174, 110, 109, 108, 107, 106, 105, 103, - 102, 101, 99, 97, 96, 95, 94, 93, 92, 90, - 88, 87, 86, 84, 83, 82, 81, 80, 79, 78, - 76, 71, 70, 68, 65, 63, 62, 58, 52, 51, - 49, 48, 47, 43, 40, 24, 23, 21, 15, 11, - 8, 6, 3, 2, 160, 160, 160, 160, 160, 160, + 7, 7, 7, 7, 7, 7, 7, 7, 14, 14, + 14, 16, 17, 18, 19, 22, 22, 19, 25, 26, + 38, 158, 26, 31, 33, 44, 31, 31, 31, 157, + 18, 16, 19, 31, 19, 156, 19, 26, 19, 26, + 38, 26, 44, 26, 36, 36, 36, 155, 17, 25, + 28, 28, 28, 28, 130, 33, 130, 28, 46, 34, + 34, 34, 91, 91, 28, 28, 28, 28, 34, 34, + 34, 35, 35, 35, 61, 46, 75, 152, 151, 67, + 35, 35, 67, 67, 67, 112, 61, 61, 61, 67, + + 69, 69, 69, 75, 77, 85, 98, 77, 100, 69, + 69, 98, 100, 121, 129, 112, 150, 85, 85, 85, + 135, 135, 135, 143, 147, 149, 129, 129, 129, 146, + 138, 138, 138, 121, 138, 142, 142, 142, 145, 142, + 144, 141, 140, 143, 147, 161, 161, 161, 161, 161, + 161, 161, 161, 162, 139, 137, 136, 162, 162, 163, + 163, 163, 163, 163, 163, 163, 163, 164, 164, 164, + 164, 165, 134, 165, 166, 133, 128, 166, 127, 166, + 166, 167, 126, 125, 167, 167, 167, 167, 168, 124, + 168, 168, 169, 169, 169, 169, 169, 169, 169, 169, + + 170, 170, 170, 170, 170, 170, 170, 170, 171, 123, + 171, 172, 122, 172, 172, 120, 172, 172, 173, 173, + 173, 173, 173, 173, 173, 173, 174, 174, 174, 174, + 174, 174, 174, 174, 119, 118, 117, 116, 114, 113, + 111, 110, 109, 108, 107, 106, 105, 103, 102, 101, + 99, 97, 96, 95, 94, 93, 92, 90, 88, 87, + 86, 84, 83, 82, 81, 80, 79, 78, 76, 71, + 70, 68, 65, 63, 62, 58, 52, 51, 49, 48, + 47, 43, 40, 24, 23, 21, 15, 11, 8, 6, + 3, 2, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, 160, 160 + 160, 160, 160, 160, 160, 160, 160, 160, 160 } ; static yy_state_type yy_last_accepting_state; diff --git a/scripts/dtc/dtc-parser.tab.c_shipped b/scripts/dtc/dtc-parser.tab.c_shipped index 4af55900a15b..ee1d8c3042fb 100644 --- a/scripts/dtc/dtc-parser.tab.c_shipped +++ b/scripts/dtc/dtc-parser.tab.c_shipped @@ -1,10 +1,8 @@ +/* A Bison parser, made by GNU Bison 2.5. */ -/* A Bison parser, made by GNU Bison 2.4.1. */ - -/* Skeleton implementation for Bison's Yacc-like parsers in C +/* Bison implementation for Yacc-like parsers in C - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 - Free Software Foundation, Inc. + Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -46,7 +44,7 @@ #define YYBISON 1 /* Bison version. */ -#define YYBISON_VERSION "2.4.1" +#define YYBISON_VERSION "2.5" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -67,7 +65,7 @@ /* Copy the first part of user declarations. */ -/* Line 189 of yacc.c */ +/* Line 268 of yacc.c */ #line 21 "dtc-parser.y" #include <stdio.h> @@ -88,8 +86,8 @@ static unsigned long long eval_literal(const char *s, int base, int bits); static unsigned char eval_char_literal(const char *s); -/* Line 189 of yacc.c */ -#line 93 "dtc-parser.tab.c" +/* Line 268 of yacc.c */ +#line 91 "dtc-parser.tab.c" /* Enabling traces. */ #ifndef YYDEBUG @@ -147,7 +145,7 @@ static unsigned char eval_char_literal(const char *s); typedef union YYSTYPE { -/* Line 214 of yacc.c */ +/* Line 293 of yacc.c */ #line 40 "dtc-parser.y" char *propnodename; @@ -171,8 +169,8 @@ typedef union YYSTYPE -/* Line 214 of yacc.c */ -#line 176 "dtc-parser.tab.c" +/* Line 293 of yacc.c */ +#line 174 "dtc-parser.tab.c" } YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ @@ -183,8 +181,8 @@ typedef union YYSTYPE /* Copy the second part of user declarations. */ -/* Line 264 of yacc.c */ -#line 188 "dtc-parser.tab.c" +/* Line 343 of yacc.c */ +#line 186 "dtc-parser.tab.c" #ifdef short # undef short @@ -234,7 +232,7 @@ typedef short int yytype_int16; #define YYSIZE_MAXIMUM ((YYSIZE_T) -1) #ifndef YY_ -# if YYENABLE_NLS +# if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include <libintl.h> /* INFRINGES ON USER NAME SPACE */ # define YY_(msgid) dgettext ("bison-runtime", msgid) @@ -287,11 +285,11 @@ YYID (yyi) # define alloca _alloca # else # define YYSTACK_ALLOC alloca -# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ +# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ -# ifndef _STDLIB_H -# define _STDLIB_H 1 +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 # endif # endif # endif @@ -314,24 +312,24 @@ YYID (yyi) # ifndef YYSTACK_ALLOC_MAXIMUM # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM # endif -# if (defined __cplusplus && ! defined _STDLIB_H \ +# if (defined __cplusplus && ! defined EXIT_SUCCESS \ && ! ((defined YYMALLOC || defined malloc) \ && (defined YYFREE || defined free))) # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ -# ifndef _STDLIB_H -# define _STDLIB_H 1 +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 # endif # endif # ifndef YYMALLOC # define YYMALLOC malloc -# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ +# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free -# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ +# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif @@ -360,23 +358,7 @@ union yyalloc ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM) -/* Copy COUNT objects from FROM to TO. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if defined __GNUC__ && 1 < __GNUC__ -# define YYCOPY(To, From, Count) \ - __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -# else -# define YYCOPY(To, From, Count) \ - do \ - { \ - YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (To)[yyi] = (From)[yyi]; \ - } \ - while (YYID (0)) -# endif -# endif +# define YYCOPY_NEEDED 1 /* Relocate STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of @@ -396,6 +378,26 @@ union yyalloc #endif +#if defined YYCOPY_NEEDED && YYCOPY_NEEDED +/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# else +# define YYCOPY(To, From, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ + while (YYID (0)) +# endif +# endif +#endif /* !YYCOPY_NEEDED */ + /* YYFINAL -- State number of the termination state. */ #define YYFINAL 4 /* YYLAST -- Last index in YYTABLE. */ @@ -571,8 +573,8 @@ static const yytype_uint8 yyr2[] = 2, 0, 2, 2, 0, 2, 2, 2, 3, 2 }; -/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state - STATE-NUM when YYTABLE doesn't specify something else to do. Zero +/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. + Performed when YYTABLE doesn't specify something else to do. Zero means the default is an error. */ static const yytype_uint8 yydefact[] = { @@ -633,8 +635,7 @@ static const yytype_int8 yypgoto[] = /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which - number is the opposite. If zero, do what YYDEFACT says. - If YYTABLE_NINF, syntax error. */ + number is the opposite. If YYTABLE_NINF, syntax error. */ #define YYTABLE_NINF -1 static const yytype_uint8 yytable[] = { @@ -654,6 +655,12 @@ static const yytype_uint8 yytable[] = 137, 0, 73, 139 }; +#define yypact_value_is_default(yystate) \ + ((yystate) == (-78)) + +#define yytable_value_is_error(yytable_value) \ + YYID (0) + static const yytype_int16 yycheck[] = { 5, 38, 39, 17, 18, 19, 12, 12, 17, 18, @@ -705,9 +712,18 @@ static const yytype_uint8 yystos[] = /* Like YYERROR except do call yyerror. This remains here temporarily to ease the transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. */ + Once GCC version 2 has supplanted version 1, this can go. However, + YYFAIL appears to be in use. Nevertheless, it is formally deprecated + in Bison 2.4.2's NEWS entry, where a plan to phase it out is + discussed. */ #define YYFAIL goto yyerrlab +#if defined YYFAIL + /* This is here to suppress warnings from the GCC cpp's + -Wunused-macros. Normally we don't worry about that warning, but + some users do, and we want to make it easy for users to remove + YYFAIL uses, which will produce warnings from Bison 2.5. */ +#endif #define YYRECOVERING() (!!yyerrstatus) @@ -717,7 +733,6 @@ do \ { \ yychar = (Token); \ yylval = (Value); \ - yytoken = YYTRANSLATE (yychar); \ YYPOPSTACK (1); \ goto yybackup; \ } \ @@ -759,19 +774,10 @@ while (YYID (0)) #endif -/* YY_LOCATION_PRINT -- Print the location on the stream. - This macro was not mandated originally: define only if we know - we won't break user code: when these are the locations we know. */ +/* This macro is provided for backward compatibility. */ #ifndef YY_LOCATION_PRINT -# if YYLTYPE_IS_TRIVIAL -# define YY_LOCATION_PRINT(File, Loc) \ - fprintf (File, "%d.%d-%d.%d", \ - (Loc).first_line, (Loc).first_column, \ - (Loc).last_line, (Loc).last_column) -# else -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -# endif +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) #endif @@ -963,7 +969,6 @@ int yydebug; # define YYMAXDEPTH 10000 #endif - #if YYERROR_VERBOSE @@ -1066,115 +1071,142 @@ yytnamerr (char *yyres, const char *yystr) } # endif -/* Copy into YYRESULT an error message about the unexpected token - YYCHAR while in state YYSTATE. Return the number of bytes copied, - including the terminating null byte. If YYRESULT is null, do not - copy anything; just return the number of bytes that would be - copied. As a special case, return 0 if an ordinary "syntax error" - message will do. Return YYSIZE_MAXIMUM if overflow occurs during - size calculation. */ -static YYSIZE_T -yysyntax_error (char *yyresult, int yystate, int yychar) -{ - int yyn = yypact[yystate]; +/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message + about the unexpected token YYTOKEN for the state stack whose top is + YYSSP. - if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) - return 0; - else + Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is + not large enough to hold the message. In that case, also set + *YYMSG_ALLOC to the required number of bytes. Return 2 if the + required number of bytes is too large to store. */ +static int +yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, + yytype_int16 *yyssp, int yytoken) +{ + YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]); + YYSIZE_T yysize = yysize0; + YYSIZE_T yysize1; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + /* Internationalized format string. */ + const char *yyformat = 0; + /* Arguments of yyformat. */ + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + /* Number of reported tokens (one for the "unexpected", one per + "expected"). */ + int yycount = 0; + + /* There are many possibilities here to consider: + - Assume YYFAIL is not used. It's too flawed to consider. See + <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html> + for details. YYERROR is fine as it does not invoke this + function. + - If this state is a consistent state with a default action, then + the only way this function was invoked is if the default action + is an error action. In that case, don't check for expected + tokens because there are none. + - The only way there can be no lookahead present (in yychar) is if + this state is a consistent state with a default action. Thus, + detecting the absence of a lookahead is sufficient to determine + that there is no unexpected or expected token to report. In that + case, just report a simple "syntax error". + - Don't assume there isn't a lookahead just because this state is a + consistent state with a default action. There might have been a + previous inconsistent state, consistent state with a non-default + action, or user semantic action that manipulated yychar. + - Of course, the expected token list depends on states to have + correct lookahead information, and it depends on the parser not + to perform extra reductions after fetching a lookahead from the + scanner and before detecting a syntax error. Thus, state merging + (from LALR or IELR) and default reductions corrupt the expected + token list. However, the list is correct for canonical LR with + one exception: it will still contain any token that will not be + accepted due to an error action in a later state. + */ + if (yytoken != YYEMPTY) { - int yytype = YYTRANSLATE (yychar); - YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); - YYSIZE_T yysize = yysize0; - YYSIZE_T yysize1; - int yysize_overflow = 0; - enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - int yyx; - -# if 0 - /* This is so xgettext sees the translatable formats that are - constructed on the fly. */ - YY_("syntax error, unexpected %s"); - YY_("syntax error, unexpected %s, expecting %s"); - YY_("syntax error, unexpected %s, expecting %s or %s"); - YY_("syntax error, unexpected %s, expecting %s or %s or %s"); - YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); -# endif - char *yyfmt; - char const *yyf; - static char const yyunexpected[] = "syntax error, unexpected %s"; - static char const yyexpecting[] = ", expecting %s"; - static char const yyor[] = " or %s"; - char yyformat[sizeof yyunexpected - + sizeof yyexpecting - 1 - + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) - * (sizeof yyor - 1))]; - char const *yyprefix = yyexpecting; - - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. */ - int yyxbegin = yyn < 0 ? -yyn : 0; - - /* Stay within bounds of both yycheck and yytname. */ - int yychecklim = YYLAST - yyn + 1; - int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; - int yycount = 1; - - yyarg[0] = yytname[yytype]; - yyfmt = yystpcpy (yyformat, yyunexpected); - - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - { - if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) - { - yycount = 1; - yysize = yysize0; - yyformat[sizeof yyunexpected - 1] = '\0'; - break; - } - yyarg[yycount++] = yytname[yyx]; - yysize1 = yysize + yytnamerr (0, yytname[yyx]); - yysize_overflow |= (yysize1 < yysize); - yysize = yysize1; - yyfmt = yystpcpy (yyfmt, yyprefix); - yyprefix = yyor; - } + int yyn = yypact[*yyssp]; + yyarg[yycount++] = yytname[yytoken]; + if (!yypact_value_is_default (yyn)) + { + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. In other words, skip the first -YYN actions for + this state because they are default actions. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yyx; + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR + && !yytable_value_is_error (yytable[yyx + yyn])) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + break; + } + yyarg[yycount++] = yytname[yyx]; + yysize1 = yysize + yytnamerr (0, yytname[yyx]); + if (! (yysize <= yysize1 + && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + } + } + } - yyf = YY_(yyformat); - yysize1 = yysize + yystrlen (yyf); - yysize_overflow |= (yysize1 < yysize); - yysize = yysize1; + switch (yycount) + { +# define YYCASE_(N, S) \ + case N: \ + yyformat = S; \ + break + YYCASE_(0, YY_("syntax error")); + YYCASE_(1, YY_("syntax error, unexpected %s")); + YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); + YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); + YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); + YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); +# undef YYCASE_ + } - if (yysize_overflow) - return YYSIZE_MAXIMUM; + yysize1 = yysize + yystrlen (yyformat); + if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; - if (yyresult) - { - /* Avoid sprintf, as that infringes on the user's name space. - Don't have undefined behavior even if the translation - produced a string with the wrong number of "%s"s. */ - char *yyp = yyresult; - int yyi = 0; - while ((*yyp = *yyf) != '\0') - { - if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) - { - yyp += yytnamerr (yyp, yyarg[yyi++]); - yyf += 2; - } - else - { - yyp++; - yyf++; - } - } - } - return yysize; + if (*yymsg_alloc < yysize) + { + *yymsg_alloc = 2 * yysize; + if (! (yysize <= *yymsg_alloc + && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) + *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; + return 1; } + + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + { + char *yyp = *yymsg; + int yyi = 0; + while ((*yyp = *yyformat) != '\0') + if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyformat += 2; + } + else + { + yyp++; + yyformat++; + } + } + return 0; } #endif /* YYERROR_VERBOSE */ - /*-----------------------------------------------. | Release the memory associated to this symbol. | @@ -1207,6 +1239,7 @@ yydestruct (yymsg, yytype, yyvaluep) } } + /* Prevent warnings from -Wmissing-prototypes. */ #ifdef YYPARSE_PARAM #if defined __STDC__ || defined __cplusplus @@ -1233,10 +1266,9 @@ YYSTYPE yylval; int yynerrs; - -/*-------------------------. -| yyparse or yypush_parse. | -`-------------------------*/ +/*----------. +| yyparse. | +`----------*/ #ifdef YYPARSE_PARAM #if (defined __STDC__ || defined __C99__FUNC__ \ @@ -1260,8 +1292,6 @@ yyparse () #endif #endif { - - int yystate; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus; @@ -1416,7 +1446,7 @@ yybackup: /* First try to decide what to do without reference to lookahead token. */ yyn = yypact[yystate]; - if (yyn == YYPACT_NINF) + if (yypact_value_is_default (yyn)) goto yydefault; /* Not known => get a lookahead token if don't already have one. */ @@ -1447,8 +1477,8 @@ yybackup: yyn = yytable[yyn]; if (yyn <= 0) { - if (yyn == 0 || yyn == YYTABLE_NINF) - goto yyerrlab; + if (yytable_value_is_error (yyn)) + goto yyerrlab; yyn = -yyn; goto yyreduce; } @@ -1503,72 +1533,72 @@ yyreduce: { case 2: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 110 "dtc-parser.y" { the_boot_info = build_boot_info((yyvsp[(3) - (4)].re), (yyvsp[(4) - (4)].node), guess_boot_cpuid((yyvsp[(4) - (4)].node))); - ;} + } break; case 3: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 118 "dtc-parser.y" { (yyval.re) = NULL; - ;} + } break; case 4: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 122 "dtc-parser.y" { (yyval.re) = chain_reserve_entry((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].re)); - ;} + } break; case 5: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 129 "dtc-parser.y" { (yyval.re) = build_reserve_entry((yyvsp[(2) - (4)].integer), (yyvsp[(3) - (4)].integer)); - ;} + } break; case 6: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 133 "dtc-parser.y" { add_label(&(yyvsp[(2) - (2)].re)->labels, (yyvsp[(1) - (2)].labelref)); (yyval.re) = (yyvsp[(2) - (2)].re); - ;} + } break; case 7: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 141 "dtc-parser.y" { (yyval.node) = name_node((yyvsp[(2) - (2)].node), ""); - ;} + } break; case 8: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 145 "dtc-parser.y" { (yyval.node) = merge_nodes((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); - ;} + } break; case 9: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 149 "dtc-parser.y" { struct node *target = get_node_by_ref((yyvsp[(1) - (3)].node), (yyvsp[(2) - (3)].labelref)); @@ -1578,12 +1608,12 @@ yyreduce: else print_error("label or path, '%s', not found", (yyvsp[(2) - (3)].labelref)); (yyval.node) = (yyvsp[(1) - (3)].node); - ;} + } break; case 10: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 159 "dtc-parser.y" { struct node *target = get_node_by_ref((yyvsp[(1) - (4)].node), (yyvsp[(3) - (4)].labelref)); @@ -1594,112 +1624,112 @@ yyreduce: delete_node(target); (yyval.node) = (yyvsp[(1) - (4)].node); - ;} + } break; case 11: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 173 "dtc-parser.y" { (yyval.node) = build_node((yyvsp[(2) - (5)].proplist), (yyvsp[(3) - (5)].nodelist)); - ;} + } break; case 12: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 180 "dtc-parser.y" { (yyval.proplist) = NULL; - ;} + } break; case 13: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 184 "dtc-parser.y" { (yyval.proplist) = chain_property((yyvsp[(2) - (2)].prop), (yyvsp[(1) - (2)].proplist)); - ;} + } break; case 14: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 191 "dtc-parser.y" { (yyval.prop) = build_property((yyvsp[(1) - (4)].propnodename), (yyvsp[(3) - (4)].data)); - ;} + } break; case 15: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 195 "dtc-parser.y" { (yyval.prop) = build_property((yyvsp[(1) - (2)].propnodename), empty_data); - ;} + } break; case 16: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 199 "dtc-parser.y" { (yyval.prop) = build_property_delete((yyvsp[(2) - (3)].propnodename)); - ;} + } break; case 17: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 203 "dtc-parser.y" { add_label(&(yyvsp[(2) - (2)].prop)->labels, (yyvsp[(1) - (2)].labelref)); (yyval.prop) = (yyvsp[(2) - (2)].prop); - ;} + } break; case 18: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 211 "dtc-parser.y" { (yyval.data) = data_merge((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].data)); - ;} + } break; case 19: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 215 "dtc-parser.y" { (yyval.data) = data_merge((yyvsp[(1) - (3)].data), (yyvsp[(2) - (3)].array).data); - ;} + } break; case 20: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 219 "dtc-parser.y" { (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data)); - ;} + } break; case 21: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 223 "dtc-parser.y" { (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), REF_PATH, (yyvsp[(2) - (2)].labelref)); - ;} + } break; case 22: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 227 "dtc-parser.y" { FILE *f = srcfile_relative_open((yyvsp[(4) - (9)].data).val, NULL); @@ -1716,12 +1746,12 @@ yyreduce: (yyval.data) = data_merge((yyvsp[(1) - (9)].data), d); fclose(f); - ;} + } break; case 23: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 244 "dtc-parser.y" { FILE *f = srcfile_relative_open((yyvsp[(4) - (5)].data).val, NULL); @@ -1731,48 +1761,48 @@ yyreduce: (yyval.data) = data_merge((yyvsp[(1) - (5)].data), d); fclose(f); - ;} + } break; case 24: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 254 "dtc-parser.y" { (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); - ;} + } break; case 25: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 261 "dtc-parser.y" { (yyval.data) = empty_data; - ;} + } break; case 26: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 265 "dtc-parser.y" { (yyval.data) = (yyvsp[(1) - (2)].data); - ;} + } break; case 27: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 269 "dtc-parser.y" { (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); - ;} + } break; case 28: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 276 "dtc-parser.y" { (yyval.array).data = empty_data; @@ -1787,22 +1817,22 @@ yyreduce: " are currently supported"); (yyval.array).bits = 32; } - ;} + } break; case 29: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 291 "dtc-parser.y" { (yyval.array).data = empty_data; (yyval.array).bits = 32; - ;} + } break; case 30: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 296 "dtc-parser.y" { if ((yyvsp[(1) - (2)].array).bits < 64) { @@ -1822,12 +1852,12 @@ yyreduce: } (yyval.array).data = data_append_integer((yyvsp[(1) - (2)].array).data, (yyvsp[(2) - (2)].integer), (yyvsp[(1) - (2)].array).bits); - ;} + } break; case 31: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 316 "dtc-parser.y" { uint64_t val = ~0ULL >> (64 - (yyvsp[(1) - (2)].array).bits); @@ -1841,288 +1871,299 @@ yyreduce: "arrays with 32-bit elements."); (yyval.array).data = data_append_integer((yyvsp[(1) - (2)].array).data, val, (yyvsp[(1) - (2)].array).bits); - ;} + } break; case 32: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 330 "dtc-parser.y" { (yyval.array).data = data_add_marker((yyvsp[(1) - (2)].array).data, LABEL, (yyvsp[(2) - (2)].labelref)); - ;} + } break; case 33: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 337 "dtc-parser.y" { (yyval.integer) = eval_literal((yyvsp[(1) - (1)].literal), 0, 64); - ;} + } break; case 34: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 341 "dtc-parser.y" { (yyval.integer) = eval_char_literal((yyvsp[(1) - (1)].literal)); - ;} + } break; case 35: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 345 "dtc-parser.y" { (yyval.integer) = (yyvsp[(2) - (3)].integer); - ;} + } break; case 38: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 356 "dtc-parser.y" - { (yyval.integer) = (yyvsp[(1) - (5)].integer) ? (yyvsp[(3) - (5)].integer) : (yyvsp[(5) - (5)].integer); ;} + { (yyval.integer) = (yyvsp[(1) - (5)].integer) ? (yyvsp[(3) - (5)].integer) : (yyvsp[(5) - (5)].integer); } break; case 40: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 361 "dtc-parser.y" - { (yyval.integer) = (yyvsp[(1) - (3)].integer) || (yyvsp[(3) - (3)].integer); ;} + { (yyval.integer) = (yyvsp[(1) - (3)].integer) || (yyvsp[(3) - (3)].integer); } break; case 42: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 366 "dtc-parser.y" - { (yyval.integer) = (yyvsp[(1) - (3)].integer) && (yyvsp[(3) - (3)].integer); ;} + { (yyval.integer) = (yyvsp[(1) - (3)].integer) && (yyvsp[(3) - (3)].integer); } break; case 44: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 371 "dtc-parser.y" - { (yyval.integer) = (yyvsp[(1) - (3)].integer) | (yyvsp[(3) - (3)].integer); ;} + { (yyval.integer) = (yyvsp[(1) - (3)].integer) | (yyvsp[(3) - (3)].integer); } break; case 46: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 376 "dtc-parser.y" - { (yyval.integer) = (yyvsp[(1) - (3)].integer) ^ (yyvsp[(3) - (3)].integer); ;} + { (yyval.integer) = (yyvsp[(1) - (3)].integer) ^ (yyvsp[(3) - (3)].integer); } break; case 48: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 381 "dtc-parser.y" - { (yyval.integer) = (yyvsp[(1) - (3)].integer) & (yyvsp[(3) - (3)].integer); ;} + { (yyval.integer) = (yyvsp[(1) - (3)].integer) & (yyvsp[(3) - (3)].integer); } break; case 50: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 386 "dtc-parser.y" - { (yyval.integer) = (yyvsp[(1) - (3)].integer) == (yyvsp[(3) - (3)].integer); ;} + { (yyval.integer) = (yyvsp[(1) - (3)].integer) == (yyvsp[(3) - (3)].integer); } break; case 51: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 387 "dtc-parser.y" - { (yyval.integer) = (yyvsp[(1) - (3)].integer) != (yyvsp[(3) - (3)].integer); ;} + { (yyval.integer) = (yyvsp[(1) - (3)].integer) != (yyvsp[(3) - (3)].integer); } break; case 53: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 392 "dtc-parser.y" - { (yyval.integer) = (yyvsp[(1) - (3)].integer) < (yyvsp[(3) - (3)].integer); ;} + { (yyval.integer) = (yyvsp[(1) - (3)].integer) < (yyvsp[(3) - (3)].integer); } break; case 54: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 393 "dtc-parser.y" - { (yyval.integer) = (yyvsp[(1) - (3)].integer) > (yyvsp[(3) - (3)].integer); ;} + { (yyval.integer) = (yyvsp[(1) - (3)].integer) > (yyvsp[(3) - (3)].integer); } break; case 55: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 394 "dtc-parser.y" - { (yyval.integer) = (yyvsp[(1) - (3)].integer) <= (yyvsp[(3) - (3)].integer); ;} + { (yyval.integer) = (yyvsp[(1) - (3)].integer) <= (yyvsp[(3) - (3)].integer); } break; case 56: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 395 "dtc-parser.y" - { (yyval.integer) = (yyvsp[(1) - (3)].integer) >= (yyvsp[(3) - (3)].integer); ;} + { (yyval.integer) = (yyvsp[(1) - (3)].integer) >= (yyvsp[(3) - (3)].integer); } break; case 57: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 399 "dtc-parser.y" - { (yyval.integer) = (yyvsp[(1) - (3)].integer) << (yyvsp[(3) - (3)].integer); ;} + { (yyval.integer) = (yyvsp[(1) - (3)].integer) << (yyvsp[(3) - (3)].integer); } break; case 58: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 400 "dtc-parser.y" - { (yyval.integer) = (yyvsp[(1) - (3)].integer) >> (yyvsp[(3) - (3)].integer); ;} + { (yyval.integer) = (yyvsp[(1) - (3)].integer) >> (yyvsp[(3) - (3)].integer); } break; case 60: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 405 "dtc-parser.y" - { (yyval.integer) = (yyvsp[(1) - (3)].integer) + (yyvsp[(3) - (3)].integer); ;} + { (yyval.integer) = (yyvsp[(1) - (3)].integer) + (yyvsp[(3) - (3)].integer); } break; case 61: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 406 "dtc-parser.y" - { (yyval.integer) = (yyvsp[(1) - (3)].integer) - (yyvsp[(3) - (3)].integer); ;} + { (yyval.integer) = (yyvsp[(1) - (3)].integer) - (yyvsp[(3) - (3)].integer); } break; case 63: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 411 "dtc-parser.y" - { (yyval.integer) = (yyvsp[(1) - (3)].integer) * (yyvsp[(3) - (3)].integer); ;} + { (yyval.integer) = (yyvsp[(1) - (3)].integer) * (yyvsp[(3) - (3)].integer); } break; case 64: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 412 "dtc-parser.y" - { (yyval.integer) = (yyvsp[(1) - (3)].integer) / (yyvsp[(3) - (3)].integer); ;} + { (yyval.integer) = (yyvsp[(1) - (3)].integer) / (yyvsp[(3) - (3)].integer); } break; case 65: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 413 "dtc-parser.y" - { (yyval.integer) = (yyvsp[(1) - (3)].integer) % (yyvsp[(3) - (3)].integer); ;} + { (yyval.integer) = (yyvsp[(1) - (3)].integer) % (yyvsp[(3) - (3)].integer); } break; case 68: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 419 "dtc-parser.y" - { (yyval.integer) = -(yyvsp[(2) - (2)].integer); ;} + { (yyval.integer) = -(yyvsp[(2) - (2)].integer); } break; case 69: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 420 "dtc-parser.y" - { (yyval.integer) = ~(yyvsp[(2) - (2)].integer); ;} + { (yyval.integer) = ~(yyvsp[(2) - (2)].integer); } break; case 70: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 421 "dtc-parser.y" - { (yyval.integer) = !(yyvsp[(2) - (2)].integer); ;} + { (yyval.integer) = !(yyvsp[(2) - (2)].integer); } break; case 71: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 426 "dtc-parser.y" { (yyval.data) = empty_data; - ;} + } break; case 72: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 430 "dtc-parser.y" { (yyval.data) = data_append_byte((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].byte)); - ;} + } break; case 73: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 434 "dtc-parser.y" { (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); - ;} + } break; case 74: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 441 "dtc-parser.y" { (yyval.nodelist) = NULL; - ;} + } break; case 75: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 445 "dtc-parser.y" { (yyval.nodelist) = chain_node((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].nodelist)); - ;} + } break; case 76: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 449 "dtc-parser.y" { print_error("syntax error: properties must precede subnodes"); YYERROR; - ;} + } break; case 77: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 457 "dtc-parser.y" { (yyval.node) = name_node((yyvsp[(2) - (2)].node), (yyvsp[(1) - (2)].propnodename)); - ;} + } break; case 78: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 461 "dtc-parser.y" { (yyval.node) = name_node(build_node_delete(), (yyvsp[(2) - (3)].propnodename)); - ;} + } break; case 79: -/* Line 1455 of yacc.c */ +/* Line 1806 of yacc.c */ #line 465 "dtc-parser.y" { add_label(&(yyvsp[(2) - (2)].node)->labels, (yyvsp[(1) - (2)].labelref)); (yyval.node) = (yyvsp[(2) - (2)].node); - ;} + } break; -/* Line 1455 of yacc.c */ -#line 2124 "dtc-parser.tab.c" +/* Line 1806 of yacc.c */ +#line 2154 "dtc-parser.tab.c" default: break; } + /* User semantic actions sometimes alter yychar, and that requires + that yytoken be updated with the new translation. We take the + approach of translating immediately before every use of yytoken. + One alternative is translating here after every semantic action, + but that translation would be missed if the semantic action invokes + YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or + if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an + incorrect destructor might then be invoked immediately. In the + case of YYERROR or YYBACKUP, subsequent parser actions might lead + to an incorrect destructor call or verbose syntax error message + before the lookahead is translated. */ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); YYPOPSTACK (yylen); @@ -2150,6 +2191,10 @@ yyreduce: | yyerrlab -- here on detecting error | `------------------------------------*/ yyerrlab: + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); + /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { @@ -2157,37 +2202,36 @@ yyerrlab: #if ! YYERROR_VERBOSE yyerror (YY_("syntax error")); #else +# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ + yyssp, yytoken) { - YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); - if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) - { - YYSIZE_T yyalloc = 2 * yysize; - if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) - yyalloc = YYSTACK_ALLOC_MAXIMUM; - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); - yymsg = (char *) YYSTACK_ALLOC (yyalloc); - if (yymsg) - yymsg_alloc = yyalloc; - else - { - yymsg = yymsgbuf; - yymsg_alloc = sizeof yymsgbuf; - } - } - - if (0 < yysize && yysize <= yymsg_alloc) - { - (void) yysyntax_error (yymsg, yystate, yychar); - yyerror (yymsg); - } - else - { - yyerror (YY_("syntax error")); - if (yysize != 0) - goto yyexhaustedlab; - } + char const *yymsgp = YY_("syntax error"); + int yysyntax_error_status; + yysyntax_error_status = YYSYNTAX_ERROR; + if (yysyntax_error_status == 0) + yymsgp = yymsg; + else if (yysyntax_error_status == 1) + { + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); + if (!yymsg) + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + yysyntax_error_status = 2; + } + else + { + yysyntax_error_status = YYSYNTAX_ERROR; + yymsgp = yymsg; + } + } + yyerror (yymsgp); + if (yysyntax_error_status == 2) + goto yyexhaustedlab; } +# undef YYSYNTAX_ERROR #endif } @@ -2246,7 +2290,7 @@ yyerrlab1: for (;;) { yyn = yypact[yystate]; - if (yyn != YYPACT_NINF) + if (!yypact_value_is_default (yyn)) { yyn += YYTERROR; if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) @@ -2305,8 +2349,13 @@ yyexhaustedlab: yyreturn: if (yychar != YYEMPTY) - yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval); + { + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = YYTRANSLATE (yychar); + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval); + } /* Do not reclaim the symbols of the rule which action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); @@ -2331,7 +2380,7 @@ yyreturn: -/* Line 1675 of yacc.c */ +/* Line 2067 of yacc.c */ #line 471 "dtc-parser.y" diff --git a/scripts/dtc/dtc-parser.tab.h_shipped b/scripts/dtc/dtc-parser.tab.h_shipped index 9d2dce41211f..25d3b88c6132 100644 --- a/scripts/dtc/dtc-parser.tab.h_shipped +++ b/scripts/dtc/dtc-parser.tab.h_shipped @@ -1,10 +1,8 @@ +/* A Bison parser, made by GNU Bison 2.5. */ -/* A Bison parser, made by GNU Bison 2.4.1. */ - -/* Skeleton interface for Bison's Yacc-like parsers in C +/* Bison interface for Yacc-like parsers in C - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 - Free Software Foundation, Inc. + Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -70,7 +68,7 @@ typedef union YYSTYPE { -/* Line 1676 of yacc.c */ +/* Line 2068 of yacc.c */ #line 40 "dtc-parser.y" char *propnodename; @@ -94,8 +92,8 @@ typedef union YYSTYPE -/* Line 1676 of yacc.c */ -#line 99 "dtc-parser.tab.h" +/* Line 2068 of yacc.c */ +#line 97 "dtc-parser.tab.h" } YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ diff --git a/scripts/kconfig/lxdialog/menubox.c b/scripts/kconfig/lxdialog/menubox.c index 48d382e7e374..38cd69c5660e 100644 --- a/scripts/kconfig/lxdialog/menubox.c +++ b/scripts/kconfig/lxdialog/menubox.c @@ -303,10 +303,11 @@ do_resize: } } - if (i < max_choice || - key == KEY_UP || key == KEY_DOWN || - key == '-' || key == '+' || - key == KEY_PPAGE || key == KEY_NPAGE) { + if (item_count() != 0 && + (i < max_choice || + key == KEY_UP || key == KEY_DOWN || + key == '-' || key == '+' || + key == KEY_PPAGE || key == KEY_NPAGE)) { /* Remove highligt of current item */ print_item(scroll + choice, choice, FALSE); diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c index 387dc8daf7b2..a69cbd78fb38 100644 --- a/scripts/kconfig/mconf.c +++ b/scripts/kconfig/mconf.c @@ -670,11 +670,12 @@ static void conf(struct menu *menu, struct menu *active_menu) active_menu, &s_scroll); if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL) break; - if (!item_activate_selected()) - continue; - if (!item_tag()) - continue; - + if (item_count() != 0) { + if (!item_activate_selected()) + continue; + if (!item_tag()) + continue; + } submenu = item_data(); active_menu = item_data(); if (submenu) diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index b5c7d90df9df..fd3f0180e08f 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -146,11 +146,24 @@ struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *e struct menu *menu = current_entry; while ((menu = menu->parent) != NULL) { + struct expr *dup_expr; + if (!menu->visibility) continue; + /* + * Do not add a reference to the + * menu's visibility expression but + * use a copy of it. Otherwise the + * expression reduction functions + * will modify expressions that have + * multiple references which can + * cause unwanted side effects. + */ + dup_expr = expr_copy(menu->visibility); + prop->visible.expr = expr_alloc_and(prop->visible.expr, - menu->visibility); + dup_expr); } } diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c index 8ab295154517..d03081886214 100644 --- a/security/selinux/xfrm.c +++ b/security/selinux/xfrm.c @@ -316,6 +316,7 @@ int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx, memcpy(new_ctx, old_ctx, sizeof(*new_ctx)); memcpy(new_ctx->ctx_str, old_ctx->ctx_str, new_ctx->ctx_len); + atomic_inc(&selinux_xfrm_refcount); *new_ctxp = new_ctx; } return 0; @@ -326,6 +327,7 @@ int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx, */ void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx) { + atomic_dec(&selinux_xfrm_refcount); kfree(ctx); } @@ -335,17 +337,13 @@ void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx) int selinux_xfrm_policy_delete(struct xfrm_sec_ctx *ctx) { const struct task_security_struct *tsec = current_security(); - int rc = 0; - if (ctx) { - rc = avc_has_perm(tsec->sid, ctx->ctx_sid, - SECCLASS_ASSOCIATION, - ASSOCIATION__SETCONTEXT, NULL); - if (rc == 0) - atomic_dec(&selinux_xfrm_refcount); - } + if (!ctx) + return 0; - return rc; + return avc_has_perm(tsec->sid, ctx->ctx_sid, + SECCLASS_ASSOCIATION, ASSOCIATION__SETCONTEXT, + NULL); } /* @@ -370,8 +368,8 @@ int selinux_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *uct */ void selinux_xfrm_state_free(struct xfrm_state *x) { - struct xfrm_sec_ctx *ctx = x->security; - kfree(ctx); + atomic_dec(&selinux_xfrm_refcount); + kfree(x->security); } /* @@ -381,17 +379,13 @@ int selinux_xfrm_state_delete(struct xfrm_state *x) { const struct task_security_struct *tsec = current_security(); struct xfrm_sec_ctx *ctx = x->security; - int rc = 0; - if (ctx) { - rc = avc_has_perm(tsec->sid, ctx->ctx_sid, - SECCLASS_ASSOCIATION, - ASSOCIATION__SETCONTEXT, NULL); - if (rc == 0) - atomic_dec(&selinux_xfrm_refcount); - } + if (!ctx) + return 0; - return rc; + return avc_has_perm(tsec->sid, ctx->ctx_sid, + SECCLASS_ASSOCIATION, ASSOCIATION__SETCONTEXT, + NULL); } /* diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index ccfa383f1fda..f92818155958 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -1649,6 +1649,7 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd) } if (!snd_pcm_stream_linked(substream)) { substream->group = group; + group = NULL; spin_lock_init(&substream->group->lock); INIT_LIST_HEAD(&substream->group->substreams); list_add_tail(&substream->link_list, &substream->group->substreams); @@ -1663,8 +1664,7 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd) _nolock: snd_card_unref(substream1->pcm->card); fput_light(file, fput_needed); - if (res < 0) - kfree(group); + kfree(group); return res; } diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index ae85bbd2e6f8..4b1524a861f3 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -788,6 +788,8 @@ static void set_pin_eapd(struct hda_codec *codec, hda_nid_t pin, bool enable) return; if (codec->inv_eapd) enable = !enable; + if (spec->keep_eapd_on && !enable) + return; snd_hda_codec_update_cache(codec, pin, 0, AC_VERB_SET_EAPD_BTLENABLE, enable ? 0x02 : 0x00); @@ -1938,17 +1940,7 @@ static int create_speaker_out_ctls(struct hda_codec *codec) * independent HP controls */ -/* update HP auto-mute state too */ -static void update_hp_automute_hook(struct hda_codec *codec) -{ - struct hda_gen_spec *spec = codec->spec; - - if (spec->hp_automute_hook) - spec->hp_automute_hook(codec, NULL); - else - snd_hda_gen_hp_automute(codec, NULL); -} - +static void call_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *jack); static int indep_hp_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { @@ -2009,7 +2001,7 @@ static int indep_hp_put(struct snd_kcontrol *kcontrol, else *dacp = spec->alt_dac_nid; - update_hp_automute_hook(codec); + call_hp_automute(codec, NULL); ret = 1; } unlock: @@ -2305,7 +2297,7 @@ static void update_hp_mic(struct hda_codec *codec, int adc_mux, bool force) else val = PIN_HP; set_pin_target(codec, pin, val, true); - update_hp_automute_hook(codec); + call_hp_automute(codec, NULL); } } @@ -2714,7 +2706,7 @@ static int hp_mic_jack_mode_put(struct snd_kcontrol *kcontrol, val = snd_hda_get_default_vref(codec, nid); } snd_hda_set_pin_ctl_cache(codec, nid, val); - update_hp_automute_hook(codec); + call_hp_automute(codec, NULL); return 1; } @@ -3859,20 +3851,42 @@ void snd_hda_gen_mic_autoswitch(struct hda_codec *codec, struct hda_jack_tbl *ja } EXPORT_SYMBOL_HDA(snd_hda_gen_mic_autoswitch); -/* update jack retasking */ -static void update_automute_all(struct hda_codec *codec) +/* call appropriate hooks */ +static void call_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *jack) { struct hda_gen_spec *spec = codec->spec; + if (spec->hp_automute_hook) + spec->hp_automute_hook(codec, jack); + else + snd_hda_gen_hp_automute(codec, jack); +} - update_hp_automute_hook(codec); +static void call_line_automute(struct hda_codec *codec, + struct hda_jack_tbl *jack) +{ + struct hda_gen_spec *spec = codec->spec; if (spec->line_automute_hook) - spec->line_automute_hook(codec, NULL); + spec->line_automute_hook(codec, jack); else - snd_hda_gen_line_automute(codec, NULL); + snd_hda_gen_line_automute(codec, jack); +} + +static void call_mic_autoswitch(struct hda_codec *codec, + struct hda_jack_tbl *jack) +{ + struct hda_gen_spec *spec = codec->spec; if (spec->mic_autoswitch_hook) - spec->mic_autoswitch_hook(codec, NULL); + spec->mic_autoswitch_hook(codec, jack); else - snd_hda_gen_mic_autoswitch(codec, NULL); + snd_hda_gen_mic_autoswitch(codec, jack); +} + +/* update jack retasking */ +static void update_automute_all(struct hda_codec *codec) +{ + call_hp_automute(codec, NULL); + call_line_automute(codec, NULL); + call_mic_autoswitch(codec, NULL); } /* @@ -4009,9 +4023,7 @@ static int check_auto_mute_availability(struct hda_codec *codec) snd_printdd("hda-codec: Enable HP auto-muting on NID 0x%x\n", nid); snd_hda_jack_detect_enable_callback(codec, nid, HDA_GEN_HP_EVENT, - spec->hp_automute_hook ? - spec->hp_automute_hook : - snd_hda_gen_hp_automute); + call_hp_automute); spec->detect_hp = 1; } @@ -4024,9 +4036,7 @@ static int check_auto_mute_availability(struct hda_codec *codec) snd_printdd("hda-codec: Enable Line-Out auto-muting on NID 0x%x\n", nid); snd_hda_jack_detect_enable_callback(codec, nid, HDA_GEN_FRONT_EVENT, - spec->line_automute_hook ? - spec->line_automute_hook : - snd_hda_gen_line_automute); + call_line_automute); spec->detect_lo = 1; } spec->automute_lo_possible = spec->detect_hp; @@ -4068,9 +4078,7 @@ static bool auto_mic_check_imux(struct hda_codec *codec) snd_hda_jack_detect_enable_callback(codec, spec->am_entry[i].pin, HDA_GEN_MIC_EVENT, - spec->mic_autoswitch_hook ? - spec->mic_autoswitch_hook : - snd_hda_gen_mic_autoswitch); + call_mic_autoswitch); return true; } diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h index 54e665160379..76200314ee95 100644 --- a/sound/pci/hda/hda_generic.h +++ b/sound/pci/hda/hda_generic.h @@ -222,6 +222,7 @@ struct hda_gen_spec { unsigned int multi_cap_vol:1; /* allow multiple capture xxx volumes */ unsigned int inv_dmic_split:1; /* inverted dmic w/a for conexant */ unsigned int own_eapd_ctl:1; /* set EAPD by own function */ + unsigned int keep_eapd_on:1; /* don't turn off EAPD automatically */ unsigned int vmaster_mute_enum:1; /* add vmaster mute mode enum */ unsigned int indep_hp:1; /* independent HP supported */ unsigned int prefer_hp_amp:1; /* enable HP amp for speaker if any */ diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index bd8d46cca2b3..cccaf9c7a7bb 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c @@ -58,6 +58,7 @@ enum { CS420X_GPIO_23, CS420X_MBP101, CS420X_MBP81, + CS420X_MBA42, CS420X_AUTO, /* aliases */ CS420X_IMAC27_122 = CS420X_GPIO_23, @@ -346,6 +347,7 @@ static const struct hda_model_fixup cs420x_models[] = { { .id = CS420X_APPLE, .name = "apple" }, { .id = CS420X_MBP101, .name = "mbp101" }, { .id = CS420X_MBP81, .name = "mbp81" }, + { .id = CS420X_MBA42, .name = "mba42" }, {} }; @@ -361,6 +363,7 @@ static const struct snd_pci_quirk cs420x_fixup_tbl[] = { SND_PCI_QUIRK(0x106b, 0x1c00, "MacBookPro 8,1", CS420X_MBP81), SND_PCI_QUIRK(0x106b, 0x2000, "iMac 12,2", CS420X_IMAC27_122), SND_PCI_QUIRK(0x106b, 0x2800, "MacBookPro 10,1", CS420X_MBP101), + SND_PCI_QUIRK(0x106b, 0x5b00, "MacBookAir 4,2", CS420X_MBA42), SND_PCI_QUIRK_VENDOR(0x106b, "Apple", CS420X_APPLE), {} /* terminator */ }; @@ -414,6 +417,20 @@ static const struct hda_pintbl mbp101_pincfgs[] = { {} /* terminator */ }; +static const struct hda_pintbl mba42_pincfgs[] = { + { 0x09, 0x012b4030 }, /* HP */ + { 0x0a, 0x400000f0 }, + { 0x0b, 0x90100120 }, /* speaker */ + { 0x0c, 0x400000f0 }, + { 0x0d, 0x90a00110 }, /* mic */ + { 0x0e, 0x400000f0 }, + { 0x0f, 0x400000f0 }, + { 0x10, 0x400000f0 }, + { 0x12, 0x400000f0 }, + { 0x15, 0x400000f0 }, + {} /* terminator */ +}; + static void cs420x_fixup_gpio_13(struct hda_codec *codec, const struct hda_fixup *fix, int action) { @@ -482,6 +499,12 @@ static const struct hda_fixup cs420x_fixups[] = { .chained = true, .chain_id = CS420X_GPIO_13, }, + [CS420X_MBA42] = { + .type = HDA_FIXUP_PINS, + .v.pins = mba42_pincfgs, + .chained = true, + .chain_id = CS420X_GPIO_13, + }, }; static struct cs_spec *cs_alloc_spec(struct hda_codec *codec, int vendor_nid) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 59d2e91a9ab6..403010c9e82e 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -3483,6 +3483,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1028, 0x05ca, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x05cb, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x05de, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x05e0, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x05e9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x05ea, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x05eb, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), @@ -3493,6 +3494,10 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1028, 0x05f4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x05f5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x05f8, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x0606, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x0608, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x0609, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x1973, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), @@ -3530,6 +3535,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK), SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK), SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK), + SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK), SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK), SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K), SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), @@ -3593,6 +3599,8 @@ static const struct hda_model_fixup alc269_fixup_models[] = { {.id = ALC269_FIXUP_INV_DMIC, .name = "inv-dmic"}, {.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"}, {.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"}, + {.id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "dell-headset-multi"}, + {.id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "dell-headset-dock"}, {} }; @@ -4272,6 +4280,7 @@ static const struct hda_model_fixup alc662_fixup_models[] = { {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"}, {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"}, {.id = ALC662_FIXUP_INV_DMIC, .name = "inv-dmic"}, + {.id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE, .name = "dell-headset-multi"}, {} }; diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index e0dadcf2030d..e5245544eb52 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -136,6 +136,7 @@ static struct via_spec *via_new_spec(struct hda_codec *codec) spec->codec_type = VT1708S; spec->no_pin_power_ctl = 1; spec->gen.indep_hp = 1; + spec->gen.keep_eapd_on = 1; spec->gen.pcm_playback_hook = via_playback_pcm_hook; return spec; } @@ -231,9 +232,14 @@ static void vt1708_update_hp_work(struct hda_codec *codec) static void set_widgets_power_state(struct hda_codec *codec) { +#if 0 /* FIXME: the assumed connections don't match always with the + * actual routes by the generic parser, so better to disable + * the control for safety. + */ struct via_spec *spec = codec->spec; if (spec->set_widgets_power_state) spec->set_widgets_power_state(codec); +#endif } static void update_power_state(struct hda_codec *codec, hda_nid_t nid, @@ -478,7 +484,9 @@ static int via_suspend(struct hda_codec *codec) /* Fix pop noise on headphones */ int i; for (i = 0; i < spec->gen.autocfg.hp_outs; i++) - snd_hda_set_pin_ctl(codec, spec->gen.autocfg.hp_pins[i], 0); + snd_hda_codec_write(codec, spec->gen.autocfg.hp_pins[i], + 0, AC_VERB_SET_PIN_WIDGET_CONTROL, + 0x00); } return 0; diff --git a/sound/pci/sis7019.c b/sound/pci/sis7019.c index d59abe1682c5..748e82d4d257 100644 --- a/sound/pci/sis7019.c +++ b/sound/pci/sis7019.c @@ -1341,7 +1341,8 @@ static int sis_chip_create(struct snd_card *card, if (rc) goto error_out; - if (pci_set_dma_mask(pci, DMA_BIT_MASK(30)) < 0) { + rc = pci_set_dma_mask(pci, DMA_BIT_MASK(30)); + if (rc < 0) { dev_err(&pci->dev, "architecture does not support 30-bit PCI busmaster DMA"); goto error_out_enabled; } diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c index 0f6f481cec09..987f728718c5 100644 --- a/sound/soc/codecs/cs42l52.c +++ b/sound/soc/codecs/cs42l52.c @@ -86,7 +86,7 @@ static const struct reg_default cs42l52_reg_defaults[] = { { CS42L52_BEEP_VOL, 0x00 }, /* r1D Beep Volume off Time */ { CS42L52_BEEP_TONE_CTL, 0x00 }, /* r1E Beep Tone Cfg. */ { CS42L52_TONE_CTL, 0x00 }, /* r1F Tone Ctl */ - { CS42L52_MASTERA_VOL, 0x88 }, /* r20 Master A Volume */ + { CS42L52_MASTERA_VOL, 0x00 }, /* r20 Master A Volume */ { CS42L52_MASTERB_VOL, 0x00 }, /* r21 Master B Volume */ { CS42L52_HPA_VOL, 0x00 }, /* r22 Headphone A Volume */ { CS42L52_HPB_VOL, 0x00 }, /* r23 Headphone B Volume */ @@ -193,6 +193,8 @@ static DECLARE_TLV_DB_SCALE(mic_tlv, 1600, 100, 0); static DECLARE_TLV_DB_SCALE(pga_tlv, -600, 50, 0); +static DECLARE_TLV_DB_SCALE(mix_tlv, -50, 50, 0); + static const unsigned int limiter_tlv[] = { TLV_DB_RANGE_HEAD(2), 0, 2, TLV_DB_SCALE_ITEM(-3000, 600, 0), @@ -225,7 +227,7 @@ static const char * const mic_bias_level_text[] = { }; static const struct soc_enum mic_bias_level_enum = - SOC_ENUM_SINGLE(CS42L52_IFACE_CTL1, 0, + SOC_ENUM_SINGLE(CS42L52_IFACE_CTL2, 0, ARRAY_SIZE(mic_bias_level_text), mic_bias_level_text); static const char * const cs42l52_mic_text[] = { "Single", "Differential" }; @@ -260,7 +262,7 @@ static const char * const hp_gain_num_text[] = { }; static const struct soc_enum hp_gain_enum = - SOC_ENUM_SINGLE(CS42L52_PB_CTL1, 4, + SOC_ENUM_SINGLE(CS42L52_PB_CTL1, 5, ARRAY_SIZE(hp_gain_num_text), hp_gain_num_text); static const char * const beep_pitch_text[] = { @@ -413,7 +415,7 @@ static const struct snd_kcontrol_new cs42l52_snd_controls[] = { SOC_ENUM("Headphone Analog Gain", hp_gain_enum), SOC_DOUBLE_R_SX_TLV("Speaker Volume", CS42L52_SPKA_VOL, - CS42L52_SPKB_VOL, 7, 0x1, 0xff, hl_tlv), + CS42L52_SPKB_VOL, 0, 0x1, 0xff, hl_tlv), SOC_DOUBLE_R_SX_TLV("Bypass Volume", CS42L52_PASSTHRUA_VOL, CS42L52_PASSTHRUB_VOL, 6, 0x18, 0x90, pga_tlv), @@ -441,7 +443,7 @@ static const struct snd_kcontrol_new cs42l52_snd_controls[] = { SOC_DOUBLE_R_SX_TLV("PCM Mixer Volume", CS42L52_PCMA_MIXER_VOL, CS42L52_PCMB_MIXER_VOL, - 6, 0x7f, 0x19, hl_tlv), + 0, 0x7f, 0x19, mix_tlv), SOC_DOUBLE_R("PCM Mixer Switch", CS42L52_PCMA_MIXER_VOL, CS42L52_PCMB_MIXER_VOL, 7, 1, 1), diff --git a/sound/soc/codecs/cs42l52.h b/sound/soc/codecs/cs42l52.h index 60985c059071..4277012c4719 100644 --- a/sound/soc/codecs/cs42l52.h +++ b/sound/soc/codecs/cs42l52.h @@ -157,7 +157,7 @@ #define CS42L52_PB_CTL1_INV_PCMA (1 << 2) #define CS42L52_PB_CTL1_MSTB_MUTE (1 << 1) #define CS42L52_PB_CTL1_MSTA_MUTE (1 << 0) -#define CS42L52_PB_CTL1_MUTE_MASK 0xFFFD +#define CS42L52_PB_CTL1_MUTE_MASK 0x03 #define CS42L52_PB_CTL1_MUTE 3 #define CS42L52_PB_CTL1_UNMUTE 0 diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c index ce0d36412c97..8d14a76c7249 100644 --- a/sound/soc/codecs/max98090.c +++ b/sound/soc/codecs/max98090.c @@ -2233,7 +2233,7 @@ static int max98090_probe(struct snd_soc_codec *codec) dev_dbg(codec->dev, "irq = %d\n", max98090->irq); ret = request_threaded_irq(max98090->irq, NULL, - max98090_interrupt, IRQF_TRIGGER_FALLING, + max98090_interrupt, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "max98090_interrupt", codec); if (ret < 0) { dev_err(codec->dev, "request_irq failed: %d\n", diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 65d09d60b7c6..1514bf845e4b 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -187,14 +187,14 @@ static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol, break; } - - if (found) - snd_soc_dapm_sync(widget->dapm); } - ret = snd_soc_update_bits(widget->codec, reg, val_mask, val); - mutex_unlock(&widget->codec->mutex); + + if (found) + snd_soc_dapm_sync(widget->dapm); + + ret = snd_soc_update_bits_locked(widget->codec, reg, val_mask, val); return ret; } diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index e895d3939eef..100fdadda56a 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -1120,7 +1120,8 @@ SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0, ARIZONA_DSP_WIDGETS(DSP1, "DSP1"), SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1, - ARIZONA_AEC_LOOPBACK_ENA, 0, &wm5102_aec_loopback_mux), + ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0, + &wm5102_aec_loopback_mux), SND_SOC_DAPM_PGA_E("OUT1L", SND_SOC_NOPM, ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev, diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index 731884e04776..88ad7db52dde 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c @@ -190,7 +190,7 @@ ARIZONA_MIXER_CONTROLS("DSP2R", ARIZONA_DSP2RMIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("DSP3L", ARIZONA_DSP3LMIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("DSP3R", ARIZONA_DSP3RMIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("DSP4L", ARIZONA_DSP4LMIX_INPUT_1_SOURCE), -ARIZONA_MIXER_CONTROLS("DSP5R", ARIZONA_DSP4RMIX_INPUT_1_SOURCE), +ARIZONA_MIXER_CONTROLS("DSP4R", ARIZONA_DSP4RMIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("Mic", ARIZONA_MICMIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("Noise", ARIZONA_NOISEMIX_INPUT_1_SOURCE), @@ -503,7 +503,8 @@ SND_SOC_DAPM_PGA("ASRC2R", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC2R_ENA_SHIFT, 0, NULL, 0), SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1, - ARIZONA_AEC_LOOPBACK_ENA, 0, &wm5110_aec_loopback_mux), + ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0, + &wm5110_aec_loopback_mux), SND_SOC_DAPM_AIF_OUT("AIF1TX1", NULL, 0, ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX1_ENA_SHIFT, 0), @@ -976,6 +977,8 @@ static int wm5110_codec_probe(struct snd_soc_codec *codec) if (ret != 0) return ret; + arizona_init_spk(codec); + snd_soc_dapm_disable_pin(&codec->dapm, "HAPTICS"); priv->core.arizona->dapm = &codec->dapm; diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 1eb152cb1097..29e95f93d482 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -383,6 +383,8 @@ static int wm8994_get_drc_enum(struct snd_kcontrol *kcontrol, struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); int drc = wm8994_get_drc(kcontrol->id.name); + if (drc < 0) + return drc; ucontrol->value.enumerated.item[0] = wm8994->drc_cfg[drc]; return 0; @@ -488,6 +490,9 @@ static int wm8994_get_retune_mobile_enum(struct snd_kcontrol *kcontrol, struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); int block = wm8994_get_retune_mobile_block(kcontrol->id.name); + if (block < 0) + return block; + ucontrol->value.enumerated.item[0] = wm8994->retune_mobile_cfg[block]; return 0; @@ -1031,7 +1036,7 @@ static int aif1clk_ev(struct snd_soc_dapm_widget *w, { struct snd_soc_codec *codec = w->codec; struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); - struct wm8994 *control = codec->control_data; + struct wm8994 *control = wm8994->wm8994; int mask = WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA; int i; int dac; @@ -3831,8 +3836,14 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data) ret); } else if (!(ret & WM1811_JACKDET_LVL)) { dev_dbg(codec->dev, "Ignoring removed jack\n"); - return IRQ_HANDLED; + goto out; } + } else if (!(reg & WM8958_MICD_STS)) { + snd_soc_jack_report(wm8994->micdet[0].jack, 0, + SND_JACK_MECHANICAL | SND_JACK_HEADSET | + wm8994->btn_mask); + wm8994->mic_detecting = true; + goto out; } if (wm8994->mic_detecting) diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 56ecfc72f2e9..81490febac6d 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -631,7 +631,8 @@ static int davinci_config_channel_size(struct davinci_audio_dev *dev, int word_length) { u32 fmt; - u32 rotate = (word_length / 4) & 0x7; + u32 tx_rotate = (word_length / 4) & 0x7; + u32 rx_rotate = (32 - word_length) / 4; u32 mask = (1ULL << word_length) - 1; /* @@ -655,9 +656,9 @@ static int davinci_config_channel_size(struct davinci_audio_dev *dev, mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, TXSSZ(fmt), TXSSZ(0x0F)); mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, - TXROT(rotate), TXROT(7)); + TXROT(tx_rotate), TXROT(7)); mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMT_REG, - RXROT(rotate), RXROT(7)); + RXROT(rx_rotate), RXROT(7)); mcasp_set_reg(dev->base + DAVINCI_MCASP_RXMASK_REG, mask); } diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c index 3853f7eb3f28..06a8000aa07b 100644 --- a/sound/soc/soc-compress.c +++ b/sound/soc/soc-compress.c @@ -220,8 +220,12 @@ static int soc_compr_set_params(struct snd_compr_stream *cstream, goto err; } - snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK, - SND_SOC_DAPM_STREAM_START); + if (cstream->direction == SND_COMPRESS_PLAYBACK) + snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK, + SND_SOC_DAPM_STREAM_START); + else + snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_CAPTURE, + SND_SOC_DAPM_STREAM_START); /* cancel any delayed stream shutdown that is pending */ rtd->pop_wait = 0; diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index a80c883bb8be..c7051c457b75 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -55,7 +55,8 @@ static int dapm_up_seq[] = { [snd_soc_dapm_clock_supply] = 1, [snd_soc_dapm_micbias] = 2, [snd_soc_dapm_dai_link] = 2, - [snd_soc_dapm_dai] = 3, + [snd_soc_dapm_dai_in] = 3, + [snd_soc_dapm_dai_out] = 3, [snd_soc_dapm_aif_in] = 3, [snd_soc_dapm_aif_out] = 3, [snd_soc_dapm_mic] = 4, @@ -92,7 +93,8 @@ static int dapm_down_seq[] = { [snd_soc_dapm_value_mux] = 9, [snd_soc_dapm_aif_in] = 10, [snd_soc_dapm_aif_out] = 10, - [snd_soc_dapm_dai] = 10, + [snd_soc_dapm_dai_in] = 10, + [snd_soc_dapm_dai_out] = 10, [snd_soc_dapm_dai_link] = 11, [snd_soc_dapm_clock_supply] = 12, [snd_soc_dapm_regulator_supply] = 12, @@ -419,7 +421,8 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w, case snd_soc_dapm_clock_supply: case snd_soc_dapm_aif_in: case snd_soc_dapm_aif_out: - case snd_soc_dapm_dai: + case snd_soc_dapm_dai_in: + case snd_soc_dapm_dai_out: case snd_soc_dapm_hp: case snd_soc_dapm_mic: case snd_soc_dapm_spk: @@ -820,7 +823,7 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget, switch (widget->id) { case snd_soc_dapm_adc: case snd_soc_dapm_aif_out: - case snd_soc_dapm_dai: + case snd_soc_dapm_dai_out: if (widget->active) { widget->outputs = snd_soc_dapm_suspend_check(widget); return widget->outputs; @@ -916,7 +919,7 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget, switch (widget->id) { case snd_soc_dapm_dac: case snd_soc_dapm_aif_in: - case snd_soc_dapm_dai: + case snd_soc_dapm_dai_in: if (widget->active) { widget->inputs = snd_soc_dapm_suspend_check(widget); return widget->inputs; @@ -1135,16 +1138,6 @@ static int dapm_generic_check_power(struct snd_soc_dapm_widget *w) return out != 0 && in != 0; } -static int dapm_dai_check_power(struct snd_soc_dapm_widget *w) -{ - DAPM_UPDATE_STAT(w, power_checks); - - if (w->active) - return w->active; - - return dapm_generic_check_power(w); -} - /* Check to see if an ADC has power */ static int dapm_adc_check_power(struct snd_soc_dapm_widget *w) { @@ -2318,7 +2311,8 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm, case snd_soc_dapm_clock_supply: case snd_soc_dapm_aif_in: case snd_soc_dapm_aif_out: - case snd_soc_dapm_dai: + case snd_soc_dapm_dai_in: + case snd_soc_dapm_dai_out: case snd_soc_dapm_dai_link: list_add(&path->list, &dapm->card->paths); list_add(&path->list_sink, &wsink->sources); @@ -3129,10 +3123,12 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, break; case snd_soc_dapm_adc: case snd_soc_dapm_aif_out: + case snd_soc_dapm_dai_out: w->power_check = dapm_adc_check_power; break; case snd_soc_dapm_dac: case snd_soc_dapm_aif_in: + case snd_soc_dapm_dai_in: w->power_check = dapm_dac_check_power; break; case snd_soc_dapm_pga: @@ -3152,9 +3148,6 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, case snd_soc_dapm_clock_supply: w->power_check = dapm_supply_check_power; break; - case snd_soc_dapm_dai: - w->power_check = dapm_dai_check_power; - break; default: w->power_check = dapm_always_on_check_power; break; @@ -3375,7 +3368,7 @@ int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm, template.reg = SND_SOC_NOPM; if (dai->driver->playback.stream_name) { - template.id = snd_soc_dapm_dai; + template.id = snd_soc_dapm_dai_in; template.name = dai->driver->playback.stream_name; template.sname = dai->driver->playback.stream_name; @@ -3393,7 +3386,7 @@ int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm, } if (dai->driver->capture.stream_name) { - template.id = snd_soc_dapm_dai; + template.id = snd_soc_dapm_dai_out; template.name = dai->driver->capture.stream_name; template.sname = dai->driver->capture.stream_name; @@ -3423,8 +3416,13 @@ int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card) /* For each DAI widget... */ list_for_each_entry(dai_w, &card->widgets, list) { - if (dai_w->id != snd_soc_dapm_dai) + switch (dai_w->id) { + case snd_soc_dapm_dai_in: + case snd_soc_dapm_dai_out: + break; + default: continue; + } dai = dai_w->priv; @@ -3433,8 +3431,13 @@ int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card) if (w->dapm != dai_w->dapm) continue; - if (w->id == snd_soc_dapm_dai) + switch (w->id) { + case snd_soc_dapm_dai_in: + case snd_soc_dapm_dai_out: continue; + default: + break; + } if (!w->sname) continue; diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 73bb8eefa491..ccb6be4d658d 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -928,8 +928,13 @@ static int dpcm_add_paths(struct snd_soc_pcm_runtime *fe, int stream, /* Create any new FE <--> BE connections */ for (i = 0; i < list->num_widgets; i++) { - if (list->widgets[i]->id != snd_soc_dapm_dai) + switch (list->widgets[i]->id) { + case snd_soc_dapm_dai_in: + case snd_soc_dapm_dai_out: + break; + default: continue; + } /* is there a valid BE rtd for this widget */ be = dpcm_get_be(card, list->widgets[i], stream); @@ -2011,9 +2016,11 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) if (cpu_dai->driver->capture.channels_min) capture = 1; } else { - if (codec_dai->driver->playback.channels_min) + if (codec_dai->driver->playback.channels_min && + cpu_dai->driver->playback.channels_min) playback = 1; - if (codec_dai->driver->capture.channels_min) + if (codec_dai->driver->capture.channels_min && + cpu_dai->driver->capture.channels_min) capture = 1; } diff --git a/sound/usb/6fire/firmware.c b/sound/usb/6fire/firmware.c index a1d9b0792a1e..b9defcdeb7ef 100644 --- a/sound/usb/6fire/firmware.c +++ b/sound/usb/6fire/firmware.c @@ -42,8 +42,8 @@ static const u8 ep_w_max_packet_size[] = { 0x94, 0x01, 0x5c, 0x02 /* alt 3: 404 EP2 and 604 EP6 (25 fpp) */ }; -static const u8 known_fw_versions[][4] = { - { 0x03, 0x01, 0x0b, 0x00 } +static const u8 known_fw_versions[][2] = { + { 0x03, 0x01 } }; struct ihex_record { @@ -343,7 +343,7 @@ static int usb6fire_fw_check(u8 *version) int i; for (i = 0; i < ARRAY_SIZE(known_fw_versions); i++) - if (!memcmp(version, known_fw_versions + i, 4)) + if (!memcmp(version, known_fw_versions + i, 2)) return 0; snd_printk(KERN_ERR PREFIX "invalid fimware version in device: %*ph. " diff --git a/sound/usb/card.c b/sound/usb/card.c index 1a033177b83f..64952e2d3ed1 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c @@ -147,14 +147,32 @@ static int snd_usb_create_stream(struct snd_usb_audio *chip, int ctrlif, int int return -EINVAL; } + alts = &iface->altsetting[0]; + altsd = get_iface_desc(alts); + + /* + * Android with both accessory and audio interfaces enabled gets the + * interface numbers wrong. + */ + if ((chip->usb_id == USB_ID(0x18d1, 0x2d04) || + chip->usb_id == USB_ID(0x18d1, 0x2d05)) && + interface == 0 && + altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC && + altsd->bInterfaceSubClass == USB_SUBCLASS_VENDOR_SPEC) { + interface = 2; + iface = usb_ifnum_to_if(dev, interface); + if (!iface) + return -EINVAL; + alts = &iface->altsetting[0]; + altsd = get_iface_desc(alts); + } + if (usb_interface_claimed(iface)) { snd_printdd(KERN_INFO "%d:%d:%d: skipping, already claimed\n", dev->devnum, ctrlif, interface); return -EINVAL; } - alts = &iface->altsetting[0]; - altsd = get_iface_desc(alts); if ((altsd->bInterfaceClass == USB_CLASS_AUDIO || altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC) && altsd->bInterfaceSubClass == USB_SUBCLASS_MIDISTREAMING) { diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index ca4739c3f650..d5438083fd6a 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -885,7 +885,9 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval, case USB_ID(0x046d, 0x0808): case USB_ID(0x046d, 0x0809): + case USB_ID(0x046d, 0x081b): /* HD Webcam c310 */ case USB_ID(0x046d, 0x081d): /* HD Webcam c510 */ + case USB_ID(0x046d, 0x0825): /* HD Webcam c270 */ case USB_ID(0x046d, 0x0991): /* Most audio usb devices lie about volume resolution. * Most Logitech webcams have res = 384. diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index 7f1722f82c89..8b75bcf136f6 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h @@ -215,7 +215,13 @@ .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL }, { - USB_DEVICE(0x046d, 0x0990), + .match_flags = USB_DEVICE_ID_MATCH_DEVICE | + USB_DEVICE_ID_MATCH_INT_CLASS | + USB_DEVICE_ID_MATCH_INT_SUBCLASS, + .idVendor = 0x046d, + .idProduct = 0x0990, + .bInterfaceClass = USB_CLASS_AUDIO, + .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL, .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { .vendor_name = "Logitech, Inc.", .product_name = "QuickCam Pro 9000", @@ -1792,7 +1798,11 @@ YAMAHA_DEVICE(0x7010, "UB99"), USB_DEVICE_VENDOR_SPEC(0x0582, 0x0108), .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { .ifnum = 0, - .type = QUIRK_MIDI_STANDARD_INTERFACE + .type = QUIRK_MIDI_FIXED_ENDPOINT, + .data = & (const struct snd_usb_midi_endpoint_info) { + .out_cables = 0x0007, + .in_cables = 0x0007 + } } }, { diff --git a/tools/perf/scripts/python/net_dropmonitor.py b/tools/perf/scripts/python/net_dropmonitor.py index a4ffc9500023..b5740599aabd 100755 --- a/tools/perf/scripts/python/net_dropmonitor.py +++ b/tools/perf/scripts/python/net_dropmonitor.py @@ -15,35 +15,38 @@ kallsyms = [] def get_kallsyms_table(): global kallsyms + try: f = open("/proc/kallsyms", "r") - linecount = 0 - for line in f: - linecount = linecount+1 - f.seek(0) except: return - - j = 0 for line in f: loc = int(line.split()[0], 16) name = line.split()[2] - j = j +1 - if ((j % 100) == 0): - print "\r" + str(j) + "/" + str(linecount), - kallsyms.append({ 'loc': loc, 'name' : name}) - - print "\r" + str(j) + "/" + str(linecount) + kallsyms.append((loc, name)) kallsyms.sort() - return def get_sym(sloc): loc = int(sloc) - for i in kallsyms: - if (i['loc'] >= loc): - return (i['name'], i['loc']-loc) - return (None, 0) + + # Invariant: kallsyms[i][0] <= loc for all 0 <= i <= start + # kallsyms[i][0] > loc for all end <= i < len(kallsyms) + start, end = -1, len(kallsyms) + while end != start + 1: + pivot = (start + end) // 2 + if loc < kallsyms[pivot][0]: + end = pivot + else: + start = pivot + + # Now (start == -1 or kallsyms[start][0] <= loc) + # and (start == len(kallsyms) - 1 or loc < kallsyms[start + 1][0]) + if start >= 0: + symloc, name = kallsyms[start] + return (name, loc - symloc) + else: + return (None, 0) def print_drop_table(): print "%25s %25s %25s" % ("LOCATION", "OFFSET", "COUNT") @@ -64,7 +67,7 @@ def trace_end(): # called from perf, when it finds a correspoinding event def skb__kfree_skb(name, context, cpu, sec, nsec, pid, comm, - skbaddr, protocol, location): + skbaddr, location, protocol): slocation = str(location) try: drop_log[slocation] = drop_log[slocation] + 1 diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 9e9d34871195..fe702076ca46 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -2191,7 +2191,7 @@ int initialize_counters(int cpu_id) void allocate_output_buffer() { - output_buffer = calloc(1, (1 + topo.num_cpus) * 128); + output_buffer = calloc(1, (1 + topo.num_cpus) * 256); outp = output_buffer; if (outp == NULL) { perror("calloc"); diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index d4abc59ce1d9..0a63658065f0 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@ -6,7 +6,6 @@ TARGETS += memory-hotplug TARGETS += mqueue TARGETS += net TARGETS += ptrace -TARGETS += soft-dirty TARGETS += vm all: diff --git a/tools/testing/selftests/soft-dirty/Makefile b/tools/testing/selftests/soft-dirty/Makefile deleted file mode 100644 index a9cdc823d6e0..000000000000 --- a/tools/testing/selftests/soft-dirty/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -CFLAGS += -iquote../../../../include/uapi -Wall -soft-dirty: soft-dirty.c - -all: soft-dirty - -clean: - rm -f soft-dirty - -run_tests: all - @./soft-dirty || echo "soft-dirty selftests: [FAIL]" diff --git a/tools/testing/selftests/soft-dirty/soft-dirty.c b/tools/testing/selftests/soft-dirty/soft-dirty.c deleted file mode 100644 index aba4f87f87f0..000000000000 --- a/tools/testing/selftests/soft-dirty/soft-dirty.c +++ /dev/null @@ -1,114 +0,0 @@ -#include <stdlib.h> -#include <stdio.h> -#include <sys/mman.h> -#include <unistd.h> -#include <fcntl.h> -#include <sys/types.h> - -typedef unsigned long long u64; - -#define PME_PRESENT (1ULL << 63) -#define PME_SOFT_DIRTY (1Ull << 55) - -#define PAGES_TO_TEST 3 -#ifndef PAGE_SIZE -#define PAGE_SIZE 4096 -#endif - -static void get_pagemap2(char *mem, u64 *map) -{ - int fd; - - fd = open("/proc/self/pagemap2", O_RDONLY); - if (fd < 0) { - perror("Can't open pagemap2"); - exit(1); - } - - lseek(fd, (unsigned long)mem / PAGE_SIZE * sizeof(u64), SEEK_SET); - read(fd, map, sizeof(u64) * PAGES_TO_TEST); - close(fd); -} - -static inline char map_p(u64 map) -{ - return map & PME_PRESENT ? 'p' : '-'; -} - -static inline char map_sd(u64 map) -{ - return map & PME_SOFT_DIRTY ? 'd' : '-'; -} - -static int check_pte(int step, int page, u64 *map, u64 want) -{ - if ((map[page] & want) != want) { - printf("Step %d Page %d has %c%c, want %c%c\n", - step, page, - map_p(map[page]), map_sd(map[page]), - map_p(want), map_sd(want)); - return 1; - } - - return 0; -} - -static void clear_refs(void) -{ - int fd; - char *v = "4"; - - fd = open("/proc/self/clear_refs", O_WRONLY); - if (write(fd, v, 3) < 3) { - perror("Can't clear soft-dirty bit"); - exit(1); - } - close(fd); -} - -int main(void) -{ - char *mem, x; - u64 map[PAGES_TO_TEST]; - - mem = mmap(NULL, PAGES_TO_TEST * PAGE_SIZE, - PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, 0, 0); - - x = mem[0]; - mem[2 * PAGE_SIZE] = 'c'; - get_pagemap2(mem, map); - - if (check_pte(1, 0, map, PME_PRESENT)) - return 1; - if (check_pte(1, 1, map, 0)) - return 1; - if (check_pte(1, 2, map, PME_PRESENT | PME_SOFT_DIRTY)) - return 1; - - clear_refs(); - get_pagemap2(mem, map); - - if (check_pte(2, 0, map, PME_PRESENT)) - return 1; - if (check_pte(2, 1, map, 0)) - return 1; - if (check_pte(2, 2, map, PME_PRESENT)) - return 1; - - mem[0] = 'a'; - mem[PAGE_SIZE] = 'b'; - x = mem[2 * PAGE_SIZE]; - get_pagemap2(mem, map); - - if (check_pte(3, 0, map, PME_PRESENT | PME_SOFT_DIRTY)) - return 1; - if (check_pte(3, 1, map, PME_PRESENT | PME_SOFT_DIRTY)) - return 1; - if (check_pte(3, 2, map, PME_PRESENT)) - return 1; - - (void)x; /* gcc warn */ - - printf("PASS\n"); - return 0; -} |