-
Linux2.6
内核
PCI
< br>驱动程序开发
一,
PCI
p>
相关数据结构说明
1.1
struct
pci_driver
这个数据结构在文件
/linux/p
ci.h
里,这是
Linux
内核版本
2.4
之后为新型的
PCI
设备驱
动程序所添加的,其中最主要的是用于识别设备的
< br>id_table
结构,以及用于检测设备的函数
pro
be( )
和卸载设备的函数
remove(
)
。
struct pci_driver {
struct list_head node;
char *name;
const struct pci_device_id *id_table;
int
(*probe)
(struct
pci_dev *dev, const struct pci_device_id *id);
void (*remove) (struct
pci_dev *dev);
int
(*save_state) (struct pci_dev *dev, u32
state);
int
(*suspend)(struct pci_dev *dev, u32
state);
int
(*resume) (struct pci_dev *dev);
int
(*enable_wake) (struct pci_dev *dev,
u32 state, int enable);
};
为
创
建
一
p>
个
正
确
的
struct
pci_driver
结
构
,
只<
/p>
有
4
个
字
段
需
要
被
初
始
化
:name,id
_table,probe
和
remove
。
其中
id_table
初始化可以用到宏
PCI_DEVICE(
VENDOR_ID,DEVICE_ID)
,
VENDOR_
ID
和
DEVICE_ID
分别为设备
和厂商编号,由板卡生产厂家指定。
Static
const struct pci_device_id mypci[] =
{
{
PCI_DEVICE(VENDOR_ID,DEVICE_ID)
},
{}
};
1.2
pci_dev
这个数据结构也在文件
include/linux/pci.h
里,它详细描述了一个
PCI
设备几乎所有的<
/p>
硬件信息,包括厂商
ID
、设备
ID
、各种资源等。可以根据需要使用其中的数据成员。
struct pci_dev {
struct list_head global_list;
struct list_head bus_list;
struct pci_bus
*bus;
struct pci_bus
*subordinate;
void
*sysdata;
struct proc_dir_entry *procent;
unsigned int
devfn;
unsigned short
vendor;
unsigned short
device;
unsigned short
subsystem_vendor;
- 1 -
unsigned short
subsystem_device;
unsigned int
class;
u8
hdr_type;
u8
rom_base_reg;
struct pci_driver *driver;
void
*driver_data;
u64
dma_mask;
u32
current_state;
unsigned short
vendor_compatible[DEVICE_COUNT_COMPATIBLE];
unsigned short device_compatible[DEVICE
_COUNT_COMPA
TIBLE];
unsigned int
irq;
struct resource
resource[DEVICE_COUNT_RESOURCE];
struct resource
dma_resource[DEVICE_COUNT_DMA];
struct resource
irq_resource[DEVICE_COUNT_IRQ];
char
name[80];
char
slot_name[8];
int
active;
int
ro;
unsigned short
regs;
int
(*prepare)(struct pci_dev *dev);
int
(*activate)(struct pci_dev *dev);
int
(*deactivate)(struct pci_dev *dev);
};
二,
PCI
驱动基本框架
在用模块方式实现
PCI
设备驱动程序时,通常至少要实现以下几个部分:初始化设备
模块、
设备打开模块、
数据读写和控制模块、
中断处理模块、
p>
设备释放模块、
设备卸载模块。
下面给出一
个典型的
PCI
设备驱动程序的基本框架。
/*
指明该驱动程序适用于哪一些
PCI
设备
*/
static struct pci_device_id
demo_pci_tbl [] __initdata = {
{PCI_VENDOR_ID_DEMO,
PCI_DEVICE_ID_DEMO,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEMO},
{0,}
};
/*
对特定
PCI
< br>设备进行描述的数据结构
*/
struct demo_card {
unsigned int magic;
/*
使用链表保存所有同类的
PCI
设备
*/
- 2 -
struct
demo_card *next;
/*
... */
}
/*
中断处理模块
*/
static void demo_interrupt(int irq,
void *dev_id, struct pt_regs *regs)
{
/* ... */
}
/*
设备模块信息
*/
static struct pci_driver
demo_pci_driver = {
name:
demo_MODULE_NAME,
/*
设备模块名称
*/
id_table:
demo_pci_tbl,
/*
能够驱动的设备列表
*/
probe:
demo_probe,
/*
查找并初始化设备
*/
remove:
demo_remove
/*
卸载设备模块
*/
/* ... */
};
static int __init demo_init_module
(void)
{
pci_register_driver(&demo_pci_driver);
}
static void
__exit demo_cleanup_module (void)
{
p>
pci_unregister_driver(&demo_pci_driver);
}
/*
加载驱动程序模块入口
*/
module_init(demo_init_module);
/*
卸载驱动程序模块入口
*/
module_exit(demo_cleanup_module);
三,
PCI
设备操作实现
3.1
设备初始化
在
demo_init_module
中,用
pci_register_driver(
)
函数来注册
PCI
设
备的驱动程序,此
时需要提供一个
pci_driver
结构,在该结构中给出的
probe
探测例程
将负责完成对硬件的检
测工作。
<
/p>
在
probe
函数中,需要实现以下几个
功能:
(
1
)使能
PCI
在
PCI
驱动的探测函数中
,
在驱动可存取
PCI
设备的任何设备资源
(I/O
区或者
中断
)
之前
,
- 3 -
-
-
-
-
-
-
-
-
-
上一篇:掉话及未接通原因分类
下一篇:主板cmos自检出错