Need HELP for a tiny module driver

Gheorghe VELCSOV (rush@linux1.aut.utt.ro)
Fri, 13 Jun 1997 19:58:18 +0300 (EET DST)


Hi!

I need some help in a URGENTLY problem.

I need a driver which can be loaded into kernel as a module.
With this CHR driver -rdrv.c- I must send bytes through LP1 (0x378) Port
to a little robot - simple, without any acknowledge from robot.
I can't make it to run.
Without the 'outb_p' from rdrv_write() it works.
But with 'outp_b'(or 'outb') it give me a protection fault.
When I tried 'cat >/dev/rush54' it blocks.

We have a 2.0.30 Linux Kernel, gcc 2.7.2, lp.o is module and it
was unloaded on tests with rdrv.o.

I know you can help me. Please reply directly to my address. I'm not in
the list.

Many Thanks, Rush.

Here is the source.

------------------------------rdrv.c-----------------------------
// Compiled with: gcc -O2 -DMODULE -D__KERNEL__ -Wall -c rdrv.c

#include <linux/config.h>

#ifdef MODULE
#include <linux/module.h>
#include <linux/version.h>
#else
#define MOD_INC_USE_COUNT
#define MOD_DEC_USE_COUNT
#endif

#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/sched.h>
#include <linux/ioport.h>
#include <linux/fcntl.h>
#include <linux/delay.h>

#include <asm/io.h>
#include <asm/segment.h>
#include <asm/system.h>

#define RDRV_MAJOR 54
#define portLPT1 0x0378

static int write_rdrv(struct inode * inode, struct file * file,
const char * buf, int count) {
outb_p ((char) *buf, (unsigned short) portLPT1);
return count;
}

static int open_rdrv(struct inode *inode, struct file * file) {
MOD_INC_USE_COUNT;
return 0;
}

static void release_rdrv(struct inode *inode, struct file * file) {
MOD_DEC_USE_COUNT;
}

static struct file_operations rdrv_fops = {
NULL,
NULL,
write_rdrv,
NULL, /* no special rdrv_readdir */
NULL, /* no special rdrv_select */
NULL, /* no special rdrv_ioctl */
NULL, /* no special rdrv_mmap */
open_rdrv,
release_rdrv,
NULL, /* no special fsync */
NULL, /* no special fasync */
NULL, /* no special check_media_change */
NULL, /* no special revalidate */
};

#ifndef MODULE
long rdrv_init(long mem_start, long mem_end) {
if (rdrv_major = register_chrdev(RDRV_MAJOR, "rdrv", &rdrv_fops))
printk("ERROR\n");
return mem_start;
}

#else

int init_module(void){
if ((register_chrdev(RDRV_MAJOR, "rdrv", &rdrv_fops) ) == -EBUSY) {
unregister_chrdev(RDRV_MAJOR,"rdrv");
return -EIO;
}
if(check_region(portLPT1,1)<0){
return -1;
}
request_region(portLPT1, 8, "rdrv");
return 0;
}

void cleanup_module(void){
unregister_chrdev(RDRV_MAJOR, "rdrv");
release_region(portLPT1, 8);
}
#endif
------------------------------end of rdrv.c-------------------------------

_______________________________________________________________________________
Gheorghe VELCSOV Rush email: rush@linux1.aut.utt.ro
tel: +40-(0)56-230392