1 /* drm_scatter.h -- IOCTLs to manage scatter/gather memory -*- linux-c -*-
2 * Created: Mon Dec 18 23:20:54 2000 by gareth@valinux.com */
3 /*-
4 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
5 * All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
16 * Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
22 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
25 *
26 * Authors:
27 * Gareth Hughes <gareth@valinux.com>
28 * Eric Anholt <anholt@FreeBSD.org>
29 *
30 */
31
32 #include <sys/cdefs.h>
33 __FBSDID("$FreeBSD: releng/6.4/sys/dev/drm/drm_scatter.c 158686 2006-05-17 07:40:12Z anholt $");
34
35 #include "dev/drm/drmP.h"
36
37 #define DEBUG_SCATTER 0
38
39 void drm_sg_cleanup(drm_sg_mem_t *entry)
40 {
41 free((void *)entry->handle, M_DRM);
42 free(entry->busaddr, M_DRM);
43 free(entry, M_DRM);
44 }
45
46 int drm_sg_alloc(DRM_IOCTL_ARGS)
47 {
48 DRM_DEVICE;
49 drm_scatter_gather_t request;
50 drm_sg_mem_t *entry;
51 unsigned long pages;
52 int i;
53
54 DRM_DEBUG( "%s\n", __FUNCTION__ );
55
56 if ( dev->sg )
57 return EINVAL;
58
59 DRM_COPY_FROM_USER_IOCTL(request, (drm_scatter_gather_t *)data,
60 sizeof(request) );
61
62 entry = malloc(sizeof(*entry), M_DRM, M_WAITOK | M_ZERO);
63 if ( !entry )
64 return ENOMEM;
65
66 pages = round_page(request.size) / PAGE_SIZE;
67 DRM_DEBUG( "sg size=%ld pages=%ld\n", request.size, pages );
68
69 entry->pages = pages;
70
71 entry->busaddr = malloc(pages * sizeof(*entry->busaddr), M_DRM,
72 M_WAITOK | M_ZERO);
73 if ( !entry->busaddr ) {
74 drm_sg_cleanup(entry);
75 return ENOMEM;
76 }
77
78 entry->handle = (long)malloc(pages << PAGE_SHIFT, M_DRM,
79 M_WAITOK | M_ZERO);
80 if (entry->handle == 0) {
81 drm_sg_cleanup(entry);
82 return ENOMEM;
83 }
84
85 for (i = 0; i < pages; i++) {
86 entry->busaddr[i] = vtophys(entry->handle + i * PAGE_SIZE);
87 }
88
89 DRM_DEBUG( "sg alloc handle = %08lx\n", entry->handle );
90
91 entry->virtual = (void *)entry->handle;
92 request.handle = entry->handle;
93
94 DRM_COPY_TO_USER_IOCTL( (drm_scatter_gather_t *)data,
95 request,
96 sizeof(request) );
97
98 DRM_LOCK();
99 if (dev->sg) {
100 DRM_UNLOCK();
101 drm_sg_cleanup(entry);
102 return EINVAL;
103 }
104 dev->sg = entry;
105 DRM_UNLOCK();
106
107 return 0;
108 }
109
110 int drm_sg_free(DRM_IOCTL_ARGS)
111 {
112 DRM_DEVICE;
113 drm_scatter_gather_t request;
114 drm_sg_mem_t *entry;
115
116 DRM_COPY_FROM_USER_IOCTL( request, (drm_scatter_gather_t *)data,
117 sizeof(request) );
118
119 DRM_LOCK();
120 entry = dev->sg;
121 dev->sg = NULL;
122 DRM_UNLOCK();
123
124 if ( !entry || entry->handle != request.handle )
125 return EINVAL;
126
127 DRM_DEBUG( "sg free virtual = 0x%lx\n", entry->handle );
128
129 drm_sg_cleanup(entry);
130
131 return 0;
132 }
Cache object: 1d37192f33fd6e730f8a0365e3285453
|