/* $Id: dma.c,v 1.5 1992/11/18 02:49:05 root Exp root $
 * linux/kernel/dma.c: A DMA channel allocator. Inspired by linux/kernel/irq.c.
 * Written by Hennus Bergman, 1992.
 */

#include <linux/kernel.h>
#include <linux/errno.h>
#include <asm/dma.h>

/* A note on resource allocation:
 *
 * All drivers needing DMA channels, should allocate and release them
 * through the public routines `request_dma()' and `free_dma()'.
 *
 * In order to avoid problems, all processes should allocate resources in
 * the same sequence and release them in the reverse order.
 *
 * So, when allocating DMAs and IRQs, first allocate the IRQ, then the DMA.
 * When releasing them, first release the DMA, then release the IRQ.
 * If you don't, you may cause allocation requests to fail unnecessarily.
 * This doesn't really matter now, but it will once we get real semaphores
 * in the kernel.
 */

/* Channel n is busy iff dma_chan_busy[n] != 0.
 * DMA0 is reserved for DRAM refresh, I think.
 * DMA4 is reserved for cascading (?).
 */
 /* dma_chan_busy[n] != 0 表示该通道不可用
 * DMA0 用作DRAM的刷新.
 * DMA4 用作级连.
 */
static volatile unsigned int dma_chan_busy[MAX_DMA_CHANNELS] = {
    1, 0, 0, 0, 1, 0, 0, 0
};

/* Atomically swap memory location [32 bits] with `newval'.
 * This avoid the cli()/sti() junk and related problems.
 * [And it's faster too :-)]
 * Maybe this should be in include/asm/mutex.h and be used for
 * implementing kernel-semaphores as well.
 */
 // 将*p指向的数据替换为newval.由关键字xchgl看,这个值是32位的值。
 // xchgl是原子操作,可以省去cli和sti.
static __inline__ unsigned int mutex_atomic_swap(volatile unsigned int * p, unsigned int newval)
{
    unsigned int semval = newval;

/* If one of the operands for the XCHG instructions is a memory ref,
     * it makes the swap an uninterruptible RMW cycle.
     *
     * One operand must be in memory, the other in a register, otherwise
     * the swap may not be atomic.
     */

asm __volatile__ ("xchgl %2, %0\n"
            : /* outputs: semval   */ "=r" (semval)
            : /* inputs: newval, p */ "0" (semval), "m" (*p)
            );    /* p is a var, containing an address */
    return semval;
} /* mutex_atomic_swap */

//请求DMA,核心由上个函数mutex_atomic_swap完成
int request_dma(unsigned int dmanr)
{
    if (dmanr >= MAX_DMA_CHANNELS)
        return -EINVAL;

if (mutex_atomic_swap(&dma_chan_busy[dmanr], 1) != 0)
        return -EBUSY;
    else
        /* old flag was 0, now contains 1 to indicate busy */
        return 0;
} /* request_dma */

//释放DMA,核心由函数mutex_atomic_swap完成
void free_dma(unsigned int dmanr)
{
    if (dmanr >= MAX_DMA_CHANNELS) {
        printk("Trying to free DMA%d\n", dmanr);
        return;
    }

if (mutex_atomic_swap(&dma_chan_busy[dmanr], 0) == 0)
        printk("Trying to free free DMA%d\n", dmanr);
} /* free_dma */

