--- a/mythtv/libs/libmythtv/firewiredevice.cpp
+++ b/mythtv/libs/libmythtv/firewiredevice.cpp
@@ -30,7 +30,7 @@
     m_speed(speed),
     m_last_channel(0),      m_last_crc(0),
     m_buffer_cleared(true), m_open_port_cnt(0),
-    m_lock()
+    m_lock(), m_is_no_input(false), m_error(false)
 {
 }
 
@@ -66,6 +66,24 @@
     VERBOSE(VB_RECORD, LOC + "RemoveListener() "<<m_listeners.size());
 }
 
+TSDataListener * FirewireDevice::GetTopListener(void) const
+{
+    if (m_listeners.empty())
+        return NULL;
+    return m_listeners.back();
+}
+
+bool  FirewireDevice::GetAndResetIsNoInput(void)
+{
+    if (!m_is_no_input)
+        return false;
+    QMutexLocker locker(&m_lock);
+    bool ret = m_is_no_input;
+    m_is_no_input = false;
+    return ret;
+}
+
+
 bool FirewireDevice::SetPowerState(bool on)
 {
     QMutexLocker locker(&m_lock);
--- a/mythtv/libs/libmythtv/firewiredevice.h
+++ b/mythtv/libs/libmythtv/firewiredevice.h
@@ -199,6 +199,7 @@
 
     virtual void AddListener(TSDataListener*);
     virtual void RemoveListener(TSDataListener*);
+    bool GetAndResetIsNoInput(void);
 
     // Sets
     virtual bool SetPowerState(bool on);
@@ -208,6 +209,8 @@
     // Gets
     virtual bool IsPortOpen(void) const = 0;
     bool IsSTBBufferCleared(void) const { return m_buffer_cleared; }
+    TSDataListener * GetTopListener(void) const;
+    bool IsError(void) const { return m_error; }
 
     // non-const Gets
     virtual PowerState GetPowerState(void);
@@ -240,6 +243,9 @@
     uint                     m_open_port_cnt;
     vector<TSDataListener*>  m_listeners;
     mutable QMutex           m_lock;
+    // Indicator for trapping "No Input in xxx msec" errors
+    bool                     m_is_no_input;
+    bool                     m_error;
 
     /// Vendor ID + Model ID to FirewireDevice STB model string
     static QMap<uint64_t,QString> s_id_to_model;
--- a/mythtv/libs/libmythtv/firewirerecorder.cpp
+++ b/mythtv/libs/libmythtv/firewirerecorder.cpp
@@ -28,19 +28,15 @@
 
 bool FirewireRecorder::Open(void)
 {
-    if (!isopen)
-        isopen = channel->GetFirewireDevice()->OpenPort();
-
+    isopen = channel->GetFirewireDevice()->OpenPort();
     return isopen;
 }
 
-void FirewireRecorder::Close(void)
+bool FirewireRecorder::Close(void)
 {
-    if (isopen)
-    {
-        channel->GetFirewireDevice()->ClosePort();
-        isopen = false;
-    }
+    channel->GetFirewireDevice()->ClosePort();
+    isopen = channel->GetFirewireDevice()->IsPortOpen();
+    return isopen;
 }
 
 void FirewireRecorder::StartStreaming(void)
@@ -55,26 +51,123 @@
 
 void FirewireRecorder::StartRecording(void)
 {
-    VERBOSE(VB_RECORD, LOC + "StartRecording");
-
-    if (!Open())
-    {
-        _error = true;
-        return;
-    }
-
-    _request_recording = true;
-    _recording = true;
-
-    StartStreaming();
-
-    while (_request_recording)
-    {
-        if (!PauseAndWait())
-            usleep(50 * 1000);
+    bool is_no_input = false;
+    bool must_save_listeners = false;
+    vector<TSDataListener*>  saved_listeners;
+    int number_opens = 1;
+    time_t time_last_reset = 0;
+
+    VERBOSE(VB_RECORD, LOC + "StartRecording " + curRecording->GetTitle());
+
+    // This loop contains logic to handle a firewire no input error
+    // When the firewire device reports no input received for 400 msec
+    // this is indication of a problem that does not go away. To fix the error
+    // we close the firewire port and open it again in this loop.
+    do {
+        while(number_opens > 0)
+        {
+            if (!Open())
+            {
+                _error = true;
+                return;
+            }
+            number_opens--;
+        }
+
+        _request_recording = true;
+        _recording = true;
+
+        if (saved_listeners.empty())
+            StartStreaming();
+        else
+        {
+            // Restore Listeners
+            int count = 0;
+            TSDataListener* listener;
+            listener = saved_listeners.back();
+            while (listener!=NULL)
+            {
+                VERBOSE(VB_RECORD, LOC + QString("Restoring listener %1").arg(++count));
+                channel->GetFirewireDevice()->AddListener(listener);
+                saved_listeners.pop_back();
+                if (saved_listeners.empty())
+                    listener = NULL;
+                else
+                    listener = saved_listeners.back();
+            }
+        }
+        // If adding listeners caused a failure, cancel recording
+        if (channel->GetFirewireDevice()->IsError()) {
+            _error = true;
+            StopRecording();
+        }
+
+        while (_request_recording)
+        {
+            if (is_no_input)
+            {
+                time_t now = time(NULL);
+                time_t elapsed = now - time_last_reset;
+                // if less than 30 seconds since last reset, ignore the error
+                // and let bus reset maybe fix it
+                if (elapsed <= 30) {
+                    VERBOSE(VB_RECORD, LOC + QString("Repeated Firewire No Input Error - Try Bus Reset."));
+                    is_no_input = false;
+                }
+                // if between 30 seconds and 5 minutes since last reset - we
+                // have a persistent error - fail the recording
+                if (elapsed > 30 && elapsed <= 300) {
+                    VERBOSE(VB_IMPORTANT, LOC + QString("Repeated Firewire No Input Error - Recording Fails."));
+                    is_no_input = false;
+                    _error = true;
+                    StopRecording();
+                }
+                // if more than 5 minutes since last reset, or this is the first,
+                // proceed with reset
+                if (elapsed > 300) {
+                    VERBOSE(VB_IMPORTANT, LOC + QString("Firewire No Input Error - Resetting device."));
+                    StopRecording();
+                    is_no_input = false;
+                    must_save_listeners = true;
+                    time_last_reset = now;
+                }
+            }
+
+            if (!PauseAndWait())
+                usleep(50 * 1000);
+
+            // Look at firewire device to see if it is having an error. The call GetAndResetIsNoInput
+            // resets the indicator in thread safe way so that only one thread will handle repairing
+            // the broken firewire connection.
+            if (!must_save_listeners && channel->GetFirewireDevice()->GetAndResetIsNoInput())
+                is_no_input = true;
+        }
+
+        if (must_save_listeners)
+        {
+            // Remove And Save Listeners - may not be thread safe if others are concurrently
+            // adding or removing listeners
+            int count = 0;
+            TSDataListener* listener;
+            listener = channel->GetFirewireDevice()->GetTopListener();
+            while (listener != NULL)
+            {
+                VERBOSE(VB_RECORD, LOC + QString("Saving listener %1").arg(++count));
+                saved_listeners.push_back(listener);
+                channel->GetFirewireDevice()->RemoveListener(listener);
+                listener = channel->GetFirewireDevice()->GetTopListener();
+            }
+            must_save_listeners = false;
+            number_opens = 0;
+            while(Close())
+                number_opens++;
+            VERBOSE(VB_RECORD, LOC + QString("Number of closes: %1").arg(++number_opens));
+        }
     }
+    while(!saved_listeners.empty());
 
     StopStreaming();
+    Close();
     FinishRecording();
 
     _recording = false;
--- a/mythtv/libs/libmythtv/firewirerecorder.h
+++ b/mythtv/libs/libmythtv/firewirerecorder.h
@@ -34,7 +34,7 @@
 
     // Commands
     bool Open(void);
-    void Close(void);
+    bool Close(void);
 
     void StartStreaming(void);
     void StopStreaming(void);
--- a/mythtv/libs/libmythtv/linuxfirewiredevice.cpp
+++ b/mythtv/libs/libmythtv/linuxfirewiredevice.cpp
@@ -269,6 +269,7 @@
         VERBOSE(VB_IMPORTANT, LOC_ERR + QString("Not an STB"));
 
         m_lock.unlock();
+        m_priv->start_stop_port_handler_lock.unlock();
         ClosePort();
         m_lock.lock();
 
@@ -362,9 +363,11 @@
 
     if (!m_listeners.empty())
     {
-        OpenNode();
-        OpenAVStream();
-        StartStreaming();
+        m_error = !OpenNode();
+        if (!m_error)
+            m_error = !OpenAVStream();
+        if (!m_error)
+            m_error = !StartStreaming();
     }
 }
 
@@ -608,6 +611,7 @@
 {
     VERBOSE(VB_RECORD, LOC + "RunPortHandler -- start");
     m_lock.lock();
+    m_is_no_input = false;
     VERBOSE(VB_RECORD, LOC + "RunPortHandler -- got first lock");
     m_priv->is_port_handler_running = true;
 
@@ -659,6 +663,12 @@
 
             VERBOSE(VB_IMPORTANT, LOC_WARN + QString("No Input in %1 msec...")
                     .arg(m_priv->no_data_cnt * kNoDataTimeout));
+            // Set indicator for endless no data errors
+            // so that FirewireRecorder can reset the device
+            if (m_priv->no_data_cnt == 8)
+            {
+                m_is_no_input = true;
+            }
         }
 
         // Confirm that we won't block, now that we have the lock...
@@ -676,7 +686,6 @@
             }
         }
     }
-
     m_priv->is_port_handler_running = false;
     m_lock.unlock();
     VERBOSE(VB_RECORD, LOC + "RunPortHandler -- end");
--- a/mythtv/libs/libmythtv/firewiresignalmonitor.cpp
+++ b/mythtv/libs/libmythtv/firewiresignalmonitor.cpp
@@ -150,11 +150,79 @@
 
     FirewireDevice *dev = lchan->GetFirewireDevice();
 
-    dev->OpenPort();
-    dev->AddListener(this);
+    // This loop contains logic to handle a firewire no input error
+    // When the firewire device reports no input received for 400 msec
+    // this is indication of a problem that does not go away. To fix the error
+    // we close the firewire port and open it again in this loop.
+    bool is_no_input = false;
+    bool must_save_listeners = false;
+    vector<TSDataListener*>  saved_listeners;
+    int number_opens = 1;
+    do {
+        while(number_opens > 0)
+        {
+            dev->OpenPort();
+            number_opens--;
+        }
+        if (saved_listeners.empty())
+            dev->AddListener(this);
+        else
+        {
+            // Restore Listeners
+            int count = 0;
+            TSDataListener* listener;
+            listener = saved_listeners.back();
+            while (listener!=NULL)
+            {
+                VERBOSE(VB_CHANNEL, LOC + QString("Restoring listener %1").arg(++count));
+                dev->AddListener(listener);
+                saved_listeners.pop_back();
+                if (saved_listeners.empty())
+                    listener = NULL;
+                else
+                    listener = saved_listeners.back();
+            }
+        }
 
-    while (dtvMonitorRunning && GetStreamData())
-        usleep(100000);
+        while (dtvMonitorRunning && GetStreamData() && !must_save_listeners)
+        {
+            if (is_no_input)
+            {
+                // proceed with reset
+                VERBOSE(VB_IMPORTANT, LOC + QString("Firewire No Input Error - Resetting device."));
+                is_no_input = false;
+                must_save_listeners = true;
+            }
+            usleep(100000);
+
+            // Look at firewire device to see if it is having an error. The call GetAndResetIsNoInput
+            // resets the indicator in thread safe way so that only one thread will handle repairing
+            // the broken firewire connection.
+            if (!must_save_listeners && dev->GetAndResetIsNoInput())
+                is_no_input = true;
+        }
+        if (must_save_listeners)
+        {
+            // Remove And Save Listeners - may not be thread safe if others are concurrently
+            // adding or removing listeners
+            int count = 0;
+            TSDataListener* listener;
+            listener = dev->GetTopListener();
+            while (listener != NULL)
+            {
+                VERBOSE(VB_CHANNEL, LOC + QString("Saving listener %1").arg(++count));
+                saved_listeners.push_back(listener);
+                dev->RemoveListener(listener);
+                listener = dev->GetTopListener();
+            }
+            must_save_listeners = false;
+            number_opens = 0;
+            while(dev->ClosePort())
+                number_opens++;
+            VERBOSE(VB_CHANNEL, LOC + QString("Number of closes: %1").arg(++number_opens));
+        }
+    }
+    while(!saved_listeners.empty());
 
     VERBOSE(VB_CHANNEL, LOC + "RunTableMonitor(): -- shutdown ");
 
