📄 trndrv.c
字号:
// trndrv.c - the framework of PCI card driver in LINUX.
// By ---- -- (XWorm) Dec. 11 2001
// xworm@eyou.com
//
// This file is written as an example of CHAR-type driver in LINUX.
// It serves a PCI card. It is free to copy and distribute in non-commercial
conditions.
// There is no warranty provided by the programmer. And no responsibility of
programmer
// is available to the results of the programs.
#ifndef CONFIG_PCI
#define CONFIG_PCI
#endif
#ifndef CONFIG_PROC_FS
#define CONFIG_PROC_FS
#endif
#include <linux/pci.h>
#include <linux/proc_fs.h>
#include <linux/module.h>
#include <asm/uaccess.h>
/*****************************************\
|* IOCTL MACRO DEFINITIONS *|
\*****************************************/
#define TRNDRV_IOC_MAGIC 'k'
#define TRNDRV_IOCREADCONFREGS _IOR(TRNDRV_IOC_MAGIC, 0, 0x40)
#define TRNDRV_IOCREADOPERREGS _IOR(TRNDRV_IOC_MAGIC, 1, 0x40)
#define TRNDRV_IOC_MAXNR 2
/*****************************************\
|* IOCTL MACRO DEFINITIONS *|
\*****************************************/
#define VENDORID 0x1234 // unsigned short for vendor id of the PCI card
#define DEVICEID 0x4321 // unsigned short for device id of the PCI card
/*****************************************\
|* GLOBAL DEFINITIONS *|
\*****************************************/
struct pci_dev *pdev = NULL;
int readconfregs(u8 *regs);
int readoperregs(u8 *regs);
/****************************************\
|* Driver "trndrv.o"`s entries *|
\****************************************/
loff_t trndrv_llseek(struct file *filp, loff_t off, int whence)
{
loff_t newpos = -EINVAL;
return newpos;
}
int trndrv_open(struct inode *inode, struct file *filp)
{
return 0;
}
int trndrv_release(struct inode *inode, struct file *filp)
{
return 0;
}
ssize_t trndrv_read(struct file *filp, char *buf, size_t count,
loff_t *f_pos)
{
return 0;
}
ssize_t trndrv_write(struct file *filp, const char *buf, size_t count,
loff_t *f_pos)
{
return 0;
}
int trndrv_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
u8 regs[256];
int i;
switch (cmd)
{
case TRNDRV_IOCREADCONFREGS:
if (readconfregs(regs))
return -PCIBIOS_BAD_REGISTER_NUMBER;
for (i = 0; i < 256; i ++)
put_user(regs[i], (u8 *)(arg + i));
break;
case TRNDRV_IOCREADOPERREGS:
readoperregs(regs);
break;
default:
return -EINVAL;
}
return 0;
}
struct file_operations trndrv_fops = {
llseek: trndrv_llseek,
read: trndrv_read,
write: trndrv_write,
ioctl: trndrv_ioctl,
open: trndrv_open,
release: trndrv_release,
};
/*****************************************\
|* Self-defined Functions *|
\*****************************************/
struct proc_dir_entry *create_proc_fops_entry(const char *name,
mode_t mode, struct proc_dir_entry *base,
void * data)
{
struct proc_dir_entry *result = create_proc_entry(name, mode, base);
if (result)
{
result->proc_fops = &trndrv_fops;
result->data = data;
}
return result;
}
int readconfregs(u8 *regs)
{
int result;
int i;
for (i = 0; i < 256; i ++)
{
result = pci_read_config_byte(pdev, i, regs + i);
if (result)
{
printk(KERN_EMERG "reading config regs error\n");
return result;
}
}
return 0;
}
int readoperregs(u8 *regs)
{
return 0;
}
void cleanup_module(void)
{
remove_proc_entry("trndrv", 0);
}
int init_module(void)
{
create_proc_fops_entry("trndrv", 0, NULL, NULL);
pdev = pci_find_device(VENDORID, DEVICEID, NULL);
if (pdev == NULL)
{
printk(KERN_EMERG "no pci card specified\n");
return -PCIBIOS_DEVICE_NOT_FOUND;
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -