diff --git a/src/libs/3rdparty/net7ssh/src/ne7ssh.cpp b/src/libs/3rdparty/net7ssh/src/ne7ssh.cpp
index 08fbe52a1be3537cdc70a6534eb7fa43249e1206..fee569089a397026a18b31ddb45a3aeb06beb638 100644
--- a/src/libs/3rdparty/net7ssh/src/ne7ssh.cpp
+++ b/src/libs/3rdparty/net7ssh/src/ne7ssh.cpp
@@ -293,13 +293,15 @@ void *ne7ssh::selectThread (void *initData)
   return 0;
 }
 
-int ne7ssh::connectWithPassword (const char *host, const int port, const char* username, const char* password, bool shell, const int timeout)
+int ne7ssh::connectWithPassword (const char *host, const int port,
+    const char* username, const char* password, bool shell, const int timeout,
+    void (*callbackFunc)(void *), void *callbackArg)
 {
   int channel;
   uint32 currentRecord, z;
   uint32 channelID;
 
-  ne7ssh_connection* con = new ne7ssh_connection ();
+  ne7ssh_connection* con = new ne7ssh_connection (callbackFunc, callbackArg);
 
   if (!lock()) return -1;
   if (!conCount) connections = (ne7ssh_connection**) malloc (sizeof (ne7ssh_connection*));
@@ -344,13 +346,15 @@ int ne7ssh::connectWithPassword (const char *host, const int port, const char* u
   return channel;
 }
 
-int ne7ssh::connectWithKey (const char* host, const int port, const char* username, const char* privKeyFileName, bool shell, const int timeout)
+int ne7ssh::connectWithKey (const char* host, const int port,
+    const char* username, const char* privKeyFileName, bool shell,
+    const int timeout, void (*callbackFunc)(void *), void *callbackArg)
 {
   int channel;
   uint32 currentRecord, z;
   uint32 channelID;
 
-  ne7ssh_connection* con = new ne7ssh_connection ();
+  ne7ssh_connection* con = new ne7ssh_connection (callbackFunc, callbackArg);
   if (!lock()) return -1;
   if (!conCount) connections = (ne7ssh_connection**) malloc (sizeof (ne7ssh_connection*) * (conCount + 1));
   else connections = (ne7ssh_connection**) realloc (connections, sizeof (ne7ssh_connection*) * (conCount + 1));
diff --git a/src/libs/3rdparty/net7ssh/src/ne7ssh.h b/src/libs/3rdparty/net7ssh/src/ne7ssh.h
index 853d8b08ffe5fca7dceda626138b3b5618ce570f..57cc281b90285ab309504c416d89e532ed71f70c 100644
--- a/src/libs/3rdparty/net7ssh/src/ne7ssh.h
+++ b/src/libs/3rdparty/net7ssh/src/ne7ssh.h
@@ -175,7 +175,9 @@ class SSH_EXPORT ne7ssh
      * @param timeout Timeout for the connection procedure, in seconds.
      * @return Returns newly assigned channel ID, or -1 if connection failed.
      */
-    int connectWithPassword (const char* host, const int port, const char* username, const char* password, bool shell = true, const int timeout = 0);
+    int connectWithPassword (const char* host, const int port, const char* username,
+        const char* password, bool shell = true, const int timeout = 0,
+        void (*callbackFunc)(void *) = 0, void *callbackArg = 0);
 
     /**
      * Connect to remote host using SSH2 protocol, with publickey authentication.
@@ -189,7 +191,9 @@ class SSH_EXPORT ne7ssh
      * @param timeout Timeout for the connection procedure, in seconds.
      * @return Returns newly assigned channel ID, or -1 if connection failed.
      */
-    int connectWithKey (const char* host, const int port, const char* username, const char* privKeyFileName, bool shell = true, const int timeout = 0);
+    int connectWithKey (const char* host, const int port, const char* username,
+        const char* privKeyFileName, bool shell = true, const int timeout = 0,
+        void (*callbackFunc)(void *) = 0, void *callbackArg = 0);
 
     /**
      * Retrieves a pointer to all current connections.
diff --git a/src/libs/3rdparty/net7ssh/src/ne7ssh_connection.cpp b/src/libs/3rdparty/net7ssh/src/ne7ssh_connection.cpp
index 569eaa44508a9c4dc3af49a194ef3115c423567f..7361dba4d80c183b98b309cdf372ed97e79edc41 100644
--- a/src/libs/3rdparty/net7ssh/src/ne7ssh_connection.cpp
+++ b/src/libs/3rdparty/net7ssh/src/ne7ssh_connection.cpp
@@ -20,7 +20,10 @@
 
 using namespace Botan;
 
-ne7ssh_connection::ne7ssh_connection() : sock (-1), thisChannel(0), sftp(0), connected(false), cmdRunning(false), cmdClosed(false)
+ne7ssh_connection::ne7ssh_connection(void (*callbackFunc)(void *),
+    void *callbackArg)
+    : sock (-1), thisChannel(0), sftp(0), connected(false), cmdRunning(false),
+      cmdClosed(false), callbackFunc(callbackFunc), callbackArg(callbackArg)
 {
   session = new ne7ssh_session();
   crypto = new ne7ssh_crypt(session);
@@ -285,6 +288,8 @@ bool ne7ssh_connection::sendLocalVersion ()
 void ne7ssh_connection::handleData ()
 {
   channel->receive();
+  if (callbackFunc && getReceived().size() > 0)
+      callbackFunc(callbackArg);
 }
 
 void ne7ssh_connection::sendData (const char* data)
diff --git a/src/libs/3rdparty/net7ssh/src/ne7ssh_connection.h b/src/libs/3rdparty/net7ssh/src/ne7ssh_connection.h
index a201c19262f564252f8bff415a876fdda0faa240..182b48294fcf4293b3594f6febf9ad7d653d9f0c 100644
--- a/src/libs/3rdparty/net7ssh/src/ne7ssh_connection.h
+++ b/src/libs/3rdparty/net7ssh/src/ne7ssh_connection.h
@@ -46,6 +46,8 @@ class ne7ssh_connection
     bool cmdRunning;
     bool cmdClosed;
 
+    void (*callbackFunc)(void *);
+    void *callbackArg;
 
     /**
      * Checks if remote side is returning a correctly formated SSH version string, and makes sure that version 2 of SSH protocol is supported by the remote side.
@@ -88,7 +90,7 @@ class ne7ssh_connection
     /**
      * ne7ssh_connection class constructor.
      */
-    ne7ssh_connection();
+    ne7ssh_connection(void (*callbackFunc)(void *) = 0, void *callbackArg = 0);
 
     /**
      * ne7ssh_connection class destructor.
diff --git a/src/plugins/coreplugin/ssh/sshconnection.cpp b/src/plugins/coreplugin/ssh/sshconnection.cpp
index 4b3f1741c2d7b9a97c3bfb611b7ecb43a6061e5b..4f5b54f2f3454f23d5fd024f4693d85842f2d9d1 100644
--- a/src/plugins/coreplugin/ssh/sshconnection.cpp
+++ b/src/plugins/coreplugin/ssh/sshconnection.cpp
@@ -46,7 +46,9 @@
 #include <QtCore/QCoreApplication>
 #include <QtCore/QDir>
 #include <QtCore/QFileInfo>
+#include <QtCore/QMutex>
 #include <QtCore/QThread>
+#include <QtCore/QWaitCondition>
 
 #include <ne7ssh.h>
 
@@ -71,14 +73,14 @@ public:
         quit();
     }
 
-    bool start(bool shell)
+    bool start(bool shell, void (*callbackFunc)(void *), void *callbackArg)
     {
         Q_ASSERT(m_channel == -1);
 
         try {
             const QString *authString;
             int (ne7ssh::*connFunc)(const char *, int, const char *,
-                                    const char *, bool, int);
+                const char *, bool, int, void (*)(void *), void *);
             if (m_server.authType == SshServerInfo::AuthByPwd) {
                 authString = &m_server.pwd;
                 connFunc = &ne7ssh::connectWithPassword;
@@ -87,14 +89,14 @@ public:
                 connFunc = &ne7ssh::connectWithKey;
             }
             m_channel = (ssh.data()->*connFunc)(m_server.host.toLatin1(),
-                            m_server.port, m_server.uname.toAscii(),
-                            authString->toLatin1(), shell, m_server.timeout);
+                m_server.port, m_server.uname.toAscii(), authString->toLatin1(),
+                shell, m_server.timeout, callbackFunc, callbackArg);
             if (m_channel == -1) {
                 setError(tr("Could not connect to host."), false);
                 return false;
             }
         } catch (const std::exception &e) {
-        // Should in theory not be necessary, but Net7 leaks Botan exceptions.
+            // Should in theory not be necessary, but Net7 leaks Botan exceptions.
             setError(tr("Error in cryptography backend: %1")
                      .arg(QLatin1String(e.what())), false);
             return false;
@@ -133,7 +135,6 @@ private:
     int m_channel;
 };
 
-
 char *alloc(size_t n)
 {
     return new char[n];
@@ -165,7 +166,8 @@ class ConnectionOutputReader : public QThread
 {
 public:
     ConnectionOutputReader(InteractiveSshConnection *parent)
-        : QThread(parent), m_conn(parent), m_stopRequested(false)
+        : QThread(parent), m_conn(parent), m_stopRequested(false),
+          m_dataAvailable(false)
     {}
 
     ~ConnectionOutputReader()
@@ -174,35 +176,63 @@ public:
         wait();
     }
 
-    // TODO: Use a wakeup mechanism here as soon as we no longer poll for output
-    // from Net7.
     void stop()
     {
+        m_mutex.lock();
         m_stopRequested = true;
+        m_waitCond.wakeOne();
+        m_mutex.unlock();
+    }
+
+    void dataAvailable()
+    {
+        m_mutex.lock();
+        m_dataAvailable = true;
+        m_waitCond.wakeOne();
+        m_mutex.unlock();
     }
 
 private:
     virtual void run()
     {
-        while (!m_stopRequested) {
+        while (true) {
+            m_mutex.lock();
+            if (m_stopRequested) {
+                m_mutex.unlock();
+                return;
+            }
             const int channel = m_conn->d->conn.channel();
-            if (channel != -1) {
-                QScopedPointer<char, QScopedPointerArrayDeleter<char> >
+            if (!m_dataAvailable || channel == -1)
+                m_waitCond.wait(&m_mutex);
+            m_dataAvailable = false;
+            m_mutex.unlock();
+            QScopedPointer<char, QScopedPointerArrayDeleter<char> >
                     output(m_conn->d->conn.ssh->readAndReset(channel, alloc));
-                if (output)
-                    emit m_conn->remoteOutput(QByteArray(output.data()));
-            }
-            usleep(100000); // TODO: Hack Net7 to enable wait() functionality.
+            if (output)
+                emit m_conn->remoteOutput(QByteArray(output.data()));
         }
     }
 
     InteractiveSshConnection *m_conn;
     bool m_stopRequested;
+    bool m_dataAvailable;
+    QMutex m_mutex;
+    QWaitCondition m_waitCond;
 };
 
 } // namespace Internal
 
 
+namespace {
+
+void wakeupReader(void *opaqueReader)
+{
+    static_cast<Internal::ConnectionOutputReader*>(opaqueReader)->dataAvailable();
+}
+
+} // Anonymous namespace
+
+
 InteractiveSshConnection::InteractiveSshConnection(const SshServerInfo &server)
     : d(new Internal::InteractiveSshConnectionPrivate(server))
 {
@@ -218,7 +248,7 @@ InteractiveSshConnection::~InteractiveSshConnection()
 
 bool InteractiveSshConnection::start()
 {
-    if (!d->conn.start(true))
+    if (!d->conn.start(true, wakeupReader, d->outputReader))
         return false;
 
     d->outputReader->start();
@@ -283,7 +313,7 @@ SftpConnection::~SftpConnection()
 
 bool SftpConnection::start()
 {
-    if (!d->conn.start(false))
+    if (!d->conn.start(false, 0, 0))
         return false;
     if (!d->conn.ssh->initSftp(d->sftp, d->conn.channel())
         || !d->sftp.setTimeout(d->conn.server().timeout)) {