Registering a Midi Device in Modern Kernel Versions - c

I am currently writing a Linux Kernel module that will create a virtual Midi device so that a user-space program can send midi signals to any DAW-like software. I found a wonderful function to help me in my task: int register_sound_midi(const struct file_operations * fops, int dev). The problem is that this function ceased to exist after Kernel Version 4.15. From V15 to V16 the register and unregister functions just disappear. I'm now dumbfounded on how to register a fake midi device from the kernel in versions post 4.15. How can I register a midi device in versions of Kernel post 4.15? Is it possible to make the module backwards compatible with older kernel versions?
Current Code:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/sound.h>
#include <sound/core.h>
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Module to create dummy midi devices.");
MODULE_VERSION("0.01");
static int dummy_midi_open(struct inode *, struct file *);
static int dummy_midi_release(struct inode *, struct file *);
static ssize_t dummy_midi_read(struct file *, char *, size_t, loff_t *);
static ssize_t dummy_midi_write(struct file *, const char *, size_t, loff_t *);
static struct file_operations dummy_midi_fops = {
.owner = THIS_MODULE,
.read = dummy_midi_read,
.write = dummy_midi_write,
.open = dummy_midi_open,
.release = dummy_midi_release
};
static int minor;
static int dummy_midi_open(struct inode *midi_inode, struct file *midi_file)
{
printk(KERN_INFO"Open\n");
return 0;
}
static int dummy_midi_release(struct inode *midi_inode, struct file *midi_file)
{
printk(KERN_INFO"Release\n");
return 0;
}
static ssize_t dummy_midi_read(struct file *filp, char *buf, size_t count, loff_t *f_pos)
{
printk(KERN_INFO"Read\n");
return 0;
}
static ssize_t dummy_midi_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos)
{
printk(KERN_INFO"Write\n");
return 0;
}
static int __init midimodule_init(void)
{
printk(KERN_INFO"Initializing Module\n");
minor = register_sound_midi(&dummy_midi_fops,-1);
printk(KERN_INFO"Registered MIDI Device: %d\n",minor);
return 0;
}
static void __exit midimodule_exit(void)
{
printk(KERN_INFO"Leaving now\n");
unregister_sound_midi(minor);
printk(KERN_INFO"Unregistered MIDI Device: %d\n",minor);
}
module_init(midimodule_init);
module_exit(midimodule_exit);

Related

Linux Device Driver -- file operations not working

