--- /dev/null
+From 86f40622af7329375e38f282f6c0aab95f3e5f72 Mon Sep 17 00:00:00 2001
+From: Jianguo Wu <wujianguo@huawei.com>
+Date: Thu, 24 Apr 2014 03:45:56 +0100
+Subject: ARM: 8037/1: mm: support big-endian page tables
+
+From: Jianguo Wu <wujianguo@huawei.com>
+
+commit 86f40622af7329375e38f282f6c0aab95f3e5f72 upstream.
+
+When enable LPAE and big-endian in a hisilicon board, while specify
+mem=384M mem=512M@7680M, will get bad page state:
+
+Freeing unused kernel memory: 180K (c0466000 - c0493000)
+BUG: Bad page state in process init pfn:fa442
+page:c7749840 count:0 mapcount:-1 mapping: (null) index:0x0
+page flags: 0x40000400(reserved)
+Modules linked in:
+CPU: 0 PID: 1 Comm: init Not tainted 3.10.27+ #66
+[<c000f5f0>] (unwind_backtrace+0x0/0x11c) from [<c000cbc4>] (show_stack+0x10/0x14)
+[<c000cbc4>] (show_stack+0x10/0x14) from [<c009e448>] (bad_page+0xd4/0x104)
+[<c009e448>] (bad_page+0xd4/0x104) from [<c009e520>] (free_pages_prepare+0xa8/0x14c)
+[<c009e520>] (free_pages_prepare+0xa8/0x14c) from [<c009f8ec>] (free_hot_cold_page+0x18/0xf0)
+[<c009f8ec>] (free_hot_cold_page+0x18/0xf0) from [<c00b5444>] (handle_pte_fault+0xcf4/0xdc8)
+[<c00b5444>] (handle_pte_fault+0xcf4/0xdc8) from [<c00b6458>] (handle_mm_fault+0xf4/0x120)
+[<c00b6458>] (handle_mm_fault+0xf4/0x120) from [<c0013754>] (do_page_fault+0xfc/0x354)
+[<c0013754>] (do_page_fault+0xfc/0x354) from [<c0008400>] (do_DataAbort+0x2c/0x90)
+[<c0008400>] (do_DataAbort+0x2c/0x90) from [<c0008fb4>] (__dabt_usr+0x34/0x40)
+
+The bad pfn:fa442 is not system memory(mem=384M mem=512M@7680M), after debugging,
+I find in page fault handler, will get wrong pfn from pte just after set pte,
+as follow:
+do_anonymous_page()
+{
+ ...
+ set_pte_at(mm, address, page_table, entry);
+
+ //debug code
+ pfn = pte_pfn(entry);
+ pr_info("pfn:0x%lx, pte:0x%llxn", pfn, pte_val(entry));
+
+ //read out the pte just set
+ new_pte = pte_offset_map(pmd, address);
+ new_pfn = pte_pfn(*new_pte);
+ pr_info("new pfn:0x%lx, new pte:0x%llxn", pfn, pte_val(entry));
+ ...
+}
+
+pfn: 0x1fa4f5, pte:0xc00001fa4f575f
+new_pfn:0xfa4f5, new_pte:0xc00000fa4f5f5f //new pfn/pte is wrong.
+
+The bug is happened in cpu_v7_set_pte_ext(ptep, pte):
+An LPAE PTE is a 64bit quantity, passed to cpu_v7_set_pte_ext in the r2 and r3 registers.
+On an LE kernel, r2 contains the LSB of the PTE, and r3 the MSB.
+On a BE kernel, the assignment is reversed.
+
+Unfortunately, the current code always assumes the LE case,
+leading to corruption of the PTE when clearing/setting bits.
+
+This patch fixes this issue much like it has been done already in the
+cpu_v7_switch_mm case.
+
+Signed-off-by: Jianguo Wu <wujianguo@huawei.com>
+Acked-by: Marc Zyngier <marc.zyngier@arm.com>
+Acked-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm/mm/proc-v7-3level.S | 18 +++++++++++++-----
+ 1 file changed, 13 insertions(+), 5 deletions(-)
+
+--- a/arch/arm/mm/proc-v7-3level.S
++++ b/arch/arm/mm/proc-v7-3level.S
+@@ -56,6 +56,14 @@ ENTRY(cpu_v7_switch_mm)
+ mov pc, lr
+ ENDPROC(cpu_v7_switch_mm)
+
++#ifdef __ARMEB__
++#define rl r3
++#define rh r2
++#else
++#define rl r2
++#define rh r3
++#endif
++
+ /*
+ * cpu_v7_set_pte_ext(ptep, pte)
+ *
+@@ -65,13 +73,13 @@ ENDPROC(cpu_v7_switch_mm)
+ */
+ ENTRY(cpu_v7_set_pte_ext)
+ #ifdef CONFIG_MMU
+- tst r2, #L_PTE_VALID
++ tst rl, #L_PTE_VALID
+ beq 1f
+- tst r3, #1 << (57 - 32) @ L_PTE_NONE
+- bicne r2, #L_PTE_VALID
++ tst rh, #1 << (57 - 32) @ L_PTE_NONE
++ bicne rl, #L_PTE_VALID
+ bne 1f
+- tst r3, #1 << (55 - 32) @ L_PTE_DIRTY
+- orreq r2, #L_PTE_RDONLY
++ tst rh, #1 << (55 - 32) @ L_PTE_DIRTY
++ orreq rl, #L_PTE_RDONLY
+ 1: strd r2, r3, [r0]
+ ALT_SMP(W(nop))
+ ALT_UP (mcr p15, 0, r0, c7, c10, 1) @ flush_pte
--- /dev/null
+From 3683f44c42e991d313dc301504ee0fca1aeb8580 Mon Sep 17 00:00:00 2001
+From: Russell King <rmk+kernel@arm.linux.org.uk>
+Date: Sat, 3 May 2014 11:03:28 +0100
+Subject: ARM: stacktrace: avoid listing stacktrace functions in stacktrace
+
+From: Russell King <rmk+kernel@arm.linux.org.uk>
+
+commit 3683f44c42e991d313dc301504ee0fca1aeb8580 upstream.
+
+While debugging the FEC ethernet driver using stacktrace, it was noticed
+that the stacktraces always begin as follows:
+
+ [<c00117b4>] save_stack_trace_tsk+0x0/0x98
+ [<c0011870>] save_stack_trace+0x24/0x28
+ ...
+
+This is because the stack trace code includes the stack frames for itself.
+This is incorrect behaviour, and also leads to "skip" doing the wrong
+thing (which is the number of stack frames to avoid recording.)
+
+Perversely, it does the right thing when passed a non-current thread. Fix
+this by ensuring that we have a known constant number of frames above the
+main stack trace function, and always skip these.
+
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm/kernel/stacktrace.c | 18 +++++++++++++-----
+ 1 file changed, 13 insertions(+), 5 deletions(-)
+
+--- a/arch/arm/kernel/stacktrace.c
++++ b/arch/arm/kernel/stacktrace.c
+@@ -83,13 +83,16 @@ static int save_trace(struct stackframe
+ return trace->nr_entries >= trace->max_entries;
+ }
+
+-void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
++/* This must be noinline to so that our skip calculation works correctly */
++static noinline void __save_stack_trace(struct task_struct *tsk,
++ struct stack_trace *trace, unsigned int nosched)
+ {
+ struct stack_trace_data data;
+ struct stackframe frame;
+
+ data.trace = trace;
+ data.skip = trace->skip;
++ data.no_sched_functions = nosched;
+
+ if (tsk != current) {
+ #ifdef CONFIG_SMP
+@@ -102,7 +105,6 @@ void save_stack_trace_tsk(struct task_st
+ trace->entries[trace->nr_entries++] = ULONG_MAX;
+ return;
+ #else
+- data.no_sched_functions = 1;
+ frame.fp = thread_saved_fp(tsk);
+ frame.sp = thread_saved_sp(tsk);
+ frame.lr = 0; /* recovered from the stack */
+@@ -111,11 +113,12 @@ void save_stack_trace_tsk(struct task_st
+ } else {
+ register unsigned long current_sp asm ("sp");
+
+- data.no_sched_functions = 0;
++ /* We don't want this function nor the caller */
++ data.skip += 2;
+ frame.fp = (unsigned long)__builtin_frame_address(0);
+ frame.sp = current_sp;
+ frame.lr = (unsigned long)__builtin_return_address(0);
+- frame.pc = (unsigned long)save_stack_trace_tsk;
++ frame.pc = (unsigned long)__save_stack_trace;
+ }
+
+ walk_stackframe(&frame, save_trace, &data);
+@@ -123,9 +126,14 @@ void save_stack_trace_tsk(struct task_st
+ trace->entries[trace->nr_entries++] = ULONG_MAX;
+ }
+
++void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
++{
++ __save_stack_trace(tsk, trace, 1);
++}
++
+ void save_stack_trace(struct stack_trace *trace)
+ {
+- save_stack_trace_tsk(current, trace);
++ __save_stack_trace(current, trace, 0);
+ }
+ EXPORT_SYMBOL_GPL(save_stack_trace);
+ #endif
--- /dev/null
+From 8a96f3cd22878fc0bb564a8478a6e17c0b8dca73 Mon Sep 17 00:00:00 2001
+From: Jukka Taimisto <jtt@codenomicon.com>
+Date: Thu, 22 May 2014 10:02:39 +0000
+Subject: Bluetooth: Fix L2CAP deadlock
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jukka Taimisto <jtt@codenomicon.com>
+
+commit 8a96f3cd22878fc0bb564a8478a6e17c0b8dca73 upstream.
+
+-[0x01 Introduction
+
+We have found a programming error causing a deadlock in Bluetooth subsystem
+of Linux kernel. The problem is caused by missing release_sock() call when
+L2CAP connection creation fails due full accept queue.
+
+The issue can be reproduced with 3.15-rc5 kernel and is also present in
+earlier kernels.
+
+-[0x02 Details
+
+The problem occurs when multiple L2CAP connections are created to a PSM which
+contains listening socket (like SDP) and left pending, for example,
+configuration (the underlying ACL link is not disconnected between
+connections).
+
+When L2CAP connection request is received and listening socket is found the
+l2cap_sock_new_connection_cb() function (net/bluetooth/l2cap_sock.c) is called.
+This function locks the 'parent' socket and then checks if the accept queue
+is full.
+
+1178 lock_sock(parent);
+1179
+1180 /* Check for backlog size */
+1181 if (sk_acceptq_is_full(parent)) {
+1182 BT_DBG("backlog full %d", parent->sk_ack_backlog);
+1183 return NULL;
+1184 }
+
+If case the accept queue is full NULL is returned, but the 'parent' socket
+is not released. Thus when next L2CAP connection request is received the code
+blocks on lock_sock() since the parent is still locked.
+
+Also note that for connections already established and waiting for
+configuration to complete a timeout will occur and l2cap_chan_timeout()
+(net/bluetooth/l2cap_core.c) will be called. All threads calling this
+function will also be blocked waiting for the channel mutex since the thread
+which is waiting on lock_sock() alread holds the channel mutex.
+
+We were able to reproduce this by sending continuously L2CAP connection
+request followed by disconnection request containing invalid CID. This left
+the created connections pending configuration.
+
+After the deadlock occurs it is impossible to kill bluetoothd, btmon will not
+get any more data etc. requiring reboot to recover.
+
+-[0x03 Fix
+
+Releasing the 'parent' socket when l2cap_sock_new_connection_cb() returns NULL
+seems to fix the issue.
+
+Signed-off-by: Jukka Taimisto <jtt@codenomicon.com>
+Reported-by: Tommi Mäkilä <tmakila@codenomicon.com>
+Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/bluetooth/l2cap_sock.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/net/bluetooth/l2cap_sock.c
++++ b/net/bluetooth/l2cap_sock.c
+@@ -949,13 +949,16 @@ static struct l2cap_chan *l2cap_sock_new
+ /* Check for backlog size */
+ if (sk_acceptq_is_full(parent)) {
+ BT_DBG("backlog full %d", parent->sk_ack_backlog);
++ release_sock(parent);
+ return NULL;
+ }
+
+ sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP,
+ GFP_ATOMIC);
+- if (!sk)
++ if (!sk) {
++ release_sock(parent);
+ return NULL;
++ }
+
+ bt_sock_reclassify_lock(sk, BTPROTO_L2CAP);
+
--- /dev/null
+From da64c27d3c93ee9f89956b9de86c4127eb244494 Mon Sep 17 00:00:00 2001
+From: Felipe Balbi <balbi@ti.com>
+Date: Wed, 23 Apr 2014 09:58:26 -0500
+Subject: bluetooth: hci_ldisc: fix deadlock condition
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Felipe Balbi <balbi@ti.com>
+
+commit da64c27d3c93ee9f89956b9de86c4127eb244494 upstream.
+
+LDISCs shouldn't call tty->ops->write() from within
+->write_wakeup().
+
+->write_wakeup() is called with port lock taken and
+IRQs disabled, tty->ops->write() will try to acquire
+the same port lock and we will deadlock.
+
+Acked-by: Marcel Holtmann <marcel@holtmann.org>
+Reviewed-by: Peter Hurley <peter@hurleysoftware.com>
+Reported-by: Huang Shijie <b32955@freescale.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Tested-by: Andreas Bießmann <andreas@biessmann.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/bluetooth/hci_ldisc.c | 24 +++++++++++++++++++-----
+ drivers/bluetooth/hci_uart.h | 1 +
+ 2 files changed, 20 insertions(+), 5 deletions(-)
+
+--- a/drivers/bluetooth/hci_ldisc.c
++++ b/drivers/bluetooth/hci_ldisc.c
+@@ -118,10 +118,6 @@ static inline struct sk_buff *hci_uart_d
+
+ int hci_uart_tx_wakeup(struct hci_uart *hu)
+ {
+- struct tty_struct *tty = hu->tty;
+- struct hci_dev *hdev = hu->hdev;
+- struct sk_buff *skb;
+-
+ if (test_and_set_bit(HCI_UART_SENDING, &hu->tx_state)) {
+ set_bit(HCI_UART_TX_WAKEUP, &hu->tx_state);
+ return 0;
+@@ -129,6 +125,22 @@ int hci_uart_tx_wakeup(struct hci_uart *
+
+ BT_DBG("");
+
++ schedule_work(&hu->write_work);
++
++ return 0;
++}
++
++static void hci_uart_write_work(struct work_struct *work)
++{
++ struct hci_uart *hu = container_of(work, struct hci_uart, write_work);
++ struct tty_struct *tty = hu->tty;
++ struct hci_dev *hdev = hu->hdev;
++ struct sk_buff *skb;
++
++ /* REVISIT: should we cope with bad skbs or ->write() returning
++ * and error value ?
++ */
++
+ restart:
+ clear_bit(HCI_UART_TX_WAKEUP, &hu->tx_state);
+
+@@ -153,7 +165,6 @@ restart:
+ goto restart;
+
+ clear_bit(HCI_UART_SENDING, &hu->tx_state);
+- return 0;
+ }
+
+ static void hci_uart_init_work(struct work_struct *work)
+@@ -289,6 +300,7 @@ static int hci_uart_tty_open(struct tty_
+ tty->receive_room = 65536;
+
+ INIT_WORK(&hu->init_ready, hci_uart_init_work);
++ INIT_WORK(&hu->write_work, hci_uart_write_work);
+
+ spin_lock_init(&hu->rx_lock);
+
+@@ -326,6 +338,8 @@ static void hci_uart_tty_close(struct tt
+ if (hdev)
+ hci_uart_close(hdev);
+
++ cancel_work_sync(&hu->write_work);
++
+ if (test_and_clear_bit(HCI_UART_PROTO_SET, &hu->flags)) {
+ if (hdev) {
+ if (test_bit(HCI_UART_REGISTERED, &hu->flags))
+--- a/drivers/bluetooth/hci_uart.h
++++ b/drivers/bluetooth/hci_uart.h
+@@ -68,6 +68,7 @@ struct hci_uart {
+ unsigned long hdev_flags;
+
+ struct work_struct init_ready;
++ struct work_struct write_work;
+
+ struct hci_uart_proto *proto;
+ void *priv;
--- /dev/null
+From 3b35fc81e7ec552147a4fd843d0da0bbbe4ef253 Mon Sep 17 00:00:00 2001
+From: Olivier Langlois <olivier@trillion01.com>
+Date: Fri, 28 Mar 2014 02:42:38 -0300
+Subject: media: uvcvideo: Fix clock param realtime setting
+
+From: Olivier Langlois <olivier@trillion01.com>
+
+commit 3b35fc81e7ec552147a4fd843d0da0bbbe4ef253 upstream.
+
+timestamps in v4l2 buffers returned to userspace are updated in
+uvc_video_clock_update() which uses timestamps fetched from
+uvc_video_clock_decode() by calling unconditionally ktime_get_ts().
+
+Hence setting the module clock param to realtime has no effect before
+this patch.
+
+This has been tested with ffmpeg:
+
+ffmpeg -y -f v4l2 -input_format yuyv422 -video_size 640x480 -framerate 30 -i /dev/video0 \
+ -f alsa -acodec pcm_s16le -ar 16000 -ac 1 -i default \
+ -c:v libx264 -preset ultrafast \
+ -c:a libfdk_aac \
+ out.mkv
+
+and inspecting the v4l2 input starting timestamp.
+
+Signed-off-by: Olivier Langlois <olivier@trillion01.com>
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/media/usb/uvc/uvc_video.c | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+--- a/drivers/media/usb/uvc/uvc_video.c
++++ b/drivers/media/usb/uvc/uvc_video.c
+@@ -361,6 +361,14 @@ static int uvc_commit_video(struct uvc_s
+ * Clocks and timestamps
+ */
+
++static inline void uvc_video_get_ts(struct timespec *ts)
++{
++ if (uvc_clock_param == CLOCK_MONOTONIC)
++ ktime_get_ts(ts);
++ else
++ ktime_get_real_ts(ts);
++}
++
+ static void
+ uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf,
+ const __u8 *data, int len)
+@@ -420,7 +428,7 @@ uvc_video_clock_decode(struct uvc_stream
+ stream->clock.last_sof = dev_sof;
+
+ host_sof = usb_get_current_frame_number(stream->dev->udev);
+- ktime_get_ts(&ts);
++ uvc_video_get_ts(&ts);
+
+ /* The UVC specification allows device implementations that can't obtain
+ * the USB frame number to keep their own frame counters as long as they
+@@ -1010,10 +1018,7 @@ static int uvc_video_decode_start(struct
+ return -ENODATA;
+ }
+
+- if (uvc_clock_param == CLOCK_MONOTONIC)
+- ktime_get_ts(&ts);
+- else
+- ktime_get_real_ts(&ts);
++ uvc_video_get_ts(&ts);
+
+ buf->buf.v4l2_buf.sequence = stream->sequence;
+ buf->buf.v4l2_buf.timestamp.tv_sec = ts.tv_sec;
media-stk1160-avoid-stack-allocated-buffer-for-control-urbs.patch
acpica-utstring-check-array-index-bound-before-use.patch
acpi-fix-conflict-between-customized-dsdt-and-dsdt-local-copy.patch
+media-uvcvideo-fix-clock-param-realtime-setting.patch
+arm-stacktrace-avoid-listing-stacktrace-functions-in-stacktrace.patch
+arm-8037-1-mm-support-big-endian-page-tables.patch
+bluetooth-hci_ldisc-fix-deadlock-condition.patch
+bluetooth-fix-l2cap-deadlock.patch
+target-iser-bail-from-accept_np-if-np_thread-is-trying-to-close.patch
+target-iser-fix-hangs-in-connection-teardown.patch
--- /dev/null
+From e346ab343f4f58c12a96725c7b13df9cc2ad56f6 Mon Sep 17 00:00:00 2001
+From: Sagi Grimberg <sagig@mellanox.com>
+Date: Mon, 19 May 2014 17:44:22 +0300
+Subject: Target/iser: Bail from accept_np if np_thread is trying to close
+
+From: Sagi Grimberg <sagig@mellanox.com>
+
+commit e346ab343f4f58c12a96725c7b13df9cc2ad56f6 upstream.
+
+In case np_thread state is in RESET/SHUTDOWN/EXIT states,
+no point for isert to stall there as we may get a hang in
+case no one will wake it up later.
+
+Signed-off-by: Sagi Grimberg <sagig@mellanox.com>
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/infiniband/ulp/isert/ib_isert.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+--- a/drivers/infiniband/ulp/isert/ib_isert.c
++++ b/drivers/infiniband/ulp/isert/ib_isert.c
+@@ -2190,9 +2190,14 @@ accept_wait:
+ return -ENODEV;
+
+ spin_lock_bh(&np->np_thread_lock);
+- if (np->np_thread_state == ISCSI_NP_THREAD_RESET) {
++ if (np->np_thread_state >= ISCSI_NP_THREAD_RESET) {
+ spin_unlock_bh(&np->np_thread_lock);
+- pr_debug("ISCSI_NP_THREAD_RESET for isert_accept_np\n");
++ pr_debug("np_thread_state %d for isert_accept_np\n",
++ np->np_thread_state);
++ /**
++ * No point in stalling here when np_thread
++ * is in state RESET/SHUTDOWN/EXIT - bail
++ **/
+ return -ENODEV;
+ }
+ spin_unlock_bh(&np->np_thread_lock);
--- /dev/null
+From 9d49f5e284e700576f3b65f1e28dea8539da6661 Mon Sep 17 00:00:00 2001
+From: Sagi Grimberg <sagig@mellanox.com>
+Date: Mon, 19 May 2014 17:44:23 +0300
+Subject: Target/iser: Fix hangs in connection teardown
+
+From: Sagi Grimberg <sagig@mellanox.com>
+
+commit 9d49f5e284e700576f3b65f1e28dea8539da6661 upstream.
+
+In ungraceful teardowns isert close flows seem racy such that
+isert_wait_conn hangs as RDMA_CM_EVENT_DISCONNECTED never
+gets invoked (no one called rdma_disconnect).
+
+Both graceful and ungraceful teardowns will have rx flush errors
+(isert posts a batch once connection is established). Once all
+flush errors are consumed we invoke isert_wait_conn and it will
+be responsible for calling rdma_disconnect. This way it can be
+sure that rdma_disconnect was called and it won't wait forever.
+
+This patch also removes the logout_posted indicator. either the
+logout completion was consumed and no problem decrementing the
+post_send_buf_count, or it was consumed as a flush error. no point
+of keeping it for isert_wait_conn as there is no danger that
+isert_conn will be accidentally removed while it is running.
+
+(Drop unnecessary sleep_on_conn_wait_comp check in
+ isert_cq_rx_comp_err - nab)
+
+Signed-off-by: Sagi Grimberg <sagig@mellanox.com>
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/infiniband/ulp/isert/ib_isert.c | 31 ++++++++++---------------------
+ drivers/infiniband/ulp/isert/ib_isert.h | 1 -
+ 2 files changed, 10 insertions(+), 22 deletions(-)
+
+--- a/drivers/infiniband/ulp/isert/ib_isert.c
++++ b/drivers/infiniband/ulp/isert/ib_isert.c
+@@ -572,14 +572,10 @@ isert_disconnect_work(struct work_struct
+ isert_put_conn(isert_conn);
+ return;
+ }
+- if (!isert_conn->logout_posted) {
+- pr_debug("Calling rdma_disconnect for !logout_posted from"
+- " isert_disconnect_work\n");
+- rdma_disconnect(isert_conn->conn_cm_id);
+- mutex_unlock(&isert_conn->conn_mutex);
+- iscsit_cause_connection_reinstatement(isert_conn->conn, 0);
+- goto wake_up;
+- }
++
++ /* Send DREQ/DREP towards our initiator */
++ rdma_disconnect(isert_conn->conn_cm_id);
++
+ mutex_unlock(&isert_conn->conn_mutex);
+
+ wake_up:
+@@ -1371,11 +1367,8 @@ isert_do_control_comp(struct work_struct
+ break;
+ case ISTATE_SEND_LOGOUTRSP:
+ pr_debug("Calling iscsit_logout_post_handler >>>>>>>>>>>>>>\n");
+- /*
+- * Call atomic_dec(&isert_conn->post_send_buf_count)
+- * from isert_wait_conn()
+- */
+- isert_conn->logout_posted = true;
++
++ atomic_dec(&isert_conn->post_send_buf_count);
+ iscsit_logout_post_handler(cmd, cmd->conn);
+ break;
+ default:
+@@ -1483,6 +1476,8 @@ isert_cq_rx_comp_err(struct isert_conn *
+ isert_conn->state = ISER_CONN_DOWN;
+ mutex_unlock(&isert_conn->conn_mutex);
+
++ iscsit_cause_connection_reinstatement(isert_conn->conn, 0);
++
+ complete(&isert_conn->conn_wait_comp_err);
+ }
+
+@@ -2247,15 +2242,9 @@ static void isert_wait_conn(struct iscsi
+ struct isert_conn *isert_conn = conn->context;
+
+ pr_debug("isert_wait_conn: Starting \n");
+- /*
+- * Decrement post_send_buf_count for special case when called
+- * from isert_do_control_comp() -> iscsit_logout_post_handler()
+- */
+- mutex_lock(&isert_conn->conn_mutex);
+- if (isert_conn->logout_posted)
+- atomic_dec(&isert_conn->post_send_buf_count);
+
+- if (isert_conn->conn_cm_id && isert_conn->state != ISER_CONN_DOWN) {
++ mutex_lock(&isert_conn->conn_mutex);
++ if (isert_conn->conn_cm_id) {
+ pr_debug("Calling rdma_disconnect from isert_wait_conn\n");
+ rdma_disconnect(isert_conn->conn_cm_id);
+ }
+--- a/drivers/infiniband/ulp/isert/ib_isert.h
++++ b/drivers/infiniband/ulp/isert/ib_isert.h
+@@ -78,7 +78,6 @@ struct isert_device;
+
+ struct isert_conn {
+ enum iser_conn_state state;
+- bool logout_posted;
+ int post_recv_buf_count;
+ atomic_t post_send_buf_count;
+ u32 responder_resources;