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

Subversion Repositories pcie_ds_dma

[/] [pcie_ds_dma/] [trunk/] [soft/] [linux/] [driver/] [pexdrv/] [dmachan.c] - Blame information for rev 54

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 dsmv
 
2
#include <linux/kernel.h>
3
#define __NO_VERSION__
4
#include <linux/module.h>
5
#include <linux/types.h>
6
#include <linux/ioport.h>
7
#include <linux/pci.h>
8
#include <linux/interrupt.h>
9
#include <linux/pagemap.h>
10
#include <linux/interrupt.h>
11
#include <linux/proc_fs.h>
12 54 v.karak
#include <linux/delay.h>
13
#include <linux/wait.h>
14 2 dsmv
#include <asm/io.h>
15
 
16
#ifndef _EVENT_H_
17
#include "event.h"
18
#endif
19
#ifndef  _DMA_CHAN_H_
20
#include "dmachan.h"
21
#endif
22
#ifndef  _HARDWARE_H_
23
#include "hardware.h"
24
#endif
25
 
26
//-----------------------------------------------------------------------------
27
 
28
struct CDmaChannel* CDmaChannelCreate(  u32 NumberOfChannel,
29 54 v.karak
        TASKLET_ROUTINE dpc,
30 2 dsmv
        void *brd,
31
        struct device   *dev,
32
        u32 cbMaxTransferLength,
33
        u16 idBlockFifo,
34
        int bScatterGather )
35
{
36
    struct CDmaChannel *dma = NULL;
37
 
38
    dma = kzalloc(sizeof(struct CDmaChannel), GFP_KERNEL);
39
    if(!dma) {
40 54 v.karak
        printk("%s(): Error allocate memory for CDmaChannel object\n", __FUNCTION__);
41 2 dsmv
        return NULL;
42
    }
43
 
44
    dma->m_NumberOfChannel = NumberOfChannel;
45
    dma->m_Board = brd;
46
    dma->m_dev = dev;
47
    dma->m_UseCount = 0;
48 54 v.karak
    dma->m_DpcForIsr = dpc;
49 2 dsmv
    dma->m_idBlockFifo = idBlockFifo;
50
 
51
    spin_lock_init( &dma->m_DmaLock );
52
    init_waitqueue_head( &dma->m_DmaWq );
53
    tasklet_init( &dma->m_Dpc, dma->m_DpcForIsr, (unsigned long)dma );
54
    InitKevent( &dma->m_BlockEndEvent );
55
    InitKevent( &dma->m_BufferEndEvent );
56
 
57 54 v.karak
    //printk("%s(%d): COMPLETE.\n", __FUNCTION__, dma->m_NumberOfChannel);
58 2 dsmv
 
59
    return dma;
60
}
61
 
62
//-----------------------------------------------------------------------------
63
 
64
void CDmaChannelDelete(struct CDmaChannel *dma)
65
{
66 54 v.karak
    //printk("%s()\n", __FUNCTION__);
67 2 dsmv
    if (dma) {
68
        tasklet_kill( &dma->m_Dpc );
69
        kfree(dma);
70
    }
71
}
72
 
73
//-----------------------------------------------------------------------------
74
 
75
int RequestMemory(struct CDmaChannel *dma, void** ppVirtAddr, u32 size, u32 *pCount, void** pStub, u32 bMemType)
76
{
77
    int Status = -ENOMEM;
78
 
79 54 v.karak
    //printk("%s(): Channel = %d\n", __FUNCTION__, dma->m_NumberOfChannel);
80 2 dsmv
 
81
    // при первом обращении действительно выделяем память,
82
    // а при повторных только отображаем выделенную память на пользовательское пространство
83 54 v.karak
    if(dma->m_UseCount == 0)
84 2 dsmv
    {
85 6 v.karak
        dma_addr_t pa = (dma_addr_t)0;
86
 
87 2 dsmv
        dma->m_MemType = bMemType;
88
        dma->m_BlockCount = *pCount;
89
        dma->m_BlockSize = size;
90
 
91
        // выделяем память под описатели блоков (системный, и логический адрес для каждого блока)
92
        dma->m_pBufDscr.SystemAddress = (void*)dma_alloc_coherent( dma->m_dev,
93
                                                                   dma->m_BlockCount * sizeof(SHARED_MEMORY_DESCRIPTION),
94 6 v.karak
                                                                   &pa, GFP_KERNEL);
95 2 dsmv
        if(!dma->m_pBufDscr.SystemAddress)
96
        {
97 54 v.karak
            printk("%s(): Not memory for buffer descriptions\n", __FUNCTION__);
98 2 dsmv
            return -ENOMEM;
99
        }
100
 
101 6 v.karak
        dma->m_pBufDscr.LogicalAddress = (size_t)pa;
102 2 dsmv
        dma->m_ScatterGatherTableEntryCnt = 0;
103
    }
104
 
105
    Status = RequestStub(dma, pStub);
106
    if(Status == 0)
107
    {
108
        if(dma->m_MemType == SYSTEM_MEMORY_TYPE) {
109
            Status = RequestSysBuf(dma, ppVirtAddr);
110
        } else {
111
            ReleaseStub(dma);
112
            dma_free_coherent(dma->m_dev,
113
                              dma->m_BlockCount * sizeof(SHARED_MEMORY_DESCRIPTION),
114
                              dma->m_pBufDscr.SystemAddress,
115
                              dma->m_pBufDscr.LogicalAddress);
116
            dma->m_pBufDscr.SystemAddress = NULL;
117
            dma->m_pBufDscr.LogicalAddress = 0;
118 54 v.karak
            printk("%s(): Invalid memory type for DMA data blocks\n", __FUNCTION__);
119 2 dsmv
            return -EINVAL;
120
        }
121
 
122
        if(Status == 0)
123
        {
124 54 v.karak
            if(dma->m_UseCount == 0)
125 2 dsmv
            {
126 54 v.karak
                //printk("%s(): Scatter/Gather Table Entry is %d\n", __FUNCTION__, dma->m_ScatterGatherTableEntryCnt);
127 2 dsmv
                if(dma->m_idBlockFifo == PE_EXT_FIFO_ID)
128
                    SetScatterGatherListExt(dma);
129
                else {
130 54 v.karak
                    printk("%s(): Scatter/Gather Table Entry not created\n", __FUNCTION__);
131 2 dsmv
                    //SetScatterGatherList(dma);
132
                }
133
                dma->m_pStub = (PAMB_STUB)dma->m_StubDscr.SystemAddress;
134
                dma->m_pStub->lastBlock = -1;
135
                dma->m_pStub->totalCounter = 0;
136
                dma->m_pStub->offset = 0;
137
                dma->m_pStub->state = STATE_STOP;
138
            }
139 54 v.karak
 
140
            *pCount = dma->m_BlockCount;
141
 
142 2 dsmv
            dma->m_UseCount++;
143
        }
144
        else
145
        {
146
            ReleaseStub(dma);
147
            dma_free_coherent(dma->m_dev, dma->m_BlockCount * sizeof(SHARED_MEMORY_DESCRIPTION),
148
                              dma->m_pBufDscr.SystemAddress, dma->m_pBufDscr.LogicalAddress);
149
            dma->m_pBufDscr.SystemAddress = NULL;
150
            dma->m_pBufDscr.LogicalAddress = 0;
151 54 v.karak
            printk("%s(): Error allocate memory\n", __FUNCTION__);
152 2 dsmv
            return -EINVAL;
153
        }
154
    }
155
    else
156 54 v.karak
    {
157
        if(dma->m_UseCount == 0) {
158
            dma_free_coherent(dma->m_dev,
159
                              dma->m_BlockCount * sizeof(SHARED_MEMORY_DESCRIPTION),
160
                              dma->m_pBufDscr.SystemAddress, dma->m_pBufDscr.LogicalAddress);
161
            dma->m_pBufDscr.SystemAddress = NULL;
162
            dma->m_pBufDscr.LogicalAddress = 0;
163
        }
164 2 dsmv
    }
165 54 v.karak
    return Status;
166 2 dsmv
}
167
 
168
//-----------------------------------------------------------------------------
169
 
170 54 v.karak
int ReleaseMemory(struct CDmaChannel *dma)
171 2 dsmv
{
172 54 v.karak
    printk("%s(): Entered. Channel = %d\n", __FUNCTION__, dma->m_NumberOfChannel);
173 2 dsmv
 
174 54 v.karak
    if(dma->m_UseCount == 0) {
175
        printk("%s(): Memory not allocated. m_UseCount = %d\n", __FUNCTION__, dma->m_UseCount);
176
        return -1;
177 2 dsmv
    }
178
 
179 54 v.karak
    dma->m_UseCount--;
180
 
181 2 dsmv
    ReleaseStub( dma );
182
    ReleaseSGList( dma );
183
    ReleaseSysBuf( dma );
184
 
185
    dma_free_coherent(dma->m_dev,
186
                      dma->m_BlockCount * sizeof(SHARED_MEMORY_DESCRIPTION),
187
                      dma->m_pBufDscr.SystemAddress, dma->m_pBufDscr.LogicalAddress);
188
 
189
    dma->m_pBufDscr.SystemAddress = NULL;
190
    dma->m_pBufDscr.LogicalAddress = 0;
191 54 v.karak
    return 0;
192 2 dsmv
}
193
 
194
//-----------------------------------------------------------------------------
195
 
196
int SetScatterGatherListExt(struct CDmaChannel *dma)
197
{
198
    int Status = 0;
199
    u32 iBlock = 0;
200
    //u32 ii = 0;
201
    u32 iEntry = 0;
202
    u32 iBlkEntry = 0;
203
    u64 *pDscrBuf = NULL;
204
    u16* pNextDscr = NULL;
205
    u32 DscrSize = 0;
206
    SHARED_MEMORY_DESCRIPTION *pMemDscr = (SHARED_MEMORY_DESCRIPTION*)dma->m_pBufDscr.SystemAddress;
207
    DMA_CHAINING_DESCR_EXT      *pSGTEx = NULL;
208
 
209 54 v.karak
    //printk("%s()\n", __FUNCTION__);
210 2 dsmv
 
211
    Status = RequestSGList(dma);
212
    if(Status < 0)
213
        return Status;
214
 
215
    //получим адрес таблицы для хранения цепочек DMA
216
    dma->m_pScatterGatherTableExt = (DMA_CHAINING_DESCR_EXT*)dma->m_SGTableDscr.SystemAddress;
217
    pSGTEx = dma->m_pScatterGatherTableExt;
218
 
219
    DscrSize = DSCR_BLOCK_SIZE*sizeof(DMA_CHAINING_DESCR_EXT);
220
 
221
    //обнулим таблицу дескрипторов DMA
222
    memset(pSGTEx, 0, dma->m_ScatterGatherBlockCnt*DscrSize);
223
 
224 54 v.karak
    printk("%s(): m_SGTableDscr.SystemAddress = %p\n", __FUNCTION__, dma->m_SGTableDscr.SystemAddress );
225
    printk("%s(): m_SGTableDscr.LogicalAddress = 0x%llx\n", __FUNCTION__, dma->m_SGTableDscr.LogicalAddress );
226 2 dsmv
 
227
    //заполним значениями таблицу цепочек DMA
228
    for(iBlock=0, iEntry=0; iBlock < dma->m_BlockCount; iBlock++) {
229
 
230
        //адрес и размер DMA блока
231
        u64     address = pMemDscr[iBlock].LogicalAddress;
232
        u64     DmaSize = dma->m_BlockSize - 0x1000;
233
 
234
        //заполним поля элментов таблицы дескрипторов
235
        pSGTEx[iEntry].AddrByte1  = (u8)((address >> 8) & 0xFF);
236
        pSGTEx[iEntry].AddrByte2  = (u8)((address >> 16) & 0xFF);
237
        pSGTEx[iEntry].AddrByte3  = (u8)((address >> 24) & 0xFF);
238
        pSGTEx[iEntry].AddrByte4  = (u8)((address >> 32) & 0xFF);
239
        pSGTEx[iEntry].SizeByte1  = (u8)((DmaSize >> 8) & 0xFF);
240
        pSGTEx[iEntry].SizeByte2  = (u8)((DmaSize >> 16) & 0xFF);
241
        pSGTEx[iEntry].SizeByte3  = (u8)((DmaSize >> 24) & 0xFF);
242
        pSGTEx[iEntry].Cmd.JumpNextDescr = 1; //перейти к следующему дескриптору
243
        pSGTEx[iEntry].Cmd.JumpNextBlock = 0; //перейти к следующему блоку дескрипторов
244
        pSGTEx[iEntry].Cmd.JumpDescr0 = 0;
245
        pSGTEx[iEntry].Cmd.Res0 = 0;
246
        pSGTEx[iEntry].Cmd.EndOfTrans = 1;
247
        pSGTEx[iEntry].Cmd.Res = 0;
248
        pSGTEx[iEntry].SizeByte1 |= dma->m_DmaDirection;
249
 
250
        {
251
            //u32 *ptr=(u32*)&pSGTEx[iEntry];
252 54 v.karak
            //printk("%s(): %d: Entry Addr: %p, Data Addr: %llx  %.8X %.8X\n",
253 2 dsmv
            //       __FUNCTION__, iEntry, &pSGTEx[iEntry], address, ptr[1], ptr[0]);
254
        }
255
 
256
        if(((iEntry+2)%DSCR_BLOCK_SIZE) == 0)
257
        {
258
            size_t NextDscrBlockAddr = 0;
259
            DMA_NEXT_BLOCK *pNextBlock = NULL;
260
 
261
            pSGTEx[iEntry].Cmd.JumpNextBlock = 1;
262
            pSGTEx[iEntry].Cmd.JumpNextDescr = 0;
263
 
264
            //NextDscrBlockAddr = virt_to_bus((void*)&pSGTEx[iEntry+2]);
265
            NextDscrBlockAddr = (size_t)((u8*)dma->m_SGTableDscr.LogicalAddress + sizeof(DMA_CHAINING_DESCR_EXT)*(iEntry +2));
266
 
267 54 v.karak
            //printk("%s(): NextDscrBlock [PA]: 0x%lx\n", __FUNCTION__, NextDscrBlockAddr);
268
            //printk("%s(): NextDscrBlock [VA]: %p\n", __FUNCTION__, &pSGTEx[iEntry+2]);
269 2 dsmv
 
270
            pNextBlock = (DMA_NEXT_BLOCK*)&pSGTEx[iEntry+1];
271
 
272 54 v.karak
            //printk("%s(): pNextBlock: %p\n", __FUNCTION__, pNextBlock);
273 2 dsmv
 
274
            pNextBlock->NextBlkAddr = (NextDscrBlockAddr >> 8) & 0xFFFFFF;
275
            pNextBlock->Signature = 0x4953;
276
            pNextBlock->Crc = 0;
277
            iEntry++;
278
        }
279
        iEntry++;
280
    }
281
 
282 54 v.karak
    //printk("%s(): iEntry = %d\n", __FUNCTION__, iEntry);
283 2 dsmv
 
284
    if(((iEntry % DSCR_BLOCK_SIZE)) != 0)
285
    {
286
        DMA_NEXT_BLOCK *pNextBlock = NULL;
287
        u32 i = 0;
288
 
289
        pSGTEx[iEntry-1].Cmd.JumpNextDescr = 0;
290
 
291
        pNextBlock = (DMA_NEXT_BLOCK*)(&pSGTEx[iEntry]);
292
        pNextBlock->NextBlkAddr = (dma->m_SGTableDscr.LogicalAddress >> 8);
293
 
294
        i = (DSCR_BLOCK_SIZE * dma->m_ScatterGatherBlockCnt) - 1;
295
        pNextBlock = (DMA_NEXT_BLOCK*)(&pSGTEx[i]);
296
 
297 54 v.karak
        //printk("%s(): %d: pNextBlock: %p\n", __FUNCTION__, i, pNextBlock );
298 2 dsmv
 
299
        pNextBlock->NextBlkAddr = 0;
300
        pNextBlock->Signature = 0x4953;
301
        pNextBlock->Crc = 0;
302
    }
303
 
304 54 v.karak
    printk("%s(): DmaDirection = %d, DmaLocalAddress = 0x%X\n", __FUNCTION__, dma->m_DmaDirection, dma->m_DmaLocalAddress);
305 2 dsmv
 
306
    //for( ii=0; ii<dma->m_ScatterGatherBlockCnt*DSCR_BLOCK_SIZE; ii++ )
307
    //{
308 54 v.karak
    //    u32 *ptr=(u32*)&pSGTEx[ii];
309
    //    printk("%s(): %02d: %08X %08X\n", __FUNCTION__, ii, ptr[1], ptr[0]);
310
    //}
311 2 dsmv
 
312 54 v.karak
    pDscrBuf = (u64*)dma->m_pScatterGatherTableExt;
313
 
314
    for(iBlkEntry = 0; iBlkEntry < dma->m_ScatterGatherBlockCnt; iBlkEntry++)
315
    {
316
        u32 ctrl_code = 0xFFFFFFFF;
317
 
318
        for(iBlock = 0; iBlock < DSCR_BLOCK_SIZE; iBlock++)
319
        {
320
            u16 data0 = (u16)(pDscrBuf[iBlock] & 0xFFFF);
321
            u16 data1 = (u16)((pDscrBuf[iBlock] >> 16) & 0xFFFF);
322
            u16 data2 = (u16)((pDscrBuf[iBlock] >> 32) & 0xFFFF);
323
            u16 data3 = (u16)((pDscrBuf[iBlock] >> 48) & 0xFFFF);
324
            if(iBlock == DSCR_BLOCK_SIZE-1)
325
            {
326
                ctrl_code = ctrl_code ^ data0 ^ data1 ^ data2 ^ data3;
327
 
328
                //printk("%s(): DSCR_BLCK[%02d] - NextBlkAddr = 0x%08X, Signature = 0x%04X, Crc = 0x%04X\n", __FUNCTION__,
329
                //       iBlkEntry,
330
                //       (u32)(pDscrBuf[iBlock] << 8),
331
                //       (u16)((pDscrBuf[iBlock] >> 32) & 0xFFFF),
332
                //       (u16)ctrl_code);
333
            }
334
            else
335
            {
336
                u32 ctrl_tmp = 0;
337
                ctrl_code = ctrl_code ^ data0 ^ data1 ^ data2 ^ data3;
338
                ctrl_tmp = ctrl_code << 1;
339
                ctrl_tmp |= (ctrl_code & 0x8000) ? 0: 1;
340
                ctrl_code = ctrl_tmp;
341
 
342
                //printk("%s(): %02d(%02d) - PciAddr = 0x%08X, Cmd = 0x%04X, DmaLength = 0x%08X (%02X %02X %02X)\n",  __FUNCTION__,
343
                //                                    iBlock, iBlkEntry,
344
                //                                    (u32)(pDscrBuf[iBlock] << 8),
345
                //                                   (u8)(pDscrBuf[iBlock] >> 32),
346
                //                                    (u32)((pDscrBuf[iBlock] >> 41) << 9),
347
                //                                    (u8)(pDscrBuf[iBlock] >> 56),
348
                //                                    (u8)(pDscrBuf[iBlock] >> 48),
349
                //                                    (u8)(pDscrBuf[iBlock] >> 40));
350
            }
351
        }
352
        pNextDscr = (u16*)pDscrBuf;
353
        pNextDscr[255] |= (u16)ctrl_code;
354
        pDscrBuf += DSCR_BLOCK_SIZE;
355
    }
356
    return 0;
357
}
358
 
