aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/drm
diff options
context:
space:
mode:
authorGeorge Sapountzis <gsap7@yahoo.gr>2006-10-24 15:03:04 -0400
committerairlied <airlied@linux.ie>2006-12-06 23:53:31 -0500
commit3417f33e762bf7d4277031a655e3ad07e73ce0be (patch)
tree255d4871a0a7affbeab8d35f5b072a70ef064cfd /drivers/char/drm
parent5c2df2bfb121a77d925dba580f53da08b4020528 (diff)
drm: add flag for mapping PCI DMA buffers read-only.
Add DRM_PCI_BUFFER_RO flag for mapping PCI DMA buffer read-only. An additional flag is needed, since PCI DMA buffers do not have an associated map. Signed-off-by: Dave Airlie <airlied@linux.ie>
Diffstat (limited to 'drivers/char/drm')
-rw-r--r--drivers/char/drm/drm.h3
-rw-r--r--drivers/char/drm/drmP.h3
-rw-r--r--drivers/char/drm/drm_bufs.c10
-rw-r--r--drivers/char/drm/drm_vm.c16
4 files changed, 27 insertions, 5 deletions
diff --git a/drivers/char/drm/drm.h b/drivers/char/drm/drm.h
index 3f28a1551621..8db9041e306c 100644
--- a/drivers/char/drm/drm.h
+++ b/drivers/char/drm/drm.h
@@ -356,7 +356,8 @@ typedef struct drm_buf_desc {
356 _DRM_PAGE_ALIGN = 0x01, /**< Align on page boundaries for DMA */ 356 _DRM_PAGE_ALIGN = 0x01, /**< Align on page boundaries for DMA */
357 _DRM_AGP_BUFFER = 0x02, /**< Buffer is in AGP space */ 357 _DRM_AGP_BUFFER = 0x02, /**< Buffer is in AGP space */
358 _DRM_SG_BUFFER = 0x04, /**< Scatter/gather memory buffer */ 358 _DRM_SG_BUFFER = 0x04, /**< Scatter/gather memory buffer */
359 _DRM_FB_BUFFER = 0x08 /**< Buffer is in frame buffer */ 359 _DRM_FB_BUFFER = 0x08, /**< Buffer is in frame buffer */
360 _DRM_PCI_BUFFER_RO = 0x10 /**< Map PCI DMA buffer read-only */
360 } flags; 361 } flags;
361 unsigned long agp_start; /**< 362 unsigned long agp_start; /**<
362 * Start address of where the AGP buffers are 363 * Start address of where the AGP buffers are
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
index 2f18329c5eb8..0bbb04f2390f 100644
--- a/drivers/char/drm/drmP.h
+++ b/drivers/char/drm/drmP.h
@@ -431,7 +431,8 @@ typedef struct drm_device_dma {
431 enum { 431 enum {
432 _DRM_DMA_USE_AGP = 0x01, 432 _DRM_DMA_USE_AGP = 0x01,
433 _DRM_DMA_USE_SG = 0x02, 433 _DRM_DMA_USE_SG = 0x02,
434 _DRM_DMA_USE_FB = 0x04 434 _DRM_DMA_USE_FB = 0x04,
435 _DRM_DMA_USE_PCI_RO = 0x08
435 } flags; 436 } flags;
436 437
437} drm_device_dma_t; 438} drm_device_dma_t;
diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c
index 6eafff13dab6..9f65f5697ba8 100644
--- a/drivers/char/drm/drm_bufs.c
+++ b/drivers/char/drm/drm_bufs.c
@@ -887,6 +887,9 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request)
887 request->count = entry->buf_count; 887 request->count = entry->buf_count;
888 request->size = size; 888 request->size = size;
889 889
890 if (request->flags & _DRM_PCI_BUFFER_RO)
891 dma->flags = _DRM_DMA_USE_PCI_RO;
892
890 atomic_dec(&dev->buf_alloc); 893 atomic_dec(&dev->buf_alloc);
891 return 0; 894 return 0;
892 895
@@ -1471,9 +1474,10 @@ int drm_freebufs(struct inode *inode, struct file *filp,
1471 * \param arg pointer to a drm_buf_map structure. 1474 * \param arg pointer to a drm_buf_map structure.
1472 * \return zero on success or a negative number on failure. 1475 * \return zero on success or a negative number on failure.
1473 * 1476 *
1474 * Maps the AGP or SG buffer region with do_mmap(), and copies information 1477 * Maps the AGP, SG or PCI buffer region with do_mmap(), and copies information
1475 * about each buffer into user space. The PCI buffers are already mapped on the 1478 * about each buffer into user space. For PCI buffers, it calls do_mmap() with
1476 * addbufs_pci() call. 1479 * offset equal to 0, which drm_mmap() interpretes as PCI buffers and calls
1480 * drm_mmap_dma().
1477 */ 1481 */
1478int drm_mapbufs(struct inode *inode, struct file *filp, 1482int drm_mapbufs(struct inode *inode, struct file *filp,
1479 unsigned int cmd, unsigned long arg) 1483 unsigned int cmd, unsigned long arg)
diff --git a/drivers/char/drm/drm_vm.c b/drivers/char/drm/drm_vm.c
index b40ae438f531..74686e9a2d34 100644
--- a/drivers/char/drm/drm_vm.c
+++ b/drivers/char/drm/drm_vm.c
@@ -473,6 +473,22 @@ static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma)
473 } 473 }
474 unlock_kernel(); 474 unlock_kernel();
475 475
476 if (!capable(CAP_SYS_ADMIN) &&
477 (dma->flags & _DRM_DMA_USE_PCI_RO)) {
478 vma->vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
479#if defined(__i386__) || defined(__x86_64__)
480 pgprot_val(vma->vm_page_prot) &= ~_PAGE_RW;
481#else
482 /* Ye gads this is ugly. With more thought
483 we could move this up higher and use
484 `protection_map' instead. */
485 vma->vm_page_prot =
486 __pgprot(pte_val
487 (pte_wrprotect
488 (__pte(pgprot_val(vma->vm_page_prot)))));
489#endif
490 }
491
476 vma->vm_ops = &drm_vm_dma_ops; 492 vma->vm_ops = &drm_vm_dma_ops;
477 493
478 vma->vm_flags |= VM_RESERVED; /* Don't swap */ 494 vma->vm_flags |= VM_RESERVED; /* Don't swap */