kernel/dma.c的更多相关文章

  1. include/asm/dma.h

    /* $Id: dma.h,v 1.7 1992/12/14 00:29:34 root Exp root $ * linux/include/asm/dma.h: Defines for using ...

  2. iommu分析之---DMA remap框架实现

    本文主要介绍iommu的框架.基于4.19.204内核 IOMMU核心框架是管理IOMMU设备的一个通过框架,IOMMU设备通过实现特定的回调函数并将自身注册到IOMMU核心框架中,以此通过IOMMU ...

  3. Linux服务器宕机案例一则

    案例环境 操作系统 :Oracle Linux Server release 5.7 64bit 虚拟机 硬件配置 : 物理机型号为DELL R720 资源配置 :RAM 8G Intel(R) Xe ...

  4. Linux系统OOM killer机制详解

    介绍: Linux下面有个特性叫OOM killer(Out Of Memory killer),会在系统内存耗尽的情况下出现,选择性的干掉一些进程以求释放一些内存.广大从事Linux方面的IT农民工 ...

  5. VNF网络性能提升解决方案及实践

    VNF网络性能提升解决方案及实践 2016年7月 作者:    王智民 贡献者:     创建时间:    2016-7-20 稳定程度:    初稿 修改历史 版本 日期 修订人 说明 1.0 20 ...

  6. linux驱动(续)

    网络通信 --> IO多路复用之select.poll.epoll详解 IO多路复用之select.poll.epoll详解      目前支持I/O多路复用的系统调用有 select,psel ...

  7. Linux 驱动开发

    linux驱动开发总结(一) 基础性总结 1, linux驱动一般分为3大类: * 字符设备 * 块设备 * 网络设备 2, 开发环境构建: * 交叉工具链构建 * NFS和tftp服务器安装 3, ...

  8. 【内核】linux内核启动流程详细分析

    Linux内核启动流程 arch/arm/kernel/head-armv.S 该文件是内核最先执行的一个文件,包括内核入口ENTRY(stext)到start_kernel间的初始化代码, 主要作用 ...

  9. 【内核】linux内核启动流程详细分析【转】

    转自:http://www.cnblogs.com/lcw/p/3337937.html Linux内核启动流程 arch/arm/kernel/head-armv.S 该文件是内核最先执行的一个文件 ...

随机推荐

  1. 《Pro Express.js》学习笔记——app.params中间件

    app.param中间件用于对URL中的参数进行获取.加工.输出,提供公有逻辑,以达到代码重构的目的. 以下示例采取三个步骤对代码进行重构,app.param中间件的作用非常明显: 不使用中间件 使用 ...

  2. svd自我学习

    svd(singular value decomposition) 奇异值分解  2015-05-17 16:28:50 图和部分内容来自:http://blog.csdn.net/wangzhiqi ...

  3. Linux 命令 find

    find命令的基本格式是:find [路径] [选项] [操作]路径是find命令所查找的范围,如用.来表示当前目录,用/来表示根目录,选项用于指定查找条件,如:可以指定按照文件的属主,更改时间文件类 ...

  4. DotNetBar for Windows Forms 12.1.0.0_冰河之刃重打包版 原创发布

    关于 DotNetBar for Windows Forms 12.1.0.0_冰河之刃重打包版 --------------------11.8.0.8_冰河之刃重打包版-------------- ...

  5. ctags and vim

    1,源码目录下第归检索. ctags -R * 2,搜索tag并用vim打开: vim -t <tag> 3,在vim 下的一些操作: Keyboard command Action Ct ...

  6. 看的oracle数据库视频 记的一点笔记

    3个默认的用户    sys          //网络管理员  权限由上到下降低 [最后加上 as sysdba]    system  //本地管理员    scott     //普通用户  默 ...

  7. 利用calc计算宽度

    width:calc(100% - 40px)可用 + - * / 进行计算(ie9+) 注:计算符号前后必须跟上空格.

  8. Go语言的传值与传引用

    Go语言里的传值与传引用大致与C语言中一致,但有2个特例,map和channel默认传引用,也就是说可以直接修改传入的参数,其他的情况如果不用指针的话,传入的都是参数的副本,在函数中修改不会改变调用者 ...

  9. 小型资源管理器,IO操作,读取和写入文件和目录的常用操作

    解决方案: 小总结: 用IO流,的file,DirectoryInfo的方法绑定Treeview控件上和删除,读取, 可以熟练掌握一下IO流 主页面: private void Form1_Load( ...

  10. iOS仿直播带有气泡动画的UIButton

    现在直播软件确实很火,因为需要就写了一个带有动画气泡的按钮,代码中的部分动画有参考到其他童鞋,在这里万分感谢! .h文件 @interface YYBubbleButton : UIButton @p ...