I have recently updated my kernel and I am no longer able to use a previously written device drivers. My driver's init and exit functions work fine and log a message to the kernel log. However, I am no longer able to write, read, ioctl, open, or release the file. The functions do not print anything into the log file. I am compiling against linux-headers-5.4.79-v7l+.
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/kdev_t.h>
#include <linux/cdev.h>
#include <linux/uaccess.h>
#include <linux/slab.h>
MODULE_LICENSE("Dual BSD/GPL");
#define DEVICE_NAME "device"
static int device_open(struct inode *, struct file *);
static int device_release(struct inode *, struct file *);
static ssize_t device_read(struct file *, char *, size_t, loff_t *);
static ssize_t device_write(struct file *, const char *, size_t, loff_t *);
static long int device_ioctl(struct file *, unsigned int, unsigned long);
static struct file_operations fops =
{
owner: THIS_MODULE,
read: device_read,
write:device_write,
unlocked_ioctl: device_ioctl,
open: device_open,
release: device_release
};
struct cdev *device_cdev;
dev_t deviceNumbers;
static int init(void)
{
int ret = alloc_chrdev_region(&deviceNumbers, 0, 1, DEVICE_NAME);
if (ret < 0) {
printk(KERN_ALERT "Error registering: %d", ret);
return -1;
}
device_cdev = cdev_alloc();
cdev_init(device_cdev, &fops);
ret = cdev_add(device_cdev, deviceNumbers, 1);
printk(KERN_INFO "Device initialized");
return 0;
}
static void cleanup(void)
{
unregister_chrdev_region(deviceNumbers, 1);
cdev_del(device_cdev);
printk(KERN_INFO "Device unloaded");
}
static int device_open(struct inode *inode, struct file *file)
{
printk(KERN_INFO "Device open");
return 0;
}
static int device_release(struct inode *inode, struct file *file)
{
printk(KERN_INFO "Device released");
return 0;
}
static ssize_t device_write(struct file *filp, const char *buff, size_t len, loff_t * off)
{
printk(KERN_INFO "Device write");
return 0;
}
static ssize_t device_read(struct file *filp, char *buff, size_t len, loff_t * off)
{
printk(KERN_INFO "Device read");
return 0;
}
static long int device_ioctl(struct file *file, unsigned int ioctl_num, unsigned long ioctl_param)
{
printk(KERN_INFO "Device IOCTL");
return 0;
}
module_init(init);
module_exit(cleanup);
You should add terminating "\n" at the end of your prints to force their flush into the kernel log buffer. Here is your module with some enhancement suggestions:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/kdev_t.h>
#include <linux/cdev.h>
#include <linux/uaccess.h>
#include <linux/slab.h>
MODULE_LICENSE("Dual BSD/GPL");
#define DEVICE_NAME "device"
static int device_open(struct inode *, struct file *);
static int device_release(struct inode *, struct file *);
static ssize_t device_read(struct file *, char *, size_t, loff_t *);
static ssize_t device_write(struct file *, const char *, size_t, loff_t *);
static long int device_ioctl(struct file *, unsigned int, unsigned long);
static const struct file_operations fops =
{
.owner= THIS_MODULE,
.read= device_read,
.write=device_write,
.unlocked_ioctl= device_ioctl,
.open= device_open,
.release= device_release
};
struct cdev *device_cdev;
dev_t deviceNumbers;
static int __init init(void) // <------ Add __init keyword for kernel cleanups
{
// This returns the major number chosen dynamically in deviceNumbers
int ret = alloc_chrdev_region(&deviceNumbers, 0, 1, DEVICE_NAME);
if (ret < 0) {
printk(KERN_ALERT "Error registering: %d\n", ret);
return -1;
}
device_cdev = cdev_alloc();
cdev_init(device_cdev, &fops);
ret = cdev_add(device_cdev, deviceNumbers, 1);
printk(KERN_INFO "Device initialized (major number is %d)\n", MAJOR(deviceNumbers));
return 0;
}
static void __exit cleanup(void) // <------ Add __exit keyword for kernel cleanups
{
unregister_chrdev_region(deviceNumbers, 1);
cdev_del(device_cdev);
printk(KERN_INFO "Device unloaded\n");
}
static int device_open(struct inode *inode, struct file *file)
{
printk(KERN_INFO "Device open\n");
return 0;
}
static int device_release(struct inode *inode, struct file *file)
{
printk(KERN_INFO "Device released\n");
return 0;
}
static ssize_t device_write(struct file *filp, const char *buff, size_t len, loff_t * off)
{
printk(KERN_INFO "Device write\n");
return len; // <-------------- To stop the write
}
static ssize_t device_read(struct file *filp, char *buff, size_t len, loff_t * off)
{
printk(KERN_INFO "Device read\n");
return len; // <-------------- To stop the read
}
static long int device_ioctl(struct file *file, unsigned int ioctl_num, unsigned long ioctl_param)
{
printk(KERN_INFO "Device IOCTL\n");
return 0;
}
module_init(init);
module_exit(cleanup);
Check the current settings for the kernel log level.
$ cat /proc/sys/kernel/printk
4 4 1 7
In the preceding, the first column specifies that only messages with a log level lower than 4 will be printed.
The values accepted by printk() are:
KERN_EMERG 0 System is unusable
KERN_ALERT 1 Action must be taken immediately
KERN_CRIT 2 Critical conditions
KERN_ERR 3 Error conditions
KERN_WARNING 4 Warning conditions
KERN_NOTICE 5 Normal but significant condition
KERN_INFO 6 Informational
KERN_DEBUG 7 Debug-level messages
So, the KERN_INFO level is 6 which is greater than 4!
We modify the configuration:
$ sudo sh -c "echo 7 4 1 7 > /proc/sys/kernel/printk"
$ cat /proc/sys/kernel/printk
7 4 1 7
I built your module with the suggested modifications and tried it on Linux 5.4.0-58:
$ uname -a
Linux xxxx 5.4.0-58-generic #64-Ubuntu SMP Wed Dec 9 08:16:25 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
$ sudo insmod ./device.ko
$ dmesg
[...]
[ 7244.516706] Device initialized (major number is 235)
$ lsmod
Module Size Used by
device 16384 0
[...]
$ cat /proc/devices
Character devices:
[...]
235 device
$ sudo mknod /dev/device c 235 0
$ ls -l /dev/device
crw-r--r-- 1 root root 235, 0 janv. 3 10:33 /dev/device
$ sudo sh -c "echo foo > /dev/device"
$ dmesg
[...]
[ 7244.516706] Device initialized (major number is 235)
[ 7311.507652] Device open
[ 7311.507672] Device write
[ 7311.507677] Device released
$ sudo rmmod device
$ dmesg
[...]
[ 7244.516706] Device initialized (major number is 235)
[ 7311.507652] Device open
[ 7311.507672] Device write
[ 7311.507677] Device released
[ 7361.523964] Device unloaded
$ sudo rm /dev/device

writing driver - "Failed to register device class"

I am trying to write a character device driver based on this tutorial.
But when trying to insert my module I get the following error:
$ sudo insmod modules/main/main.ko
insmod: ERROR: could not insert module modules/main/main.ko: Operation not permitted
$dmesg
[ 1085.409026] Failed to register device class
This is the corresponding code snippet:
#ifndef __KERNEL__
#define __KERNEL__
#endif
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/device.h>
#define CLASS_NAME "my_class"
#define DEV_NAME "my_device"
static int dev_open(struct inode *, struct file *);
static int dev_release(struct inode *, struct file *);
static ssize_t dev_read(struct file *, char *, size_t, loff_t *);
static ssize_t dev_write(struct file *, const char *, size_t, loff_t *);
static int myCharClass;
static int myCharDevice;
int majorNumber;
static struct file_operations fops =
{
.open = dev_open,
.read = dev_read,
.write = dev_write,
.release = dev_release
};
int init_module(void)
{
printk("Hello world - DAO \n");
majorNumber = register_chrdev(0, DEV_NAME, &fops);
if (majorNumber < 0)
{
printk("Error when registering character device driver.\n");
return -1;
}
myCharClass = class_create(THIS_MODULE, CLASS_NAME);
if (IS_ERR(myCharClass))
{
unregister_chrdev(majorNumber, DEV_NAME);
printk(KERN_ALERT "Failed to register device class\n");
return -1;
}
myCharDevice = device_create(myCharClass, NULL, MKDEV(majorNumber, 0), NULL, DEV_NAME);
if (IS_ERR(myCharDevice))
{
class_destroy(myCharClass);
unregister_chrdev(majorNumber, DEV_NAME);
printk(KERN_ALERT "Failed to create the device\n");
return -1;
}
return 0;
}
void cleanup_module(void)
{
printk("<1> Ciao - DAO\n");
}
static int dev_open(struct inode *p_inode, struct file *p_file)
{
printk("Opened device.\n");
return 0;
}
static ssize_t dev_read(struct file *filep, char *buffer, size_t len, loff_t *offset)
{
printk("Reading device.\n");
return 0;
}
static ssize_t dev_write(struct file *filep, const char *buffer, size_t len, loff_t *offset)
{
printk("Writing device\n");
return 0;
}
static int dev_release(struct inode *inodep, struct file *filep)
{
printk("Releasing device.\n");
return 0;
}
MODULE_LICENSE("GPL");
Does anybody know what I am doing incorrectly?
I had a look at this post, but it didn't really help me, because I didn't really what the issue is.
Thanks

char driver node is not opening

I wrote a simple char driver for my beaglebone kernel
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/uaccess.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/fs.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("mrigendra.chaubey#gmail.com");
#define DEVICE_NAME "experm"
#define CLASS_NAME "exp"
static struct class* myclass = NULL; ///< The device-driver class struct pointer
static struct device* mychardevice = NULL; ///< The device-driver device struct pointer
static int myopen(struct inode *, struct file *);
static int release(struct inode *, struct file *);
static int myioctl(struct inode *, struct file *, unsigned int cmd, unsigned long arg);
static size_t myread(struct file *,char * , size_t, loff_t *);
static size_t mywrite(struct file *,char * , size_t, loff_t *);
static dev_t mydev;
static int myopen(struct inode *nd, struct file *fp)
{
printk(KERN_INFO "myopen\n");
return 0;
}
static int myrelease(struct inode *nd, struct file *fp)
{
printk(KERN_INFO "myrelease\n");
return 0;
}
static int myioctl(struct inode *nd, struct file *fp, unsigned int cmd, unsigned long arg)
{
printk(KERN_INFO "myioctl\n");
return 0;
}
static size_t myread(struct file *fp, char *buf, size_t len, loff_t *ofs)
{
printk(KERN_INFO "myread\n");
return 0;
}
static size_t mywrite(struct file *fp, char *buf, size_t len, loff_t *ofs)
{
printk(KERN_INFO "mywrite\n");
return 0;
}
static struct file_operations fops = {
.open = myopen,
.release = myrelease,
.read = myread,
.write = mywrite,
.unlocked_ioctl = myioctl,
};
static int __init myinit(void)
{
int err;
//extern int alloc_chrdev_region(dev_t *, unsigned minor number, unsigned total, const char *);
err = alloc_chrdev_region(&mydev, 0, 1, "expermdev");
if(err<0)
{
printk(KERN_INFO "major and minor can't be created, err = %d\n", err);
return err;
}
//struct class * class_create ( struct module *owner, const char *name);
myclass = class_create(THIS_MODULE, CLASS_NAME);
if(IS_ERR(myclass))
{
unregister_chrdev(MAJOR(mydev), "expermdev");
printk(KERN_ALERT "Failed to register device class\n");
return PTR_ERR(myclass);
}
//struct device *device_create(struct class *cls, struct device *parent, dev_t devt, void *drvdata, const char *fmt, ...);
//This function can be used by char device classes. A struct device will be created in sysfs, registered to the specified class.
mychardevice = device_create(myclass, NULL, mydev, NULL, "expermdev");
if(IS_ERR(mychardevice))
{
class_destroy(myclass);
unregister_chrdev(MAJOR(mydev), "expermdev");
printk(KERN_ALERT "Failed to create the device\n");
return PTR_ERR(mychardevice);
}
printk(KERN_INFO "my device created correctly\n");
return 0;
}
static void __exit myexit(void)
{
device_destroy(mychardevice, mydev);
class_unregister(myclass);
class_destroy(myclass);
unregister_chrdev(MAJOR(mydev), "expermdev");
printk(KERN_INFO "exited\n");
}
module_init(myinit);
module_exit(myexit);
and app.c file
#include <stdio.h>
#include<fcntl.h>
int main()
{
int fp;
fp = open ("/dev/expermdev", O_RDWR);
if(fp < 0)
printf("file can't be opened\n");
else
printf("file opened\n");
return 0;
}
I am compiling the driver as a module and insmod it, also compiled app.c with the same cross compiler, and put this binary in bin directory. I ran this bin file, but it says
file can't be opened
What am I doing wrong?
Got it. I did not used cdev struture and added fops to it. After that I have to tell kernel about it.
cdev = cdev_alloc();//allocate memory to Char Device structure
cdev->ops = &fops;//link our file operations to the char device
result=cdev_add(cdev,mydev,1);//Notify the kernel abt the new device
also delete this cdev in exit function before unregistering the driver.
In register_chrdev_region we do both things at the same time, but in dynamic allocation of major and minor numbers we have to use cdev to do the rest.

endlessly looping when reading from character device

