|
@@ -290,157 +290,3 @@ int ttm_fbdev_mmap(struct vm_area_struct *vma, struct ttm_buffer_object *bo)
|
|
|
return 0;
|
|
|
}
|
|
|
EXPORT_SYMBOL(ttm_fbdev_mmap);
|
|
|
-
|
|
|
-
|
|
|
-ssize_t ttm_bo_io(struct ttm_bo_device *bdev, struct file *filp,
|
|
|
- const char __user *wbuf, char __user *rbuf, size_t count,
|
|
|
- loff_t *f_pos, bool write)
|
|
|
-{
|
|
|
- struct ttm_buffer_object *bo;
|
|
|
- struct ttm_bo_driver *driver;
|
|
|
- struct ttm_bo_kmap_obj map;
|
|
|
- unsigned long dev_offset = (*f_pos >> PAGE_SHIFT);
|
|
|
- unsigned long kmap_offset;
|
|
|
- unsigned long kmap_end;
|
|
|
- unsigned long kmap_num;
|
|
|
- size_t io_size;
|
|
|
- unsigned int page_offset;
|
|
|
- char *virtual;
|
|
|
- int ret;
|
|
|
- bool no_wait = false;
|
|
|
- bool dummy;
|
|
|
-
|
|
|
- bo = ttm_bo_vm_lookup(bdev, dev_offset, 1);
|
|
|
- if (unlikely(bo == NULL))
|
|
|
- return -EFAULT;
|
|
|
-
|
|
|
- driver = bo->bdev->driver;
|
|
|
- if (unlikely(!driver->verify_access)) {
|
|
|
- ret = -EPERM;
|
|
|
- goto out_unref;
|
|
|
- }
|
|
|
-
|
|
|
- ret = driver->verify_access(bo, filp);
|
|
|
- if (unlikely(ret != 0))
|
|
|
- goto out_unref;
|
|
|
-
|
|
|
- kmap_offset = dev_offset - drm_vma_node_start(&bo->vma_node);
|
|
|
- if (unlikely(kmap_offset >= bo->num_pages)) {
|
|
|
- ret = -EFBIG;
|
|
|
- goto out_unref;
|
|
|
- }
|
|
|
-
|
|
|
- page_offset = *f_pos & ~PAGE_MASK;
|
|
|
- io_size = bo->num_pages - kmap_offset;
|
|
|
- io_size = (io_size << PAGE_SHIFT) - page_offset;
|
|
|
- if (count < io_size)
|
|
|
- io_size = count;
|
|
|
-
|
|
|
- kmap_end = (*f_pos + count - 1) >> PAGE_SHIFT;
|
|
|
- kmap_num = kmap_end - kmap_offset + 1;
|
|
|
-
|
|
|
- ret = ttm_bo_reserve(bo, true, no_wait, false, 0);
|
|
|
-
|
|
|
- switch (ret) {
|
|
|
- case 0:
|
|
|
- break;
|
|
|
- case -EBUSY:
|
|
|
- ret = -EAGAIN;
|
|
|
- goto out_unref;
|
|
|
- default:
|
|
|
- goto out_unref;
|
|
|
- }
|
|
|
-
|
|
|
- ret = ttm_bo_kmap(bo, kmap_offset, kmap_num, &map);
|
|
|
- if (unlikely(ret != 0)) {
|
|
|
- ttm_bo_unreserve(bo);
|
|
|
- goto out_unref;
|
|
|
- }
|
|
|
-
|
|
|
- virtual = ttm_kmap_obj_virtual(&map, &dummy);
|
|
|
- virtual += page_offset;
|
|
|
-
|
|
|
- if (write)
|
|
|
- ret = copy_from_user(virtual, wbuf, io_size);
|
|
|
- else
|
|
|
- ret = copy_to_user(rbuf, virtual, io_size);
|
|
|
-
|
|
|
- ttm_bo_kunmap(&map);
|
|
|
- ttm_bo_unreserve(bo);
|
|
|
- ttm_bo_unref(&bo);
|
|
|
-
|
|
|
- if (unlikely(ret != 0))
|
|
|
- return -EFBIG;
|
|
|
-
|
|
|
- *f_pos += io_size;
|
|
|
-
|
|
|
- return io_size;
|
|
|
-out_unref:
|
|
|
- ttm_bo_unref(&bo);
|
|
|
- return ret;
|
|
|
-}
|
|
|
-
|
|
|
-ssize_t ttm_bo_fbdev_io(struct ttm_buffer_object *bo, const char __user *wbuf,
|
|
|
- char __user *rbuf, size_t count, loff_t *f_pos,
|
|
|
- bool write)
|
|
|
-{
|
|
|
- struct ttm_bo_kmap_obj map;
|
|
|
- unsigned long kmap_offset;
|
|
|
- unsigned long kmap_end;
|
|
|
- unsigned long kmap_num;
|
|
|
- size_t io_size;
|
|
|
- unsigned int page_offset;
|
|
|
- char *virtual;
|
|
|
- int ret;
|
|
|
- bool no_wait = false;
|
|
|
- bool dummy;
|
|
|
-
|
|
|
- kmap_offset = (*f_pos >> PAGE_SHIFT);
|
|
|
- if (unlikely(kmap_offset >= bo->num_pages))
|
|
|
- return -EFBIG;
|
|
|
-
|
|
|
- page_offset = *f_pos & ~PAGE_MASK;
|
|
|
- io_size = bo->num_pages - kmap_offset;
|
|
|
- io_size = (io_size << PAGE_SHIFT) - page_offset;
|
|
|
- if (count < io_size)
|
|
|
- io_size = count;
|
|
|
-
|
|
|
- kmap_end = (*f_pos + count - 1) >> PAGE_SHIFT;
|
|
|
- kmap_num = kmap_end - kmap_offset + 1;
|
|
|
-
|
|
|
- ret = ttm_bo_reserve(bo, true, no_wait, false, 0);
|
|
|
-
|
|
|
- switch (ret) {
|
|
|
- case 0:
|
|
|
- break;
|
|
|
- case -EBUSY:
|
|
|
- return -EAGAIN;
|
|
|
- default:
|
|
|
- return ret;
|
|
|
- }
|
|
|
-
|
|
|
- ret = ttm_bo_kmap(bo, kmap_offset, kmap_num, &map);
|
|
|
- if (unlikely(ret != 0)) {
|
|
|
- ttm_bo_unreserve(bo);
|
|
|
- return ret;
|
|
|
- }
|
|
|
-
|
|
|
- virtual = ttm_kmap_obj_virtual(&map, &dummy);
|
|
|
- virtual += page_offset;
|
|
|
-
|
|
|
- if (write)
|
|
|
- ret = copy_from_user(virtual, wbuf, io_size);
|
|
|
- else
|
|
|
- ret = copy_to_user(rbuf, virtual, io_size);
|
|
|
-
|
|
|
- ttm_bo_kunmap(&map);
|
|
|
- ttm_bo_unreserve(bo);
|
|
|
- ttm_bo_unref(&bo);
|
|
|
-
|
|
|
- if (unlikely(ret != 0))
|
|
|
- return ret;
|
|
|
-
|
|
|
- *f_pos += io_size;
|
|
|
-
|
|
|
- return io_size;
|
|
|
-}
|