- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
DMA通道资源的申请 任何ISA卡在使用某个DMA通道进行DMA传输之前,其设备驱动程序都必须向内核提出DMA通道资源的申请。只有申请获得成功后才能使用相应的DMA通道。否则就会发生资源冲突。 函数request_dma()实现DMA通道资源的申请。其源码如下: DMA通道资源的申请(case) int request_dma(unsigned int dmanr, const char * device_id) { ????? if (dmanr = MAX_DMA_CHANNELS) ?? return -EINVAL; ????? if (xchg(dma_chan_busy[dmanr].lock, 1) != 0) ?? ??????? return -EBUSY; ????? dma_chan_busy[dmanr].device_id = device_id; ??????? /* old flag was 0, now contains 1 to indicate busy */ return 0;} 上述函数的核心实现就是用原子操作xchg()让成员变量dma_chan_busy[dmanr].lock和值1进行交换操作,xchg()将返回 lock成员在交换操作之前的值。因此:如果xchg()返回非0值,这说明dmanr所指定的DMA通道已被其他设备所占用,所以 request_dma()函数返回错误值-EBUSY表示指定DMA通道正忙;否则,如果xchg()返回0值,说明dmanr所指定的DMA通道正处于free状态,于是xchg()将其lock成员设置为1,取得资源的使用权。 释放DMA通道资源 DMA传输事务完成后,设备驱动程序一定要记得释放所占用的DMA通道资源。否则别的外设将一直无法使用该DMA通道。函数free_dma()释放指定的DMA通道资源。如下: void free_dma(unsigned int dmanr) { ??????? if (dmanr = MAX_DMA_CHANNELS) { ??????? ??????? printk(Trying to free DMA%d, dmanr);??????? ???return;????} ??????? if (xchg(dma_chan_busy[dmanr].lock, 0) == 0) {??????? ????printk(Trying to free free DMA%d, dmanr);??????? ????return;????} } /* free_dma */ 显然,上述函数的核心实现就是用原子操作xchg()将lock成员清零。 对/proc/dma文件的实现 文件/proc/dma列出当前8个DMA通道的使用状况。Linux在kernel/dma.c文件中通过函数get_dma_list() (2.6中变为proc_dma_show)来实现/proc/dma文件。函数get_dma_list()的实现比较简单。主要就是遍历数组dma_chan_busy[],并将那些 lock成员为非零值的数组元素输出到列表中即可。如下: int get_dma_list(char *buf) { ????? int i, len = 0; ????? for (i = 0 ; i MAX_DMA_CHANNELS ; i++) { ???? ??????? if (dma_chan_busy[i].lock) { ??????? ??????? len += sprintf(buf+len, %2d: %s,i,dma_chan_busy[i].device_id); ???? ??????? }? } ??????? return len; } /* get_dma_list */ 5.3 I/O软件原理 I/O软件是控制外部设备和内存间进行数据交换的所有软件的统称。 I/O软件的主要任务是充分发挥各种设备的作用,屏蔽各种设备的特殊性,在保证系统具有较高的整体性的同时,尽可能向用户提供一个友好、清晰、规范和设备独立的配置和使用界面。 计算机系统的I/O软件也同样具有层次结构。 Linux系统I/O软件层次结构图 设备命令、保护 缓冲管理 设备分配 设备驱动程序 中断处理程序 硬件设备 设 备 无 关 软 件 文 件 系 统 I/O请求 I/O应答 用户进程:发出I/O请求,接收I/O结果 I/O体系结构 总线:PC的CPU、RAM、I/O设备之间需要某些数据通路来保证信息的流动 总类: ISA、 EISA、 VESA、PCI以及MCA等等 三种基本类型 数据总线
文档评论(0)