359
int SetScatterGatherListExtUser(struct CDmaChannel *dma)
360
{
361
    int Status = 0;
362
    u32 iBlock = 0;
363
    //u32 ii = 0;
364
    u32 iEntry = 0;
365
    u32 iBlkEntry = 0;
366
    u64 *pDscrBuf = NULL;
367
    u16* pNextDscr = NULL;
368
    u32 DscrSize = 0;
369
    SHARED_MEMORY_DESCRIPTION *pMemDscr = (SHARED_MEMORY_DESCRIPTION*)&dma->m_BufDscrVA;
370
    DMA_CHAINING_DESCR_EXT      *pSGTEx = NULL;
371
 
372
    printk("%s()\n", __FUNCTION__);
373
 
374
    Status = RequestSGList(dma);
375
    if(Status < 0)
376
        return Status;
377
 
378
    //получим адрес таблицы для хранения цепочек DMA
379
    dma->m_pScatterGatherTableExt = (DMA_CHAINING_DESCR_EXT*)dma->m_SGTableDscr.SystemAddress;
380
    pSGTEx = dma->m_pScatterGatherTableExt;
381
 
382
    DscrSize = DSCR_BLOCK_SIZE*sizeof(DMA_CHAINING_DESCR_EXT);
383
 
384
    //обнулим таблицу дескрипторов DMA
385
    memset(pSGTEx, 0, dma->m_ScatterGatherBlockCnt*DscrSize);
386
 
387
    printk("%s(): m_SGTableDscr.SystemAddress = %p\n", __FUNCTION__, dma->m_SGTableDscr.SystemAddress );
388
    printk("%s(): m_SGTableDscr.LogicalAddress = 0x%llx\n", __FUNCTION__, dma->m_SGTableDscr.LogicalAddress );
389
 
390
    //заполним значениями таблицу цепочек DMA
391
    for(iBlock=0, iEntry=0; iBlock < pMemDscr->PageCount; iBlock++) {
392
 
393
        //адрес и размер DMA блока
394
        u64     address = page_to_phys(pMemDscr->LockedPages[iBlock]);
395
        u64     DmaSize = dma->m_BlockSize - 0x1000;
396
 
397
 
398
        //заполним поля элментов таблицы дескрипторов
399
        pSGTEx[iEntry].AddrByte1  = (u8)((address >> 8) & 0xFF);
400
        pSGTEx[iEntry].AddrByte2  = (u8)((address >> 16) & 0xFF);
401
        pSGTEx[iEntry].AddrByte3  = (u8)((address >> 24) & 0xFF);
402
        pSGTEx[iEntry].AddrByte4  = (u8)((address >> 32) & 0xFF);
403
        pSGTEx[iEntry].SizeByte1  = (u8)((DmaSize >> 8) & 0xFF);
404
        pSGTEx[iEntry].SizeByte2  = (u8)((DmaSize >> 16) & 0xFF);
405
        pSGTEx[iEntry].SizeByte3  = (u8)((DmaSize >> 24) & 0xFF);
406
        pSGTEx[iEntry].Cmd.JumpNextDescr = 1; //перейти к следующему дескриптору
407
        pSGTEx[iEntry].Cmd.JumpNextBlock = 0; //перейти к следующему блоку дескрипторов
408
        pSGTEx[iEntry].Cmd.JumpDescr0 = 0;
409
        pSGTEx[iEntry].Cmd.Res0 = 0;
410
        pSGTEx[iEntry].Cmd.EndOfTrans = 1;
411
        pSGTEx[iEntry].Cmd.Res = 0;
412
        pSGTEx[iEntry].SizeByte1 |= dma->m_DmaDirection;
413
 
414
        {
415
            u32 *ptr=(u32*)&pSGTEx[iEntry];
416
            printk("%s(): %d: Entry Addr: %p, Data Addr: %llx  %.8X %.8X\n",
417
                   __FUNCTION__, iEntry, &pSGTEx[iEntry], address, ptr[1], ptr[0]);
418
        }
419
 
420
        if(((iEntry+2)%DSCR_BLOCK_SIZE) == 0)
421
        {
422
            size_t NextDscrBlockAddr = 0;
423
            DMA_NEXT_BLOCK *pNextBlock = NULL;
424
 
425
            pSGTEx[iEntry].Cmd.JumpNextBlock = 1;
426
            pSGTEx[iEntry].Cmd.JumpNextDescr = 0;
427
 
428
            NextDscrBlockAddr = virt_to_phys((void*)&pSGTEx[iEntry+2]);
429
            //NextDscrBlockAddr = (size_t)((u8*)dma->m_SGTableDscr.LogicalAddress + sizeof(DMA_CHAINING_DESCR_EXT)*(iEntry +2));
430
 
431
            printk("%s(): NextDscrBlock [PA]: 0x%lx\n", __FUNCTION__, NextDscrBlockAddr);
432
            printk("%s(): NextDscrBlock [VA]: %p\n", __FUNCTION__, &pSGTEx[iEntry+2]);
433
 
434
            pNextBlock = (DMA_NEXT_BLOCK*)&pSGTEx[iEntry+1];
435
 
436
            printk("%s(): pNextBlock: %p\n", __FUNCTION__, pNextBlock);
437
 
438
            pNextBlock->NextBlkAddr = (NextDscrBlockAddr >> 8) & 0xFFFFFF;
439
            pNextBlock->Signature = 0x4953;
440
            pNextBlock->Crc = 0;
441
            iEntry++;
442
        }
443
        iEntry++;
444
    }
445
 
446
    printk("%s(): iEntry = %d\n", __FUNCTION__, iEntry);
447
 
448
    if(((iEntry % DSCR_BLOCK_SIZE)) != 0)
449
    {
450
        DMA_NEXT_BLOCK *pNextBlock = NULL;
451
        u32 i = 0;
452
 
453
        pSGTEx[iEntry-1].Cmd.JumpNextDescr = 0;
454
 
455
        pNextBlock = (DMA_NEXT_BLOCK*)(&pSGTEx[iEntry]);
456
        pNextBlock->NextBlkAddr = (dma->m_SGTableDscr.LogicalAddress >> 8);
457
 
458
        i = (DSCR_BLOCK_SIZE * dma->m_ScatterGatherBlockCnt) - 1;
459
        pNextBlock = (DMA_NEXT_BLOCK*)(&pSGTEx[i]);
460
 
461
        printk("%s(): %d: pNextBlock: %p\n", __FUNCTION__, i, pNextBlock );
462
 
463
        pNextBlock->NextBlkAddr = 0;
464
        pNextBlock->Signature = 0x4953;
465
        pNextBlock->Crc = 0;
466
    }
467
 
468
    printk("%s(): DmaDirection = %d, DmaLocalAddress = 0x%X\n", __FUNCTION__, dma->m_DmaDirection, dma->m_DmaLocalAddress);
469
 
470
    //for( ii=0; ii<dma->m_ScatterGatherBlockCnt*DSCR_BLOCK_SIZE; ii++ )
471
    //{
472
    //    u32 *ptr=(u32*)&pSGTEx[ii];
473
    //    printk("%s(): %d: %.8X %.8X\n", __FUNCTION__, ii, ptr[1], ptr[0]);
474 2 dsmv
    //}
475
 
476
    pDscrBuf = (u64*)dma->m_pScatterGatherTableExt;
477
 
478
    for(iBlkEntry = 0; iBlkEntry < dma->m_ScatterGatherBlockCnt; iBlkEntry++)
479
    {
480
        u32 ctrl_code = 0xFFFFFFFF;
481
 
482
        for(iBlock = 0; iBlock < DSCR_BLOCK_SIZE; iBlock++)
483
        {
484
            u16 data0 = (u16)(pDscrBuf[iBlock] & 0xFFFF);
485
            u16 data1 = (u16)((pDscrBuf[iBlock] >> 16) & 0xFFFF);
486
            u16 data2 = (u16)((pDscrBuf[iBlock] >> 32) & 0xFFFF);
487
            u16 data3 = (u16)((pDscrBuf[iBlock] >> 48) & 0xFFFF);
488
            if(iBlock == DSCR_BLOCK_SIZE-1)
489
            {
490
                ctrl_code = ctrl_code ^ data0 ^ data1 ^ data2 ^ data3;
491 54 v.karak
                printk("%s(): DSCR_BLCK[%d] - NextBlkAddr = 0x%8X, Signature = 0x%4X, Crc = 0x%4X\n", __FUNCTION__,
492 2 dsmv
                       iBlkEntry,
493
                       (u32)(pDscrBuf[iBlock] << 8),
494
                       (u16)((pDscrBuf[iBlock] >> 32) & 0xFFFF),
495
                       (u16)ctrl_code);
496
            }
497
            else
498
            {
499
                u32 ctrl_tmp = 0;
500
                ctrl_code = ctrl_code ^ data0 ^ data1 ^ data2 ^ data3;
501
                ctrl_tmp = ctrl_code << 1;
502
                ctrl_tmp |= (ctrl_code & 0x8000) ? 0: 1;
503
                ctrl_code = ctrl_tmp;
504
 
505 54 v.karak
                printk("%s(): %d(%d) - PciAddr = 0x%8X, Cmd = 0x%2X, DmaLength = %d(%2X %2X %2X)\n",  __FUNCTION__,
506
                                                    iBlock, iBlkEntry,
507
                                                    (u32)(pDscrBuf[iBlock] << 8),
508
                                                    (u8)(pDscrBuf[iBlock] >> 32),
509
                                                    (u32)((pDscrBuf[iBlock] >> 41) << 9),
510
                                                    (u8)(pDscrBuf[iBlock] >> 56),
511
                                                    (u8)(pDscrBuf[iBlock] >> 48),
512
                                                    (u8)(pDscrBuf[iBlock] >> 40));
513
                //printk("%s(): JumpNextDescr = %d, JumpNextBlock = %d, JumpDescr0 = %d, EndOfTrans = %d, Signature = 0x%08X, Crc = 0x%08X\n",
514
                //                                    __FUNCTION__, dma->m_pScatterGatherTableExt[iEntry].Cmd.EndOfChain,
515
                //                                    dma->m_pScatterGatherTableExt[iEntry].Cmd.EndOfTrans,
516
                //                                    dma->m_pScatterGatherTableExt[iEntry].Signature,
517
                //                                    dma->m_pScatterGatherTableExt[iEntry].Crc );
518 2 dsmv
            }
519
        }
520
        pNextDscr = (u16*)pDscrBuf;
521
        pNextDscr[255] |= (u16)ctrl_code;
522
        pDscrBuf += DSCR_BLOCK_SIZE;
523
    }
524
    return 0;
525
}
526
 
