diff --git a/src/WZDmaInputFilter.cc b/src/WZDmaInputFilter.cc
index 930d937e78f6ac8f830784e3948576fa0190a4dc..1b0ed3c256e2804101b0aa383a87e465bdf49942 100644
--- a/src/WZDmaInputFilter.cc
+++ b/src/WZDmaInputFilter.cc
@@ -18,6 +18,7 @@ WZDmaInputFilter::WZDmaInputFilter(size_t packetBufferSize,
       sconeHost_{conf.getSconeHost()}, sconePort_{conf.getSconePort()},
       sconeBoard_{conf.getSconeBoard()} {
   // Initialize the DMA subsystem
+  dma_is_initialized_ = false;
   if (wz_init(&dma_) < 0) {
     std::string msg = "Cannot initialize WZ DMA device";
     if (errno == ENOENT) {
@@ -27,6 +28,7 @@ WZDmaInputFilter::WZDmaInputFilter(size_t packetBufferSize,
     }
     throw std::system_error(errno, std::system_category(), msg);
   }
+  dma_is_initialized_ = true;
 
   // Start the DMA
   if (wz_start_dma(&dma_) < 0) {
@@ -38,8 +40,11 @@ WZDmaInputFilter::WZDmaInputFilter(size_t packetBufferSize,
 }
 
 WZDmaInputFilter::~WZDmaInputFilter() {
-  wz_stop_dma(&dma_);
-  wz_close(&dma_);
+  if (dma_is_initialized_) {
+    wz_stop_dma(&dma_);
+    wz_close(&dma_);
+    dma_is_initialized_ = false;
+  }
   LOG(TRACE) << "Destroyed WZ DMA input filter";
 }
 
@@ -51,22 +56,26 @@ inline ssize_t WZDmaInputFilter::read_packet_from_dma(char **buffer) {
     bytes_read = wz_read_start(&dma_, buffer);
 
     if (bytes_read < 0) {
+      int errno_saved = errno;
       stats.nbDmaErrors++;
-      LOG(ERROR) << tools::strerror(
-          "#" + std::to_string(nbReads()) +
-          ": Read failed, returned: " + std::to_string(bytes_read));
+      LOG(ERROR) << tools::strerror("#" + std::to_string(nbReads()) +
+                                    ": Read failed, returned: " +
+                                    std::to_string(bytes_read))
+                 << ", errno: " << errno_saved;
 
-      if (errno == EIO) {
+      if (errno_saved == EIO) {
         LOG(ERROR) << "#" << nbReads() << ": Trying to restart DMA (attempt #"
                    << tries << "):";
         wz_stop_dma(&dma_);
         wz_close(&dma_);
+        dma_is_initialized_ = false;
 
         // Initialize the DMA subsystem
         if (wz_init(&dma_) < 0) {
           throw std::system_error(errno, std::system_category(),
                                   "Cannot initialize WZ DMA device");
         }
+        dma_is_initialized_ = true;
 
         if (wz_start_dma(&dma_) < 0) {
           throw std::system_error(errno, std::system_category(),
@@ -81,7 +90,7 @@ inline ssize_t WZDmaInputFilter::read_packet_from_dma(char **buffer) {
         }
         continue;
       }
-      throw std::system_error(errno, std::system_category(),
+      throw std::system_error(errno_saved, std::system_category(),
                               "FATAL: Unrecoverable DMA error detected.");
     }
     break;
diff --git a/src/WZDmaInputFilter.h b/src/WZDmaInputFilter.h
index c80cbf6f870b59712397533b6494a30b8eaa85fd..e8a4e8846df275c6738cfecf13784b6f864ab900 100644
--- a/src/WZDmaInputFilter.h
+++ b/src/WZDmaInputFilter.h
@@ -33,6 +33,7 @@ private:
   } stats;
 
   struct wz_private dma_;
+  bool dma_is_initialized_;
 
   std::string sconeHost_;
   std::string sconePort_;
diff --git a/src/wz_dma.c b/src/wz_dma.c
index 267a6c7d7d7032ae39886a42cfaf53841b024996..6a3bb685803a6412e12ecca4f49f49397146569b 100644
--- a/src/wz_dma.c
+++ b/src/wz_dma.c
@@ -23,40 +23,52 @@ int wz_init(struct wz_private* wz)
 	wz->fd_user = -1;
 	wz->fd_control = -1;
 	wz->fd_memory = -1;
+	wz->fd_memory_is_allocated = 0;
 	wz->usr_regs = NULL;
 	wz->data_buf = NULL;
 
 	//int err = 0;
 
 	if ( (wz->fd_user = open("/dev/wz-xdma0_user", O_RDWR)) < 0 ) {
+		wz->fd_user = -1;
 		PERROR("Can't open /dev/wz-xdma0_user");
 		return -1;
 	};
 
 	if ( (wz->fd_control = open("/dev/wz-xdma0_control", O_RDWR)) < 0 ) {
+		wz->fd_control = -1;
 		PERROR("Can't open /dev/wz-xdma0_control");
+		wz_close(wz);
 		return -1;
 	};
 
 	if ( (wz->fd_memory = open("/dev/wz-xdma0_c2h_0", O_RDWR)) < 0 ) {
+		wz->fd_memory = -1;
 		PERROR("Can't open /dev/wz-xdma0_c2h_0");
+		wz_close(wz);
 		return -1;
 	};
 
 	//Allocate buffers
 	if ( (res = ioctl(wz->fd_memory, IOCTL_XDMA_WZ_ALLOC_BUFFERS, 0L)) < 0 ) {
 		PERROR("Can't mmap DMA buffers");
+		wz_close(wz);
 		return -1;
 	}
+	wz->fd_memory_is_allocated = 1;
 
 	//Now mmap the user registers
 	if ( (wz->usr_regs = (volatile uint32_t *) mmap(NULL, 1024*1024, PROT_READ | PROT_WRITE, MAP_SHARED, wz->fd_user, 0)) == MAP_FAILED) {
+		wz->usr_regs = NULL;
 		PERROR("Can't mmap user registers");
+		wz_close(wz);
 		return -1;	
 	}
 
 	if ( (wz->data_buf = (volatile char *) mmap(NULL, TOT_BUF_LEN, PROT_READ|PROT_WRITE, MAP_SHARED, wz->fd_memory, 0)) == MAP_FAILED) { 
+		wz->data_buf = NULL;
 		PERROR("Can't mmap data buffer");
+		wz_close(wz);
 		return -1;
 	}
 
@@ -75,12 +87,32 @@ int wz_init(struct wz_private* wz)
 /* The opposite of wz_init */
 int wz_close(struct wz_private* wz) 
 {
-	munmap((void *)wz->data_buf, TOT_BUF_LEN);
-	munmap((void *)wz->usr_regs, 1024*1024);
-	ioctl(wz->fd_memory, IOCTL_XDMA_WZ_FREE_BUFFERS, 0L);
-	close(wz->fd_memory);
-	close(wz->fd_control);
-	close(wz->fd_user);
+	if (wz->data_buf) {
+		munmap((void *)wz->data_buf, TOT_BUF_LEN);
+	}
+	if (wz->usr_regs) {
+		munmap((void *)wz->usr_regs, 1024*1024);
+	}
+	if (wz->fd_memory_is_allocated) {
+		ioctl(wz->fd_memory, IOCTL_XDMA_WZ_FREE_BUFFERS, 0L);
+	}
+	if (wz->fd_memory != -1) {
+		close(wz->fd_memory);
+	}
+	if (wz->fd_control != -1) {
+		close(wz->fd_control);
+	}
+	if (wz->fd_user != -1) {
+		close(wz->fd_user);
+	}
+
+	wz->fd_user = -1;
+	wz->fd_control = -1;
+	wz->fd_memory = -1;
+	wz->fd_memory_is_allocated = 0;
+	wz->usr_regs = NULL;
+	wz->data_buf = NULL;
+
 	return 0;
 }
 
diff --git a/src/wz_dma.h b/src/wz_dma.h
index d32563c67f8920662a7a900b396a43f8dd5653b4..e84ddc1d9367fb3dcea2d28e5b2ebf1dbad1e659 100644
--- a/src/wz_dma.h
+++ b/src/wz_dma.h
@@ -11,6 +11,7 @@ struct wz_private {
   int fd_user;
   int fd_control;
   int fd_memory;
+  int fd_memory_is_allocated;
   volatile uint32_t *usr_regs;
   volatile char *data_buf;
 };