1/***************************************************************************
2
3 Copyright 2013 Intel Corporation.  All Rights Reserved.
4
5 Permission is hereby granted, free of charge, to any person obtaining a
6 copy of this software and associated documentation files (the
7 "Software"), to deal in the Software without restriction, including
8 without limitation the rights to use, copy, modify, merge, publish,
9 distribute, sub license, and/or sell copies of the Software, and to
10 permit persons to whom the Software is furnished to do so, subject to
11 the following conditions:
12
13 The above copyright notice and this permission notice (including the
14 next paragraph) shall be included in all copies or substantial portions
15 of the Software.
16
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
20 IN NO EVENT SHALL INTEL, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
21 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
23 THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
25 **************************************************************************/
26
27#ifdef HAVE_CONFIG_H
28#include "config.h"
29#endif
30
31#include <sys/types.h>
32#include <sys/stat.h>
33#include <assert.h>
34#include <string.h>
35#include <unistd.h>
36#include <fcntl.h>
37#include <stdlib.h>
38#include <dirent.h>
39#include <errno.h>
40
41#if MAJOR_IN_MKDEV
42#include <sys/mkdev.h>
43#elif MAJOR_IN_SYSMACROS
44#include <sys/sysmacros.h>
45#endif
46
47#include <pciaccess.h>
48
49#include <xorg-server.h>
50#include <xf86.h>
51#include <xf86drm.h>
52#include <xf86drmMode.h>
53#include <xf86_OSproc.h>
54#include <i915_drm.h>
55
56#ifdef XSERVER_PLATFORM_BUS
57#include <xf86platformBus.h>
58#endif
59
60#ifdef HAVE_VALGRIND
61#include <valgrind.h>
62#include <memcheck.h>
63#define VG(x) x
64#else
65#define VG(x)
66#endif
67
68#define VG_CLEAR(s) VG(memset(&s, 0, sizeof(s)))
69
70#include "intel_driver.h"
71#include "fd.h"
72
73struct intel_device {
74	int idx;
75	char *master_node;
76	char *render_node;
77	int fd;
78	int device_id;
79	int open_count;
80	int master_count;
81};
82
83static int intel_device_key = -1;
84
85static int dump_file(ScrnInfoPtr scrn, const char *path)
86{
87	FILE *file;
88	size_t len = 0;
89	char *line = NULL;
90
91	file = fopen(path, "r");
92	if (file == NULL)
93		return 0;
94
95	xf86DrvMsg(scrn->scrnIndex, X_INFO, "[drm] Contents of '%s':\n", path);
96	while (getline(&line, &len, file) != -1)
97		xf86DrvMsg(scrn->scrnIndex, X_INFO, "[drm] %s", line);
98
99	free(line);
100	fclose(file);
101	return 1;
102}
103
104static int __find_debugfs(void)
105{
106	int i;
107
108	for (i = 0; i < DRM_MAX_MINOR; i++) {
109		char path[80];
110
111		sprintf(path, "/sys/kernel/debug/dri/%d/i915_wedged", i);
112		if (access(path, R_OK) == 0)
113			return i;
114
115		sprintf(path, "/debug/dri/%d/i915_wedged", i);
116		if (access(path, R_OK) == 0)
117			return i;
118	}
119
120	return -1;
121}
122
123static int drm_get_minor(int fd)
124{
125	struct stat st;
126
127	if (fstat(fd, &st))
128		return __find_debugfs();
129
130	if (!S_ISCHR(st.st_mode))
131		return __find_debugfs();
132
133	return st.st_rdev & 0x63;
134}
135
136#if __linux__
137#include <sys/mount.h>
138
139static void dump_debugfs(ScrnInfoPtr scrn, int fd, const char *name)
140{
141	char path[80];
142	int minor;
143
144	minor = drm_get_minor(fd);
145	if (minor < 0)
146		return;
147
148	sprintf(path, "/sys/kernel/debug/dri/%d/%s", minor, name);
149	if (dump_file(scrn, path))
150		return;
151
152	sprintf(path, "/debug/dri/%d/%s", minor, name);
153	if (dump_file(scrn, path))
154		return;
155
156	if (mount("X-debug", "/sys/kernel/debug", "debugfs", 0, 0) == 0) {
157		sprintf(path, "/sys/kernel/debug/dri/%d/%s", minor, name);
158		dump_file(scrn, path);
159		umount("X-debug");
160		return;
161	}
162}
163#else
164static void dump_debugfs(ScrnInfoPtr scrn, int fd, const char *name) { }
165#endif
166
167static void dump_clients_info(ScrnInfoPtr scrn, int fd)
168{
169	dump_debugfs(scrn, fd, "clients");
170}
171
172static int __intel_get_device_id(int fd)
173{
174	struct drm_i915_getparam gp;
175	int devid = 0;
176
177	VG_CLEAR(gp);
178	gp.param = I915_PARAM_CHIPSET_ID;
179	gp.value = &devid;
180
181	if (drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp))
182		return 0;
183
184	return devid;
185}
186
187int intel_entity_get_devid(int idx)
188{
189	struct intel_device *dev;
190
191	dev = xf86GetEntityPrivate(idx, intel_device_key)->ptr;
192	if (dev == NULL)
193		return 0;
194
195	return dev->device_id;
196}
197
198static inline struct intel_device *intel_device(ScrnInfoPtr scrn)
199{
200	if (scrn->entityList == NULL)
201		return NULL;
202
203	return xf86GetEntityPrivate(scrn->entityList[0], intel_device_key)->ptr;
204}
205
206static const char *kernel_module_names[] ={
207	"i915",
208	NULL,
209};
210
211static int is_i915_device(int fd)
212{
213	drm_version_t version;
214	const char **kn;
215	char name[5] = "";
216
217	memset(&version, 0, sizeof(version));
218	version.name_len = 4;
219	version.name = name;
220
221	if (drmIoctl(fd, DRM_IOCTL_VERSION, &version))
222		return 0;
223
224	for (kn = kernel_module_names; *kn; kn++)
225		if (strcmp(*kn, name) == 0)
226			return 1;
227
228	return 0;
229}
230
231static int load_i915_kernel_module(void)
232{
233	const char **kn;
234
235	for (kn = kernel_module_names; *kn; kn++)
236		if (xf86LoadKernelModule(*kn))
237			return 0;
238
239	return -1;
240}
241
242static int is_i915_gem(int fd)
243{
244	int ret = is_i915_device(fd);
245
246	if (ret) {
247		struct drm_i915_getparam gp;
248
249		VG_CLEAR(gp);
250		gp.param = I915_PARAM_HAS_GEM;
251		gp.value = &ret;
252
253		if (drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp))
254			ret = 0;
255	}
256
257	return ret;
258}
259
260static int __intel_check_device(int fd)
261{
262	int ret;
263
264	/* Confirm that this is a i915.ko device with GEM/KMS enabled */
265	ret = is_i915_gem(fd);
266	if (ret && !hosted()) {
267		struct drm_mode_card_res res;
268
269		memset(&res, 0, sizeof(res));
270		if (drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res))
271			ret = 0;
272	}
273
274	return ret;
275}
276
277static int open_cloexec(const char *path)
278{
279	struct stat st;
280	int loop = 1000;
281	int fd;
282
283	/* No file? Assume the driver is loading slowly */
284	while (stat(path, &st) == -1 && errno == ENOENT && --loop)
285		usleep(50000);
286
287	if (loop != 1000)
288		ErrorF("intel: waited %d ms for '%s' to appear\n",
289		       (1000 - loop) * 50, path);
290
291	fd = -1;
292#ifdef O_CLOEXEC
293	fd = open(path, O_RDWR | O_NONBLOCK | O_CLOEXEC);
294#endif
295	if (fd == -1)
296		fd = fd_set_cloexec(open(path, O_RDWR | O_NONBLOCK));
297
298	return fd;
299}
300
301#ifdef __linux__
302static int __intel_open_device__major_minor(int _major, int _minor)
303{
304	char path[256];
305	DIR *dir;
306	struct dirent *de;
307	int base, fd = -1;
308
309	base = sprintf(path, "/dev/dri/");
310
311	dir = opendir(path);
312	if (dir == NULL)
313		return -1;
314
315	while ((de = readdir(dir)) != NULL) {
316		struct stat st;
317
318		if (*de->d_name == '.')
319			continue;
320
321		sprintf(path + base, "%s", de->d_name);
322		if (stat(path, &st) == 0 &&
323		    major(st.st_rdev) == _major &&
324		    minor(st.st_rdev) == _minor) {
325			fd = open_cloexec(path);
326			break;
327		}
328	}
329
330	closedir(dir);
331
332	return fd;
333}
334
335static int __intel_open_device__pci(const struct pci_device *pci)
336{
337	struct stat st;
338	char path[256];
339	DIR *dir;
340	struct dirent *de;
341	int base;
342	int fd;
343
344	/* Look up the major:minor for the drm device through sysfs.
345	 * First we need to check that sysfs is available, then
346	 * check that we have loaded our driver. When we are happy
347	 * that our KMS module is loaded, we can then search for our
348	 * device node. We make the assumption that it uses the same
349	 * name, but after that we read the major:minor assigned to us
350	 * and search for a matching entry in /dev.
351	 */
352
353	base = sprintf(path,
354		       "/sys/bus/pci/devices/%04x:%02x:%02x.%d/",
355		       pci->domain, pci->bus, pci->dev, pci->func);
356	if (stat(path, &st))
357		return -1;
358
359	sprintf(path + base, "drm");
360	dir = opendir(path);
361	if (dir == NULL) {
362		int loop = 0;
363
364		sprintf(path + base, "driver");
365		if (stat(path, &st)) {
366			if (load_i915_kernel_module())
367				return -1;
368			(void)xf86LoadKernelModule("fbcon");
369		}
370
371		sprintf(path + base, "drm");
372		while ((dir = opendir(path)) == NULL && loop++ < 100)
373			usleep(20000);
374
375		ErrorF("intel: waited %d ms for i915.ko driver to load\n", loop * 20000 / 1000);
376
377		if (dir == NULL)
378			return -1;
379	}
380
381	fd = -1;
382	while ((de = readdir(dir)) != NULL) {
383		if (*de->d_name == '.')
384			continue;
385
386		if (strncmp(de->d_name, "card", 4) == 0) {
387			sprintf(path + base + 4, "/dev/dri/%s", de->d_name);
388			fd = open_cloexec(path + base + 4);
389			if (fd != -1)
390				break;
391
392			sprintf(path + base + 3, "/%s/dev", de->d_name);
393			fd = open(path, O_RDONLY);
394			if (fd == -1)
395				break;
396
397			base = read(fd, path, sizeof(path) - 1);
398			close(fd);
399
400			fd = -1;
401			if (base > 0) {
402				int major, minor;
403				path[base] = '\0';
404				if (sscanf(path, "%d:%d", &major, &minor) == 2)
405					fd = __intel_open_device__major_minor(major, minor);
406			}
407			break;
408		}
409	}
410	closedir(dir);
411
412	return fd;
413}
414#else
415static int __intel_open_device__pci(const struct pci_device *pci) { return -1; }
416#endif
417
418static int __intel_open_device__legacy(const struct pci_device *pci)
419{
420	char id[20];
421	int ret;
422
423	snprintf(id, sizeof(id),
424		 "pci:%04x:%02x:%02x.%d",
425		 pci->domain, pci->bus, pci->dev, pci->func);
426
427	ret = drmCheckModesettingSupported(id);
428	if (ret) {
429		if (load_i915_kernel_module() == 0)
430			ret = drmCheckModesettingSupported(id);
431		if (ret)
432			return -1;
433		/* Be nice to the user and load fbcon too */
434		(void)xf86LoadKernelModule("fbcon");
435	}
436
437	return fd_set_nonblock(drmOpen(NULL, id));
438}
439
440static int __intel_open_device(const struct pci_device *pci, const char *path)
441{
442	int fd;
443
444	if (path == NULL) {
445		if (pci == NULL)
446			return -1;
447
448		fd = __intel_open_device__pci(pci);
449		if (fd == -1)
450			fd = __intel_open_device__legacy(pci);
451	} else
452		fd = open_cloexec(path);
453
454	return fd;
455}
456
457static char *find_master_node(int fd)
458{
459	struct stat st, master;
460	char buf[128];
461
462	if (fstat(fd, &st))
463		return NULL;
464
465	if (!S_ISCHR(st.st_mode))
466		return NULL;
467
468	sprintf(buf, "/dev/dri/card%d", (int)(st.st_rdev & 0x7f));
469	if (stat(buf, &master) == 0 &&
470	    S_ISCHR(master.st_mode) &&
471	    (st.st_rdev & 0x7f) == master.st_rdev)
472		return strdup(buf);
473
474	/* Fallback to iterating over the usual suspects */
475	return drmGetDeviceNameFromFd(fd);
476}
477
478static int is_render_node(int fd, struct stat *st)
479{
480	if (fstat(fd, st))
481		return -1;
482
483	if (!S_ISCHR(st->st_mode))
484		return -1;
485
486	return st->st_rdev & 0x80;
487}
488
489static char *find_render_node(int fd)
490{
491	struct stat master, render;
492	char buf[128];
493	int i;
494
495	/* Are we a render-node ourselves? */
496	if (is_render_node(fd, &master))
497		return NULL;
498
499	sprintf(buf, "/dev/dri/renderD%d", (int)((master.st_rdev | 0x80) & 0xbf));
500	if (stat(buf, &render) == 0 &&
501	    S_ISCHR(render.st_mode) &&
502	    render.st_rdev == (master.st_rdev | 0x80))
503		return strdup(buf);
504
505	/* Misaligned card <-> renderD, do a full search */
506	for (i = 0; i < 16; i++) {
507		sprintf(buf, "/dev/dri/renderD%d", i + 128);
508		if (stat(buf, &render) == 0 &&
509		    S_ISCHR(render.st_mode) &&
510		    render.st_rdev == (master.st_rdev | 0x80))
511			return strdup(buf);
512	}
513
514	return NULL;
515}
516
517#if defined(ODEV_ATTRIB_PATH)
518static char *get_path(struct xf86_platform_device *dev)
519{
520	const char *path;
521
522	if (dev == NULL)
523		return NULL;
524
525	path = xf86_get_platform_device_attrib(dev, ODEV_ATTRIB_PATH);
526	if (path == NULL)
527		return NULL;
528
529	return strdup(path);
530}
531
532#else
533
534static char *get_path(struct xf86_platform_device *dev)
535{
536	return NULL;
537}
538#endif
539
540
541#if defined(ODEV_ATTRIB_FD)
542static int get_fd(struct xf86_platform_device *dev)
543{
544	if (dev == NULL)
545		return -1;
546
547	return xf86_get_platform_device_int_attrib(dev, ODEV_ATTRIB_FD, -1);
548}
549
550#else
551
552static int get_fd(struct xf86_platform_device *dev)
553{
554	return -1;
555}
556#endif
557
558static int is_master(int fd)
559{
560	drmSetVersion sv;
561
562	sv.drm_di_major = 1;
563	sv.drm_di_minor = 1;
564	sv.drm_dd_major = -1;
565	sv.drm_dd_minor = -1;
566
567	return drmIoctl(fd, DRM_IOCTL_SET_VERSION, &sv) == 0;
568}
569
570int intel_open_device(int entity_num,
571		      const struct pci_device *pci,
572		      struct xf86_platform_device *platform)
573{
574	struct intel_device *dev;
575	char *path;
576	int fd, master_count;
577
578	if (intel_device_key == -1)
579		intel_device_key = xf86AllocateEntityPrivateIndex();
580	if (intel_device_key == -1)
581		return -1;
582
583	dev = xf86GetEntityPrivate(entity_num, intel_device_key)->ptr;
584	if (dev)
585		return dev->fd;
586
587	path = get_path(platform);
588
589	master_count = 1; /* DRM_MASTER is managed by Xserver */
590	fd = get_fd(platform);
591	if (fd == -1) {
592		fd = __intel_open_device(pci, path);
593		if (fd == -1)
594			goto err_path;
595
596		master_count = 0;
597	}
598
599	if (path == NULL) {
600		path = find_master_node(fd);
601		if (path == NULL)
602			goto err_close;
603	}
604
605	if (!__intel_check_device(fd))
606		goto err_close;
607
608	dev = malloc(sizeof(*dev));
609	if (dev == NULL)
610		goto err_close;
611
612	/* If hosted under a system compositor, just pretend to be master */
613	if (hosted())
614		master_count++;
615
616	/* Non-root user holding MASTER, don't let go */
617	if (geteuid() && is_master(fd))
618		master_count++;
619
620	if (pci)
621		dev->device_id = pci->device_id;
622	else
623		dev->device_id = __intel_get_device_id(fd);
624
625	dev->idx = entity_num;
626	dev->fd = fd;
627	dev->open_count = master_count;
628	dev->master_count = master_count;
629	dev->master_node = path;
630	dev->render_node = find_render_node(fd);
631	if (dev->render_node == NULL)
632		dev->render_node = dev->master_node;
633
634	xf86GetEntityPrivate(entity_num, intel_device_key)->ptr = dev;
635
636	return fd;
637
638err_close:
639	if (master_count == 0) /* Don't close server-fds */
640		close(fd);
641err_path:
642	free(path);
643	return -1;
644}
645
646void intel_close_device(int entity_num)
647{
648	struct intel_device *dev;
649
650	if (intel_device_key == -1)
651		return;
652
653	dev = xf86GetEntityPrivate(entity_num, intel_device_key)->ptr;
654	xf86GetEntityPrivate(entity_num, intel_device_key)->ptr = NULL;
655	if (!dev)
656		return;
657
658	if (dev->master_count == 0) /* Don't close server-fds */
659		close(dev->fd);
660
661	if (dev->render_node != dev->master_node)
662		free(dev->render_node);
663	free(dev->master_node);
664	free(dev);
665}
666
667int __intel_peek_fd(ScrnInfoPtr scrn)
668{
669	struct intel_device *dev;
670
671	dev = intel_device(scrn);
672	assert(dev && dev->fd != -1);
673
674	return dev->fd;
675}
676
677int intel_has_render_node(struct intel_device *dev)
678{
679	struct stat st;
680
681	assert(dev && dev->fd != -1);
682	return is_render_node(dev->fd, &st);
683}
684
685struct intel_device *intel_get_device(ScrnInfoPtr scrn, int *fd)
686{
687	struct intel_device *dev;
688	int ret;
689
690	dev = intel_device(scrn);
691	if (dev == NULL)
692		return NULL;
693
694	assert(dev->fd != -1);
695
696	if (dev->open_count++ == 0) {
697		drmSetVersion sv;
698		int retry = 2000;
699
700		assert(!hosted());
701
702		/* Check that what we opened was a master or a
703		 * master-capable FD, by setting the version of the
704		 * interface we'll use to talk to it.
705		 */
706		do {
707			sv.drm_di_major = 1;
708			sv.drm_di_minor = 1;
709			sv.drm_dd_major = -1;
710			sv.drm_dd_minor = -1;
711			ret = drmIoctl(dev->fd, DRM_IOCTL_SET_VERSION, &sv);
712			if (ret == 0)
713				break;
714
715			usleep(1000);
716		} while (--retry);
717		if (ret != 0) {
718			xf86DrvMsg(scrn->scrnIndex, X_ERROR,
719				   "[drm] failed to set drm interface version: %s [%d].\n",
720				   strerror(errno), errno);
721			dump_clients_info(scrn, dev->fd);
722			dev->open_count--;
723			return NULL;
724		}
725	}
726
727	*fd = dev->fd;
728	return dev;
729}
730
731const char *intel_get_master_name(struct intel_device *dev)
732{
733	assert(dev && dev->master_node);
734	return dev->master_node;
735}
736
737const char *intel_get_client_name(struct intel_device *dev)
738{
739	assert(dev && dev->render_node);
740	return dev->render_node;
741}
742
743static int authorise(struct intel_device *dev, int fd)
744{
745	struct stat st;
746	drm_magic_t magic;
747
748	if (is_render_node(fd, &st)) /* restricted authority, do not elevate */
749		return 1;
750
751	return drmGetMagic(fd, &magic) == 0 && drmAuthMagic(dev->fd, magic) == 0;
752}
753
754int intel_get_client_fd(struct intel_device *dev)
755{
756	int fd = -1;
757
758	assert(dev && dev->fd != -1);
759	assert(dev->render_node);
760
761#ifdef O_CLOEXEC
762	fd = open(dev->render_node, O_RDWR | O_CLOEXEC);
763#endif
764	if (fd < 0)
765		fd = fd_set_cloexec(open(dev->render_node, O_RDWR));
766	if (fd < 0)
767		return -BadAlloc;
768
769	if (!authorise(dev, fd)) {
770		close(fd);
771		return -BadMatch;
772	}
773
774	assert(is_i915_gem(fd));
775
776	return fd;
777}
778
779int intel_get_device_id(struct intel_device *dev)
780{
781	assert(dev && dev->fd != -1);
782	return dev->device_id;
783}
784
785int intel_get_master(struct intel_device *dev)
786{
787	int ret;
788
789	assert(dev && dev->fd != -1);
790
791	ret = 0;
792	if (dev->master_count++ == 0) {
793		int retry = 2000;
794
795		assert(!hosted());
796		do {
797			ret = drmSetMaster(dev->fd);
798			if (ret == 0)
799				break;
800			usleep(1000);
801		} while (--retry);
802	}
803
804	return ret;
805}
806
807int intel_put_master(struct intel_device *dev)
808{
809	int ret;
810
811	assert(dev && dev->fd != -1);
812
813	ret = 0;
814	assert(dev->master_count);
815	if (--dev->master_count == 0) {
816		assert(!hosted());
817		assert(drmSetMaster(dev->fd) == 0);
818		ret = drmDropMaster(dev->fd);
819	}
820
821	return ret;
822}
823
824void intel_put_device(struct intel_device *dev)
825{
826	assert(dev && dev->fd != -1);
827
828	assert(dev->open_count);
829	if (--dev->open_count)
830		return;
831
832	assert(!hosted());
833	xf86GetEntityPrivate(dev->idx, intel_device_key)->ptr = NULL;
834
835	drmClose(dev->fd);
836	if (dev->render_node != dev->master_node)
837		free(dev->render_node);
838	free(dev->master_node);
839	free(dev);
840}
841