527
//-----------------------------------------------------------------------------
528
/*
529
u32 NexDscrAddress(void *pVirtualAddress)
530
{
531
    return (u32)(virt_to_bus(pVirtualAddress)>>4);
532
}
533
*/
534
//-----------------------------------------------------------------------------
535
// размещение в системном адресном пространстве памяти,
536
// доступной для операций ПДП и отображаемой в пользовательское пространство
537
//-----------------------------------------------------------------------------
538
 
539
int RequestSysBuf(struct CDmaChannel *dma, void **pMemPhysAddr)
540
{
541
    u32 iBlock = 0;
542
    SHARED_MEMORY_DESCRIPTION *pMemDscr = (SHARED_MEMORY_DESCRIPTION*)dma->m_pBufDscr.SystemAddress;
543 54 v.karak
    //u32 order = get_order(dma->m_BlockSize);
544 2 dsmv
 
545 54 v.karak
    printk("%s()\n", __FUNCTION__);
546 2 dsmv
 
547
    for(iBlock = 0; iBlock < dma->m_BlockCount; iBlock++)
548
    {
549
        dma_addr_t       LogicalAddress;
550
        void            *pSystemAddress = NULL;
551
 
552 54 v.karak
        // if buffer not allocated - allocate memory
553
        if(dma->m_UseCount == 0) {
554
            pSystemAddress = dma_alloc_coherent(  dma->m_dev, dma->m_BlockSize, &LogicalAddress, GFP_KERNEL );
555
            //pSystemAddress = (void*)__get_free_pages(GFP_KERNEL, order);
556
            if(!pSystemAddress) {
557
                printk("%s(): Not enought memory for %i block location. m_BlockSize = %X\n",
558
                       __FUNCTION__, (int)iBlock, (int)dma->m_BlockSize );
559
                return -ENOMEM;
560
            }
561 2 dsmv
 
562 54 v.karak
            pMemDscr[iBlock].SystemAddress = pSystemAddress;
563
            pMemDscr[iBlock].LogicalAddress = LogicalAddress;
564
            //pMemDscr[iBlock].LogicalAddress = virt_to_bus(pSystemAddress);
565 2 dsmv
 
566 54 v.karak
            lock_pages( pMemDscr[iBlock].SystemAddress, dma->m_BlockSize );
567
        }
568 2 dsmv
 
569 54 v.karak
        // if buffer allocated - copy memory block addresses
570 2 dsmv
        pMemPhysAddr[iBlock] = (void*)pMemDscr[iBlock].LogicalAddress;
571
 
572 54 v.karak
        {
573
            // fill memory block
574
            //int iii=0;
575
            //u32 *buffer = (u32*)pMemDscr[iBlock].SystemAddress;
576
            //for(iii=0; iii<dma->m_BlockSize/4; iii++) {
577
            //    buffer[iii] = 0x12345678;
578
            //}
579 2 dsmv
        }
580
 
581 54 v.karak
        printk("%s(): %i: %p\n", __FUNCTION__, iBlock, pMemPhysAddr[iBlock]);
582 2 dsmv
    }
583
 
584
    dma->m_BlockCount = iBlock;
585
    dma->m_ScatterGatherTableEntryCnt = iBlock;
586
 
587
    return 0;
588
}
589
 
