summaryrefslogtreecommitdiff
path: root/linux-core
diff options
context:
space:
mode:
Diffstat (limited to 'linux-core')
-rw-r--r--linux-core/drmP.h19
-rw-r--r--linux-core/drm_bufs.c10
-rw-r--r--linux-core/drm_irq.c3
-rw-r--r--linux-core/drm_stub.c3
-rw-r--r--linux-core/drm_vm.c16
-rw-r--r--linux-core/radeon_drv.c2
6 files changed, 46 insertions, 7 deletions
diff --git a/linux-core/drmP.h b/linux-core/drmP.h
index d78ea7c8..17fab2bd 100644
--- a/linux-core/drmP.h
+++ b/linux-core/drmP.h
@@ -484,7 +484,8 @@ typedef struct drm_device_dma {
enum {
_DRM_DMA_USE_AGP = 0x01,
_DRM_DMA_USE_SG = 0x02,
- _DRM_DMA_USE_FB = 0x04
+ _DRM_DMA_USE_FB = 0x04,
+ _DRM_DMA_USE_PCI_RO = 0x08
} flags;
} drm_device_dma_t;
@@ -937,6 +938,8 @@ typedef struct drm_device {
drm_agp_head_t *agp; /**< AGP data */
struct pci_dev *pdev; /**< PCI device structure */
+ int pci_vendor; /**< PCI vendor id */
+ int pci_device; /**< PCI device id */
#ifdef __alpha__
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,3)
struct pci_controler *hose;
@@ -1046,7 +1049,7 @@ static __inline__ int drm_core_check_feature(struct drm_device *dev,
#ifdef __alpha__
#define drm_get_pci_domain(dev) dev->hose->bus->number
#else
-#define drm_get_pci_domain(dev) pci_domain_nr(dev->pdev->bus)
+#define drm_get_pci_domain(dev) 0
#endif
#if __OS_HAS_AGP
@@ -1079,6 +1082,18 @@ static inline int drm_mtrr_del(int handle, unsigned long offset,
}
#else
+static inline int drm_mtrr_add(unsigned long offset, unsigned long size,
+ unsigned int flags)
+{
+ return -ENODEV;
+}
+
+static inline int drm_mtrr_del(int handle, unsigned long offset,
+ unsigned long size, unsigned int flags)
+{
+ return -ENODEV;
+}
+
#define drm_core_has_MTRR(dev) (0)
#endif
diff --git a/linux-core/drm_bufs.c b/linux-core/drm_bufs.c
index dd897a19..d6ebc8d1 100644
--- a/linux-core/drm_bufs.c
+++ b/linux-core/drm_bufs.c
@@ -945,6 +945,9 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request)
request->count = entry->buf_count;
request->size = size;
+ if (request->flags & _DRM_PCI_BUFFER_RO)
+ dma->flags = _DRM_DMA_USE_PCI_RO;
+
atomic_dec(&dev->buf_alloc);
return 0;
@@ -1531,9 +1534,10 @@ int drm_freebufs(struct inode *inode, struct file *filp,
* \param arg pointer to a drm_buf_map structure.
* \return zero on success or a negative number on failure.
*
- * Maps the AGP or SG buffer region with do_mmap(), and copies information
- * about each buffer into user space. The PCI buffers are already mapped on the
- * addbufs_pci() call.
+ * Maps the AGP, SG or PCI buffer region with do_mmap(), and copies information
+ * about each buffer into user space. For PCI buffers, it calls do_mmap() with
+ * offset equal to 0, which drm_mmap() interpretes as PCI buffers and calls
+ * drm_mmap_dma().
*/
int drm_mapbufs(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
diff --git a/linux-core/drm_irq.c b/linux-core/drm_irq.c
index 21c3887d..c365c08e 100644
--- a/linux-core/drm_irq.c
+++ b/linux-core/drm_irq.c
@@ -458,7 +458,8 @@ void drm_locked_tasklet(drm_device_t *dev, void (*func)(drm_device_t*))
unsigned long irqflags;
static DECLARE_TASKLET(drm_tasklet, drm_locked_tasklet_func, 0);
- if (test_bit(TASKLET_STATE_SCHED, &drm_tasklet.state))
+ if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ) ||
+ test_bit(TASKLET_STATE_SCHED, &drm_tasklet.state))
return;
spin_lock_irqsave(&dev->tasklet_lock, irqflags);
diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c
index 8413fb4f..c03a56a1 100644
--- a/linux-core/drm_stub.c
+++ b/linux-core/drm_stub.c
@@ -67,12 +67,15 @@ static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev,
spin_lock_init(&dev->count_lock);
spin_lock_init(&dev->drw_lock);
+ spin_lock_init(&dev->tasklet_lock);
init_timer(&dev->timer);
mutex_init(&dev->struct_mutex);
mutex_init(&dev->ctxlist_mutex);
mutex_init(&dev->bm.init_mutex);
dev->pdev = pdev;
+ dev->pci_device = pdev->device;
+ dev->pci_vendor = pdev->vendor;
#ifdef __alpha__
dev->hose = pdev->sysdata;
diff --git a/linux-core/drm_vm.c b/linux-core/drm_vm.c
index aa112751..ba4b1451 100644
--- a/linux-core/drm_vm.c
+++ b/linux-core/drm_vm.c
@@ -693,6 +693,22 @@ static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma)
}
unlock_kernel();
+ if (!capable(CAP_SYS_ADMIN) &&
+ (dma->flags & _DRM_DMA_USE_PCI_RO)) {
+ vma->vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
+#if defined(__i386__) || defined(__x86_64__)
+ pgprot_val(vma->vm_page_prot) &= ~_PAGE_RW;
+#else
+ /* Ye gads this is ugly. With more thought
+ we could move this up higher and use
+ `protection_map' instead. */
+ vma->vm_page_prot =
+ __pgprot(pte_val
+ (pte_wrprotect
+ (__pte(pgprot_val(vma->vm_page_prot)))));
+#endif
+ }
+
vma->vm_ops = &drm_vm_dma_ops;
#if LINUX_VERSION_CODE <= 0x02040e /* KERNEL_VERSION(2,4,14) */
diff --git a/linux-core/radeon_drv.c b/linux-core/radeon_drv.c
index fca2d4e7..b15e983e 100644
--- a/linux-core/radeon_drv.c
+++ b/linux-core/radeon_drv.c
@@ -45,7 +45,7 @@ module_param_named(no_wb, radeon_no_wb, int, 0444);
static int dri_library_name(struct drm_device * dev, char * buf)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
- int family = dev_priv->flags & CHIP_FAMILY_MASK;
+ int family = dev_priv->flags & RADEON_FAMILY_MASK;
return snprintf(buf, PAGE_SIZE, "%s\n",
(family < CHIP_R200) ? "radeon" :