📄 ppd.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 + -