Index: module/dvb_loopback.c
===================================================================
--- module/dvb_loopback.c	(revision 24)
+++ module/dvb_loopback.c	(working copy)
@@ -175,6 +175,7 @@
 static int get_new_filemap(struct dvblb_devinfo *lbdev, int id) {
 	int i;
 	for(i = 0; i < DVBLB_MAXFD; i++)
+	{
 		if(lbdev->filemap[i] == NULL) {
 			if(id)
 				lbdev->filemap[i] = lbdev->user_dev;
@@ -182,6 +183,7 @@
 				lbdev->filemap[i] = lbdev->lb_dev;
 			return i;
 		}
+	}
 	return -1;
 }
 
@@ -207,10 +209,10 @@
 	int ret = 0;
 	dprintk2("dvblb_fake_ioctl (%d) : %lu\n", lbdev->parent->adapter.num,
 	         0xFF & cmd);
-	if (down_interruptible(&lbdev->lock_fake_ioctl))
+	if (mutex_lock_interruptible(&lbdev->lock_fake_ioctl))
 		return -ERESTARTSYS;
-	if (down_interruptible(&lbdev->lock_ioctl)) {
-		up(&lbdev->lock_fake_ioctl);
+	if (mutex_lock_interruptible(&lbdev->lock_ioctl)) {
+		mutex_unlock(&lbdev->lock_fake_ioctl);
 		return -ERESTARTSYS;
 	}
 	//printk("Sleep up on cmd: %u\n", cmd);
@@ -228,7 +230,7 @@
 	lbdev->ioctldata = arg;
 	//kill_proc(lbdev->pid, SIGIO, 1);
 
-	up(&lbdev->lock_ioctl);
+	mutex_unlock(&lbdev->lock_ioctl);
 	wake_up_interruptible(&lbdev->wait_virt_poll);
 	while(1) {
 	        ret = wait_event_interruptible_timeout(lbdev->wait_ioctl,
@@ -249,20 +251,20 @@
 			   could do something about it here */
 			printk("dvblb_fake_ioctl interrupted: %lu\n",
 			       lbdev->ioctlcmd);
-			up(&lbdev->lock_fake_ioctl);
+			mutex_unlock(&lbdev->lock_fake_ioctl);
 			return -1;
 		}
 		dprintk("dvbloopback: timeout waiting for userspace\n");
 	}
 
-	if (down_interruptible(&lbdev->lock_ioctl)) {
-		up(&lbdev->lock_fake_ioctl);
+	if (mutex_lock_interruptible(&lbdev->lock_ioctl)) {
+		mutex_unlock(&lbdev->lock_fake_ioctl);
 		return -ERESTARTSYS;
 	}
 	//printk("Woke up on cmd: %u\n", cmd);
 	if (lbdev->ioctlcmd != ULONG_MAX) {
-		up(&lbdev->lock_ioctl);
-		up(&lbdev->lock_fake_ioctl);
+		mutex_unlock(&lbdev->lock_ioctl);
+		mutex_unlock(&lbdev->lock_fake_ioctl);
 		printk("dvblb_fake_ioctl failed: %lu\n",lbdev->ioctlcmd);
 		return -1;
 	}
@@ -271,8 +273,8 @@
 		memcpy(arg, lbdev->ioctlretdata + sizeof(int), lbdev->ioctllen);
 
 	ret = lbdev->ioctlretval;
-	up(&lbdev->lock_ioctl);
-	up(&lbdev->lock_fake_ioctl);
+	mutex_unlock(&lbdev->lock_ioctl);
+	mutex_unlock(&lbdev->lock_fake_ioctl);
 	return ret;
 }
 
@@ -300,28 +302,32 @@
 		struct dvblb_custommsg ci;
 
 		/*must update private_data so we can map fds properly */
-		if (down_interruptible(&lbdev->lock_ioctl))
+		if (mutex_lock_interruptible(&lbdev->lock_ioctl))
 			return -ERESTARTSYS;
 		map = get_new_filemap(lbdev, 0);
 		if (map < 0) {
 			printk("dvblb_open %s: Failed to set filemap\n",
 			       dnames[dvbdev->type]);
+			mutex_unlock(&lbdev->lock_ioctl);
 			return -EBUSY;
 		}
-                lbdev->dbgfilemap[map] = f;
+		try_module_get(THIS_MODULE);
+		lbdev->dbgfilemap[map] = f;
 		f->private_data = &lbdev->filemap[map];
 		lbdev->poll_waiting = 0;
-		up(&lbdev->lock_ioctl);
+		mutex_unlock(&lbdev->lock_ioctl);
 		dprintk("dvblb_open %s: fd: %d\n", dnames[dvbdev->type], map);
 		if (lbdev->forward_dev) {
 			ret = dvblb_forward_open(lbdev, inode, f);
 			if(ret < 0) {
+				module_put(THIS_MODULE);
 				lbdev->filemap[map] = NULL;
 			}
 			return ret;
 		}
 
 		if (lbdev->pid == -1) {
+			module_put(THIS_MODULE);
 			lbdev->filemap[map] = NULL;
 			return -EFAULT;
 		}
@@ -330,8 +336,10 @@
 		ret = dvblb_fake_ioctl(lbdev, &lbdev->filemap[map],
 		                       DVBLB_CMD_OPEN, &ci);
 		if(ret < 0) {
+			module_put(THIS_MODULE);
 			lbdev->filemap[map] = NULL;
 		}
+
 		return ret;
 	}
 	/* This is the userspace control device */
@@ -342,13 +350,20 @@
 		lbdev->pid = current->pid;
 		lbdev->ioctlcmd = ULONG_MAX;
 		lbdev->ioctllen = 0;
-		down(&lbdev->lock_ioctl);
+		mutex_lock(&lbdev->lock_ioctl);
 		memset(lbdev->filemap, 0, sizeof(lbdev->filemap));
 		map = get_new_filemap(lbdev, 1);
+		if (map < 0) {
+			printk("dvblb_open %s: Failed to set filemap\n",
+			       dnames[dvbdev->type]);
+			mutex_unlock(&lbdev->lock_ioctl);
+			return -EBUSY;
+		}
+		try_module_get(THIS_MODULE);
 		f->private_data = &lbdev->filemap[map];
                 lbdev->dbgfilemap[map] = f;
 		lbdev->poll_waiting = 0;
-		up(&lbdev->lock_ioctl);
+		mutex_unlock(&lbdev->lock_ioctl);
 		dprintk("dvblb_open %s: fd: %d\n", dnames[dvbdev->type], map);
 	}
 	return ret;
@@ -358,7 +373,7 @@
 {
 	struct dvb_device *dvbdev, **filemap;
 	struct dvblb_devinfo *lbdev;
-	int err;
+	int ret;
 
 	filemap  = (struct dvb_device **) f->private_data;
 	if(filemap == NULL) {
@@ -378,42 +393,52 @@
 	dprintk("dvblb_release %d%s%d fd:%d\n", lbdev->parent->adapter.num,
 	        dnames[dvbdev->type],
 	        dvbdev->id, find_filemap(lbdev, filemap));
+
 	if(dvbdev->id == 0) {
 		/* This is the looped device */
 		struct dvblb_custommsg ci;
-		int ret;
 
 		if (lbdev->forward_dev) {
 			ret = dvblb_forward_release(lbdev, f);
 			*filemap = NULL;
-			return ret;
+			goto out;
 		}
 
-		if (lbdev->pid == -1)
-			return -EFAULT;
+		if (lbdev->pid == -1) {
+			ret = -EFAULT;
+			goto out;
+		}
 		ci.type = DVBLB_CLOSE;
 		ret = dvblb_fake_ioctl(lbdev, filemap, DVBLB_CMD_CLOSE, &ci);
-		if (down_interruptible(&lbdev->lock_ioctl))
-			return -ERESTARTSYS;
+		if (mutex_lock_interruptible(&lbdev->lock_ioctl)) {
+			ret = -ERESTARTSYS;
+			goto out;
+		}
 		lbdev->poll_waiting = 0;
 		*filemap = NULL;
-		up(&lbdev->lock_ioctl);
-		return ret;
+		mutex_unlock(&lbdev->lock_ioctl);
+		goto out;
 	}
 	/* This is the userspace control device */
 	*filemap = NULL;
 	f->private_data = dvbdev;
-	err = dvb_generic_release(inode, f);
-	if (err < 0)
-		return err;
+	ret = dvb_generic_release(inode, f);
+	if (ret < 0) {
+		goto out;
+	}
 	lbdev->pid = -1;
-	down_interruptible(&lbdev->lock_buffer);
+	mutex_lock_interruptible(&lbdev->lock_buffer);
 	if (lbdev->buffer) {
 		rvfree(lbdev->buffer, lbdev->buflen*N_BUFFS);
 		lbdev->buffer = NULL;
 	}
-	up(&lbdev->lock_buffer);
-	return 0;
+	mutex_unlock(&lbdev->lock_buffer);
+	ret = 0;
+	goto out;
+
+out:
+	module_put(THIS_MODULE);
+	return ret;
 }
 
 static ssize_t dvblb_write(struct file *f, const char *buf,
@@ -482,20 +507,20 @@
 		ci.u.count = count;
 		if (lbdev->pid == -1)
 			return -EFAULT;
-		if (down_interruptible(&lbdev->lock_buffer))
+		if (mutex_lock_interruptible(&lbdev->lock_buffer))
 			return -ERESTARTSYS;
 		if(dvblb_fake_ioctl(lbdev, filemap, DVBLB_CMD_READ, &ci) < 0 ||
 		   ! lbdev->buffer) {
-			up(&lbdev->lock_buffer);
+			mutex_unlock(&lbdev->lock_buffer);
 			return 0;
 		}
 		if (ci.u.count > lbdev->buflen)
 			ci.u.count = lbdev->buflen;
 		if (copy_to_user(buf, lbdev->buffer, ci.u.count)) {
-			up(&lbdev->lock_buffer);
+			mutex_unlock(&lbdev->lock_buffer);
 			return -EFAULT;
 		}
-		up(&lbdev->lock_buffer);
+		mutex_unlock(&lbdev->lock_buffer);
 		dprintk3("Read %ld bytes\n", (long)ci.u.count);
 		return ci.u.count;
 	} else {
@@ -503,7 +528,7 @@
 		/* We pass ioctls to the userspace driver this way */
 		unsigned long int cmd, base_size, size;
 		base_size = sizeof(cmd) + sizeof(lbdev->ioctlfd);
-		if (down_interruptible(&lbdev->lock_ioctl))
+		if (mutex_lock_interruptible(&lbdev->lock_ioctl))
 			return -ERESTARTSYS;
 
 		cmd = lbdev->ioctlcmd;
@@ -511,7 +536,7 @@
 		                                         sizeof(int);
 		if (count < base_size + size || lbdev->ioctlcmd == ULONG_MAX ||
                     lbdev->ioctl_already_read) {
-			up(&lbdev->lock_ioctl);
+			mutex_unlock(&lbdev->lock_ioctl);
 			return -EFAULT;
 		}
 		if (cmd == ULONG_MAX)
@@ -520,32 +545,32 @@
 		count = size + base_size;
 
 		if (copy_to_user(buf, &cmd, sizeof(cmd))) {
-			up(&lbdev->lock_ioctl);
+			mutex_unlock(&lbdev->lock_ioctl);
 			return -EFAULT;
 		}
 
 		if (copy_to_user(buf + sizeof(cmd), &lbdev->ioctlfd,
 		                 sizeof(lbdev->ioctlfd))) {
-			up(&lbdev->lock_ioctl);
+			mutex_unlock(&lbdev->lock_ioctl);
 			return -EFAULT;
 		}
 
 		if (lbdev->ioctllen == 0) {
 			if (copy_to_user(buf + base_size, &lbdev->ioctldata,
 			                 size)) {
-				up(&lbdev->lock_ioctl);
+				mutex_unlock(&lbdev->lock_ioctl);
 				return -EFAULT;
 			}
 			
 		} else {
 			if (copy_to_user(buf + base_size, lbdev->ioctldata,
 			                 size)) {
-				up(&lbdev->lock_ioctl);
+				mutex_unlock(&lbdev->lock_ioctl);
 				return -EFAULT;
 			}
 		}
 		lbdev->ioctl_already_read = 1;
-		up(&lbdev->lock_ioctl);
+		mutex_unlock(&lbdev->lock_ioctl);
 		return count;
 	}
 }
