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 2

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

powered by: WebSVN 2.1.0

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