OSDN Git Service

nouveau: fix annoying compiler warning
[android-x86/external-libdrm.git] / nouveau / nouveau_device.c
1 /*
2  * Copyright 2007 Nouveau Project
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19  * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20  * SOFTWARE.
21  */
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <errno.h>
26
27 #include "nouveau_private.h"
28
29 #if NOUVEAU_DRM_HEADER_PATCHLEVEL != 16
30 #error nouveau_drm.h does not match expected patchlevel, update libdrm.
31 #endif
32
33 int
34 nouveau_device_open_existing(struct nouveau_device **dev, int close,
35                              int fd, drm_context_t ctx)
36 {
37         struct nouveau_device_priv *nvdev;
38         drmVersionPtr ver;
39         uint64_t value;
40         int ret;
41
42         if (!dev || *dev)
43             return -EINVAL;
44
45         ver = drmGetVersion(fd);
46         if (!ver || ver->version_patchlevel != NOUVEAU_DRM_HEADER_PATCHLEVEL)
47                 return -EINVAL;
48         drmFreeVersion(ver);
49
50         nvdev = calloc(1, sizeof(*nvdev));
51         if (!nvdev)
52             return -ENOMEM;
53         nvdev->fd = fd;
54         nvdev->ctx = ctx;
55         nvdev->needs_close = close;
56
57         ret = nouveau_device_get_param(&nvdev->base,
58                                        NOUVEAU_GETPARAM_VM_VRAM_BASE, &value);
59         if (ret) {
60                 nouveau_device_close((void *)&nvdev);
61                 return ret;
62         }
63         nvdev->base.vm_vram_base = value;
64
65         ret = nouveau_device_get_param(&nvdev->base,
66                                        NOUVEAU_GETPARAM_FB_SIZE, &value);
67         if (ret) {
68                 nouveau_device_close((void *)&nvdev);
69                 return ret;
70         }
71         nvdev->base.vm_vram_size = value;
72
73         ret = nouveau_device_get_param(&nvdev->base,
74                                        NOUVEAU_GETPARAM_AGP_SIZE, &value);
75         if (ret) {
76                 nouveau_device_close((void *)&nvdev);
77                 return ret;
78         }
79         nvdev->base.vm_gart_size = value;
80
81         ret = nouveau_bo_init(&nvdev->base);
82         if (ret) {
83                 nouveau_device_close((void *)&nvdev);
84                 return ret;
85         }
86
87         ret = nouveau_device_get_param(&nvdev->base,
88                                        NOUVEAU_GETPARAM_CHIPSET_ID, &value);
89         if (ret) {
90                 nouveau_device_close((void *)&nvdev);
91                 return ret;
92         }
93         nvdev->base.chipset = value;
94
95         *dev = &nvdev->base;
96         return 0;
97 }
98
99 int
100 nouveau_device_open(struct nouveau_device **dev, const char *busid)
101 {
102         drm_context_t ctx;
103         int fd, ret;
104
105         if (!dev || *dev)
106                 return -EINVAL;
107
108         fd = drmOpen("nouveau", busid);
109         if (fd < 0)
110                 return -EINVAL;
111
112         ret = drmCreateContext(fd, &ctx);
113         if (ret) {
114                 drmClose(fd);
115                 return ret;
116         }
117
118         ret = nouveau_device_open_existing(dev, 1, fd, ctx);
119         if (ret) {
120             drmDestroyContext(fd, ctx);
121             drmClose(fd);
122             return ret;
123         }
124
125         return 0;
126 }
127
128 void
129 nouveau_device_close(struct nouveau_device **dev)
130 {
131         struct nouveau_device_priv *nvdev;
132
133         if (!dev || !*dev)
134                 return;
135         nvdev = nouveau_device(*dev);
136         *dev = NULL;
137
138         nouveau_bo_takedown(&nvdev->base);
139
140         if (nvdev->needs_close) {
141                 drmDestroyContext(nvdev->fd, nvdev->ctx);
142                 drmClose(nvdev->fd);
143         }
144         free(nvdev);
145 }
146
147 int
148 nouveau_device_get_param(struct nouveau_device *dev,
149                          uint64_t param, uint64_t *value)
150 {
151         struct nouveau_device_priv *nvdev = nouveau_device(dev);
152         struct drm_nouveau_getparam g;
153         int ret;
154
155         if (!nvdev || !value)
156                 return -EINVAL;
157
158         g.param = param;
159         ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_GETPARAM,
160                                   &g, sizeof(g));
161         if (ret)
162                 return ret;
163
164         *value = g.value;
165         return 0;
166 }
167
168 int
169 nouveau_device_set_param(struct nouveau_device *dev,
170                          uint64_t param, uint64_t value)
171 {
172         struct nouveau_device_priv *nvdev = nouveau_device(dev);
173         struct drm_nouveau_setparam s;
174         int ret;
175
176         if (!nvdev)
177                 return -EINVAL;
178
179         s.param = param;
180         s.value = value;
181         ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_SETPARAM,
182                                   &s, sizeof(s));
183         if (ret)
184                 return ret;
185
186         return 0;
187 }
188