aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/emgd/pvr/services4/srvkm/env/linux/osfunc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/emgd/pvr/services4/srvkm/env/linux/osfunc.c')
-rw-r--r--drivers/gpu/drm/emgd/pvr/services4/srvkm/env/linux/osfunc.c2558
1 files changed, 0 insertions, 2558 deletions
diff --git a/drivers/gpu/drm/emgd/pvr/services4/srvkm/env/linux/osfunc.c b/drivers/gpu/drm/emgd/pvr/services4/srvkm/env/linux/osfunc.c
deleted file mode 100644
index 531e2b778dd1..000000000000
--- a/drivers/gpu/drm/emgd/pvr/services4/srvkm/env/linux/osfunc.c
+++ /dev/null
@@ -1,2558 +0,0 @@
-/**********************************************************************
- *
- * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful but, except
- * as otherwise stated in writing, without any warranty; without even the
- * implied warranty of merchantability or fitness for a particular purpose.
- * See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * The full GNU General Public License is included in this distribution in
- * the file called "COPYING".
- *
- * Contact Information:
- * Imagination Technologies Ltd. <gpl-support@imgtec.com>
- * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
- *
- ******************************************************************************/
-
-#ifndef AUTOCONF_INCLUDED
- #include <linux/config.h>
-#endif
-
-#include <linux/version.h>
-#include <asm/io.h>
-#include <asm/page.h>
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22))
-#include <asm/system.h>
-#endif
-#if defined(SUPPORT_CPU_CACHED_BUFFERS)
-#include <asm/cacheflush.h>
-#endif
-#include <linux/mm.h>
-#include <linux/pagemap.h>
-#include <linux/hugetlb.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/delay.h>
-#include <linux/pci.h>
-
-#include <linux/string.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <asm/hardirq.h>
-#include <linux/timer.h>
-#include <linux/capability.h>
-#include <asm/uaccess.h>
-#include <linux/spinlock.h>
-#if defined(PVR_LINUX_MISR_USING_WORKQUEUE) || \
- defined(PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE) || \
- defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) || \
- defined(PVR_LINUX_USING_WORKQUEUES)
-#include <linux/workqueue.h>
-#endif
-
-#include "img_types.h"
-#include "services_headers.h"
-#include "mm.h"
-#include "pvrmmap.h"
-#include "mmap.h"
-#include "env_data.h"
-#include "proc.h"
-#include "mutex.h"
-#include "event.h"
-#include "linkage.h"
-
-#define EVENT_OBJECT_TIMEOUT_MS (100)
-
-#if defined(SUPPORT_CPU_CACHED_BUFFERS) || \
- defined(SUPPORT_CACHEFLUSH_ON_ALLOC)
-
-#if defined(__i386__)
-static void per_cpu_cache_flush(void *arg)
-{
- PVR_UNREFERENCED_PARAMETER(arg);
- wbinvd();
-}
-#endif
-
-#if !defined(SUPPORT_CPU_CACHED_BUFFERS)
-static
-#endif
-IMG_VOID OSFlushCPUCacheKM(IMG_VOID)
-{
-#if defined(__arm__)
- flush_cache_all();
-#elif defined(__i386__)
-
- on_each_cpu(per_cpu_cache_flush, NULL, 1);
-#else
-#error "Implement full CPU cache flush for this CPU!"
-#endif
-}
-
-#endif
-#if defined(SUPPORT_CPU_CACHED_BUFFERS)
-
-IMG_VOID OSFlushCPUCacheRangeKM(IMG_VOID *pvRangeAddrStart,
- IMG_VOID *pvRangeAddrEnd)
-{
- PVR_UNREFERENCED_PARAMETER(pvRangeAddrStart);
- PVR_UNREFERENCED_PARAMETER(pvRangeAddrEnd);
-
-
- OSFlushCPUCacheKM();
-}
-
-#endif
-
-#define HOST_ALLOC_MEM_USING_KMALLOC ((IMG_HANDLE)0)
-#define HOST_ALLOC_MEM_USING_VMALLOC ((IMG_HANDLE)1)
-
-#if !defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
-PVRSRV_ERROR OSAllocMem_Impl(IMG_UINT32 ui32Flags, IMG_UINT32 ui32Size, IMG_PVOID *ppvCpuVAddr, IMG_HANDLE *phBlockAlloc)
-#else
-PVRSRV_ERROR OSAllocMem_Impl(IMG_UINT32 ui32Flags, IMG_UINT32 ui32Size, IMG_PVOID *ppvCpuVAddr, IMG_HANDLE *phBlockAlloc, IMG_CHAR *pszFilename, IMG_UINT32 ui32Line)
-#endif
-{
- PVR_UNREFERENCED_PARAMETER(ui32Flags);
-
-#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
- *ppvCpuVAddr = _KMallocWrapper(ui32Size, pszFilename, ui32Line);
-#else
- *ppvCpuVAddr = KMallocWrapper(ui32Size);
-#endif
- if(*ppvCpuVAddr)
- {
- if (phBlockAlloc)
- {
-
- *phBlockAlloc = HOST_ALLOC_MEM_USING_KMALLOC;
- }
- }
- else
- {
- if (!phBlockAlloc)
- {
- return PVRSRV_ERROR_OUT_OF_MEMORY;
- }
-
-
-#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
- *ppvCpuVAddr = _VMallocWrapper(ui32Size, PVRSRV_HAP_CACHED, pszFilename, ui32Line);
-#else
- *ppvCpuVAddr = VMallocWrapper(ui32Size, PVRSRV_HAP_CACHED);
-#endif
- if (!*ppvCpuVAddr)
- {
- return PVRSRV_ERROR_OUT_OF_MEMORY;
- }
-
-
- *phBlockAlloc = HOST_ALLOC_MEM_USING_VMALLOC;
- }
-
- return PVRSRV_OK;
-}
-
-
-#if !defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
-PVRSRV_ERROR OSFreeMem_Impl(IMG_UINT32 ui32Flags, IMG_UINT32 ui32Size, IMG_PVOID pvCpuVAddr, IMG_HANDLE hBlockAlloc)
-#else
-PVRSRV_ERROR OSFreeMem_Impl(IMG_UINT32 ui32Flags, IMG_UINT32 ui32Size, IMG_PVOID pvCpuVAddr, IMG_HANDLE hBlockAlloc, IMG_CHAR *pszFilename, IMG_UINT32 ui32Line)
-#endif
-{
- PVR_UNREFERENCED_PARAMETER(ui32Flags);
- PVR_UNREFERENCED_PARAMETER(ui32Size);
-
- if (hBlockAlloc == HOST_ALLOC_MEM_USING_VMALLOC)
- {
-#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
- _VFreeWrapper(pvCpuVAddr, pszFilename, ui32Line);
-#else
- VFreeWrapper(pvCpuVAddr);
-#endif
- }
- else
- {
-#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
- _KFreeWrapper(pvCpuVAddr, pszFilename, ui32Line);
-#else
- KFreeWrapper(pvCpuVAddr);
-#endif
- }
-
- return PVRSRV_OK;
-}
-
-
-PVRSRV_ERROR
-OSAllocPages_Impl(IMG_UINT32 ui32AllocFlags,
- IMG_UINT32 ui32Size,
- IMG_UINT32 ui32PageSize,
- IMG_VOID **ppvCpuVAddr,
- IMG_HANDLE *phOSMemHandle)
-{
- LinuxMemArea *psLinuxMemArea;
-
- PVR_UNREFERENCED_PARAMETER(ui32PageSize);
-
-#if 0
-
- if(ui32AllocFlags & PVRSRV_HAP_SINGLE_PROCESS)
- {
- ui32AllocFlags &= ~PVRSRV_HAP_SINGLE_PROCESS;
- ui32AllocFlags |= PVRSRV_HAP_MULTI_PROCESS;
- }
-#endif
-
- switch(ui32AllocFlags & PVRSRV_HAP_MAPTYPE_MASK)
- {
- case PVRSRV_HAP_KERNEL_ONLY:
- {
- psLinuxMemArea = NewVMallocLinuxMemArea(ui32Size, ui32AllocFlags);
- if(!psLinuxMemArea)
- {
- return PVRSRV_ERROR_OUT_OF_MEMORY;
- }
- break;
- }
- case PVRSRV_HAP_SINGLE_PROCESS:
- {
-
-
- psLinuxMemArea = NewAllocPagesLinuxMemArea(ui32Size, ui32AllocFlags);
- if(!psLinuxMemArea)
- {
- return PVRSRV_ERROR_OUT_OF_MEMORY;
- }
- PVRMMapRegisterArea(psLinuxMemArea);
- break;
- }
-
- case PVRSRV_HAP_MULTI_PROCESS:
- {
-
-#if defined(VIVT_CACHE) || defined(__sh__)
-
- ui32AllocFlags &= ~PVRSRV_HAP_CACHED;
-#endif
- psLinuxMemArea = NewVMallocLinuxMemArea(ui32Size, ui32AllocFlags);
- if(!psLinuxMemArea)
- {
- return PVRSRV_ERROR_OUT_OF_MEMORY;
- }
- PVRMMapRegisterArea(psLinuxMemArea);
- break;
- }
- default:
- PVR_DPF((PVR_DBG_ERROR, "OSAllocPages: invalid flags 0x%x\n", ui32AllocFlags));
- *ppvCpuVAddr = NULL;
- *phOSMemHandle = (IMG_HANDLE)0;
- return PVRSRV_ERROR_INVALID_PARAMS;
- }
-
-#if defined(SUPPORT_CACHEFLUSH_ON_ALLOC)
-
- if(ui32AllocFlags & (PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_UNCACHED))
- {
- OSFlushCPUCacheKM();
- }
-#endif
-
- *ppvCpuVAddr = LinuxMemAreaToCpuVAddr(psLinuxMemArea);
- *phOSMemHandle = psLinuxMemArea;
-
- LinuxMemAreaRegister(psLinuxMemArea);
-
- return PVRSRV_OK;
-}
-
-
-PVRSRV_ERROR
-OSFreePages(IMG_UINT32 ui32AllocFlags, IMG_UINT32 ui32Bytes, IMG_VOID *pvCpuVAddr, IMG_HANDLE hOSMemHandle)
-{
- LinuxMemArea *psLinuxMemArea;
- PVR_UNREFERENCED_PARAMETER(ui32Bytes);
- PVR_UNREFERENCED_PARAMETER(pvCpuVAddr);
-
- psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
-
- switch(ui32AllocFlags & PVRSRV_HAP_MAPTYPE_MASK)
- {
- case PVRSRV_HAP_KERNEL_ONLY:
- break;
- case PVRSRV_HAP_SINGLE_PROCESS:
- case PVRSRV_HAP_MULTI_PROCESS:
- if(PVRMMapRemoveRegisteredArea(psLinuxMemArea) != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR,
- "OSFreePages(ui32AllocFlags=0x%08X, ui32Bytes=%ld, "
- "pvCpuVAddr=%p, hOSMemHandle=%p) FAILED!",
- ui32AllocFlags, ui32Bytes, pvCpuVAddr, hOSMemHandle));
- return PVRSRV_ERROR_GENERIC;
- }
- break;
- default:
- PVR_DPF((PVR_DBG_ERROR,"%s: invalid flags 0x%x\n",
- __FUNCTION__, ui32AllocFlags));
- return PVRSRV_ERROR_INVALID_PARAMS;
- }
-
- LinuxMemAreaDeepFree(psLinuxMemArea);
-
- return PVRSRV_OK;
-}
-
-
-PVRSRV_ERROR
-OSGetSubMemHandle(IMG_HANDLE hOSMemHandle,
- IMG_UINT32 ui32ByteOffset,
- IMG_UINT32 ui32Bytes,
- IMG_UINT32 ui32Flags,
- IMG_HANDLE *phOSMemHandleRet)
-{
- LinuxMemArea *psParentLinuxMemArea, *psLinuxMemArea;
- PVRSRV_ERROR eError;
-
- psParentLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
-
- psLinuxMemArea = NewSubLinuxMemArea(psParentLinuxMemArea, ui32ByteOffset, ui32Bytes);
- if(!psLinuxMemArea)
- {
- *phOSMemHandleRet = NULL;
- return PVRSRV_ERROR_OUT_OF_MEMORY;
- }
- *phOSMemHandleRet = psLinuxMemArea;
-
-
- if(ui32Flags & PVRSRV_HAP_KERNEL_ONLY)
- {
- return PVRSRV_OK;
- }
-
- eError = PVRMMapRegisterArea(psLinuxMemArea);
- if(eError != PVRSRV_OK)
- {
- goto failed_register_area;
- }
-
- return PVRSRV_OK;
-
-failed_register_area:
- *phOSMemHandleRet = NULL;
- LinuxMemAreaDeepFree(psLinuxMemArea);
- return eError;
-}
-
-PVRSRV_ERROR
-OSReleaseSubMemHandle(IMG_VOID *hOSMemHandle, IMG_UINT32 ui32Flags)
-{
- LinuxMemArea *psLinuxMemArea;
- PVRSRV_ERROR eError;
-
- psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
- PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_SUB_ALLOC);
-
- if((ui32Flags & PVRSRV_HAP_KERNEL_ONLY) == 0)
- {
- eError = PVRMMapRemoveRegisteredArea(psLinuxMemArea);
- if(eError != PVRSRV_OK)
- {
- return eError;
- }
- }
- LinuxMemAreaDeepFree(psLinuxMemArea);
-
- return PVRSRV_OK;
-}
-
-
-IMG_CPU_PHYADDR
-OSMemHandleToCpuPAddr(IMG_VOID *hOSMemHandle, IMG_UINT32 ui32ByteOffset)
-{
- PVR_ASSERT(hOSMemHandle);
-
- return LinuxMemAreaToCpuPAddr(hOSMemHandle, ui32ByteOffset);
-}
-
-
-
-IMG_VOID OSMemCopy(IMG_VOID *pvDst, IMG_VOID *pvSrc, IMG_UINT32 ui32Size)
-{
-#if defined(USE_UNOPTIMISED_MEMCPY)
- IMG_UINT8 *Src,*Dst;
- IMG_INT i;
-
- Src=(IMG_UINT8 *)pvSrc;
- Dst=(IMG_UINT8 *)pvDst;
- for(i=0;i<ui32Size;i++)
- {
- Dst[i]=Src[i];
- }
-#else
- memcpy(pvDst, pvSrc, ui32Size);
-#endif
-}
-
-
-IMG_VOID OSMemSet(IMG_VOID *pvDest, IMG_UINT8 ui8Value, IMG_UINT32 ui32Size)
-{
-#if defined(USE_UNOPTIMISED_MEMSET)
- IMG_UINT8 *Buff;
- IMG_INT i;
-
- Buff=(IMG_UINT8 *)pvDest;
- for(i=0;i<ui32Size;i++)
- {
- Buff[i]=ui8Value;
- }
-#else
- memset(pvDest, (IMG_INT) ui8Value, (size_t) ui32Size);
-#endif
-}
-
-
-IMG_CHAR *OSStringCopy(IMG_CHAR *pszDest, const IMG_CHAR *pszSrc)
-{
- return (strcpy(pszDest, pszSrc));
-}
-
-IMG_INT32 OSSNPrintf(IMG_CHAR *pStr, IMG_UINT32 ui32Size, const IMG_CHAR *pszFormat, ...)
-{
- va_list argList;
- IMG_INT32 iCount;
-
- va_start(argList, pszFormat);
- iCount = vsnprintf(pStr, (size_t)ui32Size, pszFormat, argList);
- va_end(argList);
-
- return iCount;
-}
-
-IMG_VOID OSBreakResourceLock (PVRSRV_RESOURCE *psResource, IMG_UINT32 ui32ID)
-{
- volatile IMG_UINT32 *pui32Access = (volatile IMG_UINT32 *)&psResource->ui32Lock;
-
- if(*pui32Access)
- {
- if(psResource->ui32ID == ui32ID)
- {
- psResource->ui32ID = 0;
- *pui32Access = 0;
- }
- else
- {
- PVR_DPF((PVR_DBG_MESSAGE,"OSBreakResourceLock: Resource is not locked for this process."));
- }
- }
- else
- {
- PVR_DPF((PVR_DBG_MESSAGE,"OSBreakResourceLock: Resource is not locked"));
- }
-}
-
-
-PVRSRV_ERROR OSCreateResource(PVRSRV_RESOURCE *psResource)
-{
- psResource->ui32ID = 0;
- psResource->ui32Lock = 0;
-
- return PVRSRV_OK;
-}
-
-
-PVRSRV_ERROR OSDestroyResource (PVRSRV_RESOURCE *psResource)
-{
- OSBreakResourceLock (psResource, psResource->ui32ID);
-
- return PVRSRV_OK;
-}
-
-
-PVRSRV_ERROR OSInitEnvData(IMG_PVOID *ppvEnvSpecificData)
-{
- ENV_DATA *psEnvData;
-
-
- if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(ENV_DATA), (IMG_VOID **)&psEnvData, IMG_NULL,
- "Environment Data") != PVRSRV_OK)
- {
- return PVRSRV_ERROR_GENERIC;
- }
-
- if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, PVRSRV_MAX_BRIDGE_IN_SIZE + PVRSRV_MAX_BRIDGE_OUT_SIZE,
- &psEnvData->pvBridgeData, IMG_NULL,
- "Bridge Data") != PVRSRV_OK)
- {
- OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(ENV_DATA), psEnvData, IMG_NULL);
-
- return PVRSRV_ERROR_GENERIC;
- }
-
-
-
- psEnvData->bMISRInstalled = IMG_FALSE;
- psEnvData->bLISRInstalled = IMG_FALSE;
-
-
- *ppvEnvSpecificData = psEnvData;
-
- return PVRSRV_OK;
-}
-
-
-PVRSRV_ERROR OSDeInitEnvData(IMG_PVOID pvEnvSpecificData)
-{
- ENV_DATA *psEnvData = (ENV_DATA*)pvEnvSpecificData;
-
- PVR_ASSERT(!psEnvData->bMISRInstalled);
- PVR_ASSERT(!psEnvData->bLISRInstalled);
-
- OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, PVRSRV_MAX_BRIDGE_IN_SIZE + PVRSRV_MAX_BRIDGE_OUT_SIZE, psEnvData->pvBridgeData, IMG_NULL);
- psEnvData->pvBridgeData = IMG_NULL;
-
- OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(ENV_DATA), pvEnvSpecificData, IMG_NULL);
-
-
- return PVRSRV_OK;
-}
-
-
-
-IMG_VOID OSReleaseThreadQuanta(IMG_VOID)
-{
- schedule();
-}
-
-
-
-IMG_UINT32 OSClockus(IMG_VOID)
-{
- IMG_UINT32 time, j = jiffies;
-
- time = j * (1000000 / HZ);
-
- return time;
-}
-
-
-
-IMG_VOID OSWaitus(IMG_UINT32 ui32Timeus)
-{
- udelay(ui32Timeus);
-}
-
-
-IMG_UINT32 OSGetCurrentProcessIDKM(IMG_VOID)
-{
- if (in_interrupt())
- {
- return KERNEL_ID;
- }
-
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
- return (IMG_UINT32)current->pgrp;
-#else
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24))
- return (IMG_UINT32)task_tgid_nr(current);
-#else
- return (IMG_UINT32)current->tgid;
-#endif
-#endif
-}
-
-
-IMG_UINT32 OSGetPageSize(IMG_VOID)
-{
-#if defined(__sh__)
- IMG_UINT32 ui32ReturnValue = PAGE_SIZE;
-
- return (ui32ReturnValue);
-#else
- return PAGE_SIZE;
-#endif
-}
-
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0))
-static irqreturn_t DeviceISRWrapper(int irq, void *dev_id
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
- , struct pt_regs *regs
-#endif
- )
-{
- PVRSRV_DEVICE_NODE *psDeviceNode;
- IMG_BOOL bStatus = IMG_FALSE;
-
- PVR_UNREFERENCED_PARAMETER(irq);
-
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
- PVR_UNREFERENCED_PARAMETER(regs);
-#endif
- psDeviceNode = (PVRSRV_DEVICE_NODE*)dev_id;
- if(!psDeviceNode)
- {
- PVR_DPF((PVR_DBG_ERROR, "DeviceISRWrapper: invalid params\n"));
- goto out;
- }
-
- bStatus = PVRSRVDeviceLISR(psDeviceNode);
-
- if (bStatus)
- {
- OSScheduleMISR((IMG_VOID *)psDeviceNode->psSysData);
- }
-
-out:
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
- return bStatus ? IRQ_HANDLED : IRQ_NONE;
-#endif
-}
-
-
-
-static irqreturn_t SystemISRWrapper(int irq, void *dev_id
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
- , struct pt_regs *regs
-#endif
- )
-{
- SYS_DATA *psSysData;
- IMG_BOOL bStatus = IMG_FALSE;
-
- PVR_UNREFERENCED_PARAMETER(irq);
-
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
- PVR_UNREFERENCED_PARAMETER(regs);
-#endif
- psSysData = (SYS_DATA *)dev_id;
- if(!psSysData)
- {
- PVR_DPF((PVR_DBG_ERROR, "SystemISRWrapper: invalid params\n"));
- goto out;
- }
-
- bStatus = PVRSRVSystemLISR(psSysData);
-
- if (bStatus)
- {
- OSScheduleMISR((IMG_VOID *)psSysData);
- }
-
-out:
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
- return bStatus ? IRQ_HANDLED : IRQ_NONE;
-#endif
-}
-PVRSRV_ERROR OSInstallDeviceLISR(IMG_VOID *pvSysData,
- IMG_UINT32 ui32Irq,
- IMG_CHAR *pszISRName,
- IMG_VOID *pvDeviceNode)
-{
- SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
- ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
-
- if (psEnvData->bLISRInstalled)
- {
- PVR_DPF((PVR_DBG_ERROR, "OSInstallDeviceLISR: An ISR has already been installed: IRQ %d cookie %x", psEnvData->ui32IRQ, psEnvData->pvISRCookie));
- return PVRSRV_ERROR_GENERIC;
- }
-
- PVR_TRACE(("Installing device LISR %s on IRQ %d with cookie %x", pszISRName, ui32Irq, pvDeviceNode));
-
- if(request_irq(ui32Irq, DeviceISRWrapper,
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22))
- SA_SHIRQ
-#else
- IRQF_SHARED
-#endif
- , pszISRName, pvDeviceNode))
- {
- PVR_DPF((PVR_DBG_ERROR,"OSInstallDeviceLISR: Couldn't install device LISR on IRQ %d", ui32Irq));
-
- return PVRSRV_ERROR_GENERIC;
- }
-
- psEnvData->ui32IRQ = ui32Irq;
- psEnvData->pvISRCookie = pvDeviceNode;
- psEnvData->bLISRInstalled = IMG_TRUE;
-
- return PVRSRV_OK;
-}
-
-PVRSRV_ERROR OSUninstallDeviceLISR(IMG_VOID *pvSysData)
-{
- SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
- ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
-
- if (!psEnvData->bLISRInstalled)
- {
- PVR_DPF((PVR_DBG_ERROR, "OSUninstallDeviceLISR: No LISR has been installed"));
- return PVRSRV_ERROR_GENERIC;
- }
-
- PVR_TRACE(("Uninstalling device LISR on IRQ %d with cookie %x", psEnvData->ui32IRQ, psEnvData->pvISRCookie));
-
- free_irq(psEnvData->ui32IRQ, psEnvData->pvISRCookie);
-
- psEnvData->bLISRInstalled = IMG_FALSE;
-
- return PVRSRV_OK;
-}
-
-
-PVRSRV_ERROR OSInstallSystemLISR(IMG_VOID *pvSysData, IMG_UINT32 ui32Irq)
-{
- SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
- ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
-
- if (psEnvData->bLISRInstalled)
- {
- PVR_DPF((PVR_DBG_ERROR, "OSInstallSystemLISR: An LISR has already been installed: IRQ %d cookie %x", psEnvData->ui32IRQ, psEnvData->pvISRCookie));
- return PVRSRV_ERROR_GENERIC;
- }
-
- PVR_TRACE(("Installing system LISR on IRQ %d with cookie %x", ui32Irq, pvSysData));
-
- if(request_irq(ui32Irq, SystemISRWrapper,
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22))
- SA_SHIRQ
-#else
- IRQF_SHARED
-#endif
- , "PowerVR", pvSysData))
- {
- PVR_DPF((PVR_DBG_ERROR,"OSInstallSystemLISR: Couldn't install system LISR on IRQ %d", ui32Irq));
-
- return PVRSRV_ERROR_GENERIC;
- }
-
- psEnvData->ui32IRQ = ui32Irq;
- psEnvData->pvISRCookie = pvSysData;
- psEnvData->bLISRInstalled = IMG_TRUE;
-
- return PVRSRV_OK;
-}
-
-
-PVRSRV_ERROR OSUninstallSystemLISR(IMG_VOID *pvSysData)
-{
- SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
- ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
-
- if (!psEnvData->bLISRInstalled)
- {
- PVR_DPF((PVR_DBG_ERROR, "OSUninstallSystemLISR: No LISR has been installed"));
- return PVRSRV_ERROR_GENERIC;
- }
-
- PVR_TRACE(("Uninstalling system LISR on IRQ %d with cookie %x", psEnvData->ui32IRQ, psEnvData->pvISRCookie));
-
- free_irq(psEnvData->ui32IRQ, psEnvData->pvISRCookie);
-
- psEnvData->bLISRInstalled = IMG_FALSE;
-
- return PVRSRV_OK;
-}
-
-#if defined(PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE)
-static void MISRWrapper(
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
- void *data
-#else
- struct work_struct *data
-#endif
-)
-{
- ENV_DATA *psEnvData = container_of(data, ENV_DATA, sMISRWork);
- SYS_DATA *psSysData = (SYS_DATA *)psEnvData->pvMISRData;
-
- PVRSRVMISR(psSysData);
-}
-
-
-PVRSRV_ERROR OSInstallMISR(IMG_VOID *pvSysData)
-{
- SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
- ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
-
- if (psEnvData->bMISRInstalled)
- {
- PVR_DPF((PVR_DBG_ERROR, "OSInstallMISR: An MISR has already been installed"));
- return PVRSRV_ERROR_GENERIC;
- }
-
- PVR_TRACE(("Installing MISR with cookie %p", pvSysData));
-
- psEnvData->psWorkQueue = create_singlethread_workqueue("pvr_workqueue");
-
- if (psEnvData->psWorkQueue == IMG_NULL)
- {
- PVR_DPF((PVR_DBG_ERROR, "OSInstallMISR: create_singlethreaded_workqueue failed"));
- return PVRSRV_ERROR_GENERIC;
- }
-
- INIT_WORK(&psEnvData->sMISRWork, MISRWrapper
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
- , (void *)&psEnvData->sMISRWork
-#endif
- );
-
- psEnvData->pvMISRData = pvSysData;
- psEnvData->bMISRInstalled = IMG_TRUE;
-
- return PVRSRV_OK;
-}
-
-
-PVRSRV_ERROR OSUninstallMISR(IMG_VOID *pvSysData)
-{
- SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
- ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
-
- if (!psEnvData->bMISRInstalled)
- {
- PVR_DPF((PVR_DBG_ERROR, "OSUninstallMISR: No MISR has been installed"));
- return PVRSRV_ERROR_GENERIC;
- }
-
- PVR_TRACE(("Uninstalling MISR"));
-
- destroy_workqueue(psEnvData->psWorkQueue);
-
- psEnvData->bMISRInstalled = IMG_FALSE;
-
- return PVRSRV_OK;
-}
-
-
-PVRSRV_ERROR OSScheduleMISR(IMG_VOID *pvSysData)
-{
- SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
- ENV_DATA *psEnvData = (ENV_DATA*)psSysData->pvEnvSpecificData;
-
- if (psEnvData->bMISRInstalled)
- {
- queue_work(psEnvData->psWorkQueue, &psEnvData->sMISRWork);
- }
-
- return PVRSRV_OK;
-}
-#else
-#if defined(PVR_LINUX_MISR_USING_WORKQUEUE)
-static void MISRWrapper(
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
- void *data
-#else
- struct work_struct *data
-#endif
-)
-{
- ENV_DATA *psEnvData = container_of(data, ENV_DATA, sMISRWork);
- SYS_DATA *psSysData = (SYS_DATA *)psEnvData->pvMISRData;
-
- PVRSRVMISR(psSysData);
-}
-
-
-PVRSRV_ERROR OSInstallMISR(IMG_VOID *pvSysData)
-{
- SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
- ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
-
- if (psEnvData->bMISRInstalled)
- {
- PVR_DPF((PVR_DBG_ERROR, "OSInstallMISR: An MISR has already been installed"));
- return PVRSRV_ERROR_GENERIC;
- }
-
- PVR_TRACE(("Installing MISR with cookie %x", pvSysData));
-
- INIT_WORK(&psEnvData->sMISRWork, MISRWrapper
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
- , (void *)&psEnvData->sMISRWork
-#endif
- );
-
- psEnvData->pvMISRData = pvSysData;
- psEnvData->bMISRInstalled = IMG_TRUE;
-
- return PVRSRV_OK;
-}
-
-
-PVRSRV_ERROR OSUninstallMISR(IMG_VOID *pvSysData)
-{
- SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
- ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
-
- if (!psEnvData->bMISRInstalled)
- {
- PVR_DPF((PVR_DBG_ERROR, "OSUninstallMISR: No MISR has been installed"));
- return PVRSRV_ERROR_GENERIC;
- }
-
- PVR_TRACE(("Uninstalling MISR"));
-
- flush_scheduled_work();
-
- psEnvData->bMISRInstalled = IMG_FALSE;
-
- return PVRSRV_OK;
-}
-
-
-PVRSRV_ERROR OSScheduleMISR(IMG_VOID *pvSysData)
-{
- SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
- ENV_DATA *psEnvData = (ENV_DATA*)psSysData->pvEnvSpecificData;
-
- if (psEnvData->bMISRInstalled)
- {
- schedule_work(&psEnvData->sMISRWork);
- }
-
- return PVRSRV_OK;
-}
-
-#else
-
-
-static void MISRWrapper(unsigned long data)
-{
- SYS_DATA *psSysData;
-
- psSysData = (SYS_DATA *)data;
-
- PVRSRVMISR(psSysData);
-}
-
-
-PVRSRV_ERROR OSInstallMISR(IMG_VOID *pvSysData)
-{
- SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
- ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
-
- if (psEnvData->bMISRInstalled)
- {
- PVR_DPF((PVR_DBG_ERROR, "OSInstallMISR: An MISR has already been installed"));
- return PVRSRV_ERROR_GENERIC;
- }
-
- PVR_TRACE(("Installing MISR with cookie %x", pvSysData));
-
- tasklet_init(&psEnvData->sMISRTasklet, MISRWrapper, (unsigned long)pvSysData);
-
- psEnvData->bMISRInstalled = IMG_TRUE;
-
- return PVRSRV_OK;
-}
-
-
-PVRSRV_ERROR OSUninstallMISR(IMG_VOID *pvSysData)
-{
- SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
- ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
-
- if (!psEnvData->bMISRInstalled)
- {
- PVR_DPF((PVR_DBG_ERROR, "OSUninstallMISR: No MISR has been installed"));
- return PVRSRV_ERROR_GENERIC;
- }
-
- PVR_TRACE(("Uninstalling MISR"));
-
- tasklet_kill(&psEnvData->sMISRTasklet);
-
- psEnvData->bMISRInstalled = IMG_FALSE;
-
- return PVRSRV_OK;
-}
-
-PVRSRV_ERROR OSScheduleMISR(IMG_VOID *pvSysData)
-{
- SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
- ENV_DATA *psEnvData = (ENV_DATA*)psSysData->pvEnvSpecificData;
-
- if (psEnvData->bMISRInstalled)
- {
- tasklet_schedule(&psEnvData->sMISRTasklet);
- }
-
- return PVRSRV_OK;
-}
-
-#endif
-#endif
-
-#endif
-
-IMG_VOID OSPanic(IMG_VOID)
-{
- BUG();
-}
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22))
-#define OS_TAS(p) xchg((p), 1)
-#else
-#define OS_TAS(p) tas(p)
-#endif
-PVRSRV_ERROR OSLockResource ( PVRSRV_RESOURCE *psResource,
- IMG_UINT32 ui32ID)
-
-{
- PVRSRV_ERROR eError = PVRSRV_OK;
-
- if(!OS_TAS(&psResource->ui32Lock))
- psResource->ui32ID = ui32ID;
- else
- eError = PVRSRV_ERROR_GENERIC;
-
- return eError;
-}
-
-
-PVRSRV_ERROR OSUnlockResource (PVRSRV_RESOURCE *psResource, IMG_UINT32 ui32ID)
-{
- volatile IMG_UINT32 *pui32Access = (volatile IMG_UINT32 *)&psResource->ui32Lock;
- PVRSRV_ERROR eError = PVRSRV_OK;
-
- if(*pui32Access)
- {
- if(psResource->ui32ID == ui32ID)
- {
- psResource->ui32ID = 0;
- *pui32Access = 0;
- }
- else
- {
- PVR_DPF((PVR_DBG_ERROR,"OSUnlockResource: Resource %p is not locked with expected value.", psResource));
- PVR_DPF((PVR_DBG_MESSAGE,"Should be %x is actually %x", ui32ID, psResource->ui32ID));
- eError = PVRSRV_ERROR_GENERIC;
- }
- }
- else
- {
- PVR_DPF((PVR_DBG_ERROR,"OSUnlockResource: Resource %p is not locked", psResource));
- eError = PVRSRV_ERROR_GENERIC;
- }
-
- return eError;
-}
-
-
-IMG_BOOL OSIsResourceLocked (PVRSRV_RESOURCE *psResource, IMG_UINT32 ui32ID)
-{
- volatile IMG_UINT32 *pui32Access = (volatile IMG_UINT32 *)&psResource->ui32Lock;
-
- return (*(volatile IMG_UINT32 *)pui32Access == 1) && (psResource->ui32ID == ui32ID)
- ? IMG_TRUE
- : IMG_FALSE;
-}
-
-
-IMG_CPU_PHYADDR OSMapLinToCPUPhys(IMG_VOID *pvLinAddr)
-{
- IMG_CPU_PHYADDR CpuPAddr;
-
- CpuPAddr.uiAddr = (IMG_UINTPTR_T)VMallocToPhys(pvLinAddr);
-
- return CpuPAddr;
-}
-
-
-IMG_VOID *
-OSMapPhysToLin(IMG_CPU_PHYADDR BasePAddr,
- IMG_UINT32 ui32Bytes,
- IMG_UINT32 ui32MappingFlags,
- IMG_HANDLE *phOSMemHandle)
-{
- if(phOSMemHandle)
- {
- *phOSMemHandle = (IMG_HANDLE)0;
- }
-
- if(ui32MappingFlags & PVRSRV_HAP_KERNEL_ONLY)
- {
- IMG_VOID *pvIORemapCookie;
- pvIORemapCookie = IORemapWrapper(BasePAddr, ui32Bytes, ui32MappingFlags);
- if(pvIORemapCookie == IMG_NULL)
- {
- return NULL;
- }
- return pvIORemapCookie;
- }
- else
- {
- PVR_DPF((PVR_DBG_ERROR,
- "OSMapPhysToLin should only be used with PVRSRV_HAP_KERNEL_ONLY "
- " (Use OSReservePhys otherwise)"));
- return NULL;
- }
-}
-
-IMG_BOOL
-OSUnMapPhysToLin(IMG_VOID *pvLinAddr, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32MappingFlags, IMG_HANDLE hPageAlloc)
-{
- PVR_TRACE(("%s: unmapping %d bytes from 0x%08x", __FUNCTION__, ui32Bytes, pvLinAddr));
-
- PVR_UNREFERENCED_PARAMETER(hPageAlloc);
- PVR_UNREFERENCED_PARAMETER(ui32Bytes);
-
- if(ui32MappingFlags & PVRSRV_HAP_KERNEL_ONLY)
- {
- IOUnmapWrapper(pvLinAddr);
- return IMG_TRUE;
- }
- else
- {
- PVR_DPF((PVR_DBG_ERROR,
- "OSUnMapPhysToLin should only be used with PVRSRV_HAP_KERNEL_ONLY "
- " (Use OSUnReservePhys otherwise)"));
- return IMG_FALSE;
- }
-}
-
-static PVRSRV_ERROR
-RegisterExternalMem(IMG_SYS_PHYADDR *pBasePAddr,
- IMG_VOID *pvCPUVAddr,
- IMG_UINT32 ui32Bytes,
- IMG_BOOL bPhysContig,
- IMG_UINT32 ui32MappingFlags,
- IMG_HANDLE *phOSMemHandle)
-{
- LinuxMemArea *psLinuxMemArea;
-
- switch(ui32MappingFlags & PVRSRV_HAP_MAPTYPE_MASK)
- {
- case PVRSRV_HAP_KERNEL_ONLY:
- {
- psLinuxMemArea = NewExternalKVLinuxMemArea(pBasePAddr, pvCPUVAddr, ui32Bytes, bPhysContig, ui32MappingFlags);
-
- if(!psLinuxMemArea)
- {
- return PVRSRV_ERROR_GENERIC;
- }
- break;
- }
- case PVRSRV_HAP_SINGLE_PROCESS:
- {
- psLinuxMemArea = NewExternalKVLinuxMemArea(pBasePAddr, pvCPUVAddr, ui32Bytes, bPhysContig, ui32MappingFlags);
-
- if(!psLinuxMemArea)
- {
- return PVRSRV_ERROR_GENERIC;
- }
- PVRMMapRegisterArea(psLinuxMemArea);
- break;
- }
- case PVRSRV_HAP_MULTI_PROCESS:
- {
-
-#if defined(VIVT_CACHE) || defined(__sh__)
-
- ui32MappingFlags &= ~PVRSRV_HAP_CACHED;
-#endif
- psLinuxMemArea = NewExternalKVLinuxMemArea(pBasePAddr, pvCPUVAddr, ui32Bytes, bPhysContig, ui32MappingFlags);
-
- if(!psLinuxMemArea)
- {
- return PVRSRV_ERROR_GENERIC;
- }
- PVRMMapRegisterArea(psLinuxMemArea);
- break;
- }
- default:
- PVR_DPF((PVR_DBG_ERROR,"OSRegisterMem : invalid flags 0x%x\n", ui32MappingFlags));
- *phOSMemHandle = (IMG_HANDLE)0;
- return PVRSRV_ERROR_GENERIC;
- }
-
- *phOSMemHandle = (IMG_HANDLE)psLinuxMemArea;
-
- LinuxMemAreaRegister(psLinuxMemArea);
-
- return PVRSRV_OK;
-}
-
-
-PVRSRV_ERROR
-OSRegisterMem(IMG_CPU_PHYADDR BasePAddr,
- IMG_VOID *pvCPUVAddr,
- IMG_UINT32 ui32Bytes,
- IMG_UINT32 ui32MappingFlags,
- IMG_HANDLE *phOSMemHandle)
-{
- IMG_SYS_PHYADDR SysPAddr = SysCpuPAddrToSysPAddr(BasePAddr);
-
- return RegisterExternalMem(&SysPAddr, pvCPUVAddr, ui32Bytes, IMG_TRUE, ui32MappingFlags, phOSMemHandle);
-}
-
-
-PVRSRV_ERROR OSRegisterDiscontigMem(IMG_SYS_PHYADDR *pBasePAddr, IMG_VOID *pvCPUVAddr, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32MappingFlags, IMG_HANDLE *phOSMemHandle)
-{
- return RegisterExternalMem(pBasePAddr, pvCPUVAddr, ui32Bytes, IMG_FALSE, ui32MappingFlags, phOSMemHandle);
-}
-
-
-PVRSRV_ERROR
-OSUnRegisterMem (IMG_VOID *pvCpuVAddr,
- IMG_UINT32 ui32Bytes,
- IMG_UINT32 ui32MappingFlags,
- IMG_HANDLE hOSMemHandle)
-{
- LinuxMemArea *psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
-
- PVR_UNREFERENCED_PARAMETER(pvCpuVAddr);
- PVR_UNREFERENCED_PARAMETER(ui32Bytes);
-
- switch(ui32MappingFlags & PVRSRV_HAP_MAPTYPE_MASK)
- {
- case PVRSRV_HAP_KERNEL_ONLY:
- break;
- case PVRSRV_HAP_SINGLE_PROCESS:
- case PVRSRV_HAP_MULTI_PROCESS:
- {
- if(PVRMMapRemoveRegisteredArea(psLinuxMemArea) != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "%s(%p, %d, 0x%08X, %p) FAILED!",
- __FUNCTION__, pvCpuVAddr, ui32Bytes,
- ui32MappingFlags, hOSMemHandle));
- return PVRSRV_ERROR_GENERIC;
- }
- break;
- }
- default:
- {
- PVR_DPF((PVR_DBG_ERROR, "OSUnRegisterMem : invalid flags 0x%x", ui32MappingFlags));
- return PVRSRV_ERROR_INVALID_PARAMS;
- }
- }
-
- LinuxMemAreaDeepFree(psLinuxMemArea);
-
- return PVRSRV_OK;
-}
-
-PVRSRV_ERROR OSUnRegisterDiscontigMem(IMG_VOID *pvCpuVAddr, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32Flags, IMG_HANDLE hOSMemHandle)
-{
- return OSUnRegisterMem(pvCpuVAddr, ui32Bytes, ui32Flags, hOSMemHandle);
-}
-
-PVRSRV_ERROR
-OSReservePhys(IMG_CPU_PHYADDR BasePAddr,
- IMG_UINT32 ui32Bytes,
- IMG_UINT32 ui32MappingFlags,
- IMG_VOID **ppvCpuVAddr,
- IMG_HANDLE *phOSMemHandle)
-{
- LinuxMemArea *psLinuxMemArea;
-
-#if 0
-
- if(ui32MappingFlags & PVRSRV_HAP_SINGLE_PROCESS)
- {
- ui32MappingFlags &= ~PVRSRV_HAP_SINGLE_PROCESS;
- ui32MappingFlags |= PVRSRV_HAP_MULTI_PROCESS;
- }
-#endif
-
- switch(ui32MappingFlags & PVRSRV_HAP_MAPTYPE_MASK)
- {
- case PVRSRV_HAP_KERNEL_ONLY:
- {
-
- psLinuxMemArea = NewIORemapLinuxMemArea(BasePAddr, ui32Bytes, ui32MappingFlags);
- if(!psLinuxMemArea)
- {
- return PVRSRV_ERROR_GENERIC;
- }
- break;
- }
- case PVRSRV_HAP_SINGLE_PROCESS:
- {
-
- psLinuxMemArea = NewIOLinuxMemArea(BasePAddr, ui32Bytes, ui32MappingFlags);
- if(!psLinuxMemArea)
- {
- return PVRSRV_ERROR_GENERIC;
- }
- PVRMMapRegisterArea(psLinuxMemArea);
- break;
- }
- case PVRSRV_HAP_MULTI_PROCESS:
- {
-
-#if defined(VIVT_CACHE) || defined(__sh__)
-
- ui32MappingFlags &= ~PVRSRV_HAP_CACHED;
-#endif
- psLinuxMemArea = NewIORemapLinuxMemArea(BasePAddr, ui32Bytes, ui32MappingFlags);
- if(!psLinuxMemArea)
- {
- return PVRSRV_ERROR_GENERIC;
- }
- PVRMMapRegisterArea(psLinuxMemArea);
- break;
- }
- default:
- PVR_DPF((PVR_DBG_ERROR,"OSMapPhysToLin : invalid flags 0x%x\n", ui32MappingFlags));
- *ppvCpuVAddr = NULL;
- *phOSMemHandle = (IMG_HANDLE)0;
- return PVRSRV_ERROR_GENERIC;
- }
-
- *phOSMemHandle = (IMG_HANDLE)psLinuxMemArea;
- *ppvCpuVAddr = LinuxMemAreaToCpuVAddr(psLinuxMemArea);
-
- LinuxMemAreaRegister(psLinuxMemArea);
-
- return PVRSRV_OK;
-}
-
-PVRSRV_ERROR
-OSUnReservePhys(IMG_VOID *pvCpuVAddr,
- IMG_UINT32 ui32Bytes,
- IMG_UINT32 ui32MappingFlags,
- IMG_HANDLE hOSMemHandle)
-{
- LinuxMemArea *psLinuxMemArea;
-
- PVR_UNREFERENCED_PARAMETER(pvCpuVAddr);
- PVR_UNREFERENCED_PARAMETER(ui32Bytes);
-
- psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
-
- switch(ui32MappingFlags & PVRSRV_HAP_MAPTYPE_MASK)
- {
- case PVRSRV_HAP_KERNEL_ONLY:
- break;
- case PVRSRV_HAP_SINGLE_PROCESS:
- case PVRSRV_HAP_MULTI_PROCESS:
- {
- if(PVRMMapRemoveRegisteredArea(psLinuxMemArea) != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "%s(%p, %d, 0x%08X, %p) FAILED!",
- __FUNCTION__, pvCpuVAddr, ui32Bytes,
- ui32MappingFlags, hOSMemHandle));
- return PVRSRV_ERROR_GENERIC;
- }
- break;
- }
- default:
- {
- PVR_DPF((PVR_DBG_ERROR, "OSUnMapPhysToLin : invalid flags 0x%x", ui32MappingFlags));
- return PVRSRV_ERROR_INVALID_PARAMS;
- }
- }
-
- LinuxMemAreaDeepFree(psLinuxMemArea);
-
- return PVRSRV_OK;
-}
-
-
-PVRSRV_ERROR OSBaseAllocContigMemory(IMG_UINT32 ui32Size, IMG_CPU_VIRTADDR *pvLinAddr, IMG_CPU_PHYADDR *psPhysAddr)
-{
-#if !defined(NO_HARDWARE)
- PVR_UNREFERENCED_PARAMETER(ui32Size);
- PVR_UNREFERENCED_PARAMETER(pvLinAddr);
- PVR_UNREFERENCED_PARAMETER(psPhysAddr);
- PVR_DPF((PVR_DBG_ERROR, "%s: Not available", __FUNCTION__));
-
- return PVRSRV_ERROR_OUT_OF_MEMORY;
-#else
- IMG_VOID *pvKernLinAddr;
-
-#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
- pvKernLinAddr = _KMallocWrapper(ui32Size, __FILE__, __LINE__);
-#else
- pvKernLinAddr = KMallocWrapper(ui32Size);
-#endif
- if (!pvKernLinAddr)
- {
- return PVRSRV_ERROR_OUT_OF_MEMORY;
- }
-
- *pvLinAddr = pvKernLinAddr;
-
- psPhysAddr->uiAddr = virt_to_phys(pvKernLinAddr);
-
- return PVRSRV_OK;
-#endif
-}
-
-
-PVRSRV_ERROR OSBaseFreeContigMemory(IMG_UINT32 ui32Size, IMG_CPU_VIRTADDR pvLinAddr, IMG_CPU_PHYADDR psPhysAddr)
-{
-#if !defined(NO_HARDWARE)
- PVR_UNREFERENCED_PARAMETER(ui32Size);
- PVR_UNREFERENCED_PARAMETER(pvLinAddr);
- PVR_UNREFERENCED_PARAMETER(psPhysAddr.uiAddr);
-
- PVR_DPF((PVR_DBG_WARNING, "%s: Not available", __FUNCTION__));
-#else
- PVR_UNREFERENCED_PARAMETER(ui32Size);
- PVR_UNREFERENCED_PARAMETER(psPhysAddr.uiAddr);
-
- KFreeWrapper(pvLinAddr);
-#endif
- return PVRSRV_OK;
-}
-
-IMG_UINT32 OSReadHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset)
-{
-#if !defined(NO_HARDWARE)
- return (IMG_UINT32) readl((IMG_PBYTE)pvLinRegBaseAddr+ui32Offset);
-#else
- return *(IMG_UINT32 *)((IMG_PBYTE)pvLinRegBaseAddr+ui32Offset);
-#endif
-}
-
-IMG_VOID OSWriteHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value)
-{
-#if !defined(NO_HARDWARE)
- writel(ui32Value, (IMG_PBYTE)pvLinRegBaseAddr+ui32Offset);
-#else
- *(IMG_UINT32 *)((IMG_PBYTE)pvLinRegBaseAddr+ui32Offset) = ui32Value;
-#endif
-}
-
-#if defined(CONFIG_PCI) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14))
-
-PVRSRV_PCI_DEV_HANDLE OSPCISetDev(IMG_VOID *pvPCICookie, HOST_PCI_INIT_FLAGS eFlags)
-{
- int err;
- IMG_UINT32 i;
- PVR_PCI_DEV *psPVRPCI;
-
- PVR_TRACE(("OSPCISetDev"));
-
- if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*psPVRPCI), (IMG_VOID **)&psPVRPCI, IMG_NULL,
- "PCI Device") != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "OSPCISetDev: Couldn't allocate PVR PCI structure"));
- return IMG_NULL;
- }
-
- psPVRPCI->psPCIDev = (struct pci_dev *)pvPCICookie;
- psPVRPCI->ePCIFlags = eFlags;
-
- err = pci_enable_device(psPVRPCI->psPCIDev);
- if (err != 0)
- {
- PVR_DPF((PVR_DBG_ERROR, "OSPCISetDev: Couldn't enable device (%d)", err));
- return IMG_NULL;
- }
-
- if (psPVRPCI->ePCIFlags & HOST_PCI_INIT_FLAG_BUS_MASTER)
- {
- pci_set_master(psPVRPCI->psPCIDev);
- }
-
- if (psPVRPCI->ePCIFlags & HOST_PCI_INIT_FLAG_MSI)
- {
-#if defined(CONFIG_PCI_MSI)
- err = pci_enable_msi(psPVRPCI->psPCIDev);
- if (err != 0)
- {
- PVR_DPF((PVR_DBG_WARNING, "OSPCISetDev: Couldn't enable MSI (%d)", err));
- psPVRPCI->ePCIFlags &= ~HOST_PCI_INIT_FLAG_MSI;
- }
-#else
- PVR_DPF((PVR_DBG_WARNING, "OSPCISetDev: MSI support not enabled in the kernel"));
-#endif
- }
-
-
- for (i = 0; i < DEVICE_COUNT_RESOURCE; i++)
- {
- psPVRPCI->abPCIResourceInUse[i] = IMG_FALSE;
- }
-
- return (PVRSRV_PCI_DEV_HANDLE)psPVRPCI;
-}
-
-PVRSRV_PCI_DEV_HANDLE OSPCIAcquireDev(IMG_UINT16 ui16VendorID, IMG_UINT16 ui16DeviceID, HOST_PCI_INIT_FLAGS eFlags)
-{
- struct pci_dev *psPCIDev;
-
- psPCIDev = pci_get_device(ui16VendorID, ui16DeviceID, NULL);
- if (psPCIDev == NULL)
- {
- PVR_DPF((PVR_DBG_ERROR, "OSPCIAcquireDev: Couldn't acquire device"));
- return IMG_NULL;
- }
-
- return OSPCISetDev((IMG_VOID *)psPCIDev, eFlags);
-}
-
-PVRSRV_ERROR OSPCIIRQ(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 *pui32IRQ)
-{
- PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI;
-
- *pui32IRQ = psPVRPCI->psPCIDev->irq;
-
- return PVRSRV_OK;
-}
-
-enum HOST_PCI_ADDR_RANGE_FUNC
-{
- HOST_PCI_ADDR_RANGE_FUNC_LEN,
- HOST_PCI_ADDR_RANGE_FUNC_START,
- HOST_PCI_ADDR_RANGE_FUNC_END,
- HOST_PCI_ADDR_RANGE_FUNC_REQUEST,
- HOST_PCI_ADDR_RANGE_FUNC_RELEASE
-};
-
-static IMG_UINT32 OSPCIAddrRangeFunc(enum HOST_PCI_ADDR_RANGE_FUNC eFunc,
- PVRSRV_PCI_DEV_HANDLE hPVRPCI,
- IMG_UINT32 ui32Index)
-{
- PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI;
-
- if (ui32Index >= DEVICE_COUNT_RESOURCE)
- {
- PVR_DPF((PVR_DBG_ERROR, "OSPCIAddrRangeFunc: Index out of range"));
- return 0;
-
- }
-
- switch (eFunc)
- {
- case HOST_PCI_ADDR_RANGE_FUNC_LEN:
- return pci_resource_len(psPVRPCI->psPCIDev, ui32Index);
- case HOST_PCI_ADDR_RANGE_FUNC_START:
- return pci_resource_start(psPVRPCI->psPCIDev, ui32Index);
- case HOST_PCI_ADDR_RANGE_FUNC_END:
- return pci_resource_end(psPVRPCI->psPCIDev, ui32Index);
- case HOST_PCI_ADDR_RANGE_FUNC_REQUEST:
- {
- int err;
-
- err = pci_request_region(psPVRPCI->psPCIDev, (IMG_INT)ui32Index, "PowerVR");
- if (err != 0)
- {
- PVR_DPF((PVR_DBG_ERROR, "OSPCIAddrRangeFunc: pci_request_region_failed (%d)", err));
- return 0;
- }
- psPVRPCI->abPCIResourceInUse[ui32Index] = IMG_TRUE;
- return 1;
- }
- case HOST_PCI_ADDR_RANGE_FUNC_RELEASE:
- if (psPVRPCI->abPCIResourceInUse[ui32Index])
- {
- pci_release_region(psPVRPCI->psPCIDev, (IMG_INT)ui32Index);
- psPVRPCI->abPCIResourceInUse[ui32Index] = IMG_FALSE;
- }
- return 1;
- default:
- PVR_DPF((PVR_DBG_ERROR, "OSPCIAddrRangeFunc: Unknown function"));
- break;
- }
-
- return 0;
-}
-
-IMG_UINT32 OSPCIAddrRangeLen(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index)
-{
- return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_LEN, hPVRPCI, ui32Index);
-}
-
-IMG_UINT32 OSPCIAddrRangeStart(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index)
-{
- return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_START, hPVRPCI, ui32Index);
-}
-
-IMG_UINT32 OSPCIAddrRangeEnd(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index)
-{
- return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_END, hPVRPCI, ui32Index);
-}
-
-PVRSRV_ERROR OSPCIRequestAddrRange(PVRSRV_PCI_DEV_HANDLE hPVRPCI,
- IMG_UINT32 ui32Index)
-{
- return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_REQUEST, hPVRPCI, ui32Index) == 0 ? PVRSRV_ERROR_GENERIC : PVRSRV_OK;
-}
-
-PVRSRV_ERROR OSPCIReleaseAddrRange(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index)
-{
- return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_RELEASE, hPVRPCI, ui32Index) == 0 ? PVRSRV_ERROR_GENERIC : PVRSRV_OK;
-}
-
-PVRSRV_ERROR OSPCIReleaseDev(PVRSRV_PCI_DEV_HANDLE hPVRPCI)
-{
- PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI;
- int i;
-
- PVR_TRACE(("OSPCIReleaseDev"));
-
-
- for (i = 0; i < DEVICE_COUNT_RESOURCE; i++)
- {
- if (psPVRPCI->abPCIResourceInUse[i])
- {
- PVR_TRACE(("OSPCIReleaseDev: Releasing Address range %d", i));
- pci_release_region(psPVRPCI->psPCIDev, i);
- psPVRPCI->abPCIResourceInUse[i] = IMG_FALSE;
- }
- }
-
-#if defined(CONFIG_PCI_MSI)
- if (psPVRPCI->ePCIFlags & HOST_PCI_INIT_FLAG_MSI)
- {
- pci_disable_msi(psPVRPCI->psPCIDev);
- }
-#endif
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29))
- if (psPVRPCI->ePCIFlags & HOST_PCI_INIT_FLAG_BUS_MASTER)
- {
- pci_clear_master(psPVRPCI->psPCIDev);
- }
-#endif
- pci_disable_device(psPVRPCI->psPCIDev);
-
- OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*psPVRPCI), (IMG_VOID *)psPVRPCI, IMG_NULL);
-
-
- return PVRSRV_OK;
-}
-
-PVRSRV_ERROR OSPCISuspendDev(PVRSRV_PCI_DEV_HANDLE hPVRPCI)
-{
- PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI;
- int i;
- int err;
-
- PVR_TRACE(("OSPCISuspendDev"));
-
-
- for (i = 0; i < DEVICE_COUNT_RESOURCE; i++)
- {
- if (psPVRPCI->abPCIResourceInUse[i])
- {
- pci_release_region(psPVRPCI->psPCIDev, i);
- }
- }
-
- err = pci_save_state(psPVRPCI->psPCIDev);
- if (err != 0)
- {
- PVR_DPF((PVR_DBG_ERROR, "OSPCISuspendDev: pci_save_state_failed (%d)", err));
- return PVRSRV_ERROR_GENERIC;
- }
-
- pci_disable_device(psPVRPCI->psPCIDev);
-
- err = pci_set_power_state(psPVRPCI->psPCIDev, pci_choose_state(psPVRPCI->psPCIDev, PMSG_SUSPEND));
- switch(err)
- {
- case 0:
- break;
- case -EIO:
- PVR_DPF((PVR_DBG_WARNING, "OSPCISuspendDev: device doesn't support PCI PM"));
- break;
- case -EINVAL:
- PVR_DPF((PVR_DBG_ERROR, "OSPCISuspendDev: can't enter requested power state"));
- break;
- default:
- PVR_DPF((PVR_DBG_ERROR, "OSPCISuspendDev: pci_set_power_state failed (%d)", err));
- break;
- }
-
- return PVRSRV_OK;
-}
-
-PVRSRV_ERROR OSPCIResumeDev(PVRSRV_PCI_DEV_HANDLE hPVRPCI)
-{
- PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI;
- int err;
- int i;
-
- PVR_TRACE(("OSPCIResumeDev"));
-
- err = pci_set_power_state(psPVRPCI->psPCIDev, pci_choose_state(psPVRPCI->psPCIDev, PMSG_ON));
- switch(err)
- {
- case 0:
- break;
- case -EIO:
- PVR_DPF((PVR_DBG_WARNING, "OSPCIResumeDev: device doesn't support PCI PM"));
- break;
- case -EINVAL:
- PVR_DPF((PVR_DBG_ERROR, "OSPCIResumeDev: can't enter requested power state"));
- return PVRSRV_ERROR_GENERIC;
- default:
- PVR_DPF((PVR_DBG_ERROR, "OSPCIResumeDev: pci_set_power_state failed (%d)", err));
- return PVRSRV_ERROR_GENERIC;
- }
-
- err = pci_restore_state(psPVRPCI->psPCIDev);
- if (err != 0)
- {
- PVR_DPF((PVR_DBG_ERROR, "OSPCIResumeDev: pci_restore_state failed (%d)", err));
- return PVRSRV_ERROR_GENERIC;
- }
-
- err = pci_enable_device(psPVRPCI->psPCIDev);
- if (err != 0)
- {
- PVR_DPF((PVR_DBG_ERROR, "OSPCIResumeDev: Couldn't enable device (%d)", err));
- return PVRSRV_ERROR_GENERIC;
- }
-
- if (psPVRPCI->ePCIFlags & HOST_PCI_INIT_FLAG_BUS_MASTER)
- pci_set_master(psPVRPCI->psPCIDev);
-
-
- for (i = 0; i < DEVICE_COUNT_RESOURCE; i++)
- {
- if (psPVRPCI->abPCIResourceInUse[i])
- {
- err = pci_request_region(psPVRPCI->psPCIDev, i, "PowerVR");
- if (err != 0)
- {
- PVR_DPF((PVR_DBG_ERROR, "OSPCIResumeDev: pci_request_region_failed (region %d, error %d)", i, err));
- }
- }
-
- }
-
- return PVRSRV_OK;
-}
-
-#endif
-
-#define OS_MAX_TIMERS 8
-
-typedef struct TIMER_CALLBACK_DATA_TAG
-{
- IMG_BOOL bInUse;
- PFN_TIMER_FUNC pfnTimerFunc;
- IMG_VOID *pvData;
- struct timer_list sTimer;
- IMG_UINT32 ui32Delay;
- IMG_BOOL bActive;
-#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
- struct work_struct sWork;
-#endif
-}TIMER_CALLBACK_DATA;
-
-#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
-static struct workqueue_struct *psTimerWorkQueue;
-#endif
-
-static TIMER_CALLBACK_DATA sTimers[OS_MAX_TIMERS];
-
-#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
-DEFINE_MUTEX(sTimerStructLock);
-#else
-static spinlock_t sTimerStructLock = SPIN_LOCK_UNLOCKED;
-#endif
-
-static void OSTimerCallbackBody(TIMER_CALLBACK_DATA *psTimerCBData)
-{
- if (!psTimerCBData->bActive)
- return;
-
-
- psTimerCBData->pfnTimerFunc(psTimerCBData->pvData);
-
-
- mod_timer(&psTimerCBData->sTimer, psTimerCBData->ui32Delay + jiffies);
-}
-
-
-#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
-static void OSTimerWorkQueueCallBack(struct work_struct *psWork)
-{
- TIMER_CALLBACK_DATA *psTimerCBData = container_of(psWork, TIMER_CALLBACK_DATA, sWork);
-
- OSTimerCallbackBody(psTimerCBData);
-}
-#endif
-
-static IMG_VOID OSTimerCallbackWrapper(IMG_UINT32 ui32Data)
-{
- TIMER_CALLBACK_DATA *psTimerCBData = (TIMER_CALLBACK_DATA*)ui32Data;
-
-#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
- int res;
-
- res = queue_work(psTimerWorkQueue, &psTimerCBData->sWork);
- if (res == 0)
- {
- PVR_DPF((PVR_DBG_WARNING, "OSTimerCallbackWrapper: work already queued"));
- }
-#else
- OSTimerCallbackBody(psTimerCBData);
-#endif
-}
-
-
-IMG_HANDLE OSAddTimer(PFN_TIMER_FUNC pfnTimerFunc, IMG_VOID *pvData, IMG_UINT32 ui32MsTimeout)
-{
- TIMER_CALLBACK_DATA *psTimerCBData;
- IMG_UINT32 ui32i;
-#if !defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
- unsigned long ulLockFlags;
-#endif
-
-
- if(!pfnTimerFunc)
- {
- PVR_DPF((PVR_DBG_ERROR, "OSAddTimer: passed invalid callback"));
- return IMG_NULL;
- }
-
-
-#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
- mutex_lock(&sTimerStructLock);
-#else
- spin_lock_irqsave(&sTimerStructLock, ulLockFlags);
-#endif
- for (ui32i = 0; ui32i < OS_MAX_TIMERS; ui32i++)
- {
- psTimerCBData = &sTimers[ui32i];
- if (!psTimerCBData->bInUse)
- {
- psTimerCBData->bInUse = IMG_TRUE;
- break;
- }
- }
-#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
- mutex_unlock(&sTimerStructLock);
-#else
- spin_unlock_irqrestore(&sTimerStructLock, ulLockFlags);
-#endif
- if (ui32i >= OS_MAX_TIMERS)
- {
- PVR_DPF((PVR_DBG_ERROR, "OSAddTimer: all timers are in use"));
- return IMG_NULL;
- }
-
- psTimerCBData->pfnTimerFunc = pfnTimerFunc;
- psTimerCBData->pvData = pvData;
- psTimerCBData->bActive = IMG_FALSE;
-
-
-
-
- psTimerCBData->ui32Delay = ((HZ * ui32MsTimeout) < 1000)
- ? 1
- : ((HZ * ui32MsTimeout) / 1000);
-
- init_timer(&psTimerCBData->sTimer);
-
-
- psTimerCBData->sTimer.function = (IMG_VOID *)OSTimerCallbackWrapper;
- psTimerCBData->sTimer.data = (IMG_UINT32)psTimerCBData;
- psTimerCBData->sTimer.expires = psTimerCBData->ui32Delay + jiffies;
-
- return (IMG_HANDLE)(ui32i + 1);
-}
-
-
-static inline TIMER_CALLBACK_DATA *GetTimerStructure(IMG_HANDLE hTimer)
-{
- IMG_UINT32 ui32i = ((IMG_UINT32)hTimer) - 1;
-
- PVR_ASSERT(ui32i < OS_MAX_TIMERS);
-
- return &sTimers[ui32i];
-}
-
-PVRSRV_ERROR OSRemoveTimer (IMG_HANDLE hTimer)
-{
- TIMER_CALLBACK_DATA *psTimerCBData = GetTimerStructure(hTimer);
-
- PVR_ASSERT(psTimerCBData->bInUse);
- PVR_ASSERT(!psTimerCBData->bActive);
-
-
- psTimerCBData->bInUse = IMG_FALSE;
-
- return PVRSRV_OK;
-}
-
-
-PVRSRV_ERROR OSEnableTimer (IMG_HANDLE hTimer)
-{
- TIMER_CALLBACK_DATA *psTimerCBData = GetTimerStructure(hTimer);
-
- PVR_ASSERT(psTimerCBData->bInUse);
- PVR_ASSERT(!psTimerCBData->bActive);
-
-
- psTimerCBData->bActive = IMG_TRUE;
-
-
- psTimerCBData->sTimer.expires = psTimerCBData->ui32Delay + jiffies;
-
-
- add_timer(&psTimerCBData->sTimer);
-
- return PVRSRV_OK;
-}
-
-
-PVRSRV_ERROR OSDisableTimer (IMG_HANDLE hTimer)
-{
- TIMER_CALLBACK_DATA *psTimerCBData = GetTimerStructure(hTimer);
-
- PVR_ASSERT(psTimerCBData->bInUse);
- PVR_ASSERT(psTimerCBData->bActive);
-
-
- psTimerCBData->bActive = IMG_FALSE;
- smp_mb();
-
-#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
- flush_workqueue(psTimerWorkQueue);
-#endif
-
-
- del_timer_sync(&psTimerCBData->sTimer);
-
-#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
-
- flush_workqueue(psTimerWorkQueue);
-#endif
-
- return PVRSRV_OK;
-}
-
-
-PVRSRV_ERROR OSEventObjectCreate(const IMG_CHAR *pszName, PVRSRV_EVENTOBJECT *psEventObject)
-{
-
- PVRSRV_ERROR eError = PVRSRV_OK;
-
- if(psEventObject)
- {
- if(pszName)
- {
-
- strncpy(psEventObject->szName, pszName, EVENTOBJNAME_MAXLENGTH);
- }
- else
- {
-
- static IMG_UINT16 ui16NameIndex = 0;
- snprintf(psEventObject->szName, EVENTOBJNAME_MAXLENGTH, "PVRSRV_EVENTOBJECT_%d", ui16NameIndex++);
- }
-
- if(LinuxEventObjectListCreate(&psEventObject->hOSEventKM) != PVRSRV_OK)
- {
- eError = PVRSRV_ERROR_OUT_OF_MEMORY;
- }
-
- }
- else
- {
- PVR_DPF((PVR_DBG_ERROR, "OSEventObjectCreate: psEventObject is not a valid pointer"));
- eError = PVRSRV_ERROR_GENERIC;
- }
-
- return eError;
-
-}
-
-
-PVRSRV_ERROR OSEventObjectDestroy(PVRSRV_EVENTOBJECT *psEventObject)
-{
- PVRSRV_ERROR eError = PVRSRV_OK;
-
- if(psEventObject)
- {
- if(psEventObject->hOSEventKM)
- {
- LinuxEventObjectListDestroy(psEventObject->hOSEventKM);
- }
- else
- {
- PVR_DPF((PVR_DBG_ERROR, "OSEventObjectDestroy: hOSEventKM is not a valid pointer"));
- eError = PVRSRV_ERROR_INVALID_PARAMS;
- }
- }
- else
- {
- PVR_DPF((PVR_DBG_ERROR, "OSEventObjectDestroy: psEventObject is not a valid pointer"));
- eError = PVRSRV_ERROR_INVALID_PARAMS;
- }
-
- return eError;
-}
-
-PVRSRV_ERROR OSEventObjectWait(IMG_HANDLE hOSEventKM)
-{
- PVRSRV_ERROR eError;
-
- if(hOSEventKM)
- {
- eError = LinuxEventObjectWait(hOSEventKM, EVENT_OBJECT_TIMEOUT_MS);
- }
- else
- {
- PVR_DPF((PVR_DBG_ERROR, "OSEventObjectWait: hOSEventKM is not a valid handle"));
- eError = PVRSRV_ERROR_INVALID_PARAMS;
- }
-
- return eError;
-}
-
-PVRSRV_ERROR OSEventObjectOpen(PVRSRV_EVENTOBJECT *psEventObject,
- IMG_HANDLE *phOSEvent)
-{
- PVRSRV_ERROR eError = PVRSRV_OK;
-
- if(psEventObject)
- {
- if(LinuxEventObjectAdd(psEventObject->hOSEventKM, phOSEvent) != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectAdd: failed"));
- eError = PVRSRV_ERROR_INVALID_PARAMS;
- }
-
- }
- else
- {
- PVR_DPF((PVR_DBG_ERROR, "OSEventObjectCreate: psEventObject is not a valid pointer"));
- eError = PVRSRV_ERROR_INVALID_PARAMS;
- }
-
- return eError;
-}
-
-PVRSRV_ERROR OSEventObjectClose(PVRSRV_EVENTOBJECT *psEventObject,
- IMG_HANDLE hOSEventKM)
-{
- PVRSRV_ERROR eError = PVRSRV_OK;
-
- if(psEventObject)
- {
- if(LinuxEventObjectDelete(psEventObject->hOSEventKM, hOSEventKM) != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectDelete: failed"));
- eError = PVRSRV_ERROR_INVALID_PARAMS;
- }
-
- }
- else
- {
- PVR_DPF((PVR_DBG_ERROR, "OSEventObjectDestroy: psEventObject is not a valid pointer"));
- eError = PVRSRV_ERROR_INVALID_PARAMS;
- }
-
- return eError;
-
-}
-
-PVRSRV_ERROR OSEventObjectSignal(IMG_HANDLE hOSEventKM)
-{
- PVRSRV_ERROR eError;
-
- if(hOSEventKM)
- {
- eError = LinuxEventObjectSignal(hOSEventKM);
- }
- else
- {
- PVR_DPF((PVR_DBG_ERROR, "OSEventObjectSignal: hOSEventKM is not a valid handle"));
- eError = PVRSRV_ERROR_INVALID_PARAMS;
- }
-
- return eError;
-}
-
-IMG_BOOL OSProcHasPrivSrvInit(IMG_VOID)
-{
- return (capable(CAP_SYS_MODULE) != 0) ? IMG_TRUE : IMG_FALSE;
-}
-
-PVRSRV_ERROR OSCopyToUser(IMG_PVOID pvProcess,
- IMG_VOID *pvDest,
- IMG_VOID *pvSrc,
- IMG_UINT32 ui32Bytes)
-{
- PVR_UNREFERENCED_PARAMETER(pvProcess);
-
- if(copy_to_user(pvDest, pvSrc, ui32Bytes)==0)
- return PVRSRV_OK;
- else
- return PVRSRV_ERROR_GENERIC;
-}
-
-PVRSRV_ERROR OSCopyFromUser( IMG_PVOID pvProcess,
- IMG_VOID *pvDest,
- IMG_VOID *pvSrc,
- IMG_UINT32 ui32Bytes)
-{
- PVR_UNREFERENCED_PARAMETER(pvProcess);
-
- if(copy_from_user(pvDest, pvSrc, ui32Bytes)==0)
- return PVRSRV_OK;
- else
- return PVRSRV_ERROR_GENERIC;
-}
-
-IMG_BOOL OSAccessOK(IMG_VERIFY_TEST eVerification, IMG_VOID *pvUserPtr, IMG_UINT32 ui32Bytes)
-{
- IMG_INT linuxType;
-
- if (eVerification == PVR_VERIFY_READ)
- {
- linuxType = VERIFY_READ;
- }
- else
- {
- PVR_ASSERT(eVerification == PVR_VERIFY_WRITE);
- linuxType = VERIFY_WRITE;
- }
-
- return access_ok(linuxType, pvUserPtr, ui32Bytes);
-}
-
-typedef enum _eWrapMemType_
-{
- WRAP_TYPE_CLEANUP,
- WRAP_TYPE_GET_USER_PAGES,
- WRAP_TYPE_FIND_VMA_PAGES,
- WRAP_TYPE_FIND_VMA_PFN
-} eWrapMemType;
-
-typedef struct _sWrapMemInfo_
-{
- eWrapMemType eType;
- IMG_INT iNumPages;
- struct page **ppsPages;
- IMG_SYS_PHYADDR *psPhysAddr;
- IMG_INT iPageOffset;
- IMG_INT iContiguous;
-#if defined(DEBUG)
- IMG_UINT32 ulStartAddr;
- IMG_UINT32 ulBeyondEndAddr;
- struct vm_area_struct *psVMArea;
-#endif
- IMG_BOOL bWrapWorkaround;
-} sWrapMemInfo;
-
-static IMG_VOID CheckPagesContiguous(sWrapMemInfo *psInfo)
-{
- IMG_INT i;
- IMG_UINT32 ui32AddrChk;
-
- BUG_ON(psInfo == IMG_NULL);
-
- psInfo->iContiguous = 1;
-
- for (i = 0, ui32AddrChk = psInfo->psPhysAddr[0].uiAddr;
- i < psInfo->iNumPages;
- i++, ui32AddrChk += PAGE_SIZE)
- {
- if (psInfo->psPhysAddr[i].uiAddr != ui32AddrChk)
- {
- psInfo->iContiguous = 0;
- break;
- }
- }
-}
-
-static struct page *CPUVAddrToPage(struct vm_area_struct *psVMArea, IMG_UINT32 ulCPUVAddr)
-{
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,10))
- pgd_t *psPGD;
- pud_t *psPUD;
- pmd_t *psPMD;
- pte_t *psPTE;
- struct mm_struct *psMM = psVMArea->vm_mm;
- IMG_UINT32 ulPFN;
- spinlock_t *psPTLock;
- struct page *psPage;
-
- psPGD = pgd_offset(psMM, ulCPUVAddr);
- if (pgd_none(*psPGD) || pgd_bad(*psPGD))
- return NULL;
-
- psPUD = pud_offset(psPGD, ulCPUVAddr);
- if (pud_none(*psPUD) || pud_bad(*psPUD))
- return NULL;
-
- psPMD = pmd_offset(psPUD, ulCPUVAddr);
- if (pmd_none(*psPMD) || pmd_bad(*psPMD))
- return NULL;
-
- psPage = NULL;
-
- psPTE = (pte_t *)pte_offset_map_lock(psMM, psPMD, ulCPUVAddr, &psPTLock);
- if ((pte_none(*psPTE) != 0) || (pte_present(*psPTE) == 0) || (pte_write(*psPTE) == 0))
- goto exit_unlock;
-
- ulPFN = pte_pfn(*psPTE);
- if (!pfn_valid(ulPFN))
- goto exit_unlock;
-
- psPage = pfn_to_page(ulPFN);
-
- get_page(psPage);
-
-exit_unlock:
- pte_unmap_unlock(psPTE, psPTLock);
-
- return psPage;
-#else
- return NULL;
-#endif
-}
-PVRSRV_ERROR OSReleasePhysPageAddr(IMG_HANDLE hOSWrapMem)
-{
- sWrapMemInfo *psInfo = (sWrapMemInfo *)hOSWrapMem;
- IMG_INT i;
-
- BUG_ON(psInfo == IMG_NULL);
-
- switch (psInfo->eType)
- {
- case WRAP_TYPE_CLEANUP:
- break;
- case WRAP_TYPE_FIND_VMA_PFN:
- break;
- case WRAP_TYPE_GET_USER_PAGES:
- {
- for (i = 0; i < psInfo->iNumPages; i++)
- {
- struct page *psPage = psInfo->ppsPages[i];
-
-
- if (!PageReserved(psPage));
- {
- SetPageDirty(psPage);
- }
- page_cache_release(psPage);
- }
- break;
- }
- case WRAP_TYPE_FIND_VMA_PAGES:
- {
- for (i = 0; i < psInfo->iNumPages; i++)
- {
- if(psInfo->bWrapWorkaround)
- put_page(psInfo->ppsPages[i]);
- else
- put_page_testzero(psInfo->ppsPages[i]);
- }
- break;
- }
- default:
- {
- PVR_DPF((PVR_DBG_ERROR,
- "OSReleasePhysPageAddr: Unknown wrap type (%d)", psInfo->eType));
- return PVRSRV_ERROR_GENERIC;
- }
- }
-
- if (psInfo->ppsPages != IMG_NULL)
- {
- kfree(psInfo->ppsPages);
- }
-
- if (psInfo->psPhysAddr != IMG_NULL)
- {
- kfree(psInfo->psPhysAddr);
- }
-
- kfree(psInfo);
-
- return PVRSRV_OK;
-}
-
-PVRSRV_ERROR OSAcquirePhysPageAddr(IMG_VOID* pvCPUVAddr,
- IMG_UINT32 ui32Bytes,
- IMG_SYS_PHYADDR *psSysPAddr,
- IMG_HANDLE *phOSWrapMem,
- IMG_BOOL bWrapWorkaround)
-{
- IMG_UINT32 ulStartAddrOrig = (IMG_UINT32) pvCPUVAddr;
- IMG_UINT32 ulAddrRangeOrig = (IMG_UINT32) ui32Bytes;
- IMG_UINT32 ulBeyondEndAddrOrig = ulStartAddrOrig + ulAddrRangeOrig;
- IMG_UINT32 ulStartAddr;
- IMG_UINT32 ulAddrRange;
- IMG_UINT32 ulBeyondEndAddr;
- IMG_UINT32 ulAddr;
- IMG_INT iNumPagesMapped;
- IMG_INT i;
- struct vm_area_struct *psVMArea;
- sWrapMemInfo *psInfo;
-
-
- ulStartAddr = ulStartAddrOrig & PAGE_MASK;
- ulBeyondEndAddr = PAGE_ALIGN(ulBeyondEndAddrOrig);
- ulAddrRange = ulBeyondEndAddr - ulStartAddr;
-
-
- psInfo = kmalloc(sizeof(*psInfo), GFP_KERNEL);
- if (psInfo == NULL)
- {
- PVR_DPF((PVR_DBG_ERROR,
- "OSAcquirePhysPageAddr: Couldn't allocate information structure"));
- return PVRSRV_ERROR_OUT_OF_MEMORY;
- }
- memset(psInfo, 0, sizeof(*psInfo));
- psInfo->bWrapWorkaround = bWrapWorkaround;
-
-#if defined(DEBUG)
- psInfo->ulStartAddr = ulStartAddrOrig;
- psInfo->ulBeyondEndAddr = ulBeyondEndAddrOrig;
-#endif
-
- psInfo->iNumPages = (IMG_INT)(ulAddrRange >> PAGE_SHIFT);
- psInfo->iPageOffset = (IMG_INT)(ulStartAddrOrig & ~PAGE_MASK);
-
-
- psInfo->psPhysAddr = kmalloc((size_t)psInfo->iNumPages * sizeof(*psInfo->psPhysAddr), GFP_KERNEL);
- if (psInfo->psPhysAddr == NULL)
- {
- PVR_DPF((PVR_DBG_ERROR,
- "OSAcquirePhysPageAddr: Couldn't allocate page array"));
- goto error_free;
- }
-
-
- psInfo->ppsPages = kmalloc((size_t)psInfo->iNumPages * sizeof(*psInfo->ppsPages), GFP_KERNEL);
- if (psInfo->ppsPages == NULL)
- {
- PVR_DPF((PVR_DBG_ERROR,
- "OSAcquirePhysPageAddr: Couldn't allocate page array"));
- goto error_free;
- }
-
-
- down_read(&current->mm->mmap_sem);
- iNumPagesMapped = get_user_pages(current, current->mm, ulStartAddr, psInfo->iNumPages, 1, 0, psInfo->ppsPages, NULL);
- up_read(&current->mm->mmap_sem);
-
- if (iNumPagesMapped >= 0)
- {
-
- if (iNumPagesMapped != psInfo->iNumPages)
- {
- PVR_TRACE(("OSAcquirePhysPageAddr: Couldn't map all the pages needed (wanted: %d, got %d)", psInfo->iNumPages, iNumPagesMapped));
-
-
- for (i = 0; i < iNumPagesMapped; i++)
- {
- page_cache_release(psInfo->ppsPages[i]);
-
- }
- goto error_free;
- }
-
-
- for (i = 0; i < psInfo->iNumPages; i++)
- {
- IMG_CPU_PHYADDR CPUPhysAddr;
-
- CPUPhysAddr.uiAddr = page_to_pfn(psInfo->ppsPages[i]) << PAGE_SHIFT;
- psInfo->psPhysAddr[i] = SysCpuPAddrToSysPAddr(CPUPhysAddr);
- psSysPAddr[i] = psInfo->psPhysAddr[i];
-
- }
-
- psInfo->eType = WRAP_TYPE_GET_USER_PAGES;
-
- goto exit_check;
- }
-
- PVR_DPF((PVR_DBG_MESSAGE, "OSAcquirePhysPageAddr: get_user_pages failed (%d), trying something else", iNumPagesMapped));
-
-
- down_read(&current->mm->mmap_sem);
-
- psVMArea = find_vma(current->mm, ulStartAddrOrig);
- if (psVMArea == NULL)
- {
- PVR_DPF((PVR_DBG_ERROR,
- "OSAcquirePhysPageAddr: Couldn't find memory region containing start address %lx", ulStartAddrOrig));
-
- goto error_release_mmap_sem;
- }
-#if defined(DEBUG)
- psInfo->psVMArea = psVMArea;
-#endif
-
-
- if (ulStartAddrOrig < psVMArea->vm_start)
- {
- PVR_DPF((PVR_DBG_ERROR,
- "OSAcquirePhysPageAddr: Start address %lx is outside of the region returned by find_vma", ulStartAddrOrig));
- goto error_release_mmap_sem;
- }
-
-
- if (ulBeyondEndAddrOrig > psVMArea->vm_end)
- {
- PVR_DPF((PVR_DBG_ERROR,
- "OSAcquirePhysPageAddr: End address %lx is outside of the region returned by find_vma", ulBeyondEndAddrOrig));
- goto error_release_mmap_sem;
- }
-
-
- if ((psVMArea->vm_flags & (VM_IO | VM_RESERVED)) != (VM_IO | VM_RESERVED))
- {
- PVR_DPF((PVR_DBG_ERROR,
- "OSAcquirePhysPageAddr: Memory region does not represent memory mapped I/O (VMA flags: 0x%lx)", psVMArea->vm_flags));
- goto error_release_mmap_sem;
- }
-
-
- if ((psVMArea->vm_flags & (VM_READ | VM_WRITE)) != (VM_READ | VM_WRITE))
- {
- PVR_DPF((PVR_DBG_ERROR,
- "OSAcquirePhysPageAddr: No read/write access to memory region (VMA flags: 0x%lx)", psVMArea->vm_flags));
- goto error_release_mmap_sem;
- }
-
-
- for (ulAddr = ulStartAddrOrig, i = 0; ulAddr < ulBeyondEndAddrOrig; ulAddr += PAGE_SIZE, i++)
- {
- struct page *psPage;
-
- BUG_ON(i >= psInfo->iNumPages);
-
- psPage = CPUVAddrToPage(psVMArea, ulAddr);
- if (psPage == NULL)
- {
- IMG_INT j;
-
- PVR_TRACE(("OSAcquirePhysPageAddr: Couldn't lookup page structure for address 0x%lx, trying something else", ulAddr));
-
-
- for (j = 0; j < i; j++)
- {
- if(psInfo->bWrapWorkaround)
- put_page(psInfo->ppsPages[j]);
- else
- put_page_testzero(psInfo->ppsPages[j]);
- }
- break;
- }
-
- psInfo->ppsPages[i] = psPage;
- }
-
- BUG_ON(i > psInfo->iNumPages);
- if (i == psInfo->iNumPages)
- {
-
- for (i = 0; i < psInfo->iNumPages; i++)
- {
- struct page *psPage = psInfo->ppsPages[i];
- IMG_CPU_PHYADDR CPUPhysAddr;
-
-
- CPUPhysAddr.uiAddr = page_to_pfn(psPage) << PAGE_SHIFT;
-
- psInfo->psPhysAddr[i] = SysCpuPAddrToSysPAddr(CPUPhysAddr);
- psSysPAddr[i] = psInfo->psPhysAddr[i];
- }
-
- psInfo->eType = WRAP_TYPE_FIND_VMA_PAGES;
- }
- else
- {
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,10)) && defined(PVR_SECURE_HANDLES)
-
-
-
- if ((psVMArea->vm_flags & VM_PFNMAP) == 0)
- {
- PVR_DPF((PVR_DBG_WARNING,
- "OSAcquirePhysPageAddr: Region isn't a raw PFN mapping. Giving up."));
- goto error_release_mmap_sem;
- }
-
- for (ulAddr = ulStartAddrOrig, i = 0; ulAddr < ulBeyondEndAddrOrig; ulAddr += PAGE_SIZE, i++)
- {
- IMG_CPU_PHYADDR CPUPhysAddr;
-
- CPUPhysAddr.uiAddr = ((ulAddr - psVMArea->vm_start) + (psVMArea->vm_pgoff << PAGE_SHIFT)) & PAGE_MASK;
-
- psInfo->psPhysAddr[i] = SysCpuPAddrToSysPAddr(CPUPhysAddr);
- psSysPAddr[i] = psInfo->psPhysAddr[i];
- }
- BUG_ON(i != psInfo->iNumPages);
-
- psInfo->eType = WRAP_TYPE_FIND_VMA_PFN;
-
-
- PVR_DPF((PVR_DBG_WARNING,
- "OSAcquirePhysPageAddr: Region can't be locked down"));
-#else
- PVR_DPF((PVR_DBG_WARNING,
- "OSAcquirePhysPageAddr: Raw PFN mappings not supported. Giving up."));
- goto error_release_mmap_sem;
-#endif
- }
-
- up_read(&current->mm->mmap_sem);
-
-exit_check:
- CheckPagesContiguous(psInfo);
-
-
-
- *phOSWrapMem = (IMG_HANDLE)psInfo;
-
- return PVRSRV_OK;
-
-error_release_mmap_sem:
- up_read(&current->mm->mmap_sem);
-error_free:
- psInfo->eType = WRAP_TYPE_CLEANUP;
- OSReleasePhysPageAddr((IMG_HANDLE)psInfo);
- return PVRSRV_ERROR_GENERIC;
-}
-
-PVRSRV_ERROR PVROSFuncInit(IMG_VOID)
-{
-#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
- {
- IMG_UINT32 ui32i;
-
- psTimerWorkQueue = create_workqueue("pvr_timer");
- if (psTimerWorkQueue == NULL)
- {
- PVR_DPF((PVR_DBG_ERROR, "%s: couldn't create timer workqueue", __FUNCTION__));
- return PVRSRV_ERROR_GENERIC;
-
- }
-
- for (ui32i = 0; ui32i < OS_MAX_TIMERS; ui32i++)
- {
- TIMER_CALLBACK_DATA *psTimerCBData = &sTimers[ui32i];
-
- INIT_WORK(&psTimerCBData->sWork, OSTimerWorkQueueCallBack);
- }
- }
-#endif
- return PVRSRV_OK;
-}
-
-IMG_VOID PVROSFuncDeInit(IMG_VOID)
-{
-#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
- if (psTimerWorkQueue != NULL)
- {
- destroy_workqueue(psTimerWorkQueue);
- }
-#endif
-}