For a homework assignment, I have written a character device driver. It seems to work OK. I can read and write it. The problem is that when I read the device, it endlessly loops, printing out the contents of the message buffer over and over.
This seems like it should be fairly straight forward. Just use copy_to_user(), but it's proven to be very problematic.
Anyway, here is the code. I think the problem is in the gdev_read() function.
The printk's are there to serve as debugging as well as talking points, since I have to present the project in class.
/*
* Implement a generic character pseudo-device driver
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/types.h>
#include <linux/vmalloc.h>
#include <asm/uaccess.h>
/* you need these, or the kernel will be tainted */
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("A simple sample character device driver");
/*
* function prototypes
*/
int init_module(void);
void cleanup_module(void);
static ssize_t gdev_read(struct file *, char *, size_t, loff_t *);
static ssize_t gdev_write(struct file *, const char *, size_t, loff_t *);
static int gdev_open(struct inode *, struct file *);
static int gdev_release(struct inode *, struct file *);
/* macros */
#define TRUE 1
#define FALSE 0
#define MAX_MSG_LEN 64
/*
* global variables
*/
static dev_t dev_num; /* device number, for new device */
static char *mesg; /* buffer for message */
/* file operations structure, so my device knows how to act */
static struct file_operations fops = {
.owner = THIS_MODULE,
.read = gdev_read,
.write = gdev_write,
.open = gdev_open,
.release = gdev_release,
};
/* character device struct. Declaired here, but initialized elsewhere */
struct cdev *gdev;
int init_module(void)
{
int err;
printk(KERN_ALERT "in init_module\n");
if(alloc_chrdev_region(&dev_num, 0, 1, "/dev/gdev")){
printk(KERN_INFO "Could not allocate device numbers\n");
printk(KERN_INFO "Module gdev not loaded\n");
return -1;
}
/* now I need to make the device and register it */
gdev = cdev_alloc();
gdev->owner = THIS_MODULE;
gdev->ops = &fops;
err = cdev_add(gdev, dev_num, 1);
if(err){
printk(KERN_NOTICE "Error %d adding gdev", err);
return err;
}
mesg = (char *)vmalloc(MAX_MSG_LEN);
printk(KERN_INFO "Module gdev successfully loaded.\n");
printk(KERN_INFO "gdev Major Number: %d\n", MAJOR(dev_num));
return 0;
}
void cleanup_module(void)
{
printk(KERN_ALERT "in cleanup_module\n");
unregister_chrdev_region(dev_num, 3);
vfree(mesg);
cdev_del( gdev );
printk(KERN_INFO "Module gdev unregistered\n");
}
static ssize_t gdev_read(struct file *filp, char *page,
size_t len, loff_t *offset)
{
ssize_t bytes = len < MAX_MSG_LEN ? len : MAX_MSG_LEN;
printk(KERN_ALERT "in gdev_read\n");
if(copy_to_user(page, mesg, bytes)){
return -EFAULT;
}
return bytes;
}
static ssize_t gdev_write(struct file *filp, const char *page,
size_t len, loff_t *offset)
{
ssize_t bytes = len < MAX_MSG_LEN ? len : MAX_MSG_LEN;
printk(KERN_ALERT "in gdev_write\n");
if(copy_from_user(mesg, page, bytes)){
return -EFAULT;
}
return bytes;
}
static int gdev_open(struct inode *inode, struct file *filp)
{
printk(KERN_ALERT "in gdev_open\n");
return 0;
}
static int gdev_release(struct inode *inode, struct file *filp)
{
printk(KERN_ALERT "in gdev_release\n");
/* doesn't do anything because it doesn't need too */
return 0;
}
If zero is not returned from read() (in your case gdev_read()), the read function will be called again.
To stop this you use the loff_t *offset parameter. Increment it by how many bytes you have read using (*offset) += bytes; after copy_to_user(). Next time read() is called, offset will be what you have incremented it to. Now just check how many bytes you have previously sent, and only send what you still have remaining. Your function should look like this:
static ssize_t gdev_read(struct file *filp, char *page,
size_t len, loff_t *offset)
{
ssize_t bytes = len < (MAX_MSG_LEN-(*offset)) ? len : (MAX_MSG_LEN-(*offset));
printk(KERN_ALERT "in gdev_read\n");
if(copy_to_user(page, mesg, bytes)){
return -EFAULT;
}
(*offset) += bytes;
return bytes;
}
You could use 'simple_read_from_buffer' function from 'linux/fs.h':
static ssize_t gdev_read(struct file *filep, char __user *buff, size_t count, loff_t *offp)
{
return simple_read_from_buffer(buff, count, offp, my_buffer, buffer_len);
}
'my_buffer' and 'buffer_len' are defined in your module.

