diff options
author | Thorsten Leemhuis <fedora@leemhuis.info> | 2017-02-16 07:31:07 +0100 |
---|---|---|
committer | Thorsten Leemhuis <fedora@leemhuis.info> | 2017-02-16 07:31:07 +0100 |
commit | 3cb80ea3dcbb09376a71a5fd716de5998ee60780 (patch) | |
tree | 1061bdeb25e23a4494899d337b34e001d88d7468 | |
parent | 7e2af66052bf66472c3028add3f11430977c766c (diff) | |
parent | 716fb36dd76eef374399145580416fb5d995c138 (diff) | |
download | kernel-3cb80ea3dcbb09376a71a5fd716de5998ee60780.tar.gz kernel-3cb80ea3dcbb09376a71a5fd716de5998ee60780.tar.xz kernel-3cb80ea3dcbb09376a71a5fd716de5998ee60780.zip |
fix merge conflictkernel-4.9.10-100.vanilla.knurd.1.fc24
-rw-r--r-- | 0001-sctp-avoid-BUG_ON-on-sctp_wait_for_sndbuf.patch | 39 | ||||
-rw-r--r-- | 0001-x86-efi-always-map-first-physical-page-into-EFI-page.patch | 64 | ||||
-rw-r--r-- | PCI-ASPM-Handle-PCI-to-PCIe-bridges-as-roots-of-PCIe-hierarchies.patch | 90 | ||||
-rw-r--r-- | config-generic | 8 | ||||
-rw-r--r-- | drm-vc4-Fix-OOPSes-from-trying-to-cache-a-partially-constructed-BO..patch | 42 | ||||
-rw-r--r-- | ipv4-keep-skb-dst-around-in-presence-of-IP-options.patch | 47 | ||||
-rw-r--r-- | kernel.spec | 43 | ||||
-rw-r--r-- | sources | 2 | ||||
-rw-r--r-- | w1-ds2490-USB-transfer-buffers-need-to-be-DMAable.patch | 360 |
9 files changed, 528 insertions, 167 deletions
diff --git a/0001-sctp-avoid-BUG_ON-on-sctp_wait_for_sndbuf.patch b/0001-sctp-avoid-BUG_ON-on-sctp_wait_for_sndbuf.patch new file mode 100644 index 000000000..134e1ea39 --- /dev/null +++ b/0001-sctp-avoid-BUG_ON-on-sctp_wait_for_sndbuf.patch @@ -0,0 +1,39 @@ +From 2dcab598484185dea7ec22219c76dcdd59e3cb90 Mon Sep 17 00:00:00 2001 +From: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com> +Date: Mon, 6 Feb 2017 18:10:31 -0200 +Subject: [PATCH] sctp: avoid BUG_ON on sctp_wait_for_sndbuf + +Alexander Popov reported that an application may trigger a BUG_ON in +sctp_wait_for_sndbuf if the socket tx buffer is full, a thread is +waiting on it to queue more data and meanwhile another thread peels off +the association being used by the first thread. + +This patch replaces the BUG_ON call with a proper error handling. It +will return -EPIPE to the original sendmsg call, similarly to what would +have been done if the association wasn't found in the first place. + +Acked-by: Alexander Popov <alex.popov@linux.com> +Signed-off-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com> +Reviewed-by: Xin Long <lucien.xin@gmail.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + net/sctp/socket.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/net/sctp/socket.c b/net/sctp/socket.c +index 37eeab7..e214d2e 100644 +--- a/net/sctp/socket.c ++++ b/net/sctp/socket.c +@@ -7426,7 +7426,8 @@ static int sctp_wait_for_sndbuf(struct sctp_association *asoc, long *timeo_p, + */ + release_sock(sk); + current_timeo = schedule_timeout(current_timeo); +- BUG_ON(sk != asoc->base.sk); ++ if (sk != asoc->base.sk) ++ goto do_error; + lock_sock(sk); + + *timeo_p = current_timeo; +-- +2.9.3 + diff --git a/0001-x86-efi-always-map-first-physical-page-into-EFI-page.patch b/0001-x86-efi-always-map-first-physical-page-into-EFI-page.patch deleted file mode 100644 index 55baf9b52..000000000 --- a/0001-x86-efi-always-map-first-physical-page-into-EFI-page.patch +++ /dev/null @@ -1,64 +0,0 @@ -From fb1d9d3f95654f00c4156129f3cd90d3efe32d26 Mon Sep 17 00:00:00 2001 -From: Jiri Kosina <jkosina@suse.cz> -Date: Wed, 25 Jan 2017 20:52:33 +0100 -Subject: [PATCH] x86/efi: always map first physical page into EFI pagetables - -Commit 129766708 ("x86/efi: Only map RAM into EFI page tables if in -mixed-mode") stopped creating 1:1 mapping for all RAM in case of running -in native 64bit mode. - -It turns out though that there are 64bit EFI implementations in the wild -(this particular problem has been reported on Lenovo Yoga 710-11IKB) which -still make use of first physical page for their own private use (which is -what legacy BIOS used to do, but EFI specification doesn't grant any such -right to EFI BIOS ... oh well). - -In case there is no mapping for this particular frame in EFI pagetables, -as soon as firmware tries to make use of it, triple fault occurs and the -system reboots (in case of Yoga 710-11IKB this is very early during boot). - -Fix that by always mapping the first page of physical memory into EFI -pagetables. - -Note: just reverting 129766708 is not enough on v4.9-rc1+ to fix the -regression on affected hardware, as commit ab72a27da ("x86/efi: -Consolidate region mapping logic") later made the first physical frame not -to be mapped anyway. - -Fixes: 129766708 ("x86/efi: Only map RAM into EFI page tables if in mixed-mode") -Cc: stable@kernel.org # v4.8+ -Cc: Waiman Long <waiman.long@hpe.com> -Cc: Borislav Petkov <bp@suse.de> -Cc: Laura Abbott <labbott@redhat.com> -Cc: Vojtech Pavlik <vojtech@ucw.cz> -Reported-by: Hanka Pavlikova <hanka@ucw.cz> -Signed-off-by: Jiri Kosina <jkosina@suse.cz> ---- - arch/x86/platform/efi/efi_64.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c -index 319148bd4b05..02ae2abe8b8e 100644 ---- a/arch/x86/platform/efi/efi_64.c -+++ b/arch/x86/platform/efi/efi_64.c -@@ -269,6 +269,17 @@ int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages) - efi_scratch.use_pgd = true; - - /* -+ * Certain firmware versions are way too sentimental and still believe -+ * they are exclusive and unquestionable owners of first physical page. -+ * Create 1:1 mapping for this page to avoid triple faults during early -+ * boot with such firmware. -+ */ -+ if (kernel_map_pages_in_pgd(pgd, 0x0, 0x0, 1, _PAGE_RW)) { -+ pr_err("Failed to create 1:1 mapping of first page\n"); -+ return 1; -+ } -+ -+ /* - * When making calls to the firmware everything needs to be 1:1 - * mapped and addressable with 32-bit pointers. Map the kernel - * text and allocate a new stack because we can't rely on the --- -2.11.0 - diff --git a/PCI-ASPM-Handle-PCI-to-PCIe-bridges-as-roots-of-PCIe-hierarchies.patch b/PCI-ASPM-Handle-PCI-to-PCIe-bridges-as-roots-of-PCIe-hierarchies.patch deleted file mode 100644 index a76639e6a..000000000 --- a/PCI-ASPM-Handle-PCI-to-PCIe-bridges-as-roots-of-PCIe-hierarchies.patch +++ /dev/null @@ -1,90 +0,0 @@ -From patchwork Mon Jan 30 15:23:24 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: PCI/ASPM: Handle PCI-to-PCIe bridges as roots of PCIe hierarchies -From: Bjorn Helgaas <bhelgaas@google.com> -X-Patchwork-Id: 9545603 -Message-Id: <20170130152324.32437.37400.stgit@bhelgaas-glaptop.roam.corp.google.com> -To: linux-pci@vger.kernel.org -Cc: Jao Ching Chen <jcchen@pericom.com>, lists@ssl-mail.com, - linux-kernel@vger.kernel.org, Blake Moore <blake.moore@men.de>, - Takashi Iwai <tiwai@suse.com> -Date: Mon, 30 Jan 2017 09:23:24 -0600 - -In a struct pcie_link_state, link->root points to the pcie_link_state of -the root of the PCIe hierarchy. For the topmost link, this points to -itself (link->root = link). For others, we copy the pointer from the -parent (link->root = link->parent->root). - -Previously we recognized that Root Ports originated PCIe hierarchies, but -we treated PCI/PCI-X to PCIe Bridges as being in the middle of the -hierarchy, and when we tried to copy the pointer from link->parent->root, -there was no parent, and we dereferenced a NULL pointer: - - BUG: unable to handle kernel NULL pointer dereference at 0000000000000090 - IP: [<ffffffff9e424350>] pcie_aspm_init_link_state+0x170/0x820 - -Recognize that PCI/PCI-X to PCIe Bridges originate PCIe hierarchies just -like Root Ports do, so link->root for these devices should also point to -itself. - -Fixes: 51ebfc92b72b ("PCI: Enumerate switches below PCI-to-PCIe bridges") -Link: https://bugzilla.kernel.org/show_bug.cgi?id=193411 -Link: https://bugzilla.opensuse.org/show_bug.cgi?id=1022181 -Tested-by: lists@ssl-mail.com -Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> -CC: stable@vger.kernel.org # v4.2+ ---- - drivers/pci/pcie/aspm.c | 19 +++++++++++++------ - 1 file changed, 13 insertions(+), 6 deletions(-) - - --- -To unsubscribe from this list: send the line "unsubscribe linux-pci" in -the body of a message to majordomo@vger.kernel.org -More majordomo info at http://vger.kernel.org/majordomo-info.html - -diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c -index 17ac1dce3286..3dd8bcbb3011 100644 ---- a/drivers/pci/pcie/aspm.c -+++ b/drivers/pci/pcie/aspm.c -@@ -532,25 +532,32 @@ static struct pcie_link_state *alloc_pcie_link_state(struct pci_dev *pdev) - link = kzalloc(sizeof(*link), GFP_KERNEL); - if (!link) - return NULL; -+ - INIT_LIST_HEAD(&link->sibling); - INIT_LIST_HEAD(&link->children); - INIT_LIST_HEAD(&link->link); - link->pdev = pdev; -- if (pci_pcie_type(pdev) != PCI_EXP_TYPE_ROOT_PORT) { -+ -+ /* -+ * Root Ports and PCI/PCI-X to PCIe Bridges are roots of PCIe -+ * hierarchies. -+ */ -+ if (pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT || -+ pci_pcie_type(pdev) == PCI_EXP_TYPE_PCIE_BRIDGE) { -+ link->root = link; -+ } else { - struct pcie_link_state *parent; -+ - parent = pdev->bus->parent->self->link_state; - if (!parent) { - kfree(link); - return NULL; - } -+ - link->parent = parent; -+ link->root = link->parent->root; - list_add(&link->link, &parent->children); - } -- /* Setup a pointer to the root port link */ -- if (!link->parent) -- link->root = link; -- else -- link->root = link->parent->root; - - list_add(&link->sibling, &link_list); - pdev->link_state = link; diff --git a/config-generic b/config-generic index c2859f4ef..4da90f2b1 100644 --- a/config-generic +++ b/config-generic @@ -165,6 +165,9 @@ CONFIG_MMC_MTK=m # CONFIG_MMC_USDHI6ROL0 is not set # CONFIG_MMC_SDHCI_OF_ESDHC is not set +CONFIG_PWRSEQ_EMMC=m +CONFIG_PWRSEQ_SIMPLE=m + CONFIG_CB710_CORE=m # CONFIG_CB710_DEBUG is not set @@ -5537,7 +5540,7 @@ CONFIG_NO_HZ=y # CONFIG_SCHED_STACK_END_CHECK is not set # CONFIG_DEBUG_TIMEKEEPING is not set -CONFIG_TIMER_STATS=y +# CONFIG_TIMER_STATS is not set CONFIG_HIGH_RES_TIMERS=y CONFIG_PERF_EVENTS=y @@ -6057,9 +6060,6 @@ CONFIG_SYSTEM_BLACKLIST_KEYRING=y # CONFIG_COMMON_CLK_SI514 is not set # CONFIG_CLK_QORIQ is not set -# CONFIG_PWRSEQ_EMMC is not set -# CONFIG_PWRSEQ_SIMPLE is not set - # The kernel code has a nice comment # WARNING: Do not even assume this interface is staying stable! # CONFIG_MCE_AMD_INJ is not set diff --git a/drm-vc4-Fix-OOPSes-from-trying-to-cache-a-partially-constructed-BO..patch b/drm-vc4-Fix-OOPSes-from-trying-to-cache-a-partially-constructed-BO..patch new file mode 100644 index 000000000..70a528253 --- /dev/null +++ b/drm-vc4-Fix-OOPSes-from-trying-to-cache-a-partially-constructed-BO..patch @@ -0,0 +1,42 @@ +From patchwork Thu Feb 9 18:16:00 2017 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: drm/vc4: Fix OOPSes from trying to cache a partially constructed BO. +From: Eric Anholt <eric@anholt.net> +X-Patchwork-Id: 138087 +Message-Id: <20170209181600.24048-1-eric@anholt.net> +To: dri-devel@lists.freedesktop.org +Cc: linux-kernel@vger.kernel.org, pbrobinson@gmail.com +Date: Thu, 9 Feb 2017 10:16:00 -0800 + +If a CMA allocation failed, the partially constructed BO would be +unreferenced through the normal path, and we might choose to put it in +the BO cache. If we then reused it before it expired from the cache, +the kernel would OOPS. + +Signed-off-by: Eric Anholt <eric@anholt.net> +Fixes: c826a6e10644 ("drm/vc4: Add a BO cache.") +--- + drivers/gpu/drm/vc4/vc4_bo.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c +index 5ec14f25625d..fd83a2807656 100644 +--- a/drivers/gpu/drm/vc4/vc4_bo.c ++++ b/drivers/gpu/drm/vc4/vc4_bo.c +@@ -314,6 +314,14 @@ void vc4_free_object(struct drm_gem_object *gem_bo) + goto out; + } + ++ /* If this object was partially constructed but CMA allocation ++ * had failed, just free it. ++ */ ++ if (!bo->base.vaddr) { ++ vc4_bo_destroy(bo); ++ goto out; ++ } ++ + cache_list = vc4_get_cache_list_for_size(dev, gem_bo->size); + if (!cache_list) { + vc4_bo_destroy(bo); diff --git a/ipv4-keep-skb-dst-around-in-presence-of-IP-options.patch b/ipv4-keep-skb-dst-around-in-presence-of-IP-options.patch new file mode 100644 index 000000000..821e3fce8 --- /dev/null +++ b/ipv4-keep-skb-dst-around-in-presence-of-IP-options.patch @@ -0,0 +1,47 @@ +From 34b2cef20f19c87999fff3da4071e66937db9644 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet <edumazet@google.com> +Date: Sat, 4 Feb 2017 11:16:52 -0800 +Subject: [PATCH] ipv4: keep skb->dst around in presence of IP options + +Andrey Konovalov got crashes in __ip_options_echo() when a NULL skb->dst +is accessed. + +ipv4_pktinfo_prepare() should not drop the dst if (evil) IP options +are present. + +We could refine the test to the presence of ts_needtime or srr, +but IP options are not often used, so let's be conservative. + +Thanks to syzkaller team for finding this bug. + +Fixes: d826eb14ecef ("ipv4: PKTINFO doesnt need dst reference") +Signed-off-by: Eric Dumazet <edumazet@google.com> +Reported-by: Andrey Konovalov <andreyknvl@google.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + net/ipv4/ip_sockglue.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c +index 53ae0c6..9000117 100644 +--- a/net/ipv4/ip_sockglue.c ++++ b/net/ipv4/ip_sockglue.c +@@ -1238,7 +1238,14 @@ void ipv4_pktinfo_prepare(const struct sock *sk, struct sk_buff *skb) + pktinfo->ipi_ifindex = 0; + pktinfo->ipi_spec_dst.s_addr = 0; + } +- skb_dst_drop(skb); ++ /* We need to keep the dst for __ip_options_echo() ++ * We could restrict the test to opt.ts_needtime || opt.srr, ++ * but the following is good enough as IP options are not often used. ++ */ ++ if (unlikely(IPCB(skb)->opt.optlen)) ++ skb_dst_force(skb); ++ else ++ skb_dst_drop(skb); + } + + int ip_setsockopt(struct sock *sk, int level, +-- +2.9.3 + diff --git a/kernel.spec b/kernel.spec index 5c7e93875..f2400e598 100644 --- a/kernel.spec +++ b/kernel.spec @@ -44,7 +44,7 @@ Summary: The Linux kernel # For non-released -rc kernels, this will be appended after the rcX and # gitX tags, so a 3 here would become part of release "0.rcX.gitX.3" # -%global baserelease 101 +%global baserelease 100 %global fedora_build %{baserelease} # base_sublevel is the kernel version we're starting with and patching @@ -59,7 +59,7 @@ Summary: The Linux kernel # Do we have a -stable update to apply? -%define stable_update 9 +%define stable_update 10 # Set rpm version accordingly %if 0%{?stable_update} %define stablerev %{stable_update} @@ -542,6 +542,8 @@ Patch430: ARM-tegra-usb-no-reset.patch Patch431: bcm2837-initial-support.patch +Patch432: drm-vc4-Fix-OOPSes-from-trying-to-cache-a-partially-constructed-BO..patch + # http://www.spinics.net/lists/linux-mmc/msg41151.html Patch433: bcm283x-mmc-imp-speed.patch @@ -649,15 +651,9 @@ Patch851: selinux-namespace-fix.patch #rhbz 1390308 Patch852: nouveau-add-maxwell-to-backlight-init.patch -#The saddest EFI firmware bug -Patch854: 0001-x86-efi-always-map-first-physical-page-into-EFI-page.patch - #CVE-2017-2596 rhbz 1417812 1417813 Patch855: kvm-fix-page-struct-leak-in-handle_vmon.patch -# rhbz 1418858 -Patch856: PCI-ASPM-Handle-PCI-to-PCIe-bridges-as-roots-of-PCIe-hierarchies.patch - #CVE-2017-5897 rhbz 1419848 1419851 Patch857: ip6_gre-fix-ip6gre_err-invalid-reads.patch @@ -665,6 +661,15 @@ Patch857: ip6_gre-fix-ip6gre_err-invalid-reads.patch Patch858: 1-2-media-cxusb-Use-a-dma-capable-buffer-also-for-reading.patch Patch859: 2-2-media-dvb-usb-firmware-don-t-do-DMA-on-stack.patch +#rhbz 1420276 +Patch860: 0001-sctp-avoid-BUG_ON-on-sctp_wait_for_sndbuf.patch + +#rhbz 1415397 +Patch861: w1-ds2490-USB-transfer-buffers-need-to-be-DMAable.patch + +#CVE-2017-5970 rhbz 1421638 +Patch862: ipv4-keep-skb-dst-around-in-presence-of-IP-options.patch + # END OF PATCH DEFINITIONS %endif @@ -2197,6 +2202,28 @@ fi # # %changelog +* Wed Feb 15 2017 Peter Robinson <pbrobinson@fedoraproject.org> +- Enable PWRSEQ_SIMPLE module (fixes rhbz 1377816) + +* Wed Feb 15 2017 Justin M. Forbes <jforbes@fedoraproject.org> - 4.9.10-100 +- Linux v4.9.10 + +* Tue Feb 14 2017 Justin M. Forbes <jforbes@fedoraproject.org> +- CVE-2017-5967 Disable CONFIG_TIMER_STATS (rhbz 1422138 1422140) + +* Mon Feb 13 2017 Justin M. Forbes <jforbes@fedoraproject.org> +- CVE-2017-5970 keep skb->dst around in presence of IP options (rhbz 1421638) + +* Thu Feb 9 2017 Peter Robinson <pbrobinson@fedoraproject.org> +- Fix OOPSes in vc4 (Raspberry Pi) + +* Thu Feb 09 2017 Laura Abbott <labbott@fedoraproject.org> - 4.9.9-100 +- Linux v4.9.9 +- Fix DMA on stack from 1-wire driver (rhbz 1415397) + +* Thu Feb 9 2017 Justin M. Forbes <jforbes@fedoraproject.org> +- sctp: avoid BUG_ON on sctp_wait_for_sndbuf (rhbz 1420276) + * Tue Feb 7 2017 Laura Abbott <labbott@fedoraproject.org> - Fix for some DMA on stack with DVB devices (rhbz 1417829) - Enable CONFIG_SENSORS_JC42 (rhbz 1417454) @@ -1,3 +1,3 @@ SHA512 (linux-4.9.tar.xz) = bf67ff812cc3cb7e5059e82cc5db0d9a7c5637f7ed9a42e4730c715bf7047c81ed3a571225f92a33ef0b6d65f35595bc32d773356646df2627da55e9bc7f1f1a SHA512 (perf-man-4.9.tar.gz) = d23bb3da1eadd6623fddbf4696948de7675f3dcf57c711a7427dd7ae111394f58d8f42752938bbea7cd219f1e7f6f116fc67a1c74f769711063940a065f37b99 -SHA512 (patch-4.9.8.xz) = 98400f66cdb4536dfefc8e88a60d9c84dd60e999e1f8547dd25c1e1476099fa76c4f6a0b6b45f91ddc6003ec6233a3e1b6e44b8172c8e89b3e9aca7ffde7b15e +SHA512 (patch-4.9.10.xz) = 93958f4b932a46bbd9a122f52bf09b8c4b864b419a0774514baeb7dc83f11f55a5ba84f2e586a904dbfeeb7d976352e40670fbe2e32e25c35085ddf87e41b58d diff --git a/w1-ds2490-USB-transfer-buffers-need-to-be-DMAable.patch b/w1-ds2490-USB-transfer-buffers-need-to-be-DMAable.patch new file mode 100644 index 000000000..7e902b100 --- /dev/null +++ b/w1-ds2490-USB-transfer-buffers-need-to-be-DMAable.patch @@ -0,0 +1,360 @@ +From patchwork Wed Jan 18 20:31:11 2017 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: w1: ds2490: USB transfer buffers need to be DMAable +From: "Maciej S. Szmigiero" <mail@maciej.szmigiero.name> +X-Patchwork-Id: 9524693 +Message-Id: <5ba98814-d0b0-fbd4-d631-eda3472f4017@maciej.szmigiero.name> +To: Evgeniy Polyakov <zbr@ioremap.net> +Cc: linux-kernel <linux-kernel@vger.kernel.org> +Date: Wed, 18 Jan 2017 21:31:11 +0100 + +ds2490 driver was doing USB transfers from / to buffers on a stack. +This is not permitted and made the driver non-working with vmapped stacks. + +Since all these transfers are done under the same bus_mutex lock we can +simply use shared buffers in a device private structure for two most common +of them. + +While we are at it, let's also fix a comparison between int and size_t in +ds9490r_search() which made the driver spin in this function if state +register get requests were failing. + +Signed-off-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name> +Cc: stable@vger.kernel.org +--- + drivers/w1/masters/ds2490.c | 142 ++++++++++++++++++++++++++------------------ + 1 file changed, 84 insertions(+), 58 deletions(-) + +diff --git a/drivers/w1/masters/ds2490.c b/drivers/w1/masters/ds2490.c +index 049a884a756f..59d74d1b47a8 100644 +--- a/drivers/w1/masters/ds2490.c ++++ b/drivers/w1/masters/ds2490.c +@@ -153,6 +153,9 @@ struct ds_device + */ + u16 spu_bit; + ++ u8 st_buf[ST_SIZE]; ++ u8 byte_buf; ++ + struct w1_bus_master master; + }; + +@@ -174,7 +177,6 @@ struct ds_status + u8 data_in_buffer_status; + u8 reserved1; + u8 reserved2; +- + }; + + static struct usb_device_id ds_id_table [] = { +@@ -244,28 +246,6 @@ static int ds_send_control(struct ds_device *dev, u16 value, u16 index) + return err; + } + +-static int ds_recv_status_nodump(struct ds_device *dev, struct ds_status *st, +- unsigned char *buf, int size) +-{ +- int count, err; +- +- memset(st, 0, sizeof(*st)); +- +- count = 0; +- err = usb_interrupt_msg(dev->udev, usb_rcvintpipe(dev->udev, +- dev->ep[EP_STATUS]), buf, size, &count, 1000); +- if (err < 0) { +- pr_err("Failed to read 1-wire data from 0x%x: err=%d.\n", +- dev->ep[EP_STATUS], err); +- return err; +- } +- +- if (count >= sizeof(*st)) +- memcpy(st, buf, sizeof(*st)); +- +- return count; +-} +- + static inline void ds_print_msg(unsigned char *buf, unsigned char *str, int off) + { + pr_info("%45s: %8x\n", str, buf[off]); +@@ -324,6 +304,35 @@ static void ds_dump_status(struct ds_device *dev, unsigned char *buf, int count) + } + } + ++static int ds_recv_status(struct ds_device *dev, struct ds_status *st, ++ bool dump) ++{ ++ int count, err; ++ ++ if (st) ++ memset(st, 0, sizeof(*st)); ++ ++ count = 0; ++ err = usb_interrupt_msg(dev->udev, ++ usb_rcvintpipe(dev->udev, ++ dev->ep[EP_STATUS]), ++ dev->st_buf, sizeof(dev->st_buf), ++ &count, 1000); ++ if (err < 0) { ++ pr_err("Failed to read 1-wire data from 0x%x: err=%d.\n", ++ dev->ep[EP_STATUS], err); ++ return err; ++ } ++ ++ if (dump) ++ ds_dump_status(dev, dev->st_buf, count); ++ ++ if (st && count >= sizeof(*st)) ++ memcpy(st, dev->st_buf, sizeof(*st)); ++ ++ return count; ++} ++ + static void ds_reset_device(struct ds_device *dev) + { + ds_send_control_cmd(dev, CTL_RESET_DEVICE, 0); +@@ -344,7 +353,6 @@ static void ds_reset_device(struct ds_device *dev) + static int ds_recv_data(struct ds_device *dev, unsigned char *buf, int size) + { + int count, err; +- struct ds_status st; + + /* Careful on size. If size is less than what is available in + * the input buffer, the device fails the bulk transfer and +@@ -359,14 +367,9 @@ static int ds_recv_data(struct ds_device *dev, unsigned char *buf, int size) + err = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN]), + buf, size, &count, 1000); + if (err < 0) { +- u8 buf[ST_SIZE]; +- int count; +- + pr_info("Clearing ep0x%x.\n", dev->ep[EP_DATA_IN]); + usb_clear_halt(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN])); +- +- count = ds_recv_status_nodump(dev, &st, buf, sizeof(buf)); +- ds_dump_status(dev, buf, count); ++ ds_recv_status(dev, NULL, true); + return err; + } + +@@ -404,7 +407,6 @@ int ds_stop_pulse(struct ds_device *dev, int limit) + { + struct ds_status st; + int count = 0, err = 0; +- u8 buf[ST_SIZE]; + + do { + err = ds_send_control(dev, CTL_HALT_EXE_IDLE, 0); +@@ -413,7 +415,7 @@ int ds_stop_pulse(struct ds_device *dev, int limit) + err = ds_send_control(dev, CTL_RESUME_EXE, 0); + if (err) + break; +- err = ds_recv_status_nodump(dev, &st, buf, sizeof(buf)); ++ err = ds_recv_status(dev, &st, false); + if (err) + break; + +@@ -456,18 +458,17 @@ int ds_detect(struct ds_device *dev, struct ds_status *st) + + static int ds_wait_status(struct ds_device *dev, struct ds_status *st) + { +- u8 buf[ST_SIZE]; + int err, count = 0; + + do { + st->status = 0; +- err = ds_recv_status_nodump(dev, st, buf, sizeof(buf)); ++ err = ds_recv_status(dev, st, false); + #if 0 + if (err >= 0) { + int i; + printk("0x%x: count=%d, status: ", dev->ep[EP_STATUS], err); + for (i=0; i<err; ++i) +- printk("%02x ", buf[i]); ++ printk("%02x ", dev->st_buf[i]); + printk("\n"); + } + #endif +@@ -485,7 +486,7 @@ static int ds_wait_status(struct ds_device *dev, struct ds_status *st) + * can do something with it). + */ + if (err > 16 || count >= 100 || err < 0) +- ds_dump_status(dev, buf, err); ++ ds_dump_status(dev, dev->st_buf, err); + + /* Extended data isn't an error. Well, a short is, but the dump + * would have already told the user that and we can't do anything +@@ -608,7 +609,6 @@ static int ds_write_byte(struct ds_device *dev, u8 byte) + { + int err; + struct ds_status st; +- u8 rbyte; + + err = ds_send_control(dev, COMM_BYTE_IO | COMM_IM | dev->spu_bit, byte); + if (err) +@@ -621,11 +621,11 @@ static int ds_write_byte(struct ds_device *dev, u8 byte) + if (err) + return err; + +- err = ds_recv_data(dev, &rbyte, sizeof(rbyte)); ++ err = ds_recv_data(dev, &dev->byte_buf, 1); + if (err < 0) + return err; + +- return !(byte == rbyte); ++ return !(byte == dev->byte_buf); + } + + static int ds_read_byte(struct ds_device *dev, u8 *byte) +@@ -712,7 +712,6 @@ static void ds9490r_search(void *data, struct w1_master *master, + int err; + u16 value, index; + struct ds_status st; +- u8 st_buf[ST_SIZE]; + int search_limit; + int found = 0; + int i; +@@ -724,7 +723,12 @@ static void ds9490r_search(void *data, struct w1_master *master, + /* FIFO 128 bytes, bulk packet size 64, read a multiple of the + * packet size. + */ +- u64 buf[2*64/8]; ++ const size_t bufsize = 2 * 64; ++ u64 *buf; ++ ++ buf = kmalloc(bufsize, GFP_KERNEL); ++ if (!buf) ++ return; + + mutex_lock(&master->bus_mutex); + +@@ -745,10 +749,9 @@ static void ds9490r_search(void *data, struct w1_master *master, + do { + schedule_timeout(jtime); + +- if (ds_recv_status_nodump(dev, &st, st_buf, sizeof(st_buf)) < +- sizeof(st)) { ++ err = ds_recv_status(dev, &st, false); ++ if (err < 0 || err < sizeof(st)) + break; +- } + + if (st.data_in_buffer_status) { + /* Bulk in can receive partial ids, but when it does +@@ -758,7 +761,7 @@ static void ds9490r_search(void *data, struct w1_master *master, + * bulk without first checking if status says there + * is data to read. + */ +- err = ds_recv_data(dev, (u8 *)buf, sizeof(buf)); ++ err = ds_recv_data(dev, (u8 *)buf, bufsize); + if (err < 0) + break; + for (i = 0; i < err/8; ++i) { +@@ -794,9 +797,14 @@ static void ds9490r_search(void *data, struct w1_master *master, + } + search_out: + mutex_unlock(&master->bus_mutex); ++ kfree(buf); + } + + #if 0 ++/* ++ * FIXME: if this disabled code is ever used in the future all ds_send_data() ++ * calls must be changed to use a DMAable buffer. ++ */ + static int ds_match_access(struct ds_device *dev, u64 init) + { + int err; +@@ -845,13 +853,12 @@ static int ds_set_path(struct ds_device *dev, u64 init) + + static u8 ds9490r_touch_bit(void *data, u8 bit) + { +- u8 ret; + struct ds_device *dev = data; + +- if (ds_touch_bit(dev, bit, &ret)) ++ if (ds_touch_bit(dev, bit, &dev->byte_buf)) + return 0; + +- return ret; ++ return dev->byte_buf; + } + + #if 0 +@@ -866,13 +873,12 @@ static u8 ds9490r_read_bit(void *data) + { + struct ds_device *dev = data; + int err; +- u8 bit = 0; + +- err = ds_touch_bit(dev, 1, &bit); ++ err = ds_touch_bit(dev, 1, &dev->byte_buf); + if (err) + return 0; + +- return bit & 1; ++ return dev->byte_buf & 1; + } + #endif + +@@ -887,32 +893,52 @@ static u8 ds9490r_read_byte(void *data) + { + struct ds_device *dev = data; + int err; +- u8 byte = 0; + +- err = ds_read_byte(dev, &byte); ++ err = ds_read_byte(dev, &dev->byte_buf); + if (err) + return 0; + +- return byte; ++ return dev->byte_buf; + } + + static void ds9490r_write_block(void *data, const u8 *buf, int len) + { + struct ds_device *dev = data; ++ u8 *tbuf; ++ ++ if (len <= 0) ++ return; ++ ++ tbuf = kmalloc(len, GFP_KERNEL); ++ if (!tbuf) ++ return; + +- ds_write_block(dev, (u8 *)buf, len); ++ memcpy(tbuf, buf, len); ++ ds_write_block(dev, tbuf, len); ++ ++ kfree(tbuf); + } + + static u8 ds9490r_read_block(void *data, u8 *buf, int len) + { + struct ds_device *dev = data; + int err; ++ u8 *tbuf; + +- err = ds_read_block(dev, buf, len); +- if (err < 0) ++ if (len <= 0) ++ return 0; ++ ++ tbuf = kmalloc(len, GFP_KERNEL); ++ if (!tbuf) + return 0; + +- return len; ++ err = ds_read_block(dev, tbuf, len); ++ if (err >= 0) ++ memcpy(buf, tbuf, len); ++ ++ kfree(tbuf); ++ ++ return err >= 0 ? len : 0; + } + + static u8 ds9490r_reset(void *data) |