@@ -627,7 +652,7 @@
 			printk("Failed to read pollmsg from ioctl\n");
 			return -EFAULT;
 		}
-		if (down_interruptible(&lbdev->lock_ioctl))
+		if (mutex_lock_interruptible(&lbdev->lock_ioctl))
 			return -ERESTARTSYS;
 		if (pollmsg.count == 0) {
 			/* Send wakeup to all waiting polls */
@@ -651,16 +676,16 @@
 				wake_up_interruptible(&lbdev->wait_poll[pos]);
 			}
 		}
-		up(&lbdev->lock_ioctl);
+		mutex_unlock(&lbdev->lock_ioctl);
 		return 0;
 	}
-	if (down_interruptible(&lbdev->lock_ioctl))
+	if (mutex_lock_interruptible(&lbdev->lock_ioctl))
 		return -ERESTARTSYS;
 	if (cmd != lbdev->ioctlcmd) {
 		// Incorrect response
 		printk("dvbloopback: Got wrong response (%u != %lu)\n", cmd,
 		       lbdev->ioctlcmd);
-		up(&lbdev->lock_ioctl);
+		mutex_unlock(&lbdev->lock_ioctl);
 		return 0;
 	}
 	if (cmd < DVBLB_MAX_CMDS)
@@ -671,12 +696,12 @@
 		size = sizeof(int) + _IOC_SIZE(cmd);
 
 	if (copy_from_user(lbdev->ioctlretdata, parg, size)) {
-		up(&lbdev->lock_ioctl);
+		mutex_unlock(&lbdev->lock_ioctl);
 		return -EFAULT;
 	}
 	lbdev->ioctlretval = *(int *)lbdev->ioctlretdata;
 	lbdev->ioctlcmd = ULONG_MAX;
