| 124 | } |
| 125 | |
| 126 | vm_object_t |
| 127 | cdev_pager_allocate(void *handle, enum obj_type tp, struct cdev_pager_ops *ops, |
| 128 | vm_ooffset_t size, vm_prot_t prot, vm_ooffset_t foff, struct ucred *cred) |
| 129 | { |
| 130 | vm_object_t object, object1; |
| 131 | vm_pindex_t pindex; |
| 132 | u_short color; |
| 133 | |
| 134 | if (tp != OBJT_DEVICE && tp != OBJT_MGTDEVICE) |
| 135 | return (NULL); |
| 136 | KASSERT(tp == OBJT_MGTDEVICE || ops->cdev_pg_populate == NULL, |
| 137 | ("populate on unmanaged device pager")); |
| 138 | |
| 139 | /* |
| 140 | * Offset should be page aligned. |
| 141 | */ |
| 142 | if (foff & PAGE_MASK) |
| 143 | return (NULL); |
| 144 | |
| 145 | /* |
| 146 | * Treat the mmap(2) file offset as an unsigned value for a |
| 147 | * device mapping. This, in effect, allows a user to pass all |
| 148 | * possible off_t values as the mapping cookie to the driver. At |
| 149 | * this point, we know that both foff and size are a multiple |
| 150 | * of the page size. Do a check to avoid wrap. |
| 151 | */ |
| 152 | size = round_page(size); |
| 153 | pindex = OFF_TO_IDX(foff) + OFF_TO_IDX(size); |
| 154 | if (pindex > OBJ_MAX_SIZE || pindex < OFF_TO_IDX(foff) || |
| 155 | pindex < OFF_TO_IDX(size)) |
| 156 | return (NULL); |
| 157 | |
| 158 | if (ops->cdev_pg_ctor(handle, size, prot, foff, cred, &color) != 0) |
| 159 | return (NULL); |
| 160 | mtx_lock(&dev_pager_mtx); |
| 161 | |
| 162 | /* |
| 163 | * Look up pager, creating as necessary. |
| 164 | */ |
| 165 | object1 = NULL; |
| 166 | object = vm_pager_object_lookup(&dev_pager_object_list, handle); |
| 167 | if (object == NULL) { |
| 168 | /* |
| 169 | * Allocate object and associate it with the pager. Initialize |
| 170 | * the object's pg_color based upon the physical address of the |
| 171 | * device's memory. |
| 172 | */ |
| 173 | mtx_unlock(&dev_pager_mtx); |
| 174 | object1 = vm_object_allocate(tp, pindex); |
| 175 | object1->flags |= OBJ_COLORED; |
| 176 | object1->pg_color = color; |
| 177 | object1->handle = handle; |
| 178 | object1->un_pager.devp.ops = ops; |
| 179 | object1->un_pager.devp.dev = handle; |
| 180 | TAILQ_INIT(&object1->un_pager.devp.devp_pglist); |
| 181 | mtx_lock(&dev_pager_mtx); |
| 182 | object = vm_pager_object_lookup(&dev_pager_object_list, handle); |
| 183 | if (object != NULL) { |
no test coverage detected