PCI总线驱动
1.pci驱动注册
pci_register_driver(struct pci_driver *drv)
static struct pci_driver hamachi_driver = {
.name = DRV_NAME,
.id_table = hamachi_pci_tbl,
.probe = hamachi_init_one,
.remove = __devexit_p(hamachi_remove_one),
};
2.私有数据
pci_set_drvdata 设置驱动私有数据
pci_get_drvdata 获取驱动私有数据
3.PCI配置空间
pci_read_config_byte/word/dword(struct pci_dev *pdev, int offset, int *value)
pci_write_config_byte/word/dword(struct pci_dev *pdev, int offset, int *value)
4.PCI的I/O和内存空间
pci_resource_start(struct pci_dev *dev, int bar) Bar值的范围为0-5 ;从配置区相应寄存器得到I/O区域的基址:
pci_resource_length(struct pci_dev *dev, int bar) Bar值的范围为0-5;从配置区相应寄存器得到I/O区域的内存区域长度
pci_resource_flags(struct pci_dev *dev, int bar) Bar值的范围为0-5;从配置区相应寄存器得到I/O区域的内存的相关标志
request_mem_region(io_base, length, name) 申请I/O端口
release_mem_region(io_base, length, name) 释放I/O端口
inb() inw() inl() outb() outw() outl() 读写I/O端口
pci_enable_device 启用设备的I/O
和内存资源,分配不足的资源,如果需要,还要唤醒一个处于暂停状态的设备。需要注意的是,这个操作可能会失败。
pci_set_master 设定设备工作在总线主设备模式
ioremap_nocache 让CPU 可以访问设备的内存
pci_dma_supported
pci_set_dma_mask()和dma_set_mask()辅助函数用于检查总线是否可以接收给定大小的总线地址(mask),如果可以,则通知总线层给定的外围设备将使用该大小的总线地址。
pci_alloc_consistent 返回一致性dma映射缓冲区的虚拟地址
upci_free_consistent 释放一致性dma缓冲区映射
pci_save_state 配置空间(包括PCI、PCI-X、PCI-E)存到pci_dev里头
原子操作
Atomic_read(v) 返回原子变量的值
atomic_set(v,i) 设置原子变量的值
Atomic_add(int i, atomic_t *v) 原子的递增计数的值
static inline int atomic_add_return(int i, atomic_t *v) 只不过将变量v的最新值返回
Atomic_sub(int i, atomic_t *v) 原子的递减计数的值
static inline int atomic_sub_return(int i, atomic_t *v) 只不过将变量v的最新值返回
atomic_cmpxchg(atomic_t *ptr, int old, int new) 比较old和原子变量ptr中的值,如果相等,那么就把new值赋给原子变量。 返回旧的原子变量ptr中的值
atomic_clear_mask 原子的清除掩码
atomic_inc(v) 原子变量的值加一
atomic_inc_return(v) 同上,只不过将变量v的最新值返回
atomic_dec(v) 原子变量的值减去一
atomic_dec_return(v) 同上,只不过将变量v的最新值返回
atomic_sub_and_test(i, v) 给一个原子变量v减去i,并判断变量v的最新值是否等于0
atomic_add_negative(i,v) 给一个原子变量v增加i,并判断变量v的最新值是否是负数
static inline int atomic_add_unless(atomic_t *v, int a, int u) 只要原子变量v不等于u,那么就执行原子变量v加a的操作。 如果v不等于u,返回非0值,否则返回0值
char设备注册
1.int register_chrdev_region(dev_t from, unsigned count, const char *name)
为一个字符驱动获取一个或多个设备编号来使用。用于分配指定的设备编号范围。如果申请的设备编号范围跨越了主设备号,它会把分配范围内的编号按主设备号分割成较小的子范围,并在每个子范围上调用 __register_chrdev_region() 。如果其中有一次分配失败的话,那会把之前成功分配的都全部退回。
int alloc_chrdev_region(dev_t *dev, unsigned baseminor