⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ppd.c

📁 并口打印机驱动源代码,看看用不用得上
💻 C
字号:
#ifndef __KERNEL__
# define __KERNEL__
#endif
#ifndef MODULE
# define MODULE
#endif

//#include <linux/malloc.h>
#include <linux/config.h>
#include <linux/module.h>
#include <linux/version.h>
#include <asm/uaccess.h>
#include <linux/sched.h>
#include <linux/kernel.h> /* printk() */
#include <linux/fs.h> /* everything... */
#include <linux/errno.h> /* error codes */
#include <linux/delay.h> /* udelay */
//#include </usr/src/linux-2.4/include/linux/malloc.h>
#include <linux/slab.h>

#include <linux/mm.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/tqueue.h>
#include <asm/io.h>

#define PPD_STATUS (*((volatile unsigned char *)(0xF0300000))) 
#define PPD_CONTROL (*((volatile unsigned char *)(0xF0200000))) 
#define PPD_DATA (*((volatile unsigned char *)(0xF0100000))) 
#define BUSY 0x80
#define STROBE 0x1

#ifdef MODULE_LICENSE
MODULE_LICENSE ("GPL");
#endif

static unsigned long base = 0xF0100000;
unsigned long short_base = 0xF0100000;
static unsigned long major = 15;
unsigned  int portnum = 0x00400000;

int
short_open (struct inode *inode, struct file *filp)
{
MOD_INC_USE_COUNT;
//PPD_CONTROL = 0xe;
//udelay(10);
return 0;
}

int
short_release (struct inode *inode, struct file *filp)
{
MOD_DEC_USE_COUNT;
return 0;
}

ssize_t
do_short_write (struct inode * inode, struct file * filp, const char *buf,
size_t count, loff_t * f_pos)
{
int retval = count;
//unsigned long address = short_base + 2;

unsigned char *kbuf = kmalloc (count, GFP_KERNEL), *ptr;

if (!kbuf)
return -ENOMEM;
if (copy_from_user (kbuf, buf, count))
return -EFAULT;
ptr = kbuf;

while (count--)
{
while ((PPD_STATUS&0x80) != 0);
	PPD_CONTROL = 0x7;
	udelay(10);
	
	PPD_DATA = *ptr;
	ptr++;
	udelay(5);
	
	PPD_CONTROL = 0x6;
	udelay(10);
	PPD_CONTROL = 0x7;
	//udelay(5);
//outb (*(ptr++), address);
//wmb ();
}

kfree (kbuf);
return retval;
}

ssize_t
do_short_read (struct inode * inode,
struct file * filp, char *buf, size_t count, loff_t * f_pos)
{
/*
int retval = count;
unsigned long address = short_base + 2;
unsigned char *kbuf = kmalloc (count, GFP_KERNEL), *ptr;

if (!kbuf)
return -ENOMEM;
ptr = kbuf;

while (count--)
{
*(ptr++) = inb (address);
rmb ();
}

if ((retval > 0) && copy_to_user (buf, kbuf, retval))
retval = -EFAULT;
kfree (kbuf);
return retval;
*/
return 0;
}

ssize_t
short_read (struct file * filp, char *buf, size_t count, loff_t * f_pos)
{
return do_short_read (filp->f_dentry->d_inode, filp, buf, count, f_pos);
}

ssize_t
short_write (struct file * filp, const char *buf, size_t count, loff_t * f_pos)
{
return do_short_write (filp->f_dentry->d_inode, filp, buf, count, f_pos);
}


struct file_operations short_fops = {
	owner:	THIS_MODULE,
	read:	short_read,
	write:	short_write,
	open:	short_open,
	release:  short_release,
};

int
init_module (void)
{
//int portnum = 0x00400000;
int result;

SET_MODULE_OWNER (&short_fops);

result = check_region (base, portnum);

if (result)
{
printk (KERN_INFO "short: can't get I/O port address 0x%lx\n",
short_base);
return result;
}
request_region (base, portnum, "lp0");

result = register_chrdev (major, "lp0", &short_fops);
if (result < 0)
{
printk (KERN_INFO "short: can't get major number\n");
release_region (short_base, portnum);
return result;
}
if (major == 0)
major = result;
//PPD_CONTROL = 0xe;
//udelay(10);
return 0;
}

void
cleanup_module (void)
{
printk ("major = 0x%lx\n", major);
unregister_chrdev (major, "lp0");
release_region (base, portnum);
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -