mirror of
https://git.yoctoproject.org/meta-ti
synced 2026-04-20 19:53:43 +00:00
linux-ti335x-psp 3.2: update to 3.2.14
Signed-off-by: Koen Kooi <koen@dominion.thruhere.net> Signed-off-by: Denys Dmytriyenko <denys@ti.com>
This commit is contained in:
committed by
Denys Dmytriyenko
parent
f5135a2cb7
commit
bb34e69f3d
@@ -0,0 +1,45 @@
|
||||
From cc33a57bd7f9104a9c2f77f11dc3e7f9c22b9340 Mon Sep 17 00:00:00 2001
|
||||
From: Meng Zhang <meng.zhang@mediatek.com>
|
||||
Date: Mon, 27 Feb 2012 08:24:19 +0100
|
||||
Subject: [PATCH 001/147] USB: option: Add MediaTek MT6276M modem&app
|
||||
interfaces
|
||||
|
||||
commit 0d8520a1d7f43328bc7085d4244d93c595064157 upstream.
|
||||
|
||||
Add MEDIATEK products to Option driver
|
||||
|
||||
Signed-off-by: Meng Zhang <meng.zhang@mediatek.com>
|
||||
Signed-off-by: Matthias Urlichs <matthias@urlichs.de>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/serial/option.c | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
|
||||
index 68fa8c7..547c9b9 100644
|
||||
--- a/drivers/usb/serial/option.c
|
||||
+++ b/drivers/usb/serial/option.c
|
||||
@@ -484,6 +484,9 @@ static void option_instat_callback(struct urb *urb);
|
||||
#define LG_VENDOR_ID 0x1004
|
||||
#define LG_PRODUCT_L02C 0x618f
|
||||
|
||||
+/* MediaTek products */
|
||||
+#define MEDIATEK_VENDOR_ID 0x0e8d
|
||||
+
|
||||
/* some devices interfaces need special handling due to a number of reasons */
|
||||
enum option_blacklist_reason {
|
||||
OPTION_BLACKLIST_NONE = 0,
|
||||
@@ -1198,6 +1201,10 @@ static const struct usb_device_id option_ids[] = {
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(VIETTEL_VENDOR_ID, VIETTEL_PRODUCT_VT1000, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZD_VENDOR_ID, ZD_PRODUCT_7000, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE(LG_VENDOR_ID, LG_PRODUCT_L02C) }, /* docomo L-02C modem */
|
||||
+ { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, 0x00a1, 0xff, 0x00, 0x00) },
|
||||
+ { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, 0x00a1, 0xff, 0x02, 0x01) },
|
||||
+ { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, 0x00a2, 0xff, 0x00, 0x00) },
|
||||
+ { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, 0x00a2, 0xff, 0x02, 0x01) }, /* MediaTek MT6276M modem & app port */
|
||||
{ } /* Terminating entry */
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, option_ids);
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
From 17ad305add28a63e155a74678178a6ce6a6a5998 Mon Sep 17 00:00:00 2001
|
||||
From: Daniele Palmas <dnlplm@gmail.com>
|
||||
Date: Wed, 29 Feb 2012 15:32:05 +0100
|
||||
Subject: [PATCH 002/147] USB: option driver: adding support for Telit
|
||||
CC864-SINGLE, CC864-DUAL and DE910-DUAL modems
|
||||
|
||||
commit 7204cf584836c24b4b06e4ad4a8e6bb8ea84908e upstream.
|
||||
|
||||
Adding PID for Telit CC864-SINGLE, CC864-DUAL and DE910-DUAL
|
||||
modems
|
||||
|
||||
Signed-off-by: Daniele Palmas <dnlplm@gmail.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/serial/option.c | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
|
||||
index 547c9b9..3c4b7df 100644
|
||||
--- a/drivers/usb/serial/option.c
|
||||
+++ b/drivers/usb/serial/option.c
|
||||
@@ -307,6 +307,9 @@ static void option_instat_callback(struct urb *urb);
|
||||
#define TELIT_VENDOR_ID 0x1bc7
|
||||
#define TELIT_PRODUCT_UC864E 0x1003
|
||||
#define TELIT_PRODUCT_UC864G 0x1004
|
||||
+#define TELIT_PRODUCT_CC864_DUAL 0x1005
|
||||
+#define TELIT_PRODUCT_CC864_SINGLE 0x1006
|
||||
+#define TELIT_PRODUCT_DE910_DUAL 0x1010
|
||||
|
||||
/* ZTE PRODUCTS */
|
||||
#define ZTE_VENDOR_ID 0x19d2
|
||||
@@ -771,6 +774,9 @@ static const struct usb_device_id option_ids[] = {
|
||||
{ USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6008) },
|
||||
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) },
|
||||
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864G) },
|
||||
+ { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_DUAL) },
|
||||
+ { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_SINGLE) },
|
||||
+ { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_DE910_DUAL) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&net_intf1_blacklist },
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
From ebdc22267ac3cd3aef9e300a553c0f32ac5da6f2 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= <bjorn@mork.no>
|
||||
Date: Fri, 16 Mar 2012 12:56:44 +0100
|
||||
Subject: [PATCH 003/147] USB: option: make interface blacklist work again
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
commit 963940cf472d76eca2d36296e461202cc6997352 upstream.
|
||||
|
||||
commit 0d905fd "USB: option: convert Huawei K3765, K4505, K4605
|
||||
reservered interface to blacklist" accidentally ANDed two
|
||||
blacklist tests by leaving out a return. This was not noticed
|
||||
because the two consecutive bracketless if statements made it
|
||||
syntactically correct.
|
||||
|
||||
Signed-off-by: Bj??rn Mork <bjorn@mork.no>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/serial/option.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
|
||||
index 3c4b7df..6410935 100644
|
||||
--- a/drivers/usb/serial/option.c
|
||||
+++ b/drivers/usb/serial/option.c
|
||||
@@ -1373,6 +1373,7 @@ static int option_probe(struct usb_serial *serial,
|
||||
serial->interface->cur_altsetting->desc.bInterfaceNumber,
|
||||
OPTION_BLACKLIST_RESERVED_IF,
|
||||
(const struct option_blacklist_info *) id->driver_info))
|
||||
+ return -ENODEV;
|
||||
|
||||
/* Don't bind network interface on Samsung GT-B3730, it is handled by a separate module */
|
||||
if (serial->dev->descriptor.idVendor == SAMSUNG_VENDOR_ID &&
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
From 0b49c52b5b44e5db6fe288173faec7136ea18c68 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= <bjorn@mork.no>
|
||||
Date: Fri, 16 Mar 2012 15:41:26 +0100
|
||||
Subject: [PATCH 004/147] USB: option: add ZTE MF820D
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
commit 5889d3d4209c1050b4a3c96c41faf6c0976a4acf upstream.
|
||||
|
||||
This device presents a total of 5 interfaces with ff/ff/ff
|
||||
class/subclass/protocol. The last one of these is verified
|
||||
to be a QMI/wwan combined interface which should be handled
|
||||
by the qmi_wwan driver, so we blacklist it here.
|
||||
|
||||
Signed-off-by: Bj??rn Mork <bjorn@mork.no>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/serial/option.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
|
||||
index 6410935..54898c9 100644
|
||||
--- a/drivers/usb/serial/option.c
|
||||
+++ b/drivers/usb/serial/option.c
|
||||
@@ -901,6 +901,8 @@ static const struct usb_device_id option_ids[] = {
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0162, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0164, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0165, 0xff, 0xff, 0xff) },
|
||||
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0167, 0xff, 0xff, 0xff),
|
||||
+ .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1008, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1010, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1012, 0xff, 0xff, 0xff) },
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
From 24c8eaa136cf3193f2719e9d04cc4efea3b2b732 Mon Sep 17 00:00:00 2001
|
||||
From: Andrea Righi <andrea@betterlinux.com>
|
||||
Date: Mon, 20 Feb 2012 13:11:49 +0100
|
||||
Subject: [PATCH 005/147] staging: zcache: avoid AB-BA deadlock condition
|
||||
|
||||
commit cfbc6a92212e74b07aa76c9e2f20c542e36077fb upstream.
|
||||
|
||||
Commit 9256a47 fixed a deadlock condition, being sure that the buddy
|
||||
list spinlock is always taken before the page spinlock.
|
||||
|
||||
However in zbud_free_and_delist() locking order is the opposite
|
||||
(page lock -> list lock).
|
||||
|
||||
Possible unsafe locking scenario (reported by lockdep):
|
||||
|
||||
CPU0 CPU1
|
||||
---- ----
|
||||
lock(&(&zbpg->lock)->rlock);
|
||||
lock(zbud_budlists_spinlock);
|
||||
lock(&(&zbpg->lock)->rlock);
|
||||
lock(zbud_budlists_spinlock);
|
||||
|
||||
Fix by grabbing the locks in opposite order in zbud_free_and_delist().
|
||||
|
||||
Signed-off-by: Andrea Righi <andrea@betterlinux.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/staging/zcache/zcache-main.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/staging/zcache/zcache-main.c b/drivers/staging/zcache/zcache-main.c
|
||||
index f5e469d..16ad9fe 100644
|
||||
--- a/drivers/staging/zcache/zcache-main.c
|
||||
+++ b/drivers/staging/zcache/zcache-main.c
|
||||
@@ -299,10 +299,12 @@ static void zbud_free_and_delist(struct zbud_hdr *zh)
|
||||
struct zbud_page *zbpg =
|
||||
container_of(zh, struct zbud_page, buddy[budnum]);
|
||||
|
||||
+ spin_lock(&zbud_budlists_spinlock);
|
||||
spin_lock(&zbpg->lock);
|
||||
if (list_empty(&zbpg->bud_list)) {
|
||||
/* ignore zombie page... see zbud_evict_pages() */
|
||||
spin_unlock(&zbpg->lock);
|
||||
+ spin_unlock(&zbud_budlists_spinlock);
|
||||
return;
|
||||
}
|
||||
size = zbud_free(zh);
|
||||
@@ -310,7 +312,6 @@ static void zbud_free_and_delist(struct zbud_hdr *zh)
|
||||
zh_other = &zbpg->buddy[(budnum == 0) ? 1 : 0];
|
||||
if (zh_other->size == 0) { /* was unbuddied: unlist and free */
|
||||
chunks = zbud_size_to_chunks(size) ;
|
||||
- spin_lock(&zbud_budlists_spinlock);
|
||||
BUG_ON(list_empty(&zbud_unbuddied[chunks].list));
|
||||
list_del_init(&zbpg->bud_list);
|
||||
zbud_unbuddied[chunks].count--;
|
||||
@@ -318,7 +319,6 @@ static void zbud_free_and_delist(struct zbud_hdr *zh)
|
||||
zbud_free_raw_page(zbpg);
|
||||
} else { /* was buddied: move remaining buddy to unbuddied list */
|
||||
chunks = zbud_size_to_chunks(zh_other->size) ;
|
||||
- spin_lock(&zbud_budlists_spinlock);
|
||||
list_del_init(&zbpg->bud_list);
|
||||
zcache_zbud_buddied_count--;
|
||||
list_add_tail(&zbpg->bud_list, &zbud_unbuddied[chunks].list);
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
From 662c920fb175331db0c7813edd168390b51d3e31 Mon Sep 17 00:00:00 2001
|
||||
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
Date: Tue, 28 Feb 2012 09:20:09 -0800
|
||||
Subject: [PATCH 006/147] USB: ftdi_sio: fix problem when the manufacture is a
|
||||
NULL string
|
||||
|
||||
commit 656d2b3964a9d0f9864d472f8dfa2dd7dd42e6c0 upstream.
|
||||
|
||||
On some misconfigured ftdi_sio devices, if the manufacturer string is
|
||||
NULL, the kernel will oops when the device is plugged in. This patch
|
||||
fixes the problem.
|
||||
|
||||
Reported-by: Wojciech M Zabolotny <W.Zabolotny@elka.pw.edu.pl>
|
||||
Tested-by: Wojciech M Zabolotny <W.Zabolotny@elka.pw.edu.pl>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/serial/ftdi_sio.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
|
||||
index f030471..d170b2a 100644
|
||||
--- a/drivers/usb/serial/ftdi_sio.c
|
||||
+++ b/drivers/usb/serial/ftdi_sio.c
|
||||
@@ -1763,7 +1763,8 @@ static int ftdi_8u2232c_probe(struct usb_serial *serial)
|
||||
|
||||
dbg("%s", __func__);
|
||||
|
||||
- if (strcmp(udev->manufacturer, "CALAO Systems") == 0)
|
||||
+ if ((udev->manufacturer) &&
|
||||
+ (strcmp(udev->manufacturer, "CALAO Systems") == 0))
|
||||
return ftdi_jtag_probe(serial);
|
||||
|
||||
return 0;
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
From 5cabeb029a6230a2ade6a4e6821f444cc40816dd Mon Sep 17 00:00:00 2001
|
||||
From: Peter Korsgaard <jacmet@sunsite.dk>
|
||||
Date: Wed, 29 Feb 2012 10:05:37 +0100
|
||||
Subject: [PATCH 007/147] USB: ftdi_sio: add support for BeagleBone rev A5+
|
||||
|
||||
commit 444aa7fa9bd752d19ce472d3e02558b987c3cc67 upstream.
|
||||
|
||||
BeagleBone changed to the default FTDI 0403:6010 id in rev A5 to make life
|
||||
easier for Windows users, so we need a similar workaround as the Calao
|
||||
board to support it.
|
||||
|
||||
Signed-off-by: Peter Korsgaard <jacmet@sunsite.dk>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/serial/ftdi_sio.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
|
||||
index d170b2a..30839d4 100644
|
||||
--- a/drivers/usb/serial/ftdi_sio.c
|
||||
+++ b/drivers/usb/serial/ftdi_sio.c
|
||||
@@ -1763,8 +1763,8 @@ static int ftdi_8u2232c_probe(struct usb_serial *serial)
|
||||
|
||||
dbg("%s", __func__);
|
||||
|
||||
- if ((udev->manufacturer) &&
|
||||
- (strcmp(udev->manufacturer, "CALAO Systems") == 0))
|
||||
+ if ((udev->manufacturer && !strcmp(udev->manufacturer, "CALAO Systems")) ||
|
||||
+ (udev->product && !strcmp(udev->product, "BeagleBone/XDS100")))
|
||||
return ftdi_jtag_probe(serial);
|
||||
|
||||
return 0;
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
From f2f8f7f7d9dfc406b8e5a9a1b89e904318c8ac0f Mon Sep 17 00:00:00 2001
|
||||
From: Bruno Thomsen <bruno.thomsen@gmail.com>
|
||||
Date: Sun, 4 Mar 2012 15:19:14 +0100
|
||||
Subject: [PATCH 008/147] USB: Microchip VID mislabeled as Hornby VID in
|
||||
ftdi_sio.
|
||||
|
||||
commit c1cee1d84001815a1b4321c49b995254c0df3100 upstream.
|
||||
|
||||
Microchip VID (0x04d8) was mislabeled as Hornby VID according to USB-IDs.
|
||||
|
||||
A Full Speed USB Demo Board PID (0x000a) was mislabeled as
|
||||
Hornby Elite (an Digital Command Controller Console for model railways).
|
||||
|
||||
Most likely the Hornby based their design on
|
||||
PIC18F87J50 Full Speed USB Demo Board.
|
||||
|
||||
Signed-off-by: Bruno Thomsen <bruno.thomsen@gmail.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/serial/ftdi_sio.c | 2 +-
|
||||
drivers/usb/serial/ftdi_sio_ids.h | 10 +++++++---
|
||||
2 files changed, 8 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
|
||||
index 30839d4..363e995 100644
|
||||
--- a/drivers/usb/serial/ftdi_sio.c
|
||||
+++ b/drivers/usb/serial/ftdi_sio.c
|
||||
@@ -797,7 +797,7 @@ static struct usb_device_id id_table_combined [] = {
|
||||
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
|
||||
{ USB_DEVICE(ADI_VID, ADI_GNICEPLUS_PID),
|
||||
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
|
||||
- { USB_DEVICE(HORNBY_VID, HORNBY_ELITE_PID) },
|
||||
+ { USB_DEVICE(MICROCHIP_VID, MICROCHIP_USB_BOARD_PID) },
|
||||
{ USB_DEVICE(JETI_VID, JETI_SPC1201_PID) },
|
||||
{ USB_DEVICE(MARVELL_VID, MARVELL_SHEEVAPLUG_PID),
|
||||
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
|
||||
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h
|
||||
index 4eb7715..df87939 100644
|
||||
--- a/drivers/usb/serial/ftdi_sio_ids.h
|
||||
+++ b/drivers/usb/serial/ftdi_sio_ids.h
|
||||
@@ -532,10 +532,14 @@
|
||||
#define ADI_GNICEPLUS_PID 0xF001
|
||||
|
||||
/*
|
||||
- * Hornby Elite
|
||||
+ * Microchip Technology, Inc.
|
||||
+ *
|
||||
+ * MICROCHIP_VID (0x04D8) and MICROCHIP_USB_BOARD_PID (0x000A) are also used by:
|
||||
+ * Hornby Elite - Digital Command Control Console
|
||||
+ * http://www.hornby.com/hornby-dcc/controllers/
|
||||
*/
|
||||
-#define HORNBY_VID 0x04D8
|
||||
-#define HORNBY_ELITE_PID 0x000A
|
||||
+#define MICROCHIP_VID 0x04D8
|
||||
+#define MICROCHIP_USB_BOARD_PID 0x000A /* CDC RS-232 Emulation Demo */
|
||||
|
||||
/*
|
||||
* RATOC REX-USB60F
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
From 42eb98a4b9dc721f8565ce0d3063db8d141f516b Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Micha=C5=82=20Wr=C3=B3bel?= <michal.wrobel@flytronic.pl>
|
||||
Date: Fri, 9 Mar 2012 14:40:18 +0100
|
||||
Subject: [PATCH 009/147] USB: ftdi_sio: new PID: Distortec JTAG-lock-pick
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
commit 47594d5528f28a4c025c2955c68104c75815637c upstream.
|
||||
|
||||
Signed-off-by: Micha?? Wr??bel <michal.wrobel@flytronic.pl>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/serial/ftdi_sio.c | 2 ++
|
||||
drivers/usb/serial/ftdi_sio_ids.h | 2 ++
|
||||
2 files changed, 4 insertions(+)
|
||||
|
||||
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
|
||||
index 363e995..a319eaa 100644
|
||||
--- a/drivers/usb/serial/ftdi_sio.c
|
||||
+++ b/drivers/usb/serial/ftdi_sio.c
|
||||
@@ -846,6 +846,8 @@ static struct usb_device_id id_table_combined [] = {
|
||||
{ USB_DEVICE(ST_VID, ST_STMCLT1030_PID),
|
||||
.driver_info = (kernel_ulong_t)&ftdi_stmclite_quirk },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_RF_R106) },
|
||||
+ { USB_DEVICE(FTDI_VID, FTDI_DISTORTEC_JTAG_LOCK_PICK_PID),
|
||||
+ .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
|
||||
{ }, /* Optional parameter entry */
|
||||
{ } /* Terminating entry */
|
||||
};
|
||||
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h
|
||||
index df87939..bed1b1f 100644
|
||||
--- a/drivers/usb/serial/ftdi_sio_ids.h
|
||||
+++ b/drivers/usb/serial/ftdi_sio_ids.h
|
||||
@@ -97,6 +97,8 @@
|
||||
#define FTDI_TACTRIX_OPENPORT_13S_PID 0xCC49 /* OpenPort 1.3 Subaru */
|
||||
#define FTDI_TACTRIX_OPENPORT_13U_PID 0xCC4A /* OpenPort 1.3 Universal */
|
||||
|
||||
+#define FTDI_DISTORTEC_JTAG_LOCK_PICK_PID 0xCFF8
|
||||
+
|
||||
/* SCS HF Radio Modems PID's (http://www.scs-ptc.com) */
|
||||
/* the VID is the standard ftdi vid (FTDI_VID) */
|
||||
#define FTDI_SCS_DEVICE_0_PID 0xD010 /* SCS PTC-IIusb */
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
From a1460f8a00ab8864ee14c39d4dfaa0dea4cff95e Mon Sep 17 00:00:00 2001
|
||||
From: Jim Paris <jim@jtan.com>
|
||||
Date: Wed, 14 Mar 2012 17:54:25 -0400
|
||||
Subject: [PATCH 010/147] USB: ftdi_sio: add support for FT-X series devices
|
||||
|
||||
commit dc0827c128c0ee5a58b822b99d662b59f4b8e970 upstream.
|
||||
|
||||
Add PID 0x6015, corresponding to the new series of FT-X chips
|
||||
(FT220XD, FT201X, FT220X, FT221X, FT230X, FT231X, FT240X). They all
|
||||
appear as serial devices, and seem indistinguishable except for the
|
||||
default product string stored in their EEPROM. The baudrate
|
||||
generation matches FT232RL devices.
|
||||
|
||||
Tested with a FT201X and FT230X at various baudrates (100 - 3000000).
|
||||
|
||||
Sample dmesg:
|
||||
ftdi_sio: v1.6.0:USB FTDI Serial Converters Driver
|
||||
usb 2-1: new full-speed USB device number 6 using ohci_hcd
|
||||
usb 2-1: New USB device found, idVendor=0403, idProduct=6015
|
||||
usb 2-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
|
||||
usb 2-1: Product: FT230X USB Half UART
|
||||
usb 2-1: Manufacturer: FTDI
|
||||
usb 2-1: SerialNumber: DC001WI6
|
||||
ftdi_sio 2-1:1.0: FTDI USB Serial Device converter detected
|
||||
drivers/usb/serial/ftdi_sio.c: ftdi_sio_port_probe
|
||||
drivers/usb/serial/ftdi_sio.c: ftdi_determine_type: bcdDevice = 0x1000, bNumInterfaces = 1
|
||||
usb 2-1: Detected FT-X
|
||||
usb 2-1: Number of endpoints 2
|
||||
usb 2-1: Endpoint 1 MaxPacketSize 64
|
||||
usb 2-1: Endpoint 2 MaxPacketSize 64
|
||||
usb 2-1: Setting MaxPacketSize 64
|
||||
drivers/usb/serial/ftdi_sio.c: read_latency_timer
|
||||
drivers/usb/serial/ftdi_sio.c: write_latency_timer: setting latency timer = 1
|
||||
drivers/usb/serial/ftdi_sio.c: create_sysfs_attrs
|
||||
drivers/usb/serial/ftdi_sio.c: sysfs attributes for FT-X
|
||||
usb 2-1: FTDI USB Serial Device converter now attached to ttyUSB0
|
||||
|
||||
Signed-off-by: Jim Paris <jim@jtan.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/serial/ftdi_sio.c | 20 +++++++++++++++-----
|
||||
drivers/usb/serial/ftdi_sio.h | 3 ++-
|
||||
drivers/usb/serial/ftdi_sio_ids.h | 1 +
|
||||
3 files changed, 18 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
|
||||
index a319eaa..b64fddc 100644
|
||||
--- a/drivers/usb/serial/ftdi_sio.c
|
||||
+++ b/drivers/usb/serial/ftdi_sio.c
|
||||
@@ -188,6 +188,7 @@ static struct usb_device_id id_table_combined [] = {
|
||||
.driver_info = (kernel_ulong_t)&ftdi_8u2232c_quirk },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_4232H_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_232H_PID) },
|
||||
+ { USB_DEVICE(FTDI_VID, FTDI_FTX_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_OPENDCC_PID) },
|
||||
@@ -870,7 +871,8 @@ static const char *ftdi_chip_name[] = {
|
||||
[FT232RL] = "FT232RL",
|
||||
[FT2232H] = "FT2232H",
|
||||
[FT4232H] = "FT4232H",
|
||||
- [FT232H] = "FT232H"
|
||||
+ [FT232H] = "FT232H",
|
||||
+ [FTX] = "FT-X"
|
||||
};
|
||||
|
||||
|
||||
@@ -1171,7 +1173,8 @@ static __u32 get_ftdi_divisor(struct tty_struct *tty,
|
||||
break;
|
||||
case FT232BM: /* FT232BM chip */
|
||||
case FT2232C: /* FT2232C chip */
|
||||
- case FT232RL:
|
||||
+ case FT232RL: /* FT232RL chip */
|
||||
+ case FTX: /* FT-X series */
|
||||
if (baud <= 3000000) {
|
||||
__u16 product_id = le16_to_cpu(
|
||||
port->serial->dev->descriptor.idProduct);
|
||||
@@ -1460,10 +1463,14 @@ static void ftdi_determine_type(struct usb_serial_port *port)
|
||||
} else if (version < 0x900) {
|
||||
/* Assume it's an FT232RL */
|
||||
priv->chip_type = FT232RL;
|
||||
- } else {
|
||||
+ } else if (version < 0x1000) {
|
||||
/* Assume it's an FT232H */
|
||||
priv->chip_type = FT232H;
|
||||
+ } else {
|
||||
+ /* Assume it's an FT-X series device */
|
||||
+ priv->chip_type = FTX;
|
||||
}
|
||||
+
|
||||
dev_info(&udev->dev, "Detected %s\n", ftdi_chip_name[priv->chip_type]);
|
||||
}
|
||||
|
||||
@@ -1591,7 +1598,8 @@ static int create_sysfs_attrs(struct usb_serial_port *port)
|
||||
priv->chip_type == FT232RL ||
|
||||
priv->chip_type == FT2232H ||
|
||||
priv->chip_type == FT4232H ||
|
||||
- priv->chip_type == FT232H)) {
|
||||
+ priv->chip_type == FT232H ||
|
||||
+ priv->chip_type == FTX)) {
|
||||
retval = device_create_file(&port->dev,
|
||||
&dev_attr_latency_timer);
|
||||
}
|
||||
@@ -1613,7 +1621,8 @@ static void remove_sysfs_attrs(struct usb_serial_port *port)
|
||||
priv->chip_type == FT232RL ||
|
||||
priv->chip_type == FT2232H ||
|
||||
priv->chip_type == FT4232H ||
|
||||
- priv->chip_type == FT232H) {
|
||||
+ priv->chip_type == FT232H ||
|
||||
+ priv->chip_type == FTX) {
|
||||
device_remove_file(&port->dev, &dev_attr_latency_timer);
|
||||
}
|
||||
}
|
||||
@@ -2287,6 +2296,7 @@ static int ftdi_tiocmget(struct tty_struct *tty)
|
||||
case FT2232H:
|
||||
case FT4232H:
|
||||
case FT232H:
|
||||
+ case FTX:
|
||||
len = 2;
|
||||
break;
|
||||
default:
|
||||
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h
|
||||
index 19584fa..ed58c6f 100644
|
||||
--- a/drivers/usb/serial/ftdi_sio.h
|
||||
+++ b/drivers/usb/serial/ftdi_sio.h
|
||||
@@ -157,7 +157,8 @@ enum ftdi_chip_type {
|
||||
FT232RL = 5,
|
||||
FT2232H = 6,
|
||||
FT4232H = 7,
|
||||
- FT232H = 8
|
||||
+ FT232H = 8,
|
||||
+ FTX = 9,
|
||||
};
|
||||
|
||||
enum ftdi_sio_baudrate {
|
||||
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h
|
||||
index bed1b1f..ac1c42e 100644
|
||||
--- a/drivers/usb/serial/ftdi_sio_ids.h
|
||||
+++ b/drivers/usb/serial/ftdi_sio_ids.h
|
||||
@@ -23,6 +23,7 @@
|
||||
#define FTDI_8U2232C_PID 0x6010 /* Dual channel device */
|
||||
#define FTDI_4232H_PID 0x6011 /* Quad channel hi-speed device */
|
||||
#define FTDI_232H_PID 0x6014 /* Single channel hi-speed device */
|
||||
+#define FTDI_FTX_PID 0x6015 /* FT-X series (FT201X, FT230X, FT231X, etc) */
|
||||
#define FTDI_SIO_PID 0x8372 /* Product Id SIO application of 8U100AX */
|
||||
#define FTDI_232RL_PID 0xFBFA /* Product ID for FT232RL */
|
||||
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
From f1a77f929e5e9c5399bf0e0a589280719f96654c Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Micha=C5=82=20Wr=C3=B3bel?= <michal.wrobel@flytronic.pl>
|
||||
Date: Thu, 15 Mar 2012 17:24:04 +0100
|
||||
Subject: [PATCH 011/147] USB: ftdi_sio: new PID: LUMEL PD12
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
commit 57e596f3af88ef52dea9640ed5e34ecd38893a02 upstream.
|
||||
|
||||
Signed-off-by: Micha?? Wr??bel <michal.wrobel@flytronic.pl>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/serial/ftdi_sio.c | 1 +
|
||||
drivers/usb/serial/ftdi_sio_ids.h | 2 ++
|
||||
2 files changed, 3 insertions(+)
|
||||
|
||||
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
|
||||
index b64fddc..3f3ccf6 100644
|
||||
--- a/drivers/usb/serial/ftdi_sio.c
|
||||
+++ b/drivers/usb/serial/ftdi_sio.c
|
||||
@@ -849,6 +849,7 @@ static struct usb_device_id id_table_combined [] = {
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_RF_R106) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_DISTORTEC_JTAG_LOCK_PICK_PID),
|
||||
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
|
||||
+ { USB_DEVICE(FTDI_VID, FTDI_LUMEL_PD12_PID) },
|
||||
{ }, /* Optional parameter entry */
|
||||
{ } /* Terminating entry */
|
||||
};
|
||||
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h
|
||||
index ac1c42e..abf6bbc 100644
|
||||
--- a/drivers/usb/serial/ftdi_sio_ids.h
|
||||
+++ b/drivers/usb/serial/ftdi_sio_ids.h
|
||||
@@ -30,6 +30,8 @@
|
||||
|
||||
/*** third-party PIDs (using FTDI_VID) ***/
|
||||
|
||||
+#define FTDI_LUMEL_PD12_PID 0x6002
|
||||
+
|
||||
/*
|
||||
* Marvell OpenRD Base, Client
|
||||
* http://www.open-rd.org
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
From 9091aa838fdba8fef22a629f43cd039daa714da6 Mon Sep 17 00:00:00 2001
|
||||
From: Shengzhou Liu <Shengzhou.Liu@freescale.com>
|
||||
Date: Thu, 16 Feb 2012 18:02:20 +0800
|
||||
Subject: [PATCH 012/147] powerpc/usb: fix bug of kernel hang when
|
||||
initializing usb
|
||||
|
||||
commit 28c56ea1431421dec51b7b229369e991481453df upstream.
|
||||
|
||||
If USB UTMI PHY is not enable, writing to portsc register will lead to
|
||||
kernel hang during boot up.
|
||||
|
||||
Signed-off-by: Shengzhou Liu <Shengzhou.Liu@freescale.com>
|
||||
Reported-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/host/ehci-fsl.c | 4 ++++
|
||||
drivers/usb/host/ehci-fsl.h | 1 +
|
||||
2 files changed, 5 insertions(+)
|
||||
|
||||
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
|
||||
index b556a72..da487fd 100644
|
||||
--- a/drivers/usb/host/ehci-fsl.c
|
||||
+++ b/drivers/usb/host/ehci-fsl.c
|
||||
@@ -216,6 +216,8 @@ static void ehci_fsl_setup_phy(struct ehci_hcd *ehci,
|
||||
unsigned int port_offset)
|
||||
{
|
||||
u32 portsc;
|
||||
+ struct usb_hcd *hcd = ehci_to_hcd(ehci);
|
||||
+ void __iomem *non_ehci = hcd->regs;
|
||||
|
||||
portsc = ehci_readl(ehci, &ehci->regs->port_status[port_offset]);
|
||||
portsc &= ~(PORT_PTS_MSK | PORT_PTS_PTW);
|
||||
@@ -231,6 +233,8 @@ static void ehci_fsl_setup_phy(struct ehci_hcd *ehci,
|
||||
portsc |= PORT_PTS_PTW;
|
||||
/* fall through */
|
||||
case FSL_USB2_PHY_UTMI:
|
||||
+ /* enable UTMI PHY */
|
||||
+ setbits32(non_ehci + FSL_SOC_USB_CTRL, CTRL_UTMI_PHY_EN);
|
||||
portsc |= PORT_PTS_UTMI;
|
||||
break;
|
||||
case FSL_USB2_PHY_NONE:
|
||||
diff --git a/drivers/usb/host/ehci-fsl.h b/drivers/usb/host/ehci-fsl.h
|
||||
index 4918062..bea5013 100644
|
||||
--- a/drivers/usb/host/ehci-fsl.h
|
||||
+++ b/drivers/usb/host/ehci-fsl.h
|
||||
@@ -45,5 +45,6 @@
|
||||
#define FSL_SOC_USB_PRICTRL 0x40c /* NOTE: big-endian */
|
||||
#define FSL_SOC_USB_SICTRL 0x410 /* NOTE: big-endian */
|
||||
#define FSL_SOC_USB_CTRL 0x500 /* NOTE: big-endian */
|
||||
+#define CTRL_UTMI_PHY_EN (1<<9)
|
||||
#define SNOOP_SIZE_2GB 0x1e
|
||||
#endif /* _EHCI_FSL_H */
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
From 737186258370f25f44b7aa152ae1bef1e308a929 Mon Sep 17 00:00:00 2001
|
||||
From: Larry Finger <Larry.Finger@lwfinger.net>
|
||||
Date: Thu, 9 Feb 2012 16:37:17 -0600
|
||||
Subject: [PATCH 013/147] staging: r8712u: Add missing initialization and
|
||||
remove configuration parameter CONFIG_R8712_AP
|
||||
|
||||
commit 073863432f7eaa23c7c09733414d4be2eabf5eef upstream.
|
||||
|
||||
When this driver was upgraded to the vendor 20100831 version in
|
||||
commit 93c55dda092c7 et al,, one listhead initialization was missed.
|
||||
This broke complete operation of the driver whenever AP mode was
|
||||
enabled. This fixes https://bugs.archlinux.org/task/27996.
|
||||
|
||||
The configuration parameter R8712_AP is misleading as the driver cannot
|
||||
function as an AP without a heavily hacked version of hostapd. Thus, it
|
||||
makes sense to remove the parameter; however the code and data configured
|
||||
for the option is left in.
|
||||
|
||||
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/staging/rtl8712/Kconfig | 7 -------
|
||||
drivers/staging/rtl8712/rtl871x_sta_mgt.c | 5 +----
|
||||
drivers/staging/rtl8712/sta_info.h | 4 ----
|
||||
3 files changed, 1 insertion(+), 15 deletions(-)
|
||||
|
||||
diff --git a/drivers/staging/rtl8712/Kconfig b/drivers/staging/rtl8712/Kconfig
|
||||
index ea37473..6a43312 100644
|
||||
--- a/drivers/staging/rtl8712/Kconfig
|
||||
+++ b/drivers/staging/rtl8712/Kconfig
|
||||
@@ -9,13 +9,6 @@ config R8712U
|
||||
This option adds the Realtek RTL8712 USB device such as the D-Link DWA-130.
|
||||
If built as a module, it will be called r8712u.
|
||||
|
||||
-config R8712_AP
|
||||
- bool "Realtek RTL8712U AP code"
|
||||
- depends on R8712U
|
||||
- default N
|
||||
- ---help---
|
||||
- This option allows the Realtek RTL8712 USB device to be an Access Point.
|
||||
-
|
||||
config R8712_TX_AGGR
|
||||
bool "Realtek RTL8712U Transmit Aggregation code"
|
||||
depends on R8712U && BROKEN
|
||||
diff --git a/drivers/staging/rtl8712/rtl871x_sta_mgt.c b/drivers/staging/rtl8712/rtl871x_sta_mgt.c
|
||||
index 64f5696..1247b3d 100644
|
||||
--- a/drivers/staging/rtl8712/rtl871x_sta_mgt.c
|
||||
+++ b/drivers/staging/rtl8712/rtl871x_sta_mgt.c
|
||||
@@ -42,9 +42,8 @@ static void _init_stainfo(struct sta_info *psta)
|
||||
_init_listhead(&psta->hash_list);
|
||||
_r8712_init_sta_xmit_priv(&psta->sta_xmitpriv);
|
||||
_r8712_init_sta_recv_priv(&psta->sta_recvpriv);
|
||||
-#ifdef CONFIG_R8712_AP
|
||||
+ _init_listhead(&psta->asoc_list);
|
||||
_init_listhead(&psta->auth_list);
|
||||
-#endif
|
||||
}
|
||||
|
||||
u32 _r8712_init_sta_priv(struct sta_priv *pstapriv)
|
||||
@@ -71,10 +70,8 @@ u32 _r8712_init_sta_priv(struct sta_priv *pstapriv)
|
||||
get_list_head(&pstapriv->free_sta_queue));
|
||||
psta++;
|
||||
}
|
||||
-#ifdef CONFIG_R8712_AP
|
||||
_init_listhead(&pstapriv->asoc_list);
|
||||
_init_listhead(&pstapriv->auth_list);
|
||||
-#endif
|
||||
return _SUCCESS;
|
||||
}
|
||||
|
||||
diff --git a/drivers/staging/rtl8712/sta_info.h b/drivers/staging/rtl8712/sta_info.h
|
||||
index 48d6a14..f8016e9 100644
|
||||
--- a/drivers/staging/rtl8712/sta_info.h
|
||||
+++ b/drivers/staging/rtl8712/sta_info.h
|
||||
@@ -90,7 +90,6 @@ struct sta_info {
|
||||
* curr_network(mlme_priv/security_priv/qos/ht) : AP CAP/INFO
|
||||
* sta_info: (AP & STA) CAP/INFO
|
||||
*/
|
||||
-#ifdef CONFIG_R8712_AP
|
||||
struct list_head asoc_list;
|
||||
struct list_head auth_list;
|
||||
unsigned int expire_to;
|
||||
@@ -98,7 +97,6 @@ struct sta_info {
|
||||
unsigned int authalg;
|
||||
unsigned char chg_txt[128];
|
||||
unsigned int tx_ra_bitmap;
|
||||
-#endif
|
||||
};
|
||||
|
||||
struct sta_priv {
|
||||
@@ -111,13 +109,11 @@ struct sta_priv {
|
||||
struct __queue sleep_q;
|
||||
struct __queue wakeup_q;
|
||||
struct _adapter *padapter;
|
||||
-#ifdef CONFIG_R8712_AP
|
||||
struct list_head asoc_list;
|
||||
struct list_head auth_list;
|
||||
unsigned int auth_to; /* sec, time to expire in authenticating. */
|
||||
unsigned int assoc_to; /* sec, time to expire before associating. */
|
||||
unsigned int expire_to; /* sec , time to expire after associated. */
|
||||
-#endif
|
||||
};
|
||||
|
||||
static inline u32 wifi_mac_hash(u8 *mac)
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
From 10fcebe06f12c7f87ad05084848c51d69f118505 Mon Sep 17 00:00:00 2001
|
||||
From: Larry Finger <Larry.Finger@lwfinger.net>
|
||||
Date: Sat, 25 Feb 2012 18:10:20 -0600
|
||||
Subject: [PATCH 014/147] staging: r8712u: Fix regression introduced by commit
|
||||
a5ee652
|
||||
|
||||
commit 9f4bc8cf3fe750ed093856a5f5d41c11cc12ad22 upstream.
|
||||
|
||||
In commit a5ee652 "staging: r8712u: Interface-state not fully tracked",
|
||||
the private boolean "bup" was set false when the interface was brought down,
|
||||
as that seemed appropriate. This change has not caused any problems when
|
||||
using NetworkManager or manual control of the device; however, when wicd
|
||||
control is used, there is a locking problem in wpa_supplicant, as shown in
|
||||
https://bugzilla.kernel.org/show_bug.cgi?id=42818.
|
||||
|
||||
This fix reverts the only code change in commit a5ee652. My
|
||||
analysis is that "bup" is badly named. In its present form, it
|
||||
seems to indicate the up/down state of the device, but its usage
|
||||
is more consistent with an initialized/uninitialized state. That
|
||||
problem will be addressed in a later patch.
|
||||
|
||||
Note: Commit 8c213fa, which introdued asynchronous firmware loading
|
||||
for this driver, exposed this bug to a greater extent. That bug
|
||||
is addressed in the next patch in this series.
|
||||
|
||||
This bug is also responsible for the bug in
|
||||
https://bugzilla.kernel.org/show_bug.cgi?id=42815. and this bug is
|
||||
also part of the problems discussed at https://bugs.archlinux.org/task/27996#comment89950.
|
||||
|
||||
Tested-by: Alberto Lago Ballesteros <saniukeokusainaya@gmail.com>
|
||||
Tested-by: Adrian <agib@gmx.de>
|
||||
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/staging/rtl8712/os_intfs.c | 2 --
|
||||
1 file changed, 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/staging/rtl8712/os_intfs.c b/drivers/staging/rtl8712/os_intfs.c
|
||||
index 98a3d68..fb11743 100644
|
||||
--- a/drivers/staging/rtl8712/os_intfs.c
|
||||
+++ b/drivers/staging/rtl8712/os_intfs.c
|
||||
@@ -476,8 +476,6 @@ static int netdev_close(struct net_device *pnetdev)
|
||||
r8712_free_assoc_resources(padapter);
|
||||
/*s2-4.*/
|
||||
r8712_free_network_queue(padapter);
|
||||
- /* The interface is no longer Up: */
|
||||
- padapter->bup = false;
|
||||
release_firmware(padapter->fw);
|
||||
/* never exit with a firmware callback pending */
|
||||
wait_for_completion(&padapter->rtl8712_fw_ready);
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
From a8385f8f3089aba9d0d9b0faf580e89510648367 Mon Sep 17 00:00:00 2001
|
||||
From: Larry Finger <Larry.Finger@lwfinger.net>
|
||||
Date: Sun, 26 Feb 2012 22:08:36 -0600
|
||||
Subject: [PATCH 015/147] staging: r8712u: Fix regression in signal level
|
||||
after commit c6dc001
|
||||
|
||||
commit da3e6ec2f443ac00aa623c5921e3521f5f38efe4 upstream.
|
||||
|
||||
In commit c6dc001 "staging: r8712u: Merging Realtek's latest (v2.6.6).
|
||||
Various fixes", the returned qual.qual member of the iw_statistics
|
||||
struct was changed. For strong signals, this change made no difference;
|
||||
however for medium and weak signals it results in a low signal that
|
||||
shows considerable fluctuation, When using wicd for a medium-strength
|
||||
AP, the value reported in the status line is reduced from 100% to 60% by
|
||||
this bug.
|
||||
|
||||
This problem is reported in https://bugzilla.kernel.org/show_bug.cgi?id=42826.
|
||||
|
||||
Reported-and-tested-by: Robert Crawford <wrc1944@gmail.com>
|
||||
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/staging/rtl8712/rtl871x_ioctl_linux.c | 8 +-------
|
||||
1 file changed, 1 insertion(+), 7 deletions(-)
|
||||
|
||||
diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c
|
||||
index 507584b8..ef35bc2 100644
|
||||
--- a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c
|
||||
+++ b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c
|
||||
@@ -2380,13 +2380,7 @@ static struct iw_statistics *r871x_get_wireless_stats(struct net_device *dev)
|
||||
tmp_qual = padapter->recvpriv.signal;
|
||||
tmp_noise = padapter->recvpriv.noise;
|
||||
piwstats->qual.level = tmp_level;
|
||||
- /*piwstats->qual.qual = tmp_qual;
|
||||
- * The NetworkManager of Fedora 10, 13 will use the link
|
||||
- * quality for its display.
|
||||
- * So, use the fw_rssi on link quality variable because
|
||||
- * fw_rssi will be updated per 2 seconds.
|
||||
- */
|
||||
- piwstats->qual.qual = tmp_level;
|
||||
+ piwstats->qual.qual = tmp_qual;
|
||||
piwstats->qual.noise = tmp_noise;
|
||||
}
|
||||
piwstats->qual.updated = IW_QUAL_ALL_UPDATED;
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
From 0a7695bc47ddfdeaaa1b30b88912f38a481e3abd Mon Sep 17 00:00:00 2001
|
||||
From: Paul Zimmerman <Paul.Zimmerman@synopsys.com>
|
||||
Date: Fri, 17 Feb 2012 14:10:16 -0800
|
||||
Subject: [PATCH 016/147] usb: dwc3: fix bogus test in dwc3_gadget_start_isoc
|
||||
|
||||
commit 9bafa56c7cee5c6fa68de5924220abb220c7e229 upstream.
|
||||
|
||||
Zero is a valid value for a microframe number. So remove the bogus
|
||||
test for non-zero in dwc3_gadget_start_isoc().
|
||||
|
||||
Signed-off-by: Paul Zimmerman <paulz@synopsys.com>
|
||||
Signed-off-by: Felipe Balbi <balbi@ti.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/dwc3/gadget.c | 16 +++++-----------
|
||||
1 file changed, 5 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
|
||||
index 5802720..41a2ea6 100644
|
||||
--- a/drivers/usb/dwc3/gadget.c
|
||||
+++ b/drivers/usb/dwc3/gadget.c
|
||||
@@ -1405,7 +1405,7 @@ static void dwc3_endpoint_transfer_complete(struct dwc3 *dwc,
|
||||
static void dwc3_gadget_start_isoc(struct dwc3 *dwc,
|
||||
struct dwc3_ep *dep, const struct dwc3_event_depevt *event)
|
||||
{
|
||||
- u32 uf;
|
||||
+ u32 uf, mask;
|
||||
|
||||
if (list_empty(&dep->request_list)) {
|
||||
dev_vdbg(dwc->dev, "ISOC ep %s run out for requests.\n",
|
||||
@@ -1413,16 +1413,10 @@ static void dwc3_gadget_start_isoc(struct dwc3 *dwc,
|
||||
return;
|
||||
}
|
||||
|
||||
- if (event->parameters) {
|
||||
- u32 mask;
|
||||
-
|
||||
- mask = ~(dep->interval - 1);
|
||||
- uf = event->parameters & mask;
|
||||
- /* 4 micro frames in the future */
|
||||
- uf += dep->interval * 4;
|
||||
- } else {
|
||||
- uf = 0;
|
||||
- }
|
||||
+ mask = ~(dep->interval - 1);
|
||||
+ uf = event->parameters & mask;
|
||||
+ /* 4 micro frames in the future */
|
||||
+ uf += dep->interval * 4;
|
||||
|
||||
__dwc3_gadget_kick_transfer(dep, uf, 1);
|
||||
}
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
From cdbcc2f017a258caca6390e7353709a6603bc452 Mon Sep 17 00:00:00 2001
|
||||
From: Anton Tikhomirov <av.tikhomirov@samsung.com>
|
||||
Date: Thu, 23 Feb 2012 15:38:46 +0900
|
||||
Subject: [PATCH 017/147] usb: dwc3: use proper function for setting endpoint
|
||||
name
|
||||
|
||||
commit 27a78d6a283d6782438f72306746afe4bf44c215 upstream.
|
||||
|
||||
It's wrong to use the size of array as an argument for strncat.
|
||||
Memory corruption is possible. strlcat is exactly what we need here.
|
||||
|
||||
Signed-off-by: Anton Tikhomirov <av.tikhomirov@samsung.com>
|
||||
Signed-off-by: Felipe Balbi <balbi@ti.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/dwc3/gadget.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
|
||||
index 41a2ea6..dfcda94 100644
|
||||
--- a/drivers/usb/dwc3/gadget.c
|
||||
+++ b/drivers/usb/dwc3/gadget.c
|
||||
@@ -449,16 +449,16 @@ static int dwc3_gadget_ep_enable(struct usb_ep *ep,
|
||||
|
||||
switch (usb_endpoint_type(desc)) {
|
||||
case USB_ENDPOINT_XFER_CONTROL:
|
||||
- strncat(dep->name, "-control", sizeof(dep->name));
|
||||
+ strlcat(dep->name, "-control", sizeof(dep->name));
|
||||
break;
|
||||
case USB_ENDPOINT_XFER_ISOC:
|
||||
- strncat(dep->name, "-isoc", sizeof(dep->name));
|
||||
+ strlcat(dep->name, "-isoc", sizeof(dep->name));
|
||||
break;
|
||||
case USB_ENDPOINT_XFER_BULK:
|
||||
- strncat(dep->name, "-bulk", sizeof(dep->name));
|
||||
+ strlcat(dep->name, "-bulk", sizeof(dep->name));
|
||||
break;
|
||||
case USB_ENDPOINT_XFER_INT:
|
||||
- strncat(dep->name, "-int", sizeof(dep->name));
|
||||
+ strlcat(dep->name, "-int", sizeof(dep->name));
|
||||
break;
|
||||
default:
|
||||
dev_err(dwc->dev, "invalid endpoint transfer type\n");
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
From 868208aaab0df10df8bff2cb3bc2ccae0fa0a16d Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Faber <thfabba@gmx.de>
|
||||
Date: Fri, 2 Mar 2012 09:41:50 +0100
|
||||
Subject: [PATCH 018/147] usb: gadgetfs: return number of bytes on ep0 read
|
||||
request
|
||||
|
||||
commit 85b4b3c8c189e0159101f7628a71411af072ff69 upstream.
|
||||
|
||||
A read from GadgetFS endpoint 0 during the data stage of a control
|
||||
request would always return 0 on success (as returned by
|
||||
wait_event_interruptible) despite having written data into the user
|
||||
buffer.
|
||||
This patch makes it correctly set the return value to the number of
|
||||
bytes read.
|
||||
|
||||
Signed-off-by: Thomas Faber <thfabba@gmx.de>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/gadget/inode.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c
|
||||
index 9361251..2a96f57 100644
|
||||
--- a/drivers/usb/gadget/inode.c
|
||||
+++ b/drivers/usb/gadget/inode.c
|
||||
@@ -1043,6 +1043,8 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr)
|
||||
// FIXME don't call this with the spinlock held ...
|
||||
if (copy_to_user (buf, dev->req->buf, len))
|
||||
retval = -EFAULT;
|
||||
+ else
|
||||
+ retval = len;
|
||||
clean_req (dev->gadget->ep0, dev->req);
|
||||
/* NOTE userspace can't yet choose to stall */
|
||||
}
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
From 68f1d29a63c33ab9478d1d5b11d4ba522fa3d167 Mon Sep 17 00:00:00 2001
|
||||
From: Orjan Friberg <of@flatfrog.com>
|
||||
Date: Wed, 7 Mar 2012 17:16:14 +0100
|
||||
Subject: [PATCH 019/147] USB: gadget: Make g_hid device class conform to
|
||||
spec.
|
||||
|
||||
commit 33d2832ab0149a26418d360af3c444969a63fb28 upstream.
|
||||
|
||||
HID devices should specify this in their interface descriptors, not in the
|
||||
device descriptor. This fixes a "missing hardware id" bug under Windows 7 with
|
||||
a VIA VL800 (3.0) controller.
|
||||
|
||||
Signed-off-by: Orjan Friberg <of@flatfrog.com>
|
||||
Cc: Felipe Balbi <balbi@ti.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/gadget/hid.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/usb/gadget/hid.c b/drivers/usb/gadget/hid.c
|
||||
index f888c3e..3493adf 100644
|
||||
--- a/drivers/usb/gadget/hid.c
|
||||
+++ b/drivers/usb/gadget/hid.c
|
||||
@@ -60,9 +60,9 @@ static struct usb_device_descriptor device_desc = {
|
||||
/* .bDeviceClass = USB_CLASS_COMM, */
|
||||
/* .bDeviceSubClass = 0, */
|
||||
/* .bDeviceProtocol = 0, */
|
||||
- .bDeviceClass = 0xEF,
|
||||
- .bDeviceSubClass = 2,
|
||||
- .bDeviceProtocol = 1,
|
||||
+ .bDeviceClass = USB_CLASS_PER_INTERFACE,
|
||||
+ .bDeviceSubClass = 0,
|
||||
+ .bDeviceProtocol = 0,
|
||||
/* .bMaxPacketSize0 = f(hardware) */
|
||||
|
||||
/* Vendor and product id can be overridden by module parameters. */
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
From 67cc4b87ba54c6101c7fd5dbde9b2547463339d1 Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Gleixner <tglx@linutronix.de>
|
||||
Date: Wed, 15 Feb 2012 12:08:34 +0100
|
||||
Subject: [PATCH 020/147] futex: Cover all PI opcodes with cmpxchg enabled
|
||||
check
|
||||
|
||||
commit 59263b513c11398cd66a52d4c5b2b118ce1e0359 upstream.
|
||||
|
||||
Some of the newer futex PI opcodes do not check the cmpxchg enabled
|
||||
variable and call unconditionally into the handling functions. Cover
|
||||
all PI opcodes in a separate check.
|
||||
|
||||
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Darren Hart <dvhart@linux.intel.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
kernel/futex.c | 19 +++++++++++++------
|
||||
1 file changed, 13 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/kernel/futex.c b/kernel/futex.c
|
||||
index 1614be2..0677023 100644
|
||||
--- a/kernel/futex.c
|
||||
+++ b/kernel/futex.c
|
||||
@@ -2641,6 +2641,16 @@ long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout,
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
+ case FUTEX_LOCK_PI:
|
||||
+ case FUTEX_UNLOCK_PI:
|
||||
+ case FUTEX_TRYLOCK_PI:
|
||||
+ case FUTEX_WAIT_REQUEUE_PI:
|
||||
+ case FUTEX_CMP_REQUEUE_PI:
|
||||
+ if (!futex_cmpxchg_enabled)
|
||||
+ return -ENOSYS;
|
||||
+ }
|
||||
+
|
||||
+ switch (cmd) {
|
||||
case FUTEX_WAIT:
|
||||
val3 = FUTEX_BITSET_MATCH_ANY;
|
||||
case FUTEX_WAIT_BITSET:
|
||||
@@ -2661,16 +2671,13 @@ long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout,
|
||||
ret = futex_wake_op(uaddr, flags, uaddr2, val, val2, val3);
|
||||
break;
|
||||
case FUTEX_LOCK_PI:
|
||||
- if (futex_cmpxchg_enabled)
|
||||
- ret = futex_lock_pi(uaddr, flags, val, timeout, 0);
|
||||
+ ret = futex_lock_pi(uaddr, flags, val, timeout, 0);
|
||||
break;
|
||||
case FUTEX_UNLOCK_PI:
|
||||
- if (futex_cmpxchg_enabled)
|
||||
- ret = futex_unlock_pi(uaddr, flags);
|
||||
+ ret = futex_unlock_pi(uaddr, flags);
|
||||
break;
|
||||
case FUTEX_TRYLOCK_PI:
|
||||
- if (futex_cmpxchg_enabled)
|
||||
- ret = futex_lock_pi(uaddr, flags, 0, timeout, 1);
|
||||
+ ret = futex_lock_pi(uaddr, flags, 0, timeout, 1);
|
||||
break;
|
||||
case FUTEX_WAIT_REQUEUE_PI:
|
||||
val3 = FUTEX_BITSET_MATCH_ANY;
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
From 58d245d715be41e6b0d736466a9589d75156f0ff Mon Sep 17 00:00:00 2001
|
||||
From: Masami Ichikawa <masami256@gmail.com>
|
||||
Date: Tue, 21 Feb 2012 07:43:50 +0900
|
||||
Subject: [PATCH 021/147] sysfs: Fix memory leak in sysfs_sd_setsecdata().
|
||||
|
||||
commit 93518dd2ebafcc761a8637b2877008cfd748c202 upstream.
|
||||
|
||||
This patch fixies follwing two memory leak patterns that reported by kmemleak.
|
||||
sysfs_sd_setsecdata() is called during sys_lsetxattr() operation.
|
||||
It checks sd->s_iattr is NULL or not. Then if it is NULL, it calls
|
||||
sysfs_init_inode_attrs() to allocate memory.
|
||||
That code is this.
|
||||
|
||||
iattrs = sd->s_iattr;
|
||||
if (!iattrs)
|
||||
iattrs = sysfs_init_inode_attrs(sd);
|
||||
|
||||
The iattrs recieves sysfs_init_inode_attrs()'s result, but sd->s_iattr
|
||||
doesn't know the address. so it needs to set correct address to
|
||||
sd->s_iattr to free memory in other function.
|
||||
|
||||
unreferenced object 0xffff880250b73e60 (size 32):
|
||||
comm "systemd", pid 1, jiffies 4294683888 (age 94.553s)
|
||||
hex dump (first 32 bytes):
|
||||
73 79 73 74 65 6d 5f 75 3a 6f 62 6a 65 63 74 5f system_u:object_
|
||||
72 3a 73 79 73 66 73 5f 74 3a 73 30 00 00 00 00 r:sysfs_t:s0....
|
||||
backtrace:
|
||||
[<ffffffff814cb1d0>] kmemleak_alloc+0x73/0x98
|
||||
[<ffffffff811270ab>] __kmalloc+0x100/0x12c
|
||||
[<ffffffff8120775a>] context_struct_to_string+0x106/0x210
|
||||
[<ffffffff81207cc1>] security_sid_to_context_core+0x10b/0x129
|
||||
[<ffffffff812090ef>] security_sid_to_context+0x10/0x12
|
||||
[<ffffffff811fb0da>] selinux_inode_getsecurity+0x7d/0xa8
|
||||
[<ffffffff811fb127>] selinux_inode_getsecctx+0x22/0x2e
|
||||
[<ffffffff811f4d62>] security_inode_getsecctx+0x16/0x18
|
||||
[<ffffffff81191dad>] sysfs_setxattr+0x96/0x117
|
||||
[<ffffffff811542f0>] __vfs_setxattr_noperm+0x73/0xd9
|
||||
[<ffffffff811543d9>] vfs_setxattr+0x83/0xa1
|
||||
[<ffffffff811544c6>] setxattr+0xcf/0x101
|
||||
[<ffffffff81154745>] sys_lsetxattr+0x6a/0x8f
|
||||
[<ffffffff814efda9>] system_call_fastpath+0x16/0x1b
|
||||
[<ffffffffffffffff>] 0xffffffffffffffff
|
||||
unreferenced object 0xffff88024163c5a0 (size 96):
|
||||
comm "systemd", pid 1, jiffies 4294683888 (age 94.553s)
|
||||
hex dump (first 32 bytes):
|
||||
00 00 00 00 ed 41 00 00 00 00 00 00 00 00 00 00 .....A..........
|
||||
00 00 00 00 00 00 00 00 0c 64 42 4f 00 00 00 00 .........dBO....
|
||||
backtrace:
|
||||
[<ffffffff814cb1d0>] kmemleak_alloc+0x73/0x98
|
||||
[<ffffffff81127402>] kmem_cache_alloc_trace+0xc4/0xee
|
||||
[<ffffffff81191cbe>] sysfs_init_inode_attrs+0x2a/0x83
|
||||
[<ffffffff81191dd6>] sysfs_setxattr+0xbf/0x117
|
||||
[<ffffffff811542f0>] __vfs_setxattr_noperm+0x73/0xd9
|
||||
[<ffffffff811543d9>] vfs_setxattr+0x83/0xa1
|
||||
[<ffffffff811544c6>] setxattr+0xcf/0x101
|
||||
[<ffffffff81154745>] sys_lsetxattr+0x6a/0x8f
|
||||
[<ffffffff814efda9>] system_call_fastpath+0x16/0x1b
|
||||
[<ffffffffffffffff>] 0xffffffffffffffff
|
||||
`
|
||||
|
||||
Signed-off-by: Masami Ichikawa <masami256@gmail.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
fs/sysfs/inode.c | 11 ++++++-----
|
||||
1 file changed, 6 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
|
||||
index deb804b..9db61a4 100644
|
||||
--- a/fs/sysfs/inode.c
|
||||
+++ b/fs/sysfs/inode.c
|
||||
@@ -136,12 +136,13 @@ static int sysfs_sd_setsecdata(struct sysfs_dirent *sd, void **secdata, u32 *sec
|
||||
void *old_secdata;
|
||||
size_t old_secdata_len;
|
||||
|
||||
- iattrs = sd->s_iattr;
|
||||
- if (!iattrs)
|
||||
- iattrs = sysfs_init_inode_attrs(sd);
|
||||
- if (!iattrs)
|
||||
- return -ENOMEM;
|
||||
+ if (!sd->s_iattr) {
|
||||
+ sd->s_iattr = sysfs_init_inode_attrs(sd);
|
||||
+ if (!sd->s_iattr)
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
|
||||
+ iattrs = sd->s_iattr;
|
||||
old_secdata = iattrs->ia_secdata;
|
||||
old_secdata_len = iattrs->ia_secdata_len;
|
||||
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
From 94f82d523fc497167379eb0624420a2bd535103d Mon Sep 17 00:00:00 2001
|
||||
From: Dan Carpenter <dan.carpenter@oracle.com>
|
||||
Date: Wed, 7 Mar 2012 13:05:00 +0300
|
||||
Subject: [PATCH 022/147] tty: moxa: fix bit test in moxa_start()
|
||||
|
||||
commit 58112dfbfe02d803566a2c6c8bd97b5fa3c62cdc upstream.
|
||||
|
||||
This is supposed to be doing a shift before the comparison instead of
|
||||
just doing a bitwise AND directly. The current code means the start()
|
||||
just returns without doing anything.
|
||||
|
||||
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
|
||||
Acked-by: Jiri Slaby <jslaby@suse.cz>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/tty/moxa.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/tty/moxa.c b/drivers/tty/moxa.c
|
||||
index d15a071..0174d2d 100644
|
||||
--- a/drivers/tty/moxa.c
|
||||
+++ b/drivers/tty/moxa.c
|
||||
@@ -1331,7 +1331,7 @@ static void moxa_start(struct tty_struct *tty)
|
||||
if (ch == NULL)
|
||||
return;
|
||||
|
||||
- if (!(ch->statusflags & TXSTOPPED))
|
||||
+ if (!test_bit(TXSTOPPED, &ch->statusflags))
|
||||
return;
|
||||
|
||||
MoxaPortTxEnable(ch);
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
From 7d00c6261eadb39ffffd02141aa566deda4d7cb3 Mon Sep 17 00:00:00 2001
|
||||
From: Liz Clark <liz.clark@hp.com>
|
||||
Date: Thu, 15 Mar 2012 10:33:29 -0700
|
||||
Subject: [PATCH 023/147] TTY: Wrong unicode value copied in con_set_unimap()
|
||||
|
||||
commit 4a4c61b7ce26bfc9d49ea4bd121d52114bad9f99 upstream.
|
||||
|
||||
Bugzilla 40012: PIO_UNIMAP bug: error updating Unicode-to-font map
|
||||
https://bugzilla.kernel.org/show_bug.cgi?id=40012
|
||||
|
||||
The unicode font map for the virtual console is a 32x32x64 table which
|
||||
allocates rows dynamically as entries are added. The unicode value
|
||||
increases sequentially and should count all entries even in empty
|
||||
rows. The defect is when copying the unicode font map in con_set_unimap(),
|
||||
the unicode value is not incremented properly. The wrong unicode value
|
||||
is entered in the new font map.
|
||||
|
||||
Signed-off-by: Liz Clark <liz.clark@hp.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/tty/vt/consolemap.c | 51 ++++++++++++++++++++++++++++++++++++-------
|
||||
1 file changed, 43 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/drivers/tty/vt/consolemap.c b/drivers/tty/vt/consolemap.c
|
||||
index 45d3e80..f343808 100644
|
||||
--- a/drivers/tty/vt/consolemap.c
|
||||
+++ b/drivers/tty/vt/consolemap.c
|
||||
@@ -516,6 +516,7 @@ int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list)
|
||||
int err = 0, err1, i;
|
||||
struct uni_pagedir *p, *q;
|
||||
|
||||
+ /* Save original vc_unipagdir_loc in case we allocate a new one */
|
||||
p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc;
|
||||
if (p->readonly) return -EIO;
|
||||
|
||||
@@ -528,26 +529,57 @@ int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list)
|
||||
err1 = con_clear_unimap(vc, NULL);
|
||||
if (err1) return err1;
|
||||
|
||||
+ /*
|
||||
+ * Since refcount was > 1, con_clear_unimap() allocated a
|
||||
+ * a new uni_pagedir for this vc. Re: p != q
|
||||
+ */
|
||||
q = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc;
|
||||
- for (i = 0, l = 0; i < 32; i++)
|
||||
+
|
||||
+ /*
|
||||
+ * uni_pgdir is a 32*32*64 table with rows allocated
|
||||
+ * when its first entry is added. The unicode value must
|
||||
+ * still be incremented for empty rows. We are copying
|
||||
+ * entries from "p" (old) to "q" (new).
|
||||
+ */
|
||||
+ l = 0; /* unicode value */
|
||||
+ for (i = 0; i < 32; i++)
|
||||
if ((p1 = p->uni_pgdir[i]))
|
||||
for (j = 0; j < 32; j++)
|
||||
- if ((p2 = p1[j]))
|
||||
+ if ((p2 = p1[j])) {
|
||||
for (k = 0; k < 64; k++, l++)
|
||||
if (p2[k] != 0xffff) {
|
||||
+ /*
|
||||
+ * Found one, copy entry for unicode
|
||||
+ * l with fontpos value p2[k].
|
||||
+ */
|
||||
err1 = con_insert_unipair(q, l, p2[k]);
|
||||
if (err1) {
|
||||
p->refcount++;
|
||||
*vc->vc_uni_pagedir_loc = (unsigned long)p;
|
||||
con_release_unimap(q);
|
||||
kfree(q);
|
||||
- return err1;
|
||||
+ return err1;
|
||||
}
|
||||
- }
|
||||
- p = q;
|
||||
- } else if (p == dflt)
|
||||
+ }
|
||||
+ } else {
|
||||
+ /* Account for row of 64 empty entries */
|
||||
+ l += 64;
|
||||
+ }
|
||||
+ else
|
||||
+ /* Account for empty table */
|
||||
+ l += 32 * 64;
|
||||
+
|
||||
+ /*
|
||||
+ * Finished copying font table, set vc_uni_pagedir to new table
|
||||
+ */
|
||||
+ p = q;
|
||||
+ } else if (p == dflt) {
|
||||
dflt = NULL;
|
||||
-
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Insert user specified unicode pairs into new table.
|
||||
+ */
|
||||
while (ct--) {
|
||||
unsigned short unicode, fontpos;
|
||||
__get_user(unicode, &list->unicode);
|
||||
@@ -557,11 +589,14 @@ int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list)
|
||||
list++;
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * Merge with fontmaps of any other virtual consoles.
|
||||
+ */
|
||||
if (con_unify_unimap(vc, p))
|
||||
return err;
|
||||
|
||||
for (i = 0; i <= 3; i++)
|
||||
- set_inverse_transl(vc, p, i); /* Update all inverse translations */
|
||||
+ set_inverse_transl(vc, p, i); /* Update inverse translations */
|
||||
set_inverse_trans_unicode(vc, p);
|
||||
|
||||
return err;
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
From 6a49ff9d91721997f9c625b79e70b9a37bfdf10f Mon Sep 17 00:00:00 2001
|
||||
From: Johan Hovold <jhovold@gmail.com>
|
||||
Date: Fri, 10 Feb 2012 13:20:49 +0100
|
||||
Subject: [PATCH 024/147] USB: serial: fix console error reporting
|
||||
|
||||
commit 548dd4b6da8a8e428453d55f7fa7b8a46498d147 upstream.
|
||||
|
||||
Do not report errors in write path if port is used as a console as this
|
||||
may trigger the same error (and error report) resulting in a loop.
|
||||
|
||||
Reported-by: Stephen Hemminger <shemminger@vyatta.com>
|
||||
Signed-off-by: Johan Hovold <jhovold@gmail.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/serial/generic.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
|
||||
index e4db5ad..9f0b2bf 100644
|
||||
--- a/drivers/usb/serial/generic.c
|
||||
+++ b/drivers/usb/serial/generic.c
|
||||
@@ -215,8 +215,10 @@ retry:
|
||||
clear_bit(i, &port->write_urbs_free);
|
||||
result = usb_submit_urb(urb, GFP_ATOMIC);
|
||||
if (result) {
|
||||
- dev_err(&port->dev, "%s - error submitting urb: %d\n",
|
||||
+ if (!port->port.console) {
|
||||
+ dev_err(&port->dev, "%s - error submitting urb: %d\n",
|
||||
__func__, result);
|
||||
+ }
|
||||
set_bit(i, &port->write_urbs_free);
|
||||
spin_lock_irqsave(&port->lock, flags);
|
||||
port->tx_bytes -= count;
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
From 028d778c63336663590f673854c0e128e1b8fa34 Mon Sep 17 00:00:00 2001
|
||||
From: Ben Hutchings <ben@decadent.org.uk>
|
||||
Date: Sun, 12 Feb 2012 06:00:41 +0000
|
||||
Subject: [PATCH 025/147] cdc-wdm: Fix more races on the read path
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
commit 711c68b3c0f7a924ffbee4aa962d8f62b85188ff upstream.
|
||||
|
||||
We must not allow the input buffer length to change while we're
|
||||
shuffling the buffer contents. We also mustn't clear the WDM_READ
|
||||
flag after more data might have arrived. Therefore move both of these
|
||||
into the spinlocked region at the bottom of wdm_read().
|
||||
|
||||
When reading desc->length without holding the iuspin lock, use
|
||||
ACCESS_ONCE() to ensure the compiler doesn't re-read it with
|
||||
inconsistent results.
|
||||
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
Tested-by: Bj??rn Mork <bjorn@mork.no>
|
||||
Cc: Oliver Neukum <oliver@neukum.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/class/cdc-wdm.c | 16 +++++++++++-----
|
||||
1 file changed, 11 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
|
||||
index fd4aee1..eb650b7 100644
|
||||
--- a/drivers/usb/class/cdc-wdm.c
|
||||
+++ b/drivers/usb/class/cdc-wdm.c
|
||||
@@ -397,7 +397,7 @@ outnl:
|
||||
static ssize_t wdm_read
|
||||
(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
|
||||
{
|
||||
- int rv, cntr = 0;
|
||||
+ int rv, cntr;
|
||||
int i = 0;
|
||||
struct wdm_device *desc = file->private_data;
|
||||
|
||||
@@ -406,7 +406,8 @@ static ssize_t wdm_read
|
||||
if (rv < 0)
|
||||
return -ERESTARTSYS;
|
||||
|
||||
- if (desc->length == 0) {
|
||||
+ cntr = ACCESS_ONCE(desc->length);
|
||||
+ if (cntr == 0) {
|
||||
desc->read = 0;
|
||||
retry:
|
||||
if (test_bit(WDM_DISCONNECTING, &desc->flags)) {
|
||||
@@ -457,25 +458,30 @@ retry:
|
||||
goto retry;
|
||||
}
|
||||
clear_bit(WDM_READ, &desc->flags);
|
||||
+ cntr = desc->length;
|
||||
spin_unlock_irq(&desc->iuspin);
|
||||
}
|
||||
|
||||
- cntr = count > desc->length ? desc->length : count;
|
||||
+ if (cntr > count)
|
||||
+ cntr = count;
|
||||
rv = copy_to_user(buffer, desc->ubuf, cntr);
|
||||
if (rv > 0) {
|
||||
rv = -EFAULT;
|
||||
goto err;
|
||||
}
|
||||
|
||||
+ spin_lock_irq(&desc->iuspin);
|
||||
+
|
||||
for (i = 0; i < desc->length - cntr; i++)
|
||||
desc->ubuf[i] = desc->ubuf[i + cntr];
|
||||
|
||||
- spin_lock_irq(&desc->iuspin);
|
||||
desc->length -= cntr;
|
||||
- spin_unlock_irq(&desc->iuspin);
|
||||
/* in case we had outstanding data */
|
||||
if (!desc->length)
|
||||
clear_bit(WDM_READ, &desc->flags);
|
||||
+
|
||||
+ spin_unlock_irq(&desc->iuspin);
|
||||
+
|
||||
rv = cntr;
|
||||
|
||||
err:
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
From 77094c1a611d4c874a2903e9a702d35a4f5a6be9 Mon Sep 17 00:00:00 2001
|
||||
From: Ben Hutchings <ben@decadent.org.uk>
|
||||
Date: Sun, 12 Feb 2012 06:02:43 +0000
|
||||
Subject: [PATCH 026/147] cdc-wdm: Don't clear WDM_READ unless entire read
|
||||
buffer is emptied
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
commit b7a205545345578712611106b371538992e142ff upstream.
|
||||
|
||||
The WDM_READ flag is cleared later iff desc->length is reduced to 0.
|
||||
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
Tested-by: Bj??rn Mork <bjorn@mork.no>
|
||||
Cc: Oliver Neukum <oliver@neukum.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/class/cdc-wdm.c | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
|
||||
index eb650b7..9eb71d8 100644
|
||||
--- a/drivers/usb/class/cdc-wdm.c
|
||||
+++ b/drivers/usb/class/cdc-wdm.c
|
||||
@@ -457,7 +457,6 @@ retry:
|
||||
spin_unlock_irq(&desc->iuspin);
|
||||
goto retry;
|
||||
}
|
||||
- clear_bit(WDM_READ, &desc->flags);
|
||||
cntr = desc->length;
|
||||
spin_unlock_irq(&desc->iuspin);
|
||||
}
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
From 0e5ef14de4874bc31ca8ab4bd1759ead8151950e Mon Sep 17 00:00:00 2001
|
||||
From: Peter Chen <peter.chen@freescale.com>
|
||||
Date: Thu, 16 Feb 2012 09:36:25 +0800
|
||||
Subject: [PATCH 027/147] usb: fsl_udc_core: Fix scheduling while atomic dump
|
||||
message
|
||||
|
||||
commit c5cc5ed86667d4ae74fe40ee4ed893f4b46aba05 upstream.
|
||||
|
||||
When loading g_ether gadget, there is below message:
|
||||
|
||||
Backtrace:
|
||||
[<80012248>] (dump_backtrace+0x0/0x10c) from [<803cb42c>] (dump_stack+0x18/0x1c)
|
||||
r7:00000000 r6:80512000 r5:8052bef8 r4:80513f30
|
||||
[<803cb414>] (dump_stack+0x0/0x1c) from [<8000feb4>] (show_regs+0x44/0x50)
|
||||
[<8000fe70>] (show_regs+0x0/0x50) from [<8004c840>] (__schedule_bug+0x68/0x84)
|
||||
r5:8052bef8 r4:80513f30
|
||||
[<8004c7d8>] (__schedule_bug+0x0/0x84) from [<803cd0e4>] (__schedule+0x4b0/0x528)
|
||||
r5:8052bef8 r4:809aad00
|
||||
[<803ccc34>] (__schedule+0x0/0x528) from [<803cd214>] (_cond_resched+0x44/0x58)
|
||||
[<803cd1d0>] (_cond_resched+0x0/0x58) from [<800a9488>] (dma_pool_alloc+0x184/0x250)
|
||||
r5:9f9b4000 r4:9fb4fb80
|
||||
[<800a9304>] (dma_pool_alloc+0x0/0x250) from [<802a8ad8>] (fsl_req_to_dtd+0xac/0x180)
|
||||
[<802a8a2c>] (fsl_req_to_dtd+0x0/0x180) from [<802a8ce4>] (fsl_ep_queue+0x138/0x274)
|
||||
[<802a8bac>] (fsl_ep_queue+0x0/0x274) from [<7f004328>] (composite_setup+0x2d4/0xfac [g_ether])
|
||||
[<7f004054>] (composite_setup+0x0/0xfac [g_ether]) from [<802a9bb4>] (fsl_udc_irq+0x8dc/0xd38)
|
||||
[<802a92d8>] (fsl_udc_irq+0x0/0xd38) from [<800704f8>] (handle_irq_event_percpu+0x54/0x188)
|
||||
[<800704a4>] (handle_irq_event_percpu+0x0/0x188) from [<80070674>] (handle_irq_event+0x48/0x68)
|
||||
[<8007062c>] (handle_irq_event+0x0/0x68) from [<800738ec>] (handle_level_irq+0xb4/0x138)
|
||||
r5:80514f94 r4:80514f40
|
||||
[<80073838>] (handle_level_irq+0x0/0x138) from [<8006ffa4>] (generic_handle_irq+0x38/0x44)
|
||||
r7:00000012 r6:80510b1c r5:80529860 r4:80512000
|
||||
[<8006ff6c>] (generic_handle_irq+0x0/0x44) from [<8000f4c4>] (handle_IRQ+0x54/0xb4)
|
||||
[<8000f470>] (handle_IRQ+0x0/0xb4) from [<800085b8>] (tzic_handle_irq+0x64/0x94)
|
||||
r9:412fc085 r8:00000000 r7:80513f30 r6:00000001 r5:00000000
|
||||
r4:00000000
|
||||
[<80008554>] (tzic_handle_irq+0x0/0x94) from [<8000e680>] (__irq_svc+0x40/0x60)
|
||||
|
||||
The reason of above dump message is calling dma_poll_alloc with can-schedule
|
||||
mem_flags at atomic context.
|
||||
|
||||
To fix this problem, below changes are made:
|
||||
- fsl_req_to_dtd doesn't need to be protected by spin_lock_irqsave,
|
||||
as struct usb_request can be access at process context. Move lock
|
||||
to beginning of hardware visit (fsl_queue_td).
|
||||
- Change the memory flag which using to allocate dTD descriptor buffer,
|
||||
the memory flag can be from gadget layer.
|
||||
|
||||
It is tested at i.mx51 bbg board with g_mass_storage, g_ether, g_serial.
|
||||
|
||||
Signed-off-by: Peter Chen <peter.chen@freescale.com>
|
||||
Acked-by: Li Yang <leoli@freescale.com>
|
||||
Signed-off-by: Felipe Balbi <balbi@ti.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/gadget/fsl_udc_core.c | 18 ++++++++----------
|
||||
1 file changed, 8 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c
|
||||
index d7ea6c0..9085d14 100644
|
||||
--- a/drivers/usb/gadget/fsl_udc_core.c
|
||||
+++ b/drivers/usb/gadget/fsl_udc_core.c
|
||||
@@ -768,7 +768,7 @@ static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req)
|
||||
* @is_last: return flag if it is the last dTD of the request
|
||||
* return: pointer to the built dTD */
|
||||
static struct ep_td_struct *fsl_build_dtd(struct fsl_req *req, unsigned *length,
|
||||
- dma_addr_t *dma, int *is_last)
|
||||
+ dma_addr_t *dma, int *is_last, gfp_t gfp_flags)
|
||||
{
|
||||
u32 swap_temp;
|
||||
struct ep_td_struct *dtd;
|
||||
@@ -777,7 +777,7 @@ static struct ep_td_struct *fsl_build_dtd(struct fsl_req *req, unsigned *length,
|
||||
*length = min(req->req.length - req->req.actual,
|
||||
(unsigned)EP_MAX_LENGTH_TRANSFER);
|
||||
|
||||
- dtd = dma_pool_alloc(udc_controller->td_pool, GFP_KERNEL, dma);
|
||||
+ dtd = dma_pool_alloc(udc_controller->td_pool, gfp_flags, dma);
|
||||
if (dtd == NULL)
|
||||
return dtd;
|
||||
|
||||
@@ -827,7 +827,7 @@ static struct ep_td_struct *fsl_build_dtd(struct fsl_req *req, unsigned *length,
|
||||
}
|
||||
|
||||
/* Generate dtd chain for a request */
|
||||
-static int fsl_req_to_dtd(struct fsl_req *req)
|
||||
+static int fsl_req_to_dtd(struct fsl_req *req, gfp_t gfp_flags)
|
||||
{
|
||||
unsigned count;
|
||||
int is_last;
|
||||
@@ -836,7 +836,7 @@ static int fsl_req_to_dtd(struct fsl_req *req)
|
||||
dma_addr_t dma;
|
||||
|
||||
do {
|
||||
- dtd = fsl_build_dtd(req, &count, &dma, &is_last);
|
||||
+ dtd = fsl_build_dtd(req, &count, &dma, &is_last, gfp_flags);
|
||||
if (dtd == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -910,13 +910,11 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
|
||||
req->req.actual = 0;
|
||||
req->dtd_count = 0;
|
||||
|
||||
- spin_lock_irqsave(&udc->lock, flags);
|
||||
-
|
||||
/* build dtds and push them to device queue */
|
||||
- if (!fsl_req_to_dtd(req)) {
|
||||
+ if (!fsl_req_to_dtd(req, gfp_flags)) {
|
||||
+ spin_lock_irqsave(&udc->lock, flags);
|
||||
fsl_queue_td(ep, req);
|
||||
} else {
|
||||
- spin_unlock_irqrestore(&udc->lock, flags);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@@ -1295,7 +1293,7 @@ static int ep0_prime_status(struct fsl_udc *udc, int direction)
|
||||
ep_is_in(ep) ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
|
||||
req->mapped = 1;
|
||||
|
||||
- if (fsl_req_to_dtd(req) == 0)
|
||||
+ if (fsl_req_to_dtd(req, GFP_ATOMIC) == 0)
|
||||
fsl_queue_td(ep, req);
|
||||
else
|
||||
return -ENOMEM;
|
||||
@@ -1379,7 +1377,7 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value,
|
||||
req->mapped = 1;
|
||||
|
||||
/* prime the data phase */
|
||||
- if ((fsl_req_to_dtd(req) == 0))
|
||||
+ if ((fsl_req_to_dtd(req, GFP_ATOMIC) == 0))
|
||||
fsl_queue_td(ep, req);
|
||||
else /* no mem */
|
||||
goto stall;
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
From 14449b27e92835504278ce397b02ca2b183cbd31 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Chen <peter.chen@freescale.com>
|
||||
Date: Thu, 16 Feb 2012 09:41:52 +0800
|
||||
Subject: [PATCH 028/147] usb: Fix build error due to dma_mask is not at
|
||||
pdev_archdata at ARM
|
||||
|
||||
commit e90fc3cb087ce5c5f81e814358222cd6d197b5db upstream.
|
||||
|
||||
When build i.mx platform with imx_v6_v7_defconfig, and after adding
|
||||
USB Gadget support, it has below build error:
|
||||
|
||||
CC drivers/usb/host/fsl-mph-dr-of.o
|
||||
drivers/usb/host/fsl-mph-dr-of.c: In function 'fsl_usb2_device_register':
|
||||
drivers/usb/host/fsl-mph-dr-of.c:97: error: 'struct pdev_archdata'
|
||||
has no member named 'dma_mask'
|
||||
|
||||
It has discussed at: http://www.spinics.net/lists/linux-usb/msg57302.html
|
||||
|
||||
For PowerPC, there is dma_mask at struct pdev_archdata, but there is
|
||||
no dma_mask at struct pdev_archdata for ARM. The pdev_archdata is
|
||||
related to specific platform, it should NOT be accessed by
|
||||
cross platform drivers, like USB.
|
||||
|
||||
The code for pdev_archdata should be useless, as for PowerPC,
|
||||
it has already gotten the value for pdev->dev.dma_mask at function
|
||||
arch_setup_pdev_archdata of arch/powerpc/kernel/setup-common.c.
|
||||
|
||||
Tested-by: Ramneek Mehresh <ramneek.mehresh@freescale.com>
|
||||
Signed-off-by: Peter Chen <peter.chen@freescale.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/host/fsl-mph-dr-of.c | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr-of.c
|
||||
index 9037035..5a42cf0 100644
|
||||
--- a/drivers/usb/host/fsl-mph-dr-of.c
|
||||
+++ b/drivers/usb/host/fsl-mph-dr-of.c
|
||||
@@ -94,7 +94,6 @@ struct platform_device * __devinit fsl_usb2_device_register(
|
||||
pdev->dev.parent = &ofdev->dev;
|
||||
|
||||
pdev->dev.coherent_dma_mask = ofdev->dev.coherent_dma_mask;
|
||||
- pdev->dev.dma_mask = &pdev->archdata.dma_mask;
|
||||
*pdev->dev.dma_mask = *ofdev->dev.dma_mask;
|
||||
|
||||
retval = platform_device_add_data(pdev, pdata, sizeof(*pdata));
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
From 1ae819c56089722e15e3fe2d84125e4f5aa32d4e Mon Sep 17 00:00:00 2001
|
||||
From: Josh Boyer <jwboyer@redhat.com>
|
||||
Date: Mon, 20 Feb 2012 15:34:34 -0500
|
||||
Subject: [PATCH 029/147] USB: ums_realtek: do not use stack memory for DMA in
|
||||
__do_config_autodelink
|
||||
|
||||
commit 4898e07174b79013afd2b422ef6c4336ef8e6783 upstream.
|
||||
|
||||
__do_config_autodelink passes the data variable to the transport function.
|
||||
If the calling functions pass a stack variable, this will eventually trigger
|
||||
a DMA-API debug backtrace for mapping stack memory in the DMA buffer. Fix
|
||||
this by calling kmemdup for the passed data instead.
|
||||
|
||||
Signed-off-by: Josh Boyer <jwboyer@redhat.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/storage/realtek_cr.c | 8 +++++++-
|
||||
1 file changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/usb/storage/realtek_cr.c b/drivers/usb/storage/realtek_cr.c
|
||||
index 32c93d7..e39b188 100644
|
||||
--- a/drivers/usb/storage/realtek_cr.c
|
||||
+++ b/drivers/usb/storage/realtek_cr.c
|
||||
@@ -509,9 +509,14 @@ static int __do_config_autodelink(struct us_data *us, u8 *data, u16 len)
|
||||
int retval;
|
||||
u16 addr = 0xFE47;
|
||||
u8 cmnd[12] = {0};
|
||||
+ u8 *buf;
|
||||
|
||||
US_DEBUGP("%s, addr = 0x%x, len = %d\n", __FUNCTION__, addr, len);
|
||||
|
||||
+ buf = kmemdup(data, len, GFP_NOIO);
|
||||
+ if (!buf)
|
||||
+ return USB_STOR_TRANSPORT_ERROR;
|
||||
+
|
||||
cmnd[0] = 0xF0;
|
||||
cmnd[1] = 0x0E;
|
||||
cmnd[2] = (u8)(addr >> 8);
|
||||
@@ -519,7 +524,8 @@ static int __do_config_autodelink(struct us_data *us, u8 *data, u16 len)
|
||||
cmnd[4] = (u8)(len >> 8);
|
||||
cmnd[5] = (u8)len;
|
||||
|
||||
- retval = rts51x_bulk_transport_special(us, 0, cmnd, 12, data, len, DMA_TO_DEVICE, NULL);
|
||||
+ retval = rts51x_bulk_transport_special(us, 0, cmnd, 12, buf, len, DMA_TO_DEVICE, NULL);
|
||||
+ kfree(buf);
|
||||
if (retval != USB_STOR_TRANSPORT_GOOD) {
|
||||
return -EIO;
|
||||
}
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
From e3ed8846e20e35e9a94c80270d72b20befec0859 Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Tuttle <ttuttle@chromium.org>
|
||||
Date: Wed, 1 Feb 2012 16:07:17 -0500
|
||||
Subject: [PATCH 030/147] USB: qcserial: add several new serial devices
|
||||
|
||||
commit 2db4d87070e87d198ab630e66a898b45eff316d9 upstream.
|
||||
|
||||
Signed-off-by: Thomas Tuttle <ttuttle@chromium.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/usb/serial/qcserial.c | 14 ++++++++++++++
|
||||
1 file changed, 14 insertions(+)
|
||||
|
||||
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c
|
||||
index aa9367f..1e87d49 100644
|
||||
--- a/drivers/usb/serial/qcserial.c
|
||||
+++ b/drivers/usb/serial/qcserial.c
|
||||
@@ -36,6 +36,11 @@ static const struct usb_device_id id_table[] = {
|
||||
{USB_DEVICE(0x413c, 0x8171)}, /* Dell Gobi QDL device */
|
||||
{USB_DEVICE(0x1410, 0xa001)}, /* Novatel Gobi Modem device */
|
||||
{USB_DEVICE(0x1410, 0xa008)}, /* Novatel Gobi QDL device */
|
||||
+ {USB_DEVICE(0x1410, 0xa010)}, /* Novatel Gobi QDL device */
|
||||
+ {USB_DEVICE(0x1410, 0xa011)}, /* Novatel Gobi QDL device */
|
||||
+ {USB_DEVICE(0x1410, 0xa012)}, /* Novatel Gobi QDL device */
|
||||
+ {USB_DEVICE(0x1410, 0xa013)}, /* Novatel Gobi QDL device */
|
||||
+ {USB_DEVICE(0x1410, 0xa014)}, /* Novatel Gobi QDL device */
|
||||
{USB_DEVICE(0x0b05, 0x1776)}, /* Asus Gobi Modem device */
|
||||
{USB_DEVICE(0x0b05, 0x1774)}, /* Asus Gobi QDL device */
|
||||
{USB_DEVICE(0x19d2, 0xfff3)}, /* ONDA Gobi Modem device */
|
||||
@@ -86,7 +91,16 @@ static const struct usb_device_id id_table[] = {
|
||||
{USB_DEVICE(0x16d8, 0x8002)}, /* CMDTech Gobi 2000 Modem device (VU922) */
|
||||
{USB_DEVICE(0x05c6, 0x9204)}, /* Gobi 2000 QDL device */
|
||||
{USB_DEVICE(0x05c6, 0x9205)}, /* Gobi 2000 Modem device */
|
||||
+
|
||||
+ {USB_DEVICE(0x05c6, 0x920c)}, /* Gobi 3000 QDL */
|
||||
+ {USB_DEVICE(0x05c6, 0x920d)}, /* Gobi 3000 Composite */
|
||||
+ {USB_DEVICE(0x1410, 0xa020)}, /* Novatel Gobi 3000 QDL */
|
||||
+ {USB_DEVICE(0x1410, 0xa021)}, /* Novatel Gobi 3000 Composite */
|
||||
+ {USB_DEVICE(0x413c, 0x8193)}, /* Dell Gobi 3000 QDL */
|
||||
+ {USB_DEVICE(0x413c, 0x8194)}, /* Dell Gobi 3000 Composite */
|
||||
{USB_DEVICE(0x1199, 0x9013)}, /* Sierra Wireless Gobi 3000 Modem device (MC8355) */
|
||||
+ {USB_DEVICE(0x12D1, 0x14F0)}, /* Sony Gobi 3000 QDL */
|
||||
+ {USB_DEVICE(0x12D1, 0x14F1)}, /* Sony Gobi 3000 Composite */
|
||||
{ } /* Terminating entry */
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, id_table);
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,177 @@
|
||||
From 8544c3691b838f3377a752b88365bb522eb04b72 Mon Sep 17 00:00:00 2001
|
||||
From: Dan Williams <dcbw@redhat.com>
|
||||
Date: Fri, 24 Feb 2012 13:08:43 -0600
|
||||
Subject: [PATCH 031/147] USB: qcserial: don't grab QMI port on Gobi 1000
|
||||
devices
|
||||
|
||||
commit c192c8e71a2ded01170c1a992cd21aaedc822756 upstream.
|
||||
|
||||
Gobi 1000 devices have a different port layout, which wasn't respected
|
||||
by the current driver, and thus it grabbed the QMI/net port. In the
|
||||
near future we'll be attaching another driver to the QMI/net port for
|
||||
these devices (cdc-wdm and qmi_wwan) so make sure the qcserial driver
|
||||
doesn't claim them. This patch also prevents qcserial from binding to
|
||||
interfaces 0 and 1 on 1K devices because those interfaces do not
|
||||
respond.
|
||||
|
||||
Signed-off-by: Dan Williams <dcbw@redhat.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/serial/qcserial.c | 105 ++++++++++++++++++++++++-----------------
|
||||
1 file changed, 62 insertions(+), 43 deletions(-)
|
||||
|
||||
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c
|
||||
index 1e87d49..3187d8b 100644
|
||||
--- a/drivers/usb/serial/qcserial.c
|
||||
+++ b/drivers/usb/serial/qcserial.c
|
||||
@@ -24,39 +24,44 @@
|
||||
|
||||
static int debug;
|
||||
|
||||
+#define DEVICE_G1K(v, p) \
|
||||
+ USB_DEVICE(v, p), .driver_info = 1
|
||||
+
|
||||
static const struct usb_device_id id_table[] = {
|
||||
- {USB_DEVICE(0x05c6, 0x9211)}, /* Acer Gobi QDL device */
|
||||
- {USB_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */
|
||||
- {USB_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */
|
||||
- {USB_DEVICE(0x03f0, 0x201d)}, /* HP un2400 Gobi QDL Device */
|
||||
- {USB_DEVICE(0x03f0, 0x371d)}, /* HP un2430 Mobile Broadband Module */
|
||||
- {USB_DEVICE(0x04da, 0x250d)}, /* Panasonic Gobi Modem device */
|
||||
- {USB_DEVICE(0x04da, 0x250c)}, /* Panasonic Gobi QDL device */
|
||||
- {USB_DEVICE(0x413c, 0x8172)}, /* Dell Gobi Modem device */
|
||||
- {USB_DEVICE(0x413c, 0x8171)}, /* Dell Gobi QDL device */
|
||||
- {USB_DEVICE(0x1410, 0xa001)}, /* Novatel Gobi Modem device */
|
||||
- {USB_DEVICE(0x1410, 0xa008)}, /* Novatel Gobi QDL device */
|
||||
- {USB_DEVICE(0x1410, 0xa010)}, /* Novatel Gobi QDL device */
|
||||
- {USB_DEVICE(0x1410, 0xa011)}, /* Novatel Gobi QDL device */
|
||||
- {USB_DEVICE(0x1410, 0xa012)}, /* Novatel Gobi QDL device */
|
||||
- {USB_DEVICE(0x1410, 0xa013)}, /* Novatel Gobi QDL device */
|
||||
- {USB_DEVICE(0x1410, 0xa014)}, /* Novatel Gobi QDL device */
|
||||
- {USB_DEVICE(0x0b05, 0x1776)}, /* Asus Gobi Modem device */
|
||||
- {USB_DEVICE(0x0b05, 0x1774)}, /* Asus Gobi QDL device */
|
||||
- {USB_DEVICE(0x19d2, 0xfff3)}, /* ONDA Gobi Modem device */
|
||||
- {USB_DEVICE(0x19d2, 0xfff2)}, /* ONDA Gobi QDL device */
|
||||
- {USB_DEVICE(0x1557, 0x0a80)}, /* OQO Gobi QDL device */
|
||||
- {USB_DEVICE(0x05c6, 0x9001)}, /* Generic Gobi Modem device */
|
||||
- {USB_DEVICE(0x05c6, 0x9002)}, /* Generic Gobi Modem device */
|
||||
- {USB_DEVICE(0x05c6, 0x9202)}, /* Generic Gobi Modem device */
|
||||
- {USB_DEVICE(0x05c6, 0x9203)}, /* Generic Gobi Modem device */
|
||||
- {USB_DEVICE(0x05c6, 0x9222)}, /* Generic Gobi Modem device */
|
||||
- {USB_DEVICE(0x05c6, 0x9008)}, /* Generic Gobi QDL device */
|
||||
- {USB_DEVICE(0x05c6, 0x9009)}, /* Generic Gobi Modem device */
|
||||
- {USB_DEVICE(0x05c6, 0x9201)}, /* Generic Gobi QDL device */
|
||||
- {USB_DEVICE(0x05c6, 0x9221)}, /* Generic Gobi QDL device */
|
||||
- {USB_DEVICE(0x05c6, 0x9231)}, /* Generic Gobi QDL device */
|
||||
- {USB_DEVICE(0x1f45, 0x0001)}, /* Unknown Gobi QDL device */
|
||||
+ /* Gobi 1000 devices */
|
||||
+ {DEVICE_G1K(0x05c6, 0x9211)}, /* Acer Gobi QDL device */
|
||||
+ {DEVICE_G1K(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */
|
||||
+ {DEVICE_G1K(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */
|
||||
+ {DEVICE_G1K(0x03f0, 0x201d)}, /* HP un2400 Gobi QDL Device */
|
||||
+ {DEVICE_G1K(0x04da, 0x250d)}, /* Panasonic Gobi Modem device */
|
||||
+ {DEVICE_G1K(0x04da, 0x250c)}, /* Panasonic Gobi QDL device */
|
||||
+ {DEVICE_G1K(0x413c, 0x8172)}, /* Dell Gobi Modem device */
|
||||
+ {DEVICE_G1K(0x413c, 0x8171)}, /* Dell Gobi QDL device */
|
||||
+ {DEVICE_G1K(0x1410, 0xa001)}, /* Novatel Gobi Modem device */
|
||||
+ {DEVICE_G1K(0x1410, 0xa008)}, /* Novatel Gobi QDL device */
|
||||
+ {DEVICE_G1K(0x0b05, 0x1776)}, /* Asus Gobi Modem device */
|
||||
+ {DEVICE_G1K(0x0b05, 0x1774)}, /* Asus Gobi QDL device */
|
||||
+ {DEVICE_G1K(0x19d2, 0xfff3)}, /* ONDA Gobi Modem device */
|
||||
+ {DEVICE_G1K(0x19d2, 0xfff2)}, /* ONDA Gobi QDL device */
|
||||
+ {DEVICE_G1K(0x1557, 0x0a80)}, /* OQO Gobi QDL device */
|
||||
+ {DEVICE_G1K(0x05c6, 0x9001)}, /* Generic Gobi Modem device */
|
||||
+ {DEVICE_G1K(0x05c6, 0x9002)}, /* Generic Gobi Modem device */
|
||||
+ {DEVICE_G1K(0x05c6, 0x9202)}, /* Generic Gobi Modem device */
|
||||
+ {DEVICE_G1K(0x05c6, 0x9203)}, /* Generic Gobi Modem device */
|
||||
+ {DEVICE_G1K(0x05c6, 0x9222)}, /* Generic Gobi Modem device */
|
||||
+ {DEVICE_G1K(0x05c6, 0x9008)}, /* Generic Gobi QDL device */
|
||||
+ {DEVICE_G1K(0x05c6, 0x9009)}, /* Generic Gobi Modem device */
|
||||
+ {DEVICE_G1K(0x05c6, 0x9201)}, /* Generic Gobi QDL device */
|
||||
+ {DEVICE_G1K(0x05c6, 0x9221)}, /* Generic Gobi QDL device */
|
||||
+ {DEVICE_G1K(0x05c6, 0x9231)}, /* Generic Gobi QDL device */
|
||||
+ {DEVICE_G1K(0x1f45, 0x0001)}, /* Unknown Gobi QDL device */
|
||||
+
|
||||
+ /* Gobi 2000 devices */
|
||||
+ {USB_DEVICE(0x1410, 0xa010)}, /* Novatel Gobi 2000 QDL device */
|
||||
+ {USB_DEVICE(0x1410, 0xa011)}, /* Novatel Gobi 2000 QDL device */
|
||||
+ {USB_DEVICE(0x1410, 0xa012)}, /* Novatel Gobi 2000 QDL device */
|
||||
+ {USB_DEVICE(0x1410, 0xa013)}, /* Novatel Gobi 2000 QDL device */
|
||||
+ {USB_DEVICE(0x1410, 0xa014)}, /* Novatel Gobi 2000 QDL device */
|
||||
{USB_DEVICE(0x413c, 0x8185)}, /* Dell Gobi 2000 QDL device (N0218, VU936) */
|
||||
{USB_DEVICE(0x413c, 0x8186)}, /* Dell Gobi 2000 Modem device (N0218, VU936) */
|
||||
{USB_DEVICE(0x05c6, 0x9208)}, /* Generic Gobi 2000 QDL device */
|
||||
@@ -92,6 +97,8 @@ static const struct usb_device_id id_table[] = {
|
||||
{USB_DEVICE(0x05c6, 0x9204)}, /* Gobi 2000 QDL device */
|
||||
{USB_DEVICE(0x05c6, 0x9205)}, /* Gobi 2000 Modem device */
|
||||
|
||||
+ /* Gobi 3000 devices */
|
||||
+ {USB_DEVICE(0x03f0, 0x371d)}, /* HP un2430 Gobi 3000 QDL */
|
||||
{USB_DEVICE(0x05c6, 0x920c)}, /* Gobi 3000 QDL */
|
||||
{USB_DEVICE(0x05c6, 0x920d)}, /* Gobi 3000 Composite */
|
||||
{USB_DEVICE(0x1410, 0xa020)}, /* Novatel Gobi 3000 QDL */
|
||||
@@ -122,8 +129,10 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
|
||||
int retval = -ENODEV;
|
||||
__u8 nintf;
|
||||
__u8 ifnum;
|
||||
+ bool is_gobi1k = id->driver_info ? true : false;
|
||||
|
||||
dbg("%s", __func__);
|
||||
+ dbg("Is Gobi 1000 = %d", is_gobi1k);
|
||||
|
||||
nintf = serial->dev->actconfig->desc.bNumInterfaces;
|
||||
dbg("Num Interfaces = %d", nintf);
|
||||
@@ -171,15 +180,25 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
|
||||
|
||||
case 3:
|
||||
case 4:
|
||||
- /* Composite mode */
|
||||
- /* ifnum == 0 is a broadband network adapter */
|
||||
- if (ifnum == 1) {
|
||||
- /*
|
||||
- * Diagnostics Monitor (serial line 9600 8N1)
|
||||
- * Qualcomm DM protocol
|
||||
- * use "libqcdm" (ModemManager) for communication
|
||||
- */
|
||||
- dbg("Diagnostics Monitor found");
|
||||
+ /* Composite mode; don't bind to the QMI/net interface as that
|
||||
+ * gets handled by other drivers.
|
||||
+ */
|
||||
+
|
||||
+ /* Gobi 1K USB layout:
|
||||
+ * 0: serial port (doesn't respond)
|
||||
+ * 1: serial port (doesn't respond)
|
||||
+ * 2: AT-capable modem port
|
||||
+ * 3: QMI/net
|
||||
+ *
|
||||
+ * Gobi 2K+ USB layout:
|
||||
+ * 0: QMI/net
|
||||
+ * 1: DM/DIAG (use libqcdm from ModemManager for communication)
|
||||
+ * 2: AT-capable modem port
|
||||
+ * 3: NMEA
|
||||
+ */
|
||||
+
|
||||
+ if (ifnum == 1 && !is_gobi1k) {
|
||||
+ dbg("Gobi 2K+ DM/DIAG interface found");
|
||||
retval = usb_set_interface(serial->dev, ifnum, 0);
|
||||
if (retval < 0) {
|
||||
dev_err(&serial->dev->dev,
|
||||
@@ -198,13 +217,13 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
|
||||
retval = -ENODEV;
|
||||
kfree(data);
|
||||
}
|
||||
- } else if (ifnum==3) {
|
||||
+ } else if (ifnum==3 && !is_gobi1k) {
|
||||
/*
|
||||
* NMEA (serial line 9600 8N1)
|
||||
* # echo "\$GPS_START" > /dev/ttyUSBx
|
||||
* # echo "\$GPS_STOP" > /dev/ttyUSBx
|
||||
*/
|
||||
- dbg("NMEA GPS interface found");
|
||||
+ dbg("Gobi 2K+ NMEA GPS interface found");
|
||||
retval = usb_set_interface(serial->dev, ifnum, 0);
|
||||
if (retval < 0) {
|
||||
dev_err(&serial->dev->dev,
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
From 94b027170f277f8d39aa3e6b2fe0ec2d01ad90f9 Mon Sep 17 00:00:00 2001
|
||||
From: Scott Dial <scott.dial@scientiallc.com>
|
||||
Date: Fri, 24 Feb 2012 19:04:09 -0500
|
||||
Subject: [PATCH 032/147] usb-serial: Add support for the Sealevel SeaLINK+8
|
||||
2038-ROHS device
|
||||
|
||||
commit 6d161b99f875269ad4ffa44375e1e54bca6fd02e upstream.
|
||||
|
||||
This patch adds new device IDs to the ftdi_sio module to support
|
||||
the new Sealevel SeaLINK+8 2038-ROHS device.
|
||||
|
||||
Signed-off-by: Scott Dial <scott.dial@scientiallc.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/serial/ftdi_sio.c | 4 ++++
|
||||
drivers/usb/serial/ftdi_sio_ids.h | 4 ++++
|
||||
2 files changed, 8 insertions(+)
|
||||
|
||||
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
|
||||
index 3f3ccf6..f2c9ef7 100644
|
||||
--- a/drivers/usb/serial/ftdi_sio.c
|
||||
+++ b/drivers/usb/serial/ftdi_sio.c
|
||||
@@ -537,6 +537,10 @@ static struct usb_device_id id_table_combined [] = {
|
||||
{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_6_PID) },
|
||||
{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_7_PID) },
|
||||
{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_8_PID) },
|
||||
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803R_1_PID) },
|
||||
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803R_2_PID) },
|
||||
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803R_3_PID) },
|
||||
+ { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803R_4_PID) },
|
||||
{ USB_DEVICE(IDTECH_VID, IDTECH_IDT1221U_PID) },
|
||||
{ USB_DEVICE(OCT_VID, OCT_US101_PID) },
|
||||
{ USB_DEVICE(OCT_VID, OCT_DK201_PID) },
|
||||
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h
|
||||
index abf6bbc..c6dd18e 100644
|
||||
--- a/drivers/usb/serial/ftdi_sio_ids.h
|
||||
+++ b/drivers/usb/serial/ftdi_sio_ids.h
|
||||
@@ -689,6 +689,10 @@
|
||||
#define SEALEVEL_2803_6_PID 0X2863 /* SeaLINK+8 (2803) Port 6 */
|
||||
#define SEALEVEL_2803_7_PID 0X2873 /* SeaLINK+8 (2803) Port 7 */
|
||||
#define SEALEVEL_2803_8_PID 0X2883 /* SeaLINK+8 (2803) Port 8 */
|
||||
+#define SEALEVEL_2803R_1_PID 0Xa02a /* SeaLINK+8 (2803-ROHS) Port 1+2 */
|
||||
+#define SEALEVEL_2803R_2_PID 0Xa02b /* SeaLINK+8 (2803-ROHS) Port 3+4 */
|
||||
+#define SEALEVEL_2803R_3_PID 0Xa02c /* SeaLINK+8 (2803-ROHS) Port 5+6 */
|
||||
+#define SEALEVEL_2803R_4_PID 0Xa02d /* SeaLINK+8 (2803-ROHS) Port 7+8 */
|
||||
|
||||
/*
|
||||
* JETI SPECTROMETER SPECBOS 1201
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
From 4d2e98ccb5f7c69868760e889389c5ba01a89bf5 Mon Sep 17 00:00:00 2001
|
||||
From: Preston Fick <preston.fick@silabs.com>
|
||||
Date: Fri, 24 Feb 2012 13:42:39 -0600
|
||||
Subject: [PATCH 033/147] usb: cp210x: Update to support CP2105 and multiple
|
||||
interface devices
|
||||
|
||||
commit a5360a53a7ccad5ed9ccef210b94fef13c6e5529 upstream.
|
||||
|
||||
This patch updates the cp210x driver to support CP210x multiple
|
||||
interface devices devices from Silicon Labs. The existing driver
|
||||
always sends control requests to interface 0, which is hardcoded in
|
||||
the usb_control_msg function calls. This only allows for single
|
||||
interface devices to be used, and causes a bug when using ports on an
|
||||
interface other than 0 in the multiple interface devices.
|
||||
|
||||
Here are the changes included in this patch:
|
||||
- Updated the device list to contain the Silicon Labs factory default
|
||||
VID/PID for multiple interface CP210x devices
|
||||
- Created a cp210x_port_private struct created for each port on
|
||||
startup, this struct holds the interface number
|
||||
- Added a cp210x_release function to clean up the cp210x_port_private
|
||||
memory created on startup
|
||||
- Modified usb_get_config and usb_set_config to get a pointer to the
|
||||
cp210x_port_private struct, and use the interface number there in the
|
||||
usb_control_message wIndex param
|
||||
|
||||
Signed-off-by: Preston Fick <preston.fick@silabs.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/serial/cp210x.c | 44 ++++++++++++++++++++++++++++++++++++++++---
|
||||
1 file changed, 41 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
|
||||
index 33d25d4..4c12404 100644
|
||||
--- a/drivers/usb/serial/cp210x.c
|
||||
+++ b/drivers/usb/serial/cp210x.c
|
||||
@@ -49,6 +49,7 @@ static int cp210x_tiocmset_port(struct usb_serial_port *port,
|
||||
unsigned int, unsigned int);
|
||||
static void cp210x_break_ctl(struct tty_struct *, int);
|
||||
static int cp210x_startup(struct usb_serial *);
|
||||
+static void cp210x_release(struct usb_serial *);
|
||||
static void cp210x_dtr_rts(struct usb_serial_port *p, int on);
|
||||
|
||||
static int debug;
|
||||
@@ -121,6 +122,8 @@ static const struct usb_device_id id_table[] = {
|
||||
{ USB_DEVICE(0x10C4, 0x8665) }, /* AC-Services OBD-IF */
|
||||
{ USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
|
||||
{ USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
|
||||
+ { USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */
|
||||
+ { USB_DEVICE(0x10C4, 0xEA80) }, /* Silicon Labs factory default */
|
||||
{ USB_DEVICE(0x10C4, 0xEA71) }, /* Infinity GPS-MIC-1 Radio Monophone */
|
||||
{ USB_DEVICE(0x10C4, 0xF001) }, /* Elan Digital Systems USBscope50 */
|
||||
{ USB_DEVICE(0x10C4, 0xF002) }, /* Elan Digital Systems USBwave12 */
|
||||
@@ -149,6 +152,10 @@ static const struct usb_device_id id_table[] = {
|
||||
|
||||
MODULE_DEVICE_TABLE(usb, id_table);
|
||||
|
||||
+struct cp210x_port_private {
|
||||
+ __u8 bInterfaceNumber;
|
||||
+};
|
||||
+
|
||||
static struct usb_driver cp210x_driver = {
|
||||
.name = "cp210x",
|
||||
.probe = usb_serial_probe,
|
||||
@@ -174,6 +181,7 @@ static struct usb_serial_driver cp210x_device = {
|
||||
.tiocmget = cp210x_tiocmget,
|
||||
.tiocmset = cp210x_tiocmset,
|
||||
.attach = cp210x_startup,
|
||||
+ .release = cp210x_release,
|
||||
.dtr_rts = cp210x_dtr_rts
|
||||
};
|
||||
|
||||
@@ -261,6 +269,7 @@ static int cp210x_get_config(struct usb_serial_port *port, u8 request,
|
||||
unsigned int *data, int size)
|
||||
{
|
||||
struct usb_serial *serial = port->serial;
|
||||
+ struct cp210x_port_private *port_priv = usb_get_serial_port_data(port);
|
||||
__le32 *buf;
|
||||
int result, i, length;
|
||||
|
||||
@@ -276,7 +285,7 @@ static int cp210x_get_config(struct usb_serial_port *port, u8 request,
|
||||
/* Issue the request, attempting to read 'size' bytes */
|
||||
result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
|
||||
request, REQTYPE_DEVICE_TO_HOST, 0x0000,
|
||||
- 0, buf, size, 300);
|
||||
+ port_priv->bInterfaceNumber, buf, size, 300);
|
||||
|
||||
/* Convert data into an array of integers */
|
||||
for (i = 0; i < length; i++)
|
||||
@@ -304,6 +313,7 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request,
|
||||
unsigned int *data, int size)
|
||||
{
|
||||
struct usb_serial *serial = port->serial;
|
||||
+ struct cp210x_port_private *port_priv = usb_get_serial_port_data(port);
|
||||
__le32 *buf;
|
||||
int result, i, length;
|
||||
|
||||
@@ -325,12 +335,12 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request,
|
||||
result = usb_control_msg(serial->dev,
|
||||
usb_sndctrlpipe(serial->dev, 0),
|
||||
request, REQTYPE_HOST_TO_DEVICE, 0x0000,
|
||||
- 0, buf, size, 300);
|
||||
+ port_priv->bInterfaceNumber, buf, size, 300);
|
||||
} else {
|
||||
result = usb_control_msg(serial->dev,
|
||||
usb_sndctrlpipe(serial->dev, 0),
|
||||
request, REQTYPE_HOST_TO_DEVICE, data[0],
|
||||
- 0, NULL, 0, 300);
|
||||
+ port_priv->bInterfaceNumber, NULL, 0, 300);
|
||||
}
|
||||
|
||||
kfree(buf);
|
||||
@@ -830,11 +840,39 @@ static void cp210x_break_ctl (struct tty_struct *tty, int break_state)
|
||||
|
||||
static int cp210x_startup(struct usb_serial *serial)
|
||||
{
|
||||
+ struct cp210x_port_private *port_priv;
|
||||
+ int i;
|
||||
+
|
||||
/* cp210x buffers behave strangely unless device is reset */
|
||||
usb_reset_device(serial->dev);
|
||||
+
|
||||
+ for (i = 0; i < serial->num_ports; i++) {
|
||||
+ port_priv = kzalloc(sizeof(*port_priv), GFP_KERNEL);
|
||||
+ if (!port_priv)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ memset(port_priv, 0x00, sizeof(*port_priv));
|
||||
+ port_priv->bInterfaceNumber =
|
||||
+ serial->interface->cur_altsetting->desc.bInterfaceNumber;
|
||||
+
|
||||
+ usb_set_serial_port_data(serial->port[i], port_priv);
|
||||
+ }
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static void cp210x_release(struct usb_serial *serial)
|
||||
+{
|
||||
+ struct cp210x_port_private *port_priv;
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < serial->num_ports; i++) {
|
||||
+ port_priv = usb_get_serial_port_data(serial->port[i]);
|
||||
+ kfree(port_priv);
|
||||
+ usb_set_serial_port_data(serial->port[i], NULL);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static int __init cp210x_init(void)
|
||||
{
|
||||
int retval;
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
From 7121306391cac4f482edc239e2c8b0f8ac310f92 Mon Sep 17 00:00:00 2001
|
||||
From: Donald Lee <donald@asix.com.tw>
|
||||
Date: Wed, 14 Mar 2012 15:26:33 +0800
|
||||
Subject: [PATCH 034/147] USB: serial: mos7840: Fixed MCS7820 device attach
|
||||
problem
|
||||
|
||||
commit 093ea2d3a766cb8a4c4de57efec6c0a127a58792 upstream.
|
||||
|
||||
A MCS7820 device supports two serial ports and a MCS7840 device supports
|
||||
four serial ports. Both devices use the same driver, but the attach function
|
||||
in driver was unable to correctly handle the port numbers for MCS7820
|
||||
device. This problem has been fixed in this patch and this fix has been
|
||||
verified on x86 Linux kernel 3.2.9 with both MCS7820 and MCS7840 devices.
|
||||
|
||||
Signed-off-by: Donald Lee <donald@asix.com.tw>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/serial/mos7840.c | 83 +++++++++++++++++++++++++++++-------------
|
||||
1 file changed, 57 insertions(+), 26 deletions(-)
|
||||
|
||||
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
|
||||
index c72abd5..5c7d654 100644
|
||||
--- a/drivers/usb/serial/mos7840.c
|
||||
+++ b/drivers/usb/serial/mos7840.c
|
||||
@@ -174,6 +174,7 @@
|
||||
|
||||
#define CLK_MULTI_REGISTER ((__u16)(0x02))
|
||||
#define CLK_START_VALUE_REGISTER ((__u16)(0x03))
|
||||
+#define GPIO_REGISTER ((__u16)(0x07))
|
||||
|
||||
#define SERIAL_LCR_DLAB ((__u16)(0x0080))
|
||||
|
||||
@@ -1103,14 +1104,25 @@ static int mos7840_open(struct tty_struct *tty, struct usb_serial_port *port)
|
||||
mos7840_port->read_urb = port->read_urb;
|
||||
|
||||
/* set up our bulk in urb */
|
||||
-
|
||||
- usb_fill_bulk_urb(mos7840_port->read_urb,
|
||||
- serial->dev,
|
||||
- usb_rcvbulkpipe(serial->dev,
|
||||
- port->bulk_in_endpointAddress),
|
||||
- port->bulk_in_buffer,
|
||||
- mos7840_port->read_urb->transfer_buffer_length,
|
||||
- mos7840_bulk_in_callback, mos7840_port);
|
||||
+ if ((serial->num_ports == 2)
|
||||
+ && ((((__u16)port->number -
|
||||
+ (__u16)(port->serial->minor)) % 2) != 0)) {
|
||||
+ usb_fill_bulk_urb(mos7840_port->read_urb,
|
||||
+ serial->dev,
|
||||
+ usb_rcvbulkpipe(serial->dev,
|
||||
+ (port->bulk_in_endpointAddress) + 2),
|
||||
+ port->bulk_in_buffer,
|
||||
+ mos7840_port->read_urb->transfer_buffer_length,
|
||||
+ mos7840_bulk_in_callback, mos7840_port);
|
||||
+ } else {
|
||||
+ usb_fill_bulk_urb(mos7840_port->read_urb,
|
||||
+ serial->dev,
|
||||
+ usb_rcvbulkpipe(serial->dev,
|
||||
+ port->bulk_in_endpointAddress),
|
||||
+ port->bulk_in_buffer,
|
||||
+ mos7840_port->read_urb->transfer_buffer_length,
|
||||
+ mos7840_bulk_in_callback, mos7840_port);
|
||||
+ }
|
||||
|
||||
dbg("mos7840_open: bulkin endpoint is %d",
|
||||
port->bulk_in_endpointAddress);
|
||||
@@ -1521,13 +1533,25 @@ static int mos7840_write(struct tty_struct *tty, struct usb_serial_port *port,
|
||||
memcpy(urb->transfer_buffer, current_position, transfer_size);
|
||||
|
||||
/* fill urb with data and submit */
|
||||
- usb_fill_bulk_urb(urb,
|
||||
- serial->dev,
|
||||
- usb_sndbulkpipe(serial->dev,
|
||||
- port->bulk_out_endpointAddress),
|
||||
- urb->transfer_buffer,
|
||||
- transfer_size,
|
||||
- mos7840_bulk_out_data_callback, mos7840_port);
|
||||
+ if ((serial->num_ports == 2)
|
||||
+ && ((((__u16)port->number -
|
||||
+ (__u16)(port->serial->minor)) % 2) != 0)) {
|
||||
+ usb_fill_bulk_urb(urb,
|
||||
+ serial->dev,
|
||||
+ usb_sndbulkpipe(serial->dev,
|
||||
+ (port->bulk_out_endpointAddress) + 2),
|
||||
+ urb->transfer_buffer,
|
||||
+ transfer_size,
|
||||
+ mos7840_bulk_out_data_callback, mos7840_port);
|
||||
+ } else {
|
||||
+ usb_fill_bulk_urb(urb,
|
||||
+ serial->dev,
|
||||
+ usb_sndbulkpipe(serial->dev,
|
||||
+ port->bulk_out_endpointAddress),
|
||||
+ urb->transfer_buffer,
|
||||
+ transfer_size,
|
||||
+ mos7840_bulk_out_data_callback, mos7840_port);
|
||||
+ }
|
||||
|
||||
data1 = urb->transfer_buffer;
|
||||
dbg("bulkout endpoint is %d", port->bulk_out_endpointAddress);
|
||||
@@ -1840,7 +1864,7 @@ static int mos7840_send_cmd_write_baud_rate(struct moschip_port *mos7840_port,
|
||||
|
||||
} else {
|
||||
#ifdef HW_flow_control
|
||||
- / *setting h/w flow control bit to 0 */
|
||||
+ /* setting h/w flow control bit to 0 */
|
||||
Data = 0xb;
|
||||
mos7840_port->shadowMCR = Data;
|
||||
status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER,
|
||||
@@ -2309,19 +2333,26 @@ static int mos7840_ioctl(struct tty_struct *tty,
|
||||
|
||||
static int mos7840_calc_num_ports(struct usb_serial *serial)
|
||||
{
|
||||
- int mos7840_num_ports = 0;
|
||||
-
|
||||
- dbg("numberofendpoints: cur %d, alt %d",
|
||||
- (int)serial->interface->cur_altsetting->desc.bNumEndpoints,
|
||||
- (int)serial->interface->altsetting->desc.bNumEndpoints);
|
||||
- if (serial->interface->cur_altsetting->desc.bNumEndpoints == 5) {
|
||||
- mos7840_num_ports = serial->num_ports = 2;
|
||||
- } else if (serial->interface->cur_altsetting->desc.bNumEndpoints == 9) {
|
||||
+ __u16 Data = 0x00;
|
||||
+ int ret = 0;
|
||||
+ int mos7840_num_ports;
|
||||
+
|
||||
+ ret = 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);
|
||||
+
|
||||
+ if ((Data & 0x01) == 0) {
|
||||
+ mos7840_num_ports = 2;
|
||||
+ serial->num_bulk_in = 2;
|
||||
+ serial->num_bulk_out = 2;
|
||||
+ serial->num_ports = 2;
|
||||
+ } else {
|
||||
+ mos7840_num_ports = 4;
|
||||
serial->num_bulk_in = 4;
|
||||
serial->num_bulk_out = 4;
|
||||
- mos7840_num_ports = serial->num_ports = 4;
|
||||
+ serial->num_ports = 4;
|
||||
}
|
||||
- dbg ("mos7840_num_ports = %d", mos7840_num_ports);
|
||||
+
|
||||
return mos7840_num_ports;
|
||||
}
|
||||
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
From bdab95dd61b9879afe660d0f5d97bf5b6ab0533e Mon Sep 17 00:00:00 2001
|
||||
From: Gertjan van Wingerde <gwingerde@gmail.com>
|
||||
Date: Sat, 11 Feb 2012 21:58:09 +0100
|
||||
Subject: [PATCH 035/147] rt2x00: Add support for D-Link DWA-127 to rt2800usb.
|
||||
|
||||
commit d42a179b941a9e4cc6cf41d0f3cbadd75fc48a89 upstream.
|
||||
|
||||
This is an RT3070 based device.
|
||||
|
||||
Reported-by: Mikhail Kryshen <mikhail@kryshen.net>
|
||||
Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
|
||||
Acked-by: Ivo van Doorn <IvDoorn@gmail.com>
|
||||
Signed-off-by: John W. Linville <linville@tuxdriver.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/net/wireless/rt2x00/rt2800usb.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
|
||||
index 3265b34..cb71e88 100644
|
||||
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
|
||||
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
|
||||
@@ -935,6 +935,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
|
||||
{ USB_DEVICE(0x07d1, 0x3c0f) },
|
||||
{ USB_DEVICE(0x07d1, 0x3c11) },
|
||||
{ USB_DEVICE(0x07d1, 0x3c16) },
|
||||
+ { USB_DEVICE(0x2001, 0x3c1b) },
|
||||
/* Draytek */
|
||||
{ USB_DEVICE(0x07fa, 0x7712) },
|
||||
/* DVICO */
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
From a28aa8ba24d7303a4d8677ebf8b159014f19dca0 Mon Sep 17 00:00:00 2001
|
||||
From: Larry Finger <Larry.Finger@lwfinger.net>
|
||||
Date: Sat, 7 Jan 2012 20:46:40 -0600
|
||||
Subject: [PATCH 036/147] rtlwifi: rtl8192c_common: rtl8192de: Check for
|
||||
allocation failures
|
||||
|
||||
commit 76a92be537f1c8c259e393632301446257ca3ea9 upstream.
|
||||
|
||||
In https://bugzilla.redhat.com/show_bug.cgi?id=771656, a kernel bug was
|
||||
triggered due to a failed skb allocation that was not checked. This event
|
||||
lead to an audit of all memory allocations in the complete rtlwifi family
|
||||
of drivers. This patch fixes the rest.
|
||||
|
||||
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
|
||||
Signed-off-by: John W. Linville <linville@tuxdriver.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/net/wireless/rtlwifi/pci.c | 2 ++
|
||||
drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c | 2 ++
|
||||
drivers/net/wireless/rtlwifi/rtl8192de/fw.c | 14 +++++++++-----
|
||||
drivers/net/wireless/rtlwifi/usb.c | 12 +++++++-----
|
||||
4 files changed, 20 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c
|
||||
index eb61061..19bb550 100644
|
||||
--- a/drivers/net/wireless/rtlwifi/pci.c
|
||||
+++ b/drivers/net/wireless/rtlwifi/pci.c
|
||||
@@ -657,6 +657,8 @@ static void _rtl_receive_one(struct ieee80211_hw *hw, struct sk_buff *skb,
|
||||
return;
|
||||
|
||||
uskb = dev_alloc_skb(skb->len + 128);
|
||||
+ if (!uskb)
|
||||
+ return; /* exit if allocation failed */
|
||||
memcpy(IEEE80211_SKB_RXCB(uskb), &rx_status, sizeof(rx_status));
|
||||
pdata = (u8 *)skb_put(uskb, skb->len);
|
||||
memcpy(pdata, skb->data, skb->len);
|
||||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
|
||||
index 950c65a..13fc0f9 100644
|
||||
--- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
|
||||
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
|
||||
@@ -752,6 +752,8 @@ void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished)
|
||||
|
||||
|
||||
skb = dev_alloc_skb(totalpacketlen);
|
||||
+ if (!skb)
|
||||
+ return;
|
||||
memcpy((u8 *) skb_put(skb, totalpacketlen),
|
||||
&reserved_page_packet, totalpacketlen);
|
||||
|
||||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/fw.c b/drivers/net/wireless/rtlwifi/rtl8192de/fw.c
|
||||
index 82f060b..c44757f 100644
|
||||
--- a/drivers/net/wireless/rtlwifi/rtl8192de/fw.c
|
||||
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/fw.c
|
||||
@@ -763,12 +763,16 @@ void rtl92d_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished)
|
||||
"rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
|
||||
u1RsvdPageLoc, 3);
|
||||
skb = dev_alloc_skb(totalpacketlen);
|
||||
- memcpy((u8 *) skb_put(skb, totalpacketlen), &reserved_page_packet,
|
||||
- totalpacketlen);
|
||||
- rtstatus = _rtl92d_cmd_send_packet(hw, skb);
|
||||
+ if (!skb) {
|
||||
+ dlok = false;
|
||||
+ } else {
|
||||
+ memcpy((u8 *) skb_put(skb, totalpacketlen),
|
||||
+ &reserved_page_packet, totalpacketlen);
|
||||
+ rtstatus = _rtl92d_cmd_send_packet(hw, skb);
|
||||
|
||||
- if (rtstatus)
|
||||
- dlok = true;
|
||||
+ if (rtstatus)
|
||||
+ dlok = true;
|
||||
+ }
|
||||
if (dlok) {
|
||||
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
|
||||
("Set RSVD page location to Fw.\n"));
|
||||
diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c
|
||||
index 54cb8a6..2b7bcc8 100644
|
||||
--- a/drivers/net/wireless/rtlwifi/usb.c
|
||||
+++ b/drivers/net/wireless/rtlwifi/usb.c
|
||||
@@ -481,12 +481,14 @@ static void _rtl_usb_rx_process_noagg(struct ieee80211_hw *hw,
|
||||
u8 *pdata;
|
||||
|
||||
uskb = dev_alloc_skb(skb->len + 128);
|
||||
- memcpy(IEEE80211_SKB_RXCB(uskb), &rx_status,
|
||||
- sizeof(rx_status));
|
||||
- pdata = (u8 *)skb_put(uskb, skb->len);
|
||||
- memcpy(pdata, skb->data, skb->len);
|
||||
+ if (uskb) { /* drop packet on allocation failure */
|
||||
+ memcpy(IEEE80211_SKB_RXCB(uskb), &rx_status,
|
||||
+ sizeof(rx_status));
|
||||
+ pdata = (u8 *)skb_put(uskb, skb->len);
|
||||
+ memcpy(pdata, skb->data, skb->len);
|
||||
+ ieee80211_rx_irqsafe(hw, uskb);
|
||||
+ }
|
||||
dev_kfree_skb_any(skb);
|
||||
- ieee80211_rx_irqsafe(hw, uskb);
|
||||
} else {
|
||||
dev_kfree_skb_any(skb);
|
||||
}
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
From 80ee9108bee3d22e90191a67036133de09faf7cc Mon Sep 17 00:00:00 2001
|
||||
From: Simon Graham <simon.graham@virtualcomputer.com>
|
||||
Date: Tue, 7 Feb 2012 18:07:38 -0600
|
||||
Subject: [PATCH 037/147] rtlwifi: Handle previous allocation failures when
|
||||
freeing device memory
|
||||
|
||||
commit 7f66c2f93e5779625c10d262c84537427a2673ca upstream.
|
||||
|
||||
Handle previous allocation failures when freeing device memory
|
||||
|
||||
Signed-off-by: Simon Graham <simon.graham@virtualcomputer.com>
|
||||
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
|
||||
Signed-off-by: John W. Linville <linville@tuxdriver.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/net/wireless/rtlwifi/pci.c | 16 ++++++++++------
|
||||
1 file changed, 10 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c
|
||||
index 19bb550..9afcad3 100644
|
||||
--- a/drivers/net/wireless/rtlwifi/pci.c
|
||||
+++ b/drivers/net/wireless/rtlwifi/pci.c
|
||||
@@ -1155,10 +1155,12 @@ static void _rtl_pci_free_tx_ring(struct ieee80211_hw *hw,
|
||||
ring->idx = (ring->idx + 1) % ring->entries;
|
||||
}
|
||||
|
||||
- pci_free_consistent(rtlpci->pdev,
|
||||
- sizeof(*ring->desc) * ring->entries,
|
||||
- ring->desc, ring->dma);
|
||||
- ring->desc = NULL;
|
||||
+ if (ring->desc) {
|
||||
+ pci_free_consistent(rtlpci->pdev,
|
||||
+ sizeof(*ring->desc) * ring->entries,
|
||||
+ ring->desc, ring->dma);
|
||||
+ ring->desc = NULL;
|
||||
+ }
|
||||
}
|
||||
|
||||
static void _rtl_pci_free_rx_ring(struct rtl_pci *rtlpci)
|
||||
@@ -1182,12 +1184,14 @@ static void _rtl_pci_free_rx_ring(struct rtl_pci *rtlpci)
|
||||
kfree_skb(skb);
|
||||
}
|
||||
|
||||
- pci_free_consistent(rtlpci->pdev,
|
||||
+ if (rtlpci->rx_ring[rx_queue_idx].desc) {
|
||||
+ pci_free_consistent(rtlpci->pdev,
|
||||
sizeof(*rtlpci->rx_ring[rx_queue_idx].
|
||||
desc) * rtlpci->rxringcount,
|
||||
rtlpci->rx_ring[rx_queue_idx].desc,
|
||||
rtlpci->rx_ring[rx_queue_idx].dma);
|
||||
- rtlpci->rx_ring[rx_queue_idx].desc = NULL;
|
||||
+ rtlpci->rx_ring[rx_queue_idx].desc = NULL;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
From 9d3a0177f72e20f06c844ede994dc3541bdae01b Mon Sep 17 00:00:00 2001
|
||||
From: Larry Finger <Larry.Finger@lwfinger.net>
|
||||
Date: Fri, 2 Mar 2012 15:23:36 -0600
|
||||
Subject: [PATCH 038/147] rtlwifi: rtl8192c: Prevent sleeping from invalid
|
||||
context in rtl8192cu
|
||||
|
||||
commit ebecdcc12fed5d3c81853dea61a0a78a5aefab52 upstream.
|
||||
|
||||
When driver rtl8192cu is used with the debug level set to 3 or greater,
|
||||
the result is "sleeping function called from invalid context" due to
|
||||
an rcu_read_lock() call in the DM refresh routine in driver rtl8192c.
|
||||
This lock is not necessary as the USB driver does not use the struct
|
||||
being protected, thus the lock is set only when a PCI interface is
|
||||
active.
|
||||
|
||||
This bug is reported in https://bugzilla.kernel.org/show_bug.cgi?id=42775.
|
||||
|
||||
Reported-by: Ronald Wahl <ronald.wahl@raritan.com>
|
||||
Tested-by: Ronald Wahl <ronald.wahl@raritan.com>
|
||||
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
|
||||
Cc: Ronald Wahl <ronald.wahl@raritan.com>
|
||||
Signed-off-by: John W. Linville <linville@tuxdriver.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c | 11 ++++++++---
|
||||
1 file changed, 8 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
|
||||
index 72a98ca..4de6b78 100644
|
||||
--- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
|
||||
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
|
||||
@@ -1219,13 +1219,18 @@ static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)
|
||||
("PreState = %d, CurState = %d\n",
|
||||
p_ra->pre_ratr_state, p_ra->ratr_state));
|
||||
|
||||
- rcu_read_lock();
|
||||
- sta = ieee80211_find_sta(mac->vif, mac->bssid);
|
||||
+ /* Only the PCI card uses sta in the update rate table
|
||||
+ * callback routine */
|
||||
+ if (rtlhal->interface == INTF_PCI) {
|
||||
+ rcu_read_lock();
|
||||
+ sta = ieee80211_find_sta(mac->vif, mac->bssid);
|
||||
+ }
|
||||
rtlpriv->cfg->ops->update_rate_tbl(hw, sta,
|
||||
p_ra->ratr_state);
|
||||
|
||||
p_ra->pre_ratr_state = p_ra->ratr_state;
|
||||
- rcu_read_unlock();
|
||||
+ if (rtlhal->interface == INTF_PCI)
|
||||
+ rcu_read_unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
From 83d83582d1097f305c41838a2ca01dde71d608a1 Mon Sep 17 00:00:00 2001
|
||||
From: Jingjun Wu <jingjun_wu@realsil.com.cn>
|
||||
Date: Fri, 2 Mar 2012 20:52:14 -0600
|
||||
Subject: [PATCH 039/147] rtlwifi: rtl8192ce: Fix loss of receive performance
|
||||
|
||||
commit a9b89e2567c743483e6354f64d7a7e3a8c101e9e upstream.
|
||||
|
||||
Driver rtl8192ce when used with the RTL8188CE device would start at about
|
||||
20 Mbps on a 54 Mbps connection, but quickly drop to 1 Mbps. One of the
|
||||
symptoms is that the AP would need to retransmit each packet 4 of 5 times
|
||||
before the driver would acknowledge it. Recovery is possible only by
|
||||
unloading and reloading the driver. This problem was reported at
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=770207.
|
||||
|
||||
The problem is due to a missing update of the gain setting.
|
||||
|
||||
Signed-off-by: Jingjun Wu <jingjun_wu@realsil.com.cn>
|
||||
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
|
||||
Signed-off-by: John W. Linville <linville@tuxdriver.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
|
||||
index 4de6b78..a004ad7 100644
|
||||
--- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
|
||||
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
|
||||
@@ -524,6 +524,10 @@ void rtl92c_dm_write_dig(struct ieee80211_hw *hw)
|
||||
dm_digtable.cur_igvalue, dm_digtable.pre_igvalue,
|
||||
dm_digtable.backoff_val));
|
||||
|
||||
+ dm_digtable.cur_igvalue += 2;
|
||||
+ if (dm_digtable.cur_igvalue > 0x3f)
|
||||
+ dm_digtable.cur_igvalue = 0x3f;
|
||||
+
|
||||
if (dm_digtable.pre_igvalue != dm_digtable.cur_igvalue) {
|
||||
rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f,
|
||||
dm_digtable.cur_igvalue);
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
From 3d581df915fb46fe7929371df85da52ec6d65d69 Mon Sep 17 00:00:00 2001
|
||||
From: Johannes Berg <johannes.berg@intel.com>
|
||||
Date: Sun, 4 Mar 2012 08:50:46 -0800
|
||||
Subject: [PATCH 040/147] iwlwifi: always monitor for stuck queues
|
||||
|
||||
commit 342bbf3fee2fa9a18147e74b2e3c4229a4564912 upstream.
|
||||
|
||||
If we only monitor while associated, the following
|
||||
can happen:
|
||||
- we're associated, and the queue stuck check
|
||||
runs, setting the queue "touch" time to X
|
||||
- we disassociate, stopping the monitoring,
|
||||
which leaves the time set to X
|
||||
- almost 2s later, we associate, and enqueue
|
||||
a frame
|
||||
- before the frame is transmitted, we monitor
|
||||
for stuck queues, and find the time set to
|
||||
X, although it is now later than X + 2000ms,
|
||||
so we decide that the queue is stuck and
|
||||
erroneously restart the device
|
||||
|
||||
It happens more with P2P because there we can
|
||||
go between associated/unassociated frequently.
|
||||
|
||||
Reported-by: Ben Cahill <ben.m.cahill@intel.com>
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
|
||||
Signed-off-by: John W. Linville <linville@tuxdriver.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/net/wireless/iwlwifi/iwl-core.c | 18 ++++--------------
|
||||
1 file changed, 4 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
|
||||
index fcf5416..3d75d4c 100644
|
||||
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
|
||||
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
|
||||
@@ -1787,20 +1787,10 @@ void iwl_bg_watchdog(unsigned long data)
|
||||
if (timeout == 0)
|
||||
return;
|
||||
|
||||
- /* monitor and check for stuck cmd queue */
|
||||
- if (iwl_check_stuck_queue(priv, priv->shrd->cmd_queue))
|
||||
- return;
|
||||
-
|
||||
- /* monitor and check for other stuck queues */
|
||||
- if (iwl_is_any_associated(priv)) {
|
||||
- for (cnt = 0; cnt < hw_params(priv).max_txq_num; cnt++) {
|
||||
- /* skip as we already checked the command queue */
|
||||
- if (cnt == priv->shrd->cmd_queue)
|
||||
- continue;
|
||||
- if (iwl_check_stuck_queue(priv, cnt))
|
||||
- return;
|
||||
- }
|
||||
- }
|
||||
+ /* monitor and check for stuck queues */
|
||||
+ for (cnt = 0; cnt < hw_params(priv).max_txq_num; cnt++)
|
||||
+ if (iwl_check_stuck_queue(priv, cnt))
|
||||
+ return;
|
||||
|
||||
mod_timer(&priv->watchdog, jiffies +
|
||||
msecs_to_jiffies(IWL_WD_TICK(timeout)));
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
From 0041e471301214d86b8d15b4da69899f47161df6 Mon Sep 17 00:00:00 2001
|
||||
From: Sasha Levin <levinsasha928@gmail.com>
|
||||
Date: Thu, 15 Mar 2012 12:36:13 -0400
|
||||
Subject: [PATCH 041/147] math: Introduce div64_long
|
||||
|
||||
commit f910381a55cdaa097030291f272f6e6e4380c39a upstream.
|
||||
|
||||
Add a div64_long macro which is used to devide a 64bit number by a long (which
|
||||
can be 4 bytes on 32bit systems and 8 bytes on 64bit systems).
|
||||
|
||||
Suggested-by: Thomas Gleixner <tglx@linutronix.de>
|
||||
Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
|
||||
Cc: johnstul@us.ibm.com
|
||||
Link: http://lkml.kernel.org/r/1331829374-31543-1-git-send-email-levinsasha928@gmail.com
|
||||
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
include/linux/math64.h | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/include/linux/math64.h b/include/linux/math64.h
|
||||
index 23fcdfc..b8ba855 100644
|
||||
--- a/include/linux/math64.h
|
||||
+++ b/include/linux/math64.h
|
||||
@@ -6,6 +6,8 @@
|
||||
|
||||
#if BITS_PER_LONG == 64
|
||||
|
||||
+#define div64_long(x,y) div64_s64((x),(y))
|
||||
+
|
||||
/**
|
||||
* div_u64_rem - unsigned 64bit divide with 32bit divisor with remainder
|
||||
*
|
||||
@@ -45,6 +47,8 @@ static inline s64 div64_s64(s64 dividend, s64 divisor)
|
||||
|
||||
#elif BITS_PER_LONG == 32
|
||||
|
||||
+#define div64_long(x,y) div_s64((x),(y))
|
||||
+
|
||||
#ifndef div_u64_rem
|
||||
static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder)
|
||||
{
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
From c763173b9ab87b7413e63a82be88987250677b89 Mon Sep 17 00:00:00 2001
|
||||
From: Sasha Levin <levinsasha928@gmail.com>
|
||||
Date: Thu, 15 Mar 2012 12:36:14 -0400
|
||||
Subject: [PATCH 042/147] ntp: Fix integer overflow when setting time
|
||||
|
||||
commit a078c6d0e6288fad6d83fb6d5edd91ddb7b6ab33 upstream.
|
||||
|
||||
'long secs' is passed as divisor to div_s64, which accepts a 32bit
|
||||
divisor. On 64bit machines that value is trimmed back from 8 bytes
|
||||
back to 4, causing a divide by zero when the number is bigger than
|
||||
(1 << 32) - 1 and all 32 lower bits are 0.
|
||||
|
||||
Use div64_long() instead.
|
||||
|
||||
Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
|
||||
Cc: johnstul@us.ibm.com
|
||||
Link: http://lkml.kernel.org/r/1331829374-31543-2-git-send-email-levinsasha928@gmail.com
|
||||
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
kernel/time/ntp.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
|
||||
index f6117a4..4b85a7a 100644
|
||||
--- a/kernel/time/ntp.c
|
||||
+++ b/kernel/time/ntp.c
|
||||
@@ -275,7 +275,7 @@ static inline s64 ntp_update_offset_fll(s64 offset64, long secs)
|
||||
|
||||
time_status |= STA_MODE;
|
||||
|
||||
- return div_s64(offset64 << (NTP_SCALE_SHIFT - SHIFT_FLL), secs);
|
||||
+ return div64_long(offset64 << (NTP_SCALE_SHIFT - SHIFT_FLL), secs);
|
||||
}
|
||||
|
||||
static void ntp_update_offset(long offset)
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
From 30890ccb8ef54dedb2569535dbb781fa2f10a119 Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Vagin <avagin@openvz.org>
|
||||
Date: Wed, 7 Mar 2012 14:49:56 +0400
|
||||
Subject: [PATCH 043/147] uevent: send events in correct order according to
|
||||
seqnum (v3)
|
||||
|
||||
commit 7b60a18da393ed70db043a777fd9e6d5363077c4 upstream.
|
||||
|
||||
The queue handling in the udev daemon assumes that the events are
|
||||
ordered.
|
||||
|
||||
Before this patch uevent_seqnum is incremented under sequence_lock,
|
||||
than an event is send uner uevent_sock_mutex. I want to say that code
|
||||
contained a window between incrementing seqnum and sending an event.
|
||||
|
||||
This patch locks uevent_sock_mutex before incrementing uevent_seqnum.
|
||||
|
||||
v2: delete sequence_lock, uevent_seqnum is protected by uevent_sock_mutex
|
||||
v3: unlock the mutex before the goto exit
|
||||
|
||||
Thanks for Kay for the comments.
|
||||
|
||||
Signed-off-by: Andrew Vagin <avagin@openvz.org>
|
||||
Tested-By: Kay Sievers <kay.sievers@vrfy.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
lib/kobject_uevent.c | 19 +++++++++----------
|
||||
1 file changed, 9 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c
|
||||
index ad72a03..6d40244 100644
|
||||
--- a/lib/kobject_uevent.c
|
||||
+++ b/lib/kobject_uevent.c
|
||||
@@ -29,16 +29,17 @@
|
||||
|
||||
u64 uevent_seqnum;
|
||||
char uevent_helper[UEVENT_HELPER_PATH_LEN] = CONFIG_UEVENT_HELPER_PATH;
|
||||
-static DEFINE_SPINLOCK(sequence_lock);
|
||||
#ifdef CONFIG_NET
|
||||
struct uevent_sock {
|
||||
struct list_head list;
|
||||
struct sock *sk;
|
||||
};
|
||||
static LIST_HEAD(uevent_sock_list);
|
||||
-static DEFINE_MUTEX(uevent_sock_mutex);
|
||||
#endif
|
||||
|
||||
+/* This lock protects uevent_seqnum and uevent_sock_list */
|
||||
+static DEFINE_MUTEX(uevent_sock_mutex);
|
||||
+
|
||||
/* the strings here must match the enum in include/linux/kobject.h */
|
||||
static const char *kobject_actions[] = {
|
||||
[KOBJ_ADD] = "add",
|
||||
@@ -136,7 +137,6 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
|
||||
struct kobject *top_kobj;
|
||||
struct kset *kset;
|
||||
const struct kset_uevent_ops *uevent_ops;
|
||||
- u64 seq;
|
||||
int i = 0;
|
||||
int retval = 0;
|
||||
#ifdef CONFIG_NET
|
||||
@@ -243,17 +243,16 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
|
||||
else if (action == KOBJ_REMOVE)
|
||||
kobj->state_remove_uevent_sent = 1;
|
||||
|
||||
+ mutex_lock(&uevent_sock_mutex);
|
||||
/* we will send an event, so request a new sequence number */
|
||||
- spin_lock(&sequence_lock);
|
||||
- seq = ++uevent_seqnum;
|
||||
- spin_unlock(&sequence_lock);
|
||||
- retval = add_uevent_var(env, "SEQNUM=%llu", (unsigned long long)seq);
|
||||
- if (retval)
|
||||
+ retval = add_uevent_var(env, "SEQNUM=%llu", (unsigned long long)++uevent_seqnum);
|
||||
+ if (retval) {
|
||||
+ mutex_unlock(&uevent_sock_mutex);
|
||||
goto exit;
|
||||
+ }
|
||||
|
||||
#if defined(CONFIG_NET)
|
||||
/* send netlink message */
|
||||
- mutex_lock(&uevent_sock_mutex);
|
||||
list_for_each_entry(ue_sk, &uevent_sock_list, list) {
|
||||
struct sock *uevent_sock = ue_sk->sk;
|
||||
struct sk_buff *skb;
|
||||
@@ -287,8 +286,8 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
|
||||
} else
|
||||
retval = -ENOMEM;
|
||||
}
|
||||
- mutex_unlock(&uevent_sock_mutex);
|
||||
#endif
|
||||
+ mutex_unlock(&uevent_sock_mutex);
|
||||
|
||||
/* call uevent_helper, usually only enabled during early boot */
|
||||
if (uevent_helper[0] && !kobj_usermode_filter(kobj)) {
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
From 30baeed7abf879cdb6abc168307abd194d0d2668 Mon Sep 17 00:00:00 2001
|
||||
From: Russell King <linux@arm.linux.org.uk>
|
||||
Date: Mon, 5 Mar 2012 15:07:25 -0800
|
||||
Subject: [PATCH 044/147] genirq: Fix long-term regression in genirq
|
||||
irq_set_irq_type() handling
|
||||
|
||||
commit a09b659cd68c10ec6a30cb91ebd2c327fcd5bfe5 upstream.
|
||||
|
||||
In 2008, commit 0c5d1eb77a8be ("genirq: record trigger type") modified the
|
||||
way set_irq_type() handles the 'no trigger' condition. However, this has
|
||||
an adverse effect on PCMCIA support on Intel StrongARM and probably PXA
|
||||
platforms.
|
||||
|
||||
PCMCIA has several status signals on the socket which can trigger
|
||||
interrupts; some of these status signals depend on the card's mode
|
||||
(whether it is configured in memory or IO mode). For example, cards have
|
||||
a 'Ready/IRQ' signal: in memory mode, this provides an indication to
|
||||
PCMCIA that the card has finished its power up initialization. In IO
|
||||
mode, it provides the device interrupt signal. Other status signals
|
||||
switch between on-board battery status and loud speaker output.
|
||||
|
||||
In classical PCMCIA implementations, where you have a specific socket
|
||||
controller, the controller provides a method to mask interrupts from the
|
||||
socket, and importantly ignore any state transitions on the pins which
|
||||
correspond with interrupts once masked. This masking prevents unwanted
|
||||
events caused by the removal and application of socket power being
|
||||
forwarded.
|
||||
|
||||
However, on platforms where there is no socket controller, the PCMCIA
|
||||
status and interrupt signals are routed to standard edge-triggered GPIOs.
|
||||
These GPIOs can be configured to interrupt on rising edge, falling edge,
|
||||
or never. This is where the problems start.
|
||||
|
||||
Edge triggered interrupts are required to record events while disabled via
|
||||
the usual methods of {free,request,disable,enable}_irq() to prevent
|
||||
problems with dropped interrupts (eg, the 8390 driver uses disable_irq()
|
||||
to defer the delivery of interrupts). As a result, these interfaces can
|
||||
not be used to implement the desired behaviour.
|
||||
|
||||
The side effect of this is that if the 'Ready/IRQ' GPIO is disabled via
|
||||
disable_irq() on suspend, and enabled via enable_irq() after resume, we
|
||||
will record the state transitions caused by powering events as valid
|
||||
interrupts, and foward them to the card driver, which may attempt to
|
||||
access a card which is not powered up.
|
||||
|
||||
This leads delays resume while drivers spin in their interrupt handlers,
|
||||
and complaints from drivers before they realize what's happened.
|
||||
|
||||
Moreover, in the case of the 'Ready/IRQ' signal, this is requested and
|
||||
freed by the card driver itself; the PCMCIA core has no idea whether the
|
||||
interrupt is requested, and, therefore, whether a call to disable_irq()
|
||||
would be valid. (We tried this around 2.4.17 / 2.5.1 kernel era, and
|
||||
ended up throwing it out because of this problem.)
|
||||
|
||||
Therefore, it was decided back in around 2002 to disable the edge
|
||||
triggering instead, resulting in all state transitions on the GPIO being
|
||||
ignored. That's what we actually need the hardware to do.
|
||||
|
||||
The commit above changes this behaviour; it explicitly prevents the 'no
|
||||
trigger' state being selected.
|
||||
|
||||
The reason that request_irq() does not accept the 'no trigger' state is
|
||||
for compatibility with existing drivers which do not provide their desired
|
||||
triggering configuration. The set_irq_type() function is 'new' and not
|
||||
used by non-trigger aware drivers.
|
||||
|
||||
Therefore, revert this change, and restore previously working platforms
|
||||
back to their former state.
|
||||
|
||||
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
|
||||
Cc: linux@arm.linux.org.uk
|
||||
Cc: Ingo Molnar <mingo@elte.hu>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
kernel/irq/chip.c | 3 +--
|
||||
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||
|
||||
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
|
||||
index fb7db75..25784d6 100644
|
||||
--- a/kernel/irq/chip.c
|
||||
+++ b/kernel/irq/chip.c
|
||||
@@ -61,8 +61,7 @@ int irq_set_irq_type(unsigned int irq, unsigned int type)
|
||||
return -EINVAL;
|
||||
|
||||
type &= IRQ_TYPE_SENSE_MASK;
|
||||
- if (type != IRQ_TYPE_NONE)
|
||||
- ret = __irq_set_trigger(desc, irq, type);
|
||||
+ ret = __irq_set_trigger(desc, irq, type);
|
||||
irq_put_desc_busunlock(desc, flags);
|
||||
return ret;
|
||||
}
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
From 8cc03040447868b0c8ca3f6ca027fdf45216f493 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Gordeev <agordeev@redhat.com>
|
||||
Date: Fri, 9 Mar 2012 14:59:13 +0100
|
||||
Subject: [PATCH 045/147] genirq: Fix incorrect check for forced IRQ thread
|
||||
handler
|
||||
|
||||
commit 540b60e24f3f4781d80e47122f0c4486a03375b8 upstream.
|
||||
|
||||
We do not want a bitwise AND between boolean operands
|
||||
|
||||
Signed-off-by: Alexander Gordeev <agordeev@redhat.com>
|
||||
Cc: Oleg Nesterov <oleg@redhat.com>
|
||||
Link: http://lkml.kernel.org/r/20120309135912.GA2114@dhcp-26-207.brq.redhat.com
|
||||
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
kernel/irq/manage.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
|
||||
index ae95cd2..7600092 100644
|
||||
--- a/kernel/irq/manage.c
|
||||
+++ b/kernel/irq/manage.c
|
||||
@@ -773,7 +773,7 @@ static int irq_thread(void *data)
|
||||
struct irqaction *action);
|
||||
int wake;
|
||||
|
||||
- if (force_irqthreads & test_bit(IRQTF_FORCED_THREAD,
|
||||
+ if (force_irqthreads && test_bit(IRQTF_FORCED_THREAD,
|
||||
&action->thread_flags))
|
||||
handler_fn = irq_forced_thread_fn;
|
||||
else
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
From 7d3eb8bf92abead3bd005400d600f32ea4bf9d63 Mon Sep 17 00:00:00 2001
|
||||
From: Rabin Vincent <rabin.vincent@stericsson.com>
|
||||
Date: Tue, 22 Nov 2011 11:03:14 +0100
|
||||
Subject: [PATCH 046/147] rtc: Disable the alarm in the hardware (v2)
|
||||
|
||||
commit 41c7f7424259ff11009449f87c95656f69f9b186 upstream.
|
||||
|
||||
Currently, the RTC code does not disable the alarm in the hardware.
|
||||
|
||||
This means that after a sequence such as the one below (the files are in the
|
||||
RTC sysfs), the box will boot up after 2 minutes even though we've
|
||||
asked for the alarm to be turned off.
|
||||
|
||||
# echo $((`cat since_epoch`)+120) > wakealarm
|
||||
# echo 0 > wakealarm
|
||||
# poweroff
|
||||
|
||||
Fix this by disabling the alarm when there are no timers to run.
|
||||
|
||||
The original version of this patch was reverted. This version
|
||||
disables the irq directly instead of setting a disabled timer
|
||||
in the future.
|
||||
|
||||
Cc: John Stultz <john.stultz@linaro.org>
|
||||
Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com>
|
||||
[Merged in the second revision from Rabin]
|
||||
Signed-off-by: John Stultz <john.stultz@linaro.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/rtc/interface.c | 15 +++++++++++++--
|
||||
1 file changed, 13 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
|
||||
index 8a1c031..c1edbf8 100644
|
||||
--- a/drivers/rtc/interface.c
|
||||
+++ b/drivers/rtc/interface.c
|
||||
@@ -763,6 +763,14 @@ static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static void rtc_alarm_disable(struct rtc_device *rtc)
|
||||
+{
|
||||
+ if (!rtc->ops || !rtc->ops->alarm_irq_enable)
|
||||
+ return;
|
||||
+
|
||||
+ rtc->ops->alarm_irq_enable(rtc->dev.parent, false);
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* rtc_timer_remove - Removes a rtc_timer from the rtc_device timerqueue
|
||||
* @rtc rtc device
|
||||
@@ -784,8 +792,10 @@ static void rtc_timer_remove(struct rtc_device *rtc, struct rtc_timer *timer)
|
||||
struct rtc_wkalrm alarm;
|
||||
int err;
|
||||
next = timerqueue_getnext(&rtc->timerqueue);
|
||||
- if (!next)
|
||||
+ if (!next) {
|
||||
+ rtc_alarm_disable(rtc);
|
||||
return;
|
||||
+ }
|
||||
alarm.time = rtc_ktime_to_tm(next->expires);
|
||||
alarm.enabled = 1;
|
||||
err = __rtc_set_alarm(rtc, &alarm);
|
||||
@@ -847,7 +857,8 @@ again:
|
||||
err = __rtc_set_alarm(rtc, &alarm);
|
||||
if (err == -ETIME)
|
||||
goto again;
|
||||
- }
|
||||
+ } else
|
||||
+ rtc_alarm_disable(rtc);
|
||||
|
||||
mutex_unlock(&rtc->ops_lock);
|
||||
}
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
From 4a8252cb16f69ca39f21e3bf65064d70046adf38 Mon Sep 17 00:00:00 2001
|
||||
From: Max Filippov <jcmvbkbc@gmail.com>
|
||||
Date: Thu, 1 Mar 2012 00:40:08 +0400
|
||||
Subject: [PATCH 047/147] p54spi: Release GPIO lines and IRQ on error in
|
||||
p54spi_probe
|
||||
|
||||
commit 62ebeed8d00aef75eac4fd6c161cae75a41965ca upstream.
|
||||
|
||||
This makes it possible to reload driver if insmod has failed due to
|
||||
missing firmware.
|
||||
|
||||
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
|
||||
Acked-by: Christian Lamparter <chunkeey@googlemail.com>
|
||||
Signed-off-by: John W. Linville <linville@tuxdriver.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/net/wireless/p54/p54spi.c | 14 ++++++++++----
|
||||
1 file changed, 10 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c
|
||||
index 78d0d69..428401b 100644
|
||||
--- a/drivers/net/wireless/p54/p54spi.c
|
||||
+++ b/drivers/net/wireless/p54/p54spi.c
|
||||
@@ -622,19 +622,19 @@ static int __devinit p54spi_probe(struct spi_device *spi)
|
||||
ret = spi_setup(spi);
|
||||
if (ret < 0) {
|
||||
dev_err(&priv->spi->dev, "spi_setup failed");
|
||||
- goto err_free_common;
|
||||
+ goto err_free;
|
||||
}
|
||||
|
||||
ret = gpio_request(p54spi_gpio_power, "p54spi power");
|
||||
if (ret < 0) {
|
||||
dev_err(&priv->spi->dev, "power GPIO request failed: %d", ret);
|
||||
- goto err_free_common;
|
||||
+ goto err_free;
|
||||
}
|
||||
|
||||
ret = gpio_request(p54spi_gpio_irq, "p54spi irq");
|
||||
if (ret < 0) {
|
||||
dev_err(&priv->spi->dev, "irq GPIO request failed: %d", ret);
|
||||
- goto err_free_common;
|
||||
+ goto err_free_gpio_power;
|
||||
}
|
||||
|
||||
gpio_direction_output(p54spi_gpio_power, 0);
|
||||
@@ -645,7 +645,7 @@ static int __devinit p54spi_probe(struct spi_device *spi)
|
||||
priv->spi);
|
||||
if (ret < 0) {
|
||||
dev_err(&priv->spi->dev, "request_irq() failed");
|
||||
- goto err_free_common;
|
||||
+ goto err_free_gpio_irq;
|
||||
}
|
||||
|
||||
irq_set_irq_type(gpio_to_irq(p54spi_gpio_irq), IRQ_TYPE_EDGE_RISING);
|
||||
@@ -677,6 +677,12 @@ static int __devinit p54spi_probe(struct spi_device *spi)
|
||||
return 0;
|
||||
|
||||
err_free_common:
|
||||
+ free_irq(gpio_to_irq(p54spi_gpio_irq), spi);
|
||||
+err_free_gpio_irq:
|
||||
+ gpio_free(p54spi_gpio_irq);
|
||||
+err_free_gpio_power:
|
||||
+ gpio_free(p54spi_gpio_power);
|
||||
+err_free:
|
||||
p54_free_common(priv->hw);
|
||||
return ret;
|
||||
}
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
From cf7eecb4e8e024ff0de45c29a63241a518ddf4a0 Mon Sep 17 00:00:00 2001
|
||||
From: Greg Rose <gregory.v.rose@intel.com>
|
||||
Date: Wed, 8 Feb 2012 00:45:00 +0000
|
||||
Subject: [PATCH 048/147] rtnetlink: Fix VF IFLA policy
|
||||
|
||||
commit 48752f6513012a1b078da08b145d5c40a644f058 upstream.
|
||||
|
||||
Add VF spoof check to IFLA policy. The original patch I submitted to
|
||||
add the spoof checking feature to rtnl failed to add the proper policy
|
||||
rule that identifies the data type and len. This patch corrects that
|
||||
oversight. No bugs have been reported against this but it may cause
|
||||
some problem for the netlink message parsing that uses the policy
|
||||
table.
|
||||
|
||||
Signed-off-by: Greg Rose <gregory.v.rose@intel.com>
|
||||
Tested-by: Sibai Li <sibai.li@intel.com>
|
||||
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
net/core/rtnetlink.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
|
||||
index 9083e82..2ef859a 100644
|
||||
--- a/net/core/rtnetlink.c
|
||||
+++ b/net/core/rtnetlink.c
|
||||
@@ -1116,6 +1116,8 @@ static const struct nla_policy ifla_vf_policy[IFLA_VF_MAX+1] = {
|
||||
.len = sizeof(struct ifla_vf_vlan) },
|
||||
[IFLA_VF_TX_RATE] = { .type = NLA_BINARY,
|
||||
.len = sizeof(struct ifla_vf_tx_rate) },
|
||||
+ [IFLA_VF_SPOOFCHK] = { .type = NLA_BINARY,
|
||||
+ .len = sizeof(struct ifla_vf_spoofchk) },
|
||||
};
|
||||
|
||||
static const struct nla_policy ifla_port_policy[IFLA_PORT_MAX+1] = {
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
From de960f13b12a65cff5f74f1f7bb6871fbd9ac432 Mon Sep 17 00:00:00 2001
|
||||
From: Or Gerlitz <ogerlitz@mellanox.com>
|
||||
Date: Mon, 5 Mar 2012 18:21:44 +0200
|
||||
Subject: [PATCH 049/147] IB/iser: Post initial receive buffers before sending
|
||||
the final login request
|
||||
|
||||
commit 89e984e2c2cd14f77ccb26c47726ac7f13b70ae8 upstream.
|
||||
|
||||
An iser target may send iscsi NO-OP PDUs as soon as it marks the iSER
|
||||
iSCSI session as fully operative. This means that there is window
|
||||
where there are no posted receive buffers on the initiator side, so
|
||||
it's possible for the iSER RC connection to break because of RNR NAK /
|
||||
retry errors. To fix this, rely on the flags bits in the login
|
||||
request to have FFP (0x3) in the lower nibble as a marker for the
|
||||
final login request, and post an initial chunk of receive buffers
|
||||
before sending that login request instead of after getting the login
|
||||
response.
|
||||
|
||||
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
|
||||
Signed-off-by: Roland Dreier <roland@purestorage.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/infiniband/ulp/iser/iscsi_iser.c | 18 ++++------------
|
||||
drivers/infiniband/ulp/iser/iscsi_iser.h | 1 +
|
||||
drivers/infiniband/ulp/iser/iser_initiator.c | 30 +++++++++++++++-----------
|
||||
3 files changed, 22 insertions(+), 27 deletions(-)
|
||||
|
||||
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c
|
||||
index 7e7373a..d5f3b69 100644
|
||||
--- a/drivers/infiniband/ulp/iser/iscsi_iser.c
|
||||
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.c
|
||||
@@ -364,6 +364,9 @@ iscsi_iser_conn_bind(struct iscsi_cls_session *cls_session,
|
||||
}
|
||||
ib_conn = ep->dd_data;
|
||||
|
||||
+ if (iser_alloc_rx_descriptors(ib_conn))
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
/* binds the iSER connection retrieved from the previously
|
||||
* connected ep_handle to the iSCSI layer connection. exchanges
|
||||
* connection pointers */
|
||||
@@ -398,19 +401,6 @@ iscsi_iser_conn_stop(struct iscsi_cls_conn *cls_conn, int flag)
|
||||
iser_conn->ib_conn = NULL;
|
||||
}
|
||||
|
||||
-static int
|
||||
-iscsi_iser_conn_start(struct iscsi_cls_conn *cls_conn)
|
||||
-{
|
||||
- struct iscsi_conn *conn = cls_conn->dd_data;
|
||||
- int err;
|
||||
-
|
||||
- err = iser_conn_set_full_featured_mode(conn);
|
||||
- if (err)
|
||||
- return err;
|
||||
-
|
||||
- return iscsi_conn_start(cls_conn);
|
||||
-}
|
||||
-
|
||||
static void iscsi_iser_session_destroy(struct iscsi_cls_session *cls_session)
|
||||
{
|
||||
struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
|
||||
@@ -724,7 +714,7 @@ static struct iscsi_transport iscsi_iser_transport = {
|
||||
.get_conn_param = iscsi_conn_get_param,
|
||||
.get_ep_param = iscsi_iser_get_ep_param,
|
||||
.get_session_param = iscsi_session_get_param,
|
||||
- .start_conn = iscsi_iser_conn_start,
|
||||
+ .start_conn = iscsi_conn_start,
|
||||
.stop_conn = iscsi_iser_conn_stop,
|
||||
/* iscsi host params */
|
||||
.get_host_param = iscsi_host_get_param,
|
||||
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h
|
||||
index db7ea37..296be43 100644
|
||||
--- a/drivers/infiniband/ulp/iser/iscsi_iser.h
|
||||
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.h
|
||||
@@ -366,4 +366,5 @@ int iser_dma_map_task_data(struct iscsi_iser_task *iser_task,
|
||||
void iser_dma_unmap_task_data(struct iscsi_iser_task *iser_task);
|
||||
int iser_initialize_task_headers(struct iscsi_task *task,
|
||||
struct iser_tx_desc *tx_desc);
|
||||
+int iser_alloc_rx_descriptors(struct iser_conn *ib_conn);
|
||||
#endif
|
||||
diff --git a/drivers/infiniband/ulp/iser/iser_initiator.c b/drivers/infiniband/ulp/iser/iser_initiator.c
|
||||
index a607542..738a149 100644
|
||||
--- a/drivers/infiniband/ulp/iser/iser_initiator.c
|
||||
+++ b/drivers/infiniband/ulp/iser/iser_initiator.c
|
||||
@@ -170,7 +170,7 @@ static void iser_create_send_desc(struct iser_conn *ib_conn,
|
||||
}
|
||||
|
||||
|
||||
-static int iser_alloc_rx_descriptors(struct iser_conn *ib_conn)
|
||||
+int iser_alloc_rx_descriptors(struct iser_conn *ib_conn)
|
||||
{
|
||||
int i, j;
|
||||
u64 dma_addr;
|
||||
@@ -242,23 +242,24 @@ void iser_free_rx_descriptors(struct iser_conn *ib_conn)
|
||||
kfree(ib_conn->rx_descs);
|
||||
}
|
||||
|
||||
-/**
|
||||
- * iser_conn_set_full_featured_mode - (iSER API)
|
||||
- */
|
||||
-int iser_conn_set_full_featured_mode(struct iscsi_conn *conn)
|
||||
+static int iser_post_rx_bufs(struct iscsi_conn *conn, struct iscsi_hdr *req)
|
||||
{
|
||||
struct iscsi_iser_conn *iser_conn = conn->dd_data;
|
||||
|
||||
- iser_dbg("Initially post: %d\n", ISER_MIN_POSTED_RX);
|
||||
-
|
||||
- /* Check that there is no posted recv or send buffers left - */
|
||||
- /* they must be consumed during the login phase */
|
||||
- BUG_ON(iser_conn->ib_conn->post_recv_buf_count != 0);
|
||||
- BUG_ON(atomic_read(&iser_conn->ib_conn->post_send_buf_count) != 0);
|
||||
+ iser_dbg("req op %x flags %x\n", req->opcode, req->flags);
|
||||
+ /* check if this is the last login - going to full feature phase */
|
||||
+ if ((req->flags & ISCSI_FULL_FEATURE_PHASE) != ISCSI_FULL_FEATURE_PHASE)
|
||||
+ return 0;
|
||||
|
||||
- if (iser_alloc_rx_descriptors(iser_conn->ib_conn))
|
||||
- return -ENOMEM;
|
||||
+ /*
|
||||
+ * Check that there is one posted recv buffer (for the last login
|
||||
+ * response) and no posted send buffers left - they must have been
|
||||
+ * consumed during previous login phases.
|
||||
+ */
|
||||
+ WARN_ON(iser_conn->ib_conn->post_recv_buf_count != 1);
|
||||
+ WARN_ON(atomic_read(&iser_conn->ib_conn->post_send_buf_count) != 0);
|
||||
|
||||
+ iser_dbg("Initially post: %d\n", ISER_MIN_POSTED_RX);
|
||||
/* Initial post receive buffers */
|
||||
if (iser_post_recvm(iser_conn->ib_conn, ISER_MIN_POSTED_RX))
|
||||
return -ENOMEM;
|
||||
@@ -438,6 +439,9 @@ int iser_send_control(struct iscsi_conn *conn,
|
||||
err = iser_post_recvl(iser_conn->ib_conn);
|
||||
if (err)
|
||||
goto send_control_error;
|
||||
+ err = iser_post_rx_bufs(conn, task->hdr);
|
||||
+ if (err)
|
||||
+ goto send_control_error;
|
||||
}
|
||||
|
||||
err = iser_post_send(iser_conn->ib_conn, mdesc);
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
From 48128d2a875a34aeef5b89ed93e2887179534b33 Mon Sep 17 00:00:00 2001
|
||||
From: Fabio Estevam <festevam@gmail.com>
|
||||
Date: Thu, 5 Jan 2012 12:49:54 -0200
|
||||
Subject: [PATCH 050/147] ima: fix Kconfig dependencies
|
||||
|
||||
commit f4a0391dfa91155bd961673b31eb42d9d45c799d upstream.
|
||||
|
||||
Fix the following build warning:
|
||||
warning: (IMA) selects TCG_TPM which has unmet direct dependencies
|
||||
(HAS_IOMEM && EXPERIMENTAL)
|
||||
|
||||
Suggested-by: Rajiv Andrade <srajiv@linux.vnet.ibm.com>
|
||||
Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
|
||||
Signed-off-by: Rajiv Andrade <srajiv@linux.vnet.ibm.com>
|
||||
Signed-off-by: Mimi Zohar <zohar@us.ibm.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/char/tpm/Kconfig | 1 -
|
||||
security/integrity/ima/Kconfig | 2 +-
|
||||
2 files changed, 1 insertion(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig
|
||||
index fa567f1..c9e045c 100644
|
||||
--- a/drivers/char/tpm/Kconfig
|
||||
+++ b/drivers/char/tpm/Kconfig
|
||||
@@ -5,7 +5,6 @@
|
||||
menuconfig TCG_TPM
|
||||
tristate "TPM Hardware Support"
|
||||
depends on HAS_IOMEM
|
||||
- depends on EXPERIMENTAL
|
||||
select SECURITYFS
|
||||
---help---
|
||||
If you have a TPM security chip in your system, which
|
||||
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
|
||||
index 4f554f2..063298a 100644
|
||||
--- a/security/integrity/ima/Kconfig
|
||||
+++ b/security/integrity/ima/Kconfig
|
||||
@@ -9,7 +9,7 @@ config IMA
|
||||
select CRYPTO_HMAC
|
||||
select CRYPTO_MD5
|
||||
select CRYPTO_SHA1
|
||||
- select TCG_TPM if !S390 && !UML
|
||||
+ select TCG_TPM if HAS_IOMEM && !UML
|
||||
select TCG_TIS if TCG_TPM
|
||||
help
|
||||
The Trusted Computing Group(TCG) runtime Integrity
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
From 817b882783a89bae08689d9eff2b5af91f44c4e1 Mon Sep 17 00:00:00 2001
|
||||
From: Suresh Siddha <suresh.b.siddha@intel.com>
|
||||
Date: Mon, 12 Mar 2012 11:36:33 -0700
|
||||
Subject: [PATCH 051/147] x86/ioapic: Add register level checks to detect
|
||||
bogus io-apic entries
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
commit 73d63d038ee9f769f5e5b46792d227fe20e442c5 upstream.
|
||||
|
||||
With the recent changes to clear_IO_APIC_pin() which tries to
|
||||
clear remoteIRR bit explicitly, some of the users started to see
|
||||
"Unable to reset IRR for apic .." messages.
|
||||
|
||||
Close look shows that these are related to bogus IO-APIC entries
|
||||
which return's all 1's for their io-apic registers. And the
|
||||
above mentioned error messages are benign. But kernel should
|
||||
have ignored such io-apic's in the first place.
|
||||
|
||||
Check if register 0, 1, 2 of the listed io-apic are all 1's and
|
||||
ignore such io-apic.
|
||||
|
||||
Reported-by: ??lvaro Castillo <midgoon@gmail.com>
|
||||
Tested-by: Jon Dufresne <jon@jondufresne.org>
|
||||
Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
|
||||
Cc: yinghai@kernel.org
|
||||
Cc: kernel-team@fedoraproject.org
|
||||
Cc: Josh Boyer <jwboyer@redhat.com>
|
||||
Link: http://lkml.kernel.org/r/1331577393.31585.94.camel@sbsiddha-desk.sc.intel.com
|
||||
[ Performed minor cleanup of affected code. ]
|
||||
Signed-off-by: Ingo Molnar <mingo@elte.hu>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
arch/x86/kernel/apic/io_apic.c | 40 ++++++++++++++++++++++++++++++++--------
|
||||
1 file changed, 32 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
|
||||
index 6d939d7..a25e276 100644
|
||||
--- a/arch/x86/kernel/apic/io_apic.c
|
||||
+++ b/arch/x86/kernel/apic/io_apic.c
|
||||
@@ -3963,18 +3963,36 @@ int mp_find_ioapic_pin(int ioapic, u32 gsi)
|
||||
static __init int bad_ioapic(unsigned long address)
|
||||
{
|
||||
if (nr_ioapics >= MAX_IO_APICS) {
|
||||
- printk(KERN_WARNING "WARNING: Max # of I/O APICs (%d) exceeded "
|
||||
- "(found %d), skipping\n", MAX_IO_APICS, nr_ioapics);
|
||||
+ pr_warn("WARNING: Max # of I/O APICs (%d) exceeded (found %d), skipping\n",
|
||||
+ MAX_IO_APICS, nr_ioapics);
|
||||
return 1;
|
||||
}
|
||||
if (!address) {
|
||||
- printk(KERN_WARNING "WARNING: Bogus (zero) I/O APIC address"
|
||||
- " found in table, skipping!\n");
|
||||
+ pr_warn("WARNING: Bogus (zero) I/O APIC address found in table, skipping!\n");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static __init int bad_ioapic_register(int idx)
|
||||
+{
|
||||
+ union IO_APIC_reg_00 reg_00;
|
||||
+ union IO_APIC_reg_01 reg_01;
|
||||
+ union IO_APIC_reg_02 reg_02;
|
||||
+
|
||||
+ reg_00.raw = io_apic_read(idx, 0);
|
||||
+ reg_01.raw = io_apic_read(idx, 1);
|
||||
+ reg_02.raw = io_apic_read(idx, 2);
|
||||
+
|
||||
+ if (reg_00.raw == -1 && reg_01.raw == -1 && reg_02.raw == -1) {
|
||||
+ pr_warn("I/O APIC 0x%x registers return all ones, skipping!\n",
|
||||
+ mpc_ioapic_addr(idx));
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
|
||||
{
|
||||
int idx = 0;
|
||||
@@ -3991,6 +4009,12 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
|
||||
ioapics[idx].mp_config.apicaddr = address;
|
||||
|
||||
set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address);
|
||||
+
|
||||
+ if (bad_ioapic_register(idx)) {
|
||||
+ clear_fixmap(FIX_IO_APIC_BASE_0 + idx);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
ioapics[idx].mp_config.apicid = io_apic_unique_id(id);
|
||||
ioapics[idx].mp_config.apicver = io_apic_get_version(idx);
|
||||
|
||||
@@ -4011,10 +4035,10 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
|
||||
if (gsi_cfg->gsi_end >= gsi_top)
|
||||
gsi_top = gsi_cfg->gsi_end + 1;
|
||||
|
||||
- printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%x, "
|
||||
- "GSI %d-%d\n", idx, mpc_ioapic_id(idx),
|
||||
- mpc_ioapic_ver(idx), mpc_ioapic_addr(idx),
|
||||
- gsi_cfg->gsi_base, gsi_cfg->gsi_end);
|
||||
+ pr_info("IOAPIC[%d]: apic_id %d, version %d, address 0x%x, GSI %d-%d\n",
|
||||
+ idx, mpc_ioapic_id(idx),
|
||||
+ mpc_ioapic_ver(idx), mpc_ioapic_addr(idx),
|
||||
+ gsi_cfg->gsi_base, gsi_cfg->gsi_end);
|
||||
|
||||
nr_ioapics++;
|
||||
}
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,480 @@
|
||||
From 11c78e244603f384d1f8cebc627823cc01e952eb Mon Sep 17 00:00:00 2001
|
||||
From: Andrea Arcangeli <aarcange@redhat.com>
|
||||
Date: Wed, 21 Mar 2012 16:33:42 -0700
|
||||
Subject: [PATCH 052/147] mm: thp: fix pmd_bad() triggering in code paths
|
||||
holding mmap_sem read mode
|
||||
|
||||
commit 1a5a9906d4e8d1976b701f889d8f35d54b928f25 upstream.
|
||||
|
||||
In some cases it may happen that pmd_none_or_clear_bad() is called with
|
||||
the mmap_sem hold in read mode. In those cases the huge page faults can
|
||||
allocate hugepmds under pmd_none_or_clear_bad() and that can trigger a
|
||||
false positive from pmd_bad() that will not like to see a pmd
|
||||
materializing as trans huge.
|
||||
|
||||
It's not khugepaged causing the problem, khugepaged holds the mmap_sem
|
||||
in write mode (and all those sites must hold the mmap_sem in read mode
|
||||
to prevent pagetables to go away from under them, during code review it
|
||||
seems vm86 mode on 32bit kernels requires that too unless it's
|
||||
restricted to 1 thread per process or UP builds). The race is only with
|
||||
the huge pagefaults that can convert a pmd_none() into a
|
||||
pmd_trans_huge().
|
||||
|
||||
Effectively all these pmd_none_or_clear_bad() sites running with
|
||||
mmap_sem in read mode are somewhat speculative with the page faults, and
|
||||
the result is always undefined when they run simultaneously. This is
|
||||
probably why it wasn't common to run into this. For example if the
|
||||
madvise(MADV_DONTNEED) runs zap_page_range() shortly before the page
|
||||
fault, the hugepage will not be zapped, if the page fault runs first it
|
||||
will be zapped.
|
||||
|
||||
Altering pmd_bad() not to error out if it finds hugepmds won't be enough
|
||||
to fix this, because zap_pmd_range would then proceed to call
|
||||
zap_pte_range (which would be incorrect if the pmd become a
|
||||
pmd_trans_huge()).
|
||||
|
||||
The simplest way to fix this is to read the pmd in the local stack
|
||||
(regardless of what we read, no need of actual CPU barriers, only
|
||||
compiler barrier needed), and be sure it is not changing under the code
|
||||
that computes its value. Even if the real pmd is changing under the
|
||||
value we hold on the stack, we don't care. If we actually end up in
|
||||
zap_pte_range it means the pmd was not none already and it was not huge,
|
||||
and it can't become huge from under us (khugepaged locking explained
|
||||
above).
|
||||
|
||||
All we need is to enforce that there is no way anymore that in a code
|
||||
path like below, pmd_trans_huge can be false, but pmd_none_or_clear_bad
|
||||
can run into a hugepmd. The overhead of a barrier() is just a compiler
|
||||
tweak and should not be measurable (I only added it for THP builds). I
|
||||
don't exclude different compiler versions may have prevented the race
|
||||
too by caching the value of *pmd on the stack (that hasn't been
|
||||
verified, but it wouldn't be impossible considering
|
||||
pmd_none_or_clear_bad, pmd_bad, pmd_trans_huge, pmd_none are all inlines
|
||||
and there's no external function called in between pmd_trans_huge and
|
||||
pmd_none_or_clear_bad).
|
||||
|
||||
if (pmd_trans_huge(*pmd)) {
|
||||
if (next-addr != HPAGE_PMD_SIZE) {
|
||||
VM_BUG_ON(!rwsem_is_locked(&tlb->mm->mmap_sem));
|
||||
split_huge_page_pmd(vma->vm_mm, pmd);
|
||||
} else if (zap_huge_pmd(tlb, vma, pmd, addr))
|
||||
continue;
|
||||
/* fall through */
|
||||
}
|
||||
if (pmd_none_or_clear_bad(pmd))
|
||||
|
||||
Because this race condition could be exercised without special
|
||||
privileges this was reported in CVE-2012-1179.
|
||||
|
||||
The race was identified and fully explained by Ulrich who debugged it.
|
||||
I'm quoting his accurate explanation below, for reference.
|
||||
|
||||
====== start quote =======
|
||||
mapcount 0 page_mapcount 1
|
||||
kernel BUG at mm/huge_memory.c:1384!
|
||||
|
||||
At some point prior to the panic, a "bad pmd ..." message similar to the
|
||||
following is logged on the console:
|
||||
|
||||
mm/memory.c:145: bad pmd ffff8800376e1f98(80000000314000e7).
|
||||
|
||||
The "bad pmd ..." message is logged by pmd_clear_bad() before it clears
|
||||
the page's PMD table entry.
|
||||
|
||||
143 void pmd_clear_bad(pmd_t *pmd)
|
||||
144 {
|
||||
-> 145 pmd_ERROR(*pmd);
|
||||
146 pmd_clear(pmd);
|
||||
147 }
|
||||
|
||||
After the PMD table entry has been cleared, there is an inconsistency
|
||||
between the actual number of PMD table entries that are mapping the page
|
||||
and the page's map count (_mapcount field in struct page). When the page
|
||||
is subsequently reclaimed, __split_huge_page() detects this inconsistency.
|
||||
|
||||
1381 if (mapcount != page_mapcount(page))
|
||||
1382 printk(KERN_ERR "mapcount %d page_mapcount %d\n",
|
||||
1383 mapcount, page_mapcount(page));
|
||||
-> 1384 BUG_ON(mapcount != page_mapcount(page));
|
||||
|
||||
The root cause of the problem is a race of two threads in a multithreaded
|
||||
process. Thread B incurs a page fault on a virtual address that has never
|
||||
been accessed (PMD entry is zero) while Thread A is executing an madvise()
|
||||
system call on a virtual address within the same 2 MB (huge page) range.
|
||||
|
||||
virtual address space
|
||||
.---------------------.
|
||||
| |
|
||||
| |
|
||||
.-|---------------------|
|
||||
| | |
|
||||
| | |<-- B(fault)
|
||||
| | |
|
||||
2 MB | |/////////////////////|-.
|
||||
huge < |/////////////////////| > A(range)
|
||||
page | |/////////////////////|-'
|
||||
| | |
|
||||
| | |
|
||||
'-|---------------------|
|
||||
| |
|
||||
| |
|
||||
'---------------------'
|
||||
|
||||
- Thread A is executing an madvise(..., MADV_DONTNEED) system call
|
||||
on the virtual address range "A(range)" shown in the picture.
|
||||
|
||||
sys_madvise
|
||||
// Acquire the semaphore in shared mode.
|
||||
down_read(¤t->mm->mmap_sem)
|
||||
...
|
||||
madvise_vma
|
||||
switch (behavior)
|
||||
case MADV_DONTNEED:
|
||||
madvise_dontneed
|
||||
zap_page_range
|
||||
unmap_vmas
|
||||
unmap_page_range
|
||||
zap_pud_range
|
||||
zap_pmd_range
|
||||
//
|
||||
// Assume that this huge page has never been accessed.
|
||||
// I.e. content of the PMD entry is zero (not mapped).
|
||||
//
|
||||
if (pmd_trans_huge(*pmd)) {
|
||||
// We don't get here due to the above assumption.
|
||||
}
|
||||
//
|
||||
// Assume that Thread B incurred a page fault and
|
||||
.---------> // sneaks in here as shown below.
|
||||
| //
|
||||
| if (pmd_none_or_clear_bad(pmd))
|
||||
| {
|
||||
| if (unlikely(pmd_bad(*pmd)))
|
||||
| pmd_clear_bad
|
||||
| {
|
||||
| pmd_ERROR
|
||||
| // Log "bad pmd ..." message here.
|
||||
| pmd_clear
|
||||
| // Clear the page's PMD entry.
|
||||
| // Thread B incremented the map count
|
||||
| // in page_add_new_anon_rmap(), but
|
||||
| // now the page is no longer mapped
|
||||
| // by a PMD entry (-> inconsistency).
|
||||
| }
|
||||
| }
|
||||
|
|
||||
v
|
||||
- Thread B is handling a page fault on virtual address "B(fault)" shown
|
||||
in the picture.
|
||||
|
||||
...
|
||||
do_page_fault
|
||||
__do_page_fault
|
||||
// Acquire the semaphore in shared mode.
|
||||
down_read_trylock(&mm->mmap_sem)
|
||||
...
|
||||
handle_mm_fault
|
||||
if (pmd_none(*pmd) && transparent_hugepage_enabled(vma))
|
||||
// We get here due to the above assumption (PMD entry is zero).
|
||||
do_huge_pmd_anonymous_page
|
||||
alloc_hugepage_vma
|
||||
// Allocate a new transparent huge page here.
|
||||
...
|
||||
__do_huge_pmd_anonymous_page
|
||||
...
|
||||
spin_lock(&mm->page_table_lock)
|
||||
...
|
||||
page_add_new_anon_rmap
|
||||
// Here we increment the page's map count (starts at -1).
|
||||
atomic_set(&page->_mapcount, 0)
|
||||
set_pmd_at
|
||||
// Here we set the page's PMD entry which will be cleared
|
||||
// when Thread A calls pmd_clear_bad().
|
||||
...
|
||||
spin_unlock(&mm->page_table_lock)
|
||||
|
||||
The mmap_sem does not prevent the race because both threads are acquiring
|
||||
it in shared mode (down_read). Thread B holds the page_table_lock while
|
||||
the page's map count and PMD table entry are updated. However, Thread A
|
||||
does not synchronize on that lock.
|
||||
|
||||
====== end quote =======
|
||||
|
||||
[akpm@linux-foundation.org: checkpatch fixes]
|
||||
Reported-by: Ulrich Obergfell <uobergfe@redhat.com>
|
||||
Signed-off-by: Andrea Arcangeli <aarcange@redhat.com>
|
||||
Acked-by: Johannes Weiner <hannes@cmpxchg.org>
|
||||
Cc: Mel Gorman <mgorman@suse.de>
|
||||
Cc: Hugh Dickins <hughd@google.com>
|
||||
Cc: Dave Jones <davej@redhat.com>
|
||||
Acked-by: Larry Woodman <lwoodman@redhat.com>
|
||||
Acked-by: Rik van Riel <riel@redhat.com>
|
||||
Cc: Mark Salter <msalter@redhat.com>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
arch/x86/kernel/vm86_32.c | 2 ++
|
||||
fs/proc/task_mmu.c | 9 ++++++
|
||||
include/asm-generic/pgtable.h | 61 +++++++++++++++++++++++++++++++++++++++++
|
||||
mm/memcontrol.c | 4 +++
|
||||
mm/memory.c | 16 ++++++++---
|
||||
mm/mempolicy.c | 2 +-
|
||||
mm/mincore.c | 2 +-
|
||||
mm/pagewalk.c | 2 +-
|
||||
mm/swapfile.c | 4 +--
|
||||
9 files changed, 92 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c
|
||||
index 863f875..04b8726 100644
|
||||
--- a/arch/x86/kernel/vm86_32.c
|
||||
+++ b/arch/x86/kernel/vm86_32.c
|
||||
@@ -172,6 +172,7 @@ static void mark_screen_rdonly(struct mm_struct *mm)
|
||||
spinlock_t *ptl;
|
||||
int i;
|
||||
|
||||
+ down_write(&mm->mmap_sem);
|
||||
pgd = pgd_offset(mm, 0xA0000);
|
||||
if (pgd_none_or_clear_bad(pgd))
|
||||
goto out;
|
||||
@@ -190,6 +191,7 @@ static void mark_screen_rdonly(struct mm_struct *mm)
|
||||
}
|
||||
pte_unmap_unlock(pte, ptl);
|
||||
out:
|
||||
+ up_write(&mm->mmap_sem);
|
||||
flush_tlb();
|
||||
}
|
||||
|
||||
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
|
||||
index 7dcd2a2..3efa725 100644
|
||||
--- a/fs/proc/task_mmu.c
|
||||
+++ b/fs/proc/task_mmu.c
|
||||
@@ -409,6 +409,9 @@ static int smaps_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
|
||||
} else {
|
||||
spin_unlock(&walk->mm->page_table_lock);
|
||||
}
|
||||
+
|
||||
+ if (pmd_trans_unstable(pmd))
|
||||
+ return 0;
|
||||
/*
|
||||
* The mmap_sem held all the way back in m_start() is what
|
||||
* keeps khugepaged out of here and from collapsing things
|
||||
@@ -507,6 +510,8 @@ static int clear_refs_pte_range(pmd_t *pmd, unsigned long addr,
|
||||
struct page *page;
|
||||
|
||||
split_huge_page_pmd(walk->mm, pmd);
|
||||
+ if (pmd_trans_unstable(pmd))
|
||||
+ return 0;
|
||||
|
||||
pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
|
||||
for (; addr != end; pte++, addr += PAGE_SIZE) {
|
||||
@@ -670,6 +675,8 @@ static int pagemap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
|
||||
int err = 0;
|
||||
|
||||
split_huge_page_pmd(walk->mm, pmd);
|
||||
+ if (pmd_trans_unstable(pmd))
|
||||
+ return 0;
|
||||
|
||||
/* find the first VMA at or above 'addr' */
|
||||
vma = find_vma(walk->mm, addr);
|
||||
@@ -961,6 +968,8 @@ static int gather_pte_stats(pmd_t *pmd, unsigned long addr,
|
||||
spin_unlock(&walk->mm->page_table_lock);
|
||||
}
|
||||
|
||||
+ if (pmd_trans_unstable(pmd))
|
||||
+ return 0;
|
||||
orig_pte = pte = pte_offset_map_lock(walk->mm, pmd, addr, &ptl);
|
||||
do {
|
||||
struct page *page = can_gather_numa_stats(*pte, md->vma, addr);
|
||||
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
|
||||
index 76bff2b..a03c098 100644
|
||||
--- a/include/asm-generic/pgtable.h
|
||||
+++ b/include/asm-generic/pgtable.h
|
||||
@@ -425,6 +425,8 @@ extern void untrack_pfn_vma(struct vm_area_struct *vma, unsigned long pfn,
|
||||
unsigned long size);
|
||||
#endif
|
||||
|
||||
+#ifdef CONFIG_MMU
|
||||
+
|
||||
#ifndef CONFIG_TRANSPARENT_HUGEPAGE
|
||||
static inline int pmd_trans_huge(pmd_t pmd)
|
||||
{
|
||||
@@ -441,7 +443,66 @@ static inline int pmd_write(pmd_t pmd)
|
||||
return 0;
|
||||
}
|
||||
#endif /* __HAVE_ARCH_PMD_WRITE */
|
||||
+#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
|
||||
+
|
||||
+/*
|
||||
+ * This function is meant to be used by sites walking pagetables with
|
||||
+ * the mmap_sem hold in read mode to protect against MADV_DONTNEED and
|
||||
+ * transhuge page faults. MADV_DONTNEED can convert a transhuge pmd
|
||||
+ * into a null pmd and the transhuge page fault can convert a null pmd
|
||||
+ * into an hugepmd or into a regular pmd (if the hugepage allocation
|
||||
+ * fails). While holding the mmap_sem in read mode the pmd becomes
|
||||
+ * stable and stops changing under us only if it's not null and not a
|
||||
+ * transhuge pmd. When those races occurs and this function makes a
|
||||
+ * difference vs the standard pmd_none_or_clear_bad, the result is
|
||||
+ * undefined so behaving like if the pmd was none is safe (because it
|
||||
+ * can return none anyway). The compiler level barrier() is critically
|
||||
+ * important to compute the two checks atomically on the same pmdval.
|
||||
+ */
|
||||
+static inline int pmd_none_or_trans_huge_or_clear_bad(pmd_t *pmd)
|
||||
+{
|
||||
+ /* depend on compiler for an atomic pmd read */
|
||||
+ pmd_t pmdval = *pmd;
|
||||
+ /*
|
||||
+ * The barrier will stabilize the pmdval in a register or on
|
||||
+ * the stack so that it will stop changing under the code.
|
||||
+ */
|
||||
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
||||
+ barrier();
|
||||
+#endif
|
||||
+ if (pmd_none(pmdval))
|
||||
+ return 1;
|
||||
+ if (unlikely(pmd_bad(pmdval))) {
|
||||
+ if (!pmd_trans_huge(pmdval))
|
||||
+ pmd_clear_bad(pmd);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * This is a noop if Transparent Hugepage Support is not built into
|
||||
+ * the kernel. Otherwise it is equivalent to
|
||||
+ * pmd_none_or_trans_huge_or_clear_bad(), and shall only be called in
|
||||
+ * places that already verified the pmd is not none and they want to
|
||||
+ * walk ptes while holding the mmap sem in read mode (write mode don't
|
||||
+ * need this). If THP is not enabled, the pmd can't go away under the
|
||||
+ * code even if MADV_DONTNEED runs, but if THP is enabled we need to
|
||||
+ * run a pmd_trans_unstable before walking the ptes after
|
||||
+ * split_huge_page_pmd returns (because it may have run when the pmd
|
||||
+ * become null, but then a page fault can map in a THP and not a
|
||||
+ * regular page).
|
||||
+ */
|
||||
+static inline int pmd_trans_unstable(pmd_t *pmd)
|
||||
+{
|
||||
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
||||
+ return pmd_none_or_trans_huge_or_clear_bad(pmd);
|
||||
+#else
|
||||
+ return 0;
|
||||
#endif
|
||||
+}
|
||||
+
|
||||
+#endif /* CONFIG_MMU */
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
|
||||
index de67e91..778554f 100644
|
||||
--- a/mm/memcontrol.c
|
||||
+++ b/mm/memcontrol.c
|
||||
@@ -5237,6 +5237,8 @@ static int mem_cgroup_count_precharge_pte_range(pmd_t *pmd,
|
||||
spinlock_t *ptl;
|
||||
|
||||
split_huge_page_pmd(walk->mm, pmd);
|
||||
+ if (pmd_trans_unstable(pmd))
|
||||
+ return 0;
|
||||
|
||||
pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
|
||||
for (; addr != end; pte++, addr += PAGE_SIZE)
|
||||
@@ -5398,6 +5400,8 @@ static int mem_cgroup_move_charge_pte_range(pmd_t *pmd,
|
||||
spinlock_t *ptl;
|
||||
|
||||
split_huge_page_pmd(walk->mm, pmd);
|
||||
+ if (pmd_trans_unstable(pmd))
|
||||
+ return 0;
|
||||
retry:
|
||||
pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
|
||||
for (; addr != end; addr += PAGE_SIZE) {
|
||||
diff --git a/mm/memory.c b/mm/memory.c
|
||||
index 829d437..1b1ca17 100644
|
||||
--- a/mm/memory.c
|
||||
+++ b/mm/memory.c
|
||||
@@ -1228,16 +1228,24 @@ static inline unsigned long zap_pmd_range(struct mmu_gather *tlb,
|
||||
do {
|
||||
next = pmd_addr_end(addr, end);
|
||||
if (pmd_trans_huge(*pmd)) {
|
||||
- if (next-addr != HPAGE_PMD_SIZE) {
|
||||
+ if (next - addr != HPAGE_PMD_SIZE) {
|
||||
VM_BUG_ON(!rwsem_is_locked(&tlb->mm->mmap_sem));
|
||||
split_huge_page_pmd(vma->vm_mm, pmd);
|
||||
} else if (zap_huge_pmd(tlb, vma, pmd))
|
||||
- continue;
|
||||
+ goto next;
|
||||
/* fall through */
|
||||
}
|
||||
- if (pmd_none_or_clear_bad(pmd))
|
||||
- continue;
|
||||
+ /*
|
||||
+ * Here there can be other concurrent MADV_DONTNEED or
|
||||
+ * trans huge page faults running, and if the pmd is
|
||||
+ * none or trans huge it can change under us. This is
|
||||
+ * because MADV_DONTNEED holds the mmap_sem in read
|
||||
+ * mode.
|
||||
+ */
|
||||
+ if (pmd_none_or_trans_huge_or_clear_bad(pmd))
|
||||
+ goto next;
|
||||
next = zap_pte_range(tlb, vma, pmd, addr, next, details);
|
||||
+next:
|
||||
cond_resched();
|
||||
} while (pmd++, addr = next, addr != end);
|
||||
|
||||
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
|
||||
index c3fdbcb..b26aae2 100644
|
||||
--- a/mm/mempolicy.c
|
||||
+++ b/mm/mempolicy.c
|
||||
@@ -512,7 +512,7 @@ static inline int check_pmd_range(struct vm_area_struct *vma, pud_t *pud,
|
||||
do {
|
||||
next = pmd_addr_end(addr, end);
|
||||
split_huge_page_pmd(vma->vm_mm, pmd);
|
||||
- if (pmd_none_or_clear_bad(pmd))
|
||||
+ if (pmd_none_or_trans_huge_or_clear_bad(pmd))
|
||||
continue;
|
||||
if (check_pte_range(vma, pmd, addr, next, nodes,
|
||||
flags, private))
|
||||
diff --git a/mm/mincore.c b/mm/mincore.c
|
||||
index 636a868..936b4ce 100644
|
||||
--- a/mm/mincore.c
|
||||
+++ b/mm/mincore.c
|
||||
@@ -164,7 +164,7 @@ static void mincore_pmd_range(struct vm_area_struct *vma, pud_t *pud,
|
||||
}
|
||||
/* fall through */
|
||||
}
|
||||
- if (pmd_none_or_clear_bad(pmd))
|
||||
+ if (pmd_none_or_trans_huge_or_clear_bad(pmd))
|
||||
mincore_unmapped_range(vma, addr, next, vec);
|
||||
else
|
||||
mincore_pte_range(vma, pmd, addr, next, vec);
|
||||
diff --git a/mm/pagewalk.c b/mm/pagewalk.c
|
||||
index 2f5cf10..aa9701e 100644
|
||||
--- a/mm/pagewalk.c
|
||||
+++ b/mm/pagewalk.c
|
||||
@@ -59,7 +59,7 @@ again:
|
||||
continue;
|
||||
|
||||
split_huge_page_pmd(walk->mm, pmd);
|
||||
- if (pmd_none_or_clear_bad(pmd))
|
||||
+ if (pmd_none_or_trans_huge_or_clear_bad(pmd))
|
||||
goto again;
|
||||
err = walk_pte_range(pmd, addr, next, walk);
|
||||
if (err)
|
||||
diff --git a/mm/swapfile.c b/mm/swapfile.c
|
||||
index b1cd120..2015a1e 100644
|
||||
--- a/mm/swapfile.c
|
||||
+++ b/mm/swapfile.c
|
||||
@@ -931,9 +931,7 @@ static inline int unuse_pmd_range(struct vm_area_struct *vma, pud_t *pud,
|
||||
pmd = pmd_offset(pud, addr);
|
||||
do {
|
||||
next = pmd_addr_end(addr, end);
|
||||
- if (unlikely(pmd_trans_huge(*pmd)))
|
||||
- continue;
|
||||
- if (pmd_none_or_clear_bad(pmd))
|
||||
+ if (pmd_none_or_trans_huge_or_clear_bad(pmd))
|
||||
continue;
|
||||
ret = unuse_pte_range(vma, pmd, addr, next, entry, page);
|
||||
if (ret)
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
From 6afa33c872ff109ed854c7dcec52130732f9e62e Mon Sep 17 00:00:00 2001
|
||||
From: Tim Gardner <tim.gardner@canonical.com>
|
||||
Date: Tue, 6 Dec 2011 11:29:20 -0700
|
||||
Subject: [PATCH 053/147] TPM: Zero buffer whole after copying to userspace
|
||||
|
||||
commit 3ab1aff89477dafb1aaeafe8c8669114a02b7226 upstream.
|
||||
|
||||
Commit 3321c07ae5068568cd61ac9f4ba749006a7185c9 correctly clears the TPM
|
||||
buffer if the user specified read length is >= the TPM buffer length. However,
|
||||
if the user specified read length is < the TPM buffer length, then part of the
|
||||
TPM buffer is left uncleared.
|
||||
|
||||
Reported-by: Seth Forshee <seth.forshee@canonical.com>
|
||||
Cc: Debora Velarde <debora@linux.vnet.ibm.com>
|
||||
Cc: Rajiv Andrade <srajiv@linux.vnet.ibm.com>
|
||||
Cc: Marcel Selhorst <m.selhorst@sirrix.com>
|
||||
Cc: tpmdd-devel@lists.sourceforge.net
|
||||
Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
|
||||
Signed-off-by: Rajiv Andrade <srajiv@linux.vnet.ibm.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/char/tpm/tpm.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
|
||||
index 361a1df..b366b34 100644
|
||||
--- a/drivers/char/tpm/tpm.c
|
||||
+++ b/drivers/char/tpm/tpm.c
|
||||
@@ -1115,12 +1115,13 @@ ssize_t tpm_read(struct file *file, char __user *buf,
|
||||
ret_size = atomic_read(&chip->data_pending);
|
||||
atomic_set(&chip->data_pending, 0);
|
||||
if (ret_size > 0) { /* relay data */
|
||||
+ ssize_t orig_ret_size = ret_size;
|
||||
if (size < ret_size)
|
||||
ret_size = size;
|
||||
|
||||
mutex_lock(&chip->buffer_mutex);
|
||||
rc = copy_to_user(buf, chip->data_buffer, ret_size);
|
||||
- memset(chip->data_buffer, 0, ret_size);
|
||||
+ memset(chip->data_buffer, 0, orig_ret_size);
|
||||
if (rc)
|
||||
ret_size = -EFAULT;
|
||||
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
From 51962c5f291ab2abb638e6121c36fbaa93a9567c Mon Sep 17 00:00:00 2001
|
||||
From: "Rafael J. Wysocki" <rjw@sisk.pl>
|
||||
Date: Tue, 13 Mar 2012 22:39:31 +0100
|
||||
Subject: [PATCH 054/147] PM / Domains: Fix handling of wakeup devices during
|
||||
system resume
|
||||
|
||||
commit cc85b20780562d404e18a47b9b55b4a5102ae53e upstream.
|
||||
|
||||
During system suspend pm_genpd_suspend_noirq() checks if the given
|
||||
device is in a wakeup path (i.e. it appears to be needed for one or
|
||||
more wakeup devices to work or is a wakeup device itself) and if it
|
||||
needs to be "active" for wakeup to work. If that is the case, the
|
||||
function returns 0 without incrementing the device domain's counter
|
||||
of suspended devices and without executing genpd_stop_dev() for the
|
||||
device. In consequence, the device is not stopped (e.g. its clock
|
||||
isn't disabled) and power is always supplied to its domain in the
|
||||
resulting system sleep state.
|
||||
|
||||
However, pm_genpd_resume_noirq() doesn't repeat that check and it
|
||||
runs genpd_start_dev() and decrements the domain's counter of
|
||||
suspended devices even for the wakeup device that weren't stopped by
|
||||
pm_genpd_suspend_noirq(). As a result, the start callback may be run
|
||||
unnecessarily for them and their domains' counters of suspended
|
||||
devices may become negative. Both outcomes aren't desirable, so fix
|
||||
pm_genpd_resume_noirq() to look for wakeup devices that might not be
|
||||
stopped by during system suspend.
|
||||
|
||||
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
|
||||
Tested-by: Simon Horman <horms@verge.net.au>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/base/power/domain.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
|
||||
index 6790cf7..79038e5 100644
|
||||
--- a/drivers/base/power/domain.c
|
||||
+++ b/drivers/base/power/domain.c
|
||||
@@ -751,7 +751,8 @@ static int pm_genpd_resume_noirq(struct device *dev)
|
||||
if (IS_ERR(genpd))
|
||||
return -EINVAL;
|
||||
|
||||
- if (genpd->suspend_power_off)
|
||||
+ if (genpd->suspend_power_off
|
||||
+ || (dev->power.wakeup_path && genpd_dev_active_wakeup(genpd, dev)))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
From ad2b33f9aee5de482d4077bcd81d6afde2935336 Mon Sep 17 00:00:00 2001
|
||||
From: Nishanth Aravamudan <nacc@linux.vnet.ibm.com>
|
||||
Date: Wed, 21 Mar 2012 16:34:07 -0700
|
||||
Subject: [PATCH 055/147] bootmem/sparsemem: remove limit constraint in
|
||||
alloc_bootmem_section
|
||||
|
||||
commit f5bf18fa22f8c41a13eb8762c7373eb3a93a7333 upstream.
|
||||
|
||||
While testing AMS (Active Memory Sharing) / CMO (Cooperative Memory
|
||||
Overcommit) on powerpc, we tripped the following:
|
||||
|
||||
kernel BUG at mm/bootmem.c:483!
|
||||
cpu 0x0: Vector: 700 (Program Check) at [c000000000c03940]
|
||||
pc: c000000000a62bd8: .alloc_bootmem_core+0x90/0x39c
|
||||
lr: c000000000a64bcc: .sparse_early_usemaps_alloc_node+0x84/0x29c
|
||||
sp: c000000000c03bc0
|
||||
msr: 8000000000021032
|
||||
current = 0xc000000000b0cce0
|
||||
paca = 0xc000000001d80000
|
||||
pid = 0, comm = swapper
|
||||
kernel BUG at mm/bootmem.c:483!
|
||||
enter ? for help
|
||||
[c000000000c03c80] c000000000a64bcc
|
||||
.sparse_early_usemaps_alloc_node+0x84/0x29c
|
||||
[c000000000c03d50] c000000000a64f10 .sparse_init+0x12c/0x28c
|
||||
[c000000000c03e20] c000000000a474f4 .setup_arch+0x20c/0x294
|
||||
[c000000000c03ee0] c000000000a4079c .start_kernel+0xb4/0x460
|
||||
[c000000000c03f90] c000000000009670 .start_here_common+0x1c/0x2c
|
||||
|
||||
This is
|
||||
|
||||
BUG_ON(limit && goal + size > limit);
|
||||
|
||||
and after some debugging, it seems that
|
||||
|
||||
goal = 0x7ffff000000
|
||||
limit = 0x80000000000
|
||||
|
||||
and sparse_early_usemaps_alloc_node ->
|
||||
sparse_early_usemaps_alloc_pgdat_section calls
|
||||
|
||||
return alloc_bootmem_section(usemap_size() * count, section_nr);
|
||||
|
||||
This is on a system with 8TB available via the AMS pool, and as a quirk
|
||||
of AMS in firmware, all of that memory shows up in node 0. So, we end
|
||||
up with an allocation that will fail the goal/limit constraints.
|
||||
|
||||
In theory, we could "fall-back" to alloc_bootmem_node() in
|
||||
sparse_early_usemaps_alloc_node(), but since we actually have HOTREMOVE
|
||||
defined, we'll BUG_ON() instead. A simple solution appears to be to
|
||||
unconditionally remove the limit condition in alloc_bootmem_section,
|
||||
meaning allocations are allowed to cross section boundaries (necessary
|
||||
for systems of this size).
|
||||
|
||||
Johannes Weiner pointed out that if alloc_bootmem_section() no longer
|
||||
guarantees section-locality, we need check_usemap_section_nr() to print
|
||||
possible cross-dependencies between node descriptors and the usemaps
|
||||
allocated through it. That makes the two loops in
|
||||
sparse_early_usemaps_alloc_node() identical, so re-factor the code a
|
||||
bit.
|
||||
|
||||
[akpm@linux-foundation.org: code simplification]
|
||||
Signed-off-by: Nishanth Aravamudan <nacc@us.ibm.com>
|
||||
Cc: Dave Hansen <haveblue@us.ibm.com>
|
||||
Cc: Anton Blanchard <anton@au1.ibm.com>
|
||||
Cc: Paul Mackerras <paulus@samba.org>
|
||||
Cc: Ben Herrenschmidt <benh@kernel.crashing.org>
|
||||
Cc: Robert Jennings <rcj@linux.vnet.ibm.com>
|
||||
Acked-by: Johannes Weiner <hannes@cmpxchg.org>
|
||||
Acked-by: Mel Gorman <mgorman@suse.de>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
mm/bootmem.c | 5 ++---
|
||||
mm/sparse.c | 30 +++++++++++-------------------
|
||||
2 files changed, 13 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/mm/bootmem.c b/mm/bootmem.c
|
||||
index 1a77012..b863822 100644
|
||||
--- a/mm/bootmem.c
|
||||
+++ b/mm/bootmem.c
|
||||
@@ -768,14 +768,13 @@ void * __init alloc_bootmem_section(unsigned long size,
|
||||
unsigned long section_nr)
|
||||
{
|
||||
bootmem_data_t *bdata;
|
||||
- unsigned long pfn, goal, limit;
|
||||
+ unsigned long pfn, goal;
|
||||
|
||||
pfn = section_nr_to_pfn(section_nr);
|
||||
goal = pfn << PAGE_SHIFT;
|
||||
- limit = section_nr_to_pfn(section_nr + 1) << PAGE_SHIFT;
|
||||
bdata = &bootmem_node_data[early_pfn_to_nid(pfn)];
|
||||
|
||||
- return alloc_bootmem_core(bdata, size, SMP_CACHE_BYTES, goal, limit);
|
||||
+ return alloc_bootmem_core(bdata, size, SMP_CACHE_BYTES, goal, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
diff --git a/mm/sparse.c b/mm/sparse.c
|
||||
index 61d7cde..a8bc7d3 100644
|
||||
--- a/mm/sparse.c
|
||||
+++ b/mm/sparse.c
|
||||
@@ -353,29 +353,21 @@ static void __init sparse_early_usemaps_alloc_node(unsigned long**usemap_map,
|
||||
|
||||
usemap = sparse_early_usemaps_alloc_pgdat_section(NODE_DATA(nodeid),
|
||||
usemap_count);
|
||||
- if (usemap) {
|
||||
- for (pnum = pnum_begin; pnum < pnum_end; pnum++) {
|
||||
- if (!present_section_nr(pnum))
|
||||
- continue;
|
||||
- usemap_map[pnum] = usemap;
|
||||
- usemap += size;
|
||||
+ if (!usemap) {
|
||||
+ usemap = alloc_bootmem_node(NODE_DATA(nodeid), size * usemap_count);
|
||||
+ if (!usemap) {
|
||||
+ printk(KERN_WARNING "%s: allocation failed\n", __func__);
|
||||
+ return;
|
||||
}
|
||||
- return;
|
||||
}
|
||||
|
||||
- usemap = alloc_bootmem_node(NODE_DATA(nodeid), size * usemap_count);
|
||||
- if (usemap) {
|
||||
- for (pnum = pnum_begin; pnum < pnum_end; pnum++) {
|
||||
- if (!present_section_nr(pnum))
|
||||
- continue;
|
||||
- usemap_map[pnum] = usemap;
|
||||
- usemap += size;
|
||||
- check_usemap_section_nr(nodeid, usemap_map[pnum]);
|
||||
- }
|
||||
- return;
|
||||
+ for (pnum = pnum_begin; pnum < pnum_end; pnum++) {
|
||||
+ if (!present_section_nr(pnum))
|
||||
+ continue;
|
||||
+ usemap_map[pnum] = usemap;
|
||||
+ usemap += size;
|
||||
+ check_usemap_section_nr(nodeid, usemap_map[pnum]);
|
||||
}
|
||||
-
|
||||
- printk(KERN_WARNING "%s: allocation failed\n", __func__);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_SPARSEMEM_VMEMMAP
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
From 2bc105d9e4132f8a07cec0b5df3d308c1b99455f Mon Sep 17 00:00:00 2001
|
||||
From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
|
||||
Date: Wed, 21 Mar 2012 16:34:08 -0700
|
||||
Subject: [PATCH 056/147] hugetlbfs: avoid taking i_mutex from
|
||||
hugetlbfs_read()
|
||||
|
||||
commit a05b0855fd15504972dba2358e5faa172a1e50ba upstream.
|
||||
|
||||
Taking i_mutex in hugetlbfs_read() can result in deadlock with mmap as
|
||||
explained below
|
||||
|
||||
Thread A:
|
||||
read() on hugetlbfs
|
||||
hugetlbfs_read() called
|
||||
i_mutex grabbed
|
||||
hugetlbfs_read_actor() called
|
||||
__copy_to_user() called
|
||||
page fault is triggered
|
||||
Thread B, sharing address space with A:
|
||||
mmap() the same file
|
||||
->mmap_sem is grabbed on task_B->mm->mmap_sem
|
||||
hugetlbfs_file_mmap() is called
|
||||
attempt to grab ->i_mutex and block waiting for A to give it up
|
||||
Thread A:
|
||||
pagefault handled blocked on attempt to grab task_A->mm->mmap_sem,
|
||||
which happens to be the same thing as task_B->mm->mmap_sem. Block waiting
|
||||
for B to give it up.
|
||||
|
||||
AFAIU the i_mutex locking was added to hugetlbfs_read() as per
|
||||
http://lkml.indiana.edu/hypermail/linux/kernel/0707.2/3066.html to take
|
||||
care of the race between truncate and read. This patch fixes this by
|
||||
looking at page->mapping under lock_page() (find_lock_page()) to ensure
|
||||
that the inode didn't get truncated in the range during a parallel read.
|
||||
|
||||
Ideally we can extend the patch to make sure we don't increase i_size in
|
||||
mmap. But that will break userspace, because applications will now have
|
||||
to use truncate(2) to increase i_size in hugetlbfs.
|
||||
|
||||
Based on the original patch from Hillf Danton.
|
||||
|
||||
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
|
||||
Cc: Hillf Danton <dhillf@gmail.com>
|
||||
Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
|
||||
Cc: Al Viro <viro@zeniv.linux.org.uk>
|
||||
Cc: Hugh Dickins <hughd@google.com>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
fs/hugetlbfs/inode.c | 25 +++++++++----------------
|
||||
1 file changed, 9 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
|
||||
index 0be5a78..2d0ca24 100644
|
||||
--- a/fs/hugetlbfs/inode.c
|
||||
+++ b/fs/hugetlbfs/inode.c
|
||||
@@ -238,17 +238,10 @@ static ssize_t hugetlbfs_read(struct file *filp, char __user *buf,
|
||||
loff_t isize;
|
||||
ssize_t retval = 0;
|
||||
|
||||
- mutex_lock(&inode->i_mutex);
|
||||
-
|
||||
/* validate length */
|
||||
if (len == 0)
|
||||
goto out;
|
||||
|
||||
- isize = i_size_read(inode);
|
||||
- if (!isize)
|
||||
- goto out;
|
||||
-
|
||||
- end_index = (isize - 1) >> huge_page_shift(h);
|
||||
for (;;) {
|
||||
struct page *page;
|
||||
unsigned long nr, ret;
|
||||
@@ -256,18 +249,21 @@ static ssize_t hugetlbfs_read(struct file *filp, char __user *buf,
|
||||
|
||||
/* nr is the maximum number of bytes to copy from this page */
|
||||
nr = huge_page_size(h);
|
||||
+ isize = i_size_read(inode);
|
||||
+ if (!isize)
|
||||
+ goto out;
|
||||
+ end_index = (isize - 1) >> huge_page_shift(h);
|
||||
if (index >= end_index) {
|
||||
if (index > end_index)
|
||||
goto out;
|
||||
nr = ((isize - 1) & ~huge_page_mask(h)) + 1;
|
||||
- if (nr <= offset) {
|
||||
+ if (nr <= offset)
|
||||
goto out;
|
||||
- }
|
||||
}
|
||||
nr = nr - offset;
|
||||
|
||||
/* Find the page */
|
||||
- page = find_get_page(mapping, index);
|
||||
+ page = find_lock_page(mapping, index);
|
||||
if (unlikely(page == NULL)) {
|
||||
/*
|
||||
* We have a HOLE, zero out the user-buffer for the
|
||||
@@ -279,17 +275,18 @@ static ssize_t hugetlbfs_read(struct file *filp, char __user *buf,
|
||||
else
|
||||
ra = 0;
|
||||
} else {
|
||||
+ unlock_page(page);
|
||||
+
|
||||
/*
|
||||
* We have the page, copy it to user space buffer.
|
||||
*/
|
||||
ra = hugetlbfs_read_actor(page, offset, buf, len, nr);
|
||||
ret = ra;
|
||||
+ page_cache_release(page);
|
||||
}
|
||||
if (ra < 0) {
|
||||
if (retval == 0)
|
||||
retval = ra;
|
||||
- if (page)
|
||||
- page_cache_release(page);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -299,16 +296,12 @@ static ssize_t hugetlbfs_read(struct file *filp, char __user *buf,
|
||||
index += offset >> huge_page_shift(h);
|
||||
offset &= ~huge_page_mask(h);
|
||||
|
||||
- if (page)
|
||||
- page_cache_release(page);
|
||||
-
|
||||
/* short read or no more work */
|
||||
if ((ret != nr) || (len == 0))
|
||||
break;
|
||||
}
|
||||
out:
|
||||
*ppos = ((loff_t)index << huge_page_shift(h)) + offset;
|
||||
- mutex_unlock(&inode->i_mutex);
|
||||
return retval;
|
||||
}
|
||||
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
From a7338f169446baa4311a9248017ab75ed417a46c Mon Sep 17 00:00:00 2001
|
||||
From: Timur Tabi <timur@freescale.com>
|
||||
Date: Fri, 16 Mar 2012 16:32:52 -0500
|
||||
Subject: [PATCH 057/147] ASoC: fsl: p1022ds: tell the WM8776 codec driver
|
||||
that it's the master
|
||||
|
||||
commit 70ac07bb633dee75ac554195b9a4d69adfa7803c upstream.
|
||||
|
||||
The WM8776 codec driver requires the machine driver to set one of the
|
||||
SND_SOC_DAIFMT_CBx_xxx values. The P1022DS machine driver should be setting
|
||||
SND_SOC_DAIFMT_CBM_CFM, but since that value was zero, no one noticed.
|
||||
|
||||
Commit 75d9ac46 ("ASoC: Allow DAI formats to be specified in the
|
||||
dai_link"), however, changed the value of SND_SOC_DAIFMT_CBM_CFM from zero
|
||||
to a non-zero value, which means that it now needs to be specifically set
|
||||
by the machine driver.
|
||||
|
||||
We also set SND_SOC_DAIFMT_NB_NF, for the same reason.
|
||||
|
||||
Signed-off-by: Timur Tabi <timur@freescale.com>
|
||||
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
sound/soc/fsl/p1022_ds.c | 24 ++++++++++++++++--------
|
||||
1 file changed, 16 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/sound/soc/fsl/p1022_ds.c b/sound/soc/fsl/p1022_ds.c
|
||||
index 2c064a9..075677c 100644
|
||||
--- a/sound/soc/fsl/p1022_ds.c
|
||||
+++ b/sound/soc/fsl/p1022_ds.c
|
||||
@@ -392,7 +392,8 @@ static int p1022_ds_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
if (strcasecmp(sprop, "i2s-slave") == 0) {
|
||||
- mdata->dai_format = SND_SOC_DAIFMT_I2S;
|
||||
+ mdata->dai_format = SND_SOC_DAIFMT_NB_NF |
|
||||
+ SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM;
|
||||
mdata->codec_clk_direction = SND_SOC_CLOCK_OUT;
|
||||
mdata->cpu_clk_direction = SND_SOC_CLOCK_IN;
|
||||
|
||||
@@ -409,31 +410,38 @@ static int p1022_ds_probe(struct platform_device *pdev)
|
||||
}
|
||||
mdata->clk_frequency = be32_to_cpup(iprop);
|
||||
} else if (strcasecmp(sprop, "i2s-master") == 0) {
|
||||
- mdata->dai_format = SND_SOC_DAIFMT_I2S;
|
||||
+ mdata->dai_format = SND_SOC_DAIFMT_NB_NF |
|
||||
+ SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS;
|
||||
mdata->codec_clk_direction = SND_SOC_CLOCK_IN;
|
||||
mdata->cpu_clk_direction = SND_SOC_CLOCK_OUT;
|
||||
} else if (strcasecmp(sprop, "lj-slave") == 0) {
|
||||
- mdata->dai_format = SND_SOC_DAIFMT_LEFT_J;
|
||||
+ mdata->dai_format = SND_SOC_DAIFMT_NB_NF |
|
||||
+ SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_CBM_CFM;
|
||||
mdata->codec_clk_direction = SND_SOC_CLOCK_OUT;
|
||||
mdata->cpu_clk_direction = SND_SOC_CLOCK_IN;
|
||||
} else if (strcasecmp(sprop, "lj-master") == 0) {
|
||||
- mdata->dai_format = SND_SOC_DAIFMT_LEFT_J;
|
||||
+ mdata->dai_format = SND_SOC_DAIFMT_NB_NF |
|
||||
+ SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_CBS_CFS;
|
||||
mdata->codec_clk_direction = SND_SOC_CLOCK_IN;
|
||||
mdata->cpu_clk_direction = SND_SOC_CLOCK_OUT;
|
||||
} else if (strcasecmp(sprop, "rj-slave") == 0) {
|
||||
- mdata->dai_format = SND_SOC_DAIFMT_RIGHT_J;
|
||||
+ mdata->dai_format = SND_SOC_DAIFMT_NB_NF |
|
||||
+ SND_SOC_DAIFMT_RIGHT_J | SND_SOC_DAIFMT_CBM_CFM;
|
||||
mdata->codec_clk_direction = SND_SOC_CLOCK_OUT;
|
||||
mdata->cpu_clk_direction = SND_SOC_CLOCK_IN;
|
||||
} else if (strcasecmp(sprop, "rj-master") == 0) {
|
||||
- mdata->dai_format = SND_SOC_DAIFMT_RIGHT_J;
|
||||
+ mdata->dai_format = SND_SOC_DAIFMT_NB_NF |
|
||||
+ SND_SOC_DAIFMT_RIGHT_J | SND_SOC_DAIFMT_CBS_CFS;
|
||||
mdata->codec_clk_direction = SND_SOC_CLOCK_IN;
|
||||
mdata->cpu_clk_direction = SND_SOC_CLOCK_OUT;
|
||||
} else if (strcasecmp(sprop, "ac97-slave") == 0) {
|
||||
- mdata->dai_format = SND_SOC_DAIFMT_AC97;
|
||||
+ mdata->dai_format = SND_SOC_DAIFMT_NB_NF |
|
||||
+ SND_SOC_DAIFMT_AC97 | SND_SOC_DAIFMT_CBM_CFM;
|
||||
mdata->codec_clk_direction = SND_SOC_CLOCK_OUT;
|
||||
mdata->cpu_clk_direction = SND_SOC_CLOCK_IN;
|
||||
} else if (strcasecmp(sprop, "ac97-master") == 0) {
|
||||
- mdata->dai_format = SND_SOC_DAIFMT_AC97;
|
||||
+ mdata->dai_format = SND_SOC_DAIFMT_NB_NF |
|
||||
+ SND_SOC_DAIFMT_AC97 | SND_SOC_DAIFMT_CBS_CFS;
|
||||
mdata->codec_clk_direction = SND_SOC_CLOCK_IN;
|
||||
mdata->cpu_clk_direction = SND_SOC_CLOCK_OUT;
|
||||
} else {
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
From ab7d4a1c2c58f17a777947ef7e0ae242fea985e4 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Mack <zonque@gmail.com>
|
||||
Date: Mon, 19 Mar 2012 09:12:53 +0100
|
||||
Subject: [PATCH 058/147] ASoC: pxa-ssp: atomically set stream active masks
|
||||
|
||||
commit 273b72c8ce6b28df6b49423d775c3e59072c73c5 upstream.
|
||||
|
||||
PXA's SSP engine fails to take its current channel phase into account
|
||||
when enabling a stream while the engine is already running. This
|
||||
results in randomly swapped left/right channels on either the record
|
||||
or the playback side, depending on which one was enabled first.
|
||||
|
||||
The following patch fixes this by factoring out the bit field
|
||||
modifications in question to a separate function that pauses the
|
||||
engine temporarily, modifies the bits and kicks it off again
|
||||
afterwards. Appearantly, a transition of SSCR0_SSE syncs both
|
||||
directions properly.
|
||||
|
||||
The patch has been rolled out to quite a number of devices over the
|
||||
last weeks and seems to fix the issue reliably.
|
||||
|
||||
Signed-off-by: Daniel Mack <zonque@gmail.com>
|
||||
Reported-and-tested-by: Sven Neumann <s.neumann@raumfeld.com>
|
||||
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
sound/soc/pxa/pxa-ssp.c | 61 ++++++++++++++++++++++++++++-------------------
|
||||
1 file changed, 36 insertions(+), 25 deletions(-)
|
||||
|
||||
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
|
||||
index 8ad93ee..b583e60 100644
|
||||
--- a/sound/soc/pxa/pxa-ssp.c
|
||||
+++ b/sound/soc/pxa/pxa-ssp.c
|
||||
@@ -668,6 +668,38 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static void pxa_ssp_set_running_bit(struct snd_pcm_substream *substream,
|
||||
+ struct ssp_device *ssp, int value)
|
||||
+{
|
||||
+ uint32_t sscr0 = pxa_ssp_read_reg(ssp, SSCR0);
|
||||
+ uint32_t sscr1 = pxa_ssp_read_reg(ssp, SSCR1);
|
||||
+ uint32_t sspsp = pxa_ssp_read_reg(ssp, SSPSP);
|
||||
+ uint32_t sssr = pxa_ssp_read_reg(ssp, SSSR);
|
||||
+
|
||||
+ if (value && (sscr0 & SSCR0_SSE))
|
||||
+ pxa_ssp_write_reg(ssp, SSCR0, sscr0 & ~SSCR0_SSE);
|
||||
+
|
||||
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
+ if (value)
|
||||
+ sscr1 |= SSCR1_TSRE;
|
||||
+ else
|
||||
+ sscr1 &= ~SSCR1_TSRE;
|
||||
+ } else {
|
||||
+ if (value)
|
||||
+ sscr1 |= SSCR1_RSRE;
|
||||
+ else
|
||||
+ sscr1 &= ~SSCR1_RSRE;
|
||||
+ }
|
||||
+
|
||||
+ pxa_ssp_write_reg(ssp, SSCR1, sscr1);
|
||||
+
|
||||
+ if (value) {
|
||||
+ pxa_ssp_write_reg(ssp, SSSR, sssr);
|
||||
+ pxa_ssp_write_reg(ssp, SSPSP, sspsp);
|
||||
+ pxa_ssp_write_reg(ssp, SSCR0, sscr0 | SSCR0_SSE);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||
struct snd_soc_dai *cpu_dai)
|
||||
{
|
||||
@@ -681,42 +713,21 @@ static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||
pxa_ssp_enable(ssp);
|
||||
break;
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
|
||||
- val = pxa_ssp_read_reg(ssp, SSCR1);
|
||||
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
- val |= SSCR1_TSRE;
|
||||
- else
|
||||
- val |= SSCR1_RSRE;
|
||||
- pxa_ssp_write_reg(ssp, SSCR1, val);
|
||||
+ pxa_ssp_set_running_bit(substream, ssp, 1);
|
||||
val = pxa_ssp_read_reg(ssp, SSSR);
|
||||
pxa_ssp_write_reg(ssp, SSSR, val);
|
||||
break;
|
||||
case SNDRV_PCM_TRIGGER_START:
|
||||
- val = pxa_ssp_read_reg(ssp, SSCR1);
|
||||
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
- val |= SSCR1_TSRE;
|
||||
- else
|
||||
- val |= SSCR1_RSRE;
|
||||
- pxa_ssp_write_reg(ssp, SSCR1, val);
|
||||
- pxa_ssp_enable(ssp);
|
||||
+ pxa_ssp_set_running_bit(substream, ssp, 1);
|
||||
break;
|
||||
case SNDRV_PCM_TRIGGER_STOP:
|
||||
- val = pxa_ssp_read_reg(ssp, SSCR1);
|
||||
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
- val &= ~SSCR1_TSRE;
|
||||
- else
|
||||
- val &= ~SSCR1_RSRE;
|
||||
- pxa_ssp_write_reg(ssp, SSCR1, val);
|
||||
+ pxa_ssp_set_running_bit(substream, ssp, 0);
|
||||
break;
|
||||
case SNDRV_PCM_TRIGGER_SUSPEND:
|
||||
pxa_ssp_disable(ssp);
|
||||
break;
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
||||
- val = pxa_ssp_read_reg(ssp, SSCR1);
|
||||
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
- val &= ~SSCR1_TSRE;
|
||||
- else
|
||||
- val &= ~SSCR1_RSRE;
|
||||
- pxa_ssp_write_reg(ssp, SSCR1, val);
|
||||
+ pxa_ssp_set_running_bit(substream, ssp, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
From eb6dc69e78c98c8c61faba348a6eaf6cee1439d9 Mon Sep 17 00:00:00 2001
|
||||
From: Roland Dreier <roland@purestorage.com>
|
||||
Date: Tue, 14 Feb 2012 15:30:31 -0800
|
||||
Subject: [PATCH 059/147] tcm_loop: Set residual field for SCSI commands
|
||||
|
||||
commit 6cf3fa6918baab0c447f1206f1cef9166ad04864 upstream.
|
||||
|
||||
If the target core signals an over- or under-run, tcm_loop should call
|
||||
scsi_set_resid() to tell the SCSI midlayer about the residual data length.
|
||||
|
||||
The difference can be seen by doing something like
|
||||
|
||||
strace -eioctl sg_raw -r 1024 /dev/sda 8 0 0 0 1 0 > /dev/null
|
||||
|
||||
and looking at the "resid=" part of the SG_IO ioctl -- after this patch,
|
||||
the field is correctly reported as 512.
|
||||
|
||||
Signed-off-by: Roland Dreier <roland@purestorage.com>
|
||||
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/target/loopback/tcm_loop.c | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c
|
||||
index 81d5832..5d1d4f2 100644
|
||||
--- a/drivers/target/loopback/tcm_loop.c
|
||||
+++ b/drivers/target/loopback/tcm_loop.c
|
||||
@@ -866,6 +866,9 @@ static int tcm_loop_queue_data_in(struct se_cmd *se_cmd)
|
||||
|
||||
sc->result = SAM_STAT_GOOD;
|
||||
set_host_byte(sc, DID_OK);
|
||||
+ if ((se_cmd->se_cmd_flags & SCF_OVERFLOW_BIT) ||
|
||||
+ (se_cmd->se_cmd_flags & SCF_UNDERFLOW_BIT))
|
||||
+ scsi_set_resid(sc, se_cmd->residual_count);
|
||||
sc->scsi_done(sc);
|
||||
return 0;
|
||||
}
|
||||
@@ -891,6 +894,9 @@ static int tcm_loop_queue_status(struct se_cmd *se_cmd)
|
||||
sc->result = se_cmd->scsi_status;
|
||||
|
||||
set_host_byte(sc, DID_OK);
|
||||
+ if ((se_cmd->se_cmd_flags & SCF_OVERFLOW_BIT) ||
|
||||
+ (se_cmd->se_cmd_flags & SCF_UNDERFLOW_BIT))
|
||||
+ scsi_set_resid(sc, se_cmd->residual_count);
|
||||
sc->scsi_done(sc);
|
||||
return 0;
|
||||
}
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
From eeb9b513b81a2ebbb3812150c091ff26ee28d912 Mon Sep 17 00:00:00 2001
|
||||
From: Nicholas Bellinger <nab@linux-iscsi.org>
|
||||
Date: Thu, 23 Feb 2012 17:28:43 -0800
|
||||
Subject: [PATCH 060/147] iscsi-target: Fix iscsit_alloc_buffs() failure cases
|
||||
|
||||
commit d335e6054db616bce3f040e659fa38440518ad1d upstream.
|
||||
|
||||
Make iscsit_alloc_buffs() failure case for page_alloc_failed use correct
|
||||
__free_page() SGL pointer, and return -ENOMEM for iscsit_allocate_iovecs
|
||||
failure to push se_cmd->t_mem_sg release into iscsit_release_cmd()
|
||||
callback during iscsit_add_reject_from_cmd() connection reset.
|
||||
|
||||
Also drop cmd->t_mem_sg = NULL assignment from page_alloc_failed
|
||||
failure case.
|
||||
|
||||
Reported-by: Roland Dreier <roland@purestorage.com>
|
||||
Cc: Andy Grover <agrover@redhat.com>
|
||||
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/target/iscsi/iscsi_target.c | 14 ++++++--------
|
||||
1 file changed, 6 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
|
||||
index 03d3528..0842cc7 100644
|
||||
--- a/drivers/target/iscsi/iscsi_target.c
|
||||
+++ b/drivers/target/iscsi/iscsi_target.c
|
||||
@@ -781,7 +781,7 @@ static int iscsit_alloc_buffs(struct iscsi_cmd *cmd)
|
||||
struct scatterlist *sgl;
|
||||
u32 length = cmd->se_cmd.data_length;
|
||||
int nents = DIV_ROUND_UP(length, PAGE_SIZE);
|
||||
- int i = 0, ret;
|
||||
+ int i = 0, j = 0, ret;
|
||||
/*
|
||||
* If no SCSI payload is present, allocate the default iovecs used for
|
||||
* iSCSI PDU Header
|
||||
@@ -822,17 +822,15 @@ static int iscsit_alloc_buffs(struct iscsi_cmd *cmd)
|
||||
*/
|
||||
ret = iscsit_allocate_iovecs(cmd);
|
||||
if (ret < 0)
|
||||
- goto page_alloc_failed;
|
||||
+ return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
|
||||
page_alloc_failed:
|
||||
- while (i >= 0) {
|
||||
- __free_page(sg_page(&sgl[i]));
|
||||
- i--;
|
||||
- }
|
||||
- kfree(cmd->t_mem_sg);
|
||||
- cmd->t_mem_sg = NULL;
|
||||
+ while (j < i)
|
||||
+ __free_page(sg_page(&sgl[j++]));
|
||||
+
|
||||
+ kfree(sgl);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
From 43d63ac69fcc86c6b92dc1b923a3b0e5bd59dab5 Mon Sep 17 00:00:00 2001
|
||||
From: Nicholas Bellinger <nab@linux-iscsi.org>
|
||||
Date: Sun, 26 Feb 2012 22:16:07 -0800
|
||||
Subject: [PATCH 061/147] iscsi-target: Fix dynamic -> explict NodeACL pointer
|
||||
reference
|
||||
|
||||
commit d06283341aee9e48eff1b068779d340785c635ce upstream.
|
||||
|
||||
This patch fixes a free after use in lio_target_make_nodeacl() where
|
||||
iscsi_node_acl was referenced from the original se_nacl_new allocation,
|
||||
instead of from core_tpg_add_initiator_node_acl() in the case of dynamic
|
||||
-> explict NodeACL conversion.
|
||||
|
||||
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/target/iscsi/iscsi_target_configfs.c | 6 ++----
|
||||
1 file changed, 2 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c
|
||||
index db32784..83dcf49 100644
|
||||
--- a/drivers/target/iscsi/iscsi_target_configfs.c
|
||||
+++ b/drivers/target/iscsi/iscsi_target_configfs.c
|
||||
@@ -816,9 +816,6 @@ static struct se_node_acl *lio_target_make_nodeacl(
|
||||
if (!se_nacl_new)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
- acl = container_of(se_nacl_new, struct iscsi_node_acl,
|
||||
- se_node_acl);
|
||||
-
|
||||
cmdsn_depth = ISCSI_TPG_ATTRIB(tpg)->default_cmdsn_depth;
|
||||
/*
|
||||
* se_nacl_new may be released by core_tpg_add_initiator_node_acl()
|
||||
@@ -829,7 +826,8 @@ static struct se_node_acl *lio_target_make_nodeacl(
|
||||
if (IS_ERR(se_nacl))
|
||||
return se_nacl;
|
||||
|
||||
- stats_cg = &acl->se_node_acl.acl_fabric_stat_group;
|
||||
+ acl = container_of(se_nacl, struct iscsi_node_acl, se_node_acl);
|
||||
+ stats_cg = &se_nacl->acl_fabric_stat_group;
|
||||
|
||||
stats_cg->default_groups = kzalloc(sizeof(struct config_group) * 2,
|
||||
GFP_KERNEL);
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
From 6b3759def25d01a00d3a88701e97cb397f3aa805 Mon Sep 17 00:00:00 2001
|
||||
From: Anssi Hannula <anssi.hannula@iki.fi>
|
||||
Date: Tue, 13 Mar 2012 17:43:02 +0200
|
||||
Subject: [PATCH 062/147] ALSA: hda - fix printing of high HDMI sample rates
|
||||
|
||||
commit 25dc16f69892182192b1234594fd3cf342ad4195 upstream.
|
||||
|
||||
A previous commit af65cbf296 (ALSA: hdmi: fix printout of SAD sampling
|
||||
rates) fixed the sample rates shown in /proc/asound/cardX/eldY and
|
||||
kernel log to not be entirely wrong. However, a missing rate from the
|
||||
array added in the patch causes HDMI rates 88.2 kHz, 96 kHz, 176.4 kHz,
|
||||
and 192 kHz to be shown as 96 kHz, 176.4 kHz, 192 kHz, and 384 kHz,
|
||||
respectively.
|
||||
|
||||
Fix the reporting by adding the ALSA rate 64 kHz into the conversion
|
||||
array between 48 kHz and 88.2 kHz.
|
||||
|
||||
Signed-off-by: Anssi Hannula <anssi.hannula@iki.fi>
|
||||
Cc: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
sound/pci/hda/hda_eld.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c
|
||||
index c1da422..b58b4b1 100644
|
||||
--- a/sound/pci/hda/hda_eld.c
|
||||
+++ b/sound/pci/hda/hda_eld.c
|
||||
@@ -385,8 +385,8 @@ error:
|
||||
static void hdmi_print_pcm_rates(int pcm, char *buf, int buflen)
|
||||
{
|
||||
static unsigned int alsa_rates[] = {
|
||||
- 5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000, 88200,
|
||||
- 96000, 176400, 192000, 384000
|
||||
+ 5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000,
|
||||
+ 88200, 96000, 176400, 192000, 384000
|
||||
};
|
||||
int i, j;
|
||||
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,190 @@
|
||||
From 7086d25802a86ade70baa0edfa830e10ad7cd434 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Lothar=20Wa=C3=9Fmann?= <LW@KARO-electronics.de>
|
||||
Date: Sun, 11 Mar 2012 15:08:46 +0100
|
||||
Subject: [PATCH 063/147] usb gadget: fix a section mismatch when compiling
|
||||
g_ffs with CONFIG_USB_FUNCTIONFS_ETH
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
commit 8d0698428822ce63f7269e7fe81fc4580807b9ac upstream.
|
||||
|
||||
commit 28824b18ac4705e876a282a15ea0de8fc957551f:
|
||||
|Author: Michal Nazarewicz <m.nazarewicz@samsung.com>
|
||||
|Date: Wed May 5 12:53:13 2010 +0200
|
||||
|
|
||||
| USB: gadget: __init and __exit tags removed
|
||||
|
|
||||
| __init, __initdata and __exit tags have have been removed from
|
||||
| various files to make it possible for gadgets that do not use
|
||||
| the __init/__exit tags to use those.
|
||||
obviously missed (at least) this case leading to a section mismatch in
|
||||
g_ffs.c when compiling with CONFIG_USB_FUNCTIONFS_ETH enabled.
|
||||
|
||||
Signed-off-by: Lothar Wa??mann <LW@KARO-electronics.de>
|
||||
Acked-by: Michal Nazarewicz <mina86@mina86.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/gadget/f_subset.c | 34 +++++++++++++++++-----------------
|
||||
1 file changed, 17 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/drivers/usb/gadget/f_subset.c b/drivers/usb/gadget/f_subset.c
|
||||
index 85bd9bd..160ba02 100644
|
||||
--- a/drivers/usb/gadget/f_subset.c
|
||||
+++ b/drivers/usb/gadget/f_subset.c
|
||||
@@ -74,7 +74,7 @@ static inline struct f_gether *func_to_geth(struct usb_function *f)
|
||||
|
||||
/* interface descriptor: */
|
||||
|
||||
-static struct usb_interface_descriptor subset_data_intf __initdata = {
|
||||
+static struct usb_interface_descriptor subset_data_intf = {
|
||||
.bLength = sizeof subset_data_intf,
|
||||
.bDescriptorType = USB_DT_INTERFACE,
|
||||
|
||||
@@ -87,7 +87,7 @@ static struct usb_interface_descriptor subset_data_intf __initdata = {
|
||||
/* .iInterface = DYNAMIC */
|
||||
};
|
||||
|
||||
-static struct usb_cdc_header_desc mdlm_header_desc __initdata = {
|
||||
+static struct usb_cdc_header_desc mdlm_header_desc = {
|
||||
.bLength = sizeof mdlm_header_desc,
|
||||
.bDescriptorType = USB_DT_CS_INTERFACE,
|
||||
.bDescriptorSubType = USB_CDC_HEADER_TYPE,
|
||||
@@ -95,7 +95,7 @@ static struct usb_cdc_header_desc mdlm_header_desc __initdata = {
|
||||
.bcdCDC = cpu_to_le16(0x0110),
|
||||
};
|
||||
|
||||
-static struct usb_cdc_mdlm_desc mdlm_desc __initdata = {
|
||||
+static struct usb_cdc_mdlm_desc mdlm_desc = {
|
||||
.bLength = sizeof mdlm_desc,
|
||||
.bDescriptorType = USB_DT_CS_INTERFACE,
|
||||
.bDescriptorSubType = USB_CDC_MDLM_TYPE,
|
||||
@@ -111,7 +111,7 @@ static struct usb_cdc_mdlm_desc mdlm_desc __initdata = {
|
||||
* can't really use its struct. All we do here is say that we're using
|
||||
* the submode of "SAFE" which directly matches the CDC Subset.
|
||||
*/
|
||||
-static u8 mdlm_detail_desc[] __initdata = {
|
||||
+static u8 mdlm_detail_desc[] = {
|
||||
6,
|
||||
USB_DT_CS_INTERFACE,
|
||||
USB_CDC_MDLM_DETAIL_TYPE,
|
||||
@@ -121,7 +121,7 @@ static u8 mdlm_detail_desc[] __initdata = {
|
||||
0, /* network data capabilities ("raw" encapsulation) */
|
||||
};
|
||||
|
||||
-static struct usb_cdc_ether_desc ether_desc __initdata = {
|
||||
+static struct usb_cdc_ether_desc ether_desc = {
|
||||
.bLength = sizeof ether_desc,
|
||||
.bDescriptorType = USB_DT_CS_INTERFACE,
|
||||
.bDescriptorSubType = USB_CDC_ETHERNET_TYPE,
|
||||
@@ -136,7 +136,7 @@ static struct usb_cdc_ether_desc ether_desc __initdata = {
|
||||
|
||||
/* full speed support: */
|
||||
|
||||
-static struct usb_endpoint_descriptor fs_subset_in_desc __initdata = {
|
||||
+static struct usb_endpoint_descriptor fs_subset_in_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
|
||||
@@ -144,7 +144,7 @@ static struct usb_endpoint_descriptor fs_subset_in_desc __initdata = {
|
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||
};
|
||||
|
||||
-static struct usb_endpoint_descriptor fs_subset_out_desc __initdata = {
|
||||
+static struct usb_endpoint_descriptor fs_subset_out_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
|
||||
@@ -152,7 +152,7 @@ static struct usb_endpoint_descriptor fs_subset_out_desc __initdata = {
|
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||
};
|
||||
|
||||
-static struct usb_descriptor_header *fs_eth_function[] __initdata = {
|
||||
+static struct usb_descriptor_header *fs_eth_function[] = {
|
||||
(struct usb_descriptor_header *) &subset_data_intf,
|
||||
(struct usb_descriptor_header *) &mdlm_header_desc,
|
||||
(struct usb_descriptor_header *) &mdlm_desc,
|
||||
@@ -165,7 +165,7 @@ static struct usb_descriptor_header *fs_eth_function[] __initdata = {
|
||||
|
||||
/* high speed support: */
|
||||
|
||||
-static struct usb_endpoint_descriptor hs_subset_in_desc __initdata = {
|
||||
+static struct usb_endpoint_descriptor hs_subset_in_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
|
||||
@@ -173,7 +173,7 @@ static struct usb_endpoint_descriptor hs_subset_in_desc __initdata = {
|
||||
.wMaxPacketSize = cpu_to_le16(512),
|
||||
};
|
||||
|
||||
-static struct usb_endpoint_descriptor hs_subset_out_desc __initdata = {
|
||||
+static struct usb_endpoint_descriptor hs_subset_out_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
|
||||
@@ -181,7 +181,7 @@ static struct usb_endpoint_descriptor hs_subset_out_desc __initdata = {
|
||||
.wMaxPacketSize = cpu_to_le16(512),
|
||||
};
|
||||
|
||||
-static struct usb_descriptor_header *hs_eth_function[] __initdata = {
|
||||
+static struct usb_descriptor_header *hs_eth_function[] = {
|
||||
(struct usb_descriptor_header *) &subset_data_intf,
|
||||
(struct usb_descriptor_header *) &mdlm_header_desc,
|
||||
(struct usb_descriptor_header *) &mdlm_desc,
|
||||
@@ -194,7 +194,7 @@ static struct usb_descriptor_header *hs_eth_function[] __initdata = {
|
||||
|
||||
/* super speed support: */
|
||||
|
||||
-static struct usb_endpoint_descriptor ss_subset_in_desc __initdata = {
|
||||
+static struct usb_endpoint_descriptor ss_subset_in_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
|
||||
@@ -202,7 +202,7 @@ static struct usb_endpoint_descriptor ss_subset_in_desc __initdata = {
|
||||
.wMaxPacketSize = cpu_to_le16(1024),
|
||||
};
|
||||
|
||||
-static struct usb_endpoint_descriptor ss_subset_out_desc __initdata = {
|
||||
+static struct usb_endpoint_descriptor ss_subset_out_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
|
||||
@@ -210,7 +210,7 @@ static struct usb_endpoint_descriptor ss_subset_out_desc __initdata = {
|
||||
.wMaxPacketSize = cpu_to_le16(1024),
|
||||
};
|
||||
|
||||
-static struct usb_ss_ep_comp_descriptor ss_subset_bulk_comp_desc __initdata = {
|
||||
+static struct usb_ss_ep_comp_descriptor ss_subset_bulk_comp_desc = {
|
||||
.bLength = sizeof ss_subset_bulk_comp_desc,
|
||||
.bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
|
||||
|
||||
@@ -219,7 +219,7 @@ static struct usb_ss_ep_comp_descriptor ss_subset_bulk_comp_desc __initdata = {
|
||||
/* .bmAttributes = 0, */
|
||||
};
|
||||
|
||||
-static struct usb_descriptor_header *ss_eth_function[] __initdata = {
|
||||
+static struct usb_descriptor_header *ss_eth_function[] = {
|
||||
(struct usb_descriptor_header *) &subset_data_intf,
|
||||
(struct usb_descriptor_header *) &mdlm_header_desc,
|
||||
(struct usb_descriptor_header *) &mdlm_desc,
|
||||
@@ -290,7 +290,7 @@ static void geth_disable(struct usb_function *f)
|
||||
|
||||
/* serial function driver setup/binding */
|
||||
|
||||
-static int __init
|
||||
+static int
|
||||
geth_bind(struct usb_configuration *c, struct usb_function *f)
|
||||
{
|
||||
struct usb_composite_dev *cdev = c->cdev;
|
||||
@@ -405,7 +405,7 @@ geth_unbind(struct usb_configuration *c, struct usb_function *f)
|
||||
* Caller must have called @gether_setup(). Caller is also responsible
|
||||
* for calling @gether_cleanup() before module unload.
|
||||
*/
|
||||
-int __init geth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN])
|
||||
+int geth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN])
|
||||
{
|
||||
struct f_gether *geth;
|
||||
int status;
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
From 65fc28a302c7d7220dbe8609899724edb9687162 Mon Sep 17 00:00:00 2001
|
||||
From: Kay Sievers <kay.sievers@vrfy.org>
|
||||
Date: Sat, 28 Jan 2012 19:57:46 +0000
|
||||
Subject: [PATCH 064/147] udlfb: remove sysfs framebuffer device with USB
|
||||
.disconnect()
|
||||
|
||||
commit ce880cb860f36694d2cdebfac9e6ae18176fe4c4 upstream.
|
||||
|
||||
The USB graphics card driver delays the unregistering of the framebuffer
|
||||
device to a workqueue, which breaks the userspace visible remove uevent
|
||||
sequence. Recent userspace tools started to support USB graphics card
|
||||
hotplug out-of-the-box and rely on proper events sent by the kernel.
|
||||
|
||||
The framebuffer device is a direct child of the USB interface which is
|
||||
removed immediately after the USB .disconnect() callback. But the fb device
|
||||
in /sys stays around until its final cleanup, at a time where all the parent
|
||||
devices have been removed already.
|
||||
|
||||
To work around that, we remove the sysfs fb device directly in the USB
|
||||
.disconnect() callback and leave only the cleanup of the internal fb
|
||||
data to the delayed work.
|
||||
|
||||
Before:
|
||||
add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2 (usb)
|
||||
add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0 (usb)
|
||||
add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/graphics/fb0 (graphics)
|
||||
remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0 (usb)
|
||||
remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2 (usb)
|
||||
remove /2-1.2:1.0/graphics/fb0 (graphics)
|
||||
|
||||
After:
|
||||
add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2 (usb)
|
||||
add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0 (usb)
|
||||
add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/graphics/fb1 (graphics)
|
||||
remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/graphics/fb1 (graphics)
|
||||
remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0 (usb)
|
||||
remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2 (usb)
|
||||
|
||||
Tested-by: Bernie Thompson <bernie@plugable.com>
|
||||
Acked-by: Bernie Thompson <bernie@plugable.com>
|
||||
Signed-off-by: Kay Sievers <kay.sievers@vrfy.org>
|
||||
Signed-off-by: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/video/fbmem.c | 18 +++++++++++++++++-
|
||||
drivers/video/udlfb.c | 2 +-
|
||||
include/linux/fb.h | 1 +
|
||||
3 files changed, 19 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
|
||||
index ad93629..7a41220 100644
|
||||
--- a/drivers/video/fbmem.c
|
||||
+++ b/drivers/video/fbmem.c
|
||||
@@ -1651,6 +1651,7 @@ static int do_unregister_framebuffer(struct fb_info *fb_info)
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
|
||||
+ unlink_framebuffer(fb_info);
|
||||
if (fb_info->pixmap.addr &&
|
||||
(fb_info->pixmap.flags & FB_PIXMAP_DEFAULT))
|
||||
kfree(fb_info->pixmap.addr);
|
||||
@@ -1658,7 +1659,6 @@ static int do_unregister_framebuffer(struct fb_info *fb_info)
|
||||
registered_fb[i] = NULL;
|
||||
num_registered_fb--;
|
||||
fb_cleanup_device(fb_info);
|
||||
- device_destroy(fb_class, MKDEV(FB_MAJOR, i));
|
||||
event.info = fb_info;
|
||||
fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event);
|
||||
|
||||
@@ -1667,6 +1667,22 @@ static int do_unregister_framebuffer(struct fb_info *fb_info)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+int unlink_framebuffer(struct fb_info *fb_info)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ i = fb_info->node;
|
||||
+ if (i < 0 || i >= FB_MAX || registered_fb[i] != fb_info)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (fb_info->dev) {
|
||||
+ device_destroy(fb_class, MKDEV(FB_MAJOR, i));
|
||||
+ fb_info->dev = NULL;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL(unlink_framebuffer);
|
||||
+
|
||||
void remove_conflicting_framebuffers(struct apertures_struct *a,
|
||||
const char *name, bool primary)
|
||||
{
|
||||
diff --git a/drivers/video/udlfb.c b/drivers/video/udlfb.c
|
||||
index 3473e75..41746bb 100644
|
||||
--- a/drivers/video/udlfb.c
|
||||
+++ b/drivers/video/udlfb.c
|
||||
@@ -1739,7 +1739,7 @@ static void dlfb_usb_disconnect(struct usb_interface *interface)
|
||||
for (i = 0; i < ARRAY_SIZE(fb_device_attrs); i++)
|
||||
device_remove_file(info->dev, &fb_device_attrs[i]);
|
||||
device_remove_bin_file(info->dev, &edid_attr);
|
||||
-
|
||||
+ unlink_framebuffer(info);
|
||||
usb_set_intfdata(interface, NULL);
|
||||
|
||||
/* if clients still have us open, will be freed on last close */
|
||||
diff --git a/include/linux/fb.h b/include/linux/fb.h
|
||||
index 1d6836c..73845ce 100644
|
||||
--- a/include/linux/fb.h
|
||||
+++ b/include/linux/fb.h
|
||||
@@ -997,6 +997,7 @@ extern ssize_t fb_sys_write(struct fb_info *info, const char __user *buf,
|
||||
/* drivers/video/fbmem.c */
|
||||
extern int register_framebuffer(struct fb_info *fb_info);
|
||||
extern int unregister_framebuffer(struct fb_info *fb_info);
|
||||
+extern int unlink_framebuffer(struct fb_info *fb_info);
|
||||
extern void remove_conflicting_framebuffers(struct apertures_struct *a,
|
||||
const char *name, bool primary);
|
||||
extern int fb_prepare_logo(struct fb_info *fb_info, int rotate);
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
From a38ce1660f9b3f6abec9206118adc0a33bda9730 Mon Sep 17 00:00:00 2001
|
||||
From: Nicholas Bellinger <nab@linux-iscsi.org>
|
||||
Date: Fri, 9 Mar 2012 23:45:38 -0800
|
||||
Subject: [PATCH 065/147] tcm_fc: Fix fc_exch memory leak in
|
||||
ft_send_resp_status
|
||||
|
||||
commit 031ed4d565b31880a4136bb7366bc89f5b1dba7d upstream.
|
||||
|
||||
This patch fixes a bug in tcm_fc where fc_exch memory from fc_exch_mgr->ep_pool
|
||||
is currently being leaked by ft_send_resp_status() usage. Following current
|
||||
code in ft_queue_status() response path, using lport->tt.seq_send() needs to be
|
||||
followed by a lport->tt.exch_done() in order to release fc_exch memory back into
|
||||
libfc_em kmem_cache.
|
||||
|
||||
ft_send_resp_status() code is currently used in pre submit se_cmd ft_send_work()
|
||||
error exceptions, TM request setup exceptions, and main TM response callback
|
||||
path in ft_queue_tm_resp(). This bugfix addresses the leak in these cases.
|
||||
|
||||
Cc: Mark D Rustad <mark.d.rustad@intel.com>
|
||||
Cc: Kiran Patil <kiran.patil@intel.com>
|
||||
Cc: Robert Love <robert.w.love@intel.com>
|
||||
Cc: Andy Grover <agrover@redhat.com>
|
||||
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/target/tcm_fc/tfc_cmd.c | 6 ++++--
|
||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/target/tcm_fc/tfc_cmd.c b/drivers/target/tcm_fc/tfc_cmd.c
|
||||
index 71fc9ce..754b669 100644
|
||||
--- a/drivers/target/tcm_fc/tfc_cmd.c
|
||||
+++ b/drivers/target/tcm_fc/tfc_cmd.c
|
||||
@@ -329,10 +329,12 @@ static void ft_send_resp_status(struct fc_lport *lport,
|
||||
|
||||
fc_fill_reply_hdr(fp, rx_fp, FC_RCTL_DD_CMD_STATUS, 0);
|
||||
sp = fr_seq(fp);
|
||||
- if (sp)
|
||||
+ if (sp) {
|
||||
lport->tt.seq_send(lport, sp, fp);
|
||||
- else
|
||||
+ lport->tt.exch_done(sp);
|
||||
+ } else {
|
||||
lport->tt.frame_send(lport, fp);
|
||||
+ }
|
||||
}
|
||||
|
||||
/*
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
From 850bfe24a75251acf10ad9dbacd4bc750005fd1b Mon Sep 17 00:00:00 2001
|
||||
From: NeilBrown <neilb@suse.de>
|
||||
Date: Mon, 19 Mar 2012 12:46:37 +1100
|
||||
Subject: [PATCH 066/147] md/bitmap: ensure to load bitmap when creating via
|
||||
sysfs.
|
||||
|
||||
commit 4474ca42e2577563a919fd3ed782e2ec55bf11a2 upstream.
|
||||
|
||||
When commit 69e51b449d383e (md/bitmap: separate out loading a bitmap...)
|
||||
created bitmap_load, it missed calling it after bitmap_create when a
|
||||
bitmap is created through the sysfs interface.
|
||||
So if a bitmap is added this way, we don't allocate memory properly
|
||||
and can crash.
|
||||
|
||||
This is suitable for any -stable release since 2.6.35.
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/md/bitmap.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
|
||||
index 6d03774..2a8722b 100644
|
||||
--- a/drivers/md/bitmap.c
|
||||
+++ b/drivers/md/bitmap.c
|
||||
@@ -1904,6 +1904,8 @@ location_store(struct mddev *mddev, const char *buf, size_t len)
|
||||
if (mddev->pers) {
|
||||
mddev->pers->quiesce(mddev, 1);
|
||||
rv = bitmap_create(mddev);
|
||||
+ if (!rv)
|
||||
+ rv = bitmap_load(mddev);
|
||||
if (rv) {
|
||||
bitmap_destroy(mddev);
|
||||
mddev->bitmap_info.offset = 0;
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
From c52810052a2cbfeb2b8768081f8a22240c0d0abe Mon Sep 17 00:00:00 2001
|
||||
From: NeilBrown <neilb@suse.de>
|
||||
Date: Mon, 19 Mar 2012 12:46:37 +1100
|
||||
Subject: [PATCH 067/147] md: don't set md arrays to readonly on shutdown.
|
||||
|
||||
commit c744a65c1e2d59acc54333ce80a5b0702a98010b upstream.
|
||||
|
||||
It seems that with recent kernel, writeback can still be happening
|
||||
while shutdown is happening, and consequently data can be written
|
||||
after the md reboot notifier switches all arrays to read-only.
|
||||
This causes a BUG.
|
||||
|
||||
So don't switch them to read-only - just mark them clean and
|
||||
set 'safemode' to '2' which mean that immediately after any
|
||||
write the array will be switch back to 'clean'.
|
||||
|
||||
This could result in the shutdown happening when array is marked
|
||||
dirty, thus forcing a resync on reboot. However if you reboot
|
||||
without performing a "sync" first, you get to keep both halves.
|
||||
|
||||
This is suitable for any stable kernel (though there might be some
|
||||
conflicts with obvious fixes in earlier kernels).
|
||||
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/md/md.c | 37 +++++++++++++++----------------------
|
||||
1 file changed, 15 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/drivers/md/md.c b/drivers/md/md.c
|
||||
index f47f1f8..65d552a 100644
|
||||
--- a/drivers/md/md.c
|
||||
+++ b/drivers/md/md.c
|
||||
@@ -8097,30 +8097,23 @@ static int md_notify_reboot(struct notifier_block *this,
|
||||
struct mddev *mddev;
|
||||
int need_delay = 0;
|
||||
|
||||
- if ((code == SYS_DOWN) || (code == SYS_HALT) || (code == SYS_POWER_OFF)) {
|
||||
-
|
||||
- printk(KERN_INFO "md: stopping all md devices.\n");
|
||||
-
|
||||
- for_each_mddev(mddev, tmp) {
|
||||
- if (mddev_trylock(mddev)) {
|
||||
- /* Force a switch to readonly even array
|
||||
- * appears to still be in use. Hence
|
||||
- * the '100'.
|
||||
- */
|
||||
- md_set_readonly(mddev, 100);
|
||||
- mddev_unlock(mddev);
|
||||
- }
|
||||
- need_delay = 1;
|
||||
+ for_each_mddev(mddev, tmp) {
|
||||
+ if (mddev_trylock(mddev)) {
|
||||
+ __md_stop_writes(mddev);
|
||||
+ mddev->safemode = 2;
|
||||
+ mddev_unlock(mddev);
|
||||
}
|
||||
- /*
|
||||
- * certain more exotic SCSI devices are known to be
|
||||
- * volatile wrt too early system reboots. While the
|
||||
- * right place to handle this issue is the given
|
||||
- * driver, we do want to have a safe RAID driver ...
|
||||
- */
|
||||
- if (need_delay)
|
||||
- mdelay(1000*1);
|
||||
+ need_delay = 1;
|
||||
}
|
||||
+ /*
|
||||
+ * certain more exotic SCSI devices are known to be
|
||||
+ * volatile wrt too early system reboots. While the
|
||||
+ * right place to handle this issue is the given
|
||||
+ * driver, we do want to have a safe RAID driver ...
|
||||
+ */
|
||||
+ if (need_delay)
|
||||
+ mdelay(1000*1);
|
||||
+
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
From 250082bf56c6157c888f21df27d73475cb6f0065 Mon Sep 17 00:00:00 2001
|
||||
From: NeilBrown <neilb@suse.de>
|
||||
Date: Mon, 19 Mar 2012 12:46:38 +1100
|
||||
Subject: [PATCH 068/147] md/raid1,raid10: avoid deadlock during
|
||||
resync/recovery.
|
||||
|
||||
commit d6b42dcb995e6acd7cc276774e751ffc9f0ef4bf upstream.
|
||||
|
||||
If RAID1 or RAID10 is used under LVM or some other stacking
|
||||
block device, it is possible to enter a deadlock during
|
||||
resync or recovery.
|
||||
This can happen if the upper level block device creates
|
||||
two requests to the RAID1 or RAID10. The first request gets
|
||||
processed, blocks recovery and queue requests for underlying
|
||||
requests in current->bio_list. A resync request then starts
|
||||
which will wait for those requests and block new IO.
|
||||
|
||||
But then the second request to the RAID1/10 will be attempted
|
||||
and it cannot progress until the resync request completes,
|
||||
which cannot progress until the underlying device requests complete,
|
||||
which are on a queue behind that second request.
|
||||
|
||||
So allow that second request to proceed even though there is
|
||||
a resync request about to start.
|
||||
|
||||
This is suitable for any -stable kernel.
|
||||
|
||||
Reported-by: Ray Morris <support@bettercgi.com>
|
||||
Tested-by: Ray Morris <support@bettercgi.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/md/raid1.c | 17 +++++++++++++++--
|
||||
drivers/md/raid10.c | 17 +++++++++++++++--
|
||||
2 files changed, 30 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
|
||||
index 7d9e071..7af60ec 100644
|
||||
--- a/drivers/md/raid1.c
|
||||
+++ b/drivers/md/raid1.c
|
||||
@@ -731,9 +731,22 @@ static void wait_barrier(struct r1conf *conf)
|
||||
spin_lock_irq(&conf->resync_lock);
|
||||
if (conf->barrier) {
|
||||
conf->nr_waiting++;
|
||||
- wait_event_lock_irq(conf->wait_barrier, !conf->barrier,
|
||||
+ /* Wait for the barrier to drop.
|
||||
+ * However if there are already pending
|
||||
+ * requests (preventing the barrier from
|
||||
+ * rising completely), and the
|
||||
+ * pre-process bio queue isn't empty,
|
||||
+ * then don't wait, as we need to empty
|
||||
+ * that queue to get the nr_pending
|
||||
+ * count down.
|
||||
+ */
|
||||
+ wait_event_lock_irq(conf->wait_barrier,
|
||||
+ !conf->barrier ||
|
||||
+ (conf->nr_pending &&
|
||||
+ current->bio_list &&
|
||||
+ !bio_list_empty(current->bio_list)),
|
||||
conf->resync_lock,
|
||||
- );
|
||||
+ );
|
||||
conf->nr_waiting--;
|
||||
}
|
||||
conf->nr_pending++;
|
||||
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
|
||||
index 685ddf3..b219449 100644
|
||||
--- a/drivers/md/raid10.c
|
||||
+++ b/drivers/md/raid10.c
|
||||
@@ -790,9 +790,22 @@ static void wait_barrier(struct r10conf *conf)
|
||||
spin_lock_irq(&conf->resync_lock);
|
||||
if (conf->barrier) {
|
||||
conf->nr_waiting++;
|
||||
- wait_event_lock_irq(conf->wait_barrier, !conf->barrier,
|
||||
+ /* Wait for the barrier to drop.
|
||||
+ * However if there are already pending
|
||||
+ * requests (preventing the barrier from
|
||||
+ * rising completely), and the
|
||||
+ * pre-process bio queue isn't empty,
|
||||
+ * then don't wait, as we need to empty
|
||||
+ * that queue to get the nr_pending
|
||||
+ * count down.
|
||||
+ */
|
||||
+ wait_event_lock_irq(conf->wait_barrier,
|
||||
+ !conf->barrier ||
|
||||
+ (conf->nr_pending &&
|
||||
+ current->bio_list &&
|
||||
+ !bio_list_empty(current->bio_list)),
|
||||
conf->resync_lock,
|
||||
- );
|
||||
+ );
|
||||
conf->nr_waiting--;
|
||||
}
|
||||
conf->nr_pending++;
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
From c1566b5f4f2d8cbc8badc75b774fa79d6c03477b Mon Sep 17 00:00:00 2001
|
||||
From: NeilBrown <neilb@suse.de>
|
||||
Date: Mon, 19 Mar 2012 12:46:41 +1100
|
||||
Subject: [PATCH 069/147] md: fix clearing of the 'changed' flags for the bad
|
||||
blocks list.
|
||||
|
||||
commit d0962936bff659d20522555b517582a2715fd23f upstream.
|
||||
|
||||
In super_1_sync (the first hunk) we need to clear 'changed' before
|
||||
checking read_seqretry(), otherwise we might race with other code
|
||||
adding a bad block and so won't retry later.
|
||||
|
||||
In md_update_sb (the second hunk), in the case where there is no
|
||||
metadata (neither persistent nor external), we treat any bad blocks as
|
||||
an error. However we need to clear the 'changed' flag before calling
|
||||
md_ack_all_badblocks, else it won't do anything.
|
||||
|
||||
This patch is suitable for -stable release 3.0 and later.
|
||||
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/md/md.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/md/md.c b/drivers/md/md.c
|
||||
index 65d552a..6f37aa4 100644
|
||||
--- a/drivers/md/md.c
|
||||
+++ b/drivers/md/md.c
|
||||
@@ -1801,13 +1801,13 @@ retry:
|
||||
| BB_LEN(internal_bb));
|
||||
*bbp++ = cpu_to_le64(store_bb);
|
||||
}
|
||||
+ bb->changed = 0;
|
||||
if (read_seqretry(&bb->lock, seq))
|
||||
goto retry;
|
||||
|
||||
bb->sector = (rdev->sb_start +
|
||||
(int)le32_to_cpu(sb->bblog_offset));
|
||||
bb->size = le16_to_cpu(sb->bblog_size);
|
||||
- bb->changed = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2362,6 +2362,7 @@ repeat:
|
||||
clear_bit(MD_CHANGE_PENDING, &mddev->flags);
|
||||
list_for_each_entry(rdev, &mddev->disks, same_set) {
|
||||
if (rdev->badblocks.changed) {
|
||||
+ rdev->badblocks.changed = 0;
|
||||
md_ack_all_badblocks(&rdev->badblocks);
|
||||
md_error(mddev, rdev);
|
||||
}
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
From bee686c633c4875d2910e0559b7ce4bba5da1911 Mon Sep 17 00:00:00 2001
|
||||
From: Chris Wilson <chris@chris-wilson.co.uk>
|
||||
Date: Wed, 14 Dec 2011 13:57:23 +0100
|
||||
Subject: [PATCH 070/147] drm/i915: Only clear the GPU domains upon a
|
||||
successful finish
|
||||
|
||||
commit c501ae7f332cdaf42e31af30b72b4b66cbbb1604 upstream.
|
||||
|
||||
By clearing the GPU read domains before waiting upon the buffer, we run
|
||||
the risk of the wait being interrupted and the domains prematurely
|
||||
cleared. The next time we attempt to wait upon the buffer (after
|
||||
userspace handles the signal), we believe that the buffer is idle and so
|
||||
skip the wait.
|
||||
|
||||
There are a number of bugs across all generations which show signs of an
|
||||
overly haste reuse of active buffers.
|
||||
|
||||
Such as:
|
||||
|
||||
https://bugs.freedesktop.org/show_bug.cgi?id=29046
|
||||
https://bugs.freedesktop.org/show_bug.cgi?id=35863
|
||||
https://bugs.freedesktop.org/show_bug.cgi?id=38952
|
||||
https://bugs.freedesktop.org/show_bug.cgi?id=40282
|
||||
https://bugs.freedesktop.org/show_bug.cgi?id=41098
|
||||
https://bugs.freedesktop.org/show_bug.cgi?id=41102
|
||||
https://bugs.freedesktop.org/show_bug.cgi?id=41284
|
||||
https://bugs.freedesktop.org/show_bug.cgi?id=42141
|
||||
|
||||
A couple of those pre-date i915_gem_object_finish_gpu(), so may be
|
||||
unrelated (such as a wild write from a userspace command buffer), but
|
||||
this does look like a convincing cause for most of those bugs.
|
||||
|
||||
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
|
||||
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
|
||||
Reviewed-by: Eugeni Dodonov <eugeni.dodonov@intel.com>
|
||||
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/gpu/drm/i915/i915_gem.c | 7 +++++--
|
||||
1 file changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
|
||||
index 8359dc7..3e7c478 100644
|
||||
--- a/drivers/gpu/drm/i915/i915_gem.c
|
||||
+++ b/drivers/gpu/drm/i915/i915_gem.c
|
||||
@@ -3084,10 +3084,13 @@ i915_gem_object_finish_gpu(struct drm_i915_gem_object *obj)
|
||||
return ret;
|
||||
}
|
||||
|
||||
+ ret = i915_gem_object_wait_rendering(obj);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
/* Ensure that we invalidate the GPU's caches and TLBs. */
|
||||
obj->base.read_domains &= ~I915_GEM_GPU_DOMAINS;
|
||||
-
|
||||
- return i915_gem_object_wait_rendering(obj);
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
From 37e7d6645532f78e279da5f5257faf0ee0c0f8f3 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Michel=20D=C3=A4nzer?= <michel.daenzer@amd.com>
|
||||
Date: Wed, 14 Mar 2012 17:12:41 +0100
|
||||
Subject: [PATCH 071/147] drm/radeon: Restrict offset for legacy hardware
|
||||
cursor.
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
commit c4353016dac10133fa5d8535af83f0c4845a2915 upstream.
|
||||
|
||||
The hardware only takes 27 bits for the offset, so larger offsets are
|
||||
truncated, and the hardware cursor shows random bits other than the intended
|
||||
ones.
|
||||
|
||||
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=46796
|
||||
|
||||
Signed-off-by: Michel D??nzer <michel.daenzer@amd.com>
|
||||
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
|
||||
Signed-off-by: Dave Airlie <airlied@redhat.com>
|
||||
---
|
||||
drivers/gpu/drm/radeon/radeon_cursor.c | 13 +++++++++++--
|
||||
drivers/gpu/drm/radeon/radeon_object.c | 18 +++++++++++++++++-
|
||||
drivers/gpu/drm/radeon/radeon_object.h | 2 ++
|
||||
3 files changed, 30 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/radeon/radeon_cursor.c b/drivers/gpu/drm/radeon/radeon_cursor.c
|
||||
index fde25c0..986d608 100644
|
||||
--- a/drivers/gpu/drm/radeon/radeon_cursor.c
|
||||
+++ b/drivers/gpu/drm/radeon/radeon_cursor.c
|
||||
@@ -151,7 +151,9 @@ int radeon_crtc_cursor_set(struct drm_crtc *crtc,
|
||||
uint32_t height)
|
||||
{
|
||||
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
|
||||
+ struct radeon_device *rdev = crtc->dev->dev_private;
|
||||
struct drm_gem_object *obj;
|
||||
+ struct radeon_bo *robj;
|
||||
uint64_t gpu_addr;
|
||||
int ret;
|
||||
|
||||
@@ -173,7 +175,15 @@ int radeon_crtc_cursor_set(struct drm_crtc *crtc,
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
- ret = radeon_gem_object_pin(obj, RADEON_GEM_DOMAIN_VRAM, &gpu_addr);
|
||||
+ robj = gem_to_radeon_bo(obj);
|
||||
+ ret = radeon_bo_reserve(robj, false);
|
||||
+ if (unlikely(ret != 0))
|
||||
+ goto fail;
|
||||
+ /* Only 27 bit offset for legacy cursor */
|
||||
+ ret = radeon_bo_pin_restricted(robj, RADEON_GEM_DOMAIN_VRAM,
|
||||
+ ASIC_IS_AVIVO(rdev) ? 0 : 1 << 27,
|
||||
+ &gpu_addr);
|
||||
+ radeon_bo_unreserve(robj);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
@@ -181,7 +191,6 @@ int radeon_crtc_cursor_set(struct drm_crtc *crtc,
|
||||
radeon_crtc->cursor_height = height;
|
||||
|
||||
radeon_lock_cursor(crtc, true);
|
||||
- /* XXX only 27 bit offset for legacy cursor */
|
||||
radeon_set_cursor(crtc, obj, gpu_addr);
|
||||
radeon_show_cursor(crtc);
|
||||
radeon_lock_cursor(crtc, false);
|
||||
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c
|
||||
index 1c85152..f3ae607 100644
|
||||
--- a/drivers/gpu/drm/radeon/radeon_object.c
|
||||
+++ b/drivers/gpu/drm/radeon/radeon_object.c
|
||||
@@ -204,7 +204,8 @@ void radeon_bo_unref(struct radeon_bo **bo)
|
||||
*bo = NULL;
|
||||
}
|
||||
|
||||
-int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 *gpu_addr)
|
||||
+int radeon_bo_pin_restricted(struct radeon_bo *bo, u32 domain, u64 max_offset,
|
||||
+ u64 *gpu_addr)
|
||||
{
|
||||
int r, i;
|
||||
|
||||
@@ -212,6 +213,7 @@ int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 *gpu_addr)
|
||||
bo->pin_count++;
|
||||
if (gpu_addr)
|
||||
*gpu_addr = radeon_bo_gpu_offset(bo);
|
||||
+ WARN_ON_ONCE(max_offset != 0);
|
||||
return 0;
|
||||
}
|
||||
radeon_ttm_placement_from_domain(bo, domain);
|
||||
@@ -219,6 +221,15 @@ int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 *gpu_addr)
|
||||
/* force to pin into visible video ram */
|
||||
bo->placement.lpfn = bo->rdev->mc.visible_vram_size >> PAGE_SHIFT;
|
||||
}
|
||||
+ if (max_offset) {
|
||||
+ u64 lpfn = max_offset >> PAGE_SHIFT;
|
||||
+
|
||||
+ if (!bo->placement.lpfn)
|
||||
+ bo->placement.lpfn = bo->rdev->mc.gtt_size >> PAGE_SHIFT;
|
||||
+
|
||||
+ if (lpfn < bo->placement.lpfn)
|
||||
+ bo->placement.lpfn = lpfn;
|
||||
+ }
|
||||
for (i = 0; i < bo->placement.num_placement; i++)
|
||||
bo->placements[i] |= TTM_PL_FLAG_NO_EVICT;
|
||||
r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false, false);
|
||||
@@ -232,6 +243,11 @@ int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 *gpu_addr)
|
||||
return r;
|
||||
}
|
||||
|
||||
+int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 *gpu_addr)
|
||||
+{
|
||||
+ return radeon_bo_pin_restricted(bo, domain, 0, gpu_addr);
|
||||
+}
|
||||
+
|
||||
int radeon_bo_unpin(struct radeon_bo *bo)
|
||||
{
|
||||
int r, i;
|
||||
diff --git a/drivers/gpu/drm/radeon/radeon_object.h b/drivers/gpu/drm/radeon/radeon_object.h
|
||||
index b07f0f9..fb3f433 100644
|
||||
--- a/drivers/gpu/drm/radeon/radeon_object.h
|
||||
+++ b/drivers/gpu/drm/radeon/radeon_object.h
|
||||
@@ -108,6 +108,8 @@ extern int radeon_bo_kmap(struct radeon_bo *bo, void **ptr);
|
||||
extern void radeon_bo_kunmap(struct radeon_bo *bo);
|
||||
extern void radeon_bo_unref(struct radeon_bo **bo);
|
||||
extern int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 *gpu_addr);
|
||||
+extern int radeon_bo_pin_restricted(struct radeon_bo *bo, u32 domain,
|
||||
+ u64 max_offset, u64 *gpu_addr);
|
||||
extern int radeon_bo_unpin(struct radeon_bo *bo);
|
||||
extern int radeon_bo_evict_vram(struct radeon_device *rdev);
|
||||
extern void radeon_bo_force_delete(struct radeon_device *rdev);
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
From de31bb0d8975b5a6b55c0c0fb10fb7f84ca15c5d Mon Sep 17 00:00:00 2001
|
||||
From: Alex Deucher <alexander.deucher@amd.com>
|
||||
Date: Fri, 16 Mar 2012 12:22:09 -0400
|
||||
Subject: [PATCH 072/147] drm/radeon/kms: fix analog load detection on DVI-I
|
||||
connectors
|
||||
|
||||
commit e00e8b5e760cbbe9067daeae5454d67c44c8d035 upstream.
|
||||
|
||||
We digital encoders have a detect function as well (for
|
||||
DP to VGA bridges), so we make sure we choose the analog
|
||||
one here.
|
||||
|
||||
Fixes:
|
||||
https://bugs.freedesktop.org/show_bug.cgi?id=47007
|
||||
|
||||
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
|
||||
Signed-off-by: Dave Airlie <airlied@redhat.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/gpu/drm/radeon/radeon_connectors.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
|
||||
index e7cb3ab..f7d39ac 100644
|
||||
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
|
||||
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
|
||||
@@ -946,6 +946,10 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
|
||||
|
||||
encoder = obj_to_encoder(obj);
|
||||
|
||||
+ if (encoder->encoder_type != DRM_MODE_ENCODER_DAC ||
|
||||
+ encoder->encoder_type != DRM_MODE_ENCODER_TVDAC)
|
||||
+ continue;
|
||||
+
|
||||
encoder_funcs = encoder->helper_private;
|
||||
if (encoder_funcs->detect) {
|
||||
if (ret != connector_status_connected) {
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
From 5efedf1eea47c18e516e55bbfb417e447e76fc0d Mon Sep 17 00:00:00 2001
|
||||
From: Alex Deucher <alexander.deucher@amd.com>
|
||||
Date: Fri, 16 Mar 2012 12:22:10 -0400
|
||||
Subject: [PATCH 073/147] drm/radeon/kms: add connector quirk for Fujitsu
|
||||
D3003-S2 board
|
||||
|
||||
commit 4c1b2d2da3451f5c8dd59bd7e05bd9729d2aee05 upstream.
|
||||
|
||||
vbios lists DVI-I port as VGA and DVI-D.
|
||||
|
||||
Fixes:
|
||||
https://bugs.freedesktop.org/show_bug.cgi?id=47007
|
||||
|
||||
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
|
||||
Signed-off-by: Dave Airlie <airlied@redhat.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/gpu/drm/radeon/radeon_atombios.c | 14 ++++++++++++++
|
||||
1 file changed, 14 insertions(+)
|
||||
|
||||
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
|
||||
index 5082d17..8e1532f 100644
|
||||
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
|
||||
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
|
||||
@@ -442,6 +442,20 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev,
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
*i2c_bus = radeon_lookup_i2c_gpio(rdev, 0x93);
|
||||
}
|
||||
+
|
||||
+ /* Fujitsu D3003-S2 board lists DVI-I as DVI-D and VGA */
|
||||
+ if ((dev->pdev->device == 0x9802) &&
|
||||
+ (dev->pdev->subsystem_vendor == 0x1734) &&
|
||||
+ (dev->pdev->subsystem_device == 0x11bd)) {
|
||||
+ if (*connector_type == DRM_MODE_CONNECTOR_VGA) {
|
||||
+ *connector_type = DRM_MODE_CONNECTOR_DVII;
|
||||
+ *line_mux = 0x3103;
|
||||
+ } else if (*connector_type == DRM_MODE_CONNECTOR_DVID) {
|
||||
+ *connector_type = DRM_MODE_CONNECTOR_DVII;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+
|
||||
return true;
|
||||
}
|
||||
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
From 7f95ff0ee05801dd087ec704be16aae6383f0076 Mon Sep 17 00:00:00 2001
|
||||
From: Roland Dreier <roland@purestorage.com>
|
||||
Date: Mon, 13 Feb 2012 16:18:16 -0800
|
||||
Subject: [PATCH 074/147] target: Don't set WBUS16 or SYNC bits in INQUIRY
|
||||
response
|
||||
|
||||
commit effc6cc8828257c32c37635e737f14fd6e19ecd7 upstream.
|
||||
|
||||
SPC-4 says about the WBUS16 and SYNC bits:
|
||||
|
||||
The meanings of these fields are specific to SPI-5 (see 6.4.3).
|
||||
For SCSI transport protocols other than the SCSI Parallel
|
||||
Interface, these fields are reserved.
|
||||
|
||||
We don't have a SPI fabric module, so we should never set these bits.
|
||||
(The comment was misleading, since it only mentioned Sync but the
|
||||
actual code set WBUS16 too).
|
||||
|
||||
Signed-off-by: Roland Dreier <roland@purestorage.com>
|
||||
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/target/target_core_cdb.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/target/target_core_cdb.c b/drivers/target/target_core_cdb.c
|
||||
index 8facd33..65ea65a 100644
|
||||
--- a/drivers/target/target_core_cdb.c
|
||||
+++ b/drivers/target/target_core_cdb.c
|
||||
@@ -116,7 +116,7 @@ target_emulate_inquiry_std(struct se_cmd *cmd)
|
||||
goto out;
|
||||
}
|
||||
|
||||
- buf[7] = 0x32; /* Sync=1 and CmdQue=1 */
|
||||
+ buf[7] = 0x2; /* CmdQue=1 */
|
||||
|
||||
/*
|
||||
* Do not include vendor, product, reversion info in INQUIRY
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
From 679e28aac79ff6dc71e84679bcd97e5246697ccf Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?J=C3=B6rn=20Engel?= <joern@logfs.org>
|
||||
Date: Wed, 15 Feb 2012 16:51:32 -0500
|
||||
Subject: [PATCH 075/147] target: fix use after free in target_report_luns
|
||||
|
||||
commit 382436f8804fe1cb20b9a2a811a10eb2d8554721 upstream.
|
||||
|
||||
Fix possible NULL pointer dereference in target_report_luns failure path.
|
||||
|
||||
Signed-off-by: Joern Engel <joern@logfs.org>
|
||||
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/target/target_core_device.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c
|
||||
index 19f8aca..097178b 100644
|
||||
--- a/drivers/target/target_core_device.c
|
||||
+++ b/drivers/target/target_core_device.c
|
||||
@@ -696,12 +696,12 @@ int target_report_luns(struct se_task *se_task)
|
||||
* See SPC3 r07, page 159.
|
||||
*/
|
||||
done:
|
||||
- transport_kunmap_data_sg(se_cmd);
|
||||
lun_count *= 8;
|
||||
buf[0] = ((lun_count >> 24) & 0xff);
|
||||
buf[1] = ((lun_count >> 16) & 0xff);
|
||||
buf[2] = ((lun_count >> 8) & 0xff);
|
||||
buf[3] = (lun_count & 0xff);
|
||||
+ transport_kunmap_data_sg(se_cmd);
|
||||
|
||||
se_task->task_scsi_status = GOOD;
|
||||
transport_complete_task(se_task, 1);
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
From 238ac5c459c0204f5134a324f95588aed557b41c Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?J=C3=B6rn=20Engel?= <joern@logfs.org>
|
||||
Date: Wed, 15 Feb 2012 16:52:11 -0500
|
||||
Subject: [PATCH 076/147] target: prevent NULL pointer dereference in
|
||||
target_report_luns
|
||||
|
||||
commit 47f1b8803e1e358ebbf4f82bfdb98971c912a2c3 upstream.
|
||||
|
||||
transport_kmap_data_sg can return NULL. I never saw this trigger, but
|
||||
returning -ENOMEM seems better than a crash. Also removes a pointless
|
||||
case while at it.
|
||||
|
||||
Signed-off-by: Joern Engel <joern@logfs.org>
|
||||
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/target/target_core_device.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c
|
||||
index 097178b..f8773ae 100644
|
||||
--- a/drivers/target/target_core_device.c
|
||||
+++ b/drivers/target/target_core_device.c
|
||||
@@ -658,7 +658,9 @@ int target_report_luns(struct se_task *se_task)
|
||||
unsigned char *buf;
|
||||
u32 cdb_offset = 0, lun_count = 0, offset = 8, i;
|
||||
|
||||
- buf = (unsigned char *) transport_kmap_data_sg(se_cmd);
|
||||
+ buf = transport_kmap_data_sg(se_cmd);
|
||||
+ if (!buf)
|
||||
+ return -ENOMEM;
|
||||
|
||||
/*
|
||||
* If no struct se_session pointer is present, this struct se_cmd is
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
From 407e1b9350ad2124952f769ade034023a9155c71 Mon Sep 17 00:00:00 2001
|
||||
From: Roland Dreier <roland@purestorage.com>
|
||||
Date: Thu, 23 Feb 2012 17:22:12 -0800
|
||||
Subject: [PATCH 077/147] target: Fix 16-bit target ports for SET TARGET PORT
|
||||
GROUPS emulation
|
||||
|
||||
commit 33395fb8a13731c7ef7b175dbf5a4d8a6738fe6c upstream.
|
||||
|
||||
The old code did (MSB << 8) & 0xff, which always evaluates to 0. Just use
|
||||
get_unaligned_be16() so we don't have to worry about whether our open-coded
|
||||
version is correct or not.
|
||||
|
||||
Signed-off-by: Roland Dreier <roland@purestorage.com>
|
||||
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/target/target_core_alua.c | 7 +++----
|
||||
1 file changed, 3 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c
|
||||
index 1d24512..5b05744 100644
|
||||
--- a/drivers/target/target_core_alua.c
|
||||
+++ b/drivers/target/target_core_alua.c
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <linux/export.h>
|
||||
#include <scsi/scsi.h>
|
||||
#include <scsi/scsi_cmnd.h>
|
||||
+#include <asm/unaligned.h>
|
||||
|
||||
#include <target/target_core_base.h>
|
||||
#include <target/target_core_device.h>
|
||||
@@ -268,8 +269,7 @@ int target_emulate_set_target_port_groups(struct se_task *task)
|
||||
* changed.
|
||||
*/
|
||||
if (primary) {
|
||||
- tg_pt_id = ((ptr[2] << 8) & 0xff);
|
||||
- tg_pt_id |= (ptr[3] & 0xff);
|
||||
+ tg_pt_id = get_unaligned_be16(ptr + 2);
|
||||
/*
|
||||
* Locate the matching target port group ID from
|
||||
* the global tg_pt_gp list
|
||||
@@ -313,8 +313,7 @@ int target_emulate_set_target_port_groups(struct se_task *task)
|
||||
* the Target Port in question for the the incoming
|
||||
* SET_TARGET_PORT_GROUPS op.
|
||||
*/
|
||||
- rtpi = ((ptr[2] << 8) & 0xff);
|
||||
- rtpi |= (ptr[3] & 0xff);
|
||||
+ rtpi = get_unaligned_be16(ptr + 2);
|
||||
/*
|
||||
* Locate the matching relative target port identifer
|
||||
* for the struct se_device storage object.
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
From d559faa856c1c6f84dc400b9e77af843d3b79c10 Mon Sep 17 00:00:00 2001
|
||||
From: Keng-Yu Lin <kengyu@canonical.com>
|
||||
Date: Wed, 30 Nov 2011 18:32:37 +0800
|
||||
Subject: [PATCH 078/147] Bluetooth: Add AR30XX device ID on Asus laptops
|
||||
|
||||
commit 6b6ba88b5bb8779156b21bb957520a448c3642e2 upstream.
|
||||
|
||||
The ID is found on Asus K54HR and K53U.
|
||||
Blacklist the AR3011-based device ID [0489:e03d]
|
||||
and add to ath3k.c for firmware loading.
|
||||
|
||||
Below is the output of usb-devices script:
|
||||
|
||||
Before the fiwmware loading:
|
||||
|
||||
T: Bus=01 Lev=02 Prnt=02 Port=00 Cnt=01 Dev#= 3 Spd=12 MxCh= 0
|
||||
D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1
|
||||
P: Vendor=0489 ProdID=e03d Rev=00.01
|
||||
C: #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA
|
||||
I: If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
|
||||
I: If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
|
||||
|
||||
After the fiwmware loading:
|
||||
|
||||
T: Bus=01 Lev=02 Prnt=02 Port=00 Cnt=01 Dev#= 5 Spd=12 MxCh= 0
|
||||
D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1
|
||||
P: Vendor=0cf3 ProdID=3005 Rev=00.01
|
||||
C: #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA
|
||||
I: If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
|
||||
I: If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
|
||||
|
||||
Signed-off-by: Keng-Yu Lin <kengyu@canonical.com>
|
||||
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
|
||||
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/bluetooth/ath3k.c | 1 +
|
||||
drivers/bluetooth/btusb.c | 1 +
|
||||
2 files changed, 2 insertions(+)
|
||||
|
||||
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
|
||||
index 106beb1..db811d2 100644
|
||||
--- a/drivers/bluetooth/ath3k.c
|
||||
+++ b/drivers/bluetooth/ath3k.c
|
||||
@@ -64,6 +64,7 @@ static struct usb_device_id ath3k_table[] = {
|
||||
{ USB_DEVICE(0x0CF3, 0x3002) },
|
||||
{ USB_DEVICE(0x13d3, 0x3304) },
|
||||
{ USB_DEVICE(0x0930, 0x0215) },
|
||||
+ { USB_DEVICE(0x0489, 0xE03D) },
|
||||
|
||||
/* Atheros AR9285 Malbec with sflash firmware */
|
||||
{ USB_DEVICE(0x03F0, 0x311D) },
|
||||
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
|
||||
index eabc437..11a925c 100644
|
||||
--- a/drivers/bluetooth/btusb.c
|
||||
+++ b/drivers/bluetooth/btusb.c
|
||||
@@ -119,6 +119,7 @@ static struct usb_device_id blacklist_table[] = {
|
||||
{ USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE },
|
||||
{ USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE },
|
||||
{ USB_DEVICE(0x0930, 0x0215), .driver_info = BTUSB_IGNORE },
|
||||
+ { USB_DEVICE(0x0489, 0xe03d), .driver_info = BTUSB_IGNORE },
|
||||
|
||||
/* Atheros AR9285 Malbec with sflash firmware */
|
||||
{ USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE },
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
From 5c473125260020cedb5e4285eea74fc4528eee85 Mon Sep 17 00:00:00 2001
|
||||
From: Keng-Yu Lin <kengyu@canonical.com>
|
||||
Date: Thu, 2 Feb 2012 10:31:26 +0100
|
||||
Subject: [PATCH 079/147] HID: add extra hotkeys in Asus AIO keyboards
|
||||
|
||||
commit 3596bb929f2abd3433c2eaa5755fad48ac207af1 upstream.
|
||||
|
||||
The Asus All-In-One PC has a wireless keyboard with wifi toggle,
|
||||
brightness up, brightness down and display off hotkeys.
|
||||
|
||||
This patch adds suppoort for these hotkeys.
|
||||
|
||||
Signed-off-by: Keng-Yu Lin <kengyu@canonical.com>
|
||||
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/hid/hid-chicony.c | 5 +++++
|
||||
drivers/hid/hid-core.c | 1 +
|
||||
drivers/hid/hid-ids.h | 1 +
|
||||
3 files changed, 7 insertions(+)
|
||||
|
||||
diff --git a/drivers/hid/hid-chicony.c b/drivers/hid/hid-chicony.c
|
||||
index 8965ad9..4162505 100644
|
||||
--- a/drivers/hid/hid-chicony.c
|
||||
+++ b/drivers/hid/hid-chicony.c
|
||||
@@ -45,6 +45,10 @@ static int ch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
|
||||
case 0xff09: ch_map_key_clear(BTN_9); break;
|
||||
case 0xff0a: ch_map_key_clear(BTN_A); break;
|
||||
case 0xff0b: ch_map_key_clear(BTN_B); break;
|
||||
+ case 0x00f1: ch_map_key_clear(KEY_WLAN); break;
|
||||
+ case 0x00f2: ch_map_key_clear(KEY_BRIGHTNESSDOWN); break;
|
||||
+ case 0x00f3: ch_map_key_clear(KEY_BRIGHTNESSUP); break;
|
||||
+ case 0x00f4: ch_map_key_clear(KEY_DISPLAY_OFF); break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -53,6 +57,7 @@ static int ch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
|
||||
|
||||
static const struct hid_device_id ch_devices[] = {
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) },
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS2) },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(hid, ch_devices);
|
||||
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
|
||||
index bb656d8..c27b402 100644
|
||||
--- a/drivers/hid/hid-core.c
|
||||
+++ b/drivers/hid/hid-core.c
|
||||
@@ -1394,6 +1394,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS) },
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS2) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_CHUNGHWAT, USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_PRODIKEYS_PCMIDI) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_CVTOUCH, USB_DEVICE_ID_CVTOUCH_SCREEN) },
|
||||
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
|
||||
index 3c3daec..fba3fc4 100644
|
||||
--- a/drivers/hid/hid-ids.h
|
||||
+++ b/drivers/hid/hid-ids.h
|
||||
@@ -192,6 +192,7 @@
|
||||
#define USB_DEVICE_ID_CHICONY_TACTICAL_PAD 0x0418
|
||||
#define USB_DEVICE_ID_CHICONY_MULTI_TOUCH 0xb19d
|
||||
#define USB_DEVICE_ID_CHICONY_WIRELESS 0x0618
|
||||
+#define USB_DEVICE_ID_CHICONY_WIRELESS2 0x1123
|
||||
|
||||
#define USB_VENDOR_ID_CHUNGHWAT 0x2247
|
||||
#define USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH 0x0001
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
From 236648a7e4f6330831cb031c7c970b07db3cf39f Mon Sep 17 00:00:00 2001
|
||||
From: Keng-Yu Lin <kengyu@canonical.com>
|
||||
Date: Mon, 30 Jan 2012 14:25:45 +0800
|
||||
Subject: [PATCH 080/147] HID: add more hotkeys in Asus AIO keyboards
|
||||
|
||||
commit 6c30d5a53229aad22bb675e0bd6eb518ecaa4316 upstream.
|
||||
|
||||
Add support for the camera key. The hotkey for
|
||||
Asus S.H.E(Super Hybrid Engine) mode is mapped to KEY_KEY_PROG1
|
||||
just for notifying the userspace.
|
||||
|
||||
Signed-off-by: Keng-Yu Lin <kengyu@canonical.com>
|
||||
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/hid/hid-chicony.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/drivers/hid/hid-chicony.c b/drivers/hid/hid-chicony.c
|
||||
index 4162505..b99af34 100644
|
||||
--- a/drivers/hid/hid-chicony.c
|
||||
+++ b/drivers/hid/hid-chicony.c
|
||||
@@ -49,6 +49,8 @@ static int ch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
|
||||
case 0x00f2: ch_map_key_clear(KEY_BRIGHTNESSDOWN); break;
|
||||
case 0x00f3: ch_map_key_clear(KEY_BRIGHTNESSUP); break;
|
||||
case 0x00f4: ch_map_key_clear(KEY_DISPLAY_OFF); break;
|
||||
+ case 0x00f7: ch_map_key_clear(KEY_CAMERA); break;
|
||||
+ case 0x00f8: ch_map_key_clear(KEY_PROG1); break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
From 9d312025d223d521d0f5a46ab994323646114050 Mon Sep 17 00:00:00 2001
|
||||
From: Sergei Shtylyov <sshtylyov@ru.mvista.com>
|
||||
Date: Thu, 19 Jan 2012 19:09:56 +0300
|
||||
Subject: [PATCH 081/147] pata_legacy: correctly mask recovery field for
|
||||
HT6560B
|
||||
|
||||
commit 9716387311c790de381214c03e7f1b72b91a8189 upstream.
|
||||
|
||||
According to the HT6560H datasheet, the recovery timing field is 4-bit wide,
|
||||
with a value of 0 meaning 16 cycles. Correct obvious thinko in the recovery
|
||||
field mask.
|
||||
|
||||
Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
|
||||
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/ata/pata_legacy.c | 3 +--
|
||||
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c
|
||||
index 35aca7d..4fe9d21 100644
|
||||
--- a/drivers/ata/pata_legacy.c
|
||||
+++ b/drivers/ata/pata_legacy.c
|
||||
@@ -401,8 +401,7 @@ static void ht6560b_set_piomode(struct ata_port *ap, struct ata_device *adev)
|
||||
ata_timing_compute(adev, adev->pio_mode, &t, 20000, 1000);
|
||||
|
||||
active = clamp_val(t.active, 2, 15);
|
||||
- recover = clamp_val(t.recover, 2, 16);
|
||||
- recover &= 0x15;
|
||||
+ recover = clamp_val(t.recover, 2, 16) & 0x0F;
|
||||
|
||||
inb(0x3E6);
|
||||
inb(0x3E6);
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
From d98908a17ece4ec33e477158112adc527c365b83 Mon Sep 17 00:00:00 2001
|
||||
From: Clemens Ladisch <clemens@ladisch.de>
|
||||
Date: Mon, 12 Mar 2012 21:45:47 +0100
|
||||
Subject: [PATCH 082/147] firewire: ohci: fix too-early completion of IR
|
||||
multichannel buffers
|
||||
|
||||
commit 0c0efbacab8d70700d13301e0ae7975783c0cb0a upstream.
|
||||
|
||||
handle_ir_buffer_fill() assumed that a completed descriptor would be
|
||||
indicated by a non-zero transfer_status (as in most other descriptors).
|
||||
However, this field is written by the controller as soon as (the end of)
|
||||
the first packet has been written into the buffer. As a consequence, if
|
||||
we happen to run into such a descriptor when the interrupt handler is
|
||||
executed after such a packet has completed, the descriptor would be
|
||||
taken out of the list of active descriptors as soon as the buffer had
|
||||
been partially filled, so the event for the buffer being completely
|
||||
filled would never be sent.
|
||||
|
||||
To fix this, handle descriptors only when they have been completely
|
||||
filled, i.e., when res_count == 0. (This also matches the condition
|
||||
that is reported by the controller with an interrupt.)
|
||||
|
||||
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
|
||||
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/firewire/ohci.c | 5 ++---
|
||||
1 file changed, 2 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
|
||||
index 7f5f0da..0a0225a 100644
|
||||
--- a/drivers/firewire/ohci.c
|
||||
+++ b/drivers/firewire/ohci.c
|
||||
@@ -2748,7 +2748,7 @@ static int handle_ir_buffer_fill(struct context *context,
|
||||
container_of(context, struct iso_context, context);
|
||||
u32 buffer_dma;
|
||||
|
||||
- if (!last->transfer_status)
|
||||
+ if (last->res_count != 0)
|
||||
/* Descriptor(s) not done yet, stop iteration */
|
||||
return 0;
|
||||
|
||||
@@ -2762,8 +2762,7 @@ static int handle_ir_buffer_fill(struct context *context,
|
||||
if (le16_to_cpu(last->control) & DESCRIPTOR_IRQ_ALWAYS)
|
||||
ctx->base.callback.mc(&ctx->base,
|
||||
le32_to_cpu(last->data_address) +
|
||||
- le16_to_cpu(last->req_count) -
|
||||
- le16_to_cpu(last->res_count),
|
||||
+ le16_to_cpu(last->req_count),
|
||||
ctx->base.callback_data);
|
||||
|
||||
return 1;
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
From d76b5f6c352194eaec8afbe8397b43f1ee4130d0 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Stephan=20B=C3=A4rwolf?= <stephan.baerwolf@tu-ilmenau.de>
|
||||
Date: Thu, 12 Jan 2012 16:43:03 +0100
|
||||
Subject: [PATCH 083/147] KVM: x86: extend "struct x86_emulate_ops" with
|
||||
"get_cpuid"
|
||||
|
||||
commit bdb42f5afebe208eae90406959383856ae2caf2b upstream.
|
||||
|
||||
In order to be able to proceed checks on CPU-specific properties
|
||||
within the emulator, function "get_cpuid" is introduced.
|
||||
With "get_cpuid" it is possible to virtually call the guests
|
||||
"cpuid"-opcode without changing the VM's context.
|
||||
|
||||
[mtosatti: cleanup/beautify code]
|
||||
|
||||
Signed-off-by: Stephan Baerwolf <stephan.baerwolf@tu-ilmenau.de>
|
||||
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
|
||||
Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
arch/x86/include/asm/kvm_emulate.h | 3 +++
|
||||
arch/x86/kvm/x86.c | 23 +++++++++++++++++++++++
|
||||
2 files changed, 26 insertions(+)
|
||||
|
||||
diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
|
||||
index a026507..a440a7f 100644
|
||||
--- a/arch/x86/include/asm/kvm_emulate.h
|
||||
+++ b/arch/x86/include/asm/kvm_emulate.h
|
||||
@@ -189,6 +189,9 @@ struct x86_emulate_ops {
|
||||
int (*intercept)(struct x86_emulate_ctxt *ctxt,
|
||||
struct x86_instruction_info *info,
|
||||
enum x86_intercept_stage stage);
|
||||
+
|
||||
+ bool (*get_cpuid)(struct x86_emulate_ctxt *ctxt,
|
||||
+ u32 *eax, u32 *ebx, u32 *ecx, u32 *edx);
|
||||
};
|
||||
|
||||
typedef u32 __attribute__((vector_size(16))) sse128_t;
|
||||
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
|
||||
index 4c938da..e04cae1 100644
|
||||
--- a/arch/x86/kvm/x86.c
|
||||
+++ b/arch/x86/kvm/x86.c
|
||||
@@ -4655,6 +4655,28 @@ static int emulator_intercept(struct x86_emulate_ctxt *ctxt,
|
||||
return kvm_x86_ops->check_intercept(emul_to_vcpu(ctxt), info, stage);
|
||||
}
|
||||
|
||||
+static bool emulator_get_cpuid(struct x86_emulate_ctxt *ctxt,
|
||||
+ u32 *eax, u32 *ebx, u32 *ecx, u32 *edx)
|
||||
+{
|
||||
+ struct kvm_cpuid_entry2 *cpuid = NULL;
|
||||
+
|
||||
+ if (eax && ecx)
|
||||
+ cpuid = kvm_find_cpuid_entry(emul_to_vcpu(ctxt),
|
||||
+ *eax, *ecx);
|
||||
+
|
||||
+ if (cpuid) {
|
||||
+ *eax = cpuid->eax;
|
||||
+ *ecx = cpuid->ecx;
|
||||
+ if (ebx)
|
||||
+ *ebx = cpuid->ebx;
|
||||
+ if (edx)
|
||||
+ *edx = cpuid->edx;
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
static struct x86_emulate_ops emulate_ops = {
|
||||
.read_std = kvm_read_guest_virt_system,
|
||||
.write_std = kvm_write_guest_virt_system,
|
||||
@@ -4685,6 +4707,7 @@ static struct x86_emulate_ops emulate_ops = {
|
||||
.get_fpu = emulator_get_fpu,
|
||||
.put_fpu = emulator_put_fpu,
|
||||
.intercept = emulator_intercept,
|
||||
+ .get_cpuid = emulator_get_cpuid,
|
||||
};
|
||||
|
||||
static void cache_all_regs(struct kvm_vcpu *vcpu)
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
From 9dab57c31c4146a8d1118a8c833fb8a3e788fec6 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Stephan=20B=C3=A4rwolf?= <stephan.baerwolf@tu-ilmenau.de>
|
||||
Date: Thu, 12 Jan 2012 16:43:04 +0100
|
||||
Subject: [PATCH 084/147] KVM: x86: fix missing checks in syscall emulation
|
||||
|
||||
commit c2226fc9e87ba3da060e47333657cd6616652b84 upstream.
|
||||
|
||||
On hosts without this patch, 32bit guests will crash (and 64bit guests
|
||||
may behave in a wrong way) for example by simply executing following
|
||||
nasm-demo-application:
|
||||
|
||||
[bits 32]
|
||||
global _start
|
||||
SECTION .text
|
||||
_start: syscall
|
||||
|
||||
(I tested it with winxp and linux - both always crashed)
|
||||
|
||||
Disassembly of section .text:
|
||||
|
||||
00000000 <_start>:
|
||||
0: 0f 05 syscall
|
||||
|
||||
The reason seems a missing "invalid opcode"-trap (int6) for the
|
||||
syscall opcode "0f05", which is not available on Intel CPUs
|
||||
within non-longmodes, as also on some AMD CPUs within legacy-mode.
|
||||
(depending on CPU vendor, MSR_EFER and cpuid)
|
||||
|
||||
Because previous mentioned OSs may not engage corresponding
|
||||
syscall target-registers (STAR, LSTAR, CSTAR), they remain
|
||||
NULL and (non trapping) syscalls are leading to multiple
|
||||
faults and finally crashs.
|
||||
|
||||
Depending on the architecture (AMD or Intel) pretended by
|
||||
guests, various checks according to vendor's documentation
|
||||
are implemented to overcome the current issue and behave
|
||||
like the CPUs physical counterparts.
|
||||
|
||||
[mtosatti: cleanup/beautify code]
|
||||
|
||||
Signed-off-by: Stephan Baerwolf <stephan.baerwolf@tu-ilmenau.de>
|
||||
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
|
||||
Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
arch/x86/include/asm/kvm_emulate.h | 13 +++++++++
|
||||
arch/x86/kvm/emulate.c | 51 ++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 64 insertions(+)
|
||||
|
||||
diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
|
||||
index a440a7f..70ea6fd 100644
|
||||
--- a/arch/x86/include/asm/kvm_emulate.h
|
||||
+++ b/arch/x86/include/asm/kvm_emulate.h
|
||||
@@ -300,6 +300,19 @@ struct x86_emulate_ctxt {
|
||||
#define X86EMUL_MODE_PROT (X86EMUL_MODE_PROT16|X86EMUL_MODE_PROT32| \
|
||||
X86EMUL_MODE_PROT64)
|
||||
|
||||
+/* CPUID vendors */
|
||||
+#define X86EMUL_CPUID_VENDOR_AuthenticAMD_ebx 0x68747541
|
||||
+#define X86EMUL_CPUID_VENDOR_AuthenticAMD_ecx 0x444d4163
|
||||
+#define X86EMUL_CPUID_VENDOR_AuthenticAMD_edx 0x69746e65
|
||||
+
|
||||
+#define X86EMUL_CPUID_VENDOR_AMDisbetterI_ebx 0x69444d41
|
||||
+#define X86EMUL_CPUID_VENDOR_AMDisbetterI_ecx 0x21726574
|
||||
+#define X86EMUL_CPUID_VENDOR_AMDisbetterI_edx 0x74656273
|
||||
+
|
||||
+#define X86EMUL_CPUID_VENDOR_GenuineIntel_ebx 0x756e6547
|
||||
+#define X86EMUL_CPUID_VENDOR_GenuineIntel_ecx 0x6c65746e
|
||||
+#define X86EMUL_CPUID_VENDOR_GenuineIntel_edx 0x49656e69
|
||||
+
|
||||
enum x86_intercept_stage {
|
||||
X86_ICTP_NONE = 0, /* Allow zero-init to not match anything */
|
||||
X86_ICPT_PRE_EXCEPT,
|
||||
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
|
||||
index f1e3be18..f5302da 100644
|
||||
--- a/arch/x86/kvm/emulate.c
|
||||
+++ b/arch/x86/kvm/emulate.c
|
||||
@@ -1877,6 +1877,51 @@ setup_syscalls_segments(struct x86_emulate_ctxt *ctxt,
|
||||
ss->p = 1;
|
||||
}
|
||||
|
||||
+static bool em_syscall_is_enabled(struct x86_emulate_ctxt *ctxt)
|
||||
+{
|
||||
+ struct x86_emulate_ops *ops = ctxt->ops;
|
||||
+ u32 eax, ebx, ecx, edx;
|
||||
+
|
||||
+ /*
|
||||
+ * syscall should always be enabled in longmode - so only become
|
||||
+ * vendor specific (cpuid) if other modes are active...
|
||||
+ */
|
||||
+ if (ctxt->mode == X86EMUL_MODE_PROT64)
|
||||
+ return true;
|
||||
+
|
||||
+ eax = 0x00000000;
|
||||
+ ecx = 0x00000000;
|
||||
+ if (ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx)) {
|
||||
+ /*
|
||||
+ * Intel ("GenuineIntel")
|
||||
+ * remark: Intel CPUs only support "syscall" in 64bit
|
||||
+ * longmode. Also an 64bit guest with a
|
||||
+ * 32bit compat-app running will #UD !! While this
|
||||
+ * behaviour can be fixed (by emulating) into AMD
|
||||
+ * response - CPUs of AMD can't behave like Intel.
|
||||
+ */
|
||||
+ if (ebx == X86EMUL_CPUID_VENDOR_GenuineIntel_ebx &&
|
||||
+ ecx == X86EMUL_CPUID_VENDOR_GenuineIntel_ecx &&
|
||||
+ edx == X86EMUL_CPUID_VENDOR_GenuineIntel_edx)
|
||||
+ return false;
|
||||
+
|
||||
+ /* AMD ("AuthenticAMD") */
|
||||
+ if (ebx == X86EMUL_CPUID_VENDOR_AuthenticAMD_ebx &&
|
||||
+ ecx == X86EMUL_CPUID_VENDOR_AuthenticAMD_ecx &&
|
||||
+ edx == X86EMUL_CPUID_VENDOR_AuthenticAMD_edx)
|
||||
+ return true;
|
||||
+
|
||||
+ /* AMD ("AMDisbetter!") */
|
||||
+ if (ebx == X86EMUL_CPUID_VENDOR_AMDisbetterI_ebx &&
|
||||
+ ecx == X86EMUL_CPUID_VENDOR_AMDisbetterI_ecx &&
|
||||
+ edx == X86EMUL_CPUID_VENDOR_AMDisbetterI_edx)
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ /* default: (not Intel, not AMD), apply Intel's stricter rules... */
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
static int em_syscall(struct x86_emulate_ctxt *ctxt)
|
||||
{
|
||||
struct x86_emulate_ops *ops = ctxt->ops;
|
||||
@@ -1890,9 +1935,15 @@ static int em_syscall(struct x86_emulate_ctxt *ctxt)
|
||||
ctxt->mode == X86EMUL_MODE_VM86)
|
||||
return emulate_ud(ctxt);
|
||||
|
||||
+ if (!(em_syscall_is_enabled(ctxt)))
|
||||
+ return emulate_ud(ctxt);
|
||||
+
|
||||
ops->get_msr(ctxt, MSR_EFER, &efer);
|
||||
setup_syscalls_segments(ctxt, &cs, &ss);
|
||||
|
||||
+ if (!(efer & EFER_SCE))
|
||||
+ return emulate_ud(ctxt);
|
||||
+
|
||||
ops->get_msr(ctxt, MSR_STAR, &msr_data);
|
||||
msr_data >>= 32;
|
||||
cs_sel = (u16)(msr_data & 0xfffc);
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,193 @@
|
||||
From 3876d640cb4c4f09bdc26a8befea1df94fd4e71e Mon Sep 17 00:00:00 2001
|
||||
From: Trond Myklebust <Trond.Myklebust@netapp.com>
|
||||
Date: Mon, 5 Mar 2012 19:56:44 -0500
|
||||
Subject: [PATCH 085/147] NFS: Properly handle the case where the delegation
|
||||
is revoked
|
||||
|
||||
commit a1d0b5eebc4fd6e0edb02688b35f17f67f42aea5 upstream.
|
||||
|
||||
If we know that the delegation stateid is bad or revoked, we need to
|
||||
remove that delegation as soon as possible, and then mark all the
|
||||
stateids that relied on that delegation for recovery. We cannot use
|
||||
the delegation as part of the recovery process.
|
||||
|
||||
Also note that NFSv4.1 uses a different error code (NFS4ERR_DELEG_REVOKED)
|
||||
to indicate that the delegation was revoked.
|
||||
|
||||
Finally, ensure that setlk() and setattr() can both recover safely from
|
||||
a revoked delegation.
|
||||
|
||||
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
fs/nfs/delegation.c | 11 +++++++++++
|
||||
fs/nfs/delegation.h | 1 +
|
||||
fs/nfs/nfs4_fs.h | 2 ++
|
||||
fs/nfs/nfs4proc.c | 18 ++++++++++++++++--
|
||||
fs/nfs/nfs4state.c | 29 +++++++++++++++++++++++++++--
|
||||
5 files changed, 57 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
|
||||
index 7f26540..ac889af 100644
|
||||
--- a/fs/nfs/delegation.c
|
||||
+++ b/fs/nfs/delegation.c
|
||||
@@ -466,6 +466,17 @@ static void nfs_delegation_run_state_manager(struct nfs_client *clp)
|
||||
nfs4_schedule_state_manager(clp);
|
||||
}
|
||||
|
||||
+void nfs_remove_bad_delegation(struct inode *inode)
|
||||
+{
|
||||
+ struct nfs_delegation *delegation;
|
||||
+
|
||||
+ delegation = nfs_detach_delegation(NFS_I(inode), NFS_SERVER(inode));
|
||||
+ if (delegation) {
|
||||
+ nfs_inode_find_state_and_recover(inode, &delegation->stateid);
|
||||
+ nfs_free_delegation(delegation);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* nfs_expire_all_delegation_types
|
||||
* @clp: client to process
|
||||
diff --git a/fs/nfs/delegation.h b/fs/nfs/delegation.h
|
||||
index d9322e4..691a796 100644
|
||||
--- a/fs/nfs/delegation.h
|
||||
+++ b/fs/nfs/delegation.h
|
||||
@@ -45,6 +45,7 @@ void nfs_expire_unreferenced_delegations(struct nfs_client *clp);
|
||||
void nfs_handle_cb_pathdown(struct nfs_client *clp);
|
||||
int nfs_client_return_marked_delegations(struct nfs_client *clp);
|
||||
int nfs_delegations_present(struct nfs_client *clp);
|
||||
+void nfs_remove_bad_delegation(struct inode *inode);
|
||||
|
||||
void nfs_delegation_mark_reclaim(struct nfs_client *clp);
|
||||
void nfs_delegation_reap_unclaimed(struct nfs_client *clp);
|
||||
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
|
||||
index 693ae22..d6ba137f 100644
|
||||
--- a/fs/nfs/nfs4_fs.h
|
||||
+++ b/fs/nfs/nfs4_fs.h
|
||||
@@ -324,6 +324,8 @@ extern void nfs4_put_open_state(struct nfs4_state *);
|
||||
extern void nfs4_close_state(struct nfs4_state *, fmode_t);
|
||||
extern void nfs4_close_sync(struct nfs4_state *, fmode_t);
|
||||
extern void nfs4_state_set_mode_locked(struct nfs4_state *, fmode_t);
|
||||
+extern void nfs_inode_find_state_and_recover(struct inode *inode,
|
||||
+ const nfs4_stateid *stateid);
|
||||
extern void nfs4_schedule_lease_recovery(struct nfs_client *);
|
||||
extern void nfs4_schedule_state_manager(struct nfs_client *);
|
||||
extern void nfs4_schedule_path_down_recovery(struct nfs_client *clp);
|
||||
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
|
||||
index e527030..a51e1dd 100644
|
||||
--- a/fs/nfs/nfs4proc.c
|
||||
+++ b/fs/nfs/nfs4proc.c
|
||||
@@ -263,8 +263,11 @@ static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struc
|
||||
switch(errorcode) {
|
||||
case 0:
|
||||
return 0;
|
||||
+ case -NFS4ERR_DELEG_REVOKED:
|
||||
case -NFS4ERR_ADMIN_REVOKED:
|
||||
case -NFS4ERR_BAD_STATEID:
|
||||
+ if (state != NULL)
|
||||
+ nfs_remove_bad_delegation(state->inode);
|
||||
case -NFS4ERR_OPENMODE:
|
||||
if (state == NULL)
|
||||
break;
|
||||
@@ -1316,8 +1319,11 @@ int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state
|
||||
* The show must go on: exit, but mark the
|
||||
* stateid as needing recovery.
|
||||
*/
|
||||
+ case -NFS4ERR_DELEG_REVOKED:
|
||||
case -NFS4ERR_ADMIN_REVOKED:
|
||||
case -NFS4ERR_BAD_STATEID:
|
||||
+ nfs_inode_find_state_and_recover(state->inode,
|
||||
+ stateid);
|
||||
nfs4_schedule_stateid_recovery(server, state);
|
||||
case -EKEYEXPIRED:
|
||||
/*
|
||||
@@ -1893,7 +1899,9 @@ static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
|
||||
struct nfs4_state *state)
|
||||
{
|
||||
struct nfs_server *server = NFS_SERVER(inode);
|
||||
- struct nfs4_exception exception = { };
|
||||
+ struct nfs4_exception exception = {
|
||||
+ .state = state,
|
||||
+ };
|
||||
int err;
|
||||
do {
|
||||
err = nfs4_handle_exception(server,
|
||||
@@ -3707,8 +3715,11 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
|
||||
if (task->tk_status >= 0)
|
||||
return 0;
|
||||
switch(task->tk_status) {
|
||||
+ case -NFS4ERR_DELEG_REVOKED:
|
||||
case -NFS4ERR_ADMIN_REVOKED:
|
||||
case -NFS4ERR_BAD_STATEID:
|
||||
+ if (state != NULL)
|
||||
+ nfs_remove_bad_delegation(state->inode);
|
||||
case -NFS4ERR_OPENMODE:
|
||||
if (state == NULL)
|
||||
break;
|
||||
@@ -4526,7 +4537,9 @@ out:
|
||||
|
||||
static int nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request)
|
||||
{
|
||||
- struct nfs4_exception exception = { };
|
||||
+ struct nfs4_exception exception = {
|
||||
+ .state = state,
|
||||
+ };
|
||||
int err;
|
||||
|
||||
do {
|
||||
@@ -4619,6 +4632,7 @@ int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
|
||||
* The show must go on: exit, but mark the
|
||||
* stateid as needing recovery.
|
||||
*/
|
||||
+ case -NFS4ERR_DELEG_REVOKED:
|
||||
case -NFS4ERR_ADMIN_REVOKED:
|
||||
case -NFS4ERR_BAD_STATEID:
|
||||
case -NFS4ERR_OPENMODE:
|
||||
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
|
||||
index a58eed7..0596fd6 100644
|
||||
--- a/fs/nfs/nfs4state.c
|
||||
+++ b/fs/nfs/nfs4state.c
|
||||
@@ -1071,12 +1071,37 @@ void nfs4_schedule_stateid_recovery(const struct nfs_server *server, struct nfs4
|
||||
{
|
||||
struct nfs_client *clp = server->nfs_client;
|
||||
|
||||
- if (test_and_clear_bit(NFS_DELEGATED_STATE, &state->flags))
|
||||
- nfs_async_inode_return_delegation(state->inode, &state->stateid);
|
||||
nfs4_state_mark_reclaim_nograce(clp, state);
|
||||
nfs4_schedule_state_manager(clp);
|
||||
}
|
||||
|
||||
+void nfs_inode_find_state_and_recover(struct inode *inode,
|
||||
+ const nfs4_stateid *stateid)
|
||||
+{
|
||||
+ struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
|
||||
+ struct nfs_inode *nfsi = NFS_I(inode);
|
||||
+ struct nfs_open_context *ctx;
|
||||
+ struct nfs4_state *state;
|
||||
+ bool found = false;
|
||||
+
|
||||
+ spin_lock(&inode->i_lock);
|
||||
+ list_for_each_entry(ctx, &nfsi->open_files, list) {
|
||||
+ state = ctx->state;
|
||||
+ if (state == NULL)
|
||||
+ continue;
|
||||
+ if (!test_bit(NFS_DELEGATED_STATE, &state->flags))
|
||||
+ continue;
|
||||
+ if (memcmp(state->stateid.data, stateid->data, sizeof(state->stateid.data)) != 0)
|
||||
+ continue;
|
||||
+ nfs4_state_mark_reclaim_nograce(clp, state);
|
||||
+ found = true;
|
||||
+ }
|
||||
+ spin_unlock(&inode->i_lock);
|
||||
+ if (found)
|
||||
+ nfs4_schedule_state_manager(clp);
|
||||
+}
|
||||
+
|
||||
+
|
||||
static int nfs4_reclaim_locks(struct nfs4_state *state, const struct nfs4_state_recovery_ops *ops)
|
||||
{
|
||||
struct inode *inode = state->inode;
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
From f56543c626d44b8ca33f2d37ee4758d1faab0e74 Mon Sep 17 00:00:00 2001
|
||||
From: Trond Myklebust <Trond.Myklebust@netapp.com>
|
||||
Date: Wed, 7 Mar 2012 16:39:06 -0500
|
||||
Subject: [PATCH 086/147] NFSv4: Return the delegation if the server returns
|
||||
NFS4ERR_OPENMODE
|
||||
|
||||
commit 3114ea7a24d3264c090556a2444fc6d2c06176d4 upstream.
|
||||
|
||||
If a setattr() fails because of an NFS4ERR_OPENMODE error, it is
|
||||
probably due to us holding a read delegation. Ensure that the
|
||||
recovery routines return that delegation in this case.
|
||||
|
||||
Reported-by: Miklos Szeredi <miklos@szeredi.hu>
|
||||
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
fs/nfs/nfs4_fs.h | 1 +
|
||||
fs/nfs/nfs4proc.c | 13 ++++++++++++-
|
||||
2 files changed, 13 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
|
||||
index d6ba137f..0983b25 100644
|
||||
--- a/fs/nfs/nfs4_fs.h
|
||||
+++ b/fs/nfs/nfs4_fs.h
|
||||
@@ -191,6 +191,7 @@ struct nfs4_exception {
|
||||
long timeout;
|
||||
int retry;
|
||||
struct nfs4_state *state;
|
||||
+ struct inode *inode;
|
||||
};
|
||||
|
||||
struct nfs4_state_recovery_ops {
|
||||
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
|
||||
index a51e1dd..758e809 100644
|
||||
--- a/fs/nfs/nfs4proc.c
|
||||
+++ b/fs/nfs/nfs4proc.c
|
||||
@@ -257,18 +257,28 @@ static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struc
|
||||
{
|
||||
struct nfs_client *clp = server->nfs_client;
|
||||
struct nfs4_state *state = exception->state;
|
||||
+ struct inode *inode = exception->inode;
|
||||
int ret = errorcode;
|
||||
|
||||
exception->retry = 0;
|
||||
switch(errorcode) {
|
||||
case 0:
|
||||
return 0;
|
||||
+ case -NFS4ERR_OPENMODE:
|
||||
+ if (nfs_have_delegation(inode, FMODE_READ)) {
|
||||
+ nfs_inode_return_delegation(inode);
|
||||
+ exception->retry = 1;
|
||||
+ return 0;
|
||||
+ }
|
||||
+ if (state == NULL)
|
||||
+ break;
|
||||
+ nfs4_schedule_stateid_recovery(server, state);
|
||||
+ goto wait_on_recovery;
|
||||
case -NFS4ERR_DELEG_REVOKED:
|
||||
case -NFS4ERR_ADMIN_REVOKED:
|
||||
case -NFS4ERR_BAD_STATEID:
|
||||
if (state != NULL)
|
||||
nfs_remove_bad_delegation(state->inode);
|
||||
- case -NFS4ERR_OPENMODE:
|
||||
if (state == NULL)
|
||||
break;
|
||||
nfs4_schedule_stateid_recovery(server, state);
|
||||
@@ -1901,6 +1911,7 @@ static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
|
||||
struct nfs_server *server = NFS_SERVER(inode);
|
||||
struct nfs4_exception exception = {
|
||||
.state = state,
|
||||
+ .inode = inode,
|
||||
};
|
||||
int err;
|
||||
do {
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
From e5d6f5ef25f0e67126092de0837e7c8f2ecfbc86 Mon Sep 17 00:00:00 2001
|
||||
From: Dave Chinner <dchinner@redhat.com>
|
||||
Date: Wed, 7 Mar 2012 04:50:25 +0000
|
||||
Subject: [PATCH 087/147] xfs: fix inode lookup race
|
||||
|
||||
commit f30d500f809eca67a21704347ab14bb35877b5ee upstream.
|
||||
|
||||
When we get concurrent lookups of the same inode that is not in the
|
||||
per-AG inode cache, there is a race condition that triggers warnings
|
||||
in unlock_new_inode() indicating that we are initialising an inode
|
||||
that isn't in a the correct state for a new inode.
|
||||
|
||||
When we do an inode lookup via a file handle or a bulkstat, we don't
|
||||
serialise lookups at a higher level through the dentry cache (i.e.
|
||||
pathless lookup), and so we can get concurrent lookups of the same
|
||||
inode.
|
||||
|
||||
The race condition is between the insertion of the inode into the
|
||||
cache in the case of a cache miss and a concurrently lookup:
|
||||
|
||||
Thread 1 Thread 2
|
||||
xfs_iget()
|
||||
xfs_iget_cache_miss()
|
||||
xfs_iread()
|
||||
lock radix tree
|
||||
radix_tree_insert()
|
||||
rcu_read_lock
|
||||
radix_tree_lookup
|
||||
lock inode flags
|
||||
XFS_INEW not set
|
||||
igrab()
|
||||
unlock inode flags
|
||||
rcu_read_unlock
|
||||
use uninitialised inode
|
||||
.....
|
||||
lock inode flags
|
||||
set XFS_INEW
|
||||
unlock inode flags
|
||||
unlock radix tree
|
||||
xfs_setup_inode()
|
||||
inode flags = I_NEW
|
||||
unlock_new_inode()
|
||||
WARNING as inode flags != I_NEW
|
||||
|
||||
This can lead to inode corruption, inode list corruption, etc, and
|
||||
is generally a bad thing to occur.
|
||||
|
||||
Fix this by setting XFS_INEW before inserting the inode into the
|
||||
radix tree. This will ensure any concurrent lookup will find the new
|
||||
inode with XFS_INEW set and that forces the lookup to wait until the
|
||||
XFS_INEW flag is removed before allowing the lookup to succeed.
|
||||
|
||||
Signed-off-by: Dave Chinner <dchinner@redhat.com>
|
||||
Reviewed-by: Christoph Hellwig <hch@lst.de>
|
||||
Signed-off-by: Ben Myers <bpm@sgi.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
fs/xfs/xfs_iget.c | 18 ++++++++++++------
|
||||
1 file changed, 12 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c
|
||||
index 0fa98b1..cfc4277 100644
|
||||
--- a/fs/xfs/xfs_iget.c
|
||||
+++ b/fs/xfs/xfs_iget.c
|
||||
@@ -353,9 +353,20 @@ xfs_iget_cache_miss(
|
||||
BUG();
|
||||
}
|
||||
|
||||
- spin_lock(&pag->pag_ici_lock);
|
||||
+ /*
|
||||
+ * These values must be set before inserting the inode into the radix
|
||||
+ * tree as the moment it is inserted a concurrent lookup (allowed by the
|
||||
+ * RCU locking mechanism) can find it and that lookup must see that this
|
||||
+ * is an inode currently under construction (i.e. that XFS_INEW is set).
|
||||
+ * The ip->i_flags_lock that protects the XFS_INEW flag forms the
|
||||
+ * memory barrier that ensures this detection works correctly at lookup
|
||||
+ * time.
|
||||
+ */
|
||||
+ ip->i_udquot = ip->i_gdquot = NULL;
|
||||
+ xfs_iflags_set(ip, XFS_INEW);
|
||||
|
||||
/* insert the new inode */
|
||||
+ spin_lock(&pag->pag_ici_lock);
|
||||
error = radix_tree_insert(&pag->pag_ici_root, agino, ip);
|
||||
if (unlikely(error)) {
|
||||
WARN_ON(error != -EEXIST);
|
||||
@@ -363,11 +374,6 @@ xfs_iget_cache_miss(
|
||||
error = EAGAIN;
|
||||
goto out_preload_end;
|
||||
}
|
||||
-
|
||||
- /* These values _must_ be set before releasing the radix tree lock! */
|
||||
- ip->i_udquot = ip->i_gdquot = NULL;
|
||||
- xfs_iflags_set(ip, XFS_INEW);
|
||||
-
|
||||
spin_unlock(&pag->pag_ici_lock);
|
||||
radix_tree_preload_end();
|
||||
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,212 @@
|
||||
From 8ceb94d9185c4640cf49d48a06ddfb9ef94ec16d Mon Sep 17 00:00:00 2001
|
||||
From: Pavel Shilovsky <piastry@etersoft.ru>
|
||||
Date: Tue, 20 Mar 2012 12:55:09 +0300
|
||||
Subject: [PATCH 088/147] CIFS: Respect negotiated MaxMpxCount
|
||||
|
||||
commit 10b9b98e41ba248a899f6175ce96ee91431b6194 upstream.
|
||||
|
||||
Some servers sets this value less than 50 that was hardcoded and
|
||||
we lost the connection if when we exceed this limit. Fix this by
|
||||
respecting this value - not sending more than the server allows.
|
||||
|
||||
Reviewed-by: Jeff Layton <jlayton@samba.org>
|
||||
Signed-off-by: Pavel Shilovsky <piastry@etersoft.ru>
|
||||
Signed-off-by: Steve French <sfrench@us.ibm.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
fs/cifs/cifsfs.c | 8 ++++----
|
||||
fs/cifs/cifsglob.h | 10 +++-------
|
||||
fs/cifs/cifssmb.c | 9 +++++++--
|
||||
fs/cifs/connect.c | 11 ++++-------
|
||||
fs/cifs/dir.c | 6 ++++--
|
||||
fs/cifs/file.c | 4 ++--
|
||||
fs/cifs/transport.c | 4 ++--
|
||||
7 files changed, 26 insertions(+), 26 deletions(-)
|
||||
|
||||
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
|
||||
index 8f1fe32..b4c2c99 100644
|
||||
--- a/fs/cifs/cifsfs.c
|
||||
+++ b/fs/cifs/cifsfs.c
|
||||
@@ -76,7 +76,7 @@ MODULE_PARM_DESC(cifs_min_small, "Small network buffers in pool. Default: 30 "
|
||||
unsigned int cifs_max_pending = CIFS_MAX_REQ;
|
||||
module_param(cifs_max_pending, int, 0444);
|
||||
MODULE_PARM_DESC(cifs_max_pending, "Simultaneous requests to server. "
|
||||
- "Default: 50 Range: 2 to 256");
|
||||
+ "Default: 32767 Range: 2 to 32767.");
|
||||
unsigned short echo_retries = 5;
|
||||
module_param(echo_retries, ushort, 0644);
|
||||
MODULE_PARM_DESC(echo_retries, "Number of echo attempts before giving up and "
|
||||
@@ -1116,9 +1116,9 @@ init_cifs(void)
|
||||
if (cifs_max_pending < 2) {
|
||||
cifs_max_pending = 2;
|
||||
cFYI(1, "cifs_max_pending set to min of 2");
|
||||
- } else if (cifs_max_pending > 256) {
|
||||
- cifs_max_pending = 256;
|
||||
- cFYI(1, "cifs_max_pending set to max of 256");
|
||||
+ } else if (cifs_max_pending > CIFS_MAX_REQ) {
|
||||
+ cifs_max_pending = CIFS_MAX_REQ;
|
||||
+ cFYI(1, "cifs_max_pending set to max of %u", CIFS_MAX_REQ);
|
||||
}
|
||||
|
||||
rc = cifs_fscache_register();
|
||||
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
|
||||
index 8238aa1..c467ac8 100644
|
||||
--- a/fs/cifs/cifsglob.h
|
||||
+++ b/fs/cifs/cifsglob.h
|
||||
@@ -55,14 +55,9 @@
|
||||
|
||||
/*
|
||||
* MAX_REQ is the maximum number of requests that WE will send
|
||||
- * on one socket concurrently. It also matches the most common
|
||||
- * value of max multiplex returned by servers. We may
|
||||
- * eventually want to use the negotiated value (in case
|
||||
- * future servers can handle more) when we are more confident that
|
||||
- * we will not have problems oveloading the socket with pending
|
||||
- * write data.
|
||||
+ * on one socket concurrently.
|
||||
*/
|
||||
-#define CIFS_MAX_REQ 50
|
||||
+#define CIFS_MAX_REQ 32767
|
||||
|
||||
#define RFC1001_NAME_LEN 15
|
||||
#define RFC1001_NAME_LEN_WITH_NULL (RFC1001_NAME_LEN + 1)
|
||||
@@ -263,6 +258,7 @@ struct TCP_Server_Info {
|
||||
bool session_estab; /* mark when very first sess is established */
|
||||
u16 dialect; /* dialect index that server chose */
|
||||
enum securityEnum secType;
|
||||
+ bool oplocks:1; /* enable oplocks */
|
||||
unsigned int maxReq; /* Clients should submit no more */
|
||||
/* than maxReq distinct unanswered SMBs to the server when using */
|
||||
/* multiplexed reads or writes */
|
||||
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
|
||||
index 6600aa2..0e6adac 100644
|
||||
--- a/fs/cifs/cifssmb.c
|
||||
+++ b/fs/cifs/cifssmb.c
|
||||
@@ -458,7 +458,10 @@ CIFSSMBNegotiate(unsigned int xid, struct cifs_ses *ses)
|
||||
goto neg_err_exit;
|
||||
}
|
||||
server->sec_mode = (__u8)le16_to_cpu(rsp->SecurityMode);
|
||||
- server->maxReq = le16_to_cpu(rsp->MaxMpxCount);
|
||||
+ server->maxReq = min_t(unsigned int,
|
||||
+ le16_to_cpu(rsp->MaxMpxCount),
|
||||
+ cifs_max_pending);
|
||||
+ server->oplocks = server->maxReq > 1 ? enable_oplocks : false;
|
||||
server->maxBuf = le16_to_cpu(rsp->MaxBufSize);
|
||||
server->max_vcs = le16_to_cpu(rsp->MaxNumberVcs);
|
||||
/* even though we do not use raw we might as well set this
|
||||
@@ -564,7 +567,9 @@ CIFSSMBNegotiate(unsigned int xid, struct cifs_ses *ses)
|
||||
|
||||
/* one byte, so no need to convert this or EncryptionKeyLen from
|
||||
little endian */
|
||||
- server->maxReq = le16_to_cpu(pSMBr->MaxMpxCount);
|
||||
+ server->maxReq = min_t(unsigned int, le16_to_cpu(pSMBr->MaxMpxCount),
|
||||
+ cifs_max_pending);
|
||||
+ server->oplocks = server->maxReq > 1 ? enable_oplocks : false;
|
||||
/* probably no need to store and check maxvcs */
|
||||
server->maxBuf = le32_to_cpu(pSMBr->MaxBufferSize);
|
||||
server->max_rw = le32_to_cpu(pSMBr->MaxRawSize);
|
||||
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
|
||||
index 720edf5..a26b98f 100644
|
||||
--- a/fs/cifs/connect.c
|
||||
+++ b/fs/cifs/connect.c
|
||||
@@ -625,14 +625,10 @@ static void clean_demultiplex_info(struct TCP_Server_Info *server)
|
||||
spin_unlock(&GlobalMid_Lock);
|
||||
wake_up_all(&server->response_q);
|
||||
|
||||
- /*
|
||||
- * Check if we have blocked requests that need to free. Note that
|
||||
- * cifs_max_pending is normally 50, but can be set at module install
|
||||
- * time to as little as two.
|
||||
- */
|
||||
+ /* Check if we have blocked requests that need to free. */
|
||||
spin_lock(&GlobalMid_Lock);
|
||||
- if (atomic_read(&server->inFlight) >= cifs_max_pending)
|
||||
- atomic_set(&server->inFlight, cifs_max_pending - 1);
|
||||
+ if (atomic_read(&server->inFlight) >= server->maxReq)
|
||||
+ atomic_set(&server->inFlight, server->maxReq - 1);
|
||||
/*
|
||||
* We do not want to set the max_pending too low or we could end up
|
||||
* with the counter going negative.
|
||||
@@ -1890,6 +1886,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
|
||||
tcp_ses->noautotune = volume_info->noautotune;
|
||||
tcp_ses->tcp_nodelay = volume_info->sockopt_tcp_nodelay;
|
||||
atomic_set(&tcp_ses->inFlight, 0);
|
||||
+ tcp_ses->maxReq = 1; /* enough to send negotiate request */
|
||||
init_waitqueue_head(&tcp_ses->response_q);
|
||||
init_waitqueue_head(&tcp_ses->request_q);
|
||||
INIT_LIST_HEAD(&tcp_ses->pending_mid_q);
|
||||
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
|
||||
index bf68b4f..6937e7c 100644
|
||||
--- a/fs/cifs/dir.c
|
||||
+++ b/fs/cifs/dir.c
|
||||
@@ -171,7 +171,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
|
||||
}
|
||||
tcon = tlink_tcon(tlink);
|
||||
|
||||
- if (enable_oplocks)
|
||||
+ if (tcon->ses->server->oplocks)
|
||||
oplock = REQ_OPLOCK;
|
||||
|
||||
if (nd)
|
||||
@@ -492,7 +492,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
|
||||
{
|
||||
int xid;
|
||||
int rc = 0; /* to get around spurious gcc warning, set to zero here */
|
||||
- __u32 oplock = enable_oplocks ? REQ_OPLOCK : 0;
|
||||
+ __u32 oplock;
|
||||
__u16 fileHandle = 0;
|
||||
bool posix_open = false;
|
||||
struct cifs_sb_info *cifs_sb;
|
||||
@@ -518,6 +518,8 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
|
||||
}
|
||||
pTcon = tlink_tcon(tlink);
|
||||
|
||||
+ oplock = pTcon->ses->server->oplocks ? REQ_OPLOCK : 0;
|
||||
+
|
||||
/*
|
||||
* Don't allow the separator character in a path component.
|
||||
* The VFS will not allow "/", but "\" is allowed by posix.
|
||||
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
|
||||
index 5e64748..4aa6080 100644
|
||||
--- a/fs/cifs/file.c
|
||||
+++ b/fs/cifs/file.c
|
||||
@@ -380,7 +380,7 @@ int cifs_open(struct inode *inode, struct file *file)
|
||||
cFYI(1, "inode = 0x%p file flags are 0x%x for %s",
|
||||
inode, file->f_flags, full_path);
|
||||
|
||||
- if (enable_oplocks)
|
||||
+ if (tcon->ses->server->oplocks)
|
||||
oplock = REQ_OPLOCK;
|
||||
else
|
||||
oplock = 0;
|
||||
@@ -505,7 +505,7 @@ static int cifs_reopen_file(struct cifsFileInfo *pCifsFile, bool can_flush)
|
||||
cFYI(1, "inode = 0x%p file flags 0x%x for %s",
|
||||
inode, pCifsFile->f_flags, full_path);
|
||||
|
||||
- if (enable_oplocks)
|
||||
+ if (tcon->ses->server->oplocks)
|
||||
oplock = REQ_OPLOCK;
|
||||
else
|
||||
oplock = 0;
|
||||
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
|
||||
index 0cc9584..99a27cf 100644
|
||||
--- a/fs/cifs/transport.c
|
||||
+++ b/fs/cifs/transport.c
|
||||
@@ -265,12 +265,12 @@ static int wait_for_free_request(struct TCP_Server_Info *server,
|
||||
|
||||
spin_lock(&GlobalMid_Lock);
|
||||
while (1) {
|
||||
- if (atomic_read(&server->inFlight) >= cifs_max_pending) {
|
||||
+ if (atomic_read(&server->inFlight) >= server->maxReq) {
|
||||
spin_unlock(&GlobalMid_Lock);
|
||||
cifs_num_waiters_inc(server);
|
||||
wait_event(server->request_q,
|
||||
atomic_read(&server->inFlight)
|
||||
- < cifs_max_pending);
|
||||
+ < server->maxReq);
|
||||
cifs_num_waiters_dec(server);
|
||||
spin_lock(&GlobalMid_Lock);
|
||||
} else {
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
From bf2a3ba7a460d3f1904077d790028269f468d7c1 Mon Sep 17 00:00:00 2001
|
||||
From: Jeff Layton <jlayton@redhat.com>
|
||||
Date: Wed, 21 Mar 2012 06:30:40 -0400
|
||||
Subject: [PATCH 089/147] cifs: fix issue mounting of DFS ROOT when
|
||||
redirecting from one domain controller to the next
|
||||
|
||||
commit 1daaae8fa4afe3df78ca34e724ed7e8187e4eb32 upstream.
|
||||
|
||||
This patch fixes an issue when cifs_mount receives a
|
||||
STATUS_BAD_NETWORK_NAME error during cifs_get_tcon but is able to
|
||||
continue after an DFS ROOT referral. In this case, the return code
|
||||
variable is not reset prior to trying to mount from the system referred
|
||||
to. Thus, is_path_accessible is not executed and the final DFS referral
|
||||
is not performed causing a mount error.
|
||||
|
||||
Use case: In DNS, example.com resolves to the secondary AD server
|
||||
ad2.example.com Our primary domain controller is ad1.example.com and has
|
||||
a DFS redirection set up from \\ad1\share\Users to \\files\share\Users.
|
||||
Mounting \\example.com\share\Users fails.
|
||||
|
||||
Regression introduced by commit 724d9f1.
|
||||
|
||||
Reviewed-by: Pavel Shilovsky <piastry@etersoft.ru
|
||||
Signed-off-by: Thomas Hadig <thomas@intapp.com>
|
||||
Signed-off-by: Jeff Layton <jlayton@redhat.com>
|
||||
Signed-off-by: Steve French <sfrench@us.ibm.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
fs/cifs/connect.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
|
||||
index a26b98f..9e0675a 100644
|
||||
--- a/fs/cifs/connect.c
|
||||
+++ b/fs/cifs/connect.c
|
||||
@@ -3217,7 +3217,7 @@ cifs_ra_pages(struct cifs_sb_info *cifs_sb)
|
||||
int
|
||||
cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info)
|
||||
{
|
||||
- int rc = 0;
|
||||
+ int rc;
|
||||
int xid;
|
||||
struct cifs_ses *pSesInfo;
|
||||
struct cifs_tcon *tcon;
|
||||
@@ -3244,6 +3244,7 @@ try_mount_again:
|
||||
FreeXid(xid);
|
||||
}
|
||||
#endif
|
||||
+ rc = 0;
|
||||
tcon = NULL;
|
||||
pSesInfo = NULL;
|
||||
srvTcp = NULL;
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
From 456290dcbf936c8883bf84492b7c3f04e73efa1a Mon Sep 17 00:00:00 2001
|
||||
From: Pavel Shilovsky <piastry@etersoft.ru>
|
||||
Date: Sat, 17 Mar 2012 09:46:55 +0300
|
||||
Subject: [PATCH 090/147] CIFS: Fix a spurious error in cifs_push_posix_locks
|
||||
|
||||
commit ce85852b90a214cf577fc1b4f49d99fd7e98784a upstream.
|
||||
|
||||
Signed-off-by: Pavel Shilovsky <piastry@etersoft.ru>
|
||||
Reviewed-by: Jeff Layton <jlayton@redhat.com>
|
||||
Reported-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
Signed-off-by: Steve French <sfrench@us.ibm.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
fs/cifs/file.c | 19 ++++++++++---------
|
||||
1 file changed, 10 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
|
||||
index 4aa6080..159fcc5 100644
|
||||
--- a/fs/cifs/file.c
|
||||
+++ b/fs/cifs/file.c
|
||||
@@ -960,9 +960,9 @@ cifs_push_posix_locks(struct cifsFileInfo *cfile)
|
||||
INIT_LIST_HEAD(&locks_to_send);
|
||||
|
||||
/*
|
||||
- * Allocating count locks is enough because no locks can be added to
|
||||
- * the list while we are holding cinode->lock_mutex that protects
|
||||
- * locking operations of this inode.
|
||||
+ * Allocating count locks is enough because no FL_POSIX locks can be
|
||||
+ * added to the list while we are holding cinode->lock_mutex that
|
||||
+ * protects locking operations of this inode.
|
||||
*/
|
||||
for (; i < count; i++) {
|
||||
lck = kmalloc(sizeof(struct lock_to_push), GFP_KERNEL);
|
||||
@@ -973,18 +973,20 @@ cifs_push_posix_locks(struct cifsFileInfo *cfile)
|
||||
list_add_tail(&lck->llist, &locks_to_send);
|
||||
}
|
||||
|
||||
- i = 0;
|
||||
el = locks_to_send.next;
|
||||
lock_flocks();
|
||||
cifs_for_each_lock(cfile->dentry->d_inode, before) {
|
||||
+ flock = *before;
|
||||
+ if ((flock->fl_flags & FL_POSIX) == 0)
|
||||
+ continue;
|
||||
if (el == &locks_to_send) {
|
||||
- /* something is really wrong */
|
||||
+ /*
|
||||
+ * The list ended. We don't have enough allocated
|
||||
+ * structures - something is really wrong.
|
||||
+ */
|
||||
cERROR(1, "Can't push all brlocks!");
|
||||
break;
|
||||
}
|
||||
- flock = *before;
|
||||
- if ((flock->fl_flags & FL_POSIX) == 0)
|
||||
- continue;
|
||||
length = 1 + flock->fl_end - flock->fl_start;
|
||||
if (flock->fl_type == F_RDLCK || flock->fl_type == F_SHLCK)
|
||||
type = CIFS_RDLCK;
|
||||
@@ -996,7 +998,6 @@ cifs_push_posix_locks(struct cifsFileInfo *cfile)
|
||||
lck->length = length;
|
||||
lck->type = type;
|
||||
lck->offset = flock->fl_start;
|
||||
- i++;
|
||||
el = el->next;
|
||||
}
|
||||
unlock_flocks();
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
From a3dcecf0adebe74332981c56c453556e3a4ebd5b Mon Sep 17 00:00:00 2001
|
||||
From: Richard Weinberger <richard@nod.at>
|
||||
Date: Mon, 30 Jan 2012 18:20:13 +0100
|
||||
Subject: [PATCH 091/147] UBI: fix error handling in ubi_scan()
|
||||
|
||||
commit a29852be492d61001d86c6ebf5fff9b93d7b4be9 upstream.
|
||||
|
||||
Two bad things can happen in ubi_scan():
|
||||
1. If kmem_cache_create() fails we jump to out_si and call
|
||||
ubi_scan_destroy_si() which calls kmem_cache_destroy().
|
||||
But si->scan_leb_slab is NULL.
|
||||
2. If process_eb() fails we jump to out_vidh, call
|
||||
kmem_cache_destroy() and ubi_scan_destroy_si() which calls
|
||||
again kmem_cache_destroy().
|
||||
|
||||
Signed-off-by: Richard Weinberger <richard@nod.at>
|
||||
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/mtd/ubi/scan.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c
|
||||
index 0cb17d9..b99318e 100644
|
||||
--- a/drivers/mtd/ubi/scan.c
|
||||
+++ b/drivers/mtd/ubi/scan.c
|
||||
@@ -1174,7 +1174,7 @@ struct ubi_scan_info *ubi_scan(struct ubi_device *ubi)
|
||||
|
||||
ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL);
|
||||
if (!ech)
|
||||
- goto out_slab;
|
||||
+ goto out_si;
|
||||
|
||||
vidh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL);
|
||||
if (!vidh)
|
||||
@@ -1235,8 +1235,6 @@ out_vidh:
|
||||
ubi_free_vid_hdr(ubi, vidh);
|
||||
out_ech:
|
||||
kfree(ech);
|
||||
-out_slab:
|
||||
- kmem_cache_destroy(si->scan_leb_slab);
|
||||
out_si:
|
||||
ubi_scan_destroy_si(si);
|
||||
return ERR_PTR(err);
|
||||
@@ -1325,7 +1323,9 @@ void ubi_scan_destroy_si(struct ubi_scan_info *si)
|
||||
}
|
||||
}
|
||||
|
||||
- kmem_cache_destroy(si->scan_leb_slab);
|
||||
+ if (si->scan_leb_slab)
|
||||
+ kmem_cache_destroy(si->scan_leb_slab);
|
||||
+
|
||||
kfree(si);
|
||||
}
|
||||
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
From 7abbe27ba63bb9559ea47b8449c4f0a50d98073e Mon Sep 17 00:00:00 2001
|
||||
From: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
|
||||
Date: Wed, 7 Mar 2012 19:08:36 +0200
|
||||
Subject: [PATCH 092/147] UBI: fix eraseblock picking criteria
|
||||
|
||||
commit 7eb3aa65853e1b223bfc786b023b702018cb76c0 upstream.
|
||||
|
||||
The 'find_wl_entry()' function expects the maximum difference as the second
|
||||
argument, not the maximum absolute value. So the "unknown" eraseblock picking
|
||||
was incorrect, as Shmulik Ladkani spotted. This patch fixes the issue.
|
||||
|
||||
Reported-by: Shmulik Ladkani <shmulik.ladkani@gmail.com>
|
||||
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
|
||||
Reviewed-by: Shmulik Ladkani <shmulik.ladkani@gmail.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/mtd/ubi/wl.c | 10 ++++------
|
||||
1 file changed, 4 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
|
||||
index 0696e36..cf42971 100644
|
||||
--- a/drivers/mtd/ubi/wl.c
|
||||
+++ b/drivers/mtd/ubi/wl.c
|
||||
@@ -389,7 +389,7 @@ static struct ubi_wl_entry *find_wl_entry(struct rb_root *root, int max)
|
||||
*/
|
||||
int ubi_wl_get_peb(struct ubi_device *ubi, int dtype)
|
||||
{
|
||||
- int err, medium_ec;
|
||||
+ int err;
|
||||
struct ubi_wl_entry *e, *first, *last;
|
||||
|
||||
ubi_assert(dtype == UBI_LONGTERM || dtype == UBI_SHORTTERM ||
|
||||
@@ -427,7 +427,7 @@ retry:
|
||||
* For unknown data we pick a physical eraseblock with medium
|
||||
* erase counter. But we by no means can pick a physical
|
||||
* eraseblock with erase counter greater or equivalent than the
|
||||
- * lowest erase counter plus %WL_FREE_MAX_DIFF.
|
||||
+ * lowest erase counter plus %WL_FREE_MAX_DIFF/2.
|
||||
*/
|
||||
first = rb_entry(rb_first(&ubi->free), struct ubi_wl_entry,
|
||||
u.rb);
|
||||
@@ -436,10 +436,8 @@ retry:
|
||||
if (last->ec - first->ec < WL_FREE_MAX_DIFF)
|
||||
e = rb_entry(ubi->free.rb_node,
|
||||
struct ubi_wl_entry, u.rb);
|
||||
- else {
|
||||
- medium_ec = (first->ec + WL_FREE_MAX_DIFF)/2;
|
||||
- e = find_wl_entry(&ubi->free, medium_ec);
|
||||
- }
|
||||
+ else
|
||||
+ e = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF/2);
|
||||
break;
|
||||
case UBI_SHORTTERM:
|
||||
/*
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
From cdc2a3f4e2494e413531264d3949ce6801123ad9 Mon Sep 17 00:00:00 2001
|
||||
From: Trond Myklebust <Trond.Myklebust@netapp.com>
|
||||
Date: Mon, 19 Mar 2012 13:39:35 -0400
|
||||
Subject: [PATCH 093/147] SUNRPC: We must not use list_for_each_entry_safe()
|
||||
in rpc_wake_up()
|
||||
|
||||
commit 540a0f7584169651f485e8ab67461fcb06934e38 upstream.
|
||||
|
||||
The problem is that for the case of priority queues, we
|
||||
have to assume that __rpc_remove_wait_queue_priority will move new
|
||||
elements from the tk_wait.links lists into the queue->tasks[] list.
|
||||
We therefore cannot use list_for_each_entry_safe() on queue->tasks[],
|
||||
since that will skip these new tasks that __rpc_remove_wait_queue_priority
|
||||
is adding.
|
||||
|
||||
Without this fix, rpc_wake_up and rpc_wake_up_status will both fail
|
||||
to wake up all functions on priority wait queues, which can result
|
||||
in some nasty hangs.
|
||||
|
||||
Reported-by: Andy Adamson <andros@netapp.com>
|
||||
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
net/sunrpc/sched.c | 15 +++++++++++----
|
||||
1 file changed, 11 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
|
||||
index 00a1a2a..4e2b3b4 100644
|
||||
--- a/net/sunrpc/sched.c
|
||||
+++ b/net/sunrpc/sched.c
|
||||
@@ -500,14 +500,18 @@ EXPORT_SYMBOL_GPL(rpc_wake_up_next);
|
||||
*/
|
||||
void rpc_wake_up(struct rpc_wait_queue *queue)
|
||||
{
|
||||
- struct rpc_task *task, *next;
|
||||
struct list_head *head;
|
||||
|
||||
spin_lock_bh(&queue->lock);
|
||||
head = &queue->tasks[queue->maxpriority];
|
||||
for (;;) {
|
||||
- list_for_each_entry_safe(task, next, head, u.tk_wait.list)
|
||||
+ while (!list_empty(head)) {
|
||||
+ struct rpc_task *task;
|
||||
+ task = list_first_entry(head,
|
||||
+ struct rpc_task,
|
||||
+ u.tk_wait.list);
|
||||
rpc_wake_up_task_queue_locked(queue, task);
|
||||
+ }
|
||||
if (head == &queue->tasks[0])
|
||||
break;
|
||||
head--;
|
||||
@@ -525,13 +529,16 @@ EXPORT_SYMBOL_GPL(rpc_wake_up);
|
||||
*/
|
||||
void rpc_wake_up_status(struct rpc_wait_queue *queue, int status)
|
||||
{
|
||||
- struct rpc_task *task, *next;
|
||||
struct list_head *head;
|
||||
|
||||
spin_lock_bh(&queue->lock);
|
||||
head = &queue->tasks[queue->maxpriority];
|
||||
for (;;) {
|
||||
- list_for_each_entry_safe(task, next, head, u.tk_wait.list) {
|
||||
+ while (!list_empty(head)) {
|
||||
+ struct rpc_task *task;
|
||||
+ task = list_first_entry(head,
|
||||
+ struct rpc_task,
|
||||
+ u.tk_wait.list);
|
||||
task->tk_status = status;
|
||||
rpc_wake_up_task_queue_locked(queue, task);
|
||||
}
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
From 25aa7a79e5be3c393eee41e3939d8eefa9672fc7 Mon Sep 17 00:00:00 2001
|
||||
From: "tom.leiming@gmail.com" <tom.leiming@gmail.com>
|
||||
Date: Thu, 22 Mar 2012 03:22:18 +0000
|
||||
Subject: [PATCH 094/147] usbnet: increase URB reference count before
|
||||
usb_unlink_urb
|
||||
|
||||
commit 0956a8c20b23d429e79ff86d4325583fc06f9eb4 upstream.
|
||||
|
||||
Commit 4231d47e6fe69f061f96c98c30eaf9fb4c14b96d(net/usbnet: avoid
|
||||
recursive locking in usbnet_stop()) fixes the recursive locking
|
||||
problem by releasing the skb queue lock, but it makes usb_unlink_urb
|
||||
racing with defer_bh, and the URB to being unlinked may be freed before
|
||||
or during calling usb_unlink_urb, so use-after-free problem may be
|
||||
triggerd inside usb_unlink_urb.
|
||||
|
||||
The patch fixes the use-after-free problem by increasing URB
|
||||
reference count with skb queue lock held before calling
|
||||
usb_unlink_urb, so the URB won't be freed until return from
|
||||
usb_unlink_urb.
|
||||
|
||||
Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
|
||||
Cc: Alan Stern <stern@rowland.harvard.edu>
|
||||
Cc: Oliver Neukum <oliver@neukum.org>
|
||||
Reported-by: Dave Jones <davej@redhat.com>
|
||||
Signed-off-by: Ming Lei <tom.leiming@gmail.com>
|
||||
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/net/usb/usbnet.c | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
|
||||
index 81b96e3..cf6a515 100644
|
||||
--- a/drivers/net/usb/usbnet.c
|
||||
+++ b/drivers/net/usb/usbnet.c
|
||||
@@ -589,6 +589,14 @@ static int unlink_urbs (struct usbnet *dev, struct sk_buff_head *q)
|
||||
entry = (struct skb_data *) skb->cb;
|
||||
urb = entry->urb;
|
||||
|
||||
+ /*
|
||||
+ * Get reference count of the URB to avoid it to be
|
||||
+ * freed during usb_unlink_urb, which may trigger
|
||||
+ * use-after-free problem inside usb_unlink_urb since
|
||||
+ * usb_unlink_urb is always racing with .complete
|
||||
+ * handler(include defer_bh).
|
||||
+ */
|
||||
+ usb_get_urb(urb);
|
||||
spin_unlock_irqrestore(&q->lock, flags);
|
||||
// during some PM-driven resume scenarios,
|
||||
// these (async) unlinks complete immediately
|
||||
@@ -597,6 +605,7 @@ static int unlink_urbs (struct usbnet *dev, struct sk_buff_head *q)
|
||||
netdev_dbg(dev->net, "unlink urb err, %d\n", retval);
|
||||
else
|
||||
count++;
|
||||
+ usb_put_urb(urb);
|
||||
spin_lock_irqsave(&q->lock, flags);
|
||||
}
|
||||
spin_unlock_irqrestore (&q->lock, flags);
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
From 31dcb2223cbb8ca92371811a9d59ed6f721e6d5d Mon Sep 17 00:00:00 2001
|
||||
From: "tom.leiming@gmail.com" <tom.leiming@gmail.com>
|
||||
Date: Thu, 22 Mar 2012 03:22:38 +0000
|
||||
Subject: [PATCH 095/147] usbnet: don't clear urb->dev in tx_complete
|
||||
|
||||
commit 5d5440a835710d09f0ef18da5000541ec98b537a upstream.
|
||||
|
||||
URB unlinking is always racing with its completion and tx_complete
|
||||
may be called before or during running usb_unlink_urb, so tx_complete
|
||||
must not clear urb->dev since it will be used in unlink path,
|
||||
otherwise invalid memory accesses or usb device leak may be caused
|
||||
inside usb_unlink_urb.
|
||||
|
||||
Cc: Alan Stern <stern@rowland.harvard.edu>
|
||||
Cc: Oliver Neukum <oliver@neukum.org>
|
||||
Signed-off-by: Ming Lei <tom.leiming@gmail.com>
|
||||
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/net/usb/usbnet.c | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
|
||||
index cf6a515..750e330 100644
|
||||
--- a/drivers/net/usb/usbnet.c
|
||||
+++ b/drivers/net/usb/usbnet.c
|
||||
@@ -1037,7 +1037,6 @@ static void tx_complete (struct urb *urb)
|
||||
}
|
||||
|
||||
usb_autopm_put_interface_async(dev->intf);
|
||||
- urb->dev = NULL;
|
||||
entry->state = tx_done;
|
||||
defer_bh(dev, skb, &dev->txq);
|
||||
}
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
From 4c14b8afd02d6923243bf2e2f14bd8ad750741d3 Mon Sep 17 00:00:00 2001
|
||||
From: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
|
||||
Date: Fri, 18 Nov 2011 14:25:00 +0000
|
||||
Subject: [PATCH 096/147] e1000e: Avoid wrong check on TX hang
|
||||
|
||||
commit 09357b00255c233705b1cf6d76a8d147340545b8 upstream.
|
||||
|
||||
Based on the original patch submitted my Michael Wang
|
||||
<wangyun@linux.vnet.ibm.com>.
|
||||
Descriptors may not be write-back while checking TX hang with flag
|
||||
FLAG2_DMA_BURST on.
|
||||
So when we detect hang, we just flush the descriptor and detect
|
||||
again for once.
|
||||
|
||||
-v2 change 1 to true and 0 to false and remove extra ()
|
||||
|
||||
CC: Michael Wang <wangyun@linux.vnet.ibm.com>
|
||||
CC: Flavio Leitner <fbl@redhat.com>
|
||||
Acked-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
|
||||
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
|
||||
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/net/ethernet/intel/e1000e/e1000.h | 1 +
|
||||
drivers/net/ethernet/intel/e1000e/netdev.c | 23 ++++++++++++++++++++---
|
||||
2 files changed, 21 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h
|
||||
index 9fe18d1..f478a22 100644
|
||||
--- a/drivers/net/ethernet/intel/e1000e/e1000.h
|
||||
+++ b/drivers/net/ethernet/intel/e1000e/e1000.h
|
||||
@@ -309,6 +309,7 @@ struct e1000_adapter {
|
||||
u32 txd_cmd;
|
||||
|
||||
bool detect_tx_hung;
|
||||
+ bool tx_hang_recheck;
|
||||
u8 tx_timeout_factor;
|
||||
|
||||
u32 tx_int_delay;
|
||||
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
|
||||
index a855db1..4e933d1 100644
|
||||
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
|
||||
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
|
||||
@@ -1030,6 +1030,7 @@ static void e1000_print_hw_hang(struct work_struct *work)
|
||||
struct e1000_adapter *adapter = container_of(work,
|
||||
struct e1000_adapter,
|
||||
print_hang_task);
|
||||
+ struct net_device *netdev = adapter->netdev;
|
||||
struct e1000_ring *tx_ring = adapter->tx_ring;
|
||||
unsigned int i = tx_ring->next_to_clean;
|
||||
unsigned int eop = tx_ring->buffer_info[i].next_to_watch;
|
||||
@@ -1041,6 +1042,21 @@ static void e1000_print_hw_hang(struct work_struct *work)
|
||||
if (test_bit(__E1000_DOWN, &adapter->state))
|
||||
return;
|
||||
|
||||
+ if (!adapter->tx_hang_recheck &&
|
||||
+ (adapter->flags2 & FLAG2_DMA_BURST)) {
|
||||
+ /* May be block on write-back, flush and detect again
|
||||
+ * flush pending descriptor writebacks to memory
|
||||
+ */
|
||||
+ ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD);
|
||||
+ /* execute the writes immediately */
|
||||
+ e1e_flush();
|
||||
+ adapter->tx_hang_recheck = true;
|
||||
+ return;
|
||||
+ }
|
||||
+ /* Real hang detected */
|
||||
+ adapter->tx_hang_recheck = false;
|
||||
+ netif_stop_queue(netdev);
|
||||
+
|
||||
e1e_rphy(hw, PHY_STATUS, &phy_status);
|
||||
e1e_rphy(hw, PHY_1000T_STATUS, &phy_1000t_status);
|
||||
e1e_rphy(hw, PHY_EXT_STATUS, &phy_ext_status);
|
||||
@@ -1154,10 +1170,10 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
|
||||
if (tx_ring->buffer_info[i].time_stamp &&
|
||||
time_after(jiffies, tx_ring->buffer_info[i].time_stamp
|
||||
+ (adapter->tx_timeout_factor * HZ)) &&
|
||||
- !(er32(STATUS) & E1000_STATUS_TXOFF)) {
|
||||
+ !(er32(STATUS) & E1000_STATUS_TXOFF))
|
||||
schedule_work(&adapter->print_hang_task);
|
||||
- netif_stop_queue(netdev);
|
||||
- }
|
||||
+ else
|
||||
+ adapter->tx_hang_recheck = false;
|
||||
}
|
||||
adapter->total_tx_bytes += total_tx_bytes;
|
||||
adapter->total_tx_packets += total_tx_packets;
|
||||
@@ -3782,6 +3798,7 @@ static int e1000_open(struct net_device *netdev)
|
||||
|
||||
e1000_irq_enable(adapter);
|
||||
|
||||
+ adapter->tx_hang_recheck = false;
|
||||
netif_start_queue(netdev);
|
||||
|
||||
adapter->idle_check = true;
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
From 37d297b39726f3284da2f83d235c94b0d224e047 Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Adamushko <dmitry.adamushko@gmail.com>
|
||||
Date: Thu, 22 Mar 2012 21:39:25 +0100
|
||||
Subject: [PATCH 097/147] x86-32: Fix endless loop when processing signals for
|
||||
kernel tasks
|
||||
|
||||
commit 29a2e2836ff9ea65a603c89df217f4198973a74f upstream.
|
||||
|
||||
The problem occurs on !CONFIG_VM86 kernels [1] when a kernel-mode task
|
||||
returns from a system call with a pending signal.
|
||||
|
||||
A real-life scenario is a child of 'khelper' returning from a failed
|
||||
kernel_execve() in ____call_usermodehelper() [ kernel/kmod.c ].
|
||||
kernel_execve() fails due to a pending SIGKILL, which is the result of
|
||||
"kill -9 -1" (at least, busybox's init does it upon reboot).
|
||||
|
||||
The loop is as follows:
|
||||
|
||||
* syscall_exit_work:
|
||||
- work_pending: // start_of_the_loop
|
||||
- work_notify_sig:
|
||||
- do_notify_resume()
|
||||
- do_signal()
|
||||
- if (!user_mode(regs)) return;
|
||||
- resume_userspace // TIF_SIGPENDING is still set
|
||||
- work_pending // so we call work_pending => goto
|
||||
// start_of_the_loop
|
||||
|
||||
More information can be found in another LKML thread:
|
||||
http://www.serverphorums.com/read.php?12,457826
|
||||
|
||||
[1] the problem was also seen on MIPS.
|
||||
|
||||
Signed-off-by: Dmitry Adamushko <dmitry.adamushko@gmail.com>
|
||||
Link: http://lkml.kernel.org/r/1332448765.2299.68.camel@dimm
|
||||
Cc: Oleg Nesterov <oleg@redhat.com>
|
||||
Cc: Roland McGrath <roland@hack.frob.com>
|
||||
Cc: Andrew Morton <akpm@linux-foundation.org>
|
||||
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
arch/x86/kernel/entry_32.S | 17 ++++++++++-------
|
||||
1 file changed, 10 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
|
||||
index f3f6f53..bcda816 100644
|
||||
--- a/arch/x86/kernel/entry_32.S
|
||||
+++ b/arch/x86/kernel/entry_32.S
|
||||
@@ -99,12 +99,6 @@
|
||||
#endif
|
||||
.endm
|
||||
|
||||
-#ifdef CONFIG_VM86
|
||||
-#define resume_userspace_sig check_userspace
|
||||
-#else
|
||||
-#define resume_userspace_sig resume_userspace
|
||||
-#endif
|
||||
-
|
||||
/*
|
||||
* User gs save/restore
|
||||
*
|
||||
@@ -328,10 +322,19 @@ ret_from_exception:
|
||||
preempt_stop(CLBR_ANY)
|
||||
ret_from_intr:
|
||||
GET_THREAD_INFO(%ebp)
|
||||
-check_userspace:
|
||||
+resume_userspace_sig:
|
||||
+#ifdef CONFIG_VM86
|
||||
movl PT_EFLAGS(%esp), %eax # mix EFLAGS and CS
|
||||
movb PT_CS(%esp), %al
|
||||
andl $(X86_EFLAGS_VM | SEGMENT_RPL_MASK), %eax
|
||||
+#else
|
||||
+ /*
|
||||
+ * We can be coming here from a syscall done in the kernel space,
|
||||
+ * e.g. a failed kernel_execve().
|
||||
+ */
|
||||
+ movl PT_CS(%esp), %eax
|
||||
+ andl $SEGMENT_RPL_MASK, %eax
|
||||
+#endif
|
||||
cmpl $USER_RPL, %eax
|
||||
jb resume_kernel # not returning to v8086 or userspace
|
||||
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
From 0b21a3eba2629ca8e573e5b0cd7d1627d17c7cf6 Mon Sep 17 00:00:00 2001
|
||||
From: Pravin B Shelar <pshelar@nicira.com>
|
||||
Date: Fri, 23 Mar 2012 15:02:55 -0700
|
||||
Subject: [PATCH 098/147] proc-ns: use d_set_d_op() API to set dentry ops in
|
||||
proc_ns_instantiate().
|
||||
|
||||
commit 1b26c9b334044cff6d1d2698f2be41bc7d9a0864 upstream.
|
||||
|
||||
The namespace cleanup path leaks a dentry which holds a reference count
|
||||
on a network namespace. Keeping that network namespace from being freed
|
||||
when the last user goes away. Leaving things like vlan devices in the
|
||||
leaked network namespace.
|
||||
|
||||
If you use ip netns add for much real work this problem becomes apparent
|
||||
pretty quickly. It light testing the problem hides because frequently
|
||||
you simply don't notice the leak.
|
||||
|
||||
Use d_set_d_op() so that DCACHE_OP_* flags are set correctly.
|
||||
|
||||
This issue exists back to 3.0.
|
||||
|
||||
Acked-by: "Eric W. Biederman" <ebiederm@xmission.com>
|
||||
Reported-by: Justin Pettit <jpettit@nicira.com>
|
||||
Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
|
||||
Signed-off-by: Jesse Gross <jesse@nicira.com>
|
||||
Cc: David Miller <davem@davemloft.net>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
fs/proc/namespaces.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/fs/proc/namespaces.c b/fs/proc/namespaces.c
|
||||
index be177f7..d6c078e 100644
|
||||
--- a/fs/proc/namespaces.c
|
||||
+++ b/fs/proc/namespaces.c
|
||||
@@ -54,7 +54,7 @@ static struct dentry *proc_ns_instantiate(struct inode *dir,
|
||||
ei->ns_ops = ns_ops;
|
||||
ei->ns = ns;
|
||||
|
||||
- dentry->d_op = &pid_dentry_operations;
|
||||
+ d_set_d_op(dentry, &pid_dentry_operations);
|
||||
d_add(dentry, inode);
|
||||
/* Close the race of the process dying before we return the dentry */
|
||||
if (pid_revalidate(dentry, NULL))
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
From fd9b78dce7a6acf7a69902d69c82980634cd7136 Mon Sep 17 00:00:00 2001
|
||||
From: Steffen Persvold <sp@numascale.com>
|
||||
Date: Thu, 15 Mar 2012 15:20:29 +0100
|
||||
Subject: [PATCH 099/147] iommu/amd: Fix section warning for
|
||||
prealloc_protection_domains
|
||||
|
||||
commit cebd5fa4d3046d5b43ce1836a0120612822a7fb0 upstream.
|
||||
|
||||
Fix the following section warning in drivers/iommu/amd_iommu.c :
|
||||
|
||||
WARNING: vmlinux.o(.text+0x526e77): Section mismatch in reference from the function prealloc_protection_domains() to the function .init.text:alloc_passthrough_domain()
|
||||
The function prealloc_protection_domains() references
|
||||
the function __init alloc_passthrough_domain().
|
||||
This is often because prealloc_protection_domains lacks a __init
|
||||
annotation or the annotation of alloc_passthrough_domain is wrong.
|
||||
|
||||
Signed-off-by: Steffen Persvold <sp@numascale.com>
|
||||
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/iommu/amd_iommu.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
|
||||
index e0b3e33..966a6e7 100644
|
||||
--- a/drivers/iommu/amd_iommu.c
|
||||
+++ b/drivers/iommu/amd_iommu.c
|
||||
@@ -2432,7 +2432,7 @@ static int amd_iommu_dma_supported(struct device *dev, u64 mask)
|
||||
* we don't need to preallocate the protection domains anymore.
|
||||
* For now we have to.
|
||||
*/
|
||||
-static void prealloc_protection_domains(void)
|
||||
+static void __init prealloc_protection_domains(void)
|
||||
{
|
||||
struct pci_dev *dev = NULL;
|
||||
struct dma_ops_domain *dma_dom;
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
From 55d8b2b2ea9545b29091216b9875c4e119215b63 Mon Sep 17 00:00:00 2001
|
||||
From: Lucas De Marchi <lucas.demarchi@profusion.mobi>
|
||||
Date: Thu, 22 Mar 2012 14:42:22 -0700
|
||||
Subject: [PATCH 100/147] sysctl: protect poll() in entries that may go away
|
||||
|
||||
commit 4e474a00d7ff746ed177ddae14fa8b2d4bad7a00 upstream.
|
||||
|
||||
Protect code accessing ctl_table by grabbing the header with grab_header()
|
||||
and after releasing with sysctl_head_finish(). This is needed if poll()
|
||||
is called in entries created by modules: currently only hostname and
|
||||
domainname support poll(), but this bug may be triggered when/if modules
|
||||
use it and if user called poll() in a file that doesn't support it.
|
||||
|
||||
Dave Jones reported the following when using a syscall fuzzer while
|
||||
hibernating/resuming:
|
||||
|
||||
RIP: 0010:[<ffffffff81233e3e>] [<ffffffff81233e3e>] proc_sys_poll+0x4e/0x90
|
||||
RAX: 0000000000000145 RBX: ffff88020cab6940 RCX: 0000000000000000
|
||||
RDX: ffffffff81233df0 RSI: 6b6b6b6b6b6b6b6b RDI: ffff88020cab6940
|
||||
[ ... ]
|
||||
Code: 00 48 89 fb 48 89 f1 48 8b 40 30 4c 8b 60 e8 b8 45 01 00 00 49 83
|
||||
7c 24 28 00 74 2e 49 8b 74 24 30 48 85 f6 74 24 48 85 c9 75 32 <8b> 16
|
||||
b8 45 01 00 00 48 63 d2 49 39 d5 74 10 8b 06 48 98 48 89
|
||||
|
||||
If an entry goes away while we are polling() it, ctl_table may not exist
|
||||
anymore.
|
||||
|
||||
Reported-by: Dave Jones <davej@redhat.com>
|
||||
Signed-off-by: Lucas De Marchi <lucas.demarchi@profusion.mobi>
|
||||
Cc: Al Viro <viro@zeniv.linux.org.uk>
|
||||
Cc: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Cc: Alexey Dobriyan <adobriyan@gmail.com>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
fs/proc/proc_sysctl.c | 17 ++++++++++++++++-
|
||||
1 file changed, 16 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c
|
||||
index a6b6217..53c3bce 100644
|
||||
--- a/fs/proc/proc_sysctl.c
|
||||
+++ b/fs/proc/proc_sysctl.c
|
||||
@@ -188,20 +188,32 @@ static ssize_t proc_sys_write(struct file *filp, const char __user *buf,
|
||||
|
||||
static int proc_sys_open(struct inode *inode, struct file *filp)
|
||||
{
|
||||
+ struct ctl_table_header *head = grab_header(inode);
|
||||
struct ctl_table *table = PROC_I(inode)->sysctl_entry;
|
||||
|
||||
+ /* sysctl was unregistered */
|
||||
+ if (IS_ERR(head))
|
||||
+ return PTR_ERR(head);
|
||||
+
|
||||
if (table->poll)
|
||||
filp->private_data = proc_sys_poll_event(table->poll);
|
||||
|
||||
+ sysctl_head_finish(head);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int proc_sys_poll(struct file *filp, poll_table *wait)
|
||||
{
|
||||
struct inode *inode = filp->f_path.dentry->d_inode;
|
||||
+ struct ctl_table_header *head = grab_header(inode);
|
||||
struct ctl_table *table = PROC_I(inode)->sysctl_entry;
|
||||
- unsigned long event = (unsigned long)filp->private_data;
|
||||
unsigned int ret = DEFAULT_POLLMASK;
|
||||
+ unsigned long event;
|
||||
+
|
||||
+ /* sysctl was unregistered */
|
||||
+ if (IS_ERR(head))
|
||||
+ return POLLERR | POLLHUP;
|
||||
|
||||
if (!table->proc_handler)
|
||||
goto out;
|
||||
@@ -209,6 +221,7 @@ static unsigned int proc_sys_poll(struct file *filp, poll_table *wait)
|
||||
if (!table->poll)
|
||||
goto out;
|
||||
|
||||
+ event = (unsigned long)filp->private_data;
|
||||
poll_wait(filp, &table->poll->wait, wait);
|
||||
|
||||
if (event != atomic_read(&table->poll->event)) {
|
||||
@@ -217,6 +230,8 @@ static unsigned int proc_sys_poll(struct file *filp, poll_table *wait)
|
||||
}
|
||||
|
||||
out:
|
||||
+ sysctl_head_finish(head);
|
||||
+
|
||||
return ret;
|
||||
}
|
||||
|
||||
--
|
||||
1.7.9.4
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user