From 0b23ab78528141ec47c30c950b9b0c2740ee5ed7 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E6=9D=9C=E5=9D=A4=E6=98=8E?= Date: Mon, 19 Dec 2011 11:04:04 +0800 Subject: [PATCH] gpu : enable shutdown control & add some command check. --- .../os/linux/kernel/gc_hal_kernel_driver.c | 93 ++++++++++++++----- 1 file changed, 69 insertions(+), 24 deletions(-) diff --git a/drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_driver.c b/drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_driver.c index cdcdcd712640..4fde4ad134b6 100755 --- a/drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_driver.c +++ b/drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_driver.c @@ -465,31 +465,52 @@ long drv_ioctl(struct file *filp, } #if gcdkUSE_MEMORY_RECORD - if (iface.command == gcvHAL_EVENT_COMMIT) + if (iface.command == gcvHAL_UNLOCK_VIDEO_MEMORY) + { + MEMORY_RECORD_PTR mr; + mr = FindVideoMemoryRecord(device->os, + private, + &private->memoryRecordList, + iface.u.UnlockVideoMemory.node); + + if (mr == gcvNULL) + { + gcmkPRINT("*ERROR* Invalid video memory for unlock"); + return -ENOTTY; + } + + } + else if (iface.command == gcvHAL_EVENT_COMMIT) { MEMORY_RECORD_PTR mr; gcsQUEUE_PTR queue = iface.u.Event.queue; while (queue != gcvNULL) { - gcsQUEUE_PTR record, next; + gcsQUEUE_PTR next; + gcsQUEUE record; + + /* Copy record into kernel memory. */ + copyLen = copy_from_user(&record, + (void *) queue, + gcmSIZEOF(gcsQUEUE)); - /* Map record into kernel memory. */ - gcmkERR_BREAK(gckOS_MapUserPointer(device->os, - queue, - gcmSIZEOF(gcsQUEUE), - (gctPOINTER *) &record)); + if (copyLen != 0) + { + /* The input buffer is not big enough. So fail the I/O. */ + return -ENOTTY; + } - switch (record->iface.command) + switch (record.iface.command) { case gcvHAL_FREE_NON_PAGED_MEMORY: mr = FindMemoryRecord(device->os, private, &private->memoryRecordList, gcvNON_PAGED_MEMORY, - record->iface.u.FreeNonPagedMemory.bytes, - record->iface.u.FreeNonPagedMemory.physical, - record->iface.u.FreeNonPagedMemory.logical); + record.iface.u.FreeNonPagedMemory.bytes, + record.iface.u.FreeNonPagedMemory.physical, + record.iface.u.FreeNonPagedMemory.logical); if (mr != gcvNULL) { @@ -506,9 +527,9 @@ long drv_ioctl(struct file *filp, private, &private->memoryRecordList, gcvCONTIGUOUS_MEMORY, - record->iface.u.FreeContiguousMemory.bytes, - record->iface.u.FreeContiguousMemory.physical, - record->iface.u.FreeContiguousMemory.logical); + record.iface.u.FreeContiguousMemory.bytes, + record.iface.u.FreeContiguousMemory.physical, + record.iface.u.FreeContiguousMemory.logical); if (mr != gcvNULL) { @@ -524,7 +545,7 @@ long drv_ioctl(struct file *filp, mr = FindVideoMemoryRecord(device->os, private, &private->memoryRecordList, - record->iface.u.FreeVideoMemory.node); + record.iface.u.FreeVideoMemory.node); if (mr != gcvNULL) { @@ -541,16 +562,41 @@ long drv_ioctl(struct file *filp, } /* Next record in the queue. */ - next = record->next; + next = record.next; - /* Unmap record from kernel memory. */ - gcmkERR_BREAK(gckOS_UnmapUserPointer(device->os, - queue, - gcmSIZEOF(gcsQUEUE), - (gctPOINTER *) record)); queue = next; } } + else if (iface.command == gcvHAL_LOCK_VIDEO_MEMORY) + { + MEMORY_RECORD_PTR mr; + + mr = FindVideoMemoryRecord(device->os, + private, + &private->memoryRecordList, + iface.u.LockVideoMemory.node); + + if (mr == gcvNULL) + { + gcmkPRINT("*ERROR* Invalid video memory for lock"); + return -ENOTTY; + } + } + else if (iface.command == gcvHAL_UNLOCK_VIDEO_MEMORY) + { + MEMORY_RECORD_PTR mr; + + mr = FindVideoMemoryRecord(device->os, + private, + &private->memoryRecordList, + iface.u.UnlockVideoMemory.node); + + if (mr == gcvNULL) + { + gcmkPRINT("*ERROR* Invalid video memory for unlock"); + return -ENOTTY; + } + } #endif dprintk(D_IOCTL, "gckKERNEL_Dispatch(FromUser %d, Cmd %d)\n", (ioctlCode == IOCTL_GCHAL_INTERFACE), iface.command); @@ -958,10 +1004,9 @@ static void drv_exit(void) unregister_chrdev(major, DRV_NAME); #endif - // È¥µô,±ÜÃâ¹Ø»úµÄʱºò¶¯Ì¬×ÀÃ汨´í - //shutdown = 1; + shutdown = 1; - mdelay(50); + mdelay(100); gckGALDEVICE_Stop(galDevice); mdelay(50); gckGALDEVICE_Destroy(galDevice); -- 2.34.1