diff options
Diffstat (limited to 'linux-core')
-rw-r--r-- | linux-core/drmP.h | 19 | ||||
-rw-r--r-- | linux-core/drm_bufs.c | 10 | ||||
-rw-r--r-- | linux-core/drm_irq.c | 3 | ||||
-rw-r--r-- | linux-core/drm_stub.c | 3 | ||||
-rw-r--r-- | linux-core/drm_vm.c | 16 | ||||
-rw-r--r-- | linux-core/radeon_drv.c | 2 |
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" : |