590
//-----------------------------------------------------------------------------
591
 
592 54 v.karak
int ReleaseSysBuf(struct CDmaChannel *dma)
593 2 dsmv
{
594
    u32 iBlock = 0;
595
    SHARED_MEMORY_DESCRIPTION *pMemDscr = (SHARED_MEMORY_DESCRIPTION*)dma->m_pBufDscr.SystemAddress;
596 54 v.karak
    //u32 order = get_order(dma->m_BlockSize);
597 2 dsmv
 
598 54 v.karak
    if(dma->m_UseCount != 0) {
599
        printk("%s(): Memory may be used in another process! m_UseCount = %d.\n", __FUNCTION__, dma->m_UseCount);
600
        return -1;
601
    }
602 2 dsmv
 
603 54 v.karak
    printk("%s()\n", __FUNCTION__);
604 2 dsmv
 
605
    for(iBlock = 0; iBlock < dma->m_BlockCount; iBlock++)
606
    {
607
        unlock_pages( pMemDscr[iBlock].SystemAddress, dma->m_BlockSize );
608
 
609
        dma_free_coherent( dma->m_dev, dma->m_BlockSize, pMemDscr[iBlock].SystemAddress, pMemDscr[iBlock].LogicalAddress );
610
        //free_pages((size_t)pMemDscr[iBlock].SystemAddress, order);
611
 
612
        pMemDscr[iBlock].SystemAddress = NULL;
613
        pMemDscr[iBlock].LogicalAddress = 0;
614
    }
615 54 v.karak
 
616
    return 0;
617 2 dsmv
}
618
 
619
//-----------------------------------------------------------------------------
620
 
621
int RequestStub(struct CDmaChannel *dma, void **pStubPhysAddr)
622
{
623
    dma_addr_t LogicalAddress = 0;
624
    u32 StubSize = 0;
625
 
626 54 v.karak
    //printk("%s()\n", __FUNCTION__ );
627 2 dsmv
 
628
    if(!dma)
629
        return -EINVAL;
630
 
631
    StubSize = sizeof(AMB_STUB) > PAGE_SIZE ? sizeof(AMB_STUB) : PAGE_SIZE;
632
 
633 54 v.karak
    //printk("%s() 0\n", __FUNCTION__ );
634 2 dsmv
 
635 54 v.karak
    if(dma->m_UseCount == 0)
636 2 dsmv
    {
637
        void *pStub = dma_alloc_coherent( dma->m_dev, StubSize, &LogicalAddress, GFP_KERNEL );
638
        if(!pStub)
639
        {
640 54 v.karak
            printk("%s(): Not enought memory for stub\n", __FUNCTION__);
641 2 dsmv
            return -ENOMEM;
642
        }
643
 
644
        lock_pages( pStub, StubSize );
645
 
646 54 v.karak
        //printk("%s() 1\n", __FUNCTION__ );
647 2 dsmv
 
648
        dma->m_StubDscr.SystemAddress = pStub;
649
        dma->m_StubDscr.LogicalAddress = LogicalAddress;
650
        dma->m_pStub = (AMB_STUB*)pStub;          //может быть в этом нет необходимости,
651
        //но в дальнейшем в модуле используется dma->m_pStub
652
    }
653
 
654 54 v.karak
    //printk("%s() 2\n", __FUNCTION__ );
655 2 dsmv
 
656
    pStubPhysAddr[0] = (void*)dma->m_StubDscr.LogicalAddress;
657
 
658 54 v.karak
    printk("%s(): Stub physical address: %llx\n", __FUNCTION__, dma->m_StubDscr.LogicalAddress);
659
    printk("%s(): Stub virtual address: %p\n", __FUNCTION__, dma->m_StubDscr.SystemAddress);
660 2 dsmv
 
661
    return 0;
662
}
663
 
664
//-----------------------------------------------------------------------------
665
 
666
void ReleaseStub(struct CDmaChannel *dma)
667
{
668
    u32 StubSize = sizeof(AMB_STUB) > PAGE_SIZE ? sizeof(AMB_STUB) : PAGE_SIZE;
669
 
670 54 v.karak
    if(dma->m_UseCount == 0)
671 2 dsmv
    {
672
        unlock_pages(dma->m_StubDscr.SystemAddress, StubSize);
673
 
674
        dma_free_coherent(dma->m_dev, StubSize,
675
                          dma->m_StubDscr.SystemAddress,
676
                          dma->m_StubDscr.LogicalAddress);
677
        dma->m_pStub = NULL;
678
        dma->m_StubDscr.SystemAddress = NULL;
679
        dma->m_StubDscr.LogicalAddress = 0;
680 54 v.karak
 
681
        printk("%s()\n", __FUNCTION__);
682 2 dsmv
    }
683
}
684
 
