1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-21 11:13:30 +00:00

Use dev_re[fl]thread() to maintain a ref on the device driver while

we call the ->d_mmap function.
This commit is contained in:
Poul-Henning Kamp 2004-09-24 05:59:11 +00:00
parent 5ef8cac184
commit 751fdd08fe
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=135707

View File

@ -103,12 +103,12 @@ static vm_object_t
dev_pager_alloc(void *handle, vm_ooffset_t size, vm_prot_t prot, vm_ooffset_t foff) dev_pager_alloc(void *handle, vm_ooffset_t size, vm_prot_t prot, vm_ooffset_t foff)
{ {
struct cdev *dev; struct cdev *dev;
d_mmap_t *mapfunc;
vm_object_t object; vm_object_t object;
vm_pindex_t pindex; vm_pindex_t pindex;
unsigned int npages; unsigned int npages;
vm_paddr_t paddr; vm_paddr_t paddr;
vm_offset_t off; vm_offset_t off;
struct cdevsw *csw;
/* /*
* Offset should be page aligned. * Offset should be page aligned.
@ -123,13 +123,10 @@ dev_pager_alloc(void *handle, vm_ooffset_t size, vm_prot_t prot, vm_ooffset_t fo
* Make sure this device can be mapped. * Make sure this device can be mapped.
*/ */
dev = handle; dev = handle;
mtx_lock(&Giant); csw = dev_refthread(dev);
mapfunc = devsw(dev)->d_mmap; if (csw == NULL)
if (mapfunc == NULL || mapfunc == (d_mmap_t *)nullop) {
printf("obsolete map function %p\n", (void *)mapfunc);
mtx_unlock(&Giant);
return (NULL); return (NULL);
} mtx_lock(&Giant);
/* /*
* Check that the specified range of the device allows the desired * Check that the specified range of the device allows the desired
@ -139,8 +136,9 @@ dev_pager_alloc(void *handle, vm_ooffset_t size, vm_prot_t prot, vm_ooffset_t fo
*/ */
npages = OFF_TO_IDX(size); npages = OFF_TO_IDX(size);
for (off = foff; npages--; off += PAGE_SIZE) for (off = foff; npages--; off += PAGE_SIZE)
if ((*mapfunc)(dev, off, &paddr, (int)prot) != 0) { if ((*csw->d_mmap)(dev, off, &paddr, (int)prot) != 0) {
mtx_unlock(&Giant); mtx_unlock(&Giant);
dev_relthread(dev);
return (NULL); return (NULL);
} }
@ -174,6 +172,7 @@ dev_pager_alloc(void *handle, vm_ooffset_t size, vm_prot_t prot, vm_ooffset_t fo
sx_xunlock(&dev_pager_sx); sx_xunlock(&dev_pager_sx);
mtx_unlock(&Giant); mtx_unlock(&Giant);
dev_relthread(dev);
return (object); return (object);
} }
@ -207,23 +206,23 @@ dev_pager_getpages(object, m, count, reqpage)
vm_page_t page; vm_page_t page;
struct cdev *dev; struct cdev *dev;
int i, ret; int i, ret;
d_mmap_t *mapfunc;
int prot; int prot;
struct cdevsw *csw;
VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); VM_OBJECT_LOCK_ASSERT(object, MA_OWNED);
dev = object->handle; dev = object->handle;
offset = m[reqpage]->pindex; offset = m[reqpage]->pindex;
VM_OBJECT_UNLOCK(object); VM_OBJECT_UNLOCK(object);
csw = dev_refthread(dev);
if (csw == NULL)
panic("dev_pager_getpage: no cdevsw");
mtx_lock(&Giant); mtx_lock(&Giant);
prot = PROT_READ; /* XXX should pass in? */ prot = PROT_READ; /* XXX should pass in? */
mapfunc = devsw(dev)->d_mmap;
if (mapfunc == NULL || mapfunc == (d_mmap_t *)nullop) ret = (*csw->d_mmap)(dev, (vm_offset_t)offset << PAGE_SHIFT, &paddr, prot);
panic("dev_pager_getpage: no map function");
ret = (*mapfunc)(dev, (vm_offset_t)offset << PAGE_SHIFT, &paddr, prot);
KASSERT(ret == 0, ("dev_pager_getpage: map function returns error")); KASSERT(ret == 0, ("dev_pager_getpage: map function returns error"));
mtx_unlock(&Giant); mtx_unlock(&Giant);
dev_relthread(dev);
if ((m[reqpage]->flags & PG_FICTITIOUS) != 0) { if ((m[reqpage]->flags & PG_FICTITIOUS) != 0) {
/* /*