EM8300 MPEG2/DVD DECODER CARD DRIVER (http://dxr3.sourceforge.net)
Patch for Linux Kernel 4.x by Eric Voirin (oerg866@tototek.com)

Patch against em8300-0.18.0.tar/modules

Not very clean but it works. I didn't put in any kernel version checks
and even removed some old ones. 

So this probably breaks compatibility with pre-3.10 kernels.

Includes some work for 3.0 by Jaroslav Tulach

diff -Naurp modules/adv717x.c modules_FIXED/adv717x.c
--- modules/adv717x.c	2009-12-20 23:24:55.000000000 +0100
+++ modules_FIXED/adv717x.c	2017-08-25 22:32:59.000000000 +0200
@@ -39,7 +39,7 @@
 #include <linux/sched.h>
 #include <linux/types.h>
 
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
 #include <asm/uaccess.h>
 
 #include <linux/i2c.h>
@@ -134,7 +134,7 @@ static output_mode_t output_mode_nr[EM83
 static char *output_mode[EM8300_MAX] = { [ 0 ... EM8300_MAX-1 ] = NULL };
 MODULE_PARM(output_mode, "1-" __MODULE_STRING(EM8300_MAX) "s");
 #else
-module_param_array_named(output_mode, output_mode_nr, output_mode_t, NULL, 0444);
+//module_param_array_named(output_mode, output_mode_nr, output_mode_t, NULL, 0444);
 #endif
 MODULE_PARM_DESC(output_mode, "Specifies the output mode to use for the ADV717x video encoder. See the README-modoptions file for the list of mode names to use. Default is SVideo + composite (\"comp+svideo\").");
 
diff -Naurp modules/adv717x.mod.c modules_FIXED/adv717x.mod.c
--- modules/adv717x.mod.c	1970-01-01 01:00:00.000000000 +0100
+++ modules_FIXED/adv717x.mod.c	2017-08-26 18:55:27.000000000 +0200
@@ -0,0 +1,24 @@
+#include <linux/module.h>
+#include <linux/vermagic.h>
+#include <linux/compiler.h>
+
+MODULE_INFO(vermagic, VERMAGIC_STRING);
+
+__visible struct module __this_module
+__attribute__((section(".gnu.linkonce.this_module"))) = {
+	.name = KBUILD_MODNAME,
+	.init = init_module,
+#ifdef CONFIG_MODULE_UNLOAD
+	.exit = cleanup_module,
+#endif
+	.arch = MODULE_ARCH_INIT,
+};
+
+static const char __module_depends[]
+__used
+__attribute__((section(".modinfo"))) =
+"depends=";
+
+MODULE_ALIAS("i2c:adv717x");
+
+MODULE_INFO(srcversion, "D8107D672190210382EB11C");
diff -Naurp modules/bt865.c modules_FIXED/bt865.c
--- modules/bt865.c	2009-12-20 23:24:55.000000000 +0100
+++ modules_FIXED/bt865.c	2017-08-25 22:32:59.000000000 +0200
@@ -43,7 +43,7 @@
 #include <linux/sched.h>
 #include <linux/types.h>
 
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
 #include <asm/uaccess.h>
 
 #include <linux/i2c.h>
@@ -88,7 +88,7 @@ static output_mode_t output_mode_nr[EM83
 static char *output_mode[EM8300_MAX] = { [ 0 ... EM8300_MAX-1 ] = NULL };
 MODULE_PARM(output_mode, "1-" __MODULE_STRING(EM8300_MAX) "s");
 #else
-module_param_array_named(output_mode, output_mode_nr, output_mode_t, NULL, 0444);
+//module_param_array_named(output_mode, output_mode_nr, output_mode_t, NULL, 0444);
 #endif
 MODULE_PARM_DESC(output_mode, "Specifies the output mode to use for the BT865 video encoder. See the README-modoptions file for the list of mode names to use. Default is SVideo + composite (\"comp+svideo\").");
 
diff -Naurp modules/bt865.mod.c modules_FIXED/bt865.mod.c
--- modules/bt865.mod.c	1970-01-01 01:00:00.000000000 +0100
+++ modules_FIXED/bt865.mod.c	2017-08-26 18:55:27.000000000 +0200
@@ -0,0 +1,24 @@
+#include <linux/module.h>
+#include <linux/vermagic.h>
+#include <linux/compiler.h>
+
+MODULE_INFO(vermagic, VERMAGIC_STRING);
+
+__visible struct module __this_module
+__attribute__((section(".gnu.linkonce.this_module"))) = {
+	.name = KBUILD_MODNAME,
+	.init = init_module,
+#ifdef CONFIG_MODULE_UNLOAD
+	.exit = cleanup_module,
+#endif
+	.arch = MODULE_ARCH_INIT,
+};
+
+static const char __module_depends[]
+__used
+__attribute__((section(".modinfo"))) =
+"depends=";
+
+MODULE_ALIAS("i2c:bt865");
+
+MODULE_INFO(srcversion, "3C08CFE3A0010DECCCC89BA");
diff -Naurp modules/em8300.mod.c modules_FIXED/em8300.mod.c
--- modules/em8300.mod.c	1970-01-01 01:00:00.000000000 +0100
+++ modules_FIXED/em8300.mod.c	2017-08-26 18:57:09.000000000 +0200
@@ -0,0 +1,24 @@
+#include <linux/module.h>
+#include <linux/vermagic.h>
+#include <linux/compiler.h>
+
+MODULE_INFO(vermagic, VERMAGIC_STRING);
+
+__visible struct module __this_module
+__attribute__((section(".gnu.linkonce.this_module"))) = {
+	.name = KBUILD_MODNAME,
+	.init = init_module,
+#ifdef CONFIG_MODULE_UNLOAD
+	.exit = cleanup_module,
+#endif
+	.arch = MODULE_ARCH_INIT,
+};
+
+static const char __module_depends[]
+__used
+__attribute__((section(".modinfo"))) =
+"depends=snd-pcm,soundcore,snd,i2c-algo-bit";
+
+MODULE_ALIAS("pci:v00001105d00008300sv*sd*bc*sc*i*");
+
+MODULE_INFO(srcversion, "94B30C2B70C7F40B84CE97F");
diff -Naurp modules/em8300_alsa.c modules_FIXED/em8300_alsa.c
--- modules/em8300_alsa.c	2009-12-20 23:24:55.000000000 +0100
+++ modules_FIXED/em8300_alsa.c	2017-08-26 05:59:45.000000000 +0200
@@ -54,14 +54,6 @@
 #define snd_device_ops_t struct snd_device_ops
 #endif
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)
-#define snd_card_create(idx, xid, module, extra_size, card_ret)		\
-({									\
-	*(card_ret) = snd_card_new(idx, xid, module, extra_size);	\
-	*(card_ret) == NULL?-1:0;					\
-})
-#endif
-
 typedef struct snd_em8300_pcm_indirect {
 	unsigned int hw_buffer_size;    /* Byte size of hardware buffer */
 	unsigned int hw_queue_size;     /* Max queue size of hw buffer (0 = buffer size) */
@@ -487,7 +479,7 @@ static int snd_em8300_create(snd_card_t
 
 	memset(em8300_alsa, 0, sizeof(em8300_alsa_t));
 
-	init_MUTEX(&em8300_alsa->lock);
+	sema_init(&em8300_alsa->lock, 1);
 
 	em8300_alsa->em = em;
 	em8300_alsa->card = card;
@@ -511,7 +503,7 @@ static void em8300_alsa_enable_card(stru
 
 	em->alsa_card = NULL;
 
-	if ((err = snd_card_create(alsa_index[em->card_nr], alsa_id[em->card_nr], THIS_MODULE, 0, &card)) < 0)
+	if ((err = snd_card_new(&em->dev->dev, alsa_index[em->card_nr], alsa_id[em->card_nr], THIS_MODULE, 0, &card)) < 0)
 		return;
 
 	if ((err = snd_em8300_create(card, em, &em8300_alsa)) < 0) {
diff -Naurp modules/em8300_eeprom.c modules_FIXED/em8300_eeprom.c
--- modules/em8300_eeprom.c	2009-12-20 23:24:55.000000000 +0100
+++ modules_FIXED/em8300_eeprom.c	2017-08-26 18:56:57.000000000 +0200
@@ -22,6 +22,7 @@
 #include <linux/em8300.h>
 #include <linux/i2c.h>
 #include <linux/crypto.h>
+#include <crypto/hash.h>
 #include <linux/slab.h>
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
 #include <linux/scatterlist.h>
@@ -90,47 +91,33 @@ int em8300_eeprom_checksum_init(struct e
 		goto cleanup1;
 	}
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
 	{
-		struct crypto_hash *tfm;
-		struct hash_desc desc;
-		struct scatterlist tmp;
-
-		tfm = crypto_alloc_hash("md5", 0, CRYPTO_ALG_ASYNC);
-		if (IS_ERR(tfm)) {
-			err = PTR_ERR(tfm);
+		struct crypto_ahash *hash;
+        struct ahash_request *req;
+		struct scatterlist sg;
+
+		hash = crypto_alloc_ahash("md5", 0, CRYPTO_ALG_ASYNC);
+        
+		if (IS_ERR(hash)) {
+			err = PTR_ERR(hash);
 			goto cleanup2;
 		}
 
-		desc.tfm = tfm;
-		desc.flags = 0;
-		sg_init_one(&tmp, buf, 256);
-
-		err = crypto_hash_digest(&desc, &tmp, 128, em->eeprom_checksum);
+		req = ahash_request_alloc(hash, GFP_ATOMIC);
+        
+        sg_init_one(&sg, buf, 256);
+
+        ahash_request_set_callback(req, 0, NULL, NULL);
+        ahash_request_set_crypt(req, &sg, em->eeprom_checksum, 128);
+        
+        err = crypto_ahash_digest(req);
+//		err = crypto_hash_digest(&desc, &tmp, 128, em->eeprom_checksum);
 
-		crypto_free_hash(tfm);
+		crypto_free_ahash(hash);
 
 		if (err != 0)
 			goto cleanup2;
 	}
-#else
-	{
-		struct crypto_tfm *tfm;
-		struct scatterlist tmp;
-
-		tfm = crypto_alloc_tfm("md5", 0);
-		if (tfm == NULL) {
-			err = -5;
-			goto cleanup2;
-		}
-
-		sg_init_one(&tmp, buf, 128);
-
-		crypto_digest_digest(tfm, &tmp, 1, em->eeprom_checksum);
-
-		crypto_free_tfm(tfm);
-	}
-#endif
 
 	kfree(buf);
 
diff -Naurp modules/em8300_fifo.c modules_FIXED/em8300_fifo.c
--- modules/em8300_fifo.c	2009-12-20 23:24:55.000000000 +0100
+++ modules_FIXED/em8300_fifo.c	2017-08-25 22:32:59.000000000 +0200
@@ -115,7 +115,7 @@ int em8300_fifo_init(struct em8300_s *em
 		}
 	}
 
-	init_MUTEX(&f->lock);
+	sema_init(&f->lock, 1);
 	f->valid = 1;
 
 	return 0;
diff -Naurp modules/em8300_i2c.c modules_FIXED/em8300_i2c.c
--- modules/em8300_i2c.c	2009-12-20 23:24:55.000000000 +0100
+++ modules_FIXED/em8300_i2c.c	2017-08-25 23:05:00.000000000 +0200
@@ -122,9 +122,9 @@ static int em8300_i2c_lock_client(struct
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,54)
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-	if (!try_module_get(client->driver->driver.owner))
+	if (!try_module_get(to_i2c_driver(client->dev.driver)->driver.owner))
 #else
-	if (!try_module_get(client->driver->owner))
+	if (!try_module_get(to_i2c_driver(client->dev.driver)->owner))
 #endif
 	{
 		printk(KERN_ERR "em8300-%d: i2c: Unable to lock client module\n", em->card_nr);
@@ -138,9 +138,9 @@ static void em8300_i2c_unlock_client(str
 {
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,54)
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-	module_put(client->driver->driver.owner);
+	module_put(to_i2c_driver(client->dev.driver)->driver.owner);
 #else
-	module_put(client->driver->owner);
+	module_put(to_i2c_driver(client->dev.driver)->owner);
 #endif
 #endif
 }
@@ -151,16 +151,16 @@ static void em8300_adv717x_setup(struct
 	struct getconfig_s data;
 	struct setparam_s param;
 
-	if (!((client->driver) && (client->driver->command))) {
+	if (!((to_i2c_driver(client->dev.driver)) && (to_i2c_driver(client->dev.driver)->command))) {
 		printk("em8300-%d: cannot configure adv717x encoder: "
-		       "no client->driver->command\n", em->card_nr);
+		       "no to_i2c_driver(client->dev.driver)->command\n", em->card_nr);
 		return;
 	}
 
-	client->driver->command(client, ENCODER_CMD_ENABLEOUTPUT, (void *)0);
+	to_i2c_driver(client->dev.driver)->command(client, ENCODER_CMD_ENABLEOUTPUT, (void *)0);
 
 	data.card_nr = em->card_nr;
-	if (client->driver->command(client, ENCODER_CMD_GETCONFIG,
+	if (to_i2c_driver(client->dev.driver)->command(client, ENCODER_CMD_GETCONFIG,
 				    (void *) &data) != 0) {
 		printk("em8300-%d: ENCODER_CMD_GETCONFIG failed\n",
 		       em->card_nr);
@@ -183,31 +183,31 @@ static void em8300_adv717x_setup(struct
 	param.param = ENCODER_PARAM_COLORBARS;
 	param.modes = (uint32_t)-1;
 	param.val = data.config[4] ? 1 : 0;
-	client->driver->command(client, ENCODER_CMD_SETPARAM,
+	to_i2c_driver(client->dev.driver)->command(client, ENCODER_CMD_SETPARAM,
 				&param);
 	param.param = ENCODER_PARAM_OUTPUTMODE;
 	param.val = data.config[5];
-	client->driver->command(client, ENCODER_CMD_SETPARAM,
+	to_i2c_driver(client->dev.driver)->command(client, ENCODER_CMD_SETPARAM,
 				&param);
 	param.param = ENCODER_PARAM_PPORT;
 	param.modes = NTSC_MODES_MASK;
 	param.val = em->config.adv717x_model.pixelport_16bit?1:0;
-	client->driver->command(client, ENCODER_CMD_SETPARAM,
+	to_i2c_driver(client->dev.driver)->command(client, ENCODER_CMD_SETPARAM,
 				&param);
 	param.modes = PAL_MODES_MASK;
 	param.val = em->config.adv717x_model.pixelport_other_pal
 		? (em->config.adv717x_model.pixelport_16bit ? 0 : 1)
 		: (em->config.adv717x_model.pixelport_16bit ? 1 : 0);
-	client->driver->command(client, ENCODER_CMD_SETPARAM,
+	to_i2c_driver(client->dev.driver)->command(client, ENCODER_CMD_SETPARAM,
 				&param);
 	param.param = ENCODER_PARAM_PDADJ;
 	param.modes = NTSC_MODES_MASK;
 	param.val = em->config.adv717x_model.pixeldata_adjust_ntsc;
-	client->driver->command(client, ENCODER_CMD_SETPARAM,
+	to_i2c_driver(client->dev.driver)->command(client, ENCODER_CMD_SETPARAM,
 				&param);
 	param.modes = PAL_MODES_MASK;
 	param.val = em->config.adv717x_model.pixeldata_adjust_pal;
-	client->driver->command(client, ENCODER_CMD_SETPARAM,
+	to_i2c_driver(client->dev.driver)->command(client, ENCODER_CMD_SETPARAM,
 				&param);
 }
 
@@ -331,7 +331,6 @@ int em8300_i2c_init1(struct em8300_s *em
 	em->i2c_data_2.data = pdata;
 
 	strcpy(em->i2c_ops_2.name, "EM8300 I2C bus 2");
-	em->i2c_ops_2.id = I2C_HW_B_EM8300;
 	em->i2c_ops_2.algo = NULL;
 	em->i2c_ops_2.algo_data = &em->i2c_data_2;
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
@@ -354,7 +353,7 @@ int em8300_i2c_init1(struct em8300_s *em
 		struct i2c_board_info i2c_info;
 		const unsigned short eeprom_addr[] = { 0x50, I2C_CLIENT_END };
 		i2c_info = (struct i2c_board_info){ I2C_BOARD_INFO("eeprom", 0) };
-		em->eeprom = i2c_new_probed_device(&em->i2c_ops_2, &i2c_info, eeprom_addr);
+		em->eeprom = i2c_new_probed_device(&em->i2c_ops_2, &i2c_info, eeprom_addr, NULL);
 		if (em->eeprom) {
 			if (sysfs_create_link(&em->dev->dev.kobj, &em->eeprom->dev.kobj, "eeprom"))
 				printk(KERN_WARNING "em8300-%d: i2c: unable to create the eeprom link\n", em->card_nr);
@@ -384,7 +383,6 @@ int em8300_i2c_init2(struct em8300_s *em
 	em->i2c_data_1.data = pdata;
 
 	strcpy(em->i2c_ops_1.name, "EM8300 I2C bus 1");
-	em->i2c_ops_1.id = I2C_HW_B_EM8300;
 	em->i2c_ops_1.algo = NULL;
 	em->i2c_ops_1.algo_data = &em->i2c_data_1;
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
@@ -425,11 +423,11 @@ int em8300_i2c_init2(struct em8300_s *em
 		const unsigned short adv717x_addr[] = { 0x6a, I2C_CLIENT_END };
 		const unsigned short bt865_addr[] = { 0x45, I2C_CLIENT_END };
 		i2c_info = (struct i2c_board_info){ I2C_BOARD_INFO("adv717x", 0) };
-		em->encoder = i2c_new_probed_device(&em->i2c_ops_1, &i2c_info, adv717x_addr);
+		em->encoder = i2c_new_probed_device(&em->i2c_ops_1, &i2c_info, adv717x_addr, NULL);
 		if (em->encoder)
 			goto found;
 		i2c_info = (struct i2c_board_info){ I2C_BOARD_INFO("bt865", 0) };
-		em->encoder = i2c_new_probed_device(&em->i2c_ops_1, &i2c_info, bt865_addr);
+		em->encoder = i2c_new_probed_device(&em->i2c_ops_1, &i2c_info, bt865_addr, NULL);
 		if (em->encoder)
 			goto found;
 	}
@@ -437,11 +435,11 @@ int em8300_i2c_init2(struct em8300_s *em
 	return 0;
 
  found:
-	for (i = 0; (i < 50) && !em->encoder->driver; i++) {
+	for (i = 0; (i < 50) && !to_i2c_driver(em->encoder->dev.driver); i++) {
 		set_current_state(TASK_UNINTERRUPTIBLE);
 		schedule_timeout(HZ/10);
 	}
-	if (!em->encoder->driver) {	
+	if (!to_i2c_driver(em->encoder->dev.driver)) {	
 		printk(KERN_ERR "em8300-%d: encoder chip found but no driver found within 5 seconds\n", em->card_nr);
 		i2c_unregister_device(em->encoder);
 		em->encoder = NULL;
diff -Naurp modules/em8300_ioctl.c modules_FIXED/em8300_ioctl.c
--- modules/em8300_ioctl.c	2009-12-20 23:24:55.000000000 +0100
+++ modules_FIXED/em8300_ioctl.c	2017-08-25 23:06:42.000000000 +0200
@@ -549,9 +549,9 @@ int em8300_ioctl_setvideomode(struct em8
 
 	em8300_dicom_disable(em);
 
-	if ((em->encoder) && (em->encoder->driver)
-	    && (em->encoder->driver->command))
-		em->encoder->driver->command(em->encoder, ENCODER_CMD_SETMODE, (void *)encoder);
+	if ((em->encoder) && (to_i2c_driver(em->encoder->dev.driver))
+	    && (to_i2c_driver(em->encoder->dev.driver)->command))
+		to_i2c_driver(em->encoder->dev.driver)->command(em->encoder, ENCODER_CMD_SETMODE, (void *)encoder);
 	em8300_dicom_enable(em);
 	em8300_dicom_update(em);
 
@@ -562,9 +562,9 @@ void em8300_ioctl_enable_videoout(struct
 {
 	em8300_dicom_disable(em);
 
-	if ((em->encoder) && (em->encoder->driver)
-	    && (em->encoder->driver->command))
-		em->encoder->driver->command(em->encoder,
+	if ((em->encoder) && (to_i2c_driver(em->encoder->dev.driver))
+	    && (to_i2c_driver(em->encoder->dev.driver)->command))
+		to_i2c_driver(em->encoder->dev.driver)->command(em->encoder,
 					     ENCODER_CMD_ENABLEOUTPUT,
 					     (void *)(long int)(stop_video[em->card_nr]?mode:1));
 
@@ -629,9 +629,9 @@ int em8300_ioctl_overlay_setmode(struct
 	case EM8300_OVERLAY_MODE_RECTANGLE:
 	case EM8300_OVERLAY_MODE_OVERLAY:
 		if (!em->overlay_enabled) {
-			if ((em->encoder) && (em->encoder->driver)
-			    && (em->encoder->driver->command))
-				em->encoder->driver->command(em->encoder,
+			if ((em->encoder) && (to_i2c_driver(em->encoder->dev.driver))
+			    && (to_i2c_driver(em->encoder->dev.driver)->command))
+				to_i2c_driver(em->encoder->dev.driver)->command(em->encoder,
 							     ENCODER_CMD_ENABLEOUTPUT,
 							     (void *)(long int)0);
 			em->clockgen = (em->clockgen & ~CLOCKGEN_MODEMASK) | em->clockgen_overlaymode;
diff -Naurp modules/em8300_main.c modules_FIXED/em8300_main.c
--- modules/em8300_main.c	2009-12-20 23:24:56.000000000 +0100
+++ modules_FIXED/em8300_main.c	2017-08-26 16:42:53.000000000 +0200
@@ -160,16 +160,16 @@ static irqreturn_t em8300_irq(int irq, v
 
 static void release_em8300(struct em8300_s *em)
 {
-	if ((em->encoder) && (em->encoder->driver)
-	    && (em->encoder->driver->command))
-		em->encoder->driver->command(em->encoder,
+	if ((em->encoder) && (to_i2c_driver(em->encoder->dev.driver))
+	    && (to_i2c_driver(em->encoder->dev.driver)->command))
+		to_i2c_driver(em->encoder->dev.driver)->command(em->encoder,
 					     ENCODER_CMD_ENABLEOUTPUT,
 					     (void *) 0);
 
-#ifdef CONFIG_MTRR
+/*#ifdef CONFIG_MTRR
 	if (em->mtrr_reg)
 		mtrr_del(em->mtrr_reg, em->adr, em->memsize);
-#endif
+#endif*/
 
 	em8300_eeprom_checksum_deinit(em);
 	em8300_i2c_exit(em);
@@ -192,11 +192,13 @@ static void release_em8300(struct em8300
 	kfree(em);
 }
 
-static int em8300_io_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
+static long em8300_io_ioctl(struct file *filp, unsigned int cmd,
+                        unsigned long arg)
 {
 	struct em8300_s *em = filp->private_data;
-	int subdevice = EM8300_IMINOR(inode) % 4;
-
+	int subdevice = EM8300_IMINOR(filp->f_path.dentry->d_inode) % 4;
+        
+       // printk("ioc. cmd: %d device: %d\n", cmd, subdevice);
 	switch (subdevice) {
 	case EM8300_SUBDEVICE_AUDIO:
 		return em8300_audio_ioctl(em, cmd, arg);
@@ -291,7 +293,7 @@ static int em8300_io_open(struct inode *
 static ssize_t em8300_io_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
 {
 	struct em8300_s *em = file->private_data;
-	int subdevice = EM8300_IMINOR(file->f_dentry->d_inode) % 4;
+	int subdevice = EM8300_IMINOR(file->f_path.dentry->d_inode) % 4;
 
 	switch (subdevice) {
 	case EM8300_SUBDEVICE_VIDEO:
@@ -315,7 +317,7 @@ int em8300_io_mmap(struct file *file, st
 {
 	struct em8300_s *em = file->private_data;
 	unsigned long size = vma->vm_end - vma->vm_start;
-	int subdevice = EM8300_IMINOR(file->f_dentry->d_inode) % 4;
+	int subdevice = EM8300_IMINOR(file->f_path.dentry->d_inode) % 4;
 
 	if (subdevice != EM8300_SUBDEVICE_CONTROL)
 		return -EPERM;
@@ -388,7 +390,7 @@ int em8300_io_mmap(struct file *file, st
 		remap_pfn_range(vma, vma->vm_start, em->adr >> PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot);
 #endif
 		vma->vm_file = file;
-		atomic_inc(&file->f_dentry->d_inode->i_count);
+		atomic_inc(&file->f_path.dentry->d_inode->i_count);
 		break;
 	default:
 		return -EINVAL;
@@ -400,7 +402,7 @@ int em8300_io_mmap(struct file *file, st
 static unsigned int em8300_poll(struct file *file, struct poll_table_struct *wait)
 {
 	struct em8300_s *em = file->private_data;
-	int subdevice = EM8300_IMINOR(file->f_dentry->d_inode) % 4;
+	int subdevice = EM8300_IMINOR(file->f_path.dentry->d_inode) % 4;
 	unsigned int mask = 0;
 
 	switch (subdevice) {
@@ -481,7 +483,7 @@ int em8300_io_release(struct inode *inod
 struct file_operations em8300_fops = {
 	.owner = THIS_MODULE,
 	.write = em8300_io_write,
-	.ioctl = em8300_io_ioctl,
+	.unlocked_ioctl = em8300_io_ioctl,
 	.mmap = em8300_io_mmap,
 	.poll = em8300_poll,
 	.open = em8300_io_open,
@@ -492,7 +494,7 @@ struct file_operations em8300_fops = {
 };
 
 #if defined(CONFIG_SOUND) || defined(CONFIG_SOUND_MODULE)
-static int em8300_dsp_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
+static long em8300_dsp_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
 	struct em8300_s *em = filp->private_data;
 	return em8300_audio_ioctl(em, cmd, arg);
@@ -584,7 +586,7 @@ int em8300_dsp_release(struct inode *ino
 static struct file_operations em8300_dsp_audio_fops = {
 	.owner = THIS_MODULE,
 	.write = em8300_dsp_write,
-	.ioctl = em8300_dsp_ioctl,
+	.unlocked_ioctl = em8300_dsp_ioctl,
 	.poll = em8300_dsp_poll,
 	.open = em8300_dsp_open,
 	.release = em8300_dsp_release,
@@ -722,7 +724,7 @@ static int em8300_pci_setup(struct pci_d
 	return 0;
 }
 
-static int __devinit em8300_probe(struct pci_dev *dev,
+static int em8300_probe(struct pci_dev *dev,
 				  const struct pci_device_id *pci_id)
 {
 	struct em8300_s *em;
@@ -812,20 +814,20 @@ static int __devinit em8300_probe(struct
 	}
 
 	pr_info("em8300-%d: mapped-memory at 0x%p\n", em->card_nr, em->mem);
-#ifdef CONFIG_MTRR
+/*#ifdef CONFIG_MTRR
 	em->mtrr_reg = mtrr_add(em->adr, em->memsize, MTRR_TYPE_UNCACHABLE, 1);
 	if (em->mtrr_reg)
 		pr_info("em8300-%d: using MTRR\n", em->card_nr);
-#endif
+#endif*/
 
 	init_waitqueue_head(&em->video_ptsfifo_wait);
 	init_waitqueue_head(&em->vbi_wait);
 	init_waitqueue_head(&em->sp_ptsfifo_wait);
 
 	em->audio_driver_style = NONE;
-	init_MUTEX(&em->audio_driver_style_lock);
+	sema_init(&em->audio_driver_style_lock,1);
 
-	result = request_irq(dev->irq, em8300_irq, IRQF_SHARED | IRQF_DISABLED, "em8300", (void *) em);
+	result = request_irq(dev->irq, em8300_irq, IRQF_SHARED, "em8300", (void *) em);
 
 	if (result == -EINVAL) {
 		printk(KERN_ERR "em8300-%d: Bad irq number or handler\n", em->card_nr);
@@ -854,10 +856,10 @@ static int __devinit em8300_probe(struct
 	return 0;
 
 irq_error:
-#ifdef CONFIG_MTRR
+/*#ifdef CONFIG_MTRR
 	if (em->mtrr_reg)
 		mtrr_del(em->mtrr_reg, em->adr, em->memsize);
-#endif
+#endif*/
 	iounmap(em->mem);
 
 mem_free:
@@ -865,7 +867,7 @@ mem_free:
 	return result;
 }
 
-static void __devexit em8300_remove(struct pci_dev *pci)
+static void em8300_remove(struct pci_dev *pci)
 {
 	struct em8300_s *em = pci_get_drvdata(pci);
 
@@ -894,7 +896,7 @@ struct pci_driver em8300_driver = {
 	.name     = "Sigma Designs EM8300",
 	.id_table = em8300_ids,
 	.probe    = em8300_probe,
-	.remove   = __devexit_p(em8300_remove),
+	.remove   = em8300_remove,
 };
 
 static void __exit em8300_exit(void)
diff -Naurp modules/em8300_params.c modules_FIXED/em8300_params.c
--- modules/em8300_params.c	2009-12-20 23:24:56.000000000 +0100
+++ modules_FIXED/em8300_params.c	2017-08-25 22:32:59.000000000 +0200
@@ -133,7 +133,7 @@ static int param_get_audio_driver_t(char
 	return sprintf(buffer, "%s", audio_driver_name[*(audio_driver_t *)kp->arg]);
 }
 
-module_param_array_named(audio_driver, audio_driver_nr, audio_driver_t, NULL, 0444);
+//module_param_array_named(audio_driver, audio_driver_nr, audio_driver_t, NULL, 0444);
 #endif
 MODULE_PARM_DESC(audio_driver, "[DEPRECATED] The audio driver to use (none, osslike, oss, or alsa).");
 
diff -Naurp modules/em8300_procfs.c modules_FIXED/em8300_procfs.c
--- modules/em8300_procfs.c	2009-12-20 23:24:56.000000000 +0100
+++ modules_FIXED/em8300_procfs.c	2017-08-26 05:44:48.000000000 +0200
@@ -19,7 +19,9 @@
 */
 #include <linux/proc_fs.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <asm/io.h>
+#include <asm/uaccess.h>
 #include "em8300_procfs.h"
 #include "em8300_reg.h"
 #include "em8300_eeprom.h"
@@ -32,131 +34,167 @@
 #define EM8300_PROCFS_DIR "em8300"
 #endif
 
-struct proc_dir_entry *em8300_proc;
+struct proc_dir_entry *em8300_parent;
 
+static const struct file_operations em8300_fops = {
+    .owner = THIS_MODULE,
+    .read = em8300_proc_read,
+    .open = em8300_open,
+    .release = em8300_close,
+};
 
-static int em8300_proc_read(char *page, char **start, off_t off, int count, int *eof, void *data)
+int em8300_open (struct inode *inode, struct file *file)
 {
-	int len = 0;
-	struct em8300_s *em = (struct em8300_s *) data;
-	char *encoder_name;
+	try_module_get(THIS_MODULE);
+	return 0;
+}
+
+int em8300_close (struct inode *inode, struct file *file)
+{
+	module_put(THIS_MODULE);
+	return 0;		/* success */
+}
+
 
-	*start = 0;
-	*eof = 1;
+ssize_t em8300_proc_read(struct file *fp, char __user *buffer, size_t buffer_size, loff_t *offset) {
 
-	len += sprintf(page + len,
+    char *kbuf;
+    int len = 0;
+    char *encoder_name;
+    unsigned long result;
+    int found;
+    
+    struct em8300_s *em = (struct em8300_s *) PDE_DATA(file_inode(fp));
+    
+    kbuf = kmalloc(2048, GFP_KERNEL);
+    
+	len += sprintf(kbuf + len,
 		       "----- Driver Info -----\n");
-	len += sprintf(page + len,
+	len += sprintf(kbuf + len,
 		       "em8300 module version %s\n",
 		       EM8300_VERSION);
 	/* Device information */
-	len += sprintf(page + len,
+	len += sprintf(kbuf + len,
 		       "Card revision %d\n",
 		       em->pci_revision);
-	len += sprintf(page + len,
+	len += sprintf(kbuf + len,
 		       "Chip revision %d\n",
 		       em->chip_revision);
-	switch (em->encoder_type) {
-	case ENCODER_BT865:
-		encoder_name = "BT865";
-		break;
-	case ENCODER_ADV7170:
-		encoder_name = "ADV7170";
-		break;
-	case ENCODER_ADV7175:
-		encoder_name = "ADV7175";
-		break;
-	default:
-		len += sprintf(page + len, "No known video encoder found.\n");
-		goto encoder_done;
-	}
-	len += sprintf(page + len,
+               
+    found = 0;
+    
+    switch (em->encoder_type) {
+        case ENCODER_BT865:
+            encoder_name = "BT865";
+            found = 1;
+            break;
+        case ENCODER_ADV7170:
+            encoder_name = "ADV7170";
+            found = 1;
+            break;
+        case ENCODER_ADV7175:
+            encoder_name = "ADV7175";
+            found = 1;
+            break;
+        default:
+            encoder_name = "Unknown";
+	}
+    
+    if (found) {
+    	len += sprintf(kbuf + len,
 		       "Video encoder: %s at address 0x%02x on %s\n",
 		       encoder_name, em->encoder->addr,
 		       em->encoder->adapter->name);
- encoder_done:
+    } else {
+    	len += sprintf(kbuf + len, "No known video encoder found.\n");
+    }
+    
 	{
 		u8 *buf;
 		int i;
 		if ((buf = kmalloc(256, GFP_KERNEL)) != NULL) {
 			if (!em8300_eeprom_read(em, buf)) {
-				len += sprintf(page + len, "EEPROM data:");
+				len += sprintf(kbuf + len, "EEPROM data:");
 				for (i=0; i<256; i++) {
 					if (i%32 == 0)
-						len += sprintf(page + len, "\n\t");
-					len += sprintf(page + len, "%02x", buf[i]);
+						len += sprintf(kbuf + len, "\n\t");
+					len += sprintf(kbuf + len, "%02x", buf[i]);
 				}
-				len += sprintf(page + len, "\n");
+				len += sprintf(kbuf + len, "\n");
 			}
 			kfree(buf);
 		}
 		if (em->eeprom_checksum) {
-			len += sprintf(page + len, "EEPROM checksum: ");
+			len += sprintf(kbuf + len, "EEPROM checksum: ");
 			for (i=0; i<16; i++) {
-				len += sprintf(page + len, "%02x", em->eeprom_checksum[i]);
+				len += sprintf(kbuf + len, "%02x", em->eeprom_checksum[i]);
 			}
-			len += sprintf(page + len, "\n");
+			len += sprintf(kbuf + len, "\n");
 		}
 	}
-
-	len += sprintf(page + len,
+    
+    len += sprintf(kbuf + len,
 		       "Memory mapped at address range 0x%0lx->0x%0lx%s\n",
 		       (unsigned long int) em->mem,
 		       (unsigned long int) em->mem
 		       + (unsigned long int) em->memsize,
 		       em->mtrr_reg ? " (FIFOs using MTRR)" : "");
 	if (em->ucodeloaded) {
-		len += sprintf(page + len,
+		len += sprintf(kbuf + len,
 			       "Microcode version 0x%02x loaded\n",
 			       read_ucregister(MicroCodeVersion));
 		em8300_dicom_get_dbufinfo(em);
-		len += sprintf(page + len,
+		len += sprintf(kbuf + len,
 			       "Display buffer resolution: %dx%d\n",
 			       em->dbuf_info.xsize, em->dbuf_info.ysize);
-		len += sprintf(page + len,
+		len += sprintf(kbuf + len,
 			       "Dicom set to %s\n",
 			       em->dicom_tvout ? "TV-out" : "overlay");
 		if (em->dicom_tvout) {
-			len += sprintf(page + len,
+			len += sprintf(kbuf + len,
 				       "Using %s\n",
 				       (em->video_mode == EM8300_VIDEOMODE_PAL) ? "PAL" : "NTSC");
-			len += sprintf(page + len,
+			len += sprintf(kbuf + len,
 				       "Aspect is %s\n",
 				       (em->aspect_ratio == EM8300_ASPECTRATIO_4_3) ? "4:3" : "16:9");
 		} else {
-			len += sprintf(page + len,
+			len += sprintf(kbuf + len,
 				       "em9010 %s\n",
 				       em->overlay_enabled ? "online" : "offline");
-			len += sprintf(page + len,
+			len += sprintf(kbuf + len,
 				       "Video mapped to screen coordinates %dx%d (%dx%d)\n",
 				       em->overlay_frame_xpos, em->overlay_frame_ypos,
 				       em->overlay_xres, em->overlay_yres);
 		}
 	} else {
-		len += sprintf(page + len, "Microcode not loaded\n");
+		len += sprintf(kbuf + len, "Microcode not loaded\n");
 	}
-	len += sprintf(page + len,
+	len += sprintf(kbuf + len,
 		       "%s audio output\n",
 		       (em->audio_mode == EM8300_AUDIOMODE_ANALOG) ? "Analog" : "Digital");
-	return len;
+                  
+    result = copy_to_user(buffer + *offset, kbuf, len);
+    
+    if (result > 0) {
+        printk(KERN_ERR "em8300: procfs read callback failed: not enough space in user memory!\n");
+        }
+    
+    return len;
 }
 
-
 static void em8300_procfs_register_card(struct em8300_s *em)
 {
 	char devname[64];
-	if (em8300_proc) {
+	if (em8300_parent) {
 		struct proc_dir_entry *proc;
 		sprintf(devname, "%d", em->card_nr);
-		proc = create_proc_entry(devname,
+		proc = proc_create_data(devname,
 					 S_IFREG | S_IRUGO,
-					 em8300_proc);
-		if (proc) {
-			proc->data = (void *) em;
-			proc->read_proc = em8300_proc_read;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)
-			proc->owner = THIS_MODULE;
-#endif
+					 em8300_parent, 
+                     &em8300_fops,
+                     (void *) em);
+		if (!proc) {
+            printk(KERN_ERR "em8300: call to proc_create_data() failed!\n");
 		}
 	}
 }
@@ -164,30 +202,25 @@ static void em8300_procfs_register_card(
 static void em8300_procfs_unregister_card(struct em8300_s *em)
 {
 	char devname[64];
-	if (em8300_proc) {
+	if (em8300_parent) {
 		sprintf(devname, "%d", em->card_nr);
-		remove_proc_entry(devname, em8300_proc);
+		remove_proc_entry(devname, em8300_parent);
 	}
 }
 
 static void em8300_procfs_unregister_driver(void)
 {
-	if (em8300_proc) {
+	if (em8300_parent) {
 		remove_proc_entry(EM8300_PROCFS_DIR, NULL);
 	}
 }
 
 static void em8300_procfs_register_driver(void)
 {
-	em8300_proc = create_proc_entry(EM8300_PROCFS_DIR,
-					S_IFDIR | S_IRUGO | S_IXUGO,
-					NULL);
-	if (!em8300_proc)
-		printk(KERN_ERR "em8300: unable to register proc entry!\n");
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)
-	else
-		em8300_proc->owner = THIS_MODULE;
-#endif
+	em8300_parent = proc_mkdir(EM8300_PROCFS_DIR, NULL);
+	if (!em8300_parent)
+		printk(KERN_ERR "em8300: call to proc_mkdir() failed!\n");
+	
 }
 
 struct em8300_registrar_s em8300_procfs_registrar =
diff -Naurp modules/em8300_procfs.h modules_FIXED/em8300_procfs.h
--- modules/em8300_procfs.h	2009-12-20 23:24:56.000000000 +0100
+++ modules_FIXED/em8300_procfs.h	2017-08-26 05:35:34.000000000 +0200
@@ -23,6 +23,10 @@
 
 #include "em8300_registration.h"
 
+int     em8300_open         (struct inode *inode, struct file *file);
+int     em8300_close        (struct inode *inode, struct file *file);
+ssize_t em8300_proc_read    (struct file *fp, char __user *buffer, size_t buffer_size, loff_t *offset) ;
+
 extern struct em8300_registrar_s em8300_procfs_registrar;
 
 #endif /* EM8300_PROCFS_H */
diff -Naurp modules/em8300_sysfs.c modules_FIXED/em8300_sysfs.c
--- modules/em8300_sysfs.c	2009-12-20 23:24:56.000000000 +0100
+++ modules_FIXED/em8300_sysfs.c	2017-08-25 22:32:59.000000000 +0200
@@ -23,6 +23,7 @@
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,46)
 
+#include <linux/stat.h>
 #include <linux/device.h>
 #include <linux/pci.h>
 
diff -Naurp modules/em8300_udev.c modules_FIXED/em8300_udev.c
--- modules/em8300_udev.c	2009-12-20 23:24:56.000000000 +0100
+++ modules_FIXED/em8300_udev.c	2017-08-25 22:32:59.000000000 +0200
@@ -22,6 +22,7 @@
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,2)
 
+#include <linux/module.h>
 #include <linux/device.h>
 #include <linux/pci.h>
 #include <linux/kdev_t.h>
diff -Naurp modules/ldm modules_FIXED/ldm
--- modules/ldm	2009-12-20 23:24:56.000000000 +0100
+++ modules_FIXED/ldm	2017-08-26 23:43:55.000000000 +0200
@@ -2,12 +2,6 @@
 
 modprobe i2c-algo-bit
 
-if uname -r | sed -e 's/^\([[:digit:]]\+\)\.\([[:digit:]]\+\)\.\([[:digit:]]\+\).*/\1 * 65536 + \2 * 256 + \3 >= 2 * 65536 + 5 * 256 + 51/' | xargs expr > /dev/null; then
-    insmod adv717x.ko # pixelport_16bit=1 pixelport_other_pal=0 swap_redblue_pal=0 color_bars=1
-    insmod bt865.ko   # color_bars=1
-    insmod em8300.ko  # use_bt865=0 bt865_ucode_timeout=1 dicom_fix=0 dicom_control=0 dicom_other_pal=0
-else
-    insmod adv717x.o # pixelport_16bit=1 pixelport_other_pal=0 swap_redblue_pal=0 color_bars=1
-    insmod bt865.o   # color_bars=1
-    insmod em8300.o  # use_bt865=0 bt865_ucode_timeout=1 dicom_fix=0 dicom_control=0 dicom_other_pal=0
-fi
+insmod adv717x.ko # pixelport_16bit=1 pixelport_other_pal=0 swap_redblue_pal=0 color_bars=1
+insmod bt865.ko   # color_bars=1
+insmod em8300.ko  # use_bt865=0 bt865_ucode_timeout=1 dicom_fix=0 dicom_control=0 dicom_other_pal=0