ARGSUSED */
| 74 | |
| 75 | /* ARGSUSED */ |
| 76 | int |
| 77 | memrw(struct cdev *dev, struct uio *uio, int flags) |
| 78 | { |
| 79 | struct iovec *iov; |
| 80 | int error = 0; |
| 81 | vm_offset_t va, eva, off, v; |
| 82 | vm_prot_t prot; |
| 83 | struct vm_page m; |
| 84 | vm_page_t marr; |
| 85 | vm_size_t cnt; |
| 86 | |
| 87 | cnt = 0; |
| 88 | error = 0; |
| 89 | |
| 90 | pmap_page_init(&m); |
| 91 | while (uio->uio_resid > 0 && !error) { |
| 92 | iov = uio->uio_iov; |
| 93 | if (iov->iov_len == 0) { |
| 94 | uio->uio_iov++; |
| 95 | uio->uio_iovcnt--; |
| 96 | if (uio->uio_iovcnt < 0) |
| 97 | panic("memrw"); |
| 98 | continue; |
| 99 | } |
| 100 | if (dev2unit(dev) == CDEV_MINOR_MEM) { |
| 101 | v = uio->uio_offset; |
| 102 | |
| 103 | off = uio->uio_offset & PAGE_MASK; |
| 104 | cnt = PAGE_SIZE - ((vm_offset_t)iov->iov_base & |
| 105 | PAGE_MASK); |
| 106 | cnt = min(cnt, PAGE_SIZE - off); |
| 107 | cnt = min(cnt, iov->iov_len); |
| 108 | |
| 109 | m.phys_addr = trunc_page(v); |
| 110 | marr = &m; |
| 111 | error = uiomove_fromphys(&marr, off, cnt, uio); |
| 112 | } |
| 113 | else if (dev2unit(dev) == CDEV_MINOR_KMEM) { |
| 114 | va = uio->uio_offset; |
| 115 | |
| 116 | va = trunc_page(uio->uio_offset); |
| 117 | eva = round_page(uio->uio_offset |
| 118 | + iov->iov_len); |
| 119 | |
| 120 | /* |
| 121 | * Make sure that all the pages are currently resident |
| 122 | * so that we don't create any zero-fill pages. |
| 123 | */ |
| 124 | if (va >= VM_MIN_KERNEL_ADDRESS && |
| 125 | eva <= VM_MAX_KERNEL_ADDRESS) { |
| 126 | for (; va < eva; va += PAGE_SIZE) |
| 127 | if (pmap_extract(kernel_pmap, va) == 0) |
| 128 | return (EFAULT); |
| 129 | |
| 130 | prot = (uio->uio_rw == UIO_READ) |
| 131 | ? VM_PROT_READ : VM_PROT_WRITE; |
| 132 | |
| 133 | va = uio->uio_offset; |
nothing calls this directly
no test coverage detected