685
//-----------------------------------------------------------------------------
686
// вызываем только при первичном размещении буфера
687
//-----------------------------------------------------------------------------
688
 
689
int RequestSGList(struct CDmaChannel *dma)
690
{
691
    u32 SGListMemSize = 0;
692
    u32 SGListSize = 0;
693
    dma_addr_t PhysicalAddress;
694
 
695 54 v.karak
    printk("%s()\n", __FUNCTION__);
696 2 dsmv
 
697
    if(dma->m_idBlockFifo == PE_EXT_FIFO_ID)
698
    {
699
        dma->m_ScatterGatherBlockCnt = dma->m_ScatterGatherTableEntryCnt / (DSCR_BLOCK_SIZE-1);
700
        dma->m_ScatterGatherBlockCnt = (dma->m_ScatterGatherTableEntryCnt % (DSCR_BLOCK_SIZE-1)) ? (dma->m_ScatterGatherBlockCnt+1) : dma->m_ScatterGatherBlockCnt;
701
        SGListSize = sizeof(DMA_CHAINING_DESCR_EXT) * DSCR_BLOCK_SIZE * dma->m_ScatterGatherBlockCnt;
702 54 v.karak
        printk("%s(): SGBlockCnt = %d, SGListSize = %d.\n", __FUNCTION__, dma->m_ScatterGatherBlockCnt, SGListSize);
703 2 dsmv
    }
704
 
705
    SGListMemSize = (SGListSize >= PAGE_SIZE) ? SGListSize : PAGE_SIZE;
706
 
707
    //  выделяем память под список
708
    dma->m_SGTableDscr.SystemAddress = dma_alloc_coherent( dma->m_dev, SGListMemSize, &PhysicalAddress, GFP_KERNEL);
709
    if(!dma->m_SGTableDscr.SystemAddress)
710
    {
711 54 v.karak
        printk("%s(): Not enought memory for scatter/gather list\n", __FUNCTION__);
712 2 dsmv
        return -ENOMEM;
713
    }
714
 
715
    dma->m_SGTableDscr.LogicalAddress = PhysicalAddress;
716
 
717
    // закрепляем список в физической памяти
718
    lock_pages(dma->m_SGTableDscr.SystemAddress, SGListMemSize);
719
 
720
    return 0;
721
}
722
 
723
//-----------------------------------------------------------------------------
724
 
725 54 v.karak
int ReleaseSGList(struct CDmaChannel *dma)
726 2 dsmv
{
727
    u32 SGListMemSize = 0;
728
    u32 SGListSize = 0;
729
 
730 54 v.karak
    if(dma->m_UseCount != 0) {
731
        printk("%s(): Memory may be used in anoether process. m_UseCount = %d\n", __FUNCTION__, dma->m_UseCount);
732
        return -1;
733
    }
734 2 dsmv
 
735 54 v.karak
    printk("%s()\n", __FUNCTION__);
736
 
737
    if(dma->m_idBlockFifo == PE_EXT_FIFO_ID) {
738 2 dsmv
        SGListSize = sizeof(DMA_CHAINING_DESCR_EXT) * DSCR_BLOCK_SIZE * dma->m_ScatterGatherBlockCnt;
739
    }
740
 
741
    SGListMemSize = (SGListSize >= PAGE_SIZE) ? SGListSize : PAGE_SIZE;
742
 
743 54 v.karak
    // освободим страницы списока из физической памяти
744 2 dsmv
    unlock_pages(dma->m_SGTableDscr.SystemAddress, SGListMemSize);
745
 
746
    dma_free_coherent( dma->m_dev, SGListMemSize,
747
                       dma->m_SGTableDscr.SystemAddress,
748
                       dma->m_SGTableDscr.LogicalAddress );
749
 
750
    dma->m_SGTableDscr.SystemAddress = NULL;
751
    dma->m_SGTableDscr.LogicalAddress = 0;
752 54 v.karak
 
753
    return 0;
754 2 dsmv
}
755
 
756
//-----------------------------------------------------------------------------
757
 
758
int StartDmaTransfer(struct CDmaChannel *dma, u32 IsCycling)
759
{
760 54 v.karak
    printk("%s()\n", __FUNCTION__);
761 2 dsmv
 
762
    dma->m_DmaCycling = IsCycling;
763
    dma->m_DoneBlock = -1;
764
    dma->m_DoneFlag = 1;
765
    dma->m_CycleNum     = 0;
766
    dma->m_BlocksRemaining      = dma->m_BlockCount;
767
    dma->m_CurBlockNum = 0;
768
    dma->m_preBlockCount1 = 1;
769
    dma->m_preBlockCount2 = 2;
770
    dma->m_preBlockCount3 = 3;
771
 
772
    if(dma->m_idBlockFifo == PE_EXT_FIFO_ID)
773
    {
774
        u64 *pDscrBuf = NULL;
775
        u32 ctrl_code = ~0;
776
        u16* pDscr = NULL;
777
        int iEntry = 0;
778 54 v.karak
        int ii=0;
779
        DMA_CHAINING_DESCR_EXT  *pSGTEx = dma->m_pScatterGatherTableExt;
780
 
781 2 dsmv
        u32 iLastEntry = dma->m_ScatterGatherTableEntryCnt + dma->m_ScatterGatherBlockCnt - 1;
782
        if(dma->m_ScatterGatherBlockCnt == 1)
783
            dma->m_pScatterGatherTableExt[iLastEntry - 1].Cmd.JumpDescr0 = dma->m_DmaCycling;
784
        else
785
            dma->m_pScatterGatherTableExt[iLastEntry - 1].Cmd.JumpNextBlock = dma->m_DmaCycling;
786
 
787 54 v.karak
        printk("%s(): m_DmaCycling = %d\n", __FUNCTION__, dma->m_DmaCycling);
788 2 dsmv
 
789
        pDscrBuf = (u64*)dma->m_pScatterGatherTableExt + DSCR_BLOCK_SIZE * (dma->m_ScatterGatherBlockCnt - 1);
790
        ctrl_code = 0xFFFFFFFF;
791
        pDscr = (u16*)pDscrBuf;
792
        pDscr[255] = 0;
793
        for(iEntry = 0; iEntry < DSCR_BLOCK_SIZE; iEntry++)
794
        {
795
            u16 data0 = (u16)(pDscrBuf[iEntry] & 0xFFFF);
796
            u16 data1 = (u16)((pDscrBuf[iEntry] >> 16) & 0xFFFF);
797
            u16 data2 = (u16)((pDscrBuf[iEntry] >> 32) & 0xFFFF);
798
            u16 data3 = (u16)((pDscrBuf[iEntry] >> 48) & 0xFFFF);
799
            if(iEntry == DSCR_BLOCK_SIZE-1)
800
            {
801
                ctrl_code = ctrl_code ^ data0 ^ data1 ^ data2 ^ data3;
802 54 v.karak
 
803
                //printk("%s(): DSCR_BLK[%d] - NextBlkAddr = 0x%08X, Signature = 0x%04X, Crc = 0x%04X\n",
804
                //       __FUNCTION__,
805
                //       dma->m_ScatterGatherBlockCnt-1,
806
                //       (u32)(pDscrBuf[iEntry] << 8),
807
                //       (u16)((pDscrBuf[iEntry] >> 32) & 0xFFFF),
808
                //       (u16)ctrl_code);
809
 
810
                printk("%s(): ENTRY[%d] - SIGN = 0x%04X, CRC = 0x%04X\n", __FUNCTION__, iEntry, (u16)((pDscrBuf[iEntry] >> 32) & 0xFFFF), (u16)ctrl_code);
811 2 dsmv
            }
812
            else
813
            {
814
                u32 ctrl_tmp = 0;
815
                ctrl_code = ctrl_code ^ data0 ^ data1 ^ data2 ^ data3;
816
                ctrl_tmp = ctrl_code << 1;
817
                ctrl_tmp |= (ctrl_code & 0x8000) ? 0: 1;
818
                ctrl_code = ctrl_tmp;
819
 
820
                // 3 способа циклического сдвига влево 32-разрядного значения
821
                // (у нас оказалось не совсем то: значение берется 16-разрядное и старший бит при переносе в младший инвертируется)
822
                //_rotl(ctrl_code, 1);
823
                //ctrl_code = (ctrl_code << 1) | (ctrl_code >> 31);
824
                //__asm {
825
                //      rol ctrl_code,1
826
                //}
827
 
828 54 v.karak
                //printk("%s(): %02d(%02d) - PciAddr = 0x%08X, Cmd = 0x%04X, DmaLength = 0x%08X (%02X %02X %02X)\n",
829
                //                                    __FUNCTION__,
830
                //                                    iEntry, dma->m_ScatterGatherBlockCnt-1,
831
                //                                    (u32)(pDscrBuf[iEntry] << 8),
832
                //                                    (u16)(pDscrBuf[iEntry] >> 32),
833
                //                                    (u32)((pDscrBuf[iEntry] >> 41) << 9),
834
                //                                    (u8)(pDscrBuf[iEntry] >> 56), (u8)(pDscrBuf[iEntry] >> 48), (u8)(pDscrBuf[iEntry] >> 40));
835 2 dsmv
            }
836
        }
837
        pDscr[255] |= (u16)ctrl_code;
838 54 v.karak
 
839
        printk("%s(): S/G LIST\n",__FUNCTION__);
840
        for( ii=0; ii<dma->m_ScatterGatherBlockCnt*DSCR_BLOCK_SIZE; ii++ )
841
        {
842
            u32 *ptr=(u32*)&pSGTEx[ii];
843
            printk("%s(): %02d: %08X %08X\n", __FUNCTION__, ii, ptr[1], ptr[0]);
844
        }
845
        printk("%s()\n",__FUNCTION__);
846 2 dsmv
    }
847
 
848
    dma->m_pStub->lastBlock = -1;
849
    dma->m_pStub->totalCounter = 0;
850
    dma->m_pStub->state = STATE_RUN;
851
 
852
    return 0;
853
}
854
 
