gfx: pvr: add helper function to lookup a pvr buf by id
authorImre Deak <imre.deak@intel.com>
Thu, 22 Dec 2011 20:48:30 +0000 (22:48 +0200)
committerMarkus Lehtonen <markus.lehtonen@linux.intel.com>
Tue, 3 Jul 2012 09:29:19 +0000 (12:29 +0300)
Needed by the upcoming patch adding support for wrapping a pvr buffer
as ttm buffer.

Signed-off-by: Imre Deak <imre.deak@intel.com>
Signed-off-by: Pauli Nieminen <pauli.nieminen@linux.intel.com>
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
drivers/staging/mrst/pvr/services4/include/pvr_bridge_km.h
drivers/staging/mrst/pvr/services4/srvkm/bridged/bridged_pvr_bridge.c

index 7f82e93..fe38282 100644 (file)
@@ -34,6 +34,11 @@ extern "C" {
 #include "pvr_bridge.h"
 #include "perproc.h"
 
+struct pvr_buf_info {
+       size_t          page_cnt;
+       struct page     **pages;
+};
+
 #if defined(__linux__)
 PVRSRV_ERROR LinuxBridgeInit(IMG_VOID);
 IMG_VOID LinuxBridgeDeInit(IMG_VOID);
@@ -278,6 +283,9 @@ PVRSRVFreeSharedSysMemoryKM(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo);
 IMG_IMPORT PVRSRV_ERROR
 PVRSRVDissociateMemFromResmanKM(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo);
 
+int pvr_lookup_dev_buf(unsigned long id, struct pvr_buf_info *buf);
+void pvr_put_dev_buf(struct pvr_buf_info *buf);
+
 #if defined (__cplusplus)
 }
 #endif
index 322dd64..04b0797 100644 (file)
@@ -69,6 +69,8 @@
 #include "psb_intel_display.h" /* mdfld__intel_plane_set_alpha() */
 
 #include "srvkm.h"
+#include "mutex.h"
+#include "lock.h"
 
 PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY g_BridgeDispatchTable[BRIDGE_DISPATCH_TABLE_ENTRY_COUNT];
 
@@ -3636,6 +3638,86 @@ PVRSRVFreeSyncInfoBW(IMG_UINT32                                          ui32Bri
        return 0;
 }
 
+int pvr_lookup_dev_buf(unsigned long id, struct pvr_buf_info *binfo)
+{
+       unsigned pid;
+       PVRSRV_PER_PROCESS_DATA *proc_info;
+       PVRSRV_KERNEL_MEM_INFO *meminfo;
+       PVRSRV_MEMBLK *memblk;
+       off_t page_offset;
+       int page_cnt;
+       PVRSRV_ERROR err;
+       int ret;
+       unsigned i;
+
+       mutex_lock(&gPVRSRVLock);
+
+       pid = OSGetCurrentProcessIDKM();
+       proc_info = PVRSRVPerProcessData(pid);
+       err = PVRSRVLookupHandle(proc_info->psHandleBase, (void **)&meminfo,
+                                (void *)id, PVRSRV_HANDLE_TYPE_MEM_INFO);
+
+       if (err != PVRSRV_OK) {
+               ret = -ENOENT;
+               goto err1;
+       }
+
+       memblk = &meminfo->sMemBlk;
+       page_offset = meminfo->sDevVAddr.uiAddr & ~PAGE_MASK;
+       /* Suballocated buffers may not be shared */
+       BUG_ON(page_offset != 0);
+       page_cnt = PAGE_ALIGN(meminfo->ui32AllocSize) >> PAGE_SHIFT;
+
+       if (!memblk->psIntSysPAddr) {
+               ret = -EINVAL;
+               goto err1;
+       }
+
+       binfo->pages = kmalloc(page_cnt * sizeof(struct page *), GFP_KERNEL);
+       if (!binfo->pages) {
+               ret = -ENOMEM;
+               goto err1;
+       }
+
+       for (i = 0; i < page_cnt; i++) {
+               unsigned long addr = memblk->psIntSysPAddr[i].uiAddr;
+               unsigned long pfn = addr >> PAGE_SHIFT;
+               struct page *page;
+
+               if (!pfn_valid(pfn)) {
+                       ret = -EINVAL;
+                       goto err2;
+               }
+               page = pfn_to_page(pfn);
+               get_page(page);
+               binfo->pages[i] = page;
+       }
+
+       mutex_unlock(&gPVRSRVLock);
+
+       binfo->page_cnt = page_cnt;
+
+       return 0;
+err2:
+       while (i--)
+               put_page(binfo->pages[i]);
+       kfree(binfo->pages);
+err1:
+       mutex_unlock(&gPVRSRVLock);
+
+       return ret;
+}
+
+void pvr_put_dev_buf(struct pvr_buf_info *binfo)
+{
+       int page_cnt;
+       int i;
+
+       for (i = 0; i < binfo->page_cnt; i++)
+               put_page(binfo->pages[i]);
+
+       kfree(binfo->pages);
+}
 
 PVRSRV_ERROR
 CommonBridgeInit(IMG_VOID)