--- //depot/vendor/freebsd/src/sys/dev/drm/drm_bufs.h 2005/02/22 14:00:48 +++ //depot/user/jhb/acpipci/dev/drm/drm_bufs.h 2005/02/25 19:55:35 @@ -923,12 +923,8 @@ #ifdef __FreeBSD__ vaddr = round_page((vm_offset_t)vms->vm_daddr + MAXDSIZ); -#ifdef this_is_just_plain_bogus retcode = vm_mmap(&vms->vm_map, &vaddr, size, PROT_READ | PROT_WRITE, - VM_PROT_ALL, MAP_SHARED, SLIST_FIRST(&kdev->si_hlist), foff ); -#else - retcode = EOPNOTSUPP; -#endif + VM_PROT_ALL, MAP_SHARED | MAP_CDEV, kdev, foff ); #elif defined(__NetBSD__) vaddr = round_page((vaddr_t)vms->vm_daddr + MAXDSIZ); retcode = uvm_mmap(&vms->vm_map, &vaddr, size, --- //depot/vendor/freebsd/src/sys/sys/mman.h 2004/04/27 13:15:33 +++ //depot/user/jhb/acpipci/sys/mman.h 2005/02/25 19:55:35 @@ -84,6 +84,10 @@ * Extended flags */ #define MAP_NOCORE 0x00020000 /* dont include these pages in a coredump */ +#ifdef _KERNEL +#define MAP_CDEV 0x00040000 /* map from a cdev, not a vnode */ +#define MAP_KERNEL_ONLY MAP_CDEV +#endif #endif /* __BSD_VISIBLE */ #if __POSIX_VISIBLE >= 199309 --- //depot/vendor/freebsd/src/sys/vm/vm_mmap.c 2005/01/25 00:40:30 +++ //depot/user/jhb/acpipci/vm/vm_mmap.c 2005/02/25 20:00:21 @@ -109,6 +109,8 @@ static int vm_mmap_vnode(struct thread *, vm_size_t, vm_prot_t, vm_prot_t *, int *, struct vnode *, vm_ooffset_t, vm_object_t *); +static int vm_mmap_cdev(struct thread *, vm_size_t, vm_prot_t, vm_prot_t *, + int *, struct cdev *, vm_ooffset_t, vm_object_t *); /* * MPSAFE @@ -218,7 +220,7 @@ fp = NULL; /* make sure mapping fits into numeric range etc */ if ((ssize_t) uap->len < 0 || - ((flags & MAP_ANON) && uap->fd != -1)) + ((flags & MAP_ANON) && uap->fd != -1) || (flags & MAP_KERNEL_ONLY)) return (EINVAL); if (flags & MAP_STACK) { @@ -1166,6 +1168,55 @@ } /* + * vm_mmap_cdev() + * + * MPSAFE + * + * Helper function for vm_mmap. Perform sanity check specific for mmap + * operations on cdevs. + */ +int +vm_mmap_cdev(struct thread *td, vm_size_t objsize, + vm_prot_t prot, vm_prot_t *maxprotp, int *flagsp, + struct cdev *cdev, vm_ooffset_t foff, vm_object_t *objp) +{ + vm_object_t obj; + int flags; + + flags = *flagsp; + + /* XXX: lack thredref on device */ + if (cdev->si_devsw->d_flags & D_MMAP_ANON) { + *maxprotp = VM_PROT_ALL; + *flagsp |= MAP_ANON; + return (0); + } + /* + * cdevs does not provide private mappings of any kind. + */ + if ((*maxprotp & VM_PROT_WRITE) == 0 && + (prot & PROT_WRITE) != 0) + return (EACCES); + if (flags & (MAP_PRIVATE|MAP_COPY)) + return (EINVAL); + /* + * Force device mappings to be shared. + */ + flags |= MAP_SHARED; +#ifdef MAC_XXX + error = mac_check_vnode_mmap(td->td_ucred, vp, prot); + if (error != 0) + return (error); +#endif + obj = vm_pager_allocate(OBJT_DEVICE, cdev, objsize, prot, foff); + if (obj == NULL) + return (EINVAL); + *objp = obj; + *flagsp = flags; + return (0); +} + +/* * vm_mmap() * * MPSAFE @@ -1223,11 +1274,14 @@ * Lookup/allocate object. */ if (handle != NULL) { - error = vm_mmap_vnode(td, size, prot, &maxprot, &flags, - handle, foff, &object); - if (error) { + if (flags & MAP_CDEV) + error = vm_mmap_cdev(td, size, prot, &maxprot, &flags, + handle, foff, &object); + else + error = vm_mmap_vnode(td, size, prot, &maxprot, &flags, + handle, foff, &object); + if (error) return (error); - } } if (flags & MAP_ANON) { object = NULL;