Line 7... |
Line 7... |
#include <linux/pci.h>
|
#include <linux/pci.h>
|
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
#include <linux/pagemap.h>
|
#include <linux/pagemap.h>
|
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
#include <linux/proc_fs.h>
|
#include <linux/proc_fs.h>
|
|
#include <linux/delay.h>
|
|
#include <linux/wait.h>
|
#include <asm/io.h>
|
#include <asm/io.h>
|
|
|
#ifndef _EVENT_H_
|
#ifndef _EVENT_H_
|
#include "event.h"
|
#include "event.h"
|
#endif
|
#endif
|
Line 22... |
Line 24... |
#endif
|
#endif
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
|
|
struct CDmaChannel* CDmaChannelCreate( u32 NumberOfChannel,
|
struct CDmaChannel* CDmaChannelCreate( u32 NumberOfChannel,
|
|
TASKLET_ROUTINE dpc,
|
void *brd,
|
void *brd,
|
struct device *dev,
|
struct device *dev,
|
u32 cbMaxTransferLength,
|
u32 cbMaxTransferLength,
|
u16 idBlockFifo,
|
u16 idBlockFifo,
|
int bScatterGather )
|
int bScatterGather )
|
{
|
{
|
struct CDmaChannel *dma = NULL;
|
struct CDmaChannel *dma = NULL;
|
|
|
dma = kzalloc(sizeof(struct CDmaChannel), GFP_KERNEL);
|
dma = kzalloc(sizeof(struct CDmaChannel), GFP_KERNEL);
|
if(!dma) {
|
if(!dma) {
|
printk("<0>%s(): Error allocate memory for CDmaChannel object\n", __FUNCTION__);
|
printk("%s(): Error allocate memory for CDmaChannel object\n", __FUNCTION__);
|
return NULL;
|
return NULL;
|
}
|
}
|
|
|
dma->m_NumberOfChannel = NumberOfChannel;
|
dma->m_NumberOfChannel = NumberOfChannel;
|
dma->m_Board = brd;
|
dma->m_Board = brd;
|
dma->m_dev = dev;
|
dma->m_dev = dev;
|
dma->m_UseCount = 0;
|
dma->m_UseCount = 0;
|
dma->m_DpcForIsr = DmaDpcForIsr;
|
dma->m_DpcForIsr = dpc;
|
dma->m_idBlockFifo = idBlockFifo;
|
dma->m_idBlockFifo = idBlockFifo;
|
|
|
spin_lock_init( &dma->m_DmaLock );
|
spin_lock_init( &dma->m_DmaLock );
|
init_waitqueue_head( &dma->m_DmaWq );
|
init_waitqueue_head( &dma->m_DmaWq );
|
tasklet_init( &dma->m_Dpc, dma->m_DpcForIsr, (unsigned long)dma );
|
tasklet_init( &dma->m_Dpc, dma->m_DpcForIsr, (unsigned long)dma );
|
InitKevent( &dma->m_BlockEndEvent );
|
InitKevent( &dma->m_BlockEndEvent );
|
InitKevent( &dma->m_BufferEndEvent );
|
InitKevent( &dma->m_BufferEndEvent );
|
|
|
//printk("<0>%s(%d): COMPLETE.\n", __FUNCTION__, dma->m_NumberOfChannel);
|
//printk("%s(%d): COMPLETE.\n", __FUNCTION__, dma->m_NumberOfChannel);
|
|
|
return dma;
|
return dma;
|
}
|
}
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
|
|
void CDmaChannelDelete(struct CDmaChannel *dma)
|
void CDmaChannelDelete(struct CDmaChannel *dma)
|
{
|
{
|
//printk("<0>%s()\n", __FUNCTION__);
|
//printk("%s()\n", __FUNCTION__);
|
if (dma) {
|
if (dma) {
|
tasklet_kill( &dma->m_Dpc );
|
tasklet_kill( &dma->m_Dpc );
|
kfree(dma);
|
kfree(dma);
|
}
|
}
|
}
|
}
|
Line 71... |
Line 74... |
|
|
int RequestMemory(struct CDmaChannel *dma, void** ppVirtAddr, u32 size, u32 *pCount, void** pStub, u32 bMemType)
|
int RequestMemory(struct CDmaChannel *dma, void** ppVirtAddr, u32 size, u32 *pCount, void** pStub, u32 bMemType)
|
{
|
{
|
int Status = -ENOMEM;
|
int Status = -ENOMEM;
|
|
|
//printk("<0>%s(): Channel = %d\n", __FUNCTION__, dma->m_NumberOfChannel);
|
//printk("%s(): Channel = %d\n", __FUNCTION__, dma->m_NumberOfChannel);
|
|
|
// при первом обращении действительно выделяем память,
|
// при первом обращении действительно выделяем память,
|
// а при повторных только отображаем выделенную память на пользовательское пространство
|
// а при повторных только отображаем выделенную память на пользовательское пространство
|
if(!dma->m_UseCount)
|
if(dma->m_UseCount == 0)
|
{
|
{
|
dma_addr_t pa = (dma_addr_t)0;
|
dma_addr_t pa = (dma_addr_t)0;
|
|
|
dma->m_MemType = bMemType;
|
dma->m_MemType = bMemType;
|
dma->m_BlockCount = *pCount;
|
dma->m_BlockCount = *pCount;
|
Line 89... |
Line 92... |
dma->m_pBufDscr.SystemAddress = (void*)dma_alloc_coherent( dma->m_dev,
|
dma->m_pBufDscr.SystemAddress = (void*)dma_alloc_coherent( dma->m_dev,
|
dma->m_BlockCount * sizeof(SHARED_MEMORY_DESCRIPTION),
|
dma->m_BlockCount * sizeof(SHARED_MEMORY_DESCRIPTION),
|
&pa, GFP_KERNEL);
|
&pa, GFP_KERNEL);
|
if(!dma->m_pBufDscr.SystemAddress)
|
if(!dma->m_pBufDscr.SystemAddress)
|
{
|
{
|
printk("<0>%s(): Not memory for buffer descriptions\n", __FUNCTION__);
|
printk("%s(): Not memory for buffer descriptions\n", __FUNCTION__);
|
return -ENOMEM;
|
return -ENOMEM;
|
}
|
}
|
|
|
dma->m_pBufDscr.LogicalAddress = (size_t)pa;
|
dma->m_pBufDscr.LogicalAddress = (size_t)pa;
|
dma->m_ScatterGatherTableEntryCnt = 0;
|
dma->m_ScatterGatherTableEntryCnt = 0;
|
Line 110... |
Line 113... |
dma->m_BlockCount * sizeof(SHARED_MEMORY_DESCRIPTION),
|
dma->m_BlockCount * sizeof(SHARED_MEMORY_DESCRIPTION),
|
dma->m_pBufDscr.SystemAddress,
|
dma->m_pBufDscr.SystemAddress,
|
dma->m_pBufDscr.LogicalAddress);
|
dma->m_pBufDscr.LogicalAddress);
|
dma->m_pBufDscr.SystemAddress = NULL;
|
dma->m_pBufDscr.SystemAddress = NULL;
|
dma->m_pBufDscr.LogicalAddress = 0;
|
dma->m_pBufDscr.LogicalAddress = 0;
|
printk("<0>%s(): Invalid memory type for DMA data blocks\n", __FUNCTION__);
|
printk("%s(): Invalid memory type for DMA data blocks\n", __FUNCTION__);
|
return -EINVAL;
|
return -EINVAL;
|
}
|
}
|
|
|
if(Status == 0)
|
if(Status == 0)
|
{
|
{
|
if(!dma->m_UseCount)
|
if(dma->m_UseCount == 0)
|
{
|
{
|
//printk("<0>%s(): Scatter/Gather Table Entry is %d\n", __FUNCTION__, dma->m_ScatterGatherTableEntryCnt);
|
//printk("%s(): Scatter/Gather Table Entry is %d\n", __FUNCTION__, dma->m_ScatterGatherTableEntryCnt);
|
if(dma->m_idBlockFifo == PE_EXT_FIFO_ID)
|
if(dma->m_idBlockFifo == PE_EXT_FIFO_ID)
|
SetScatterGatherListExt(dma);
|
SetScatterGatherListExt(dma);
|
else {
|
else {
|
printk("<0>%s(): Scatter/Gather Table Entry not created\n", __FUNCTION__);
|
printk("%s(): Scatter/Gather Table Entry not created\n", __FUNCTION__);
|
//SetScatterGatherList(dma);
|
//SetScatterGatherList(dma);
|
}
|
}
|
*pCount = dma->m_BlockCount;
|
|
dma->m_pStub = (PAMB_STUB)dma->m_StubDscr.SystemAddress;
|
dma->m_pStub = (PAMB_STUB)dma->m_StubDscr.SystemAddress;
|
dma->m_pStub->lastBlock = -1;
|
dma->m_pStub->lastBlock = -1;
|
dma->m_pStub->totalCounter = 0;
|
dma->m_pStub->totalCounter = 0;
|
dma->m_pStub->offset = 0;
|
dma->m_pStub->offset = 0;
|
dma->m_pStub->state = STATE_STOP;
|
dma->m_pStub->state = STATE_STOP;
|
}
|
}
|
|
|
|
*pCount = dma->m_BlockCount;
|
|
|
dma->m_UseCount++;
|
dma->m_UseCount++;
|
}
|
}
|
else
|
else
|
{
|
{
|
ReleaseStub(dma);
|
ReleaseStub(dma);
|
dma_free_coherent(dma->m_dev, dma->m_BlockCount * sizeof(SHARED_MEMORY_DESCRIPTION),
|
dma_free_coherent(dma->m_dev, dma->m_BlockCount * sizeof(SHARED_MEMORY_DESCRIPTION),
|
dma->m_pBufDscr.SystemAddress, dma->m_pBufDscr.LogicalAddress);
|
dma->m_pBufDscr.SystemAddress, dma->m_pBufDscr.LogicalAddress);
|
dma->m_pBufDscr.SystemAddress = NULL;
|
dma->m_pBufDscr.SystemAddress = NULL;
|
dma->m_pBufDscr.LogicalAddress = 0;
|
dma->m_pBufDscr.LogicalAddress = 0;
|
printk("<0>%s(): Error allocate memory\n", __FUNCTION__);
|
printk("%s(): Error allocate memory\n", __FUNCTION__);
|
return -EINVAL;
|
return -EINVAL;
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
if(!dma->m_UseCount) {
|
if(dma->m_UseCount == 0) {
|
dma_free_coherent(dma->m_dev,
|
dma_free_coherent(dma->m_dev,
|
dma->m_BlockCount * sizeof(SHARED_MEMORY_DESCRIPTION),
|
dma->m_BlockCount * sizeof(SHARED_MEMORY_DESCRIPTION),
|
dma->m_pBufDscr.SystemAddress, dma->m_pBufDscr.LogicalAddress);
|
dma->m_pBufDscr.SystemAddress, dma->m_pBufDscr.LogicalAddress);
|
dma->m_pBufDscr.SystemAddress = NULL;
|
dma->m_pBufDscr.SystemAddress = NULL;
|
dma->m_pBufDscr.LogicalAddress = 0;
|
dma->m_pBufDscr.LogicalAddress = 0;
|
Line 160... |
Line 165... |
return Status;
|
return Status;
|
}
|
}
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
|
|
void ReleaseMemory(struct CDmaChannel *dma)
|
int ReleaseMemory(struct CDmaChannel *dma)
|
{
|
{
|
//printk("<0>%s(): Entered. Channel = %d\n", __FUNCTION__, dma->m_NumberOfChannel);
|
printk("%s(): Entered. Channel = %d\n", __FUNCTION__, dma->m_NumberOfChannel);
|
|
|
if(!dma->m_UseCount) {
|
if(dma->m_UseCount == 0) {
|
printk("<0> %s: Memory not allocated.\n", __FUNCTION__);
|
printk("%s(): Memory not allocated. m_UseCount = %d\n", __FUNCTION__, dma->m_UseCount);
|
return;
|
return -1;
|
}
|
}
|
|
|
|
dma->m_UseCount--;
|
|
|
ReleaseStub( dma );
|
ReleaseStub( dma );
|
ReleaseSGList( dma );
|
ReleaseSGList( dma );
|
ReleaseSysBuf( dma );
|
ReleaseSysBuf( dma );
|
|
|
dma_free_coherent(dma->m_dev,
|
dma_free_coherent(dma->m_dev,
|
dma->m_BlockCount * sizeof(SHARED_MEMORY_DESCRIPTION),
|
dma->m_BlockCount * sizeof(SHARED_MEMORY_DESCRIPTION),
|
dma->m_pBufDscr.SystemAddress, dma->m_pBufDscr.LogicalAddress);
|
dma->m_pBufDscr.SystemAddress, dma->m_pBufDscr.LogicalAddress);
|
|
|
dma->m_pBufDscr.SystemAddress = NULL;
|
dma->m_pBufDscr.SystemAddress = NULL;
|
dma->m_pBufDscr.LogicalAddress = 0;
|
dma->m_pBufDscr.LogicalAddress = 0;
|
dma->m_UseCount--;
|
return 0;
|
}
|
}
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
|
|
int SetScatterGatherListExt(struct CDmaChannel *dma)
|
int SetScatterGatherListExt(struct CDmaChannel *dma)
|
Line 197... |
Line 204... |
u16* pNextDscr = NULL;
|
u16* pNextDscr = NULL;
|
u32 DscrSize = 0;
|
u32 DscrSize = 0;
|
SHARED_MEMORY_DESCRIPTION *pMemDscr = (SHARED_MEMORY_DESCRIPTION*)dma->m_pBufDscr.SystemAddress;
|
SHARED_MEMORY_DESCRIPTION *pMemDscr = (SHARED_MEMORY_DESCRIPTION*)dma->m_pBufDscr.SystemAddress;
|
DMA_CHAINING_DESCR_EXT *pSGTEx = NULL;
|
DMA_CHAINING_DESCR_EXT *pSGTEx = NULL;
|
|
|
//printk("<0>%s()\n", __FUNCTION__);
|
//printk("%s()\n", __FUNCTION__);
|
|
|
Status = RequestSGList(dma);
|
Status = RequestSGList(dma);
|
if(Status < 0)
|
if(Status < 0)
|
return Status;
|
return Status;
|
|
|
Line 212... |
Line 219... |
DscrSize = DSCR_BLOCK_SIZE*sizeof(DMA_CHAINING_DESCR_EXT);
|
DscrSize = DSCR_BLOCK_SIZE*sizeof(DMA_CHAINING_DESCR_EXT);
|
|
|
//обнулим таблицу дескрипторов DMA
|
//обнулим таблицу дескрипторов DMA
|
memset(pSGTEx, 0, dma->m_ScatterGatherBlockCnt*DscrSize);
|
memset(pSGTEx, 0, dma->m_ScatterGatherBlockCnt*DscrSize);
|
|
|
//printk("<0>%s(): m_SGTableDscr.SystemAddress = %p\n", __FUNCTION__, dma->m_SGTableDscr.SystemAddress );
|
printk("%s(): m_SGTableDscr.SystemAddress = %p\n", __FUNCTION__, dma->m_SGTableDscr.SystemAddress );
|
//printk("<0>%s(): m_SGTableDscr.LogicalAddress = %zx\n", __FUNCTION__, dma->m_SGTableDscr.LogicalAddress );
|
printk("%s(): m_SGTableDscr.LogicalAddress = 0x%llx\n", __FUNCTION__, dma->m_SGTableDscr.LogicalAddress );
|
|
|
//заполним значениями таблицу цепочек DMA
|
//заполним значениями таблицу цепочек DMA
|
for(iBlock=0, iEntry=0; iBlock < dma->m_BlockCount; iBlock++) {
|
for(iBlock=0, iEntry=0; iBlock < dma->m_BlockCount; iBlock++) {
|
|
|
//адрес и размер DMA блока
|
//адрес и размер DMA блока
|
u64 address = pMemDscr[iBlock].LogicalAddress;
|
u64 address = pMemDscr[iBlock].LogicalAddress;
|
u64 DmaSize = dma->m_BlockSize - 0x1000;
|
u64 DmaSize = dma->m_BlockSize - 0x1000;
|
|
|
|
|
//заполним поля элментов таблицы дескрипторов
|
//заполним поля элментов таблицы дескрипторов
|
pSGTEx[iEntry].AddrByte1 = (u8)((address >> 8) & 0xFF);
|
pSGTEx[iEntry].AddrByte1 = (u8)((address >> 8) & 0xFF);
|
pSGTEx[iEntry].AddrByte2 = (u8)((address >> 16) & 0xFF);
|
pSGTEx[iEntry].AddrByte2 = (u8)((address >> 16) & 0xFF);
|
pSGTEx[iEntry].AddrByte3 = (u8)((address >> 24) & 0xFF);
|
pSGTEx[iEntry].AddrByte3 = (u8)((address >> 24) & 0xFF);
|
pSGTEx[iEntry].AddrByte4 = (u8)((address >> 32) & 0xFF);
|
pSGTEx[iEntry].AddrByte4 = (u8)((address >> 32) & 0xFF);
|
Line 241... |
Line 247... |
pSGTEx[iEntry].Cmd.Res = 0;
|
pSGTEx[iEntry].Cmd.Res = 0;
|
pSGTEx[iEntry].SizeByte1 |= dma->m_DmaDirection;
|
pSGTEx[iEntry].SizeByte1 |= dma->m_DmaDirection;
|
|
|
{
|
{
|
//u32 *ptr=(u32*)&pSGTEx[iEntry];
|
//u32 *ptr=(u32*)&pSGTEx[iEntry];
|
//printk("<0>%s(): %d: Entry Addr: %p, Data Addr: %llx %.8X %.8X\n",
|
//printk("%s(): %d: Entry Addr: %p, Data Addr: %llx %.8X %.8X\n",
|
// __FUNCTION__, iEntry, &pSGTEx[iEntry], address, ptr[1], ptr[0]);
|
// __FUNCTION__, iEntry, &pSGTEx[iEntry], address, ptr[1], ptr[0]);
|
}
|
}
|
|
|
if(((iEntry+2)%DSCR_BLOCK_SIZE) == 0)
|
if(((iEntry+2)%DSCR_BLOCK_SIZE) == 0)
|
{
|
{
|
Line 256... |
Line 262... |
pSGTEx[iEntry].Cmd.JumpNextDescr = 0;
|
pSGTEx[iEntry].Cmd.JumpNextDescr = 0;
|
|
|
//NextDscrBlockAddr = virt_to_bus((void*)&pSGTEx[iEntry+2]);
|
//NextDscrBlockAddr = virt_to_bus((void*)&pSGTEx[iEntry+2]);
|
NextDscrBlockAddr = (size_t)((u8*)dma->m_SGTableDscr.LogicalAddress + sizeof(DMA_CHAINING_DESCR_EXT)*(iEntry +2));
|
NextDscrBlockAddr = (size_t)((u8*)dma->m_SGTableDscr.LogicalAddress + sizeof(DMA_CHAINING_DESCR_EXT)*(iEntry +2));
|
|
|
//printk("<0>%s(): NextDscrBlock [PA]: %x\n", __FUNCTION__, NextDscrBlockAddr);
|
//printk("%s(): NextDscrBlock [PA]: 0x%lx\n", __FUNCTION__, NextDscrBlockAddr);
|
//printk("<0>%s(): NextDscrBlock [VA]: %p\n", __FUNCTION__, &pSGTEx[iEntry+2]);
|
//printk("%s(): NextDscrBlock [VA]: %p\n", __FUNCTION__, &pSGTEx[iEntry+2]);
|
|
|
pNextBlock = (DMA_NEXT_BLOCK*)&pSGTEx[iEntry+1];
|
pNextBlock = (DMA_NEXT_BLOCK*)&pSGTEx[iEntry+1];
|
|
|
//printk("<0>%s(): pNextBlock: %p\n", __FUNCTION__, pNextBlock);
|
//printk("%s(): pNextBlock: %p\n", __FUNCTION__, pNextBlock);
|
|
|
pNextBlock->NextBlkAddr = (NextDscrBlockAddr >> 8) & 0xFFFFFF;
|
pNextBlock->NextBlkAddr = (NextDscrBlockAddr >> 8) & 0xFFFFFF;
|
pNextBlock->Signature = 0x4953;
|
pNextBlock->Signature = 0x4953;
|
pNextBlock->Crc = 0;
|
pNextBlock->Crc = 0;
|
iEntry++;
|
iEntry++;
|
}
|
}
|
iEntry++;
|
iEntry++;
|
}
|
}
|
|
|
//printk("<0>%s(): iEntry = %d\n", __FUNCTION__, iEntry);
|
//printk("%s(): iEntry = %d\n", __FUNCTION__, iEntry);
|
|
|
if(((iEntry % DSCR_BLOCK_SIZE)) != 0)
|
if(((iEntry % DSCR_BLOCK_SIZE)) != 0)
|
{
|
{
|
DMA_NEXT_BLOCK *pNextBlock = NULL;
|
DMA_NEXT_BLOCK *pNextBlock = NULL;
|
u32 i = 0;
|
u32 i = 0;
|
Line 286... |
Line 292... |
pNextBlock->NextBlkAddr = (dma->m_SGTableDscr.LogicalAddress >> 8);
|
pNextBlock->NextBlkAddr = (dma->m_SGTableDscr.LogicalAddress >> 8);
|
|
|
i = (DSCR_BLOCK_SIZE * dma->m_ScatterGatherBlockCnt) - 1;
|
i = (DSCR_BLOCK_SIZE * dma->m_ScatterGatherBlockCnt) - 1;
|
pNextBlock = (DMA_NEXT_BLOCK*)(&pSGTEx[i]);
|
pNextBlock = (DMA_NEXT_BLOCK*)(&pSGTEx[i]);
|
|
|
//printk("<0>%s(): %d: pNextBlock: %p\n", __FUNCTION__, i, pNextBlock );
|
//printk("%s(): %d: pNextBlock: %p\n", __FUNCTION__, i, pNextBlock );
|
|
|
pNextBlock->NextBlkAddr = 0;
|
pNextBlock->NextBlkAddr = 0;
|
pNextBlock->Signature = 0x4953;
|
pNextBlock->Signature = 0x4953;
|
pNextBlock->Crc = 0;
|
pNextBlock->Crc = 0;
|
}
|
}
|
|
|
//printk("<0>%s(): DmaDirection = %d, DmaLocalAddress = 0x%X\n", __FUNCTION__, dma->m_DmaDirection, dma->m_DmaLocalAddress);
|
printk("%s(): DmaDirection = %d, DmaLocalAddress = 0x%X\n", __FUNCTION__, dma->m_DmaDirection, dma->m_DmaLocalAddress);
|
|
|
//for( ii=0; ii<dma->m_ScatterGatherBlockCnt*DSCR_BLOCK_SIZE; ii++ )
|
//for( ii=0; ii<dma->m_ScatterGatherBlockCnt*DSCR_BLOCK_SIZE; ii++ )
|
//{
|
//{
|
//u32 *ptr=(u32*)&pSGTEx[ii];
|
//u32 *ptr=(u32*)&pSGTEx[ii];
|
//printk("<0>%s(): %d: %.8X %.8X\n", __FUNCTION__, ii, ptr[1], ptr[0]);
|
// printk("%s(): %02d: %08X %08X\n", __FUNCTION__, ii, ptr[1], ptr[0]);
|
|
|
//}
|
//}
|
|
|
pDscrBuf = (u64*)dma->m_pScatterGatherTableExt;
|
pDscrBuf = (u64*)dma->m_pScatterGatherTableExt;
|
|
|
for(iBlkEntry = 0; iBlkEntry < dma->m_ScatterGatherBlockCnt; iBlkEntry++)
|
for(iBlkEntry = 0; iBlkEntry < dma->m_ScatterGatherBlockCnt; iBlkEntry++)
|
Line 317... |
Line 322... |
u16 data2 = (u16)((pDscrBuf[iBlock] >> 32) & 0xFFFF);
|
u16 data2 = (u16)((pDscrBuf[iBlock] >> 32) & 0xFFFF);
|
u16 data3 = (u16)((pDscrBuf[iBlock] >> 48) & 0xFFFF);
|
u16 data3 = (u16)((pDscrBuf[iBlock] >> 48) & 0xFFFF);
|
if(iBlock == DSCR_BLOCK_SIZE-1)
|
if(iBlock == DSCR_BLOCK_SIZE-1)
|
{
|
{
|
ctrl_code = ctrl_code ^ data0 ^ data1 ^ data2 ^ data3;
|
ctrl_code = ctrl_code ^ data0 ^ data1 ^ data2 ^ data3;
|
/*
|
|
printk("<0>%s(): DSCR_BLCK[%d] - NextBlkAddr = 0x%8X, Signature = 0x%4X, Crc = 0x%4X\n", __FUNCTION__,
|
//printk("%s(): DSCR_BLCK[%02d] - NextBlkAddr = 0x%08X, Signature = 0x%04X, Crc = 0x%04X\n", __FUNCTION__,
|
iBlkEntry,
|
// iBlkEntry,
|
(u32)(pDscrBuf[iBlock] << 8),
|
// (u32)(pDscrBuf[iBlock] << 8),
|
(u16)((pDscrBuf[iBlock] >> 32) & 0xFFFF),
|
// (u16)((pDscrBuf[iBlock] >> 32) & 0xFFFF),
|
(u16)ctrl_code);
|
// (u16)ctrl_code);
|
*/
|
|
}
|
}
|
else
|
else
|
{
|
{
|
u32 ctrl_tmp = 0;
|
u32 ctrl_tmp = 0;
|
ctrl_code = ctrl_code ^ data0 ^ data1 ^ data2 ^ data3;
|
ctrl_code = ctrl_code ^ data0 ^ data1 ^ data2 ^ data3;
|
ctrl_tmp = ctrl_code << 1;
|
ctrl_tmp = ctrl_code << 1;
|
ctrl_tmp |= (ctrl_code & 0x8000) ? 0: 1;
|
ctrl_tmp |= (ctrl_code & 0x8000) ? 0: 1;
|
ctrl_code = ctrl_tmp;
|
ctrl_code = ctrl_tmp;
|
|
|
//printk("<0>%s(): %d(%d) - PciAddr = 0x%8X, Cmd = 0x%2X, DmaLength = %d(%2X %2X %2X)\n", __FUNCTION__,
|
//printk("%s(): %02d(%02d) - PciAddr = 0x%08X, Cmd = 0x%04X, DmaLength = 0x%08X (%02X %02X %02X)\n", __FUNCTION__,
|
// iBlock, iBlkEntry,
|
// iBlock, iBlkEntry,
|
// (u32)(pDscrBuf[iBlock] << 8),
|
// (u32)(pDscrBuf[iBlock] << 8),
|
// (u8)(pDscrBuf[iBlock] >> 32),
|
// (u8)(pDscrBuf[iBlock] >> 32),
|
// (u32)((pDscrBuf[iBlock] >> 41) << 9),
|
// (u32)((pDscrBuf[iBlock] >> 41) << 9),
|
// (u8)(pDscrBuf[iBlock] >> 56),
|
// (u8)(pDscrBuf[iBlock] >> 56),
|
// (u8)(pDscrBuf[iBlock] >> 48),
|
// (u8)(pDscrBuf[iBlock] >> 48),
|
// (u8)(pDscrBuf[iBlock] >> 40));
|
// (u8)(pDscrBuf[iBlock] >> 40));
|
//printk("<0>%s(): JumpNextDescr = %d, JumpNextBlock = %d, JumpDescr0 = %d, EndOfTrans = %d, Signature = 0x%08X, Crc = 0x%08X\n",
|
}
|
// __FUNCTION__, m_pScatterGatherTable[iEntry].Cmd.EndOfChain,
|
}
|
// m_pScatterGatherTable[iEntry].Cmd.EndOfTrans,
|
pNextDscr = (u16*)pDscrBuf;
|
// m_pScatterGatherTable[iEntry].Signature,
|
pNextDscr[255] |= (u16)ctrl_code;
|
// m_pScatterGatherTable[iEntry].Crc
|
pDscrBuf += DSCR_BLOCK_SIZE;
|
// );
|
}
|
|
return 0;
|
|
}
|
|
|
|
int SetScatterGatherListExtUser(struct CDmaChannel *dma)
|
|
{
|
|
int Status = 0;
|
|
u32 iBlock = 0;
|
|
//u32 ii = 0;
|
|
u32 iEntry = 0;
|
|
u32 iBlkEntry = 0;
|
|
u64 *pDscrBuf = NULL;
|
|
u16* pNextDscr = NULL;
|
|
u32 DscrSize = 0;
|
|
SHARED_MEMORY_DESCRIPTION *pMemDscr = (SHARED_MEMORY_DESCRIPTION*)&dma->m_BufDscrVA;
|
|
DMA_CHAINING_DESCR_EXT *pSGTEx = NULL;
|
|
|
|
printk("%s()\n", __FUNCTION__);
|
|
|
|
Status = RequestSGList(dma);
|
|
if(Status < 0)
|
|
return Status;
|
|
|
|
//получим адрес таблицы для хранения цепочек DMA
|
|
dma->m_pScatterGatherTableExt = (DMA_CHAINING_DESCR_EXT*)dma->m_SGTableDscr.SystemAddress;
|
|
pSGTEx = dma->m_pScatterGatherTableExt;
|
|
|
|
DscrSize = DSCR_BLOCK_SIZE*sizeof(DMA_CHAINING_DESCR_EXT);
|
|
|
|
//обнулим таблицу дескрипторов DMA
|
|
memset(pSGTEx, 0, dma->m_ScatterGatherBlockCnt*DscrSize);
|
|
|
|
printk("%s(): m_SGTableDscr.SystemAddress = %p\n", __FUNCTION__, dma->m_SGTableDscr.SystemAddress );
|
|
printk("%s(): m_SGTableDscr.LogicalAddress = 0x%llx\n", __FUNCTION__, dma->m_SGTableDscr.LogicalAddress );
|
|
|
|
//заполним значениями таблицу цепочек DMA
|
|
for(iBlock=0, iEntry=0; iBlock < pMemDscr->PageCount; iBlock++) {
|
|
|
|
//адрес и размер DMA блока
|
|
u64 address = page_to_phys(pMemDscr->LockedPages[iBlock]);
|
|
u64 DmaSize = dma->m_BlockSize - 0x1000;
|
|
|
|
|
|
//заполним поля элментов таблицы дескрипторов
|
|
pSGTEx[iEntry].AddrByte1 = (u8)((address >> 8) & 0xFF);
|
|
pSGTEx[iEntry].AddrByte2 = (u8)((address >> 16) & 0xFF);
|
|
pSGTEx[iEntry].AddrByte3 = (u8)((address >> 24) & 0xFF);
|
|
pSGTEx[iEntry].AddrByte4 = (u8)((address >> 32) & 0xFF);
|
|
pSGTEx[iEntry].SizeByte1 = (u8)((DmaSize >> 8) & 0xFF);
|
|
pSGTEx[iEntry].SizeByte2 = (u8)((DmaSize >> 16) & 0xFF);
|
|
pSGTEx[iEntry].SizeByte3 = (u8)((DmaSize >> 24) & 0xFF);
|
|
pSGTEx[iEntry].Cmd.JumpNextDescr = 1; //перейти к следующему дескриптору
|
|
pSGTEx[iEntry].Cmd.JumpNextBlock = 0; //перейти к следующему блоку дескрипторов
|
|
pSGTEx[iEntry].Cmd.JumpDescr0 = 0;
|
|
pSGTEx[iEntry].Cmd.Res0 = 0;
|
|
pSGTEx[iEntry].Cmd.EndOfTrans = 1;
|
|
pSGTEx[iEntry].Cmd.Res = 0;
|
|
pSGTEx[iEntry].SizeByte1 |= dma->m_DmaDirection;
|
|
|
|
{
|
|
u32 *ptr=(u32*)&pSGTEx[iEntry];
|
|
printk("%s(): %d: Entry Addr: %p, Data Addr: %llx %.8X %.8X\n",
|
|
__FUNCTION__, iEntry, &pSGTEx[iEntry], address, ptr[1], ptr[0]);
|
|
}
|
|
|
|
if(((iEntry+2)%DSCR_BLOCK_SIZE) == 0)
|
|
{
|
|
size_t NextDscrBlockAddr = 0;
|
|
DMA_NEXT_BLOCK *pNextBlock = NULL;
|
|
|
|
pSGTEx[iEntry].Cmd.JumpNextBlock = 1;
|
|
pSGTEx[iEntry].Cmd.JumpNextDescr = 0;
|
|
|
|
NextDscrBlockAddr = virt_to_phys((void*)&pSGTEx[iEntry+2]);
|
|
//NextDscrBlockAddr = (size_t)((u8*)dma->m_SGTableDscr.LogicalAddress + sizeof(DMA_CHAINING_DESCR_EXT)*(iEntry +2));
|
|
|
|
printk("%s(): NextDscrBlock [PA]: 0x%lx\n", __FUNCTION__, NextDscrBlockAddr);
|
|
printk("%s(): NextDscrBlock [VA]: %p\n", __FUNCTION__, &pSGTEx[iEntry+2]);
|
|
|
|
pNextBlock = (DMA_NEXT_BLOCK*)&pSGTEx[iEntry+1];
|
|
|
|
printk("%s(): pNextBlock: %p\n", __FUNCTION__, pNextBlock);
|
|
|
|
pNextBlock->NextBlkAddr = (NextDscrBlockAddr >> 8) & 0xFFFFFF;
|
|
pNextBlock->Signature = 0x4953;
|
|
pNextBlock->Crc = 0;
|
|
iEntry++;
|
|
}
|
|
iEntry++;
|
|
}
|
|
|
|
printk("%s(): iEntry = %d\n", __FUNCTION__, iEntry);
|
|
|
|
if(((iEntry % DSCR_BLOCK_SIZE)) != 0)
|
|
{
|
|
DMA_NEXT_BLOCK *pNextBlock = NULL;
|
|
u32 i = 0;
|
|
|
|
pSGTEx[iEntry-1].Cmd.JumpNextDescr = 0;
|
|
|
|
pNextBlock = (DMA_NEXT_BLOCK*)(&pSGTEx[iEntry]);
|
|
pNextBlock->NextBlkAddr = (dma->m_SGTableDscr.LogicalAddress >> 8);
|
|
|
|
i = (DSCR_BLOCK_SIZE * dma->m_ScatterGatherBlockCnt) - 1;
|
|
pNextBlock = (DMA_NEXT_BLOCK*)(&pSGTEx[i]);
|
|
|
|
printk("%s(): %d: pNextBlock: %p\n", __FUNCTION__, i, pNextBlock );
|
|
|
|
pNextBlock->NextBlkAddr = 0;
|
|
pNextBlock->Signature = 0x4953;
|
|
pNextBlock->Crc = 0;
|
|
}
|
|
|
|
printk("%s(): DmaDirection = %d, DmaLocalAddress = 0x%X\n", __FUNCTION__, dma->m_DmaDirection, dma->m_DmaLocalAddress);
|
|
|
|
//for( ii=0; ii<dma->m_ScatterGatherBlockCnt*DSCR_BLOCK_SIZE; ii++ )
|
|
//{
|
|
// u32 *ptr=(u32*)&pSGTEx[ii];
|
|
// printk("%s(): %d: %.8X %.8X\n", __FUNCTION__, ii, ptr[1], ptr[0]);
|
|
//}
|
|
|
|
pDscrBuf = (u64*)dma->m_pScatterGatherTableExt;
|
|
|
|
for(iBlkEntry = 0; iBlkEntry < dma->m_ScatterGatherBlockCnt; iBlkEntry++)
|
|
{
|
|
u32 ctrl_code = 0xFFFFFFFF;
|
|
|
|
for(iBlock = 0; iBlock < DSCR_BLOCK_SIZE; iBlock++)
|
|
{
|
|
u16 data0 = (u16)(pDscrBuf[iBlock] & 0xFFFF);
|
|
u16 data1 = (u16)((pDscrBuf[iBlock] >> 16) & 0xFFFF);
|
|
u16 data2 = (u16)((pDscrBuf[iBlock] >> 32) & 0xFFFF);
|
|
u16 data3 = (u16)((pDscrBuf[iBlock] >> 48) & 0xFFFF);
|
|
if(iBlock == DSCR_BLOCK_SIZE-1)
|
|
{
|
|
ctrl_code = ctrl_code ^ data0 ^ data1 ^ data2 ^ data3;
|
|
printk("%s(): DSCR_BLCK[%d] - NextBlkAddr = 0x%8X, Signature = 0x%4X, Crc = 0x%4X\n", __FUNCTION__,
|
|
iBlkEntry,
|
|
(u32)(pDscrBuf[iBlock] << 8),
|
|
(u16)((pDscrBuf[iBlock] >> 32) & 0xFFFF),
|
|
(u16)ctrl_code);
|
|
}
|
|
else
|
|
{
|
|
u32 ctrl_tmp = 0;
|
|
ctrl_code = ctrl_code ^ data0 ^ data1 ^ data2 ^ data3;
|
|
ctrl_tmp = ctrl_code << 1;
|
|
ctrl_tmp |= (ctrl_code & 0x8000) ? 0: 1;
|
|
ctrl_code = ctrl_tmp;
|
|
|
|
printk("%s(): %d(%d) - PciAddr = 0x%8X, Cmd = 0x%2X, DmaLength = %d(%2X %2X %2X)\n", __FUNCTION__,
|
|
iBlock, iBlkEntry,
|
|
(u32)(pDscrBuf[iBlock] << 8),
|
|
(u8)(pDscrBuf[iBlock] >> 32),
|
|
(u32)((pDscrBuf[iBlock] >> 41) << 9),
|
|
(u8)(pDscrBuf[iBlock] >> 56),
|
|
(u8)(pDscrBuf[iBlock] >> 48),
|
|
(u8)(pDscrBuf[iBlock] >> 40));
|
|
//printk("%s(): JumpNextDescr = %d, JumpNextBlock = %d, JumpDescr0 = %d, EndOfTrans = %d, Signature = 0x%08X, Crc = 0x%08X\n",
|
|
// __FUNCTION__, dma->m_pScatterGatherTableExt[iEntry].Cmd.EndOfChain,
|
|
// dma->m_pScatterGatherTableExt[iEntry].Cmd.EndOfTrans,
|
|
// dma->m_pScatterGatherTableExt[iEntry].Signature,
|
|
// dma->m_pScatterGatherTableExt[iEntry].Crc );
|
}
|
}
|
}
|
}
|
pNextDscr = (u16*)pDscrBuf;
|
pNextDscr = (u16*)pDscrBuf;
|
pNextDscr[255] |= (u16)ctrl_code;
|
pNextDscr[255] |= (u16)ctrl_code;
|
pDscrBuf += DSCR_BLOCK_SIZE;
|
pDscrBuf += DSCR_BLOCK_SIZE;
|
Line 371... |
Line 537... |
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
|
|
int RequestSysBuf(struct CDmaChannel *dma, void **pMemPhysAddr)
|
int RequestSysBuf(struct CDmaChannel *dma, void **pMemPhysAddr)
|
{
|
{
|
u32 iBlock = 0;
|
u32 iBlock = 0;
|
u32 order = 0;
|
|
SHARED_MEMORY_DESCRIPTION *pMemDscr = (SHARED_MEMORY_DESCRIPTION*)dma->m_pBufDscr.SystemAddress;
|
SHARED_MEMORY_DESCRIPTION *pMemDscr = (SHARED_MEMORY_DESCRIPTION*)dma->m_pBufDscr.SystemAddress;
|
|
//u32 order = get_order(dma->m_BlockSize);
|
|
|
//printk("<0>%s()\n", __FUNCTION__);
|
printk("%s()\n", __FUNCTION__);
|
|
|
order = get_order(dma->m_BlockSize);
|
|
|
|
for(iBlock = 0; iBlock < dma->m_BlockCount; iBlock++)
|
for(iBlock = 0; iBlock < dma->m_BlockCount; iBlock++)
|
{
|
{
|
dma_addr_t LogicalAddress;
|
dma_addr_t LogicalAddress;
|
void *pSystemAddress = NULL;
|
void *pSystemAddress = NULL;
|
u32 *buffer = NULL;
|
|
int iii=0;
|
|
|
|
|
// if buffer not allocated - allocate memory
|
|
if(dma->m_UseCount == 0) {
|
pSystemAddress = dma_alloc_coherent( dma->m_dev, dma->m_BlockSize, &LogicalAddress, GFP_KERNEL );
|
pSystemAddress = dma_alloc_coherent( dma->m_dev, dma->m_BlockSize, &LogicalAddress, GFP_KERNEL );
|
//pSystemAddress = (void*)__get_free_pages(GFP_KERNEL, order);
|
//pSystemAddress = (void*)__get_free_pages(GFP_KERNEL, order);
|
if(!pSystemAddress) {
|
if(!pSystemAddress) {
|
printk("<0>%s(): Not enought memory for %i block location. m_BlockSize = %X, BlockOrder = %d\n",
|
printk("%s(): Not enought memory for %i block location. m_BlockSize = %X\n",
|
__FUNCTION__, (int)iBlock, (int)dma->m_BlockSize, (int)order );
|
__FUNCTION__, (int)iBlock, (int)dma->m_BlockSize );
|
return -ENOMEM;
|
return -ENOMEM;
|
}
|
}
|
|
|
pMemDscr[iBlock].SystemAddress = pSystemAddress;
|
pMemDscr[iBlock].SystemAddress = pSystemAddress;
|
pMemDscr[iBlock].LogicalAddress = LogicalAddress;
|
pMemDscr[iBlock].LogicalAddress = LogicalAddress;
|
//pMemDscr[iBlock].LogicalAddress = virt_to_bus(pSystemAddress);
|
//pMemDscr[iBlock].LogicalAddress = virt_to_bus(pSystemAddress);
|
|
|
lock_pages( pMemDscr[iBlock].SystemAddress, dma->m_BlockSize );
|
lock_pages( pMemDscr[iBlock].SystemAddress, dma->m_BlockSize );
|
|
}
|
|
|
|
// if buffer allocated - copy memory block addresses
|
pMemPhysAddr[iBlock] = (void*)pMemDscr[iBlock].LogicalAddress;
|
pMemPhysAddr[iBlock] = (void*)pMemDscr[iBlock].LogicalAddress;
|
|
|
buffer = (u32*)pMemDscr[iBlock].SystemAddress;
|
{
|
for(iii=0; iii<dma->m_BlockSize/4; iii++) {
|
// fill memory block
|
buffer[iii] = 0x12345678;
|
//int iii=0;
|
|
//u32 *buffer = (u32*)pMemDscr[iBlock].SystemAddress;
|
|
//for(iii=0; iii<dma->m_BlockSize/4; iii++) {
|
|
// buffer[iii] = 0x12345678;
|
|
//}
|
}
|
}
|
|
|
//printk("<0>%s(): %i: %p\n", __FUNCTION__, iBlock, pMemPhysAddr[iBlock]);
|
printk("%s(): %i: %p\n", __FUNCTION__, iBlock, pMemPhysAddr[iBlock]);
|
}
|
}
|
|
|
dma->m_BlockCount = iBlock;
|
dma->m_BlockCount = iBlock;
|
dma->m_ScatterGatherTableEntryCnt = iBlock;
|
dma->m_ScatterGatherTableEntryCnt = iBlock;
|
|
|
return 0;
|
return 0;
|
}
|
}
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
|
|
void ReleaseSysBuf(struct CDmaChannel *dma)
|
int ReleaseSysBuf(struct CDmaChannel *dma)
|
{
|
{
|
u32 iBlock = 0;
|
u32 iBlock = 0;
|
//u32 order = 0;
|
|
SHARED_MEMORY_DESCRIPTION *pMemDscr = (SHARED_MEMORY_DESCRIPTION*)dma->m_pBufDscr.SystemAddress;
|
SHARED_MEMORY_DESCRIPTION *pMemDscr = (SHARED_MEMORY_DESCRIPTION*)dma->m_pBufDscr.SystemAddress;
|
|
//u32 order = get_order(dma->m_BlockSize);
|
|
|
//printk("<0>%s()\n", __FUNCTION__);
|
if(dma->m_UseCount != 0) {
|
|
printk("%s(): Memory may be used in another process! m_UseCount = %d.\n", __FUNCTION__, dma->m_UseCount);
|
//order = get_order(dma->m_BlockSize);
|
return -1;
|
|
|
if(!dma->m_UseCount) {
|
|
printk("<0> ReleaseSysBuf(): Memory not allocated.\n");
|
|
return;
|
|
}
|
}
|
|
|
|
printk("%s()\n", __FUNCTION__);
|
|
|
for(iBlock = 0; iBlock < dma->m_BlockCount; iBlock++)
|
for(iBlock = 0; iBlock < dma->m_BlockCount; iBlock++)
|
{
|
{
|
unlock_pages( pMemDscr[iBlock].SystemAddress, dma->m_BlockSize );
|
unlock_pages( pMemDscr[iBlock].SystemAddress, dma->m_BlockSize );
|
|
|
dma_free_coherent( dma->m_dev, dma->m_BlockSize, pMemDscr[iBlock].SystemAddress, pMemDscr[iBlock].LogicalAddress );
|
dma_free_coherent( dma->m_dev, dma->m_BlockSize, pMemDscr[iBlock].SystemAddress, pMemDscr[iBlock].LogicalAddress );
|
//free_pages((size_t)pMemDscr[iBlock].SystemAddress, order);
|
//free_pages((size_t)pMemDscr[iBlock].SystemAddress, order);
|
|
|
pMemDscr[iBlock].SystemAddress = NULL;
|
pMemDscr[iBlock].SystemAddress = NULL;
|
pMemDscr[iBlock].LogicalAddress = 0;
|
pMemDscr[iBlock].LogicalAddress = 0;
|
}
|
}
|
|
|
|
return 0;
|
}
|
}
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
|
|
int RequestStub(struct CDmaChannel *dma, void **pStubPhysAddr)
|
int RequestStub(struct CDmaChannel *dma, void **pStubPhysAddr)
|
{
|
{
|
dma_addr_t LogicalAddress = 0;
|
dma_addr_t LogicalAddress = 0;
|
u32 StubSize = 0;
|
u32 StubSize = 0;
|
|
|
//printk("<0>%s()\n", __FUNCTION__ );
|
//printk("%s()\n", __FUNCTION__ );
|
|
|
if(!dma)
|
if(!dma)
|
return -EINVAL;
|
return -EINVAL;
|
|
|
StubSize = sizeof(AMB_STUB) > PAGE_SIZE ? sizeof(AMB_STUB) : PAGE_SIZE;
|
StubSize = sizeof(AMB_STUB) > PAGE_SIZE ? sizeof(AMB_STUB) : PAGE_SIZE;
|
|
|
//printk("<0>%s() 0\n", __FUNCTION__ );
|
//printk("%s() 0\n", __FUNCTION__ );
|
|
|
if(!dma->m_UseCount)
|
if(dma->m_UseCount == 0)
|
{
|
{
|
void *pStub = dma_alloc_coherent( dma->m_dev, StubSize, &LogicalAddress, GFP_KERNEL );
|
void *pStub = dma_alloc_coherent( dma->m_dev, StubSize, &LogicalAddress, GFP_KERNEL );
|
if(!pStub)
|
if(!pStub)
|
{
|
{
|
printk("<0>%s(): Not enought memory for stub\n", __FUNCTION__);
|
printk("%s(): Not enought memory for stub\n", __FUNCTION__);
|
return -ENOMEM;
|
return -ENOMEM;
|
}
|
}
|
|
|
lock_pages( pStub, StubSize );
|
lock_pages( pStub, StubSize );
|
|
|
//printk("<0>%s() 1\n", __FUNCTION__ );
|
//printk("%s() 1\n", __FUNCTION__ );
|
|
|
dma->m_StubDscr.SystemAddress = pStub;
|
dma->m_StubDscr.SystemAddress = pStub;
|
dma->m_StubDscr.LogicalAddress = LogicalAddress;
|
dma->m_StubDscr.LogicalAddress = LogicalAddress;
|
dma->m_pStub = (AMB_STUB*)pStub; //может быть в этом нет необходимости,
|
dma->m_pStub = (AMB_STUB*)pStub; //может быть в этом нет необходимости,
|
//но в дальнейшем в модуле используется dma->m_pStub
|
//но в дальнейшем в модуле используется dma->m_pStub
|
}
|
}
|
|
|
//printk("<0>%s() 2\n", __FUNCTION__ );
|
//printk("%s() 2\n", __FUNCTION__ );
|
|
|
pStubPhysAddr[0] = (void*)dma->m_StubDscr.LogicalAddress;
|
pStubPhysAddr[0] = (void*)dma->m_StubDscr.LogicalAddress;
|
|
|
//printk("<0>%s(): Stub physical address: %zx\n", __FUNCTION__, dma->m_StubDscr.LogicalAddress);
|
printk("%s(): Stub physical address: %llx\n", __FUNCTION__, dma->m_StubDscr.LogicalAddress);
|
//printk("<0>%s(): Stub virtual address: %p\n", __FUNCTION__, dma->m_StubDscr.SystemAddress);
|
printk("%s(): Stub virtual address: %p\n", __FUNCTION__, dma->m_StubDscr.SystemAddress);
|
|
|
return 0;
|
return 0;
|
}
|
}
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
|
|
void ReleaseStub(struct CDmaChannel *dma)
|
void ReleaseStub(struct CDmaChannel *dma)
|
{
|
{
|
u32 StubSize = sizeof(AMB_STUB) > PAGE_SIZE ? sizeof(AMB_STUB) : PAGE_SIZE;
|
u32 StubSize = sizeof(AMB_STUB) > PAGE_SIZE ? sizeof(AMB_STUB) : PAGE_SIZE;
|
|
|
//printk("<0>%s()\n", __FUNCTION__);
|
if(dma->m_UseCount == 0)
|
|
|
if(!dma->m_UseCount)
|
|
{
|
{
|
unlock_pages(dma->m_StubDscr.SystemAddress, StubSize);
|
unlock_pages(dma->m_StubDscr.SystemAddress, StubSize);
|
|
|
dma_free_coherent(dma->m_dev, StubSize,
|
dma_free_coherent(dma->m_dev, StubSize,
|
dma->m_StubDscr.SystemAddress,
|
dma->m_StubDscr.SystemAddress,
|
dma->m_StubDscr.LogicalAddress);
|
dma->m_StubDscr.LogicalAddress);
|
dma->m_pStub = NULL;
|
dma->m_pStub = NULL;
|
dma->m_StubDscr.SystemAddress = NULL;
|
dma->m_StubDscr.SystemAddress = NULL;
|
dma->m_StubDscr.LogicalAddress = 0;
|
dma->m_StubDscr.LogicalAddress = 0;
|
|
|
|
printk("%s()\n", __FUNCTION__);
|
}
|
}
|
}
|
}
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// вызываем только при первичном размещении буфера
|
// вызываем только при первичном размещении буфера
|
Line 520... |
Line 690... |
{
|
{
|
u32 SGListMemSize = 0;
|
u32 SGListMemSize = 0;
|
u32 SGListSize = 0;
|
u32 SGListSize = 0;
|
dma_addr_t PhysicalAddress;
|
dma_addr_t PhysicalAddress;
|
|
|
//printk("<0>%s()\n", __FUNCTION__);
|
printk("%s()\n", __FUNCTION__);
|
|
|
if(dma->m_idBlockFifo == PE_EXT_FIFO_ID)
|
if(dma->m_idBlockFifo == PE_EXT_FIFO_ID)
|
{
|
{
|
dma->m_ScatterGatherBlockCnt = dma->m_ScatterGatherTableEntryCnt / (DSCR_BLOCK_SIZE-1);
|
dma->m_ScatterGatherBlockCnt = dma->m_ScatterGatherTableEntryCnt / (DSCR_BLOCK_SIZE-1);
|
dma->m_ScatterGatherBlockCnt = (dma->m_ScatterGatherTableEntryCnt % (DSCR_BLOCK_SIZE-1)) ? (dma->m_ScatterGatherBlockCnt+1) : dma->m_ScatterGatherBlockCnt;
|
dma->m_ScatterGatherBlockCnt = (dma->m_ScatterGatherTableEntryCnt % (DSCR_BLOCK_SIZE-1)) ? (dma->m_ScatterGatherBlockCnt+1) : dma->m_ScatterGatherBlockCnt;
|
SGListSize = sizeof(DMA_CHAINING_DESCR_EXT) * DSCR_BLOCK_SIZE * dma->m_ScatterGatherBlockCnt;
|
SGListSize = sizeof(DMA_CHAINING_DESCR_EXT) * DSCR_BLOCK_SIZE * dma->m_ScatterGatherBlockCnt;
|
//printk("<0>%s(): SGBlockCnt = %d, SGListSize = %d.\n", __FUNCTION__, dma->m_ScatterGatherBlockCnt, SGListSize);
|
printk("%s(): SGBlockCnt = %d, SGListSize = %d.\n", __FUNCTION__, dma->m_ScatterGatherBlockCnt, SGListSize);
|
}
|
}
|
|
|
SGListMemSize = (SGListSize >= PAGE_SIZE) ? SGListSize : PAGE_SIZE;
|
SGListMemSize = (SGListSize >= PAGE_SIZE) ? SGListSize : PAGE_SIZE;
|
|
|
// выделяем память под список
|
// выделяем память под список
|
dma->m_SGTableDscr.SystemAddress = dma_alloc_coherent( dma->m_dev, SGListMemSize, &PhysicalAddress, GFP_KERNEL);
|
dma->m_SGTableDscr.SystemAddress = dma_alloc_coherent( dma->m_dev, SGListMemSize, &PhysicalAddress, GFP_KERNEL);
|
if(!dma->m_SGTableDscr.SystemAddress)
|
if(!dma->m_SGTableDscr.SystemAddress)
|
{
|
{
|
printk("<0>%s(): Not enought memory for scatter/gather list\n", __FUNCTION__);
|
printk("%s(): Not enought memory for scatter/gather list\n", __FUNCTION__);
|
return -ENOMEM;
|
return -ENOMEM;
|
}
|
}
|
|
|
dma->m_SGTableDscr.LogicalAddress = PhysicalAddress;
|
dma->m_SGTableDscr.LogicalAddress = PhysicalAddress;
|
|
|
Line 550... |
Line 720... |
return 0;
|
return 0;
|
}
|
}
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
|
|
void ReleaseSGList(struct CDmaChannel *dma)
|
int ReleaseSGList(struct CDmaChannel *dma)
|
{
|
{
|
u32 SGListMemSize = 0;
|
u32 SGListMemSize = 0;
|
u32 SGListSize = 0;
|
u32 SGListSize = 0;
|
|
|
//printk("<0>%s()\n", __FUNCTION__);
|
if(dma->m_UseCount != 0) {
|
|
printk("%s(): Memory may be used in anoether process. m_UseCount = %d\n", __FUNCTION__, dma->m_UseCount);
|
|
return -1;
|
|
}
|
|
|
if(dma->m_idBlockFifo == PE_EXT_FIFO_ID)
|
printk("%s()\n", __FUNCTION__);
|
{
|
|
|
if(dma->m_idBlockFifo == PE_EXT_FIFO_ID) {
|
SGListSize = sizeof(DMA_CHAINING_DESCR_EXT) * DSCR_BLOCK_SIZE * dma->m_ScatterGatherBlockCnt;
|
SGListSize = sizeof(DMA_CHAINING_DESCR_EXT) * DSCR_BLOCK_SIZE * dma->m_ScatterGatherBlockCnt;
|
}
|
}
|
|
|
SGListMemSize = (SGListSize >= PAGE_SIZE) ? SGListSize : PAGE_SIZE;
|
SGListMemSize = (SGListSize >= PAGE_SIZE) ? SGListSize : PAGE_SIZE;
|
|
|
// закрепляем список в физической памяти
|
// освободим страницы списока из физической памяти
|
unlock_pages(dma->m_SGTableDscr.SystemAddress, SGListMemSize);
|
unlock_pages(dma->m_SGTableDscr.SystemAddress, SGListMemSize);
|
|
|
dma_free_coherent( dma->m_dev, SGListMemSize,
|
dma_free_coherent( dma->m_dev, SGListMemSize,
|
dma->m_SGTableDscr.SystemAddress,
|
dma->m_SGTableDscr.SystemAddress,
|
dma->m_SGTableDscr.LogicalAddress );
|
dma->m_SGTableDscr.LogicalAddress );
|
|
|
dma->m_SGTableDscr.SystemAddress = NULL;
|
dma->m_SGTableDscr.SystemAddress = NULL;
|
dma->m_SGTableDscr.LogicalAddress = 0;
|
dma->m_SGTableDscr.LogicalAddress = 0;
|
|
|
|
return 0;
|
}
|
}
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
|
|
int StartDmaTransfer(struct CDmaChannel *dma, u32 IsCycling)
|
int StartDmaTransfer(struct CDmaChannel *dma, u32 IsCycling)
|
{
|
{
|
//printk("<0>%s()\n", __FUNCTION__);
|
printk("%s()\n", __FUNCTION__);
|
|
|
dma->m_DmaCycling = IsCycling;
|
dma->m_DmaCycling = IsCycling;
|
dma->m_DoneBlock = -1;
|
dma->m_DoneBlock = -1;
|
dma->m_DoneFlag = 1;
|
dma->m_DoneFlag = 1;
|
dma->m_CycleNum = 0;
|
dma->m_CycleNum = 0;
|
Line 597... |
Line 773... |
{
|
{
|
u64 *pDscrBuf = NULL;
|
u64 *pDscrBuf = NULL;
|
u32 ctrl_code = ~0;
|
u32 ctrl_code = ~0;
|
u16* pDscr = NULL;
|
u16* pDscr = NULL;
|
int iEntry = 0;
|
int iEntry = 0;
|
|
int ii=0;
|
|
DMA_CHAINING_DESCR_EXT *pSGTEx = dma->m_pScatterGatherTableExt;
|
|
|
u32 iLastEntry = dma->m_ScatterGatherTableEntryCnt + dma->m_ScatterGatherBlockCnt - 1;
|
u32 iLastEntry = dma->m_ScatterGatherTableEntryCnt + dma->m_ScatterGatherBlockCnt - 1;
|
if(dma->m_ScatterGatherBlockCnt == 1)
|
if(dma->m_ScatterGatherBlockCnt == 1)
|
dma->m_pScatterGatherTableExt[iLastEntry - 1].Cmd.JumpDescr0 = dma->m_DmaCycling;
|
dma->m_pScatterGatherTableExt[iLastEntry - 1].Cmd.JumpDescr0 = dma->m_DmaCycling;
|
else
|
else
|
dma->m_pScatterGatherTableExt[iLastEntry - 1].Cmd.JumpNextBlock = dma->m_DmaCycling;
|
dma->m_pScatterGatherTableExt[iLastEntry - 1].Cmd.JumpNextBlock = dma->m_DmaCycling;
|
|
|
//printk("<0>%s(): m_DmaCycling = %d\n", __FUNCTION__, dma->m_DmaCycling);
|
printk("%s(): m_DmaCycling = %d\n", __FUNCTION__, dma->m_DmaCycling);
|
|
|
pDscrBuf = (u64*)dma->m_pScatterGatherTableExt + DSCR_BLOCK_SIZE * (dma->m_ScatterGatherBlockCnt - 1);
|
pDscrBuf = (u64*)dma->m_pScatterGatherTableExt + DSCR_BLOCK_SIZE * (dma->m_ScatterGatherBlockCnt - 1);
|
ctrl_code = 0xFFFFFFFF;
|
ctrl_code = 0xFFFFFFFF;
|
pDscr = (u16*)pDscrBuf;
|
pDscr = (u16*)pDscrBuf;
|
pDscr[255] = 0;
|
pDscr[255] = 0;
|
Line 618... |
Line 797... |
u16 data2 = (u16)((pDscrBuf[iEntry] >> 32) & 0xFFFF);
|
u16 data2 = (u16)((pDscrBuf[iEntry] >> 32) & 0xFFFF);
|
u16 data3 = (u16)((pDscrBuf[iEntry] >> 48) & 0xFFFF);
|
u16 data3 = (u16)((pDscrBuf[iEntry] >> 48) & 0xFFFF);
|
if(iEntry == DSCR_BLOCK_SIZE-1)
|
if(iEntry == DSCR_BLOCK_SIZE-1)
|
{
|
{
|
ctrl_code = ctrl_code ^ data0 ^ data1 ^ data2 ^ data3;
|
ctrl_code = ctrl_code ^ data0 ^ data1 ^ data2 ^ data3;
|
/*
|
|
printk("<0>%s(): DSCR_BLK[%d] - NextBlkAddr = 0x%08X, Signature = 0x%04X, Crc = 0x%04X\n",
|
//printk("%s(): DSCR_BLK[%d] - NextBlkAddr = 0x%08X, Signature = 0x%04X, Crc = 0x%04X\n",
|
__FUNCTION__,
|
// __FUNCTION__,
|
dma->m_ScatterGatherBlockCnt-1,
|
// dma->m_ScatterGatherBlockCnt-1,
|
(u32)(pDscrBuf[iEntry] << 8),
|
// (u32)(pDscrBuf[iEntry] << 8),
|
(u16)((pDscrBuf[iEntry] >> 32) & 0xFFFF),
|
// (u16)((pDscrBuf[iEntry] >> 32) & 0xFFFF),
|
(u16)ctrl_code);
|
// (u16)ctrl_code);
|
*/
|
|
|
printk("%s(): ENTRY[%d] - SIGN = 0x%04X, CRC = 0x%04X\n", __FUNCTION__, iEntry, (u16)((pDscrBuf[iEntry] >> 32) & 0xFFFF), (u16)ctrl_code);
|
}
|
}
|
else
|
else
|
{
|
{
|
u32 ctrl_tmp = 0;
|
u32 ctrl_tmp = 0;
|
ctrl_code = ctrl_code ^ data0 ^ data1 ^ data2 ^ data3;
|
ctrl_code = ctrl_code ^ data0 ^ data1 ^ data2 ^ data3;
|
Line 643... |
Line 823... |
//ctrl_code = (ctrl_code << 1) | (ctrl_code >> 31);
|
//ctrl_code = (ctrl_code << 1) | (ctrl_code >> 31);
|
//__asm {
|
//__asm {
|
// rol ctrl_code,1
|
// rol ctrl_code,1
|
//}
|
//}
|
|
|
//printk("<0>%s(): %d(%d) - PciAddr = 0x%08X, Cmd = 0x%02X, DmaLength = %d(%02X %02X %02X)\n",
|
//printk("%s(): %02d(%02d) - PciAddr = 0x%08X, Cmd = 0x%04X, DmaLength = 0x%08X (%02X %02X %02X)\n",
|
// __FUNCTION__,
|
// __FUNCTION__,
|
// iEntry, dma->m_ScatterGatherBlockCnt-1,
|
// iEntry, dma->m_ScatterGatherBlockCnt-1,
|
// (u32)(pDscrBuf[iEntry] << 8),
|
// (u32)(pDscrBuf[iEntry] << 8),
|
// (u16)(pDscrBuf[iEntry] >> 32),
|
// (u16)(pDscrBuf[iEntry] >> 32),
|
// (u32)((pDscrBuf[iEntry] >> 41) << 9),
|
// (u32)((pDscrBuf[iEntry] >> 41) << 9),
|
// (u8)(pDscrBuf[iEntry] >> 56), (u8)(pDscrBuf[iEntry] >> 48), (u8)(pDscrBuf[iEntry] >> 40));
|
// (u8)(pDscrBuf[iEntry] >> 56), (u8)(pDscrBuf[iEntry] >> 48), (u8)(pDscrBuf[iEntry] >> 40));
|
}
|
}
|
}
|
}
|
pDscr[255] |= (u16)ctrl_code;
|
pDscr[255] |= (u16)ctrl_code;
|
|
|
|
printk("%s(): S/G LIST\n",__FUNCTION__);
|
|
for( ii=0; ii<dma->m_ScatterGatherBlockCnt*DSCR_BLOCK_SIZE; ii++ )
|
|
{
|
|
u32 *ptr=(u32*)&pSGTEx[ii];
|
|
printk("%s(): %02d: %08X %08X\n", __FUNCTION__, ii, ptr[1], ptr[0]);
|
|
}
|
|
printk("%s()\n",__FUNCTION__);
|
}
|
}
|
|
|
dma->m_pStub->lastBlock = -1;
|
dma->m_pStub->lastBlock = -1;
|
dma->m_pStub->totalCounter = 0;
|
dma->m_pStub->totalCounter = 0;
|
dma->m_pStub->state = STATE_RUN;
|
dma->m_pStub->state = STATE_RUN;
|
Line 666... |
Line 854... |
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
|
|
u32 NextDmaTransfer(struct CDmaChannel *dma)
|
u32 NextDmaTransfer(struct CDmaChannel *dma)
|
{
|
{
|
//printk("<0>%s(): - last block = %d, cycle counter = %d\n", __FUNCTION__, dma->m_pStub->lastBlock, dma->m_CycleNum);
|
printk("%s(): - last block = %d, cycle counter = %d\n", __FUNCTION__, dma->m_pStub->lastBlock, dma->m_CycleNum);
|
|
|
if(dma->m_pStub->lastBlock + 1 >= (long)dma->m_BlockCount)
|
if(dma->m_pStub->lastBlock + 1 >= (long)dma->m_BlockCount)
|
dma->m_pStub->lastBlock = 0;
|
dma->m_pStub->lastBlock = 0;
|
else
|
else
|
dma->m_pStub->lastBlock++;
|
dma->m_pStub->lastBlock++;
|
Line 679... |
Line 867... |
dma->m_pStub->totalCounter++;
|
dma->m_pStub->totalCounter++;
|
dma->m_BlocksRemaining--;
|
dma->m_BlocksRemaining--;
|
|
|
tasklet_hi_schedule(&dma->m_Dpc);
|
tasklet_hi_schedule(&dma->m_Dpc);
|
|
|
//printk("<0>%s(): tasklet_hi_schedule()\n", __FUNCTION__);
|
//printk("%s(): tasklet_hi_schedule()\n", __FUNCTION__);
|
/*
|
/*
|
if(dma->m_AdjustMode && dma->m_DmaCycling)
|
if(dma->m_AdjustMode && dma->m_DmaCycling)
|
{
|
{
|
u32 next_done_blk = (dma->m_DoneBlock == dma->m_BlockCount-1) ? 0 : (dma->m_DoneBlock + 1);
|
u32 next_done_blk = (dma->m_DoneBlock == dma->m_BlockCount-1) ? 0 : (dma->m_DoneBlock + 1);
|
u32 next_cur_blk = ((dma->m_CurBlockNum + 1) >= dma->m_BlockCount) ? ((dma->m_CurBlockNum + 1) - dma->m_BlockCount) : (dma->m_CurBlockNum + 1);
|
u32 next_cur_blk = ((dma->m_CurBlockNum + 1) >= dma->m_BlockCount) ? ((dma->m_CurBlockNum + 1) - dma->m_BlockCount) : (dma->m_CurBlockNum + 1);
|
Line 727... |
Line 915... |
|
|
if(dma->m_AdjustMode && dma->m_DmaCycling)
|
if(dma->m_AdjustMode && dma->m_DmaCycling)
|
{
|
{
|
if(((dma->m_preBlockCount3 == 0)&&(dma->m_DoneBlock == -1)) || (dma->m_preBlockCount3 == dma->m_DoneBlock)) {
|
if(((dma->m_preBlockCount3 == 0)&&(dma->m_DoneBlock == -1)) || (dma->m_preBlockCount3 == dma->m_DoneBlock)) {
|
dma->m_DoneFlag = 0;
|
dma->m_DoneFlag = 0;
|
//printk("<0>%s(): m_preBlockCount = %d, m_DoneBlock = %d\n", __FUNCTION__, dma->m_preBlockCount3, dma->m_DoneBlock);
|
printk("%s(): m_preBlockCount = %d, m_DoneBlock = %d\n", __FUNCTION__, dma->m_preBlockCount3, dma->m_DoneBlock);
|
}
|
}
|
}
|
}
|
|
|
return dma->m_DoneFlag;
|
return dma->m_DoneFlag;
|
}
|
}
|
Line 751... |
Line 939... |
dma->m_DoneFlag = 1;
|
dma->m_DoneFlag = 1;
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
//printk("<0>%s(): DoneBlock = %d, DoneFlag = %d\n", __FUNCTION__, dma->m_DoneBlock, dma->m_DoneFlag);
|
printk("%s(): DoneBlock = %d, DoneFlag = %d\n", __FUNCTION__, dma->m_DoneBlock, dma->m_DoneFlag);
|
|
|
return dma->m_DoneFlag;
|
return dma->m_DoneFlag;
|
}
|
}
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
|
|
void GetState(struct CDmaChannel *dma, u32 *BlockNum, u32 *BlockNumTotal, u32 *OffsetInBlock, u32 *DmaChanState)
|
void GetState(struct CDmaChannel *dma, u32 *BlockNum, u32 *BlockNumTotal, u32 *OffsetInBlock, u32 *DmaChanState)
|
{
|
{
|
//printk("<0>%s(): - last block = %d, cycle counter = %d\n", __FUNCTION__, dma->m_pStub->lastBlock, dma->m_CycleNum);
|
//printk("%s(): - last block = %d, cycle counter = %d\n", __FUNCTION__, dma->m_pStub->lastBlock, dma->m_CycleNum);
|
|
|
*BlockNum = dma->m_State.lastBlock;
|
*BlockNum = dma->m_State.lastBlock;
|
*BlockNumTotal = dma->m_State.totalCounter;
|
*BlockNumTotal = dma->m_State.totalCounter;
|
*OffsetInBlock = dma->m_State.offset;// регистр подсчета переданных байт в текущем буфере будет реализован позже
|
*OffsetInBlock = dma->m_State.offset;// регистр подсчета переданных байт в текущем буфере будет реализован позже
|
*DmaChanState = dma->m_State.state;
|
*DmaChanState = dma->m_State.state;
|
Line 772... |
Line 960... |
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
|
|
void FreezeState(struct CDmaChannel *dma)
|
void FreezeState(struct CDmaChannel *dma)
|
{
|
{
|
//printk("<0>%s()\n", __FUNCTION__);
|
//printk("%s()\n", __FUNCTION__);
|
}
|
}
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
|
|
int WaitBlockEndEvent(struct CDmaChannel *dma, u32 msTimeout)
|
int WaitBlockEndEvent(struct CDmaChannel *dma, u32 msTimeout)
|
{
|
{
|
int status = -ETIMEDOUT;
|
int status = -ETIMEDOUT;
|
|
|
//printk("<0>%s(): DMA%d\n", __FUNCTION__, dma->m_NumberOfChannel);
|
//printk("%s(): DMA%d\n", __FUNCTION__, dma->m_NumberOfChannel);
|
|
|
if( msTimeout < 0 ) {
|
if( msTimeout < 0 ) {
|
status = GrabEvent( &dma->m_BlockEndEvent, -1 );
|
status = GrabEvent( &dma->m_BlockEndEvent, -1 );
|
} else {
|
} else {
|
status = GrabEvent( &dma->m_BlockEndEvent, msTimeout );
|
status = GrabEvent( &dma->m_BlockEndEvent, msTimeout );
|
Line 797... |
Line 985... |
|
|
int WaitBufferEndEvent(struct CDmaChannel *dma, u32 msTimeout)
|
int WaitBufferEndEvent(struct CDmaChannel *dma, u32 msTimeout)
|
{
|
{
|
int status = -ETIMEDOUT;
|
int status = -ETIMEDOUT;
|
|
|
//printk("<0>%s(): DMA%d\n", __FUNCTION__, dma->m_NumberOfChannel);
|
//printk("%s(): DMA%d\n", __FUNCTION__, dma->m_NumberOfChannel);
|
|
|
if( msTimeout < 0 ) {
|
if( msTimeout < 0 ) {
|
status = GrabEvent( &dma->m_BufferEndEvent, -1 );
|
status = GrabEvent( &dma->m_BufferEndEvent, -1 );
|
} else {
|
} else {
|
status = GrabEvent( &dma->m_BufferEndEvent, msTimeout );
|
status = GrabEvent( &dma->m_BufferEndEvent, msTimeout );
|
Line 812... |
Line 1000... |
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
|
|
int CompleteDmaTransfer(struct CDmaChannel *dma)
|
int CompleteDmaTransfer(struct CDmaChannel *dma)
|
{
|
{
|
//printk("<0> %s(): DMA%d\n", __FUNCTION__, dma->m_NumberOfChannel);
|
//printk("%s(): DMA%d\n", __FUNCTION__, dma->m_NumberOfChannel);
|
dma->m_pStub->state = STATE_STOP;
|
dma->m_pStub->state = STATE_STOP;
|
return 0;
|
return 0;
|
}
|
}
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
Line 848... |
Line 1036... |
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
|
|
void Adjust(struct CDmaChannel *dma, u32 mode)
|
void Adjust(struct CDmaChannel *dma, u32 mode)
|
{
|
{
|
//printk("<0>%s()\n", __FUNCTION__);
|
//printk("%s()\n", __FUNCTION__);
|
dma->m_AdjustMode = mode;
|
dma->m_AdjustMode = mode;
|
}
|
}
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
|
|
void SetAdmTetr(struct CDmaChannel *dma, u32 AdmNum, u32 TetrNum)
|
void SetAdmTetr(struct CDmaChannel *dma, u32 AdmNum, u32 TetrNum)
|
{
|
{
|
//printk("<0>%s()\n", __FUNCTION__);
|
//printk("%s()\n", __FUNCTION__);
|
dma->m_AdmNum = AdmNum;
|
dma->m_AdmNum = AdmNum;
|
dma->m_TetrNum = TetrNum;
|
dma->m_TetrNum = TetrNum;
|
}
|
}
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
|
|
void SetDmaLocalAddress(struct CDmaChannel *dma, u32 Address)
|
void SetDmaLocalAddress(struct CDmaChannel *dma, u32 Address)
|
{
|
{
|
//printk("<0>%s()\n", __FUNCTION__);
|
//printk("%s()\n", __FUNCTION__);
|
dma->m_DmaLocalAddress = Address;
|
dma->m_DmaLocalAddress = Address;
|
}
|
}
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
|
|
int SetDmaDirection(struct CDmaChannel *dma, u32 DmaDirection)
|
int SetDmaDirection(struct CDmaChannel *dma, u32 DmaDirection)
|
{
|
{
|
printk("<0>%s()\n", __FUNCTION__);
|
printk("%s()\n", __FUNCTION__);
|
switch(DmaDirection)
|
switch(DmaDirection)
|
{
|
{
|
case 1:
|
case 1:
|
dma->m_DmaDirection = TRANSFER_DIR_FROM_DEVICE;
|
dma->m_DmaDirection = TRANSFER_DIR_FROM_DEVICE;
|
break;
|
break;
|
Line 904... |
Line 1092... |
{
|
{
|
return dma->m_TetrNum;
|
return dma->m_TetrNum;
|
}
|
}
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
|
/*
|
|
void DmaDpcForIsr( unsigned long Context )
|
|
{
|
|
struct CDmaChannel *DmaChannel = (struct CDmaChannel *)Context;
|
|
unsigned long flags = 0;
|
|
|
void DmaDpcForIsr( unsigned long Context )
|
spin_lock_irqsave(&DmaChannel->m_DmaLock, flags);
|
{
|
|
struct CDmaChannel *DmaChannel = (struct CDmaChannel *)Context;
|
|
unsigned long flags = 0;
|
|
|
|
spin_lock_irqsave(&DmaChannel->m_DmaLock, flags);
|
|
|
|
//printk("<0>%s(): [DMA%d] m_CurBlockNum = %d, m_BlockCount = %d\n",
|
printk("%s(): [DMA%d] m_CurBlockNum = %d, m_BlockCount = %d\n",
|
// __FUNCTION__, DmaChannel->m_NumberOfChannel, DmaChannel->m_CurBlockNum, DmaChannel->m_BlockCount );
|
__FUNCTION__, DmaChannel->m_NumberOfChannel, DmaChannel->m_CurBlockNum, DmaChannel->m_BlockCount );
|
DmaChannel->m_State = *DmaChannel->m_pStub;
|
DmaChannel->m_State = *DmaChannel->m_pStub;
|
|
|
SetEvent( &DmaChannel->m_BlockEndEvent );
|
SetEvent( &DmaChannel->m_BlockEndEvent );
|
|
|
if(DmaChannel->m_CurBlockNum >= DmaChannel->m_BlockCount)
|
if(DmaChannel->m_CurBlockNum >= DmaChannel->m_BlockCount)
|
{
|
{
|
HwCompleteDmaTransfer(DmaChannel->m_Board,DmaChannel->m_NumberOfChannel);
|
HwCompleteDmaTransfer(DmaChannel->m_Board,DmaChannel->m_NumberOfChannel);
|
SetEvent( &DmaChannel->m_BufferEndEvent );
|
SetEvent( &DmaChannel->m_BufferEndEvent );
|
}
|
wake_up_interruptible(&DmaChannel->m_DmaWq);
|
|
printk("%s(): Wake up!\n", __FUNCTION__);
|
|
}
|
|
|
spin_unlock_irqrestore(&DmaChannel->m_DmaLock, flags);
|
spin_unlock_irqrestore(&DmaChannel->m_DmaLock, flags);
|
}
|
}
|
|
*/
|
|
|
No newline at end of file
|
No newline at end of file
|