summaryrefslogtreecommitdiff
path: root/bsd-core/drm_drv.c
AgeCommit message (Expand)Author
2005-08-12Fix build after linux-side checkin of master/root-only split. Still onlyEric Anholt
2005-08-05Rename the driver hooks in the DRM to something a little moreEric Anholt
2005-08-04Fix the MGA driver on BSD by passing in the proper chipset flags to theEric Anholt
2005-06-29Get the BSD DRM compiling again after MGA and mapping changes. Note thatEric Anholt
2005-06-14Adds support for PCI cards to MGA DRMIan Romanick
2005-06-06Add a few more bits of Tonnerre's NetBSD port (Still need to deal with theEric Anholt
2005-04-16Use /*- to begin license blocks in BSD code to reduce diffs against FreeBSDEric Anholt
2005-02-19Merge r1.26 from FreeBSD: Now that mem(4) is a kernel module, we need toEric Anholt
2005-02-14Use the proper API to get PCI vendor/device number for a dev.Eric Anholt
2005-02-05- Implement drm_initmap, and extend it with the resource number to helpEric Anholt
2004-11-07Refine the locking of the DRM. Most significant is covering the driverEric Anholt
2004-11-07Now that the memory debug code is gone, and all 3 BSDs have M_ZERO, stopEric Anholt
2004-11-06Get r128 basically working: Hook up the driver's dma ioctl, use the properEric Anholt
2004-11-06Move the lock/unlock ioctls to a more logical place, in drm_lock.c.Eric Anholt
2004-11-06Hook the debug output up to a sysctl, so you can choose to enable atEric Anholt
2004-11-06Commit first pieces of port to OpenBSD, done by Martin Lexa (martin atEric Anholt
2004-11-06Commit WIP of BSD conversion to core model. Compiles for r128, radeon, butEric Anholt
2004-08-17Merged drmfntbl-0-0-1Dave Airlie
2004-08-03bring over fix from i865-agp branch, it now probes the driver, X hangsDave Airlie
2004-07-06MFC as of 20040705: dev_t -> struct cdev * change.Eric Anholt
2004-05-11Merge from FreeBSD-current. Mostly 64-bit cleanliness fixes, but a fewEric Anholt
2004-05-09Warning fixes.Eric Anholt
2004-05-09Commit sysfs and drm PCI changes for 2.6 kernelDave Airlie
2004-04-21centralise pci ids into one place and use scripts to generate files forDave Airlie
2003-12-16Don't ioremap the framebuffer area. The ioremapped area wasn't used byEric Anholt
2003-11-12Fix a locking nit, and add asserts in some things that should be calledEric Anholt
2003-11-05- Tie the DRM to a specific device: setunique no longer succeeds when givenEric Anholt
2003-11-05Remove buf_alloc which is unused since the locking commit.Eric Anholt
2003-11-04Memory layout transition:Michel Daenzer
2003-10-23- Introduce a new ioctl, DRM_IOCTL_SET_VERSION. This ioctl allows theEric Anholt
2003-10-22- Add DRM_GET_PRIV_WITH_RETURN macro. This can be used in shared code toEric Anholt
2003-10-20Fix the possibility of sleeping with locks held in sysctls by copying theEric Anholt
2003-10-20Clean up BSD MTRR handling. The NetBSD code is untested, but it's my bestEric Anholt
2003-10-19- SMPng lock the DRM. This is only partial -- there are a few code pathsEric Anholt
2003-10-17- Move IRQ functions from drm_dma.h to new drm_irq.h and disentangle themEric Anholt
2003-10-17- Converted Linux drivers to initialize DRM instances based on PCI IDs, notEric Anholt
2003-10-03Some code cleanups done while working on locking. Reduces always-trueEric Anholt
2003-10-03Stylistic preparation for SMPng locking work: DRM_LOCK/DRM_UNLOCK have sideEric Anholt
2003-10-02Mostly whitespace cleanups and style(9) fixes focused on "if(" -> "if ("Eric Anholt
2003-10-02Allow the DRM to attach to a "drmsub" device. This will be provided by theEric Anholt
2003-08-19- Remove $FreeBSD$ tags as they weren't too useful and merges are now beingEric Anholt
2003-04-28Fix a typo: On takedown the mtrr operation is MEMRANGE_SET_REMOVE, notEric Anholt
2003-04-25Merge from FreeBSD-current.Eric Anholt
2003-04-24Clean up the style of the linux-compat code and use ioctl() directly ratherEric Anholt
2003-04-24Remove more gamma DMA infrastructure. Most of this code was copied straightEric Anholt
2003-04-24Remove more gamma DMA code. This isn't all of it, but it's a major portion.Eric Anholt
2003-04-24Move some common code from addbufs_<type> to addbufs. Make buf_alloc beEric Anholt
2003-04-24Remove the ioctl_count variable from the device. A reference is held to theEric Anholt
2003-04-24Remove a bunch of dead code and fix spelling of a couple of comments.Eric Anholt
2003-04-24Move one definition to drm_drv.h and remove the rest of drm_init.h whichEric Anholt
hl com"> * Gareth Hughes <gareth@valinux.com> */ #define __NO_VERSION__ #include "drmP.h" struct vm_operations_struct drm_vm_ops = { nopage: DRM(vm_nopage), open: DRM(vm_open), close: DRM(vm_close), }; struct vm_operations_struct drm_vm_shm_ops = { nopage: DRM(vm_shm_nopage), open: DRM(vm_open), close: DRM(vm_close), }; struct vm_operations_struct drm_vm_shm_lock_ops = { nopage: DRM(vm_shm_nopage_lock), open: DRM(vm_open), close: DRM(vm_close), }; struct vm_operations_struct drm_vm_dma_ops = { nopage: DRM(vm_dma_nopage), open: DRM(vm_open), close: DRM(vm_close), }; #if LINUX_VERSION_CODE < 0x020317 unsigned long DRM(vm_nopage)(struct vm_area_struct *vma, unsigned long address, int write_access) #else /* Return type changed in 2.3.23 */ struct page *DRM(vm_nopage)(struct vm_area_struct *vma, unsigned long address, int write_access) #endif { return NOPAGE_SIGBUS; /* Disallow mremap */ } #if LINUX_VERSION_CODE < 0x020317 unsigned long DRM(vm_shm_nopage)(struct vm_area_struct *vma, unsigned long address, int write_access) #else /* Return type changed in 2.3.23 */ struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma, unsigned long address, int write_access) #endif { #if LINUX_VERSION_CODE >= 0x020300 drm_map_t *map = (drm_map_t *)vma->vm_private_data; #else drm_map_t *map = (drm_map_t *)vma->vm_pte; #endif unsigned long physical; unsigned long offset; if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */ if (!map) return NOPAGE_OOM; /* Nothing allocated */ offset = address - vma->vm_start; physical = (unsigned long)map->handle + offset; atomic_inc(&virt_to_page(physical)->count); /* Dec. by kernel */ DRM_DEBUG("0x%08lx => 0x%08lx\n", address, physical); #if LINUX_VERSION_CODE < 0x020317 return physical; #else return virt_to_page(physical); #endif } #if LINUX_VERSION_CODE < 0x020317 unsigned long DRM(vm_shm_nopage_lock)(struct vm_area_struct *vma, unsigned long address, int write_access) #else /* Return type changed in 2.3.23 */ struct page *DRM(vm_shm_nopage_lock)(struct vm_area_struct *vma, unsigned long address, int write_access) #endif { drm_file_t *priv = vma->vm_file->private_data; drm_device_t *dev = priv->dev; unsigned long physical; unsigned long offset; unsigned long page; if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */ if (!dev->lock.hw_lock) return NOPAGE_OOM; /* Nothing allocated */ offset = address - vma->vm_start; page = offset >> PAGE_SHIFT; physical = (unsigned long)dev->lock.hw_lock + offset; atomic_inc(&virt_to_page(physical)->count); /* Dec. by kernel */ DRM_DEBUG("0x%08lx (page %lu) => 0x%08lx\n", address, page, physical); #if LINUX_VERSION_CODE < 0x020317 return physical; #else return virt_to_page(physical); #endif } #if LINUX_VERSION_CODE < 0x020317 unsigned long DRM(vm_dma_nopage)(struct vm_area_struct *vma, unsigned long address, int write_access) #else /* Return type changed in 2.3.23 */ struct page *DRM(vm_dma_nopage)(struct vm_area_struct *vma, unsigned long address, int write_access) #endif { drm_file_t *priv = vma->vm_file->private_data; drm_device_t *dev = priv->dev; drm_device_dma_t *dma = dev->dma; unsigned long physical; unsigned long offset; unsigned long page; if (!dma) return NOPAGE_SIGBUS; /* Error */ if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */ if (!dma->pagelist) return NOPAGE_OOM ; /* Nothing allocated */ offset = address - vma->vm_start; /* vm_[pg]off[set] should be 0 */ page = offset >> PAGE_SHIFT; physical = dma->pagelist[page] + (offset & (~PAGE_MASK)); atomic_inc(&virt_to_page(physical)->count); /* Dec. by kernel */ DRM_DEBUG("0x%08lx (page %lu) => 0x%08lx\n", address, page, physical); #if LINUX_VERSION_CODE < 0x020317 return physical; #else return virt_to_page(physical); #endif } void DRM(vm_open)(struct vm_area_struct *vma) { drm_file_t *priv = vma->vm_file->private_data; drm_device_t *dev = priv->dev; #if DRM_DEBUG_CODE drm_vma_entry_t *vma_entry; #endif DRM_DEBUG("0x%08lx,0x%08lx\n", vma->vm_start, vma->vm_end - vma->vm_start); atomic_inc(&dev->vma_count); #if LINUX_VERSION_CODE < 0x020333 /* The map can exist after the fd is closed. */ MOD_INC_USE_COUNT; /* Needed before Linux 2.3.51 */ #endif #if DRM_DEBUG_CODE vma_entry = DRM(alloc)(sizeof(*vma_entry), DRM_MEM_VMAS); if (vma_entry) { down(&dev->struct_sem); vma_entry->vma = vma; vma_entry->next = dev->vmalist; vma_entry->pid = current->pid; dev->vmalist = vma_entry; up(&dev->struct_sem); } #endif } void DRM(vm_close)(struct vm_area_struct *vma) { drm_file_t *priv = vma->vm_file->private_data; drm_device_t *dev = priv->dev; #if DRM_DEBUG_CODE drm_vma_entry_t *pt, *prev; #endif DRM_DEBUG("0x%08lx,0x%08lx\n", vma->vm_start, vma->vm_end - vma->vm_start); #if LINUX_VERSION_CODE < 0x020333 MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */ #endif atomic_dec(&dev->vma_count); #if DRM_DEBUG_CODE down(&dev->struct_sem); for (pt = dev->vmalist, prev = NULL; pt; prev = pt, pt = pt->next) { if (pt->vma == vma) { if (prev) { prev->next = pt->next; } else { dev->vmalist = pt->next; } DRM(free)(pt, sizeof(*pt), DRM_MEM_VMAS); break; } } up(&dev->struct_sem); #endif } int DRM(mmap_dma)(struct file *filp, struct vm_area_struct *vma) { drm_file_t *priv = filp->private_data; drm_device_t *dev; drm_device_dma_t *dma; unsigned long length = vma->vm_end - vma->vm_start; lock_kernel(); dev = priv->dev; dma = dev->dma; DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n", vma->vm_start, vma->vm_end, VM_OFFSET(vma)); /* Length must match exact page count */ if (!dma || (length >> PAGE_SHIFT) != dma->page_count) { unlock_kernel(); return -EINVAL; } unlock_kernel(); vma->vm_ops = &drm_vm_dma_ops; vma->vm_flags |= VM_LOCKED | VM_SHM; /* Don't swap */ #if LINUX_VERSION_CODE < 0x020203 /* KERNEL_VERSION(2,2,3) */ /* In Linux 2.2.3 and above, this is handled in do_mmap() in mm/mmap.c. */ ++filp->f_count; #endif vma->vm_file = filp; /* Needed for drm_vm_open() */ DRM(vm_open)(vma); return 0; } int DRM(mmap)(struct file *filp, struct vm_area_struct *vma) { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; drm_map_t *map = NULL; int i; DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n", vma->vm_start, vma->vm_end, VM_OFFSET(vma)); if (!VM_OFFSET(vma)) return DRM(mmap_dma)(filp, vma); /* 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