/* $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. iOS中真机连接电脑运行程序出现问题

  2. He faced a maximum sentence of three years.

    Police raided his home in August and found more than 100g of marijuana. He faced a maximum sentence ...

  3. HBase的基本架构及其原理介绍

    1.概述:最近,有一些工程师问我有关HBase的基本架构的问题,其实这个问题仅仅说架构是非常简单,但是需要理解.在这里,我觉得可以用HDFS的架构作为借鉴.(其实像Hadoop生态系统中的大部分组建的 ...

  4. ListView.post(Runnable {})和ListView.postDelayed

    1. boolean android.view.View.post(Runnable action): 是listview 继承 view,同样具有此方法 post(Runnable action) ...

  5. 北大poj- 1028

    Web Navigation Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 33281   Accepted: 14836 ...

  6. iphone APP 去广告。 【转载】

    iPhone怎么去广告?相信大家对APP中的广告条都非常不喜欢,界面丑且容易误点被跳转,相信很多朋友都使用插件来去除广告,但是不越狱怎么去广告呢?下面小编教大家不越狱去除iPhone广告. iPhon ...

  7. nosql->redis学习 数据类型

    redis->string 二进制 setnx name lijie  判断键值 是否存在  如果存在返回0 不存在 吧值设置进去   setex  指定键值有效期时间  setex name ...

  8. Facebook 帆布接入的总结

    研究接入facebook也有不短的时间, 上线过几款产品,这里把接入所有的点 都记录一下. 1.首先进入facebook的开发者页面,直接入口在右下角更多里面 然后注册开发者账号, 创建APP 选择F ...

  9. UE4 Android相对路径转绝对路径方法笔记

    在windows端用FPaths::ConvertRelativePathToFull可以将相对路径转成绝对路径. 在Andoird端,就麻烦些.可模仿UE4源码中AndroidFile.Cpp转换相 ...

  10. HDU 4059 容斥初步练习

    #include <iostream> #include <cstring> #include <cstdio> #include <algorithm> ...