855
//-----------------------------------------------------------------------------
856
 
857
u32 NextDmaTransfer(struct CDmaChannel *dma)
858
{
859 54 v.karak
    printk("%s(): - last block = %d, cycle counter = %d\n", __FUNCTION__, dma->m_pStub->lastBlock, dma->m_CycleNum);
860 2 dsmv
 
861
    if(dma->m_pStub->lastBlock + 1 >= (long)dma->m_BlockCount)
862
        dma->m_pStub->lastBlock = 0;
863
    else
864
        dma->m_pStub->lastBlock++;
865
 
866
    dma->m_CurBlockNum++;
867
    dma->m_pStub->totalCounter++;
868
    dma->m_BlocksRemaining--;
869
 
870
    tasklet_hi_schedule(&dma->m_Dpc);
871
 
872 54 v.karak
    //printk("%s(): tasklet_hi_schedule()\n", __FUNCTION__);
873
    /*
874 2 dsmv
    if(dma->m_AdjustMode && dma->m_DmaCycling)
875
    {
876
        u32 next_done_blk = (dma->m_DoneBlock == dma->m_BlockCount-1) ? 0 : (dma->m_DoneBlock + 1);
877
        u32 next_cur_blk = ((dma->m_CurBlockNum + 1) >= dma->m_BlockCount) ? ((dma->m_CurBlockNum + 1) - dma->m_BlockCount) : (dma->m_CurBlockNum + 1);
878
        s32 difBlock = next_done_blk - next_cur_blk;
879
 
880
        if(!difBlock)
881
            dma->m_DoneFlag = 0;
882
 
883
        //printk("%s(): DoneBlock = %d, Nextdb = %d, CurBlock = %d, Nextcb = %d, difBlock = %d, DoneFlag = %d\n",
884
        //       __FUNCTION__, dma->m_DoneBlock, next_done_blk, dma->m_CurBlockNum, next_cur_blk, difBlock, dma->m_DoneFlag);
885
    }
886
*/
887
    if(dma->m_BlocksRemaining <= 0 && dma->m_DmaCycling)
888
    {
889
        dma->m_BlocksRemaining = dma->m_BlockCount;
890
        dma->m_CurBlockNum = 0;
891
        dma->m_CycleNum++;
892
    }
893
 
894
    if(dma->m_preBlockCount1+1 == dma->m_BlockCount)
895
    {
896
        dma->m_preBlockCount1 = 0;
897
    } else {
898
        dma->m_preBlockCount1++;
899
    }
900
 
901
    if(dma->m_preBlockCount2+1 == dma->m_BlockCount)
902
    {
903
        dma->m_preBlockCount2 = 0;
904
    } else {
905
        dma->m_preBlockCount2++;
906
    }
907
 
908
    if(dma->m_preBlockCount3+1 == dma->m_BlockCount)
909
    {
910
        dma->m_preBlockCount3 = 0;
911
    } else {
912
        dma->m_preBlockCount3++;
913
    }
914
 
915
 
916
    if(dma->m_AdjustMode && dma->m_DmaCycling)
917
    {
918
        if(((dma->m_preBlockCount3 == 0)&&(dma->m_DoneBlock == -1)) || (dma->m_preBlockCount3 == dma->m_DoneBlock)) {
919
            dma->m_DoneFlag = 0;
920 54 v.karak
            printk("%s(): m_preBlockCount = %d, m_DoneBlock = %d\n", __FUNCTION__, dma->m_preBlockCount3, dma->m_DoneBlock);
921 2 dsmv
        }
922
    }
923
 
924
    return dma->m_DoneFlag;
925
}
926
 
927
//-----------------------------------------------------------------------------
928
 
929
u32 SetDoneBlock(struct CDmaChannel *dma, long numBlk)
930
{
931
    if(numBlk != dma->m_DoneBlock)
932
    {
933
        dma->m_DoneBlock = numBlk;
934
 
935
        if((dma->m_preBlockCount1 != dma->m_DoneBlock) && (dma->m_preBlockCount2 != dma->m_DoneBlock) && (dma->m_preBlockCount3 != dma->m_DoneBlock)) {
936
 
937
            if(dma->m_AdjustMode && dma->m_DmaCycling && !dma->m_DoneFlag)
938
            {
939
                dma->m_DoneFlag = 1;
940
            }
941
        }
942
    }
943
 
944 54 v.karak
    printk("%s(): DoneBlock = %d, DoneFlag = %d\n", __FUNCTION__, dma->m_DoneBlock, dma->m_DoneFlag);
945 2 dsmv
 
946
    return dma->m_DoneFlag;
947
}
948
 
949
//-----------------------------------------------------------------------------
950
 
