A message for Linux.com registered users: We are in the process of making changes to the Linux forums. Starting Monday, 8/13/18 at 6:00 PM PT, you will be unable to access the forums. They will re-launch as soon as possible on Wednesday, 8/15/18 with new features and improved functionality. Thank you for your patience and stay tuned for the new improved forums.

October 11, 2010

Parallel port driver not working?!

Hello everyone!
I've been doing some kernel module development for Linux lately, and I figured: Why not make a 6V LED light up?
So I hooked up to wires with the LED and plugged the wires into hole/pin 2 and 25 (data0 and GND respectively) of my parallel port. Now all I needed was the device driver.. now the device driver is done..... it's not working.
I have tested my homegrown "LED hardware" standalone with a 1.5V battery, which did make the LED glow slightly, so the 5V of the parallel port should definitely make it glow!
I have made a virtual device using 'mknod' to communicate with the parallel port at 0x378 (confirmed, by the way).
This is my mknod command: "sudo mknod /dev/parlelport c 61 0", and finally, to make the "device" accessible to anyone: "sudo chmod 666 /dev/parlelport".
I can not insert the module with parport_pc running, so I remove that and the modules using it, before I 'insmod' my kernel module, which looks like this:

#include <linux/module.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <asm/io.h>

ssize_t driver_read(struct file *filp, char *buf, size_t count, loff_t *f_pos);
ssize_t driver_write(struct file *filp, char *buf, size_t count, loff_t *f_pos);
int driver_open(struct inode *inode, struct file *filp);
int driver_release(struct inode *inode, struct file *filp);

int major = 61;
int port;

struct file_operations f_ops = {
read: driver_read,
write: driver_write,
open: driver_open,
release: driver_release

void driver_exit(void){
unregister_chrdev(major, "parlelport");

release_region(0x378, 1);

printk("<parallel_port_module>: Removing...\n");

int driver_init(void){
int result;
result = register_chrdev(major, "parlelport", &f_ops);

if(result < 0){
printk("<parallel_port_module>: Unable to register module!\n");
return result;

port = check_region(0x378, 1);

printk("<parallel_port_module>: Requested region already reserved!\n");
result = port;
goto fail;

request_region(0x378, 1, "parlelport");
printk("<parallel_port_module>: Inserting...\n");
return 0;

return result;

ssize_t driver_read(struct file *filp, char *buf, size_t count, loff_t *f_pos){
char buffer;
int status;
buffer = inb(0x378);
status = copy_to_user(buf, &buffer, 1);

case 0:
printk("%i\n", buffer);

if(*f_pos == 0){
*f_pos += 1;
return 0;
return 0;

ssize_t driver_write(struct file *filp, char *buf, size_t count, loff_t *f_pos){
char *tmp;
char buffer;
int status;
tmp = buf + count - 1;

status = copy_from_user(&buffer, tmp, 1);
outb(buffer, 0x378);

if(status == 0){
printk("%i\n", buffer);

return 1;

int driver_open(struct inode *inode, struct file *filp){
return 0;

int driver_release(struct inode *inode, struct file *filp){
return 0;

MODULE_AUTHOR("Benjamin D####");

I DO get a "/home/benjamin/Documents/c/kernel/parlelport/parlelport.c:16: warning: initialization from incompatible pointer type" waning when compiling from my Makefile though.. I don't know to fix it..

Line 16: write: driver_write,

Apparently it does register, reserve, and initialize correctly but something with the data in/outputs just doesn't seem right...
As you can see my read and write functions log the data they in/output, and when doing an 'echo -n A >/dev/parlelport' followed by a 'cat /dev/parlelport', this shows up in my system log, NO MATTER WHAT DATA I WRITE TO THE DEVICE:

[ 1962.448227]
: Inserting...
[ 1985.132240] 65
[ 1994.501861] -1

Only '65' might change depending on what char I sent too the parlelport device, but I always receive -1 from the parallel port.....

Click Here!