linux 1.0 内核注解 linux/kernel/dma.c
时间:2009-03-08 来源:taozhijiangscu
/********************************************
*Created By: 陶治江
*Date: 2009-3-6
********************************************/
#include <linux/kernel.h>
#include <linux/errno.h>
#include <asm/dma.h> //关于DMA
//一般的PC机有两片DMA控制器,它们之间进行级联。
//一个DMA控制器有一个16位的地址寄存器和一个8位的页
//寄存器,共构成一个24位的物理地址,所以这也是为什么
//DMA只能访问16M的地址的原因了 //这里对DMA进行了管理,所有需要使用DMA通道的都需要申请和释放
//request_dma() free_dma()
// So, when allocating DMAs and IRQs, first allocate the IRQ, then the DMA.
//When releasing them, first release the DMA, then release the IRQ. //这里的0 4被保留了,第四个是用来DMA级联的,不可用,第一个?
static volatile unsigned int dma_chan_busy[MAX_DMA_CHANNELS] = {
1, 0, 0, 0, 1, 0, 0, 0
};
//原子性的交换*p和newval值
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 */ int request_dma(unsigned int dmanr)
{
if (dmanr >= MAX_DMA_CHANNELS) /*8*/
return -EINVAL; if (mutex_atomic_swap(&dma_chan_busy[dmanr], 1) != 0)
//返回的是原先的值,如果是1表示已经被分配出去了
return -EBUSY;
else
/* old flag was 0, now contains 1 to indicate busy */
return 0;
} /* request_dma */
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 */ 文档地址:http://blogimg.chinaunix.net/blog/upfile2/090308125940.pdf
*Created By: 陶治江
*Date: 2009-3-6
********************************************/
#include <linux/kernel.h>
#include <linux/errno.h>
#include <asm/dma.h> //关于DMA
//一般的PC机有两片DMA控制器,它们之间进行级联。
//一个DMA控制器有一个16位的地址寄存器和一个8位的页
//寄存器,共构成一个24位的物理地址,所以这也是为什么
//DMA只能访问16M的地址的原因了 //这里对DMA进行了管理,所有需要使用DMA通道的都需要申请和释放
//request_dma() free_dma()
// So, when allocating DMAs and IRQs, first allocate the IRQ, then the DMA.
//When releasing them, first release the DMA, then release the IRQ. //这里的0 4被保留了,第四个是用来DMA级联的,不可用,第一个?
static volatile unsigned int dma_chan_busy[MAX_DMA_CHANNELS] = {
1, 0, 0, 0, 1, 0, 0, 0
};
//原子性的交换*p和newval值
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 */ int request_dma(unsigned int dmanr)
{
if (dmanr >= MAX_DMA_CHANNELS) /*8*/
return -EINVAL; if (mutex_atomic_swap(&dma_chan_busy[dmanr], 1) != 0)
//返回的是原先的值,如果是1表示已经被分配出去了
return -EBUSY;
else
/* old flag was 0, now contains 1 to indicate busy */
return 0;
} /* request_dma */
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 */ 文档地址:http://blogimg.chinaunix.net/blog/upfile2/090308125940.pdf
相关阅读 更多 +
排行榜 更多 +