951
void GetState(struct CDmaChannel *dma, u32 *BlockNum, u32 *BlockNumTotal, u32 *OffsetInBlock, u32 *DmaChanState)
952
{
953 54 v.karak
    //printk("%s(): - last block = %d, cycle counter = %d\n", __FUNCTION__, dma->m_pStub->lastBlock, dma->m_CycleNum);
954 2 dsmv
 
955
    *BlockNum = dma->m_State.lastBlock;
956
    *BlockNumTotal = dma->m_State.totalCounter;
957
    *OffsetInBlock = dma->m_State.offset;// регистр подсчета переданных байт в текущем буфере будет реализован позже
958
    *DmaChanState = dma->m_State.state;
959
}
960
 
961
//-----------------------------------------------------------------------------
962
 
963
void FreezeState(struct CDmaChannel *dma)
964
{
965 54 v.karak
    //printk("%s()\n", __FUNCTION__);
966 2 dsmv
}
967
 
968
//-----------------------------------------------------------------------------
969
 
970
int WaitBlockEndEvent(struct CDmaChannel *dma, u32 msTimeout)
971
{
972
    int status = -ETIMEDOUT;
973
 
974 54 v.karak
    //printk("%s(): DMA%d\n", __FUNCTION__, dma->m_NumberOfChannel);
975 2 dsmv
 
976
    if( msTimeout < 0 ) {
977
        status = GrabEvent( &dma->m_BlockEndEvent, -1 );
978
    } else {
979
        status = GrabEvent( &dma->m_BlockEndEvent, msTimeout );
980
    }
981
    return status;
982
}
983
 
984
//-----------------------------------------------------------------------------
985
 
986
int WaitBufferEndEvent(struct CDmaChannel *dma, u32 msTimeout)
987
{
988
    int status = -ETIMEDOUT;
989
 
990 54 v.karak
    //printk("%s(): DMA%d\n", __FUNCTION__, dma->m_NumberOfChannel);
991 2 dsmv
 
992
    if( msTimeout < 0 ) {
993
        status = GrabEvent( &dma->m_BufferEndEvent, -1 );
994
    } else {
995
        status = GrabEvent( &dma->m_BufferEndEvent, msTimeout );
996
    }
997
 
998
    return status;
999
}
1000
 
1001
//-----------------------------------------------------------------------------
1002
 
1003
int CompleteDmaTransfer(struct CDmaChannel *dma)
1004
{
1005 54 v.karak
    //printk("%s(): DMA%d\n", __FUNCTION__, dma->m_NumberOfChannel);
1006 2 dsmv
    dma->m_pStub->state = STATE_STOP;
1007
    return 0;
1008
}
1009
 
1010
//-----------------------------------------------------------------------------
1011
 
1012
void GetSGStartParams(struct CDmaChannel *dma, u64 *SGTableAddress, u32 *LocalAddress, u32 *DmaDirection)
1013
{
1014
    if(dma->m_idBlockFifo == PE_EXT_FIFO_ID)
1015
    {
1016
        *SGTableAddress = dma->m_SGTableDscr.LogicalAddress;
1017
    }
1018
 
1019
    *LocalAddress = dma->m_DmaLocalAddress;
1020
    *DmaDirection = dma->m_DmaDirection;
1021
}
1022
 
1023
//-----------------------------------------------------------------------------
1024
 
1025
void GetStartParams(struct CDmaChannel *dma, u32 *PciAddress, u32 *LocalAddress, u32 *DmaLength)
1026
{
1027
    // возвращает адрес и размер DMA из первого элемента таблицы
1028
    if(dma->m_idBlockFifo == PE_EXT_FIFO_ID)
1029
    {
1030
        u64 *pDscrBuf = (u64*)dma->m_pScatterGatherTableExt;
1031
        *PciAddress = (u32)(pDscrBuf[0] << 16);
1032
        *DmaLength = (u32)((pDscrBuf[0] >> 40) << 8);
1033
    }
1034
    *LocalAddress = dma->m_DmaLocalAddress;
1035
}
1036
 
1037
//-----------------------------------------------------------------------------
1038
 
1039
void Adjust(struct CDmaChannel *dma, u32 mode)
1040
{
1041 54 v.karak
    //printk("%s()\n", __FUNCTION__);
1042 2 dsmv
    dma->m_AdjustMode = mode;
1043
}
1044
 
1045
//-----------------------------------------------------------------------------
1046
 
1047
void SetAdmTetr(struct CDmaChannel *dma, u32 AdmNum, u32 TetrNum)
1048
{
1049 54 v.karak
    //printk("%s()\n", __FUNCTION__);
1050 2 dsmv
    dma->m_AdmNum = AdmNum;
1051
    dma->m_TetrNum = TetrNum;
1052
}
1053
 
1054
//-----------------------------------------------------------------------------
1055
 
1056
void SetDmaLocalAddress(struct CDmaChannel *dma, u32 Address)
1057
{
1058 54 v.karak
    //printk("%s()\n", __FUNCTION__);
1059 2 dsmv
    dma->m_DmaLocalAddress = Address;
1060
}
1061
 
1062
//-----------------------------------------------------------------------------
1063
 
1064
int SetDmaDirection(struct CDmaChannel *dma, u32 DmaDirection)
1065
{
1066 54 v.karak
    printk("%s()\n", __FUNCTION__);
1067 2 dsmv
    switch(DmaDirection)
1068
    {
1069
    case 1:
1070
        dma->m_DmaDirection = TRANSFER_DIR_FROM_DEVICE;
1071
        break;
1072
    case 2:
1073
        dma->m_DmaDirection = TRANSFER_DIR_TO_DEVICE;
1074
        break;
1075
    default:
1076
        return -EINVAL;
1077
    }
1078
 
1079
    return 0;
1080
}
1081
 
1082
//-----------------------------------------------------------------------------
1083
 
1084
u32 GetAdmNum(struct CDmaChannel *dma)
1085
{
1086
    return dma->m_AdmNum;
1087
}
1088
 
1089
//-----------------------------------------------------------------------------
1090
 
1091
u32 GetTetrNum(struct CDmaChannel *dma)
1092
{
1093
    return dma->m_TetrNum;
1094
}
1095
 
1096
//-----------------------------------------------------------------------------
1097 54 v.karak
/*
1098 2 dsmv
void DmaDpcForIsr( unsigned long Context )
1099
{
1100
    struct CDmaChannel *DmaChannel = (struct CDmaChannel *)Context;
1101
    unsigned long flags = 0;
1102
 
1103
    spin_lock_irqsave(&DmaChannel->m_DmaLock, flags);
1104
 
1105 54 v.karak
    printk("%s(): [DMA%d] m_CurBlockNum = %d, m_BlockCount = %d\n",
1106
           __FUNCTION__, DmaChannel->m_NumberOfChannel, DmaChannel->m_CurBlockNum, DmaChannel->m_BlockCount );
1107 9 v.karak
    DmaChannel->m_State = *DmaChannel->m_pStub;
1108 2 dsmv
 
1109
    SetEvent( &DmaChannel->m_BlockEndEvent );
1110
 
1111
    if(DmaChannel->m_CurBlockNum >= DmaChannel->m_BlockCount)
1112
    {
1113
        HwCompleteDmaTransfer(DmaChannel->m_Board,DmaChannel->m_NumberOfChannel);
1114
        SetEvent( &DmaChannel->m_BufferEndEvent );
1115 54 v.karak
        wake_up_interruptible(&DmaChannel->m_DmaWq);
1116
        printk("%s(): Wake up!\n", __FUNCTION__);
1117 2 dsmv
    }
1118
 
1119
    spin_unlock_irqrestore(&DmaChannel->m_DmaLock, flags);
1120
}
1121 54 v.karak
*/

powered by: WebSVN 2.1.0

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