LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Software > Linux - Kernel
User Name
Password
Linux - Kernel This forum is for all discussion relating to the Linux kernel.

Notices


Reply
  Search this Thread
Old 10-09-2009, 10:15 AM   #1
steegie
LQ Newbie
 
Registered: Oct 2009
Posts: 7

Rep: Reputation: 0
simple parallel port driver (parlel)


Hi,

I'm currently using the 'linux device drivers' book to get a better understanding of drivers in linux. I also found a simple parallel port driver on the net (Writing device drivers in Linux: A brief tutorial) and decided to try this one out.

The driver makes use of port address 0x378 and this first gave me an error since also the parport driver was using this port on my fc9 distro. Therefore I removed the ppdev, parport_pc and parport modules (i'm not sure if this is sufficient however). After this, the initialization of the driver was ok and I could find it back in /proc/ioports :

cat /proc/ioports
...
02f8-02ff : serial
0376-0376 : 0000:00:1f.1
0376-0376 : ata_piix
0378-0378 : parlelport
03c0-03df : vga+
03f0-03f1 : pnp 00:0f
...

So next step was to write to the driver and check the result :
echo -n A > /dev/parlelport

As a consequence, I should get a high value at pin2 and pin8, pin 3..7 and pin 9 should be low

After measuring I found out that all pins are high.... This is independent of the fact which character I write to the driver.

Reading back the values of the output port is done with
dd if=/dev/parlelport bs=1 count=1 | od -t x1
0000000 ff
1+0 records in
1+0 records out
1 byte (1 B) copied, 0.000611734 s, 1.6 kB/s

and gives me ff (the same value as I measure on the output port).

For some reason I'm not able to set the output port properly with this driver... Therefore I reloaded the parport driver again and I used parashell (a user program that can be used to write ports). This seems to work fine so I can conclude that my parallel port is not broken and that it has something to do with the driver itself (could be that there is a timing issue in the simple driver...).

Anyone an idea?

-----------------------------------------------------------------------------------------------------
Here's the complete code :

/* Necessary includes for drivers */
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h> /* printk() */
#include <linux/slab.h> /* kmalloc() */
#include <linux/fs.h> /* everything... */
#include <linux/errno.h> /* error codes */
#include <linux/types.h> /* size_t */
#include <linux/proc_fs.h>
#include <linux/fcntl.h> /* O_ACCMODE */
#include <linux/ioport.h>
#include <asm/system.h> /* cli(), *_flags */
#include <asm/uaccess.h> /* copy_from/to_user */
#include <asm/io.h> /* inb, outb */

/* Function declaration of parlelport.c */
int parlelport_open(struct inode *inode, struct file *filp);
int parlelport_release(struct inode *inode, struct file *filp);
ssize_t parlelport_read(struct file *filp, char *buf,
size_t count, loff_t *f_pos);
ssize_t parlelport_write(struct file *filp, char *buf,
size_t count, loff_t *f_pos);
int parlelport_init(void);
void parlelport_exit(void);

/* Structure that declares the common */
/* file access fcuntions */
struct file_operations parlelport_fops = {
read: parlelport_read,
write: parlelport_write,
open: parlelport_open,
release: parlelport_release
};
/* Driver global variables */
/* Major number */
int parlelport_major = 247;
/* Control variable for memory */
/* reservation of the parallel port*/
int port;

ssize_t parlelport_read(struct file *filp, char *buf,
size_t count, loff_t *f_pos) {
/* Buffer to read the device */
char parlelport_buffer;
int j;

parlelport_buffer = 'A';
printk("<1>parlelport: read value %c from port 0x378\n", parlelport_buffer);

parlelport_buffer = inb_p(0x378);
printk("<1>parlelport: read value %c from port 0x378\n", parlelport_buffer);

for (j = 7; j >= 0; j --)
{
if ( (parlelport_buffer & (1 << j)) )
printk("%d", 1);
else
printk("%d", 0);
}
printk("\n");

/* We transfer data to user space */
copy_to_user(buf,&parlelport_buffer,1);
/* We change the reading position as best suits */
if (*f_pos == 0) {
*f_pos+=1;
return 1;
} else {
return 0;
}
}

ssize_t parlelport_write( struct file *filp, char *buf,
size_t count, loff_t *f_pos) {
char *tmp;
/* Buffer writing to the device */
char parlelport_buffer;
tmp=buf+count-1;

parlelport_buffer = '5';
printk("<1>parlelport: write value %c to port 0x378\n", parlelport_buffer);

copy_from_user(&parlelport_buffer,tmp,1);
printk("<1>parlelport: write value %c to port 0x378\n", parlelport_buffer);
outb_p(parlelport_buffer,0x378);
return 1;
}

int parlelport_open(struct inode *inode, struct file *filp) {
/* Success */
return 0;
}

int parlelport_release(struct inode *inode, struct file *filp) {
/* Success */
return 0;
}

int parlelport_init(void)
{
int result;
/* Registering device */
result = register_chrdev(parlelport_major, "parlelport",
&parlelport_fops);
if (result < 0) {
printk(
"<1>parlelport: cannot obtain major number %d\n",
parlelport_major);
return result;
}
/* Registering port */
port = check_region(0x378, 1);
if (port) {
printk("<1>parlelport: cannot reserve 0x378\n");
result = port;
goto fail;
}
request_region(0x378, 1, "parlelport");

printk("<1>Inserting parlelport module\n");
return 0;
fail:
parlelport_exit();
return result;
}


void parlelport_exit(void)
{
/* Make major number free! */
unregister_chrdev(parlelport_major, "parlelport");
/* Make port free! */
if (!port) {
release_region(0x378,1);
}
printk("<1>Removing parlelport module\n");
}

module_init(parlelport_init);
module_exit(parlelport_exit);


MODULE_LICENSE("GPL");

Last edited by steegie; 10-09-2009 at 10:36 AM.
 
Old 10-12-2009, 09:16 AM   #2
steegie
LQ Newbie
 
Registered: Oct 2009
Posts: 7

Original Poster
Rep: Reputation: 0
After re-reading the article and the comments it seems that the unloading of the parport module is causing the parallel port to be in a unusable state. The kernel is configured to have the module available in the kernel's base image(not loadable). I will change the kernel configuration and see if this helps...
 
Old 10-12-2009, 10:32 AM   #3
steegie
LQ Newbie
 
Registered: Oct 2009
Posts: 7

Original Poster
Rep: Reputation: 0
I looked at my kernel configuration, but it seems that the parport driver is already configured as a loadable module. So Somebody is loading it at boot time. How can i make sure that the parport module isn't loaded at boot time?
 
Old 10-13-2009, 04:59 AM   #4
steegie
LQ Newbie
 
Registered: Oct 2009
Posts: 7

Original Poster
Rep: Reputation: 0
I found a solution for this :

The parport_pc driver is loaded by acpi at boot time.The unloading of this driver turns off the according parallel port hardware.

You need to configure the kernel in such a way that acpi is disabled (I believe it can be done by disabling CONFIG_PNP and CONFIG_PNPACPI...).

As a workaround I passed the acpi=off option in grub.conf for my kernel and after doing this, I could drive the outputs of my parallel port and read them back.

I was using kernel version 2.6.27.25. I don't know if newer versions have the same behaviour when unloading the parport_pc driver.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
My parallel port driver not working BilalMehdi Linux - Kernel 7 05-02-2012 08:36 AM
Parallel Port Device Driver Resmi Linux - Embedded & Single-board computer 2 01-07-2009 01:22 AM
Writing own parallel port driver mathimca05 Linux - Kernel 1 10-08-2008 06:03 AM
Parallel Port Device Driver rajtendulkar Linux - Hardware 4 03-16-2006 11:34 PM
Hidden Simple Parallel Port Problem, Croching Stupid Newbie novak Linux - Hardware 2 02-01-2004 04:04 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Software > Linux - Kernel

All times are GMT -5. The time now is 06:15 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration