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 6

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

powered by: WebSVN 2.1.0

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