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