diff --git a/contrib/sasc-ng/dvbloopback/module/dvb_loopback.c b/contrib/sasc-ng/dvbloopback/module/dvb_loopback.c
index 5299dbe..a8500dd 100644
--- a/contrib/sasc-ng/dvbloopback/module/dvb_loopback.c
+++ b/contrib/sasc-ng/dvbloopback/module/dvb_loopback.c
@@ -49,6 +49,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/pagemap.h>
+#include <linux/slab.h>
 #include <linux/dvb/ca.h>
 #include <linux/dvb/frontend.h>
 #include <linux/dvb/version.h>
diff --git a/contrib/sasc-ng/dvbloopback/module/dvblb_proc.c b/contrib/sasc-ng/dvbloopback/module/dvblb_proc.c
index c78aa33..2c3637f 100644
--- a/contrib/sasc-ng/dvbloopback/module/dvblb_proc.c
+++ b/contrib/sasc-ng/dvbloopback/module/dvblb_proc.c
@@ -23,14 +23,16 @@
  */
 #include <linux/version.h>      /* >= 2.6.14 LINUX_VERSION_CODE */
 #include <linux/errno.h>
+#include <linux/fs.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/seq_file.h>
 
 #include <linux/proc_fs.h>
 #include "dvblb_internal.h"
 
 static struct proc_dir_entry *procdir;
