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/] [ioctlrw.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/pagemap.h>
9
#include <linux/interrupt.h>
10
#include <linux/proc_fs.h>
11
//#include <linux/atomic.h>
12
#include <asm/io.h>
13
 
14
#include "pexmodule.h"
15
#include "pexioctl.h"
16
#include "hardware.h"
17
#include "ambpexregs.h"
18 6 v.karak
#include "brd_info.h"
19 2 dsmv
 
20
//--------------------------------------------------------------------
21
 
22
int ioctl_board_info(struct pex_device *brd, unsigned long arg)
23
{
24
    struct board_info bi;
25
    int error = 0;
26
 
27
    down(&brd->m_BoardSem);
28
 
29
    dbg_msg(dbg_trace, "%s(): get board information\n", __FUNCTION__);
30
 
31
    memset(&bi, 0, sizeof(struct board_info));
32
 
33
    bi.PhysAddress[0] = brd->m_BAR0.physical_address;
34
    bi.VirtAddress[0] = brd->m_BAR0.virtual_address;
35
    bi.Size[0] = brd->m_BAR0.size;
36
 
37
    bi.PhysAddress[1] = brd->m_BAR1.physical_address;
38
    bi.VirtAddress[1] = brd->m_BAR1.virtual_address;
39
    bi.Size[1] = brd->m_BAR1.size;
40
 
41
    bi.InterruptLevel = 0;
42
    bi.InterruptVector = brd->m_Interrupt;
43
    bi.vendor_id = brd->m_pci->vendor;
44
    bi.device_id = brd->m_pci->device;
45
 
46
    if(copy_to_user((void*)arg, &bi, sizeof(struct board_info))) {
47
        err_msg(err_trace, "%s(): Error copy board info to user space\n", __FUNCTION__);
48
        error = -EINVAL;
49
    }
50
 
51
    up(&brd->m_BoardSem);
52
 
53
    return error;
54
}
55
 
56
//--------------------------------------------------------------------
57
 
58
int ioctl_memory_alloc(struct pex_device *brd, unsigned long arg)
59
{
60
    struct memory_block mb = {0};
61
    dma_addr_t dma_handle = {0};
62
    int error = 0;
63
    int i = 0;
64
 
65
    down(&brd->m_BoardSem);
66
 
67
    if(copy_from_user((void*)&mb, (void*)arg, sizeof(struct memory_block))) {
68
        err_msg(err_trace, "%s(): Error copy block descriptor from user space\n", __FUNCTION__);
69
        error = -EINVAL;
70
        goto do_exit;
71
    }
72
 
73
    if(mb.size == 0) {
74
        err_msg(err_trace, "%s(): Invalid block size.\n", __FUNCTION__);
75
        goto do_exit;
76
    }
77
 
78
    mb.virt = allocate_memory_block(brd, mb.size, &dma_handle);
79
        if(!mb.virt) {
80
            err_msg(err_trace, "%s(): Error allocate block %d.\n", __FUNCTION__, i);
81
            error = -ENOMEM;
82
            goto do_exit;
83
        }
84
        mb.phys = dma_handle;
85
 
86
    if(copy_to_user((void*)arg, &mb, sizeof(struct memory_block))) {
87
        err_msg(err_trace, "%s(): Error copy block descriptor to user space\n", __FUNCTION__);
88
        error = -EINVAL;
89
    }
90
 
91
do_exit:
92
    up(&brd->m_BoardSem);
93
 
94
    return error;
95
}
96
 
97
//--------------------------------------------------------------------
98
 
99
int ioctl_memory_free(struct pex_device *brd, unsigned long arg)
100
{
101
    struct memory_block mb = {0};
102
    int error = 0;
103
    int i = 0;
104
 
105
    down(&brd->m_BoardSem);
106
 
107
    if(copy_from_user((void*)&mb, (void*)arg, sizeof(struct memory_block))) {
108
        err_msg(err_trace, "%s(): Error copy block descriptor from user space\n", __FUNCTION__);
109
        error = -EINVAL;
110
        goto do_exit;
111
    }
112
 
113
    if(mb.size == 0 || mb.phys == 0 || mb.virt == 0) {
114
        err_msg(err_trace, "%s(): Invalid block parameters.\n", __FUNCTION__);
115
        goto do_exit;
116
    }
117
 
118
    error = free_memory_block(brd, mb);
119
    if(error < 0) {
120
        err_msg(err_trace, "%s(): Error free block %d.\n", __FUNCTION__, i);
121
        goto do_exit;
122
    }
123
 
124
do_exit:
125
    up(&brd->m_BoardSem);
126
 
127
    return error;
128
}
129
 
130
//--------------------------------------------------------------------
131
 
132
int ioctl_stub_alloc(struct pex_device *brd, unsigned long arg)
133
{
134
/*
135
    struct stub_descriptor stub = {0};
136
    struct dma_channel *dma = NULL;
137
    void *cpu_addr = NULL;
138
    dma_addr_t dma_handle = {0};
139
    int locked = 0;
140
    int error = -EINVAL;
141
 
142
    down(&brd->m_BoardSem);
143
 
144
    if(copy_from_user((void*)&stub, (void*)arg, sizeof(struct stub_descriptor))) {
145
        err_msg(err_trace, "%s(): Error copy stub descriptor from user space\n", __FUNCTION__);
146
        error = -EINVAL;
147
        goto do_exit;
148
    }
149
 
150
    if(stub.dma_channel >= MAX_NUMBER_OF_DMACHANNELS) {
151
        err_msg(err_trace, "%s(): Invalid DMA channel number.\n", __FUNCTION__);
152
        error = -EINVAL;
153
        goto do_exit;
154
    }
155
 
156
    dma = &brd->m_DMA[stub.dma_channel];
157
 
158
    spin_lock(&dma->m_MemListLock);
159
 
160
    cpu_addr = dma_alloc_coherent(&dma->m_pci->dev, PAGE_SIZE, &dma_handle, GFP_KERNEL);
161
    if(!cpu_addr) {
162
        err_msg(err_trace, "%s(): Error allocate physical memory for stub.\n", __FUNCTION__);
163
        error = -ENOMEM;
164
        goto do_unlock;
165
    }
166
 
167
    dma->m_MemStub.dma_handle = dma_handle;
168
    dma->m_MemStub.cpu_addr = cpu_addr;
169
    dma->m_MemStub.size = PAGE_SIZE;
170
 
171
    stub.stub.phys = dma_handle;
172
    stub.stub.size = PAGE_SIZE;
173
    stub.stub.virt = NULL;
174
 
175
    locked = lock_pages(dma->m_MemStub.cpu_addr, dma->m_MemStub.size);
176
 
177
    dbg_msg(dbg_trace, "%s(): PA = 0x%zx, VA = %p, SZ = 0x%zx, PAGES = %d\n",
178
            __FUNCTION__, (size_t)dma->m_MemStub.dma_handle, dma->m_MemStub.cpu_addr, dma->m_MemStub.size, locked );
179
 
180
    if(copy_to_user((void*)arg, &stub, sizeof(struct stub_descriptor))) {
181
        err_msg(err_trace, "%s(): Error copy stub descriptor to user space\n", __FUNCTION__);
182
        error = -EINVAL;
183
        goto do_free_mem;
184
    }
185
 
186
    spin_unlock(&dma->m_MemListLock);
187
 
188
    return 0;
189
 
190
do_free_mem:
191
    dma_free_coherent(&dma->m_pci->dev, PAGE_SIZE, cpu_addr, dma_handle);
192
 
193
do_unlock:
194
    spin_unlock(&dma->m_MemListLock);
195
 
196
do_exit:
197
    up(&brd->m_BoardSem);
198
 
199
    return error;
200
*/
201
    return -ENOSYS;
202
}
203
 
204
//--------------------------------------------------------------------
205
 
206
int ioctl_stub_free(struct pex_device *brd, unsigned long arg)
207
{
208
    down(&brd->m_BoardSem);
209
 
210
    dbg_msg(err_trace, "%s(): ioctl not implemented.\n", __FUNCTION__);
211
 
212
    up(&brd->m_BoardSem);
213
 
214
    return -ENOSYS;
215
}
216
 
217
//--------------------------------------------------------------------
218
 
219
int ioctl_set_mem(struct pex_device *brd, unsigned long arg)
220
{
221
    int error = 0;
222
    u32 i = 0;
223
    u32 AdmNumber = 0;
224
    u32 TetrNumber = 0;
225
    u32 Address = 0;
226
    u32 tmpSize = 0;
227
    struct CDmaChannel *dma = NULL;
228
    AMB_MEM_DMA_CHANNEL MemDscr = {0};
229
    PAMB_MEM_DMA_CHANNEL pKernMemDscr = NULL;
230
    PAMB_MEM_DMA_CHANNEL pUserMemDscr = &MemDscr;
231
 
232
    down(&brd->m_BoardSem);
233
 
234
    dbg_msg(dbg_trace, "%s(): Started\n", __FUNCTION__);
235
 
236
    if( copy_from_user((void *)pUserMemDscr, (void *)arg, sizeof(AMB_MEM_DMA_CHANNEL))) {
237
        err_msg(err_trace, "%s(): Error copy descriptor from user space\n", __FUNCTION__);
238
        error = -EFAULT;
239
        goto do_exit;
240
    }
241
 
242
    tmpSize = sizeof(AMB_MEM_DMA_CHANNEL)+(pUserMemDscr->BlockCnt-1)*sizeof(void*);
243
 
244
    pKernMemDscr = kzalloc(tmpSize, GFP_KERNEL);
245
    if(!pKernMemDscr) {
246
        err_msg(err_trace, "%s(): Error allocate descriptor in kernel space\n", __FUNCTION__);
247
        error = -ENOMEM;
248
        goto do_free_mem;
249
    }
250
 
251
    memcpy(pKernMemDscr, pUserMemDscr, tmpSize);
252
 
253
    if(pKernMemDscr->DmaChanNum >= MAX_NUMBER_OF_DMACHANNELS) {
254
        err_msg(err_trace, "%s(): Invalid DMA channel number\n", __FUNCTION__);
255
        error = -EINVAL;
256
        goto do_free_mem;
257
    }
258
 
259
    if(!(brd->m_DmaChanMask & (1 << pKernMemDscr->DmaChanNum))) {
260
        err_msg(err_trace, "%s(): Invalid stream number\n", __FUNCTION__);
261
        error = -EINVAL;
262
        goto do_free_mem;
263
    }
264
 
265
    i = pKernMemDscr->DmaChanNum;
266
    dma = brd->m_DmaChannel[i];
267
 
268
    dbg_msg(dbg_trace, "%s(): 1\n", __FUNCTION__);
269
 
270
    error = SetDmaDirection(dma, pKernMemDscr->Direction);
271
    if(error != 0) {
272
        err_msg(err_trace, "%s(): Error in SetDmaDirection()\n", __FUNCTION__);
273
        error = -EINVAL;
274
        goto do_free_mem;
275
    }
276
 
277
    dbg_msg(dbg_trace, "%s(): 2\n", __FUNCTION__);
278
 
279
    Adjust(dma,0);
280
 
281
    dbg_msg(dbg_trace, "%s(): 3\n", __FUNCTION__);
282
 
283
    pKernMemDscr->BlockSize = (pKernMemDscr->BlockSize >> 12) << 12;
284
    if(!pKernMemDscr->BlockSize) {
285
        err_msg(err_trace, "%s(): BlockSize is zero\n", __FUNCTION__);
286
        error = -EINVAL;
287
        goto do_free_mem;
288
    }
289
 
290
    AdmNumber = pKernMemDscr->LocalAddr >> 16;
291
    TetrNumber = pKernMemDscr->LocalAddr & 0xff;
292
    Address = AdmNumber*ADM_SIZE + TetrNumber*TETRAD_SIZE + TRDadr_DATA*REG_SIZE;
293
 
294 54 v.karak
    SetDmaLocalAddress(dma, Address);
295
    SetAdmTetr(dma, AdmNumber, TetrNumber);
296
    error = SetDmaMode(brd, i, AdmNumber, TetrNumber);
297 2 dsmv
 
298
    dbg_msg(dbg_trace, "%s(): 4\n", __FUNCTION__);
299
 
300
    error = RequestMemory( dma, pKernMemDscr->pBlock, pKernMemDscr->BlockSize,
301
                            (u32*)&pKernMemDscr->BlockCnt, &pKernMemDscr->pStub, pKernMemDscr->MemType );
302
    if(error < 0) {
303
        err_msg(err_trace, "%s(): Error in RequestMemory()\n", __FUNCTION__);
304
        error = -ENOMEM;
305
        goto do_free_mem;
306
    }
307
 
308
    dbg_msg(dbg_trace, "%s(): 5\n", __FUNCTION__);
309
 
310
    if(copy_to_user((void*)arg, (void*)pKernMemDscr, tmpSize)) {
311
        err_msg(err_trace, "%s(): Error copy descriptor to user space\n", __FUNCTION__);
312
        error = -EFAULT;
313
    }
314
 
315
do_free_mem:
316
    kfree(pKernMemDscr);
317
 
318
do_exit:
319
    up(&brd->m_BoardSem);
320
 
321
    return error;
322
}
323
 
324
//--------------------------------------------------------------------
325
 
326
int ioctl_free_mem(struct pex_device *brd, size_t arg)
327
{
328
    int error = 0;
329
    AMB_MEM_DMA_CHANNEL MemDscr = {0};
330
    PAMB_MEM_DMA_CHANNEL pMemDscr = &MemDscr;
331
 
332
    down(&brd->m_BoardSem);
333
 
334
    if( copy_from_user((void *)pMemDscr, (void *)arg, sizeof(AMB_MEM_DMA_CHANNEL))) {
335
        err_msg(err_trace, "%s(): Error copy descriptor from user space\n", __FUNCTION__);
336
        error = -EFAULT;
337
        goto do_exit;
338
    }
339
 
340
    if(pMemDscr->DmaChanNum >= MAX_NUMBER_OF_DMACHANNELS) {
341
        err_msg(err_trace, "%s(): Invalid DMA channel number\n", __FUNCTION__);
342
        error = -EINVAL;
343
        goto do_exit;
344
    }
345
 
346 54 v.karak
    error = ReleaseMemory(brd->m_DmaChannel[pMemDscr->DmaChanNum]);
347 2 dsmv
 
348 54 v.karak
    //if(copy_to_user (( void *)arg, (void *)&MemDscr, sizeof(AMB_MEM_DMA_CHANNEL) + (pMemDscr->BlockCnt - 1) * sizeof(void*) )) {
349
    //    err_msg(err_trace, "%s(): Error copy descriptor to user space\n", __FUNCTION__);
350
    //    error = -EFAULT;
351
    //    goto do_exit;
352
    //}
353 2 dsmv
 
354
do_exit:
355
    up(&brd->m_BoardSem);
356
 
357
    return error;
358
}
359
 
360
//--------------------------------------------------------------------
361
 
362
int ioctl_start_mem(struct pex_device *brd, size_t arg)
363
{
364
    int Status = -EINVAL;
365
    AMB_START_DMA_CHANNEL StartDscr;
366
    PAMB_START_DMA_CHANNEL pStartDscr = &StartDscr;
367
 
368 54 v.karak
    printk("%s(): Entered.\n", __FUNCTION__);
369 2 dsmv
    down(&brd->m_BoardSem);
370
 
371
    if( copy_from_user((void *)&StartDscr, (void *)arg, sizeof(AMB_START_DMA_CHANNEL))) {
372
        err_msg(err_trace, "%s(): Error copy data from userspace\n", __FUNCTION__ );
373
        up(&brd->m_BoardSem);
374
        return -EFAULT;
375
    }
376
 
377
    if(pStartDscr->DmaChanNum >= MAX_NUMBER_OF_DMACHANNELS) {
378 54 v.karak
        printk("%s(): too large stream number\n", __FUNCTION__);
379 2 dsmv
        up(&brd->m_BoardSem);
380
        return -EINVAL;
381
    }
382
 
383
    if(!(brd->m_DmaChanMask & (1 << pStartDscr->DmaChanNum))) {
384 54 v.karak
        printk("%s(): invalid stream number\n", __FUNCTION__);
385 2 dsmv
        up(&brd->m_BoardSem);
386
        return -EINVAL;
387
    }
388
 
389
    Status = StartDmaTransfer(brd->m_DmaChannel[pStartDscr->DmaChanNum], pStartDscr->IsCycling);
390
    Status = HwStartDmaTransfer(brd, pStartDscr->DmaChanNum);
391
 
392
    up(&brd->m_BoardSem);
393 54 v.karak
    printk("%s(): exit Status=0x%.8X \n", __FUNCTION__, Status);
394 2 dsmv
 
395
    return Status;
396
}
397
 
398
//--------------------------------------------------------------------
399
 
400
int ioctl_stop_mem(struct pex_device *brd, size_t arg)
401
{
402
    int Status = -EINVAL;
403
    u32 i;
404
    AMB_STATE_DMA_CHANNEL StopDscr;
405
    PAMB_STATE_DMA_CHANNEL pStopDscr = &StopDscr;
406
 
407
    down(&brd->m_BoardSem);
408
 
409
    // get the user buffer
410
    if( copy_from_user((void *)&StopDscr, (void *)arg, sizeof(AMB_STATE_DMA_CHANNEL))) {
411
        err_msg(err_trace, "%s(): Error copy data from userspace\n", __FUNCTION__ );
412
        up(&brd->m_BoardSem);
413
        return -EFAULT;
414
    }
415
 
416 54 v.karak
    //printk("%s()\n", __FUNCTION__);
417 2 dsmv
 
418
    if(pStopDscr->DmaChanNum >= MAX_NUMBER_OF_DMACHANNELS)
419
    {
420 54 v.karak
        printk("IoctlStopMem: too large stream number\n");
421 2 dsmv
        up(&brd->m_BoardSem);
422
        return -EINVAL;
423
    }
424
 
425
    i = pStopDscr->DmaChanNum;
426
    if(pStopDscr->Timeout)
427
        Status = WaitBlockEndEvent(brd->m_DmaChannel[i], pStopDscr->Timeout);
428
    else
429
        Status = 0;
430
    /*
431
        PIRP CurrentIrp = m_DmaChannel[i].GetQueueIrp();
432
        if(CurrentIrp)
433
                CancelIrp(CurrentIrp, WambpIrpCancelCallback);
434
*/
435
    HwCompleteDmaTransfer(brd, i);
436
    //FreezeState(brd->m_DmaChannel[i]);
437
    GetState( brd->m_DmaChannel[i], (u32*)&pStopDscr->BlockNum,
438
              (u32*)&pStopDscr->BlockCntTotal, (u32*)&pStopDscr->OffsetInBlock,
439
              (u32*)&pStopDscr->DmaChanState);
440
 
441
    if(copy_to_user (( void *)arg, (void *)&StopDscr, sizeof(AMB_STATE_DMA_CHANNEL))) {
442
        err_msg(err_trace, "%s(): Error copy data to userspace\n", __FUNCTION__ );
443
        up(&brd->m_BoardSem);
444
        return -EFAULT;
445
    }
446
 
447
    up(&brd->m_BoardSem);
448
 
449
    return Status;
450
}
451
 
452
//--------------------------------------------------------------------
453
 
454
int ioctl_state_mem(struct pex_device *brd, size_t arg)
455
{
456
    int Status = -EINVAL;
457
    u32 i=0;
458
    AMB_STATE_DMA_CHANNEL StateDscr;
459
    PAMB_STATE_DMA_CHANNEL pStateDscr = &StateDscr;
460
 
461
    down(&brd->m_BoardSem);
462
 
463
    // get the user buffer
464
    if( copy_from_user((void *)&StateDscr, (void *)arg, sizeof(AMB_STATE_DMA_CHANNEL))) {
465
        err_msg(err_trace, "%s(): Error copy data from userspace\n", __FUNCTION__ );
466
        up(&brd->m_BoardSem);
467
        return -EFAULT;
468
    }
469
 
470 54 v.karak
    //printk("%s()\n", __FUNCTION__);
471 2 dsmv
 
472
    if(pStateDscr->DmaChanNum >= MAX_NUMBER_OF_DMACHANNELS)
473
    {
474 54 v.karak
        printk("IoctlStateMem: too large stream number\n");
475 2 dsmv
        up(&brd->m_BoardSem);
476
        return -EINVAL;
477
    }
478
 
479
    i = pStateDscr->DmaChanNum;
480
    if(pStateDscr->Timeout)
481
        Status = WaitBlockEndEvent(brd->m_DmaChannel[i], pStateDscr->Timeout);
482
    else
483
        Status = 0;
484
 
485
    //FreezeState(brd->m_DmaChannel[i]);
486
    GetState(brd->m_DmaChannel[i],      (u32*)&pStateDscr->BlockNum,
487
             (u32*)&pStateDscr->BlockCntTotal,
488
             (u32*)&pStateDscr->OffsetInBlock,
489
             (u32*)&pStateDscr->DmaChanState);
490
 
491
    if(copy_to_user (( void *)arg, (void *)&StateDscr, sizeof(AMB_STATE_DMA_CHANNEL))) {
492
        err_msg(err_trace, "%s(): Error copy data to userspace\n", __FUNCTION__ );
493
        up(&brd->m_BoardSem);
494
        return -EFAULT;
495
    }
496
 
497
    up(&brd->m_BoardSem);
498
 
499
    return Status;
500
}
501
 
502
//--------------------------------------------------------------------
503
 
504
int ioctl_set_dir_mem(struct pex_device *brd, size_t arg)
505
{
506
    int Status = -EINVAL;
507
    u32 i;
508
    AMB_SET_DMA_CHANNEL MemDscr;
509
    PAMB_SET_DMA_CHANNEL pMemDscr = &MemDscr;
510
 
511 54 v.karak
    printk("%s()\n", __FUNCTION__);
512 2 dsmv
    down(&brd->m_BoardSem);
513
 
514
    // get the user buffer
515
    if( copy_from_user((void *)&MemDscr, (void *)arg, sizeof(AMB_SET_DMA_CHANNEL))) {
516
        err_msg(err_trace, "%s(): Error copy data from userspace\n", __FUNCTION__ );
517
        up(&brd->m_BoardSem);
518
        return -EFAULT;
519
    }
520
 
521
    if(pMemDscr->DmaChanNum >= MAX_NUMBER_OF_DMACHANNELS)
522
    {
523 54 v.karak
        printk("%s(): too large stream number\n", __FUNCTION__);
524 2 dsmv
        up(&brd->m_BoardSem);
525
        return -EINVAL;
526
    }
527
 
528
    i = pMemDscr->DmaChanNum;
529
    Status = SetDmaDirection(brd->m_DmaChannel[i], pMemDscr->Param);
530
 
531
    up(&brd->m_BoardSem);
532
 
533
    return Status;
534
}
535
 
536
//--------------------------------------------------------------------
537
 
538
int ioctl_set_src_mem(struct pex_device *brd, size_t arg)
539
{
540
    int Status = -EINVAL;
541
    u32 i;
542
    u32 AdmNumber = 0;
543
    u32 TetrNumber = 0;
544
    u32 Address = 0;
545
    AMB_SET_DMA_CHANNEL MemDscr;
546
    PAMB_SET_DMA_CHANNEL pMemDscr = &MemDscr;
547
 
548 54 v.karak
    printk("%s()\n", __FUNCTION__);
549 2 dsmv
    down(&brd->m_BoardSem);
550
 
551
    // get the user buffer
552
    if( copy_from_user((void *)&MemDscr, (void *)arg, sizeof(AMB_SET_DMA_CHANNEL))) {
553
        err_msg(err_trace, "%s(): Error copy data from userspace\n", __FUNCTION__ );
554
        up(&brd->m_BoardSem);
555
        return -EFAULT;
556
    }
557
 
558
    if(pMemDscr->DmaChanNum >= MAX_NUMBER_OF_DMACHANNELS)
559
    {
560 54 v.karak
        printk("%s(): too large stream number\n", __FUNCTION__);
561 2 dsmv
        up(&brd->m_BoardSem);
562
        return -EINVAL;
563
    }
564
 
565
    i = pMemDscr->DmaChanNum;
566 54 v.karak
    AdmNumber = pMemDscr->Param >> 16;
567
    TetrNumber = pMemDscr->Param & 0xff;
568
    Address = AdmNumber * ADM_SIZE + TetrNumber * TETRAD_SIZE + TRDadr_DATA * REG_SIZE;
569 2 dsmv
    SetDmaLocalAddress(brd->m_DmaChannel[i], Address);
570
    SetAdmTetr(brd->m_DmaChannel[i], AdmNumber, TetrNumber);
571 54 v.karak
    Status = SetDmaMode(brd, i, AdmNumber, TetrNumber);
572 2 dsmv
 
573
    up(&brd->m_BoardSem);
574
 
575
    return Status;
576
}
577
 
578
//--------------------------------------------------------------------
579
 
580
int ioctl_set_drq_mem(struct pex_device *brd, size_t arg)
581
{
582
    int Status = -EINVAL;
583
    u32 i;
584
    u32 AdmNum = 0;
585
    u32 TetrNum = 0;
586
    AMB_SET_DMA_CHANNEL MemDscr;
587
    PAMB_SET_DMA_CHANNEL pMemDscr = &MemDscr;
588
 
589
    down(&brd->m_BoardSem);
590
 
591 54 v.karak
    //printk("%s()\n", __FUNCTION__);
592 2 dsmv
 
593
    // get the user buffer
594
    if( copy_from_user((void *)&MemDscr, (void *)arg, sizeof(AMB_SET_DMA_CHANNEL))) {
595
        err_msg(err_trace, "%s(): Error copy data from userspace\n", __FUNCTION__ );
596
        up(&brd->m_BoardSem);
597
        return -EFAULT;
598
    }
599
 
600
    if(pMemDscr->DmaChanNum >= MAX_NUMBER_OF_DMACHANNELS)
601
    {
602 54 v.karak
        printk("IoctlSetDrqMem: too large stream number\n");
603 2 dsmv
        up(&brd->m_BoardSem);
604
        return -EINVAL;
605
    }
606
 
607
    i = pMemDscr->DmaChanNum;
608
    AdmNum = GetAdmNum( brd->m_DmaChannel[i] );
609
    TetrNum = GetTetrNum( brd->m_DmaChannel[i] );
610
    Status = SetDrqFlag( brd, AdmNum, TetrNum, pMemDscr->Param );
611
 
612
    up(&brd->m_BoardSem);
613
 
614
    return Status;
615
}
616
 
617
//--------------------------------------------------------------------
618
 
619
int ioctl_adjust(struct pex_device *brd, size_t arg)
620
{
621
    u32 i;
622
    AMB_SET_DMA_CHANNEL MemDscr;
623
    PAMB_SET_DMA_CHANNEL pMemDscr = &MemDscr;
624
 
625
    down(&brd->m_BoardSem);
626
 
627 54 v.karak
    //printk("%s()\n", __FUNCTION__);
628 2 dsmv
 
629
    if( copy_from_user((void *)&MemDscr, (void *)arg, sizeof(AMB_SET_DMA_CHANNEL))) {
630
        err_msg(err_trace, "%s(): Error copy data from userspace\n", __FUNCTION__ );
631
        up(&brd->m_BoardSem);
632
        return -EFAULT;
633
    }
634
 
635
    if(pMemDscr->DmaChanNum >= MAX_NUMBER_OF_DMACHANNELS)
636
    {
637 54 v.karak
        printk("IoctlSetDrqMem: too large stream number\n");
638 2 dsmv
        up(&brd->m_BoardSem);
639
        return -EINVAL;
640
    }
641
    if(!(brd->m_DmaChanMask & (1 << pMemDscr->DmaChanNum)))
642
    {
643 54 v.karak
        printk("%s(): invalid stream number\n", __FUNCTION__);
644 2 dsmv
        up(&brd->m_BoardSem);
645
        return -EINVAL;
646
    }
647
 
648
    i = pMemDscr->DmaChanNum;
649
    Adjust(brd->m_DmaChannel[i], pMemDscr->Param);
650
 
651
    up(&brd->m_BoardSem);
652
 
653
    return 0;
654
}
655
 
656
//--------------------------------------------------------------------
657
 
658
int ioctl_done(struct pex_device *brd, size_t arg)
659
{
660
    int Status = -EINVAL;
661
    u32 i;
662
    u32 done_flag;
663
    AMB_SET_DMA_CHANNEL MemDscr;
664
    PAMB_SET_DMA_CHANNEL pMemDscr = &MemDscr;
665
 
666
    down(&brd->m_BoardSem);
667
 
668 54 v.karak
    //printk("%s()\n", __FUNCTION__);
669 2 dsmv
 
670
    // get the user buffer
671
    if( copy_from_user((void *)&MemDscr, (void *)arg, sizeof(AMB_SET_DMA_CHANNEL))) {
672
        err_msg(err_trace, "%s(): Error copy data from userspace\n", __FUNCTION__ );
673
        up(&brd->m_BoardSem);
674
        return -EFAULT;
675
    }
676
 
677
    if(pMemDscr->DmaChanNum >= MAX_NUMBER_OF_DMACHANNELS)
678
    {
679 54 v.karak
        printk("IoctlSetDrqMem: too large stream number\n");
680 2 dsmv
        up(&brd->m_BoardSem);
681
        return -EINVAL;
682
    }
683
    if(!(brd->m_DmaChanMask & (1 << pMemDscr->DmaChanNum)))
684
    {
685 54 v.karak
        printk("%s(): invalid stream number\n", __FUNCTION__);
686 2 dsmv
        up(&brd->m_BoardSem);
687
        return -EINVAL;
688
    }
689
 
690
    i = pMemDscr->DmaChanNum;
691
    done_flag = SetDoneBlock(brd->m_DmaChannel[i], pMemDscr->Param);
692
    if(done_flag)
693
        Status = Done(brd, i);
694
 
695
    up(&brd->m_BoardSem);
696
 
697
    return 0;
698
}
699
 
700
//--------------------------------------------------------------------
701
 
702
int ioctl_reset_fifo(struct pex_device *brd, size_t arg)
703
{
704
    int Status = -EINVAL;
705
    AMB_SET_DMA_CHANNEL MemDscr;
706
    PAMB_SET_DMA_CHANNEL pMemDscr = &MemDscr;
707
 
708
    down(&brd->m_BoardSem);
709
 
710
    // get the user buffer
711
    if( copy_from_user((void *)&MemDscr, (void *)arg, sizeof(AMB_SET_DMA_CHANNEL))) {
712
        err_msg(err_trace, "%s(): Error copy data from userspace\n", __FUNCTION__ );
713
        up(&brd->m_BoardSem);
714
        return -EFAULT;
715
    }
716
 
717
    if(pMemDscr->DmaChanNum >= MAX_NUMBER_OF_DMACHANNELS)
718
    {
719 54 v.karak
        printk("%s(): too large stream number\n", __FUNCTION__);
720 2 dsmv
        up(&brd->m_BoardSem);
721
        return -EINVAL;
722
    }
723
    if(!(brd->m_DmaChanMask & (1 << pMemDscr->DmaChanNum)))
724
    {
725 54 v.karak
        printk("%s(): invalid stream number\n", __FUNCTION__);
726 2 dsmv
        up(&brd->m_BoardSem);
727
        return -EINVAL;
728
    }
729
 
730
    Status = ResetFifo(brd, pMemDscr->DmaChanNum);
731
 
732
    up(&brd->m_BoardSem);
733
 
734
    return Status;
735
}
736
 
737
//--------------------------------------------------------------------
738
 
739
int ioctl_get_dma_channel_info(struct pex_device *brd, size_t arg)
740
{
741
    AMB_GET_DMA_INFO DmaInfo = {0};
742
 
743
    down(&brd->m_BoardSem);
744
 
745
    // get the user buffer
746
    if( copy_from_user((void *)&DmaInfo, (void *)arg, sizeof(AMB_GET_DMA_INFO))) {
747
        err_msg(err_trace, "%s(): Error copy data from userspace\n", __FUNCTION__ );
748
        up(&brd->m_BoardSem);
749
        return -EFAULT;
750
    }
751
 
752
    if(DmaInfo.DmaChanNum >= MAX_NUMBER_OF_DMACHANNELS)
753
    {
754 54 v.karak
        printk("%s(): too large stream number\n", __FUNCTION__);
755 2 dsmv
        up(&brd->m_BoardSem);
756
        return -EINVAL;
757
    }
758
    if(!(brd->m_DmaChanMask & (1 << DmaInfo.DmaChanNum)))
759
    {
760 54 v.karak
        printk("%s(): invalid stream number\n", __FUNCTION__);
761 2 dsmv
        up(&brd->m_BoardSem);
762
        return -EINVAL;
763
    }
764
 
765
    DmaInfo.Direction = brd->m_DmaDir[DmaInfo.DmaChanNum];
766
    DmaInfo.FifoSize = brd->m_DmaFifoSize[DmaInfo.DmaChanNum];
767
    DmaInfo.MaxDmaSize = brd->m_MaxDmaSize[DmaInfo.DmaChanNum];
768
 
769
    if(copy_to_user (( void *)arg, (void *)&DmaInfo, sizeof(AMB_GET_DMA_INFO))) {
770
                err_msg(err_trace, "%s(): Error copy data to userspace\n", __FUNCTION__ );
771
        up(&brd->m_BoardSem);
772
        return -EFAULT;
773
    }
774
 
775
    up(&brd->m_BoardSem);
776
 
777
    return 0;
778
}
779
 
780
//--------------------------------------------------------------------
781
 
782
int ioctl_wait_dma_buffer(struct pex_device *brd, size_t arg)
783
{
784
    int Status = -EINVAL;
785
    u32 i=0;
786
    AMB_STATE_DMA_CHANNEL StateDscr;
787
    PAMB_STATE_DMA_CHANNEL pStateDscr = &StateDscr;
788
 
789
    down ( &brd->m_BoardSem );
790
 
791
    // get the user buffer
792
    if( copy_from_user((void *)&StateDscr, (void *)arg, sizeof(AMB_STATE_DMA_CHANNEL))) {
793
                err_msg(err_trace, "%s(): Error copy data from userspace\n", __FUNCTION__ );
794
        up(&brd->m_BoardSem);
795
        return -EFAULT;
796
    }
797
 
798 54 v.karak
    //printk("%s(): DMA %d\n", __FUNCTION__, pStateDscr->DmaChanNum);
799 2 dsmv
 
800
    if(pStateDscr->DmaChanNum >= MAX_NUMBER_OF_DMACHANNELS)
801
    {
802 54 v.karak
        printk("%s(): too large stream number\n", __FUNCTION__);
803 2 dsmv
        up(&brd->m_BoardSem);
804
        return -EINVAL;
805
    }
806
 
807
    i = pStateDscr->DmaChanNum;
808
 
809
    Status = WaitBufferEndEvent(brd->m_DmaChannel[i], pStateDscr->Timeout);
810
 
811
    GetState(brd->m_DmaChannel[i],      (u32*)&pStateDscr->BlockNum,
812
             (u32*)&pStateDscr->BlockCntTotal,
813
             (u32*)&pStateDscr->OffsetInBlock,
814
             (u32*)&pStateDscr->DmaChanState);
815
 
816
    if(copy_to_user (( void *)arg, (void *)&StateDscr, sizeof(AMB_STATE_DMA_CHANNEL))) {
817
                err_msg(err_trace, "%s(): Error copy data to userspace\n", __FUNCTION__ );
818
        up(&brd->m_BoardSem);
819
        return -EFAULT;
820
    }
821
 
822
    up(&brd->m_BoardSem);
823
 
824
    return Status;
825
}
826
 
827
//--------------------------------------------------------------------
828
 
829
int ioctl_wait_dma_block(struct pex_device *brd, size_t arg)
830
{
831
    int Status = -EINVAL;
832
    u32 i=0;
833
    AMB_STATE_DMA_CHANNEL StateDscr;
834
    PAMB_STATE_DMA_CHANNEL pStateDscr = &StateDscr;
835
 
836
    down ( &brd->m_BoardSem );
837
 
838
    // get the user buffer
839
    if( copy_from_user((void *)&StateDscr, (void *)arg, sizeof(AMB_STATE_DMA_CHANNEL))) {
840
        err_msg(err_trace, "%s(): Error copy data from userspace\n", __FUNCTION__ );
841
        up(&brd->m_BoardSem);
842
        return -EFAULT;
843
    }
844
 
845 54 v.karak
    printk("%s(): DMA %d\n", __FUNCTION__, pStateDscr->DmaChanNum);
846 2 dsmv
 
847
    if(pStateDscr->DmaChanNum >= MAX_NUMBER_OF_DMACHANNELS)
848
    {
849 54 v.karak
        printk("%s(): too large stream number\n", __FUNCTION__);
850 2 dsmv
        up(&brd->m_BoardSem);
851
        return -EINVAL;
852
    }
853
 
854
    i = pStateDscr->DmaChanNum;
855
 
856
    Status = WaitBlockEndEvent(brd->m_DmaChannel[i], pStateDscr->Timeout);
857
 
858
    GetState(brd->m_DmaChannel[i],      (u32*)&pStateDscr->BlockNum,
859
             (u32*)&pStateDscr->BlockCntTotal,
860
             (u32*)&pStateDscr->OffsetInBlock,
861
             (u32*)&pStateDscr->DmaChanState);
862
 
863
    if(copy_to_user (( void *)arg, (void *)&StateDscr, sizeof(AMB_STATE_DMA_CHANNEL))) {
864
        err_msg(err_trace, "%s(): Error copy data to userspace\n", __FUNCTION__ );
865
        up(&brd->m_BoardSem);
866
        return -EFAULT;
867
    }
868
 
869
    up(&brd->m_BoardSem);
870
 
871
    return Status;
872
}
873
 
874
//--------------------------------------------------------------------
875
 
876
 
877
 

powered by: WebSVN 2.1.0

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