OpenCores
URL https://opencores.org/ocsvn/pcie_ds_dma/pcie_ds_dma/trunk

Subversion Repositories pcie_ds_dma

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /pcie_ds_dma/trunk
    from Rev 53 to Rev 54
    Reverse comparison

Rev 53 → Rev 54

/soft/linux/application/adm_test/bin/test_main.cfg
17,7 → 17,7
 
trdNo 0 ; Number of trd ( 0 - TRD_MAIN, 6 - TRD_DIO64_IN )
 
strmNo 1 ; Number of stream ( 0 or 1 )
strmNo 0 ; Number of stream ( 0 or 1 )
 
ISVI_FILE data_main ; file name
 
/soft/linux/application/adm_test/src/Makefile
25,7 → 25,7
INCLUDE := $(addprefix -I, $(INCDIR))
 
CFLAGS := -D__LINUX__ -O2 -Wall $(INCLUDE)
LFLAGS := -Wl -ldl -lrt -lpthread -lm -lncurses
LFLAGS := -ldl -lrt -lpthread -lm -lncurses
 
SRCFILE := $(wildcard *.cpp)
SRCFILE += $(wildcard ../../../common/board/*.cpp)
/soft/linux/application/adm_test/src/work/tf_teststrm.cpp
225,11 → 225,11
void* TF_TestStrm::ThreadFunc( void* lpvThreadParm )
{
TF_TestStrm *test=(TF_TestStrm*)lpvThreadParm;
UINT ret;
uint32_t ret;
if( !test )
return 0;
ret=test->Execute();
return (void*)ret;
return (void*)(size_t)ret;
}
 
//-----------------------------------------------------------------------------
237,13 → 237,13
void* TF_TestStrm::ThreadFuncIsvi( void* lpvThreadParm )
{
TF_TestStrm *test=(TF_TestStrm*)lpvThreadParm;
UINT ret;
uint32_t ret;
if( !test )
return 0;
 
Sleep( 200 );
ret=test->ExecuteIsvi();
return (void*)ret;
return (void*)(size_t)ret;
}
 
//-----------------------------------------------------------------------------
/soft/linux/application/adm_test/src/work/tf_teststrmout.cpp
138,7 → 138,7
if( !test )
return 0;
ret=test->Execute();
return (void*)ret;
return (void*)(size_t)ret;
}
 
 
/soft/linux/application/board_exam/Makefile
21,7 → 21,7
 
#CFLAGS := -D__linux__ -D__VERBOSE__ -g -Wall $(INCLUDE)
CFLAGS := -D__linux__ -O2 -Wall $(INCLUDE)
LFLAGS := -Wl,-rpath $(LIBDIR) -L"$(LIBDIR)" -lboard -ldl -lpthread
LFLAGS := -L"$(LIBDIR)" -lboard -ldl -lpthread
 
#EXTFILES := ../common/net/net_board.cpp
#EXTFILES := ../common/net/netcmn.cpp
/soft/linux/application/board_exam/main.cpp
78,25 → 78,6
brd->brd_init();
brd->brd_pld_info();
 
std::cout << "Reset FPGA..." << std::endl;
brd->brd_reg_poke_ind(0,0,1);
brd->brd_delay(100);
brd->brd_reg_poke_ind(0,0,0);
brd->brd_delay(100);
 
std::cout << "Init FPGA..." << std::endl;
for( int trd=0; trd<8; trd++ ) {
brd->brd_reg_poke_ind( trd, 0, 1 );
}
for( int trd=0; trd<8; trd++ ) {
for( int ii=1; ii<32; ii++ ) {
brd->brd_reg_poke_ind( trd, ii, 0 );
}
}
for( int trd=0; trd<8; trd++ ) {
brd->brd_reg_poke_ind( trd, 0, 0 );
}
 
std ::cout << "Press enter to allocate DMA memory..." << endl;
getchar();
 
112,12 → 93,11
NULL,
};
 
brd->dma_alloc(dmaChan, &sSCA);
brd->dma_allocate_memory(dmaChan, &sSCA);
 
brd->dma_set_local_addr(DmaChan, 0x1000);
brd->dma_stop(DmaChan);
brd->dma_reset_fifo(DmaChan);
brd->dma_reset_fifo(DmaChan);
 
std ::cout << "Press enter to start DMA channel..." << endl;
getchar();
143,7 → 123,7
 
std ::cout << "DMA data buffer " << j << ":" << endl;
buffer = (u32*)pBuffers[j];
for(unsigned i=0; i<32; i++) {
for(unsigned i=0; i<8; i++) {
std::cout << hex << buffer[i] << " ";
}
std ::cout << endl;
/soft/linux/application/wb_test/src/Makefile
24,7 → 24,7
INCLUDE := $(addprefix -I, $(INCDIR))
 
CFLAGS := -D__LINUX__ -O2 -Wall $(INCLUDE)
LFLAGS := -Wl -ldl -lrt -lpthread -lm
LFLAGS := -ldl -lrt -lpthread -lm
 
SRCFILE := $(wildcard *.cpp)
SRCFILE += $(wildcard ../../../common/board/*.cpp)
/soft/linux/common/board/board.cpp
222,10 → 222,10
 
//----------BRDSHELL-----------------------------------------------------------
 
u32 board::dma_alloc(int DmaChan, BRDctrl_StreamCBufAlloc* sSCA)
u32 board::dma_allocate_memory(int DmaChan, BRDctrl_StreamCBufAlloc* sSCA)
{
DEBUG_PRINT("%s()\n", __FUNCTION__);
return core_alloc(DmaChan, sSCA);
return core_allocate_memory(DmaChan, sSCA);
}
 
//-----------------------------------------------------------------------------
/soft/linux/common/board/board.h
45,7 → 45,7
virtual int core_resource() = 0;
virtual void core_delay(int ms) = 0;
 
virtual u32 core_alloc(int DmaChan, BRDctrl_StreamCBufAlloc* sSCA) = 0;
virtual u32 core_allocate_memory(int DmaChan, BRDctrl_StreamCBufAlloc* sSCA) = 0;
virtual u32 core_allocate_memory(int DmaChan, void** pBuf, u32 blkSize,
u32 blkNum, u32 isSysMem, u32 dir,
u32 addr, BRDstrm_Stub **pStub ) = 0;
86,7 → 86,7
int brd_resource();
 
//! Методы управления каналами DMA BRDSHELL
u32 dma_alloc(int DmaChan, BRDctrl_StreamCBufAlloc* sSCA);
u32 dma_allocate_memory(int DmaChan, BRDctrl_StreamCBufAlloc* sSCA);
u32 dma_allocate_memory(int DmaChan, void** pBuf, u32 blkSize,
u32 blkNum, u32 isSysMem,
u32 dir, u32 addr, BRDstrm_Stub **pStub);
/soft/linux/common/pex/pex_board.cpp
51,7 → 51,8
if(fd > 0)
return 0;
 
fd = open(name, S_IROTH | S_IWOTH );
//fd = open(name, S_IROTH | S_IWOTH );
fd = open(name, 0666 );
if(fd < 0) {
std::cerr << __FUNCTION__ << "(): " << " error open device: " << name << endl;
goto do_out;
182,6 → 183,24
 
int pex_board::core_reset()
{
/* for test read() syscall in userspace DMA mode
void *data = NULL;
size_t size = sysconf(_SC_PAGESIZE)*16;
size_t align = sysconf(_SC_PAGESIZE);
int res = posix_memalign(&data, align, size);
if(res < 0) {
fprintf(stderr, "error in posix_memalign()\n");
return -1;
}
 
res = read(fd, data, size);
if(res < 0) {
fprintf(stderr, "error in read()\n");
return -1;
}
 
free(data);
*/
return 0;
}
 
364,8 → 383,10
 