-	up(&lbdev->lock_ioctl);
+	mutex_unlock(&lbdev->lock_ioctl);
 	wake_up(&lbdev->wait_ioctl);
 	return 0;
 }
@@ -717,7 +742,7 @@
 	/* This is the userspace control device */
 	if (!size)
 		return -EINVAL;
-	if (down_interruptible(&lbdev->lock_buffer))
+	if (mutex_lock_interruptible(&lbdev->lock_buffer))
 		return -ERESTARTSYS;
 	if (lbdev->buffer)
 		rvfree(lbdev->buffer, lbdev->buflen*N_BUFFS);
@@ -725,28 +750,28 @@
 	lbdev->buffer=rvmalloc(lbdev->buflen*N_BUFFS);
 
 	if (lbdev->buffer == NULL) {
-		up(&lbdev->lock_buffer);
+		mutex_unlock(&lbdev->lock_buffer);
 		return -EINVAL;
 	}
 
         if (size > (((N_BUFFS * lbdev->buflen) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))) {
-		up(&lbdev->lock_buffer);
+		mutex_unlock(&lbdev->lock_buffer);
                 return -EINVAL;
 	}
 
-        pos = (unsigned long)lbdev->buffer;
+	pos = (unsigned long)lbdev->buffer;
         while (size > 0) {
 		page = vmalloc_to_pfn((void *)pos);
 		if (remap_pfn_range(vma, start, page, PAGE_SIZE,
-				PAGE_SHARED)) {
-			up(&lbdev->lock_buffer);
+				 PAGE_SHARED)) {
+			mutex_unlock(&lbdev->lock_buffer);
                         return -EAGAIN;
 		}
                 start += PAGE_SIZE;
-                pos += PAGE_SIZE;
+		pos += PAGE_SIZE;
 		size -= PAGE_SIZE;
         }
-	up(&lbdev->lock_buffer);
+	mutex_unlock(&lbdev->lock_buffer);
 
 	return 0;
 }
@@ -796,13 +821,13 @@
 		}
 		poll_wait(f, &lbdev->wait_poll[pos], wait);
 
-		if (down_interruptible(&lbdev->lock_ioctl))
+		if (mutex_lock_interruptible(&lbdev->lock_ioctl))
 			return -ERESTARTSYS;
 		if(lbdev->poll_waiting & (1 << pos))
 			do_poll = 0;
 		else /* need to set it before the fake_ioctl to prevent race */
 			lbdev->poll_waiting |= (1 << pos);
