1 1.16 riastrad /* $NetBSD: drm_bufs.c,v 1.16 2021/12/19 12:30:04 riastradh Exp $ */ 2 1.1 riastrad 3 1.1 riastrad /* 4 1.8 riastrad * Legacy: Generic DRM Buffer Management 5 1.1 riastrad * 6 1.1 riastrad * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas. 7 1.1 riastrad * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. 8 1.1 riastrad * All Rights Reserved. 9 1.1 riastrad * 10 1.8 riastrad * Author: Rickard E. (Rik) Faith <faith (at) valinux.com> 11 1.8 riastrad * Author: Gareth Hughes <gareth (at) valinux.com> 12 1.8 riastrad * 13 1.1 riastrad * Permission is hereby granted, free of charge, to any person obtaining a 14 1.1 riastrad * copy of this software and associated documentation files (the "Software"), 15 1.1 riastrad * to deal in the Software without restriction, including without limitation 16 1.1 riastrad * the rights to use, copy, modify, merge, publish, distribute, sublicense, 17 1.1 riastrad * and/or sell copies of the Software, and to permit persons to whom the 18 1.1 riastrad * Software is furnished to do so, subject to the following conditions: 19 1.1 riastrad * 20 1.1 riastrad * The above copyright notice and this permission notice (including the next 21 1.1 riastrad * paragraph) shall be included in all copies or substantial portions of the 22 1.1 riastrad * Software. 23 1.1 riastrad * 24 1.1 riastrad * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 25 1.1 riastrad * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 26 1.1 riastrad * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 27 1.1 riastrad * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 28 1.1 riastrad * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 29 1.1 riastrad * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 30 1.1 riastrad * OTHER DEALINGS IN THE SOFTWARE. 31 1.1 riastrad */ 32 1.1 riastrad 33 1.8 riastrad #include <sys/cdefs.h> 34 1.16 riastrad __KERNEL_RCSID(0, "$NetBSD: drm_bufs.c,v 1.16 2021/12/19 12:30:04 riastradh Exp $"); 35 1.8 riastrad 36 1.13 riastrad #include <linux/export.h> 37 1.13 riastrad #include <linux/log2.h> 38 1.13 riastrad #include <linux/mm.h> 39 1.13 riastrad #include <linux/mman.h> 40 1.13 riastrad #include <linux/nospec.h> 41 1.13 riastrad #include <linux/slab.h> 42 1.13 riastrad #include <linux/uaccess.h> 43 1.1 riastrad #include <linux/vmalloc.h> 44 1.13 riastrad 45 1.1 riastrad #include <asm/shmparam.h> 46 1.13 riastrad 47 1.13 riastrad #include <drm/drm_agpsupport.h> 48 1.13 riastrad #include <drm/drm_device.h> 49 1.13 riastrad #include <drm/drm_drv.h> 50 1.13 riastrad #include <drm/drm_file.h> 51 1.13 riastrad #include <drm/drm_pci.h> 52 1.13 riastrad #include <drm/drm_print.h> 53 1.13 riastrad 54 1.8 riastrad #include "drm_legacy.h" 55 1.1 riastrad 56 1.13 riastrad 57 1.1 riastrad static struct drm_map_list *drm_find_matching_map(struct drm_device *dev, 58 1.1 riastrad struct drm_local_map *map) 59 1.1 riastrad { 60 1.1 riastrad struct drm_map_list *entry; 61 1.1 riastrad list_for_each_entry(entry, &dev->maplist, head) { 62 1.1 riastrad /* 63 1.1 riastrad * Because the kernel-userspace ABI is fixed at a 32-bit offset 64 1.1 riastrad * while PCI resources may live above that, we only compare the 65 1.1 riastrad * lower 32 bits of the map offset for maps of type 66 1.1 riastrad * _DRM_FRAMEBUFFER or _DRM_REGISTERS. 67 1.1 riastrad * It is assumed that if a driver have more than one resource 68 1.1 riastrad * of each type, the lower 32 bits are different. 69 1.1 riastrad */ 70 1.1 riastrad if (!entry->map || 71 1.1 riastrad map->type != entry->map->type || 72 1.13 riastrad entry->master != dev->master) 73 1.1 riastrad continue; 74 1.1 riastrad switch (map->type) { 75 1.1 riastrad case _DRM_SHM: 76 1.1 riastrad if (map->flags != _DRM_CONTAINS_LOCK) 77 1.1 riastrad break; 78 1.1 riastrad return entry; 79 1.1 riastrad case _DRM_REGISTERS: 80 1.1 riastrad case _DRM_FRAME_BUFFER: 81 1.1 riastrad if ((entry->map->offset & 0xffffffff) == 82 1.1 riastrad (map->offset & 0xffffffff)) 83 1.1 riastrad return entry; 84 1.1 riastrad default: /* Make gcc happy */ 85 1.1 riastrad ; 86 1.1 riastrad } 87 1.1 riastrad if (entry->map->offset == map->offset) 88 1.1 riastrad return entry; 89 1.1 riastrad } 90 1.1 riastrad 91 1.1 riastrad return NULL; 92 1.1 riastrad } 93 1.1 riastrad 94 1.1 riastrad static int drm_map_handle(struct drm_device *dev, struct drm_hash_item *hash, 95 1.1 riastrad unsigned long user_token, int hashed_handle, int shm) 96 1.1 riastrad { 97 1.1 riastrad int use_hashed_handle, shift; 98 1.1 riastrad unsigned long add; 99 1.1 riastrad 100 1.2 riastrad use_hashed_handle = (user_token &~ 0xffffffffUL) || hashed_handle; 101 1.1 riastrad if (!use_hashed_handle) { 102 1.1 riastrad int ret; 103 1.1 riastrad hash->key = user_token >> PAGE_SHIFT; 104 1.1 riastrad ret = drm_ht_insert_item(&dev->map_hash, hash); 105 1.1 riastrad if (ret != -EINVAL) 106 1.1 riastrad return ret; 107 1.1 riastrad } 108 1.1 riastrad 109 1.1 riastrad shift = 0; 110 1.1 riastrad add = DRM_MAP_HASH_OFFSET >> PAGE_SHIFT; 111 1.1 riastrad if (shm && (SHMLBA > PAGE_SIZE)) { 112 1.1 riastrad int bits = ilog2(SHMLBA >> PAGE_SHIFT) + 1; 113 1.1 riastrad 114 1.1 riastrad /* For shared memory, we have to preserve the SHMLBA 115 1.1 riastrad * bits of the eventual vma->vm_pgoff value during 116 1.1 riastrad * mmap(). Otherwise we run into cache aliasing problems 117 1.1 riastrad * on some platforms. On these platforms, the pgoff of 118 1.1 riastrad * a mmap() request is used to pick a suitable virtual 119 1.1 riastrad * address for the mmap() region such that it will not 120 1.1 riastrad * cause cache aliasing problems. 121 1.1 riastrad * 122 1.1 riastrad * Therefore, make sure the SHMLBA relevant bits of the 123 1.1 riastrad * hash value we use are equal to those in the original 124 1.1 riastrad * kernel virtual address. 125 1.1 riastrad */ 126 1.1 riastrad shift = bits; 127 1.1 riastrad add |= ((user_token >> PAGE_SHIFT) & ((1UL << bits) - 1UL)); 128 1.1 riastrad } 129 1.1 riastrad 130 1.1 riastrad return drm_ht_just_insert_please(&dev->map_hash, hash, 131 1.1 riastrad user_token, 32 - PAGE_SHIFT - 3, 132 1.1 riastrad shift, add); 133 1.1 riastrad } 134 1.1 riastrad 135 1.1 riastrad /** 136 1.1 riastrad * Core function to create a range of memory available for mapping by a 137 1.1 riastrad * non-root process. 138 1.1 riastrad * 139 1.1 riastrad * Adjusts the memory offset to its absolute value according to the mapping 140 1.1 riastrad * type. Adds the map to the map list drm_device::maplist. Adds MTRR's where 141 1.1 riastrad * applicable and if supported by the kernel. 142 1.1 riastrad */ 143 1.13 riastrad static int drm_addmap_core(struct drm_device *dev, resource_size_t offset, 144 1.1 riastrad unsigned int size, enum drm_map_type type, 145 1.1 riastrad enum drm_map_flags flags, 146 1.13 riastrad struct drm_map_list **maplist) 147 1.1 riastrad { 148 1.1 riastrad struct drm_local_map *map; 149 1.1 riastrad struct drm_map_list *list; 150 1.1 riastrad drm_dma_handle_t *dmah; 151 1.1 riastrad unsigned long user_token; 152 1.1 riastrad int ret; 153 1.1 riastrad 154 1.1 riastrad map = kmalloc(sizeof(*map), GFP_KERNEL); 155 1.1 riastrad if (!map) 156 1.1 riastrad return -ENOMEM; 157 1.1 riastrad 158 1.1 riastrad map->offset = offset; 159 1.1 riastrad map->size = size; 160 1.1 riastrad map->flags = flags; 161 1.1 riastrad map->type = type; 162 1.1 riastrad 163 1.1 riastrad /* Only allow shared memory to be removable since we only keep enough 164 1.1 riastrad * book keeping information about shared memory to allow for removal 165 1.1 riastrad * when processes fork. 166 1.1 riastrad */ 167 1.1 riastrad if ((map->flags & _DRM_REMOVABLE) && map->type != _DRM_SHM) { 168 1.1 riastrad kfree(map); 169 1.1 riastrad return -EINVAL; 170 1.1 riastrad } 171 1.1 riastrad DRM_DEBUG("offset = 0x%08llx, size = 0x%08lx, type = %d\n", 172 1.1 riastrad (unsigned long long)map->offset, map->size, map->type); 173 1.1 riastrad 174 1.1 riastrad /* page-align _DRM_SHM maps. They are allocated here so there is no security 175 1.1 riastrad * hole created by that and it works around various broken drivers that use 176 1.1 riastrad * a non-aligned quantity to map the SAREA. --BenH 177 1.1 riastrad */ 178 1.1 riastrad if (map->type == _DRM_SHM) 179 1.1 riastrad map->size = PAGE_ALIGN(map->size); 180 1.1 riastrad 181 1.1 riastrad if ((map->offset & (~(resource_size_t)PAGE_MASK)) || (map->size & (~PAGE_MASK))) { 182 1.1 riastrad kfree(map); 183 1.1 riastrad return -EINVAL; 184 1.1 riastrad } 185 1.1 riastrad map->mtrr = -1; 186 1.1 riastrad map->handle = NULL; 187 1.1 riastrad 188 1.1 riastrad switch (map->type) { 189 1.1 riastrad case _DRM_REGISTERS: 190 1.1 riastrad case _DRM_FRAME_BUFFER: 191 1.4 riastrad #ifndef __NetBSD__ /* XXX No idea what this is for... */ 192 1.1 riastrad #if !defined(__sparc__) && !defined(__alpha__) && !defined(__ia64__) && !defined(__powerpc64__) && !defined(__x86_64__) && !defined(__arm__) 193 1.1 riastrad if (map->offset + (map->size-1) < map->offset || 194 1.1 riastrad map->offset < virt_to_phys(high_memory)) { 195 1.1 riastrad kfree(map); 196 1.1 riastrad return -EINVAL; 197 1.1 riastrad } 198 1.1 riastrad #endif 199 1.4 riastrad #endif 200 1.1 riastrad /* Some drivers preinitialize some maps, without the X Server 201 1.1 riastrad * needing to be aware of it. Therefore, we just return success 202 1.1 riastrad * when the server tries to create a duplicate map. 203 1.1 riastrad */ 204 1.1 riastrad list = drm_find_matching_map(dev, map); 205 1.1 riastrad if (list != NULL) { 206 1.1 riastrad if (list->map->size != map->size) { 207 1.1 riastrad DRM_DEBUG("Matching maps of type %d with " 208 1.1 riastrad "mismatched sizes, (%ld vs %ld)\n", 209 1.1 riastrad map->type, map->size, 210 1.1 riastrad list->map->size); 211 1.1 riastrad list->map->size = map->size; 212 1.1 riastrad } 213 1.1 riastrad 214 1.1 riastrad kfree(map); 215 1.1 riastrad *maplist = list; 216 1.1 riastrad return 0; 217 1.1 riastrad } 218 1.1 riastrad 219 1.5 riastrad if (map->type == _DRM_FRAME_BUFFER || 220 1.5 riastrad (map->flags & _DRM_WRITE_COMBINING)) { 221 1.5 riastrad map->mtrr = 222 1.5 riastrad arch_phys_wc_add(map->offset, map->size); 223 1.1 riastrad } 224 1.1 riastrad if (map->type == _DRM_REGISTERS) { 225 1.2 riastrad #ifdef __NetBSD__ 226 1.9 riastrad drm_legacy_ioremap(map, dev); 227 1.2 riastrad #else 228 1.5 riastrad if (map->flags & _DRM_WRITE_COMBINING) 229 1.5 riastrad map->handle = ioremap_wc(map->offset, 230 1.5 riastrad map->size); 231 1.5 riastrad else 232 1.5 riastrad map->handle = ioremap(map->offset, map->size); 233 1.2 riastrad #endif 234 1.1 riastrad if (!map->handle) { 235 1.1 riastrad kfree(map); 236 1.1 riastrad return -ENOMEM; 237 1.1 riastrad } 238 1.1 riastrad } 239 1.1 riastrad 240 1.1 riastrad break; 241 1.1 riastrad case _DRM_SHM: 242 1.1 riastrad list = drm_find_matching_map(dev, map); 243 1.1 riastrad if (list != NULL) { 244 1.13 riastrad if (list->map->size != map->size) { 245 1.1 riastrad DRM_DEBUG("Matching maps of type %d with " 246 1.1 riastrad "mismatched sizes, (%ld vs %ld)\n", 247 1.1 riastrad map->type, map->size, list->map->size); 248 1.1 riastrad list->map->size = map->size; 249 1.1 riastrad } 250 1.1 riastrad 251 1.1 riastrad kfree(map); 252 1.1 riastrad *maplist = list; 253 1.1 riastrad return 0; 254 1.1 riastrad } 255 1.1 riastrad map->handle = vmalloc_user(map->size); 256 1.1 riastrad DRM_DEBUG("%lu %d %p\n", 257 1.5 riastrad map->size, order_base_2(map->size), map->handle); 258 1.1 riastrad if (!map->handle) { 259 1.1 riastrad kfree(map); 260 1.1 riastrad return -ENOMEM; 261 1.1 riastrad } 262 1.1 riastrad map->offset = (unsigned long)map->handle; 263 1.1 riastrad if (map->flags & _DRM_CONTAINS_LOCK) { 264 1.1 riastrad /* Prevent a 2nd X Server from creating a 2nd lock */ 265 1.16 riastrad spin_lock(&dev->master->lock.spinlock); 266 1.13 riastrad if (dev->master->lock.hw_lock != NULL) { 267 1.15 riastrad spin_unlock(&dev->master->lock.spinlock); 268 1.1 riastrad vfree(map->handle); 269 1.1 riastrad kfree(map); 270 1.1 riastrad return -EBUSY; 271 1.1 riastrad } 272 1.16 riastrad spin_unlock(&dev->master->lock.spinlock); 273 1.13 riastrad dev->sigdata.lock = dev->master->lock.hw_lock = map->handle; /* Pointer to lock */ 274 1.1 riastrad } 275 1.1 riastrad break; 276 1.1 riastrad case _DRM_AGP: { 277 1.1 riastrad struct drm_agp_mem *entry; 278 1.1 riastrad int valid = 0; 279 1.1 riastrad 280 1.5 riastrad if (!dev->agp) { 281 1.1 riastrad kfree(map); 282 1.1 riastrad return -EINVAL; 283 1.1 riastrad } 284 1.1 riastrad #ifdef __alpha__ 285 1.1 riastrad map->offset += dev->hose->mem_space->start; 286 1.1 riastrad #endif 287 1.1 riastrad /* In some cases (i810 driver), user space may have already 288 1.1 riastrad * added the AGP base itself, because dev->agp->base previously 289 1.1 riastrad * only got set during AGP enable. So, only add the base 290 1.1 riastrad * address if the map's offset isn't already within the 291 1.1 riastrad * aperture. 292 1.1 riastrad */ 293 1.2 riastrad #ifdef __NetBSD__ 294 1.2 riastrad if (map->offset < dev->agp->base || 295 1.2 riastrad map->offset > dev->agp->base + 296 1.6 riastrad dev->agp->agp_info.aki_info.ai_aperture_size - 1) { 297 1.2 riastrad map->offset += dev->agp->base; 298 1.2 riastrad } 299 1.2 riastrad #else 300 1.1 riastrad if (map->offset < dev->agp->base || 301 1.1 riastrad map->offset > dev->agp->base + 302 1.1 riastrad dev->agp->agp_info.aper_size * 1024 * 1024 - 1) { 303 1.1 riastrad map->offset += dev->agp->base; 304 1.1 riastrad } 305 1.2 riastrad #endif 306 1.1 riastrad map->mtrr = dev->agp->agp_mtrr; /* for getmap */ 307 1.1 riastrad 308 1.1 riastrad /* This assumes the DRM is in total control of AGP space. 309 1.1 riastrad * It's not always the case as AGP can be in the control 310 1.1 riastrad * of user space (i.e. i810 driver). So this loop will get 311 1.1 riastrad * skipped and we double check that dev->agp->memory is 312 1.1 riastrad * actually set as well as being invalid before EPERM'ing 313 1.1 riastrad */ 314 1.1 riastrad list_for_each_entry(entry, &dev->agp->memory, head) { 315 1.1 riastrad if ((map->offset >= entry->bound) && 316 1.1 riastrad (map->offset + map->size <= entry->bound + entry->pages * PAGE_SIZE)) { 317 1.1 riastrad valid = 1; 318 1.1 riastrad break; 319 1.1 riastrad } 320 1.1 riastrad } 321 1.1 riastrad if (!list_empty(&dev->agp->memory) && !valid) { 322 1.1 riastrad kfree(map); 323 1.1 riastrad return -EPERM; 324 1.1 riastrad } 325 1.1 riastrad DRM_DEBUG("AGP offset = 0x%08llx, size = 0x%08lx\n", 326 1.1 riastrad (unsigned long long)map->offset, map->size); 327 1.1 riastrad 328 1.1 riastrad break; 329 1.1 riastrad } 330 1.1 riastrad case _DRM_SCATTER_GATHER: 331 1.1 riastrad if (!dev->sg) { 332 1.1 riastrad kfree(map); 333 1.1 riastrad return -EINVAL; 334 1.1 riastrad } 335 1.1 riastrad map->offset += (unsigned long)dev->sg->virtual; 336 1.1 riastrad break; 337 1.1 riastrad case _DRM_CONSISTENT: 338 1.1 riastrad /* dma_addr_t is 64bit on i386 with CONFIG_HIGHMEM64G, 339 1.1 riastrad * As we're limiting the address to 2^32-1 (or less), 340 1.1 riastrad * casting it down to 32 bits is no problem, but we 341 1.1 riastrad * need to point to a 64bit variable first. */ 342 1.1 riastrad dmah = drm_pci_alloc(dev, map->size, map->size); 343 1.1 riastrad if (!dmah) { 344 1.1 riastrad kfree(map); 345 1.1 riastrad return -ENOMEM; 346 1.1 riastrad } 347 1.1 riastrad map->handle = dmah->vaddr; 348 1.1 riastrad map->offset = (unsigned long)dmah->busaddr; 349 1.2 riastrad #ifdef __NetBSD__ 350 1.2 riastrad map->lm_data.dmah = dmah; 351 1.2 riastrad #else 352 1.1 riastrad kfree(dmah); 353 1.2 riastrad #endif 354 1.1 riastrad break; 355 1.1 riastrad default: 356 1.1 riastrad kfree(map); 357 1.1 riastrad return -EINVAL; 358 1.1 riastrad } 359 1.1 riastrad 360 1.1 riastrad list = kzalloc(sizeof(*list), GFP_KERNEL); 361 1.1 riastrad if (!list) { 362 1.1 riastrad if (map->type == _DRM_REGISTERS) 363 1.2 riastrad #ifdef __NetBSD__ 364 1.9 riastrad drm_legacy_ioremapfree(map, dev); 365 1.2 riastrad #else 366 1.1 riastrad iounmap(map->handle); 367 1.2 riastrad #endif 368 1.1 riastrad kfree(map); 369 1.1 riastrad return -EINVAL; 370 1.1 riastrad } 371 1.1 riastrad list->map = map; 372 1.1 riastrad 373 1.1 riastrad mutex_lock(&dev->struct_mutex); 374 1.1 riastrad list_add(&list->head, &dev->maplist); 375 1.1 riastrad 376 1.1 riastrad /* Assign a 32-bit handle */ 377 1.1 riastrad /* We do it here so that dev->struct_mutex protects the increment */ 378 1.1 riastrad user_token = (map->type == _DRM_SHM) ? (unsigned long)map->handle : 379 1.1 riastrad map->offset; 380 1.1 riastrad ret = drm_map_handle(dev, &list->hash, user_token, 0, 381 1.1 riastrad (map->type == _DRM_SHM)); 382 1.1 riastrad if (ret) { 383 1.1 riastrad if (map->type == _DRM_REGISTERS) 384 1.2 riastrad #ifdef __NetBSD__ /* XXX What about other map types...? */ 385 1.9 riastrad drm_legacy_ioremapfree(map, dev); 386 1.2 riastrad #else 387 1.1 riastrad iounmap(map->handle); 388 1.2 riastrad #endif 389 1.1 riastrad kfree(map); 390 1.1 riastrad kfree(list); 391 1.1 riastrad mutex_unlock(&dev->struct_mutex); 392 1.1 riastrad return ret; 393 1.1 riastrad } 394 1.1 riastrad 395 1.1 riastrad list->user_token = list->hash.key << PAGE_SHIFT; 396 1.1 riastrad mutex_unlock(&dev->struct_mutex); 397 1.1 riastrad 398 1.1 riastrad if (!(map->flags & _DRM_DRIVER)) 399 1.13 riastrad list->master = dev->master; 400 1.1 riastrad *maplist = list; 401 1.1 riastrad return 0; 402 1.8 riastrad } 403 1.1 riastrad 404 1.13 riastrad int drm_legacy_addmap(struct drm_device *dev, resource_size_t offset, 405 1.8 riastrad unsigned int size, enum drm_map_type type, 406 1.8 riastrad enum drm_map_flags flags, struct drm_local_map **map_ptr) 407 1.1 riastrad { 408 1.1 riastrad struct drm_map_list *list; 409 1.1 riastrad int rc; 410 1.1 riastrad 411 1.1 riastrad rc = drm_addmap_core(dev, offset, size, type, flags, &list); 412 1.1 riastrad if (!rc) 413 1.1 riastrad *map_ptr = list->map; 414 1.1 riastrad return rc; 415 1.1 riastrad } 416 1.8 riastrad EXPORT_SYMBOL(drm_legacy_addmap); 417 1.1 riastrad 418 1.13 riastrad struct drm_local_map *drm_legacy_findmap(struct drm_device *dev, 419 1.13 riastrad unsigned int token) 420 1.13 riastrad { 421 1.13 riastrad struct drm_map_list *_entry; 422 1.13 riastrad list_for_each_entry(_entry, &dev->maplist, head) 423 1.13 riastrad if (_entry->user_token == token) 424 1.13 riastrad return _entry->map; 425 1.13 riastrad return NULL; 426 1.13 riastrad } 427 1.13 riastrad EXPORT_SYMBOL(drm_legacy_findmap); 428 1.13 riastrad 429 1.1 riastrad /** 430 1.1 riastrad * Ioctl to specify a range of memory that is available for mapping by a 431 1.1 riastrad * non-root process. 432 1.1 riastrad * 433 1.1 riastrad * \param inode device inode. 434 1.1 riastrad * \param file_priv DRM file private. 435 1.1 riastrad * \param cmd command. 436 1.1 riastrad * \param arg pointer to a drm_map structure. 437 1.1 riastrad * \return zero on success or a negative value on error. 438 1.1 riastrad * 439 1.1 riastrad */ 440 1.8 riastrad int drm_legacy_addmap_ioctl(struct drm_device *dev, void *data, 441 1.8 riastrad struct drm_file *file_priv) 442 1.1 riastrad { 443 1.1 riastrad struct drm_map *map = data; 444 1.1 riastrad struct drm_map_list *maplist; 445 1.1 riastrad int err; 446 1.1 riastrad 447 1.1 riastrad if (!(capable(CAP_SYS_ADMIN) || map->type == _DRM_AGP || map->type == _DRM_SHM)) 448 1.1 riastrad return -EPERM; 449 1.1 riastrad 450 1.13 riastrad if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) && 451 1.13 riastrad !drm_core_check_feature(dev, DRIVER_LEGACY)) 452 1.13 riastrad return -EOPNOTSUPP; 453 1.13 riastrad 454 1.1 riastrad err = drm_addmap_core(dev, map->offset, map->size, map->type, 455 1.1 riastrad map->flags, &maplist); 456 1.1 riastrad 457 1.1 riastrad if (err) 458 1.1 riastrad return err; 459 1.1 riastrad 460 1.1 riastrad /* avoid a warning on 64-bit, this casting isn't very nice, but the API is set so too late */ 461 1.1 riastrad map->handle = (void *)(unsigned long)maplist->user_token; 462 1.5 riastrad 463 1.5 riastrad /* 464 1.5 riastrad * It appears that there are no users of this value whatsoever -- 465 1.5 riastrad * drmAddMap just discards it. Let's not encourage its use. 466 1.5 riastrad * (Keeping drm_addmap_core's returned mtrr value would be wrong -- 467 1.5 riastrad * it's not a real mtrr index anymore.) 468 1.5 riastrad */ 469 1.5 riastrad map->mtrr = -1; 470 1.5 riastrad 471 1.1 riastrad return 0; 472 1.1 riastrad } 473 1.1 riastrad 474 1.13 riastrad /* 475 1.13 riastrad * Get a mapping information. 476 1.13 riastrad * 477 1.13 riastrad * \param inode device inode. 478 1.13 riastrad * \param file_priv DRM file private. 479 1.13 riastrad * \param cmd command. 480 1.13 riastrad * \param arg user argument, pointing to a drm_map structure. 481 1.13 riastrad * 482 1.13 riastrad * \return zero on success or a negative number on failure. 483 1.13 riastrad * 484 1.13 riastrad * Searches for the mapping with the specified offset and copies its information 485 1.13 riastrad * into userspace 486 1.13 riastrad */ 487 1.13 riastrad int drm_legacy_getmap_ioctl(struct drm_device *dev, void *data, 488 1.13 riastrad struct drm_file *file_priv) 489 1.13 riastrad { 490 1.13 riastrad struct drm_map *map = data; 491 1.13 riastrad struct drm_map_list *r_list = NULL; 492 1.13 riastrad struct list_head *list; 493 1.13 riastrad int idx; 494 1.13 riastrad int i; 495 1.13 riastrad 496 1.13 riastrad if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) && 497 1.13 riastrad !drm_core_check_feature(dev, DRIVER_LEGACY)) 498 1.13 riastrad return -EOPNOTSUPP; 499 1.13 riastrad 500 1.13 riastrad idx = map->offset; 501 1.13 riastrad if (idx < 0) 502 1.13 riastrad return -EINVAL; 503 1.13 riastrad 504 1.13 riastrad i = 0; 505 1.13 riastrad mutex_lock(&dev->struct_mutex); 506 1.13 riastrad list_for_each(list, &dev->maplist) { 507 1.13 riastrad if (i == idx) { 508 1.13 riastrad r_list = list_entry(list, struct drm_map_list, head); 509 1.13 riastrad break; 510 1.13 riastrad } 511 1.13 riastrad i++; 512 1.13 riastrad } 513 1.13 riastrad if (!r_list || !r_list->map) { 514 1.13 riastrad mutex_unlock(&dev->struct_mutex); 515 1.13 riastrad return -EINVAL; 516 1.13 riastrad } 517 1.13 riastrad 518 1.13 riastrad map->offset = r_list->map->offset; 519 1.13 riastrad map->size = r_list->map->size; 520 1.13 riastrad map->type = r_list->map->type; 521 1.13 riastrad map->flags = r_list->map->flags; 522 1.13 riastrad map->handle = (void *)(unsigned long) r_list->user_token; 523 1.13 riastrad map->mtrr = arch_phys_wc_index(r_list->map->mtrr); 524 1.13 riastrad 525 1.13 riastrad mutex_unlock(&dev->struct_mutex); 526 1.13 riastrad 527 1.13 riastrad return 0; 528 1.13 riastrad } 529 1.13 riastrad 530 1.1 riastrad /** 531 1.1 riastrad * Remove a map private from list and deallocate resources if the mapping 532 1.1 riastrad * isn't in use. 533 1.1 riastrad * 534 1.1 riastrad * Searches the map on drm_device::maplist, removes it from the list, see if 535 1.13 riastrad * it's being used, and free any associated resource (such as MTRR's) if it's not 536 1.1 riastrad * being on use. 537 1.1 riastrad * 538 1.8 riastrad * \sa drm_legacy_addmap 539 1.1 riastrad */ 540 1.8 riastrad int drm_legacy_rmmap_locked(struct drm_device *dev, struct drm_local_map *map) 541 1.1 riastrad { 542 1.1 riastrad struct drm_map_list *r_list = NULL, *list_t; 543 1.2 riastrad #ifndef __NetBSD__ 544 1.1 riastrad drm_dma_handle_t dmah; 545 1.2 riastrad #endif 546 1.1 riastrad int found = 0; 547 1.1 riastrad struct drm_master *master; 548 1.1 riastrad 549 1.1 riastrad /* Find the list entry for the map and remove it */ 550 1.1 riastrad list_for_each_entry_safe(r_list, list_t, &dev->maplist, head) { 551 1.1 riastrad if (r_list->map == map) { 552 1.1 riastrad master = r_list->master; 553 1.1 riastrad list_del(&r_list->head); 554 1.1 riastrad drm_ht_remove_key(&dev->map_hash, 555 1.1 riastrad r_list->user_token >> PAGE_SHIFT); 556 1.1 riastrad kfree(r_list); 557 1.1 riastrad found = 1; 558 1.1 riastrad break; 559 1.1 riastrad } 560 1.1 riastrad } 561 1.1 riastrad 562 1.1 riastrad if (!found) 563 1.1 riastrad return -EINVAL; 564 1.1 riastrad 565 1.1 riastrad switch (map->type) { 566 1.1 riastrad case _DRM_REGISTERS: 567 1.2 riastrad #ifdef __NetBSD__ 568 1.9 riastrad drm_legacy_ioremapfree(map, dev); 569 1.2 riastrad #else 570 1.1 riastrad iounmap(map->handle); 571 1.2 riastrad #endif 572 1.1 riastrad /* FALLTHROUGH */ 573 1.1 riastrad case _DRM_FRAME_BUFFER: 574 1.5 riastrad arch_phys_wc_del(map->mtrr); 575 1.1 riastrad break; 576 1.1 riastrad case _DRM_SHM: 577 1.3 riastrad if (master && (map->flags & _DRM_CONTAINS_LOCK)) { 578 1.2 riastrad spin_lock(&master->lock.spinlock); 579 1.2 riastrad /* 580 1.2 riastrad * If we successfully removed this mapping, 581 1.2 riastrad * then the mapping must have been there in the 582 1.2 riastrad * first place, and we must have had a 583 1.2 riastrad * heavyweight lock, so we assert here instead 584 1.2 riastrad * of just checking and failing. 585 1.2 riastrad * 586 1.2 riastrad * XXX What about the _DRM_CONTAINS_LOCK flag? 587 1.2 riastrad * Where is that supposed to be set? Is it 588 1.2 riastrad * equivalent to having a master set? 589 1.2 riastrad * 590 1.2 riastrad * XXX There is copypasta of this in 591 1.16 riastrad * drm_lock.c, drm_legacy_lock_master_cleanup. 592 1.2 riastrad */ 593 1.2 riastrad BUG_ON(master->lock.hw_lock == NULL); 594 1.1 riastrad if (dev->sigdata.lock == master->lock.hw_lock) 595 1.1 riastrad dev->sigdata.lock = NULL; 596 1.1 riastrad master->lock.hw_lock = NULL; /* SHM removed */ 597 1.1 riastrad master->lock.file_priv = NULL; 598 1.2 riastrad #ifdef __NetBSD__ 599 1.2 riastrad DRM_SPIN_WAKEUP_ALL(&master->lock.lock_queue, 600 1.2 riastrad &master->lock.spinlock); 601 1.2 riastrad #else 602 1.1 riastrad wake_up_interruptible_all(&master->lock.lock_queue); 603 1.2 riastrad #endif 604 1.2 riastrad spin_unlock(&master->lock.spinlock); 605 1.1 riastrad } 606 1.2 riastrad vfree(map->handle); 607 1.1 riastrad break; 608 1.1 riastrad case _DRM_AGP: 609 1.1 riastrad case _DRM_SCATTER_GATHER: 610 1.1 riastrad break; 611 1.1 riastrad case _DRM_CONSISTENT: 612 1.2 riastrad #ifdef __NetBSD__ 613 1.2 riastrad drm_pci_free(dev, map->lm_data.dmah); 614 1.2 riastrad #else 615 1.1 riastrad dmah.vaddr = map->handle; 616 1.1 riastrad dmah.busaddr = map->offset; 617 1.1 riastrad dmah.size = map->size; 618 1.8 riastrad __drm_legacy_pci_free(dev, &dmah); 619 1.2 riastrad #endif 620 1.1 riastrad break; 621 1.1 riastrad } 622 1.1 riastrad kfree(map); 623 1.1 riastrad 624 1.1 riastrad return 0; 625 1.1 riastrad } 626 1.8 riastrad EXPORT_SYMBOL(drm_legacy_rmmap_locked); 627 1.1 riastrad 628 1.13 riastrad void drm_legacy_rmmap(struct drm_device *dev, struct drm_local_map *map) 629 1.1 riastrad { 630 1.13 riastrad if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) && 631 1.13 riastrad !drm_core_check_feature(dev, DRIVER_LEGACY)) 632 1.13 riastrad return; 633 1.1 riastrad 634 1.1 riastrad mutex_lock(&dev->struct_mutex); 635 1.13 riastrad drm_legacy_rmmap_locked(dev, map); 636 1.1 riastrad mutex_unlock(&dev->struct_mutex); 637 1.13 riastrad } 638 1.13 riastrad EXPORT_SYMBOL(drm_legacy_rmmap); 639 1.1 riastrad 640 1.13 riastrad void drm_legacy_master_rmmaps(struct drm_device *dev, struct drm_master *master) 641 1.13 riastrad { 642 1.13 riastrad struct drm_map_list *r_list, *list_temp; 643 1.13 riastrad 644 1.13 riastrad if (!drm_core_check_feature(dev, DRIVER_LEGACY)) 645 1.13 riastrad return; 646 1.13 riastrad 647 1.13 riastrad mutex_lock(&dev->struct_mutex); 648 1.13 riastrad list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head) { 649 1.13 riastrad if (r_list->master == master) { 650 1.13 riastrad drm_legacy_rmmap_locked(dev, r_list->map); 651 1.13 riastrad r_list = NULL; 652 1.13 riastrad } 653 1.13 riastrad } 654 1.13 riastrad mutex_unlock(&dev->struct_mutex); 655 1.13 riastrad } 656 1.13 riastrad 657 1.13 riastrad void drm_legacy_rmmaps(struct drm_device *dev) 658 1.13 riastrad { 659 1.13 riastrad struct drm_map_list *r_list, *list_temp; 660 1.13 riastrad 661 1.13 riastrad list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head) 662 1.13 riastrad drm_legacy_rmmap(dev, r_list->map); 663 1.1 riastrad } 664 1.1 riastrad 665 1.1 riastrad /* The rmmap ioctl appears to be unnecessary. All mappings are torn down on 666 1.1 riastrad * the last close of the device, and this is necessary for cleanup when things 667 1.1 riastrad * exit uncleanly. Therefore, having userland manually remove mappings seems 668 1.1 riastrad * like a pointless exercise since they're going away anyway. 669 1.1 riastrad * 670 1.1 riastrad * One use case might be after addmap is allowed for normal users for SHM and 671 1.1 riastrad * gets used by drivers that the server doesn't need to care about. This seems 672 1.1 riastrad * unlikely. 673 1.1 riastrad * 674 1.1 riastrad * \param inode device inode. 675 1.1 riastrad * \param file_priv DRM file private. 676 1.1 riastrad * \param cmd command. 677 1.1 riastrad * \param arg pointer to a struct drm_map structure. 678 1.1 riastrad * \return zero on success or a negative value on error. 679 1.1 riastrad */ 680 1.8 riastrad int drm_legacy_rmmap_ioctl(struct drm_device *dev, void *data, 681 1.8 riastrad struct drm_file *file_priv) 682 1.1 riastrad { 683 1.1 riastrad struct drm_map *request = data; 684 1.1 riastrad struct drm_local_map *map = NULL; 685 1.1 riastrad struct drm_map_list *r_list; 686 1.1 riastrad int ret; 687 1.1 riastrad 688 1.13 riastrad if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) && 689 1.13 riastrad !drm_core_check_feature(dev, DRIVER_LEGACY)) 690 1.13 riastrad return -EOPNOTSUPP; 691 1.13 riastrad 692 1.1 riastrad mutex_lock(&dev->struct_mutex); 693 1.1 riastrad list_for_each_entry(r_list, &dev->maplist, head) { 694 1.1 riastrad if (r_list->map && 695 1.1 riastrad r_list->user_token == (unsigned long)request->handle && 696 1.1 riastrad r_list->map->flags & _DRM_REMOVABLE) { 697 1.1 riastrad map = r_list->map; 698 1.1 riastrad break; 699 1.1 riastrad } 700 1.1 riastrad } 701 1.1 riastrad 702 1.13 riastrad /* List has wrapped around to the head pointer, or it's empty we didn't 703 1.1 riastrad * find anything. 704 1.1 riastrad */ 705 1.1 riastrad if (list_empty(&dev->maplist) || !map) { 706 1.1 riastrad mutex_unlock(&dev->struct_mutex); 707 1.1 riastrad return -EINVAL; 708 1.1 riastrad } 709 1.1 riastrad 710 1.1 riastrad /* Register and framebuffer maps are permanent */ 711 1.1 riastrad if ((map->type == _DRM_REGISTERS) || (map->type == _DRM_FRAME_BUFFER)) { 712 1.1 riastrad mutex_unlock(&dev->struct_mutex); 713 1.1 riastrad return 0; 714 1.1 riastrad } 715 1.1 riastrad 716 1.8 riastrad ret = drm_legacy_rmmap_locked(dev, map); 717 1.1 riastrad 718 1.1 riastrad mutex_unlock(&dev->struct_mutex); 719 1.1 riastrad 720 1.1 riastrad return ret; 721 1.1 riastrad } 722 1.1 riastrad 723 1.1 riastrad /** 724 1.1 riastrad * Cleanup after an error on one of the addbufs() functions. 725 1.1 riastrad * 726 1.1 riastrad * \param dev DRM device. 727 1.1 riastrad * \param entry buffer entry where the error occurred. 728 1.1 riastrad * 729 1.1 riastrad * Frees any pages and buffers associated with the given entry. 730 1.1 riastrad */ 731 1.13 riastrad static void drm_cleanup_buf_error(struct drm_device *dev, 732 1.13 riastrad struct drm_buf_entry *entry) 733 1.1 riastrad { 734 1.1 riastrad int i; 735 1.1 riastrad 736 1.1 riastrad if (entry->seg_count) { 737 1.1 riastrad for (i = 0; i < entry->seg_count; i++) { 738 1.1 riastrad if (entry->seglist[i]) { 739 1.1 riastrad drm_pci_free(dev, entry->seglist[i]); 740 1.1 riastrad } 741 1.1 riastrad } 742 1.1 riastrad kfree(entry->seglist); 743 1.1 riastrad 744 1.1 riastrad entry->seg_count = 0; 745 1.1 riastrad } 746 1.1 riastrad 747 1.1 riastrad if (entry->buf_count) { 748 1.1 riastrad for (i = 0; i < entry->buf_count; i++) { 749 1.1 riastrad kfree(entry->buflist[i].dev_private); 750 1.1 riastrad } 751 1.1 riastrad kfree(entry->buflist); 752 1.1 riastrad 753 1.1 riastrad entry->buf_count = 0; 754 1.1 riastrad } 755 1.1 riastrad } 756 1.1 riastrad 757 1.8 riastrad #if IS_ENABLED(CONFIG_AGP) 758 1.1 riastrad /** 759 1.1 riastrad * Add AGP buffers for DMA transfers. 760 1.1 riastrad * 761 1.1 riastrad * \param dev struct drm_device to which the buffers are to be added. 762 1.1 riastrad * \param request pointer to a struct drm_buf_desc describing the request. 763 1.1 riastrad * \return zero on success or a negative number on failure. 764 1.1 riastrad * 765 1.1 riastrad * After some sanity checks creates a drm_buf structure for each buffer and 766 1.1 riastrad * reallocates the buffer list of the same size order to accommodate the new 767 1.1 riastrad * buffers. 768 1.1 riastrad */ 769 1.8 riastrad int drm_legacy_addbufs_agp(struct drm_device *dev, 770 1.8 riastrad struct drm_buf_desc *request) 771 1.1 riastrad { 772 1.1 riastrad struct drm_device_dma *dma = dev->dma; 773 1.1 riastrad struct drm_buf_entry *entry; 774 1.1 riastrad struct drm_agp_mem *agp_entry; 775 1.1 riastrad struct drm_buf *buf; 776 1.1 riastrad unsigned long offset; 777 1.1 riastrad unsigned long agp_offset; 778 1.1 riastrad int count; 779 1.1 riastrad int order; 780 1.1 riastrad int size; 781 1.1 riastrad int alignment; 782 1.1 riastrad int page_order; 783 1.1 riastrad int total; 784 1.1 riastrad int byte_count; 785 1.1 riastrad int i, valid; 786 1.1 riastrad struct drm_buf **temp_buflist; 787 1.1 riastrad 788 1.1 riastrad if (!dma) 789 1.1 riastrad return -EINVAL; 790 1.1 riastrad 791 1.1 riastrad count = request->count; 792 1.5 riastrad order = order_base_2(request->size); 793 1.1 riastrad size = 1 << order; 794 1.1 riastrad 795 1.1 riastrad alignment = (request->flags & _DRM_PAGE_ALIGN) 796 1.1 riastrad ? PAGE_ALIGN(size) : size; 797 1.1 riastrad page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0; 798 1.1 riastrad total = PAGE_SIZE << page_order; 799 1.1 riastrad 800 1.1 riastrad byte_count = 0; 801 1.1 riastrad agp_offset = dev->agp->base + request->agp_start; 802 1.1 riastrad 803 1.1 riastrad DRM_DEBUG("count: %d\n", count); 804 1.1 riastrad DRM_DEBUG("order: %d\n", order); 805 1.1 riastrad DRM_DEBUG("size: %d\n", size); 806 1.1 riastrad DRM_DEBUG("agp_offset: %lx\n", agp_offset); 807 1.1 riastrad DRM_DEBUG("alignment: %d\n", alignment); 808 1.1 riastrad DRM_DEBUG("page_order: %d\n", page_order); 809 1.1 riastrad DRM_DEBUG("total: %d\n", total); 810 1.1 riastrad 811 1.1 riastrad if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) 812 1.1 riastrad return -EINVAL; 813 1.1 riastrad 814 1.1 riastrad /* Make sure buffers are located in AGP memory that we own */ 815 1.1 riastrad valid = 0; 816 1.1 riastrad list_for_each_entry(agp_entry, &dev->agp->memory, head) { 817 1.1 riastrad if ((agp_offset >= agp_entry->bound) && 818 1.1 riastrad (agp_offset + total * count <= agp_entry->bound + agp_entry->pages * PAGE_SIZE)) { 819 1.1 riastrad valid = 1; 820 1.1 riastrad break; 821 1.1 riastrad } 822 1.1 riastrad } 823 1.1 riastrad if (!list_empty(&dev->agp->memory) && !valid) { 824 1.1 riastrad DRM_DEBUG("zone invalid\n"); 825 1.1 riastrad return -EINVAL; 826 1.1 riastrad } 827 1.8 riastrad spin_lock(&dev->buf_lock); 828 1.1 riastrad if (dev->buf_use) { 829 1.8 riastrad spin_unlock(&dev->buf_lock); 830 1.1 riastrad return -EBUSY; 831 1.1 riastrad } 832 1.1 riastrad atomic_inc(&dev->buf_alloc); 833 1.8 riastrad spin_unlock(&dev->buf_lock); 834 1.1 riastrad 835 1.1 riastrad mutex_lock(&dev->struct_mutex); 836 1.1 riastrad entry = &dma->bufs[order]; 837 1.1 riastrad if (entry->buf_count) { 838 1.1 riastrad mutex_unlock(&dev->struct_mutex); 839 1.1 riastrad atomic_dec(&dev->buf_alloc); 840 1.1 riastrad return -ENOMEM; /* May only call once for each order */ 841 1.1 riastrad } 842 1.1 riastrad 843 1.1 riastrad if (count < 0 || count > 4096) { 844 1.1 riastrad mutex_unlock(&dev->struct_mutex); 845 1.1 riastrad atomic_dec(&dev->buf_alloc); 846 1.1 riastrad return -EINVAL; 847 1.1 riastrad } 848 1.1 riastrad 849 1.13 riastrad entry->buflist = kcalloc(count, sizeof(*entry->buflist), GFP_KERNEL); 850 1.1 riastrad if (!entry->buflist) { 851 1.1 riastrad mutex_unlock(&dev->struct_mutex); 852 1.1 riastrad atomic_dec(&dev->buf_alloc); 853 1.1 riastrad return -ENOMEM; 854 1.1 riastrad } 855 1.1 riastrad 856 1.1 riastrad entry->buf_size = size; 857 1.1 riastrad entry->page_order = page_order; 858 1.1 riastrad 859 1.1 riastrad offset = 0; 860 1.1 riastrad 861 1.1 riastrad while (entry->buf_count < count) { 862 1.1 riastrad buf = &entry->buflist[entry->buf_count]; 863 1.1 riastrad buf->idx = dma->buf_count + entry->buf_count; 864 1.1 riastrad buf->total = alignment; 865 1.1 riastrad buf->order = order; 866 1.1 riastrad buf->used = 0; 867 1.1 riastrad 868 1.1 riastrad buf->offset = (dma->byte_count + offset); 869 1.1 riastrad buf->bus_address = agp_offset + offset; 870 1.1 riastrad buf->address = (void *)(agp_offset + offset); 871 1.1 riastrad buf->next = NULL; 872 1.1 riastrad buf->waiting = 0; 873 1.1 riastrad buf->pending = 0; 874 1.1 riastrad buf->file_priv = NULL; 875 1.1 riastrad 876 1.1 riastrad buf->dev_priv_size = dev->driver->dev_priv_size; 877 1.1 riastrad buf->dev_private = kzalloc(buf->dev_priv_size, GFP_KERNEL); 878 1.1 riastrad if (!buf->dev_private) { 879 1.1 riastrad /* Set count correctly so we free the proper amount. */ 880 1.1 riastrad entry->buf_count = count; 881 1.1 riastrad drm_cleanup_buf_error(dev, entry); 882 1.1 riastrad mutex_unlock(&dev->struct_mutex); 883 1.1 riastrad atomic_dec(&dev->buf_alloc); 884 1.1 riastrad return -ENOMEM; 885 1.1 riastrad } 886 1.1 riastrad 887 1.1 riastrad DRM_DEBUG("buffer %d @ %p\n", entry->buf_count, buf->address); 888 1.1 riastrad 889 1.1 riastrad offset += alignment; 890 1.1 riastrad entry->buf_count++; 891 1.1 riastrad byte_count += PAGE_SIZE << page_order; 892 1.1 riastrad } 893 1.1 riastrad 894 1.1 riastrad DRM_DEBUG("byte_count: %d\n", byte_count); 895 1.1 riastrad 896 1.1 riastrad temp_buflist = krealloc(dma->buflist, 897 1.1 riastrad (dma->buf_count + entry->buf_count) * 898 1.1 riastrad sizeof(*dma->buflist), GFP_KERNEL); 899 1.1 riastrad if (!temp_buflist) { 900 1.1 riastrad /* Free the entry because it isn't valid */ 901 1.1 riastrad drm_cleanup_buf_error(dev, entry); 902 1.1 riastrad mutex_unlock(&dev->struct_mutex); 903 1.1 riastrad atomic_dec(&dev->buf_alloc); 904 1.1 riastrad return -ENOMEM; 905 1.1 riastrad } 906 1.1 riastrad dma->buflist = temp_buflist; 907 1.1 riastrad 908 1.1 riastrad for (i = 0; i < entry->buf_count; i++) { 909 1.1 riastrad dma->buflist[i + dma->buf_count] = &entry->buflist[i]; 910 1.1 riastrad } 911 1.1 riastrad 912 1.1 riastrad dma->buf_count += entry->buf_count; 913 1.1 riastrad dma->seg_count += entry->seg_count; 914 1.1 riastrad dma->page_count += byte_count >> PAGE_SHIFT; 915 1.1 riastrad dma->byte_count += byte_count; 916 1.1 riastrad 917 1.1 riastrad DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count); 918 1.1 riastrad DRM_DEBUG("entry->buf_count : %d\n", entry->buf_count); 919 1.1 riastrad 920 1.1 riastrad mutex_unlock(&dev->struct_mutex); 921 1.1 riastrad 922 1.1 riastrad request->count = entry->buf_count; 923 1.1 riastrad request->size = size; 924 1.1 riastrad 925 1.1 riastrad dma->flags = _DRM_DMA_USE_AGP; 926 1.1 riastrad 927 1.1 riastrad atomic_dec(&dev->buf_alloc); 928 1.1 riastrad return 0; 929 1.1 riastrad } 930 1.8 riastrad EXPORT_SYMBOL(drm_legacy_addbufs_agp); 931 1.8 riastrad #endif /* CONFIG_AGP */ 932 1.1 riastrad 933 1.8 riastrad int drm_legacy_addbufs_pci(struct drm_device *dev, 934 1.8 riastrad struct drm_buf_desc *request) 935 1.1 riastrad { 936 1.1 riastrad struct drm_device_dma *dma = dev->dma; 937 1.1 riastrad int count; 938 1.1 riastrad int order; 939 1.1 riastrad int size; 940 1.1 riastrad int total; 941 1.1 riastrad int page_order; 942 1.1 riastrad struct drm_buf_entry *entry; 943 1.1 riastrad drm_dma_handle_t *dmah; 944 1.1 riastrad struct drm_buf *buf; 945 1.1 riastrad int alignment; 946 1.1 riastrad unsigned long offset; 947 1.1 riastrad int i; 948 1.1 riastrad int byte_count; 949 1.1 riastrad int page_count; 950 1.1 riastrad unsigned long *temp_pagelist; 951 1.1 riastrad struct drm_buf **temp_buflist; 952 1.1 riastrad 953 1.1 riastrad if (!drm_core_check_feature(dev, DRIVER_PCI_DMA)) 954 1.13 riastrad return -EOPNOTSUPP; 955 1.1 riastrad 956 1.1 riastrad if (!dma) 957 1.1 riastrad return -EINVAL; 958 1.1 riastrad 959 1.1 riastrad if (!capable(CAP_SYS_ADMIN)) 960 1.1 riastrad return -EPERM; 961 1.1 riastrad 962 1.1 riastrad count = request->count; 963 1.5 riastrad order = order_base_2(request->size); 964 1.1 riastrad size = 1 << order; 965 1.1 riastrad 966 1.1 riastrad DRM_DEBUG("count=%d, size=%d (%d), order=%d\n", 967 1.1 riastrad request->count, request->size, size, order); 968 1.1 riastrad 969 1.1 riastrad if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) 970 1.1 riastrad return -EINVAL; 971 1.1 riastrad 972 1.1 riastrad alignment = (request->flags & _DRM_PAGE_ALIGN) 973 1.1 riastrad ? PAGE_ALIGN(size) : size; 974 1.1 riastrad page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0; 975 1.1 riastrad total = PAGE_SIZE << page_order; 976 1.1 riastrad 977 1.8 riastrad spin_lock(&dev->buf_lock); 978 1.1 riastrad if (dev->buf_use) { 979 1.8 riastrad spin_unlock(&dev->buf_lock); 980 1.1 riastrad return -EBUSY; 981 1.1 riastrad } 982 1.1 riastrad atomic_inc(&dev->buf_alloc); 983 1.8 riastrad spin_unlock(&dev->buf_lock); 984 1.1 riastrad 985 1.1 riastrad mutex_lock(&dev->struct_mutex); 986 1.1 riastrad entry = &dma->bufs[order]; 987 1.1 riastrad if (entry->buf_count) { 988 1.1 riastrad mutex_unlock(&dev->struct_mutex); 989 1.1 riastrad atomic_dec(&dev->buf_alloc); 990 1.1 riastrad return -ENOMEM; /* May only call once for each order */ 991 1.1 riastrad } 992 1.1 riastrad 993 1.1 riastrad if (count < 0 || count > 4096) { 994 1.1 riastrad mutex_unlock(&dev->struct_mutex); 995 1.1 riastrad atomic_dec(&dev->buf_alloc); 996 1.1 riastrad return -EINVAL; 997 1.1 riastrad } 998 1.1 riastrad 999 1.13 riastrad entry->buflist = kcalloc(count, sizeof(*entry->buflist), GFP_KERNEL); 1000 1.1 riastrad if (!entry->buflist) { 1001 1.1 riastrad mutex_unlock(&dev->struct_mutex); 1002 1.1 riastrad atomic_dec(&dev->buf_alloc); 1003 1.1 riastrad return -ENOMEM; 1004 1.1 riastrad } 1005 1.1 riastrad 1006 1.13 riastrad entry->seglist = kcalloc(count, sizeof(*entry->seglist), GFP_KERNEL); 1007 1.1 riastrad if (!entry->seglist) { 1008 1.1 riastrad kfree(entry->buflist); 1009 1.1 riastrad mutex_unlock(&dev->struct_mutex); 1010 1.1 riastrad atomic_dec(&dev->buf_alloc); 1011 1.1 riastrad return -ENOMEM; 1012 1.1 riastrad } 1013 1.1 riastrad 1014 1.1 riastrad /* Keep the original pagelist until we know all the allocations 1015 1.1 riastrad * have succeeded 1016 1.1 riastrad */ 1017 1.13 riastrad temp_pagelist = kmalloc_array(dma->page_count + (count << page_order), 1018 1.13 riastrad sizeof(*dma->pagelist), 1019 1.13 riastrad GFP_KERNEL); 1020 1.1 riastrad if (!temp_pagelist) { 1021 1.1 riastrad kfree(entry->buflist); 1022 1.1 riastrad kfree(entry->seglist); 1023 1.1 riastrad mutex_unlock(&dev->struct_mutex); 1024 1.1 riastrad atomic_dec(&dev->buf_alloc); 1025 1.1 riastrad return -ENOMEM; 1026 1.1 riastrad } 1027 1.1 riastrad memcpy(temp_pagelist, 1028 1.1 riastrad dma->pagelist, dma->page_count * sizeof(*dma->pagelist)); 1029 1.1 riastrad DRM_DEBUG("pagelist: %d entries\n", 1030 1.1 riastrad dma->page_count + (count << page_order)); 1031 1.1 riastrad 1032 1.1 riastrad entry->buf_size = size; 1033 1.1 riastrad entry->page_order = page_order; 1034 1.1 riastrad byte_count = 0; 1035 1.1 riastrad page_count = 0; 1036 1.1 riastrad 1037 1.1 riastrad while (entry->buf_count < count) { 1038 1.1 riastrad 1039 1.1 riastrad dmah = drm_pci_alloc(dev, PAGE_SIZE << page_order, 0x1000); 1040 1.1 riastrad 1041 1.1 riastrad if (!dmah) { 1042 1.1 riastrad /* Set count correctly so we free the proper amount. */ 1043 1.1 riastrad entry->buf_count = count; 1044 1.1 riastrad entry->seg_count = count; 1045 1.1 riastrad drm_cleanup_buf_error(dev, entry); 1046 1.1 riastrad kfree(temp_pagelist); 1047 1.1 riastrad mutex_unlock(&dev->struct_mutex); 1048 1.1 riastrad atomic_dec(&dev->buf_alloc); 1049 1.1 riastrad return -ENOMEM; 1050 1.1 riastrad } 1051 1.1 riastrad entry->seglist[entry->seg_count++] = dmah; 1052 1.1 riastrad for (i = 0; i < (1 << page_order); i++) { 1053 1.1 riastrad DRM_DEBUG("page %d @ 0x%08lx\n", 1054 1.1 riastrad dma->page_count + page_count, 1055 1.1 riastrad (unsigned long)dmah->vaddr + PAGE_SIZE * i); 1056 1.1 riastrad temp_pagelist[dma->page_count + page_count++] 1057 1.1 riastrad = (unsigned long)dmah->vaddr + PAGE_SIZE * i; 1058 1.1 riastrad } 1059 1.1 riastrad for (offset = 0; 1060 1.1 riastrad offset + size <= total && entry->buf_count < count; 1061 1.1 riastrad offset += alignment, ++entry->buf_count) { 1062 1.1 riastrad buf = &entry->buflist[entry->buf_count]; 1063 1.1 riastrad buf->idx = dma->buf_count + entry->buf_count; 1064 1.1 riastrad buf->total = alignment; 1065 1.1 riastrad buf->order = order; 1066 1.1 riastrad buf->used = 0; 1067 1.1 riastrad buf->offset = (dma->byte_count + byte_count + offset); 1068 1.10 riastrad buf->address = (void *)(dmah->vaddr + offset); 1069 1.1 riastrad buf->bus_address = dmah->busaddr + offset; 1070 1.1 riastrad buf->next = NULL; 1071 1.1 riastrad buf->waiting = 0; 1072 1.1 riastrad buf->pending = 0; 1073 1.1 riastrad buf->file_priv = NULL; 1074 1.1 riastrad 1075 1.1 riastrad buf->dev_priv_size = dev->driver->dev_priv_size; 1076 1.1 riastrad buf->dev_private = kzalloc(buf->dev_priv_size, 1077 1.1 riastrad GFP_KERNEL); 1078 1.1 riastrad if (!buf->dev_private) { 1079 1.1 riastrad /* Set count correctly so we free the proper amount. */ 1080 1.1 riastrad entry->buf_count = count; 1081 1.1 riastrad entry->seg_count = count; 1082 1.1 riastrad drm_cleanup_buf_error(dev, entry); 1083 1.1 riastrad kfree(temp_pagelist); 1084 1.1 riastrad mutex_unlock(&dev->struct_mutex); 1085 1.1 riastrad atomic_dec(&dev->buf_alloc); 1086 1.1 riastrad return -ENOMEM; 1087 1.1 riastrad } 1088 1.1 riastrad 1089 1.1 riastrad DRM_DEBUG("buffer %d @ %p\n", 1090 1.1 riastrad entry->buf_count, buf->address); 1091 1.1 riastrad } 1092 1.1 riastrad byte_count += PAGE_SIZE << page_order; 1093 1.1 riastrad } 1094 1.1 riastrad 1095 1.1 riastrad temp_buflist = krealloc(dma->buflist, 1096 1.1 riastrad (dma->buf_count + entry->buf_count) * 1097 1.1 riastrad sizeof(*dma->buflist), GFP_KERNEL); 1098 1.1 riastrad if (!temp_buflist) { 1099 1.1 riastrad /* Free the entry because it isn't valid */ 1100 1.1 riastrad drm_cleanup_buf_error(dev, entry); 1101 1.1 riastrad kfree(temp_pagelist); 1102 1.1 riastrad mutex_unlock(&dev->struct_mutex); 1103 1.1 riastrad atomic_dec(&dev->buf_alloc); 1104 1.1 riastrad return -ENOMEM; 1105 1.1 riastrad } 1106 1.1 riastrad dma->buflist = temp_buflist; 1107 1.1 riastrad 1108 1.1 riastrad for (i = 0; i < entry->buf_count; i++) { 1109 1.1 riastrad dma->buflist[i + dma->buf_count] = &entry->buflist[i]; 1110 1.1 riastrad } 1111 1.1 riastrad 1112 1.1 riastrad /* No allocations failed, so now we can replace the original pagelist 1113 1.1 riastrad * with the new one. 1114 1.1 riastrad */ 1115 1.1 riastrad if (dma->page_count) { 1116 1.1 riastrad kfree(dma->pagelist); 1117 1.1 riastrad } 1118 1.1 riastrad dma->pagelist = temp_pagelist; 1119 1.1 riastrad 1120 1.1 riastrad dma->buf_count += entry->buf_count; 1121 1.1 riastrad dma->seg_count += entry->seg_count; 1122 1.1 riastrad dma->page_count += entry->seg_count << page_order; 1123 1.1 riastrad dma->byte_count += PAGE_SIZE * (entry->seg_count << page_order); 1124 1.1 riastrad 1125 1.1 riastrad mutex_unlock(&dev->struct_mutex); 1126 1.1 riastrad 1127 1.1 riastrad request->count = entry->buf_count; 1128 1.1 riastrad request->size = size; 1129 1.1 riastrad 1130 1.1 riastrad if (request->flags & _DRM_PCI_BUFFER_RO) 1131 1.1 riastrad dma->flags = _DRM_DMA_USE_PCI_RO; 1132 1.1 riastrad 1133 1.1 riastrad atomic_dec(&dev->buf_alloc); 1134 1.1 riastrad return 0; 1135 1.1 riastrad 1136 1.1 riastrad } 1137 1.8 riastrad EXPORT_SYMBOL(drm_legacy_addbufs_pci); 1138 1.1 riastrad 1139 1.8 riastrad static int drm_legacy_addbufs_sg(struct drm_device *dev, 1140 1.8 riastrad struct drm_buf_desc *request) 1141 1.1 riastrad { 1142 1.1 riastrad struct drm_device_dma *dma = dev->dma; 1143 1.1 riastrad struct drm_buf_entry *entry; 1144 1.1 riastrad struct drm_buf *buf; 1145 1.1 riastrad unsigned long offset; 1146 1.1 riastrad unsigned long agp_offset; 1147 1.1 riastrad int count; 1148 1.1 riastrad int order; 1149 1.1 riastrad int size; 1150 1.1 riastrad int alignment; 1151 1.1 riastrad int page_order; 1152 1.1 riastrad int total; 1153 1.1 riastrad int byte_count; 1154 1.1 riastrad int i; 1155 1.1 riastrad struct drm_buf **temp_buflist; 1156 1.1 riastrad 1157 1.1 riastrad if (!drm_core_check_feature(dev, DRIVER_SG)) 1158 1.13 riastrad return -EOPNOTSUPP; 1159 1.1 riastrad 1160 1.1 riastrad if (!dma) 1161 1.1 riastrad return -EINVAL; 1162 1.1 riastrad 1163 1.1 riastrad if (!capable(CAP_SYS_ADMIN)) 1164 1.1 riastrad return -EPERM; 1165 1.1 riastrad 1166 1.1 riastrad count = request->count; 1167 1.5 riastrad order = order_base_2(request->size); 1168 1.1 riastrad size = 1 << order; 1169 1.1 riastrad 1170 1.1 riastrad alignment = (request->flags & _DRM_PAGE_ALIGN) 1171 1.1 riastrad ? PAGE_ALIGN(size) : size; 1172 1.1 riastrad page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0; 1173 1.1 riastrad total = PAGE_SIZE << page_order; 1174 1.1 riastrad 1175 1.1 riastrad byte_count = 0; 1176 1.1 riastrad agp_offset = request->agp_start; 1177 1.1 riastrad 1178 1.1 riastrad DRM_DEBUG("count: %d\n", count); 1179 1.1 riastrad DRM_DEBUG("order: %d\n", order); 1180 1.1 riastrad DRM_DEBUG("size: %d\n", size); 1181 1.1 riastrad DRM_DEBUG("agp_offset: %lu\n", agp_offset); 1182 1.1 riastrad DRM_DEBUG("alignment: %d\n", alignment); 1183 1.1 riastrad DRM_DEBUG("page_order: %d\n", page_order); 1184 1.1 riastrad DRM_DEBUG("total: %d\n", total); 1185 1.1 riastrad 1186 1.1 riastrad if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) 1187 1.1 riastrad return -EINVAL; 1188 1.1 riastrad 1189 1.8 riastrad spin_lock(&dev->buf_lock); 1190 1.1 riastrad if (dev->buf_use) { 1191 1.8 riastrad spin_unlock(&dev->buf_lock); 1192 1.1 riastrad return -EBUSY; 1193 1.1 riastrad } 1194 1.1 riastrad atomic_inc(&dev->buf_alloc); 1195 1.8 riastrad spin_unlock(&dev->buf_lock); 1196 1.1 riastrad 1197 1.1 riastrad mutex_lock(&dev->struct_mutex); 1198 1.1 riastrad entry = &dma->bufs[order]; 1199 1.1 riastrad if (entry->buf_count) { 1200 1.1 riastrad mutex_unlock(&dev->struct_mutex); 1201 1.1 riastrad atomic_dec(&dev->buf_alloc); 1202 1.1 riastrad return -ENOMEM; /* May only call once for each order */ 1203 1.1 riastrad } 1204 1.1 riastrad 1205 1.1 riastrad if (count < 0 || count > 4096) { 1206 1.1 riastrad mutex_unlock(&dev->struct_mutex); 1207 1.1 riastrad atomic_dec(&dev->buf_alloc); 1208 1.1 riastrad return -EINVAL; 1209 1.1 riastrad } 1210 1.1 riastrad 1211 1.13 riastrad entry->buflist = kcalloc(count, sizeof(*entry->buflist), GFP_KERNEL); 1212 1.1 riastrad if (!entry->buflist) { 1213 1.1 riastrad mutex_unlock(&dev->struct_mutex); 1214 1.1 riastrad atomic_dec(&dev->buf_alloc); 1215 1.1 riastrad return -ENOMEM; 1216 1.1 riastrad } 1217 1.1 riastrad 1218 1.1 riastrad entry->buf_size = size; 1219 1.1 riastrad entry->page_order = page_order; 1220 1.1 riastrad 1221 1.1 riastrad offset = 0; 1222 1.1 riastrad 1223 1.1 riastrad while (entry->buf_count < count) { 1224 1.1 riastrad buf = &entry->buflist[entry->buf_count]; 1225 1.1 riastrad buf->idx = dma->buf_count + entry->buf_count; 1226 1.1 riastrad buf->total = alignment; 1227 1.1 riastrad buf->order = order; 1228 1.1 riastrad buf->used = 0; 1229 1.1 riastrad 1230 1.1 riastrad buf->offset = (dma->byte_count + offset); 1231 1.1 riastrad buf->bus_address = agp_offset + offset; 1232 1.1 riastrad buf->address = (void *)(agp_offset + offset 1233 1.1 riastrad + (unsigned long)dev->sg->virtual); 1234 1.1 riastrad buf->next = NULL; 1235 1.1 riastrad buf->waiting = 0; 1236 1.1 riastrad buf->pending = 0; 1237 1.1 riastrad buf->file_priv = NULL; 1238 1.1 riastrad 1239 1.1 riastrad buf->dev_priv_size = dev->driver->dev_priv_size; 1240 1.1 riastrad buf->dev_private = kzalloc(buf->dev_priv_size, GFP_KERNEL); 1241 1.1 riastrad if (!buf->dev_private) { 1242 1.1 riastrad /* Set count correctly so we free the proper amount. */ 1243 1.1 riastrad entry->buf_count = count; 1244 1.1 riastrad drm_cleanup_buf_error(dev, entry); 1245 1.1 riastrad mutex_unlock(&dev->struct_mutex); 1246 1.1 riastrad atomic_dec(&dev->buf_alloc); 1247 1.1 riastrad return -ENOMEM; 1248 1.1 riastrad } 1249 1.1 riastrad 1250 1.1 riastrad DRM_DEBUG("buffer %d @ %p\n", entry->buf_count, buf->address); 1251 1.1 riastrad 1252 1.1 riastrad offset += alignment; 1253 1.1 riastrad entry->buf_count++; 1254 1.1 riastrad byte_count += PAGE_SIZE << page_order; 1255 1.1 riastrad } 1256 1.1 riastrad 1257 1.1 riastrad DRM_DEBUG("byte_count: %d\n", byte_count); 1258 1.1 riastrad 1259 1.1 riastrad temp_buflist = krealloc(dma->buflist, 1260 1.1 riastrad (dma->buf_count + entry->buf_count) * 1261 1.1 riastrad sizeof(*dma->buflist), GFP_KERNEL); 1262 1.1 riastrad if (!temp_buflist) { 1263 1.1 riastrad /* Free the entry because it isn't valid */ 1264 1.1 riastrad drm_cleanup_buf_error(dev, entry); 1265 1.1 riastrad mutex_unlock(&dev->struct_mutex); 1266 1.1 riastrad atomic_dec(&dev->buf_alloc); 1267 1.1 riastrad return -ENOMEM; 1268 1.1 riastrad } 1269 1.1 riastrad dma->buflist = temp_buflist; 1270 1.1 riastrad 1271 1.1 riastrad for (i = 0; i < entry->buf_count; i++) { 1272 1.1 riastrad dma->buflist[i + dma->buf_count] = &entry->buflist[i]; 1273 1.1 riastrad } 1274 1.1 riastrad 1275 1.1 riastrad dma->buf_count += entry->buf_count; 1276 1.1 riastrad dma->seg_count += entry->seg_count; 1277 1.1 riastrad dma->page_count += byte_count >> PAGE_SHIFT; 1278 1.1 riastrad dma->byte_count += byte_count; 1279 1.1 riastrad 1280 1.1 riastrad DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count); 1281 1.1 riastrad DRM_DEBUG("entry->buf_count : %d\n", entry->buf_count); 1282 1.1 riastrad 1283 1.1 riastrad mutex_unlock(&dev->struct_mutex); 1284 1.1 riastrad 1285 1.1 riastrad request->count = entry->buf_count; 1286 1.1 riastrad request->size = size; 1287 1.1 riastrad 1288 1.1 riastrad dma->flags = _DRM_DMA_USE_SG; 1289 1.1 riastrad 1290 1.1 riastrad atomic_dec(&dev->buf_alloc); 1291 1.1 riastrad return 0; 1292 1.1 riastrad } 1293 1.1 riastrad 1294 1.1 riastrad /** 1295 1.1 riastrad * Add buffers for DMA transfers (ioctl). 1296 1.1 riastrad * 1297 1.1 riastrad * \param inode device inode. 1298 1.1 riastrad * \param file_priv DRM file private. 1299 1.1 riastrad * \param cmd command. 1300 1.1 riastrad * \param arg pointer to a struct drm_buf_desc request. 1301 1.1 riastrad * \return zero on success or a negative number on failure. 1302 1.1 riastrad * 1303 1.1 riastrad * According with the memory type specified in drm_buf_desc::flags and the 1304 1.1 riastrad * build options, it dispatches the call either to addbufs_agp(), 1305 1.1 riastrad * addbufs_sg() or addbufs_pci() for AGP, scatter-gather or consistent 1306 1.1 riastrad * PCI memory respectively. 1307 1.1 riastrad */ 1308 1.8 riastrad int drm_legacy_addbufs(struct drm_device *dev, void *data, 1309 1.8 riastrad struct drm_file *file_priv) 1310 1.1 riastrad { 1311 1.1 riastrad struct drm_buf_desc *request = data; 1312 1.1 riastrad int ret; 1313 1.1 riastrad 1314 1.13 riastrad if (!drm_core_check_feature(dev, DRIVER_LEGACY)) 1315 1.13 riastrad return -EOPNOTSUPP; 1316 1.5 riastrad 1317 1.1 riastrad if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA)) 1318 1.13 riastrad return -EOPNOTSUPP; 1319 1.1 riastrad 1320 1.8 riastrad #if IS_ENABLED(CONFIG_AGP) 1321 1.1 riastrad if (request->flags & _DRM_AGP_BUFFER) 1322 1.8 riastrad ret = drm_legacy_addbufs_agp(dev, request); 1323 1.1 riastrad else 1324 1.1 riastrad #endif 1325 1.1 riastrad if (request->flags & _DRM_SG_BUFFER) 1326 1.8 riastrad ret = drm_legacy_addbufs_sg(dev, request); 1327 1.1 riastrad else if (request->flags & _DRM_FB_BUFFER) 1328 1.5 riastrad ret = -EINVAL; 1329 1.1 riastrad else 1330 1.8 riastrad ret = drm_legacy_addbufs_pci(dev, request); 1331 1.1 riastrad 1332 1.1 riastrad return ret; 1333 1.1 riastrad } 1334 1.1 riastrad 1335 1.1 riastrad /** 1336 1.1 riastrad * Get information about the buffer mappings. 1337 1.1 riastrad * 1338 1.1 riastrad * This was originally mean for debugging purposes, or by a sophisticated 1339 1.1 riastrad * client library to determine how best to use the available buffers (e.g., 1340 1.1 riastrad * large buffers can be used for image transfer). 1341 1.1 riastrad * 1342 1.1 riastrad * \param inode device inode. 1343 1.1 riastrad * \param file_priv DRM file private. 1344 1.1 riastrad * \param cmd command. 1345 1.1 riastrad * \param arg pointer to a drm_buf_info structure. 1346 1.1 riastrad * \return zero on success or a negative number on failure. 1347 1.1 riastrad * 1348 1.8 riastrad * Increments drm_device::buf_use while holding the drm_device::buf_lock 1349 1.1 riastrad * lock, preventing of allocating more buffers after this call. Information 1350 1.1 riastrad * about each requested buffer is then copied into user space. 1351 1.1 riastrad */ 1352 1.13 riastrad int __drm_legacy_infobufs(struct drm_device *dev, 1353 1.13 riastrad void *data, int *p, 1354 1.13 riastrad int (*f)(void *, int, struct drm_buf_entry *)) 1355 1.1 riastrad { 1356 1.1 riastrad struct drm_device_dma *dma = dev->dma; 1357 1.1 riastrad int i; 1358 1.1 riastrad int count; 1359 1.1 riastrad 1360 1.13 riastrad if (!drm_core_check_feature(dev, DRIVER_LEGACY)) 1361 1.13 riastrad return -EOPNOTSUPP; 1362 1.5 riastrad 1363 1.1 riastrad if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA)) 1364 1.13 riastrad return -EOPNOTSUPP; 1365 1.1 riastrad 1366 1.1 riastrad if (!dma) 1367 1.1 riastrad return -EINVAL; 1368 1.1 riastrad 1369 1.8 riastrad spin_lock(&dev->buf_lock); 1370 1.1 riastrad if (atomic_read(&dev->buf_alloc)) { 1371 1.8 riastrad spin_unlock(&dev->buf_lock); 1372 1.1 riastrad return -EBUSY; 1373 1.1 riastrad } 1374 1.1 riastrad ++dev->buf_use; /* Can't allocate more after this call */ 1375 1.8 riastrad spin_unlock(&dev->buf_lock); 1376 1.1 riastrad 1377 1.1 riastrad for (i = 0, count = 0; i < DRM_MAX_ORDER + 1; i++) { 1378 1.1 riastrad if (dma->bufs[i].buf_count) 1379 1.1 riastrad ++count; 1380 1.1 riastrad } 1381 1.1 riastrad 1382 1.1 riastrad DRM_DEBUG("count = %d\n", count); 1383 1.1 riastrad 1384 1.13 riastrad if (*p >= count) { 1385 1.1 riastrad for (i = 0, count = 0; i < DRM_MAX_ORDER + 1; i++) { 1386 1.13 riastrad struct drm_buf_entry *from = &dma->bufs[i]; 1387 1.13 riastrad if (from->buf_count) { 1388 1.13 riastrad if (f(data, count, from) < 0) 1389 1.1 riastrad return -EFAULT; 1390 1.1 riastrad DRM_DEBUG("%d %d %d %d %d\n", 1391 1.1 riastrad i, 1392 1.1 riastrad dma->bufs[i].buf_count, 1393 1.1 riastrad dma->bufs[i].buf_size, 1394 1.8 riastrad dma->bufs[i].low_mark, 1395 1.8 riastrad dma->bufs[i].high_mark); 1396 1.1 riastrad ++count; 1397 1.1 riastrad } 1398 1.1 riastrad } 1399 1.1 riastrad } 1400 1.13 riastrad *p = count; 1401 1.13 riastrad 1402 1.13 riastrad return 0; 1403 1.13 riastrad } 1404 1.1 riastrad 1405 1.13 riastrad static int copy_one_buf(void *data, int count, struct drm_buf_entry *from) 1406 1.13 riastrad { 1407 1.13 riastrad struct drm_buf_info *request = data; 1408 1.13 riastrad struct drm_buf_desc __user *to = &request->list[count]; 1409 1.13 riastrad struct drm_buf_desc v = {.count = from->buf_count, 1410 1.13 riastrad .size = from->buf_size, 1411 1.13 riastrad .low_mark = from->low_mark, 1412 1.13 riastrad .high_mark = from->high_mark}; 1413 1.13 riastrad 1414 1.13 riastrad if (copy_to_user(to, &v, offsetof(struct drm_buf_desc, flags))) 1415 1.13 riastrad return -EFAULT; 1416 1.1 riastrad return 0; 1417 1.1 riastrad } 1418 1.1 riastrad 1419 1.13 riastrad int drm_legacy_infobufs(struct drm_device *dev, void *data, 1420 1.13 riastrad struct drm_file *file_priv) 1421 1.13 riastrad { 1422 1.13 riastrad struct drm_buf_info *request = data; 1423 1.13 riastrad return __drm_legacy_infobufs(dev, data, &request->count, copy_one_buf); 1424 1.13 riastrad } 1425 1.13 riastrad 1426 1.1 riastrad /** 1427 1.1 riastrad * Specifies a low and high water mark for buffer allocation 1428 1.1 riastrad * 1429 1.1 riastrad * \param inode device inode. 1430 1.1 riastrad * \param file_priv DRM file private. 1431 1.1 riastrad * \param cmd command. 1432 1.1 riastrad * \param arg a pointer to a drm_buf_desc structure. 1433 1.1 riastrad * \return zero on success or a negative number on failure. 1434 1.1 riastrad * 1435 1.1 riastrad * Verifies that the size order is bounded between the admissible orders and 1436 1.1 riastrad * updates the respective drm_device_dma::bufs entry low and high water mark. 1437 1.1 riastrad * 1438 1.1 riastrad * \note This ioctl is deprecated and mostly never used. 1439 1.1 riastrad */ 1440 1.8 riastrad int drm_legacy_markbufs(struct drm_device *dev, void *data, 1441 1.8 riastrad struct drm_file *file_priv) 1442 1.1 riastrad { 1443 1.1 riastrad struct drm_device_dma *dma = dev->dma; 1444 1.1 riastrad struct drm_buf_desc *request = data; 1445 1.1 riastrad int order; 1446 1.1 riastrad struct drm_buf_entry *entry; 1447 1.1 riastrad 1448 1.13 riastrad if (!drm_core_check_feature(dev, DRIVER_LEGACY)) 1449 1.13 riastrad return -EOPNOTSUPP; 1450 1.5 riastrad 1451 1.1 riastrad if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA)) 1452 1.13 riastrad return -EOPNOTSUPP; 1453 1.1 riastrad 1454 1.1 riastrad if (!dma) 1455 1.1 riastrad return -EINVAL; 1456 1.1 riastrad 1457 1.1 riastrad DRM_DEBUG("%d, %d, %d\n", 1458 1.1 riastrad request->size, request->low_mark, request->high_mark); 1459 1.5 riastrad order = order_base_2(request->size); 1460 1.1 riastrad if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) 1461 1.1 riastrad return -EINVAL; 1462 1.1 riastrad entry = &dma->bufs[order]; 1463 1.1 riastrad 1464 1.1 riastrad if (request->low_mark < 0 || request->low_mark > entry->buf_count) 1465 1.1 riastrad return -EINVAL; 1466 1.1 riastrad if (request->high_mark < 0 || request->high_mark > entry->buf_count) 1467 1.1 riastrad return -EINVAL; 1468 1.1 riastrad 1469 1.8 riastrad entry->low_mark = request->low_mark; 1470 1.8 riastrad entry->high_mark = request->high_mark; 1471 1.1 riastrad 1472 1.1 riastrad return 0; 1473 1.1 riastrad } 1474 1.1 riastrad 1475 1.1 riastrad /** 1476 1.1 riastrad * Unreserve the buffers in list, previously reserved using drmDMA. 1477 1.1 riastrad * 1478 1.1 riastrad * \param inode device inode. 1479 1.1 riastrad * \param file_priv DRM file private. 1480 1.1 riastrad * \param cmd command. 1481 1.1 riastrad * \param arg pointer to a drm_buf_free structure. 1482 1.1 riastrad * \return zero on success or a negative number on failure. 1483 1.1 riastrad * 1484 1.1 riastrad * Calls free_buffer() for each used buffer. 1485 1.1 riastrad * This function is primarily used for debugging. 1486 1.1 riastrad */ 1487 1.8 riastrad int drm_legacy_freebufs(struct drm_device *dev, void *data, 1488 1.8 riastrad struct drm_file *file_priv) 1489 1.1 riastrad { 1490 1.1 riastrad struct drm_device_dma *dma = dev->dma; 1491 1.1 riastrad struct drm_buf_free *request = data; 1492 1.1 riastrad int i; 1493 1.1 riastrad int idx; 1494 1.1 riastrad struct drm_buf *buf; 1495 1.1 riastrad 1496 1.13 riastrad if (!drm_core_check_feature(dev, DRIVER_LEGACY)) 1497 1.13 riastrad return -EOPNOTSUPP; 1498 1.5 riastrad 1499 1.1 riastrad if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA)) 1500 1.13 riastrad return -EOPNOTSUPP; 1501 1.1 riastrad 1502 1.1 riastrad if (!dma) 1503 1.1 riastrad return -EINVAL; 1504 1.1 riastrad 1505 1.1 riastrad DRM_DEBUG("%d\n", request->count); 1506 1.1 riastrad for (i = 0; i < request->count; i++) { 1507 1.1 riastrad if (copy_from_user(&idx, &request->list[i], sizeof(idx))) 1508 1.1 riastrad return -EFAULT; 1509 1.1 riastrad if (idx < 0 || idx >= dma->buf_count) { 1510 1.1 riastrad DRM_ERROR("Index %d (of %d max)\n", 1511 1.1 riastrad idx, dma->buf_count - 1); 1512 1.1 riastrad return -EINVAL; 1513 1.1 riastrad } 1514 1.13 riastrad idx = array_index_nospec(idx, dma->buf_count); 1515 1.1 riastrad buf = dma->buflist[idx]; 1516 1.1 riastrad if (buf->file_priv != file_priv) { 1517 1.16 riastrad #ifdef __NetBSD__ 1518 1.16 riastrad DRM_ERROR("Process %d freeing buffer not owned\n", 1519 1.16 riastrad (int)curproc->p_pid); 1520 1.16 riastrad #else 1521 1.1 riastrad DRM_ERROR("Process %d freeing buffer not owned\n", 1522 1.1 riastrad task_pid_nr(current)); 1523 1.16 riastrad #endif 1524 1.1 riastrad return -EINVAL; 1525 1.1 riastrad } 1526 1.8 riastrad drm_legacy_free_buffer(dev, buf); 1527 1.1 riastrad } 1528 1.1 riastrad 1529 1.1 riastrad return 0; 1530 1.1 riastrad } 1531 1.1 riastrad 1532 1.1 riastrad /** 1533 1.1 riastrad * Maps all of the DMA buffers into client-virtual space (ioctl). 1534 1.1 riastrad * 1535 1.1 riastrad * \param inode device inode. 1536 1.1 riastrad * \param file_priv DRM file private. 1537 1.1 riastrad * \param cmd command. 1538 1.1 riastrad * \param arg pointer to a drm_buf_map structure. 1539 1.1 riastrad * \return zero on success or a negative number on failure. 1540 1.1 riastrad * 1541 1.1 riastrad * Maps the AGP, SG or PCI buffer region with vm_mmap(), and copies information 1542 1.1 riastrad * about each buffer into user space. For PCI buffers, it calls vm_mmap() with 1543 1.1 riastrad * offset equal to 0, which drm_mmap() interpretes as PCI buffers and calls 1544 1.1 riastrad * drm_mmap_dma(). 1545 1.1 riastrad */ 1546 1.13 riastrad int __drm_legacy_mapbufs(struct drm_device *dev, void *data, int *p, 1547 1.13 riastrad void __user **v, 1548 1.13 riastrad int (*f)(void *, int, unsigned long, 1549 1.13 riastrad struct drm_buf *), 1550 1.13 riastrad struct drm_file *file_priv) 1551 1.1 riastrad { 1552 1.1 riastrad struct drm_device_dma *dma = dev->dma; 1553 1.1 riastrad int retcode = 0; 1554 1.1 riastrad unsigned long virtual; 1555 1.1 riastrad int i; 1556 1.1 riastrad 1557 1.13 riastrad if (!drm_core_check_feature(dev, DRIVER_LEGACY)) 1558 1.13 riastrad return -EOPNOTSUPP; 1559 1.5 riastrad 1560 1.1 riastrad if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA)) 1561 1.13 riastrad return -EOPNOTSUPP; 1562 1.1 riastrad 1563 1.1 riastrad if (!dma) 1564 1.1 riastrad return -EINVAL; 1565 1.1 riastrad 1566 1.8 riastrad spin_lock(&dev->buf_lock); 1567 1.1 riastrad if (atomic_read(&dev->buf_alloc)) { 1568 1.8 riastrad spin_unlock(&dev->buf_lock); 1569 1.1 riastrad return -EBUSY; 1570 1.1 riastrad } 1571 1.1 riastrad dev->buf_use++; /* Can't allocate more after this call */ 1572 1.8 riastrad spin_unlock(&dev->buf_lock); 1573 1.1 riastrad 1574 1.13 riastrad if (*p >= dma->buf_count) { 1575 1.5 riastrad if ((dev->agp && (dma->flags & _DRM_DMA_USE_AGP)) 1576 1.1 riastrad || (drm_core_check_feature(dev, DRIVER_SG) 1577 1.5 riastrad && (dma->flags & _DRM_DMA_USE_SG))) { 1578 1.1 riastrad struct drm_local_map *map = dev->agp_buffer_map; 1579 1.1 riastrad unsigned long token = dev->agp_buffer_token; 1580 1.1 riastrad 1581 1.1 riastrad if (!map) { 1582 1.1 riastrad retcode = -EINVAL; 1583 1.1 riastrad goto done; 1584 1.1 riastrad } 1585 1.1 riastrad virtual = vm_mmap(file_priv->filp, 0, map->size, 1586 1.1 riastrad PROT_READ | PROT_WRITE, 1587 1.1 riastrad MAP_SHARED, 1588 1.1 riastrad token); 1589 1.1 riastrad } else { 1590 1.1 riastrad virtual = vm_mmap(file_priv->filp, 0, dma->byte_count, 1591 1.1 riastrad PROT_READ | PROT_WRITE, 1592 1.1 riastrad MAP_SHARED, 0); 1593 1.1 riastrad } 1594 1.1 riastrad if (virtual > -1024UL) { 1595 1.1 riastrad /* Real error */ 1596 1.1 riastrad retcode = (signed long)virtual; 1597 1.1 riastrad goto done; 1598 1.1 riastrad } 1599 1.13 riastrad *v = (void __user *)virtual; 1600 1.1 riastrad 1601 1.1 riastrad for (i = 0; i < dma->buf_count; i++) { 1602 1.13 riastrad if (f(data, i, virtual, dma->buflist[i]) < 0) { 1603 1.1 riastrad retcode = -EFAULT; 1604 1.1 riastrad goto done; 1605 1.1 riastrad } 1606 1.1 riastrad } 1607 1.1 riastrad } 1608 1.1 riastrad done: 1609 1.13 riastrad *p = dma->buf_count; 1610 1.13 riastrad DRM_DEBUG("%d buffers, retcode = %d\n", *p, retcode); 1611 1.1 riastrad 1612 1.1 riastrad return retcode; 1613 1.1 riastrad } 1614 1.1 riastrad 1615 1.13 riastrad static int map_one_buf(void *data, int idx, unsigned long virtual, 1616 1.13 riastrad struct drm_buf *buf) 1617 1.13 riastrad { 1618 1.13 riastrad struct drm_buf_map *request = data; 1619 1.13 riastrad unsigned long address = virtual + buf->offset; /* *** */ 1620 1.13 riastrad 1621 1.13 riastrad if (copy_to_user(&request->list[idx].idx, &buf->idx, 1622 1.13 riastrad sizeof(request->list[0].idx))) 1623 1.13 riastrad return -EFAULT; 1624 1.13 riastrad if (copy_to_user(&request->list[idx].total, &buf->total, 1625 1.13 riastrad sizeof(request->list[0].total))) 1626 1.13 riastrad return -EFAULT; 1627 1.13 riastrad if (clear_user(&request->list[idx].used, sizeof(int))) 1628 1.13 riastrad return -EFAULT; 1629 1.13 riastrad if (copy_to_user(&request->list[idx].address, &address, 1630 1.13 riastrad sizeof(address))) 1631 1.13 riastrad return -EFAULT; 1632 1.13 riastrad return 0; 1633 1.13 riastrad } 1634 1.13 riastrad 1635 1.13 riastrad int drm_legacy_mapbufs(struct drm_device *dev, void *data, 1636 1.13 riastrad struct drm_file *file_priv) 1637 1.13 riastrad { 1638 1.13 riastrad struct drm_buf_map *request = data; 1639 1.13 riastrad return __drm_legacy_mapbufs(dev, data, &request->count, 1640 1.13 riastrad &request->virtual, map_one_buf, 1641 1.13 riastrad file_priv); 1642 1.13 riastrad } 1643 1.13 riastrad 1644 1.8 riastrad int drm_legacy_dma_ioctl(struct drm_device *dev, void *data, 1645 1.5 riastrad struct drm_file *file_priv) 1646 1.1 riastrad { 1647 1.13 riastrad if (!drm_core_check_feature(dev, DRIVER_LEGACY)) 1648 1.13 riastrad return -EOPNOTSUPP; 1649 1.1 riastrad 1650 1.5 riastrad if (dev->driver->dma_ioctl) 1651 1.5 riastrad return dev->driver->dma_ioctl(dev, data, file_priv); 1652 1.5 riastrad else 1653 1.5 riastrad return -EINVAL; 1654 1.5 riastrad } 1655 1.1 riastrad 1656 1.8 riastrad struct drm_local_map *drm_legacy_getsarea(struct drm_device *dev) 1657 1.5 riastrad { 1658 1.5 riastrad struct drm_map_list *entry; 1659 1.1 riastrad 1660 1.5 riastrad list_for_each_entry(entry, &dev->maplist, head) { 1661 1.5 riastrad if (entry->map && entry->map->type == _DRM_SHM && 1662 1.5 riastrad (entry->map->flags & _DRM_CONTAINS_LOCK)) { 1663 1.5 riastrad return entry->map; 1664 1.5 riastrad } 1665 1.5 riastrad } 1666 1.5 riastrad return NULL; 1667 1.1 riastrad } 1668 1.8 riastrad EXPORT_SYMBOL(drm_legacy_getsarea); 1669