1
0
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:
Koen Kooi
2012-04-09 18:06:40 +02:00
committed by Denys Dmytriyenko
parent f5135a2cb7
commit bb34e69f3d
149 changed files with 11111 additions and 2 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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(&current->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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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