/*! ****************************************************************************** @Function PALLOC_Free1 ******************************************************************************/ IMG_RESULT PALLOC_Free1( IMG_UINT32 ui32AllocId ) { IMG_UINT32 ui32Result; PALLOC_sKmAlloc * psKmAlloc; IMG_HANDLE hResHandle; IMG_HANDLE hDevHandle; LOG_EVENT(PALLOC, PALLOC_FREEID, (LOG_FLAG_START | LOG_FLAG_QUAL_ARG1), ui32AllocId, 0); /* Get the resource info from the id...*/ ui32Result = RMAN_GetResource(ui32AllocId, PALLOC_RES_TYPE_1, (IMG_VOID **)&psKmAlloc, &hResHandle); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { return ui32Result; } hDevHandle = psKmAlloc->hDevHandle; /* Lock the device...*/ DMANKM_LockDeviceContext(hDevHandle); /* Free through the resource manager...*/ RMAN_FreeResource(hResHandle); /* Unlock the device...*/ DMANKM_UnlockDeviceContext(hDevHandle); LOG_EVENT(PALLOC, PALLOC_FREEID, (LOG_FLAG_END| LOG_FLAG_QUAL_ARG1), ui32AllocId, 0); /* Return IMG_SUCCESS...*/ return IMG_SUCCESS; }
/*! ****************************************************************************** @Function DMANKM_CloseDevice ******************************************************************************/ IMG_RESULT DMANKM_CloseDevice(IMG_HANDLE hDevHandle, IMG_HANDLE hConnHandle, DMANKM_eDisconnType eDisconnType) { DMANKM_sDevContext * psDevContext = (DMANKM_sDevContext *) hDevHandle; DMANKM_sConnContext * psConnContext = (DMANKM_sConnContext *) hConnHandle; IMG_UINT32 ui32Result; IMG_ASSERT(gDmanKmInitialised); IMG_ASSERT(!psConnContext->bInitConn); IMG_ASSERT(psConnContext->ui32OpenCnt != 0); /* Update the open count...*/ psConnContext->ui32OpenCnt--; /* If abort...*/ if (eDisconnType == DMAN_DCONN_ABORT) { /* Set open count to 0...*/ psConnContext->ui32OpenCnt = 0; } /* If this is not the last close...*/ if (psConnContext->ui32OpenCnt != 0) { /* Unlock the device...*/ DMANKM_UnlockDeviceContext(hDevHandle); /* Return success...*/ return IMG_SUCCESS; } /* Removed the process lost callback...*/ PMAN_RemoveProcessLostCb(psConnContext->hProcLostCbHandle); /* If disconnect/close function...*/ if (psDevContext->sDevRegister.pfnDevDisconnect != IMG_NULL ) { ui32Result = psDevContext->sDevRegister.pfnDevDisconnect(psConnContext, psDevContext->pvDevInstanceData, psConnContext->pvDevConnectionData, eDisconnType); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { return ui32Result; } } else { /* Call complete function synchronously...*/ DMANKM_DevDisconnectComplete(psConnContext); } /* Return success...*/ return IMG_SUCCESS; }
/*! ****************************************************************************** @Function PALLOC_AttachToConnection ******************************************************************************/ IMG_RESULT PALLOC_AttachToConnection( IMG_UINT32 ui32ConnId, IMG_UINT32 __user * pui32AttachId ) { IMG_HANDLE hDevHandle; IMG_UINT32 ui32Result; IMG_HANDLE hConnHandle; IMG_UINT32 ui32AttachId; LOG_EVENT(PALLOC, PALLOC_ATTACH, (LOG_FLAG_START), 0, 0); /* Get the connection handle from it's ID...*/ ui32Result = DMANKM_GetConnHandleFromId(ui32ConnId, &hConnHandle); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { return ui32Result; } /* Get the device handle from the connection...*/ hDevHandle = DMANKM_GetDevHandleFromConn(hConnHandle); /* Lock the device...*/ DMANKM_LockDeviceContext(hDevHandle); /* Call on to the kernel function...*/ ui32Result = DMANKM_AttachComponent(hConnHandle, "PALLOCBRG", palloc_fnCompAttach, IMG_NULL, &ui32AttachId); IMG_ASSERT(ui32Result == IMG_SUCCESS); /* Unlock the device...*/ DMANKM_UnlockDeviceContext(hDevHandle); SYSOSKM_CopyToUser(pui32AttachId, &ui32AttachId, sizeof(ui32AttachId)); LOG_EVENT(PALLOC, PALLOC_ATTACH, (LOG_FLAG_END), 0, 0); /* Return ui32Result...*/ return ui32Result; }
/*! ****************************************************************************** @Function DMANKM_DevDisconnectComplete ******************************************************************************/ IMG_RESULT DMANKM_DevDisconnectComplete(IMG_HANDLE hConnHandle) { IMG_UINT32 ui32Result; DMANKM_sConnContext * psConnContext = hConnHandle; DMANKM_sConnContext * psInitConnContext; DMANKM_sDevContext * psDevContext = psConnContext->psDevContext; IMG_HANDLE hProcessId; /* Disconnect components attached to this connection...*/ ui32Result = dmankm_DisconnectComps(psConnContext); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { return ui32Result; } /* Save the process id...*/ hProcessId = psConnContext->hProcessId; /* Remove and free this connection...*/ LST_remove(&psDevContext->sConnList, psConnContext); RMAN_FreeResource(psConnContext->hResHandle); IMG_FREE(psConnContext); /* Update the connection count...*/ psDevContext->ui32ConnCnt--; /* If connection count 0...*/ if (psDevContext->ui32ConnCnt == 0) { /* Deinitailise the device....*/ psInitConnContext = (DMANKM_sConnContext *) LST_first( &psDevContext->sConnList); if(psInitConnContext == NULL) { IMG_ASSERT(psInitConnContext != IMG_NULL); return IMG_ERROR_GENERIC_FAILURE; } else { IMG_ASSERT(psInitConnContext->bInitConn); } /* Deregister the LISR...*/ if (psDevContext->sDevRegister.pfnDevKmLisr != IMG_NULL ) { SYSDEVU_RemoveDevKmLisr(psDevContext->hSysDevHandle); } /* Deregister the HISR...*/ if (psDevContext->sDevRegister.pfnDevKmHisr != IMG_NULL ) { if (psDevContext->hHISRHandle) { IMG_HANDLE HISRHandle = psDevContext->hHISRHandle; psDevContext->hHISRHandle = IMG_NULL; SYSOSKM_DestroyKmHisr(HISRHandle); } } /* If we have a deinitialise function...*/ if (psDevContext->sDevRegister.pfnDevDeinit != IMG_NULL ) { psDevContext->sDevRegister.pfnDevDeinit(psDevContext, psInitConnContext, psDevContext->pvDevInstanceData); } if ((psDevContext->sDevRegister.ui32DevFlags & DMAN_DFLAG_PSEUDO_DEVICE) == 0) { /* Power the device off. */ SYSDEVU_SetPowerState(psDevContext->hSysDevHandle, SYSOSKM_POWERSTATE_S5, IMG_FALSE); } /* Disconnect components attached to the implicit connection...*/ ui32Result = dmankm_DisconnectComps(psInitConnContext); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { return ui32Result; } /* Remove and free the implicit connection...*/ LST_remove(&psDevContext->sConnList, psInitConnContext); RMAN_FreeResource(psInitConnContext->hResHandle); IMG_FREE(psInitConnContext); /* Destroy the resource bucket used for connections and attachments...*/ RMAN_DestroyBucket(psDevContext->hResBHandle); psDevContext->hResBHandle = IMG_NULL; /* If we opened the device with SYSDEVKM...*/ if (psDevContext->hSysDevHandle != IMG_NULL ) { /* Close it...*/ SYSDEVU_CloseDevice(psDevContext->hSysDevHandle); psDevContext->hSysDevHandle = IMG_NULL; } } /* Let the Process Manager know the connection has been broken...*/ PMAN_DevDisconnectComplete(hProcessId); /* Unlock the device...*/ DMANKM_UnlockDeviceContext(psDevContext); /* Return success...*/ return IMG_SUCCESS; }
/*! ****************************************************************************** @Function PALLOC_Import1 ******************************************************************************/ IMG_RESULT PALLOC_Import1( IMG_UINT32 ui32AttachId, SYS_eMemAttrib eMemAttrib, int buff_fd, PALLOC_sUmAlloc __user * psUmAlloc ) { IMG_HANDLE hDevHandle; IMG_UINT32 ui32Result; PALLOC_sKmAlloc * psKmAlloc; IMG_HANDLE hAttachHandle; PALLOC_sAttachContext * psAttachContext; IMG_UINT32 ui32PageNo; IMG_UINT32 ui32PageIdx; IMG_UINT64 ui64CpuPAddr; PALLOC_sUmAlloc sUmAllocCp; IMG_UINT64 * paui64DevAddrs; SYSDEVU_sInfo * psSysDev; SYS_eMemPool eMemPool; IMG_PVOID pvCpuKmAddr; LOG_EVENT(PALLOC, PALLOC_IMPORT, LOG_FLAG_START | LOG_FLAG_QUAL_ARG1 | LOG_FLAG_QUAL_ARG2, ui32AttachId, buff_fd); DEBUG_REPORT(REPORT_MODULE_PALLOC, "PALLOC_Import1 fd %d", buff_fd); if (SYSOSKM_CopyFromUser(&sUmAllocCp, psUmAlloc, sizeof sUmAllocCp) != IMG_SUCCESS) { return IMG_ERROR_FATAL; } IMG_ASSERT(sUmAllocCp.bMappingOnly); /* Get the attachment handle from its ID... */ ui32Result = DMANKM_GetAttachHandleFromId(ui32AttachId, &hAttachHandle); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { return ui32Result; } /* Get access to the attachment specific data...*/ psAttachContext = DMANKM_GetCompAttachmentData(hAttachHandle); /* Get access to the device handle...*/ hDevHandle = DMANKM_GetDevHandleFromAttach(hAttachHandle); /* Lock the device...*/ DMANKM_LockDeviceContext(hDevHandle); psSysDev = SYSDEVU_GetDeviceById(SYSDEVKM_GetDeviceID(psAttachContext->hSysDevHandle)); IMG_ASSERT(psSysDev != IMG_NULL); // I if (psSysDev == IMG_NULL) { ui32Result = IMG_ERROR_DEVICE_NOT_FOUND; goto error_get_dev_by_id; } eMemPool = (eMemAttrib & SYS_MEMATTRIB_SECURE) ? psSysDev->secureMemPool : psSysDev->sMemPool; /* Allocate allocation info...*/ psKmAlloc = IMG_MALLOC(sizeof *psKmAlloc); IMG_ASSERT(psKmAlloc != IMG_NULL); if (psKmAlloc == IMG_NULL) { ui32Result = IMG_ERROR_OUT_OF_MEMORY; goto error_alloc_info; } IMG_MEMSET(psKmAlloc, 0, sizeof *psKmAlloc); /* Save device handle etc... */ psKmAlloc->hDevHandle = hDevHandle; psKmAlloc->sAllocInfo.ui32Size = sUmAllocCp.ui32Size; psKmAlloc->sAllocInfo.bIsContiguous = IMG_FALSE; /* Get the device id...*/ ui32Result = DMANKM_GetDeviceId(hDevHandle, &sUmAllocCp.ui32DeviceId); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { goto error_get_dev_id; } psKmAlloc->sAllocInfo.bMappingOnly = IMG_TRUE; /* Calculate the size of the allocation in pages */ ui32PageNo = (sUmAllocCp.ui32Size + SYS_MMU_PAGE_SIZE - 1)/SYS_MMU_PAGE_SIZE; psKmAlloc->sAllocInfo.psSysPAddr = IMG_BIGORSMALL_ALLOC(sizeof(IMG_SYS_PHYADDR) * ui32PageNo); IMG_ASSERT(psKmAlloc->sAllocInfo.psSysPAddr); if (IMG_NULL == psKmAlloc->sAllocInfo.psSysPAddr) { ui32Result = IMG_ERROR_OUT_OF_MEMORY; goto error_page_array; } paui64DevAddrs = IMG_BIGORSMALL_ALLOC((sizeof *paui64DevAddrs) * ui32PageNo); IMG_ASSERT(paui64DevAddrs); if (IMG_NULL == paui64DevAddrs) { ui32Result = IMG_ERROR_OUT_OF_MEMORY; goto error_addr_array; } if(buff_fd >= 0) { pvCpuKmAddr = NULL; /* ION buffer */ #if defined ANDROID_ION_BUFFERS psKmAlloc->eBufType = PALLOC_BUFTYPE_ANDROIDNATIVE; #if defined CONFIG_X86 ui32Result = palloc_GetIONPages(eMemPool, buff_fd, sUmAllocCp.ui32Size, psKmAlloc->sAllocInfo.psSysPAddr, &pvCpuKmAddr, &psKmAlloc->hBufHandle); #else // if CONFIG_X86 ui32Result = palloc_GetIONPages(eMemPool, buff_fd, sUmAllocCp.ui32Size, psKmAlloc->sAllocInfo.psSysPAddr, NULL, &psKmAlloc->hBufHandle); #endif // if CONFIG_X86 if (ui32Result != IMG_SUCCESS) { IMG_ASSERT(!"palloc_GetIONPages"); goto error_get_pages; } #else // if ANDROID_ION_BUFFERS IMG_ASSERT(!"NOT ANDROID: ION not supported"); goto error_get_pages; #endif // if ANDROID_ION_BUFFERS } else { /* User space allocated buffer */ IMG_VOID __user * pvUmBuff = ( IMG_VOID __user * ) sUmAllocCp.pvCpuUmAddr; IMG_ASSERT(pvUmBuff); psKmAlloc->hBufHandle = (IMG_HANDLE)(sUmAllocCp.pvCpuUmAddr); psKmAlloc->eBufType = PALLOC_BUFTYPE_USERALLOC; /* Assign and lock physical addresses to the user space buffer. The mapping of the first page in the kernel is also returned */ ui32Result = SYSOSKM_CpuUmAddrToCpuPAddrArray(pvUmBuff, psKmAlloc->sAllocInfo.psSysPAddr, ui32PageNo, &pvCpuKmAddr); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { goto error_get_pages; } } /* Import pages */ ui32Result = SYSMEMU_ImportExternalPages(eMemPool, sUmAllocCp.ui32Size, eMemAttrib, &psKmAlloc->hPagesHandle, pvCpuKmAddr, psKmAlloc->sAllocInfo.psSysPAddr); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { goto error_import_pages; } // Access from user space is not needed for the moment. Can be changed. sUmAllocCp.lOffset = 0; #if PALLOC_EXPOSE_KM_HANDLE sUmAllocCp.hKmAllocHandle = psKmAlloc->hPagesHandle; #endif /* PALLOC_EXPOSE_KM_HANDLE */ for (ui32PageIdx = 0; ui32PageIdx < ui32PageNo; ++ui32PageIdx) { ui64CpuPAddr = psKmAlloc->sAllocInfo.psSysPAddr[ui32PageIdx]; paui64DevAddrs[ui32PageIdx] = SYSDEVKM_CpuPAddrToDevPAddr(psAttachContext->hSysDevHandle, ui64CpuPAddr); } /* Register this with the resource manager */ ui32Result = RMAN_RegisterResource(psAttachContext->hResBHandle, PALLOC_RES_TYPE_1, palloc_fnFree, psKmAlloc, IMG_NULL, &sUmAllocCp.ui32AllocId); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { goto error_resource_register; } LOG_EVENT(PALLOC, PALLOC_IMPORTID, LOG_FLAG_END | LOG_FLAG_QUAL_ARG1 | LOG_FLAG_QUAL_ARG2, ui32AttachId, sUmAllocCp.ui32AllocId); /* Unlock the device...*/ DMANKM_UnlockDeviceContext(hDevHandle); /* Copy to user changed PALLOC_sUmAlloc, including physical device addresses */ if (SYSOSKM_CopyToUser(psUmAlloc, &sUmAllocCp, sizeof sUmAllocCp)) { ui32Result = IMG_ERROR_FATAL; goto error_copy_to_user; } if (SYSOSKM_CopyToUser(psUmAlloc->aui64DevPAddr, paui64DevAddrs, (sizeof *paui64DevAddrs) * ui32PageNo)) { ui32Result = IMG_ERROR_FATAL; goto error_copy_to_user; } /* Free the address array */ IMG_BIGORSMALL_FREE((sizeof *paui64DevAddrs) * ui32PageNo, paui64DevAddrs); LOG_EVENT(PALLOC, PALLOC_IMPORT, LOG_FLAG_END | LOG_FLAG_QUAL_ARG1 | LOG_FLAG_QUAL_ARG2, ui32AttachId, buff_fd); /* Return. */ return IMG_SUCCESS; /* Error handling. */ error_copy_to_user: /* Free everything. */ PALLOC_Free1(sUmAllocCp.ui32AllocId); goto error_return; error_resource_register: SYSMEMU_FreePages(psKmAlloc->hPagesHandle); error_import_pages: if (buff_fd >= 0) { #ifdef ANDROID_ION_BUFFERS palloc_ReleaseIONBuf(psKmAlloc->hBufHandle, NULL); #endif /* ANDROID_ION_BUFFERS */ } else { SYSOSKM_ReleaseCpuPAddrArray(pvCpuKmAddr, psKmAlloc->hBufHandle, psKmAlloc->sAllocInfo.psSysPAddr, ui32PageNo); } error_get_pages: IMG_BIGORSMALL_FREE((sizeof *paui64DevAddrs) * ui32PageNo, paui64DevAddrs); error_addr_array: IMG_BIGORSMALL_FREE(sizeof(IMG_SYS_PHYADDR) * ui32PageNo, psKmAlloc->sAllocInfo.psSysPAddr); error_page_array: error_get_dev_id: IMG_FREE(psKmAlloc); error_alloc_info: error_get_dev_by_id: /* Unlock the device. */ DMANKM_UnlockDeviceContext(hDevHandle); error_return: return ui32Result; }
/*! ****************************************************************************** @Function PALLOC_Alloc1 ******************************************************************************/ IMG_RESULT PALLOC_Alloc1( IMG_UINT32 ui32AttachId, SYS_eMemAttrib eMemAttrib, PALLOC_sUmAlloc __user * psUmAlloc ) { IMG_HANDLE hDevHandle; IMG_UINT32 ui32Result; PALLOC_sKmAlloc * psKmAlloc; IMG_HANDLE hAttachHandle; PALLOC_sAttachContext * psAttachContext; IMG_UINT32 ui32PageNo; PALLOC_sUmAlloc sUmAllocCp; IMG_UINT32 ui32PageIdx; IMG_UINT64 * pui64Phys; SYSMEMU_sPages * psSysMem; SYS_eMemPool eMemPool; SYSDEVU_sInfo * psSysDev; /* the following code assumes that IMG_SYS_PHYADDR and IMG_UINT64 are the same size */ #ifndef SYSBRG_BRIDGING IMG_VOID * pvKmAddr; #endif if (SYSOSKM_CopyFromUser(&sUmAllocCp, psUmAlloc, sizeof(sUmAllocCp)) != IMG_SUCCESS) { return IMG_ERROR_FATAL; } LOG_EVENT(PALLOC, PALLOC_ALLOC, (LOG_FLAG_START | LOG_FLAG_QUAL_ARG1 |LOG_FLAG_QUAL_ARG2), ui32AttachId, sUmAllocCp.ui32Size); IMG_ASSERT(!sUmAllocCp.bMappingOnly); /* Get the attachment handle from its ID...*/ ui32Result = DMANKM_GetAttachHandleFromId(ui32AttachId, &hAttachHandle); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { return ui32Result; } /* Get access to the attachment specific data...*/ psAttachContext = DMANKM_GetCompAttachmentData(hAttachHandle); /* Get access to the device handle...*/ hDevHandle = DMANKM_GetDevHandleFromAttach(hAttachHandle); /* Lock the device...*/ DMANKM_LockDeviceContext(hDevHandle); psSysDev = SYSDEVU_GetDeviceById(SYSDEVKM_GetDeviceID(psAttachContext->hSysDevHandle)); IMG_ASSERT(psSysDev != IMG_NULL); // I if (psSysDev == IMG_NULL) { return IMG_ERROR_DEVICE_NOT_FOUND; } eMemPool = (eMemAttrib & SYS_MEMATTRIB_SECURE) ? psSysDev->secureMemPool : psSysDev->sMemPool; /* Allocate allocation info...*/ psKmAlloc = IMG_MALLOC(sizeof(*psKmAlloc)); IMG_ASSERT(psKmAlloc != IMG_NULL); if (psKmAlloc == IMG_NULL) { ui32Result = IMG_ERROR_OUT_OF_MEMORY; goto error_alloc_info; } IMG_MEMSET(psKmAlloc, 0, sizeof(*psKmAlloc)); /* Save device handle etc...*/ psKmAlloc->hDevHandle = hDevHandle; psKmAlloc->sAllocInfo.ui32Size = sUmAllocCp.ui32Size; psKmAlloc->hBufHandle = NULL; psKmAlloc->eBufType = PALLOC_BUFTYPE_PALLOCATED; /* Allocate pages...*/ ui32Result = SYSMEMU_AllocatePages(sUmAllocCp.ui32Size, eMemAttrib, eMemPool, &psKmAlloc->hPagesHandle, &pui64Phys); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { goto error_alloc_pages; } #ifndef SYSBRG_BRIDGING SYSMEMU_GetCpuKmAddr(&pvKmAddr, psKmAlloc->hPagesHandle); IMG_ASSERT(pvKmAddr != IMG_NULL); if(pvKmAddr == IMG_NULL) { ui32Result = IMG_ERROR_FATAL; goto error_cpu_km_addr; } #endif /* Return addresses...*/ psSysMem = psKmAlloc->hPagesHandle; #ifdef PALLOC_EXPOSE_KM_HANDLE sUmAllocCp.hKmAllocHandle = psKmAlloc->hPagesHandle; #endif /* Check if contiguous...*/ psKmAlloc->sAllocInfo.bIsContiguous = SYSMEMKM_IsContiguous(psKmAlloc->hPagesHandle); /* Get the device id...*/ ui32Result = DMANKM_GetDeviceId(hDevHandle, &sUmAllocCp.ui32DeviceId); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { goto error_get_dev_id; } sUmAllocCp.lOffset = 0; if (psSysMem->hRegHandle) { // Determine the offset to memory if it has been made mappable in UM. sUmAllocCp.lOffset = (long)pui64Phys[0]; } /* Calculate the size of the allocation in pages...*/ ui32PageNo = (sUmAllocCp.ui32Size + SYS_MMU_PAGE_SIZE - 1)/SYS_MMU_PAGE_SIZE; psKmAlloc->sAllocInfo.psSysPAddr = IMG_BIGORSMALL_ALLOC(sizeof(IMG_SYS_PHYADDR) * ui32PageNo); IMG_ASSERT(psKmAlloc->sAllocInfo.psSysPAddr); if (IMG_NULL == psKmAlloc->sAllocInfo.psSysPAddr) { ui32Result = IMG_ERROR_OUT_OF_MEMORY; goto error_page_array; } IMG_MEMSET(psKmAlloc->sAllocInfo.psSysPAddr, 0, sizeof(IMG_SYS_PHYADDR) * ui32PageNo); for (ui32PageIdx = 0; ui32PageIdx < ui32PageNo; ++ui32PageIdx) { psKmAlloc->sAllocInfo.psSysPAddr[ui32PageIdx] = pui64Phys[ui32PageIdx]; } /* Register this with the resource manager...*/ ui32Result = RMAN_RegisterResource(psAttachContext->hResBHandle, PALLOC_RES_TYPE_1, palloc_fnFree, psKmAlloc, IMG_NULL, &sUmAllocCp.ui32AllocId); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { goto error_resource_register; } LOG_EVENT(PALLOC, PALLOC_ALLOCID, (LOG_FLAG_END | LOG_FLAG_QUAL_ARG1 |LOG_FLAG_QUAL_ARG2), ui32AttachId, sUmAllocCp.ui32AllocId); /* Unlock the device...*/ DMANKM_UnlockDeviceContext(hDevHandle); /* Copy to user changed PALLOC_sUmAlloc, including physical device addresses */ if (SYSOSKM_CopyToUser(psUmAlloc, &sUmAllocCp, sizeof(sUmAllocCp))) { ui32Result = IMG_ERROR_FATAL; goto error_copy_to_user; } if (SYSOSKM_CopyToUser(psUmAlloc->aui64DevPAddr, psKmAlloc->sAllocInfo.psSysPAddr, sizeof(psKmAlloc->sAllocInfo.psSysPAddr[0]) * ui32PageNo)) { ui32Result = IMG_ERROR_FATAL; goto error_copy_to_user; } LOG_EVENT(PALLOC, PALLOC_ALLOC, (LOG_FLAG_END | LOG_FLAG_QUAL_ARG1 |LOG_FLAG_QUAL_ARG2), ui32AttachId, sUmAllocCp.ui32Size); /* Return. */ return IMG_SUCCESS; /* Error handling. */ error_copy_to_user: /* Free everything. */ PALLOC_Free1(sUmAllocCp.ui32AllocId); goto error_return; error_resource_register: IMG_BIGORSMALL_FREE(sizeof(IMG_SYS_PHYADDR) * ui32PageNo, psKmAlloc->sAllocInfo.psSysPAddr); error_page_array: error_get_dev_id: #ifndef SYSBRG_BRIDGING error_cpu_km_addr: #endif /* SYSBRG_BRIDGING */ SYSMEMU_FreePages(psKmAlloc->hPagesHandle); error_alloc_pages: IMG_FREE(psKmAlloc); error_alloc_info: /* Unlock the device. */ DMANKM_UnlockDeviceContext(hDevHandle); error_return: return ui32Result; }