Accessing the parallel port hardware on linux

I wrote a parallel port Linux device driver but I cant access the parallel port hardware
#include <linux/init.h>
#include <linux/autoconf.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/proc_fs.h>
#include <linux/fcntl.h>
#include <linux/ioport.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#define DRVNAME "parportleds"
#define BASEPORT 0x378
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Ganesh");
MODULE_DESCRIPTION("Parallel port LED driver.");
int parportleds_open(struct inode *inode, struct file *filp);
int parportleds_release(struct inode *inode, struct file *filp);
ssize_t parportleds_read(struct file *filp,char *buf,size_t count, loff_t *f_pos);
ssize_t parportleds_write(struct file *filp, const char *buf,size_t count, loff_t *f_pos);
void parportleds_exit(void);
int parportleds_init(void);
struct file_operations parportleds_fops = {
read: parportleds_read,
write: parportleds_write,
open: parportleds_open,
release: parportleds_release
};
int parportleds_major = 61;
int port;
module_init(parportleds_init);
module_exit(parportleds_exit);
int parportleds_init(void) {
int result;
result = register_chrdev(parportleds_major, DRVNAME,&parportleds_fops);
if (result < 0) {
printk("<1>parport: cannot obtain major number %d\n",parportleds_major);
return result;
}
port = check_region(BASEPORT, 1);
if (port) {
printk("<1>parportleds: cannot reserve 0x378 \n");
result = port;
goto fail;
}
request_region(BASEPORT, 1, DRVNAME);
printk("<1>Inserting parportled module\n");
return 0;
fail:
parportleds_exit();
return result;
}
void parportleds_exit(void) {
unregister_chrdev(parportleds_major, DRVNAME);
if (!port) {
release_region(BASEPORT,1);
}
printk("<1>Removing module parportleds\n");
}
int parportleds_open(struct inode *inode, struct file *filp) {
return 0;
}
int parportleds_release(struct inode *inode, struct file *filp) {
return 0;
}
ssize_t parportleds_read(struct file *filp, char *buf,size_t count, loff_t *f_pos) {
char parportleds_buffer;
parportleds_buffer = inb(BASEPORT);
copy_to_user(buf,&parportleds_buffer,1);
if (*f_pos == 0) {
*f_pos+=1;
return 1;
} else {
return 0;
}
}
ssize_t parportleds_write( struct file *filp, const char *buf, size_t count, loff_t *f_pos) {
char *tmp;
char parportleds_buffer;
tmp=(char *)buf+count-1;
copy_from_user(&parportleds_buffer,tmp,1);
outb(parportleds_buffer,BASEPORT);
printk("<1>parport write: %d\n",parportleds_buffer);
return 1;
}
This is my code when I try to read and write to /dev/parportleds am getting a sucess msg in dmesg
But when i try to make a pin high of parallel port using echo 3 > /dev/parportleds
The voltage of the datapins of paralleport remains same.
can anyone help me to fix this issue.
its my first attempt to write device drivers.
A couple of notes first:
1) Take note of InternetSeriousBusiness' comment: when you echo a character to your char device, the device will receive the ASCII encoded bit pattern. Look at an ASCII table to see which character you need to send to get the bit pattern you want.
2) You mentioned that when you send a bit pattern, the output voltage doesn't change. What about the other direction? Does the value you read accurately reflect voltages applied to the pins, or are those off to? If yes, then you know problem has something to do with writing. If no, then you may not even be connected to the port the way you think you are.
My Answer:
Buffers that interact with user data should have the __user tag attached. For example, the argument list of parportleds_write(), should look like this:
ssize_t parportleds_write(struct file *fp, const char __user *buf, ssize_t count, loff_t *f_pos){
Your call to copy_from_user() may be failing because this is missing. The __user tag should be added to your read function as well.

Resources