chiark / gitweb /
tree-wide: spelling fixes
[elogind.git] / src / libsystemd-terminal / grdev-drm.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright (C) 2014 David Herrmann <dh.herrmann@gmail.com>
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <fcntl.h>
23 #include <inttypes.h>
24 #include <libudev.h>
25 #include <stdbool.h>
26 #include <stdlib.h>
27 #include <sys/ioctl.h>
28 #include <sys/mman.h>
29 #include <sys/types.h>
30 #include <systemd/sd-bus.h>
31 #include <systemd/sd-event.h>
32 #include <unistd.h>
33
34 /* Yuck! DRM headers need system headers included first.. but we have to
35  * include it before shared/missing.h to avoid redefining ioctl bits */
36 #include <drm.h>
37 #include <drm_fourcc.h>
38 #include <drm_mode.h>
39
40 #include "bus-util.h"
41 #include "hashmap.h"
42 #include "grdev.h"
43 #include "grdev-internal.h"
44 #include "macro.h"
45 #include "udev-util.h"
46 #include "util.h"
47
48 #define GRDRM_MAX_TRIES (16)
49
50 typedef struct grdrm_object grdrm_object;
51 typedef struct grdrm_plane grdrm_plane;
52 typedef struct grdrm_connector grdrm_connector;
53 typedef struct grdrm_encoder grdrm_encoder;
54 typedef struct grdrm_crtc grdrm_crtc;
55
56 typedef struct grdrm_fb grdrm_fb;
57 typedef struct grdrm_pipe grdrm_pipe;
58 typedef struct grdrm_card grdrm_card;
59 typedef struct unmanaged_card unmanaged_card;
60 typedef struct managed_card managed_card;
61
62 /*
63  * Objects
64  */
65
66 enum {
67         GRDRM_TYPE_CRTC,
68         GRDRM_TYPE_ENCODER,
69         GRDRM_TYPE_CONNECTOR,
70         GRDRM_TYPE_PLANE,
71         GRDRM_TYPE_CNT
72 };
73
74 struct grdrm_object {
75         grdrm_card *card;
76         uint32_t id;
77         uint32_t index;
78         unsigned int type;
79         void (*free_fn) (grdrm_object *object);
80
81         bool present : 1;
82         bool assigned : 1;
83 };
84
85 struct grdrm_plane {
86         grdrm_object object;
87
88         struct {
89                 uint32_t used_crtc;
90                 uint32_t used_fb;
91                 uint32_t gamma_size;
92
93                 uint32_t n_crtcs;
94                 uint32_t max_crtcs;
95                 uint32_t *crtcs;
96                 uint32_t n_formats;
97                 uint32_t max_formats;
98                 uint32_t *formats;
99         } kern;
100 };
101
102 struct grdrm_connector {
103         grdrm_object object;
104
105         struct {
106                 uint32_t type;
107                 uint32_t type_id;
108                 uint32_t used_encoder;
109                 uint32_t connection;
110                 uint32_t mm_width;
111                 uint32_t mm_height;
112                 uint32_t subpixel;
113
114                 uint32_t n_encoders;
115                 uint32_t max_encoders;
116                 uint32_t *encoders;
117                 uint32_t n_modes;
118                 uint32_t max_modes;
119                 struct drm_mode_modeinfo *modes;
120                 uint32_t n_props;
121                 uint32_t max_props;
122                 uint32_t *prop_ids;
123                 uint64_t *prop_values;
124         } kern;
125 };
126
127 struct grdrm_encoder {
128         grdrm_object object;
129
130         struct {
131                 uint32_t type;
132                 uint32_t used_crtc;
133
134                 uint32_t n_crtcs;
135                 uint32_t max_crtcs;
136                 uint32_t *crtcs;
137                 uint32_t n_clones;
138                 uint32_t max_clones;
139                 uint32_t *clones;
140         } kern;
141 };
142
143 struct grdrm_crtc {
144         grdrm_object object;
145
146         struct {
147                 uint32_t used_fb;
148                 uint32_t fb_offset_x;
149                 uint32_t fb_offset_y;
150                 uint32_t gamma_size;
151
152                 uint32_t n_used_connectors;
153                 uint32_t max_used_connectors;
154                 uint32_t *used_connectors;
155
156                 bool mode_set;
157                 struct drm_mode_modeinfo mode;
158         } kern;
159
160         struct {
161                 bool set;
162                 uint32_t fb;
163                 uint32_t fb_x;
164                 uint32_t fb_y;
165                 uint32_t gamma;
166
167                 uint32_t n_connectors;
168                 uint32_t *connectors;
169
170                 bool mode_set;
171                 struct drm_mode_modeinfo mode;
172         } old;
173
174         struct {
175                 struct drm_mode_modeinfo mode;
176                 uint32_t n_connectors;
177                 uint32_t max_connectors;
178                 uint32_t *connectors;
179         } set;
180
181         grdrm_pipe *pipe;
182
183         bool applied : 1;
184 };
185
186 #define GRDRM_OBJECT_INIT(_card, _id, _index, _type, _free_fn) ((grdrm_object){ \
187                 .card = (_card), \
188                 .id = (_id), \
189                 .index = (_index), \
190                 .type = (_type), \
191                 .free_fn = (_free_fn), \
192         })
193
194 grdrm_object *grdrm_find_object(grdrm_card *card, uint32_t id);
195 int grdrm_object_add(grdrm_object *object);
196 grdrm_object *grdrm_object_free(grdrm_object *object);
197
198 DEFINE_TRIVIAL_CLEANUP_FUNC(grdrm_object*, grdrm_object_free);
199
200 int grdrm_plane_new(grdrm_plane **out, grdrm_card *card, uint32_t id, uint32_t index);
201 int grdrm_connector_new(grdrm_connector **out, grdrm_card *card, uint32_t id, uint32_t index);
202 int grdrm_encoder_new(grdrm_encoder **out, grdrm_card *card, uint32_t id, uint32_t index);
203 int grdrm_crtc_new(grdrm_crtc **out, grdrm_card *card, uint32_t id, uint32_t index);
204
205 #define plane_from_object(_obj) container_of((_obj), grdrm_plane, object)
206 #define connector_from_object(_obj) container_of((_obj), grdrm_connector, object)
207 #define encoder_from_object(_obj) container_of((_obj), grdrm_encoder, object)
208 #define crtc_from_object(_obj) container_of((_obj), grdrm_crtc, object)
209
210 /*
211  * Framebuffers
212  */
213
214 struct grdrm_fb {
215         grdev_fb base;
216         grdrm_card *card;
217         uint32_t id;
218         uint32_t handles[4];
219         uint32_t offsets[4];
220         uint32_t sizes[4];
221         uint32_t flipid;
222 };
223
224 static int grdrm_fb_new(grdrm_fb **out, grdrm_card *card, const struct drm_mode_modeinfo *mode);
225 grdrm_fb *grdrm_fb_free(grdrm_fb *fb);
226
227 DEFINE_TRIVIAL_CLEANUP_FUNC(grdrm_fb*, grdrm_fb_free);
228
229 #define fb_from_base(_fb) container_of((_fb), grdrm_fb, base)
230
231 /*
232  * Pipes
233  */
234
235 struct grdrm_pipe {
236         grdev_pipe base;
237         grdrm_crtc *crtc;
238         uint32_t counter;
239 };
240
241 #define grdrm_pipe_from_base(_e) container_of((_e), grdrm_pipe, base)
242
243 #define GRDRM_PIPE_NAME_MAX (GRDRM_CARD_NAME_MAX + 1 + DECIMAL_STR_MAX(uint32_t))
244
245 static const grdev_pipe_vtable grdrm_pipe_vtable;
246
247 static int grdrm_pipe_new(grdrm_pipe **out, grdrm_crtc *crtc, struct drm_mode_modeinfo *mode, size_t n_fbs);
248
249 /*
250  * Cards
251  */
252
253 struct grdrm_card {
254         grdev_card base;
255
256         int fd;
257         sd_event_source *fd_src;
258
259         uint32_t n_crtcs;
260         uint32_t n_encoders;
261         uint32_t n_connectors;
262         uint32_t n_planes;
263         uint32_t max_ids;
264         Hashmap *object_map;
265
266         bool async_hotplug : 1;
267         bool hotplug : 1;
268         bool running : 1;
269         bool ready : 1;
270         bool cap_dumb : 1;
271         bool cap_monotonic : 1;
272 };
273
274 struct unmanaged_card {
275         grdrm_card card;
276         char *devnode;
277 };
278
279 struct managed_card {
280         grdrm_card card;
281         dev_t devnum;
282
283         sd_bus_slot *slot_pause_device;
284         sd_bus_slot *slot_resume_device;
285         sd_bus_slot *slot_take_device;
286
287         bool requested : 1;             /* TakeDevice() was sent */
288         bool acquired : 1;              /* TakeDevice() was successful */
289         bool master : 1;                /* we are DRM-Master */
290 };
291
292 #define grdrm_card_from_base(_e) container_of((_e), grdrm_card, base)
293 #define unmanaged_card_from_base(_e) \
294         container_of(grdrm_card_from_base(_e), unmanaged_card, card)
295 #define managed_card_from_base(_e) \
296         container_of(grdrm_card_from_base(_e), managed_card, card)
297
298 #define GRDRM_CARD_INIT(_vtable, _session) ((grdrm_card){ \
299                 .base = GRDEV_CARD_INIT((_vtable), (_session)), \
300                 .fd = -1, \
301                 .max_ids = 32, \
302         })
303
304 #define GRDRM_CARD_NAME_MAX (6 + DECIMAL_STR_MAX(unsigned) * 2)
305
306 static const grdev_card_vtable unmanaged_card_vtable;
307 static const grdev_card_vtable managed_card_vtable;
308
309 static int grdrm_card_open(grdrm_card *card, int dev_fd);
310 static void grdrm_card_close(grdrm_card *card);
311 static bool grdrm_card_async(grdrm_card *card, int r);
312
313 /*
314  * The page-flip event of the kernel provides 64bit of arbitrary user-data. As
315  * drivers tend to drop events on intermediate deep mode-sets or because we
316  * might receive events during session activation, we try to avoid allocaing
317  * dynamic data on those events. Instead, we safe the CRTC id plus a 32bit
318  * counter in there. This way, we only get 32bit counters, not 64bit, but that
319  * should be more than enough. On the bright side, we no longer care whether we
320  * lose events. No memory leaks will occur.
321  * Modern DRM drivers might be fixed to no longer leak events, but we want to
322  * be safe. And associating dynamically allocated data with those events is
323  * kinda ugly, anyway.
324  */
325
326 static uint64_t grdrm_encode_vblank_data(uint32_t id, uint32_t counter) {
327         return id | ((uint64_t)counter << 32);
328 }
329
330 static void grdrm_decode_vblank_data(uint64_t data, uint32_t *out_id, uint32_t *out_counter) {
331         if (out_id)
332                 *out_id = data & 0xffffffffU;
333         if (out_counter)
334                 *out_counter = (data >> 32) & 0xffffffffU;
335 }
336
337 static bool grdrm_modes_compatible(const struct drm_mode_modeinfo *a, const struct drm_mode_modeinfo *b) {
338         assert(a);
339         assert(b);
340
341         /* Test whether both modes are compatible according to our internal
342          * assumptions on modes. This comparison is highly dependent on how
343          * we treat modes in grdrm. If we export mode details, we need to
344          * make this comparison much stricter. */
345
346         if (a->hdisplay != b->hdisplay)
347                 return false;
348         if (a->vdisplay != b->vdisplay)
349                 return false;
350         if (a->vrefresh != b->vrefresh)
351                 return false;
352
353         return true;
354 }
355
356 /*
357  * Objects
358  */
359
360 grdrm_object *grdrm_find_object(grdrm_card *card, uint32_t id) {
361         assert_return(card, NULL);
362
363         return id > 0 ? hashmap_get(card->object_map, UINT32_TO_PTR(id)) : NULL;
364 }
365
366 int grdrm_object_add(grdrm_object *object) {
367         int r;
368
369         assert(object);
370         assert(object->card);
371         assert(object->id > 0);
372         assert(IN_SET(object->type, GRDRM_TYPE_CRTC, GRDRM_TYPE_ENCODER, GRDRM_TYPE_CONNECTOR, GRDRM_TYPE_PLANE));
373         assert(object->free_fn);
374
375         if (object->index >= 32)
376                 log_debug("grdrm: %s: object index exceeds 32bit masks: type=%u, index=%" PRIu32,
377                           object->card->base.name, object->type, object->index);
378
379         r = hashmap_put(object->card->object_map, UINT32_TO_PTR(object->id), object);
380         if (r < 0)
381                 return r;
382
383         return 0;
384 }
385
386 grdrm_object *grdrm_object_free(grdrm_object *object) {
387         if (!object)
388                 return NULL;
389
390         assert(object->card);
391         assert(object->id > 0);
392         assert(IN_SET(object->type, GRDRM_TYPE_CRTC, GRDRM_TYPE_ENCODER, GRDRM_TYPE_CONNECTOR, GRDRM_TYPE_PLANE));
393         assert(object->free_fn);
394
395         hashmap_remove_value(object->card->object_map, UINT32_TO_PTR(object->id), object);
396
397         object->free_fn(object);
398         return NULL;
399 }
400
401 /*
402  * Planes
403  */
404
405 static void plane_free(grdrm_object *object) {
406         grdrm_plane *plane = plane_from_object(object);
407
408         free(plane->kern.formats);
409         free(plane->kern.crtcs);
410         free(plane);
411 }
412
413 int grdrm_plane_new(grdrm_plane **out, grdrm_card *card, uint32_t id, uint32_t index) {
414         _cleanup_(grdrm_object_freep) grdrm_object *object = NULL;
415         grdrm_plane *plane;
416         int r;
417
418         assert(card);
419
420         plane = new0(grdrm_plane, 1);
421         if (!plane)
422                 return -ENOMEM;
423
424         object = &plane->object;
425         *object = GRDRM_OBJECT_INIT(card, id, index, GRDRM_TYPE_PLANE, plane_free);
426
427         plane->kern.max_crtcs = 32;
428         plane->kern.crtcs = new0(uint32_t, plane->kern.max_crtcs);
429         if (!plane->kern.crtcs)
430                 return -ENOMEM;
431
432         plane->kern.max_formats = 32;
433         plane->kern.formats = new0(uint32_t, plane->kern.max_formats);
434         if (!plane->kern.formats)
435                 return -ENOMEM;
436
437         r = grdrm_object_add(object);
438         if (r < 0)
439                 return r;
440
441         if (out)
442                 *out = plane;
443         object = NULL;
444         return 0;
445 }
446
447 static int grdrm_plane_resync(grdrm_plane *plane) {
448         grdrm_card *card = plane->object.card;
449         size_t tries;
450         int r;
451
452         assert(plane);
453
454         for (tries = 0; tries < GRDRM_MAX_TRIES; ++tries) {
455                 struct drm_mode_get_plane res;
456                 grdrm_object *object;
457                 bool resized = false;
458                 Iterator iter;
459
460                 zero(res);
461                 res.plane_id = plane->object.id;
462                 res.format_type_ptr = PTR_TO_UINT64(plane->kern.formats);
463                 res.count_format_types = plane->kern.max_formats;
464
465                 r = ioctl(card->fd, DRM_IOCTL_MODE_GETPLANE, &res);
466                 if (r < 0) {
467                         r = -errno;
468                         if (r == -ENOENT) {
469                                 card->async_hotplug = true;
470                                 r = 0;
471                                 log_debug("grdrm: %s: plane %u removed during resync",
472                                           card->base.name, plane->object.id);
473                         } else {
474                                 log_debug_errno(errno, "grdrm: %s: cannot retrieve plane %u: %m",
475                                                 card->base.name, plane->object.id);
476                         }
477
478                         return r;
479                 }
480
481                 plane->kern.n_crtcs = 0;
482                 memzero(plane->kern.crtcs, sizeof(uint32_t) * plane->kern.max_crtcs);
483
484                 HASHMAP_FOREACH(object, card->object_map, iter) {
485                         if (object->type != GRDRM_TYPE_CRTC || object->index >= 32)
486                                 continue;
487                         if (!(res.possible_crtcs & (1 << object->index)))
488                                 continue;
489                         if (plane->kern.n_crtcs >= 32) {
490                                 log_debug("grdrm: %s: possible_crtcs of plane %" PRIu32 " exceeds 32bit mask",
491                                           card->base.name, plane->object.id);
492                                 continue;
493                         }
494
495                         plane->kern.crtcs[plane->kern.n_crtcs++] = object->id;
496                 }
497
498                 if (res.count_format_types > plane->kern.max_formats) {
499                         uint32_t max, *t;
500
501                         max = ALIGN_POWER2(res.count_format_types);
502                         if (!max || max > UINT16_MAX) {
503                                 log_debug("grdrm: %s: excessive plane resource limit: %" PRIu32, card->base.name, max);
504                                 return -ERANGE;
505                         }
506
507                         t = realloc(plane->kern.formats, sizeof(*t) * max);
508                         if (!t)
509                                 return -ENOMEM;
510
511                         plane->kern.formats = t;
512                         plane->kern.max_formats = max;
513                         resized = true;
514                 }
515
516                 if (resized)
517                         continue;
518
519                 plane->kern.n_formats = res.count_format_types;
520                 plane->kern.used_crtc = res.crtc_id;
521                 plane->kern.used_fb = res.fb_id;
522                 plane->kern.gamma_size = res.gamma_size;
523
524                 break;
525         }
526
527         if (tries >= GRDRM_MAX_TRIES) {
528                 log_debug("grdrm: %s: plane %u not settled for retrieval", card->base.name, plane->object.id);
529                 return -EFAULT;
530         }
531
532         return 0;
533 }
534
535 /*
536  * Connectors
537  */
538
539 static void connector_free(grdrm_object *object) {
540         grdrm_connector *connector = connector_from_object(object);
541
542         free(connector->kern.prop_values);
543         free(connector->kern.prop_ids);
544         free(connector->kern.modes);
545         free(connector->kern.encoders);
546         free(connector);
547 }
548
549 int grdrm_connector_new(grdrm_connector **out, grdrm_card *card, uint32_t id, uint32_t index) {
550         _cleanup_(grdrm_object_freep) grdrm_object *object = NULL;
551         grdrm_connector *connector;
552         int r;
553
554         assert(card);
555
556         connector = new0(grdrm_connector, 1);
557         if (!connector)
558                 return -ENOMEM;
559
560         object = &connector->object;
561         *object = GRDRM_OBJECT_INIT(card, id, index, GRDRM_TYPE_CONNECTOR, connector_free);
562
563         connector->kern.max_encoders = 32;
564         connector->kern.encoders = new0(uint32_t, connector->kern.max_encoders);
565         if (!connector->kern.encoders)
566                 return -ENOMEM;
567
568         connector->kern.max_modes = 32;
569         connector->kern.modes = new0(struct drm_mode_modeinfo, connector->kern.max_modes);
570         if (!connector->kern.modes)
571                 return -ENOMEM;
572
573         connector->kern.max_props = 32;
574         connector->kern.prop_ids = new0(uint32_t, connector->kern.max_props);
575         connector->kern.prop_values = new0(uint64_t, connector->kern.max_props);
576         if (!connector->kern.prop_ids || !connector->kern.prop_values)
577                 return -ENOMEM;
578
579         r = grdrm_object_add(object);
580         if (r < 0)
581                 return r;
582
583         if (out)
584                 *out = connector;
585         object = NULL;
586         return 0;
587 }
588
589 static int grdrm_connector_resync(grdrm_connector *connector) {
590         grdrm_card *card = connector->object.card;
591         size_t tries;
592         int r;
593
594         assert(connector);
595
596         for (tries = 0; tries < GRDRM_MAX_TRIES; ++tries) {
597                 struct drm_mode_get_connector res;
598                 bool resized = false;
599                 uint32_t max;
600
601                 zero(res);
602                 res.connector_id = connector->object.id;
603                 res.encoders_ptr = PTR_TO_UINT64(connector->kern.encoders);
604                 res.props_ptr = PTR_TO_UINT64(connector->kern.prop_ids);
605                 res.prop_values_ptr = PTR_TO_UINT64(connector->kern.prop_values);
606                 res.count_encoders = connector->kern.max_encoders;
607                 res.count_props = connector->kern.max_props;
608
609                 /* The kernel reads modes from the EDID information only if we
610                  * pass count_modes==0. This is a legacy hack for libdrm (which
611                  * called every ioctl twice). Now we have to adopt.. *sigh*.
612                  * If we never received an hotplug event, there's no reason to
613                  * sync modes. EDID reads are heavy, so skip that if not
614                  * required. */
615                 if (card->hotplug) {
616                         if (tries > 0) {
617                                 res.modes_ptr = PTR_TO_UINT64(connector->kern.modes);
618                                 res.count_modes = connector->kern.max_modes;
619                         } else {
620                                 resized = true;
621                         }
622                 }
623
624                 r = ioctl(card->fd, DRM_IOCTL_MODE_GETCONNECTOR, &res);
625                 if (r < 0) {
626                         r = -errno;
627                         if (r == -ENOENT) {
628                                 card->async_hotplug = true;
629                                 r = 0;
630                                 log_debug("grdrm: %s: connector %u removed during resync",
631                                           card->base.name, connector->object.id);
632                         } else {
633                                 log_debug_errno(errno, "grdrm: %s: cannot retrieve connector %u: %m",
634                                                 card->base.name, connector->object.id);
635                         }
636
637                         return r;
638                 }
639
640                 if (res.count_encoders > connector->kern.max_encoders) {
641                         uint32_t *t;
642
643                         max = ALIGN_POWER2(res.count_encoders);
644                         if (!max || max > UINT16_MAX) {
645                                 log_debug("grdrm: %s: excessive connector resource limit: %" PRIu32, card->base.name, max);
646                                 return -ERANGE;
647                         }
648
649                         t = realloc(connector->kern.encoders, sizeof(*t) * max);
650                         if (!t)
651                                 return -ENOMEM;
652
653                         connector->kern.encoders = t;
654                         connector->kern.max_encoders = max;
655                         resized = true;
656                 }
657
658                 if (res.count_modes > connector->kern.max_modes) {
659                         struct drm_mode_modeinfo *t;
660
661                         max = ALIGN_POWER2(res.count_modes);
662                         if (!max || max > UINT16_MAX) {
663                                 log_debug("grdrm: %s: excessive connector resource limit: %" PRIu32, card->base.name, max);
664                                 return -ERANGE;
665                         }
666
667                         t = realloc(connector->kern.modes, sizeof(*t) * max);
668                         if (!t)
669                                 return -ENOMEM;
670
671                         connector->kern.modes = t;
672                         connector->kern.max_modes = max;
673                         resized = true;
674                 }
675
676                 if (res.count_props > connector->kern.max_props) {
677                         uint32_t *tids;
678                         uint64_t *tvals;
679
680                         max = ALIGN_POWER2(res.count_props);
681                         if (!max || max > UINT16_MAX) {
682                                 log_debug("grdrm: %s: excessive connector resource limit: %" PRIu32, card->base.name, max);
683                                 return -ERANGE;
684                         }
685
686                         tids = realloc(connector->kern.prop_ids, sizeof(*tids) * max);
687                         if (!tids)
688                                 return -ENOMEM;
689                         connector->kern.prop_ids = tids;
690
691                         tvals = realloc(connector->kern.prop_values, sizeof(*tvals) * max);
692                         if (!tvals)
693                                 return -ENOMEM;
694                         connector->kern.prop_values = tvals;
695
696                         connector->kern.max_props = max;
697                         resized = true;
698                 }
699
700                 if (resized)
701                         continue;
702
703                 connector->kern.n_encoders = res.count_encoders;
704                 connector->kern.n_props = res.count_props;
705                 connector->kern.type = res.connector_type;
706                 connector->kern.type_id = res.connector_type_id;
707                 connector->kern.used_encoder = res.encoder_id;
708                 connector->kern.connection = res.connection;
709                 connector->kern.mm_width = res.mm_width;
710                 connector->kern.mm_height = res.mm_height;
711                 connector->kern.subpixel = res.subpixel;
712                 if (res.modes_ptr == PTR_TO_UINT64(connector->kern.modes))
713                         connector->kern.n_modes = res.count_modes;
714
715                 break;
716         }
717
718         if (tries >= GRDRM_MAX_TRIES) {
719                 log_debug("grdrm: %s: connector %u not settled for retrieval", card->base.name, connector->object.id);
720                 return -EFAULT;
721         }
722
723         return 0;
724 }
725
726 /*
727  * Encoders
728  */
729
730 static void encoder_free(grdrm_object *object) {
731         grdrm_encoder *encoder = encoder_from_object(object);
732
733         free(encoder->kern.clones);
734         free(encoder->kern.crtcs);
735         free(encoder);
736 }
737
738 int grdrm_encoder_new(grdrm_encoder **out, grdrm_card *card, uint32_t id, uint32_t index) {
739         _cleanup_(grdrm_object_freep) grdrm_object *object = NULL;
740         grdrm_encoder *encoder;
741         int r;
742
743         assert(card);
744
745         encoder = new0(grdrm_encoder, 1);
746         if (!encoder)
747                 return -ENOMEM;
748
749         object = &encoder->object;
750         *object = GRDRM_OBJECT_INIT(card, id, index, GRDRM_TYPE_ENCODER, encoder_free);
751
752         encoder->kern.max_crtcs = 32;
753         encoder->kern.crtcs = new0(uint32_t, encoder->kern.max_crtcs);
754         if (!encoder->kern.crtcs)
755                 return -ENOMEM;
756
757         encoder->kern.max_clones = 32;
758         encoder->kern.clones = new0(uint32_t, encoder->kern.max_clones);
759         if (!encoder->kern.clones)
760                 return -ENOMEM;
761
762         r = grdrm_object_add(object);
763         if (r < 0)
764                 return r;
765
766         if (out)
767                 *out = encoder;
768         object = NULL;
769         return 0;
770 }
771
772 static int grdrm_encoder_resync(grdrm_encoder *encoder) {
773         grdrm_card *card = encoder->object.card;
774         struct drm_mode_get_encoder res;
775         grdrm_object *object;
776         Iterator iter;
777         int r;
778
779         assert(encoder);
780
781         zero(res);
782         res.encoder_id = encoder->object.id;
783
784         r = ioctl(card->fd, DRM_IOCTL_MODE_GETENCODER, &res);
785         if (r < 0) {
786                 r = -errno;
787                 if (r == -ENOENT) {
788                         card->async_hotplug = true;
789                         r = 0;
790                         log_debug("grdrm: %s: encoder %u removed during resync",
791                                   card->base.name, encoder->object.id);
792                 } else {
793                         log_debug_errno(errno, "grdrm: %s: cannot retrieve encoder %u: %m",
794                                         card->base.name, encoder->object.id);
795                 }
796
797                 return r;
798         }
799
800         encoder->kern.type = res.encoder_type;
801         encoder->kern.used_crtc = res.crtc_id;
802
803         encoder->kern.n_crtcs = 0;
804         memzero(encoder->kern.crtcs, sizeof(uint32_t) * encoder->kern.max_crtcs);
805
806         HASHMAP_FOREACH(object, card->object_map, iter) {
807                 if (object->type != GRDRM_TYPE_CRTC || object->index >= 32)
808                         continue;
809                 if (!(res.possible_crtcs & (1 << object->index)))
810                         continue;
811                 if (encoder->kern.n_crtcs >= 32) {
812                         log_debug("grdrm: %s: possible_crtcs exceeds 32bit mask", card->base.name);
813                         continue;
814                 }
815
816                 encoder->kern.crtcs[encoder->kern.n_crtcs++] = object->id;
817         }
818
819         encoder->kern.n_clones = 0;
820         memzero(encoder->kern.clones, sizeof(uint32_t) * encoder->kern.max_clones);
821
822         HASHMAP_FOREACH(object, card->object_map, iter) {
823                 if (object->type != GRDRM_TYPE_ENCODER || object->index >= 32)
824                         continue;
825                 if (!(res.possible_clones & (1 << object->index)))
826                         continue;
827                 if (encoder->kern.n_clones >= 32) {
828                         log_debug("grdrm: %s: possible_encoders exceeds 32bit mask", card->base.name);
829                         continue;
830                 }
831
832                 encoder->kern.clones[encoder->kern.n_clones++] = object->id;
833         }
834
835         return 0;
836 }
837
838 /*
839  * Crtcs
840  */
841
842 static void crtc_free(grdrm_object *object) {
843         grdrm_crtc *crtc = crtc_from_object(object);
844
845         if (crtc->pipe)
846                 grdev_pipe_free(&crtc->pipe->base);
847         free(crtc->set.connectors);
848         free(crtc->old.connectors);
849         free(crtc->kern.used_connectors);
850         free(crtc);
851 }
852
853 int grdrm_crtc_new(grdrm_crtc **out, grdrm_card *card, uint32_t id, uint32_t index) {
854         _cleanup_(grdrm_object_freep) grdrm_object *object = NULL;
855         grdrm_crtc *crtc;
856         int r;
857
858         assert(card);
859
860         crtc = new0(grdrm_crtc, 1);
861         if (!crtc)
862                 return -ENOMEM;
863
864         object = &crtc->object;
865         *object = GRDRM_OBJECT_INIT(card, id, index, GRDRM_TYPE_CRTC, crtc_free);
866
867         crtc->kern.max_used_connectors = 32;
868         crtc->kern.used_connectors = new0(uint32_t, crtc->kern.max_used_connectors);
869         if (!crtc->kern.used_connectors)
870                 return -ENOMEM;
871
872         crtc->old.connectors = new0(uint32_t, crtc->kern.max_used_connectors);
873         if (!crtc->old.connectors)
874                 return -ENOMEM;
875
876         r = grdrm_object_add(object);
877         if (r < 0)
878                 return r;
879
880         if (out)
881                 *out = crtc;
882         object = NULL;
883         return 0;
884 }
885
886 static int grdrm_crtc_resync(grdrm_crtc *crtc) {
887         grdrm_card *card = crtc->object.card;
888         struct drm_mode_crtc res = { .crtc_id = crtc->object.id };
889         int r;
890
891         assert(crtc);
892
893         /* make sure we can cache any combination later */
894         if (card->n_connectors > crtc->kern.max_used_connectors) {
895                 uint32_t max, *t;
896
897                 max = ALIGN_POWER2(card->n_connectors);
898                 if (!max)
899                         return -ENOMEM;
900
901                 t = realloc_multiply(crtc->kern.used_connectors, sizeof(*t), max);
902                 if (!t)
903                         return -ENOMEM;
904
905                 crtc->kern.used_connectors = t;
906                 crtc->kern.max_used_connectors = max;
907
908                 if (!crtc->old.set) {
909                         crtc->old.connectors = calloc(sizeof(*t), max);
910                         if (!crtc->old.connectors)
911                                 return -ENOMEM;
912                 }
913         }
914
915         /* GETCRTC doesn't return connectors. We have to read all
916          * encoder-state and deduce the setup ourselves.. */
917         crtc->kern.n_used_connectors = 0;
918
919         r = ioctl(card->fd, DRM_IOCTL_MODE_GETCRTC, &res);
920         if (r < 0) {
921                 r = -errno;
922                 if (r == -ENOENT) {
923                         card->async_hotplug = true;
924                         r = 0;
925                         log_debug("grdrm: %s: crtc %u removed during resync",
926                                   card->base.name, crtc->object.id);
927                 } else {
928                         log_debug_errno(errno, "grdrm: %s: cannot retrieve crtc %u: %m",
929                                         card->base.name, crtc->object.id);
930                 }
931
932                 return r;
933         }
934
935         crtc->kern.used_fb = res.fb_id;
936         crtc->kern.fb_offset_x = res.x;
937         crtc->kern.fb_offset_y = res.y;
938         crtc->kern.gamma_size = res.gamma_size;
939         crtc->kern.mode_set = res.mode_valid;
940         crtc->kern.mode = res.mode;
941
942         return 0;
943 }
944
945 static void grdrm_crtc_assign(grdrm_crtc *crtc, grdrm_connector *connector) {
946         uint32_t n_connectors;
947         int r;
948
949         assert(crtc);
950         assert(!crtc->object.assigned);
951         assert(!connector || !connector->object.assigned);
952
953         /* always mark both as assigned; even if assignments cannot be set */
954         crtc->object.assigned = true;
955         if (connector)
956                 connector->object.assigned = true;
957
958         /* we will support hw clone mode in the future */
959         n_connectors = connector ? 1 : 0;
960
961         /* bail out if configuration is preserved */
962         if (crtc->set.n_connectors == n_connectors &&
963             (n_connectors == 0 || crtc->set.connectors[0] == connector->object.id))
964                 return;
965
966         crtc->applied = false;
967         crtc->set.n_connectors = 0;
968
969         if (n_connectors > crtc->set.max_connectors) {
970                 uint32_t max, *t;
971
972                 max = ALIGN_POWER2(n_connectors);
973                 if (!max) {
974                         r = -ENOMEM;
975                         goto error;
976                 }
977
978                 t = realloc(crtc->set.connectors, sizeof(*t) * max);
979                 if (!t) {
980                         r = -ENOMEM;
981                         goto error;
982                 }
983
984                 crtc->set.connectors = t;
985                 crtc->set.max_connectors = max;
986         }
987
988         if (connector) {
989                 struct drm_mode_modeinfo *m, *pref = NULL;
990                 uint32_t i;
991
992                 for (i = 0; i < connector->kern.n_modes; ++i) {
993                         m = &connector->kern.modes[i];
994
995                         /* ignore 3D modes by default */
996                         if (m->flags & DRM_MODE_FLAG_3D_MASK)
997                                 continue;
998
999                         if (!pref) {
1000                                 pref = m;
1001                                 continue;
1002                         }
1003
1004                         /* use PREFERRED over non-PREFERRED */
1005                         if ((pref->type & DRM_MODE_TYPE_PREFERRED) &&
1006                             !(m->type & DRM_MODE_TYPE_PREFERRED))
1007                                 continue;
1008
1009                         /* use DRIVER over non-PREFERRED|DRIVER */
1010                         if ((pref->type & DRM_MODE_TYPE_DRIVER) &&
1011                             !(m->type & (DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED)))
1012                                 continue;
1013
1014                         /* always prefer higher resolution */
1015                         if (pref->hdisplay > m->hdisplay ||
1016                             (pref->hdisplay == m->hdisplay && pref->vdisplay > m->vdisplay))
1017                                 continue;
1018
1019                         pref = m;
1020                 }
1021
1022                 if (pref) {
1023                         crtc->set.mode = *pref;
1024                         crtc->set.n_connectors = 1;
1025                         crtc->set.connectors[0] = connector->object.id;
1026                         log_debug("grdrm: %s: assigned connector %" PRIu32 " to crtc %" PRIu32 " with mode %s",
1027                                   crtc->object.card->base.name, connector->object.id, crtc->object.id, pref->name);
1028                 } else {
1029                         log_debug("grdrm: %s: connector %" PRIu32 " to be assigned but has no valid mode",
1030                                   crtc->object.card->base.name, connector->object.id);
1031                 }
1032         }
1033
1034         return;
1035
1036 error:
1037         log_debug("grdrm: %s: cannot assign crtc %" PRIu32 ": %s",
1038                   crtc->object.card->base.name, crtc->object.id, strerror(-r));
1039 }
1040
1041 static void grdrm_crtc_expose(grdrm_crtc *crtc) {
1042         grdrm_pipe *pipe;
1043         grdrm_fb *fb;
1044         size_t i;
1045         int r;
1046
1047         assert(crtc);
1048         assert(crtc->object.assigned);
1049
1050         if (crtc->set.n_connectors < 1) {
1051                 if (crtc->pipe)
1052                         grdev_pipe_free(&crtc->pipe->base);
1053                 crtc->pipe = NULL;
1054                 return;
1055         }
1056
1057         pipe = crtc->pipe;
1058         if (pipe) {
1059                 if (pipe->base.width != crtc->set.mode.hdisplay ||
1060                     pipe->base.height != crtc->set.mode.vdisplay ||
1061                     pipe->base.vrefresh != crtc->set.mode.vrefresh) {
1062                         grdev_pipe_free(&pipe->base);
1063                         crtc->pipe = NULL;
1064                         pipe = NULL;
1065                 }
1066         }
1067
1068         if (crtc->pipe) {
1069                 pipe->base.front = NULL;
1070                 pipe->base.back = NULL;
1071                 for (i = 0; i < pipe->base.max_fbs; ++i) {
1072                         fb = fb_from_base(pipe->base.fbs[i]);
1073                         if (fb->id == crtc->kern.used_fb)
1074                                 pipe->base.front = &fb->base;
1075                         else if (!fb->flipid)
1076                                 pipe->base.back = &fb->base;
1077                 }
1078         } else {
1079                 r = grdrm_pipe_new(&pipe, crtc, &crtc->set.mode, 2);
1080                 if (r < 0) {
1081                         log_debug("grdrm: %s: cannot create pipe for crtc %" PRIu32 ": %s",
1082                                   crtc->object.card->base.name, crtc->object.id, strerror(-r));
1083                         return;
1084                 }
1085
1086                 for (i = 0; i < pipe->base.max_fbs; ++i) {
1087                         r = grdrm_fb_new(&fb, crtc->object.card, &crtc->set.mode);
1088                         if (r < 0) {
1089                                 log_debug("grdrm: %s: cannot allocate framebuffer for crtc %" PRIu32 ": %s",
1090                                           crtc->object.card->base.name, crtc->object.id, strerror(-r));
1091                                 grdev_pipe_free(&pipe->base);
1092                                 return;
1093                         }
1094
1095                         pipe->base.fbs[i] = &fb->base;
1096                 }
1097
1098                 pipe->base.front = NULL;
1099                 pipe->base.back = pipe->base.fbs[0];
1100                 crtc->pipe = pipe;
1101         }
1102
1103         grdev_pipe_ready(&crtc->pipe->base, true);
1104 }
1105
1106 static void grdrm_crtc_commit_deep(grdrm_crtc *crtc, grdev_fb *basefb) {
1107         struct drm_mode_crtc set_crtc = { .crtc_id = crtc->object.id };
1108         grdrm_card *card = crtc->object.card;
1109         grdrm_pipe *pipe = crtc->pipe;
1110         grdrm_fb *fb;
1111         int r;
1112
1113         assert(crtc);
1114         assert(basefb);
1115         assert(pipe);
1116
1117         fb = fb_from_base(basefb);
1118
1119         set_crtc.set_connectors_ptr = PTR_TO_UINT64(crtc->set.connectors);
1120         set_crtc.count_connectors = crtc->set.n_connectors;
1121         set_crtc.fb_id = fb->id;
1122         set_crtc.x = 0;
1123         set_crtc.y = 0;
1124         set_crtc.mode_valid = 1;
1125         set_crtc.mode = crtc->set.mode;
1126
1127         r = ioctl(card->fd, DRM_IOCTL_MODE_SETCRTC, &set_crtc);
1128         if (r < 0) {
1129                 r = -errno;
1130                 log_debug_errno(errno, "grdrm: %s: cannot set crtc %" PRIu32 ": %m",
1131                                 card->base.name, crtc->object.id);
1132
1133                 grdrm_card_async(card, r);
1134                 return;
1135         }
1136
1137         if (!crtc->applied) {
1138                 log_debug("grdrm: %s: crtc %" PRIu32 " applied via deep modeset",
1139                           card->base.name, crtc->object.id);
1140                 crtc->applied = true;
1141         }
1142
1143         pipe->base.back = NULL;
1144         pipe->base.front = &fb->base;
1145         fb->flipid = 0;
1146         ++pipe->counter;
1147         pipe->base.flipping = false;
1148         pipe->base.flip = false;
1149
1150         /* We cannot schedule dummy page-flips on pipes, hence, the
1151          * application would have to schedule their own frame-timers.
1152          * To avoid duplicating that everywhere, we schedule our own
1153          * timer and raise a fake FRAME event when it fires. */
1154         grdev_pipe_schedule(&pipe->base, 1);
1155 }
1156
1157 static int grdrm_crtc_commit_flip(grdrm_crtc *crtc, grdev_fb *basefb) {
1158         struct drm_mode_crtc_page_flip page_flip = { .crtc_id = crtc->object.id };
1159         grdrm_card *card = crtc->object.card;
1160         grdrm_pipe *pipe = crtc->pipe;
1161         grdrm_fb *fb;
1162         uint32_t cnt;
1163         int r;
1164
1165         assert(crtc);
1166         assert(basefb);
1167         assert(pipe);
1168
1169         if (!crtc->applied) {
1170                 if (!grdrm_modes_compatible(&crtc->kern.mode, &crtc->set.mode))
1171                         return 0;
1172
1173                 /* TODO: Theoretically, we should be able to page-flip to our
1174                  * framebuffer here. We didn't perform any deep modeset, but the
1175                  * DRM driver is really supposed to reject our page-flip in case
1176                  * the FB is not compatible. We then properly fall back to a
1177                  * deep modeset.
1178                  * As it turns out, drivers don't to this. Therefore, we need to
1179                  * perform a full modeset on enter now. We might avoid this in
1180                  * the future with fixed drivers.. */
1181
1182                 return 0;
1183         }
1184
1185         fb = fb_from_base(basefb);
1186
1187         cnt = ++pipe->counter ? : ++pipe->counter;
1188         page_flip.fb_id = fb->id;
1189         page_flip.flags = DRM_MODE_PAGE_FLIP_EVENT;
1190         page_flip.user_data = grdrm_encode_vblank_data(crtc->object.id, cnt);
1191
1192         r = ioctl(card->fd, DRM_IOCTL_MODE_PAGE_FLIP, &page_flip);
1193         if (r < 0) {
1194                 r = -errno;
1195                 /* Avoid excessive logging on EINVAL; it is currently not
1196                  * possible to see whether cards support page-flipping, so
1197                  * avoid logging on each frame. */
1198                 if (r != -EINVAL)
1199                         log_debug_errno(errno, "grdrm: %s: cannot schedule page-flip on crtc %" PRIu32 ": %m",
1200                                         card->base.name, crtc->object.id);
1201
1202                 if (grdrm_card_async(card, r))
1203                         return r;
1204
1205                 return 0;
1206         }
1207
1208         if (!crtc->applied) {
1209                 log_debug("grdrm: %s: crtc %" PRIu32 " applied via page flip",
1210                           card->base.name, crtc->object.id);
1211                 crtc->applied = true;
1212         }
1213
1214         pipe->base.flipping = true;
1215         pipe->base.flip = false;
1216         pipe->counter = cnt;
1217         fb->flipid = cnt;
1218         pipe->base.back = NULL;
1219
1220         /* Raise fake FRAME event if it takes longer than 2
1221          * frames to receive the pageflip event. We assume the
1222          * queue ran over or some other error happened. */
1223         grdev_pipe_schedule(&pipe->base, 2);
1224
1225         return 1;
1226 }
1227
1228 static void grdrm_crtc_commit(grdrm_crtc *crtc) {
1229         struct drm_mode_crtc set_crtc = { .crtc_id = crtc->object.id };
1230         grdrm_card *card = crtc->object.card;
1231         grdrm_pipe *pipe;
1232         grdev_fb *fb;
1233         int r;
1234
1235         assert(crtc);
1236         assert(crtc->object.assigned);
1237
1238         pipe = crtc->pipe;
1239         if (!pipe) {
1240                 /* If a crtc is not assigned any connector, we want any
1241                  * previous setup to be cleared, so make sure the CRTC is
1242                  * disabled. Otherwise, there might be content on the CRTC
1243                  * while we run, which is not what we want.
1244                  * If you want to avoid modesets on specific CRTCs, you should
1245                  * still keep their assignment, but never enable the resulting
1246                  * pipe. This way, we wouldn't touch it at all. */
1247                 if (!crtc->applied) {
1248                         crtc->applied = true;
1249                         r = ioctl(card->fd, DRM_IOCTL_MODE_SETCRTC, &set_crtc);
1250                         if (r < 0) {
1251                                 r = -errno;
1252                                 log_debug_errno(errno, "grdrm: %s: cannot shutdown crtc %" PRIu32 ": %m",
1253                                                 card->base.name, crtc->object.id);
1254
1255                                 grdrm_card_async(card, r);
1256                                 return;
1257                         }
1258
1259                         log_debug("grdrm: %s: crtc %" PRIu32 " applied via shutdown",
1260                                   card->base.name, crtc->object.id);
1261                 }
1262
1263                 return;
1264         }
1265
1266         /* we always fully ignore disabled pipes */
1267         if (!pipe->base.enabled)
1268                 return;
1269
1270         assert(crtc->set.n_connectors > 0);
1271
1272         if (pipe->base.flip)
1273                 fb = pipe->base.back;
1274         else if (!crtc->applied)
1275                 fb = pipe->base.front;
1276         else
1277                 return;
1278
1279         if (!fb)
1280                 return;
1281
1282         r = grdrm_crtc_commit_flip(crtc, fb);
1283         if (r == 0) {
1284                 /* in case we couldn't page-flip, perform deep modeset */
1285                 grdrm_crtc_commit_deep(crtc, fb);
1286         }
1287 }
1288
1289 static void grdrm_crtc_restore(grdrm_crtc *crtc) {
1290         struct drm_mode_crtc set_crtc = { .crtc_id = crtc->object.id };
1291         grdrm_card *card = crtc->object.card;
1292         int r;
1293
1294         if (!crtc->old.set)
1295                 return;
1296
1297         set_crtc.set_connectors_ptr = PTR_TO_UINT64(crtc->old.connectors);
1298         set_crtc.count_connectors = crtc->old.n_connectors;
1299         set_crtc.fb_id = crtc->old.fb;
1300         set_crtc.x = crtc->old.fb_x;
1301         set_crtc.y = crtc->old.fb_y;
1302         set_crtc.gamma_size = crtc->old.gamma;
1303         set_crtc.mode_valid = crtc->old.mode_set;
1304         set_crtc.mode = crtc->old.mode;
1305
1306         r = ioctl(card->fd, DRM_IOCTL_MODE_SETCRTC, &set_crtc);
1307         if (r < 0) {
1308                 r = -errno;
1309                 log_debug_errno(errno, "grdrm: %s: cannot restore crtc %" PRIu32 ": %m",
1310                                 card->base.name, crtc->object.id);
1311
1312                 grdrm_card_async(card, r);
1313                 return;
1314         }
1315
1316         if (crtc->pipe) {
1317                 ++crtc->pipe->counter;
1318                 crtc->pipe->base.front = NULL;
1319                 crtc->pipe->base.flipping = false;
1320         }
1321
1322         log_debug("grdrm: %s: crtc %" PRIu32 " restored", card->base.name, crtc->object.id);
1323 }
1324
1325 static void grdrm_crtc_flip_complete(grdrm_crtc *crtc, uint32_t counter, struct drm_event_vblank *event) {
1326         bool flipped = false;
1327         grdrm_pipe *pipe;
1328         size_t i;
1329
1330         assert(crtc);
1331         assert(event);
1332
1333         pipe = crtc->pipe;
1334         if (!pipe)
1335                 return;
1336
1337         /* We got a page-flip event. To be safe, we reset all FBs on the same
1338          * pipe that have smaller flipids than the flip we got as we know they
1339          * are executed in order. We need to do this to guarantee
1340          * queue-overflows or other missed events don't cause starvation.
1341          * Furthermore, if we find the exact FB this event is for, *and* this
1342          * is the most recent event, we mark it as front FB and raise a
1343          * frame event. */
1344
1345         for (i = 0; i < pipe->base.max_fbs; ++i) {
1346                 grdrm_fb *fb;
1347
1348                 if (!pipe->base.fbs[i])
1349                         continue;
1350
1351                 fb = fb_from_base(pipe->base.fbs[i]);
1352                 if (counter != 0 && counter == pipe->counter && fb->flipid == counter) {
1353                         pipe->base.front = &fb->base;
1354                         fb->flipid = 0;
1355                         flipped = true;
1356                 } else if (counter - fb->flipid < UINT16_MAX) {
1357                         fb->flipid = 0;
1358                 }
1359         }
1360
1361         if (flipped) {
1362                 crtc->pipe->base.flipping = false;
1363                 grdev_pipe_frame(&pipe->base);
1364         }
1365 }
1366
1367 /*
1368  * Framebuffers
1369  */
1370
1371 static int grdrm_fb_new(grdrm_fb **out, grdrm_card *card, const struct drm_mode_modeinfo *mode) {
1372         _cleanup_(grdrm_fb_freep) grdrm_fb *fb = NULL;
1373         struct drm_mode_create_dumb create_dumb = { };
1374         struct drm_mode_map_dumb map_dumb = { };
1375         struct drm_mode_fb_cmd2 add_fb = { };
1376         unsigned int i;
1377         int r;
1378
1379         assert_return(out, -EINVAL);
1380         assert_return(card, -EINVAL);
1381
1382         fb = new0(grdrm_fb, 1);
1383         if (!fb)
1384                 return -ENOMEM;
1385
1386         /* TODO: we should choose a compatible format of the previous CRTC
1387          * setting to allow page-flip to it. Only choose fallback if the
1388          * previous setting was crap (non xrgb32'ish). */
1389
1390         fb->card = card;
1391         fb->base.format = DRM_FORMAT_XRGB8888;
1392         fb->base.width = mode->hdisplay;
1393         fb->base.height = mode->vdisplay;
1394
1395         for (i = 0; i < ELEMENTSOF(fb->base.maps); ++i)
1396                 fb->base.maps[i] = MAP_FAILED;
1397
1398         create_dumb.width = fb->base.width;
1399         create_dumb.height = fb->base.height;
1400         create_dumb.bpp = 32;
1401
1402         r = ioctl(card->fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_dumb);
1403         if (r < 0) {
1404                 r = negative_errno();
1405                 log_debug_errno(errno, "grdrm: %s: cannot create dumb buffer %" PRIu32 "x%" PRIu32": %m",
1406                                 card->base.name, fb->base.width, fb->base.height);
1407                 return r;
1408         }
1409
1410         fb->handles[0] = create_dumb.handle;
1411         fb->base.strides[0] = create_dumb.pitch;
1412         fb->sizes[0] = create_dumb.size;
1413
1414         map_dumb.handle = fb->handles[0];
1415
1416         r = ioctl(card->fd, DRM_IOCTL_MODE_MAP_DUMB, &map_dumb);
1417         if (r < 0) {
1418                 r = negative_errno();
1419                 log_debug_errno(errno, "grdrm: %s: cannot map dumb buffer %" PRIu32 "x%" PRIu32": %m",
1420                                 card->base.name, fb->base.width, fb->base.height);
1421                 return r;
1422         }
1423
1424         fb->base.maps[0] = mmap(0, fb->sizes[0], PROT_WRITE, MAP_SHARED, card->fd, map_dumb.offset);
1425         if (fb->base.maps[0] == MAP_FAILED) {
1426                 r = negative_errno();
1427                 log_debug_errno(errno, "grdrm: %s: cannot memory-map dumb buffer %" PRIu32 "x%" PRIu32": %m",
1428                                 card->base.name, fb->base.width, fb->base.height);
1429                 return r;
1430         }
1431
1432         memzero(fb->base.maps[0], fb->sizes[0]);
1433
1434         add_fb.width = fb->base.width;
1435         add_fb.height = fb->base.height;
1436         add_fb.pixel_format = fb->base.format;
1437         add_fb.flags = 0;
1438         memcpy(add_fb.handles, fb->handles, sizeof(fb->handles));
1439         memcpy(add_fb.pitches, fb->base.strides, sizeof(fb->base.strides));
1440         memcpy(add_fb.offsets, fb->offsets, sizeof(fb->offsets));
1441
1442         r = ioctl(card->fd, DRM_IOCTL_MODE_ADDFB2, &add_fb);
1443         if (r < 0) {
1444                 r = negative_errno();
1445                 log_debug_errno(errno, "grdrm: %s: cannot add framebuffer %" PRIu32 "x%" PRIu32": %m",
1446                                 card->base.name, fb->base.width, fb->base.height);
1447                 return r;
1448         }
1449
1450         fb->id = add_fb.fb_id;
1451
1452         *out = fb;
1453         fb = NULL;
1454         return 0;
1455 }
1456
1457 grdrm_fb *grdrm_fb_free(grdrm_fb *fb) {
1458         unsigned int i;
1459         int r;
1460
1461         if (!fb)
1462                 return NULL;
1463
1464         assert(fb->card);
1465
1466         if (fb->base.free_fn)
1467                 fb->base.free_fn(fb->base.data.ptr);
1468
1469         if (fb->id > 0 && fb->card->fd >= 0) {
1470                 r = ioctl(fb->card->fd, DRM_IOCTL_MODE_RMFB, fb->id);
1471                 if (r < 0)
1472                         log_debug_errno(errno, "grdrm: %s: cannot delete framebuffer %" PRIu32 ": %m",
1473                                         fb->card->base.name, fb->id);
1474         }
1475
1476         for (i = 0; i < ELEMENTSOF(fb->handles); ++i) {
1477                 struct drm_mode_destroy_dumb destroy_dumb = { };
1478
1479                 if (fb->base.maps[i] != MAP_FAILED)
1480                         munmap(fb->base.maps[i], fb->sizes[i]);
1481
1482                 if (fb->handles[i] > 0 && fb->card->fd >= 0) {
1483                         destroy_dumb.handle = fb->handles[i];
1484                         r = ioctl(fb->card->fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_dumb);
1485                         if (r < 0)
1486                                 log_debug_errno(errno, "grdrm: %s: cannot destroy dumb-buffer %" PRIu32 ": %m",
1487                                                 fb->card->base.name, fb->handles[i]);
1488                 }
1489         }
1490
1491         free(fb);
1492
1493         return NULL;
1494 }
1495
1496 /*
1497  * Pipes
1498  */
1499
1500 static void grdrm_pipe_name(char *out, grdrm_crtc *crtc) {
1501         /* @out must be at least of size GRDRM_PIPE_NAME_MAX */
1502         sprintf(out, "%s/%" PRIu32, crtc->object.card->base.name, crtc->object.id);
1503 }
1504
1505 static int grdrm_pipe_new(grdrm_pipe **out, grdrm_crtc *crtc, struct drm_mode_modeinfo *mode, size_t n_fbs) {
1506         _cleanup_(grdev_pipe_freep) grdev_pipe *basepipe = NULL;
1507         grdrm_card *card = crtc->object.card;
1508         char name[GRDRM_PIPE_NAME_MAX];
1509         grdrm_pipe *pipe;
1510         int r;
1511
1512         assert_return(crtc, -EINVAL);
1513         assert_return(grdev_is_drm_card(&card->base), -EINVAL);
1514
1515         pipe = new0(grdrm_pipe, 1);
1516         if (!pipe)
1517                 return -ENOMEM;
1518
1519         basepipe = &pipe->base;
1520         pipe->base = GRDEV_PIPE_INIT(&grdrm_pipe_vtable, &card->base);
1521         pipe->crtc = crtc;
1522         pipe->base.width = mode->hdisplay;
1523         pipe->base.height = mode->vdisplay;
1524         pipe->base.vrefresh = mode->vrefresh ? : 25;
1525
1526         grdrm_pipe_name(name, crtc);
1527         r = grdev_pipe_add(&pipe->base, name, n_fbs);
1528         if (r < 0)
1529                 return r;
1530
1531         if (out)
1532                 *out = pipe;
1533         basepipe = NULL;
1534         return 0;
1535 }
1536
1537 static void grdrm_pipe_free(grdev_pipe *basepipe) {
1538         grdrm_pipe *pipe = grdrm_pipe_from_base(basepipe);
1539         size_t i;
1540
1541         assert(pipe->crtc);
1542
1543         for (i = 0; i < pipe->base.max_fbs; ++i)
1544                 if (pipe->base.fbs[i])
1545                         grdrm_fb_free(fb_from_base(pipe->base.fbs[i]));
1546
1547         free(pipe);
1548 }
1549
1550 static grdev_fb *grdrm_pipe_target(grdev_pipe *basepipe) {
1551         grdrm_fb *fb;
1552         size_t i;
1553
1554         if (!basepipe->back) {
1555                 for (i = 0; i < basepipe->max_fbs; ++i) {
1556                         if (!basepipe->fbs[i])
1557                                 continue;
1558
1559                         fb = fb_from_base(basepipe->fbs[i]);
1560                         if (&fb->base == basepipe->front)
1561                                 continue;
1562                         if (basepipe->flipping && fb->flipid)
1563                                 continue;
1564
1565                         basepipe->back = &fb->base;
1566                         break;
1567                 }
1568         }
1569
1570         return basepipe->back;
1571 }
1572
1573 static void grdrm_pipe_enable(grdev_pipe *basepipe) {
1574         grdrm_pipe *pipe = grdrm_pipe_from_base(basepipe);
1575
1576         pipe->crtc->applied = false;
1577 }
1578
1579 static void grdrm_pipe_disable(grdev_pipe *basepipe) {
1580         grdrm_pipe *pipe = grdrm_pipe_from_base(basepipe);
1581
1582         pipe->crtc->applied = false;
1583 }
1584
1585 static const grdev_pipe_vtable grdrm_pipe_vtable = {
1586         .free                   = grdrm_pipe_free,
1587         .target                 = grdrm_pipe_target,
1588         .enable                 = grdrm_pipe_enable,
1589         .disable                = grdrm_pipe_disable,
1590 };
1591
1592 /*
1593  * Cards
1594  */
1595
1596 static void grdrm_name(char *out, dev_t devnum) {
1597         /* @out must be at least of size GRDRM_CARD_NAME_MAX */
1598         sprintf(out, "drm/%u:%u", major(devnum), minor(devnum));
1599 }
1600
1601 static void grdrm_card_print(grdrm_card *card) {
1602         grdrm_object *object;
1603         grdrm_crtc *crtc;
1604         grdrm_encoder *encoder;
1605         grdrm_connector *connector;
1606         grdrm_plane *plane;
1607         Iterator iter;
1608         uint32_t i;
1609         char *p, *buf;
1610
1611         log_debug("grdrm: %s: state dump", card->base.name);
1612
1613         log_debug("  crtcs:");
1614         HASHMAP_FOREACH(object, card->object_map, iter) {
1615                 if (object->type != GRDRM_TYPE_CRTC)
1616                         continue;
1617
1618                 crtc = crtc_from_object(object);
1619                 log_debug("    (id: %u index: %d)", object->id, object->index);
1620
1621                 if (crtc->kern.mode_set)
1622                         log_debug("      mode: %dx%d", crtc->kern.mode.hdisplay, crtc->kern.mode.vdisplay);
1623                 else
1624                         log_debug("      mode: <none>");
1625         }
1626
1627         log_debug("  encoders:");
1628         HASHMAP_FOREACH(object, card->object_map, iter) {
1629                 if (object->type != GRDRM_TYPE_ENCODER)
1630                         continue;
1631
1632                 encoder = encoder_from_object(object);
1633                 log_debug("    (id: %u index: %d)", object->id, object->index);
1634
1635                 if (encoder->kern.used_crtc)
1636                         log_debug("      crtc: %u", encoder->kern.used_crtc);
1637                 else
1638                         log_debug("      crtc: <none>");
1639
1640                 buf = malloc((DECIMAL_STR_MAX(uint32_t) + 1) * encoder->kern.n_crtcs + 1);
1641                 if (buf) {
1642                         buf[0] = 0;
1643                         p = buf;
1644
1645                         for (i = 0; i < encoder->kern.n_crtcs; ++i)
1646                                 p += sprintf(p, " %" PRIu32, encoder->kern.crtcs[i]);
1647
1648                         log_debug("      possible crtcs:%s", buf);
1649                         free(buf);
1650                 }
1651
1652                 buf = malloc((DECIMAL_STR_MAX(uint32_t) + 1) * encoder->kern.n_clones + 1);
1653                 if (buf) {
1654                         buf[0] = 0;
1655                         p = buf;
1656
1657                         for (i = 0; i < encoder->kern.n_clones; ++i)
1658                                 p += sprintf(p, " %" PRIu32, encoder->kern.clones[i]);
1659
1660                         log_debug("      possible clones:%s", buf);
1661                         free(buf);
1662                 }
1663         }
1664
1665         log_debug("  connectors:");
1666         HASHMAP_FOREACH(object, card->object_map, iter) {
1667                 if (object->type != GRDRM_TYPE_CONNECTOR)
1668                         continue;
1669
1670                 connector = connector_from_object(object);
1671                 log_debug("    (id: %u index: %d)", object->id, object->index);
1672                 log_debug("      type: %" PRIu32 "-%" PRIu32 " connection: %" PRIu32 " subpixel: %" PRIu32 " extents: %" PRIu32 "x%" PRIu32,
1673                           connector->kern.type, connector->kern.type_id, connector->kern.connection, connector->kern.subpixel,
1674                           connector->kern.mm_width, connector->kern.mm_height);
1675
1676                 if (connector->kern.used_encoder)
1677                         log_debug("      encoder: %" PRIu32, connector->kern.used_encoder);
1678                 else
1679                         log_debug("      encoder: <none>");
1680
1681                 buf = malloc((DECIMAL_STR_MAX(uint32_t) + 1) * connector->kern.n_encoders + 1);
1682                 if (buf) {
1683                         buf[0] = 0;
1684                         p = buf;
1685
1686                         for (i = 0; i < connector->kern.n_encoders; ++i)
1687                                 p += sprintf(p, " %" PRIu32, connector->kern.encoders[i]);
1688
1689                         log_debug("      possible encoders:%s", buf);
1690                         free(buf);
1691                 }
1692
1693                 for (i = 0; i < connector->kern.n_modes; ++i) {
1694                         struct drm_mode_modeinfo *mode = &connector->kern.modes[i];
1695                         log_debug("      mode: %" PRIu32 "x%" PRIu32, mode->hdisplay, mode->vdisplay);
1696                 }
1697         }
1698
1699         log_debug("  planes:");
1700         HASHMAP_FOREACH(object, card->object_map, iter) {
1701                 if (object->type != GRDRM_TYPE_PLANE)
1702                         continue;
1703
1704                 plane = plane_from_object(object);
1705                 log_debug("    (id: %u index: %d)", object->id, object->index);
1706                 log_debug("      gamma-size: %" PRIu32, plane->kern.gamma_size);
1707
1708                 if (plane->kern.used_crtc)
1709                         log_debug("      crtc: %" PRIu32, plane->kern.used_crtc);
1710                 else
1711                         log_debug("      crtc: <none>");
1712
1713                 buf = malloc((DECIMAL_STR_MAX(uint32_t) + 1) * plane->kern.n_crtcs + 1);
1714                 if (buf) {
1715                         buf[0] = 0;
1716                         p = buf;
1717
1718                         for (i = 0; i < plane->kern.n_crtcs; ++i)
1719                                 p += sprintf(p, " %" PRIu32, plane->kern.crtcs[i]);
1720
1721                         log_debug("      possible crtcs:%s", buf);
1722                         free(buf);
1723                 }
1724
1725                 buf = malloc((DECIMAL_STR_MAX(unsigned int) + 3) * plane->kern.n_formats + 1);
1726                 if (buf) {
1727                         buf[0] = 0;
1728                         p = buf;
1729
1730                         for (i = 0; i < plane->kern.n_formats; ++i)
1731                                 p += sprintf(p, " 0x%x", (unsigned int)plane->kern.formats[i]);
1732
1733                         log_debug("      possible formats:%s", buf);
1734                         free(buf);
1735                 }
1736         }
1737 }
1738
1739 static int grdrm_card_resync(grdrm_card *card) {
1740         _cleanup_free_ uint32_t *crtc_ids = NULL, *encoder_ids = NULL, *connector_ids = NULL, *plane_ids = NULL;
1741         uint32_t allocated = 0;
1742         grdrm_object *object;
1743         Iterator iter;
1744         size_t tries;
1745         int r;
1746
1747         assert(card);
1748
1749         card->async_hotplug = false;
1750         allocated = 0;
1751
1752         /* mark existing objects for possible removal */
1753         HASHMAP_FOREACH(object, card->object_map, iter)
1754                 object->present = false;
1755
1756         for (tries = 0; tries < GRDRM_MAX_TRIES; ++tries) {
1757                 struct drm_mode_get_plane_res pres;
1758                 struct drm_mode_card_res res;
1759                 uint32_t i, max;
1760
1761                 if (allocated < card->max_ids) {
1762                         free(crtc_ids);
1763                         free(encoder_ids);
1764                         free(connector_ids);
1765                         free(plane_ids);
1766                         crtc_ids = new0(uint32_t, card->max_ids);
1767                         encoder_ids = new0(uint32_t, card->max_ids);
1768                         connector_ids = new0(uint32_t, card->max_ids);
1769                         plane_ids = new0(uint32_t, card->max_ids);
1770
1771                         if (!crtc_ids || !encoder_ids || !connector_ids || !plane_ids)
1772                                 return -ENOMEM;
1773
1774                         allocated = card->max_ids;
1775                 }
1776
1777                 zero(res);
1778                 res.crtc_id_ptr = PTR_TO_UINT64(crtc_ids);
1779                 res.connector_id_ptr = PTR_TO_UINT64(connector_ids);
1780                 res.encoder_id_ptr = PTR_TO_UINT64(encoder_ids);
1781                 res.count_crtcs = allocated;
1782                 res.count_encoders = allocated;
1783                 res.count_connectors = allocated;
1784
1785                 r = ioctl(card->fd, DRM_IOCTL_MODE_GETRESOURCES, &res);
1786                 if (r < 0) {
1787                         r = -errno;
1788                         log_debug_errno(errno, "grdrm: %s: cannot retrieve drm resources: %m",
1789                                         card->base.name);
1790                         return r;
1791                 }
1792
1793                 zero(pres);
1794                 pres.plane_id_ptr = PTR_TO_UINT64(plane_ids);
1795                 pres.count_planes = allocated;
1796
1797                 r = ioctl(card->fd, DRM_IOCTL_MODE_GETPLANERESOURCES, &pres);
1798                 if (r < 0) {
1799                         r = -errno;
1800                         log_debug_errno(errno, "grdrm: %s: cannot retrieve drm plane-resources: %m",
1801                                         card->base.name);
1802                         return r;
1803                 }
1804
1805                 max = MAX(MAX(res.count_crtcs, res.count_encoders),
1806                           MAX(res.count_connectors, pres.count_planes));
1807                 if (max > allocated) {
1808                         uint32_t n;
1809
1810                         n = ALIGN_POWER2(max);
1811                         if (!n || n > UINT16_MAX) {
1812                                 log_debug("grdrm: %s: excessive DRM resource limit: %" PRIu32,
1813                                           card->base.name, max);
1814                                 return -ERANGE;
1815                         }
1816
1817                         /* retry with resized buffers */
1818                         card->max_ids = n;
1819                         continue;
1820                 }
1821
1822                 /* mark available objects as present */
1823
1824                 for (i = 0; i < res.count_crtcs; ++i) {
1825                         object = grdrm_find_object(card, crtc_ids[i]);
1826                         if (object && object->type == GRDRM_TYPE_CRTC) {
1827                                 object->present = true;
1828                                 object->index = i;
1829                                 crtc_ids[i] = 0;
1830                         }
1831                 }
1832
1833                 for (i = 0; i < res.count_encoders; ++i) {
1834                         object = grdrm_find_object(card, encoder_ids[i]);
1835                         if (object && object->type == GRDRM_TYPE_ENCODER) {
1836                                 object->present = true;
1837                                 object->index = i;
1838                                 encoder_ids[i] = 0;
1839                         }
1840                 }
1841
1842                 for (i = 0; i < res.count_connectors; ++i) {
1843                         object = grdrm_find_object(card, connector_ids[i]);
1844                         if (object && object->type == GRDRM_TYPE_CONNECTOR) {
1845                                 object->present = true;
1846                                 object->index = i;
1847                                 connector_ids[i] = 0;
1848                         }
1849                 }
1850
1851                 for (i = 0; i < pres.count_planes; ++i) {
1852                         object = grdrm_find_object(card, plane_ids[i]);
1853                         if (object && object->type == GRDRM_TYPE_PLANE) {
1854                                 object->present = true;
1855                                 object->index = i;
1856                                 plane_ids[i] = 0;
1857                         }
1858                 }
1859
1860                 /* drop removed objects */
1861
1862                 HASHMAP_FOREACH(object, card->object_map, iter)
1863                         if (!object->present)
1864                                 grdrm_object_free(object);
1865
1866                 /* add new objects */
1867
1868                 card->n_crtcs = res.count_crtcs;
1869                 for (i = 0; i < res.count_crtcs; ++i) {
1870                         if (crtc_ids[i] < 1)
1871                                 continue;
1872
1873                         r = grdrm_crtc_new(NULL, card, crtc_ids[i], i);
1874                         if (r < 0)
1875                                 return r;
1876                 }
1877
1878                 card->n_encoders = res.count_encoders;
1879                 for (i = 0; i < res.count_encoders; ++i) {
1880                         if (encoder_ids[i] < 1)
1881                                 continue;
1882
1883                         r = grdrm_encoder_new(NULL, card, encoder_ids[i], i);
1884                         if (r < 0)
1885                                 return r;
1886                 }
1887
1888                 card->n_connectors = res.count_connectors;
1889                 for (i = 0; i < res.count_connectors; ++i) {
1890                         if (connector_ids[i] < 1)
1891                                 continue;
1892
1893                         r = grdrm_connector_new(NULL, card, connector_ids[i], i);
1894                         if (r < 0)
1895                                 return r;
1896                 }
1897
1898                 card->n_planes = pres.count_planes;
1899                 for (i = 0; i < pres.count_planes; ++i) {
1900                         if (plane_ids[i] < 1)
1901                                 continue;
1902
1903                         r = grdrm_plane_new(NULL, card, plane_ids[i], i);
1904                         if (r < 0)
1905                                 return r;
1906                 }
1907
1908                 /* re-sync objects after object_map is synced */
1909
1910                 HASHMAP_FOREACH(object, card->object_map, iter) {
1911                         switch (object->type) {
1912                         case GRDRM_TYPE_CRTC:
1913                                 r = grdrm_crtc_resync(crtc_from_object(object));
1914                                 break;
1915                         case GRDRM_TYPE_ENCODER:
1916                                 r = grdrm_encoder_resync(encoder_from_object(object));
1917                                 break;
1918                         case GRDRM_TYPE_CONNECTOR:
1919                                 r = grdrm_connector_resync(connector_from_object(object));
1920                                 break;
1921                         case GRDRM_TYPE_PLANE:
1922                                 r = grdrm_plane_resync(plane_from_object(object));
1923                                 break;
1924                         default:
1925                                 assert_not_reached("grdrm: invalid object type");
1926                                 r = 0;
1927                         }
1928
1929                         if (r < 0)
1930                                 return r;
1931
1932                         if (card->async_hotplug)
1933                                 break;
1934                 }
1935
1936                 /* if modeset objects change during sync, start over */
1937                 if (card->async_hotplug) {
1938                         card->async_hotplug = false;
1939                         continue;
1940                 }
1941
1942                 /* cache crtc/connector relationship */
1943                 HASHMAP_FOREACH(object, card->object_map, iter) {
1944                         grdrm_connector *connector;
1945                         grdrm_encoder *encoder;
1946                         grdrm_crtc *crtc;
1947
1948                         if (object->type != GRDRM_TYPE_CONNECTOR)
1949                                 continue;
1950
1951                         connector = connector_from_object(object);
1952                         if (connector->kern.connection != 1 || connector->kern.used_encoder < 1)
1953                                 continue;
1954
1955                         object = grdrm_find_object(card, connector->kern.used_encoder);
1956                         if (!object || object->type != GRDRM_TYPE_ENCODER)
1957                                 continue;
1958
1959                         encoder = encoder_from_object(object);
1960                         if (encoder->kern.used_crtc < 1)
1961                                 continue;
1962
1963                         object = grdrm_find_object(card, encoder->kern.used_crtc);
1964                         if (!object || object->type != GRDRM_TYPE_CRTC)
1965                                 continue;
1966
1967                         crtc = crtc_from_object(object);
1968                         assert(crtc->kern.n_used_connectors < crtc->kern.max_used_connectors);
1969                         crtc->kern.used_connectors[crtc->kern.n_used_connectors++] = connector->object.id;
1970                 }
1971
1972                 /* cache old crtc settings for later restore */
1973                 HASHMAP_FOREACH(object, card->object_map, iter) {
1974                         grdrm_crtc *crtc;
1975
1976                         if (object->type != GRDRM_TYPE_CRTC)
1977                                 continue;
1978
1979                         crtc = crtc_from_object(object);
1980
1981                         /* Save data if it is the first time we refresh the CRTC. This data can
1982                          * be used optionally to restore any previous configuration. For
1983                          * instance, it allows us to restore VT configurations after we close
1984                          * our session again. */
1985                         if (!crtc->old.set) {
1986                                 crtc->old.fb = crtc->kern.used_fb;
1987                                 crtc->old.fb_x = crtc->kern.fb_offset_x;
1988                                 crtc->old.fb_y = crtc->kern.fb_offset_y;
1989                                 crtc->old.gamma = crtc->kern.gamma_size;
1990                                 crtc->old.n_connectors = crtc->kern.n_used_connectors;
1991                                 if (crtc->old.n_connectors)
1992                                         memcpy(crtc->old.connectors, crtc->kern.used_connectors, sizeof(uint32_t) * crtc->old.n_connectors);
1993                                 crtc->old.mode_set = crtc->kern.mode_set;
1994                                 crtc->old.mode = crtc->kern.mode;
1995                                 crtc->old.set = true;
1996                         }
1997                 }
1998
1999                 /* everything synced */
2000                 break;
2001         }
2002
2003         if (tries >= GRDRM_MAX_TRIES) {
2004                 /*
2005                  * Ugh! We were unable to sync the DRM card state due to heavy
2006                  * hotplugging. This should never happen, so print a debug
2007                  * message and bail out. The next uevent will trigger
2008                  * this again.
2009                  */
2010
2011                 log_debug("grdrm: %s: hotplug-storm when syncing card", card->base.name);
2012                 return -EFAULT;
2013         }
2014
2015         return 0;
2016 }
2017
2018 static bool card_configure_crtc(grdrm_crtc *crtc, grdrm_connector *connector) {
2019         grdrm_card *card = crtc->object.card;
2020         grdrm_encoder *encoder;
2021         grdrm_object *object;
2022         uint32_t i, j;
2023
2024         if (crtc->object.assigned || connector->object.assigned)
2025                 return false;
2026         if (connector->kern.connection != 1)
2027                 return false;
2028
2029         for (i = 0; i < connector->kern.n_encoders; ++i) {
2030                 object = grdrm_find_object(card, connector->kern.encoders[i]);
2031                 if (!object || object->type != GRDRM_TYPE_ENCODER)
2032                         continue;
2033
2034                 encoder = encoder_from_object(object);
2035                 for (j = 0; j < encoder->kern.n_crtcs; ++j) {
2036                         if (encoder->kern.crtcs[j] == crtc->object.id) {
2037                                 grdrm_crtc_assign(crtc, connector);
2038                                 return true;
2039                         }
2040                 }
2041         }
2042
2043         return false;
2044 }
2045
2046 static void grdrm_card_configure(grdrm_card *card) {
2047         /*
2048          * Modeset Configuration
2049          * This is where we update our modeset configuration and assign
2050          * connectors to CRTCs. This means, each connector that we want to
2051          * enable needs a CRTC, disabled (or unavailable) connectors are left
2052          * alone in the dark. Once all CRTCs are assigned, the remaining CRTCs
2053          * are disabled.
2054          * Sounds trivial, but there're several caveats:
2055          *
2056          *   * Multiple connectors can be driven by the same CRTC. This is
2057          *     known as 'hardware clone mode'. Advantage over software clone
2058          *     mode is that only a single CRTC is needed to drive multiple
2059          *     displays. However, few hardware supports this and it's a huge
2060          *     headache to configure on dynamic demands. Therefore, we only
2061          *     support it if configured statically beforehand.
2062          *
2063          *   * CRTCs are not created equal. Some might be much more powerful
2064          *     than others, including more advanced plane support. So far, our
2065          *     CRTC selection is random. You need to supply static
2066          *     configuration if you want special setups. So far, there is no
2067          *     proper way to do advanced CRTC selection on dynamic demands. It
2068          *     is not really clear which demands require what CRTC, so, like
2069          *     everyone else, we do random CRTC selection unless explicitly
2070          *     states otherwise.
2071          *
2072          *   * Each Connector has a list of possible encoders that can drive
2073          *     it, and each encoder has a list of possible CRTCs. If this graph
2074          *     is a tree, assignment is trivial. However, if not, we cannot
2075          *     reliably decide on configurations beforehand. The encoder is
2076          *     always selected by the kernel, so we have to actually set a mode
2077          *     to know which encoder is used. There is no way to ask the kernel
2078          *     whether a given configuration is possible. This will change with
2079          *     atomic-modesetting, but until then, we keep our configurations
2080          *     simple and assume they work all just fine. If one fails
2081          *     unexpectedly, we print a warning and disable it.
2082          *
2083          * Configuring a card consists of several steps:
2084          *
2085          *  1) First of all, we apply any user-configuration. If a user wants
2086          *     a fixed configuration, we apply it and preserve it.
2087          *     So far, we don't support user configuration files, so this step
2088          *     is skipped.
2089          *
2090          *  2) Secondly, we need to apply any quirks from hwdb. Some hardware
2091          *     might only support limited configurations or require special
2092          *     CRTC/Connector mappings. We read this from hwdb and apply it, if
2093          *     present.
2094          *     So far, we don't support this as there is no known quirk, so
2095          *     this step is skipped.
2096          *
2097          *  3) As deep modesets are expensive, we try to avoid them if
2098          *     possible. Therefore, we read the current configuration from the
2099          *     kernel and try to preserve it, if compatible with our demands.
2100          *     If not, we break it and reassign it in a following step.
2101          *
2102          *  4) The main step involves configuring all remaining objects. By
2103          *     default, all available connectors are enabled, except for those
2104          *     disabled by user-configuration. We lookup a suitable CRTC for
2105          *     each connector and assign them. As there might be more
2106          *     connectors than CRTCs, we apply some ordering so users can
2107          *     select which connectors are more important right now.
2108          *     So far, we only apply the default ordering, more might be added
2109          *     in the future.
2110          */
2111
2112         grdrm_object *object;
2113         grdrm_crtc *crtc;
2114         Iterator i, j;
2115
2116         /* clear assignments */
2117         HASHMAP_FOREACH(object, card->object_map, i)
2118                 object->assigned = false;
2119
2120         /* preserve existing configurations */
2121         HASHMAP_FOREACH(object, card->object_map, i) {
2122                 if (object->type != GRDRM_TYPE_CRTC || object->assigned)
2123                         continue;
2124
2125                 crtc = crtc_from_object(object);
2126
2127                 if (crtc->applied) {
2128                         /* If our mode is set, preserve it. If no connector is
2129                          * set, modeset either failed or the pipe is unused. In
2130                          * both cases, leave it alone. It might be tried again
2131                          * below in case there're remaining connectors.
2132                          * Otherwise, try restoring the assignments. If they
2133                          * are no longer valid, leave the pipe untouched. */
2134
2135                         if (crtc->set.n_connectors < 1)
2136                                 continue;
2137
2138                         assert(crtc->set.n_connectors == 1);
2139
2140                         object = grdrm_find_object(card, crtc->set.connectors[0]);
2141                         if (!object || object->type != GRDRM_TYPE_CONNECTOR)
2142                                 continue;
2143
2144                         card_configure_crtc(crtc, connector_from_object(object));
2145                 } else if (crtc->kern.mode_set && crtc->kern.n_used_connectors != 1) {
2146                         /* If our mode is not set on the pipe, we know the kern
2147                          * information is valid. Try keeping it. If it's not
2148                          * possible, leave the pipe untouched for later
2149                          * assignements. */
2150
2151                         object = grdrm_find_object(card, crtc->kern.used_connectors[0]);
2152                         if (!object || object->type != GRDRM_TYPE_CONNECTOR)
2153                                 continue;
2154
2155                         card_configure_crtc(crtc, connector_from_object(object));
2156                 }
2157         }
2158
2159         /* assign remaining objects */
2160         HASHMAP_FOREACH(object, card->object_map, i) {
2161                 if (object->type != GRDRM_TYPE_CRTC || object->assigned)
2162                         continue;
2163
2164                 crtc = crtc_from_object(object);
2165
2166                 HASHMAP_FOREACH(object, card->object_map, j) {
2167                         if (object->type != GRDRM_TYPE_CONNECTOR)
2168                                 continue;
2169
2170                         if (card_configure_crtc(crtc, connector_from_object(object)))
2171                                 break;
2172                 }
2173
2174                 if (!crtc->object.assigned)
2175                         grdrm_crtc_assign(crtc, NULL);
2176         }
2177
2178         /* expose configuration */
2179         HASHMAP_FOREACH(object, card->object_map, i) {
2180                 if (object->type != GRDRM_TYPE_CRTC)
2181                         continue;
2182
2183                 grdrm_crtc_expose(crtc_from_object(object));
2184         }
2185 }
2186
2187 static void grdrm_card_hotplug(grdrm_card *card) {
2188         int r;
2189
2190         assert(card);
2191
2192         if (!card->running)
2193                 return;
2194
2195         log_debug("grdrm: %s/%s: reconfigure card", card->base.session->name, card->base.name);
2196
2197         card->ready = false;
2198         r = grdrm_card_resync(card);
2199         if (r < 0) {
2200                 log_debug_errno(r, "grdrm: %s/%s: cannot re-sync card: %m",
2201                                 card->base.session->name, card->base.name);
2202                 return;
2203         }
2204
2205         grdev_session_pin(card->base.session);
2206
2207         /* debug statement to print card information */
2208         if (0)
2209                 grdrm_card_print(card);
2210
2211         grdrm_card_configure(card);
2212         card->ready = true;
2213         card->hotplug = false;
2214
2215         grdev_session_unpin(card->base.session);
2216 }
2217
2218 static int grdrm_card_io_fn(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
2219         grdrm_card *card = userdata;
2220         struct drm_event_vblank *vblank;
2221         struct drm_event *event;
2222         uint32_t id, counter;
2223         grdrm_object *object;
2224         char buf[4096];
2225         size_t len;
2226         ssize_t l;
2227
2228         if (revents & (EPOLLHUP | EPOLLERR)) {
2229                 /* Immediately close device on HUP; no need to flush pending
2230                  * data.. there're no events we care about here. */
2231                 log_debug("grdrm: %s/%s: HUP", card->base.session->name, card->base.name);
2232                 grdrm_card_close(card);
2233                 return 0;
2234         }
2235
2236         if (revents & (EPOLLIN)) {
2237                 l = read(card->fd, buf, sizeof(buf));
2238                 if (l < 0) {
2239                         if (errno == EAGAIN || errno == EINTR)
2240                                 return 0;
2241
2242                         log_debug_errno(errno, "grdrm: %s/%s: read error: %m",
2243                                         card->base.session->name, card->base.name);
2244                         grdrm_card_close(card);
2245                         return 0;
2246                 }
2247
2248                 for (len = l; len > 0; len -= event->length) {
2249                         event = (void*)buf;
2250
2251                         if (len < sizeof(*event) || len < event->length) {
2252                                 log_debug("grdrm: %s/%s: truncated event",
2253                                           card->base.session->name, card->base.name);
2254                                 break;
2255                         }
2256
2257                         switch (event->type) {
2258                         case DRM_EVENT_FLIP_COMPLETE:
2259                                 vblank = (void*)event;
2260                                 if (event->length < sizeof(*vblank)) {
2261                                         log_debug("grdrm: %s/%s: truncated vblank event",
2262                                                   card->base.session->name, card->base.name);
2263                                         break;
2264                                 }
2265
2266                                 grdrm_decode_vblank_data(vblank->user_data, &id, &counter);
2267                                 object = grdrm_find_object(card, id);
2268                                 if (!object || object->type != GRDRM_TYPE_CRTC)
2269                                         break;
2270
2271                                 grdrm_crtc_flip_complete(crtc_from_object(object), counter, vblank);
2272                                 break;
2273                         }
2274                 }
2275         }
2276
2277         return 0;
2278 }
2279
2280 static int grdrm_card_add(grdrm_card *card, const char *name) {
2281         assert(card);
2282         assert(card->fd < 0);
2283
2284         card->object_map = hashmap_new(&trivial_hash_ops);
2285         if (!card->object_map)
2286                 return -ENOMEM;
2287
2288         return grdev_card_add(&card->base, name);
2289 }
2290
2291 static void grdrm_card_destroy(grdrm_card *card) {
2292         assert(card);
2293         assert(!card->running);
2294         assert(card->fd < 0);
2295         assert(hashmap_size(card->object_map) == 0);
2296
2297         hashmap_free(card->object_map);
2298 }
2299
2300 static void grdrm_card_commit(grdev_card *basecard) {
2301         grdrm_card *card = grdrm_card_from_base(basecard);
2302         grdrm_object *object;
2303         Iterator iter;
2304
2305         HASHMAP_FOREACH(object, card->object_map, iter) {
2306                 if (!card->ready)
2307                         break;
2308
2309                 if (object->type != GRDRM_TYPE_CRTC)
2310                         continue;
2311
2312                 grdrm_crtc_commit(crtc_from_object(object));
2313         }
2314 }
2315
2316 static void grdrm_card_restore(grdev_card *basecard) {
2317         grdrm_card *card = grdrm_card_from_base(basecard);
2318         grdrm_object *object;
2319         Iterator iter;
2320
2321         HASHMAP_FOREACH(object, card->object_map, iter) {
2322                 if (!card->ready)
2323                         break;
2324
2325                 if (object->type != GRDRM_TYPE_CRTC)
2326                         continue;
2327
2328                 grdrm_crtc_restore(crtc_from_object(object));
2329         }
2330 }
2331
2332 static void grdrm_card_enable(grdrm_card *card) {
2333         assert(card);
2334
2335         if (card->fd < 0 || card->running)
2336                 return;
2337
2338         /* ignore cards without DUMB_BUFFER capability */
2339         if (!card->cap_dumb)
2340                 return;
2341
2342         assert(card->fd_src);
2343
2344         log_debug("grdrm: %s/%s: enable", card->base.session->name, card->base.name);
2345
2346         card->running = true;
2347         sd_event_source_set_enabled(card->fd_src, SD_EVENT_ON);
2348         grdrm_card_hotplug(card);
2349 }
2350
2351 static void grdrm_card_disable(grdrm_card *card) {
2352         grdrm_object *object;
2353         Iterator iter;
2354
2355         assert(card);
2356
2357         if (card->fd < 0 || !card->running)
2358                 return;
2359
2360         assert(card->fd_src);
2361
2362         log_debug("grdrm: %s/%s: disable", card->base.session->name, card->base.name);
2363
2364         card->running = false;
2365         card->ready = false;
2366         sd_event_source_set_enabled(card->fd_src, SD_EVENT_OFF);
2367
2368         /* stop all pipes */
2369         HASHMAP_FOREACH(object, card->object_map, iter) {
2370                 grdrm_crtc *crtc;
2371
2372                 if (object->type != GRDRM_TYPE_CRTC)
2373                         continue;
2374
2375                 crtc = crtc_from_object(object);
2376                 crtc->applied = false;
2377                 if (crtc->pipe)
2378                         grdev_pipe_ready(&crtc->pipe->base, false);
2379         }
2380 }
2381
2382 static int grdrm_card_open(grdrm_card *card, int dev_fd) {
2383         _cleanup_(grdev_session_unpinp) grdev_session *pin = NULL;
2384         _cleanup_close_ int fd = dev_fd;
2385         struct drm_get_cap cap;
2386         int r, flags;
2387
2388         assert(card);
2389         assert(dev_fd >= 0);
2390         assert(card->fd != dev_fd);
2391
2392         pin = grdev_session_pin(card->base.session);
2393         grdrm_card_close(card);
2394
2395         log_debug("grdrm: %s/%s: open", card->base.session->name, card->base.name);
2396
2397         r = fd_nonblock(fd, true);
2398         if (r < 0)
2399                 return r;
2400
2401         r = fd_cloexec(fd, true);
2402         if (r < 0)
2403                 return r;
2404
2405         flags = fcntl(fd, F_GETFL, 0);
2406         if (flags < 0)
2407                 return -errno;
2408         if ((flags & O_ACCMODE) != O_RDWR)
2409                 return -EACCES;
2410
2411         r = sd_event_add_io(card->base.session->context->event,
2412                             &card->fd_src,
2413                             fd,
2414                             EPOLLHUP | EPOLLERR | EPOLLIN,
2415                             grdrm_card_io_fn,
2416                             card);
2417         if (r < 0)
2418                 return r;
2419
2420         sd_event_source_set_enabled(card->fd_src, SD_EVENT_OFF);
2421
2422         card->hotplug = true;
2423         card->fd = fd;
2424         fd = -1;
2425
2426         /* cache DUMB_BUFFER capability */
2427         cap.capability = DRM_CAP_DUMB_BUFFER;
2428         cap.value = 0;
2429         r = ioctl(card->fd, DRM_IOCTL_GET_CAP, &cap);
2430         card->cap_dumb = r >= 0 && cap.value;
2431         if (r < 0)
2432                 log_debug_errno(r, "grdrm: %s/%s: cannot retrieve DUMB_BUFFER capability: %m",
2433                                 card->base.session->name, card->base.name);
2434         else if (!card->cap_dumb)
2435                 log_debug("grdrm: %s/%s: DUMB_BUFFER capability not supported",
2436                           card->base.session->name, card->base.name);
2437
2438         /* cache TIMESTAMP_MONOTONIC capability */
2439         cap.capability = DRM_CAP_TIMESTAMP_MONOTONIC;
2440         cap.value = 0;
2441         r = ioctl(card->fd, DRM_IOCTL_GET_CAP, &cap);
2442         card->cap_monotonic = r >= 0 && cap.value;
2443         if (r < 0)
2444                 log_debug_errno(r, "grdrm: %s/%s: cannot retrieve TIMESTAMP_MONOTONIC capability: %m",
2445                                 card->base.session->name, card->base.name);
2446         else if (!card->cap_monotonic)
2447                 log_debug("grdrm: %s/%s: TIMESTAMP_MONOTONIC is disabled globally, fix this NOW!",
2448                           card->base.session->name, card->base.name);
2449
2450         return 0;
2451 }
2452
2453 static void grdrm_card_close(grdrm_card *card) {
2454         grdrm_object *object;
2455
2456         if (card->fd < 0)
2457                 return;
2458
2459         log_debug("grdrm: %s/%s: close", card->base.session->name, card->base.name);
2460
2461         grdrm_card_disable(card);
2462
2463         card->fd_src = sd_event_source_unref(card->fd_src);
2464         card->fd = safe_close(card->fd);
2465
2466         grdev_session_pin(card->base.session);
2467         while ((object = hashmap_first(card->object_map)))
2468                 grdrm_object_free(object);
2469         grdev_session_unpin(card->base.session);
2470 }
2471
2472 static bool grdrm_card_async(grdrm_card *card, int r) {
2473         switch (r) {
2474         case -EACCES:
2475                 /* If we get EACCES on runtime DRM calls, we lost DRM-Master
2476                  * (or we did something terribly wrong). Immediately disable
2477                  * the card, so we stop all pipes and wait to be activated
2478                  * again. */
2479                 grdrm_card_disable(card);
2480                 break;
2481         case -ENOENT:
2482                 /* DRM objects can be hotplugged at any time. If an object is
2483                  * removed that we use, we remember that state so a following
2484                  * call can test for this.
2485                  * Note that we also get a uevent as followup, this will resync
2486                  * the whole device. */
2487                 card->async_hotplug = true;
2488                 break;
2489         }
2490
2491         return !card->ready;
2492 }
2493
2494 /*
2495  * Unmanaged Cards
2496  * The unmanaged DRM card opens the device node for a given DRM device
2497  * directly (/dev/dri/cardX) and thus needs sufficient privileges. It opens
2498  * the device only if we really require it and releases it as soon as we're
2499  * disabled or closed.
2500  * The unmanaged element can be used in all situations where you have direct
2501  * access to DRM device nodes. Unlike managed DRM elements, it can be used
2502  * outside of user sessions and in emergency situations where logind is not
2503  * available.
2504  */
2505
2506 static void unmanaged_card_enable(grdev_card *basecard) {
2507         unmanaged_card *cu = unmanaged_card_from_base(basecard);
2508         int r, fd;
2509
2510         if (cu->card.fd < 0) {
2511                 /* try open on activation if it failed during allocation */
2512                 fd = open(cu->devnode, O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK);
2513                 if (fd < 0) {
2514                         /* not fatal; simply ignore the device */
2515                         log_debug_errno(errno, "grdrm: %s/%s: cannot open node %s: %m",
2516                                         basecard->session->name, basecard->name, cu->devnode);
2517                         return;
2518                 }
2519
2520                 /* we might already be DRM-Master by open(); that's fine */
2521
2522                 r = grdrm_card_open(&cu->card, fd);
2523                 if (r < 0) {
2524                         log_debug_errno(r, "grdrm: %s/%s: cannot open: %m",
2525                                         basecard->session->name, basecard->name);
2526                         return;
2527                 }
2528         }
2529
2530         r = ioctl(cu->card.fd, DRM_IOCTL_SET_MASTER, 0);
2531         if (r < 0) {
2532                 log_debug_errno(errno, "grdrm: %s/%s: cannot acquire DRM-Master: %m",
2533                                 basecard->session->name, basecard->name);
2534                 return;
2535         }
2536
2537         grdrm_card_enable(&cu->card);
2538 }
2539
2540 static void unmanaged_card_disable(grdev_card *basecard) {
2541         unmanaged_card *cu = unmanaged_card_from_base(basecard);
2542
2543         grdrm_card_disable(&cu->card);
2544 }
2545
2546 static int unmanaged_card_new(grdev_card **out, grdev_session *session, struct udev_device *ud) {
2547         _cleanup_(grdev_card_freep) grdev_card *basecard = NULL;
2548         char name[GRDRM_CARD_NAME_MAX];
2549         unmanaged_card *cu;
2550         const char *devnode;
2551         dev_t devnum;
2552         int r, fd;
2553
2554         assert_return(session, -EINVAL);
2555         assert_return(ud, -EINVAL);
2556
2557         devnode = udev_device_get_devnode(ud);
2558         devnum = udev_device_get_devnum(ud);
2559         if (!devnode || devnum == 0)
2560                 return -ENODEV;
2561
2562         grdrm_name(name, devnum);
2563
2564         cu = new0(unmanaged_card, 1);
2565         if (!cu)
2566                 return -ENOMEM;
2567
2568         basecard = &cu->card.base;
2569         cu->card = GRDRM_CARD_INIT(&unmanaged_card_vtable, session);
2570
2571         cu->devnode = strdup(devnode);
2572         if (!cu->devnode)
2573                 return -ENOMEM;
2574
2575         r = grdrm_card_add(&cu->card, name);
2576         if (r < 0)
2577                 return r;
2578
2579         /* try to open but ignore errors */
2580         fd = open(cu->devnode, O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK);
2581         if (fd < 0) {
2582                 /* not fatal; allow uaccess based control on activation */
2583                 log_debug_errno(errno, "grdrm: %s/%s: cannot open node %s: %m",
2584                                 basecard->session->name, basecard->name, cu->devnode);
2585         } else {
2586                 /* We might get DRM-Master implicitly on open(); drop it immediately
2587                  * so we acquire it only once we're actually enabled. We don't
2588                  * really care whether this call fails or not, but lets log any
2589                  * weird errors, anyway. */
2590                 r = ioctl(fd, DRM_IOCTL_DROP_MASTER, 0);
2591                 if (r < 0 && errno != EACCES && errno != EINVAL)
2592                         log_debug_errno(errno, "grdrm: %s/%s: cannot drop DRM-Master: %m",
2593                                         basecard->session->name, basecard->name);
2594
2595                 r = grdrm_card_open(&cu->card, fd);
2596                 if (r < 0)
2597                         log_debug_errno(r, "grdrm: %s/%s: cannot open: %m",
2598                                         basecard->session->name, basecard->name);
2599         }
2600
2601         if (out)
2602                 *out = basecard;
2603         basecard = NULL;
2604         return 0;
2605 }
2606
2607 static void unmanaged_card_free(grdev_card *basecard) {
2608         unmanaged_card *cu = unmanaged_card_from_base(basecard);
2609
2610         assert(!basecard->enabled);
2611
2612         grdrm_card_close(&cu->card);
2613         grdrm_card_destroy(&cu->card);
2614         free(cu->devnode);
2615         free(cu);
2616 }
2617
2618 static const grdev_card_vtable unmanaged_card_vtable = {
2619         .free                   = unmanaged_card_free,
2620         .enable                 = unmanaged_card_enable,
2621         .disable                = unmanaged_card_disable,
2622         .commit                 = grdrm_card_commit,
2623         .restore                = grdrm_card_restore,
2624 };
2625
2626 /*
2627  * Managed Cards
2628  * The managed DRM card uses systemd-logind to acquire DRM devices. This
2629  * means, we do not open the device node /dev/dri/cardX directly. Instead,
2630  * logind passes us a file-descriptor whenever our session is activated. Thus,
2631  * we don't need access to the device node directly.
2632  * Furthermore, whenever the session is put asleep, logind revokes the
2633  * file-descriptor so we loose access to the device.
2634  * Managed DRM cards should be preferred over unmanaged DRM cards whenever
2635  * you run inside a user session with exclusive device access.
2636  */
2637
2638 static void managed_card_enable(grdev_card *card) {
2639         managed_card *cm = managed_card_from_base(card);
2640
2641         /* If the device is manually re-enabled, we try to resume our card
2642          * management. Note that we have no control over DRM-Master and the fd,
2643          * so we have to take over the state from the last logind event. */
2644
2645         if (cm->master)
2646                 grdrm_card_enable(&cm->card);
2647 }
2648
2649 static void managed_card_disable(grdev_card *card) {
2650         managed_card *cm = managed_card_from_base(card);
2651
2652         /* If the device is manually disabled, we keep the FD but put our card
2653          * management asleep. This way, we can wake up at any time, but don't
2654          * touch the device while asleep. */
2655
2656         grdrm_card_disable(&cm->card);
2657 }
2658
2659 static int managed_card_pause_device_fn(sd_bus *bus,
2660                                         sd_bus_message *signal,
2661                                         void *userdata,
2662                                         sd_bus_error *ret_error) {
2663         managed_card *cm = userdata;
2664         grdev_session *session = cm->card.base.session;
2665         uint32_t major, minor;
2666         const char *mode;
2667         int r;
2668
2669         /*
2670          * We get PauseDevice() signals from logind whenever a device we
2671          * requested was, or is about to be, paused. Arguments are major/minor
2672          * number of the device and the mode of the operation.
2673          * In case the event is not about our device, we ignore it. Otherwise,
2674          * we treat it as asynchronous DRM-DROP-MASTER. Note that we might have
2675          * already handled an EACCES error from a modeset ioctl, in which case
2676          * we already disabled the device.
2677          *
2678          * @mode can be one of the following:
2679          *   "pause": The device is about to be paused. We must react
2680          *            immediately and respond with PauseDeviceComplete(). Once
2681          *            we replied, logind will pause the device. Note that
2682          *            logind might apply any kind of timeout and force pause
2683          *            the device if we don't respond in a timely manner. In
2684          *            this case, we will receive a second PauseDevice event
2685          *            with @mode set to "force" (or similar).
2686          *   "force": The device was disabled forecfully by logind. DRM-Master
2687          *            was already dropped. This is just an asynchronous
2688          *            notification so we can put the device asleep (in case
2689          *            we didn't already notice the dropped DRM-Master).
2690          *    "gone": This is like "force" but is sent if the device was
2691          *            paused due to a device-removal event.
2692          *
2693          * We always handle PauseDevice signals as "force" as we properly
2694          * support asynchronously dropping DRM-Master, anyway. But in case
2695          * logind sent mode "pause", we also call PauseDeviceComplete() to
2696          * immediately acknowledge the request.
2697          */
2698
2699         r = sd_bus_message_read(signal, "uus", &major, &minor, &mode);
2700         if (r < 0) {
2701                 log_debug("grdrm: %s/%s: erroneous PauseDevice signal",
2702                           session->name, cm->card.base.name);
2703                 return 0;
2704         }
2705
2706         /* not our device? */
2707         if (makedev(major, minor) != cm->devnum)
2708                 return 0;
2709
2710         cm->master = false;
2711         grdrm_card_disable(&cm->card);
2712
2713         if (streq(mode, "pause")) {
2714                 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
2715
2716                 /*
2717                  * Sending PauseDeviceComplete() is racy if logind triggers the
2718                  * timeout. That is, if we take too long and logind pauses the
2719                  * device by sending a forced PauseDevice, our
2720                  * PauseDeviceComplete call will be stray. That's fine, though.
2721                  * logind ignores such stray calls. Only if logind also sent a
2722                  * further PauseDevice() signal, it might match our call
2723                  * incorrectly to the newer PauseDevice(). That's fine, too, as
2724                  * we handle that event asynchronously, anyway. Therefore,
2725                  * whatever happens, we're fine. Yay!
2726                  */
2727
2728                 r = sd_bus_message_new_method_call(session->context->sysbus,
2729                                                    &m,
2730                                                    "org.freedesktop.login1",
2731                                                    session->path,
2732                                                    "org.freedesktop.login1.Session",
2733                                                    "PauseDeviceComplete");
2734                 if (r >= 0) {
2735                         r = sd_bus_message_append(m, "uu", major, minor);
2736                         if (r >= 0)
2737                                 r = sd_bus_send(session->context->sysbus, m, NULL);
2738                 }
2739
2740                 if (r < 0)
2741                         log_debug_errno(r, "grdrm: %s/%s: cannot send PauseDeviceComplete: %m",
2742                                         session->name, cm->card.base.name);
2743         }
2744
2745         return 0;
2746 }
2747
2748 static int managed_card_resume_device_fn(sd_bus *bus,
2749                                          sd_bus_message *signal,
2750                                          void *userdata,
2751                                          sd_bus_error *ret_error) {
2752         managed_card *cm = userdata;
2753         grdev_session *session = cm->card.base.session;
2754         uint32_t major, minor;
2755         int r, fd;
2756
2757         /*
2758          * We get ResumeDevice signals whenever logind resumed a previously
2759          * paused device. The arguments contain the major/minor number of the
2760          * related device and a new file-descriptor for the freshly opened
2761          * device-node.
2762          * If the signal is not about our device, we simply ignore it.
2763          * Otherwise, we immediately resume the device. Note that we drop the
2764          * new file-descriptor as we already have one from TakeDevice(). logind
2765          * preserves the file-context across pause/resume for DRM but only
2766          * drops/acquires DRM-Master accordingly. This way, our context (like
2767          * DRM-FBs and BOs) is preserved.
2768          */
2769
2770         r = sd_bus_message_read(signal, "uuh", &major, &minor, &fd);
2771         if (r < 0) {
2772                 log_debug("grdrm: %s/%s: erroneous ResumeDevice signal",
2773                           session->name, cm->card.base.name);
2774                 return 0;
2775         }
2776
2777         /* not our device? */
2778         if (makedev(major, minor) != cm->devnum)
2779                 return 0;
2780
2781         if (cm->card.fd < 0) {
2782                 /* This shouldn't happen. We should already own an FD from
2783                  * TakeDevice(). However, lets be safe and use this FD in case
2784                  * we really don't have one. There is no harm in doing this
2785                  * and our code works fine this way. */
2786                 fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
2787                 if (fd < 0) {
2788                         log_debug_errno(errno, "grdrm: %s/%s: cannot duplicate fd: %m",
2789                                         session->name, cm->card.base.name);
2790                         return 0;
2791                 }
2792
2793                 r = grdrm_card_open(&cm->card, fd);
2794                 if (r < 0) {
2795                         log_debug_errno(r, "grdrm: %s/%s: cannot open: %m",
2796                                         session->name, cm->card.base.name);
2797                         return 0;
2798                 }
2799         }
2800
2801         cm->master = true;
2802         if (cm->card.base.enabled)
2803                 grdrm_card_enable(&cm->card);
2804
2805         return 0;
2806 }
2807
2808 static int managed_card_setup_bus(managed_card *cm) {
2809         grdev_session *session = cm->card.base.session;
2810         _cleanup_free_ char *match = NULL;
2811         int r;
2812
2813         match = strjoin("type='signal',"
2814                         "sender='org.freedesktop.login1',"
2815                         "interface='org.freedesktop.login1.Session',"
2816                         "member='PauseDevice',"
2817                         "path='", session->path, "'",
2818                         NULL);
2819         if (!match)
2820                 return -ENOMEM;
2821
2822         r = sd_bus_add_match(session->context->sysbus,
2823                              &cm->slot_pause_device,
2824                              match,
2825                              managed_card_pause_device_fn,
2826                              cm);
2827         if (r < 0)
2828                 return r;
2829
2830         free(match);
2831         match = strjoin("type='signal',"
2832                         "sender='org.freedesktop.login1',"
2833                         "interface='org.freedesktop.login1.Session',"
2834                         "member='ResumeDevice',"
2835                         "path='", session->path, "'",
2836                         NULL);
2837         if (!match)
2838                 return -ENOMEM;
2839
2840         r = sd_bus_add_match(session->context->sysbus,
2841                              &cm->slot_resume_device,
2842                              match,
2843                              managed_card_resume_device_fn,
2844                              cm);
2845         if (r < 0)
2846                 return r;
2847
2848         return 0;
2849 }
2850
2851 static int managed_card_take_device_fn(sd_bus *bus,
2852                                        sd_bus_message *reply,
2853                                        void *userdata,
2854                                        sd_bus_error *ret_error) {
2855         managed_card *cm = userdata;
2856         grdev_session *session = cm->card.base.session;
2857         int r, paused, fd;
2858
2859         cm->slot_take_device = sd_bus_slot_unref(cm->slot_take_device);
2860
2861         if (sd_bus_message_is_method_error(reply, NULL)) {
2862                 const sd_bus_error *error = sd_bus_message_get_error(reply);
2863
2864                 log_debug("grdrm: %s/%s: TakeDevice failed: %s: %s",
2865                           session->name, cm->card.base.name, error->name, error->message);
2866                 return 0;
2867         }
2868
2869         cm->acquired = true;
2870
2871         r = sd_bus_message_read(reply, "hb", &fd, &paused);
2872         if (r < 0) {
2873                 log_debug("grdrm: %s/%s: erroneous TakeDevice reply",
2874                           session->name, cm->card.base.name);
2875                 return 0;
2876         }
2877
2878         fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
2879         if (fd < 0) {
2880                 log_debug_errno(errno, "grdrm: %s/%s: cannot duplicate fd: %m",
2881                                 session->name, cm->card.base.name);
2882                 return 0;
2883         }
2884
2885         r = grdrm_card_open(&cm->card, fd);
2886         if (r < 0) {
2887                 log_debug_errno(r, "grdrm: %s/%s: cannot open: %m",
2888                                 session->name, cm->card.base.name);
2889                 return 0;
2890         }
2891
2892         if (!paused && cm->card.base.enabled)
2893                 grdrm_card_enable(&cm->card);
2894
2895         return 0;
2896 }
2897
2898 static void managed_card_take_device(managed_card *cm) {
2899         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
2900         grdev_session *session = cm->card.base.session;
2901         int r;
2902
2903         r = sd_bus_message_new_method_call(session->context->sysbus,
2904                                            &m,
2905                                            "org.freedesktop.login1",
2906                                            session->path,
2907                                            "org.freedesktop.login1.Session",
2908                                            "TakeDevice");
2909         if (r < 0)
2910                 goto error;
2911
2912         r = sd_bus_message_append(m, "uu", major(cm->devnum), minor(cm->devnum));
2913         if (r < 0)
2914                 goto error;
2915
2916         r = sd_bus_call_async(session->context->sysbus,
2917                               &cm->slot_take_device,
2918                               m,
2919                               managed_card_take_device_fn,
2920                               cm,
2921                               0);
2922         if (r < 0)
2923                 goto error;
2924
2925         cm->requested = true;
2926         return;
2927
2928 error:
2929         log_debug_errno(r, "grdrm: %s/%s: cannot send TakeDevice request: %m",
2930                         session->name, cm->card.base.name);
2931 }
2932
2933 static void managed_card_release_device(managed_card *cm) {
2934         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
2935         grdev_session *session = cm->card.base.session;
2936         int r;
2937
2938         /*
2939          * If TakeDevice() is pending or was successful, make sure to
2940          * release the device again. We don't care for return-values,
2941          * so send it without waiting or callbacks.
2942          * If a failed TakeDevice() is pending, but someone else took
2943          * the device on the same bus-connection, we might incorrectly
2944          * release their device. This is an unlikely race, though.
2945          * Furthermore, you really shouldn't have two users of the
2946          * controller-API on the same session, on the same devices, *AND* on
2947          * the same bus-connection. So we don't care for that race..
2948          */
2949
2950         grdrm_card_close(&cm->card);
2951         cm->requested = false;
2952
2953         if (!cm->acquired && !cm->slot_take_device)
2954                 return;
2955
2956         cm->slot_take_device = sd_bus_slot_unref(cm->slot_take_device);
2957         cm->acquired = false;
2958
2959         r = sd_bus_message_new_method_call(session->context->sysbus,
2960                                            &m,
2961                                            "org.freedesktop.login1",
2962                                            session->path,
2963                                            "org.freedesktop.login1.Session",
2964                                            "ReleaseDevice");
2965         if (r >= 0) {
2966                 r = sd_bus_message_append(m, "uu", major(cm->devnum), minor(cm->devnum));
2967                 if (r >= 0)
2968                         r = sd_bus_send(session->context->sysbus, m, NULL);
2969         }
2970
2971         if (r < 0 && r != -ENOTCONN)
2972                 log_debug_errno(r, "grdrm: %s/%s: cannot send ReleaseDevice: %m",
2973                                 session->name, cm->card.base.name);
2974 }
2975
2976 static int managed_card_new(grdev_card **out, grdev_session *session, struct udev_device *ud) {
2977         _cleanup_(grdev_card_freep) grdev_card *basecard = NULL;
2978         char name[GRDRM_CARD_NAME_MAX];
2979         managed_card *cm;
2980         dev_t devnum;
2981         int r;
2982
2983         assert_return(session, -EINVAL);
2984         assert_return(session->managed, -EINVAL);
2985         assert_return(session->context->sysbus, -EINVAL);
2986         assert_return(ud, -EINVAL);
2987
2988         devnum = udev_device_get_devnum(ud);
2989         if (devnum == 0)
2990                 return -ENODEV;
2991
2992         grdrm_name(name, devnum);
2993
2994         cm = new0(managed_card, 1);
2995         if (!cm)
2996                 return -ENOMEM;
2997
2998         basecard = &cm->card.base;
2999         cm->card = GRDRM_CARD_INIT(&managed_card_vtable, session);
3000         cm->devnum = devnum;
3001
3002         r = managed_card_setup_bus(cm);
3003         if (r < 0)
3004                 return r;
3005
3006         r = grdrm_card_add(&cm->card, name);
3007         if (r < 0)
3008                 return r;
3009
3010         managed_card_take_device(cm);
3011
3012         if (out)
3013                 *out = basecard;
3014         basecard = NULL;
3015         return 0;
3016 }
3017
3018 static void managed_card_free(grdev_card *basecard) {
3019         managed_card *cm = managed_card_from_base(basecard);
3020
3021         assert(!basecard->enabled);
3022
3023         managed_card_release_device(cm);
3024         cm->slot_resume_device = sd_bus_slot_unref(cm->slot_resume_device);
3025         cm->slot_pause_device = sd_bus_slot_unref(cm->slot_pause_device);
3026         grdrm_card_destroy(&cm->card);