c6205_driver_for_linux.txt
字号:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
//#include <linux/slab.h>
//#include <linux/completion.h>
//#include <linux/poll.h>
//#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <asm/semaphore.h>
#include <errno.h>
//***************************
#ifndef CONFIG_PCI
#define CONFIG_PCI
#endif
#include <linux/pci.h>
/*
预定义所需变量
*/
#define jmk_VendorID 0x104c
#define jmk_DeviceID 0xa106
unsigned int jmk_major=0;
struct pci_dev *jmkdev=NULL;
/*
定义卡可用资源区域
*/
unsigned long base0start=0,base0len=0;
unsigned long base1start=0,base1len=0;
unsigned long base2start=0,base2len=0;
unsigned long offset=0,step=0;
unsigned long i=0;//测试用作计数
void *iomembase=NULL;
// 这是2.4后的接口定义
/*
读取数据协议base0
buf[0] 要读取数据区域(0:mem 2:io)
buf[1] 要读取的数据类型(0:byte 1jmktest:word 2:dword)
buf[2] 要读取的数据起始地址偏移量
buf[3] 地址递增步长
count 要读字节数
*/
void jmk_read_base0_dword(unsigned long *buf,size_t count)
{
/*
获取参数
*/
offset=buf[2];
step=buf[3];
/*
读取数据
*/
for(i=0;i<count;i++)
{
//memcpy_fromio(buf,iomembase+offset,count);
buf[i]=readl(iomembase+offset);
offset+=step;
}
return;
}
/*
读取数据协议base2
buf[0] 要读取数据区域(0:mem 2:io)
buf[1] 要读取的数据起始地址偏移量
*/
void jmk_read_base2_dword(unsigned long *buf)
{
/*
获取参数
*/
offset=buf[1];
/*
读取数据
*/
buf[0]=inl(base2start+offset);
return;
}
static int jmk_read(struct file *file, unsigned long *buf, size_t count, loff_t *offset)
{
/*
取参数
*/
switch(buf[0])
{
case 0:
switch(buf[1])
{
case 0:
break;
case 1:
break;
case 2:
jmk_read_base0_dword(buf,count);
//printk("recv base0 cmd!\n");
break;
default:
count=-1;
break;
}
break;
case 1:
//printk("recv base1 cmd!\n");
break;
case 2:
jmk_read_base2_dword(buf);
//printk("recv base2 cmd!\n");
break;
default:
//printk("recv default cmd!\n");
count=-1;
break;
}
return count;
}
/*
写入数据协议base0
buf[0] 要写入数据区域(0:mem 2:io)
buf[1] 要写入的数据类型(0:byte 1jmktest:word 2:dword)
buf[2] 要写入的数据起始地址偏移量
buf[3] 地址递增步长
buf[4] 写入数据的起始地址
count 要读字节数
*/
void jmk_write_base0_dword(unsigned long *buf,size_t count)
{
/*
获取参数
*/
offset=buf[2];
step=buf[3];
/*
写入数据
*/
for(i=0;i<count;i++)
{
writel(buf[i+4],iomembase+offset);
offset+=step;
}
return;
}
/*
写入数据协议base2
buf[0] 要写入数据区域(0:mem 2:io)
buf[1] 要写入的数据起始地址偏移量
buf[2] 写入数据的起始地址
*/
void jmk_write_base2_dword(unsigned long *buf)
{
/*
获取参数
*/
offset=buf[1];
/*
写入数据
*/
outl(buf[2],base2start+offset);
return;
}
static int jmk_write(struct file *file, unsigned long *buf, size_t count, loff_t *offset)
{
/*
取参数
*/
switch(buf[0])
{
case 0:
switch(buf[1])
{
case 0:
break;
case 1:
break;
case 2:
jmk_write_base0_dword(buf,count);
// printk("recv base0 cmd!\n");
break;
default:
count=-1;
break;
}
break;
case 1:
//printk("recv base1 cmd!\n");
break;
case 2:
jmk_write_base2_dword(buf);
//printk("recv base2 cmd!\n");
break;
default:
//printk("recv default cmd!\n");
count=-1;
break;
}
return count;
}
static int jmk_open(struct inode *inode,struct file *file )
{
MOD_INC_USE_COUNT;
return 0;
}
// 在2.4中要一个返回值发现加密卡
static int jmk_release(struct inode *inode, struct file *file)
{
MOD_DEC_USE_COUNT;
return 0;
}
static struct file_operations jmk_fops = {
open: jmk_open,
read: jmk_read,
write: jmk_write,
release: jmk_release,
owner: THIS_MODULE,
};
//发现卡
//**********************************************
/*
主模块开始256
*/
int init_module(void)
{
int result;
unsigned long endsrc=0;
result = register_chrdev(0,"jmkdev",&jmk_fops);
if(result<0)
{
printk("jmk : can't get major number");
return result;
}
if(jmk_major==0)
{
jmk_major=result;
printk("jmk major number is %d!\n",jmk_major);
}
printk("hello world!\n");
/*
开始查找卡
*/
jmkdev=pci_find_device(jmk_VendorID,jmk_DeviceID,NULL);
if(!jmkdev)
{
printk("no kard!\n");
return -1;
}
else
{
printk("found card!\n");
}
/*
启用卡
*/
pci_enable_device(jmkdev);
/*
查找卡资源
*/
/*
base 0
*/
base0start=pci_resource_start(jmkdev,0);
endsrc=pci_resource_end(jmkdev,0);
base0len=endsrc-base0start;
printk("base 0 addr is 0x%x,len is 0x%x!\n",base0start,base0len);
/*
base 1
*/
base1start=pci_resource_start(jmkdev,1);
endsrc=pci_resource_end(jmkdev,1);
base1len=endsrc-base1start;
printk("base 1 addr is 0x%x,len is 0x%x!\n",base1start,base1len);
/*
base 2
*/
base2start=pci_resource_start(jmkdev,2);
endsrc=pci_resource_end(jmkdev,2);
base2len=endsrc-base2start;
printk("base 2 addr is 0x%x,len is 0x%x!\n",base2start,base2len);
/*
申请使用io内存
*/
request_mem_region(base0start,base0len,"jmkdev");
/*
映射io内存
*/
iomembase=ioremap(base0start,base0len);
if(iomembase==NULL)
{
printk("can't get iomem!\n");
}
else
{
printk("get iomem addr is 0x%x!\n",iomembase);
}
/*
测试获取数据base2
*/
/*
endsrc=inl(base2start+0x8);
printk("dspp the data is 0x%x!\n",endsrc);
endsrc=0x400;
outl(endsrc,base2start+0x8);
endsrc=inl(base2start+0x8);
printk("dspp the data is 0x%x!\n",endsrc);
endsrc=inl(base0start);
printk("base0start the data is 0x%x!\n",endsrc);
*/
/*
测试获取数据base0
*/
endsrc=readl(iomembase);
printk("base0 the data is 0x%x!\n",endsrc);
return 0;
}
void cleanup_module(void)
{
/*
释放io内存映射
*/
iounmap(iomembase);
/*
释放注册
*/
release_mem_region(base0start,base0len);
/*
禁用设备
*/
pci_disable_device(jmkdev);
/*
施放内存
*/
//free_page(buffer);
unregister_chrdev(jmk_major,"jmkdev");
printk("Goodbye cruel world!\n");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -