int amdgpu_bo_cpu_unmap(amdgpu_bo_handle bo) { int r; pthread_mutex_lock(&bo->cpu_access_mutex); assert(bo->cpu_map_count >= 0); if (bo->cpu_map_count == 0) { /* not mapped */ pthread_mutex_unlock(&bo->cpu_access_mutex); return -EBADMSG; } bo->cpu_map_count--; if (bo->cpu_map_count > 0) { /* mapped multiple times */ pthread_mutex_unlock(&bo->cpu_access_mutex); return 0; } r = drm_munmap(bo->cpu_ptr, bo->alloc_size) == 0 ? 0 : -errno; bo->cpu_ptr = NULL; pthread_mutex_unlock(&bo->cpu_access_mutex); return r; }
static void bo_unmap(struct bo *bo) { if (!bo->ptr) return; drm_munmap(bo->ptr, bo->size); bo->ptr = NULL; }
static struct radeon_bo *bo_unref(struct radeon_bo_int *boi) { struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)boi; struct drm_gem_close args; if (boi->cref) { return (struct radeon_bo *)boi; } if (bo_gem->priv_ptr) { drm_munmap(bo_gem->priv_ptr, boi->size); } /* Zero out args to make valgrind happy */ memset(&args, 0, sizeof(args)); /* close object */ args.handle = boi->handle; drmIoctl(boi->bom->fd, DRM_IOCTL_GEM_CLOSE, &args); memset(bo_gem, 0, sizeof(struct radeon_bo_gem)); free(bo_gem); return NULL; }
/* Called under table_lock */ drm_private void bo_del(struct fd_bo *bo) { VG_BO_FREE(bo); if (bo->map) drm_munmap(bo->map, bo->size); /* TODO probably bo's in bucket list get removed from * handle table?? */ if (bo->handle) { struct drm_gem_close req = { .handle = bo->handle, }; drmHashDelete(bo->dev->handle_table, bo->handle); if (bo->name) drmHashDelete(bo->dev->name_table, bo->name); drmIoctl(bo->dev->fd, DRM_IOCTL_GEM_CLOSE, &req); } bo->funcs->destroy(bo); } int fd_bo_get_name(struct fd_bo *bo, uint32_t *name) { if (!bo->name) { struct drm_gem_flink req = { .handle = bo->handle, }; int ret; ret = drmIoctl(bo->dev->fd, DRM_IOCTL_GEM_FLINK, &req); if (ret) { return ret; } pthread_mutex_lock(&table_lock); set_name(bo, req.name); pthread_mutex_unlock(&table_lock); bo->bo_reuse = FALSE; } *name = bo->name; return 0; } uint32_t fd_bo_handle(struct fd_bo *bo) { return bo->handle; } int fd_bo_dmabuf(struct fd_bo *bo) { int ret, prime_fd; ret = drmPrimeHandleToFD(bo->dev->fd, bo->handle, DRM_CLOEXEC, &prime_fd); if (ret) { ERROR_MSG("failed to get dmabuf fd: %d", ret); return ret; } bo->bo_reuse = FALSE; return prime_fd; } uint32_t fd_bo_size(struct fd_bo *bo) { return bo->size; } void * fd_bo_map(struct fd_bo *bo) { if (!bo->map) { uint64_t offset; int ret; ret = bo->funcs->offset(bo, &offset); if (ret) { return NULL; } bo->map = drm_mmap(0, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED, bo->dev->fd, offset); if (bo->map == MAP_FAILED) { ERROR_MSG("mmap failed: %s", strerror(errno)); bo->map = NULL; } } return bo->map; } /* a bit odd to take the pipe as an arg, but it's a, umm, quirk of kgsl.. */ int fd_bo_cpu_prep(struct fd_bo *bo, struct fd_pipe *pipe, uint32_t op) { return bo->funcs->cpu_prep(bo, pipe, op); } void fd_bo_cpu_fini(struct fd_bo *bo) { bo->funcs->cpu_fini(bo); }