int armsoc_bo_cpu_prep(struct armsoc_bo *bo, enum armsoc_gem_op op) { int ret = 0; assert(bo->refcnt > 0); if (armsoc_bo_has_dmabuf(bo)) { fd_set fds; /* 10s before printing a msg */ const struct timeval timeout = {10, 0}; struct timeval t; FD_ZERO(&fds); FD_SET(bo->dmabuf, &fds); do { t = timeout; ret = select(bo->dmabuf+1, &fds, NULL, NULL, &t); if (ret == 0) xf86DrvMsg(-1, X_ERROR, "select() on dma_buf fd has timed-out\n"); } while ((ret == -1 && errno == EINTR) || ret == 0); if (ret > 0) ret = 0; } return ret; }
void armsoc_bo_clear_dmabuf(struct armsoc_bo *bo) { assert(bo->refcnt > 0); assert(armsoc_bo_has_dmabuf(bo)); close(bo->dmabuf); bo->dmabuf = -1; }
/* used by DRI2 code to play buffer switcharoo */ void ARMSOCPixmapExchange(PixmapPtr a, PixmapPtr b) { struct ARMSOCPixmapPrivRec *apriv = exaGetPixmapDriverPrivate(a); struct ARMSOCPixmapPrivRec *bpriv = exaGetPixmapDriverPrivate(b); exchange(apriv->priv, bpriv->priv); exchange(apriv->bo, bpriv->bo); /* Ensure neither pixmap has a dmabuf fd attached to the bo if the * ext_access_cnt refcount is 0, as it will never be cleared. */ if (armsoc_bo_has_dmabuf(apriv->bo) && !apriv->ext_access_cnt) { armsoc_bo_clear_dmabuf(apriv->bo); /* Should only have to clear one dmabuf fd, otherwise the * refcount is wrong */ assert(!armsoc_bo_has_dmabuf(bpriv->bo)); } else if (armsoc_bo_has_dmabuf(bpriv->bo) && !bpriv->ext_access_cnt) { armsoc_bo_clear_dmabuf(bpriv->bo); assert(!armsoc_bo_has_dmabuf(apriv->bo)); } }
int armsoc_bo_set_dmabuf(struct armsoc_bo *bo) { int res; struct drm_prime_handle prime_handle; assert(bo->refcnt > 0); assert(!armsoc_bo_has_dmabuf(bo)); /* Try to get dma_buf fd */ prime_handle.handle = bo->handle; prime_handle.flags = 0; res = drmIoctl(bo->dev->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &prime_handle); if (res) res = errno; else bo->dmabuf = prime_handle.fd; return res; }