1 /**********************************************************************
3 * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
4 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
10 * This program is distributed in the hope it will be useful but, except
11 * as otherwise stated in writing, without any warranty; without even the
12 * implied warranty of merchantability or fitness for a particular purpose.
13 * See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
19 * The full GNU General Public License is included in this distribution in
20 * the file called "COPYING".
22 * Contact Information:
23 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
24 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
26 ******************************************************************************/
28 #include <linux/kernel.h>
29 #include <linux/module.h>
31 #include <linux/slab.h>
32 #include <asm/uaccess.h>
35 #include "img_types.h"
36 #include "servicesext.h"
37 #include "kernelbuffer.h"
40 #include <linux/dma-mapping.h>
45 typedef unsigned int IMG_UINT32, *IMG_PUINT32;
46 typedef char IMG_CHAR, *IMG_PCHAR;
47 typedef void IMG_VOID, *IMG_PVOID;
48 typedef IMG_PVOID IMG_HANDLE;
50 typedef IMG_PVOID IMG_CPU_VIRTADDR;
52 typedef struct IMG_SYS_PHYADDR IMG_SYS_PHYADDR;
53 typedef struct IMG_CPU_PHYADDR IMG_CPU_PHYADDR;
54 typedef struct BUFFER_INFO BUFFER_INFO;
55 typedef struct PVRSRV_SYNC_DATA PVRSRV_SYNC_DATA;
56 typedef struct PVRSRV_BC_BUFFER2SRV_KMJTABLE PVRSRV_BC_BUFFER2SRV_KMJTABLE;
57 typedef struct PVRSRV_BC_SRV2BUFFER_KMJTABLE PVRSRV_BC_SRV2BUFFER_KMJTABLE;
58 typedef enum PVRSRV_ERROR PVRSRV_ERROR;
59 typedef enum PVRSRV_PIXEL_FORMAT PVRSRV_PIXEL_FORMAT;
62 #define DEVNAME "bccat"
63 #define DRVNAME DEVNAME
64 #define DEVICE_COUNT 10
66 MODULE_SUPPORTED_DEVICE(DEVNAME);
68 #define unref__ __attribute__ ((unused))
70 typedef struct BC_CAT_BUFFER_TAG
73 IMG_HANDLE hMemHandle;
74 IMG_SYS_PHYADDR sSysAddr;
75 IMG_SYS_PHYADDR sPageAlignSysAddr;
76 IMG_CPU_VIRTADDR sCPUVAddr;
77 PVRSRV_SYNC_DATA *psSyncData;
78 struct BC_CAT_BUFFER_TAG *psNext;
82 typedef struct BC_CAT_DEVINFO_TAG
85 IMG_UINT32 ui32DeviceID;
86 BC_CAT_BUFFER *psSystemBuffer;
87 BUFFER_INFO sBufferInfo;
88 IMG_UINT32 ui32NumBuffers;
89 PVRSRV_BC_BUFFER2SRV_KMJTABLE sPVRJTable;
90 PVRSRV_BC_SRV2BUFFER_KMJTABLE sBCJTable;
91 IMG_HANDLE hPVRServices;
92 IMG_UINT32 ui32RefCount;
93 enum BC_memory buf_type;
97 extern IMG_IMPORT IMG_BOOL PVRGetBufferClassJTable(
98 PVRSRV_BC_BUFFER2SRV_KMJTABLE *psJTable);
100 static int bc_open(struct inode *i, struct file *f);
101 static int bc_release(struct inode *i, struct file *f);
102 static long bc_ioctl(struct file *file,
103 unsigned int cmd, unsigned long arg);
104 static int bc_mmap(struct file *filp, struct vm_area_struct *vma);
106 static int BC_CreateBuffers(int id, bc_buf_params_t *p);
107 static PVRSRV_ERROR BC_DestroyBuffers(int id);
108 static PVRSRV_ERROR BC_Register(int id);
109 static PVRSRV_ERROR BC_Unregister(int id);
111 static PVRSRV_ERROR BCOpenPVRServices(IMG_HANDLE *phPVRServices);
112 static PVRSRV_ERROR BCClosePVRServices(IMG_HANDLE hPVRServices);
114 static IMG_VOID *BCAllocKernelMem(IMG_UINT32 ui32Size);
115 static IMG_VOID BCFreeKernelMem(IMG_VOID *pvMem);
117 static PVRSRV_ERROR BCAllocContigMemory(IMG_UINT32 ui32Size,
118 IMG_HANDLE * phMemHandle,
119 IMG_CPU_VIRTADDR *pLinAddr,
120 IMG_CPU_PHYADDR *pPhysAddr);
121 static IMG_VOID BCFreeContigMemory(IMG_UINT32 ui32Size,
122 IMG_HANDLE hMemHandle,
123 IMG_CPU_VIRTADDR LinAddr,
124 IMG_CPU_PHYADDR PhysAddr);
126 static IMG_SYS_PHYADDR CpuPAddrToSysPAddrBC(IMG_CPU_PHYADDR cpu_paddr);
127 static IMG_CPU_PHYADDR SysPAddrToCpuPAddrBC(IMG_SYS_PHYADDR sys_paddr);
129 static BC_CAT_DEVINFO * GetAnchorPtr(int id);
133 static struct class *bc_class;
134 static IMG_VOID *device[DEVICE_COUNT] = { 0 };
135 static int width_align;
137 static struct file_operations bc_cat_fops = {
139 .release = bc_release,
140 .unlocked_ioctl = bc_ioctl,
145 /*****************************************************************************
146 * func implementation
147 * **************************************************************************/
149 #define file_to_id(file) (iminor(file->f_path.dentry->d_inode))
151 static BC_CAT_DEVINFO * GetAnchorPtr(int id)
153 return (BC_CAT_DEVINFO *)device[id];
156 static IMG_VOID SetAnchorPtr(int id, BC_CAT_DEVINFO *psDevInfo)
158 device[id] = (IMG_VOID*)psDevInfo;
163 static PVRSRV_ERROR OpenBCDevice(IMG_HANDLE *phDevice)
165 BC_CAT_DEVINFO *psDevInfo;
167 psDevInfo = GetAnchorPtr(id);
168 *phDevice = (IMG_HANDLE)psDevInfo;
174 #define OPEN_FXN(id) \
175 static PVRSRV_ERROR OpenBCDevice##id(IMG_HANDLE *phDevice)\
177 BC_CAT_DEVINFO *psDevInfo; \
178 psDevInfo = GetAnchorPtr (id); \
179 *phDevice = (IMG_HANDLE) psDevInfo; \
195 static PVRSRV_ERROR CloseBCDevice(IMG_HANDLE hDevice)
197 PVR_UNREFERENCED_PARAMETER(hDevice);
202 static PVRSRV_ERROR GetBCBuffer(IMG_HANDLE hDevice,
203 IMG_UINT32 ui32BufferNumber,
204 PVRSRV_SYNC_DATA *psSyncData,
205 IMG_HANDLE *phBuffer)
207 BC_CAT_DEVINFO *psDevInfo;
209 if (!hDevice || !phBuffer)
210 return PVRSRV_ERROR_INVALID_PARAMS;
212 psDevInfo = (BC_CAT_DEVINFO*)hDevice;
214 if (ui32BufferNumber < psDevInfo->sBufferInfo.ui32BufferCount) {
215 psDevInfo->psSystemBuffer[ui32BufferNumber].psSyncData = psSyncData;
216 *phBuffer = (IMG_HANDLE)&psDevInfo->psSystemBuffer[ui32BufferNumber];
218 return PVRSRV_ERROR_INVALID_PARAMS;
225 static PVRSRV_ERROR GetBCInfo(IMG_HANDLE hDevice, BUFFER_INFO *psBCInfo)
227 BC_CAT_DEVINFO *psDevInfo;
229 if (!hDevice || !psBCInfo)
230 return PVRSRV_ERROR_INVALID_PARAMS;
232 psDevInfo = (BC_CAT_DEVINFO*)hDevice;
233 *psBCInfo = psDevInfo->sBufferInfo;
239 static PVRSRV_ERROR GetBCBufferAddr(IMG_HANDLE hDevice,
241 IMG_SYS_PHYADDR **ppsSysAddr,
242 IMG_UINT32 *pui32ByteSize,
243 IMG_VOID **ppvCpuVAddr,
244 IMG_HANDLE *phOSMapInfo,
245 IMG_BOOL *pbIsContiguous)
247 BC_CAT_BUFFER *psBuffer;
249 if (!hDevice || !hBuffer || !ppsSysAddr || !pui32ByteSize)
250 return PVRSRV_ERROR_INVALID_PARAMS;
252 psBuffer = (BC_CAT_BUFFER *) hBuffer;
253 *ppsSysAddr = &psBuffer->sPageAlignSysAddr;
254 *ppvCpuVAddr = psBuffer->sCPUVAddr;
255 *pui32ByteSize = psBuffer->ui32Size;
257 *phOSMapInfo = IMG_NULL;
258 *pbIsContiguous = IMG_TRUE;
264 static int BC_CreateBuffers(int id, bc_buf_params_t *p)
266 BC_CAT_DEVINFO *psDevInfo;
267 IMG_CPU_PHYADDR paddr;
268 IMG_UINT32 i, stride, size;
269 PVRSRV_PIXEL_FORMAT pixel_fmt;
274 if (p->width <= 1 || p->width % width_align || p->height <= 1)
278 case BC_PIX_FMT_NV12:
279 pixel_fmt = PVRSRV_PIXEL_FORMAT_NV12;
282 case BC_PIX_FMT_UYVY:
283 pixel_fmt = PVRSRV_PIXEL_FORMAT_FOURCC_ORG_UYVY;
284 stride = p->width << 1;
286 case BC_PIX_FMT_RGB565:
287 pixel_fmt = PVRSRV_PIXEL_FORMAT_RGB565;
288 stride = p->width << 1;
290 case BC_PIX_FMT_YUYV:
291 pixel_fmt = PVRSRV_PIXEL_FORMAT_FOURCC_ORG_YUYV;
292 stride = p->width << 1;
299 if (p->type != BC_MEMORY_MMAP && p->type != BC_MEMORY_USERPTR)
302 if ((psDevInfo = GetAnchorPtr(id)) == IMG_NULL)
305 if (psDevInfo->ui32NumBuffers)
306 BC_DestroyBuffers(id);
308 psDevInfo->buf_type = p->type;
309 psDevInfo->psSystemBuffer =
310 BCAllocKernelMem(sizeof(BC_CAT_BUFFER) * p->count);
312 if (!psDevInfo->psSystemBuffer)
315 memset(psDevInfo->psSystemBuffer, 0, sizeof(BC_CAT_BUFFER) * p->count);
317 size = p->height * stride;
318 if (pixel_fmt == PVRSRV_PIXEL_FORMAT_NV12)
319 size += (stride >> 1) * (p->height >> 1) << 1;
321 for (i=0; i < p->count; i++) {
322 if (psDevInfo->buf_type == BC_MEMORY_MMAP) {
323 if (BCAllocContigMemory(size,
324 &psDevInfo->psSystemBuffer[i].hMemHandle,
325 &psDevInfo->psSystemBuffer[i].sCPUVAddr,
326 &paddr) != PVRSRV_OK)
327 /*TODO should free() and return failure*/
330 psDevInfo->psSystemBuffer[i].sSysAddr = CpuPAddrToSysPAddrBC(paddr);
331 psDevInfo->psSystemBuffer[i].sPageAlignSysAddr.uiAddr =
332 psDevInfo->psSystemBuffer[i].sSysAddr.uiAddr & 0xFFFFF000;
334 psDevInfo->ui32NumBuffers++;
335 psDevInfo->psSystemBuffer[i].ui32Size = size;
336 psDevInfo->psSystemBuffer[i].psSyncData = IMG_NULL;
338 p->count = psDevInfo->ui32NumBuffers;
340 psDevInfo->sBufferInfo.ui32BufferCount = psDevInfo->ui32NumBuffers;
341 psDevInfo->sBufferInfo.pixelformat = pixel_fmt;
342 psDevInfo->sBufferInfo.ui32Width = p->width;
343 psDevInfo->sBufferInfo.ui32Height = p->height;
344 psDevInfo->sBufferInfo.ui32ByteStride = stride;
345 psDevInfo->sBufferInfo.ui32BufferDeviceID = id;
346 psDevInfo->sBufferInfo.ui32Flags = PVRSRV_BC_FLAGS_YUVCSC_FULL_RANGE |
347 PVRSRV_BC_FLAGS_YUVCSC_BT601;
352 static PVRSRV_ERROR BC_DestroyBuffers(int id)
354 BC_CAT_DEVINFO *psDevInfo;
357 if ((psDevInfo = GetAnchorPtr(id)) == IMG_NULL)
358 return PVRSRV_ERROR_DEVICE_REGISTER_FAILED;
360 if (!psDevInfo->ui32NumBuffers)
363 if (psDevInfo->buf_type == BC_MEMORY_MMAP)
364 for (i = 0; i < psDevInfo->ui32NumBuffers; i++) {
365 BCFreeContigMemory(psDevInfo->psSystemBuffer[i].ui32Size,
366 psDevInfo->psSystemBuffer[i].hMemHandle,
367 psDevInfo->psSystemBuffer[i].sCPUVAddr,
368 SysPAddrToCpuPAddrBC(psDevInfo->psSystemBuffer[i].sSysAddr));
371 BCFreeKernelMem(psDevInfo->psSystemBuffer);
373 psDevInfo->ui32NumBuffers = 0;
374 psDevInfo->sBufferInfo.pixelformat = PVRSRV_PIXEL_FORMAT_UNKNOWN;
375 psDevInfo->sBufferInfo.ui32Width = 0;
376 psDevInfo->sBufferInfo.ui32Height = 0;
377 psDevInfo->sBufferInfo.ui32ByteStride = 0;
378 psDevInfo->sBufferInfo.ui32BufferDeviceID = id;
379 psDevInfo->sBufferInfo.ui32Flags = 0;
380 psDevInfo->sBufferInfo.ui32BufferCount = psDevInfo->ui32NumBuffers;
386 static PVRSRV_ERROR BC_Register(id)
388 BC_CAT_DEVINFO *psDevInfo;
390 psDevInfo = GetAnchorPtr(id);
393 psDevInfo->ui32RefCount++;
397 psDevInfo = (BC_CAT_DEVINFO *)BCAllocKernelMem(sizeof(BC_CAT_DEVINFO));
400 return PVRSRV_ERROR_OUT_OF_MEMORY;
403 psDevInfo->ui32RefCount = 0;
404 SetAnchorPtr(id, (IMG_VOID*)psDevInfo);
406 if (BCOpenPVRServices(&psDevInfo->hPVRServices) != PVRSRV_OK)
407 return PVRSRV_ERROR_INIT_FAILURE;
409 if (!PVRGetBufferClassJTable(&psDevInfo->sPVRJTable))
410 return PVRSRV_ERROR_INIT_FAILURE;
412 psDevInfo->ui32NumBuffers = 0;
414 psDevInfo->sBufferInfo.pixelformat = PVRSRV_PIXEL_FORMAT_UNKNOWN;
415 psDevInfo->sBufferInfo.ui32Width = 0;
416 psDevInfo->sBufferInfo.ui32Height = 0;
417 psDevInfo->sBufferInfo.ui32ByteStride = 0;
418 psDevInfo->sBufferInfo.ui32BufferDeviceID = id;
419 psDevInfo->sBufferInfo.ui32Flags = 0;
420 psDevInfo->sBufferInfo.ui32BufferCount = psDevInfo->ui32NumBuffers;
422 psDevInfo->sBCJTable.ui32TableSize = sizeof(PVRSRV_BC_SRV2BUFFER_KMJTABLE);
424 psDevInfo->sBCJTable.pfnOpenBCDevice = OpenBCDevice;
427 psDevInfo->sBCJTable.pfnOpenBCDevice = OpenBCDevice0;
428 } else if (id == 1) {
429 psDevInfo->sBCJTable.pfnOpenBCDevice = OpenBCDevice1;
430 } else if (id == 2) {
431 psDevInfo->sBCJTable.pfnOpenBCDevice = OpenBCDevice2;
432 } else if (id == 3) {
433 psDevInfo->sBCJTable.pfnOpenBCDevice = OpenBCDevice3;
434 } else if (id == 4) {
435 psDevInfo->sBCJTable.pfnOpenBCDevice = OpenBCDevice4;
436 } else if (id == 5) {
437 psDevInfo->sBCJTable.pfnOpenBCDevice = OpenBCDevice5;
438 } else if (id == 6) {
439 psDevInfo->sBCJTable.pfnOpenBCDevice = OpenBCDevice6;
440 } else if (id == 7) {
441 psDevInfo->sBCJTable.pfnOpenBCDevice = OpenBCDevice7;
442 } else if (id == 8) {
443 psDevInfo->sBCJTable.pfnOpenBCDevice = OpenBCDevice8;
444 } else if (id == 9) {
445 psDevInfo->sBCJTable.pfnOpenBCDevice = OpenBCDevice9;
447 printk("bad device id: %d\n", id);
448 return PVRSRV_ERROR_DEVICE_REGISTER_FAILED;
451 psDevInfo->sBCJTable.pfnCloseBCDevice = CloseBCDevice;
452 psDevInfo->sBCJTable.pfnGetBCBuffer = GetBCBuffer;
453 psDevInfo->sBCJTable.pfnGetBCInfo = GetBCInfo;
454 psDevInfo->sBCJTable.pfnGetBufferAddr = GetBCBufferAddr;
456 if (psDevInfo->sPVRJTable.pfnPVRSRVRegisterBCDevice(
457 &psDevInfo->sBCJTable,
458 &psDevInfo->ui32DeviceID) != PVRSRV_OK)
459 return PVRSRV_ERROR_DEVICE_REGISTER_FAILED;
461 psDevInfo->ui32RefCount++;
467 static PVRSRV_ERROR BC_Unregister(int id)
469 BC_CAT_DEVINFO *psDevInfo;
470 PVRSRV_BC_BUFFER2SRV_KMJTABLE *psJTable;
472 if ((psDevInfo = GetAnchorPtr(id)) == IMG_NULL)
473 return PVRSRV_ERROR_DEVICE_REGISTER_FAILED;
475 psDevInfo->ui32RefCount--;
477 if (psDevInfo->ui32RefCount)
478 return PVRSRV_ERROR_RETRY;
480 psJTable = &psDevInfo->sPVRJTable;
482 if (psJTable->pfnPVRSRVRemoveBCDevice(psDevInfo->ui32DeviceID) != PVRSRV_OK)
483 return PVRSRV_ERROR_GENERIC;
485 if (BCClosePVRServices(psDevInfo->hPVRServices) != PVRSRV_OK) {
486 psDevInfo->hPVRServices = IMG_NULL;
487 return PVRSRV_ERROR_GENERIC;
490 BCFreeKernelMem(psDevInfo);
491 SetAnchorPtr(id, IMG_NULL);
497 static int __init bc_cat_init(void)
499 struct device *bc_dev;
502 /* texture buffer width should be multiple of 8 for OMAP3 ES3.x,
504 width_align = (cpu_is_omap3530() && omap_rev() < OMAP3430_REV_ES3_0) ? 32 : 8;
506 major = register_chrdev(0, DEVNAME, &bc_cat_fops);
509 printk(KERN_ERR DRVNAME ": unable to get major number\n");
513 bc_class = class_create(THIS_MODULE, DEVNAME);
515 if (IS_ERR(bc_class)) {
516 printk(KERN_ERR DRVNAME ": upable to create device class\n");
520 for (id = 0; id < DEVICE_COUNT; id++) {
521 bc_dev = device_create(bc_class, NULL, MKDEV(major, id), NULL,
524 if (IS_ERR(bc_dev)) {
525 printk(KERN_ERR DRVNAME ": unable to create device %d\n", id);
526 goto ExitDestroyClass;
529 if (BC_Register(id) != PVRSRV_OK) {
530 printk (KERN_ERR DRVNAME ": can't register BC service %d\n", id);
532 /* lets live with the drivers that we were able to create soi
533 * far, even though it isn't as many as we'd like
544 class_destroy(bc_class);
546 unregister_chrdev(major, DEVNAME);
551 static void __exit bc_cat_cleanup(void)
555 for (id = 0; id < DEVICE_COUNT; id++) {
556 if (BC_DestroyBuffers(id) != PVRSRV_OK) {
557 printk(KERN_ERR DRVNAME ": can't free texture buffers\n");
560 if (BC_Unregister(id) != PVRSRV_OK) {
561 printk(KERN_ERR DRVNAME ": can't un-register BC service\n");
564 device_destroy(bc_class, MKDEV(major, id));
566 class_destroy(bc_class);
567 unregister_chrdev(major, DEVNAME);
571 static IMG_VOID *BCAllocKernelMem(IMG_UINT32 ui32Size)
573 return kmalloc(ui32Size, GFP_KERNEL);
576 static IMG_VOID BCFreeKernelMem(IMG_VOID *pvMem)
581 static PVRSRV_ERROR BCAllocContigMemory(IMG_UINT32 ui32Size,
582 IMG_HANDLE unref__ *phMemHandle,
583 IMG_CPU_VIRTADDR *pLinAddr,
584 IMG_CPU_PHYADDR *pPhysAddr)
587 gfp_t mask = GFP_KERNEL;
589 pvLinAddr = alloc_pages_exact(ui32Size, mask);
590 /* printk("pvLinAddr=%p, ui32Size=%ld\n", pvLinAddr, ui32Size);*/
592 if (pvLinAddr == IMG_NULL)
593 return PVRSRV_ERROR_OUT_OF_MEMORY;
595 pPhysAddr->uiAddr = virt_to_phys(pvLinAddr);
597 *pLinAddr = pvLinAddr;
602 static IMG_VOID BCFreeContigMemory(IMG_UINT32 ui32Size,
603 IMG_HANDLE unref__ hMemHandle,
604 IMG_CPU_VIRTADDR LinAddr,
605 IMG_CPU_PHYADDR PhysAddr)
607 free_pages_exact(LinAddr, ui32Size);
610 static IMG_SYS_PHYADDR CpuPAddrToSysPAddrBC(IMG_CPU_PHYADDR cpu_paddr)
612 IMG_SYS_PHYADDR sys_paddr;
614 sys_paddr.uiAddr = cpu_paddr.uiAddr;
618 static IMG_CPU_PHYADDR SysPAddrToCpuPAddrBC(IMG_SYS_PHYADDR sys_paddr)
620 IMG_CPU_PHYADDR cpu_paddr;
622 cpu_paddr.uiAddr = sys_paddr.uiAddr;
626 static PVRSRV_ERROR BCOpenPVRServices (IMG_HANDLE *phPVRServices)
633 static PVRSRV_ERROR BCClosePVRServices (IMG_HANDLE unref__ hPVRServices)
638 static int bc_open(struct inode *i, struct file *f)
640 BC_CAT_DEVINFO *devinfo;
641 int id = file_to_id(f);
643 if ((devinfo = GetAnchorPtr(id)) == IMG_NULL) {
644 printk("no device %d\n", id);
649 printk("device %d busy\n", id);
658 static int bc_release(struct inode *i, struct file *f)
660 BC_CAT_DEVINFO *devinfo;
661 int id = file_to_id(f);
663 if ((devinfo = GetAnchorPtr(id)) == IMG_NULL)
672 static int bc_mmap(struct file *filp, struct vm_area_struct *vma)
675 printk("bc_mmap: vma->vm_start = %#lx\n", vma->vm_start);
676 printk("bc_mmap: vma->vm_pgoff = %#lx\n", vma->vm_pgoff);
677 printk("bc_mmap: size = %#lx\n", vma->vm_end - vma->vm_start);
680 /*FIXME check start & size*/
681 if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
682 vma->vm_end - vma->vm_start,
683 vma->vm_page_prot)) {
684 printk("bc_mmap: failed remap_pfn_range\n");
690 static long bc_ioctl(struct file *file,
691 unsigned int cmd, unsigned long arg)
693 BC_CAT_DEVINFO *devinfo;
694 int id = file_to_id (file);
696 if ((devinfo = GetAnchorPtr(id)) == IMG_NULL)
699 switch(_IOC_NR(cmd)) {
700 case _IOC_NR(BCIOGET_BUFFERCOUNT):
702 BCIO_package *params = (BCIO_package *)arg;
704 if (!access_ok(VERIFY_WRITE, params, sizeof(BCIO_package)))
707 params->output = devinfo->sBufferInfo.ui32BufferCount;
710 case _IOC_NR(BCIOGET_BUFFERPHYADDR):
713 BCIO_package *params = (BCIO_package *)arg;
715 if (!access_ok(VERIFY_WRITE, params, sizeof(BCIO_package)))
719 if (idx < 0 || idx > devinfo->ui32NumBuffers) {
720 printk(KERN_ERR DRVNAME
721 ": BCIOGET_BUFFERADDR - idx out of range\n");
724 params->output = devinfo->psSystemBuffer[idx].sSysAddr.uiAddr;
727 case _IOC_NR(BCIOGET_BUFFERIDX):
730 BC_CAT_BUFFER *buffer;
731 BCIO_package *params = (BCIO_package *)arg;
733 if (!access_ok(VERIFY_WRITE, params, sizeof(BCIO_package)))
736 for (idx = 0; idx < devinfo->ui32NumBuffers; idx++) {
737 buffer = &devinfo->psSystemBuffer[idx];
739 if (params->input == (int)buffer->sSysAddr.uiAddr) {
740 params->output = idx;
744 printk(KERN_ERR DRVNAME ": BCIOGET_BUFFERIDX- buffer not found\n");
748 case _IOC_NR(BCIOREQ_BUFFERS):
750 bc_buf_params_t *p = (bc_buf_params_t *) arg;
752 if (!access_ok(VERIFY_WRITE, p, sizeof(bc_buf_params_t)))
755 return BC_CreateBuffers(id, p);
758 case _IOC_NR(BCIOSET_BUFFERPHYADDR):
761 IMG_CPU_PHYADDR img_pa;
763 if (copy_from_user(&p, (void __user *)arg, sizeof(p)))
766 if (p.index >= devinfo->ui32NumBuffers || !p.pa)
769 /*TODO check buffer size*/
771 img_pa.uiAddr = p.pa;
773 devinfo->psSystemBuffer[p.index].sCPUVAddr = phys_to_virt(p.pa);
774 devinfo->psSystemBuffer[p.index].sSysAddr =
775 CpuPAddrToSysPAddrBC(img_pa);
776 devinfo->psSystemBuffer[p.index].sPageAlignSysAddr.uiAddr =
777 devinfo->psSystemBuffer[p.index].sSysAddr.uiAddr &
787 module_init(bc_cat_init);
788 module_exit(bc_cat_cleanup);
790 MODULE_LICENSE("GPL v2");