u32 pex_board::core_reg_peek_dir( u32 trd, u32 reg )
{
if( (trd>15) || (reg>3) )
if( (trd>15) || (reg>3) ) {
fprintf(stderr, "%s(): Invalid arguments.\n", __FUNCTION__);
return -1;
}
 
u32 offset = trd*0x4000 + reg*0x1000;
u32 ret = *(bar1 + offset/4);
377,8 → 398,10
 
u32 pex_board::core_reg_peek_ind( u32 trd, u32 reg )
{
if( (trd>15) || (reg>0x3FF) )
if( (trd>15) || (reg>0x3FF) ) {
fprintf(stderr, "%s(): Invalid arguments.\n", __FUNCTION__);
return -1;
}
 
u32 status;
u32 Status = trd*0x4000;
411,8 → 434,10
 
void pex_board::core_reg_poke_dir( u32 trd, u32 reg, u32 val )
{
if( (trd>15) || (reg>3) )
if( (trd>15) || (reg>3) ) {
fprintf(stderr, "%s(): Invalid arguments.\n", __FUNCTION__);
return;
}
 
u32 offset = trd*0x4000+reg*0x1000;
 
423,8 → 448,10
 
void pex_board::core_reg_poke_ind( u32 trd, u32 reg, u32 val )
{
if( (trd>15) || (reg>0x3FF) )
if( (trd>15) || (reg>0x3FF) ) {
fprintf(stderr, "%s(): Invalid arguments.\n", __FUNCTION__);
return;
}
 
u32 status;
u32 Status = trd*0x4000;
491,8 → 518,10
 
u32 pex_board::core_block_read( u32 nb, u32 reg )
{
if( (nb>7) || (reg>31) )
if( (nb>7) || (reg>31) ) {
fprintf(stderr, "%s(): Invalid arguments.\n", __FUNCTION__);
return -1;
}
 
u32 ret = 0;
 
505,7 → 534,7
 
//-----------------------------------------------------------------------------
 
u32 pex_board::core_alloc(int DmaChan, BRDctrl_StreamCBufAlloc* sSCA)
u32 pex_board::core_allocate_memory(int DmaChan, BRDctrl_StreamCBufAlloc* sSCA)
{
m_DescrSize[DmaChan] = sizeof(AMB_MEM_DMA_CHANNEL) + (sSCA->blkNum - 1) * sizeof(void*);
m_Descr[DmaChan] = (AMB_MEM_DMA_CHANNEL*) new u8[m_DescrSize[DmaChan]];
662,12 → 691,15
u32 pex_board::core_free_memory(int DmaChan)
{
for(u32 iBlk = 0; iBlk < m_Descr[DmaChan]->BlockCnt; iBlk++) {
 
munmap( m_Descr[DmaChan]->pBlock[iBlk], m_Descr[DmaChan]->BlockSize );
}
 
fprintf(stderr, "%s(): Unmap blocks - OK\n", __FUNCTION__ );
 
munmap( m_Descr[DmaChan]->pStub, sizeof(AMB_STUB) );
 
fprintf(stderr, "%s(): Unmap stub - OK\n", __FUNCTION__ );
 
if(ioctl(fd, IOCTL_AMB_FREE_MEMIO, m_Descr[DmaChan]) < 0) {
fprintf(stderr, "%s(): Error free memory\n", __FUNCTION__ );
return -1;
/soft/linux/common/pex/pex_board.h
56,7 → 56,7
int core_resource();
void core_delay(int ms);
 
u32 core_alloc(int DmaChan, BRDctrl_StreamCBufAlloc* sSCA);
u32 core_allocate_memory(int DmaChan, BRDctrl_StreamCBufAlloc* sSCA);
u32 core_allocate_memory(int DmaChan, void** pBuf, u32 blkSize,
u32 blkNum, u32 isSysMem, u32 dir,
u32 addr, BRDstrm_Stub **pStub);
/soft/linux/common/utils/cl_ambpex.cpp
132,12 → 132,12
 
BRDC_fprintf( stderr, _BRDC("Allocation memory: \r\n")
_BRDC(" Type of buffer: system memory\r\n")
_BRDC(" Buffer size: %lld MB\r\n"), size );
_BRDC(" Buffer size: %ld MB\r\n"), size );
} else {
 
BRDC_fprintf( stderr, _BRDC("Allocation memory: \r\n")
_BRDC(" Type of buffer: userspace memory\r\n")
_BRDC(" Buffer size: %lld MB (%dx%d MB)\r\n"), size, cnt_buf, size_one_buf_of_bytes/(1024*1024) );
_BRDC(" Buffer size: %ld MB (%dx%d MB)\r\n"), size, cnt_buf, size_one_buf_of_bytes/(1024*1024) );
}
 
BRDctrl_StreamCBufAlloc sSCA = {
149,7 → 149,7
NULL,
};
 
u32 err = m_pBoard->dma_alloc( strm, &sSCA );
u32 err = m_pBoard->dma_allocate_memory( strm, &sSCA );
if(err != 0) {
throw( "Error allocate stream memory\n" );
return -1;
/soft/linux/common/utils/cl_wbpex.cpp
101,12 → 101,12
 
BRDC_fprintf( stderr, _BRDC("Allocation memory: \r\n")
_BRDC(" Type of buffer: system memory\r\n")
_BRDC(" Buffer size: %lld MB (%dx%d MB)\r\n\r\n"), size, cnt_buf, size_one_buf_of_bytes/(1024*1024) );
_BRDC(" Buffer size: %ld MB (%dx%d MB)\r\n\r\n"), size, cnt_buf, size_one_buf_of_bytes/(1024*1024) );
} else {
 
BRDC_fprintf( stderr, _BRDC("Allocation memory: \r\n")
_BRDC(" Type of buffer: userspace memory\r\n")
_BRDC(" Buffer size: %lld MB (%dx%d MB)\r\n\r\n"), size, cnt_buf, size_one_buf_of_bytes/(1024*1024) );
_BRDC(" Buffer size: %ld MB (%dx%d MB)\r\n\r\n"), size, cnt_buf, size_one_buf_of_bytes/(1024*1024) );
}
 
BRDctrl_StreamCBufAlloc sSCA = {
118,7 → 118,7
NULL,
};
 
u32 err = m_pBoard->dma_alloc( strm, &sSCA );
u32 err = m_pBoard->dma_allocate_memory( strm, &sSCA );
if(err != 0) {
throw( "Error allocate stream memory\n" );
return -1;
245,7 → 245,7
 
DEBUG_PRINT("CL_AMBPEX::%s()\n", __FUNCTION__);
 
StreamParam *pStrm= m_streamParam+strm;
//StreamParam *pStrm= m_streamParam+strm;
 
//RegPokeInd( pStrm->trd, 0, 2 );
 
/soft/linux/common/utils/tf_testbufm2.cpp
780,7 → 780,7
bit_error1[ii]=0;
}
 
for( int ii=0; ii<128*4; ii++ ) {
for( int ii=0; ii<128; ii++ ) {
word_error[ii]=0;
}
 
859,7 → 859,7
*/
 
// len=sprintf( ptr, "%4d Block: %-4d Index: %.8X Waiting: %.16LX Receive: %.16LX \r\n",
len=sprintf( ptr, "%4d Block: %-4d Index: %.8X Waiting: %.16llX Received: %.16llX \r\n",
len=sprintf( ptr, "%4d Block: %-4d Index: %.8X Waiting: %.16lX Received: %.16lX \r\n",
//" Bits: %s\r\n\r\n"
ii, nb, na, dout, din
//bit
/soft/linux/common/utils/tf_testbufm2.h
82,7 → 82,7
U32 buf_cnt_error; //!< Число неправильных массивов.
U32 word_cnt_error; //!< Число неправильных слов.
U32 buf_current; //!< Номер текущего массива.
__int64 word_error[4*32]; //!< Список ошибок
__int64 word_error[128];//!< Список ошибок
 
char str[10240]; //!< Буфер сообщений
U32 block_mode; //!< Тип блока
/soft/linux/common/utils/tf_workparam.cpp
166,11 → 166,11
//! Сохранение параметров в памяти
U32 TF_WorkParam::PutParamToMemory( char* ptr, U32 max_size )
{
char str[256];
int len;
//char str[256];
//int len;
int total=0;
U32 ii;
STR_CFG *cfg;
//U32 ii;
//STR_CFG *cfg;
/*
*((U32*)ptr)=max_item;
total=4;
216,12 → 216,12
//! Получение параметров из памяти
void TF_WorkParam::GetParamFromMemory( char* ptr )
{
char *src=ptr;
U32 len;
U32 n;
n=*((U32*)ptr);
U32 ii;
int total=4;
//char *src=ptr;
//U32 len;
//U32 n;
//n=*((U32*)ptr);
//U32 ii;
//int total=4;
/*
for( ii=0; ii<n; ii++ )
{
/soft/linux/driver/pexdrv/dmachan.c
9,6 → 9,8
#include <linux/pagemap.h>
#include <linux/interrupt.h>
#include <linux/proc_fs.h>
#include <linux/delay.h>
#include <linux/wait.h>
#include <asm/io.h>
 
#ifndef _EVENT_H_
24,6 → 26,7
//-----------------------------------------------------------------------------
 
struct CDmaChannel* CDmaChannelCreate( u32 NumberOfChannel,
TASKLET_ROUTINE dpc,
void *brd,
struct device *dev,
u32 cbMaxTransferLength,
34,7 → 37,7
 
dma = kzalloc(sizeof(struct CDmaChannel), GFP_KERNEL);
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;
}
 
42,7 → 45,7
dma->m_Board = brd;
dma->m_dev = dev;
dma->m_UseCount = 0;
dma->m_DpcForIsr = DmaDpcForIsr;
dma->m_DpcForIsr = dpc;
dma->m_idBlockFifo = idBlockFifo;
 
spin_lock_init( &dma->m_DmaLock );
51,7 → 54,7
InitKevent( &dma->m_BlockEndEvent );
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;
}
60,7 → 63,7
 
void CDmaChannelDelete(struct CDmaChannel *dma)
{
//printk("<0>%s()\n", __FUNCTION__);
//printk("%s()\n", __FUNCTION__);
if (dma) {
tasklet_kill( &dma->m_Dpc );
kfree(dma);
73,11 → 76,11
{
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;
 
91,7 → 94,7
&pa, GFP_KERNEL);
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;
}
 
112,22 → 115,21
dma->m_pBufDscr.LogicalAddress);
dma->m_pBufDscr.SystemAddress = NULL;
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;
}
 
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)
SetScatterGatherListExt(dma);
else {
printk("<0>%s(): Scatter/Gather Table Entry not created\n", __FUNCTION__);
printk("%s(): Scatter/Gather Table Entry not created\n", __FUNCTION__);
//SetScatterGatherList(dma);
}
*pCount = dma->m_BlockCount;
dma->m_pStub = (PAMB_STUB)dma->m_StubDscr.SystemAddress;
dma->m_pStub->lastBlock = -1;
dma->m_pStub->totalCounter = 0;
134,6 → 136,9
dma->m_pStub->offset = 0;
dma->m_pStub->state = STATE_STOP;
}
 
*pCount = dma->m_BlockCount;
 
dma->m_UseCount++;
}
else
143,34 → 148,36
dma->m_pBufDscr.SystemAddress, dma->m_pBufDscr.LogicalAddress);
dma->m_pBufDscr.SystemAddress = NULL;
dma->m_pBufDscr.LogicalAddress = 0;
printk("<0>%s(): Error allocate memory\n", __FUNCTION__);
printk("%s(): Error allocate memory\n", __FUNCTION__);
return -EINVAL;
}
}
else
{
if(!dma->m_UseCount) {
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 = NULL;
dma->m_pBufDscr.LogicalAddress = 0;
{
if(dma->m_UseCount == 0) {
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 = NULL;
dma->m_pBufDscr.LogicalAddress = 0;
}
}
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) {
printk("<0> %s: Memory not allocated.\n", __FUNCTION__);
return;
if(dma->m_UseCount == 0) {
printk("%s(): Memory not allocated. m_UseCount = %d\n", __FUNCTION__, dma->m_UseCount);
return -1;
}
 
dma->m_UseCount--;
 
ReleaseStub( dma );
ReleaseSGList( dma );
ReleaseSysBuf( dma );
181,7 → 188,7
 
dma->m_pBufDscr.SystemAddress = NULL;
dma->m_pBufDscr.LogicalAddress = 0;
dma->m_UseCount--;
return 0;
}
 
//-----------------------------------------------------------------------------
199,7 → 206,7
SHARED_MEMORY_DESCRIPTION *pMemDscr = (SHARED_MEMORY_DESCRIPTION*)dma->m_pBufDscr.SystemAddress;
DMA_CHAINING_DESCR_EXT *pSGTEx = NULL;
 
//printk("<0>%s()\n", __FUNCTION__);
//printk("%s()\n", __FUNCTION__);
 
Status = RequestSGList(dma);
if(Status < 0)
214,8 → 221,8
//обнулим таблицу дескрипторов DMA
memset(pSGTEx, 0, dma->m_ScatterGatherBlockCnt*DscrSize);
 
//printk("<0>%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.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 < dma->m_BlockCount; iBlock++) {
224,7 → 231,6
u64 address = pMemDscr[iBlock].LogicalAddress;
u64 DmaSize = dma->m_BlockSize - 0x1000;
 
 
//заполним поля элментов таблицы дескрипторов
pSGTEx[iEntry].AddrByte1 = (u8)((address >> 8) & 0xFF);
pSGTEx[iEntry].AddrByte2 = (u8)((address >> 16) & 0xFF);
243,7 → 249,7
 
{
//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]);
}
 
258,12 → 264,12
//NextDscrBlockAddr = virt_to_bus((void*)&pSGTEx[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("<0>%s(): NextDscrBlock [VA]: %p\n", __FUNCTION__, &pSGTEx[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("<0>%s(): pNextBlock: %p\n", __FUNCTION__, pNextBlock);
//printk("%s(): pNextBlock: %p\n", __FUNCTION__, pNextBlock);
 
pNextBlock->NextBlkAddr = (NextDscrBlockAddr >> 8) & 0xFFFFFF;
pNextBlock->Signature = 0x4953;
273,7 → 279,7
iEntry++;
}
 
//printk("<0>%s(): iEntry = %d\n", __FUNCTION__, iEntry);
//printk("%s(): iEntry = %d\n", __FUNCTION__, iEntry);
 
if(((iEntry % DSCR_BLOCK_SIZE)) != 0)
{
288,7 → 294,7
i = (DSCR_BLOCK_SIZE * dma->m_ScatterGatherBlockCnt) - 1;
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->Signature = 0x4953;
295,13 → 301,176
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++ )
//{
//u32 *ptr=(u32*)&pSGTEx[ii];
//printk("<0>%s(): %d: %.8X %.8X\n", __FUNCTION__, ii, ptr[1], ptr[0]);
// u32 *ptr=(u32*)&pSGTEx[ii];
// printk("%s(): %02d: %08X %08X\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[%02d] - NextBlkAddr = 0x%08X, Signature = 0x%04X, Crc = 0x%04X\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(): %02d(%02d) - PciAddr = 0x%08X, Cmd = 0x%04X, DmaLength = 0x%08X (%02X %02X %02X)\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));
}
}
pNextDscr = (u16*)pDscrBuf;
pNextDscr[255] |= (u16)ctrl_code;
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;
319,13 → 488,11
if(iBlock == DSCR_BLOCK_SIZE-1)
{
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[%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
{
335,20 → 502,19
ctrl_tmp |= (ctrl_code & 0x8000) ? 0: 1;
ctrl_code = ctrl_tmp;
 
//printk("<0>%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("<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,
// m_pScatterGatherTable[iEntry].Signature,
// m_pScatterGatherTable[iEntry].Crc
// );
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;
373,42 → 539,46
int RequestSysBuf(struct CDmaChannel *dma, void **pMemPhysAddr)
{
u32 iBlock = 0;
u32 order = 0;
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++)
{
dma_addr_t LogicalAddress;
void *pSystemAddress = NULL;
u32 *buffer = NULL;
int iii=0;
 
pSystemAddress = dma_alloc_coherent( dma->m_dev, dma->m_BlockSize, &LogicalAddress, GFP_KERNEL );
//pSystemAddress = (void*)__get_free_pages(GFP_KERNEL, order);
if(!pSystemAddress) {
printk("<0>%s(): Not enought memory for %i block location. m_BlockSize = %X, BlockOrder = %d\n",
__FUNCTION__, (int)iBlock, (int)dma->m_BlockSize, (int)order );
return -ENOMEM;
}
// 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 = (void*)__get_free_pages(GFP_KERNEL, order);
if(!pSystemAddress) {
printk("%s(): Not enought memory for %i block location. m_BlockSize = %X\n",
__FUNCTION__, (int)iBlock, (int)dma->m_BlockSize );
return -ENOMEM;
}
 
pMemDscr[iBlock].SystemAddress = pSystemAddress;
pMemDscr[iBlock].LogicalAddress = LogicalAddress;
//pMemDscr[iBlock].LogicalAddress = virt_to_bus(pSystemAddress);
pMemDscr[iBlock].SystemAddress = pSystemAddress;
pMemDscr[iBlock].LogicalAddress = LogicalAddress;
//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;
 
buffer = (u32*)pMemDscr[iBlock].SystemAddress;
for(iii=0; iii<dma->m_BlockSize/4; iii++) {
buffer[iii] = 0x12345678;
{
// fill memory block
//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;
419,21 → 589,19
 
//-----------------------------------------------------------------------------
 
void ReleaseSysBuf(struct CDmaChannel *dma)
int ReleaseSysBuf(struct CDmaChannel *dma)
{
u32 iBlock = 0;
//u32 order = 0;
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);
return -1;
}
 
//order = get_order(dma->m_BlockSize);
printk("%s()\n", __FUNCTION__);
 
if(!dma->m_UseCount) {
printk("<0> ReleaseSysBuf(): Memory not allocated.\n");
return;
}
 
for(iBlock = 0; iBlock < dma->m_BlockCount; iBlock++)
{
unlock_pages( pMemDscr[iBlock].SystemAddress, dma->m_BlockSize );
444,6 → 612,8
pMemDscr[iBlock].SystemAddress = NULL;
pMemDscr[iBlock].LogicalAddress = 0;
}
 
return 0;
}
 
//-----------------------------------------------------------------------------
453,7 → 623,7
dma_addr_t LogicalAddress = 0;
u32 StubSize = 0;
 
//printk("<0>%s()\n", __FUNCTION__ );
//printk("%s()\n", __FUNCTION__ );
 
if(!dma)
return -EINVAL;
460,20 → 630,20
 
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 );
if(!pStub)
{
printk("<0>%s(): Not enought memory for stub\n", __FUNCTION__);
printk("%s(): Not enought memory for stub\n", __FUNCTION__);
return -ENOMEM;
}
 
lock_pages( pStub, StubSize );
 
//printk("<0>%s() 1\n", __FUNCTION__ );
//printk("%s() 1\n", __FUNCTION__ );
 
dma->m_StubDscr.SystemAddress = pStub;
dma->m_StubDscr.LogicalAddress = LogicalAddress;
481,12 → 651,12
//но в дальнейшем в модуле используется dma->m_pStub
}
 
//printk("<0>%s() 2\n", __FUNCTION__ );
//printk("%s() 2\n", __FUNCTION__ );
 
pStubPhysAddr[0] = (void*)dma->m_StubDscr.LogicalAddress;
 
//printk("<0>%s(): Stub physical address: %zx\n", __FUNCTION__, dma->m_StubDscr.LogicalAddress);
//printk("<0>%s(): Stub virtual address: %p\n", __FUNCTION__, dma->m_StubDscr.SystemAddress);
printk("%s(): Stub physical address: %llx\n", __FUNCTION__, dma->m_StubDscr.LogicalAddress);
printk("%s(): Stub virtual address: %p\n", __FUNCTION__, dma->m_StubDscr.SystemAddress);
 
return 0;
}
497,9 → 667,7
{
u32 StubSize = sizeof(AMB_STUB) > PAGE_SIZE ? sizeof(AMB_STUB) : PAGE_SIZE;
 
//printk("<0>%s()\n", __FUNCTION__);
 
if(!dma->m_UseCount)
if(dma->m_UseCount == 0)
{
unlock_pages(dma->m_StubDscr.SystemAddress, StubSize);
 
509,6 → 677,8
dma->m_pStub = NULL;
dma->m_StubDscr.SystemAddress = NULL;
dma->m_StubDscr.LogicalAddress = 0;
 
printk("%s()\n", __FUNCTION__);
}
}
 
522,7 → 692,7
u32 SGListSize = 0;
dma_addr_t PhysicalAddress;
 
//printk("<0>%s()\n", __FUNCTION__);
printk("%s()\n", __FUNCTION__);
 
if(dma->m_idBlockFifo == PE_EXT_FIFO_ID)
{
529,7 → 699,7
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;
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;
538,7 → 708,7
dma->m_SGTableDscr.SystemAddress = dma_alloc_coherent( dma->m_dev, SGListMemSize, &PhysicalAddress, GFP_KERNEL);
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;
}
 
552,21 → 722,25
 
//-----------------------------------------------------------------------------
 
void ReleaseSGList(struct CDmaChannel *dma)
int ReleaseSGList(struct CDmaChannel *dma)
{
u32 SGListMemSize = 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;
}
 
SGListMemSize = (SGListSize >= PAGE_SIZE) ? SGListSize : PAGE_SIZE;
 
// закрепляем список в физической памяти
// освободим страницы списока из физической памяти
unlock_pages(dma->m_SGTableDscr.SystemAddress, SGListMemSize);
 
dma_free_coherent( dma->m_dev, SGListMemSize,
575,6 → 749,8
 
dma->m_SGTableDscr.SystemAddress = NULL;
dma->m_SGTableDscr.LogicalAddress = 0;
 
return 0;
}
 
//-----------------------------------------------------------------------------
581,7 → 757,7
 
int StartDmaTransfer(struct CDmaChannel *dma, u32 IsCycling)
{
//printk("<0>%s()\n", __FUNCTION__);
printk("%s()\n", __FUNCTION__);
 
dma->m_DmaCycling = IsCycling;
dma->m_DoneBlock = -1;
599,6 → 775,9
u32 ctrl_code = ~0;
u16* pDscr = NULL;
int iEntry = 0;
int ii=0;
DMA_CHAINING_DESCR_EXT *pSGTEx = dma->m_pScatterGatherTableExt;
 
u32 iLastEntry = dma->m_ScatterGatherTableEntryCnt + dma->m_ScatterGatherBlockCnt - 1;
if(dma->m_ScatterGatherBlockCnt == 1)
dma->m_pScatterGatherTableExt[iLastEntry - 1].Cmd.JumpDescr0 = dma->m_DmaCycling;
605,7 → 784,7
else
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);
ctrl_code = 0xFFFFFFFF;
620,14 → 799,15
if(iEntry == DSCR_BLOCK_SIZE-1)
{
ctrl_code = ctrl_code ^ data0 ^ data1 ^ data2 ^ data3;
/*
printk("<0>%s(): DSCR_BLK[%d] - NextBlkAddr = 0x%08X, Signature = 0x%04X, Crc = 0x%04X\n",
__FUNCTION__,
dma->m_ScatterGatherBlockCnt-1,
(u32)(pDscrBuf[iEntry] << 8),
(u16)((pDscrBuf[iEntry] >> 32) & 0xFFFF),
(u16)ctrl_code);
*/
 
//printk("%s(): DSCR_BLK[%d] - NextBlkAddr = 0x%08X, Signature = 0x%04X, Crc = 0x%04X\n",
// __FUNCTION__,
// dma->m_ScatterGatherBlockCnt-1,
// (u32)(pDscrBuf[iEntry] << 8),
// (u16)((pDscrBuf[iEntry] >> 32) & 0xFFFF),
// (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
{
645,16 → 825,24
// rol ctrl_code,1
//}
 
//printk("<0>%s(): %d(%d) - PciAddr = 0x%08X, Cmd = 0x%02X, DmaLength = %d(%02X %02X %02X)\n",
// __FUNCTION__,
// iEntry, dma->m_ScatterGatherBlockCnt-1,
// (u32)(pDscrBuf[iEntry] << 8),
// (u16)(pDscrBuf[iEntry] >> 32),
// (u32)((pDscrBuf[iEntry] >> 41) << 9),
// (u8)(pDscrBuf[iEntry] >> 56), (u8)(pDscrBuf[iEntry] >> 48), (u8)(pDscrBuf[iEntry] >> 40));
//printk("%s(): %02d(%02d) - PciAddr = 0x%08X, Cmd = 0x%04X, DmaLength = 0x%08X (%02X %02X %02X)\n",
// __FUNCTION__,
// iEntry, dma->m_ScatterGatherBlockCnt-1,
// (u32)(pDscrBuf[iEntry] << 8),
// (u16)(pDscrBuf[iEntry] >> 32),
// (u32)((pDscrBuf[iEntry] >> 41) << 9),
// (u8)(pDscrBuf[iEntry] >> 56), (u8)(pDscrBuf[iEntry] >> 48), (u8)(pDscrBuf[iEntry] >> 40));
}
}
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;
668,7 → 856,7
 
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)
dma->m_pStub->lastBlock = 0;
681,8 → 869,8
 
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)
{
u32 next_done_blk = (dma->m_DoneBlock == dma->m_BlockCount-1) ? 0 : (dma->m_DoneBlock + 1);
729,7 → 917,7
{
if(((dma->m_preBlockCount3 == 0)&&(dma->m_DoneBlock == -1)) || (dma->m_preBlockCount3 == dma->m_DoneBlock)) {
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);
}
}
 
753,7 → 941,7
}
}
 
//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;
}
762,7 → 950,7
 
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;
*BlockNumTotal = dma->m_State.totalCounter;
774,7 → 962,7
 
void FreezeState(struct CDmaChannel *dma)
{
//printk("<0>%s()\n", __FUNCTION__);
//printk("%s()\n", __FUNCTION__);
}
 
//-----------------------------------------------------------------------------
783,7 → 971,7
{
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 ) {
status = GrabEvent( &dma->m_BlockEndEvent, -1 );
799,7 → 987,7
{
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 ) {
status = GrabEvent( &dma->m_BufferEndEvent, -1 );
814,7 → 1002,7
 
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;
return 0;
}
850,7 → 1038,7
 
void Adjust(struct CDmaChannel *dma, u32 mode)
{
//printk("<0>%s()\n", __FUNCTION__);
//printk("%s()\n", __FUNCTION__);
dma->m_AdjustMode = mode;
}
 
858,7 → 1046,7
 
void SetAdmTetr(struct CDmaChannel *dma, u32 AdmNum, u32 TetrNum)
{
//printk("<0>%s()\n", __FUNCTION__);
//printk("%s()\n", __FUNCTION__);
dma->m_AdmNum = AdmNum;
dma->m_TetrNum = TetrNum;
}
867,7 → 1055,7
 
void SetDmaLocalAddress(struct CDmaChannel *dma, u32 Address)
{
//printk("<0>%s()\n", __FUNCTION__);
//printk("%s()\n", __FUNCTION__);
dma->m_DmaLocalAddress = Address;
}
 
875,7 → 1063,7
 
int SetDmaDirection(struct CDmaChannel *dma, u32 DmaDirection)
{
printk("<0>%s()\n", __FUNCTION__);
printk("%s()\n", __FUNCTION__);
switch(DmaDirection)
{
case 1:
906,7 → 1094,7
}
 
//-----------------------------------------------------------------------------
 
/*
void DmaDpcForIsr( unsigned long Context )
{
struct CDmaChannel *DmaChannel = (struct CDmaChannel *)Context;
914,8 → 1102,8
 
spin_lock_irqsave(&DmaChannel->m_DmaLock, flags);
 
//printk("<0>%s(): [DMA%d] m_CurBlockNum = %d, m_BlockCount = %d\n",
// __FUNCTION__, DmaChannel->m_NumberOfChannel, DmaChannel->m_CurBlockNum, DmaChannel->m_BlockCount );
printk("%s(): [DMA%d] m_CurBlockNum = %d, m_BlockCount = %d\n",
__FUNCTION__, DmaChannel->m_NumberOfChannel, DmaChannel->m_CurBlockNum, DmaChannel->m_BlockCount );
DmaChannel->m_State = *DmaChannel->m_pStub;
 
SetEvent( &DmaChannel->m_BlockEndEvent );
924,7 → 1112,10
{
HwCompleteDmaTransfer(DmaChannel->m_Board,DmaChannel->m_NumberOfChannel);
SetEvent( &DmaChannel->m_BufferEndEvent );
wake_up_interruptible(&DmaChannel->m_DmaWq);
printk("%s(): Wake up!\n", __FUNCTION__);
}
 
spin_unlock_irqrestore(&DmaChannel->m_DmaLock, flags);
}
*/
/soft/linux/driver/pexdrv/dmachan.h
13,6 → 13,7
#define _DMA_CHAN_H_
 
#include "pexioctl.h"
#include "memory.h"
 
#define PE_EXT_FIFO_ID 0x0018
 
24,15 → 25,15
u16 m_idBlockFifo;
 
void *m_Board; // PCI device object
struct device *m_dev; // PCI device object
struct tasklet_struct m_Dpc; // the DPC object
wait_queue_head_t m_DmaWq;
spinlock_t m_DmaLock; // spinlock
struct device *m_dev; // PCI device object
struct tasklet_struct m_Dpc; // the DPC object
wait_queue_head_t m_DmaWq;
spinlock_t m_DmaLock; // spinlock
 
KEVENT m_BlockEndEvent;
KEVENT m_BufferEndEvent;
 
AMB_STUB m_State;
AMB_STUB m_State;
 
u32 m_AdmNum;
u32 m_TetrNum;
55,7 → 56,7
u32 m_preBlockCount3;
 
u32 m_MemType;
AMB_STUB *m_pStub;
AMB_STUB *m_pStub;
 
SHARED_MEMORY_DESCRIPTION m_StubDscr; //Содержит описатель управляющего блока
 
62,8 → 63,17
u32 m_BlockCount; //Количество блоков для DMA
u32 m_BlockSize; //Размер одного блока DMA
 
SHARED_MEMORY_DESCRIPTION m_pBufDscr; //Описатель для адресов блоков DMA каждый элемент содержит
SHARED_MEMORY_DESCRIPTION m_pBufDscr; //Описатель для адресов блоков DMA каждый элемент содержит
SHARED_MEMORY_DESCRIPTION m_BufDscrVA;
dma_addr_t m_BufDscrPA;
/*
DMA_CHAINING_DESCRIPTOR *m_pScatterGatherTableVA;
dma_addr_t m_pScatterGatherTablePA;
 
DMA_CHAINING_DESCRIPTOR *m_SGTableDscrVA;
dma_addr_t m_SGTableDscrPA;
*/
 
DMA_CHAINING_DESCR_EXT *m_pScatterGatherTableExt; //Содержит массив для организации цепочек DMA (v2)
u32 m_ScatterGatherBlockCnt; //Количество элементов-дескрипторов цепочек DMA
SHARED_MEMORY_DESCRIPTION m_SGTableDscr; //Описатель массива цепочек DMA
73,6 → 83,7
};
 
struct CDmaChannel* CDmaChannelCreate( u32 NumberOfChannel,
TASKLET_ROUTINE dpc,
void *m_Board,
struct device *dev,
u32 cbMaxTransferLength,
80,14 → 91,15
int bScatterGather );
void CDmaChannelDelete(struct CDmaChannel *dma);
int RequestMemory(struct CDmaChannel *dma, void **ppMemPhysAddr, u32 size, u32 *pCount, void **pStubPhysAddr, u32 bMemType);
void ReleaseMemory(struct CDmaChannel *dma);
int ReleaseMemory(struct CDmaChannel *dma);
int RequestSysBuf(struct CDmaChannel *dma, void **pMemPhysAddr);
void ReleaseSysBuf(struct CDmaChannel *dma);
int ReleaseSysBuf(struct CDmaChannel *dma);
int RequestSGList(struct CDmaChannel *dma);
void ReleaseSGList(struct CDmaChannel *dma);
int ReleaseSGList(struct CDmaChannel *dma);
int RequestStub(struct CDmaChannel *dma, void **pStubPhysAddr);
void ReleaseStub(struct CDmaChannel *dma);
int SetScatterGatherListExt(struct CDmaChannel *dma);
int SetScatterGatherListExtUser(struct CDmaChannel *dma);
void FreeUserAddress(struct CDmaChannel *dma);
u32 NextDmaTransfer(struct CDmaChannel *dma);
int SetScatterGatherList(struct CDmaChannel *dma);
107,7 → 119,7
void GetSGStartParams(struct CDmaChannel *dma, u64* SGTableAddress, u32* LocalAddress, u32* DmaDirection);
int StartDmaTransfer(struct CDmaChannel *dma, u32 IsCycling);
u32 SetDoneBlock(struct CDmaChannel *dma, long numBlk);
void DmaDpcForIsr( unsigned long Context );
//void DmaDpcForIsr( unsigned long Context );
 
#endif //_DMA_CHANNEL_H_
 
/soft/linux/driver/pexdrv/event.c
41,7 → 41,7
//
int ResetEvent ( KEVENT * event )
{
//printk("<0>%s() %p\n", __FUNCTION__, event);
//printk("%s() %p\n", __FUNCTION__, event);
atomic_set ( &event->m_flag, 0 );
return 0;
}
53,7 → 53,7
 
wake_up_interruptible( &event->m_wq );
 
//printk("<0>%s(): %p\n", __FUNCTION__, event);
//printk("%s(): %p\n", __FUNCTION__, event);
 
//if (event->m_async)
// kill_fasync(&event->m_async, SIGIO, POLL_IN|POLL_OUT);
64,7 → 64,7
//
int CheckEventFlag ( KEVENT * event )
{
//printk("<0>%s(): %p\n", __FUNCTION__, event);
//printk("%s(): %p\n", __FUNCTION__, event);
 
if ( atomic_read ( &event->m_flag ) )
{
85,7 → 85,7
{
int status = -1;
 
//printk("<0>%s()\n", __FUNCTION__);
//printk("%s()\n", __FUNCTION__);
 
#ifdef DZYTOOLS_2_4_X
status = interruptible_sleep_on_timeout( &event->m_wq, ms_to_jiffies(timeout) );
94,7 → 94,7
#endif
 
if(!status) {
printk("<0>%s(): TIMEOUT\n", __FUNCTION__);
printk("%s(): TIMEOUT\n", __FUNCTION__);
return -ETIMEDOUT;
}
 
107,7 → 107,7
//
int GrabEvent( KEVENT * event, u32 timeout )
{
//printk ( "<0>%s(): E %p, T %d\n", __FUNCTION__, event, timeout );
//printk ( "%s(): E %p, T %d\n", __FUNCTION__, event, timeout );
 
if( CheckEventFlag( event ) ) {
ResetEvent(event);
/soft/linux/driver/pexdrv/exam/Makefile
13,10 → 13,10
LD = $(CROSS_COMPILE)g++
 
CFLAGS := -D__LINUX__ -g -Wall -I.. -I../../../common/utils -I../../../common/board
LFLAGS = -Wl
LFLAGS =
 
$(TARGET_NAME): $(patsubst %.cpp,%.o, $(wildcard *.cpp))
$(LD) $(LFLAGS) $(notdir $^) -o $(TARGET_NAME)
$(LD) $(notdir $^) -o $(TARGET_NAME) $(LFLAGS)
rm -f *.o *~ core
 
%.o: %.cpp
/soft/linux/driver/pexdrv/hardware.c
79,8 → 79,8
 
dbg_msg(dbg_trace, "%s(): DeviceID = 0x%X, DeviceRev = 0x%X.\n", __FUNCTION__, deviceID, deviceRev);
 
pci_set_dma_mask(brd->m_pci, DMA_BIT_MASK(32));
 
 
temp = ReadOperationWordReg(brd, PEMAINadr_PLD_VER);
 
dbg_msg(dbg_trace, "%s(): PldVER = 0x%X.\n", __FUNCTION__, temp);
446,11 → 446,11
int DmaEnable(struct pex_device *brd, u32 AdmNumber, u32 TetrNumber)
{
int Status = 0;
//u32 Value = 0;
//Status = ReadRegData(brd, AdmNumber, TetrNumber, 0, &Value);
//if(Status != 0) return Status;
//Value |= 0x8; // DRQ enable
//Status = WriteRegData(brd, AdmNumber, TetrNumber, 0, Value);
u32 Value = 0;
Status = ReadRegData(brd, AdmNumber, TetrNumber, 0, &Value);
if(Status != 0) return Status;
Value |= 0x8; // DRQ enable
Status = WriteRegData(brd, AdmNumber, TetrNumber, 0, Value);
//err_msg(err_trace, "%s: MODE0 = 0x%X.\n", __FUNCTION__, Value);
return Status;
}
460,11 → 460,11
int DmaDisable(struct pex_device *brd, u32 AdmNumber, u32 TetrNumber)
{
int Status = 0;
//u32 Value = 0;
//Status = ReadRegData(brd, AdmNumber, TetrNumber, 0, &Value);
//if(Status != 0) return Status;
//Value &= 0xfff7; // DRQ disable
//Status = WriteRegData(brd, AdmNumber, TetrNumber, 0, Value);
u32 Value = 0;
Status = ReadRegData(brd, AdmNumber, TetrNumber, 0, &Value);
if(Status != 0) return Status;
Value &= 0xfff7; // DRQ disable
Status = WriteRegData(brd, AdmNumber, TetrNumber, 0, Value);
return Status;
}
 
505,7 → 505,7
CtrlExt.AsWhole = ReadOperationWordReg(brd, PEFIFOadr_DMA_CTRL + FifoAddr);
CtrlExt.ByBits.Pause = 0;
 
//printk("<0>%s(): CtrlExt.AsWhole = 0x%x\n", __FUNCTION__, CtrlExt.AsWhole);
//printk("%s(): CtrlExt.AsWhole = 0x%x\n", __FUNCTION__, CtrlExt.AsWhole);
 
WriteOperationWordReg(brd, PEFIFOadr_DMA_CTRL + FifoAddr, CtrlExt.AsWhole);
 
522,7 → 522,7
u32 adm_num, tetr_num;
u32 FifoAddr = brd->m_FifoAddr[NumberOfChannel];
 
dbg_msg(dbg_trace, "%s(): channel = %d, FifoAddr = 0x%04X.\n",__FUNCTION__, NumberOfChannel, FifoAddr);
dbg_msg(err_trace, "%s(): channel = %d, FifoAddr = 0x%04X.\n",__FUNCTION__, NumberOfChannel, FifoAddr);
 
DmaCtrl.AsWhole = 0;
WriteOperationWordReg(brd, PEFIFOadr_DMA_CTRL + FifoAddr, DmaCtrl.AsWhole);
568,7 → 568,7
 
adm_num = GetAdmNum(brd->m_DmaChannel[NumberOfChannel]);
tetr_num = GetTetrNum(brd->m_DmaChannel[NumberOfChannel]);
//Status = DmaEnable(brd, adm_num, tetr_num);
Status = DmaEnable(brd, adm_num, tetr_num);
 
return Status;
}
583,6 → 583,8
int i = 0;
u32 tetr_num;
 
dbg_msg(err_trace, "%s(): channel = %d, FifoAddr = 0x%04X.\n",__FUNCTION__, NumberOfChannel, FifoAddr);
 
if(brd->m_BlockFifoId[NumberOfChannel] == PE_EXT_FIFO_ID)
{
DMA_CTRL_EXT CtrlExt;
604,7 → 606,7
brd->m_DmaIrqEnbl = enbl;
 
tetr_num = GetTetrNum(brd->m_DmaChannel[NumberOfChannel]);
//Status = DmaDisable(brd, 0, tetr_num);
Status = DmaDisable(brd, 0, tetr_num);
CompleteDmaTransfer(brd->m_DmaChannel[NumberOfChannel]);
 
return Status;
/soft/linux/driver/pexdrv/insert
53,10 → 53,9
echo -n " Remove loaded module : "
/sbin/rmmod $device
status $? 0
else
echo -n " Loading pexdrv module : "
fi
 
echo -n " Loading pexdrv module : "
insmod ./${module}
 
until [ -e /dev/pexdrv0 ]
/soft/linux/driver/pexdrv/ioctlrw.c
291,9 → 291,9
TetrNumber = pKernMemDscr->LocalAddr & 0xff;
Address = AdmNumber*ADM_SIZE + TetrNumber*TETRAD_SIZE + TRDadr_DATA*REG_SIZE;
 
//SetDmaLocalAddress(dma, Address);
//SetAdmTetr(dma, AdmNumber, TetrNumber);
//error = SetDmaMode(brd, i, AdmNumber, TetrNumber);
SetDmaLocalAddress(dma, Address);
SetAdmTetr(dma, AdmNumber, TetrNumber);
error = SetDmaMode(brd, i, AdmNumber, TetrNumber);
 
dbg_msg(dbg_trace, "%s(): 4\n", __FUNCTION__);
 
325,7 → 325,6
 
int ioctl_free_mem(struct pex_device *brd, size_t arg)
{
u32 i = 0;
int error = 0;
AMB_MEM_DMA_CHANNEL MemDscr = {0};
PAMB_MEM_DMA_CHANNEL pMemDscr = &MemDscr;
344,14 → 343,13
goto do_exit;
}
 
i = pMemDscr->DmaChanNum;
ReleaseMemory(brd->m_DmaChannel[i]);
error = ReleaseMemory(brd->m_DmaChannel[pMemDscr->DmaChanNum]);
 
if(copy_to_user (( void *)arg, (void *)&MemDscr, sizeof(AMB_MEM_DMA_CHANNEL) + (pMemDscr->BlockCnt - 1) * sizeof(void*) )) {
err_msg(err_trace, "%s(): Error copy descriptor to user space\n", __FUNCTION__);
error = -EFAULT;
goto do_exit;
}
//if(copy_to_user (( void *)arg, (void *)&MemDscr, sizeof(AMB_MEM_DMA_CHANNEL) + (pMemDscr->BlockCnt - 1) * sizeof(void*) )) {
// err_msg(err_trace, "%s(): Error copy descriptor to user space\n", __FUNCTION__);
// error = -EFAULT;
// goto do_exit;
//}
 
do_exit:
up(&brd->m_BoardSem);
367,7 → 365,7
AMB_START_DMA_CHANNEL StartDscr;
PAMB_START_DMA_CHANNEL pStartDscr = &StartDscr;
 
printk("<0>ioctl_start_mem: Entered.\n");
printk("%s(): Entered.\n", __FUNCTION__);
down(&brd->m_BoardSem);
 
if( copy_from_user((void *)&StartDscr, (void *)arg, sizeof(AMB_START_DMA_CHANNEL))) {
377,13 → 375,13
}
 
if(pStartDscr->DmaChanNum >= MAX_NUMBER_OF_DMACHANNELS) {
printk("<0>%s(): too large stream number\n", __FUNCTION__);
printk("%s(): too large stream number\n", __FUNCTION__);
up(&brd->m_BoardSem);
return -EINVAL;
}
 
if(!(brd->m_DmaChanMask & (1 << pStartDscr->DmaChanNum))) {
printk("<0>%s(): invalid stream number\n", __FUNCTION__);
printk("%s(): invalid stream number\n", __FUNCTION__);
up(&brd->m_BoardSem);
return -EINVAL;
}
392,7 → 390,7
Status = HwStartDmaTransfer(brd, pStartDscr->DmaChanNum);
 
up(&brd->m_BoardSem);
printk("<0>ioctl_start_mem: exit Status=0x%.8X \n", Status );
printk("%s(): exit Status=0x%.8X \n", __FUNCTION__, Status);
 
return Status;
}
415,11 → 413,11
return -EFAULT;
}
 
//printk("<0>IoctlStopMem: Entered.\n");
//printk("%s()\n", __FUNCTION__);
 
if(pStopDscr->DmaChanNum >= MAX_NUMBER_OF_DMACHANNELS)
{
printk("<0>IoctlStopMem: too large stream number\n");
printk("IoctlStopMem: too large stream number\n");
up(&brd->m_BoardSem);
return -EINVAL;
}
469,11 → 467,11
return -EFAULT;
}
 
//printk("<0>IoctlStateMem: Entered.\n");
//printk("%s()\n", __FUNCTION__);
 
if(pStateDscr->DmaChanNum >= MAX_NUMBER_OF_DMACHANNELS)
{
printk("<0>IoctlStateMem: too large stream number\n");
printk("IoctlStateMem: too large stream number\n");
up(&brd->m_BoardSem);
return -EINVAL;
}
510,7 → 508,7
AMB_SET_DMA_CHANNEL MemDscr;
PAMB_SET_DMA_CHANNEL pMemDscr = &MemDscr;
 
printk("<0>IoctlSetDirMem: Entered.\n");
printk("%s()\n", __FUNCTION__);
down(&brd->m_BoardSem);
 
// get the user buffer
522,7 → 520,7
 
if(pMemDscr->DmaChanNum >= MAX_NUMBER_OF_DMACHANNELS)
{
printk("<0>IoctlSetDirMem: too large stream number\n");
printk("%s(): too large stream number\n", __FUNCTION__);
up(&brd->m_BoardSem);
return -EINVAL;
}
547,7 → 545,7
AMB_SET_DMA_CHANNEL MemDscr;
PAMB_SET_DMA_CHANNEL pMemDscr = &MemDscr;
 
printk("<0>IoctlSetSrcMem: Entered.\n");
printk("%s()\n", __FUNCTION__);
down(&brd->m_BoardSem);
 
// get the user buffer
559,23 → 557,18
 
if(pMemDscr->DmaChanNum >= MAX_NUMBER_OF_DMACHANNELS)
{
printk("<0>IoctlSetSrcMem: too large stream number\n");
printk("%s(): too large stream number\n", __FUNCTION__);
up(&brd->m_BoardSem);
return -EINVAL;
}
 
i = pMemDscr->DmaChanNum;
//AdmNumber = pMemDscr->Param >> 16;
//TetrNumber = pMemDscr->Param & 0xff;
//Address = AdmNumber * ADM_SIZE + TetrNumber * TETRAD_SIZE + TRDadr_DATA * REG_SIZE;
 
AdmNumber=0;
TetrNumber=0;
Address = pMemDscr->Param;
AdmNumber = pMemDscr->Param >> 16;
TetrNumber = pMemDscr->Param & 0xff;
Address = AdmNumber * ADM_SIZE + TetrNumber * TETRAD_SIZE + TRDadr_DATA * REG_SIZE;
SetDmaLocalAddress(brd->m_DmaChannel[i], Address);
SetAdmTetr(brd->m_DmaChannel[i], AdmNumber, TetrNumber);
//Status = SetDmaMode(brd, i, AdmNumber, TetrNumber);
Status=0;
Status = SetDmaMode(brd, i, AdmNumber, TetrNumber);
 
up(&brd->m_BoardSem);
 
595,7 → 588,7
 
down(&brd->m_BoardSem);
 
//printk("<0>IoctlSetSrcMem: Entered.\n");
//printk("%s()\n", __FUNCTION__);
 
// get the user buffer
if( copy_from_user((void *)&MemDscr, (void *)arg, sizeof(AMB_SET_DMA_CHANNEL))) {
606,7 → 599,7
 
if(pMemDscr->DmaChanNum >= MAX_NUMBER_OF_DMACHANNELS)
{
printk("<0>IoctlSetDrqMem: too large stream number\n");
printk("IoctlSetDrqMem: too large stream number\n");
up(&brd->m_BoardSem);
return -EINVAL;
}
631,7 → 624,7
 
down(&brd->m_BoardSem);
 
//printk("<0>%s()\n", __FUNCTION__);
//printk("%s()\n", __FUNCTION__);
 
if( copy_from_user((void *)&MemDscr, (void *)arg, sizeof(AMB_SET_DMA_CHANNEL))) {
err_msg(err_trace, "%s(): Error copy data from userspace\n", __FUNCTION__ );
641,13 → 634,13
 
if(pMemDscr->DmaChanNum >= MAX_NUMBER_OF_DMACHANNELS)
{
printk("<0>IoctlSetDrqMem: too large stream number\n");
printk("IoctlSetDrqMem: too large stream number\n");
up(&brd->m_BoardSem);
return -EINVAL;
}
if(!(brd->m_DmaChanMask & (1 << pMemDscr->DmaChanNum)))
{
printk("<0>%s(): invalid stream number\n", __FUNCTION__);
printk("%s(): invalid stream number\n", __FUNCTION__);
up(&brd->m_BoardSem);
return -EINVAL;
}
672,7 → 665,7
 
down(&brd->m_BoardSem);
 
//printk("<0>%s()\n", __FUNCTION__);
//printk("%s()\n", __FUNCTION__);
 
// get the user buffer
if( copy_from_user((void *)&MemDscr, (void *)arg, sizeof(AMB_SET_DMA_CHANNEL))) {
683,13 → 676,13
 
if(pMemDscr->DmaChanNum >= MAX_NUMBER_OF_DMACHANNELS)
{
printk("<0>IoctlSetDrqMem: too large stream number\n");
printk("IoctlSetDrqMem: too large stream number\n");
up(&brd->m_BoardSem);
return -EINVAL;
}
if(!(brd->m_DmaChanMask & (1 << pMemDscr->DmaChanNum)))
{
printk("<0>%s(): invalid stream number\n", __FUNCTION__);
printk("%s(): invalid stream number\n", __FUNCTION__);
up(&brd->m_BoardSem);
return -EINVAL;
}
723,13 → 716,13
 
if(pMemDscr->DmaChanNum >= MAX_NUMBER_OF_DMACHANNELS)
{
printk("<0>%s(): too large stream number\n", __FUNCTION__);
printk("%s(): too large stream number\n", __FUNCTION__);
up(&brd->m_BoardSem);
return -EINVAL;
}
if(!(brd->m_DmaChanMask & (1 << pMemDscr->DmaChanNum)))
{
printk("<0>%s(): invalid stream number\n", __FUNCTION__);
printk("%s(): invalid stream number\n", __FUNCTION__);
up(&brd->m_BoardSem);
return -EINVAL;
}
758,13 → 751,13
 
if(DmaInfo.DmaChanNum >= MAX_NUMBER_OF_DMACHANNELS)
{
printk("<0>%s(): too large stream number\n", __FUNCTION__);
printk("%s(): too large stream number\n", __FUNCTION__);
up(&brd->m_BoardSem);
return -EINVAL;
}
if(!(brd->m_DmaChanMask & (1 << DmaInfo.DmaChanNum)))
{
printk("<0>%s(): invalid stream number\n", __FUNCTION__);
printk("%s(): invalid stream number\n", __FUNCTION__);
up(&brd->m_BoardSem);
return -EINVAL;
}
802,11 → 795,11
return -EFAULT;
}
 
//printk("<0>%s(): DMA %d\n", __FUNCTION__, pStateDscr->DmaChanNum);
//printk("%s(): DMA %d\n", __FUNCTION__, pStateDscr->DmaChanNum);
 
if(pStateDscr->DmaChanNum >= MAX_NUMBER_OF_DMACHANNELS)
{
printk("<0>%s(): too large stream number\n", __FUNCTION__);
printk("%s(): too large stream number\n", __FUNCTION__);
up(&brd->m_BoardSem);
return -EINVAL;
}
849,11 → 842,11
return -EFAULT;
}
 
printk("<0>%s(): DMA %d\n", __FUNCTION__, pStateDscr->DmaChanNum);
printk("%s(): DMA %d\n", __FUNCTION__, pStateDscr->DmaChanNum);
 
if(pStateDscr->DmaChanNum >= MAX_NUMBER_OF_DMACHANNELS)
{
printk("<0>%s(): too large stream number\n", __FUNCTION__);
printk("%s(): too large stream number\n", __FUNCTION__);
up(&brd->m_BoardSem);
return -EINVAL;
}
/soft/linux/driver/pexdrv/memory.c
1,6 → 1,6
 
#include <linux/kernel.h>
#define __NO_VERSION__
#include <linux/version.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/ioport.h>
8,10 → 8,13
#include <linux/pagemap.h>
#include <linux/interrupt.h>
#include <linux/proc_fs.h>
#include <linux/sched.h>
 
#include <asm/io.h>
 
 
#include "pexmodule.h"
#include "memory.h"
#include "pexmodule.h"
 
//--------------------------------------------------------------------
 
20,7 → 23,7
struct page *start_page_addr = virt_to_page(va);
int i = 0;
 
for (i=0; i < (size >> PAGE_CACHE_SHIFT); i++) {
for (i=0; i < (size >> PAGE_SHIFT); i++) {
SetPageReserved(start_page_addr+i);
//dbg_msg(dbg_trace, "%s(): page_addr[%d] = 0x%x\n", __FUNCTION__, i, (int)(start_page_addr+i));
}
35,7 → 38,7
struct page *start_page_addr = virt_to_page(va);
int i = 0;
 
for (i=0; i < (size >> PAGE_CACHE_SHIFT); i++) {
for (i=0; i < (size >> PAGE_SHIFT); i++) {
ClearPageReserved(start_page_addr+i);
//dbg_msg(dbg_trace, "%s(): page_addr[%d] = 0x%x\n", __FUNCTION__, i, (int)(start_page_addr+i));
}
45,62 → 48,151
 
//--------------------------------------------------------------------
 
//--------------------------------------------------------------------
/*
static int copy_memory_descriptors(unsigned long arg, struct memory_descriptor *md, struct memory_block **mb)
int check_address( void *pMemUserAddr )
{
struct memory_block *mblocks = NULL;
int error = 0;
//int i = 0;
size_t addr = (size_t)pMemUserAddr;
size_t mask = (size_t)~PAGE_MASK;
 
if(copy_from_user((void*)md, (void*)arg, sizeof(struct memory_descriptor))) {
err_msg(err_trace, "%s(): Error copy memory descriptor from user space\n", __FUNCTION__);
error = -EINVAL;
goto do_exit;
}
printk("%s()\n", __FUNCTION__);
 
dbg_msg(dbg_trace, "%s(): md.total_blocks = %zd\n", __FUNCTION__, md->total_blocks );
dbg_msg(dbg_trace, "%s(): md.blocks = %p\n", __FUNCTION__, md->blocks );
// адрес пользовательского буфера должен быть выровнен на страницу
if(addr & mask) {
printk("%s(): %p - Error! Address must be aling at PAGE_SIZE border\n", __FUNCTION__, pMemUserAddr );
return 1;
}
 
mblocks = kzalloc(md->total_blocks*sizeof(struct memory_block), GFP_KERNEL);
if(!mblocks) {
err_msg(err_trace, "%s(): Error allocate memory for memory descriptors\n", __FUNCTION__);
error = -ENOMEM;
goto do_exit;
return 0;
}
 
if(copy_from_user((void*)mblocks, (void*)md->blocks, md->total_blocks*sizeof(struct memory_block))) {
err_msg(err_trace, "%s(): Error copy memory blocks from user space\n", __FUNCTION__);
error = -EINVAL;
goto do_free_mem;
}
//--------------------------------------------------------------------
 
//for(i=0; i<md->total_blocks; i++) {
// dbg_msg(dbg_trace, "%s(): mb[%d].size = 0x%x\n", __FUNCTION__, i, mblocks[i].size );
//}
int check_size( size_t userSize )
{
printk("%s()\n", __FUNCTION__);
 
*mb = mblocks;
// размер пользовательского буфера должен быть кратен размеру страницы
if((userSize % PAGE_SIZE) != 0) {
printk("%s(): Invalid user memory block size - 0x%lX.\n", __FUNCTION__, userSize);
return 1;
}
 
return 0;
return 0;
}
 
do_free_mem:
kfree(mb);
//--------------------------------------------------------------------
 
do_exit:
return error;
int lock_user_memory( SHARED_MEMORY_DESCRIPTION *MemDscr, void* userSpaceAddress, size_t userSpaceSize )
{
int i = 0;
int requested_page_count = 0;
int allocated_page_count = 0;
 
printk("%s()\n", __FUNCTION__);
 
if(!MemDscr) {
printk("%s(): Invalid memory descriptor.\n", __FUNCTION__);
return -EINVAL;
}
 
requested_page_count = (userSpaceSize >> PAGE_SHIFT);
 
MemDscr->LockedPages = (struct page**)kmalloc(requested_page_count*sizeof(struct page*), GFP_KERNEL);
if(!MemDscr->LockedPages) {
printk("%s(): Cant allocate memory for locked pages pointers.\n", __FUNCTION__);
return -ENOMEM;
}
 
memset(MemDscr->LockedPages,0,requested_page_count*sizeof(struct page*));
 
down_read(&current->mm->mmap_sem);
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,5,0)
allocated_page_count = get_user_pages(current,
current->mm,
(size_t)userSpaceAddress,
requested_page_count,
1,
0,
MemDscr->LockedPages,
0);
#endif
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(4,9,0))
allocated_page_count = get_user_pages((size_t)userSpaceAddress,
requested_page_count,
1,
0,
MemDscr->LockedPages,
0);
#endif
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,9,0))
allocated_page_count = get_user_pages((size_t)userSpaceAddress,
requested_page_count,
1,
MemDscr->LockedPages,
0);
#endif
 
up_read(&current->mm->mmap_sem);
 
// если все ok то result содержит число страниц в массиве struct page *pages
if(MemDscr->PageCount <= 0) {
printk("%s(): Error to lock memory pages.\n", __FUNCTION__);
kfree(MemDscr->LockedPages);
MemDscr->LockedPages = NULL;
MemDscr->PageCount = 0;
return -ENOMEM;
}
 
printk("%s(): MemDscr->PageCount = %ld\n", __FUNCTION__, MemDscr->PageCount);
printk("%s(): MemDscr->LockedPages = %p\n", __FUNCTION__, MemDscr->LockedPages);
 
for(i=0; i<MemDscr->PageCount; i++) {
 
printk("%s(): LockedPages[%d] = %p\n", __FUNCTION__, i, MemDscr->LockedPages[i]);
printk("%s(): PhysicalAddress = %p\n", __FUNCTION__, (void*)page_to_phys(MemDscr->LockedPages[i]));
 
if(!PageReserved(MemDscr->LockedPages[i])) {
SetPageReserved(MemDscr->LockedPages[i]);
}
}
 
printk("%s(): Lock %ld memory pages\n", __FUNCTION__, MemDscr->PageCount);
 
return 0;
}
*/
//-----------------------------------------------------------------------------
 
int lock_user_pages(unsigned long addr, int size)
//--------------------------------------------------------------------
 
int unlock_user_memory( SHARED_MEMORY_DESCRIPTION *MemDscr )
{
//int res = 0;
//res = get_user_pages(current, current->mm, unsigned long start, int nr_pages, int write, int force,
// struct page **pages, struct vm_area_struct **vmas);
return -1;
int i = 0;
 
printk("%s()\n", __FUNCTION__);
 
if(!MemDscr) {
printk("%s(): Invalid parameter MemDscr = %p\n", __FUNCTION__, MemDscr);
return -EINVAL;
}
 
printk("%s(): MemDscr = %p\n", __FUNCTION__, MemDscr);
 
if(MemDscr->LockedPages)
printk("%s(): MemDscr->LockedPages = %p\n", __FUNCTION__, MemDscr->LockedPages);
 
for(i=0; i<MemDscr->PageCount; i++) {
if(MemDscr->LockedPages[i]) {
ClearPageReserved(MemDscr->LockedPages[i]);
//page_cache_release(MemDscr->LockedPages[i]);
printk("%s(): Unlock page %p\n", __FUNCTION__, MemDscr->LockedPages[i]);
}
}
 
if(MemDscr->LockedPages)
kfree(MemDscr->LockedPages);
 
return 0;
}
 
//-----------------------------------------------------------------------------
//--------------------------------------------------------------------
 
void* allocate_memory_block(struct pex_device *brd, size_t block_size, dma_addr_t *dma_addr)
{
/soft/linux/driver/pexdrv/memory.h
36,8 → 36,30
};
 
//-----------------------------------------------------------------------------
 
typedef struct _SHARED_PHYSMEMORY_DESCRIPTION {
void *PhysAddress; // OUT - user memory address
void *KernAddress; // OUT - user memory address
void *UserAddress; // OUT - user memory address
} SHARED_PHYSMEMORY_DESCRIPTION, *PSHARED_PHYSMEMORY_DESCRIPTION;
 
//-----------------------------------------------------------------------------
 
typedef struct _SHARED_MEMORY_DESCRIPTION {
 
void* SystemAddress; // адрес блока памяти выделенного в пространстве ядра
dma_addr_t LogicalAddress; // физический адрес блока памяти выделенного в пространстве ядра
struct page** LockedPages; // указатели на страницы блока памяти выделенного в пространстве пользователя
size_t PageCount; // количество страниц составляющи блок памяти выделенный в пространстве пользователя
 
} SHARED_MEMORY_DESCRIPTION, *PSHARED_MEMORY_DESCRIPTION;
 
//-----------------------------------------------------------------------------
 
struct pex_device;
struct memory_block;
struct CDmaChannel;
 
//-----------------------------------------------------------------------------
 
int lock_pages( void *va, u32 size );
44,6 → 66,8
int unlock_pages( void *va, u32 size );
void* allocate_memory_block(struct pex_device *brd, size_t block_size, dma_addr_t *dma_addr);
int free_memory_block(struct pex_device *brd, struct memory_block mb);
int lock_user_memory( SHARED_MEMORY_DESCRIPTION *MemDscr, void* userSpaceAddress, size_t userSpaceSize );
int unlock_user_memory( SHARED_MEMORY_DESCRIPTION *MemDscr );
 
//--------------------------------------------------------------------
 
/soft/linux/driver/pexdrv/pexioctl.h
154,14 → 154,6
#define PAGES_SPANNED(Size) (((Size) + (PAGE_SIZE - 1)) >> PAGE_SHIFT)
 
//-----------------------------------------------------------------------------
// Shared Memory between kernel and user mode description
typedef struct _SHARED_MEMORY_DESCRIPTION {
void* SystemAddress; // INOUT - system memory address
size_t LogicalAddress; // OUT - logical memory address
size_t dummy; // OUT - logical memory address
} SHARED_MEMORY_DESCRIPTION, *PSHARED_MEMORY_DESCRIPTION;
 
//-----------------------------------------------------------------------------
// Stub Structure
typedef struct _AMB_STUB {
u32 lastBlock; // Number of Block which was filled last Time
/soft/linux/driver/pexdrv/pexmodule.c
16,7 → 16,7
#include <linux/ioport.h>
#include <linux/poll.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
 
#include "pexmodule.h"
#include "hardware.h"
24,6 → 24,7
#include "ioctlrw.h"
#include "ambpexregs.h"
#include "pexproc.h"
#include "memory.h"
 
//-----------------------------------------------------------------------------
 
100,7 → 101,71
#endif
 
//-----------------------------------------------------------------------------
/*
static ssize_t pex_device_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
{
int error = 0;
u32 AdmNumber = 0;
u32 TetrNumber = 0;
u32 Address = 0;
struct CDmaChannel *dma = NULL;
 
struct pex_device *pDevice = file_to_device(file);
if(!pDevice) {
err_msg(err_trace, "%s(): No such device\n", __FUNCTION__);
return -ENODEV;
}
 
dma = pDevice->m_DmaChannel[0];
 
printk("%s(): data = %p\n", __FUNCTION__, data);
printk("%s(): size = 0x%lx\n", __FUNCTION__, count);
printk("%s(): ppos = %p\n", __FUNCTION__, ppos);
 
error = lock_user_memory( &dma->m_BufDscrVA, data, count);
if(error < 0) {
err_msg(err_trace, "%s(): Error in lock_user_memory()\n", __FUNCTION__);
return -EINVAL;
}
 
dma->m_BlockCount = dma->m_BufDscrVA.PageCount;
dma->m_ScatterGatherTableEntryCnt = dma->m_BufDscrVA.PageCount;
dma->m_BlockSize = PAGE_SIZE;
 
AdmNumber = 0;
TetrNumber = 0;
Address = AdmNumber*ADM_SIZE + TetrNumber*TETRAD_SIZE + TRDadr_DATA*REG_SIZE;
 
SetDmaDirection(dma, 1);
Adjust(dma, 0);
SetDmaLocalAddress(dma, Address);
SetAdmTetr(dma, AdmNumber, TetrNumber);
SetDmaMode(pDevice, 0, AdmNumber, TetrNumber);
 
RequestStub(dma,NULL);
SetScatterGatherListExtUser(dma);
StartDmaTransfer(dma, 0);
HwStartDmaTransfer(pDevice, 0);
 
error = WaitEvent(&dma->m_BufferEndEvent, 1000);
if(error < 0) {
err_msg(err_trace, "%s(): Timeout read operation\n", __FUNCTION__);
}
 
error = unlock_user_memory( &dma->m_BufDscrVA );
if(error < 0) {
err_msg(err_trace, "%s(): Error in lock_user_memory()\n", __FUNCTION__);
return -EINVAL;
}
 
ReleaseStub( dma );
ReleaseSGList( dma );
 
return 0;
}
*/
//-----------------------------------------------------------------------------
 
static int pex_device_fasync(int fd, struct file *file, int mode)
{
struct pex_device *pDevice = file->private_data;
276,26 → 341,28
 
//-----------------------------------------------------------------------------
 
static ssize_t pex_device_aio_read(struct kiocb *iocb, const struct iovec *iov, unsigned long count, loff_t off)
void tasklet_isr( unsigned long Context )
{
struct pex_device *pDevice = file_to_device(iocb->ki_filp);
if(!pDevice) {
err_msg(err_trace, "%s(): ioctl device failed\n", __FUNCTION__);
return -ENODEV;
}
return -ENOSYS;
}
struct CDmaChannel *DmaChannel = (struct CDmaChannel *)Context;
unsigned long flags = 0;
 
//-----------------------------------------------------------------------------
spin_lock_irqsave(&DmaChannel->m_DmaLock, flags);
 
static ssize_t pex_device_aio_write(struct kiocb *iocb, const struct iovec *iov, unsigned long count, loff_t off)
{
struct pex_device *pDevice = file_to_device(iocb->ki_filp);
if(!pDevice) {
err_msg(err_trace, "%s(): ioctl device failed\n", __FUNCTION__);
return -ENODEV;
printk("%s(): [DMA%d] m_CurBlockNum = %d, m_BlockCount = %d\n",
__FUNCTION__, DmaChannel->m_NumberOfChannel, DmaChannel->m_CurBlockNum, DmaChannel->m_BlockCount );
DmaChannel->m_State = *DmaChannel->m_pStub;
 
SetEvent( &DmaChannel->m_BlockEndEvent );
 
if(DmaChannel->m_CurBlockNum >= DmaChannel->m_BlockCount)
{
HwCompleteDmaTransfer(DmaChannel->m_Board,DmaChannel->m_NumberOfChannel);
SetEvent( &DmaChannel->m_BufferEndEvent );
wake_up_interruptible(&DmaChannel->m_DmaWq);
printk("%s(): Wake up!\n", __FUNCTION__);
}
return -ENOSYS;
 
spin_unlock_irqrestore(&DmaChannel->m_DmaLock, flags);
}
 
//-----------------------------------------------------------------------------
364,7 → 431,7
FifoStatus.AsWhole = ReadOperationWordReg(pDevice, PEFIFOadr_FIFO_STATUS + FifoAddr);
if(FifoStatus.ByBits.IntRql)
{
//err_msg(err_trace, "%s(): - Channel = %d, Fifo Status = 0x%X\n", __FUNCTION__, iChan, FifoStatus.AsWhole);
err_msg(err_trace, "%s(): - Channel = %d, Fifo Status = 0x%X\n", __FUNCTION__, iChan, FifoStatus.AsWhole);
NumberOfChannel = iChan;
pDevice->m_primChan = ((pDevice->m_primChan+1) >= MAX_NUMBER_OF_DMACHANNELS) ? 0 : pDevice->m_primChan+1;
break;
377,11 → 444,10
{
u32 flag = 0;
 
//err_msg(err_trace, "%s(%d)\n", __FUNCTION__, atomic_read(&pDevice->m_TotalIRQ));
err_msg(err_trace, "%s(%d)\n", __FUNCTION__, atomic_read(&pDevice->m_TotalIRQ));
 
flag = NextDmaTransfer(pDevice->m_DmaChannel[NumberOfChannel]);
//if(!flag)
if( 0 )
if(!flag)
{
DMA_CTRL_EXT CtrlExt;
CtrlExt.AsWhole = 0;
426,8 → 492,6
.release = pex_device_close,
.fasync = pex_device_fasync,
.poll = pex_device_poll,
.aio_read = pex_device_aio_read,
.aio_write = pex_device_aio_write,
};
 
//-----------------------------------------------------------------------------
557,6 → 621,14
 
brd->m_BoardIndex = boards_count;
 
if(pci_set_dma_mask(brd->m_pci, DMA_BIT_MASK(32))) {
dbg_msg(dbg_trace, "%s(): Error in dma_set_mask_and_coherent() - no suitable DMA available\n", __FUNCTION__);
}
 
if (dma_set_mask_and_coherent(&brd->m_pci->dev, DMA_BIT_MASK(32))) {
dbg_msg(dbg_trace, "%s(): Error in dma_set_mask_and_coherent() - no suitable DMA available\n", __FUNCTION__);
}
 
InitializeBoard(brd);
 
for(i = 0; i < MAX_NUMBER_OF_DMACHANNELS; i++) {
563,7 → 635,7
 
if(brd->m_DmaChanMask & (1 << i)) {
 
brd->m_DmaChannel[i] = CDmaChannelCreate( i, brd,
brd->m_DmaChannel[i] = CDmaChannelCreate( i, tasklet_isr, brd,
&brd->m_pci->dev,
brd->m_MaxDmaSize[i],
brd->m_BlockFifoId[i], 1 );
570,7 → 642,7
}
}
 
pex_register_proc(brd->m_name, pex_proc_info, brd);
pex_register_proc(brd->m_name, 0, brd);
 
list_add_tail(&brd->m_list, &device_list);
 
/soft/linux/driver/pexdrv/pexproc.c
2,6 → 2,7
#include <linux/kernel.h>
#define __NO_VERSION__
#include <linux/module.h>
#include <linux/version.h>
#include <linux/types.h>
#include <linux/ioport.h>
#include <linux/pci.h>
8,8 → 9,10
#include <linux/pagemap.h>
#include <linux/interrupt.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <asm/io.h>
 
 
#include "pexmodule.h"
#include "pexproc.h"
#include "ambpexregs.h"
17,25 → 20,14
 
//--------------------------------------------------------------------
 
void pex_register_proc( char *name, void *fptr, void *data )
{
create_proc_read_entry( name, 0, NULL, fptr, data );
}
#define print_info(p, S...) seq_printf(p, S)
 
//--------------------------------------------------------------------
 
void pex_remove_proc( char *name )
void pex_brd_capabilities(struct pex_device *brd, struct seq_file *p)
{
remove_proc_entry( name, NULL );
}
 
//--------------------------------------------------------------------
 
int pex_show_capabilities( char *buf, struct pex_device *brd )
{
int i = 0;
int res = 0;
char *p = buf;
u8 cap = 0;
u32 cap_id = 0;
 
44,29 → 36,25
goto err_exit;
}
 
if(!buf) {
goto err_exit;
}
print_info(p,"\n" );
 
p += sprintf(p,"\n" );
 
res = pci_read_config_byte(m_pci, 0x34, &cap);
if(res < 0) {
p += sprintf(p, " Error read capabilities pointer\n");
print_info(p, " Error read capabilities pointer\n");
goto err_exit;
}
 
p += sprintf(p, " Capability pointer: 0x%x\n", cap);
print_info(p, " Capability pointer: 0x%x\n", cap);
 
while(1) {
 
res = pci_read_config_dword(m_pci, cap, &cap_id);
if(res < 0) {
p += sprintf(p, " Error read capabilities id\n");
print_info(p, " Error read capabilities id\n");
goto err_exit;
}
 
p += sprintf(p, " Capability ID: 0x%x\n", cap_id);
print_info(p, " Capability ID: 0x%x\n", cap_id);
 
if((cap_id & 0xff) == 0x10) {
break;
78,13 → 66,13
}
 
if((cap_id & 0xff) != 0x10) {
p += sprintf(p, " Can't find PCI Express capabilities\n");
print_info(p, " Can't find PCI Express capabilities\n");
goto err_exit;
}
 
p += sprintf(p,"\n" );
p += sprintf(p, " PCI Express Capability Register Set\n");
p += sprintf(p,"\n" );
print_info(p,"\n" );
print_info(p, " PCI Express Capability Register Set\n");
print_info(p,"\n" );
 
for(i=0; i<9; i++) {
u32 reg = 0;
91,43 → 79,34
int j = cap + 4*i;
res = pci_read_config_dword(m_pci, j, &reg);
if(res < 0) {
p += sprintf(p, " Error read capabilities sructure: offset %x\n", j);
print_info(p, " Error read capabilities sructure: offset %x\n", j);
goto err_exit;
}
p += sprintf(p, " 0x%x: 0x%X\n", j, reg);
print_info(p, " 0x%x: 0x%X\n", j, reg);
}
 
return;
 
err_exit:
 
return (p-buf);
print_info(p, " Error print info\n");
}
 
int pex_proc_info( char *buf,
char **start,
off_t off,
int count,
int *eof,
void *data )
//--------------------------------------------------------------------
 
void pex_brd_info(struct pex_device *brd, struct seq_file *p)
{
int iBlock = 0;
char *p = buf;
struct pex_device *brd = (struct pex_device*)data;
 
if(!brd) {
p += sprintf(p," Invalid device pointer\n" );
*eof = 1;
return p - buf;
print_info(p," Invalid device pointer\n" );
return;
}
 
p += pex_show_capabilities(p, brd);
pex_brd_capabilities(brd, p);
 
p += sprintf(p,"\n" );
p += sprintf(p," Device information\n" );
print_info(p,"\n" );
print_info(p," Device information\n" );
print_info(p, " m_TotalIRQ = %d\n", atomic_read(&brd->m_TotalIRQ));
 
p += sprintf(p, " m_TotalIRQ = %d\n", atomic_read(&brd->m_TotalIRQ));
 
 
 
for(iBlock = 0; iBlock < brd->m_BlockCnt; iBlock++)
{
u32 FifoAddr = 0;
139,38 → 118,98
if((val & 0x0FFF) != PE_EXT_FIFO_ID)
continue;
 
p += sprintf(p,"\n" );
p += sprintf(p," PE_EXT_FIFO %d\n", iBlock+1 );
p += sprintf(p,"\n" );
print_info(p,"\n" );
print_info(p," PE_EXT_FIFO %d\n", iBlock+1 );
print_info(p,"\n" );
 
p += sprintf(p," BLOCK_ID = %x\n", (val & 0x0FFF) );
print_info(p," BLOCK_ID = %x\n", (val & 0x0FFF) );
val = ReadOperationWordReg(brd, PEFIFOadr_BLOCK_VER + FifoAddr);
p += sprintf(p," BLOCK_VER = %x\n", (val & 0xFFFF) );
print_info(p," BLOCK_VER = %x\n", (val & 0xFFFF) );
val = ReadOperationWordReg(brd, PEFIFOadr_FIFO_ID + FifoAddr);
p += sprintf(p," FIFO_ID = %x\n", (val & 0xFFFF) );
print_info(p," FIFO_ID = %x\n", (val & 0xFFFF) );
val = ReadOperationWordReg(brd, PEFIFOadr_FIFO_NUM + FifoAddr);
p += sprintf(p," FIFO_NUMBER = %x\n", (val & 0xFFFF) );
print_info(p," FIFO_NUMBER = %x\n", (val & 0xFFFF) );
val = ReadOperationWordReg(brd, PEFIFOadr_DMA_SIZE + FifoAddr);
p += sprintf(p," RESOURCE = %x\n", (val & 0xFFFF) );
print_info(p," RESOURCE = %x\n", (val & 0xFFFF) );
val = ReadOperationWordReg(brd, PEFIFOadr_FIFO_CTRL + FifoAddr);
p += sprintf(p," DMA_MODE = %x\n", (val & 0xFFFF) );
print_info(p," DMA_MODE = %x\n", (val & 0xFFFF) );
val = ReadOperationWordReg(brd, PEFIFOadr_DMA_CTRL + FifoAddr);
p += sprintf(p," DMA_CTRL = %x\n", (val & 0xFFFF) );
print_info(p," DMA_CTRL = %x\n", (val & 0xFFFF) );
val = ReadOperationWordReg(brd, PEFIFOadr_FIFO_STATUS + FifoAddr);
p += sprintf(p," FIFO_STATUS = %x\n", (val & 0xFFFF) );
print_info(p," FIFO_STATUS = %x\n", (val & 0xFFFF) );
val = ReadOperationWordReg(brd, PEFIFOadr_FLAG_CLR + FifoAddr);
p += sprintf(p," FLAG_CLR = %x\n", (val & 0xFFFF) );
print_info(p," FLAG_CLR = %x\n", (val & 0xFFFF) );
val = ReadOperationWordReg(brd, PEFIFOadr_PCI_ADDRL + FifoAddr);
p += sprintf(p," PCI_ADRL = %x\n", (val & 0xFFFF) );
print_info(p," PCI_ADRL = %x\n", (val & 0xFFFF) );
val = ReadOperationWordReg(brd, PEFIFOadr_PCI_ADDRH + FifoAddr);
p += sprintf(p," PCI_ADRH = %x\n", (val & 0xFFFF) );
print_info(p," PCI_ADRH = %x\n", (val & 0xFFFF) );
val = ReadOperationWordReg(brd, PEFIFOadr_LOCAL_ADR + FifoAddr);
p += sprintf(p," LOCAL_ADR = %x\n", (val & 0xFFFF) );
print_info(p," LOCAL_ADR = %x\n", (val & 0xFFFF) );
}
}
 
*eof = 1;
//--------------------------------------------------------------------
 
return p - buf;
static int pex_proc_show(struct seq_file *m, void *v)
{
struct pex_device *brd = m->private;
 
pex_brd_info(brd, m);
 
return 0;
}
 
//--------------------------------------------------------------------
 
static int pex_proc_open(struct inode *inode, struct file *file)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
struct pex_device* brd = PDE_DATA(inode);
#else
struct pex_device* brd = PDE(inode)->data;
#endif
 
return single_open(file, pex_proc_show, brd);
}
 
//--------------------------------------------------------------------
 
static int pex_proc_release(struct inode *inode, struct file *file)
{
return single_release(inode, file);
}
 
//--------------------------------------------------------------------
 
static const struct file_operations pex_proc_fops = {
.owner = THIS_MODULE,
.open = pex_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = pex_proc_release,
};
 
//--------------------------------------------------------------------
 
void pex_register_proc( char *name, void *fptr, void *data )
{
struct pex_device *brd = (struct pex_device *)data;
 
if(!brd) {
dbg_msg( dbg_trace, "%s(): Invalid driver pointer\n", __FUNCTION__ );
return;
}
 
if(!proc_create_data(name, S_IRUGO, NULL, &pex_proc_fops, brd)) {
dbg_msg(1, "%s(): Error register proc entry: /proc/%s\n", __FUNCTION__, name);
}
}
 
//--------------------------------------------------------------------
 
void pex_remove_proc( char *name )
{
remove_proc_entry(name, NULL);
}
 
//--------------------------------------------------------------------
/soft/linux/driver/pexdrv/pexproc.h
2,12 → 2,6
#ifndef __PEXPROC_H__
#define __PEXPROC_H__
 
int pex_proc_info(char *buf,
char **start,
off_t off,
int count,
int *eof,
void *data );
void pex_register_proc(char *name, void *fptr, void *data);
void pex_remove_proc(char *name);
 
/soft/linux/exam/Makefile
13,7 → 13,7
LD = $(CROSS_COMPILE)g++
 
CFLAGS := -D__LINUX__ -g -Wall -I../driver/pexdrv -I../common/board -I../common/utils
LFLAGS = -Wl
LFLAGS +=
 
$(TARGET_NAME): $(patsubst %.cpp,%.o, $(wildcard *.cpp))
$(LD) -o $(TARGET_NAME) $(notdir $^) $(LFLAGS)

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.