diff options
Diffstat (limited to 'sys/dev/drm/drm_vm.c')
-rw-r--r-- | sys/dev/drm/drm_vm.c | 43 |
1 files changed, 24 insertions, 19 deletions
diff --git a/sys/dev/drm/drm_vm.c b/sys/dev/drm/drm_vm.c index 8f260fd..7986856 100644 --- a/sys/dev/drm/drm_vm.c +++ b/sys/dev/drm/drm_vm.c @@ -54,6 +54,7 @@ int drm_mmap(struct cdev *kdev, vm_ooffset_t offset, vm_paddr_t *paddr, if (file_priv && !file_priv->authenticated) return EACCES; + DRM_DEBUG("called with offset %016jx\n", offset); if (dev->dma && offset < ptoa(dev->dma->page_count)) { drm_device_dma_t *dma = dev->dma; @@ -72,31 +73,31 @@ int drm_mmap(struct cdev *kdev, vm_ooffset_t offset, vm_paddr_t *paddr, } } - /* A sequential search of a linked list is - fine here because: 1) there will only be - about 5-10 entries in the list and, 2) a - DRI client only has to do this mapping - once, so it doesn't have to be optimized - for performance, even if the list was a - bit longer. */ + /* A sequential search of a linked list is + fine here because: 1) there will only be + about 5-10 entries in the list and, 2) a + DRI client only has to do this mapping + once, so it doesn't have to be optimized + for performance, even if the list was a + bit longer. + */ DRM_LOCK(); TAILQ_FOREACH(map, &dev->maplist, link) { - if (offset >= map->offset && offset < map->offset + map->size) + if (offset >> DRM_MAP_HANDLE_SHIFT == + (unsigned long)map->handle >> DRM_MAP_HANDLE_SHIFT) break; } if (map == NULL) { - DRM_DEBUG("Can't find map, requested offset = %016lx\n", - (unsigned long)offset); + DRM_DEBUG("Can't find map, request offset = %016jx\n", offset); TAILQ_FOREACH(map, &dev->maplist, link) { DRM_DEBUG("map offset = %016lx, handle = %016lx\n", - (unsigned long)map->offset, - (unsigned long)map->handle); + map->offset, (unsigned long)map->handle); } DRM_UNLOCK(); return -1; } - if (((map->flags&_DRM_RESTRICTED) && !DRM_SUSER(DRM_CURPROC))) { + if (((map->flags & _DRM_RESTRICTED) && !DRM_SUSER(DRM_CURPROC))) { DRM_UNLOCK(); DRM_DEBUG("restricted map\n"); return -1; @@ -104,18 +105,22 @@ int drm_mmap(struct cdev *kdev, vm_ooffset_t offset, vm_paddr_t *paddr, type = map->type; DRM_UNLOCK(); + offset = offset & ((1ULL << DRM_MAP_HANDLE_SHIFT) - 1); + switch (type) { case _DRM_FRAME_BUFFER: - case _DRM_REGISTERS: case _DRM_AGP: - phys = offset; - break; - case _DRM_CONSISTENT: - phys = vtophys((char *)map->handle + (offset - map->offset)); + *memattr = VM_MEMATTR_WRITE_COMBINING; + /* FALLTHROUGH */ + case _DRM_REGISTERS: + phys = map->offset + offset; break; case _DRM_SCATTER_GATHER: + *memattr = VM_MEMATTR_WRITE_COMBINING; + /* FALLTHROUGH */ + case _DRM_CONSISTENT: case _DRM_SHM: - phys = vtophys(offset); + phys = vtophys((char *)map->virtual + offset); break; default: DRM_ERROR("bad map type %d\n", type); |