-
+/*
 static int dvblb_procfs_read(char *page, char **start, off_t off, int count,
                              int *eof, void *data)
 {
@@ -41,7 +43,18 @@ static int dvblb_procfs_read(char *page, char **start, off_t off, int count,
 	val = (lbdev->forward_dev) ? 1 : 0;
 	return sprintf(page, "%03d", val);
 }
-
+*/
+static int dvblb_procfs_read(struct seq_file *s, void* v)
+{
+	struct dvblb_devinfo *lbdev = s->private;
+	int val;
+	if (lbdev == NULL)
+		return 0;
+	val = (lbdev->forward_dev) ? 1 : 0;
+	seq_printf(s, "%03d", val);
+        return 0;
+}
+/*
 static int dvblb_procfs_write(struct file *file, const char *buffer,
                               unsigned long count, void *data)
 {
@@ -95,7 +108,64 @@ static int dvblb_procfs_write(struct file *file, const char *buffer,
 	}
 	return count;
 }
-
+*/
+static ssize_t dvblb_procfs_write(struct file *file, const char *buffer,
+                              size_t count, loff_t *pos)
+{
+        // TODO: maybe update *pos at end???
+	char str[10];
+	int val, v1, v2, v3, fm;
+	//struct dvblb_devinfo *lbdev = (struct dvblb_devinfo *)data;
+        struct seq_file *s = file->private_data;
+        struct dvblb_devinfo* lbdev = s->private;
+	if (lbdev == NULL)
+		return count;
+	if (lbdev->parent->link == -1)
+		return count;
+	if (count > 10)
+		count = 10;
+	if (copy_from_user(str, buffer, count)) {
+		return -EFAULT;
+	}
+	val = simple_strtoul(str, NULL, 0);
+	v1 = val /100;
+	v2 = (val - v1*100) / 10;
+	v3 = val - v1*100 - v2*10;
+	if (v1 < 0 || v1 > 2) 
+		return -EFAULT;
+	if((fm = inuse_filemap(lbdev))) {
+		int type = lbdev->lb_dev->type;
+		printk("dvbloopback: Can't change forward on adapter%d."
+		       " Device %s still has %d users!\n",
+		       lbdev->parent->adapter.num, dnames[type], fm);
+		return count;
+	}
+	if (v3 == 1) {
+		struct list_head *entry;
+		list_for_each (entry, lbdev->parent->adapter_ll) {
+			struct dvb_adapter *adap;
+			adap = list_entry (entry, struct dvb_adapter,
+			                   list_head);
+			if (adap->num == lbdev->parent->link) {
+				struct list_head *entry0;
+				list_for_each (entry0,
+				               &adap->device_list) {
+					struct dvb_device *dev;
+					dev = list_entry (entry0,
+					       struct dvb_device, list_head);
+					if (dev->type == lbdev->lb_dev->type) {
+						lbdev->forward_dev = dev;
+						return count;
+					}
+				}
+			}
+		}
+	} else if (v3 == 0) {
+		lbdev->forward_dev = NULL;
+	}
+	return count;
+}
+/*
 static int dvblb_procfs_adapter_read(char *page, char **start, off_t off,
                                      int count, int *eof, void *data)
 {
@@ -104,7 +174,16 @@ static int dvblb_procfs_adapter_read(char *page, char **start, off_t off,
 		return 0;
 	return sprintf(page, "%d", dvblb->link);
 }
-
+*/
+static int dvblb_procfs_adapter_read(struct seq_file *s, void* v)
+{
+	struct dvblb *dvblb = s->private;
+	if (dvblb == NULL)
+		return 0;
+	seq_printf(s, "%d", dvblb->link);
+        return 0;
+}
+/*
 static int dvblb_procfs_adapter_write(struct file *file, const char *buffer,
                                       unsigned long count, void *data)
 {
@@ -121,6 +200,54 @@ static int dvblb_procfs_adapter_write(struct file *file, const char *buffer,
 	val = simple_strtol(str, NULL, 0);
 
 	if(val == -999) {
+		//This is a debug case.  Try to force close all open fds
+		//This is known not to be very reliable, but better than
+		//nothing
+		
+		for(i = 0; i < DVBLB_NUM_DEVS; i++) {
+			while((fm = inuse_filemap(&dvbdev->devinfo[i]))) {
+				filp_close(dvbdev->devinfo[i].dbgfilemap[fm],
+				           NULL);
+				dvbdev->devinfo[i].filemap[fm] = NULL;
+			}
+		}
+		return count;
+	}
+	for(i = 0; i < DVBLB_NUM_DEVS; i++) {
+		if(dvbdev->devinfo[i].forward_dev == NULL)
+			continue;
+		if((fm = inuse_filemap(&dvbdev->devinfo[i]))) {
+			int type = dvbdev->devinfo[i].lb_dev->type;
+			printk("dvbloopback: Can't change forward on adapter%d."
+			       " Device %s still has %d users!\n",
+			       dvbdev->adapter.num, dnames[type], fm);
+			return count;
+		}
+	}
+	for(i = 0; i < DVBLB_NUM_DEVS; i++)
+		dvbdev->devinfo[i].forward_dev = NULL;
+	dvbdev->link = val;
+	return count;
+}
+*/
+static ssize_t dvblb_procfs_adapter_write(struct file *file, const char *buffer,
+                              size_t count, loff_t *pos)
+{
+        // TODO: maybe update *pos at end???
+	char str[10];
+	int val, i, fm;
+        struct seq_file *s = file->private_data;
+        struct dvblb* dvbdev = s->private;
+	if (dvbdev == NULL)
+		return count;
+	if (count > 10)
+		count = 10;
+	if (copy_from_user(str, buffer, count)) {
+		return -EFAULT;
+	}
+	val = simple_strtol(str, NULL, 0);
+
+	if(val == -999) {
 		/*This is a debug case.  Try to force close all open fds
 		  This is known not to be very reliable, but better than
 		  nothing
@@ -154,31 +281,47 @@ static int dvblb_procfs_adapter_write(struct file *file, const char *buffer,
 int dvblb_remove_procfs(struct proc_dir_entry *pdir,
                         struct proc_dir_entry *parent)
 {
-	char name[20];
-	memcpy(name, pdir->name, pdir->namelen);
-	name[pdir->namelen] = '\0';
-	// printk("Removing proc: %s\n", name);
-	remove_proc_entry(name, parent);
+	proc_remove(pdir);
 	return 0;
 }
 EXPORT_SYMBOL(dvblb_remove_procfs);
 
+static int dvblb_procfs_open(struct inode *inode, struct file *filep)
+{
+    return single_open(filep, dvblb_procfs_read, PDE_DATA(inode)); 
+} 
+
+static const struct file_operations dvblb_procfs_fops = {
+    .owner      = THIS_MODULE,
+    .open       = dvblb_procfs_open,
+    .read       = seq_read,
+    .write      = dvblb_procfs_write,
+    .release    = single_release,
+};
+
 int dvblb_init_procfs_device(struct dvblb *dvblb, struct dvblb_devinfo *lbdev)
 {
-	int type = lbdev->lb_dev->type;
-	lbdev->procfile = create_proc_entry(dnames[type], 0644, dvblb->procdir);
-	if (lbdev->procfile == NULL)
-		return -ENOMEM;
-	lbdev->procfile->data = lbdev;
-	lbdev->procfile->read_proc = dvblb_procfs_read;
-	lbdev->procfile->write_proc = dvblb_procfs_write;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)
-	lbdev->procfile->owner = THIS_MODULE;
-#endif
-	return 0;
+        int type = lbdev->lb_dev->type;
+        lbdev->procfile = proc_create_data(dnames[type], 0644, dvblb->procdir, &dvblb_procfs_fops, lbdev);
+        if (lbdev->procfile == NULL)
+                return -ENOMEM;
+        return 0;
 }
 EXPORT_SYMBOL(dvblb_init_procfs_device);
 
+static int dvblb_procfs_adapter_open(struct inode *inode, struct file *filep)
+{
+    return single_open(filep, dvblb_procfs_adapter_read, PDE_DATA(inode)); 
+} 
+
+static const struct file_operations dvblb_procfs_adapter_fops = {
+    .owner      = THIS_MODULE,
+    .open       = dvblb_procfs_adapter_open,
+    .read       = seq_read,
+    .write      = dvblb_procfs_adapter_write,
+    .release    = single_release,
+};
+
 int dvblb_init_procfs_adapter(struct dvblb *dvblb)
 {
 	char name[10];
@@ -186,20 +329,12 @@ int dvblb_init_procfs_adapter(struct dvblb *dvblb)
 	dvblb->procdir = proc_mkdir(name, procdir);
 	if (dvblb->procdir == NULL)
 		return -ENOMEM;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)
-	dvblb->procdir->owner = THIS_MODULE;
-#endif
-	dvblb->procfile = create_proc_entry("adapter", 0644, dvblb->procdir);
+	//dvblb->procfile = create_proc_entry("adapter", 0644, dvblb->procdir);
+        dvblb->procfile = proc_create_data("adapter", 0644, dvblb->procdir, &dvblb_procfs_adapter_fops, dvblb);
 	if (dvblb->procfile == NULL) {
 		dvblb_remove_procfs(dvblb->procdir, procdir);
 		return -ENOMEM;
 	}
-	dvblb->procfile->data = dvblb;
-	dvblb->procfile->read_proc = dvblb_procfs_adapter_read;
-	dvblb->procfile->write_proc = dvblb_procfs_adapter_write;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)
-	dvblb->procfile->owner = THIS_MODULE;
-#endif
 	dvblb->init |= DVBLB_STATUS_PROC;
 
 	return 0;
