Merge from vendor branch GCC:
[dragonfly.git] / sys / dev / drm / drm_scatter.h
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  *
29  * $FreeBSD: src/sys/dev/drm/drm_scatter.h,v 1.4.2.1 2003/04/26 07:05:28 anholt Exp $
30  * $DragonFly: src/sys/dev/drm/Attic/drm_scatter.h,v 1.3 2005/02/17 13:59:35 joerg Exp $
31  */
32
33 #include "dev/drm/drmP.h"
34
35 #define DEBUG_SCATTER 0
36
37 #if __REALLY_HAVE_SG
38
39 void DRM(sg_cleanup)( drm_sg_mem_t *entry )
40 {
41         free( entry->virtual, DRM(M_DRM) );
42
43         DRM(free)( entry->busaddr,
44                    entry->pages * sizeof(*entry->busaddr),
45                    DRM_MEM_PAGES );
46         DRM(free)( entry,
47                    sizeof(*entry),
48                    DRM_MEM_SGLISTS );
49 }
50
51 int DRM(sg_alloc)( DRM_IOCTL_ARGS )
52 {
53         DRM_DEVICE;
54         drm_scatter_gather_t request;
55         drm_sg_mem_t *entry;
56         unsigned long pages;
57
58         DRM_DEBUG( "%s\n", __func__ );
59
60         if ( dev->sg )
61                 return EINVAL;
62
63         DRM_COPY_FROM_USER_IOCTL(request, (drm_scatter_gather_t *)data,
64                              sizeof(request) );
65
66         entry = DRM(alloc)( sizeof(*entry), DRM_MEM_SGLISTS );
67         if ( !entry )
68                 return ENOMEM;
69
70         bzero( entry, sizeof(*entry) );
71
72         pages = round_page(request.size) / PAGE_SIZE;
73         DRM_DEBUG( "sg size=%ld pages=%ld\n", request.size, pages );
74
75         entry->pages = pages;
76
77         entry->busaddr = DRM(alloc)( pages * sizeof(*entry->busaddr),
78                                      DRM_MEM_PAGES );
79         if ( !entry->busaddr ) {
80                 DRM(free)( entry,
81                            sizeof(*entry),
82                            DRM_MEM_SGLISTS );
83                 return ENOMEM;
84         }
85         bzero( (void *)entry->busaddr, pages * sizeof(*entry->busaddr) );
86
87         entry->virtual = malloc( pages << PAGE_SHIFT, DRM(M_DRM), M_WAITOK );
88         if ( !entry->virtual ) {
89                 DRM(free)( entry->busaddr,
90                            entry->pages * sizeof(*entry->busaddr),
91                            DRM_MEM_PAGES );
92                 DRM(free)( entry,
93                            sizeof(*entry),
94                            DRM_MEM_SGLISTS );
95                 return ENOMEM;
96         }
97
98         bzero( entry->virtual, pages << PAGE_SHIFT );
99
100         entry->handle = (unsigned long)entry->virtual;
101
102         DRM_DEBUG( "sg alloc handle  = %08lx\n", entry->handle );
103         DRM_DEBUG( "sg alloc virtual = %p\n", entry->virtual );
104
105         request.handle = entry->handle;
106
107         DRM_COPY_TO_USER_IOCTL( (drm_scatter_gather_t *)data,
108                            request,
109                            sizeof(request) );
110
111         dev->sg = entry;
112
113         return 0;
114
115         DRM(sg_cleanup)( entry );
116         return ENOMEM;
117 }
118
119 int DRM(sg_free)( DRM_IOCTL_ARGS )
120 {
121         DRM_DEVICE;
122         drm_scatter_gather_t request;
123         drm_sg_mem_t *entry;
124
125         DRM_COPY_FROM_USER_IOCTL( request, (drm_scatter_gather_t *)data,
126                              sizeof(request) );
127
128         entry = dev->sg;
129         dev->sg = NULL;
130
131         if ( !entry || entry->handle != request.handle )
132                 return EINVAL;
133
134         DRM_DEBUG( "sg free virtual  = %p\n", entry->virtual );
135
136         DRM(sg_cleanup)( entry );
137
138         return 0;
139 }
140
141 #else /* __REALLY_HAVE_SG */
142
143 int DRM(sg_alloc)( DRM_IOCTL_ARGS )
144 {
145         return DRM_ERR(EINVAL);
146 }
147 int DRM(sg_free)( DRM_IOCTL_ARGS )
148 {
149         return DRM_ERR(EINVAL);
150 }
151
152 #endif