drm_scatter.c (254025) | drm_scatter.c (280183) |
---|---|
1/*- 2 * Copyright (c) 2009 Robert C. Noland III <rnoland@FreeBSD.org> 3 * All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, --- 9 unchanged lines hidden (view full) --- 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 * DEALINGS IN THE SOFTWARE. 23 */ 24 25#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2009 Robert C. Noland III <rnoland@FreeBSD.org> 3 * All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, --- 9 unchanged lines hidden (view full) --- 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 * DEALINGS IN THE SOFTWARE. 23 */ 24 25#include <sys/cdefs.h> |
26__FBSDID("$FreeBSD: head/sys/dev/drm2/drm_scatter.c 254025 2013-08-07 06:21:20Z jeff $"); | 26__FBSDID("$FreeBSD: head/sys/dev/drm2/drm_scatter.c 280183 2015-03-17 18:50:33Z dumbbell $"); |
27 28/** @file drm_scatter.c 29 * Allocation of memory for scatter-gather mappings by the graphics chip. 30 * The memory allocated here is then made into an aperture in the card 31 * by mapping the pages into the GART. 32 */ 33 34#include <dev/drm2/drmP.h> 35 | 27 28/** @file drm_scatter.c 29 * Allocation of memory for scatter-gather mappings by the graphics chip. 30 * The memory allocated here is then made into an aperture in the card 31 * by mapping the pages into the GART. 32 */ 33 34#include <dev/drm2/drmP.h> 35 |
36int 37drm_sg_alloc(struct drm_device *dev, struct drm_scatter_gather *request) | 36#define DEBUG_SCATTER 0 37 38static inline vm_offset_t drm_vmalloc_dma(vm_size_t size) |
38{ | 39{ |
40 return kmem_alloc_attr(kernel_arena, size, M_NOWAIT | M_ZERO, 41 0, BUS_SPACE_MAXADDR_32BIT, VM_MEMATTR_WRITE_COMBINING); 42} 43 44void drm_sg_cleanup(struct drm_sg_mem * entry) 45{ 46 if (entry == NULL) 47 return; 48 49 if (entry->vaddr != 0) 50 kmem_free(kernel_arena, entry->vaddr, IDX_TO_OFF(entry->pages)); 51 52 free(entry->busaddr, DRM_MEM_SGLISTS); 53 free(entry, DRM_MEM_DRIVER); 54} 55 56int drm_sg_alloc(struct drm_device *dev, struct drm_scatter_gather * request) 57{ |
|
39 struct drm_sg_mem *entry; 40 vm_size_t size; 41 vm_pindex_t pindex; 42 | 58 struct drm_sg_mem *entry; 59 vm_size_t size; 60 vm_pindex_t pindex; 61 |
62 DRM_DEBUG("\n"); 63 64 if (!drm_core_check_feature(dev, DRIVER_SG)) 65 return -EINVAL; 66 |
|
43 if (dev->sg) | 67 if (dev->sg) |
44 return EINVAL; | 68 return -EINVAL; |
45 | 69 |
70 entry = malloc(sizeof(*entry), DRM_MEM_DRIVER, M_NOWAIT | M_ZERO); 71 if (!entry) 72 return -ENOMEM; 73 |
|
46 DRM_DEBUG("request size=%ld\n", request->size); 47 | 74 DRM_DEBUG("request size=%ld\n", request->size); 75 |
48 entry = malloc(sizeof(*entry), DRM_MEM_DRIVER, M_WAITOK | M_ZERO); 49 | |
50 size = round_page(request->size); 51 entry->pages = OFF_TO_IDX(size); 52 entry->busaddr = malloc(entry->pages * sizeof(*entry->busaddr), | 76 size = round_page(request->size); 77 entry->pages = OFF_TO_IDX(size); 78 entry->busaddr = malloc(entry->pages * sizeof(*entry->busaddr), |
53 DRM_MEM_SGLISTS, M_WAITOK | M_ZERO); | 79 DRM_MEM_SGLISTS, M_NOWAIT | M_ZERO); 80 if (!entry->busaddr) { 81 free(entry, DRM_MEM_DRIVER); 82 return -ENOMEM; 83 } |
54 | 84 |
55 entry->vaddr = kmem_alloc_attr(kernel_arena, size, M_WAITOK | M_ZERO, 56 0, BUS_SPACE_MAXADDR_32BIT, VM_MEMATTR_WRITE_COMBINING); | 85 entry->vaddr = drm_vmalloc_dma(size); |
57 if (entry->vaddr == 0) { | 86 if (entry->vaddr == 0) { |
58 drm_sg_cleanup(entry); 59 return (ENOMEM); | 87 free(entry->busaddr, DRM_MEM_DRIVER); 88 free(entry, DRM_MEM_DRIVER); 89 return -ENOMEM; |
60 } 61 | 90 } 91 |
62 for(pindex = 0; pindex < entry->pages; pindex++) { | 92 for (pindex = 0; pindex < entry->pages; pindex++) { |
63 entry->busaddr[pindex] = 64 vtophys(entry->vaddr + IDX_TO_OFF(pindex)); 65 } 66 | 93 entry->busaddr[pindex] = 94 vtophys(entry->vaddr + IDX_TO_OFF(pindex)); 95 } 96 |
67 DRM_LOCK(dev); 68 if (dev->sg) { 69 DRM_UNLOCK(dev); 70 drm_sg_cleanup(entry); 71 return (EINVAL); 72 } 73 dev->sg = entry; 74 DRM_UNLOCK(dev); 75 | |
76 request->handle = entry->vaddr; 77 | 97 request->handle = entry->vaddr; 98 |
99 dev->sg = entry; 100 |
|
78 DRM_DEBUG("allocated %ju pages @ 0x%08zx, contents=%08lx\n", 79 entry->pages, entry->vaddr, *(unsigned long *)entry->vaddr); 80 | 101 DRM_DEBUG("allocated %ju pages @ 0x%08zx, contents=%08lx\n", 102 entry->pages, entry->vaddr, *(unsigned long *)entry->vaddr); 103 |
81 return (0); | 104 return 0; |
82} 83 | 105} 106 |
84int 85drm_sg_alloc_ioctl(struct drm_device *dev, void *data, 86 struct drm_file *file_priv) | 107int drm_sg_alloc_ioctl(struct drm_device *dev, void *data, 108 struct drm_file *file_priv) |
87{ 88 struct drm_scatter_gather *request = data; 89 | 109{ 110 struct drm_scatter_gather *request = data; 111 |
90 DRM_DEBUG("\n"); | 112 return drm_sg_alloc(dev, request); |
91 | 113 |
92 return (drm_sg_alloc(dev, request)); | |
93} 94 | 114} 115 |
95void 96drm_sg_cleanup(struct drm_sg_mem *entry) | 116int drm_sg_free(struct drm_device *dev, void *data, 117 struct drm_file *file_priv) |
97{ | 118{ |
98 if (entry == NULL) 99 return; 100 101 if (entry->vaddr != 0) 102 kmem_free(kernel_arena, entry->vaddr, IDX_TO_OFF(entry->pages)); 103 104 free(entry->busaddr, DRM_MEM_SGLISTS); 105 free(entry, DRM_MEM_DRIVER); 106 107 return; 108} 109 110int 111drm_sg_free(struct drm_device *dev, void *data, struct drm_file *file_priv) 112{ | |
113 struct drm_scatter_gather *request = data; 114 struct drm_sg_mem *entry; 115 | 119 struct drm_scatter_gather *request = data; 120 struct drm_sg_mem *entry; 121 |
116 DRM_LOCK(dev); | 122 if (!drm_core_check_feature(dev, DRIVER_SG)) 123 return -EINVAL; 124 |
117 entry = dev->sg; 118 dev->sg = NULL; | 125 entry = dev->sg; 126 dev->sg = NULL; |
119 DRM_UNLOCK(dev); | |
120 121 if (!entry || entry->vaddr != request->handle) | 127 128 if (!entry || entry->vaddr != request->handle) |
122 return (EINVAL); | 129 return -EINVAL; |
123 124 DRM_DEBUG("free 0x%zx\n", entry->vaddr); 125 126 drm_sg_cleanup(entry); 127 | 130 131 DRM_DEBUG("free 0x%zx\n", entry->vaddr); 132 133 drm_sg_cleanup(entry); 134 |
128 return (0); | 135 return 0; |
129} | 136} |