1*7688df22SAndroid Build Coastguard Worker /**
2*7688df22SAndroid Build Coastguard Worker * \file xf86drm.c
3*7688df22SAndroid Build Coastguard Worker * User-level interface to DRM device
4*7688df22SAndroid Build Coastguard Worker *
5*7688df22SAndroid Build Coastguard Worker * \author Rickard E. (Rik) Faith <[email protected]>
6*7688df22SAndroid Build Coastguard Worker * \author Kevin E. Martin <[email protected]>
7*7688df22SAndroid Build Coastguard Worker */
8*7688df22SAndroid Build Coastguard Worker
9*7688df22SAndroid Build Coastguard Worker /*
10*7688df22SAndroid Build Coastguard Worker * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
11*7688df22SAndroid Build Coastguard Worker * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
12*7688df22SAndroid Build Coastguard Worker * All Rights Reserved.
13*7688df22SAndroid Build Coastguard Worker *
14*7688df22SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
15*7688df22SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
16*7688df22SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
17*7688df22SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense,
18*7688df22SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
19*7688df22SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions:
20*7688df22SAndroid Build Coastguard Worker *
21*7688df22SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the next
22*7688df22SAndroid Build Coastguard Worker * paragraph) shall be included in all copies or substantial portions of the
23*7688df22SAndroid Build Coastguard Worker * Software.
24*7688df22SAndroid Build Coastguard Worker *
25*7688df22SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26*7688df22SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27*7688df22SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
28*7688df22SAndroid Build Coastguard Worker * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
29*7688df22SAndroid Build Coastguard Worker * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
30*7688df22SAndroid Build Coastguard Worker * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
31*7688df22SAndroid Build Coastguard Worker * DEALINGS IN THE SOFTWARE.
32*7688df22SAndroid Build Coastguard Worker */
33*7688df22SAndroid Build Coastguard Worker
34*7688df22SAndroid Build Coastguard Worker #include <stdio.h>
35*7688df22SAndroid Build Coastguard Worker #include <stdlib.h>
36*7688df22SAndroid Build Coastguard Worker #include <stdbool.h>
37*7688df22SAndroid Build Coastguard Worker #include <unistd.h>
38*7688df22SAndroid Build Coastguard Worker #include <string.h>
39*7688df22SAndroid Build Coastguard Worker #include <strings.h>
40*7688df22SAndroid Build Coastguard Worker #include <ctype.h>
41*7688df22SAndroid Build Coastguard Worker #include <dirent.h>
42*7688df22SAndroid Build Coastguard Worker #include <stddef.h>
43*7688df22SAndroid Build Coastguard Worker #include <fcntl.h>
44*7688df22SAndroid Build Coastguard Worker #include <errno.h>
45*7688df22SAndroid Build Coastguard Worker #include <limits.h>
46*7688df22SAndroid Build Coastguard Worker #include <signal.h>
47*7688df22SAndroid Build Coastguard Worker #include <time.h>
48*7688df22SAndroid Build Coastguard Worker #include <sys/types.h>
49*7688df22SAndroid Build Coastguard Worker #include <sys/stat.h>
50*7688df22SAndroid Build Coastguard Worker #define stat_t struct stat
51*7688df22SAndroid Build Coastguard Worker #include <sys/ioctl.h>
52*7688df22SAndroid Build Coastguard Worker #include <sys/time.h>
53*7688df22SAndroid Build Coastguard Worker #include <stdarg.h>
54*7688df22SAndroid Build Coastguard Worker #ifdef MAJOR_IN_MKDEV
55*7688df22SAndroid Build Coastguard Worker #include <sys/mkdev.h>
56*7688df22SAndroid Build Coastguard Worker #endif
57*7688df22SAndroid Build Coastguard Worker #ifdef MAJOR_IN_SYSMACROS
58*7688df22SAndroid Build Coastguard Worker #include <sys/sysmacros.h>
59*7688df22SAndroid Build Coastguard Worker #endif
60*7688df22SAndroid Build Coastguard Worker #if HAVE_SYS_SYSCTL_H
61*7688df22SAndroid Build Coastguard Worker #include <sys/sysctl.h>
62*7688df22SAndroid Build Coastguard Worker #endif
63*7688df22SAndroid Build Coastguard Worker #include <inttypes.h>
64*7688df22SAndroid Build Coastguard Worker
65*7688df22SAndroid Build Coastguard Worker #if defined(__FreeBSD__)
66*7688df22SAndroid Build Coastguard Worker #include <sys/param.h>
67*7688df22SAndroid Build Coastguard Worker #include <sys/pciio.h>
68*7688df22SAndroid Build Coastguard Worker #endif
69*7688df22SAndroid Build Coastguard Worker
70*7688df22SAndroid Build Coastguard Worker #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
71*7688df22SAndroid Build Coastguard Worker
72*7688df22SAndroid Build Coastguard Worker /* Not all systems have MAP_FAILED defined */
73*7688df22SAndroid Build Coastguard Worker #ifndef MAP_FAILED
74*7688df22SAndroid Build Coastguard Worker #define MAP_FAILED ((void *)-1)
75*7688df22SAndroid Build Coastguard Worker #endif
76*7688df22SAndroid Build Coastguard Worker
77*7688df22SAndroid Build Coastguard Worker #include "xf86drm.h"
78*7688df22SAndroid Build Coastguard Worker #include "libdrm_macros.h"
79*7688df22SAndroid Build Coastguard Worker #include "drm_fourcc.h"
80*7688df22SAndroid Build Coastguard Worker
81*7688df22SAndroid Build Coastguard Worker #include "util_math.h"
82*7688df22SAndroid Build Coastguard Worker
83*7688df22SAndroid Build Coastguard Worker #ifdef __DragonFly__
84*7688df22SAndroid Build Coastguard Worker #define DRM_MAJOR 145
85*7688df22SAndroid Build Coastguard Worker #endif
86*7688df22SAndroid Build Coastguard Worker
87*7688df22SAndroid Build Coastguard Worker #ifdef __NetBSD__
88*7688df22SAndroid Build Coastguard Worker #define DRM_MAJOR 34
89*7688df22SAndroid Build Coastguard Worker #endif
90*7688df22SAndroid Build Coastguard Worker
91*7688df22SAndroid Build Coastguard Worker #ifdef __OpenBSD__
92*7688df22SAndroid Build Coastguard Worker #ifdef __i386__
93*7688df22SAndroid Build Coastguard Worker #define DRM_MAJOR 88
94*7688df22SAndroid Build Coastguard Worker #else
95*7688df22SAndroid Build Coastguard Worker #define DRM_MAJOR 87
96*7688df22SAndroid Build Coastguard Worker #endif
97*7688df22SAndroid Build Coastguard Worker #endif /* __OpenBSD__ */
98*7688df22SAndroid Build Coastguard Worker
99*7688df22SAndroid Build Coastguard Worker #ifndef DRM_MAJOR
100*7688df22SAndroid Build Coastguard Worker #define DRM_MAJOR 226 /* Linux */
101*7688df22SAndroid Build Coastguard Worker #endif
102*7688df22SAndroid Build Coastguard Worker
103*7688df22SAndroid Build Coastguard Worker #if defined(__OpenBSD__) || defined(__DragonFly__)
104*7688df22SAndroid Build Coastguard Worker struct drm_pciinfo {
105*7688df22SAndroid Build Coastguard Worker uint16_t domain;
106*7688df22SAndroid Build Coastguard Worker uint8_t bus;
107*7688df22SAndroid Build Coastguard Worker uint8_t dev;
108*7688df22SAndroid Build Coastguard Worker uint8_t func;
109*7688df22SAndroid Build Coastguard Worker uint16_t vendor_id;
110*7688df22SAndroid Build Coastguard Worker uint16_t device_id;
111*7688df22SAndroid Build Coastguard Worker uint16_t subvendor_id;
112*7688df22SAndroid Build Coastguard Worker uint16_t subdevice_id;
113*7688df22SAndroid Build Coastguard Worker uint8_t revision_id;
114*7688df22SAndroid Build Coastguard Worker };
115*7688df22SAndroid Build Coastguard Worker
116*7688df22SAndroid Build Coastguard Worker #define DRM_IOCTL_GET_PCIINFO DRM_IOR(0x15, struct drm_pciinfo)
117*7688df22SAndroid Build Coastguard Worker #endif
118*7688df22SAndroid Build Coastguard Worker
119*7688df22SAndroid Build Coastguard Worker #define DRM_MSG_VERBOSITY 3
120*7688df22SAndroid Build Coastguard Worker
121*7688df22SAndroid Build Coastguard Worker #define memclear(s) memset(&s, 0, sizeof(s))
122*7688df22SAndroid Build Coastguard Worker
123*7688df22SAndroid Build Coastguard Worker static drmServerInfoPtr drm_server_info;
124*7688df22SAndroid Build Coastguard Worker
125*7688df22SAndroid Build Coastguard Worker static bool drmNodeIsDRM(int maj, int min);
126*7688df22SAndroid Build Coastguard Worker static char *drmGetMinorNameForFD(int fd, int type);
127*7688df22SAndroid Build Coastguard Worker
128*7688df22SAndroid Build Coastguard Worker #define DRM_MODIFIER(v, f, f_name) \
129*7688df22SAndroid Build Coastguard Worker .modifier = DRM_FORMAT_MOD_##v ## _ ##f, \
130*7688df22SAndroid Build Coastguard Worker .modifier_name = #f_name
131*7688df22SAndroid Build Coastguard Worker
132*7688df22SAndroid Build Coastguard Worker #define DRM_MODIFIER_INVALID(v, f_name) \
133*7688df22SAndroid Build Coastguard Worker .modifier = DRM_FORMAT_MOD_INVALID, .modifier_name = #f_name
134*7688df22SAndroid Build Coastguard Worker
135*7688df22SAndroid Build Coastguard Worker #define DRM_MODIFIER_LINEAR(v, f_name) \
136*7688df22SAndroid Build Coastguard Worker .modifier = DRM_FORMAT_MOD_LINEAR, .modifier_name = #f_name
137*7688df22SAndroid Build Coastguard Worker
138*7688df22SAndroid Build Coastguard Worker /* Intel is abit special as the format doesn't follow other vendors naming
139*7688df22SAndroid Build Coastguard Worker * scheme */
140*7688df22SAndroid Build Coastguard Worker #define DRM_MODIFIER_INTEL(f, f_name) \
141*7688df22SAndroid Build Coastguard Worker .modifier = I915_FORMAT_MOD_##f, .modifier_name = #f_name
142*7688df22SAndroid Build Coastguard Worker
143*7688df22SAndroid Build Coastguard Worker struct drmFormatModifierInfo {
144*7688df22SAndroid Build Coastguard Worker uint64_t modifier;
145*7688df22SAndroid Build Coastguard Worker const char *modifier_name;
146*7688df22SAndroid Build Coastguard Worker };
147*7688df22SAndroid Build Coastguard Worker
148*7688df22SAndroid Build Coastguard Worker struct drmFormatModifierVendorInfo {
149*7688df22SAndroid Build Coastguard Worker uint8_t vendor;
150*7688df22SAndroid Build Coastguard Worker const char *vendor_name;
151*7688df22SAndroid Build Coastguard Worker };
152*7688df22SAndroid Build Coastguard Worker
153*7688df22SAndroid Build Coastguard Worker #include "generated_static_table_fourcc.h"
154*7688df22SAndroid Build Coastguard Worker
155*7688df22SAndroid Build Coastguard Worker struct drmVendorInfo {
156*7688df22SAndroid Build Coastguard Worker uint8_t vendor;
157*7688df22SAndroid Build Coastguard Worker char *(*vendor_cb)(uint64_t modifier);
158*7688df22SAndroid Build Coastguard Worker };
159*7688df22SAndroid Build Coastguard Worker
160*7688df22SAndroid Build Coastguard Worker struct drmFormatVendorModifierInfo {
161*7688df22SAndroid Build Coastguard Worker uint64_t modifier;
162*7688df22SAndroid Build Coastguard Worker const char *modifier_name;
163*7688df22SAndroid Build Coastguard Worker };
164*7688df22SAndroid Build Coastguard Worker
165*7688df22SAndroid Build Coastguard Worker static char *
166*7688df22SAndroid Build Coastguard Worker drmGetFormatModifierNameFromArm(uint64_t modifier);
167*7688df22SAndroid Build Coastguard Worker
168*7688df22SAndroid Build Coastguard Worker static char *
169*7688df22SAndroid Build Coastguard Worker drmGetFormatModifierNameFromNvidia(uint64_t modifier);
170*7688df22SAndroid Build Coastguard Worker
171*7688df22SAndroid Build Coastguard Worker static char *
172*7688df22SAndroid Build Coastguard Worker drmGetFormatModifierNameFromAmd(uint64_t modifier);
173*7688df22SAndroid Build Coastguard Worker
174*7688df22SAndroid Build Coastguard Worker static char *
175*7688df22SAndroid Build Coastguard Worker drmGetFormatModifierNameFromAmlogic(uint64_t modifier);
176*7688df22SAndroid Build Coastguard Worker
177*7688df22SAndroid Build Coastguard Worker static char *
178*7688df22SAndroid Build Coastguard Worker drmGetFormatModifierNameFromVivante(uint64_t modifier);
179*7688df22SAndroid Build Coastguard Worker
180*7688df22SAndroid Build Coastguard Worker static const struct drmVendorInfo modifier_format_vendor_table[] = {
181*7688df22SAndroid Build Coastguard Worker { DRM_FORMAT_MOD_VENDOR_ARM, drmGetFormatModifierNameFromArm },
182*7688df22SAndroid Build Coastguard Worker { DRM_FORMAT_MOD_VENDOR_NVIDIA, drmGetFormatModifierNameFromNvidia },
183*7688df22SAndroid Build Coastguard Worker { DRM_FORMAT_MOD_VENDOR_AMD, drmGetFormatModifierNameFromAmd },
184*7688df22SAndroid Build Coastguard Worker { DRM_FORMAT_MOD_VENDOR_AMLOGIC, drmGetFormatModifierNameFromAmlogic },
185*7688df22SAndroid Build Coastguard Worker { DRM_FORMAT_MOD_VENDOR_VIVANTE, drmGetFormatModifierNameFromVivante },
186*7688df22SAndroid Build Coastguard Worker };
187*7688df22SAndroid Build Coastguard Worker
188*7688df22SAndroid Build Coastguard Worker #ifndef AFBC_FORMAT_MOD_MODE_VALUE_MASK
189*7688df22SAndroid Build Coastguard Worker #define AFBC_FORMAT_MOD_MODE_VALUE_MASK 0x000fffffffffffffULL
190*7688df22SAndroid Build Coastguard Worker #endif
191*7688df22SAndroid Build Coastguard Worker
192*7688df22SAndroid Build Coastguard Worker static const struct drmFormatVendorModifierInfo arm_mode_value_table[] = {
193*7688df22SAndroid Build Coastguard Worker { AFBC_FORMAT_MOD_YTR, "YTR" },
194*7688df22SAndroid Build Coastguard Worker { AFBC_FORMAT_MOD_SPLIT, "SPLIT" },
195*7688df22SAndroid Build Coastguard Worker { AFBC_FORMAT_MOD_SPARSE, "SPARSE" },
196*7688df22SAndroid Build Coastguard Worker { AFBC_FORMAT_MOD_CBR, "CBR" },
197*7688df22SAndroid Build Coastguard Worker { AFBC_FORMAT_MOD_TILED, "TILED" },
198*7688df22SAndroid Build Coastguard Worker { AFBC_FORMAT_MOD_SC, "SC" },
199*7688df22SAndroid Build Coastguard Worker { AFBC_FORMAT_MOD_DB, "DB" },
200*7688df22SAndroid Build Coastguard Worker { AFBC_FORMAT_MOD_BCH, "BCH" },
201*7688df22SAndroid Build Coastguard Worker { AFBC_FORMAT_MOD_USM, "USM" },
202*7688df22SAndroid Build Coastguard Worker };
203*7688df22SAndroid Build Coastguard Worker
204*7688df22SAndroid Build Coastguard Worker static bool
drmGetAfbcFormatModifierNameFromArm(uint64_t modifier,FILE * fp)205*7688df22SAndroid Build Coastguard Worker drmGetAfbcFormatModifierNameFromArm(uint64_t modifier, FILE *fp)
206*7688df22SAndroid Build Coastguard Worker {
207*7688df22SAndroid Build Coastguard Worker uint64_t mode_value = modifier & AFBC_FORMAT_MOD_MODE_VALUE_MASK;
208*7688df22SAndroid Build Coastguard Worker uint64_t block_size = mode_value & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK;
209*7688df22SAndroid Build Coastguard Worker
210*7688df22SAndroid Build Coastguard Worker const char *block = NULL;
211*7688df22SAndroid Build Coastguard Worker const char *mode = NULL;
212*7688df22SAndroid Build Coastguard Worker bool did_print_mode = false;
213*7688df22SAndroid Build Coastguard Worker
214*7688df22SAndroid Build Coastguard Worker /* add block, can only have a (single) block */
215*7688df22SAndroid Build Coastguard Worker switch (block_size) {
216*7688df22SAndroid Build Coastguard Worker case AFBC_FORMAT_MOD_BLOCK_SIZE_16x16:
217*7688df22SAndroid Build Coastguard Worker block = "16x16";
218*7688df22SAndroid Build Coastguard Worker break;
219*7688df22SAndroid Build Coastguard Worker case AFBC_FORMAT_MOD_BLOCK_SIZE_32x8:
220*7688df22SAndroid Build Coastguard Worker block = "32x8";
221*7688df22SAndroid Build Coastguard Worker break;
222*7688df22SAndroid Build Coastguard Worker case AFBC_FORMAT_MOD_BLOCK_SIZE_64x4:
223*7688df22SAndroid Build Coastguard Worker block = "64x4";
224*7688df22SAndroid Build Coastguard Worker break;
225*7688df22SAndroid Build Coastguard Worker case AFBC_FORMAT_MOD_BLOCK_SIZE_32x8_64x4:
226*7688df22SAndroid Build Coastguard Worker block = "32x8_64x4";
227*7688df22SAndroid Build Coastguard Worker break;
228*7688df22SAndroid Build Coastguard Worker }
229*7688df22SAndroid Build Coastguard Worker
230*7688df22SAndroid Build Coastguard Worker if (!block) {
231*7688df22SAndroid Build Coastguard Worker return false;
232*7688df22SAndroid Build Coastguard Worker }
233*7688df22SAndroid Build Coastguard Worker
234*7688df22SAndroid Build Coastguard Worker fprintf(fp, "BLOCK_SIZE=%s,", block);
235*7688df22SAndroid Build Coastguard Worker
236*7688df22SAndroid Build Coastguard Worker /* add mode */
237*7688df22SAndroid Build Coastguard Worker for (unsigned int i = 0; i < ARRAY_SIZE(arm_mode_value_table); i++) {
238*7688df22SAndroid Build Coastguard Worker if (arm_mode_value_table[i].modifier & mode_value) {
239*7688df22SAndroid Build Coastguard Worker mode = arm_mode_value_table[i].modifier_name;
240*7688df22SAndroid Build Coastguard Worker if (!did_print_mode) {
241*7688df22SAndroid Build Coastguard Worker fprintf(fp, "MODE=%s", mode);
242*7688df22SAndroid Build Coastguard Worker did_print_mode = true;
243*7688df22SAndroid Build Coastguard Worker } else {
244*7688df22SAndroid Build Coastguard Worker fprintf(fp, "|%s", mode);
245*7688df22SAndroid Build Coastguard Worker }
246*7688df22SAndroid Build Coastguard Worker }
247*7688df22SAndroid Build Coastguard Worker }
248*7688df22SAndroid Build Coastguard Worker
249*7688df22SAndroid Build Coastguard Worker return true;
250*7688df22SAndroid Build Coastguard Worker }
251*7688df22SAndroid Build Coastguard Worker
252*7688df22SAndroid Build Coastguard Worker static bool
drmGetAfrcFormatModifierNameFromArm(uint64_t modifier,FILE * fp)253*7688df22SAndroid Build Coastguard Worker drmGetAfrcFormatModifierNameFromArm(uint64_t modifier, FILE *fp)
254*7688df22SAndroid Build Coastguard Worker {
255*7688df22SAndroid Build Coastguard Worker bool scan_layout;
256*7688df22SAndroid Build Coastguard Worker for (unsigned int i = 0; i < 2; ++i) {
257*7688df22SAndroid Build Coastguard Worker uint64_t coding_unit_block =
258*7688df22SAndroid Build Coastguard Worker (modifier >> (i * 4)) & AFRC_FORMAT_MOD_CU_SIZE_MASK;
259*7688df22SAndroid Build Coastguard Worker const char *coding_unit_size = NULL;
260*7688df22SAndroid Build Coastguard Worker
261*7688df22SAndroid Build Coastguard Worker switch (coding_unit_block) {
262*7688df22SAndroid Build Coastguard Worker case AFRC_FORMAT_MOD_CU_SIZE_16:
263*7688df22SAndroid Build Coastguard Worker coding_unit_size = "CU_16";
264*7688df22SAndroid Build Coastguard Worker break;
265*7688df22SAndroid Build Coastguard Worker case AFRC_FORMAT_MOD_CU_SIZE_24:
266*7688df22SAndroid Build Coastguard Worker coding_unit_size = "CU_24";
267*7688df22SAndroid Build Coastguard Worker break;
268*7688df22SAndroid Build Coastguard Worker case AFRC_FORMAT_MOD_CU_SIZE_32:
269*7688df22SAndroid Build Coastguard Worker coding_unit_size = "CU_32";
270*7688df22SAndroid Build Coastguard Worker break;
271*7688df22SAndroid Build Coastguard Worker }
272*7688df22SAndroid Build Coastguard Worker
273*7688df22SAndroid Build Coastguard Worker if (!coding_unit_size) {
274*7688df22SAndroid Build Coastguard Worker if (i == 0) {
275*7688df22SAndroid Build Coastguard Worker return false;
276*7688df22SAndroid Build Coastguard Worker }
277*7688df22SAndroid Build Coastguard Worker break;
278*7688df22SAndroid Build Coastguard Worker }
279*7688df22SAndroid Build Coastguard Worker
280*7688df22SAndroid Build Coastguard Worker if (i == 0) {
281*7688df22SAndroid Build Coastguard Worker fprintf(fp, "P0=%s,", coding_unit_size);
282*7688df22SAndroid Build Coastguard Worker } else {
283*7688df22SAndroid Build Coastguard Worker fprintf(fp, "P12=%s,", coding_unit_size);
284*7688df22SAndroid Build Coastguard Worker }
285*7688df22SAndroid Build Coastguard Worker }
286*7688df22SAndroid Build Coastguard Worker
287*7688df22SAndroid Build Coastguard Worker scan_layout =
288*7688df22SAndroid Build Coastguard Worker (modifier & AFRC_FORMAT_MOD_LAYOUT_SCAN) == AFRC_FORMAT_MOD_LAYOUT_SCAN;
289*7688df22SAndroid Build Coastguard Worker if (scan_layout) {
290*7688df22SAndroid Build Coastguard Worker fprintf(fp, "SCAN");
291*7688df22SAndroid Build Coastguard Worker } else {
292*7688df22SAndroid Build Coastguard Worker fprintf(fp, "ROT");
293*7688df22SAndroid Build Coastguard Worker }
294*7688df22SAndroid Build Coastguard Worker return true;
295*7688df22SAndroid Build Coastguard Worker }
296*7688df22SAndroid Build Coastguard Worker
297*7688df22SAndroid Build Coastguard Worker static char *
drmGetFormatModifierNameFromArm(uint64_t modifier)298*7688df22SAndroid Build Coastguard Worker drmGetFormatModifierNameFromArm(uint64_t modifier)
299*7688df22SAndroid Build Coastguard Worker {
300*7688df22SAndroid Build Coastguard Worker uint64_t type = (modifier >> 52) & 0xf;
301*7688df22SAndroid Build Coastguard Worker
302*7688df22SAndroid Build Coastguard Worker FILE *fp;
303*7688df22SAndroid Build Coastguard Worker size_t size = 0;
304*7688df22SAndroid Build Coastguard Worker char *modifier_name = NULL;
305*7688df22SAndroid Build Coastguard Worker bool result = false;
306*7688df22SAndroid Build Coastguard Worker
307*7688df22SAndroid Build Coastguard Worker fp = open_memstream(&modifier_name, &size);
308*7688df22SAndroid Build Coastguard Worker if (!fp)
309*7688df22SAndroid Build Coastguard Worker return NULL;
310*7688df22SAndroid Build Coastguard Worker
311*7688df22SAndroid Build Coastguard Worker switch (type) {
312*7688df22SAndroid Build Coastguard Worker case DRM_FORMAT_MOD_ARM_TYPE_AFBC:
313*7688df22SAndroid Build Coastguard Worker result = drmGetAfbcFormatModifierNameFromArm(modifier, fp);
314*7688df22SAndroid Build Coastguard Worker break;
315*7688df22SAndroid Build Coastguard Worker case DRM_FORMAT_MOD_ARM_TYPE_AFRC:
316*7688df22SAndroid Build Coastguard Worker result = drmGetAfrcFormatModifierNameFromArm(modifier, fp);
317*7688df22SAndroid Build Coastguard Worker break;
318*7688df22SAndroid Build Coastguard Worker /* misc type is already handled by the static table */
319*7688df22SAndroid Build Coastguard Worker case DRM_FORMAT_MOD_ARM_TYPE_MISC:
320*7688df22SAndroid Build Coastguard Worker default:
321*7688df22SAndroid Build Coastguard Worker result = false;
322*7688df22SAndroid Build Coastguard Worker break;
323*7688df22SAndroid Build Coastguard Worker }
324*7688df22SAndroid Build Coastguard Worker
325*7688df22SAndroid Build Coastguard Worker fclose(fp);
326*7688df22SAndroid Build Coastguard Worker if (!result) {
327*7688df22SAndroid Build Coastguard Worker free(modifier_name);
328*7688df22SAndroid Build Coastguard Worker return NULL;
329*7688df22SAndroid Build Coastguard Worker }
330*7688df22SAndroid Build Coastguard Worker
331*7688df22SAndroid Build Coastguard Worker return modifier_name;
332*7688df22SAndroid Build Coastguard Worker }
333*7688df22SAndroid Build Coastguard Worker
334*7688df22SAndroid Build Coastguard Worker static char *
drmGetFormatModifierNameFromNvidia(uint64_t modifier)335*7688df22SAndroid Build Coastguard Worker drmGetFormatModifierNameFromNvidia(uint64_t modifier)
336*7688df22SAndroid Build Coastguard Worker {
337*7688df22SAndroid Build Coastguard Worker uint64_t height, kind, gen, sector, compression;
338*7688df22SAndroid Build Coastguard Worker
339*7688df22SAndroid Build Coastguard Worker height = modifier & 0xf;
340*7688df22SAndroid Build Coastguard Worker kind = (modifier >> 12) & 0xff;
341*7688df22SAndroid Build Coastguard Worker
342*7688df22SAndroid Build Coastguard Worker gen = (modifier >> 20) & 0x3;
343*7688df22SAndroid Build Coastguard Worker sector = (modifier >> 22) & 0x1;
344*7688df22SAndroid Build Coastguard Worker compression = (modifier >> 23) & 0x7;
345*7688df22SAndroid Build Coastguard Worker
346*7688df22SAndroid Build Coastguard Worker /* just in case there could other simpler modifiers, not yet added, avoid
347*7688df22SAndroid Build Coastguard Worker * testing against TEGRA_TILE */
348*7688df22SAndroid Build Coastguard Worker if ((modifier & 0x10) == 0x10) {
349*7688df22SAndroid Build Coastguard Worker char *mod_nvidia;
350*7688df22SAndroid Build Coastguard Worker asprintf(&mod_nvidia, "BLOCK_LINEAR_2D,HEIGHT=%"PRIu64",KIND=%"PRIu64","
351*7688df22SAndroid Build Coastguard Worker "GEN=%"PRIu64",SECTOR=%"PRIu64",COMPRESSION=%"PRIu64"", height,
352*7688df22SAndroid Build Coastguard Worker kind, gen, sector, compression);
353*7688df22SAndroid Build Coastguard Worker return mod_nvidia;
354*7688df22SAndroid Build Coastguard Worker }
355*7688df22SAndroid Build Coastguard Worker
356*7688df22SAndroid Build Coastguard Worker return NULL;
357*7688df22SAndroid Build Coastguard Worker }
358*7688df22SAndroid Build Coastguard Worker
359*7688df22SAndroid Build Coastguard Worker static char *
drmGetFormatModifierNameFromAmd(uint64_t modifier)360*7688df22SAndroid Build Coastguard Worker drmGetFormatModifierNameFromAmd(uint64_t modifier)
361*7688df22SAndroid Build Coastguard Worker {
362*7688df22SAndroid Build Coastguard Worker static const char *gfx9_gfx11_tile_strings[32] = {
363*7688df22SAndroid Build Coastguard Worker "LINEAR",
364*7688df22SAndroid Build Coastguard Worker "256B_S",
365*7688df22SAndroid Build Coastguard Worker "256B_D",
366*7688df22SAndroid Build Coastguard Worker "256B_R",
367*7688df22SAndroid Build Coastguard Worker "4KB_Z",
368*7688df22SAndroid Build Coastguard Worker "4KB_S",
369*7688df22SAndroid Build Coastguard Worker "4KB_D",
370*7688df22SAndroid Build Coastguard Worker "4KB_R",
371*7688df22SAndroid Build Coastguard Worker "64KB_Z",
372*7688df22SAndroid Build Coastguard Worker "64KB_S",
373*7688df22SAndroid Build Coastguard Worker "64KB_D",
374*7688df22SAndroid Build Coastguard Worker "64KB_R",
375*7688df22SAndroid Build Coastguard Worker "INVALID12",
376*7688df22SAndroid Build Coastguard Worker "INVALID13",
377*7688df22SAndroid Build Coastguard Worker "INVALID14",
378*7688df22SAndroid Build Coastguard Worker "INVALID15",
379*7688df22SAndroid Build Coastguard Worker "64KB_Z_T",
380*7688df22SAndroid Build Coastguard Worker "64KB_S_T",
381*7688df22SAndroid Build Coastguard Worker "64KB_D_T",
382*7688df22SAndroid Build Coastguard Worker "64KB_R_T",
383*7688df22SAndroid Build Coastguard Worker "4KB_Z_X",
384*7688df22SAndroid Build Coastguard Worker "4KB_S_X",
385*7688df22SAndroid Build Coastguard Worker "4KB_D_X",
386*7688df22SAndroid Build Coastguard Worker "4KB_R_X",
387*7688df22SAndroid Build Coastguard Worker "64KB_Z_X",
388*7688df22SAndroid Build Coastguard Worker "64KB_S_X",
389*7688df22SAndroid Build Coastguard Worker "64KB_D_X",
390*7688df22SAndroid Build Coastguard Worker "64KB_R_X",
391*7688df22SAndroid Build Coastguard Worker "256KB_Z_X",
392*7688df22SAndroid Build Coastguard Worker "256KB_S_X",
393*7688df22SAndroid Build Coastguard Worker "256KB_D_X",
394*7688df22SAndroid Build Coastguard Worker "256KB_R_X",
395*7688df22SAndroid Build Coastguard Worker };
396*7688df22SAndroid Build Coastguard Worker static const char *gfx12_tile_strings[32] = {
397*7688df22SAndroid Build Coastguard Worker "LINEAR",
398*7688df22SAndroid Build Coastguard Worker "256B_2D",
399*7688df22SAndroid Build Coastguard Worker "4KB_2D",
400*7688df22SAndroid Build Coastguard Worker "64KB_2D",
401*7688df22SAndroid Build Coastguard Worker "256KB_2D",
402*7688df22SAndroid Build Coastguard Worker "4KB_3D",
403*7688df22SAndroid Build Coastguard Worker "64KB_3D",
404*7688df22SAndroid Build Coastguard Worker "256KB_3D",
405*7688df22SAndroid Build Coastguard Worker /* other values are unused */
406*7688df22SAndroid Build Coastguard Worker };
407*7688df22SAndroid Build Coastguard Worker uint64_t tile_version = AMD_FMT_MOD_GET(TILE_VERSION, modifier);
408*7688df22SAndroid Build Coastguard Worker FILE *fp;
409*7688df22SAndroid Build Coastguard Worker char *mod_amd = NULL;
410*7688df22SAndroid Build Coastguard Worker size_t size = 0;
411*7688df22SAndroid Build Coastguard Worker
412*7688df22SAndroid Build Coastguard Worker fp = open_memstream(&mod_amd, &size);
413*7688df22SAndroid Build Coastguard Worker if (!fp)
414*7688df22SAndroid Build Coastguard Worker return NULL;
415*7688df22SAndroid Build Coastguard Worker
416*7688df22SAndroid Build Coastguard Worker switch (tile_version) {
417*7688df22SAndroid Build Coastguard Worker case AMD_FMT_MOD_TILE_VER_GFX9:
418*7688df22SAndroid Build Coastguard Worker fprintf(fp, "GFX9");
419*7688df22SAndroid Build Coastguard Worker break;
420*7688df22SAndroid Build Coastguard Worker case AMD_FMT_MOD_TILE_VER_GFX10:
421*7688df22SAndroid Build Coastguard Worker fprintf(fp, "GFX10");
422*7688df22SAndroid Build Coastguard Worker break;
423*7688df22SAndroid Build Coastguard Worker case AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS:
424*7688df22SAndroid Build Coastguard Worker fprintf(fp, "GFX10_RBPLUS");
425*7688df22SAndroid Build Coastguard Worker break;
426*7688df22SAndroid Build Coastguard Worker case AMD_FMT_MOD_TILE_VER_GFX11:
427*7688df22SAndroid Build Coastguard Worker fprintf(fp, "GFX11");
428*7688df22SAndroid Build Coastguard Worker break;
429*7688df22SAndroid Build Coastguard Worker case AMD_FMT_MOD_TILE_VER_GFX12:
430*7688df22SAndroid Build Coastguard Worker fprintf(fp, "GFX12");
431*7688df22SAndroid Build Coastguard Worker break;
432*7688df22SAndroid Build Coastguard Worker default:
433*7688df22SAndroid Build Coastguard Worker fclose(fp);
434*7688df22SAndroid Build Coastguard Worker free(mod_amd);
435*7688df22SAndroid Build Coastguard Worker return NULL;
436*7688df22SAndroid Build Coastguard Worker }
437*7688df22SAndroid Build Coastguard Worker
438*7688df22SAndroid Build Coastguard Worker if (tile_version >= AMD_FMT_MOD_TILE_VER_GFX12) {
439*7688df22SAndroid Build Coastguard Worker unsigned tile = AMD_FMT_MOD_GET(TILE, modifier);
440*7688df22SAndroid Build Coastguard Worker
441*7688df22SAndroid Build Coastguard Worker fprintf(fp, ",%s", gfx12_tile_strings[tile]);
442*7688df22SAndroid Build Coastguard Worker
443*7688df22SAndroid Build Coastguard Worker if (AMD_FMT_MOD_GET(DCC, modifier)) {
444*7688df22SAndroid Build Coastguard Worker fprintf(fp, ",DCC,DCC_MAX_COMPRESSED_BLOCK=%uB",
445*7688df22SAndroid Build Coastguard Worker 64 << AMD_FMT_MOD_GET(DCC_MAX_COMPRESSED_BLOCK, modifier));
446*7688df22SAndroid Build Coastguard Worker
447*7688df22SAndroid Build Coastguard Worker /* Other DCC fields are unused by GFX12. */
448*7688df22SAndroid Build Coastguard Worker }
449*7688df22SAndroid Build Coastguard Worker } else {
450*7688df22SAndroid Build Coastguard Worker unsigned tile = AMD_FMT_MOD_GET(TILE, modifier);
451*7688df22SAndroid Build Coastguard Worker
452*7688df22SAndroid Build Coastguard Worker fprintf(fp, ",%s", gfx9_gfx11_tile_strings[tile]);
453*7688df22SAndroid Build Coastguard Worker
454*7688df22SAndroid Build Coastguard Worker /* All *_T and *_X modes are affected by chip-specific fields. */
455*7688df22SAndroid Build Coastguard Worker if (tile >= 16) {
456*7688df22SAndroid Build Coastguard Worker fprintf(fp, ",PIPE_XOR_BITS=%u",
457*7688df22SAndroid Build Coastguard Worker (unsigned)AMD_FMT_MOD_GET(PIPE_XOR_BITS, modifier));
458*7688df22SAndroid Build Coastguard Worker
459*7688df22SAndroid Build Coastguard Worker switch (tile_version) {
460*7688df22SAndroid Build Coastguard Worker case AMD_FMT_MOD_TILE_VER_GFX9:
461*7688df22SAndroid Build Coastguard Worker fprintf(fp, ",BANK_XOR_BITS=%u",
462*7688df22SAndroid Build Coastguard Worker (unsigned)AMD_FMT_MOD_GET(BANK_XOR_BITS, modifier));
463*7688df22SAndroid Build Coastguard Worker break;
464*7688df22SAndroid Build Coastguard Worker
465*7688df22SAndroid Build Coastguard Worker case AMD_FMT_MOD_TILE_VER_GFX10:
466*7688df22SAndroid Build Coastguard Worker /* Nothing else for GFX10. */
467*7688df22SAndroid Build Coastguard Worker break;
468*7688df22SAndroid Build Coastguard Worker
469*7688df22SAndroid Build Coastguard Worker case AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS:
470*7688df22SAndroid Build Coastguard Worker case AMD_FMT_MOD_TILE_VER_GFX11:
471*7688df22SAndroid Build Coastguard Worker /* This also determines the DCC layout, but DCC is only legal
472*7688df22SAndroid Build Coastguard Worker * with tile=27 and tile=31 (*_R_X modes).
473*7688df22SAndroid Build Coastguard Worker */
474*7688df22SAndroid Build Coastguard Worker fprintf(fp, ",PACKERS=%u",
475*7688df22SAndroid Build Coastguard Worker (unsigned)AMD_FMT_MOD_GET(PACKERS, modifier));
476*7688df22SAndroid Build Coastguard Worker break;
477*7688df22SAndroid Build Coastguard Worker }
478*7688df22SAndroid Build Coastguard Worker }
479*7688df22SAndroid Build Coastguard Worker
480*7688df22SAndroid Build Coastguard Worker if (AMD_FMT_MOD_GET(DCC, modifier)) {
481*7688df22SAndroid Build Coastguard Worker if (tile_version == AMD_FMT_MOD_TILE_VER_GFX9 &&
482*7688df22SAndroid Build Coastguard Worker (AMD_FMT_MOD_GET(DCC_PIPE_ALIGN, modifier) ||
483*7688df22SAndroid Build Coastguard Worker AMD_FMT_MOD_GET(DCC_RETILE, modifier))) {
484*7688df22SAndroid Build Coastguard Worker /* These two only determine the layout of
485*7688df22SAndroid Build Coastguard Worker * the non-displayable DCC plane.
486*7688df22SAndroid Build Coastguard Worker */
487*7688df22SAndroid Build Coastguard Worker fprintf(fp, ",RB=%u",
488*7688df22SAndroid Build Coastguard Worker (unsigned)AMD_FMT_MOD_GET(RB, modifier));
489*7688df22SAndroid Build Coastguard Worker fprintf(fp, ",PIPE=%u",
490*7688df22SAndroid Build Coastguard Worker (unsigned)AMD_FMT_MOD_GET(PIPE, modifier));
491*7688df22SAndroid Build Coastguard Worker }
492*7688df22SAndroid Build Coastguard Worker
493*7688df22SAndroid Build Coastguard Worker fprintf(fp, ",DCC,DCC_MAX_COMPRESSED_BLOCK=%uB",
494*7688df22SAndroid Build Coastguard Worker 64 << AMD_FMT_MOD_GET(DCC_MAX_COMPRESSED_BLOCK, modifier));
495*7688df22SAndroid Build Coastguard Worker
496*7688df22SAndroid Build Coastguard Worker if (AMD_FMT_MOD_GET(DCC_INDEPENDENT_64B, modifier))
497*7688df22SAndroid Build Coastguard Worker fprintf(fp, ",DCC_INDEPENDENT_64B");
498*7688df22SAndroid Build Coastguard Worker
499*7688df22SAndroid Build Coastguard Worker if (AMD_FMT_MOD_GET(DCC_INDEPENDENT_128B, modifier))
500*7688df22SAndroid Build Coastguard Worker fprintf(fp, ",DCC_INDEPENDENT_128B");
501*7688df22SAndroid Build Coastguard Worker
502*7688df22SAndroid Build Coastguard Worker if (AMD_FMT_MOD_GET(DCC_CONSTANT_ENCODE, modifier))
503*7688df22SAndroid Build Coastguard Worker fprintf(fp, ",DCC_CONSTANT_ENCODE");
504*7688df22SAndroid Build Coastguard Worker
505*7688df22SAndroid Build Coastguard Worker if (AMD_FMT_MOD_GET(DCC_PIPE_ALIGN, modifier))
506*7688df22SAndroid Build Coastguard Worker fprintf(fp, ",DCC_PIPE_ALIGN");
507*7688df22SAndroid Build Coastguard Worker
508*7688df22SAndroid Build Coastguard Worker if (AMD_FMT_MOD_GET(DCC_RETILE, modifier))
509*7688df22SAndroid Build Coastguard Worker fprintf(fp, ",DCC_RETILE");
510*7688df22SAndroid Build Coastguard Worker }
511*7688df22SAndroid Build Coastguard Worker }
512*7688df22SAndroid Build Coastguard Worker
513*7688df22SAndroid Build Coastguard Worker fclose(fp);
514*7688df22SAndroid Build Coastguard Worker return mod_amd;
515*7688df22SAndroid Build Coastguard Worker }
516*7688df22SAndroid Build Coastguard Worker
517*7688df22SAndroid Build Coastguard Worker static char *
drmGetFormatModifierNameFromAmlogic(uint64_t modifier)518*7688df22SAndroid Build Coastguard Worker drmGetFormatModifierNameFromAmlogic(uint64_t modifier)
519*7688df22SAndroid Build Coastguard Worker {
520*7688df22SAndroid Build Coastguard Worker uint64_t layout = modifier & 0xff;
521*7688df22SAndroid Build Coastguard Worker uint64_t options = (modifier >> 8) & 0xff;
522*7688df22SAndroid Build Coastguard Worker char *mod_amlogic = NULL;
523*7688df22SAndroid Build Coastguard Worker
524*7688df22SAndroid Build Coastguard Worker const char *layout_str;
525*7688df22SAndroid Build Coastguard Worker const char *opts_str;
526*7688df22SAndroid Build Coastguard Worker
527*7688df22SAndroid Build Coastguard Worker switch (layout) {
528*7688df22SAndroid Build Coastguard Worker case AMLOGIC_FBC_LAYOUT_BASIC:
529*7688df22SAndroid Build Coastguard Worker layout_str = "BASIC";
530*7688df22SAndroid Build Coastguard Worker break;
531*7688df22SAndroid Build Coastguard Worker case AMLOGIC_FBC_LAYOUT_SCATTER:
532*7688df22SAndroid Build Coastguard Worker layout_str = "SCATTER";
533*7688df22SAndroid Build Coastguard Worker break;
534*7688df22SAndroid Build Coastguard Worker default:
535*7688df22SAndroid Build Coastguard Worker layout_str = "INVALID_LAYOUT";
536*7688df22SAndroid Build Coastguard Worker break;
537*7688df22SAndroid Build Coastguard Worker }
538*7688df22SAndroid Build Coastguard Worker
539*7688df22SAndroid Build Coastguard Worker if (options & AMLOGIC_FBC_OPTION_MEM_SAVING)
540*7688df22SAndroid Build Coastguard Worker opts_str = "MEM_SAVING";
541*7688df22SAndroid Build Coastguard Worker else
542*7688df22SAndroid Build Coastguard Worker opts_str = "0";
543*7688df22SAndroid Build Coastguard Worker
544*7688df22SAndroid Build Coastguard Worker asprintf(&mod_amlogic, "FBC,LAYOUT=%s,OPTIONS=%s", layout_str, opts_str);
545*7688df22SAndroid Build Coastguard Worker return mod_amlogic;
546*7688df22SAndroid Build Coastguard Worker }
547*7688df22SAndroid Build Coastguard Worker
548*7688df22SAndroid Build Coastguard Worker static char *
drmGetFormatModifierNameFromVivante(uint64_t modifier)549*7688df22SAndroid Build Coastguard Worker drmGetFormatModifierNameFromVivante(uint64_t modifier)
550*7688df22SAndroid Build Coastguard Worker {
551*7688df22SAndroid Build Coastguard Worker const char *color_tiling, *tile_status, *compression;
552*7688df22SAndroid Build Coastguard Worker char *mod_vivante = NULL;
553*7688df22SAndroid Build Coastguard Worker
554*7688df22SAndroid Build Coastguard Worker switch (modifier & VIVANTE_MOD_TS_MASK) {
555*7688df22SAndroid Build Coastguard Worker case 0:
556*7688df22SAndroid Build Coastguard Worker tile_status = "";
557*7688df22SAndroid Build Coastguard Worker break;
558*7688df22SAndroid Build Coastguard Worker case VIVANTE_MOD_TS_64_4:
559*7688df22SAndroid Build Coastguard Worker tile_status = ",TS=64B_4";
560*7688df22SAndroid Build Coastguard Worker break;
561*7688df22SAndroid Build Coastguard Worker case VIVANTE_MOD_TS_64_2:
562*7688df22SAndroid Build Coastguard Worker tile_status = ",TS=64B_2";
563*7688df22SAndroid Build Coastguard Worker break;
564*7688df22SAndroid Build Coastguard Worker case VIVANTE_MOD_TS_128_4:
565*7688df22SAndroid Build Coastguard Worker tile_status = ",TS=128B_4";
566*7688df22SAndroid Build Coastguard Worker break;
567*7688df22SAndroid Build Coastguard Worker case VIVANTE_MOD_TS_256_4:
568*7688df22SAndroid Build Coastguard Worker tile_status = ",TS=256B_4";
569*7688df22SAndroid Build Coastguard Worker break;
570*7688df22SAndroid Build Coastguard Worker default:
571*7688df22SAndroid Build Coastguard Worker tile_status = ",TS=UNKNOWN";
572*7688df22SAndroid Build Coastguard Worker break;
573*7688df22SAndroid Build Coastguard Worker }
574*7688df22SAndroid Build Coastguard Worker
575*7688df22SAndroid Build Coastguard Worker switch (modifier & VIVANTE_MOD_COMP_MASK) {
576*7688df22SAndroid Build Coastguard Worker case 0:
577*7688df22SAndroid Build Coastguard Worker compression = "";
578*7688df22SAndroid Build Coastguard Worker break;
579*7688df22SAndroid Build Coastguard Worker case VIVANTE_MOD_COMP_DEC400:
580*7688df22SAndroid Build Coastguard Worker compression = ",COMP=DEC400";
581*7688df22SAndroid Build Coastguard Worker break;
582*7688df22SAndroid Build Coastguard Worker default:
583*7688df22SAndroid Build Coastguard Worker compression = ",COMP=UNKNOWN";
584*7688df22SAndroid Build Coastguard Worker break;
585*7688df22SAndroid Build Coastguard Worker }
586*7688df22SAndroid Build Coastguard Worker
587*7688df22SAndroid Build Coastguard Worker switch (modifier & ~VIVANTE_MOD_EXT_MASK) {
588*7688df22SAndroid Build Coastguard Worker case 0:
589*7688df22SAndroid Build Coastguard Worker color_tiling = "LINEAR";
590*7688df22SAndroid Build Coastguard Worker break;
591*7688df22SAndroid Build Coastguard Worker case DRM_FORMAT_MOD_VIVANTE_TILED:
592*7688df22SAndroid Build Coastguard Worker color_tiling = "TILED";
593*7688df22SAndroid Build Coastguard Worker break;
594*7688df22SAndroid Build Coastguard Worker case DRM_FORMAT_MOD_VIVANTE_SUPER_TILED:
595*7688df22SAndroid Build Coastguard Worker color_tiling = "SUPER_TILED";
596*7688df22SAndroid Build Coastguard Worker break;
597*7688df22SAndroid Build Coastguard Worker case DRM_FORMAT_MOD_VIVANTE_SPLIT_TILED:
598*7688df22SAndroid Build Coastguard Worker color_tiling = "SPLIT_TILED";
599*7688df22SAndroid Build Coastguard Worker break;
600*7688df22SAndroid Build Coastguard Worker case DRM_FORMAT_MOD_VIVANTE_SPLIT_SUPER_TILED:
601*7688df22SAndroid Build Coastguard Worker color_tiling = "SPLIT_SUPER_TILED";
602*7688df22SAndroid Build Coastguard Worker break;
603*7688df22SAndroid Build Coastguard Worker default:
604*7688df22SAndroid Build Coastguard Worker color_tiling = "UNKNOWN";
605*7688df22SAndroid Build Coastguard Worker break;
606*7688df22SAndroid Build Coastguard Worker }
607*7688df22SAndroid Build Coastguard Worker
608*7688df22SAndroid Build Coastguard Worker asprintf(&mod_vivante, "%s%s%s", color_tiling, tile_status, compression);
609*7688df22SAndroid Build Coastguard Worker return mod_vivante;
610*7688df22SAndroid Build Coastguard Worker }
611*7688df22SAndroid Build Coastguard Worker
log2_int(unsigned x)612*7688df22SAndroid Build Coastguard Worker static unsigned log2_int(unsigned x)
613*7688df22SAndroid Build Coastguard Worker {
614*7688df22SAndroid Build Coastguard Worker unsigned l;
615*7688df22SAndroid Build Coastguard Worker
616*7688df22SAndroid Build Coastguard Worker if (x < 2) {
617*7688df22SAndroid Build Coastguard Worker return 0;
618*7688df22SAndroid Build Coastguard Worker }
619*7688df22SAndroid Build Coastguard Worker for (l = 2; ; l++) {
620*7688df22SAndroid Build Coastguard Worker if ((unsigned)(1 << l) > x) {
621*7688df22SAndroid Build Coastguard Worker return l - 1;
622*7688df22SAndroid Build Coastguard Worker }
623*7688df22SAndroid Build Coastguard Worker }
624*7688df22SAndroid Build Coastguard Worker return 0;
625*7688df22SAndroid Build Coastguard Worker }
626*7688df22SAndroid Build Coastguard Worker
627*7688df22SAndroid Build Coastguard Worker
drmSetServerInfo(drmServerInfoPtr info)628*7688df22SAndroid Build Coastguard Worker drm_public void drmSetServerInfo(drmServerInfoPtr info)
629*7688df22SAndroid Build Coastguard Worker {
630*7688df22SAndroid Build Coastguard Worker drm_server_info = info;
631*7688df22SAndroid Build Coastguard Worker }
632*7688df22SAndroid Build Coastguard Worker
633*7688df22SAndroid Build Coastguard Worker /**
634*7688df22SAndroid Build Coastguard Worker * Output a message to stderr.
635*7688df22SAndroid Build Coastguard Worker *
636*7688df22SAndroid Build Coastguard Worker * \param format printf() like format string.
637*7688df22SAndroid Build Coastguard Worker *
638*7688df22SAndroid Build Coastguard Worker * \internal
639*7688df22SAndroid Build Coastguard Worker * This function is a wrapper around vfprintf().
640*7688df22SAndroid Build Coastguard Worker */
641*7688df22SAndroid Build Coastguard Worker
642*7688df22SAndroid Build Coastguard Worker static int DRM_PRINTFLIKE(1, 0)
drmDebugPrint(const char * format,va_list ap)643*7688df22SAndroid Build Coastguard Worker drmDebugPrint(const char *format, va_list ap)
644*7688df22SAndroid Build Coastguard Worker {
645*7688df22SAndroid Build Coastguard Worker return vfprintf(stderr, format, ap);
646*7688df22SAndroid Build Coastguard Worker }
647*7688df22SAndroid Build Coastguard Worker
648*7688df22SAndroid Build Coastguard Worker drm_public void
drmMsg(const char * format,...)649*7688df22SAndroid Build Coastguard Worker drmMsg(const char *format, ...)
650*7688df22SAndroid Build Coastguard Worker {
651*7688df22SAndroid Build Coastguard Worker va_list ap;
652*7688df22SAndroid Build Coastguard Worker const char *env;
653*7688df22SAndroid Build Coastguard Worker if (((env = getenv("LIBGL_DEBUG")) && strstr(env, "verbose")) ||
654*7688df22SAndroid Build Coastguard Worker (drm_server_info && drm_server_info->debug_print))
655*7688df22SAndroid Build Coastguard Worker {
656*7688df22SAndroid Build Coastguard Worker va_start(ap, format);
657*7688df22SAndroid Build Coastguard Worker if (drm_server_info) {
658*7688df22SAndroid Build Coastguard Worker drm_server_info->debug_print(format,ap);
659*7688df22SAndroid Build Coastguard Worker } else {
660*7688df22SAndroid Build Coastguard Worker drmDebugPrint(format, ap);
661*7688df22SAndroid Build Coastguard Worker }
662*7688df22SAndroid Build Coastguard Worker va_end(ap);
663*7688df22SAndroid Build Coastguard Worker }
664*7688df22SAndroid Build Coastguard Worker }
665*7688df22SAndroid Build Coastguard Worker
666*7688df22SAndroid Build Coastguard Worker static void *drmHashTable = NULL; /* Context switch callbacks */
667*7688df22SAndroid Build Coastguard Worker
drmGetHashTable(void)668*7688df22SAndroid Build Coastguard Worker drm_public void *drmGetHashTable(void)
669*7688df22SAndroid Build Coastguard Worker {
670*7688df22SAndroid Build Coastguard Worker return drmHashTable;
671*7688df22SAndroid Build Coastguard Worker }
672*7688df22SAndroid Build Coastguard Worker
drmMalloc(int size)673*7688df22SAndroid Build Coastguard Worker drm_public void *drmMalloc(int size)
674*7688df22SAndroid Build Coastguard Worker {
675*7688df22SAndroid Build Coastguard Worker return calloc(1, size);
676*7688df22SAndroid Build Coastguard Worker }
677*7688df22SAndroid Build Coastguard Worker
drmFree(void * pt)678*7688df22SAndroid Build Coastguard Worker drm_public void drmFree(void *pt)
679*7688df22SAndroid Build Coastguard Worker {
680*7688df22SAndroid Build Coastguard Worker free(pt);
681*7688df22SAndroid Build Coastguard Worker }
682*7688df22SAndroid Build Coastguard Worker
683*7688df22SAndroid Build Coastguard Worker /**
684*7688df22SAndroid Build Coastguard Worker * Call ioctl, restarting if it is interrupted
685*7688df22SAndroid Build Coastguard Worker */
686*7688df22SAndroid Build Coastguard Worker drm_public int
drmIoctl(int fd,unsigned long request,void * arg)687*7688df22SAndroid Build Coastguard Worker drmIoctl(int fd, unsigned long request, void *arg)
688*7688df22SAndroid Build Coastguard Worker {
689*7688df22SAndroid Build Coastguard Worker int ret;
690*7688df22SAndroid Build Coastguard Worker
691*7688df22SAndroid Build Coastguard Worker do {
692*7688df22SAndroid Build Coastguard Worker ret = ioctl(fd, request, arg);
693*7688df22SAndroid Build Coastguard Worker } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
694*7688df22SAndroid Build Coastguard Worker return ret;
695*7688df22SAndroid Build Coastguard Worker }
696*7688df22SAndroid Build Coastguard Worker
drmGetKeyFromFd(int fd)697*7688df22SAndroid Build Coastguard Worker static unsigned long drmGetKeyFromFd(int fd)
698*7688df22SAndroid Build Coastguard Worker {
699*7688df22SAndroid Build Coastguard Worker stat_t st;
700*7688df22SAndroid Build Coastguard Worker
701*7688df22SAndroid Build Coastguard Worker st.st_rdev = 0;
702*7688df22SAndroid Build Coastguard Worker fstat(fd, &st);
703*7688df22SAndroid Build Coastguard Worker return st.st_rdev;
704*7688df22SAndroid Build Coastguard Worker }
705*7688df22SAndroid Build Coastguard Worker
drmGetEntry(int fd)706*7688df22SAndroid Build Coastguard Worker drm_public drmHashEntry *drmGetEntry(int fd)
707*7688df22SAndroid Build Coastguard Worker {
708*7688df22SAndroid Build Coastguard Worker unsigned long key = drmGetKeyFromFd(fd);
709*7688df22SAndroid Build Coastguard Worker void *value;
710*7688df22SAndroid Build Coastguard Worker drmHashEntry *entry;
711*7688df22SAndroid Build Coastguard Worker
712*7688df22SAndroid Build Coastguard Worker if (!drmHashTable)
713*7688df22SAndroid Build Coastguard Worker drmHashTable = drmHashCreate();
714*7688df22SAndroid Build Coastguard Worker
715*7688df22SAndroid Build Coastguard Worker if (drmHashLookup(drmHashTable, key, &value)) {
716*7688df22SAndroid Build Coastguard Worker entry = drmMalloc(sizeof(*entry));
717*7688df22SAndroid Build Coastguard Worker entry->fd = fd;
718*7688df22SAndroid Build Coastguard Worker entry->f = NULL;
719*7688df22SAndroid Build Coastguard Worker entry->tagTable = drmHashCreate();
720*7688df22SAndroid Build Coastguard Worker drmHashInsert(drmHashTable, key, entry);
721*7688df22SAndroid Build Coastguard Worker } else {
722*7688df22SAndroid Build Coastguard Worker entry = value;
723*7688df22SAndroid Build Coastguard Worker }
724*7688df22SAndroid Build Coastguard Worker return entry;
725*7688df22SAndroid Build Coastguard Worker }
726*7688df22SAndroid Build Coastguard Worker
727*7688df22SAndroid Build Coastguard Worker /**
728*7688df22SAndroid Build Coastguard Worker * Compare two busid strings
729*7688df22SAndroid Build Coastguard Worker *
730*7688df22SAndroid Build Coastguard Worker * \param first
731*7688df22SAndroid Build Coastguard Worker * \param second
732*7688df22SAndroid Build Coastguard Worker *
733*7688df22SAndroid Build Coastguard Worker * \return 1 if matched.
734*7688df22SAndroid Build Coastguard Worker *
735*7688df22SAndroid Build Coastguard Worker * \internal
736*7688df22SAndroid Build Coastguard Worker * This function compares two bus ID strings. It understands the older
737*7688df22SAndroid Build Coastguard Worker * PCI:b:d:f format and the newer pci:oooo:bb:dd.f format. In the format, o is
738*7688df22SAndroid Build Coastguard Worker * domain, b is bus, d is device, f is function.
739*7688df22SAndroid Build Coastguard Worker */
drmMatchBusID(const char * id1,const char * id2,int pci_domain_ok)740*7688df22SAndroid Build Coastguard Worker static int drmMatchBusID(const char *id1, const char *id2, int pci_domain_ok)
741*7688df22SAndroid Build Coastguard Worker {
742*7688df22SAndroid Build Coastguard Worker /* First, check if the IDs are exactly the same */
743*7688df22SAndroid Build Coastguard Worker if (strcasecmp(id1, id2) == 0)
744*7688df22SAndroid Build Coastguard Worker return 1;
745*7688df22SAndroid Build Coastguard Worker
746*7688df22SAndroid Build Coastguard Worker /* Try to match old/new-style PCI bus IDs. */
747*7688df22SAndroid Build Coastguard Worker if (strncasecmp(id1, "pci", 3) == 0) {
748*7688df22SAndroid Build Coastguard Worker unsigned int o1, b1, d1, f1;
749*7688df22SAndroid Build Coastguard Worker unsigned int o2, b2, d2, f2;
750*7688df22SAndroid Build Coastguard Worker int ret;
751*7688df22SAndroid Build Coastguard Worker
752*7688df22SAndroid Build Coastguard Worker ret = sscanf(id1, "pci:%04x:%02x:%02x.%u", &o1, &b1, &d1, &f1);
753*7688df22SAndroid Build Coastguard Worker if (ret != 4) {
754*7688df22SAndroid Build Coastguard Worker o1 = 0;
755*7688df22SAndroid Build Coastguard Worker ret = sscanf(id1, "PCI:%u:%u:%u", &b1, &d1, &f1);
756*7688df22SAndroid Build Coastguard Worker if (ret != 3)
757*7688df22SAndroid Build Coastguard Worker return 0;
758*7688df22SAndroid Build Coastguard Worker }
759*7688df22SAndroid Build Coastguard Worker
760*7688df22SAndroid Build Coastguard Worker ret = sscanf(id2, "pci:%04x:%02x:%02x.%u", &o2, &b2, &d2, &f2);
761*7688df22SAndroid Build Coastguard Worker if (ret != 4) {
762*7688df22SAndroid Build Coastguard Worker o2 = 0;
763*7688df22SAndroid Build Coastguard Worker ret = sscanf(id2, "PCI:%u:%u:%u", &b2, &d2, &f2);
764*7688df22SAndroid Build Coastguard Worker if (ret != 3)
765*7688df22SAndroid Build Coastguard Worker return 0;
766*7688df22SAndroid Build Coastguard Worker }
767*7688df22SAndroid Build Coastguard Worker
768*7688df22SAndroid Build Coastguard Worker /* If domains aren't properly supported by the kernel interface,
769*7688df22SAndroid Build Coastguard Worker * just ignore them, which sucks less than picking a totally random
770*7688df22SAndroid Build Coastguard Worker * card with "open by name"
771*7688df22SAndroid Build Coastguard Worker */
772*7688df22SAndroid Build Coastguard Worker if (!pci_domain_ok)
773*7688df22SAndroid Build Coastguard Worker o1 = o2 = 0;
774*7688df22SAndroid Build Coastguard Worker
775*7688df22SAndroid Build Coastguard Worker if ((o1 != o2) || (b1 != b2) || (d1 != d2) || (f1 != f2))
776*7688df22SAndroid Build Coastguard Worker return 0;
777*7688df22SAndroid Build Coastguard Worker else
778*7688df22SAndroid Build Coastguard Worker return 1;
779*7688df22SAndroid Build Coastguard Worker }
780*7688df22SAndroid Build Coastguard Worker return 0;
781*7688df22SAndroid Build Coastguard Worker }
782*7688df22SAndroid Build Coastguard Worker
783*7688df22SAndroid Build Coastguard Worker /**
784*7688df22SAndroid Build Coastguard Worker * Handles error checking for chown call.
785*7688df22SAndroid Build Coastguard Worker *
786*7688df22SAndroid Build Coastguard Worker * \param path to file.
787*7688df22SAndroid Build Coastguard Worker * \param id of the new owner.
788*7688df22SAndroid Build Coastguard Worker * \param id of the new group.
789*7688df22SAndroid Build Coastguard Worker *
790*7688df22SAndroid Build Coastguard Worker * \return zero if success or -1 if failure.
791*7688df22SAndroid Build Coastguard Worker *
792*7688df22SAndroid Build Coastguard Worker * \internal
793*7688df22SAndroid Build Coastguard Worker * Checks for failure. If failure was caused by signal call chown again.
794*7688df22SAndroid Build Coastguard Worker * If any other failure happened then it will output error message using
795*7688df22SAndroid Build Coastguard Worker * drmMsg() call.
796*7688df22SAndroid Build Coastguard Worker */
797*7688df22SAndroid Build Coastguard Worker #if !UDEV
chown_check_return(const char * path,uid_t owner,gid_t group)798*7688df22SAndroid Build Coastguard Worker static int chown_check_return(const char *path, uid_t owner, gid_t group)
799*7688df22SAndroid Build Coastguard Worker {
800*7688df22SAndroid Build Coastguard Worker int rv;
801*7688df22SAndroid Build Coastguard Worker
802*7688df22SAndroid Build Coastguard Worker do {
803*7688df22SAndroid Build Coastguard Worker rv = chown(path, owner, group);
804*7688df22SAndroid Build Coastguard Worker } while (rv != 0 && errno == EINTR);
805*7688df22SAndroid Build Coastguard Worker
806*7688df22SAndroid Build Coastguard Worker if (rv == 0)
807*7688df22SAndroid Build Coastguard Worker return 0;
808*7688df22SAndroid Build Coastguard Worker
809*7688df22SAndroid Build Coastguard Worker drmMsg("Failed to change owner or group for file %s! %d: %s\n",
810*7688df22SAndroid Build Coastguard Worker path, errno, strerror(errno));
811*7688df22SAndroid Build Coastguard Worker return -1;
812*7688df22SAndroid Build Coastguard Worker }
813*7688df22SAndroid Build Coastguard Worker #endif
814*7688df22SAndroid Build Coastguard Worker
drmGetDeviceName(int type)815*7688df22SAndroid Build Coastguard Worker static const char *drmGetDeviceName(int type)
816*7688df22SAndroid Build Coastguard Worker {
817*7688df22SAndroid Build Coastguard Worker switch (type) {
818*7688df22SAndroid Build Coastguard Worker case DRM_NODE_PRIMARY:
819*7688df22SAndroid Build Coastguard Worker return DRM_DEV_NAME;
820*7688df22SAndroid Build Coastguard Worker case DRM_NODE_RENDER:
821*7688df22SAndroid Build Coastguard Worker return DRM_RENDER_DEV_NAME;
822*7688df22SAndroid Build Coastguard Worker }
823*7688df22SAndroid Build Coastguard Worker return NULL;
824*7688df22SAndroid Build Coastguard Worker }
825*7688df22SAndroid Build Coastguard Worker
826*7688df22SAndroid Build Coastguard Worker /**
827*7688df22SAndroid Build Coastguard Worker * Open the DRM device, creating it if necessary.
828*7688df22SAndroid Build Coastguard Worker *
829*7688df22SAndroid Build Coastguard Worker * \param dev major and minor numbers of the device.
830*7688df22SAndroid Build Coastguard Worker * \param minor minor number of the device.
831*7688df22SAndroid Build Coastguard Worker *
832*7688df22SAndroid Build Coastguard Worker * \return a file descriptor on success, or a negative value on error.
833*7688df22SAndroid Build Coastguard Worker *
834*7688df22SAndroid Build Coastguard Worker * \internal
835*7688df22SAndroid Build Coastguard Worker * Assembles the device name from \p minor and opens it, creating the device
836*7688df22SAndroid Build Coastguard Worker * special file node with the major and minor numbers specified by \p dev and
837*7688df22SAndroid Build Coastguard Worker * parent directory if necessary and was called by root.
838*7688df22SAndroid Build Coastguard Worker */
drmOpenDevice(dev_t dev,int minor,int type)839*7688df22SAndroid Build Coastguard Worker static int drmOpenDevice(dev_t dev, int minor, int type)
840*7688df22SAndroid Build Coastguard Worker {
841*7688df22SAndroid Build Coastguard Worker stat_t st;
842*7688df22SAndroid Build Coastguard Worker const char *dev_name = drmGetDeviceName(type);
843*7688df22SAndroid Build Coastguard Worker char buf[DRM_NODE_NAME_MAX];
844*7688df22SAndroid Build Coastguard Worker int fd;
845*7688df22SAndroid Build Coastguard Worker mode_t devmode = DRM_DEV_MODE, serv_mode;
846*7688df22SAndroid Build Coastguard Worker gid_t serv_group;
847*7688df22SAndroid Build Coastguard Worker #if !UDEV
848*7688df22SAndroid Build Coastguard Worker int isroot = !geteuid();
849*7688df22SAndroid Build Coastguard Worker uid_t user = DRM_DEV_UID;
850*7688df22SAndroid Build Coastguard Worker gid_t group = DRM_DEV_GID;
851*7688df22SAndroid Build Coastguard Worker #endif
852*7688df22SAndroid Build Coastguard Worker
853*7688df22SAndroid Build Coastguard Worker if (!dev_name)
854*7688df22SAndroid Build Coastguard Worker return -EINVAL;
855*7688df22SAndroid Build Coastguard Worker
856*7688df22SAndroid Build Coastguard Worker sprintf(buf, dev_name, DRM_DIR_NAME, minor);
857*7688df22SAndroid Build Coastguard Worker drmMsg("drmOpenDevice: node name is %s\n", buf);
858*7688df22SAndroid Build Coastguard Worker
859*7688df22SAndroid Build Coastguard Worker if (drm_server_info && drm_server_info->get_perms) {
860*7688df22SAndroid Build Coastguard Worker drm_server_info->get_perms(&serv_group, &serv_mode);
861*7688df22SAndroid Build Coastguard Worker devmode = serv_mode ? serv_mode : DRM_DEV_MODE;
862*7688df22SAndroid Build Coastguard Worker devmode &= ~(S_IXUSR|S_IXGRP|S_IXOTH);
863*7688df22SAndroid Build Coastguard Worker }
864*7688df22SAndroid Build Coastguard Worker
865*7688df22SAndroid Build Coastguard Worker #if !UDEV
866*7688df22SAndroid Build Coastguard Worker if (stat(DRM_DIR_NAME, &st)) {
867*7688df22SAndroid Build Coastguard Worker if (!isroot)
868*7688df22SAndroid Build Coastguard Worker return DRM_ERR_NOT_ROOT;
869*7688df22SAndroid Build Coastguard Worker mkdir(DRM_DIR_NAME, DRM_DEV_DIRMODE);
870*7688df22SAndroid Build Coastguard Worker chown_check_return(DRM_DIR_NAME, 0, 0); /* root:root */
871*7688df22SAndroid Build Coastguard Worker chmod(DRM_DIR_NAME, DRM_DEV_DIRMODE);
872*7688df22SAndroid Build Coastguard Worker }
873*7688df22SAndroid Build Coastguard Worker
874*7688df22SAndroid Build Coastguard Worker /* Check if the device node exists and create it if necessary. */
875*7688df22SAndroid Build Coastguard Worker if (stat(buf, &st)) {
876*7688df22SAndroid Build Coastguard Worker if (!isroot)
877*7688df22SAndroid Build Coastguard Worker return DRM_ERR_NOT_ROOT;
878*7688df22SAndroid Build Coastguard Worker remove(buf);
879*7688df22SAndroid Build Coastguard Worker mknod(buf, S_IFCHR | devmode, dev);
880*7688df22SAndroid Build Coastguard Worker }
881*7688df22SAndroid Build Coastguard Worker
882*7688df22SAndroid Build Coastguard Worker if (drm_server_info && drm_server_info->get_perms) {
883*7688df22SAndroid Build Coastguard Worker group = ((int)serv_group >= 0) ? serv_group : DRM_DEV_GID;
884*7688df22SAndroid Build Coastguard Worker chown_check_return(buf, user, group);
885*7688df22SAndroid Build Coastguard Worker chmod(buf, devmode);
886*7688df22SAndroid Build Coastguard Worker }
887*7688df22SAndroid Build Coastguard Worker #else
888*7688df22SAndroid Build Coastguard Worker /* if we modprobed then wait for udev */
889*7688df22SAndroid Build Coastguard Worker {
890*7688df22SAndroid Build Coastguard Worker int udev_count = 0;
891*7688df22SAndroid Build Coastguard Worker wait_for_udev:
892*7688df22SAndroid Build Coastguard Worker if (stat(DRM_DIR_NAME, &st)) {
893*7688df22SAndroid Build Coastguard Worker usleep(20);
894*7688df22SAndroid Build Coastguard Worker udev_count++;
895*7688df22SAndroid Build Coastguard Worker
896*7688df22SAndroid Build Coastguard Worker if (udev_count == 50)
897*7688df22SAndroid Build Coastguard Worker return -1;
898*7688df22SAndroid Build Coastguard Worker goto wait_for_udev;
899*7688df22SAndroid Build Coastguard Worker }
900*7688df22SAndroid Build Coastguard Worker
901*7688df22SAndroid Build Coastguard Worker if (stat(buf, &st)) {
902*7688df22SAndroid Build Coastguard Worker usleep(20);
903*7688df22SAndroid Build Coastguard Worker udev_count++;
904*7688df22SAndroid Build Coastguard Worker
905*7688df22SAndroid Build Coastguard Worker if (udev_count == 50)
906*7688df22SAndroid Build Coastguard Worker return -1;
907*7688df22SAndroid Build Coastguard Worker goto wait_for_udev;
908*7688df22SAndroid Build Coastguard Worker }
909*7688df22SAndroid Build Coastguard Worker }
910*7688df22SAndroid Build Coastguard Worker #endif
911*7688df22SAndroid Build Coastguard Worker
912*7688df22SAndroid Build Coastguard Worker fd = open(buf, O_RDWR | O_CLOEXEC);
913*7688df22SAndroid Build Coastguard Worker drmMsg("drmOpenDevice: open result is %d, (%s)\n",
914*7688df22SAndroid Build Coastguard Worker fd, fd < 0 ? strerror(errno) : "OK");
915*7688df22SAndroid Build Coastguard Worker if (fd >= 0)
916*7688df22SAndroid Build Coastguard Worker return fd;
917*7688df22SAndroid Build Coastguard Worker
918*7688df22SAndroid Build Coastguard Worker #if !UDEV
919*7688df22SAndroid Build Coastguard Worker /* Check if the device node is not what we expect it to be, and recreate it
920*7688df22SAndroid Build Coastguard Worker * and try again if so.
921*7688df22SAndroid Build Coastguard Worker */
922*7688df22SAndroid Build Coastguard Worker if (st.st_rdev != dev) {
923*7688df22SAndroid Build Coastguard Worker if (!isroot)
924*7688df22SAndroid Build Coastguard Worker return DRM_ERR_NOT_ROOT;
925*7688df22SAndroid Build Coastguard Worker remove(buf);
926*7688df22SAndroid Build Coastguard Worker mknod(buf, S_IFCHR | devmode, dev);
927*7688df22SAndroid Build Coastguard Worker if (drm_server_info && drm_server_info->get_perms) {
928*7688df22SAndroid Build Coastguard Worker chown_check_return(buf, user, group);
929*7688df22SAndroid Build Coastguard Worker chmod(buf, devmode);
930*7688df22SAndroid Build Coastguard Worker }
931*7688df22SAndroid Build Coastguard Worker }
932*7688df22SAndroid Build Coastguard Worker fd = open(buf, O_RDWR | O_CLOEXEC);
933*7688df22SAndroid Build Coastguard Worker drmMsg("drmOpenDevice: open result is %d, (%s)\n",
934*7688df22SAndroid Build Coastguard Worker fd, fd < 0 ? strerror(errno) : "OK");
935*7688df22SAndroid Build Coastguard Worker if (fd >= 0)
936*7688df22SAndroid Build Coastguard Worker return fd;
937*7688df22SAndroid Build Coastguard Worker
938*7688df22SAndroid Build Coastguard Worker drmMsg("drmOpenDevice: Open failed\n");
939*7688df22SAndroid Build Coastguard Worker remove(buf);
940*7688df22SAndroid Build Coastguard Worker #endif
941*7688df22SAndroid Build Coastguard Worker return -errno;
942*7688df22SAndroid Build Coastguard Worker }
943*7688df22SAndroid Build Coastguard Worker
944*7688df22SAndroid Build Coastguard Worker
945*7688df22SAndroid Build Coastguard Worker /**
946*7688df22SAndroid Build Coastguard Worker * Open the DRM device
947*7688df22SAndroid Build Coastguard Worker *
948*7688df22SAndroid Build Coastguard Worker * \param minor device minor number.
949*7688df22SAndroid Build Coastguard Worker * \param create allow to create the device if set.
950*7688df22SAndroid Build Coastguard Worker *
951*7688df22SAndroid Build Coastguard Worker * \return a file descriptor on success, or a negative value on error.
952*7688df22SAndroid Build Coastguard Worker *
953*7688df22SAndroid Build Coastguard Worker * \internal
954*7688df22SAndroid Build Coastguard Worker * Calls drmOpenDevice() if \p create is set, otherwise assembles the device
955*7688df22SAndroid Build Coastguard Worker * name from \p minor and opens it.
956*7688df22SAndroid Build Coastguard Worker */
drmOpenMinor(int minor,int create,int type)957*7688df22SAndroid Build Coastguard Worker static int drmOpenMinor(int minor, int create, int type)
958*7688df22SAndroid Build Coastguard Worker {
959*7688df22SAndroid Build Coastguard Worker int fd;
960*7688df22SAndroid Build Coastguard Worker char buf[DRM_NODE_NAME_MAX];
961*7688df22SAndroid Build Coastguard Worker const char *dev_name = drmGetDeviceName(type);
962*7688df22SAndroid Build Coastguard Worker
963*7688df22SAndroid Build Coastguard Worker if (create)
964*7688df22SAndroid Build Coastguard Worker return drmOpenDevice(makedev(DRM_MAJOR, minor), minor, type);
965*7688df22SAndroid Build Coastguard Worker
966*7688df22SAndroid Build Coastguard Worker if (!dev_name)
967*7688df22SAndroid Build Coastguard Worker return -EINVAL;
968*7688df22SAndroid Build Coastguard Worker
969*7688df22SAndroid Build Coastguard Worker sprintf(buf, dev_name, DRM_DIR_NAME, minor);
970*7688df22SAndroid Build Coastguard Worker if ((fd = open(buf, O_RDWR | O_CLOEXEC)) >= 0)
971*7688df22SAndroid Build Coastguard Worker return fd;
972*7688df22SAndroid Build Coastguard Worker return -errno;
973*7688df22SAndroid Build Coastguard Worker }
974*7688df22SAndroid Build Coastguard Worker
975*7688df22SAndroid Build Coastguard Worker
976*7688df22SAndroid Build Coastguard Worker /**
977*7688df22SAndroid Build Coastguard Worker * Determine whether the DRM kernel driver has been loaded.
978*7688df22SAndroid Build Coastguard Worker *
979*7688df22SAndroid Build Coastguard Worker * \return 1 if the DRM driver is loaded, 0 otherwise.
980*7688df22SAndroid Build Coastguard Worker *
981*7688df22SAndroid Build Coastguard Worker * \internal
982*7688df22SAndroid Build Coastguard Worker * Determine the presence of the kernel driver by attempting to open the 0
983*7688df22SAndroid Build Coastguard Worker * minor and get version information. For backward compatibility with older
984*7688df22SAndroid Build Coastguard Worker * Linux implementations, /proc/dri is also checked.
985*7688df22SAndroid Build Coastguard Worker */
drmAvailable(void)986*7688df22SAndroid Build Coastguard Worker drm_public int drmAvailable(void)
987*7688df22SAndroid Build Coastguard Worker {
988*7688df22SAndroid Build Coastguard Worker drmVersionPtr version;
989*7688df22SAndroid Build Coastguard Worker int retval = 0;
990*7688df22SAndroid Build Coastguard Worker int fd;
991*7688df22SAndroid Build Coastguard Worker
992*7688df22SAndroid Build Coastguard Worker if ((fd = drmOpenMinor(0, 1, DRM_NODE_PRIMARY)) < 0) {
993*7688df22SAndroid Build Coastguard Worker #ifdef __linux__
994*7688df22SAndroid Build Coastguard Worker /* Try proc for backward Linux compatibility */
995*7688df22SAndroid Build Coastguard Worker if (!access("/proc/dri/0", R_OK))
996*7688df22SAndroid Build Coastguard Worker return 1;
997*7688df22SAndroid Build Coastguard Worker #endif
998*7688df22SAndroid Build Coastguard Worker return 0;
999*7688df22SAndroid Build Coastguard Worker }
1000*7688df22SAndroid Build Coastguard Worker
1001*7688df22SAndroid Build Coastguard Worker if ((version = drmGetVersion(fd))) {
1002*7688df22SAndroid Build Coastguard Worker retval = 1;
1003*7688df22SAndroid Build Coastguard Worker drmFreeVersion(version);
1004*7688df22SAndroid Build Coastguard Worker }
1005*7688df22SAndroid Build Coastguard Worker close(fd);
1006*7688df22SAndroid Build Coastguard Worker
1007*7688df22SAndroid Build Coastguard Worker return retval;
1008*7688df22SAndroid Build Coastguard Worker }
1009*7688df22SAndroid Build Coastguard Worker
drmGetMinorBase(int type)1010*7688df22SAndroid Build Coastguard Worker static int drmGetMinorBase(int type)
1011*7688df22SAndroid Build Coastguard Worker {
1012*7688df22SAndroid Build Coastguard Worker switch (type) {
1013*7688df22SAndroid Build Coastguard Worker case DRM_NODE_PRIMARY:
1014*7688df22SAndroid Build Coastguard Worker return 0;
1015*7688df22SAndroid Build Coastguard Worker case DRM_NODE_RENDER:
1016*7688df22SAndroid Build Coastguard Worker return 128;
1017*7688df22SAndroid Build Coastguard Worker default:
1018*7688df22SAndroid Build Coastguard Worker return -1;
1019*7688df22SAndroid Build Coastguard Worker };
1020*7688df22SAndroid Build Coastguard Worker }
1021*7688df22SAndroid Build Coastguard Worker
drmGetMinorType(int major,int minor)1022*7688df22SAndroid Build Coastguard Worker static int drmGetMinorType(int major, int minor)
1023*7688df22SAndroid Build Coastguard Worker {
1024*7688df22SAndroid Build Coastguard Worker #ifdef __FreeBSD__
1025*7688df22SAndroid Build Coastguard Worker char name[SPECNAMELEN];
1026*7688df22SAndroid Build Coastguard Worker int id;
1027*7688df22SAndroid Build Coastguard Worker
1028*7688df22SAndroid Build Coastguard Worker if (!devname_r(makedev(major, minor), S_IFCHR, name, sizeof(name)))
1029*7688df22SAndroid Build Coastguard Worker return -1;
1030*7688df22SAndroid Build Coastguard Worker
1031*7688df22SAndroid Build Coastguard Worker if (sscanf(name, "drm/%d", &id) != 1) {
1032*7688df22SAndroid Build Coastguard Worker // If not in /dev/drm/ we have the type in the name
1033*7688df22SAndroid Build Coastguard Worker if (sscanf(name, "dri/card%d\n", &id) >= 1)
1034*7688df22SAndroid Build Coastguard Worker return DRM_NODE_PRIMARY;
1035*7688df22SAndroid Build Coastguard Worker else if (sscanf(name, "dri/renderD%d\n", &id) >= 1)
1036*7688df22SAndroid Build Coastguard Worker return DRM_NODE_RENDER;
1037*7688df22SAndroid Build Coastguard Worker return -1;
1038*7688df22SAndroid Build Coastguard Worker }
1039*7688df22SAndroid Build Coastguard Worker
1040*7688df22SAndroid Build Coastguard Worker minor = id;
1041*7688df22SAndroid Build Coastguard Worker #endif
1042*7688df22SAndroid Build Coastguard Worker char path[DRM_NODE_NAME_MAX];
1043*7688df22SAndroid Build Coastguard Worker const char *dev_name;
1044*7688df22SAndroid Build Coastguard Worker int i;
1045*7688df22SAndroid Build Coastguard Worker
1046*7688df22SAndroid Build Coastguard Worker for (i = DRM_NODE_PRIMARY; i < DRM_NODE_MAX; i++) {
1047*7688df22SAndroid Build Coastguard Worker dev_name = drmGetDeviceName(i);
1048*7688df22SAndroid Build Coastguard Worker if (!dev_name)
1049*7688df22SAndroid Build Coastguard Worker continue;
1050*7688df22SAndroid Build Coastguard Worker snprintf(path, sizeof(path), dev_name, DRM_DIR_NAME, minor);
1051*7688df22SAndroid Build Coastguard Worker if (!access(path, F_OK))
1052*7688df22SAndroid Build Coastguard Worker return i;
1053*7688df22SAndroid Build Coastguard Worker }
1054*7688df22SAndroid Build Coastguard Worker
1055*7688df22SAndroid Build Coastguard Worker return -1;
1056*7688df22SAndroid Build Coastguard Worker }
1057*7688df22SAndroid Build Coastguard Worker
drmGetMinorName(int type)1058*7688df22SAndroid Build Coastguard Worker static const char *drmGetMinorName(int type)
1059*7688df22SAndroid Build Coastguard Worker {
1060*7688df22SAndroid Build Coastguard Worker switch (type) {
1061*7688df22SAndroid Build Coastguard Worker case DRM_NODE_PRIMARY:
1062*7688df22SAndroid Build Coastguard Worker return DRM_PRIMARY_MINOR_NAME;
1063*7688df22SAndroid Build Coastguard Worker case DRM_NODE_RENDER:
1064*7688df22SAndroid Build Coastguard Worker return DRM_RENDER_MINOR_NAME;
1065*7688df22SAndroid Build Coastguard Worker default:
1066*7688df22SAndroid Build Coastguard Worker return NULL;
1067*7688df22SAndroid Build Coastguard Worker }
1068*7688df22SAndroid Build Coastguard Worker }
1069*7688df22SAndroid Build Coastguard Worker
1070*7688df22SAndroid Build Coastguard Worker /**
1071*7688df22SAndroid Build Coastguard Worker * Open the device by bus ID.
1072*7688df22SAndroid Build Coastguard Worker *
1073*7688df22SAndroid Build Coastguard Worker * \param busid bus ID.
1074*7688df22SAndroid Build Coastguard Worker * \param type device node type.
1075*7688df22SAndroid Build Coastguard Worker *
1076*7688df22SAndroid Build Coastguard Worker * \return a file descriptor on success, or a negative value on error.
1077*7688df22SAndroid Build Coastguard Worker *
1078*7688df22SAndroid Build Coastguard Worker * \internal
1079*7688df22SAndroid Build Coastguard Worker * This function attempts to open every possible minor (up to DRM_MAX_MINOR),
1080*7688df22SAndroid Build Coastguard Worker * comparing the device bus ID with the one supplied.
1081*7688df22SAndroid Build Coastguard Worker *
1082*7688df22SAndroid Build Coastguard Worker * \sa drmOpenMinor() and drmGetBusid().
1083*7688df22SAndroid Build Coastguard Worker */
drmOpenByBusid(const char * busid,int type)1084*7688df22SAndroid Build Coastguard Worker static int drmOpenByBusid(const char *busid, int type)
1085*7688df22SAndroid Build Coastguard Worker {
1086*7688df22SAndroid Build Coastguard Worker int i, pci_domain_ok = 1;
1087*7688df22SAndroid Build Coastguard Worker int fd;
1088*7688df22SAndroid Build Coastguard Worker const char *buf;
1089*7688df22SAndroid Build Coastguard Worker drmSetVersion sv;
1090*7688df22SAndroid Build Coastguard Worker int base = drmGetMinorBase(type);
1091*7688df22SAndroid Build Coastguard Worker
1092*7688df22SAndroid Build Coastguard Worker if (base < 0)
1093*7688df22SAndroid Build Coastguard Worker return -1;
1094*7688df22SAndroid Build Coastguard Worker
1095*7688df22SAndroid Build Coastguard Worker drmMsg("drmOpenByBusid: Searching for BusID %s\n", busid);
1096*7688df22SAndroid Build Coastguard Worker for (i = base; i < base + DRM_MAX_MINOR; i++) {
1097*7688df22SAndroid Build Coastguard Worker fd = drmOpenMinor(i, 1, type);
1098*7688df22SAndroid Build Coastguard Worker drmMsg("drmOpenByBusid: drmOpenMinor returns %d\n", fd);
1099*7688df22SAndroid Build Coastguard Worker if (fd >= 0) {
1100*7688df22SAndroid Build Coastguard Worker /* We need to try for 1.4 first for proper PCI domain support
1101*7688df22SAndroid Build Coastguard Worker * and if that fails, we know the kernel is busted
1102*7688df22SAndroid Build Coastguard Worker */
1103*7688df22SAndroid Build Coastguard Worker sv.drm_di_major = 1;
1104*7688df22SAndroid Build Coastguard Worker sv.drm_di_minor = 4;
1105*7688df22SAndroid Build Coastguard Worker sv.drm_dd_major = -1; /* Don't care */
1106*7688df22SAndroid Build Coastguard Worker sv.drm_dd_minor = -1; /* Don't care */
1107*7688df22SAndroid Build Coastguard Worker if (drmSetInterfaceVersion(fd, &sv)) {
1108*7688df22SAndroid Build Coastguard Worker #ifndef __alpha__
1109*7688df22SAndroid Build Coastguard Worker pci_domain_ok = 0;
1110*7688df22SAndroid Build Coastguard Worker #endif
1111*7688df22SAndroid Build Coastguard Worker sv.drm_di_major = 1;
1112*7688df22SAndroid Build Coastguard Worker sv.drm_di_minor = 1;
1113*7688df22SAndroid Build Coastguard Worker sv.drm_dd_major = -1; /* Don't care */
1114*7688df22SAndroid Build Coastguard Worker sv.drm_dd_minor = -1; /* Don't care */
1115*7688df22SAndroid Build Coastguard Worker drmMsg("drmOpenByBusid: Interface 1.4 failed, trying 1.1\n");
1116*7688df22SAndroid Build Coastguard Worker drmSetInterfaceVersion(fd, &sv);
1117*7688df22SAndroid Build Coastguard Worker }
1118*7688df22SAndroid Build Coastguard Worker buf = drmGetBusid(fd);
1119*7688df22SAndroid Build Coastguard Worker drmMsg("drmOpenByBusid: drmGetBusid reports %s\n", buf);
1120*7688df22SAndroid Build Coastguard Worker if (buf && drmMatchBusID(buf, busid, pci_domain_ok)) {
1121*7688df22SAndroid Build Coastguard Worker drmFreeBusid(buf);
1122*7688df22SAndroid Build Coastguard Worker return fd;
1123*7688df22SAndroid Build Coastguard Worker }
1124*7688df22SAndroid Build Coastguard Worker if (buf)
1125*7688df22SAndroid Build Coastguard Worker drmFreeBusid(buf);
1126*7688df22SAndroid Build Coastguard Worker close(fd);
1127*7688df22SAndroid Build Coastguard Worker }
1128*7688df22SAndroid Build Coastguard Worker }
1129*7688df22SAndroid Build Coastguard Worker return -1;
1130*7688df22SAndroid Build Coastguard Worker }
1131*7688df22SAndroid Build Coastguard Worker
1132*7688df22SAndroid Build Coastguard Worker
1133*7688df22SAndroid Build Coastguard Worker /**
1134*7688df22SAndroid Build Coastguard Worker * Open the device by name.
1135*7688df22SAndroid Build Coastguard Worker *
1136*7688df22SAndroid Build Coastguard Worker * \param name driver name.
1137*7688df22SAndroid Build Coastguard Worker * \param type the device node type.
1138*7688df22SAndroid Build Coastguard Worker *
1139*7688df22SAndroid Build Coastguard Worker * \return a file descriptor on success, or a negative value on error.
1140*7688df22SAndroid Build Coastguard Worker *
1141*7688df22SAndroid Build Coastguard Worker * \internal
1142*7688df22SAndroid Build Coastguard Worker * This function opens the first minor number that matches the driver name and
1143*7688df22SAndroid Build Coastguard Worker * isn't already in use. If it's in use it then it will already have a bus ID
1144*7688df22SAndroid Build Coastguard Worker * assigned.
1145*7688df22SAndroid Build Coastguard Worker *
1146*7688df22SAndroid Build Coastguard Worker * \sa drmOpenMinor(), drmGetVersion() and drmGetBusid().
1147*7688df22SAndroid Build Coastguard Worker */
drmOpenByName(const char * name,int type)1148*7688df22SAndroid Build Coastguard Worker static int drmOpenByName(const char *name, int type)
1149*7688df22SAndroid Build Coastguard Worker {
1150*7688df22SAndroid Build Coastguard Worker int i;
1151*7688df22SAndroid Build Coastguard Worker int fd;
1152*7688df22SAndroid Build Coastguard Worker drmVersionPtr version;
1153*7688df22SAndroid Build Coastguard Worker char * id;
1154*7688df22SAndroid Build Coastguard Worker int base = drmGetMinorBase(type);
1155*7688df22SAndroid Build Coastguard Worker
1156*7688df22SAndroid Build Coastguard Worker if (base < 0)
1157*7688df22SAndroid Build Coastguard Worker return -1;
1158*7688df22SAndroid Build Coastguard Worker
1159*7688df22SAndroid Build Coastguard Worker /*
1160*7688df22SAndroid Build Coastguard Worker * Open the first minor number that matches the driver name and isn't
1161*7688df22SAndroid Build Coastguard Worker * already in use. If it's in use it will have a busid assigned already.
1162*7688df22SAndroid Build Coastguard Worker */
1163*7688df22SAndroid Build Coastguard Worker for (i = base; i < base + DRM_MAX_MINOR; i++) {
1164*7688df22SAndroid Build Coastguard Worker if ((fd = drmOpenMinor(i, 1, type)) >= 0) {
1165*7688df22SAndroid Build Coastguard Worker if ((version = drmGetVersion(fd))) {
1166*7688df22SAndroid Build Coastguard Worker if (!strcmp(version->name, name)) {
1167*7688df22SAndroid Build Coastguard Worker drmFreeVersion(version);
1168*7688df22SAndroid Build Coastguard Worker id = drmGetBusid(fd);
1169*7688df22SAndroid Build Coastguard Worker drmMsg("drmGetBusid returned '%s'\n", id ? id : "NULL");
1170*7688df22SAndroid Build Coastguard Worker if (!id || !*id) {
1171*7688df22SAndroid Build Coastguard Worker if (id)
1172*7688df22SAndroid Build Coastguard Worker drmFreeBusid(id);
1173*7688df22SAndroid Build Coastguard Worker return fd;
1174*7688df22SAndroid Build Coastguard Worker } else {
1175*7688df22SAndroid Build Coastguard Worker drmFreeBusid(id);
1176*7688df22SAndroid Build Coastguard Worker }
1177*7688df22SAndroid Build Coastguard Worker } else {
1178*7688df22SAndroid Build Coastguard Worker drmFreeVersion(version);
1179*7688df22SAndroid Build Coastguard Worker }
1180*7688df22SAndroid Build Coastguard Worker }
1181*7688df22SAndroid Build Coastguard Worker close(fd);
1182*7688df22SAndroid Build Coastguard Worker }
1183*7688df22SAndroid Build Coastguard Worker }
1184*7688df22SAndroid Build Coastguard Worker
1185*7688df22SAndroid Build Coastguard Worker #ifdef __linux__
1186*7688df22SAndroid Build Coastguard Worker /* Backward-compatibility /proc support */
1187*7688df22SAndroid Build Coastguard Worker for (i = 0; i < 8; i++) {
1188*7688df22SAndroid Build Coastguard Worker char proc_name[64], buf[512];
1189*7688df22SAndroid Build Coastguard Worker char *driver, *pt, *devstring;
1190*7688df22SAndroid Build Coastguard Worker int retcode;
1191*7688df22SAndroid Build Coastguard Worker
1192*7688df22SAndroid Build Coastguard Worker sprintf(proc_name, "/proc/dri/%d/name", i);
1193*7688df22SAndroid Build Coastguard Worker if ((fd = open(proc_name, O_RDONLY)) >= 0) {
1194*7688df22SAndroid Build Coastguard Worker retcode = read(fd, buf, sizeof(buf)-1);
1195*7688df22SAndroid Build Coastguard Worker close(fd);
1196*7688df22SAndroid Build Coastguard Worker if (retcode) {
1197*7688df22SAndroid Build Coastguard Worker buf[retcode-1] = '\0';
1198*7688df22SAndroid Build Coastguard Worker for (driver = pt = buf; *pt && *pt != ' '; ++pt)
1199*7688df22SAndroid Build Coastguard Worker ;
1200*7688df22SAndroid Build Coastguard Worker if (*pt) { /* Device is next */
1201*7688df22SAndroid Build Coastguard Worker *pt = '\0';
1202*7688df22SAndroid Build Coastguard Worker if (!strcmp(driver, name)) { /* Match */
1203*7688df22SAndroid Build Coastguard Worker for (devstring = ++pt; *pt && *pt != ' '; ++pt)
1204*7688df22SAndroid Build Coastguard Worker ;
1205*7688df22SAndroid Build Coastguard Worker if (*pt) { /* Found busid */
1206*7688df22SAndroid Build Coastguard Worker return drmOpenByBusid(++pt, type);
1207*7688df22SAndroid Build Coastguard Worker } else { /* No busid */
1208*7688df22SAndroid Build Coastguard Worker return drmOpenDevice(strtol(devstring, NULL, 0),i, type);
1209*7688df22SAndroid Build Coastguard Worker }
1210*7688df22SAndroid Build Coastguard Worker }
1211*7688df22SAndroid Build Coastguard Worker }
1212*7688df22SAndroid Build Coastguard Worker }
1213*7688df22SAndroid Build Coastguard Worker }
1214*7688df22SAndroid Build Coastguard Worker }
1215*7688df22SAndroid Build Coastguard Worker #endif
1216*7688df22SAndroid Build Coastguard Worker
1217*7688df22SAndroid Build Coastguard Worker return -1;
1218*7688df22SAndroid Build Coastguard Worker }
1219*7688df22SAndroid Build Coastguard Worker
1220*7688df22SAndroid Build Coastguard Worker
1221*7688df22SAndroid Build Coastguard Worker /**
1222*7688df22SAndroid Build Coastguard Worker * Open the DRM device.
1223*7688df22SAndroid Build Coastguard Worker *
1224*7688df22SAndroid Build Coastguard Worker * Looks up the specified name and bus ID, and opens the device found. The
1225*7688df22SAndroid Build Coastguard Worker * entry in /dev/dri is created if necessary and if called by root.
1226*7688df22SAndroid Build Coastguard Worker *
1227*7688df22SAndroid Build Coastguard Worker * \param name driver name. Not referenced if bus ID is supplied.
1228*7688df22SAndroid Build Coastguard Worker * \param busid bus ID. Zero if not known.
1229*7688df22SAndroid Build Coastguard Worker *
1230*7688df22SAndroid Build Coastguard Worker * \return a file descriptor on success, or a negative value on error.
1231*7688df22SAndroid Build Coastguard Worker *
1232*7688df22SAndroid Build Coastguard Worker * \internal
1233*7688df22SAndroid Build Coastguard Worker * It calls drmOpenByBusid() if \p busid is specified or drmOpenByName()
1234*7688df22SAndroid Build Coastguard Worker * otherwise.
1235*7688df22SAndroid Build Coastguard Worker */
drmOpen(const char * name,const char * busid)1236*7688df22SAndroid Build Coastguard Worker drm_public int drmOpen(const char *name, const char *busid)
1237*7688df22SAndroid Build Coastguard Worker {
1238*7688df22SAndroid Build Coastguard Worker return drmOpenWithType(name, busid, DRM_NODE_PRIMARY);
1239*7688df22SAndroid Build Coastguard Worker }
1240*7688df22SAndroid Build Coastguard Worker
1241*7688df22SAndroid Build Coastguard Worker /**
1242*7688df22SAndroid Build Coastguard Worker * Open the DRM device with specified type.
1243*7688df22SAndroid Build Coastguard Worker *
1244*7688df22SAndroid Build Coastguard Worker * Looks up the specified name and bus ID, and opens the device found. The
1245*7688df22SAndroid Build Coastguard Worker * entry in /dev/dri is created if necessary and if called by root.
1246*7688df22SAndroid Build Coastguard Worker *
1247*7688df22SAndroid Build Coastguard Worker * \param name driver name. Not referenced if bus ID is supplied.
1248*7688df22SAndroid Build Coastguard Worker * \param busid bus ID. Zero if not known.
1249*7688df22SAndroid Build Coastguard Worker * \param type the device node type to open, PRIMARY or RENDER
1250*7688df22SAndroid Build Coastguard Worker *
1251*7688df22SAndroid Build Coastguard Worker * \return a file descriptor on success, or a negative value on error.
1252*7688df22SAndroid Build Coastguard Worker *
1253*7688df22SAndroid Build Coastguard Worker * \internal
1254*7688df22SAndroid Build Coastguard Worker * It calls drmOpenByBusid() if \p busid is specified or drmOpenByName()
1255*7688df22SAndroid Build Coastguard Worker * otherwise.
1256*7688df22SAndroid Build Coastguard Worker */
drmOpenWithType(const char * name,const char * busid,int type)1257*7688df22SAndroid Build Coastguard Worker drm_public int drmOpenWithType(const char *name, const char *busid, int type)
1258*7688df22SAndroid Build Coastguard Worker {
1259*7688df22SAndroid Build Coastguard Worker if (name != NULL && drm_server_info &&
1260*7688df22SAndroid Build Coastguard Worker drm_server_info->load_module && !drmAvailable()) {
1261*7688df22SAndroid Build Coastguard Worker /* try to load the kernel module */
1262*7688df22SAndroid Build Coastguard Worker if (!drm_server_info->load_module(name)) {
1263*7688df22SAndroid Build Coastguard Worker drmMsg("[drm] failed to load kernel module \"%s\"\n", name);
1264*7688df22SAndroid Build Coastguard Worker return -1;
1265*7688df22SAndroid Build Coastguard Worker }
1266*7688df22SAndroid Build Coastguard Worker }
1267*7688df22SAndroid Build Coastguard Worker
1268*7688df22SAndroid Build Coastguard Worker if (busid) {
1269*7688df22SAndroid Build Coastguard Worker int fd = drmOpenByBusid(busid, type);
1270*7688df22SAndroid Build Coastguard Worker if (fd >= 0)
1271*7688df22SAndroid Build Coastguard Worker return fd;
1272*7688df22SAndroid Build Coastguard Worker }
1273*7688df22SAndroid Build Coastguard Worker
1274*7688df22SAndroid Build Coastguard Worker if (name)
1275*7688df22SAndroid Build Coastguard Worker return drmOpenByName(name, type);
1276*7688df22SAndroid Build Coastguard Worker
1277*7688df22SAndroid Build Coastguard Worker return -1;
1278*7688df22SAndroid Build Coastguard Worker }
1279*7688df22SAndroid Build Coastguard Worker
drmOpenControl(int minor)1280*7688df22SAndroid Build Coastguard Worker drm_public int drmOpenControl(int minor)
1281*7688df22SAndroid Build Coastguard Worker {
1282*7688df22SAndroid Build Coastguard Worker return -EINVAL;
1283*7688df22SAndroid Build Coastguard Worker }
1284*7688df22SAndroid Build Coastguard Worker
drmOpenRender(int minor)1285*7688df22SAndroid Build Coastguard Worker drm_public int drmOpenRender(int minor)
1286*7688df22SAndroid Build Coastguard Worker {
1287*7688df22SAndroid Build Coastguard Worker return drmOpenMinor(minor, 0, DRM_NODE_RENDER);
1288*7688df22SAndroid Build Coastguard Worker }
1289*7688df22SAndroid Build Coastguard Worker
1290*7688df22SAndroid Build Coastguard Worker /**
1291*7688df22SAndroid Build Coastguard Worker * Free the version information returned by drmGetVersion().
1292*7688df22SAndroid Build Coastguard Worker *
1293*7688df22SAndroid Build Coastguard Worker * \param v pointer to the version information.
1294*7688df22SAndroid Build Coastguard Worker *
1295*7688df22SAndroid Build Coastguard Worker * \internal
1296*7688df22SAndroid Build Coastguard Worker * It frees the memory pointed by \p %v as well as all the non-null strings
1297*7688df22SAndroid Build Coastguard Worker * pointers in it.
1298*7688df22SAndroid Build Coastguard Worker */
drmFreeVersion(drmVersionPtr v)1299*7688df22SAndroid Build Coastguard Worker drm_public void drmFreeVersion(drmVersionPtr v)
1300*7688df22SAndroid Build Coastguard Worker {
1301*7688df22SAndroid Build Coastguard Worker if (!v)
1302*7688df22SAndroid Build Coastguard Worker return;
1303*7688df22SAndroid Build Coastguard Worker drmFree(v->name);
1304*7688df22SAndroid Build Coastguard Worker drmFree(v->date);
1305*7688df22SAndroid Build Coastguard Worker drmFree(v->desc);
1306*7688df22SAndroid Build Coastguard Worker drmFree(v);
1307*7688df22SAndroid Build Coastguard Worker }
1308*7688df22SAndroid Build Coastguard Worker
1309*7688df22SAndroid Build Coastguard Worker
1310*7688df22SAndroid Build Coastguard Worker /**
1311*7688df22SAndroid Build Coastguard Worker * Free the non-public version information returned by the kernel.
1312*7688df22SAndroid Build Coastguard Worker *
1313*7688df22SAndroid Build Coastguard Worker * \param v pointer to the version information.
1314*7688df22SAndroid Build Coastguard Worker *
1315*7688df22SAndroid Build Coastguard Worker * \internal
1316*7688df22SAndroid Build Coastguard Worker * Used by drmGetVersion() to free the memory pointed by \p %v as well as all
1317*7688df22SAndroid Build Coastguard Worker * the non-null strings pointers in it.
1318*7688df22SAndroid Build Coastguard Worker */
drmFreeKernelVersion(drm_version_t * v)1319*7688df22SAndroid Build Coastguard Worker static void drmFreeKernelVersion(drm_version_t *v)
1320*7688df22SAndroid Build Coastguard Worker {
1321*7688df22SAndroid Build Coastguard Worker if (!v)
1322*7688df22SAndroid Build Coastguard Worker return;
1323*7688df22SAndroid Build Coastguard Worker drmFree(v->name);
1324*7688df22SAndroid Build Coastguard Worker drmFree(v->date);
1325*7688df22SAndroid Build Coastguard Worker drmFree(v->desc);
1326*7688df22SAndroid Build Coastguard Worker drmFree(v);
1327*7688df22SAndroid Build Coastguard Worker }
1328*7688df22SAndroid Build Coastguard Worker
1329*7688df22SAndroid Build Coastguard Worker
1330*7688df22SAndroid Build Coastguard Worker /**
1331*7688df22SAndroid Build Coastguard Worker * Copy version information.
1332*7688df22SAndroid Build Coastguard Worker *
1333*7688df22SAndroid Build Coastguard Worker * \param d destination pointer.
1334*7688df22SAndroid Build Coastguard Worker * \param s source pointer.
1335*7688df22SAndroid Build Coastguard Worker *
1336*7688df22SAndroid Build Coastguard Worker * \internal
1337*7688df22SAndroid Build Coastguard Worker * Used by drmGetVersion() to translate the information returned by the ioctl
1338*7688df22SAndroid Build Coastguard Worker * interface in a private structure into the public structure counterpart.
1339*7688df22SAndroid Build Coastguard Worker */
drmCopyVersion(drmVersionPtr d,const drm_version_t * s)1340*7688df22SAndroid Build Coastguard Worker static void drmCopyVersion(drmVersionPtr d, const drm_version_t *s)
1341*7688df22SAndroid Build Coastguard Worker {
1342*7688df22SAndroid Build Coastguard Worker d->version_major = s->version_major;
1343*7688df22SAndroid Build Coastguard Worker d->version_minor = s->version_minor;
1344*7688df22SAndroid Build Coastguard Worker d->version_patchlevel = s->version_patchlevel;
1345*7688df22SAndroid Build Coastguard Worker d->name_len = s->name_len;
1346*7688df22SAndroid Build Coastguard Worker d->name = strdup(s->name);
1347*7688df22SAndroid Build Coastguard Worker d->date_len = s->date_len;
1348*7688df22SAndroid Build Coastguard Worker d->date = strdup(s->date);
1349*7688df22SAndroid Build Coastguard Worker d->desc_len = s->desc_len;
1350*7688df22SAndroid Build Coastguard Worker d->desc = strdup(s->desc);
1351*7688df22SAndroid Build Coastguard Worker }
1352*7688df22SAndroid Build Coastguard Worker
1353*7688df22SAndroid Build Coastguard Worker
1354*7688df22SAndroid Build Coastguard Worker /**
1355*7688df22SAndroid Build Coastguard Worker * Query the driver version information.
1356*7688df22SAndroid Build Coastguard Worker *
1357*7688df22SAndroid Build Coastguard Worker * \param fd file descriptor.
1358*7688df22SAndroid Build Coastguard Worker *
1359*7688df22SAndroid Build Coastguard Worker * \return pointer to a drmVersion structure which should be freed with
1360*7688df22SAndroid Build Coastguard Worker * drmFreeVersion().
1361*7688df22SAndroid Build Coastguard Worker *
1362*7688df22SAndroid Build Coastguard Worker * \note Similar information is available via /proc/dri.
1363*7688df22SAndroid Build Coastguard Worker *
1364*7688df22SAndroid Build Coastguard Worker * \internal
1365*7688df22SAndroid Build Coastguard Worker * It gets the version information via successive DRM_IOCTL_VERSION ioctls,
1366*7688df22SAndroid Build Coastguard Worker * first with zeros to get the string lengths, and then the actually strings.
1367*7688df22SAndroid Build Coastguard Worker * It also null-terminates them since they might not be already.
1368*7688df22SAndroid Build Coastguard Worker */
drmGetVersion(int fd)1369*7688df22SAndroid Build Coastguard Worker drm_public drmVersionPtr drmGetVersion(int fd)
1370*7688df22SAndroid Build Coastguard Worker {
1371*7688df22SAndroid Build Coastguard Worker drmVersionPtr retval;
1372*7688df22SAndroid Build Coastguard Worker drm_version_t *version = drmMalloc(sizeof(*version));
1373*7688df22SAndroid Build Coastguard Worker
1374*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_VERSION, version)) {
1375*7688df22SAndroid Build Coastguard Worker drmFreeKernelVersion(version);
1376*7688df22SAndroid Build Coastguard Worker return NULL;
1377*7688df22SAndroid Build Coastguard Worker }
1378*7688df22SAndroid Build Coastguard Worker
1379*7688df22SAndroid Build Coastguard Worker if (version->name_len)
1380*7688df22SAndroid Build Coastguard Worker version->name = drmMalloc(version->name_len + 1);
1381*7688df22SAndroid Build Coastguard Worker if (version->date_len)
1382*7688df22SAndroid Build Coastguard Worker version->date = drmMalloc(version->date_len + 1);
1383*7688df22SAndroid Build Coastguard Worker if (version->desc_len)
1384*7688df22SAndroid Build Coastguard Worker version->desc = drmMalloc(version->desc_len + 1);
1385*7688df22SAndroid Build Coastguard Worker
1386*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_VERSION, version)) {
1387*7688df22SAndroid Build Coastguard Worker drmMsg("DRM_IOCTL_VERSION: %s\n", strerror(errno));
1388*7688df22SAndroid Build Coastguard Worker drmFreeKernelVersion(version);
1389*7688df22SAndroid Build Coastguard Worker return NULL;
1390*7688df22SAndroid Build Coastguard Worker }
1391*7688df22SAndroid Build Coastguard Worker
1392*7688df22SAndroid Build Coastguard Worker /* The results might not be null-terminated strings, so terminate them. */
1393*7688df22SAndroid Build Coastguard Worker if (version->name_len) version->name[version->name_len] = '\0';
1394*7688df22SAndroid Build Coastguard Worker if (version->date_len) version->date[version->date_len] = '\0';
1395*7688df22SAndroid Build Coastguard Worker if (version->desc_len) version->desc[version->desc_len] = '\0';
1396*7688df22SAndroid Build Coastguard Worker
1397*7688df22SAndroid Build Coastguard Worker retval = drmMalloc(sizeof(*retval));
1398*7688df22SAndroid Build Coastguard Worker drmCopyVersion(retval, version);
1399*7688df22SAndroid Build Coastguard Worker drmFreeKernelVersion(version);
1400*7688df22SAndroid Build Coastguard Worker return retval;
1401*7688df22SAndroid Build Coastguard Worker }
1402*7688df22SAndroid Build Coastguard Worker
1403*7688df22SAndroid Build Coastguard Worker
1404*7688df22SAndroid Build Coastguard Worker /**
1405*7688df22SAndroid Build Coastguard Worker * Get version information for the DRM user space library.
1406*7688df22SAndroid Build Coastguard Worker *
1407*7688df22SAndroid Build Coastguard Worker * This version number is driver independent.
1408*7688df22SAndroid Build Coastguard Worker *
1409*7688df22SAndroid Build Coastguard Worker * \param fd file descriptor.
1410*7688df22SAndroid Build Coastguard Worker *
1411*7688df22SAndroid Build Coastguard Worker * \return version information.
1412*7688df22SAndroid Build Coastguard Worker *
1413*7688df22SAndroid Build Coastguard Worker * \internal
1414*7688df22SAndroid Build Coastguard Worker * This function allocates and fills a drm_version structure with a hard coded
1415*7688df22SAndroid Build Coastguard Worker * version number.
1416*7688df22SAndroid Build Coastguard Worker */
drmGetLibVersion(int fd)1417*7688df22SAndroid Build Coastguard Worker drm_public drmVersionPtr drmGetLibVersion(int fd)
1418*7688df22SAndroid Build Coastguard Worker {
1419*7688df22SAndroid Build Coastguard Worker drm_version_t *version = drmMalloc(sizeof(*version));
1420*7688df22SAndroid Build Coastguard Worker
1421*7688df22SAndroid Build Coastguard Worker /* Version history:
1422*7688df22SAndroid Build Coastguard Worker * NOTE THIS MUST NOT GO ABOVE VERSION 1.X due to drivers needing it
1423*7688df22SAndroid Build Coastguard Worker * revision 1.0.x = original DRM interface with no drmGetLibVersion
1424*7688df22SAndroid Build Coastguard Worker * entry point and many drm<Device> extensions
1425*7688df22SAndroid Build Coastguard Worker * revision 1.1.x = added drmCommand entry points for device extensions
1426*7688df22SAndroid Build Coastguard Worker * added drmGetLibVersion to identify libdrm.a version
1427*7688df22SAndroid Build Coastguard Worker * revision 1.2.x = added drmSetInterfaceVersion
1428*7688df22SAndroid Build Coastguard Worker * modified drmOpen to handle both busid and name
1429*7688df22SAndroid Build Coastguard Worker * revision 1.3.x = added server + memory manager
1430*7688df22SAndroid Build Coastguard Worker */
1431*7688df22SAndroid Build Coastguard Worker version->version_major = 1;
1432*7688df22SAndroid Build Coastguard Worker version->version_minor = 3;
1433*7688df22SAndroid Build Coastguard Worker version->version_patchlevel = 0;
1434*7688df22SAndroid Build Coastguard Worker
1435*7688df22SAndroid Build Coastguard Worker return (drmVersionPtr)version;
1436*7688df22SAndroid Build Coastguard Worker }
1437*7688df22SAndroid Build Coastguard Worker
drmGetCap(int fd,uint64_t capability,uint64_t * value)1438*7688df22SAndroid Build Coastguard Worker drm_public int drmGetCap(int fd, uint64_t capability, uint64_t *value)
1439*7688df22SAndroid Build Coastguard Worker {
1440*7688df22SAndroid Build Coastguard Worker struct drm_get_cap cap;
1441*7688df22SAndroid Build Coastguard Worker int ret;
1442*7688df22SAndroid Build Coastguard Worker
1443*7688df22SAndroid Build Coastguard Worker memclear(cap);
1444*7688df22SAndroid Build Coastguard Worker cap.capability = capability;
1445*7688df22SAndroid Build Coastguard Worker
1446*7688df22SAndroid Build Coastguard Worker ret = drmIoctl(fd, DRM_IOCTL_GET_CAP, &cap);
1447*7688df22SAndroid Build Coastguard Worker if (ret)
1448*7688df22SAndroid Build Coastguard Worker return ret;
1449*7688df22SAndroid Build Coastguard Worker
1450*7688df22SAndroid Build Coastguard Worker *value = cap.value;
1451*7688df22SAndroid Build Coastguard Worker return 0;
1452*7688df22SAndroid Build Coastguard Worker }
1453*7688df22SAndroid Build Coastguard Worker
drmSetClientCap(int fd,uint64_t capability,uint64_t value)1454*7688df22SAndroid Build Coastguard Worker drm_public int drmSetClientCap(int fd, uint64_t capability, uint64_t value)
1455*7688df22SAndroid Build Coastguard Worker {
1456*7688df22SAndroid Build Coastguard Worker struct drm_set_client_cap cap;
1457*7688df22SAndroid Build Coastguard Worker
1458*7688df22SAndroid Build Coastguard Worker memclear(cap);
1459*7688df22SAndroid Build Coastguard Worker cap.capability = capability;
1460*7688df22SAndroid Build Coastguard Worker cap.value = value;
1461*7688df22SAndroid Build Coastguard Worker
1462*7688df22SAndroid Build Coastguard Worker return drmIoctl(fd, DRM_IOCTL_SET_CLIENT_CAP, &cap);
1463*7688df22SAndroid Build Coastguard Worker }
1464*7688df22SAndroid Build Coastguard Worker
1465*7688df22SAndroid Build Coastguard Worker /**
1466*7688df22SAndroid Build Coastguard Worker * Free the bus ID information.
1467*7688df22SAndroid Build Coastguard Worker *
1468*7688df22SAndroid Build Coastguard Worker * \param busid bus ID information string as given by drmGetBusid().
1469*7688df22SAndroid Build Coastguard Worker *
1470*7688df22SAndroid Build Coastguard Worker * \internal
1471*7688df22SAndroid Build Coastguard Worker * This function is just frees the memory pointed by \p busid.
1472*7688df22SAndroid Build Coastguard Worker */
drmFreeBusid(const char * busid)1473*7688df22SAndroid Build Coastguard Worker drm_public void drmFreeBusid(const char *busid)
1474*7688df22SAndroid Build Coastguard Worker {
1475*7688df22SAndroid Build Coastguard Worker drmFree((void *)busid);
1476*7688df22SAndroid Build Coastguard Worker }
1477*7688df22SAndroid Build Coastguard Worker
1478*7688df22SAndroid Build Coastguard Worker
1479*7688df22SAndroid Build Coastguard Worker /**
1480*7688df22SAndroid Build Coastguard Worker * Get the bus ID of the device.
1481*7688df22SAndroid Build Coastguard Worker *
1482*7688df22SAndroid Build Coastguard Worker * \param fd file descriptor.
1483*7688df22SAndroid Build Coastguard Worker *
1484*7688df22SAndroid Build Coastguard Worker * \return bus ID string.
1485*7688df22SAndroid Build Coastguard Worker *
1486*7688df22SAndroid Build Coastguard Worker * \internal
1487*7688df22SAndroid Build Coastguard Worker * This function gets the bus ID via successive DRM_IOCTL_GET_UNIQUE ioctls to
1488*7688df22SAndroid Build Coastguard Worker * get the string length and data, passing the arguments in a drm_unique
1489*7688df22SAndroid Build Coastguard Worker * structure.
1490*7688df22SAndroid Build Coastguard Worker */
drmGetBusid(int fd)1491*7688df22SAndroid Build Coastguard Worker drm_public char *drmGetBusid(int fd)
1492*7688df22SAndroid Build Coastguard Worker {
1493*7688df22SAndroid Build Coastguard Worker drm_unique_t u;
1494*7688df22SAndroid Build Coastguard Worker
1495*7688df22SAndroid Build Coastguard Worker memclear(u);
1496*7688df22SAndroid Build Coastguard Worker
1497*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_GET_UNIQUE, &u))
1498*7688df22SAndroid Build Coastguard Worker return NULL;
1499*7688df22SAndroid Build Coastguard Worker u.unique = drmMalloc(u.unique_len + 1);
1500*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_GET_UNIQUE, &u)) {
1501*7688df22SAndroid Build Coastguard Worker drmFree(u.unique);
1502*7688df22SAndroid Build Coastguard Worker return NULL;
1503*7688df22SAndroid Build Coastguard Worker }
1504*7688df22SAndroid Build Coastguard Worker u.unique[u.unique_len] = '\0';
1505*7688df22SAndroid Build Coastguard Worker
1506*7688df22SAndroid Build Coastguard Worker return u.unique;
1507*7688df22SAndroid Build Coastguard Worker }
1508*7688df22SAndroid Build Coastguard Worker
1509*7688df22SAndroid Build Coastguard Worker
1510*7688df22SAndroid Build Coastguard Worker /**
1511*7688df22SAndroid Build Coastguard Worker * Set the bus ID of the device.
1512*7688df22SAndroid Build Coastguard Worker *
1513*7688df22SAndroid Build Coastguard Worker * \param fd file descriptor.
1514*7688df22SAndroid Build Coastguard Worker * \param busid bus ID string.
1515*7688df22SAndroid Build Coastguard Worker *
1516*7688df22SAndroid Build Coastguard Worker * \return zero on success, negative on failure.
1517*7688df22SAndroid Build Coastguard Worker *
1518*7688df22SAndroid Build Coastguard Worker * \internal
1519*7688df22SAndroid Build Coastguard Worker * This function is a wrapper around the DRM_IOCTL_SET_UNIQUE ioctl, passing
1520*7688df22SAndroid Build Coastguard Worker * the arguments in a drm_unique structure.
1521*7688df22SAndroid Build Coastguard Worker */
drmSetBusid(int fd,const char * busid)1522*7688df22SAndroid Build Coastguard Worker drm_public int drmSetBusid(int fd, const char *busid)
1523*7688df22SAndroid Build Coastguard Worker {
1524*7688df22SAndroid Build Coastguard Worker drm_unique_t u;
1525*7688df22SAndroid Build Coastguard Worker
1526*7688df22SAndroid Build Coastguard Worker memclear(u);
1527*7688df22SAndroid Build Coastguard Worker u.unique = (char *)busid;
1528*7688df22SAndroid Build Coastguard Worker u.unique_len = strlen(busid);
1529*7688df22SAndroid Build Coastguard Worker
1530*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_SET_UNIQUE, &u)) {
1531*7688df22SAndroid Build Coastguard Worker return -errno;
1532*7688df22SAndroid Build Coastguard Worker }
1533*7688df22SAndroid Build Coastguard Worker return 0;
1534*7688df22SAndroid Build Coastguard Worker }
1535*7688df22SAndroid Build Coastguard Worker
drmGetMagic(int fd,drm_magic_t * magic)1536*7688df22SAndroid Build Coastguard Worker drm_public int drmGetMagic(int fd, drm_magic_t * magic)
1537*7688df22SAndroid Build Coastguard Worker {
1538*7688df22SAndroid Build Coastguard Worker drm_auth_t auth;
1539*7688df22SAndroid Build Coastguard Worker
1540*7688df22SAndroid Build Coastguard Worker memclear(auth);
1541*7688df22SAndroid Build Coastguard Worker
1542*7688df22SAndroid Build Coastguard Worker *magic = 0;
1543*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_GET_MAGIC, &auth))
1544*7688df22SAndroid Build Coastguard Worker return -errno;
1545*7688df22SAndroid Build Coastguard Worker *magic = auth.magic;
1546*7688df22SAndroid Build Coastguard Worker return 0;
1547*7688df22SAndroid Build Coastguard Worker }
1548*7688df22SAndroid Build Coastguard Worker
drmAuthMagic(int fd,drm_magic_t magic)1549*7688df22SAndroid Build Coastguard Worker drm_public int drmAuthMagic(int fd, drm_magic_t magic)
1550*7688df22SAndroid Build Coastguard Worker {
1551*7688df22SAndroid Build Coastguard Worker drm_auth_t auth;
1552*7688df22SAndroid Build Coastguard Worker
1553*7688df22SAndroid Build Coastguard Worker memclear(auth);
1554*7688df22SAndroid Build Coastguard Worker auth.magic = magic;
1555*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_AUTH_MAGIC, &auth))
1556*7688df22SAndroid Build Coastguard Worker return -errno;
1557*7688df22SAndroid Build Coastguard Worker return 0;
1558*7688df22SAndroid Build Coastguard Worker }
1559*7688df22SAndroid Build Coastguard Worker
1560*7688df22SAndroid Build Coastguard Worker /**
1561*7688df22SAndroid Build Coastguard Worker * Specifies a range of memory that is available for mapping by a
1562*7688df22SAndroid Build Coastguard Worker * non-root process.
1563*7688df22SAndroid Build Coastguard Worker *
1564*7688df22SAndroid Build Coastguard Worker * \param fd file descriptor.
1565*7688df22SAndroid Build Coastguard Worker * \param offset usually the physical address. The actual meaning depends of
1566*7688df22SAndroid Build Coastguard Worker * the \p type parameter. See below.
1567*7688df22SAndroid Build Coastguard Worker * \param size of the memory in bytes.
1568*7688df22SAndroid Build Coastguard Worker * \param type type of the memory to be mapped.
1569*7688df22SAndroid Build Coastguard Worker * \param flags combination of several flags to modify the function actions.
1570*7688df22SAndroid Build Coastguard Worker * \param handle will be set to a value that may be used as the offset
1571*7688df22SAndroid Build Coastguard Worker * parameter for mmap().
1572*7688df22SAndroid Build Coastguard Worker *
1573*7688df22SAndroid Build Coastguard Worker * \return zero on success or a negative value on error.
1574*7688df22SAndroid Build Coastguard Worker *
1575*7688df22SAndroid Build Coastguard Worker * \par Mapping the frame buffer
1576*7688df22SAndroid Build Coastguard Worker * For the frame buffer
1577*7688df22SAndroid Build Coastguard Worker * - \p offset will be the physical address of the start of the frame buffer,
1578*7688df22SAndroid Build Coastguard Worker * - \p size will be the size of the frame buffer in bytes, and
1579*7688df22SAndroid Build Coastguard Worker * - \p type will be DRM_FRAME_BUFFER.
1580*7688df22SAndroid Build Coastguard Worker *
1581*7688df22SAndroid Build Coastguard Worker * \par
1582*7688df22SAndroid Build Coastguard Worker * The area mapped will be uncached. If MTRR support is available in the
1583*7688df22SAndroid Build Coastguard Worker * kernel, the frame buffer area will be set to write combining.
1584*7688df22SAndroid Build Coastguard Worker *
1585*7688df22SAndroid Build Coastguard Worker * \par Mapping the MMIO register area
1586*7688df22SAndroid Build Coastguard Worker * For the MMIO register area,
1587*7688df22SAndroid Build Coastguard Worker * - \p offset will be the physical address of the start of the register area,
1588*7688df22SAndroid Build Coastguard Worker * - \p size will be the size of the register area bytes, and
1589*7688df22SAndroid Build Coastguard Worker * - \p type will be DRM_REGISTERS.
1590*7688df22SAndroid Build Coastguard Worker * \par
1591*7688df22SAndroid Build Coastguard Worker * The area mapped will be uncached.
1592*7688df22SAndroid Build Coastguard Worker *
1593*7688df22SAndroid Build Coastguard Worker * \par Mapping the SAREA
1594*7688df22SAndroid Build Coastguard Worker * For the SAREA,
1595*7688df22SAndroid Build Coastguard Worker * - \p offset will be ignored and should be set to zero,
1596*7688df22SAndroid Build Coastguard Worker * - \p size will be the desired size of the SAREA in bytes,
1597*7688df22SAndroid Build Coastguard Worker * - \p type will be DRM_SHM.
1598*7688df22SAndroid Build Coastguard Worker *
1599*7688df22SAndroid Build Coastguard Worker * \par
1600*7688df22SAndroid Build Coastguard Worker * A shared memory area of the requested size will be created and locked in
1601*7688df22SAndroid Build Coastguard Worker * kernel memory. This area may be mapped into client-space by using the handle
1602*7688df22SAndroid Build Coastguard Worker * returned.
1603*7688df22SAndroid Build Coastguard Worker *
1604*7688df22SAndroid Build Coastguard Worker * \note May only be called by root.
1605*7688df22SAndroid Build Coastguard Worker *
1606*7688df22SAndroid Build Coastguard Worker * \internal
1607*7688df22SAndroid Build Coastguard Worker * This function is a wrapper around the DRM_IOCTL_ADD_MAP ioctl, passing
1608*7688df22SAndroid Build Coastguard Worker * the arguments in a drm_map structure.
1609*7688df22SAndroid Build Coastguard Worker */
drmAddMap(int fd,drm_handle_t offset,drmSize size,drmMapType type,drmMapFlags flags,drm_handle_t * handle)1610*7688df22SAndroid Build Coastguard Worker drm_public int drmAddMap(int fd, drm_handle_t offset, drmSize size, drmMapType type,
1611*7688df22SAndroid Build Coastguard Worker drmMapFlags flags, drm_handle_t *handle)
1612*7688df22SAndroid Build Coastguard Worker {
1613*7688df22SAndroid Build Coastguard Worker drm_map_t map;
1614*7688df22SAndroid Build Coastguard Worker
1615*7688df22SAndroid Build Coastguard Worker memclear(map);
1616*7688df22SAndroid Build Coastguard Worker map.offset = offset;
1617*7688df22SAndroid Build Coastguard Worker map.size = size;
1618*7688df22SAndroid Build Coastguard Worker map.type = (enum drm_map_type)type;
1619*7688df22SAndroid Build Coastguard Worker map.flags = (enum drm_map_flags)flags;
1620*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_ADD_MAP, &map))
1621*7688df22SAndroid Build Coastguard Worker return -errno;
1622*7688df22SAndroid Build Coastguard Worker if (handle)
1623*7688df22SAndroid Build Coastguard Worker *handle = (drm_handle_t)(uintptr_t)map.handle;
1624*7688df22SAndroid Build Coastguard Worker return 0;
1625*7688df22SAndroid Build Coastguard Worker }
1626*7688df22SAndroid Build Coastguard Worker
drmRmMap(int fd,drm_handle_t handle)1627*7688df22SAndroid Build Coastguard Worker drm_public int drmRmMap(int fd, drm_handle_t handle)
1628*7688df22SAndroid Build Coastguard Worker {
1629*7688df22SAndroid Build Coastguard Worker drm_map_t map;
1630*7688df22SAndroid Build Coastguard Worker
1631*7688df22SAndroid Build Coastguard Worker memclear(map);
1632*7688df22SAndroid Build Coastguard Worker map.handle = (void *)(uintptr_t)handle;
1633*7688df22SAndroid Build Coastguard Worker
1634*7688df22SAndroid Build Coastguard Worker if(drmIoctl(fd, DRM_IOCTL_RM_MAP, &map))
1635*7688df22SAndroid Build Coastguard Worker return -errno;
1636*7688df22SAndroid Build Coastguard Worker return 0;
1637*7688df22SAndroid Build Coastguard Worker }
1638*7688df22SAndroid Build Coastguard Worker
1639*7688df22SAndroid Build Coastguard Worker /**
1640*7688df22SAndroid Build Coastguard Worker * Make buffers available for DMA transfers.
1641*7688df22SAndroid Build Coastguard Worker *
1642*7688df22SAndroid Build Coastguard Worker * \param fd file descriptor.
1643*7688df22SAndroid Build Coastguard Worker * \param count number of buffers.
1644*7688df22SAndroid Build Coastguard Worker * \param size size of each buffer.
1645*7688df22SAndroid Build Coastguard Worker * \param flags buffer allocation flags.
1646*7688df22SAndroid Build Coastguard Worker * \param agp_offset offset in the AGP aperture
1647*7688df22SAndroid Build Coastguard Worker *
1648*7688df22SAndroid Build Coastguard Worker * \return number of buffers allocated, negative on error.
1649*7688df22SAndroid Build Coastguard Worker *
1650*7688df22SAndroid Build Coastguard Worker * \internal
1651*7688df22SAndroid Build Coastguard Worker * This function is a wrapper around DRM_IOCTL_ADD_BUFS ioctl.
1652*7688df22SAndroid Build Coastguard Worker *
1653*7688df22SAndroid Build Coastguard Worker * \sa drm_buf_desc.
1654*7688df22SAndroid Build Coastguard Worker */
drmAddBufs(int fd,int count,int size,drmBufDescFlags flags,int agp_offset)1655*7688df22SAndroid Build Coastguard Worker drm_public int drmAddBufs(int fd, int count, int size, drmBufDescFlags flags,
1656*7688df22SAndroid Build Coastguard Worker int agp_offset)
1657*7688df22SAndroid Build Coastguard Worker {
1658*7688df22SAndroid Build Coastguard Worker drm_buf_desc_t request;
1659*7688df22SAndroid Build Coastguard Worker
1660*7688df22SAndroid Build Coastguard Worker memclear(request);
1661*7688df22SAndroid Build Coastguard Worker request.count = count;
1662*7688df22SAndroid Build Coastguard Worker request.size = size;
1663*7688df22SAndroid Build Coastguard Worker request.flags = (int)flags;
1664*7688df22SAndroid Build Coastguard Worker request.agp_start = agp_offset;
1665*7688df22SAndroid Build Coastguard Worker
1666*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_ADD_BUFS, &request))
1667*7688df22SAndroid Build Coastguard Worker return -errno;
1668*7688df22SAndroid Build Coastguard Worker return request.count;
1669*7688df22SAndroid Build Coastguard Worker }
1670*7688df22SAndroid Build Coastguard Worker
drmMarkBufs(int fd,double low,double high)1671*7688df22SAndroid Build Coastguard Worker drm_public int drmMarkBufs(int fd, double low, double high)
1672*7688df22SAndroid Build Coastguard Worker {
1673*7688df22SAndroid Build Coastguard Worker drm_buf_info_t info;
1674*7688df22SAndroid Build Coastguard Worker int i;
1675*7688df22SAndroid Build Coastguard Worker
1676*7688df22SAndroid Build Coastguard Worker memclear(info);
1677*7688df22SAndroid Build Coastguard Worker
1678*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info))
1679*7688df22SAndroid Build Coastguard Worker return -EINVAL;
1680*7688df22SAndroid Build Coastguard Worker
1681*7688df22SAndroid Build Coastguard Worker if (!info.count)
1682*7688df22SAndroid Build Coastguard Worker return -EINVAL;
1683*7688df22SAndroid Build Coastguard Worker
1684*7688df22SAndroid Build Coastguard Worker if (!(info.list = drmMalloc(info.count * sizeof(*info.list))))
1685*7688df22SAndroid Build Coastguard Worker return -ENOMEM;
1686*7688df22SAndroid Build Coastguard Worker
1687*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info)) {
1688*7688df22SAndroid Build Coastguard Worker int retval = -errno;
1689*7688df22SAndroid Build Coastguard Worker drmFree(info.list);
1690*7688df22SAndroid Build Coastguard Worker return retval;
1691*7688df22SAndroid Build Coastguard Worker }
1692*7688df22SAndroid Build Coastguard Worker
1693*7688df22SAndroid Build Coastguard Worker for (i = 0; i < info.count; i++) {
1694*7688df22SAndroid Build Coastguard Worker info.list[i].low_mark = low * info.list[i].count;
1695*7688df22SAndroid Build Coastguard Worker info.list[i].high_mark = high * info.list[i].count;
1696*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_MARK_BUFS, &info.list[i])) {
1697*7688df22SAndroid Build Coastguard Worker int retval = -errno;
1698*7688df22SAndroid Build Coastguard Worker drmFree(info.list);
1699*7688df22SAndroid Build Coastguard Worker return retval;
1700*7688df22SAndroid Build Coastguard Worker }
1701*7688df22SAndroid Build Coastguard Worker }
1702*7688df22SAndroid Build Coastguard Worker drmFree(info.list);
1703*7688df22SAndroid Build Coastguard Worker
1704*7688df22SAndroid Build Coastguard Worker return 0;
1705*7688df22SAndroid Build Coastguard Worker }
1706*7688df22SAndroid Build Coastguard Worker
1707*7688df22SAndroid Build Coastguard Worker /**
1708*7688df22SAndroid Build Coastguard Worker * Free buffers.
1709*7688df22SAndroid Build Coastguard Worker *
1710*7688df22SAndroid Build Coastguard Worker * \param fd file descriptor.
1711*7688df22SAndroid Build Coastguard Worker * \param count number of buffers to free.
1712*7688df22SAndroid Build Coastguard Worker * \param list list of buffers to be freed.
1713*7688df22SAndroid Build Coastguard Worker *
1714*7688df22SAndroid Build Coastguard Worker * \return zero on success, or a negative value on failure.
1715*7688df22SAndroid Build Coastguard Worker *
1716*7688df22SAndroid Build Coastguard Worker * \note This function is primarily used for debugging.
1717*7688df22SAndroid Build Coastguard Worker *
1718*7688df22SAndroid Build Coastguard Worker * \internal
1719*7688df22SAndroid Build Coastguard Worker * This function is a wrapper around the DRM_IOCTL_FREE_BUFS ioctl, passing
1720*7688df22SAndroid Build Coastguard Worker * the arguments in a drm_buf_free structure.
1721*7688df22SAndroid Build Coastguard Worker */
drmFreeBufs(int fd,int count,int * list)1722*7688df22SAndroid Build Coastguard Worker drm_public int drmFreeBufs(int fd, int count, int *list)
1723*7688df22SAndroid Build Coastguard Worker {
1724*7688df22SAndroid Build Coastguard Worker drm_buf_free_t request;
1725*7688df22SAndroid Build Coastguard Worker
1726*7688df22SAndroid Build Coastguard Worker memclear(request);
1727*7688df22SAndroid Build Coastguard Worker request.count = count;
1728*7688df22SAndroid Build Coastguard Worker request.list = list;
1729*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_FREE_BUFS, &request))
1730*7688df22SAndroid Build Coastguard Worker return -errno;
1731*7688df22SAndroid Build Coastguard Worker return 0;
1732*7688df22SAndroid Build Coastguard Worker }
1733*7688df22SAndroid Build Coastguard Worker
1734*7688df22SAndroid Build Coastguard Worker
1735*7688df22SAndroid Build Coastguard Worker /**
1736*7688df22SAndroid Build Coastguard Worker * Close the device.
1737*7688df22SAndroid Build Coastguard Worker *
1738*7688df22SAndroid Build Coastguard Worker * \param fd file descriptor.
1739*7688df22SAndroid Build Coastguard Worker *
1740*7688df22SAndroid Build Coastguard Worker * \internal
1741*7688df22SAndroid Build Coastguard Worker * This function closes the file descriptor.
1742*7688df22SAndroid Build Coastguard Worker */
drmClose(int fd)1743*7688df22SAndroid Build Coastguard Worker drm_public int drmClose(int fd)
1744*7688df22SAndroid Build Coastguard Worker {
1745*7688df22SAndroid Build Coastguard Worker unsigned long key = drmGetKeyFromFd(fd);
1746*7688df22SAndroid Build Coastguard Worker drmHashEntry *entry = drmGetEntry(fd);
1747*7688df22SAndroid Build Coastguard Worker
1748*7688df22SAndroid Build Coastguard Worker drmHashDestroy(entry->tagTable);
1749*7688df22SAndroid Build Coastguard Worker entry->fd = 0;
1750*7688df22SAndroid Build Coastguard Worker entry->f = NULL;
1751*7688df22SAndroid Build Coastguard Worker entry->tagTable = NULL;
1752*7688df22SAndroid Build Coastguard Worker
1753*7688df22SAndroid Build Coastguard Worker drmHashDelete(drmHashTable, key);
1754*7688df22SAndroid Build Coastguard Worker drmFree(entry);
1755*7688df22SAndroid Build Coastguard Worker
1756*7688df22SAndroid Build Coastguard Worker return close(fd);
1757*7688df22SAndroid Build Coastguard Worker }
1758*7688df22SAndroid Build Coastguard Worker
1759*7688df22SAndroid Build Coastguard Worker
1760*7688df22SAndroid Build Coastguard Worker /**
1761*7688df22SAndroid Build Coastguard Worker * Map a region of memory.
1762*7688df22SAndroid Build Coastguard Worker *
1763*7688df22SAndroid Build Coastguard Worker * \param fd file descriptor.
1764*7688df22SAndroid Build Coastguard Worker * \param handle handle returned by drmAddMap().
1765*7688df22SAndroid Build Coastguard Worker * \param size size in bytes. Must match the size used by drmAddMap().
1766*7688df22SAndroid Build Coastguard Worker * \param address will contain the user-space virtual address where the mapping
1767*7688df22SAndroid Build Coastguard Worker * begins.
1768*7688df22SAndroid Build Coastguard Worker *
1769*7688df22SAndroid Build Coastguard Worker * \return zero on success, or a negative value on failure.
1770*7688df22SAndroid Build Coastguard Worker *
1771*7688df22SAndroid Build Coastguard Worker * \internal
1772*7688df22SAndroid Build Coastguard Worker * This function is a wrapper for mmap().
1773*7688df22SAndroid Build Coastguard Worker */
drmMap(int fd,drm_handle_t handle,drmSize size,drmAddressPtr address)1774*7688df22SAndroid Build Coastguard Worker drm_public int drmMap(int fd, drm_handle_t handle, drmSize size,
1775*7688df22SAndroid Build Coastguard Worker drmAddressPtr address)
1776*7688df22SAndroid Build Coastguard Worker {
1777*7688df22SAndroid Build Coastguard Worker static unsigned long pagesize_mask = 0;
1778*7688df22SAndroid Build Coastguard Worker
1779*7688df22SAndroid Build Coastguard Worker if (fd < 0)
1780*7688df22SAndroid Build Coastguard Worker return -EINVAL;
1781*7688df22SAndroid Build Coastguard Worker
1782*7688df22SAndroid Build Coastguard Worker if (!pagesize_mask)
1783*7688df22SAndroid Build Coastguard Worker pagesize_mask = getpagesize() - 1;
1784*7688df22SAndroid Build Coastguard Worker
1785*7688df22SAndroid Build Coastguard Worker size = (size + pagesize_mask) & ~pagesize_mask;
1786*7688df22SAndroid Build Coastguard Worker
1787*7688df22SAndroid Build Coastguard Worker *address = drm_mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, handle);
1788*7688df22SAndroid Build Coastguard Worker if (*address == MAP_FAILED)
1789*7688df22SAndroid Build Coastguard Worker return -errno;
1790*7688df22SAndroid Build Coastguard Worker return 0;
1791*7688df22SAndroid Build Coastguard Worker }
1792*7688df22SAndroid Build Coastguard Worker
1793*7688df22SAndroid Build Coastguard Worker
1794*7688df22SAndroid Build Coastguard Worker /**
1795*7688df22SAndroid Build Coastguard Worker * Unmap mappings obtained with drmMap().
1796*7688df22SAndroid Build Coastguard Worker *
1797*7688df22SAndroid Build Coastguard Worker * \param address address as given by drmMap().
1798*7688df22SAndroid Build Coastguard Worker * \param size size in bytes. Must match the size used by drmMap().
1799*7688df22SAndroid Build Coastguard Worker *
1800*7688df22SAndroid Build Coastguard Worker * \return zero on success, or a negative value on failure.
1801*7688df22SAndroid Build Coastguard Worker *
1802*7688df22SAndroid Build Coastguard Worker * \internal
1803*7688df22SAndroid Build Coastguard Worker * This function is a wrapper for munmap().
1804*7688df22SAndroid Build Coastguard Worker */
drmUnmap(drmAddress address,drmSize size)1805*7688df22SAndroid Build Coastguard Worker drm_public int drmUnmap(drmAddress address, drmSize size)
1806*7688df22SAndroid Build Coastguard Worker {
1807*7688df22SAndroid Build Coastguard Worker return drm_munmap(address, size);
1808*7688df22SAndroid Build Coastguard Worker }
1809*7688df22SAndroid Build Coastguard Worker
drmGetBufInfo(int fd)1810*7688df22SAndroid Build Coastguard Worker drm_public drmBufInfoPtr drmGetBufInfo(int fd)
1811*7688df22SAndroid Build Coastguard Worker {
1812*7688df22SAndroid Build Coastguard Worker drm_buf_info_t info;
1813*7688df22SAndroid Build Coastguard Worker drmBufInfoPtr retval;
1814*7688df22SAndroid Build Coastguard Worker int i;
1815*7688df22SAndroid Build Coastguard Worker
1816*7688df22SAndroid Build Coastguard Worker memclear(info);
1817*7688df22SAndroid Build Coastguard Worker
1818*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info))
1819*7688df22SAndroid Build Coastguard Worker return NULL;
1820*7688df22SAndroid Build Coastguard Worker
1821*7688df22SAndroid Build Coastguard Worker if (info.count) {
1822*7688df22SAndroid Build Coastguard Worker if (!(info.list = drmMalloc(info.count * sizeof(*info.list))))
1823*7688df22SAndroid Build Coastguard Worker return NULL;
1824*7688df22SAndroid Build Coastguard Worker
1825*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info)) {
1826*7688df22SAndroid Build Coastguard Worker drmFree(info.list);
1827*7688df22SAndroid Build Coastguard Worker return NULL;
1828*7688df22SAndroid Build Coastguard Worker }
1829*7688df22SAndroid Build Coastguard Worker
1830*7688df22SAndroid Build Coastguard Worker retval = drmMalloc(sizeof(*retval));
1831*7688df22SAndroid Build Coastguard Worker retval->count = info.count;
1832*7688df22SAndroid Build Coastguard Worker if (!(retval->list = drmMalloc(info.count * sizeof(*retval->list)))) {
1833*7688df22SAndroid Build Coastguard Worker drmFree(retval);
1834*7688df22SAndroid Build Coastguard Worker drmFree(info.list);
1835*7688df22SAndroid Build Coastguard Worker return NULL;
1836*7688df22SAndroid Build Coastguard Worker }
1837*7688df22SAndroid Build Coastguard Worker
1838*7688df22SAndroid Build Coastguard Worker for (i = 0; i < info.count; i++) {
1839*7688df22SAndroid Build Coastguard Worker retval->list[i].count = info.list[i].count;
1840*7688df22SAndroid Build Coastguard Worker retval->list[i].size = info.list[i].size;
1841*7688df22SAndroid Build Coastguard Worker retval->list[i].low_mark = info.list[i].low_mark;
1842*7688df22SAndroid Build Coastguard Worker retval->list[i].high_mark = info.list[i].high_mark;
1843*7688df22SAndroid Build Coastguard Worker }
1844*7688df22SAndroid Build Coastguard Worker drmFree(info.list);
1845*7688df22SAndroid Build Coastguard Worker return retval;
1846*7688df22SAndroid Build Coastguard Worker }
1847*7688df22SAndroid Build Coastguard Worker return NULL;
1848*7688df22SAndroid Build Coastguard Worker }
1849*7688df22SAndroid Build Coastguard Worker
1850*7688df22SAndroid Build Coastguard Worker /**
1851*7688df22SAndroid Build Coastguard Worker * Map all DMA buffers into client-virtual space.
1852*7688df22SAndroid Build Coastguard Worker *
1853*7688df22SAndroid Build Coastguard Worker * \param fd file descriptor.
1854*7688df22SAndroid Build Coastguard Worker *
1855*7688df22SAndroid Build Coastguard Worker * \return a pointer to a ::drmBufMap structure.
1856*7688df22SAndroid Build Coastguard Worker *
1857*7688df22SAndroid Build Coastguard Worker * \note The client may not use these buffers until obtaining buffer indices
1858*7688df22SAndroid Build Coastguard Worker * with drmDMA().
1859*7688df22SAndroid Build Coastguard Worker *
1860*7688df22SAndroid Build Coastguard Worker * \internal
1861*7688df22SAndroid Build Coastguard Worker * This function calls the DRM_IOCTL_MAP_BUFS ioctl and copies the returned
1862*7688df22SAndroid Build Coastguard Worker * information about the buffers in a drm_buf_map structure into the
1863*7688df22SAndroid Build Coastguard Worker * client-visible data structures.
1864*7688df22SAndroid Build Coastguard Worker */
drmMapBufs(int fd)1865*7688df22SAndroid Build Coastguard Worker drm_public drmBufMapPtr drmMapBufs(int fd)
1866*7688df22SAndroid Build Coastguard Worker {
1867*7688df22SAndroid Build Coastguard Worker drm_buf_map_t bufs;
1868*7688df22SAndroid Build Coastguard Worker drmBufMapPtr retval;
1869*7688df22SAndroid Build Coastguard Worker int i;
1870*7688df22SAndroid Build Coastguard Worker
1871*7688df22SAndroid Build Coastguard Worker memclear(bufs);
1872*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_MAP_BUFS, &bufs))
1873*7688df22SAndroid Build Coastguard Worker return NULL;
1874*7688df22SAndroid Build Coastguard Worker
1875*7688df22SAndroid Build Coastguard Worker if (!bufs.count)
1876*7688df22SAndroid Build Coastguard Worker return NULL;
1877*7688df22SAndroid Build Coastguard Worker
1878*7688df22SAndroid Build Coastguard Worker if (!(bufs.list = drmMalloc(bufs.count * sizeof(*bufs.list))))
1879*7688df22SAndroid Build Coastguard Worker return NULL;
1880*7688df22SAndroid Build Coastguard Worker
1881*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_MAP_BUFS, &bufs)) {
1882*7688df22SAndroid Build Coastguard Worker drmFree(bufs.list);
1883*7688df22SAndroid Build Coastguard Worker return NULL;
1884*7688df22SAndroid Build Coastguard Worker }
1885*7688df22SAndroid Build Coastguard Worker
1886*7688df22SAndroid Build Coastguard Worker retval = drmMalloc(sizeof(*retval));
1887*7688df22SAndroid Build Coastguard Worker retval->count = bufs.count;
1888*7688df22SAndroid Build Coastguard Worker retval->list = drmMalloc(bufs.count * sizeof(*retval->list));
1889*7688df22SAndroid Build Coastguard Worker for (i = 0; i < bufs.count; i++) {
1890*7688df22SAndroid Build Coastguard Worker retval->list[i].idx = bufs.list[i].idx;
1891*7688df22SAndroid Build Coastguard Worker retval->list[i].total = bufs.list[i].total;
1892*7688df22SAndroid Build Coastguard Worker retval->list[i].used = 0;
1893*7688df22SAndroid Build Coastguard Worker retval->list[i].address = bufs.list[i].address;
1894*7688df22SAndroid Build Coastguard Worker }
1895*7688df22SAndroid Build Coastguard Worker
1896*7688df22SAndroid Build Coastguard Worker drmFree(bufs.list);
1897*7688df22SAndroid Build Coastguard Worker return retval;
1898*7688df22SAndroid Build Coastguard Worker }
1899*7688df22SAndroid Build Coastguard Worker
1900*7688df22SAndroid Build Coastguard Worker
1901*7688df22SAndroid Build Coastguard Worker /**
1902*7688df22SAndroid Build Coastguard Worker * Unmap buffers allocated with drmMapBufs().
1903*7688df22SAndroid Build Coastguard Worker *
1904*7688df22SAndroid Build Coastguard Worker * \return zero on success, or negative value on failure.
1905*7688df22SAndroid Build Coastguard Worker *
1906*7688df22SAndroid Build Coastguard Worker * \internal
1907*7688df22SAndroid Build Coastguard Worker * Calls munmap() for every buffer stored in \p bufs and frees the
1908*7688df22SAndroid Build Coastguard Worker * memory allocated by drmMapBufs().
1909*7688df22SAndroid Build Coastguard Worker */
drmUnmapBufs(drmBufMapPtr bufs)1910*7688df22SAndroid Build Coastguard Worker drm_public int drmUnmapBufs(drmBufMapPtr bufs)
1911*7688df22SAndroid Build Coastguard Worker {
1912*7688df22SAndroid Build Coastguard Worker int i;
1913*7688df22SAndroid Build Coastguard Worker
1914*7688df22SAndroid Build Coastguard Worker for (i = 0; i < bufs->count; i++) {
1915*7688df22SAndroid Build Coastguard Worker drm_munmap(bufs->list[i].address, bufs->list[i].total);
1916*7688df22SAndroid Build Coastguard Worker }
1917*7688df22SAndroid Build Coastguard Worker
1918*7688df22SAndroid Build Coastguard Worker drmFree(bufs->list);
1919*7688df22SAndroid Build Coastguard Worker drmFree(bufs);
1920*7688df22SAndroid Build Coastguard Worker return 0;
1921*7688df22SAndroid Build Coastguard Worker }
1922*7688df22SAndroid Build Coastguard Worker
1923*7688df22SAndroid Build Coastguard Worker
1924*7688df22SAndroid Build Coastguard Worker #define DRM_DMA_RETRY 16
1925*7688df22SAndroid Build Coastguard Worker
1926*7688df22SAndroid Build Coastguard Worker /**
1927*7688df22SAndroid Build Coastguard Worker * Reserve DMA buffers.
1928*7688df22SAndroid Build Coastguard Worker *
1929*7688df22SAndroid Build Coastguard Worker * \param fd file descriptor.
1930*7688df22SAndroid Build Coastguard Worker * \param request
1931*7688df22SAndroid Build Coastguard Worker *
1932*7688df22SAndroid Build Coastguard Worker * \return zero on success, or a negative value on failure.
1933*7688df22SAndroid Build Coastguard Worker *
1934*7688df22SAndroid Build Coastguard Worker * \internal
1935*7688df22SAndroid Build Coastguard Worker * Assemble the arguments into a drm_dma structure and keeps issuing the
1936*7688df22SAndroid Build Coastguard Worker * DRM_IOCTL_DMA ioctl until success or until maximum number of retries.
1937*7688df22SAndroid Build Coastguard Worker */
drmDMA(int fd,drmDMAReqPtr request)1938*7688df22SAndroid Build Coastguard Worker drm_public int drmDMA(int fd, drmDMAReqPtr request)
1939*7688df22SAndroid Build Coastguard Worker {
1940*7688df22SAndroid Build Coastguard Worker drm_dma_t dma;
1941*7688df22SAndroid Build Coastguard Worker int ret, i = 0;
1942*7688df22SAndroid Build Coastguard Worker
1943*7688df22SAndroid Build Coastguard Worker dma.context = request->context;
1944*7688df22SAndroid Build Coastguard Worker dma.send_count = request->send_count;
1945*7688df22SAndroid Build Coastguard Worker dma.send_indices = request->send_list;
1946*7688df22SAndroid Build Coastguard Worker dma.send_sizes = request->send_sizes;
1947*7688df22SAndroid Build Coastguard Worker dma.flags = (enum drm_dma_flags)request->flags;
1948*7688df22SAndroid Build Coastguard Worker dma.request_count = request->request_count;
1949*7688df22SAndroid Build Coastguard Worker dma.request_size = request->request_size;
1950*7688df22SAndroid Build Coastguard Worker dma.request_indices = request->request_list;
1951*7688df22SAndroid Build Coastguard Worker dma.request_sizes = request->request_sizes;
1952*7688df22SAndroid Build Coastguard Worker dma.granted_count = 0;
1953*7688df22SAndroid Build Coastguard Worker
1954*7688df22SAndroid Build Coastguard Worker do {
1955*7688df22SAndroid Build Coastguard Worker ret = ioctl( fd, DRM_IOCTL_DMA, &dma );
1956*7688df22SAndroid Build Coastguard Worker } while ( ret && errno == EAGAIN && i++ < DRM_DMA_RETRY );
1957*7688df22SAndroid Build Coastguard Worker
1958*7688df22SAndroid Build Coastguard Worker if ( ret == 0 ) {
1959*7688df22SAndroid Build Coastguard Worker request->granted_count = dma.granted_count;
1960*7688df22SAndroid Build Coastguard Worker return 0;
1961*7688df22SAndroid Build Coastguard Worker } else {
1962*7688df22SAndroid Build Coastguard Worker return -errno;
1963*7688df22SAndroid Build Coastguard Worker }
1964*7688df22SAndroid Build Coastguard Worker }
1965*7688df22SAndroid Build Coastguard Worker
1966*7688df22SAndroid Build Coastguard Worker
1967*7688df22SAndroid Build Coastguard Worker /**
1968*7688df22SAndroid Build Coastguard Worker * Obtain heavyweight hardware lock.
1969*7688df22SAndroid Build Coastguard Worker *
1970*7688df22SAndroid Build Coastguard Worker * \param fd file descriptor.
1971*7688df22SAndroid Build Coastguard Worker * \param context context.
1972*7688df22SAndroid Build Coastguard Worker * \param flags flags that determine the state of the hardware when the function
1973*7688df22SAndroid Build Coastguard Worker * returns.
1974*7688df22SAndroid Build Coastguard Worker *
1975*7688df22SAndroid Build Coastguard Worker * \return always zero.
1976*7688df22SAndroid Build Coastguard Worker *
1977*7688df22SAndroid Build Coastguard Worker * \internal
1978*7688df22SAndroid Build Coastguard Worker * This function translates the arguments into a drm_lock structure and issue
1979*7688df22SAndroid Build Coastguard Worker * the DRM_IOCTL_LOCK ioctl until the lock is successfully acquired.
1980*7688df22SAndroid Build Coastguard Worker */
drmGetLock(int fd,drm_context_t context,drmLockFlags flags)1981*7688df22SAndroid Build Coastguard Worker drm_public int drmGetLock(int fd, drm_context_t context, drmLockFlags flags)
1982*7688df22SAndroid Build Coastguard Worker {
1983*7688df22SAndroid Build Coastguard Worker drm_lock_t lock;
1984*7688df22SAndroid Build Coastguard Worker
1985*7688df22SAndroid Build Coastguard Worker memclear(lock);
1986*7688df22SAndroid Build Coastguard Worker lock.context = context;
1987*7688df22SAndroid Build Coastguard Worker lock.flags = 0;
1988*7688df22SAndroid Build Coastguard Worker if (flags & DRM_LOCK_READY) lock.flags |= _DRM_LOCK_READY;
1989*7688df22SAndroid Build Coastguard Worker if (flags & DRM_LOCK_QUIESCENT) lock.flags |= _DRM_LOCK_QUIESCENT;
1990*7688df22SAndroid Build Coastguard Worker if (flags & DRM_LOCK_FLUSH) lock.flags |= _DRM_LOCK_FLUSH;
1991*7688df22SAndroid Build Coastguard Worker if (flags & DRM_LOCK_FLUSH_ALL) lock.flags |= _DRM_LOCK_FLUSH_ALL;
1992*7688df22SAndroid Build Coastguard Worker if (flags & DRM_HALT_ALL_QUEUES) lock.flags |= _DRM_HALT_ALL_QUEUES;
1993*7688df22SAndroid Build Coastguard Worker if (flags & DRM_HALT_CUR_QUEUES) lock.flags |= _DRM_HALT_CUR_QUEUES;
1994*7688df22SAndroid Build Coastguard Worker
1995*7688df22SAndroid Build Coastguard Worker while (drmIoctl(fd, DRM_IOCTL_LOCK, &lock))
1996*7688df22SAndroid Build Coastguard Worker ;
1997*7688df22SAndroid Build Coastguard Worker return 0;
1998*7688df22SAndroid Build Coastguard Worker }
1999*7688df22SAndroid Build Coastguard Worker
2000*7688df22SAndroid Build Coastguard Worker /**
2001*7688df22SAndroid Build Coastguard Worker * Release the hardware lock.
2002*7688df22SAndroid Build Coastguard Worker *
2003*7688df22SAndroid Build Coastguard Worker * \param fd file descriptor.
2004*7688df22SAndroid Build Coastguard Worker * \param context context.
2005*7688df22SAndroid Build Coastguard Worker *
2006*7688df22SAndroid Build Coastguard Worker * \return zero on success, or a negative value on failure.
2007*7688df22SAndroid Build Coastguard Worker *
2008*7688df22SAndroid Build Coastguard Worker * \internal
2009*7688df22SAndroid Build Coastguard Worker * This function is a wrapper around the DRM_IOCTL_UNLOCK ioctl, passing the
2010*7688df22SAndroid Build Coastguard Worker * argument in a drm_lock structure.
2011*7688df22SAndroid Build Coastguard Worker */
drmUnlock(int fd,drm_context_t context)2012*7688df22SAndroid Build Coastguard Worker drm_public int drmUnlock(int fd, drm_context_t context)
2013*7688df22SAndroid Build Coastguard Worker {
2014*7688df22SAndroid Build Coastguard Worker drm_lock_t lock;
2015*7688df22SAndroid Build Coastguard Worker
2016*7688df22SAndroid Build Coastguard Worker memclear(lock);
2017*7688df22SAndroid Build Coastguard Worker lock.context = context;
2018*7688df22SAndroid Build Coastguard Worker return drmIoctl(fd, DRM_IOCTL_UNLOCK, &lock);
2019*7688df22SAndroid Build Coastguard Worker }
2020*7688df22SAndroid Build Coastguard Worker
drmGetReservedContextList(int fd,int * count)2021*7688df22SAndroid Build Coastguard Worker drm_public drm_context_t *drmGetReservedContextList(int fd, int *count)
2022*7688df22SAndroid Build Coastguard Worker {
2023*7688df22SAndroid Build Coastguard Worker drm_ctx_res_t res;
2024*7688df22SAndroid Build Coastguard Worker drm_ctx_t *list;
2025*7688df22SAndroid Build Coastguard Worker drm_context_t * retval;
2026*7688df22SAndroid Build Coastguard Worker int i;
2027*7688df22SAndroid Build Coastguard Worker
2028*7688df22SAndroid Build Coastguard Worker memclear(res);
2029*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_RES_CTX, &res))
2030*7688df22SAndroid Build Coastguard Worker return NULL;
2031*7688df22SAndroid Build Coastguard Worker
2032*7688df22SAndroid Build Coastguard Worker if (!res.count)
2033*7688df22SAndroid Build Coastguard Worker return NULL;
2034*7688df22SAndroid Build Coastguard Worker
2035*7688df22SAndroid Build Coastguard Worker if (!(list = drmMalloc(res.count * sizeof(*list))))
2036*7688df22SAndroid Build Coastguard Worker return NULL;
2037*7688df22SAndroid Build Coastguard Worker if (!(retval = drmMalloc(res.count * sizeof(*retval))))
2038*7688df22SAndroid Build Coastguard Worker goto err_free_list;
2039*7688df22SAndroid Build Coastguard Worker
2040*7688df22SAndroid Build Coastguard Worker res.contexts = list;
2041*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_RES_CTX, &res))
2042*7688df22SAndroid Build Coastguard Worker goto err_free_context;
2043*7688df22SAndroid Build Coastguard Worker
2044*7688df22SAndroid Build Coastguard Worker for (i = 0; i < res.count; i++)
2045*7688df22SAndroid Build Coastguard Worker retval[i] = list[i].handle;
2046*7688df22SAndroid Build Coastguard Worker drmFree(list);
2047*7688df22SAndroid Build Coastguard Worker
2048*7688df22SAndroid Build Coastguard Worker *count = res.count;
2049*7688df22SAndroid Build Coastguard Worker return retval;
2050*7688df22SAndroid Build Coastguard Worker
2051*7688df22SAndroid Build Coastguard Worker err_free_list:
2052*7688df22SAndroid Build Coastguard Worker drmFree(list);
2053*7688df22SAndroid Build Coastguard Worker err_free_context:
2054*7688df22SAndroid Build Coastguard Worker drmFree(retval);
2055*7688df22SAndroid Build Coastguard Worker return NULL;
2056*7688df22SAndroid Build Coastguard Worker }
2057*7688df22SAndroid Build Coastguard Worker
drmFreeReservedContextList(drm_context_t * pt)2058*7688df22SAndroid Build Coastguard Worker drm_public void drmFreeReservedContextList(drm_context_t *pt)
2059*7688df22SAndroid Build Coastguard Worker {
2060*7688df22SAndroid Build Coastguard Worker drmFree(pt);
2061*7688df22SAndroid Build Coastguard Worker }
2062*7688df22SAndroid Build Coastguard Worker
2063*7688df22SAndroid Build Coastguard Worker /**
2064*7688df22SAndroid Build Coastguard Worker * Create context.
2065*7688df22SAndroid Build Coastguard Worker *
2066*7688df22SAndroid Build Coastguard Worker * Used by the X server during GLXContext initialization. This causes
2067*7688df22SAndroid Build Coastguard Worker * per-context kernel-level resources to be allocated.
2068*7688df22SAndroid Build Coastguard Worker *
2069*7688df22SAndroid Build Coastguard Worker * \param fd file descriptor.
2070*7688df22SAndroid Build Coastguard Worker * \param handle is set on success. To be used by the client when requesting DMA
2071*7688df22SAndroid Build Coastguard Worker * dispatch with drmDMA().
2072*7688df22SAndroid Build Coastguard Worker *
2073*7688df22SAndroid Build Coastguard Worker * \return zero on success, or a negative value on failure.
2074*7688df22SAndroid Build Coastguard Worker *
2075*7688df22SAndroid Build Coastguard Worker * \note May only be called by root.
2076*7688df22SAndroid Build Coastguard Worker *
2077*7688df22SAndroid Build Coastguard Worker * \internal
2078*7688df22SAndroid Build Coastguard Worker * This function is a wrapper around the DRM_IOCTL_ADD_CTX ioctl, passing the
2079*7688df22SAndroid Build Coastguard Worker * argument in a drm_ctx structure.
2080*7688df22SAndroid Build Coastguard Worker */
drmCreateContext(int fd,drm_context_t * handle)2081*7688df22SAndroid Build Coastguard Worker drm_public int drmCreateContext(int fd, drm_context_t *handle)
2082*7688df22SAndroid Build Coastguard Worker {
2083*7688df22SAndroid Build Coastguard Worker drm_ctx_t ctx;
2084*7688df22SAndroid Build Coastguard Worker
2085*7688df22SAndroid Build Coastguard Worker memclear(ctx);
2086*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_ADD_CTX, &ctx))
2087*7688df22SAndroid Build Coastguard Worker return -errno;
2088*7688df22SAndroid Build Coastguard Worker *handle = ctx.handle;
2089*7688df22SAndroid Build Coastguard Worker return 0;
2090*7688df22SAndroid Build Coastguard Worker }
2091*7688df22SAndroid Build Coastguard Worker
drmSwitchToContext(int fd,drm_context_t context)2092*7688df22SAndroid Build Coastguard Worker drm_public int drmSwitchToContext(int fd, drm_context_t context)
2093*7688df22SAndroid Build Coastguard Worker {
2094*7688df22SAndroid Build Coastguard Worker drm_ctx_t ctx;
2095*7688df22SAndroid Build Coastguard Worker
2096*7688df22SAndroid Build Coastguard Worker memclear(ctx);
2097*7688df22SAndroid Build Coastguard Worker ctx.handle = context;
2098*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_SWITCH_CTX, &ctx))
2099*7688df22SAndroid Build Coastguard Worker return -errno;
2100*7688df22SAndroid Build Coastguard Worker return 0;
2101*7688df22SAndroid Build Coastguard Worker }
2102*7688df22SAndroid Build Coastguard Worker
drmSetContextFlags(int fd,drm_context_t context,drm_context_tFlags flags)2103*7688df22SAndroid Build Coastguard Worker drm_public int drmSetContextFlags(int fd, drm_context_t context,
2104*7688df22SAndroid Build Coastguard Worker drm_context_tFlags flags)
2105*7688df22SAndroid Build Coastguard Worker {
2106*7688df22SAndroid Build Coastguard Worker drm_ctx_t ctx;
2107*7688df22SAndroid Build Coastguard Worker
2108*7688df22SAndroid Build Coastguard Worker /*
2109*7688df22SAndroid Build Coastguard Worker * Context preserving means that no context switches are done between DMA
2110*7688df22SAndroid Build Coastguard Worker * buffers from one context and the next. This is suitable for use in the
2111*7688df22SAndroid Build Coastguard Worker * X server (which promises to maintain hardware context), or in the
2112*7688df22SAndroid Build Coastguard Worker * client-side library when buffers are swapped on behalf of two threads.
2113*7688df22SAndroid Build Coastguard Worker */
2114*7688df22SAndroid Build Coastguard Worker memclear(ctx);
2115*7688df22SAndroid Build Coastguard Worker ctx.handle = context;
2116*7688df22SAndroid Build Coastguard Worker if (flags & DRM_CONTEXT_PRESERVED)
2117*7688df22SAndroid Build Coastguard Worker ctx.flags |= _DRM_CONTEXT_PRESERVED;
2118*7688df22SAndroid Build Coastguard Worker if (flags & DRM_CONTEXT_2DONLY)
2119*7688df22SAndroid Build Coastguard Worker ctx.flags |= _DRM_CONTEXT_2DONLY;
2120*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_MOD_CTX, &ctx))
2121*7688df22SAndroid Build Coastguard Worker return -errno;
2122*7688df22SAndroid Build Coastguard Worker return 0;
2123*7688df22SAndroid Build Coastguard Worker }
2124*7688df22SAndroid Build Coastguard Worker
drmGetContextFlags(int fd,drm_context_t context,drm_context_tFlagsPtr flags)2125*7688df22SAndroid Build Coastguard Worker drm_public int drmGetContextFlags(int fd, drm_context_t context,
2126*7688df22SAndroid Build Coastguard Worker drm_context_tFlagsPtr flags)
2127*7688df22SAndroid Build Coastguard Worker {
2128*7688df22SAndroid Build Coastguard Worker drm_ctx_t ctx;
2129*7688df22SAndroid Build Coastguard Worker
2130*7688df22SAndroid Build Coastguard Worker memclear(ctx);
2131*7688df22SAndroid Build Coastguard Worker ctx.handle = context;
2132*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_GET_CTX, &ctx))
2133*7688df22SAndroid Build Coastguard Worker return -errno;
2134*7688df22SAndroid Build Coastguard Worker *flags = 0;
2135*7688df22SAndroid Build Coastguard Worker if (ctx.flags & _DRM_CONTEXT_PRESERVED)
2136*7688df22SAndroid Build Coastguard Worker *flags |= DRM_CONTEXT_PRESERVED;
2137*7688df22SAndroid Build Coastguard Worker if (ctx.flags & _DRM_CONTEXT_2DONLY)
2138*7688df22SAndroid Build Coastguard Worker *flags |= DRM_CONTEXT_2DONLY;
2139*7688df22SAndroid Build Coastguard Worker return 0;
2140*7688df22SAndroid Build Coastguard Worker }
2141*7688df22SAndroid Build Coastguard Worker
2142*7688df22SAndroid Build Coastguard Worker /**
2143*7688df22SAndroid Build Coastguard Worker * Destroy context.
2144*7688df22SAndroid Build Coastguard Worker *
2145*7688df22SAndroid Build Coastguard Worker * Free any kernel-level resources allocated with drmCreateContext() associated
2146*7688df22SAndroid Build Coastguard Worker * with the context.
2147*7688df22SAndroid Build Coastguard Worker *
2148*7688df22SAndroid Build Coastguard Worker * \param fd file descriptor.
2149*7688df22SAndroid Build Coastguard Worker * \param handle handle given by drmCreateContext().
2150*7688df22SAndroid Build Coastguard Worker *
2151*7688df22SAndroid Build Coastguard Worker * \return zero on success, or a negative value on failure.
2152*7688df22SAndroid Build Coastguard Worker *
2153*7688df22SAndroid Build Coastguard Worker * \note May only be called by root.
2154*7688df22SAndroid Build Coastguard Worker *
2155*7688df22SAndroid Build Coastguard Worker * \internal
2156*7688df22SAndroid Build Coastguard Worker * This function is a wrapper around the DRM_IOCTL_RM_CTX ioctl, passing the
2157*7688df22SAndroid Build Coastguard Worker * argument in a drm_ctx structure.
2158*7688df22SAndroid Build Coastguard Worker */
drmDestroyContext(int fd,drm_context_t handle)2159*7688df22SAndroid Build Coastguard Worker drm_public int drmDestroyContext(int fd, drm_context_t handle)
2160*7688df22SAndroid Build Coastguard Worker {
2161*7688df22SAndroid Build Coastguard Worker drm_ctx_t ctx;
2162*7688df22SAndroid Build Coastguard Worker
2163*7688df22SAndroid Build Coastguard Worker memclear(ctx);
2164*7688df22SAndroid Build Coastguard Worker ctx.handle = handle;
2165*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_RM_CTX, &ctx))
2166*7688df22SAndroid Build Coastguard Worker return -errno;
2167*7688df22SAndroid Build Coastguard Worker return 0;
2168*7688df22SAndroid Build Coastguard Worker }
2169*7688df22SAndroid Build Coastguard Worker
drmCreateDrawable(int fd,drm_drawable_t * handle)2170*7688df22SAndroid Build Coastguard Worker drm_public int drmCreateDrawable(int fd, drm_drawable_t *handle)
2171*7688df22SAndroid Build Coastguard Worker {
2172*7688df22SAndroid Build Coastguard Worker drm_draw_t draw;
2173*7688df22SAndroid Build Coastguard Worker
2174*7688df22SAndroid Build Coastguard Worker memclear(draw);
2175*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_ADD_DRAW, &draw))
2176*7688df22SAndroid Build Coastguard Worker return -errno;
2177*7688df22SAndroid Build Coastguard Worker *handle = draw.handle;
2178*7688df22SAndroid Build Coastguard Worker return 0;
2179*7688df22SAndroid Build Coastguard Worker }
2180*7688df22SAndroid Build Coastguard Worker
drmDestroyDrawable(int fd,drm_drawable_t handle)2181*7688df22SAndroid Build Coastguard Worker drm_public int drmDestroyDrawable(int fd, drm_drawable_t handle)
2182*7688df22SAndroid Build Coastguard Worker {
2183*7688df22SAndroid Build Coastguard Worker drm_draw_t draw;
2184*7688df22SAndroid Build Coastguard Worker
2185*7688df22SAndroid Build Coastguard Worker memclear(draw);
2186*7688df22SAndroid Build Coastguard Worker draw.handle = handle;
2187*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_RM_DRAW, &draw))
2188*7688df22SAndroid Build Coastguard Worker return -errno;
2189*7688df22SAndroid Build Coastguard Worker return 0;
2190*7688df22SAndroid Build Coastguard Worker }
2191*7688df22SAndroid Build Coastguard Worker
drmUpdateDrawableInfo(int fd,drm_drawable_t handle,drm_drawable_info_type_t type,unsigned int num,void * data)2192*7688df22SAndroid Build Coastguard Worker drm_public int drmUpdateDrawableInfo(int fd, drm_drawable_t handle,
2193*7688df22SAndroid Build Coastguard Worker drm_drawable_info_type_t type,
2194*7688df22SAndroid Build Coastguard Worker unsigned int num, void *data)
2195*7688df22SAndroid Build Coastguard Worker {
2196*7688df22SAndroid Build Coastguard Worker drm_update_draw_t update;
2197*7688df22SAndroid Build Coastguard Worker
2198*7688df22SAndroid Build Coastguard Worker memclear(update);
2199*7688df22SAndroid Build Coastguard Worker update.handle = handle;
2200*7688df22SAndroid Build Coastguard Worker update.type = type;
2201*7688df22SAndroid Build Coastguard Worker update.num = num;
2202*7688df22SAndroid Build Coastguard Worker update.data = (unsigned long long)(unsigned long)data;
2203*7688df22SAndroid Build Coastguard Worker
2204*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_UPDATE_DRAW, &update))
2205*7688df22SAndroid Build Coastguard Worker return -errno;
2206*7688df22SAndroid Build Coastguard Worker
2207*7688df22SAndroid Build Coastguard Worker return 0;
2208*7688df22SAndroid Build Coastguard Worker }
2209*7688df22SAndroid Build Coastguard Worker
drmCrtcGetSequence(int fd,uint32_t crtcId,uint64_t * sequence,uint64_t * ns)2210*7688df22SAndroid Build Coastguard Worker drm_public int drmCrtcGetSequence(int fd, uint32_t crtcId, uint64_t *sequence,
2211*7688df22SAndroid Build Coastguard Worker uint64_t *ns)
2212*7688df22SAndroid Build Coastguard Worker {
2213*7688df22SAndroid Build Coastguard Worker struct drm_crtc_get_sequence get_seq;
2214*7688df22SAndroid Build Coastguard Worker int ret;
2215*7688df22SAndroid Build Coastguard Worker
2216*7688df22SAndroid Build Coastguard Worker memclear(get_seq);
2217*7688df22SAndroid Build Coastguard Worker get_seq.crtc_id = crtcId;
2218*7688df22SAndroid Build Coastguard Worker ret = drmIoctl(fd, DRM_IOCTL_CRTC_GET_SEQUENCE, &get_seq);
2219*7688df22SAndroid Build Coastguard Worker if (ret)
2220*7688df22SAndroid Build Coastguard Worker return ret;
2221*7688df22SAndroid Build Coastguard Worker
2222*7688df22SAndroid Build Coastguard Worker if (sequence)
2223*7688df22SAndroid Build Coastguard Worker *sequence = get_seq.sequence;
2224*7688df22SAndroid Build Coastguard Worker if (ns)
2225*7688df22SAndroid Build Coastguard Worker *ns = get_seq.sequence_ns;
2226*7688df22SAndroid Build Coastguard Worker return 0;
2227*7688df22SAndroid Build Coastguard Worker }
2228*7688df22SAndroid Build Coastguard Worker
drmCrtcQueueSequence(int fd,uint32_t crtcId,uint32_t flags,uint64_t sequence,uint64_t * sequence_queued,uint64_t user_data)2229*7688df22SAndroid Build Coastguard Worker drm_public int drmCrtcQueueSequence(int fd, uint32_t crtcId, uint32_t flags,
2230*7688df22SAndroid Build Coastguard Worker uint64_t sequence,
2231*7688df22SAndroid Build Coastguard Worker uint64_t *sequence_queued,
2232*7688df22SAndroid Build Coastguard Worker uint64_t user_data)
2233*7688df22SAndroid Build Coastguard Worker {
2234*7688df22SAndroid Build Coastguard Worker struct drm_crtc_queue_sequence queue_seq;
2235*7688df22SAndroid Build Coastguard Worker int ret;
2236*7688df22SAndroid Build Coastguard Worker
2237*7688df22SAndroid Build Coastguard Worker memclear(queue_seq);
2238*7688df22SAndroid Build Coastguard Worker queue_seq.crtc_id = crtcId;
2239*7688df22SAndroid Build Coastguard Worker queue_seq.flags = flags;
2240*7688df22SAndroid Build Coastguard Worker queue_seq.sequence = sequence;
2241*7688df22SAndroid Build Coastguard Worker queue_seq.user_data = user_data;
2242*7688df22SAndroid Build Coastguard Worker
2243*7688df22SAndroid Build Coastguard Worker ret = drmIoctl(fd, DRM_IOCTL_CRTC_QUEUE_SEQUENCE, &queue_seq);
2244*7688df22SAndroid Build Coastguard Worker if (ret == 0 && sequence_queued)
2245*7688df22SAndroid Build Coastguard Worker *sequence_queued = queue_seq.sequence;
2246*7688df22SAndroid Build Coastguard Worker
2247*7688df22SAndroid Build Coastguard Worker return ret;
2248*7688df22SAndroid Build Coastguard Worker }
2249*7688df22SAndroid Build Coastguard Worker
2250*7688df22SAndroid Build Coastguard Worker /**
2251*7688df22SAndroid Build Coastguard Worker * Acquire the AGP device.
2252*7688df22SAndroid Build Coastguard Worker *
2253*7688df22SAndroid Build Coastguard Worker * Must be called before any of the other AGP related calls.
2254*7688df22SAndroid Build Coastguard Worker *
2255*7688df22SAndroid Build Coastguard Worker * \param fd file descriptor.
2256*7688df22SAndroid Build Coastguard Worker *
2257*7688df22SAndroid Build Coastguard Worker * \return zero on success, or a negative value on failure.
2258*7688df22SAndroid Build Coastguard Worker *
2259*7688df22SAndroid Build Coastguard Worker * \internal
2260*7688df22SAndroid Build Coastguard Worker * This function is a wrapper around the DRM_IOCTL_AGP_ACQUIRE ioctl.
2261*7688df22SAndroid Build Coastguard Worker */
drmAgpAcquire(int fd)2262*7688df22SAndroid Build Coastguard Worker drm_public int drmAgpAcquire(int fd)
2263*7688df22SAndroid Build Coastguard Worker {
2264*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_AGP_ACQUIRE, NULL))
2265*7688df22SAndroid Build Coastguard Worker return -errno;
2266*7688df22SAndroid Build Coastguard Worker return 0;
2267*7688df22SAndroid Build Coastguard Worker }
2268*7688df22SAndroid Build Coastguard Worker
2269*7688df22SAndroid Build Coastguard Worker
2270*7688df22SAndroid Build Coastguard Worker /**
2271*7688df22SAndroid Build Coastguard Worker * Release the AGP device.
2272*7688df22SAndroid Build Coastguard Worker *
2273*7688df22SAndroid Build Coastguard Worker * \param fd file descriptor.
2274*7688df22SAndroid Build Coastguard Worker *
2275*7688df22SAndroid Build Coastguard Worker * \return zero on success, or a negative value on failure.
2276*7688df22SAndroid Build Coastguard Worker *
2277*7688df22SAndroid Build Coastguard Worker * \internal
2278*7688df22SAndroid Build Coastguard Worker * This function is a wrapper around the DRM_IOCTL_AGP_RELEASE ioctl.
2279*7688df22SAndroid Build Coastguard Worker */
drmAgpRelease(int fd)2280*7688df22SAndroid Build Coastguard Worker drm_public int drmAgpRelease(int fd)
2281*7688df22SAndroid Build Coastguard Worker {
2282*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_AGP_RELEASE, NULL))
2283*7688df22SAndroid Build Coastguard Worker return -errno;
2284*7688df22SAndroid Build Coastguard Worker return 0;
2285*7688df22SAndroid Build Coastguard Worker }
2286*7688df22SAndroid Build Coastguard Worker
2287*7688df22SAndroid Build Coastguard Worker
2288*7688df22SAndroid Build Coastguard Worker /**
2289*7688df22SAndroid Build Coastguard Worker * Set the AGP mode.
2290*7688df22SAndroid Build Coastguard Worker *
2291*7688df22SAndroid Build Coastguard Worker * \param fd file descriptor.
2292*7688df22SAndroid Build Coastguard Worker * \param mode AGP mode.
2293*7688df22SAndroid Build Coastguard Worker *
2294*7688df22SAndroid Build Coastguard Worker * \return zero on success, or a negative value on failure.
2295*7688df22SAndroid Build Coastguard Worker *
2296*7688df22SAndroid Build Coastguard Worker * \internal
2297*7688df22SAndroid Build Coastguard Worker * This function is a wrapper around the DRM_IOCTL_AGP_ENABLE ioctl, passing the
2298*7688df22SAndroid Build Coastguard Worker * argument in a drm_agp_mode structure.
2299*7688df22SAndroid Build Coastguard Worker */
drmAgpEnable(int fd,unsigned long mode)2300*7688df22SAndroid Build Coastguard Worker drm_public int drmAgpEnable(int fd, unsigned long mode)
2301*7688df22SAndroid Build Coastguard Worker {
2302*7688df22SAndroid Build Coastguard Worker drm_agp_mode_t m;
2303*7688df22SAndroid Build Coastguard Worker
2304*7688df22SAndroid Build Coastguard Worker memclear(m);
2305*7688df22SAndroid Build Coastguard Worker m.mode = mode;
2306*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_AGP_ENABLE, &m))
2307*7688df22SAndroid Build Coastguard Worker return -errno;
2308*7688df22SAndroid Build Coastguard Worker return 0;
2309*7688df22SAndroid Build Coastguard Worker }
2310*7688df22SAndroid Build Coastguard Worker
2311*7688df22SAndroid Build Coastguard Worker
2312*7688df22SAndroid Build Coastguard Worker /**
2313*7688df22SAndroid Build Coastguard Worker * Allocate a chunk of AGP memory.
2314*7688df22SAndroid Build Coastguard Worker *
2315*7688df22SAndroid Build Coastguard Worker * \param fd file descriptor.
2316*7688df22SAndroid Build Coastguard Worker * \param size requested memory size in bytes. Will be rounded to page boundary.
2317*7688df22SAndroid Build Coastguard Worker * \param type type of memory to allocate.
2318*7688df22SAndroid Build Coastguard Worker * \param address if not zero, will be set to the physical address of the
2319*7688df22SAndroid Build Coastguard Worker * allocated memory.
2320*7688df22SAndroid Build Coastguard Worker * \param handle on success will be set to a handle of the allocated memory.
2321*7688df22SAndroid Build Coastguard Worker *
2322*7688df22SAndroid Build Coastguard Worker * \return zero on success, or a negative value on failure.
2323*7688df22SAndroid Build Coastguard Worker *
2324*7688df22SAndroid Build Coastguard Worker * \internal
2325*7688df22SAndroid Build Coastguard Worker * This function is a wrapper around the DRM_IOCTL_AGP_ALLOC ioctl, passing the
2326*7688df22SAndroid Build Coastguard Worker * arguments in a drm_agp_buffer structure.
2327*7688df22SAndroid Build Coastguard Worker */
drmAgpAlloc(int fd,unsigned long size,unsigned long type,unsigned long * address,drm_handle_t * handle)2328*7688df22SAndroid Build Coastguard Worker drm_public int drmAgpAlloc(int fd, unsigned long size, unsigned long type,
2329*7688df22SAndroid Build Coastguard Worker unsigned long *address, drm_handle_t *handle)
2330*7688df22SAndroid Build Coastguard Worker {
2331*7688df22SAndroid Build Coastguard Worker drm_agp_buffer_t b;
2332*7688df22SAndroid Build Coastguard Worker
2333*7688df22SAndroid Build Coastguard Worker memclear(b);
2334*7688df22SAndroid Build Coastguard Worker *handle = DRM_AGP_NO_HANDLE;
2335*7688df22SAndroid Build Coastguard Worker b.size = size;
2336*7688df22SAndroid Build Coastguard Worker b.type = type;
2337*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_AGP_ALLOC, &b))
2338*7688df22SAndroid Build Coastguard Worker return -errno;
2339*7688df22SAndroid Build Coastguard Worker if (address != 0UL)
2340*7688df22SAndroid Build Coastguard Worker *address = b.physical;
2341*7688df22SAndroid Build Coastguard Worker *handle = b.handle;
2342*7688df22SAndroid Build Coastguard Worker return 0;
2343*7688df22SAndroid Build Coastguard Worker }
2344*7688df22SAndroid Build Coastguard Worker
2345*7688df22SAndroid Build Coastguard Worker
2346*7688df22SAndroid Build Coastguard Worker /**
2347*7688df22SAndroid Build Coastguard Worker * Free a chunk of AGP memory.
2348*7688df22SAndroid Build Coastguard Worker *
2349*7688df22SAndroid Build Coastguard Worker * \param fd file descriptor.
2350*7688df22SAndroid Build Coastguard Worker * \param handle handle to the allocated memory, as given by drmAgpAllocate().
2351*7688df22SAndroid Build Coastguard Worker *
2352*7688df22SAndroid Build Coastguard Worker * \return zero on success, or a negative value on failure.
2353*7688df22SAndroid Build Coastguard Worker *
2354*7688df22SAndroid Build Coastguard Worker * \internal
2355*7688df22SAndroid Build Coastguard Worker * This function is a wrapper around the DRM_IOCTL_AGP_FREE ioctl, passing the
2356*7688df22SAndroid Build Coastguard Worker * argument in a drm_agp_buffer structure.
2357*7688df22SAndroid Build Coastguard Worker */
drmAgpFree(int fd,drm_handle_t handle)2358*7688df22SAndroid Build Coastguard Worker drm_public int drmAgpFree(int fd, drm_handle_t handle)
2359*7688df22SAndroid Build Coastguard Worker {
2360*7688df22SAndroid Build Coastguard Worker drm_agp_buffer_t b;
2361*7688df22SAndroid Build Coastguard Worker
2362*7688df22SAndroid Build Coastguard Worker memclear(b);
2363*7688df22SAndroid Build Coastguard Worker b.handle = handle;
2364*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_AGP_FREE, &b))
2365*7688df22SAndroid Build Coastguard Worker return -errno;
2366*7688df22SAndroid Build Coastguard Worker return 0;
2367*7688df22SAndroid Build Coastguard Worker }
2368*7688df22SAndroid Build Coastguard Worker
2369*7688df22SAndroid Build Coastguard Worker
2370*7688df22SAndroid Build Coastguard Worker /**
2371*7688df22SAndroid Build Coastguard Worker * Bind a chunk of AGP memory.
2372*7688df22SAndroid Build Coastguard Worker *
2373*7688df22SAndroid Build Coastguard Worker * \param fd file descriptor.
2374*7688df22SAndroid Build Coastguard Worker * \param handle handle to the allocated memory, as given by drmAgpAllocate().
2375*7688df22SAndroid Build Coastguard Worker * \param offset offset in bytes. It will round to page boundary.
2376*7688df22SAndroid Build Coastguard Worker *
2377*7688df22SAndroid Build Coastguard Worker * \return zero on success, or a negative value on failure.
2378*7688df22SAndroid Build Coastguard Worker *
2379*7688df22SAndroid Build Coastguard Worker * \internal
2380*7688df22SAndroid Build Coastguard Worker * This function is a wrapper around the DRM_IOCTL_AGP_BIND ioctl, passing the
2381*7688df22SAndroid Build Coastguard Worker * argument in a drm_agp_binding structure.
2382*7688df22SAndroid Build Coastguard Worker */
drmAgpBind(int fd,drm_handle_t handle,unsigned long offset)2383*7688df22SAndroid Build Coastguard Worker drm_public int drmAgpBind(int fd, drm_handle_t handle, unsigned long offset)
2384*7688df22SAndroid Build Coastguard Worker {
2385*7688df22SAndroid Build Coastguard Worker drm_agp_binding_t b;
2386*7688df22SAndroid Build Coastguard Worker
2387*7688df22SAndroid Build Coastguard Worker memclear(b);
2388*7688df22SAndroid Build Coastguard Worker b.handle = handle;
2389*7688df22SAndroid Build Coastguard Worker b.offset = offset;
2390*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_AGP_BIND, &b))
2391*7688df22SAndroid Build Coastguard Worker return -errno;
2392*7688df22SAndroid Build Coastguard Worker return 0;
2393*7688df22SAndroid Build Coastguard Worker }
2394*7688df22SAndroid Build Coastguard Worker
2395*7688df22SAndroid Build Coastguard Worker
2396*7688df22SAndroid Build Coastguard Worker /**
2397*7688df22SAndroid Build Coastguard Worker * Unbind a chunk of AGP memory.
2398*7688df22SAndroid Build Coastguard Worker *
2399*7688df22SAndroid Build Coastguard Worker * \param fd file descriptor.
2400*7688df22SAndroid Build Coastguard Worker * \param handle handle to the allocated memory, as given by drmAgpAllocate().
2401*7688df22SAndroid Build Coastguard Worker *
2402*7688df22SAndroid Build Coastguard Worker * \return zero on success, or a negative value on failure.
2403*7688df22SAndroid Build Coastguard Worker *
2404*7688df22SAndroid Build Coastguard Worker * \internal
2405*7688df22SAndroid Build Coastguard Worker * This function is a wrapper around the DRM_IOCTL_AGP_UNBIND ioctl, passing
2406*7688df22SAndroid Build Coastguard Worker * the argument in a drm_agp_binding structure.
2407*7688df22SAndroid Build Coastguard Worker */
drmAgpUnbind(int fd,drm_handle_t handle)2408*7688df22SAndroid Build Coastguard Worker drm_public int drmAgpUnbind(int fd, drm_handle_t handle)
2409*7688df22SAndroid Build Coastguard Worker {
2410*7688df22SAndroid Build Coastguard Worker drm_agp_binding_t b;
2411*7688df22SAndroid Build Coastguard Worker
2412*7688df22SAndroid Build Coastguard Worker memclear(b);
2413*7688df22SAndroid Build Coastguard Worker b.handle = handle;
2414*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_AGP_UNBIND, &b))
2415*7688df22SAndroid Build Coastguard Worker return -errno;
2416*7688df22SAndroid Build Coastguard Worker return 0;
2417*7688df22SAndroid Build Coastguard Worker }
2418*7688df22SAndroid Build Coastguard Worker
2419*7688df22SAndroid Build Coastguard Worker
2420*7688df22SAndroid Build Coastguard Worker /**
2421*7688df22SAndroid Build Coastguard Worker * Get AGP driver major version number.
2422*7688df22SAndroid Build Coastguard Worker *
2423*7688df22SAndroid Build Coastguard Worker * \param fd file descriptor.
2424*7688df22SAndroid Build Coastguard Worker *
2425*7688df22SAndroid Build Coastguard Worker * \return major version number on success, or a negative value on failure..
2426*7688df22SAndroid Build Coastguard Worker *
2427*7688df22SAndroid Build Coastguard Worker * \internal
2428*7688df22SAndroid Build Coastguard Worker * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
2429*7688df22SAndroid Build Coastguard Worker * necessary information in a drm_agp_info structure.
2430*7688df22SAndroid Build Coastguard Worker */
drmAgpVersionMajor(int fd)2431*7688df22SAndroid Build Coastguard Worker drm_public int drmAgpVersionMajor(int fd)
2432*7688df22SAndroid Build Coastguard Worker {
2433*7688df22SAndroid Build Coastguard Worker drm_agp_info_t i;
2434*7688df22SAndroid Build Coastguard Worker
2435*7688df22SAndroid Build Coastguard Worker memclear(i);
2436*7688df22SAndroid Build Coastguard Worker
2437*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
2438*7688df22SAndroid Build Coastguard Worker return -errno;
2439*7688df22SAndroid Build Coastguard Worker return i.agp_version_major;
2440*7688df22SAndroid Build Coastguard Worker }
2441*7688df22SAndroid Build Coastguard Worker
2442*7688df22SAndroid Build Coastguard Worker
2443*7688df22SAndroid Build Coastguard Worker /**
2444*7688df22SAndroid Build Coastguard Worker * Get AGP driver minor version number.
2445*7688df22SAndroid Build Coastguard Worker *
2446*7688df22SAndroid Build Coastguard Worker * \param fd file descriptor.
2447*7688df22SAndroid Build Coastguard Worker *
2448*7688df22SAndroid Build Coastguard Worker * \return minor version number on success, or a negative value on failure.
2449*7688df22SAndroid Build Coastguard Worker *
2450*7688df22SAndroid Build Coastguard Worker * \internal
2451*7688df22SAndroid Build Coastguard Worker * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
2452*7688df22SAndroid Build Coastguard Worker * necessary information in a drm_agp_info structure.
2453*7688df22SAndroid Build Coastguard Worker */
drmAgpVersionMinor(int fd)2454*7688df22SAndroid Build Coastguard Worker drm_public int drmAgpVersionMinor(int fd)
2455*7688df22SAndroid Build Coastguard Worker {
2456*7688df22SAndroid Build Coastguard Worker drm_agp_info_t i;
2457*7688df22SAndroid Build Coastguard Worker
2458*7688df22SAndroid Build Coastguard Worker memclear(i);
2459*7688df22SAndroid Build Coastguard Worker
2460*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
2461*7688df22SAndroid Build Coastguard Worker return -errno;
2462*7688df22SAndroid Build Coastguard Worker return i.agp_version_minor;
2463*7688df22SAndroid Build Coastguard Worker }
2464*7688df22SAndroid Build Coastguard Worker
2465*7688df22SAndroid Build Coastguard Worker
2466*7688df22SAndroid Build Coastguard Worker /**
2467*7688df22SAndroid Build Coastguard Worker * Get AGP mode.
2468*7688df22SAndroid Build Coastguard Worker *
2469*7688df22SAndroid Build Coastguard Worker * \param fd file descriptor.
2470*7688df22SAndroid Build Coastguard Worker *
2471*7688df22SAndroid Build Coastguard Worker * \return mode on success, or zero on failure.
2472*7688df22SAndroid Build Coastguard Worker *
2473*7688df22SAndroid Build Coastguard Worker * \internal
2474*7688df22SAndroid Build Coastguard Worker * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
2475*7688df22SAndroid Build Coastguard Worker * necessary information in a drm_agp_info structure.
2476*7688df22SAndroid Build Coastguard Worker */
drmAgpGetMode(int fd)2477*7688df22SAndroid Build Coastguard Worker drm_public unsigned long drmAgpGetMode(int fd)
2478*7688df22SAndroid Build Coastguard Worker {
2479*7688df22SAndroid Build Coastguard Worker drm_agp_info_t i;
2480*7688df22SAndroid Build Coastguard Worker
2481*7688df22SAndroid Build Coastguard Worker memclear(i);
2482*7688df22SAndroid Build Coastguard Worker
2483*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
2484*7688df22SAndroid Build Coastguard Worker return 0;
2485*7688df22SAndroid Build Coastguard Worker return i.mode;
2486*7688df22SAndroid Build Coastguard Worker }
2487*7688df22SAndroid Build Coastguard Worker
2488*7688df22SAndroid Build Coastguard Worker
2489*7688df22SAndroid Build Coastguard Worker /**
2490*7688df22SAndroid Build Coastguard Worker * Get AGP aperture base.
2491*7688df22SAndroid Build Coastguard Worker *
2492*7688df22SAndroid Build Coastguard Worker * \param fd file descriptor.
2493*7688df22SAndroid Build Coastguard Worker *
2494*7688df22SAndroid Build Coastguard Worker * \return aperture base on success, zero on failure.
2495*7688df22SAndroid Build Coastguard Worker *
2496*7688df22SAndroid Build Coastguard Worker * \internal
2497*7688df22SAndroid Build Coastguard Worker * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
2498*7688df22SAndroid Build Coastguard Worker * necessary information in a drm_agp_info structure.
2499*7688df22SAndroid Build Coastguard Worker */
drmAgpBase(int fd)2500*7688df22SAndroid Build Coastguard Worker drm_public unsigned long drmAgpBase(int fd)
2501*7688df22SAndroid Build Coastguard Worker {
2502*7688df22SAndroid Build Coastguard Worker drm_agp_info_t i;
2503*7688df22SAndroid Build Coastguard Worker
2504*7688df22SAndroid Build Coastguard Worker memclear(i);
2505*7688df22SAndroid Build Coastguard Worker
2506*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
2507*7688df22SAndroid Build Coastguard Worker return 0;
2508*7688df22SAndroid Build Coastguard Worker return i.aperture_base;
2509*7688df22SAndroid Build Coastguard Worker }
2510*7688df22SAndroid Build Coastguard Worker
2511*7688df22SAndroid Build Coastguard Worker
2512*7688df22SAndroid Build Coastguard Worker /**
2513*7688df22SAndroid Build Coastguard Worker * Get AGP aperture size.
2514*7688df22SAndroid Build Coastguard Worker *
2515*7688df22SAndroid Build Coastguard Worker * \param fd file descriptor.
2516*7688df22SAndroid Build Coastguard Worker *
2517*7688df22SAndroid Build Coastguard Worker * \return aperture size on success, zero on failure.
2518*7688df22SAndroid Build Coastguard Worker *
2519*7688df22SAndroid Build Coastguard Worker * \internal
2520*7688df22SAndroid Build Coastguard Worker * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
2521*7688df22SAndroid Build Coastguard Worker * necessary information in a drm_agp_info structure.
2522*7688df22SAndroid Build Coastguard Worker */
drmAgpSize(int fd)2523*7688df22SAndroid Build Coastguard Worker drm_public unsigned long drmAgpSize(int fd)
2524*7688df22SAndroid Build Coastguard Worker {
2525*7688df22SAndroid Build Coastguard Worker drm_agp_info_t i;
2526*7688df22SAndroid Build Coastguard Worker
2527*7688df22SAndroid Build Coastguard Worker memclear(i);
2528*7688df22SAndroid Build Coastguard Worker
2529*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
2530*7688df22SAndroid Build Coastguard Worker return 0;
2531*7688df22SAndroid Build Coastguard Worker return i.aperture_size;
2532*7688df22SAndroid Build Coastguard Worker }
2533*7688df22SAndroid Build Coastguard Worker
2534*7688df22SAndroid Build Coastguard Worker
2535*7688df22SAndroid Build Coastguard Worker /**
2536*7688df22SAndroid Build Coastguard Worker * Get used AGP memory.
2537*7688df22SAndroid Build Coastguard Worker *
2538*7688df22SAndroid Build Coastguard Worker * \param fd file descriptor.
2539*7688df22SAndroid Build Coastguard Worker *
2540*7688df22SAndroid Build Coastguard Worker * \return memory used on success, or zero on failure.
2541*7688df22SAndroid Build Coastguard Worker *
2542*7688df22SAndroid Build Coastguard Worker * \internal
2543*7688df22SAndroid Build Coastguard Worker * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
2544*7688df22SAndroid Build Coastguard Worker * necessary information in a drm_agp_info structure.
2545*7688df22SAndroid Build Coastguard Worker */
drmAgpMemoryUsed(int fd)2546*7688df22SAndroid Build Coastguard Worker drm_public unsigned long drmAgpMemoryUsed(int fd)
2547*7688df22SAndroid Build Coastguard Worker {
2548*7688df22SAndroid Build Coastguard Worker drm_agp_info_t i;
2549*7688df22SAndroid Build Coastguard Worker
2550*7688df22SAndroid Build Coastguard Worker memclear(i);
2551*7688df22SAndroid Build Coastguard Worker
2552*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
2553*7688df22SAndroid Build Coastguard Worker return 0;
2554*7688df22SAndroid Build Coastguard Worker return i.memory_used;
2555*7688df22SAndroid Build Coastguard Worker }
2556*7688df22SAndroid Build Coastguard Worker
2557*7688df22SAndroid Build Coastguard Worker
2558*7688df22SAndroid Build Coastguard Worker /**
2559*7688df22SAndroid Build Coastguard Worker * Get available AGP memory.
2560*7688df22SAndroid Build Coastguard Worker *
2561*7688df22SAndroid Build Coastguard Worker * \param fd file descriptor.
2562*7688df22SAndroid Build Coastguard Worker *
2563*7688df22SAndroid Build Coastguard Worker * \return memory available on success, or zero on failure.
2564*7688df22SAndroid Build Coastguard Worker *
2565*7688df22SAndroid Build Coastguard Worker * \internal
2566*7688df22SAndroid Build Coastguard Worker * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
2567*7688df22SAndroid Build Coastguard Worker * necessary information in a drm_agp_info structure.
2568*7688df22SAndroid Build Coastguard Worker */
drmAgpMemoryAvail(int fd)2569*7688df22SAndroid Build Coastguard Worker drm_public unsigned long drmAgpMemoryAvail(int fd)
2570*7688df22SAndroid Build Coastguard Worker {
2571*7688df22SAndroid Build Coastguard Worker drm_agp_info_t i;
2572*7688df22SAndroid Build Coastguard Worker
2573*7688df22SAndroid Build Coastguard Worker memclear(i);
2574*7688df22SAndroid Build Coastguard Worker
2575*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
2576*7688df22SAndroid Build Coastguard Worker return 0;
2577*7688df22SAndroid Build Coastguard Worker return i.memory_allowed;
2578*7688df22SAndroid Build Coastguard Worker }
2579*7688df22SAndroid Build Coastguard Worker
2580*7688df22SAndroid Build Coastguard Worker
2581*7688df22SAndroid Build Coastguard Worker /**
2582*7688df22SAndroid Build Coastguard Worker * Get hardware vendor ID.
2583*7688df22SAndroid Build Coastguard Worker *
2584*7688df22SAndroid Build Coastguard Worker * \param fd file descriptor.
2585*7688df22SAndroid Build Coastguard Worker *
2586*7688df22SAndroid Build Coastguard Worker * \return vendor ID on success, or zero on failure.
2587*7688df22SAndroid Build Coastguard Worker *
2588*7688df22SAndroid Build Coastguard Worker * \internal
2589*7688df22SAndroid Build Coastguard Worker * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
2590*7688df22SAndroid Build Coastguard Worker * necessary information in a drm_agp_info structure.
2591*7688df22SAndroid Build Coastguard Worker */
drmAgpVendorId(int fd)2592*7688df22SAndroid Build Coastguard Worker drm_public unsigned int drmAgpVendorId(int fd)
2593*7688df22SAndroid Build Coastguard Worker {
2594*7688df22SAndroid Build Coastguard Worker drm_agp_info_t i;
2595*7688df22SAndroid Build Coastguard Worker
2596*7688df22SAndroid Build Coastguard Worker memclear(i);
2597*7688df22SAndroid Build Coastguard Worker
2598*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
2599*7688df22SAndroid Build Coastguard Worker return 0;
2600*7688df22SAndroid Build Coastguard Worker return i.id_vendor;
2601*7688df22SAndroid Build Coastguard Worker }
2602*7688df22SAndroid Build Coastguard Worker
2603*7688df22SAndroid Build Coastguard Worker
2604*7688df22SAndroid Build Coastguard Worker /**
2605*7688df22SAndroid Build Coastguard Worker * Get hardware device ID.
2606*7688df22SAndroid Build Coastguard Worker *
2607*7688df22SAndroid Build Coastguard Worker * \param fd file descriptor.
2608*7688df22SAndroid Build Coastguard Worker *
2609*7688df22SAndroid Build Coastguard Worker * \return zero on success, or zero on failure.
2610*7688df22SAndroid Build Coastguard Worker *
2611*7688df22SAndroid Build Coastguard Worker * \internal
2612*7688df22SAndroid Build Coastguard Worker * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
2613*7688df22SAndroid Build Coastguard Worker * necessary information in a drm_agp_info structure.
2614*7688df22SAndroid Build Coastguard Worker */
drmAgpDeviceId(int fd)2615*7688df22SAndroid Build Coastguard Worker drm_public unsigned int drmAgpDeviceId(int fd)
2616*7688df22SAndroid Build Coastguard Worker {
2617*7688df22SAndroid Build Coastguard Worker drm_agp_info_t i;
2618*7688df22SAndroid Build Coastguard Worker
2619*7688df22SAndroid Build Coastguard Worker memclear(i);
2620*7688df22SAndroid Build Coastguard Worker
2621*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
2622*7688df22SAndroid Build Coastguard Worker return 0;
2623*7688df22SAndroid Build Coastguard Worker return i.id_device;
2624*7688df22SAndroid Build Coastguard Worker }
2625*7688df22SAndroid Build Coastguard Worker
drmScatterGatherAlloc(int fd,unsigned long size,drm_handle_t * handle)2626*7688df22SAndroid Build Coastguard Worker drm_public int drmScatterGatherAlloc(int fd, unsigned long size,
2627*7688df22SAndroid Build Coastguard Worker drm_handle_t *handle)
2628*7688df22SAndroid Build Coastguard Worker {
2629*7688df22SAndroid Build Coastguard Worker drm_scatter_gather_t sg;
2630*7688df22SAndroid Build Coastguard Worker
2631*7688df22SAndroid Build Coastguard Worker memclear(sg);
2632*7688df22SAndroid Build Coastguard Worker
2633*7688df22SAndroid Build Coastguard Worker *handle = 0;
2634*7688df22SAndroid Build Coastguard Worker sg.size = size;
2635*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_SG_ALLOC, &sg))
2636*7688df22SAndroid Build Coastguard Worker return -errno;
2637*7688df22SAndroid Build Coastguard Worker *handle = sg.handle;
2638*7688df22SAndroid Build Coastguard Worker return 0;
2639*7688df22SAndroid Build Coastguard Worker }
2640*7688df22SAndroid Build Coastguard Worker
drmScatterGatherFree(int fd,drm_handle_t handle)2641*7688df22SAndroid Build Coastguard Worker drm_public int drmScatterGatherFree(int fd, drm_handle_t handle)
2642*7688df22SAndroid Build Coastguard Worker {
2643*7688df22SAndroid Build Coastguard Worker drm_scatter_gather_t sg;
2644*7688df22SAndroid Build Coastguard Worker
2645*7688df22SAndroid Build Coastguard Worker memclear(sg);
2646*7688df22SAndroid Build Coastguard Worker sg.handle = handle;
2647*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_SG_FREE, &sg))
2648*7688df22SAndroid Build Coastguard Worker return -errno;
2649*7688df22SAndroid Build Coastguard Worker return 0;
2650*7688df22SAndroid Build Coastguard Worker }
2651*7688df22SAndroid Build Coastguard Worker
2652*7688df22SAndroid Build Coastguard Worker /**
2653*7688df22SAndroid Build Coastguard Worker * Wait for VBLANK.
2654*7688df22SAndroid Build Coastguard Worker *
2655*7688df22SAndroid Build Coastguard Worker * \param fd file descriptor.
2656*7688df22SAndroid Build Coastguard Worker * \param vbl pointer to a drmVBlank structure.
2657*7688df22SAndroid Build Coastguard Worker *
2658*7688df22SAndroid Build Coastguard Worker * \return zero on success, or a negative value on failure.
2659*7688df22SAndroid Build Coastguard Worker *
2660*7688df22SAndroid Build Coastguard Worker * \internal
2661*7688df22SAndroid Build Coastguard Worker * This function is a wrapper around the DRM_IOCTL_WAIT_VBLANK ioctl.
2662*7688df22SAndroid Build Coastguard Worker */
drmWaitVBlank(int fd,drmVBlankPtr vbl)2663*7688df22SAndroid Build Coastguard Worker drm_public int drmWaitVBlank(int fd, drmVBlankPtr vbl)
2664*7688df22SAndroid Build Coastguard Worker {
2665*7688df22SAndroid Build Coastguard Worker struct timespec timeout, cur;
2666*7688df22SAndroid Build Coastguard Worker int ret;
2667*7688df22SAndroid Build Coastguard Worker
2668*7688df22SAndroid Build Coastguard Worker ret = clock_gettime(CLOCK_MONOTONIC, &timeout);
2669*7688df22SAndroid Build Coastguard Worker if (ret < 0) {
2670*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "clock_gettime failed: %s\n", strerror(errno));
2671*7688df22SAndroid Build Coastguard Worker goto out;
2672*7688df22SAndroid Build Coastguard Worker }
2673*7688df22SAndroid Build Coastguard Worker timeout.tv_sec++;
2674*7688df22SAndroid Build Coastguard Worker
2675*7688df22SAndroid Build Coastguard Worker do {
2676*7688df22SAndroid Build Coastguard Worker ret = ioctl(fd, DRM_IOCTL_WAIT_VBLANK, vbl);
2677*7688df22SAndroid Build Coastguard Worker vbl->request.type &= ~DRM_VBLANK_RELATIVE;
2678*7688df22SAndroid Build Coastguard Worker if (ret && errno == EINTR) {
2679*7688df22SAndroid Build Coastguard Worker clock_gettime(CLOCK_MONOTONIC, &cur);
2680*7688df22SAndroid Build Coastguard Worker /* Timeout after 1s */
2681*7688df22SAndroid Build Coastguard Worker if (cur.tv_sec > timeout.tv_sec + 1 ||
2682*7688df22SAndroid Build Coastguard Worker (cur.tv_sec == timeout.tv_sec && cur.tv_nsec >=
2683*7688df22SAndroid Build Coastguard Worker timeout.tv_nsec)) {
2684*7688df22SAndroid Build Coastguard Worker errno = EBUSY;
2685*7688df22SAndroid Build Coastguard Worker ret = -1;
2686*7688df22SAndroid Build Coastguard Worker break;
2687*7688df22SAndroid Build Coastguard Worker }
2688*7688df22SAndroid Build Coastguard Worker }
2689*7688df22SAndroid Build Coastguard Worker } while (ret && errno == EINTR);
2690*7688df22SAndroid Build Coastguard Worker
2691*7688df22SAndroid Build Coastguard Worker out:
2692*7688df22SAndroid Build Coastguard Worker return ret;
2693*7688df22SAndroid Build Coastguard Worker }
2694*7688df22SAndroid Build Coastguard Worker
drmError(int err,const char * label)2695*7688df22SAndroid Build Coastguard Worker drm_public int drmError(int err, const char *label)
2696*7688df22SAndroid Build Coastguard Worker {
2697*7688df22SAndroid Build Coastguard Worker switch (err) {
2698*7688df22SAndroid Build Coastguard Worker case DRM_ERR_NO_DEVICE:
2699*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "%s: no device\n", label);
2700*7688df22SAndroid Build Coastguard Worker break;
2701*7688df22SAndroid Build Coastguard Worker case DRM_ERR_NO_ACCESS:
2702*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "%s: no access\n", label);
2703*7688df22SAndroid Build Coastguard Worker break;
2704*7688df22SAndroid Build Coastguard Worker case DRM_ERR_NOT_ROOT:
2705*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "%s: not root\n", label);
2706*7688df22SAndroid Build Coastguard Worker break;
2707*7688df22SAndroid Build Coastguard Worker case DRM_ERR_INVALID:
2708*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "%s: invalid args\n", label);
2709*7688df22SAndroid Build Coastguard Worker break;
2710*7688df22SAndroid Build Coastguard Worker default:
2711*7688df22SAndroid Build Coastguard Worker if (err < 0)
2712*7688df22SAndroid Build Coastguard Worker err = -err;
2713*7688df22SAndroid Build Coastguard Worker fprintf( stderr, "%s: error %d (%s)\n", label, err, strerror(err) );
2714*7688df22SAndroid Build Coastguard Worker break;
2715*7688df22SAndroid Build Coastguard Worker }
2716*7688df22SAndroid Build Coastguard Worker
2717*7688df22SAndroid Build Coastguard Worker return 1;
2718*7688df22SAndroid Build Coastguard Worker }
2719*7688df22SAndroid Build Coastguard Worker
2720*7688df22SAndroid Build Coastguard Worker /**
2721*7688df22SAndroid Build Coastguard Worker * Install IRQ handler.
2722*7688df22SAndroid Build Coastguard Worker *
2723*7688df22SAndroid Build Coastguard Worker * \param fd file descriptor.
2724*7688df22SAndroid Build Coastguard Worker * \param irq IRQ number.
2725*7688df22SAndroid Build Coastguard Worker *
2726*7688df22SAndroid Build Coastguard Worker * \return zero on success, or a negative value on failure.
2727*7688df22SAndroid Build Coastguard Worker *
2728*7688df22SAndroid Build Coastguard Worker * \internal
2729*7688df22SAndroid Build Coastguard Worker * This function is a wrapper around the DRM_IOCTL_CONTROL ioctl, passing the
2730*7688df22SAndroid Build Coastguard Worker * argument in a drm_control structure.
2731*7688df22SAndroid Build Coastguard Worker */
drmCtlInstHandler(int fd,int irq)2732*7688df22SAndroid Build Coastguard Worker drm_public int drmCtlInstHandler(int fd, int irq)
2733*7688df22SAndroid Build Coastguard Worker {
2734*7688df22SAndroid Build Coastguard Worker drm_control_t ctl;
2735*7688df22SAndroid Build Coastguard Worker
2736*7688df22SAndroid Build Coastguard Worker memclear(ctl);
2737*7688df22SAndroid Build Coastguard Worker ctl.func = DRM_INST_HANDLER;
2738*7688df22SAndroid Build Coastguard Worker ctl.irq = irq;
2739*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_CONTROL, &ctl))
2740*7688df22SAndroid Build Coastguard Worker return -errno;
2741*7688df22SAndroid Build Coastguard Worker return 0;
2742*7688df22SAndroid Build Coastguard Worker }
2743*7688df22SAndroid Build Coastguard Worker
2744*7688df22SAndroid Build Coastguard Worker
2745*7688df22SAndroid Build Coastguard Worker /**
2746*7688df22SAndroid Build Coastguard Worker * Uninstall IRQ handler.
2747*7688df22SAndroid Build Coastguard Worker *
2748*7688df22SAndroid Build Coastguard Worker * \param fd file descriptor.
2749*7688df22SAndroid Build Coastguard Worker *
2750*7688df22SAndroid Build Coastguard Worker * \return zero on success, or a negative value on failure.
2751*7688df22SAndroid Build Coastguard Worker *
2752*7688df22SAndroid Build Coastguard Worker * \internal
2753*7688df22SAndroid Build Coastguard Worker * This function is a wrapper around the DRM_IOCTL_CONTROL ioctl, passing the
2754*7688df22SAndroid Build Coastguard Worker * argument in a drm_control structure.
2755*7688df22SAndroid Build Coastguard Worker */
drmCtlUninstHandler(int fd)2756*7688df22SAndroid Build Coastguard Worker drm_public int drmCtlUninstHandler(int fd)
2757*7688df22SAndroid Build Coastguard Worker {
2758*7688df22SAndroid Build Coastguard Worker drm_control_t ctl;
2759*7688df22SAndroid Build Coastguard Worker
2760*7688df22SAndroid Build Coastguard Worker memclear(ctl);
2761*7688df22SAndroid Build Coastguard Worker ctl.func = DRM_UNINST_HANDLER;
2762*7688df22SAndroid Build Coastguard Worker ctl.irq = 0;
2763*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_CONTROL, &ctl))
2764*7688df22SAndroid Build Coastguard Worker return -errno;
2765*7688df22SAndroid Build Coastguard Worker return 0;
2766*7688df22SAndroid Build Coastguard Worker }
2767*7688df22SAndroid Build Coastguard Worker
drmFinish(int fd,int context,drmLockFlags flags)2768*7688df22SAndroid Build Coastguard Worker drm_public int drmFinish(int fd, int context, drmLockFlags flags)
2769*7688df22SAndroid Build Coastguard Worker {
2770*7688df22SAndroid Build Coastguard Worker drm_lock_t lock;
2771*7688df22SAndroid Build Coastguard Worker
2772*7688df22SAndroid Build Coastguard Worker memclear(lock);
2773*7688df22SAndroid Build Coastguard Worker lock.context = context;
2774*7688df22SAndroid Build Coastguard Worker if (flags & DRM_LOCK_READY) lock.flags |= _DRM_LOCK_READY;
2775*7688df22SAndroid Build Coastguard Worker if (flags & DRM_LOCK_QUIESCENT) lock.flags |= _DRM_LOCK_QUIESCENT;
2776*7688df22SAndroid Build Coastguard Worker if (flags & DRM_LOCK_FLUSH) lock.flags |= _DRM_LOCK_FLUSH;
2777*7688df22SAndroid Build Coastguard Worker if (flags & DRM_LOCK_FLUSH_ALL) lock.flags |= _DRM_LOCK_FLUSH_ALL;
2778*7688df22SAndroid Build Coastguard Worker if (flags & DRM_HALT_ALL_QUEUES) lock.flags |= _DRM_HALT_ALL_QUEUES;
2779*7688df22SAndroid Build Coastguard Worker if (flags & DRM_HALT_CUR_QUEUES) lock.flags |= _DRM_HALT_CUR_QUEUES;
2780*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_FINISH, &lock))
2781*7688df22SAndroid Build Coastguard Worker return -errno;
2782*7688df22SAndroid Build Coastguard Worker return 0;
2783*7688df22SAndroid Build Coastguard Worker }
2784*7688df22SAndroid Build Coastguard Worker
2785*7688df22SAndroid Build Coastguard Worker /**
2786*7688df22SAndroid Build Coastguard Worker * Get IRQ from bus ID.
2787*7688df22SAndroid Build Coastguard Worker *
2788*7688df22SAndroid Build Coastguard Worker * \param fd file descriptor.
2789*7688df22SAndroid Build Coastguard Worker * \param busnum bus number.
2790*7688df22SAndroid Build Coastguard Worker * \param devnum device number.
2791*7688df22SAndroid Build Coastguard Worker * \param funcnum function number.
2792*7688df22SAndroid Build Coastguard Worker *
2793*7688df22SAndroid Build Coastguard Worker * \return IRQ number on success, or a negative value on failure.
2794*7688df22SAndroid Build Coastguard Worker *
2795*7688df22SAndroid Build Coastguard Worker * \internal
2796*7688df22SAndroid Build Coastguard Worker * This function is a wrapper around the DRM_IOCTL_IRQ_BUSID ioctl, passing the
2797*7688df22SAndroid Build Coastguard Worker * arguments in a drm_irq_busid structure.
2798*7688df22SAndroid Build Coastguard Worker */
drmGetInterruptFromBusID(int fd,int busnum,int devnum,int funcnum)2799*7688df22SAndroid Build Coastguard Worker drm_public int drmGetInterruptFromBusID(int fd, int busnum, int devnum,
2800*7688df22SAndroid Build Coastguard Worker int funcnum)
2801*7688df22SAndroid Build Coastguard Worker {
2802*7688df22SAndroid Build Coastguard Worker drm_irq_busid_t p;
2803*7688df22SAndroid Build Coastguard Worker
2804*7688df22SAndroid Build Coastguard Worker memclear(p);
2805*7688df22SAndroid Build Coastguard Worker p.busnum = busnum;
2806*7688df22SAndroid Build Coastguard Worker p.devnum = devnum;
2807*7688df22SAndroid Build Coastguard Worker p.funcnum = funcnum;
2808*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_IRQ_BUSID, &p))
2809*7688df22SAndroid Build Coastguard Worker return -errno;
2810*7688df22SAndroid Build Coastguard Worker return p.irq;
2811*7688df22SAndroid Build Coastguard Worker }
2812*7688df22SAndroid Build Coastguard Worker
drmAddContextTag(int fd,drm_context_t context,void * tag)2813*7688df22SAndroid Build Coastguard Worker drm_public int drmAddContextTag(int fd, drm_context_t context, void *tag)
2814*7688df22SAndroid Build Coastguard Worker {
2815*7688df22SAndroid Build Coastguard Worker drmHashEntry *entry = drmGetEntry(fd);
2816*7688df22SAndroid Build Coastguard Worker
2817*7688df22SAndroid Build Coastguard Worker if (drmHashInsert(entry->tagTable, context, tag)) {
2818*7688df22SAndroid Build Coastguard Worker drmHashDelete(entry->tagTable, context);
2819*7688df22SAndroid Build Coastguard Worker drmHashInsert(entry->tagTable, context, tag);
2820*7688df22SAndroid Build Coastguard Worker }
2821*7688df22SAndroid Build Coastguard Worker return 0;
2822*7688df22SAndroid Build Coastguard Worker }
2823*7688df22SAndroid Build Coastguard Worker
drmDelContextTag(int fd,drm_context_t context)2824*7688df22SAndroid Build Coastguard Worker drm_public int drmDelContextTag(int fd, drm_context_t context)
2825*7688df22SAndroid Build Coastguard Worker {
2826*7688df22SAndroid Build Coastguard Worker drmHashEntry *entry = drmGetEntry(fd);
2827*7688df22SAndroid Build Coastguard Worker
2828*7688df22SAndroid Build Coastguard Worker return drmHashDelete(entry->tagTable, context);
2829*7688df22SAndroid Build Coastguard Worker }
2830*7688df22SAndroid Build Coastguard Worker
drmGetContextTag(int fd,drm_context_t context)2831*7688df22SAndroid Build Coastguard Worker drm_public void *drmGetContextTag(int fd, drm_context_t context)
2832*7688df22SAndroid Build Coastguard Worker {
2833*7688df22SAndroid Build Coastguard Worker drmHashEntry *entry = drmGetEntry(fd);
2834*7688df22SAndroid Build Coastguard Worker void *value;
2835*7688df22SAndroid Build Coastguard Worker
2836*7688df22SAndroid Build Coastguard Worker if (drmHashLookup(entry->tagTable, context, &value))
2837*7688df22SAndroid Build Coastguard Worker return NULL;
2838*7688df22SAndroid Build Coastguard Worker
2839*7688df22SAndroid Build Coastguard Worker return value;
2840*7688df22SAndroid Build Coastguard Worker }
2841*7688df22SAndroid Build Coastguard Worker
drmAddContextPrivateMapping(int fd,drm_context_t ctx_id,drm_handle_t handle)2842*7688df22SAndroid Build Coastguard Worker drm_public int drmAddContextPrivateMapping(int fd, drm_context_t ctx_id,
2843*7688df22SAndroid Build Coastguard Worker drm_handle_t handle)
2844*7688df22SAndroid Build Coastguard Worker {
2845*7688df22SAndroid Build Coastguard Worker drm_ctx_priv_map_t map;
2846*7688df22SAndroid Build Coastguard Worker
2847*7688df22SAndroid Build Coastguard Worker memclear(map);
2848*7688df22SAndroid Build Coastguard Worker map.ctx_id = ctx_id;
2849*7688df22SAndroid Build Coastguard Worker map.handle = (void *)(uintptr_t)handle;
2850*7688df22SAndroid Build Coastguard Worker
2851*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_SET_SAREA_CTX, &map))
2852*7688df22SAndroid Build Coastguard Worker return -errno;
2853*7688df22SAndroid Build Coastguard Worker return 0;
2854*7688df22SAndroid Build Coastguard Worker }
2855*7688df22SAndroid Build Coastguard Worker
drmGetContextPrivateMapping(int fd,drm_context_t ctx_id,drm_handle_t * handle)2856*7688df22SAndroid Build Coastguard Worker drm_public int drmGetContextPrivateMapping(int fd, drm_context_t ctx_id,
2857*7688df22SAndroid Build Coastguard Worker drm_handle_t *handle)
2858*7688df22SAndroid Build Coastguard Worker {
2859*7688df22SAndroid Build Coastguard Worker drm_ctx_priv_map_t map;
2860*7688df22SAndroid Build Coastguard Worker
2861*7688df22SAndroid Build Coastguard Worker memclear(map);
2862*7688df22SAndroid Build Coastguard Worker map.ctx_id = ctx_id;
2863*7688df22SAndroid Build Coastguard Worker
2864*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_GET_SAREA_CTX, &map))
2865*7688df22SAndroid Build Coastguard Worker return -errno;
2866*7688df22SAndroid Build Coastguard Worker if (handle)
2867*7688df22SAndroid Build Coastguard Worker *handle = (drm_handle_t)(uintptr_t)map.handle;
2868*7688df22SAndroid Build Coastguard Worker
2869*7688df22SAndroid Build Coastguard Worker return 0;
2870*7688df22SAndroid Build Coastguard Worker }
2871*7688df22SAndroid Build Coastguard Worker
drmGetMap(int fd,int idx,drm_handle_t * offset,drmSize * size,drmMapType * type,drmMapFlags * flags,drm_handle_t * handle,int * mtrr)2872*7688df22SAndroid Build Coastguard Worker drm_public int drmGetMap(int fd, int idx, drm_handle_t *offset, drmSize *size,
2873*7688df22SAndroid Build Coastguard Worker drmMapType *type, drmMapFlags *flags,
2874*7688df22SAndroid Build Coastguard Worker drm_handle_t *handle, int *mtrr)
2875*7688df22SAndroid Build Coastguard Worker {
2876*7688df22SAndroid Build Coastguard Worker drm_map_t map;
2877*7688df22SAndroid Build Coastguard Worker
2878*7688df22SAndroid Build Coastguard Worker memclear(map);
2879*7688df22SAndroid Build Coastguard Worker map.offset = idx;
2880*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_GET_MAP, &map))
2881*7688df22SAndroid Build Coastguard Worker return -errno;
2882*7688df22SAndroid Build Coastguard Worker *offset = map.offset;
2883*7688df22SAndroid Build Coastguard Worker *size = map.size;
2884*7688df22SAndroid Build Coastguard Worker *type = (drmMapType)map.type;
2885*7688df22SAndroid Build Coastguard Worker *flags = (drmMapFlags)map.flags;
2886*7688df22SAndroid Build Coastguard Worker *handle = (unsigned long)map.handle;
2887*7688df22SAndroid Build Coastguard Worker *mtrr = map.mtrr;
2888*7688df22SAndroid Build Coastguard Worker return 0;
2889*7688df22SAndroid Build Coastguard Worker }
2890*7688df22SAndroid Build Coastguard Worker
drmGetClient(int fd,int idx,int * auth,int * pid,int * uid,unsigned long * magic,unsigned long * iocs)2891*7688df22SAndroid Build Coastguard Worker drm_public int drmGetClient(int fd, int idx, int *auth, int *pid, int *uid,
2892*7688df22SAndroid Build Coastguard Worker unsigned long *magic, unsigned long *iocs)
2893*7688df22SAndroid Build Coastguard Worker {
2894*7688df22SAndroid Build Coastguard Worker drm_client_t client;
2895*7688df22SAndroid Build Coastguard Worker
2896*7688df22SAndroid Build Coastguard Worker memclear(client);
2897*7688df22SAndroid Build Coastguard Worker client.idx = idx;
2898*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_GET_CLIENT, &client))
2899*7688df22SAndroid Build Coastguard Worker return -errno;
2900*7688df22SAndroid Build Coastguard Worker *auth = client.auth;
2901*7688df22SAndroid Build Coastguard Worker *pid = client.pid;
2902*7688df22SAndroid Build Coastguard Worker *uid = client.uid;
2903*7688df22SAndroid Build Coastguard Worker *magic = client.magic;
2904*7688df22SAndroid Build Coastguard Worker *iocs = client.iocs;
2905*7688df22SAndroid Build Coastguard Worker return 0;
2906*7688df22SAndroid Build Coastguard Worker }
2907*7688df22SAndroid Build Coastguard Worker
drmGetStats(int fd,drmStatsT * stats)2908*7688df22SAndroid Build Coastguard Worker drm_public int drmGetStats(int fd, drmStatsT *stats)
2909*7688df22SAndroid Build Coastguard Worker {
2910*7688df22SAndroid Build Coastguard Worker drm_stats_t s;
2911*7688df22SAndroid Build Coastguard Worker unsigned i;
2912*7688df22SAndroid Build Coastguard Worker
2913*7688df22SAndroid Build Coastguard Worker memclear(s);
2914*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_GET_STATS, &s))
2915*7688df22SAndroid Build Coastguard Worker return -errno;
2916*7688df22SAndroid Build Coastguard Worker
2917*7688df22SAndroid Build Coastguard Worker stats->count = 0;
2918*7688df22SAndroid Build Coastguard Worker memset(stats, 0, sizeof(*stats));
2919*7688df22SAndroid Build Coastguard Worker if (s.count > sizeof(stats->data)/sizeof(stats->data[0]))
2920*7688df22SAndroid Build Coastguard Worker return -1;
2921*7688df22SAndroid Build Coastguard Worker
2922*7688df22SAndroid Build Coastguard Worker #define SET_VALUE \
2923*7688df22SAndroid Build Coastguard Worker stats->data[i].long_format = "%-20.20s"; \
2924*7688df22SAndroid Build Coastguard Worker stats->data[i].rate_format = "%8.8s"; \
2925*7688df22SAndroid Build Coastguard Worker stats->data[i].isvalue = 1; \
2926*7688df22SAndroid Build Coastguard Worker stats->data[i].verbose = 0
2927*7688df22SAndroid Build Coastguard Worker
2928*7688df22SAndroid Build Coastguard Worker #define SET_COUNT \
2929*7688df22SAndroid Build Coastguard Worker stats->data[i].long_format = "%-20.20s"; \
2930*7688df22SAndroid Build Coastguard Worker stats->data[i].rate_format = "%5.5s"; \
2931*7688df22SAndroid Build Coastguard Worker stats->data[i].isvalue = 0; \
2932*7688df22SAndroid Build Coastguard Worker stats->data[i].mult_names = "kgm"; \
2933*7688df22SAndroid Build Coastguard Worker stats->data[i].mult = 1000; \
2934*7688df22SAndroid Build Coastguard Worker stats->data[i].verbose = 0
2935*7688df22SAndroid Build Coastguard Worker
2936*7688df22SAndroid Build Coastguard Worker #define SET_BYTE \
2937*7688df22SAndroid Build Coastguard Worker stats->data[i].long_format = "%-20.20s"; \
2938*7688df22SAndroid Build Coastguard Worker stats->data[i].rate_format = "%5.5s"; \
2939*7688df22SAndroid Build Coastguard Worker stats->data[i].isvalue = 0; \
2940*7688df22SAndroid Build Coastguard Worker stats->data[i].mult_names = "KGM"; \
2941*7688df22SAndroid Build Coastguard Worker stats->data[i].mult = 1024; \
2942*7688df22SAndroid Build Coastguard Worker stats->data[i].verbose = 0
2943*7688df22SAndroid Build Coastguard Worker
2944*7688df22SAndroid Build Coastguard Worker
2945*7688df22SAndroid Build Coastguard Worker stats->count = s.count;
2946*7688df22SAndroid Build Coastguard Worker for (i = 0; i < s.count; i++) {
2947*7688df22SAndroid Build Coastguard Worker stats->data[i].value = s.data[i].value;
2948*7688df22SAndroid Build Coastguard Worker switch (s.data[i].type) {
2949*7688df22SAndroid Build Coastguard Worker case _DRM_STAT_LOCK:
2950*7688df22SAndroid Build Coastguard Worker stats->data[i].long_name = "Lock";
2951*7688df22SAndroid Build Coastguard Worker stats->data[i].rate_name = "Lock";
2952*7688df22SAndroid Build Coastguard Worker SET_VALUE;
2953*7688df22SAndroid Build Coastguard Worker break;
2954*7688df22SAndroid Build Coastguard Worker case _DRM_STAT_OPENS:
2955*7688df22SAndroid Build Coastguard Worker stats->data[i].long_name = "Opens";
2956*7688df22SAndroid Build Coastguard Worker stats->data[i].rate_name = "O";
2957*7688df22SAndroid Build Coastguard Worker SET_COUNT;
2958*7688df22SAndroid Build Coastguard Worker stats->data[i].verbose = 1;
2959*7688df22SAndroid Build Coastguard Worker break;
2960*7688df22SAndroid Build Coastguard Worker case _DRM_STAT_CLOSES:
2961*7688df22SAndroid Build Coastguard Worker stats->data[i].long_name = "Closes";
2962*7688df22SAndroid Build Coastguard Worker stats->data[i].rate_name = "Lock";
2963*7688df22SAndroid Build Coastguard Worker SET_COUNT;
2964*7688df22SAndroid Build Coastguard Worker stats->data[i].verbose = 1;
2965*7688df22SAndroid Build Coastguard Worker break;
2966*7688df22SAndroid Build Coastguard Worker case _DRM_STAT_IOCTLS:
2967*7688df22SAndroid Build Coastguard Worker stats->data[i].long_name = "Ioctls";
2968*7688df22SAndroid Build Coastguard Worker stats->data[i].rate_name = "Ioc/s";
2969*7688df22SAndroid Build Coastguard Worker SET_COUNT;
2970*7688df22SAndroid Build Coastguard Worker break;
2971*7688df22SAndroid Build Coastguard Worker case _DRM_STAT_LOCKS:
2972*7688df22SAndroid Build Coastguard Worker stats->data[i].long_name = "Locks";
2973*7688df22SAndroid Build Coastguard Worker stats->data[i].rate_name = "Lck/s";
2974*7688df22SAndroid Build Coastguard Worker SET_COUNT;
2975*7688df22SAndroid Build Coastguard Worker break;
2976*7688df22SAndroid Build Coastguard Worker case _DRM_STAT_UNLOCKS:
2977*7688df22SAndroid Build Coastguard Worker stats->data[i].long_name = "Unlocks";
2978*7688df22SAndroid Build Coastguard Worker stats->data[i].rate_name = "Unl/s";
2979*7688df22SAndroid Build Coastguard Worker SET_COUNT;
2980*7688df22SAndroid Build Coastguard Worker break;
2981*7688df22SAndroid Build Coastguard Worker case _DRM_STAT_IRQ:
2982*7688df22SAndroid Build Coastguard Worker stats->data[i].long_name = "IRQs";
2983*7688df22SAndroid Build Coastguard Worker stats->data[i].rate_name = "IRQ/s";
2984*7688df22SAndroid Build Coastguard Worker SET_COUNT;
2985*7688df22SAndroid Build Coastguard Worker break;
2986*7688df22SAndroid Build Coastguard Worker case _DRM_STAT_PRIMARY:
2987*7688df22SAndroid Build Coastguard Worker stats->data[i].long_name = "Primary Bytes";
2988*7688df22SAndroid Build Coastguard Worker stats->data[i].rate_name = "PB/s";
2989*7688df22SAndroid Build Coastguard Worker SET_BYTE;
2990*7688df22SAndroid Build Coastguard Worker break;
2991*7688df22SAndroid Build Coastguard Worker case _DRM_STAT_SECONDARY:
2992*7688df22SAndroid Build Coastguard Worker stats->data[i].long_name = "Secondary Bytes";
2993*7688df22SAndroid Build Coastguard Worker stats->data[i].rate_name = "SB/s";
2994*7688df22SAndroid Build Coastguard Worker SET_BYTE;
2995*7688df22SAndroid Build Coastguard Worker break;
2996*7688df22SAndroid Build Coastguard Worker case _DRM_STAT_DMA:
2997*7688df22SAndroid Build Coastguard Worker stats->data[i].long_name = "DMA";
2998*7688df22SAndroid Build Coastguard Worker stats->data[i].rate_name = "DMA/s";
2999*7688df22SAndroid Build Coastguard Worker SET_COUNT;
3000*7688df22SAndroid Build Coastguard Worker break;
3001*7688df22SAndroid Build Coastguard Worker case _DRM_STAT_SPECIAL:
3002*7688df22SAndroid Build Coastguard Worker stats->data[i].long_name = "Special DMA";
3003*7688df22SAndroid Build Coastguard Worker stats->data[i].rate_name = "dma/s";
3004*7688df22SAndroid Build Coastguard Worker SET_COUNT;
3005*7688df22SAndroid Build Coastguard Worker break;
3006*7688df22SAndroid Build Coastguard Worker case _DRM_STAT_MISSED:
3007*7688df22SAndroid Build Coastguard Worker stats->data[i].long_name = "Miss";
3008*7688df22SAndroid Build Coastguard Worker stats->data[i].rate_name = "Ms/s";
3009*7688df22SAndroid Build Coastguard Worker SET_COUNT;
3010*7688df22SAndroid Build Coastguard Worker break;
3011*7688df22SAndroid Build Coastguard Worker case _DRM_STAT_VALUE:
3012*7688df22SAndroid Build Coastguard Worker stats->data[i].long_name = "Value";
3013*7688df22SAndroid Build Coastguard Worker stats->data[i].rate_name = "Value";
3014*7688df22SAndroid Build Coastguard Worker SET_VALUE;
3015*7688df22SAndroid Build Coastguard Worker break;
3016*7688df22SAndroid Build Coastguard Worker case _DRM_STAT_BYTE:
3017*7688df22SAndroid Build Coastguard Worker stats->data[i].long_name = "Bytes";
3018*7688df22SAndroid Build Coastguard Worker stats->data[i].rate_name = "B/s";
3019*7688df22SAndroid Build Coastguard Worker SET_BYTE;
3020*7688df22SAndroid Build Coastguard Worker break;
3021*7688df22SAndroid Build Coastguard Worker case _DRM_STAT_COUNT:
3022*7688df22SAndroid Build Coastguard Worker default:
3023*7688df22SAndroid Build Coastguard Worker stats->data[i].long_name = "Count";
3024*7688df22SAndroid Build Coastguard Worker stats->data[i].rate_name = "Cnt/s";
3025*7688df22SAndroid Build Coastguard Worker SET_COUNT;
3026*7688df22SAndroid Build Coastguard Worker break;
3027*7688df22SAndroid Build Coastguard Worker }
3028*7688df22SAndroid Build Coastguard Worker }
3029*7688df22SAndroid Build Coastguard Worker return 0;
3030*7688df22SAndroid Build Coastguard Worker }
3031*7688df22SAndroid Build Coastguard Worker
3032*7688df22SAndroid Build Coastguard Worker /**
3033*7688df22SAndroid Build Coastguard Worker * Issue a set-version ioctl.
3034*7688df22SAndroid Build Coastguard Worker *
3035*7688df22SAndroid Build Coastguard Worker * \param fd file descriptor.
3036*7688df22SAndroid Build Coastguard Worker * \param drmCommandIndex command index
3037*7688df22SAndroid Build Coastguard Worker * \param data source pointer of the data to be read and written.
3038*7688df22SAndroid Build Coastguard Worker * \param size size of the data to be read and written.
3039*7688df22SAndroid Build Coastguard Worker *
3040*7688df22SAndroid Build Coastguard Worker * \return zero on success, or a negative value on failure.
3041*7688df22SAndroid Build Coastguard Worker *
3042*7688df22SAndroid Build Coastguard Worker * \internal
3043*7688df22SAndroid Build Coastguard Worker * It issues a read-write ioctl given by
3044*7688df22SAndroid Build Coastguard Worker * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
3045*7688df22SAndroid Build Coastguard Worker */
drmSetInterfaceVersion(int fd,drmSetVersion * version)3046*7688df22SAndroid Build Coastguard Worker drm_public int drmSetInterfaceVersion(int fd, drmSetVersion *version)
3047*7688df22SAndroid Build Coastguard Worker {
3048*7688df22SAndroid Build Coastguard Worker int retcode = 0;
3049*7688df22SAndroid Build Coastguard Worker drm_set_version_t sv;
3050*7688df22SAndroid Build Coastguard Worker
3051*7688df22SAndroid Build Coastguard Worker memclear(sv);
3052*7688df22SAndroid Build Coastguard Worker sv.drm_di_major = version->drm_di_major;
3053*7688df22SAndroid Build Coastguard Worker sv.drm_di_minor = version->drm_di_minor;
3054*7688df22SAndroid Build Coastguard Worker sv.drm_dd_major = version->drm_dd_major;
3055*7688df22SAndroid Build Coastguard Worker sv.drm_dd_minor = version->drm_dd_minor;
3056*7688df22SAndroid Build Coastguard Worker
3057*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_SET_VERSION, &sv)) {
3058*7688df22SAndroid Build Coastguard Worker retcode = -errno;
3059*7688df22SAndroid Build Coastguard Worker }
3060*7688df22SAndroid Build Coastguard Worker
3061*7688df22SAndroid Build Coastguard Worker version->drm_di_major = sv.drm_di_major;
3062*7688df22SAndroid Build Coastguard Worker version->drm_di_minor = sv.drm_di_minor;
3063*7688df22SAndroid Build Coastguard Worker version->drm_dd_major = sv.drm_dd_major;
3064*7688df22SAndroid Build Coastguard Worker version->drm_dd_minor = sv.drm_dd_minor;
3065*7688df22SAndroid Build Coastguard Worker
3066*7688df22SAndroid Build Coastguard Worker return retcode;
3067*7688df22SAndroid Build Coastguard Worker }
3068*7688df22SAndroid Build Coastguard Worker
3069*7688df22SAndroid Build Coastguard Worker /**
3070*7688df22SAndroid Build Coastguard Worker * Send a device-specific command.
3071*7688df22SAndroid Build Coastguard Worker *
3072*7688df22SAndroid Build Coastguard Worker * \param fd file descriptor.
3073*7688df22SAndroid Build Coastguard Worker * \param drmCommandIndex command index
3074*7688df22SAndroid Build Coastguard Worker *
3075*7688df22SAndroid Build Coastguard Worker * \return zero on success, or a negative value on failure.
3076*7688df22SAndroid Build Coastguard Worker *
3077*7688df22SAndroid Build Coastguard Worker * \internal
3078*7688df22SAndroid Build Coastguard Worker * It issues a ioctl given by
3079*7688df22SAndroid Build Coastguard Worker * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
3080*7688df22SAndroid Build Coastguard Worker */
drmCommandNone(int fd,unsigned long drmCommandIndex)3081*7688df22SAndroid Build Coastguard Worker drm_public int drmCommandNone(int fd, unsigned long drmCommandIndex)
3082*7688df22SAndroid Build Coastguard Worker {
3083*7688df22SAndroid Build Coastguard Worker unsigned long request;
3084*7688df22SAndroid Build Coastguard Worker
3085*7688df22SAndroid Build Coastguard Worker request = DRM_IO( DRM_COMMAND_BASE + drmCommandIndex);
3086*7688df22SAndroid Build Coastguard Worker
3087*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, request, NULL)) {
3088*7688df22SAndroid Build Coastguard Worker return -errno;
3089*7688df22SAndroid Build Coastguard Worker }
3090*7688df22SAndroid Build Coastguard Worker return 0;
3091*7688df22SAndroid Build Coastguard Worker }
3092*7688df22SAndroid Build Coastguard Worker
3093*7688df22SAndroid Build Coastguard Worker
3094*7688df22SAndroid Build Coastguard Worker /**
3095*7688df22SAndroid Build Coastguard Worker * Send a device-specific read command.
3096*7688df22SAndroid Build Coastguard Worker *
3097*7688df22SAndroid Build Coastguard Worker * \param fd file descriptor.
3098*7688df22SAndroid Build Coastguard Worker * \param drmCommandIndex command index
3099*7688df22SAndroid Build Coastguard Worker * \param data destination pointer of the data to be read.
3100*7688df22SAndroid Build Coastguard Worker * \param size size of the data to be read.
3101*7688df22SAndroid Build Coastguard Worker *
3102*7688df22SAndroid Build Coastguard Worker * \return zero on success, or a negative value on failure.
3103*7688df22SAndroid Build Coastguard Worker *
3104*7688df22SAndroid Build Coastguard Worker * \internal
3105*7688df22SAndroid Build Coastguard Worker * It issues a read ioctl given by
3106*7688df22SAndroid Build Coastguard Worker * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
3107*7688df22SAndroid Build Coastguard Worker */
drmCommandRead(int fd,unsigned long drmCommandIndex,void * data,unsigned long size)3108*7688df22SAndroid Build Coastguard Worker drm_public int drmCommandRead(int fd, unsigned long drmCommandIndex,
3109*7688df22SAndroid Build Coastguard Worker void *data, unsigned long size)
3110*7688df22SAndroid Build Coastguard Worker {
3111*7688df22SAndroid Build Coastguard Worker unsigned long request;
3112*7688df22SAndroid Build Coastguard Worker
3113*7688df22SAndroid Build Coastguard Worker request = DRM_IOC( DRM_IOC_READ, DRM_IOCTL_BASE,
3114*7688df22SAndroid Build Coastguard Worker DRM_COMMAND_BASE + drmCommandIndex, size);
3115*7688df22SAndroid Build Coastguard Worker
3116*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, request, data)) {
3117*7688df22SAndroid Build Coastguard Worker return -errno;
3118*7688df22SAndroid Build Coastguard Worker }
3119*7688df22SAndroid Build Coastguard Worker return 0;
3120*7688df22SAndroid Build Coastguard Worker }
3121*7688df22SAndroid Build Coastguard Worker
3122*7688df22SAndroid Build Coastguard Worker
3123*7688df22SAndroid Build Coastguard Worker /**
3124*7688df22SAndroid Build Coastguard Worker * Send a device-specific write command.
3125*7688df22SAndroid Build Coastguard Worker *
3126*7688df22SAndroid Build Coastguard Worker * \param fd file descriptor.
3127*7688df22SAndroid Build Coastguard Worker * \param drmCommandIndex command index
3128*7688df22SAndroid Build Coastguard Worker * \param data source pointer of the data to be written.
3129*7688df22SAndroid Build Coastguard Worker * \param size size of the data to be written.
3130*7688df22SAndroid Build Coastguard Worker *
3131*7688df22SAndroid Build Coastguard Worker * \return zero on success, or a negative value on failure.
3132*7688df22SAndroid Build Coastguard Worker *
3133*7688df22SAndroid Build Coastguard Worker * \internal
3134*7688df22SAndroid Build Coastguard Worker * It issues a write ioctl given by
3135*7688df22SAndroid Build Coastguard Worker * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
3136*7688df22SAndroid Build Coastguard Worker */
drmCommandWrite(int fd,unsigned long drmCommandIndex,void * data,unsigned long size)3137*7688df22SAndroid Build Coastguard Worker drm_public int drmCommandWrite(int fd, unsigned long drmCommandIndex,
3138*7688df22SAndroid Build Coastguard Worker void *data, unsigned long size)
3139*7688df22SAndroid Build Coastguard Worker {
3140*7688df22SAndroid Build Coastguard Worker unsigned long request;
3141*7688df22SAndroid Build Coastguard Worker
3142*7688df22SAndroid Build Coastguard Worker request = DRM_IOC( DRM_IOC_WRITE, DRM_IOCTL_BASE,
3143*7688df22SAndroid Build Coastguard Worker DRM_COMMAND_BASE + drmCommandIndex, size);
3144*7688df22SAndroid Build Coastguard Worker
3145*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, request, data)) {
3146*7688df22SAndroid Build Coastguard Worker return -errno;
3147*7688df22SAndroid Build Coastguard Worker }
3148*7688df22SAndroid Build Coastguard Worker return 0;
3149*7688df22SAndroid Build Coastguard Worker }
3150*7688df22SAndroid Build Coastguard Worker
3151*7688df22SAndroid Build Coastguard Worker
3152*7688df22SAndroid Build Coastguard Worker /**
3153*7688df22SAndroid Build Coastguard Worker * Send a device-specific read-write command.
3154*7688df22SAndroid Build Coastguard Worker *
3155*7688df22SAndroid Build Coastguard Worker * \param fd file descriptor.
3156*7688df22SAndroid Build Coastguard Worker * \param drmCommandIndex command index
3157*7688df22SAndroid Build Coastguard Worker * \param data source pointer of the data to be read and written.
3158*7688df22SAndroid Build Coastguard Worker * \param size size of the data to be read and written.
3159*7688df22SAndroid Build Coastguard Worker *
3160*7688df22SAndroid Build Coastguard Worker * \return zero on success, or a negative value on failure.
3161*7688df22SAndroid Build Coastguard Worker *
3162*7688df22SAndroid Build Coastguard Worker * \internal
3163*7688df22SAndroid Build Coastguard Worker * It issues a read-write ioctl given by
3164*7688df22SAndroid Build Coastguard Worker * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
3165*7688df22SAndroid Build Coastguard Worker */
drmCommandWriteRead(int fd,unsigned long drmCommandIndex,void * data,unsigned long size)3166*7688df22SAndroid Build Coastguard Worker drm_public int drmCommandWriteRead(int fd, unsigned long drmCommandIndex,
3167*7688df22SAndroid Build Coastguard Worker void *data, unsigned long size)
3168*7688df22SAndroid Build Coastguard Worker {
3169*7688df22SAndroid Build Coastguard Worker unsigned long request;
3170*7688df22SAndroid Build Coastguard Worker
3171*7688df22SAndroid Build Coastguard Worker request = DRM_IOC( DRM_IOC_READ|DRM_IOC_WRITE, DRM_IOCTL_BASE,
3172*7688df22SAndroid Build Coastguard Worker DRM_COMMAND_BASE + drmCommandIndex, size);
3173*7688df22SAndroid Build Coastguard Worker
3174*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, request, data))
3175*7688df22SAndroid Build Coastguard Worker return -errno;
3176*7688df22SAndroid Build Coastguard Worker return 0;
3177*7688df22SAndroid Build Coastguard Worker }
3178*7688df22SAndroid Build Coastguard Worker
3179*7688df22SAndroid Build Coastguard Worker #define DRM_MAX_FDS 16
3180*7688df22SAndroid Build Coastguard Worker static struct {
3181*7688df22SAndroid Build Coastguard Worker char *BusID;
3182*7688df22SAndroid Build Coastguard Worker int fd;
3183*7688df22SAndroid Build Coastguard Worker int refcount;
3184*7688df22SAndroid Build Coastguard Worker int type;
3185*7688df22SAndroid Build Coastguard Worker } connection[DRM_MAX_FDS];
3186*7688df22SAndroid Build Coastguard Worker
3187*7688df22SAndroid Build Coastguard Worker static int nr_fds = 0;
3188*7688df22SAndroid Build Coastguard Worker
drmOpenOnce(void * unused,const char * BusID,int * newlyopened)3189*7688df22SAndroid Build Coastguard Worker drm_public int drmOpenOnce(void *unused, const char *BusID, int *newlyopened)
3190*7688df22SAndroid Build Coastguard Worker {
3191*7688df22SAndroid Build Coastguard Worker return drmOpenOnceWithType(BusID, newlyopened, DRM_NODE_PRIMARY);
3192*7688df22SAndroid Build Coastguard Worker }
3193*7688df22SAndroid Build Coastguard Worker
drmOpenOnceWithType(const char * BusID,int * newlyopened,int type)3194*7688df22SAndroid Build Coastguard Worker drm_public int drmOpenOnceWithType(const char *BusID, int *newlyopened,
3195*7688df22SAndroid Build Coastguard Worker int type)
3196*7688df22SAndroid Build Coastguard Worker {
3197*7688df22SAndroid Build Coastguard Worker int i;
3198*7688df22SAndroid Build Coastguard Worker int fd;
3199*7688df22SAndroid Build Coastguard Worker
3200*7688df22SAndroid Build Coastguard Worker for (i = 0; i < nr_fds; i++)
3201*7688df22SAndroid Build Coastguard Worker if ((strcmp(BusID, connection[i].BusID) == 0) &&
3202*7688df22SAndroid Build Coastguard Worker (connection[i].type == type)) {
3203*7688df22SAndroid Build Coastguard Worker connection[i].refcount++;
3204*7688df22SAndroid Build Coastguard Worker *newlyopened = 0;
3205*7688df22SAndroid Build Coastguard Worker return connection[i].fd;
3206*7688df22SAndroid Build Coastguard Worker }
3207*7688df22SAndroid Build Coastguard Worker
3208*7688df22SAndroid Build Coastguard Worker fd = drmOpenWithType(NULL, BusID, type);
3209*7688df22SAndroid Build Coastguard Worker if (fd < 0 || nr_fds == DRM_MAX_FDS)
3210*7688df22SAndroid Build Coastguard Worker return fd;
3211*7688df22SAndroid Build Coastguard Worker
3212*7688df22SAndroid Build Coastguard Worker connection[nr_fds].BusID = strdup(BusID);
3213*7688df22SAndroid Build Coastguard Worker connection[nr_fds].fd = fd;
3214*7688df22SAndroid Build Coastguard Worker connection[nr_fds].refcount = 1;
3215*7688df22SAndroid Build Coastguard Worker connection[nr_fds].type = type;
3216*7688df22SAndroid Build Coastguard Worker *newlyopened = 1;
3217*7688df22SAndroid Build Coastguard Worker
3218*7688df22SAndroid Build Coastguard Worker if (0)
3219*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "saved connection %d for %s %d\n",
3220*7688df22SAndroid Build Coastguard Worker nr_fds, connection[nr_fds].BusID,
3221*7688df22SAndroid Build Coastguard Worker strcmp(BusID, connection[nr_fds].BusID));
3222*7688df22SAndroid Build Coastguard Worker
3223*7688df22SAndroid Build Coastguard Worker nr_fds++;
3224*7688df22SAndroid Build Coastguard Worker
3225*7688df22SAndroid Build Coastguard Worker return fd;
3226*7688df22SAndroid Build Coastguard Worker }
3227*7688df22SAndroid Build Coastguard Worker
drmCloseOnce(int fd)3228*7688df22SAndroid Build Coastguard Worker drm_public void drmCloseOnce(int fd)
3229*7688df22SAndroid Build Coastguard Worker {
3230*7688df22SAndroid Build Coastguard Worker int i;
3231*7688df22SAndroid Build Coastguard Worker
3232*7688df22SAndroid Build Coastguard Worker for (i = 0; i < nr_fds; i++) {
3233*7688df22SAndroid Build Coastguard Worker if (fd == connection[i].fd) {
3234*7688df22SAndroid Build Coastguard Worker if (--connection[i].refcount == 0) {
3235*7688df22SAndroid Build Coastguard Worker drmClose(connection[i].fd);
3236*7688df22SAndroid Build Coastguard Worker free(connection[i].BusID);
3237*7688df22SAndroid Build Coastguard Worker
3238*7688df22SAndroid Build Coastguard Worker if (i < --nr_fds)
3239*7688df22SAndroid Build Coastguard Worker connection[i] = connection[nr_fds];
3240*7688df22SAndroid Build Coastguard Worker
3241*7688df22SAndroid Build Coastguard Worker return;
3242*7688df22SAndroid Build Coastguard Worker }
3243*7688df22SAndroid Build Coastguard Worker }
3244*7688df22SAndroid Build Coastguard Worker }
3245*7688df22SAndroid Build Coastguard Worker }
3246*7688df22SAndroid Build Coastguard Worker
drmSetMaster(int fd)3247*7688df22SAndroid Build Coastguard Worker drm_public int drmSetMaster(int fd)
3248*7688df22SAndroid Build Coastguard Worker {
3249*7688df22SAndroid Build Coastguard Worker return drmIoctl(fd, DRM_IOCTL_SET_MASTER, NULL);
3250*7688df22SAndroid Build Coastguard Worker }
3251*7688df22SAndroid Build Coastguard Worker
drmDropMaster(int fd)3252*7688df22SAndroid Build Coastguard Worker drm_public int drmDropMaster(int fd)
3253*7688df22SAndroid Build Coastguard Worker {
3254*7688df22SAndroid Build Coastguard Worker return drmIoctl(fd, DRM_IOCTL_DROP_MASTER, NULL);
3255*7688df22SAndroid Build Coastguard Worker }
3256*7688df22SAndroid Build Coastguard Worker
drmIsMaster(int fd)3257*7688df22SAndroid Build Coastguard Worker drm_public int drmIsMaster(int fd)
3258*7688df22SAndroid Build Coastguard Worker {
3259*7688df22SAndroid Build Coastguard Worker /* Detect master by attempting something that requires master.
3260*7688df22SAndroid Build Coastguard Worker *
3261*7688df22SAndroid Build Coastguard Worker * Authenticating magic tokens requires master and 0 is an
3262*7688df22SAndroid Build Coastguard Worker * internal kernel detail which we could use. Attempting this on
3263*7688df22SAndroid Build Coastguard Worker * a master fd would fail therefore fail with EINVAL because 0
3264*7688df22SAndroid Build Coastguard Worker * is invalid.
3265*7688df22SAndroid Build Coastguard Worker *
3266*7688df22SAndroid Build Coastguard Worker * A non-master fd will fail with EACCES, as the kernel checks
3267*7688df22SAndroid Build Coastguard Worker * for master before attempting to do anything else.
3268*7688df22SAndroid Build Coastguard Worker *
3269*7688df22SAndroid Build Coastguard Worker * Since we don't want to leak implementation details, use
3270*7688df22SAndroid Build Coastguard Worker * EACCES.
3271*7688df22SAndroid Build Coastguard Worker */
3272*7688df22SAndroid Build Coastguard Worker return drmAuthMagic(fd, 0) != -EACCES;
3273*7688df22SAndroid Build Coastguard Worker }
3274*7688df22SAndroid Build Coastguard Worker
drmGetDeviceNameFromFd(int fd)3275*7688df22SAndroid Build Coastguard Worker drm_public char *drmGetDeviceNameFromFd(int fd)
3276*7688df22SAndroid Build Coastguard Worker {
3277*7688df22SAndroid Build Coastguard Worker #ifdef __FreeBSD__
3278*7688df22SAndroid Build Coastguard Worker struct stat sbuf;
3279*7688df22SAndroid Build Coastguard Worker int maj, min;
3280*7688df22SAndroid Build Coastguard Worker int nodetype;
3281*7688df22SAndroid Build Coastguard Worker
3282*7688df22SAndroid Build Coastguard Worker if (fstat(fd, &sbuf))
3283*7688df22SAndroid Build Coastguard Worker return NULL;
3284*7688df22SAndroid Build Coastguard Worker
3285*7688df22SAndroid Build Coastguard Worker maj = major(sbuf.st_rdev);
3286*7688df22SAndroid Build Coastguard Worker min = minor(sbuf.st_rdev);
3287*7688df22SAndroid Build Coastguard Worker nodetype = drmGetMinorType(maj, min);
3288*7688df22SAndroid Build Coastguard Worker return drmGetMinorNameForFD(fd, nodetype);
3289*7688df22SAndroid Build Coastguard Worker #else
3290*7688df22SAndroid Build Coastguard Worker char name[128];
3291*7688df22SAndroid Build Coastguard Worker struct stat sbuf;
3292*7688df22SAndroid Build Coastguard Worker dev_t d;
3293*7688df22SAndroid Build Coastguard Worker int i;
3294*7688df22SAndroid Build Coastguard Worker
3295*7688df22SAndroid Build Coastguard Worker /* The whole drmOpen thing is a fiasco and we need to find a way
3296*7688df22SAndroid Build Coastguard Worker * back to just using open(2). For now, however, lets just make
3297*7688df22SAndroid Build Coastguard Worker * things worse with even more ad hoc directory walking code to
3298*7688df22SAndroid Build Coastguard Worker * discover the device file name. */
3299*7688df22SAndroid Build Coastguard Worker
3300*7688df22SAndroid Build Coastguard Worker fstat(fd, &sbuf);
3301*7688df22SAndroid Build Coastguard Worker d = sbuf.st_rdev;
3302*7688df22SAndroid Build Coastguard Worker
3303*7688df22SAndroid Build Coastguard Worker for (i = 0; i < DRM_MAX_MINOR; i++) {
3304*7688df22SAndroid Build Coastguard Worker snprintf(name, sizeof name, DRM_DEV_NAME, DRM_DIR_NAME, i);
3305*7688df22SAndroid Build Coastguard Worker if (stat(name, &sbuf) == 0 && sbuf.st_rdev == d)
3306*7688df22SAndroid Build Coastguard Worker break;
3307*7688df22SAndroid Build Coastguard Worker }
3308*7688df22SAndroid Build Coastguard Worker if (i == DRM_MAX_MINOR)
3309*7688df22SAndroid Build Coastguard Worker return NULL;
3310*7688df22SAndroid Build Coastguard Worker
3311*7688df22SAndroid Build Coastguard Worker return strdup(name);
3312*7688df22SAndroid Build Coastguard Worker #endif
3313*7688df22SAndroid Build Coastguard Worker }
3314*7688df22SAndroid Build Coastguard Worker
drmNodeIsDRM(int maj,int min)3315*7688df22SAndroid Build Coastguard Worker static bool drmNodeIsDRM(int maj, int min)
3316*7688df22SAndroid Build Coastguard Worker {
3317*7688df22SAndroid Build Coastguard Worker #ifdef __linux__
3318*7688df22SAndroid Build Coastguard Worker char path[64];
3319*7688df22SAndroid Build Coastguard Worker struct stat sbuf;
3320*7688df22SAndroid Build Coastguard Worker
3321*7688df22SAndroid Build Coastguard Worker snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device/drm",
3322*7688df22SAndroid Build Coastguard Worker maj, min);
3323*7688df22SAndroid Build Coastguard Worker return stat(path, &sbuf) == 0;
3324*7688df22SAndroid Build Coastguard Worker #elif defined(__FreeBSD__)
3325*7688df22SAndroid Build Coastguard Worker char name[SPECNAMELEN];
3326*7688df22SAndroid Build Coastguard Worker
3327*7688df22SAndroid Build Coastguard Worker if (!devname_r(makedev(maj, min), S_IFCHR, name, sizeof(name)))
3328*7688df22SAndroid Build Coastguard Worker return 0;
3329*7688df22SAndroid Build Coastguard Worker /* Handle drm/ and dri/ as both are present in different FreeBSD version
3330*7688df22SAndroid Build Coastguard Worker * FreeBSD on amd64/i386/powerpc external kernel modules create node in
3331*7688df22SAndroid Build Coastguard Worker * in /dev/drm/ and links in /dev/dri while a WIP in kernel driver creates
3332*7688df22SAndroid Build Coastguard Worker * only device nodes in /dev/dri/ */
3333*7688df22SAndroid Build Coastguard Worker return (!strncmp(name, "drm/", 4) || !strncmp(name, "dri/", 4));
3334*7688df22SAndroid Build Coastguard Worker #else
3335*7688df22SAndroid Build Coastguard Worker return maj == DRM_MAJOR;
3336*7688df22SAndroid Build Coastguard Worker #endif
3337*7688df22SAndroid Build Coastguard Worker }
3338*7688df22SAndroid Build Coastguard Worker
drmGetNodeTypeFromFd(int fd)3339*7688df22SAndroid Build Coastguard Worker drm_public int drmGetNodeTypeFromFd(int fd)
3340*7688df22SAndroid Build Coastguard Worker {
3341*7688df22SAndroid Build Coastguard Worker struct stat sbuf;
3342*7688df22SAndroid Build Coastguard Worker int maj, min, type;
3343*7688df22SAndroid Build Coastguard Worker
3344*7688df22SAndroid Build Coastguard Worker if (fstat(fd, &sbuf))
3345*7688df22SAndroid Build Coastguard Worker return -1;
3346*7688df22SAndroid Build Coastguard Worker
3347*7688df22SAndroid Build Coastguard Worker maj = major(sbuf.st_rdev);
3348*7688df22SAndroid Build Coastguard Worker min = minor(sbuf.st_rdev);
3349*7688df22SAndroid Build Coastguard Worker
3350*7688df22SAndroid Build Coastguard Worker if (!drmNodeIsDRM(maj, min) || !S_ISCHR(sbuf.st_mode)) {
3351*7688df22SAndroid Build Coastguard Worker errno = EINVAL;
3352*7688df22SAndroid Build Coastguard Worker return -1;
3353*7688df22SAndroid Build Coastguard Worker }
3354*7688df22SAndroid Build Coastguard Worker
3355*7688df22SAndroid Build Coastguard Worker type = drmGetMinorType(maj, min);
3356*7688df22SAndroid Build Coastguard Worker if (type == -1)
3357*7688df22SAndroid Build Coastguard Worker errno = ENODEV;
3358*7688df22SAndroid Build Coastguard Worker return type;
3359*7688df22SAndroid Build Coastguard Worker }
3360*7688df22SAndroid Build Coastguard Worker
drmPrimeHandleToFD(int fd,uint32_t handle,uint32_t flags,int * prime_fd)3361*7688df22SAndroid Build Coastguard Worker drm_public int drmPrimeHandleToFD(int fd, uint32_t handle, uint32_t flags,
3362*7688df22SAndroid Build Coastguard Worker int *prime_fd)
3363*7688df22SAndroid Build Coastguard Worker {
3364*7688df22SAndroid Build Coastguard Worker struct drm_prime_handle args;
3365*7688df22SAndroid Build Coastguard Worker int ret;
3366*7688df22SAndroid Build Coastguard Worker
3367*7688df22SAndroid Build Coastguard Worker memclear(args);
3368*7688df22SAndroid Build Coastguard Worker args.fd = -1;
3369*7688df22SAndroid Build Coastguard Worker args.handle = handle;
3370*7688df22SAndroid Build Coastguard Worker args.flags = flags;
3371*7688df22SAndroid Build Coastguard Worker ret = drmIoctl(fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &args);
3372*7688df22SAndroid Build Coastguard Worker if (ret)
3373*7688df22SAndroid Build Coastguard Worker return ret;
3374*7688df22SAndroid Build Coastguard Worker
3375*7688df22SAndroid Build Coastguard Worker *prime_fd = args.fd;
3376*7688df22SAndroid Build Coastguard Worker return 0;
3377*7688df22SAndroid Build Coastguard Worker }
3378*7688df22SAndroid Build Coastguard Worker
drmPrimeFDToHandle(int fd,int prime_fd,uint32_t * handle)3379*7688df22SAndroid Build Coastguard Worker drm_public int drmPrimeFDToHandle(int fd, int prime_fd, uint32_t *handle)
3380*7688df22SAndroid Build Coastguard Worker {
3381*7688df22SAndroid Build Coastguard Worker struct drm_prime_handle args;
3382*7688df22SAndroid Build Coastguard Worker int ret;
3383*7688df22SAndroid Build Coastguard Worker
3384*7688df22SAndroid Build Coastguard Worker memclear(args);
3385*7688df22SAndroid Build Coastguard Worker args.fd = prime_fd;
3386*7688df22SAndroid Build Coastguard Worker ret = drmIoctl(fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &args);
3387*7688df22SAndroid Build Coastguard Worker if (ret)
3388*7688df22SAndroid Build Coastguard Worker return ret;
3389*7688df22SAndroid Build Coastguard Worker
3390*7688df22SAndroid Build Coastguard Worker *handle = args.handle;
3391*7688df22SAndroid Build Coastguard Worker return 0;
3392*7688df22SAndroid Build Coastguard Worker }
3393*7688df22SAndroid Build Coastguard Worker
drmCloseBufferHandle(int fd,uint32_t handle)3394*7688df22SAndroid Build Coastguard Worker drm_public int drmCloseBufferHandle(int fd, uint32_t handle)
3395*7688df22SAndroid Build Coastguard Worker {
3396*7688df22SAndroid Build Coastguard Worker struct drm_gem_close args;
3397*7688df22SAndroid Build Coastguard Worker
3398*7688df22SAndroid Build Coastguard Worker memclear(args);
3399*7688df22SAndroid Build Coastguard Worker args.handle = handle;
3400*7688df22SAndroid Build Coastguard Worker return drmIoctl(fd, DRM_IOCTL_GEM_CLOSE, &args);
3401*7688df22SAndroid Build Coastguard Worker }
3402*7688df22SAndroid Build Coastguard Worker
drmGetMinorNameForFD(int fd,int type)3403*7688df22SAndroid Build Coastguard Worker static char *drmGetMinorNameForFD(int fd, int type)
3404*7688df22SAndroid Build Coastguard Worker {
3405*7688df22SAndroid Build Coastguard Worker #ifdef __linux__
3406*7688df22SAndroid Build Coastguard Worker DIR *sysdir;
3407*7688df22SAndroid Build Coastguard Worker struct dirent *ent;
3408*7688df22SAndroid Build Coastguard Worker struct stat sbuf;
3409*7688df22SAndroid Build Coastguard Worker const char *name = drmGetMinorName(type);
3410*7688df22SAndroid Build Coastguard Worker int len;
3411*7688df22SAndroid Build Coastguard Worker char dev_name[64], buf[64];
3412*7688df22SAndroid Build Coastguard Worker int maj, min;
3413*7688df22SAndroid Build Coastguard Worker
3414*7688df22SAndroid Build Coastguard Worker if (!name)
3415*7688df22SAndroid Build Coastguard Worker return NULL;
3416*7688df22SAndroid Build Coastguard Worker
3417*7688df22SAndroid Build Coastguard Worker len = strlen(name);
3418*7688df22SAndroid Build Coastguard Worker
3419*7688df22SAndroid Build Coastguard Worker if (fstat(fd, &sbuf))
3420*7688df22SAndroid Build Coastguard Worker return NULL;
3421*7688df22SAndroid Build Coastguard Worker
3422*7688df22SAndroid Build Coastguard Worker maj = major(sbuf.st_rdev);
3423*7688df22SAndroid Build Coastguard Worker min = minor(sbuf.st_rdev);
3424*7688df22SAndroid Build Coastguard Worker
3425*7688df22SAndroid Build Coastguard Worker if (!drmNodeIsDRM(maj, min) || !S_ISCHR(sbuf.st_mode))
3426*7688df22SAndroid Build Coastguard Worker return NULL;
3427*7688df22SAndroid Build Coastguard Worker
3428*7688df22SAndroid Build Coastguard Worker snprintf(buf, sizeof(buf), "/sys/dev/char/%d:%d/device/drm", maj, min);
3429*7688df22SAndroid Build Coastguard Worker
3430*7688df22SAndroid Build Coastguard Worker sysdir = opendir(buf);
3431*7688df22SAndroid Build Coastguard Worker if (!sysdir)
3432*7688df22SAndroid Build Coastguard Worker return NULL;
3433*7688df22SAndroid Build Coastguard Worker
3434*7688df22SAndroid Build Coastguard Worker while ((ent = readdir(sysdir))) {
3435*7688df22SAndroid Build Coastguard Worker if (strncmp(ent->d_name, name, len) == 0) {
3436*7688df22SAndroid Build Coastguard Worker if (snprintf(dev_name, sizeof(dev_name), DRM_DIR_NAME "/%s",
3437*7688df22SAndroid Build Coastguard Worker ent->d_name) < 0)
3438*7688df22SAndroid Build Coastguard Worker return NULL;
3439*7688df22SAndroid Build Coastguard Worker
3440*7688df22SAndroid Build Coastguard Worker closedir(sysdir);
3441*7688df22SAndroid Build Coastguard Worker return strdup(dev_name);
3442*7688df22SAndroid Build Coastguard Worker }
3443*7688df22SAndroid Build Coastguard Worker }
3444*7688df22SAndroid Build Coastguard Worker
3445*7688df22SAndroid Build Coastguard Worker closedir(sysdir);
3446*7688df22SAndroid Build Coastguard Worker return NULL;
3447*7688df22SAndroid Build Coastguard Worker #elif defined(__FreeBSD__)
3448*7688df22SAndroid Build Coastguard Worker struct stat sbuf;
3449*7688df22SAndroid Build Coastguard Worker char dname[SPECNAMELEN];
3450*7688df22SAndroid Build Coastguard Worker const char *mname;
3451*7688df22SAndroid Build Coastguard Worker char name[SPECNAMELEN];
3452*7688df22SAndroid Build Coastguard Worker int id, maj, min, nodetype, i;
3453*7688df22SAndroid Build Coastguard Worker
3454*7688df22SAndroid Build Coastguard Worker if (fstat(fd, &sbuf))
3455*7688df22SAndroid Build Coastguard Worker return NULL;
3456*7688df22SAndroid Build Coastguard Worker
3457*7688df22SAndroid Build Coastguard Worker maj = major(sbuf.st_rdev);
3458*7688df22SAndroid Build Coastguard Worker min = minor(sbuf.st_rdev);
3459*7688df22SAndroid Build Coastguard Worker
3460*7688df22SAndroid Build Coastguard Worker if (!drmNodeIsDRM(maj, min) || !S_ISCHR(sbuf.st_mode))
3461*7688df22SAndroid Build Coastguard Worker return NULL;
3462*7688df22SAndroid Build Coastguard Worker
3463*7688df22SAndroid Build Coastguard Worker if (!devname_r(sbuf.st_rdev, S_IFCHR, dname, sizeof(dname)))
3464*7688df22SAndroid Build Coastguard Worker return NULL;
3465*7688df22SAndroid Build Coastguard Worker
3466*7688df22SAndroid Build Coastguard Worker /* Handle both /dev/drm and /dev/dri
3467*7688df22SAndroid Build Coastguard Worker * FreeBSD on amd64/i386/powerpc external kernel modules create node in
3468*7688df22SAndroid Build Coastguard Worker * in /dev/drm/ and links in /dev/dri while a WIP in kernel driver creates
3469*7688df22SAndroid Build Coastguard Worker * only device nodes in /dev/dri/ */
3470*7688df22SAndroid Build Coastguard Worker
3471*7688df22SAndroid Build Coastguard Worker /* Get the node type represented by fd so we can deduce the target name */
3472*7688df22SAndroid Build Coastguard Worker nodetype = drmGetMinorType(maj, min);
3473*7688df22SAndroid Build Coastguard Worker if (nodetype == -1)
3474*7688df22SAndroid Build Coastguard Worker return (NULL);
3475*7688df22SAndroid Build Coastguard Worker mname = drmGetMinorName(type);
3476*7688df22SAndroid Build Coastguard Worker
3477*7688df22SAndroid Build Coastguard Worker for (i = 0; i < SPECNAMELEN; i++) {
3478*7688df22SAndroid Build Coastguard Worker if (isalpha(dname[i]) == 0 && dname[i] != '/')
3479*7688df22SAndroid Build Coastguard Worker break;
3480*7688df22SAndroid Build Coastguard Worker }
3481*7688df22SAndroid Build Coastguard Worker if (dname[i] == '\0')
3482*7688df22SAndroid Build Coastguard Worker return (NULL);
3483*7688df22SAndroid Build Coastguard Worker
3484*7688df22SAndroid Build Coastguard Worker id = (int)strtol(&dname[i], NULL, 10);
3485*7688df22SAndroid Build Coastguard Worker id -= drmGetMinorBase(nodetype);
3486*7688df22SAndroid Build Coastguard Worker snprintf(name, sizeof(name), DRM_DIR_NAME "/%s%d", mname,
3487*7688df22SAndroid Build Coastguard Worker id + drmGetMinorBase(type));
3488*7688df22SAndroid Build Coastguard Worker
3489*7688df22SAndroid Build Coastguard Worker return strdup(name);
3490*7688df22SAndroid Build Coastguard Worker #else
3491*7688df22SAndroid Build Coastguard Worker struct stat sbuf;
3492*7688df22SAndroid Build Coastguard Worker char buf[PATH_MAX + 1];
3493*7688df22SAndroid Build Coastguard Worker const char *dev_name = drmGetDeviceName(type);
3494*7688df22SAndroid Build Coastguard Worker unsigned int maj, min;
3495*7688df22SAndroid Build Coastguard Worker int n;
3496*7688df22SAndroid Build Coastguard Worker
3497*7688df22SAndroid Build Coastguard Worker if (fstat(fd, &sbuf))
3498*7688df22SAndroid Build Coastguard Worker return NULL;
3499*7688df22SAndroid Build Coastguard Worker
3500*7688df22SAndroid Build Coastguard Worker maj = major(sbuf.st_rdev);
3501*7688df22SAndroid Build Coastguard Worker min = minor(sbuf.st_rdev);
3502*7688df22SAndroid Build Coastguard Worker
3503*7688df22SAndroid Build Coastguard Worker if (!drmNodeIsDRM(maj, min) || !S_ISCHR(sbuf.st_mode))
3504*7688df22SAndroid Build Coastguard Worker return NULL;
3505*7688df22SAndroid Build Coastguard Worker
3506*7688df22SAndroid Build Coastguard Worker if (!dev_name)
3507*7688df22SAndroid Build Coastguard Worker return NULL;
3508*7688df22SAndroid Build Coastguard Worker
3509*7688df22SAndroid Build Coastguard Worker n = snprintf(buf, sizeof(buf), dev_name, DRM_DIR_NAME, min);
3510*7688df22SAndroid Build Coastguard Worker if (n == -1 || n >= sizeof(buf))
3511*7688df22SAndroid Build Coastguard Worker return NULL;
3512*7688df22SAndroid Build Coastguard Worker
3513*7688df22SAndroid Build Coastguard Worker return strdup(buf);
3514*7688df22SAndroid Build Coastguard Worker #endif
3515*7688df22SAndroid Build Coastguard Worker }
3516*7688df22SAndroid Build Coastguard Worker
drmGetPrimaryDeviceNameFromFd(int fd)3517*7688df22SAndroid Build Coastguard Worker drm_public char *drmGetPrimaryDeviceNameFromFd(int fd)
3518*7688df22SAndroid Build Coastguard Worker {
3519*7688df22SAndroid Build Coastguard Worker return drmGetMinorNameForFD(fd, DRM_NODE_PRIMARY);
3520*7688df22SAndroid Build Coastguard Worker }
3521*7688df22SAndroid Build Coastguard Worker
drmGetRenderDeviceNameFromFd(int fd)3522*7688df22SAndroid Build Coastguard Worker drm_public char *drmGetRenderDeviceNameFromFd(int fd)
3523*7688df22SAndroid Build Coastguard Worker {
3524*7688df22SAndroid Build Coastguard Worker return drmGetMinorNameForFD(fd, DRM_NODE_RENDER);
3525*7688df22SAndroid Build Coastguard Worker }
3526*7688df22SAndroid Build Coastguard Worker
3527*7688df22SAndroid Build Coastguard Worker #ifdef __linux__
3528*7688df22SAndroid Build Coastguard Worker static char * DRM_PRINTFLIKE(2, 3)
sysfs_uevent_get(const char * path,const char * fmt,...)3529*7688df22SAndroid Build Coastguard Worker sysfs_uevent_get(const char *path, const char *fmt, ...)
3530*7688df22SAndroid Build Coastguard Worker {
3531*7688df22SAndroid Build Coastguard Worker char filename[PATH_MAX + 1], *key, *line = NULL, *value = NULL;
3532*7688df22SAndroid Build Coastguard Worker size_t size = 0, len;
3533*7688df22SAndroid Build Coastguard Worker ssize_t num;
3534*7688df22SAndroid Build Coastguard Worker va_list ap;
3535*7688df22SAndroid Build Coastguard Worker FILE *fp;
3536*7688df22SAndroid Build Coastguard Worker
3537*7688df22SAndroid Build Coastguard Worker va_start(ap, fmt);
3538*7688df22SAndroid Build Coastguard Worker num = vasprintf(&key, fmt, ap);
3539*7688df22SAndroid Build Coastguard Worker va_end(ap);
3540*7688df22SAndroid Build Coastguard Worker len = num;
3541*7688df22SAndroid Build Coastguard Worker
3542*7688df22SAndroid Build Coastguard Worker snprintf(filename, sizeof(filename), "%s/uevent", path);
3543*7688df22SAndroid Build Coastguard Worker
3544*7688df22SAndroid Build Coastguard Worker fp = fopen(filename, "r");
3545*7688df22SAndroid Build Coastguard Worker if (!fp) {
3546*7688df22SAndroid Build Coastguard Worker free(key);
3547*7688df22SAndroid Build Coastguard Worker return NULL;
3548*7688df22SAndroid Build Coastguard Worker }
3549*7688df22SAndroid Build Coastguard Worker
3550*7688df22SAndroid Build Coastguard Worker while ((num = getline(&line, &size, fp)) >= 0) {
3551*7688df22SAndroid Build Coastguard Worker if ((strncmp(line, key, len) == 0) && (line[len] == '=')) {
3552*7688df22SAndroid Build Coastguard Worker char *start = line + len + 1, *end = line + num - 1;
3553*7688df22SAndroid Build Coastguard Worker
3554*7688df22SAndroid Build Coastguard Worker if (*end != '\n')
3555*7688df22SAndroid Build Coastguard Worker end++;
3556*7688df22SAndroid Build Coastguard Worker
3557*7688df22SAndroid Build Coastguard Worker value = strndup(start, end - start);
3558*7688df22SAndroid Build Coastguard Worker break;
3559*7688df22SAndroid Build Coastguard Worker }
3560*7688df22SAndroid Build Coastguard Worker }
3561*7688df22SAndroid Build Coastguard Worker
3562*7688df22SAndroid Build Coastguard Worker free(line);
3563*7688df22SAndroid Build Coastguard Worker fclose(fp);
3564*7688df22SAndroid Build Coastguard Worker
3565*7688df22SAndroid Build Coastguard Worker free(key);
3566*7688df22SAndroid Build Coastguard Worker
3567*7688df22SAndroid Build Coastguard Worker return value;
3568*7688df22SAndroid Build Coastguard Worker }
3569*7688df22SAndroid Build Coastguard Worker #endif
3570*7688df22SAndroid Build Coastguard Worker
3571*7688df22SAndroid Build Coastguard Worker /* Little white lie to avoid major rework of the existing code */
3572*7688df22SAndroid Build Coastguard Worker #define DRM_BUS_VIRTIO 0x10
3573*7688df22SAndroid Build Coastguard Worker
3574*7688df22SAndroid Build Coastguard Worker #ifdef __linux__
get_subsystem_type(const char * device_path)3575*7688df22SAndroid Build Coastguard Worker static int get_subsystem_type(const char *device_path)
3576*7688df22SAndroid Build Coastguard Worker {
3577*7688df22SAndroid Build Coastguard Worker char path[PATH_MAX + 1] = "";
3578*7688df22SAndroid Build Coastguard Worker char link[PATH_MAX + 1] = "";
3579*7688df22SAndroid Build Coastguard Worker char *name;
3580*7688df22SAndroid Build Coastguard Worker struct {
3581*7688df22SAndroid Build Coastguard Worker const char *name;
3582*7688df22SAndroid Build Coastguard Worker int bus_type;
3583*7688df22SAndroid Build Coastguard Worker } bus_types[] = {
3584*7688df22SAndroid Build Coastguard Worker { "/pci", DRM_BUS_PCI },
3585*7688df22SAndroid Build Coastguard Worker { "/usb", DRM_BUS_USB },
3586*7688df22SAndroid Build Coastguard Worker { "/platform", DRM_BUS_PLATFORM },
3587*7688df22SAndroid Build Coastguard Worker { "/spi", DRM_BUS_PLATFORM },
3588*7688df22SAndroid Build Coastguard Worker { "/host1x", DRM_BUS_HOST1X },
3589*7688df22SAndroid Build Coastguard Worker { "/virtio", DRM_BUS_VIRTIO },
3590*7688df22SAndroid Build Coastguard Worker };
3591*7688df22SAndroid Build Coastguard Worker
3592*7688df22SAndroid Build Coastguard Worker strncpy(path, device_path, PATH_MAX);
3593*7688df22SAndroid Build Coastguard Worker strncat(path, "/subsystem", PATH_MAX);
3594*7688df22SAndroid Build Coastguard Worker
3595*7688df22SAndroid Build Coastguard Worker if (readlink(path, link, PATH_MAX) < 0)
3596*7688df22SAndroid Build Coastguard Worker return -errno;
3597*7688df22SAndroid Build Coastguard Worker
3598*7688df22SAndroid Build Coastguard Worker name = strrchr(link, '/');
3599*7688df22SAndroid Build Coastguard Worker if (!name)
3600*7688df22SAndroid Build Coastguard Worker return -EINVAL;
3601*7688df22SAndroid Build Coastguard Worker
3602*7688df22SAndroid Build Coastguard Worker for (unsigned i = 0; i < ARRAY_SIZE(bus_types); i++) {
3603*7688df22SAndroid Build Coastguard Worker if (strncmp(name, bus_types[i].name, strlen(bus_types[i].name)) == 0)
3604*7688df22SAndroid Build Coastguard Worker return bus_types[i].bus_type;
3605*7688df22SAndroid Build Coastguard Worker }
3606*7688df22SAndroid Build Coastguard Worker
3607*7688df22SAndroid Build Coastguard Worker return -EINVAL;
3608*7688df22SAndroid Build Coastguard Worker }
3609*7688df22SAndroid Build Coastguard Worker #endif
3610*7688df22SAndroid Build Coastguard Worker
drmParseSubsystemType(int maj,int min)3611*7688df22SAndroid Build Coastguard Worker static int drmParseSubsystemType(int maj, int min)
3612*7688df22SAndroid Build Coastguard Worker {
3613*7688df22SAndroid Build Coastguard Worker #ifdef __linux__
3614*7688df22SAndroid Build Coastguard Worker char path[PATH_MAX + 1] = "";
3615*7688df22SAndroid Build Coastguard Worker char real_path[PATH_MAX + 1] = "";
3616*7688df22SAndroid Build Coastguard Worker int subsystem_type;
3617*7688df22SAndroid Build Coastguard Worker
3618*7688df22SAndroid Build Coastguard Worker snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device", maj, min);
3619*7688df22SAndroid Build Coastguard Worker
3620*7688df22SAndroid Build Coastguard Worker subsystem_type = get_subsystem_type(path);
3621*7688df22SAndroid Build Coastguard Worker /* Try to get the parent (underlying) device type */
3622*7688df22SAndroid Build Coastguard Worker if (subsystem_type == DRM_BUS_VIRTIO) {
3623*7688df22SAndroid Build Coastguard Worker /* Assume virtio-pci on error */
3624*7688df22SAndroid Build Coastguard Worker if (!realpath(path, real_path))
3625*7688df22SAndroid Build Coastguard Worker return DRM_BUS_VIRTIO;
3626*7688df22SAndroid Build Coastguard Worker strncat(path, "/..", PATH_MAX);
3627*7688df22SAndroid Build Coastguard Worker subsystem_type = get_subsystem_type(path);
3628*7688df22SAndroid Build Coastguard Worker if (subsystem_type < 0)
3629*7688df22SAndroid Build Coastguard Worker return DRM_BUS_VIRTIO;
3630*7688df22SAndroid Build Coastguard Worker }
3631*7688df22SAndroid Build Coastguard Worker return subsystem_type;
3632*7688df22SAndroid Build Coastguard Worker #elif defined(__OpenBSD__) || defined(__DragonFly__) || defined(__FreeBSD__)
3633*7688df22SAndroid Build Coastguard Worker return DRM_BUS_PCI;
3634*7688df22SAndroid Build Coastguard Worker #else
3635*7688df22SAndroid Build Coastguard Worker #warning "Missing implementation of drmParseSubsystemType"
3636*7688df22SAndroid Build Coastguard Worker return -EINVAL;
3637*7688df22SAndroid Build Coastguard Worker #endif
3638*7688df22SAndroid Build Coastguard Worker }
3639*7688df22SAndroid Build Coastguard Worker
3640*7688df22SAndroid Build Coastguard Worker #ifdef __linux__
3641*7688df22SAndroid Build Coastguard Worker static void
get_pci_path(int maj,int min,char * pci_path)3642*7688df22SAndroid Build Coastguard Worker get_pci_path(int maj, int min, char *pci_path)
3643*7688df22SAndroid Build Coastguard Worker {
3644*7688df22SAndroid Build Coastguard Worker char path[PATH_MAX + 1], *term;
3645*7688df22SAndroid Build Coastguard Worker
3646*7688df22SAndroid Build Coastguard Worker snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device", maj, min);
3647*7688df22SAndroid Build Coastguard Worker if (!realpath(path, pci_path)) {
3648*7688df22SAndroid Build Coastguard Worker strcpy(pci_path, path);
3649*7688df22SAndroid Build Coastguard Worker return;
3650*7688df22SAndroid Build Coastguard Worker }
3651*7688df22SAndroid Build Coastguard Worker
3652*7688df22SAndroid Build Coastguard Worker term = strrchr(pci_path, '/');
3653*7688df22SAndroid Build Coastguard Worker if (term && strncmp(term, "/virtio", 7) == 0)
3654*7688df22SAndroid Build Coastguard Worker *term = 0;
3655*7688df22SAndroid Build Coastguard Worker }
3656*7688df22SAndroid Build Coastguard Worker #endif
3657*7688df22SAndroid Build Coastguard Worker
3658*7688df22SAndroid Build Coastguard Worker #ifdef __FreeBSD__
get_sysctl_pci_bus_info(int maj,int min,drmPciBusInfoPtr info)3659*7688df22SAndroid Build Coastguard Worker static int get_sysctl_pci_bus_info(int maj, int min, drmPciBusInfoPtr info)
3660*7688df22SAndroid Build Coastguard Worker {
3661*7688df22SAndroid Build Coastguard Worker char dname[SPECNAMELEN];
3662*7688df22SAndroid Build Coastguard Worker char sysctl_name[16];
3663*7688df22SAndroid Build Coastguard Worker char sysctl_val[256];
3664*7688df22SAndroid Build Coastguard Worker size_t sysctl_len;
3665*7688df22SAndroid Build Coastguard Worker int id, type, nelem;
3666*7688df22SAndroid Build Coastguard Worker unsigned int rdev, majmin, domain, bus, dev, func;
3667*7688df22SAndroid Build Coastguard Worker
3668*7688df22SAndroid Build Coastguard Worker rdev = makedev(maj, min);
3669*7688df22SAndroid Build Coastguard Worker if (!devname_r(rdev, S_IFCHR, dname, sizeof(dname)))
3670*7688df22SAndroid Build Coastguard Worker return -EINVAL;
3671*7688df22SAndroid Build Coastguard Worker
3672*7688df22SAndroid Build Coastguard Worker if (sscanf(dname, "drm/%d\n", &id) != 1)
3673*7688df22SAndroid Build Coastguard Worker return -EINVAL;
3674*7688df22SAndroid Build Coastguard Worker type = drmGetMinorType(maj, min);
3675*7688df22SAndroid Build Coastguard Worker if (type == -1)
3676*7688df22SAndroid Build Coastguard Worker return -EINVAL;
3677*7688df22SAndroid Build Coastguard Worker
3678*7688df22SAndroid Build Coastguard Worker /* BUG: This above section is iffy, since it mandates that a driver will
3679*7688df22SAndroid Build Coastguard Worker * create both card and render node.
3680*7688df22SAndroid Build Coastguard Worker * If it does not, the next DRM device will create card#X and
3681*7688df22SAndroid Build Coastguard Worker * renderD#(128+X)-1.
3682*7688df22SAndroid Build Coastguard Worker * This is a possibility in FreeBSD but for now there is no good way for
3683*7688df22SAndroid Build Coastguard Worker * obtaining the info.
3684*7688df22SAndroid Build Coastguard Worker */
3685*7688df22SAndroid Build Coastguard Worker switch (type) {
3686*7688df22SAndroid Build Coastguard Worker case DRM_NODE_PRIMARY:
3687*7688df22SAndroid Build Coastguard Worker break;
3688*7688df22SAndroid Build Coastguard Worker case DRM_NODE_RENDER:
3689*7688df22SAndroid Build Coastguard Worker id -= 128;
3690*7688df22SAndroid Build Coastguard Worker break;
3691*7688df22SAndroid Build Coastguard Worker }
3692*7688df22SAndroid Build Coastguard Worker if (id < 0)
3693*7688df22SAndroid Build Coastguard Worker return -EINVAL;
3694*7688df22SAndroid Build Coastguard Worker
3695*7688df22SAndroid Build Coastguard Worker if (snprintf(sysctl_name, sizeof(sysctl_name), "hw.dri.%d.busid", id) <= 0)
3696*7688df22SAndroid Build Coastguard Worker return -EINVAL;
3697*7688df22SAndroid Build Coastguard Worker sysctl_len = sizeof(sysctl_val);
3698*7688df22SAndroid Build Coastguard Worker if (sysctlbyname(sysctl_name, sysctl_val, &sysctl_len, NULL, 0))
3699*7688df22SAndroid Build Coastguard Worker return -EINVAL;
3700*7688df22SAndroid Build Coastguard Worker
3701*7688df22SAndroid Build Coastguard Worker #define bus_fmt "pci:%04x:%02x:%02x.%u"
3702*7688df22SAndroid Build Coastguard Worker
3703*7688df22SAndroid Build Coastguard Worker nelem = sscanf(sysctl_val, bus_fmt, &domain, &bus, &dev, &func);
3704*7688df22SAndroid Build Coastguard Worker if (nelem != 4)
3705*7688df22SAndroid Build Coastguard Worker return -EINVAL;
3706*7688df22SAndroid Build Coastguard Worker info->domain = domain;
3707*7688df22SAndroid Build Coastguard Worker info->bus = bus;
3708*7688df22SAndroid Build Coastguard Worker info->dev = dev;
3709*7688df22SAndroid Build Coastguard Worker info->func = func;
3710*7688df22SAndroid Build Coastguard Worker
3711*7688df22SAndroid Build Coastguard Worker return 0;
3712*7688df22SAndroid Build Coastguard Worker }
3713*7688df22SAndroid Build Coastguard Worker #endif
3714*7688df22SAndroid Build Coastguard Worker
drmParsePciBusInfo(int maj,int min,drmPciBusInfoPtr info)3715*7688df22SAndroid Build Coastguard Worker static int drmParsePciBusInfo(int maj, int min, drmPciBusInfoPtr info)
3716*7688df22SAndroid Build Coastguard Worker {
3717*7688df22SAndroid Build Coastguard Worker #ifdef __linux__
3718*7688df22SAndroid Build Coastguard Worker unsigned int domain, bus, dev, func;
3719*7688df22SAndroid Build Coastguard Worker char pci_path[PATH_MAX + 1], *value;
3720*7688df22SAndroid Build Coastguard Worker int num;
3721*7688df22SAndroid Build Coastguard Worker
3722*7688df22SAndroid Build Coastguard Worker get_pci_path(maj, min, pci_path);
3723*7688df22SAndroid Build Coastguard Worker
3724*7688df22SAndroid Build Coastguard Worker value = sysfs_uevent_get(pci_path, "PCI_SLOT_NAME");
3725*7688df22SAndroid Build Coastguard Worker if (!value)
3726*7688df22SAndroid Build Coastguard Worker return -ENOENT;
3727*7688df22SAndroid Build Coastguard Worker
3728*7688df22SAndroid Build Coastguard Worker num = sscanf(value, "%04x:%02x:%02x.%1u", &domain, &bus, &dev, &func);
3729*7688df22SAndroid Build Coastguard Worker free(value);
3730*7688df22SAndroid Build Coastguard Worker
3731*7688df22SAndroid Build Coastguard Worker if (num != 4)
3732*7688df22SAndroid Build Coastguard Worker return -EINVAL;
3733*7688df22SAndroid Build Coastguard Worker
3734*7688df22SAndroid Build Coastguard Worker info->domain = domain;
3735*7688df22SAndroid Build Coastguard Worker info->bus = bus;
3736*7688df22SAndroid Build Coastguard Worker info->dev = dev;
3737*7688df22SAndroid Build Coastguard Worker info->func = func;
3738*7688df22SAndroid Build Coastguard Worker
3739*7688df22SAndroid Build Coastguard Worker return 0;
3740*7688df22SAndroid Build Coastguard Worker #elif defined(__OpenBSD__) || defined(__DragonFly__)
3741*7688df22SAndroid Build Coastguard Worker struct drm_pciinfo pinfo;
3742*7688df22SAndroid Build Coastguard Worker int fd, type;
3743*7688df22SAndroid Build Coastguard Worker
3744*7688df22SAndroid Build Coastguard Worker type = drmGetMinorType(maj, min);
3745*7688df22SAndroid Build Coastguard Worker if (type == -1)
3746*7688df22SAndroid Build Coastguard Worker return -ENODEV;
3747*7688df22SAndroid Build Coastguard Worker
3748*7688df22SAndroid Build Coastguard Worker fd = drmOpenMinor(min, 0, type);
3749*7688df22SAndroid Build Coastguard Worker if (fd < 0)
3750*7688df22SAndroid Build Coastguard Worker return -errno;
3751*7688df22SAndroid Build Coastguard Worker
3752*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_GET_PCIINFO, &pinfo)) {
3753*7688df22SAndroid Build Coastguard Worker close(fd);
3754*7688df22SAndroid Build Coastguard Worker return -errno;
3755*7688df22SAndroid Build Coastguard Worker }
3756*7688df22SAndroid Build Coastguard Worker close(fd);
3757*7688df22SAndroid Build Coastguard Worker
3758*7688df22SAndroid Build Coastguard Worker info->domain = pinfo.domain;
3759*7688df22SAndroid Build Coastguard Worker info->bus = pinfo.bus;
3760*7688df22SAndroid Build Coastguard Worker info->dev = pinfo.dev;
3761*7688df22SAndroid Build Coastguard Worker info->func = pinfo.func;
3762*7688df22SAndroid Build Coastguard Worker
3763*7688df22SAndroid Build Coastguard Worker return 0;
3764*7688df22SAndroid Build Coastguard Worker #elif defined(__FreeBSD__)
3765*7688df22SAndroid Build Coastguard Worker return get_sysctl_pci_bus_info(maj, min, info);
3766*7688df22SAndroid Build Coastguard Worker #else
3767*7688df22SAndroid Build Coastguard Worker #warning "Missing implementation of drmParsePciBusInfo"
3768*7688df22SAndroid Build Coastguard Worker return -EINVAL;
3769*7688df22SAndroid Build Coastguard Worker #endif
3770*7688df22SAndroid Build Coastguard Worker }
3771*7688df22SAndroid Build Coastguard Worker
drmDevicesEqual(drmDevicePtr a,drmDevicePtr b)3772*7688df22SAndroid Build Coastguard Worker drm_public int drmDevicesEqual(drmDevicePtr a, drmDevicePtr b)
3773*7688df22SAndroid Build Coastguard Worker {
3774*7688df22SAndroid Build Coastguard Worker if (a == NULL || b == NULL)
3775*7688df22SAndroid Build Coastguard Worker return 0;
3776*7688df22SAndroid Build Coastguard Worker
3777*7688df22SAndroid Build Coastguard Worker if (a->bustype != b->bustype)
3778*7688df22SAndroid Build Coastguard Worker return 0;
3779*7688df22SAndroid Build Coastguard Worker
3780*7688df22SAndroid Build Coastguard Worker switch (a->bustype) {
3781*7688df22SAndroid Build Coastguard Worker case DRM_BUS_PCI:
3782*7688df22SAndroid Build Coastguard Worker return memcmp(a->businfo.pci, b->businfo.pci, sizeof(drmPciBusInfo)) == 0;
3783*7688df22SAndroid Build Coastguard Worker
3784*7688df22SAndroid Build Coastguard Worker case DRM_BUS_USB:
3785*7688df22SAndroid Build Coastguard Worker return memcmp(a->businfo.usb, b->businfo.usb, sizeof(drmUsbBusInfo)) == 0;
3786*7688df22SAndroid Build Coastguard Worker
3787*7688df22SAndroid Build Coastguard Worker case DRM_BUS_PLATFORM:
3788*7688df22SAndroid Build Coastguard Worker return memcmp(a->businfo.platform, b->businfo.platform, sizeof(drmPlatformBusInfo)) == 0;
3789*7688df22SAndroid Build Coastguard Worker
3790*7688df22SAndroid Build Coastguard Worker case DRM_BUS_HOST1X:
3791*7688df22SAndroid Build Coastguard Worker return memcmp(a->businfo.host1x, b->businfo.host1x, sizeof(drmHost1xBusInfo)) == 0;
3792*7688df22SAndroid Build Coastguard Worker
3793*7688df22SAndroid Build Coastguard Worker default:
3794*7688df22SAndroid Build Coastguard Worker break;
3795*7688df22SAndroid Build Coastguard Worker }
3796*7688df22SAndroid Build Coastguard Worker
3797*7688df22SAndroid Build Coastguard Worker return 0;
3798*7688df22SAndroid Build Coastguard Worker }
3799*7688df22SAndroid Build Coastguard Worker
drmGetNodeType(const char * name)3800*7688df22SAndroid Build Coastguard Worker static int drmGetNodeType(const char *name)
3801*7688df22SAndroid Build Coastguard Worker {
3802*7688df22SAndroid Build Coastguard Worker if (strncmp(name, DRM_RENDER_MINOR_NAME,
3803*7688df22SAndroid Build Coastguard Worker sizeof(DRM_RENDER_MINOR_NAME) - 1) == 0)
3804*7688df22SAndroid Build Coastguard Worker return DRM_NODE_RENDER;
3805*7688df22SAndroid Build Coastguard Worker
3806*7688df22SAndroid Build Coastguard Worker if (strncmp(name, DRM_PRIMARY_MINOR_NAME,
3807*7688df22SAndroid Build Coastguard Worker sizeof(DRM_PRIMARY_MINOR_NAME) - 1) == 0)
3808*7688df22SAndroid Build Coastguard Worker return DRM_NODE_PRIMARY;
3809*7688df22SAndroid Build Coastguard Worker
3810*7688df22SAndroid Build Coastguard Worker return -EINVAL;
3811*7688df22SAndroid Build Coastguard Worker }
3812*7688df22SAndroid Build Coastguard Worker
drmGetMaxNodeName(void)3813*7688df22SAndroid Build Coastguard Worker static int drmGetMaxNodeName(void)
3814*7688df22SAndroid Build Coastguard Worker {
3815*7688df22SAndroid Build Coastguard Worker return sizeof(DRM_DIR_NAME) +
3816*7688df22SAndroid Build Coastguard Worker MAX3(sizeof(DRM_PRIMARY_MINOR_NAME),
3817*7688df22SAndroid Build Coastguard Worker sizeof(DRM_CONTROL_MINOR_NAME),
3818*7688df22SAndroid Build Coastguard Worker sizeof(DRM_RENDER_MINOR_NAME)) +
3819*7688df22SAndroid Build Coastguard Worker 3 /* length of the node number */;
3820*7688df22SAndroid Build Coastguard Worker }
3821*7688df22SAndroid Build Coastguard Worker
3822*7688df22SAndroid Build Coastguard Worker #ifdef __linux__
parse_separate_sysfs_files(int maj,int min,drmPciDeviceInfoPtr device,bool ignore_revision)3823*7688df22SAndroid Build Coastguard Worker static int parse_separate_sysfs_files(int maj, int min,
3824*7688df22SAndroid Build Coastguard Worker drmPciDeviceInfoPtr device,
3825*7688df22SAndroid Build Coastguard Worker bool ignore_revision)
3826*7688df22SAndroid Build Coastguard Worker {
3827*7688df22SAndroid Build Coastguard Worker static const char *attrs[] = {
3828*7688df22SAndroid Build Coastguard Worker "revision", /* Older kernels are missing the file, so check for it first */
3829*7688df22SAndroid Build Coastguard Worker "vendor",
3830*7688df22SAndroid Build Coastguard Worker "device",
3831*7688df22SAndroid Build Coastguard Worker "subsystem_vendor",
3832*7688df22SAndroid Build Coastguard Worker "subsystem_device",
3833*7688df22SAndroid Build Coastguard Worker };
3834*7688df22SAndroid Build Coastguard Worker char path[PATH_MAX + 1], pci_path[PATH_MAX + 1];
3835*7688df22SAndroid Build Coastguard Worker unsigned int data[ARRAY_SIZE(attrs)];
3836*7688df22SAndroid Build Coastguard Worker FILE *fp;
3837*7688df22SAndroid Build Coastguard Worker int ret;
3838*7688df22SAndroid Build Coastguard Worker
3839*7688df22SAndroid Build Coastguard Worker get_pci_path(maj, min, pci_path);
3840*7688df22SAndroid Build Coastguard Worker
3841*7688df22SAndroid Build Coastguard Worker for (unsigned i = ignore_revision ? 1 : 0; i < ARRAY_SIZE(attrs); i++) {
3842*7688df22SAndroid Build Coastguard Worker if (snprintf(path, PATH_MAX, "%s/%s", pci_path, attrs[i]) < 0)
3843*7688df22SAndroid Build Coastguard Worker return -errno;
3844*7688df22SAndroid Build Coastguard Worker
3845*7688df22SAndroid Build Coastguard Worker fp = fopen(path, "r");
3846*7688df22SAndroid Build Coastguard Worker if (!fp)
3847*7688df22SAndroid Build Coastguard Worker return -errno;
3848*7688df22SAndroid Build Coastguard Worker
3849*7688df22SAndroid Build Coastguard Worker ret = fscanf(fp, "%x", &data[i]);
3850*7688df22SAndroid Build Coastguard Worker fclose(fp);
3851*7688df22SAndroid Build Coastguard Worker if (ret != 1)
3852*7688df22SAndroid Build Coastguard Worker return -errno;
3853*7688df22SAndroid Build Coastguard Worker
3854*7688df22SAndroid Build Coastguard Worker }
3855*7688df22SAndroid Build Coastguard Worker
3856*7688df22SAndroid Build Coastguard Worker device->revision_id = ignore_revision ? 0xff : data[0] & 0xff;
3857*7688df22SAndroid Build Coastguard Worker device->vendor_id = data[1] & 0xffff;
3858*7688df22SAndroid Build Coastguard Worker device->device_id = data[2] & 0xffff;
3859*7688df22SAndroid Build Coastguard Worker device->subvendor_id = data[3] & 0xffff;
3860*7688df22SAndroid Build Coastguard Worker device->subdevice_id = data[4] & 0xffff;
3861*7688df22SAndroid Build Coastguard Worker
3862*7688df22SAndroid Build Coastguard Worker return 0;
3863*7688df22SAndroid Build Coastguard Worker }
3864*7688df22SAndroid Build Coastguard Worker
parse_config_sysfs_file(int maj,int min,drmPciDeviceInfoPtr device)3865*7688df22SAndroid Build Coastguard Worker static int parse_config_sysfs_file(int maj, int min,
3866*7688df22SAndroid Build Coastguard Worker drmPciDeviceInfoPtr device)
3867*7688df22SAndroid Build Coastguard Worker {
3868*7688df22SAndroid Build Coastguard Worker char path[PATH_MAX + 1], pci_path[PATH_MAX + 1];
3869*7688df22SAndroid Build Coastguard Worker unsigned char config[64];
3870*7688df22SAndroid Build Coastguard Worker int fd, ret;
3871*7688df22SAndroid Build Coastguard Worker
3872*7688df22SAndroid Build Coastguard Worker get_pci_path(maj, min, pci_path);
3873*7688df22SAndroid Build Coastguard Worker
3874*7688df22SAndroid Build Coastguard Worker if (snprintf(path, PATH_MAX, "%s/config", pci_path) < 0)
3875*7688df22SAndroid Build Coastguard Worker return -errno;
3876*7688df22SAndroid Build Coastguard Worker
3877*7688df22SAndroid Build Coastguard Worker fd = open(path, O_RDONLY);
3878*7688df22SAndroid Build Coastguard Worker if (fd < 0)
3879*7688df22SAndroid Build Coastguard Worker return -errno;
3880*7688df22SAndroid Build Coastguard Worker
3881*7688df22SAndroid Build Coastguard Worker ret = read(fd, config, sizeof(config));
3882*7688df22SAndroid Build Coastguard Worker close(fd);
3883*7688df22SAndroid Build Coastguard Worker if (ret < 0)
3884*7688df22SAndroid Build Coastguard Worker return -errno;
3885*7688df22SAndroid Build Coastguard Worker
3886*7688df22SAndroid Build Coastguard Worker device->vendor_id = config[0] | (config[1] << 8);
3887*7688df22SAndroid Build Coastguard Worker device->device_id = config[2] | (config[3] << 8);
3888*7688df22SAndroid Build Coastguard Worker device->revision_id = config[8];
3889*7688df22SAndroid Build Coastguard Worker device->subvendor_id = config[44] | (config[45] << 8);
3890*7688df22SAndroid Build Coastguard Worker device->subdevice_id = config[46] | (config[47] << 8);
3891*7688df22SAndroid Build Coastguard Worker
3892*7688df22SAndroid Build Coastguard Worker return 0;
3893*7688df22SAndroid Build Coastguard Worker }
3894*7688df22SAndroid Build Coastguard Worker #endif
3895*7688df22SAndroid Build Coastguard Worker
drmParsePciDeviceInfo(int maj,int min,drmPciDeviceInfoPtr device,uint32_t flags)3896*7688df22SAndroid Build Coastguard Worker static int drmParsePciDeviceInfo(int maj, int min,
3897*7688df22SAndroid Build Coastguard Worker drmPciDeviceInfoPtr device,
3898*7688df22SAndroid Build Coastguard Worker uint32_t flags)
3899*7688df22SAndroid Build Coastguard Worker {
3900*7688df22SAndroid Build Coastguard Worker #ifdef __linux__
3901*7688df22SAndroid Build Coastguard Worker if (!(flags & DRM_DEVICE_GET_PCI_REVISION))
3902*7688df22SAndroid Build Coastguard Worker return parse_separate_sysfs_files(maj, min, device, true);
3903*7688df22SAndroid Build Coastguard Worker
3904*7688df22SAndroid Build Coastguard Worker if (parse_separate_sysfs_files(maj, min, device, false))
3905*7688df22SAndroid Build Coastguard Worker return parse_config_sysfs_file(maj, min, device);
3906*7688df22SAndroid Build Coastguard Worker
3907*7688df22SAndroid Build Coastguard Worker return 0;
3908*7688df22SAndroid Build Coastguard Worker #elif defined(__OpenBSD__) || defined(__DragonFly__)
3909*7688df22SAndroid Build Coastguard Worker struct drm_pciinfo pinfo;
3910*7688df22SAndroid Build Coastguard Worker int fd, type;
3911*7688df22SAndroid Build Coastguard Worker
3912*7688df22SAndroid Build Coastguard Worker type = drmGetMinorType(maj, min);
3913*7688df22SAndroid Build Coastguard Worker if (type == -1)
3914*7688df22SAndroid Build Coastguard Worker return -ENODEV;
3915*7688df22SAndroid Build Coastguard Worker
3916*7688df22SAndroid Build Coastguard Worker fd = drmOpenMinor(min, 0, type);
3917*7688df22SAndroid Build Coastguard Worker if (fd < 0)
3918*7688df22SAndroid Build Coastguard Worker return -errno;
3919*7688df22SAndroid Build Coastguard Worker
3920*7688df22SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_GET_PCIINFO, &pinfo)) {
3921*7688df22SAndroid Build Coastguard Worker close(fd);
3922*7688df22SAndroid Build Coastguard Worker return -errno;
3923*7688df22SAndroid Build Coastguard Worker }
3924*7688df22SAndroid Build Coastguard Worker close(fd);
3925*7688df22SAndroid Build Coastguard Worker
3926*7688df22SAndroid Build Coastguard Worker device->vendor_id = pinfo.vendor_id;
3927*7688df22SAndroid Build Coastguard Worker device->device_id = pinfo.device_id;
3928*7688df22SAndroid Build Coastguard Worker device->revision_id = pinfo.revision_id;
3929*7688df22SAndroid Build Coastguard Worker device->subvendor_id = pinfo.subvendor_id;
3930*7688df22SAndroid Build Coastguard Worker device->subdevice_id = pinfo.subdevice_id;
3931*7688df22SAndroid Build Coastguard Worker
3932*7688df22SAndroid Build Coastguard Worker return 0;
3933*7688df22SAndroid Build Coastguard Worker #elif defined(__FreeBSD__)
3934*7688df22SAndroid Build Coastguard Worker drmPciBusInfo info;
3935*7688df22SAndroid Build Coastguard Worker struct pci_conf_io pc;
3936*7688df22SAndroid Build Coastguard Worker struct pci_match_conf patterns[1];
3937*7688df22SAndroid Build Coastguard Worker struct pci_conf results[1];
3938*7688df22SAndroid Build Coastguard Worker int fd, error;
3939*7688df22SAndroid Build Coastguard Worker
3940*7688df22SAndroid Build Coastguard Worker if (get_sysctl_pci_bus_info(maj, min, &info) != 0)
3941*7688df22SAndroid Build Coastguard Worker return -EINVAL;
3942*7688df22SAndroid Build Coastguard Worker
3943*7688df22SAndroid Build Coastguard Worker fd = open("/dev/pci", O_RDONLY);
3944*7688df22SAndroid Build Coastguard Worker if (fd < 0)
3945*7688df22SAndroid Build Coastguard Worker return -errno;
3946*7688df22SAndroid Build Coastguard Worker
3947*7688df22SAndroid Build Coastguard Worker bzero(&patterns, sizeof(patterns));
3948*7688df22SAndroid Build Coastguard Worker patterns[0].pc_sel.pc_domain = info.domain;
3949*7688df22SAndroid Build Coastguard Worker patterns[0].pc_sel.pc_bus = info.bus;
3950*7688df22SAndroid Build Coastguard Worker patterns[0].pc_sel.pc_dev = info.dev;
3951*7688df22SAndroid Build Coastguard Worker patterns[0].pc_sel.pc_func = info.func;
3952*7688df22SAndroid Build Coastguard Worker patterns[0].flags = PCI_GETCONF_MATCH_DOMAIN | PCI_GETCONF_MATCH_BUS
3953*7688df22SAndroid Build Coastguard Worker | PCI_GETCONF_MATCH_DEV | PCI_GETCONF_MATCH_FUNC;
3954*7688df22SAndroid Build Coastguard Worker bzero(&pc, sizeof(struct pci_conf_io));
3955*7688df22SAndroid Build Coastguard Worker pc.num_patterns = 1;
3956*7688df22SAndroid Build Coastguard Worker pc.pat_buf_len = sizeof(patterns);
3957*7688df22SAndroid Build Coastguard Worker pc.patterns = patterns;
3958*7688df22SAndroid Build Coastguard Worker pc.match_buf_len = sizeof(results);
3959*7688df22SAndroid Build Coastguard Worker pc.matches = results;
3960*7688df22SAndroid Build Coastguard Worker
3961*7688df22SAndroid Build Coastguard Worker if (ioctl(fd, PCIOCGETCONF, &pc) || pc.status == PCI_GETCONF_ERROR) {
3962*7688df22SAndroid Build Coastguard Worker error = errno;
3963*7688df22SAndroid Build Coastguard Worker close(fd);
3964*7688df22SAndroid Build Coastguard Worker return -error;
3965*7688df22SAndroid Build Coastguard Worker }
3966*7688df22SAndroid Build Coastguard Worker close(fd);
3967*7688df22SAndroid Build Coastguard Worker
3968*7688df22SAndroid Build Coastguard Worker device->vendor_id = results[0].pc_vendor;
3969*7688df22SAndroid Build Coastguard Worker device->device_id = results[0].pc_device;
3970*7688df22SAndroid Build Coastguard Worker device->subvendor_id = results[0].pc_subvendor;
3971*7688df22SAndroid Build Coastguard Worker device->subdevice_id = results[0].pc_subdevice;
3972*7688df22SAndroid Build Coastguard Worker device->revision_id = results[0].pc_revid;
3973*7688df22SAndroid Build Coastguard Worker
3974*7688df22SAndroid Build Coastguard Worker return 0;
3975*7688df22SAndroid Build Coastguard Worker #else
3976*7688df22SAndroid Build Coastguard Worker #warning "Missing implementation of drmParsePciDeviceInfo"
3977*7688df22SAndroid Build Coastguard Worker return -EINVAL;
3978*7688df22SAndroid Build Coastguard Worker #endif
3979*7688df22SAndroid Build Coastguard Worker }
3980*7688df22SAndroid Build Coastguard Worker
drmFreePlatformDevice(drmDevicePtr device)3981*7688df22SAndroid Build Coastguard Worker static void drmFreePlatformDevice(drmDevicePtr device)
3982*7688df22SAndroid Build Coastguard Worker {
3983*7688df22SAndroid Build Coastguard Worker if (device->deviceinfo.platform) {
3984*7688df22SAndroid Build Coastguard Worker if (device->deviceinfo.platform->compatible) {
3985*7688df22SAndroid Build Coastguard Worker char **compatible = device->deviceinfo.platform->compatible;
3986*7688df22SAndroid Build Coastguard Worker
3987*7688df22SAndroid Build Coastguard Worker while (*compatible) {
3988*7688df22SAndroid Build Coastguard Worker free(*compatible);
3989*7688df22SAndroid Build Coastguard Worker compatible++;
3990*7688df22SAndroid Build Coastguard Worker }
3991*7688df22SAndroid Build Coastguard Worker
3992*7688df22SAndroid Build Coastguard Worker free(device->deviceinfo.platform->compatible);
3993*7688df22SAndroid Build Coastguard Worker }
3994*7688df22SAndroid Build Coastguard Worker }
3995*7688df22SAndroid Build Coastguard Worker }
3996*7688df22SAndroid Build Coastguard Worker
drmFreeHost1xDevice(drmDevicePtr device)3997*7688df22SAndroid Build Coastguard Worker static void drmFreeHost1xDevice(drmDevicePtr device)
3998*7688df22SAndroid Build Coastguard Worker {
3999*7688df22SAndroid Build Coastguard Worker if (device->deviceinfo.host1x) {
4000*7688df22SAndroid Build Coastguard Worker if (device->deviceinfo.host1x->compatible) {
4001*7688df22SAndroid Build Coastguard Worker char **compatible = device->deviceinfo.host1x->compatible;
4002*7688df22SAndroid Build Coastguard Worker
4003*7688df22SAndroid Build Coastguard Worker while (*compatible) {
4004*7688df22SAndroid Build Coastguard Worker free(*compatible);
4005*7688df22SAndroid Build Coastguard Worker compatible++;
4006*7688df22SAndroid Build Coastguard Worker }
4007*7688df22SAndroid Build Coastguard Worker
4008*7688df22SAndroid Build Coastguard Worker free(device->deviceinfo.host1x->compatible);
4009*7688df22SAndroid Build Coastguard Worker }
4010*7688df22SAndroid Build Coastguard Worker }
4011*7688df22SAndroid Build Coastguard Worker }
4012*7688df22SAndroid Build Coastguard Worker
drmFreeDevice(drmDevicePtr * device)4013*7688df22SAndroid Build Coastguard Worker drm_public void drmFreeDevice(drmDevicePtr *device)
4014*7688df22SAndroid Build Coastguard Worker {
4015*7688df22SAndroid Build Coastguard Worker if (device == NULL)
4016*7688df22SAndroid Build Coastguard Worker return;
4017*7688df22SAndroid Build Coastguard Worker
4018*7688df22SAndroid Build Coastguard Worker if (*device) {
4019*7688df22SAndroid Build Coastguard Worker switch ((*device)->bustype) {
4020*7688df22SAndroid Build Coastguard Worker case DRM_BUS_PLATFORM:
4021*7688df22SAndroid Build Coastguard Worker drmFreePlatformDevice(*device);
4022*7688df22SAndroid Build Coastguard Worker break;
4023*7688df22SAndroid Build Coastguard Worker
4024*7688df22SAndroid Build Coastguard Worker case DRM_BUS_HOST1X:
4025*7688df22SAndroid Build Coastguard Worker drmFreeHost1xDevice(*device);
4026*7688df22SAndroid Build Coastguard Worker break;
4027*7688df22SAndroid Build Coastguard Worker }
4028*7688df22SAndroid Build Coastguard Worker }
4029*7688df22SAndroid Build Coastguard Worker
4030*7688df22SAndroid Build Coastguard Worker free(*device);
4031*7688df22SAndroid Build Coastguard Worker *device = NULL;
4032*7688df22SAndroid Build Coastguard Worker }
4033*7688df22SAndroid Build Coastguard Worker
drmFreeDevices(drmDevicePtr devices[],int count)4034*7688df22SAndroid Build Coastguard Worker drm_public void drmFreeDevices(drmDevicePtr devices[], int count)
4035*7688df22SAndroid Build Coastguard Worker {
4036*7688df22SAndroid Build Coastguard Worker int i;
4037*7688df22SAndroid Build Coastguard Worker
4038*7688df22SAndroid Build Coastguard Worker if (devices == NULL)
4039*7688df22SAndroid Build Coastguard Worker return;
4040*7688df22SAndroid Build Coastguard Worker
4041*7688df22SAndroid Build Coastguard Worker for (i = 0; i < count; i++)
4042*7688df22SAndroid Build Coastguard Worker if (devices[i])
4043*7688df22SAndroid Build Coastguard Worker drmFreeDevice(&devices[i]);
4044*7688df22SAndroid Build Coastguard Worker }
4045*7688df22SAndroid Build Coastguard Worker
drmDeviceAlloc(unsigned int type,const char * node,size_t bus_size,size_t device_size,char ** ptrp)4046*7688df22SAndroid Build Coastguard Worker static drmDevicePtr drmDeviceAlloc(unsigned int type, const char *node,
4047*7688df22SAndroid Build Coastguard Worker size_t bus_size, size_t device_size,
4048*7688df22SAndroid Build Coastguard Worker char **ptrp)
4049*7688df22SAndroid Build Coastguard Worker {
4050*7688df22SAndroid Build Coastguard Worker size_t max_node_length, extra, size;
4051*7688df22SAndroid Build Coastguard Worker drmDevicePtr device;
4052*7688df22SAndroid Build Coastguard Worker unsigned int i;
4053*7688df22SAndroid Build Coastguard Worker char *ptr;
4054*7688df22SAndroid Build Coastguard Worker
4055*7688df22SAndroid Build Coastguard Worker max_node_length = ALIGN(drmGetMaxNodeName(), sizeof(void *));
4056*7688df22SAndroid Build Coastguard Worker extra = DRM_NODE_MAX * (sizeof(void *) + max_node_length);
4057*7688df22SAndroid Build Coastguard Worker
4058*7688df22SAndroid Build Coastguard Worker size = sizeof(*device) + extra + bus_size + device_size;
4059*7688df22SAndroid Build Coastguard Worker
4060*7688df22SAndroid Build Coastguard Worker device = calloc(1, size);
4061*7688df22SAndroid Build Coastguard Worker if (!device)
4062*7688df22SAndroid Build Coastguard Worker return NULL;
4063*7688df22SAndroid Build Coastguard Worker
4064*7688df22SAndroid Build Coastguard Worker device->available_nodes = 1 << type;
4065*7688df22SAndroid Build Coastguard Worker
4066*7688df22SAndroid Build Coastguard Worker ptr = (char *)device + sizeof(*device);
4067*7688df22SAndroid Build Coastguard Worker device->nodes = (char **)ptr;
4068*7688df22SAndroid Build Coastguard Worker
4069*7688df22SAndroid Build Coastguard Worker ptr += DRM_NODE_MAX * sizeof(void *);
4070*7688df22SAndroid Build Coastguard Worker
4071*7688df22SAndroid Build Coastguard Worker for (i = 0; i < DRM_NODE_MAX; i++) {
4072*7688df22SAndroid Build Coastguard Worker device->nodes[i] = ptr;
4073*7688df22SAndroid Build Coastguard Worker ptr += max_node_length;
4074*7688df22SAndroid Build Coastguard Worker }
4075*7688df22SAndroid Build Coastguard Worker
4076*7688df22SAndroid Build Coastguard Worker memcpy(device->nodes[type], node, max_node_length);
4077*7688df22SAndroid Build Coastguard Worker
4078*7688df22SAndroid Build Coastguard Worker *ptrp = ptr;
4079*7688df22SAndroid Build Coastguard Worker
4080*7688df22SAndroid Build Coastguard Worker return device;
4081*7688df22SAndroid Build Coastguard Worker }
4082*7688df22SAndroid Build Coastguard Worker
drmProcessPciDevice(drmDevicePtr * device,const char * node,int node_type,int maj,int min,bool fetch_deviceinfo,uint32_t flags)4083*7688df22SAndroid Build Coastguard Worker static int drmProcessPciDevice(drmDevicePtr *device,
4084*7688df22SAndroid Build Coastguard Worker const char *node, int node_type,
4085*7688df22SAndroid Build Coastguard Worker int maj, int min, bool fetch_deviceinfo,
4086*7688df22SAndroid Build Coastguard Worker uint32_t flags)
4087*7688df22SAndroid Build Coastguard Worker {
4088*7688df22SAndroid Build Coastguard Worker drmDevicePtr dev;
4089*7688df22SAndroid Build Coastguard Worker char *addr;
4090*7688df22SAndroid Build Coastguard Worker int ret;
4091*7688df22SAndroid Build Coastguard Worker
4092*7688df22SAndroid Build Coastguard Worker dev = drmDeviceAlloc(node_type, node, sizeof(drmPciBusInfo),
4093*7688df22SAndroid Build Coastguard Worker sizeof(drmPciDeviceInfo), &addr);
4094*7688df22SAndroid Build Coastguard Worker if (!dev)
4095*7688df22SAndroid Build Coastguard Worker return -ENOMEM;
4096*7688df22SAndroid Build Coastguard Worker
4097*7688df22SAndroid Build Coastguard Worker dev->bustype = DRM_BUS_PCI;
4098*7688df22SAndroid Build Coastguard Worker
4099*7688df22SAndroid Build Coastguard Worker dev->businfo.pci = (drmPciBusInfoPtr)addr;
4100*7688df22SAndroid Build Coastguard Worker
4101*7688df22SAndroid Build Coastguard Worker ret = drmParsePciBusInfo(maj, min, dev->businfo.pci);
4102*7688df22SAndroid Build Coastguard Worker if (ret)
4103*7688df22SAndroid Build Coastguard Worker goto free_device;
4104*7688df22SAndroid Build Coastguard Worker
4105*7688df22SAndroid Build Coastguard Worker // Fetch the device info if the user has requested it
4106*7688df22SAndroid Build Coastguard Worker if (fetch_deviceinfo) {
4107*7688df22SAndroid Build Coastguard Worker addr += sizeof(drmPciBusInfo);
4108*7688df22SAndroid Build Coastguard Worker dev->deviceinfo.pci = (drmPciDeviceInfoPtr)addr;
4109*7688df22SAndroid Build Coastguard Worker
4110*7688df22SAndroid Build Coastguard Worker ret = drmParsePciDeviceInfo(maj, min, dev->deviceinfo.pci, flags);
4111*7688df22SAndroid Build Coastguard Worker if (ret)
4112*7688df22SAndroid Build Coastguard Worker goto free_device;
4113*7688df22SAndroid Build Coastguard Worker }
4114*7688df22SAndroid Build Coastguard Worker
4115*7688df22SAndroid Build Coastguard Worker *device = dev;
4116*7688df22SAndroid Build Coastguard Worker
4117*7688df22SAndroid Build Coastguard Worker return 0;
4118*7688df22SAndroid Build Coastguard Worker
4119*7688df22SAndroid Build Coastguard Worker free_device:
4120*7688df22SAndroid Build Coastguard Worker free(dev);
4121*7688df22SAndroid Build Coastguard Worker return ret;
4122*7688df22SAndroid Build Coastguard Worker }
4123*7688df22SAndroid Build Coastguard Worker
4124*7688df22SAndroid Build Coastguard Worker #ifdef __linux__
drm_usb_dev_path(int maj,int min,char * path,size_t len)4125*7688df22SAndroid Build Coastguard Worker static int drm_usb_dev_path(int maj, int min, char *path, size_t len)
4126*7688df22SAndroid Build Coastguard Worker {
4127*7688df22SAndroid Build Coastguard Worker char *value, *tmp_path, *slash;
4128*7688df22SAndroid Build Coastguard Worker bool usb_device, usb_interface;
4129*7688df22SAndroid Build Coastguard Worker
4130*7688df22SAndroid Build Coastguard Worker snprintf(path, len, "/sys/dev/char/%d:%d/device", maj, min);
4131*7688df22SAndroid Build Coastguard Worker
4132*7688df22SAndroid Build Coastguard Worker value = sysfs_uevent_get(path, "DEVTYPE");
4133*7688df22SAndroid Build Coastguard Worker if (!value)
4134*7688df22SAndroid Build Coastguard Worker return -ENOENT;
4135*7688df22SAndroid Build Coastguard Worker
4136*7688df22SAndroid Build Coastguard Worker usb_device = strcmp(value, "usb_device") == 0;
4137*7688df22SAndroid Build Coastguard Worker usb_interface = strcmp(value, "usb_interface") == 0;
4138*7688df22SAndroid Build Coastguard Worker free(value);
4139*7688df22SAndroid Build Coastguard Worker
4140*7688df22SAndroid Build Coastguard Worker if (usb_device)
4141*7688df22SAndroid Build Coastguard Worker return 0;
4142*7688df22SAndroid Build Coastguard Worker if (!usb_interface)
4143*7688df22SAndroid Build Coastguard Worker return -ENOTSUP;
4144*7688df22SAndroid Build Coastguard Worker
4145*7688df22SAndroid Build Coastguard Worker /* The parent of a usb_interface is a usb_device */
4146*7688df22SAndroid Build Coastguard Worker
4147*7688df22SAndroid Build Coastguard Worker tmp_path = realpath(path, NULL);
4148*7688df22SAndroid Build Coastguard Worker if (!tmp_path)
4149*7688df22SAndroid Build Coastguard Worker return -errno;
4150*7688df22SAndroid Build Coastguard Worker
4151*7688df22SAndroid Build Coastguard Worker slash = strrchr(tmp_path, '/');
4152*7688df22SAndroid Build Coastguard Worker if (!slash) {
4153*7688df22SAndroid Build Coastguard Worker free(tmp_path);
4154*7688df22SAndroid Build Coastguard Worker return -EINVAL;
4155*7688df22SAndroid Build Coastguard Worker }
4156*7688df22SAndroid Build Coastguard Worker
4157*7688df22SAndroid Build Coastguard Worker *slash = '\0';
4158*7688df22SAndroid Build Coastguard Worker
4159*7688df22SAndroid Build Coastguard Worker if (snprintf(path, len, "%s", tmp_path) >= (int)len) {
4160*7688df22SAndroid Build Coastguard Worker free(tmp_path);
4161*7688df22SAndroid Build Coastguard Worker return -EINVAL;
4162*7688df22SAndroid Build Coastguard Worker }
4163*7688df22SAndroid Build Coastguard Worker
4164*7688df22SAndroid Build Coastguard Worker free(tmp_path);
4165*7688df22SAndroid Build Coastguard Worker return 0;
4166*7688df22SAndroid Build Coastguard Worker }
4167*7688df22SAndroid Build Coastguard Worker #endif
4168*7688df22SAndroid Build Coastguard Worker
drmParseUsbBusInfo(int maj,int min,drmUsbBusInfoPtr info)4169*7688df22SAndroid Build Coastguard Worker static int drmParseUsbBusInfo(int maj, int min, drmUsbBusInfoPtr info)
4170*7688df22SAndroid Build Coastguard Worker {
4171*7688df22SAndroid Build Coastguard Worker #ifdef __linux__
4172*7688df22SAndroid Build Coastguard Worker char path[PATH_MAX + 1], *value;
4173*7688df22SAndroid Build Coastguard Worker unsigned int bus, dev;
4174*7688df22SAndroid Build Coastguard Worker int ret;
4175*7688df22SAndroid Build Coastguard Worker
4176*7688df22SAndroid Build Coastguard Worker ret = drm_usb_dev_path(maj, min, path, sizeof(path));
4177*7688df22SAndroid Build Coastguard Worker if (ret < 0)
4178*7688df22SAndroid Build Coastguard Worker return ret;
4179*7688df22SAndroid Build Coastguard Worker
4180*7688df22SAndroid Build Coastguard Worker value = sysfs_uevent_get(path, "BUSNUM");
4181*7688df22SAndroid Build Coastguard Worker if (!value)
4182*7688df22SAndroid Build Coastguard Worker return -ENOENT;
4183*7688df22SAndroid Build Coastguard Worker
4184*7688df22SAndroid Build Coastguard Worker ret = sscanf(value, "%03u", &bus);
4185*7688df22SAndroid Build Coastguard Worker free(value);
4186*7688df22SAndroid Build Coastguard Worker
4187*7688df22SAndroid Build Coastguard Worker if (ret <= 0)
4188*7688df22SAndroid Build Coastguard Worker return -errno;
4189*7688df22SAndroid Build Coastguard Worker
4190*7688df22SAndroid Build Coastguard Worker value = sysfs_uevent_get(path, "DEVNUM");
4191*7688df22SAndroid Build Coastguard Worker if (!value)
4192*7688df22SAndroid Build Coastguard Worker return -ENOENT;
4193*7688df22SAndroid Build Coastguard Worker
4194*7688df22SAndroid Build Coastguard Worker ret = sscanf(value, "%03u", &dev);
4195*7688df22SAndroid Build Coastguard Worker free(value);
4196*7688df22SAndroid Build Coastguard Worker
4197*7688df22SAndroid Build Coastguard Worker if (ret <= 0)
4198*7688df22SAndroid Build Coastguard Worker return -errno;
4199*7688df22SAndroid Build Coastguard Worker
4200*7688df22SAndroid Build Coastguard Worker info->bus = bus;
4201*7688df22SAndroid Build Coastguard Worker info->dev = dev;
4202*7688df22SAndroid Build Coastguard Worker
4203*7688df22SAndroid Build Coastguard Worker return 0;
4204*7688df22SAndroid Build Coastguard Worker #else
4205*7688df22SAndroid Build Coastguard Worker #warning "Missing implementation of drmParseUsbBusInfo"
4206*7688df22SAndroid Build Coastguard Worker return -EINVAL;
4207*7688df22SAndroid Build Coastguard Worker #endif
4208*7688df22SAndroid Build Coastguard Worker }
4209*7688df22SAndroid Build Coastguard Worker
drmParseUsbDeviceInfo(int maj,int min,drmUsbDeviceInfoPtr info)4210*7688df22SAndroid Build Coastguard Worker static int drmParseUsbDeviceInfo(int maj, int min, drmUsbDeviceInfoPtr info)
4211*7688df22SAndroid Build Coastguard Worker {
4212*7688df22SAndroid Build Coastguard Worker #ifdef __linux__
4213*7688df22SAndroid Build Coastguard Worker char path[PATH_MAX + 1], *value;
4214*7688df22SAndroid Build Coastguard Worker unsigned int vendor, product;
4215*7688df22SAndroid Build Coastguard Worker int ret;
4216*7688df22SAndroid Build Coastguard Worker
4217*7688df22SAndroid Build Coastguard Worker ret = drm_usb_dev_path(maj, min, path, sizeof(path));
4218*7688df22SAndroid Build Coastguard Worker if (ret < 0)
4219*7688df22SAndroid Build Coastguard Worker return ret;
4220*7688df22SAndroid Build Coastguard Worker
4221*7688df22SAndroid Build Coastguard Worker value = sysfs_uevent_get(path, "PRODUCT");
4222*7688df22SAndroid Build Coastguard Worker if (!value)
4223*7688df22SAndroid Build Coastguard Worker return -ENOENT;
4224*7688df22SAndroid Build Coastguard Worker
4225*7688df22SAndroid Build Coastguard Worker ret = sscanf(value, "%x/%x", &vendor, &product);
4226*7688df22SAndroid Build Coastguard Worker free(value);
4227*7688df22SAndroid Build Coastguard Worker
4228*7688df22SAndroid Build Coastguard Worker if (ret <= 0)
4229*7688df22SAndroid Build Coastguard Worker return -errno;
4230*7688df22SAndroid Build Coastguard Worker
4231*7688df22SAndroid Build Coastguard Worker info->vendor = vendor;
4232*7688df22SAndroid Build Coastguard Worker info->product = product;
4233*7688df22SAndroid Build Coastguard Worker
4234*7688df22SAndroid Build Coastguard Worker return 0;
4235*7688df22SAndroid Build Coastguard Worker #else
4236*7688df22SAndroid Build Coastguard Worker #warning "Missing implementation of drmParseUsbDeviceInfo"
4237*7688df22SAndroid Build Coastguard Worker return -EINVAL;
4238*7688df22SAndroid Build Coastguard Worker #endif
4239*7688df22SAndroid Build Coastguard Worker }
4240*7688df22SAndroid Build Coastguard Worker
drmProcessUsbDevice(drmDevicePtr * device,const char * node,int node_type,int maj,int min,bool fetch_deviceinfo,uint32_t flags)4241*7688df22SAndroid Build Coastguard Worker static int drmProcessUsbDevice(drmDevicePtr *device, const char *node,
4242*7688df22SAndroid Build Coastguard Worker int node_type, int maj, int min,
4243*7688df22SAndroid Build Coastguard Worker bool fetch_deviceinfo, uint32_t flags)
4244*7688df22SAndroid Build Coastguard Worker {
4245*7688df22SAndroid Build Coastguard Worker drmDevicePtr dev;
4246*7688df22SAndroid Build Coastguard Worker char *ptr;
4247*7688df22SAndroid Build Coastguard Worker int ret;
4248*7688df22SAndroid Build Coastguard Worker
4249*7688df22SAndroid Build Coastguard Worker dev = drmDeviceAlloc(node_type, node, sizeof(drmUsbBusInfo),
4250*7688df22SAndroid Build Coastguard Worker sizeof(drmUsbDeviceInfo), &ptr);
4251*7688df22SAndroid Build Coastguard Worker if (!dev)
4252*7688df22SAndroid Build Coastguard Worker return -ENOMEM;
4253*7688df22SAndroid Build Coastguard Worker
4254*7688df22SAndroid Build Coastguard Worker dev->bustype = DRM_BUS_USB;
4255*7688df22SAndroid Build Coastguard Worker
4256*7688df22SAndroid Build Coastguard Worker dev->businfo.usb = (drmUsbBusInfoPtr)ptr;
4257*7688df22SAndroid Build Coastguard Worker
4258*7688df22SAndroid Build Coastguard Worker ret = drmParseUsbBusInfo(maj, min, dev->businfo.usb);
4259*7688df22SAndroid Build Coastguard Worker if (ret < 0)
4260*7688df22SAndroid Build Coastguard Worker goto free_device;
4261*7688df22SAndroid Build Coastguard Worker
4262*7688df22SAndroid Build Coastguard Worker if (fetch_deviceinfo) {
4263*7688df22SAndroid Build Coastguard Worker ptr += sizeof(drmUsbBusInfo);
4264*7688df22SAndroid Build Coastguard Worker dev->deviceinfo.usb = (drmUsbDeviceInfoPtr)ptr;
4265*7688df22SAndroid Build Coastguard Worker
4266*7688df22SAndroid Build Coastguard Worker ret = drmParseUsbDeviceInfo(maj, min, dev->deviceinfo.usb);
4267*7688df22SAndroid Build Coastguard Worker if (ret < 0)
4268*7688df22SAndroid Build Coastguard Worker goto free_device;
4269*7688df22SAndroid Build Coastguard Worker }
4270*7688df22SAndroid Build Coastguard Worker
4271*7688df22SAndroid Build Coastguard Worker *device = dev;
4272*7688df22SAndroid Build Coastguard Worker
4273*7688df22SAndroid Build Coastguard Worker return 0;
4274*7688df22SAndroid Build Coastguard Worker
4275*7688df22SAndroid Build Coastguard Worker free_device:
4276*7688df22SAndroid Build Coastguard Worker free(dev);
4277*7688df22SAndroid Build Coastguard Worker return ret;
4278*7688df22SAndroid Build Coastguard Worker }
4279*7688df22SAndroid Build Coastguard Worker
drmParseOFBusInfo(int maj,int min,char * fullname)4280*7688df22SAndroid Build Coastguard Worker static int drmParseOFBusInfo(int maj, int min, char *fullname)
4281*7688df22SAndroid Build Coastguard Worker {
4282*7688df22SAndroid Build Coastguard Worker #ifdef __linux__
4283*7688df22SAndroid Build Coastguard Worker char path[PATH_MAX + 1], *name, *tmp_name;
4284*7688df22SAndroid Build Coastguard Worker
4285*7688df22SAndroid Build Coastguard Worker snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device", maj, min);
4286*7688df22SAndroid Build Coastguard Worker
4287*7688df22SAndroid Build Coastguard Worker name = sysfs_uevent_get(path, "OF_FULLNAME");
4288*7688df22SAndroid Build Coastguard Worker tmp_name = name;
4289*7688df22SAndroid Build Coastguard Worker if (!name) {
4290*7688df22SAndroid Build Coastguard Worker /* If the device lacks OF data, pick the MODALIAS info */
4291*7688df22SAndroid Build Coastguard Worker name = sysfs_uevent_get(path, "MODALIAS");
4292*7688df22SAndroid Build Coastguard Worker if (!name)
4293*7688df22SAndroid Build Coastguard Worker return -ENOENT;
4294*7688df22SAndroid Build Coastguard Worker
4295*7688df22SAndroid Build Coastguard Worker /* .. and strip the MODALIAS=[platform,usb...]: part. */
4296*7688df22SAndroid Build Coastguard Worker tmp_name = strrchr(name, ':');
4297*7688df22SAndroid Build Coastguard Worker if (!tmp_name) {
4298*7688df22SAndroid Build Coastguard Worker free(name);
4299*7688df22SAndroid Build Coastguard Worker return -ENOENT;
4300*7688df22SAndroid Build Coastguard Worker }
4301*7688df22SAndroid Build Coastguard Worker tmp_name++;
4302*7688df22SAndroid Build Coastguard Worker }
4303*7688df22SAndroid Build Coastguard Worker
4304*7688df22SAndroid Build Coastguard Worker strncpy(fullname, tmp_name, DRM_PLATFORM_DEVICE_NAME_LEN);
4305*7688df22SAndroid Build Coastguard Worker fullname[DRM_PLATFORM_DEVICE_NAME_LEN - 1] = '\0';
4306*7688df22SAndroid Build Coastguard Worker free(name);
4307*7688df22SAndroid Build Coastguard Worker
4308*7688df22SAndroid Build Coastguard Worker return 0;
4309*7688df22SAndroid Build Coastguard Worker #else
4310*7688df22SAndroid Build Coastguard Worker #warning "Missing implementation of drmParseOFBusInfo"
4311*7688df22SAndroid Build Coastguard Worker return -EINVAL;
4312*7688df22SAndroid Build Coastguard Worker #endif
4313*7688df22SAndroid Build Coastguard Worker }
4314*7688df22SAndroid Build Coastguard Worker
drmParseOFDeviceInfo(int maj,int min,char *** compatible)4315*7688df22SAndroid Build Coastguard Worker static int drmParseOFDeviceInfo(int maj, int min, char ***compatible)
4316*7688df22SAndroid Build Coastguard Worker {
4317*7688df22SAndroid Build Coastguard Worker #ifdef __linux__
4318*7688df22SAndroid Build Coastguard Worker char path[PATH_MAX + 1], *value, *tmp_name;
4319*7688df22SAndroid Build Coastguard Worker unsigned int count, i;
4320*7688df22SAndroid Build Coastguard Worker int err;
4321*7688df22SAndroid Build Coastguard Worker
4322*7688df22SAndroid Build Coastguard Worker snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device", maj, min);
4323*7688df22SAndroid Build Coastguard Worker
4324*7688df22SAndroid Build Coastguard Worker value = sysfs_uevent_get(path, "OF_COMPATIBLE_N");
4325*7688df22SAndroid Build Coastguard Worker if (value) {
4326*7688df22SAndroid Build Coastguard Worker sscanf(value, "%u", &count);
4327*7688df22SAndroid Build Coastguard Worker free(value);
4328*7688df22SAndroid Build Coastguard Worker } else {
4329*7688df22SAndroid Build Coastguard Worker /* Assume one entry if the device lack OF data */
4330*7688df22SAndroid Build Coastguard Worker count = 1;
4331*7688df22SAndroid Build Coastguard Worker }
4332*7688df22SAndroid Build Coastguard Worker
4333*7688df22SAndroid Build Coastguard Worker *compatible = calloc(count + 1, sizeof(char *));
4334*7688df22SAndroid Build Coastguard Worker if (!*compatible)
4335*7688df22SAndroid Build Coastguard Worker return -ENOMEM;
4336*7688df22SAndroid Build Coastguard Worker
4337*7688df22SAndroid Build Coastguard Worker for (i = 0; i < count; i++) {
4338*7688df22SAndroid Build Coastguard Worker value = sysfs_uevent_get(path, "OF_COMPATIBLE_%u", i);
4339*7688df22SAndroid Build Coastguard Worker tmp_name = value;
4340*7688df22SAndroid Build Coastguard Worker if (!value) {
4341*7688df22SAndroid Build Coastguard Worker /* If the device lacks OF data, pick the MODALIAS info */
4342*7688df22SAndroid Build Coastguard Worker value = sysfs_uevent_get(path, "MODALIAS");
4343*7688df22SAndroid Build Coastguard Worker if (!value) {
4344*7688df22SAndroid Build Coastguard Worker err = -ENOENT;
4345*7688df22SAndroid Build Coastguard Worker goto free;
4346*7688df22SAndroid Build Coastguard Worker }
4347*7688df22SAndroid Build Coastguard Worker
4348*7688df22SAndroid Build Coastguard Worker /* .. and strip the MODALIAS=[platform,usb...]: part. */
4349*7688df22SAndroid Build Coastguard Worker tmp_name = strrchr(value, ':');
4350*7688df22SAndroid Build Coastguard Worker if (!tmp_name) {
4351*7688df22SAndroid Build Coastguard Worker free(value);
4352*7688df22SAndroid Build Coastguard Worker return -ENOENT;
4353*7688df22SAndroid Build Coastguard Worker }
4354*7688df22SAndroid Build Coastguard Worker tmp_name = strdup(tmp_name + 1);
4355*7688df22SAndroid Build Coastguard Worker free(value);
4356*7688df22SAndroid Build Coastguard Worker }
4357*7688df22SAndroid Build Coastguard Worker
4358*7688df22SAndroid Build Coastguard Worker (*compatible)[i] = tmp_name;
4359*7688df22SAndroid Build Coastguard Worker }
4360*7688df22SAndroid Build Coastguard Worker
4361*7688df22SAndroid Build Coastguard Worker return 0;
4362*7688df22SAndroid Build Coastguard Worker
4363*7688df22SAndroid Build Coastguard Worker free:
4364*7688df22SAndroid Build Coastguard Worker while (i--)
4365*7688df22SAndroid Build Coastguard Worker free((*compatible)[i]);
4366*7688df22SAndroid Build Coastguard Worker
4367*7688df22SAndroid Build Coastguard Worker free(*compatible);
4368*7688df22SAndroid Build Coastguard Worker return err;
4369*7688df22SAndroid Build Coastguard Worker #else
4370*7688df22SAndroid Build Coastguard Worker #warning "Missing implementation of drmParseOFDeviceInfo"
4371*7688df22SAndroid Build Coastguard Worker return -EINVAL;
4372*7688df22SAndroid Build Coastguard Worker #endif
4373*7688df22SAndroid Build Coastguard Worker }
4374*7688df22SAndroid Build Coastguard Worker
drmProcessPlatformDevice(drmDevicePtr * device,const char * node,int node_type,int maj,int min,bool fetch_deviceinfo,uint32_t flags)4375*7688df22SAndroid Build Coastguard Worker static int drmProcessPlatformDevice(drmDevicePtr *device,
4376*7688df22SAndroid Build Coastguard Worker const char *node, int node_type,
4377*7688df22SAndroid Build Coastguard Worker int maj, int min, bool fetch_deviceinfo,
4378*7688df22SAndroid Build Coastguard Worker uint32_t flags)
4379*7688df22SAndroid Build Coastguard Worker {
4380*7688df22SAndroid Build Coastguard Worker drmDevicePtr dev;
4381*7688df22SAndroid Build Coastguard Worker char *ptr;
4382*7688df22SAndroid Build Coastguard Worker int ret;
4383*7688df22SAndroid Build Coastguard Worker
4384*7688df22SAndroid Build Coastguard Worker dev = drmDeviceAlloc(node_type, node, sizeof(drmPlatformBusInfo),
4385*7688df22SAndroid Build Coastguard Worker sizeof(drmPlatformDeviceInfo), &ptr);
4386*7688df22SAndroid Build Coastguard Worker if (!dev)
4387*7688df22SAndroid Build Coastguard Worker return -ENOMEM;
4388*7688df22SAndroid Build Coastguard Worker
4389*7688df22SAndroid Build Coastguard Worker dev->bustype = DRM_BUS_PLATFORM;
4390*7688df22SAndroid Build Coastguard Worker
4391*7688df22SAndroid Build Coastguard Worker dev->businfo.platform = (drmPlatformBusInfoPtr)ptr;
4392*7688df22SAndroid Build Coastguard Worker
4393*7688df22SAndroid Build Coastguard Worker ret = drmParseOFBusInfo(maj, min, dev->businfo.platform->fullname);
4394*7688df22SAndroid Build Coastguard Worker if (ret < 0)
4395*7688df22SAndroid Build Coastguard Worker goto free_device;
4396*7688df22SAndroid Build Coastguard Worker
4397*7688df22SAndroid Build Coastguard Worker if (fetch_deviceinfo) {
4398*7688df22SAndroid Build Coastguard Worker ptr += sizeof(drmPlatformBusInfo);
4399*7688df22SAndroid Build Coastguard Worker dev->deviceinfo.platform = (drmPlatformDeviceInfoPtr)ptr;
4400*7688df22SAndroid Build Coastguard Worker
4401*7688df22SAndroid Build Coastguard Worker ret = drmParseOFDeviceInfo(maj, min, &dev->deviceinfo.platform->compatible);
4402*7688df22SAndroid Build Coastguard Worker if (ret < 0)
4403*7688df22SAndroid Build Coastguard Worker goto free_device;
4404*7688df22SAndroid Build Coastguard Worker }
4405*7688df22SAndroid Build Coastguard Worker
4406*7688df22SAndroid Build Coastguard Worker *device = dev;
4407*7688df22SAndroid Build Coastguard Worker
4408*7688df22SAndroid Build Coastguard Worker return 0;
4409*7688df22SAndroid Build Coastguard Worker
4410*7688df22SAndroid Build Coastguard Worker free_device:
4411*7688df22SAndroid Build Coastguard Worker free(dev);
4412*7688df22SAndroid Build Coastguard Worker return ret;
4413*7688df22SAndroid Build Coastguard Worker }
4414*7688df22SAndroid Build Coastguard Worker
drmProcessHost1xDevice(drmDevicePtr * device,const char * node,int node_type,int maj,int min,bool fetch_deviceinfo,uint32_t flags)4415*7688df22SAndroid Build Coastguard Worker static int drmProcessHost1xDevice(drmDevicePtr *device,
4416*7688df22SAndroid Build Coastguard Worker const char *node, int node_type,
4417*7688df22SAndroid Build Coastguard Worker int maj, int min, bool fetch_deviceinfo,
4418*7688df22SAndroid Build Coastguard Worker uint32_t flags)
4419*7688df22SAndroid Build Coastguard Worker {
4420*7688df22SAndroid Build Coastguard Worker drmDevicePtr dev;
4421*7688df22SAndroid Build Coastguard Worker char *ptr;
4422*7688df22SAndroid Build Coastguard Worker int ret;
4423*7688df22SAndroid Build Coastguard Worker
4424*7688df22SAndroid Build Coastguard Worker dev = drmDeviceAlloc(node_type, node, sizeof(drmHost1xBusInfo),
4425*7688df22SAndroid Build Coastguard Worker sizeof(drmHost1xDeviceInfo), &ptr);
4426*7688df22SAndroid Build Coastguard Worker if (!dev)
4427*7688df22SAndroid Build Coastguard Worker return -ENOMEM;
4428*7688df22SAndroid Build Coastguard Worker
4429*7688df22SAndroid Build Coastguard Worker dev->bustype = DRM_BUS_HOST1X;
4430*7688df22SAndroid Build Coastguard Worker
4431*7688df22SAndroid Build Coastguard Worker dev->businfo.host1x = (drmHost1xBusInfoPtr)ptr;
4432*7688df22SAndroid Build Coastguard Worker
4433*7688df22SAndroid Build Coastguard Worker ret = drmParseOFBusInfo(maj, min, dev->businfo.host1x->fullname);
4434*7688df22SAndroid Build Coastguard Worker if (ret < 0)
4435*7688df22SAndroid Build Coastguard Worker goto free_device;
4436*7688df22SAndroid Build Coastguard Worker
4437*7688df22SAndroid Build Coastguard Worker if (fetch_deviceinfo) {
4438*7688df22SAndroid Build Coastguard Worker ptr += sizeof(drmHost1xBusInfo);
4439*7688df22SAndroid Build Coastguard Worker dev->deviceinfo.host1x = (drmHost1xDeviceInfoPtr)ptr;
4440*7688df22SAndroid Build Coastguard Worker
4441*7688df22SAndroid Build Coastguard Worker ret = drmParseOFDeviceInfo(maj, min, &dev->deviceinfo.host1x->compatible);
4442*7688df22SAndroid Build Coastguard Worker if (ret < 0)
4443*7688df22SAndroid Build Coastguard Worker goto free_device;
4444*7688df22SAndroid Build Coastguard Worker }
4445*7688df22SAndroid Build Coastguard Worker
4446*7688df22SAndroid Build Coastguard Worker *device = dev;
4447*7688df22SAndroid Build Coastguard Worker
4448*7688df22SAndroid Build Coastguard Worker return 0;
4449*7688df22SAndroid Build Coastguard Worker
4450*7688df22SAndroid Build Coastguard Worker free_device:
4451*7688df22SAndroid Build Coastguard Worker free(dev);
4452*7688df22SAndroid Build Coastguard Worker return ret;
4453*7688df22SAndroid Build Coastguard Worker }
4454*7688df22SAndroid Build Coastguard Worker
4455*7688df22SAndroid Build Coastguard Worker static int
process_device(drmDevicePtr * device,const char * d_name,int req_subsystem_type,bool fetch_deviceinfo,uint32_t flags)4456*7688df22SAndroid Build Coastguard Worker process_device(drmDevicePtr *device, const char *d_name,
4457*7688df22SAndroid Build Coastguard Worker int req_subsystem_type,
4458*7688df22SAndroid Build Coastguard Worker bool fetch_deviceinfo, uint32_t flags)
4459*7688df22SAndroid Build Coastguard Worker {
4460*7688df22SAndroid Build Coastguard Worker struct stat sbuf;
4461*7688df22SAndroid Build Coastguard Worker char node[PATH_MAX + 1];
4462*7688df22SAndroid Build Coastguard Worker int node_type, subsystem_type, written;
4463*7688df22SAndroid Build Coastguard Worker unsigned int maj, min;
4464*7688df22SAndroid Build Coastguard Worker const int max_node_length = ALIGN(drmGetMaxNodeName(), sizeof(void *));
4465*7688df22SAndroid Build Coastguard Worker
4466*7688df22SAndroid Build Coastguard Worker node_type = drmGetNodeType(d_name);
4467*7688df22SAndroid Build Coastguard Worker if (node_type < 0)
4468*7688df22SAndroid Build Coastguard Worker return -1;
4469*7688df22SAndroid Build Coastguard Worker
4470*7688df22SAndroid Build Coastguard Worker written = snprintf(node, PATH_MAX, "%s/%s", DRM_DIR_NAME, d_name);
4471*7688df22SAndroid Build Coastguard Worker if (written < 0)
4472*7688df22SAndroid Build Coastguard Worker return -1;
4473*7688df22SAndroid Build Coastguard Worker
4474*7688df22SAndroid Build Coastguard Worker /* anything longer than this will be truncated in drmDeviceAlloc.
4475*7688df22SAndroid Build Coastguard Worker * Account for NULL byte
4476*7688df22SAndroid Build Coastguard Worker */
4477*7688df22SAndroid Build Coastguard Worker if (written + 1 > max_node_length)
4478*7688df22SAndroid Build Coastguard Worker return -1;
4479*7688df22SAndroid Build Coastguard Worker
4480*7688df22SAndroid Build Coastguard Worker if (stat(node, &sbuf))
4481*7688df22SAndroid Build Coastguard Worker return -1;
4482*7688df22SAndroid Build Coastguard Worker
4483*7688df22SAndroid Build Coastguard Worker maj = major(sbuf.st_rdev);
4484*7688df22SAndroid Build Coastguard Worker min = minor(sbuf.st_rdev);
4485*7688df22SAndroid Build Coastguard Worker
4486*7688df22SAndroid Build Coastguard Worker if (!drmNodeIsDRM(maj, min) || !S_ISCHR(sbuf.st_mode))
4487*7688df22SAndroid Build Coastguard Worker return -1;
4488*7688df22SAndroid Build Coastguard Worker
4489*7688df22SAndroid Build Coastguard Worker subsystem_type = drmParseSubsystemType(maj, min);
4490*7688df22SAndroid Build Coastguard Worker if (req_subsystem_type != -1 && req_subsystem_type != subsystem_type)
4491*7688df22SAndroid Build Coastguard Worker return -1;
4492*7688df22SAndroid Build Coastguard Worker
4493*7688df22SAndroid Build Coastguard Worker switch (subsystem_type) {
4494*7688df22SAndroid Build Coastguard Worker case DRM_BUS_PCI:
4495*7688df22SAndroid Build Coastguard Worker case DRM_BUS_VIRTIO:
4496*7688df22SAndroid Build Coastguard Worker return drmProcessPciDevice(device, node, node_type, maj, min,
4497*7688df22SAndroid Build Coastguard Worker fetch_deviceinfo, flags);
4498*7688df22SAndroid Build Coastguard Worker case DRM_BUS_USB:
4499*7688df22SAndroid Build Coastguard Worker return drmProcessUsbDevice(device, node, node_type, maj, min,
4500*7688df22SAndroid Build Coastguard Worker fetch_deviceinfo, flags);
4501*7688df22SAndroid Build Coastguard Worker case DRM_BUS_PLATFORM:
4502*7688df22SAndroid Build Coastguard Worker return drmProcessPlatformDevice(device, node, node_type, maj, min,
4503*7688df22SAndroid Build Coastguard Worker fetch_deviceinfo, flags);
4504*7688df22SAndroid Build Coastguard Worker case DRM_BUS_HOST1X:
4505*7688df22SAndroid Build Coastguard Worker return drmProcessHost1xDevice(device, node, node_type, maj, min,
4506*7688df22SAndroid Build Coastguard Worker fetch_deviceinfo, flags);
4507*7688df22SAndroid Build Coastguard Worker default:
4508*7688df22SAndroid Build Coastguard Worker return -1;
4509*7688df22SAndroid Build Coastguard Worker }
4510*7688df22SAndroid Build Coastguard Worker }
4511*7688df22SAndroid Build Coastguard Worker
4512*7688df22SAndroid Build Coastguard Worker /* Consider devices located on the same bus as duplicate and fold the respective
4513*7688df22SAndroid Build Coastguard Worker * entries into a single one.
4514*7688df22SAndroid Build Coastguard Worker *
4515*7688df22SAndroid Build Coastguard Worker * Note: this leaves "gaps" in the array, while preserving the length.
4516*7688df22SAndroid Build Coastguard Worker */
drmFoldDuplicatedDevices(drmDevicePtr local_devices[],int count)4517*7688df22SAndroid Build Coastguard Worker static void drmFoldDuplicatedDevices(drmDevicePtr local_devices[], int count)
4518*7688df22SAndroid Build Coastguard Worker {
4519*7688df22SAndroid Build Coastguard Worker int node_type, i, j;
4520*7688df22SAndroid Build Coastguard Worker
4521*7688df22SAndroid Build Coastguard Worker for (i = 0; i < count; i++) {
4522*7688df22SAndroid Build Coastguard Worker for (j = i + 1; j < count; j++) {
4523*7688df22SAndroid Build Coastguard Worker if (drmDevicesEqual(local_devices[i], local_devices[j])) {
4524*7688df22SAndroid Build Coastguard Worker local_devices[i]->available_nodes |= local_devices[j]->available_nodes;
4525*7688df22SAndroid Build Coastguard Worker node_type = log2_int(local_devices[j]->available_nodes);
4526*7688df22SAndroid Build Coastguard Worker memcpy(local_devices[i]->nodes[node_type],
4527*7688df22SAndroid Build Coastguard Worker local_devices[j]->nodes[node_type], drmGetMaxNodeName());
4528*7688df22SAndroid Build Coastguard Worker drmFreeDevice(&local_devices[j]);
4529*7688df22SAndroid Build Coastguard Worker }
4530*7688df22SAndroid Build Coastguard Worker }
4531*7688df22SAndroid Build Coastguard Worker }
4532*7688df22SAndroid Build Coastguard Worker }
4533*7688df22SAndroid Build Coastguard Worker
4534*7688df22SAndroid Build Coastguard Worker /* Check that the given flags are valid returning 0 on success */
4535*7688df22SAndroid Build Coastguard Worker static int
drm_device_validate_flags(uint32_t flags)4536*7688df22SAndroid Build Coastguard Worker drm_device_validate_flags(uint32_t flags)
4537*7688df22SAndroid Build Coastguard Worker {
4538*7688df22SAndroid Build Coastguard Worker return (flags & ~DRM_DEVICE_GET_PCI_REVISION);
4539*7688df22SAndroid Build Coastguard Worker }
4540*7688df22SAndroid Build Coastguard Worker
4541*7688df22SAndroid Build Coastguard Worker static bool
drm_device_has_rdev(drmDevicePtr device,dev_t find_rdev)4542*7688df22SAndroid Build Coastguard Worker drm_device_has_rdev(drmDevicePtr device, dev_t find_rdev)
4543*7688df22SAndroid Build Coastguard Worker {
4544*7688df22SAndroid Build Coastguard Worker struct stat sbuf;
4545*7688df22SAndroid Build Coastguard Worker
4546*7688df22SAndroid Build Coastguard Worker for (int i = 0; i < DRM_NODE_MAX; i++) {
4547*7688df22SAndroid Build Coastguard Worker if (device->available_nodes & 1 << i) {
4548*7688df22SAndroid Build Coastguard Worker if (stat(device->nodes[i], &sbuf) == 0 &&
4549*7688df22SAndroid Build Coastguard Worker sbuf.st_rdev == find_rdev)
4550*7688df22SAndroid Build Coastguard Worker return true;
4551*7688df22SAndroid Build Coastguard Worker }
4552*7688df22SAndroid Build Coastguard Worker }
4553*7688df22SAndroid Build Coastguard Worker return false;
4554*7688df22SAndroid Build Coastguard Worker }
4555*7688df22SAndroid Build Coastguard Worker
4556*7688df22SAndroid Build Coastguard Worker /*
4557*7688df22SAndroid Build Coastguard Worker * The kernel drm core has a number of places that assume maximum of
4558*7688df22SAndroid Build Coastguard Worker * 3x64 devices nodes. That's 64 for each of primary, control and
4559*7688df22SAndroid Build Coastguard Worker * render nodes. Rounded it up to 256 for simplicity.
4560*7688df22SAndroid Build Coastguard Worker */
4561*7688df22SAndroid Build Coastguard Worker #define MAX_DRM_NODES 256
4562*7688df22SAndroid Build Coastguard Worker
4563*7688df22SAndroid Build Coastguard Worker /**
4564*7688df22SAndroid Build Coastguard Worker * Get information about a device from its dev_t identifier
4565*7688df22SAndroid Build Coastguard Worker *
4566*7688df22SAndroid Build Coastguard Worker * \param find_rdev dev_t identifier of the device
4567*7688df22SAndroid Build Coastguard Worker * \param flags feature/behaviour bitmask
4568*7688df22SAndroid Build Coastguard Worker * \param device the address of a drmDevicePtr where the information
4569*7688df22SAndroid Build Coastguard Worker * will be allocated in stored
4570*7688df22SAndroid Build Coastguard Worker *
4571*7688df22SAndroid Build Coastguard Worker * \return zero on success, negative error code otherwise.
4572*7688df22SAndroid Build Coastguard Worker */
drmGetDeviceFromDevId(dev_t find_rdev,uint32_t flags,drmDevicePtr * device)4573*7688df22SAndroid Build Coastguard Worker drm_public int drmGetDeviceFromDevId(dev_t find_rdev, uint32_t flags, drmDevicePtr *device)
4574*7688df22SAndroid Build Coastguard Worker {
4575*7688df22SAndroid Build Coastguard Worker #ifdef __OpenBSD__
4576*7688df22SAndroid Build Coastguard Worker /*
4577*7688df22SAndroid Build Coastguard Worker * DRI device nodes on OpenBSD are not in their own directory, they reside
4578*7688df22SAndroid Build Coastguard Worker * in /dev along with a large number of statically generated /dev nodes.
4579*7688df22SAndroid Build Coastguard Worker * Avoid stat'ing all of /dev needlessly by implementing this custom path.
4580*7688df22SAndroid Build Coastguard Worker */
4581*7688df22SAndroid Build Coastguard Worker drmDevicePtr d;
4582*7688df22SAndroid Build Coastguard Worker char node[PATH_MAX + 1];
4583*7688df22SAndroid Build Coastguard Worker const char *dev_name;
4584*7688df22SAndroid Build Coastguard Worker int node_type, subsystem_type;
4585*7688df22SAndroid Build Coastguard Worker int maj, min, n, ret;
4586*7688df22SAndroid Build Coastguard Worker const int max_node_length = ALIGN(drmGetMaxNodeName(), sizeof(void *));
4587*7688df22SAndroid Build Coastguard Worker struct stat sbuf;
4588*7688df22SAndroid Build Coastguard Worker
4589*7688df22SAndroid Build Coastguard Worker if (device == NULL)
4590*7688df22SAndroid Build Coastguard Worker return -EINVAL;
4591*7688df22SAndroid Build Coastguard Worker
4592*7688df22SAndroid Build Coastguard Worker maj = major(find_rdev);
4593*7688df22SAndroid Build Coastguard Worker min = minor(find_rdev);
4594*7688df22SAndroid Build Coastguard Worker
4595*7688df22SAndroid Build Coastguard Worker if (!drmNodeIsDRM(maj, min))
4596*7688df22SAndroid Build Coastguard Worker return -EINVAL;
4597*7688df22SAndroid Build Coastguard Worker
4598*7688df22SAndroid Build Coastguard Worker node_type = drmGetMinorType(maj, min);
4599*7688df22SAndroid Build Coastguard Worker if (node_type == -1)
4600*7688df22SAndroid Build Coastguard Worker return -ENODEV;
4601*7688df22SAndroid Build Coastguard Worker
4602*7688df22SAndroid Build Coastguard Worker dev_name = drmGetDeviceName(node_type);
4603*7688df22SAndroid Build Coastguard Worker if (!dev_name)
4604*7688df22SAndroid Build Coastguard Worker return -EINVAL;
4605*7688df22SAndroid Build Coastguard Worker
4606*7688df22SAndroid Build Coastguard Worker /* anything longer than this will be truncated in drmDeviceAlloc.
4607*7688df22SAndroid Build Coastguard Worker * Account for NULL byte
4608*7688df22SAndroid Build Coastguard Worker */
4609*7688df22SAndroid Build Coastguard Worker n = snprintf(node, PATH_MAX, dev_name, DRM_DIR_NAME, min);
4610*7688df22SAndroid Build Coastguard Worker if (n == -1 || n >= PATH_MAX)
4611*7688df22SAndroid Build Coastguard Worker return -errno;
4612*7688df22SAndroid Build Coastguard Worker if (n + 1 > max_node_length)
4613*7688df22SAndroid Build Coastguard Worker return -EINVAL;
4614*7688df22SAndroid Build Coastguard Worker if (stat(node, &sbuf))
4615*7688df22SAndroid Build Coastguard Worker return -EINVAL;
4616*7688df22SAndroid Build Coastguard Worker
4617*7688df22SAndroid Build Coastguard Worker subsystem_type = drmParseSubsystemType(maj, min);
4618*7688df22SAndroid Build Coastguard Worker if (subsystem_type != DRM_BUS_PCI)
4619*7688df22SAndroid Build Coastguard Worker return -ENODEV;
4620*7688df22SAndroid Build Coastguard Worker
4621*7688df22SAndroid Build Coastguard Worker ret = drmProcessPciDevice(&d, node, node_type, maj, min, true, flags);
4622*7688df22SAndroid Build Coastguard Worker if (ret)
4623*7688df22SAndroid Build Coastguard Worker return ret;
4624*7688df22SAndroid Build Coastguard Worker
4625*7688df22SAndroid Build Coastguard Worker *device = d;
4626*7688df22SAndroid Build Coastguard Worker
4627*7688df22SAndroid Build Coastguard Worker return 0;
4628*7688df22SAndroid Build Coastguard Worker #else
4629*7688df22SAndroid Build Coastguard Worker drmDevicePtr local_devices[MAX_DRM_NODES];
4630*7688df22SAndroid Build Coastguard Worker drmDevicePtr d;
4631*7688df22SAndroid Build Coastguard Worker DIR *sysdir;
4632*7688df22SAndroid Build Coastguard Worker struct dirent *dent;
4633*7688df22SAndroid Build Coastguard Worker int subsystem_type;
4634*7688df22SAndroid Build Coastguard Worker int maj, min;
4635*7688df22SAndroid Build Coastguard Worker int ret, i, node_count;
4636*7688df22SAndroid Build Coastguard Worker
4637*7688df22SAndroid Build Coastguard Worker if (drm_device_validate_flags(flags))
4638*7688df22SAndroid Build Coastguard Worker return -EINVAL;
4639*7688df22SAndroid Build Coastguard Worker
4640*7688df22SAndroid Build Coastguard Worker if (device == NULL)
4641*7688df22SAndroid Build Coastguard Worker return -EINVAL;
4642*7688df22SAndroid Build Coastguard Worker
4643*7688df22SAndroid Build Coastguard Worker maj = major(find_rdev);
4644*7688df22SAndroid Build Coastguard Worker min = minor(find_rdev);
4645*7688df22SAndroid Build Coastguard Worker
4646*7688df22SAndroid Build Coastguard Worker if (!drmNodeIsDRM(maj, min))
4647*7688df22SAndroid Build Coastguard Worker return -EINVAL;
4648*7688df22SAndroid Build Coastguard Worker
4649*7688df22SAndroid Build Coastguard Worker subsystem_type = drmParseSubsystemType(maj, min);
4650*7688df22SAndroid Build Coastguard Worker if (subsystem_type < 0)
4651*7688df22SAndroid Build Coastguard Worker return subsystem_type;
4652*7688df22SAndroid Build Coastguard Worker
4653*7688df22SAndroid Build Coastguard Worker sysdir = opendir(DRM_DIR_NAME);
4654*7688df22SAndroid Build Coastguard Worker if (!sysdir)
4655*7688df22SAndroid Build Coastguard Worker return -errno;
4656*7688df22SAndroid Build Coastguard Worker
4657*7688df22SAndroid Build Coastguard Worker i = 0;
4658*7688df22SAndroid Build Coastguard Worker while ((dent = readdir(sysdir))) {
4659*7688df22SAndroid Build Coastguard Worker ret = process_device(&d, dent->d_name, subsystem_type, true, flags);
4660*7688df22SAndroid Build Coastguard Worker if (ret)
4661*7688df22SAndroid Build Coastguard Worker continue;
4662*7688df22SAndroid Build Coastguard Worker
4663*7688df22SAndroid Build Coastguard Worker if (i >= MAX_DRM_NODES) {
4664*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "More than %d drm nodes detected. "
4665*7688df22SAndroid Build Coastguard Worker "Please report a bug - that should not happen.\n"
4666*7688df22SAndroid Build Coastguard Worker "Skipping extra nodes\n", MAX_DRM_NODES);
4667*7688df22SAndroid Build Coastguard Worker break;
4668*7688df22SAndroid Build Coastguard Worker }
4669*7688df22SAndroid Build Coastguard Worker local_devices[i] = d;
4670*7688df22SAndroid Build Coastguard Worker i++;
4671*7688df22SAndroid Build Coastguard Worker }
4672*7688df22SAndroid Build Coastguard Worker node_count = i;
4673*7688df22SAndroid Build Coastguard Worker
4674*7688df22SAndroid Build Coastguard Worker drmFoldDuplicatedDevices(local_devices, node_count);
4675*7688df22SAndroid Build Coastguard Worker
4676*7688df22SAndroid Build Coastguard Worker *device = NULL;
4677*7688df22SAndroid Build Coastguard Worker
4678*7688df22SAndroid Build Coastguard Worker for (i = 0; i < node_count; i++) {
4679*7688df22SAndroid Build Coastguard Worker if (!local_devices[i])
4680*7688df22SAndroid Build Coastguard Worker continue;
4681*7688df22SAndroid Build Coastguard Worker
4682*7688df22SAndroid Build Coastguard Worker if (drm_device_has_rdev(local_devices[i], find_rdev))
4683*7688df22SAndroid Build Coastguard Worker *device = local_devices[i];
4684*7688df22SAndroid Build Coastguard Worker else
4685*7688df22SAndroid Build Coastguard Worker drmFreeDevice(&local_devices[i]);
4686*7688df22SAndroid Build Coastguard Worker }
4687*7688df22SAndroid Build Coastguard Worker
4688*7688df22SAndroid Build Coastguard Worker closedir(sysdir);
4689*7688df22SAndroid Build Coastguard Worker if (*device == NULL)
4690*7688df22SAndroid Build Coastguard Worker return -ENODEV;
4691*7688df22SAndroid Build Coastguard Worker return 0;
4692*7688df22SAndroid Build Coastguard Worker #endif
4693*7688df22SAndroid Build Coastguard Worker }
4694*7688df22SAndroid Build Coastguard Worker
drmGetNodeTypeFromDevId(dev_t devid)4695*7688df22SAndroid Build Coastguard Worker drm_public int drmGetNodeTypeFromDevId(dev_t devid)
4696*7688df22SAndroid Build Coastguard Worker {
4697*7688df22SAndroid Build Coastguard Worker int maj, min, node_type;
4698*7688df22SAndroid Build Coastguard Worker
4699*7688df22SAndroid Build Coastguard Worker maj = major(devid);
4700*7688df22SAndroid Build Coastguard Worker min = minor(devid);
4701*7688df22SAndroid Build Coastguard Worker
4702*7688df22SAndroid Build Coastguard Worker if (!drmNodeIsDRM(maj, min))
4703*7688df22SAndroid Build Coastguard Worker return -EINVAL;
4704*7688df22SAndroid Build Coastguard Worker
4705*7688df22SAndroid Build Coastguard Worker node_type = drmGetMinorType(maj, min);
4706*7688df22SAndroid Build Coastguard Worker if (node_type == -1)
4707*7688df22SAndroid Build Coastguard Worker return -ENODEV;
4708*7688df22SAndroid Build Coastguard Worker
4709*7688df22SAndroid Build Coastguard Worker return node_type;
4710*7688df22SAndroid Build Coastguard Worker }
4711*7688df22SAndroid Build Coastguard Worker
4712*7688df22SAndroid Build Coastguard Worker /**
4713*7688df22SAndroid Build Coastguard Worker * Get information about the opened drm device
4714*7688df22SAndroid Build Coastguard Worker *
4715*7688df22SAndroid Build Coastguard Worker * \param fd file descriptor of the drm device
4716*7688df22SAndroid Build Coastguard Worker * \param flags feature/behaviour bitmask
4717*7688df22SAndroid Build Coastguard Worker * \param device the address of a drmDevicePtr where the information
4718*7688df22SAndroid Build Coastguard Worker * will be allocated in stored
4719*7688df22SAndroid Build Coastguard Worker *
4720*7688df22SAndroid Build Coastguard Worker * \return zero on success, negative error code otherwise.
4721*7688df22SAndroid Build Coastguard Worker *
4722*7688df22SAndroid Build Coastguard Worker * \note Unlike drmGetDevice it does not retrieve the pci device revision field
4723*7688df22SAndroid Build Coastguard Worker * unless the DRM_DEVICE_GET_PCI_REVISION \p flag is set.
4724*7688df22SAndroid Build Coastguard Worker */
drmGetDevice2(int fd,uint32_t flags,drmDevicePtr * device)4725*7688df22SAndroid Build Coastguard Worker drm_public int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device)
4726*7688df22SAndroid Build Coastguard Worker {
4727*7688df22SAndroid Build Coastguard Worker struct stat sbuf;
4728*7688df22SAndroid Build Coastguard Worker
4729*7688df22SAndroid Build Coastguard Worker if (fd == -1)
4730*7688df22SAndroid Build Coastguard Worker return -EINVAL;
4731*7688df22SAndroid Build Coastguard Worker
4732*7688df22SAndroid Build Coastguard Worker if (fstat(fd, &sbuf))
4733*7688df22SAndroid Build Coastguard Worker return -errno;
4734*7688df22SAndroid Build Coastguard Worker
4735*7688df22SAndroid Build Coastguard Worker if (!S_ISCHR(sbuf.st_mode))
4736*7688df22SAndroid Build Coastguard Worker return -EINVAL;
4737*7688df22SAndroid Build Coastguard Worker
4738*7688df22SAndroid Build Coastguard Worker return drmGetDeviceFromDevId(sbuf.st_rdev, flags, device);
4739*7688df22SAndroid Build Coastguard Worker }
4740*7688df22SAndroid Build Coastguard Worker
4741*7688df22SAndroid Build Coastguard Worker /**
4742*7688df22SAndroid Build Coastguard Worker * Get information about the opened drm device
4743*7688df22SAndroid Build Coastguard Worker *
4744*7688df22SAndroid Build Coastguard Worker * \param fd file descriptor of the drm device
4745*7688df22SAndroid Build Coastguard Worker * \param device the address of a drmDevicePtr where the information
4746*7688df22SAndroid Build Coastguard Worker * will be allocated in stored
4747*7688df22SAndroid Build Coastguard Worker *
4748*7688df22SAndroid Build Coastguard Worker * \return zero on success, negative error code otherwise.
4749*7688df22SAndroid Build Coastguard Worker */
drmGetDevice(int fd,drmDevicePtr * device)4750*7688df22SAndroid Build Coastguard Worker drm_public int drmGetDevice(int fd, drmDevicePtr *device)
4751*7688df22SAndroid Build Coastguard Worker {
4752*7688df22SAndroid Build Coastguard Worker return drmGetDevice2(fd, DRM_DEVICE_GET_PCI_REVISION, device);
4753*7688df22SAndroid Build Coastguard Worker }
4754*7688df22SAndroid Build Coastguard Worker
4755*7688df22SAndroid Build Coastguard Worker /**
4756*7688df22SAndroid Build Coastguard Worker * Get drm devices on the system
4757*7688df22SAndroid Build Coastguard Worker *
4758*7688df22SAndroid Build Coastguard Worker * \param flags feature/behaviour bitmask
4759*7688df22SAndroid Build Coastguard Worker * \param devices the array of devices with drmDevicePtr elements
4760*7688df22SAndroid Build Coastguard Worker * can be NULL to get the device number first
4761*7688df22SAndroid Build Coastguard Worker * \param max_devices the maximum number of devices for the array
4762*7688df22SAndroid Build Coastguard Worker *
4763*7688df22SAndroid Build Coastguard Worker * \return on error - negative error code,
4764*7688df22SAndroid Build Coastguard Worker * if devices is NULL - total number of devices available on the system,
4765*7688df22SAndroid Build Coastguard Worker * alternatively the number of devices stored in devices[], which is
4766*7688df22SAndroid Build Coastguard Worker * capped by the max_devices.
4767*7688df22SAndroid Build Coastguard Worker *
4768*7688df22SAndroid Build Coastguard Worker * \note Unlike drmGetDevices it does not retrieve the pci device revision field
4769*7688df22SAndroid Build Coastguard Worker * unless the DRM_DEVICE_GET_PCI_REVISION \p flag is set.
4770*7688df22SAndroid Build Coastguard Worker */
drmGetDevices2(uint32_t flags,drmDevicePtr devices[],int max_devices)4771*7688df22SAndroid Build Coastguard Worker drm_public int drmGetDevices2(uint32_t flags, drmDevicePtr devices[],
4772*7688df22SAndroid Build Coastguard Worker int max_devices)
4773*7688df22SAndroid Build Coastguard Worker {
4774*7688df22SAndroid Build Coastguard Worker drmDevicePtr local_devices[MAX_DRM_NODES];
4775*7688df22SAndroid Build Coastguard Worker drmDevicePtr device;
4776*7688df22SAndroid Build Coastguard Worker DIR *sysdir;
4777*7688df22SAndroid Build Coastguard Worker struct dirent *dent;
4778*7688df22SAndroid Build Coastguard Worker int ret, i, node_count, device_count;
4779*7688df22SAndroid Build Coastguard Worker
4780*7688df22SAndroid Build Coastguard Worker if (drm_device_validate_flags(flags))
4781*7688df22SAndroid Build Coastguard Worker return -EINVAL;
4782*7688df22SAndroid Build Coastguard Worker
4783*7688df22SAndroid Build Coastguard Worker sysdir = opendir(DRM_DIR_NAME);
4784*7688df22SAndroid Build Coastguard Worker if (!sysdir)
4785*7688df22SAndroid Build Coastguard Worker return -errno;
4786*7688df22SAndroid Build Coastguard Worker
4787*7688df22SAndroid Build Coastguard Worker i = 0;
4788*7688df22SAndroid Build Coastguard Worker while ((dent = readdir(sysdir))) {
4789*7688df22SAndroid Build Coastguard Worker ret = process_device(&device, dent->d_name, -1, devices != NULL, flags);
4790*7688df22SAndroid Build Coastguard Worker if (ret)
4791*7688df22SAndroid Build Coastguard Worker continue;
4792*7688df22SAndroid Build Coastguard Worker
4793*7688df22SAndroid Build Coastguard Worker if (i >= MAX_DRM_NODES) {
4794*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "More than %d drm nodes detected. "
4795*7688df22SAndroid Build Coastguard Worker "Please report a bug - that should not happen.\n"
4796*7688df22SAndroid Build Coastguard Worker "Skipping extra nodes\n", MAX_DRM_NODES);
4797*7688df22SAndroid Build Coastguard Worker break;
4798*7688df22SAndroid Build Coastguard Worker }
4799*7688df22SAndroid Build Coastguard Worker local_devices[i] = device;
4800*7688df22SAndroid Build Coastguard Worker i++;
4801*7688df22SAndroid Build Coastguard Worker }
4802*7688df22SAndroid Build Coastguard Worker node_count = i;
4803*7688df22SAndroid Build Coastguard Worker
4804*7688df22SAndroid Build Coastguard Worker drmFoldDuplicatedDevices(local_devices, node_count);
4805*7688df22SAndroid Build Coastguard Worker
4806*7688df22SAndroid Build Coastguard Worker device_count = 0;
4807*7688df22SAndroid Build Coastguard Worker for (i = 0; i < node_count; i++) {
4808*7688df22SAndroid Build Coastguard Worker if (!local_devices[i])
4809*7688df22SAndroid Build Coastguard Worker continue;
4810*7688df22SAndroid Build Coastguard Worker
4811*7688df22SAndroid Build Coastguard Worker if ((devices != NULL) && (device_count < max_devices))
4812*7688df22SAndroid Build Coastguard Worker devices[device_count] = local_devices[i];
4813*7688df22SAndroid Build Coastguard Worker else
4814*7688df22SAndroid Build Coastguard Worker drmFreeDevice(&local_devices[i]);
4815*7688df22SAndroid Build Coastguard Worker
4816*7688df22SAndroid Build Coastguard Worker device_count++;
4817*7688df22SAndroid Build Coastguard Worker }
4818*7688df22SAndroid Build Coastguard Worker
4819*7688df22SAndroid Build Coastguard Worker closedir(sysdir);
4820*7688df22SAndroid Build Coastguard Worker
4821*7688df22SAndroid Build Coastguard Worker if (devices != NULL)
4822*7688df22SAndroid Build Coastguard Worker return MIN2(device_count, max_devices);
4823*7688df22SAndroid Build Coastguard Worker
4824*7688df22SAndroid Build Coastguard Worker return device_count;
4825*7688df22SAndroid Build Coastguard Worker }
4826*7688df22SAndroid Build Coastguard Worker
4827*7688df22SAndroid Build Coastguard Worker /**
4828*7688df22SAndroid Build Coastguard Worker * Get drm devices on the system
4829*7688df22SAndroid Build Coastguard Worker *
4830*7688df22SAndroid Build Coastguard Worker * \param devices the array of devices with drmDevicePtr elements
4831*7688df22SAndroid Build Coastguard Worker * can be NULL to get the device number first
4832*7688df22SAndroid Build Coastguard Worker * \param max_devices the maximum number of devices for the array
4833*7688df22SAndroid Build Coastguard Worker *
4834*7688df22SAndroid Build Coastguard Worker * \return on error - negative error code,
4835*7688df22SAndroid Build Coastguard Worker * if devices is NULL - total number of devices available on the system,
4836*7688df22SAndroid Build Coastguard Worker * alternatively the number of devices stored in devices[], which is
4837*7688df22SAndroid Build Coastguard Worker * capped by the max_devices.
4838*7688df22SAndroid Build Coastguard Worker */
drmGetDevices(drmDevicePtr devices[],int max_devices)4839*7688df22SAndroid Build Coastguard Worker drm_public int drmGetDevices(drmDevicePtr devices[], int max_devices)
4840*7688df22SAndroid Build Coastguard Worker {
4841*7688df22SAndroid Build Coastguard Worker return drmGetDevices2(DRM_DEVICE_GET_PCI_REVISION, devices, max_devices);
4842*7688df22SAndroid Build Coastguard Worker }
4843*7688df22SAndroid Build Coastguard Worker
drmGetDeviceNameFromFd2(int fd)4844*7688df22SAndroid Build Coastguard Worker drm_public char *drmGetDeviceNameFromFd2(int fd)
4845*7688df22SAndroid Build Coastguard Worker {
4846*7688df22SAndroid Build Coastguard Worker #ifdef __linux__
4847*7688df22SAndroid Build Coastguard Worker struct stat sbuf;
4848*7688df22SAndroid Build Coastguard Worker char path[PATH_MAX + 1], *value;
4849*7688df22SAndroid Build Coastguard Worker unsigned int maj, min;
4850*7688df22SAndroid Build Coastguard Worker
4851*7688df22SAndroid Build Coastguard Worker if (fstat(fd, &sbuf))
4852*7688df22SAndroid Build Coastguard Worker return NULL;
4853*7688df22SAndroid Build Coastguard Worker
4854*7688df22SAndroid Build Coastguard Worker maj = major(sbuf.st_rdev);
4855*7688df22SAndroid Build Coastguard Worker min = minor(sbuf.st_rdev);
4856*7688df22SAndroid Build Coastguard Worker
4857*7688df22SAndroid Build Coastguard Worker if (!drmNodeIsDRM(maj, min) || !S_ISCHR(sbuf.st_mode))
4858*7688df22SAndroid Build Coastguard Worker return NULL;
4859*7688df22SAndroid Build Coastguard Worker
4860*7688df22SAndroid Build Coastguard Worker snprintf(path, sizeof(path), "/sys/dev/char/%d:%d", maj, min);
4861*7688df22SAndroid Build Coastguard Worker
4862*7688df22SAndroid Build Coastguard Worker value = sysfs_uevent_get(path, "DEVNAME");
4863*7688df22SAndroid Build Coastguard Worker if (!value)
4864*7688df22SAndroid Build Coastguard Worker return NULL;
4865*7688df22SAndroid Build Coastguard Worker
4866*7688df22SAndroid Build Coastguard Worker snprintf(path, sizeof(path), "/dev/%s", value);
4867*7688df22SAndroid Build Coastguard Worker free(value);
4868*7688df22SAndroid Build Coastguard Worker
4869*7688df22SAndroid Build Coastguard Worker return strdup(path);
4870*7688df22SAndroid Build Coastguard Worker #elif defined(__FreeBSD__)
4871*7688df22SAndroid Build Coastguard Worker return drmGetDeviceNameFromFd(fd);
4872*7688df22SAndroid Build Coastguard Worker #else
4873*7688df22SAndroid Build Coastguard Worker struct stat sbuf;
4874*7688df22SAndroid Build Coastguard Worker char node[PATH_MAX + 1];
4875*7688df22SAndroid Build Coastguard Worker const char *dev_name;
4876*7688df22SAndroid Build Coastguard Worker int node_type;
4877*7688df22SAndroid Build Coastguard Worker int maj, min, n;
4878*7688df22SAndroid Build Coastguard Worker
4879*7688df22SAndroid Build Coastguard Worker if (fstat(fd, &sbuf))
4880*7688df22SAndroid Build Coastguard Worker return NULL;
4881*7688df22SAndroid Build Coastguard Worker
4882*7688df22SAndroid Build Coastguard Worker maj = major(sbuf.st_rdev);
4883*7688df22SAndroid Build Coastguard Worker min = minor(sbuf.st_rdev);
4884*7688df22SAndroid Build Coastguard Worker
4885*7688df22SAndroid Build Coastguard Worker if (!drmNodeIsDRM(maj, min) || !S_ISCHR(sbuf.st_mode))
4886*7688df22SAndroid Build Coastguard Worker return NULL;
4887*7688df22SAndroid Build Coastguard Worker
4888*7688df22SAndroid Build Coastguard Worker node_type = drmGetMinorType(maj, min);
4889*7688df22SAndroid Build Coastguard Worker if (node_type == -1)
4890*7688df22SAndroid Build Coastguard Worker return NULL;
4891*7688df22SAndroid Build Coastguard Worker
4892*7688df22SAndroid Build Coastguard Worker dev_name = drmGetDeviceName(node_type);
4893*7688df22SAndroid Build Coastguard Worker if (!dev_name)
4894*7688df22SAndroid Build Coastguard Worker return NULL;
4895*7688df22SAndroid Build Coastguard Worker
4896*7688df22SAndroid Build Coastguard Worker n = snprintf(node, PATH_MAX, dev_name, DRM_DIR_NAME, min);
4897*7688df22SAndroid Build Coastguard Worker if (n == -1 || n >= PATH_MAX)
4898*7688df22SAndroid Build Coastguard Worker return NULL;
4899*7688df22SAndroid Build Coastguard Worker
4900*7688df22SAndroid Build Coastguard Worker return strdup(node);
4901*7688df22SAndroid Build Coastguard Worker #endif
4902*7688df22SAndroid Build Coastguard Worker }
4903*7688df22SAndroid Build Coastguard Worker
drmSyncobjCreate(int fd,uint32_t flags,uint32_t * handle)4904*7688df22SAndroid Build Coastguard Worker drm_public int drmSyncobjCreate(int fd, uint32_t flags, uint32_t *handle)
4905*7688df22SAndroid Build Coastguard Worker {
4906*7688df22SAndroid Build Coastguard Worker struct drm_syncobj_create args;
4907*7688df22SAndroid Build Coastguard Worker int ret;
4908*7688df22SAndroid Build Coastguard Worker
4909*7688df22SAndroid Build Coastguard Worker memclear(args);
4910*7688df22SAndroid Build Coastguard Worker args.flags = flags;
4911*7688df22SAndroid Build Coastguard Worker args.handle = 0;
4912*7688df22SAndroid Build Coastguard Worker ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_CREATE, &args);
4913*7688df22SAndroid Build Coastguard Worker if (ret)
4914*7688df22SAndroid Build Coastguard Worker return ret;
4915*7688df22SAndroid Build Coastguard Worker *handle = args.handle;
4916*7688df22SAndroid Build Coastguard Worker return 0;
4917*7688df22SAndroid Build Coastguard Worker }
4918*7688df22SAndroid Build Coastguard Worker
drmSyncobjDestroy(int fd,uint32_t handle)4919*7688df22SAndroid Build Coastguard Worker drm_public int drmSyncobjDestroy(int fd, uint32_t handle)
4920*7688df22SAndroid Build Coastguard Worker {
4921*7688df22SAndroid Build Coastguard Worker struct drm_syncobj_destroy args;
4922*7688df22SAndroid Build Coastguard Worker
4923*7688df22SAndroid Build Coastguard Worker memclear(args);
4924*7688df22SAndroid Build Coastguard Worker args.handle = handle;
4925*7688df22SAndroid Build Coastguard Worker return drmIoctl(fd, DRM_IOCTL_SYNCOBJ_DESTROY, &args);
4926*7688df22SAndroid Build Coastguard Worker }
4927*7688df22SAndroid Build Coastguard Worker
drmSyncobjHandleToFD(int fd,uint32_t handle,int * obj_fd)4928*7688df22SAndroid Build Coastguard Worker drm_public int drmSyncobjHandleToFD(int fd, uint32_t handle, int *obj_fd)
4929*7688df22SAndroid Build Coastguard Worker {
4930*7688df22SAndroid Build Coastguard Worker struct drm_syncobj_handle args;
4931*7688df22SAndroid Build Coastguard Worker int ret;
4932*7688df22SAndroid Build Coastguard Worker
4933*7688df22SAndroid Build Coastguard Worker memclear(args);
4934*7688df22SAndroid Build Coastguard Worker args.fd = -1;
4935*7688df22SAndroid Build Coastguard Worker args.handle = handle;
4936*7688df22SAndroid Build Coastguard Worker ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD, &args);
4937*7688df22SAndroid Build Coastguard Worker if (ret)
4938*7688df22SAndroid Build Coastguard Worker return ret;
4939*7688df22SAndroid Build Coastguard Worker *obj_fd = args.fd;
4940*7688df22SAndroid Build Coastguard Worker return 0;
4941*7688df22SAndroid Build Coastguard Worker }
4942*7688df22SAndroid Build Coastguard Worker
drmSyncobjFDToHandle(int fd,int obj_fd,uint32_t * handle)4943*7688df22SAndroid Build Coastguard Worker drm_public int drmSyncobjFDToHandle(int fd, int obj_fd, uint32_t *handle)
4944*7688df22SAndroid Build Coastguard Worker {
4945*7688df22SAndroid Build Coastguard Worker struct drm_syncobj_handle args;
4946*7688df22SAndroid Build Coastguard Worker int ret;
4947*7688df22SAndroid Build Coastguard Worker
4948*7688df22SAndroid Build Coastguard Worker memclear(args);
4949*7688df22SAndroid Build Coastguard Worker args.fd = obj_fd;
4950*7688df22SAndroid Build Coastguard Worker args.handle = 0;
4951*7688df22SAndroid Build Coastguard Worker ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE, &args);
4952*7688df22SAndroid Build Coastguard Worker if (ret)
4953*7688df22SAndroid Build Coastguard Worker return ret;
4954*7688df22SAndroid Build Coastguard Worker *handle = args.handle;
4955*7688df22SAndroid Build Coastguard Worker return 0;
4956*7688df22SAndroid Build Coastguard Worker }
4957*7688df22SAndroid Build Coastguard Worker
drmSyncobjImportSyncFile(int fd,uint32_t handle,int sync_file_fd)4958*7688df22SAndroid Build Coastguard Worker drm_public int drmSyncobjImportSyncFile(int fd, uint32_t handle,
4959*7688df22SAndroid Build Coastguard Worker int sync_file_fd)
4960*7688df22SAndroid Build Coastguard Worker {
4961*7688df22SAndroid Build Coastguard Worker struct drm_syncobj_handle args;
4962*7688df22SAndroid Build Coastguard Worker
4963*7688df22SAndroid Build Coastguard Worker memclear(args);
4964*7688df22SAndroid Build Coastguard Worker args.fd = sync_file_fd;
4965*7688df22SAndroid Build Coastguard Worker args.handle = handle;
4966*7688df22SAndroid Build Coastguard Worker args.flags = DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE;
4967*7688df22SAndroid Build Coastguard Worker return drmIoctl(fd, DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE, &args);
4968*7688df22SAndroid Build Coastguard Worker }
4969*7688df22SAndroid Build Coastguard Worker
drmSyncobjExportSyncFile(int fd,uint32_t handle,int * sync_file_fd)4970*7688df22SAndroid Build Coastguard Worker drm_public int drmSyncobjExportSyncFile(int fd, uint32_t handle,
4971*7688df22SAndroid Build Coastguard Worker int *sync_file_fd)
4972*7688df22SAndroid Build Coastguard Worker {
4973*7688df22SAndroid Build Coastguard Worker struct drm_syncobj_handle args;
4974*7688df22SAndroid Build Coastguard Worker int ret;
4975*7688df22SAndroid Build Coastguard Worker
4976*7688df22SAndroid Build Coastguard Worker memclear(args);
4977*7688df22SAndroid Build Coastguard Worker args.fd = -1;
4978*7688df22SAndroid Build Coastguard Worker args.handle = handle;
4979*7688df22SAndroid Build Coastguard Worker args.flags = DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE;
4980*7688df22SAndroid Build Coastguard Worker ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD, &args);
4981*7688df22SAndroid Build Coastguard Worker if (ret)
4982*7688df22SAndroid Build Coastguard Worker return ret;
4983*7688df22SAndroid Build Coastguard Worker *sync_file_fd = args.fd;
4984*7688df22SAndroid Build Coastguard Worker return 0;
4985*7688df22SAndroid Build Coastguard Worker }
4986*7688df22SAndroid Build Coastguard Worker
drmSyncobjWait(int fd,uint32_t * handles,unsigned num_handles,int64_t timeout_nsec,unsigned flags,uint32_t * first_signaled)4987*7688df22SAndroid Build Coastguard Worker drm_public int drmSyncobjWait(int fd, uint32_t *handles, unsigned num_handles,
4988*7688df22SAndroid Build Coastguard Worker int64_t timeout_nsec, unsigned flags,
4989*7688df22SAndroid Build Coastguard Worker uint32_t *first_signaled)
4990*7688df22SAndroid Build Coastguard Worker {
4991*7688df22SAndroid Build Coastguard Worker struct drm_syncobj_wait args;
4992*7688df22SAndroid Build Coastguard Worker int ret;
4993*7688df22SAndroid Build Coastguard Worker
4994*7688df22SAndroid Build Coastguard Worker memclear(args);
4995*7688df22SAndroid Build Coastguard Worker args.handles = (uintptr_t)handles;
4996*7688df22SAndroid Build Coastguard Worker args.timeout_nsec = timeout_nsec;
4997*7688df22SAndroid Build Coastguard Worker args.count_handles = num_handles;
4998*7688df22SAndroid Build Coastguard Worker args.flags = flags;
4999*7688df22SAndroid Build Coastguard Worker
5000*7688df22SAndroid Build Coastguard Worker ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_WAIT, &args);
5001*7688df22SAndroid Build Coastguard Worker if (ret < 0)
5002*7688df22SAndroid Build Coastguard Worker return -errno;
5003*7688df22SAndroid Build Coastguard Worker
5004*7688df22SAndroid Build Coastguard Worker if (first_signaled)
5005*7688df22SAndroid Build Coastguard Worker *first_signaled = args.first_signaled;
5006*7688df22SAndroid Build Coastguard Worker return ret;
5007*7688df22SAndroid Build Coastguard Worker }
5008*7688df22SAndroid Build Coastguard Worker
drmSyncobjReset(int fd,const uint32_t * handles,uint32_t handle_count)5009*7688df22SAndroid Build Coastguard Worker drm_public int drmSyncobjReset(int fd, const uint32_t *handles,
5010*7688df22SAndroid Build Coastguard Worker uint32_t handle_count)
5011*7688df22SAndroid Build Coastguard Worker {
5012*7688df22SAndroid Build Coastguard Worker struct drm_syncobj_array args;
5013*7688df22SAndroid Build Coastguard Worker int ret;
5014*7688df22SAndroid Build Coastguard Worker
5015*7688df22SAndroid Build Coastguard Worker memclear(args);
5016*7688df22SAndroid Build Coastguard Worker args.handles = (uintptr_t)handles;
5017*7688df22SAndroid Build Coastguard Worker args.count_handles = handle_count;
5018*7688df22SAndroid Build Coastguard Worker
5019*7688df22SAndroid Build Coastguard Worker ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_RESET, &args);
5020*7688df22SAndroid Build Coastguard Worker return ret;
5021*7688df22SAndroid Build Coastguard Worker }
5022*7688df22SAndroid Build Coastguard Worker
drmSyncobjSignal(int fd,const uint32_t * handles,uint32_t handle_count)5023*7688df22SAndroid Build Coastguard Worker drm_public int drmSyncobjSignal(int fd, const uint32_t *handles,
5024*7688df22SAndroid Build Coastguard Worker uint32_t handle_count)
5025*7688df22SAndroid Build Coastguard Worker {
5026*7688df22SAndroid Build Coastguard Worker struct drm_syncobj_array args;
5027*7688df22SAndroid Build Coastguard Worker int ret;
5028*7688df22SAndroid Build Coastguard Worker
5029*7688df22SAndroid Build Coastguard Worker memclear(args);
5030*7688df22SAndroid Build Coastguard Worker args.handles = (uintptr_t)handles;
5031*7688df22SAndroid Build Coastguard Worker args.count_handles = handle_count;
5032*7688df22SAndroid Build Coastguard Worker
5033*7688df22SAndroid Build Coastguard Worker ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_SIGNAL, &args);
5034*7688df22SAndroid Build Coastguard Worker return ret;
5035*7688df22SAndroid Build Coastguard Worker }
5036*7688df22SAndroid Build Coastguard Worker
drmSyncobjTimelineSignal(int fd,const uint32_t * handles,uint64_t * points,uint32_t handle_count)5037*7688df22SAndroid Build Coastguard Worker drm_public int drmSyncobjTimelineSignal(int fd, const uint32_t *handles,
5038*7688df22SAndroid Build Coastguard Worker uint64_t *points, uint32_t handle_count)
5039*7688df22SAndroid Build Coastguard Worker {
5040*7688df22SAndroid Build Coastguard Worker struct drm_syncobj_timeline_array args;
5041*7688df22SAndroid Build Coastguard Worker int ret;
5042*7688df22SAndroid Build Coastguard Worker
5043*7688df22SAndroid Build Coastguard Worker memclear(args);
5044*7688df22SAndroid Build Coastguard Worker args.handles = (uintptr_t)handles;
5045*7688df22SAndroid Build Coastguard Worker args.points = (uintptr_t)points;
5046*7688df22SAndroid Build Coastguard Worker args.count_handles = handle_count;
5047*7688df22SAndroid Build Coastguard Worker
5048*7688df22SAndroid Build Coastguard Worker ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL, &args);
5049*7688df22SAndroid Build Coastguard Worker return ret;
5050*7688df22SAndroid Build Coastguard Worker }
5051*7688df22SAndroid Build Coastguard Worker
drmSyncobjTimelineWait(int fd,uint32_t * handles,uint64_t * points,unsigned num_handles,int64_t timeout_nsec,unsigned flags,uint32_t * first_signaled)5052*7688df22SAndroid Build Coastguard Worker drm_public int drmSyncobjTimelineWait(int fd, uint32_t *handles, uint64_t *points,
5053*7688df22SAndroid Build Coastguard Worker unsigned num_handles,
5054*7688df22SAndroid Build Coastguard Worker int64_t timeout_nsec, unsigned flags,
5055*7688df22SAndroid Build Coastguard Worker uint32_t *first_signaled)
5056*7688df22SAndroid Build Coastguard Worker {
5057*7688df22SAndroid Build Coastguard Worker struct drm_syncobj_timeline_wait args;
5058*7688df22SAndroid Build Coastguard Worker int ret;
5059*7688df22SAndroid Build Coastguard Worker
5060*7688df22SAndroid Build Coastguard Worker memclear(args);
5061*7688df22SAndroid Build Coastguard Worker args.handles = (uintptr_t)handles;
5062*7688df22SAndroid Build Coastguard Worker args.points = (uintptr_t)points;
5063*7688df22SAndroid Build Coastguard Worker args.timeout_nsec = timeout_nsec;
5064*7688df22SAndroid Build Coastguard Worker args.count_handles = num_handles;
5065*7688df22SAndroid Build Coastguard Worker args.flags = flags;
5066*7688df22SAndroid Build Coastguard Worker
5067*7688df22SAndroid Build Coastguard Worker ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT, &args);
5068*7688df22SAndroid Build Coastguard Worker if (ret < 0)
5069*7688df22SAndroid Build Coastguard Worker return -errno;
5070*7688df22SAndroid Build Coastguard Worker
5071*7688df22SAndroid Build Coastguard Worker if (first_signaled)
5072*7688df22SAndroid Build Coastguard Worker *first_signaled = args.first_signaled;
5073*7688df22SAndroid Build Coastguard Worker return ret;
5074*7688df22SAndroid Build Coastguard Worker }
5075*7688df22SAndroid Build Coastguard Worker
5076*7688df22SAndroid Build Coastguard Worker
drmSyncobjQuery(int fd,uint32_t * handles,uint64_t * points,uint32_t handle_count)5077*7688df22SAndroid Build Coastguard Worker drm_public int drmSyncobjQuery(int fd, uint32_t *handles, uint64_t *points,
5078*7688df22SAndroid Build Coastguard Worker uint32_t handle_count)
5079*7688df22SAndroid Build Coastguard Worker {
5080*7688df22SAndroid Build Coastguard Worker struct drm_syncobj_timeline_array args;
5081*7688df22SAndroid Build Coastguard Worker int ret;
5082*7688df22SAndroid Build Coastguard Worker
5083*7688df22SAndroid Build Coastguard Worker memclear(args);
5084*7688df22SAndroid Build Coastguard Worker args.handles = (uintptr_t)handles;
5085*7688df22SAndroid Build Coastguard Worker args.points = (uintptr_t)points;
5086*7688df22SAndroid Build Coastguard Worker args.count_handles = handle_count;
5087*7688df22SAndroid Build Coastguard Worker
5088*7688df22SAndroid Build Coastguard Worker ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_QUERY, &args);
5089*7688df22SAndroid Build Coastguard Worker if (ret)
5090*7688df22SAndroid Build Coastguard Worker return ret;
5091*7688df22SAndroid Build Coastguard Worker return 0;
5092*7688df22SAndroid Build Coastguard Worker }
5093*7688df22SAndroid Build Coastguard Worker
drmSyncobjQuery2(int fd,uint32_t * handles,uint64_t * points,uint32_t handle_count,uint32_t flags)5094*7688df22SAndroid Build Coastguard Worker drm_public int drmSyncobjQuery2(int fd, uint32_t *handles, uint64_t *points,
5095*7688df22SAndroid Build Coastguard Worker uint32_t handle_count, uint32_t flags)
5096*7688df22SAndroid Build Coastguard Worker {
5097*7688df22SAndroid Build Coastguard Worker struct drm_syncobj_timeline_array args;
5098*7688df22SAndroid Build Coastguard Worker
5099*7688df22SAndroid Build Coastguard Worker memclear(args);
5100*7688df22SAndroid Build Coastguard Worker args.handles = (uintptr_t)handles;
5101*7688df22SAndroid Build Coastguard Worker args.points = (uintptr_t)points;
5102*7688df22SAndroid Build Coastguard Worker args.count_handles = handle_count;
5103*7688df22SAndroid Build Coastguard Worker args.flags = flags;
5104*7688df22SAndroid Build Coastguard Worker
5105*7688df22SAndroid Build Coastguard Worker return drmIoctl(fd, DRM_IOCTL_SYNCOBJ_QUERY, &args);
5106*7688df22SAndroid Build Coastguard Worker }
5107*7688df22SAndroid Build Coastguard Worker
5108*7688df22SAndroid Build Coastguard Worker
drmSyncobjTransfer(int fd,uint32_t dst_handle,uint64_t dst_point,uint32_t src_handle,uint64_t src_point,uint32_t flags)5109*7688df22SAndroid Build Coastguard Worker drm_public int drmSyncobjTransfer(int fd,
5110*7688df22SAndroid Build Coastguard Worker uint32_t dst_handle, uint64_t dst_point,
5111*7688df22SAndroid Build Coastguard Worker uint32_t src_handle, uint64_t src_point,
5112*7688df22SAndroid Build Coastguard Worker uint32_t flags)
5113*7688df22SAndroid Build Coastguard Worker {
5114*7688df22SAndroid Build Coastguard Worker struct drm_syncobj_transfer args;
5115*7688df22SAndroid Build Coastguard Worker int ret;
5116*7688df22SAndroid Build Coastguard Worker
5117*7688df22SAndroid Build Coastguard Worker memclear(args);
5118*7688df22SAndroid Build Coastguard Worker args.src_handle = src_handle;
5119*7688df22SAndroid Build Coastguard Worker args.dst_handle = dst_handle;
5120*7688df22SAndroid Build Coastguard Worker args.src_point = src_point;
5121*7688df22SAndroid Build Coastguard Worker args.dst_point = dst_point;
5122*7688df22SAndroid Build Coastguard Worker args.flags = flags;
5123*7688df22SAndroid Build Coastguard Worker
5124*7688df22SAndroid Build Coastguard Worker ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_TRANSFER, &args);
5125*7688df22SAndroid Build Coastguard Worker
5126*7688df22SAndroid Build Coastguard Worker return ret;
5127*7688df22SAndroid Build Coastguard Worker }
5128*7688df22SAndroid Build Coastguard Worker
drmSyncobjEventfd(int fd,uint32_t handle,uint64_t point,int ev_fd,uint32_t flags)5129*7688df22SAndroid Build Coastguard Worker drm_public int drmSyncobjEventfd(int fd, uint32_t handle, uint64_t point, int ev_fd,
5130*7688df22SAndroid Build Coastguard Worker uint32_t flags)
5131*7688df22SAndroid Build Coastguard Worker {
5132*7688df22SAndroid Build Coastguard Worker struct drm_syncobj_eventfd args;
5133*7688df22SAndroid Build Coastguard Worker
5134*7688df22SAndroid Build Coastguard Worker memclear(args);
5135*7688df22SAndroid Build Coastguard Worker args.handle = handle;
5136*7688df22SAndroid Build Coastguard Worker args.point = point;
5137*7688df22SAndroid Build Coastguard Worker args.fd = ev_fd;
5138*7688df22SAndroid Build Coastguard Worker args.flags = flags;
5139*7688df22SAndroid Build Coastguard Worker
5140*7688df22SAndroid Build Coastguard Worker return drmIoctl(fd, DRM_IOCTL_SYNCOBJ_EVENTFD, &args);
5141*7688df22SAndroid Build Coastguard Worker }
5142*7688df22SAndroid Build Coastguard Worker
5143*7688df22SAndroid Build Coastguard Worker static char *
drmGetFormatModifierFromSimpleTokens(uint64_t modifier)5144*7688df22SAndroid Build Coastguard Worker drmGetFormatModifierFromSimpleTokens(uint64_t modifier)
5145*7688df22SAndroid Build Coastguard Worker {
5146*7688df22SAndroid Build Coastguard Worker unsigned int i;
5147*7688df22SAndroid Build Coastguard Worker
5148*7688df22SAndroid Build Coastguard Worker for (i = 0; i < ARRAY_SIZE(drm_format_modifier_table); i++) {
5149*7688df22SAndroid Build Coastguard Worker if (drm_format_modifier_table[i].modifier == modifier)
5150*7688df22SAndroid Build Coastguard Worker return strdup(drm_format_modifier_table[i].modifier_name);
5151*7688df22SAndroid Build Coastguard Worker }
5152*7688df22SAndroid Build Coastguard Worker
5153*7688df22SAndroid Build Coastguard Worker return NULL;
5154*7688df22SAndroid Build Coastguard Worker }
5155*7688df22SAndroid Build Coastguard Worker
5156*7688df22SAndroid Build Coastguard Worker /** Retrieves a human-readable representation of a vendor (as a string) from
5157*7688df22SAndroid Build Coastguard Worker * the format token modifier
5158*7688df22SAndroid Build Coastguard Worker *
5159*7688df22SAndroid Build Coastguard Worker * \param modifier the format modifier token
5160*7688df22SAndroid Build Coastguard Worker * \return a char pointer to the human-readable form of the vendor. Caller is
5161*7688df22SAndroid Build Coastguard Worker * responsible for freeing it.
5162*7688df22SAndroid Build Coastguard Worker */
5163*7688df22SAndroid Build Coastguard Worker drm_public char *
drmGetFormatModifierVendor(uint64_t modifier)5164*7688df22SAndroid Build Coastguard Worker drmGetFormatModifierVendor(uint64_t modifier)
5165*7688df22SAndroid Build Coastguard Worker {
5166*7688df22SAndroid Build Coastguard Worker unsigned int i;
5167*7688df22SAndroid Build Coastguard Worker uint8_t vendor = fourcc_mod_get_vendor(modifier);
5168*7688df22SAndroid Build Coastguard Worker
5169*7688df22SAndroid Build Coastguard Worker for (i = 0; i < ARRAY_SIZE(drm_format_modifier_vendor_table); i++) {
5170*7688df22SAndroid Build Coastguard Worker if (drm_format_modifier_vendor_table[i].vendor == vendor)
5171*7688df22SAndroid Build Coastguard Worker return strdup(drm_format_modifier_vendor_table[i].vendor_name);
5172*7688df22SAndroid Build Coastguard Worker }
5173*7688df22SAndroid Build Coastguard Worker
5174*7688df22SAndroid Build Coastguard Worker return NULL;
5175*7688df22SAndroid Build Coastguard Worker }
5176*7688df22SAndroid Build Coastguard Worker
5177*7688df22SAndroid Build Coastguard Worker /** Retrieves a human-readable representation string from a format token
5178*7688df22SAndroid Build Coastguard Worker * modifier
5179*7688df22SAndroid Build Coastguard Worker *
5180*7688df22SAndroid Build Coastguard Worker * If the dedicated function was not able to extract a valid name or searching
5181*7688df22SAndroid Build Coastguard Worker * the format modifier was not in the table, this function would return NULL.
5182*7688df22SAndroid Build Coastguard Worker *
5183*7688df22SAndroid Build Coastguard Worker * \param modifier the token format
5184*7688df22SAndroid Build Coastguard Worker * \return a malloc'ed string representation of the modifier. Caller is
5185*7688df22SAndroid Build Coastguard Worker * responsible for freeing the string returned.
5186*7688df22SAndroid Build Coastguard Worker *
5187*7688df22SAndroid Build Coastguard Worker */
5188*7688df22SAndroid Build Coastguard Worker drm_public char *
drmGetFormatModifierName(uint64_t modifier)5189*7688df22SAndroid Build Coastguard Worker drmGetFormatModifierName(uint64_t modifier)
5190*7688df22SAndroid Build Coastguard Worker {
5191*7688df22SAndroid Build Coastguard Worker uint8_t vendorid = fourcc_mod_get_vendor(modifier);
5192*7688df22SAndroid Build Coastguard Worker char *modifier_found = NULL;
5193*7688df22SAndroid Build Coastguard Worker unsigned int i;
5194*7688df22SAndroid Build Coastguard Worker
5195*7688df22SAndroid Build Coastguard Worker for (i = 0; i < ARRAY_SIZE(modifier_format_vendor_table); i++) {
5196*7688df22SAndroid Build Coastguard Worker if (modifier_format_vendor_table[i].vendor == vendorid)
5197*7688df22SAndroid Build Coastguard Worker modifier_found = modifier_format_vendor_table[i].vendor_cb(modifier);
5198*7688df22SAndroid Build Coastguard Worker }
5199*7688df22SAndroid Build Coastguard Worker
5200*7688df22SAndroid Build Coastguard Worker if (!modifier_found)
5201*7688df22SAndroid Build Coastguard Worker return drmGetFormatModifierFromSimpleTokens(modifier);
5202*7688df22SAndroid Build Coastguard Worker
5203*7688df22SAndroid Build Coastguard Worker return modifier_found;
5204*7688df22SAndroid Build Coastguard Worker }
5205*7688df22SAndroid Build Coastguard Worker
5206*7688df22SAndroid Build Coastguard Worker /**
5207*7688df22SAndroid Build Coastguard Worker * Get a human-readable name for a DRM FourCC format.
5208*7688df22SAndroid Build Coastguard Worker *
5209*7688df22SAndroid Build Coastguard Worker * \param format The format.
5210*7688df22SAndroid Build Coastguard Worker * \return A malloc'ed string containing the format name. Caller is responsible
5211*7688df22SAndroid Build Coastguard Worker * for freeing it.
5212*7688df22SAndroid Build Coastguard Worker */
5213*7688df22SAndroid Build Coastguard Worker drm_public char *
drmGetFormatName(uint32_t format)5214*7688df22SAndroid Build Coastguard Worker drmGetFormatName(uint32_t format)
5215*7688df22SAndroid Build Coastguard Worker {
5216*7688df22SAndroid Build Coastguard Worker char *str, code[5];
5217*7688df22SAndroid Build Coastguard Worker const char *be;
5218*7688df22SAndroid Build Coastguard Worker size_t str_size, i;
5219*7688df22SAndroid Build Coastguard Worker
5220*7688df22SAndroid Build Coastguard Worker be = (format & DRM_FORMAT_BIG_ENDIAN) ? "_BE" : "";
5221*7688df22SAndroid Build Coastguard Worker format &= ~DRM_FORMAT_BIG_ENDIAN;
5222*7688df22SAndroid Build Coastguard Worker
5223*7688df22SAndroid Build Coastguard Worker if (format == DRM_FORMAT_INVALID)
5224*7688df22SAndroid Build Coastguard Worker return strdup("INVALID");
5225*7688df22SAndroid Build Coastguard Worker
5226*7688df22SAndroid Build Coastguard Worker code[0] = (char) ((format >> 0) & 0xFF);
5227*7688df22SAndroid Build Coastguard Worker code[1] = (char) ((format >> 8) & 0xFF);
5228*7688df22SAndroid Build Coastguard Worker code[2] = (char) ((format >> 16) & 0xFF);
5229*7688df22SAndroid Build Coastguard Worker code[3] = (char) ((format >> 24) & 0xFF);
5230*7688df22SAndroid Build Coastguard Worker code[4] = '\0';
5231*7688df22SAndroid Build Coastguard Worker
5232*7688df22SAndroid Build Coastguard Worker /* Trim spaces at the end */
5233*7688df22SAndroid Build Coastguard Worker for (i = 3; i > 0 && code[i] == ' '; i--)
5234*7688df22SAndroid Build Coastguard Worker code[i] = '\0';
5235*7688df22SAndroid Build Coastguard Worker
5236*7688df22SAndroid Build Coastguard Worker str_size = strlen(code) + strlen(be) + 1;
5237*7688df22SAndroid Build Coastguard Worker str = malloc(str_size);
5238*7688df22SAndroid Build Coastguard Worker if (!str)
5239*7688df22SAndroid Build Coastguard Worker return NULL;
5240*7688df22SAndroid Build Coastguard Worker
5241*7688df22SAndroid Build Coastguard Worker snprintf(str, str_size, "%s%s", code, be);
5242*7688df22SAndroid Build Coastguard Worker
5243*7688df22SAndroid Build Coastguard Worker return str;
5244*7688df22SAndroid Build Coastguard Worker }
5245