-		up(&lbdev->lock_ioctl);
+		mutex_unlock(&lbdev->lock_ioctl);
 
 		if(do_poll) {
 			ci.type = DVBLB_POLL;
@@ -810,10 +835,10 @@
 			ret = dvblb_fake_ioctl(lbdev, filemap, DVBLB_CMD_POLL,
 			                       &ci);
 			if(ret != 0) {
-				if (down_interruptible(&lbdev->lock_ioctl))
+				if (mutex_lock_interruptible(&lbdev->lock_ioctl))
 					return -ERESTARTSYS;
 				lbdev->poll_waiting &= ~(1 << pos);
-				up(&lbdev->lock_ioctl);
+				mutex_unlock(&lbdev->lock_ioctl);
 				if(ret < 0)
 					return ret;
 			}
@@ -832,13 +857,13 @@
 	}
 
 	poll_wait(f, &lbdev->wait_virt_poll, wait);
-	if (down_interruptible(&lbdev->lock_ioctl))
+	if (mutex_lock_interruptible(&lbdev->lock_ioctl))
 		return -ERESTARTSYS;
 	if (lbdev->ioctlcmd != ULONG_MAX && ! lbdev->ioctl_already_read) {
-		up(&lbdev->lock_ioctl);
+		mutex_unlock(&lbdev->lock_ioctl);
 		return (POLLIN | POLLPRI | POLLRDNORM);
 	}
-	up(&lbdev->lock_ioctl);
+	mutex_unlock(&lbdev->lock_ioctl);
 	return 0;
 }
 
@@ -934,9 +959,9 @@
 	}
 	init_waitqueue_head(&lbdev->wait_virt_poll);
 	init_waitqueue_head(&lbdev->wait_ioctl);
-	init_MUTEX(&lbdev->lock_fake_ioctl);
-	init_MUTEX(&lbdev->lock_ioctl);
-	init_MUTEX(&lbdev->lock_buffer);
+	mutex_init(&lbdev->lock_fake_ioctl);
+	mutex_init(&lbdev->lock_ioctl);
+	mutex_init(&lbdev->lock_buffer);
 	dvblb->init |= (1 << dev_idx);
 	return 0;
 }
@@ -1000,7 +1025,7 @@
 	}
 	printk("dvbloopback: registering %d adapters\n", num_adapters);
 
-	dvblb_global = vmalloc(sizeof(struct dvblb) * num_adapters);
+	dvblb_global = kmalloc(sizeof(struct dvblb) * num_adapters, GFP_KERNEL);
 	if (dvblb_global == NULL)
 		return -ENOMEM;
 	for(i=0; i < num_adapters; i++)
@@ -1008,13 +1033,13 @@
  
 	dvblb_basedev = platform_device_alloc("dvbloopback", -1);
 	if (!dvblb_basedev) {
-		vfree(dvblb_global);
+		kfree(dvblb_global);
 		return -ENOMEM;
 	}
 	ret = platform_device_add(dvblb_basedev);
 	if (ret) {
 		platform_device_put(dvblb_basedev);
-		vfree(dvblb_global);
+		kfree(dvblb_global);
 		return ret;
 	}
 	for(i=0; i < num_adapters; i++) {
@@ -1096,7 +1121,7 @@
 			destroy_lb_adapter(&dvblb_global[i]);
 		}
 		platform_device_unregister(dvblb_basedev);
-		vfree(dvblb_global);
+		kfree(dvblb_global);
 		return -EFAULT;
 	}
 	return 0;
@@ -1112,7 +1137,7 @@
 		destroy_lb_adapter(&dvblb_global[i]);
 	}
 	platform_device_unregister(dvblb_basedev);
-	vfree(dvblb_global);
+	kfree(dvblb_global);
 	dvblb_uninit_procfs();
 }
 
Index: module/dvblb_internal.h
===================================================================
--- module/dvblb_internal.h	(revision 24)
+++ module/dvblb_internal.h	(working copy)
@@ -28,9 +28,9 @@
 	unsigned long int  buflen;
 	wait_queue_head_t  wait_ioctl;
 	wait_queue_head_t  wait_virt_poll;
-	struct semaphore   lock_fake_ioctl;
-	struct semaphore   lock_ioctl;
-	struct semaphore   lock_buffer;
+	struct mutex   lock_fake_ioctl;
+	struct mutex   lock_ioctl;
+	struct mutex   lock_buffer;
 
 	wait_queue_head_t    wait_poll[DVBLB_MAXFD];
 	unsigned long int    poll_waiting;
