chiark / gitweb /
terminal: grdev: refresh device state on hotplug events
[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
2100         if (!card->running)
2101                 return;
2102
2103         card->ready = false;
2104         r = grdrm_card_resync(card);
2105         if (r < 0) {
2106                 log_debug("grdrm: %s/%s: cannot re-sync card: %s",
2107                           card->base.session->name, card->base.name, strerror(-r));
2108                 return;
2109         }
2110
2111         grdev_session_pin(card->base.session);
2112
2113         grdrm_card_print(card);
2114         grdrm_card_configure(card);
2115         card->ready = true;
2116
2117         grdev_session_unpin(card->base.session);
2118 }
2119
2120 static int grdrm_card_io_fn(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
2121         grdrm_card *card = userdata;
2122         struct drm_event_vblank *vblank;
2123         struct drm_event *event;
2124         uint32_t id, counter;
2125         grdrm_object *object;
2126         char buf[4096];
2127         ssize_t l, i;
2128
2129         if (revents & (EPOLLHUP | EPOLLERR)) {
2130                 /* Immediately close device on HUP; no need to flush pending
2131                  * data.. there're no events we care about here. */
2132                 log_debug("grdrm: %s/%s: HUP", card->base.session->name, card->base.name);
2133                 grdrm_card_close(card);
2134                 return 0;
2135         }
2136
2137         if (revents & (EPOLLIN)) {
2138                 l = read(card->fd, buf, sizeof(buf));
2139                 if (l < 0) {
2140                         if (errno == EAGAIN || errno == EINTR)
2141                                 return 0;
2142
2143                         log_debug("grdrm: %s/%s: read error: %m", card->base.session->name, card->base.name);
2144                         grdrm_card_close(card);
2145                         return 0;
2146                 } else if ((size_t)l < sizeof(*event)) {
2147                         log_debug("grdrm: %s/%s: short read of %zd bytes", card->base.session->name, card->base.name, l);
2148                         return 0;
2149                 }
2150
2151                 for (i = 0; i < l; i += event->length) {
2152                         event = (void*)&buf[i];
2153
2154                         if (i + event->length > l) {
2155                                 log_debug("grdrm: %s/%s: truncated event", card->base.session->name, card->base.name);
2156                                 break;
2157                         }
2158
2159                         switch (event->type) {
2160                         case DRM_EVENT_FLIP_COMPLETE:
2161                                 vblank = (void*)event;
2162                                 if (event->length < sizeof(*vblank)) {
2163                                         log_debug("grdrm: %s/%s: truncated vblank event", card->base.session->name, card->base.name);
2164                                         break;
2165                                 }
2166
2167                                 grdrm_decode_vblank_data(vblank->user_data, &id, &counter);
2168                                 object = grdrm_find_object(card, id);
2169                                 if (!object || object->type != GRDRM_TYPE_CRTC)
2170                                         break;
2171
2172                                 grdrm_crtc_flip_complete(crtc_from_object(object), counter, vblank);
2173                                 break;
2174                         }
2175                 }
2176         }
2177
2178         return 0;
2179 }
2180
2181 static int grdrm_card_add(grdrm_card *card, const char *name) {
2182         assert(card);
2183         assert(card->fd < 0);
2184
2185         card->object_map = hashmap_new(&trivial_hash_ops);
2186         if (!card->object_map)
2187                 return -ENOMEM;
2188
2189         return grdev_card_add(&card->base, name);
2190 }
2191
2192 static void grdrm_card_destroy(grdrm_card *card) {
2193         assert(card);
2194         assert(!card->running);
2195         assert(card->fd < 0);
2196         assert(hashmap_size(card->object_map) == 0);
2197
2198         hashmap_free(card->object_map);
2199 }
2200
2201 static void grdrm_card_commit(grdev_card *basecard) {
2202         grdrm_card *card = grdrm_card_from_base(basecard);
2203         grdrm_object *object;
2204         Iterator iter;
2205
2206         HASHMAP_FOREACH(object, card->object_map, iter) {
2207                 if (!card->ready)
2208                         break;
2209
2210                 if (object->type != GRDRM_TYPE_CRTC)
2211                         continue;
2212
2213                 grdrm_crtc_commit(crtc_from_object(object));
2214         }
2215 }
2216
2217 static void grdrm_card_restore(grdev_card *basecard) {
2218         grdrm_card *card = grdrm_card_from_base(basecard);
2219         grdrm_object *object;
2220         Iterator iter;
2221
2222         HASHMAP_FOREACH(object, card->object_map, iter) {
2223                 if (!card->ready)
2224                         break;
2225
2226                 if (object->type != GRDRM_TYPE_CRTC)
2227                         continue;
2228
2229                 grdrm_crtc_restore(crtc_from_object(object));
2230         }
2231 }
2232
2233 static void grdrm_card_enable(grdrm_card *card) {
2234         assert(card);
2235
2236         if (card->fd < 0 || card->running)
2237                 return;
2238
2239         /* ignore cards without DUMB_BUFFER capability */
2240         if (!card->cap_dumb)
2241                 return;
2242
2243         assert(card->fd_src);
2244
2245         log_debug("grdrm: %s/%s: enable", card->base.session->name, card->base.name);
2246
2247         card->running = true;
2248         sd_event_source_set_enabled(card->fd_src, SD_EVENT_ON);
2249         grdrm_card_hotplug(card);
2250 }
2251
2252 static void grdrm_card_disable(grdrm_card *card) {
2253         grdrm_object *object;
2254         Iterator iter;
2255
2256         assert(card);
2257
2258         if (card->fd < 0 || !card->running)
2259                 return;
2260
2261         assert(card->fd_src);
2262
2263         log_debug("grdrm: %s/%s: disable", card->base.session->name, card->base.name);
2264
2265         card->running = false;
2266         card->ready = false;
2267         sd_event_source_set_enabled(card->fd_src, SD_EVENT_OFF);
2268
2269         /* stop all pipes */
2270         HASHMAP_FOREACH(object, card->object_map, iter) {
2271                 grdrm_crtc *crtc;
2272
2273                 if (object->type != GRDRM_TYPE_CRTC)
2274                         continue;
2275
2276                 crtc = crtc_from_object(object);
2277                 crtc->applied = false;
2278                 if (crtc->pipe)
2279                         grdev_pipe_ready(&crtc->pipe->base, false);
2280         }
2281 }
2282
2283 static int grdrm_card_open(grdrm_card *card, int dev_fd) {
2284         _cleanup_(grdev_session_unpinp) grdev_session *pin = NULL;
2285         _cleanup_close_ int fd = dev_fd;
2286         struct drm_get_cap cap;
2287         int r, flags;
2288
2289         assert(card);
2290         assert(dev_fd >= 0);
2291         assert(card->fd != dev_fd);
2292
2293         pin = grdev_session_pin(card->base.session);
2294         grdrm_card_close(card);
2295
2296         log_debug("grdrm: %s/%s: open", card->base.session->name, card->base.name);
2297
2298         r = fd_nonblock(fd, true);
2299         if (r < 0)
2300                 return r;
2301
2302         r = fd_cloexec(fd, true);
2303         if (r < 0)
2304                 return r;
2305
2306         flags = fcntl(fd, F_GETFL, 0);
2307         if (flags < 0)
2308                 return -errno;
2309         if ((flags & O_ACCMODE) != O_RDWR)
2310                 return -EACCES;
2311
2312         r = sd_event_add_io(card->base.session->context->event,
2313                             &card->fd_src,
2314                             fd,
2315                             EPOLLHUP | EPOLLERR | EPOLLIN,
2316                             grdrm_card_io_fn,
2317                             card);
2318         if (r < 0)
2319                 return r;
2320
2321         sd_event_source_set_enabled(card->fd_src, SD_EVENT_OFF);
2322
2323         card->fd = fd;
2324         fd = -1;
2325
2326         /* cache DUMB_BUFFER capability */
2327         cap.capability = DRM_CAP_DUMB_BUFFER;
2328         cap.value = 0;
2329         r = ioctl(card->fd, DRM_IOCTL_GET_CAP, &cap);
2330         card->cap_dumb = r >= 0 && cap.value;
2331         if (r < 0)
2332                 log_debug("grdrm: %s/%s: cannot retrieve DUMB_BUFFER capability: %s",
2333                           card->base.session->name, card->base.name, strerror(-r));
2334         else if (!card->cap_dumb)
2335                 log_debug("grdrm: %s/%s: DUMB_BUFFER capability not supported",
2336                           card->base.session->name, card->base.name);
2337
2338         /* cache TIMESTAMP_MONOTONIC capability */
2339         cap.capability = DRM_CAP_TIMESTAMP_MONOTONIC;
2340         cap.value = 0;
2341         r = ioctl(card->fd, DRM_IOCTL_GET_CAP, &cap);
2342         card->cap_monotonic = r >= 0 && cap.value;
2343         if (r < 0)
2344                 log_debug("grdrm: %s/%s: cannot retrieve TIMESTAMP_MONOTONIC capability: %s",
2345                           card->base.session->name, card->base.name, strerror(-r));
2346         else if (!card->cap_monotonic)
2347                 log_debug("grdrm: %s/%s: TIMESTAMP_MONOTONIC is disabled globally, fix this NOW!",
2348                           card->base.session->name, card->base.name);
2349
2350         return 0;
2351 }
2352
2353 static void grdrm_card_close(grdrm_card *card) {
2354         grdrm_object *object;
2355
2356         if (card->fd < 0)
2357                 return;
2358
2359         log_debug("grdrm: %s/%s: close", card->base.session->name, card->base.name);
2360
2361         grdrm_card_disable(card);
2362
2363         card->fd_src = sd_event_source_unref(card->fd_src);
2364         card->fd = safe_close(card->fd);
2365
2366         grdev_session_pin(card->base.session);
2367         while ((object = hashmap_first(card->object_map)))
2368                 grdrm_object_free(object);
2369         grdev_session_unpin(card->base.session);
2370 }
2371
2372 static bool grdrm_card_async(grdrm_card *card, int r) {
2373         switch (r) {
2374         case -EACCES:
2375                 /* If we get EACCES on runtime DRM calls, we lost DRM-Master
2376                  * (or we did something terribly wrong). Immediately disable
2377                  * the card, so we stop all pipes and wait to be activated
2378                  * again. */
2379                 grdrm_card_disable(card);
2380                 break;
2381         case -ENOENT:
2382                 /* DRM objects can be hotplugged at any time. If an object is
2383                  * removed that we use, we remember that state so a following
2384                  * call can test for this.
2385                  * Note that we also get a uevent as followup, this will resync
2386                  * the whole device. */
2387                 card->async_hotplug = true;
2388                 break;
2389         }
2390
2391         return !card->ready;
2392 }
2393
2394 /*
2395  * Unmanaged Cards
2396  * The unmanaged DRM card opens the device node for a given DRM device
2397  * directly (/dev/dri/cardX) and thus needs sufficient privileges. It opens
2398  * the device only if we really require it and releases it as soon as we're
2399  * disabled or closed.
2400  * The unmanaged element can be used in all situations where you have direct
2401  * access to DRM device nodes. Unlike managed DRM elements, it can be used
2402  * outside of user sessions and in emergency situations where logind is not
2403  * available.
2404  */
2405
2406 static void unmanaged_card_enable(grdev_card *basecard) {
2407         unmanaged_card *cu = unmanaged_card_from_base(basecard);
2408         int r, fd;
2409
2410         if (cu->card.fd < 0) {
2411                 /* try open on activation if it failed during allocation */
2412                 fd = open(cu->devnode, O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK);
2413                 if (fd < 0) {
2414                         /* not fatal; simply ignore the device */
2415                         log_debug("grdrm: %s/%s: cannot open node %s: %m",
2416                                   basecard->session->name, basecard->name, cu->devnode);
2417                         return;
2418                 }
2419
2420                 /* we might already be DRM-Master by open(); that's fine */
2421
2422                 r = grdrm_card_open(&cu->card, fd);
2423                 if (r < 0) {
2424                         log_debug("grdrm: %s/%s: cannot open: %s",
2425                                   basecard->session->name, basecard->name, strerror(-r));
2426                         return;
2427                 }
2428         }
2429
2430         r = ioctl(cu->card.fd, DRM_IOCTL_SET_MASTER, 0);
2431         if (r < 0) {
2432                 log_debug("grdrm: %s/%s: cannot acquire DRM-Master: %m",
2433                           basecard->session->name, basecard->name);
2434                 return;
2435         }
2436
2437         grdrm_card_enable(&cu->card);
2438 }
2439
2440 static void unmanaged_card_disable(grdev_card *basecard) {
2441         unmanaged_card *cu = unmanaged_card_from_base(basecard);
2442
2443         grdrm_card_disable(&cu->card);
2444 }
2445
2446 static int unmanaged_card_new(grdev_card **out, grdev_session *session, struct udev_device *ud) {
2447         _cleanup_(grdev_card_freep) grdev_card *basecard = NULL;
2448         char name[GRDRM_CARD_NAME_MAX];
2449         unmanaged_card *cu;
2450         const char *devnode;
2451         dev_t devnum;
2452         int r, fd;
2453
2454         assert_return(session, -EINVAL);
2455         assert_return(ud, -EINVAL);
2456
2457         devnode = udev_device_get_devnode(ud);
2458         devnum = udev_device_get_devnum(ud);
2459         if (!devnode || devnum == 0)
2460                 return -ENODEV;
2461
2462         grdrm_name(name, devnum);
2463
2464         cu = new0(unmanaged_card, 1);
2465         if (!cu)
2466                 return -ENOMEM;
2467
2468         basecard = &cu->card.base;
2469         cu->card = GRDRM_CARD_INIT(&unmanaged_card_vtable, session);
2470
2471         cu->devnode = strdup(devnode);
2472         if (!cu->devnode)
2473                 return -ENOMEM;
2474
2475         r = grdrm_card_add(&cu->card, name);
2476         if (r < 0)
2477                 return r;
2478
2479         /* try to open but ignore errors */
2480         fd = open(cu->devnode, O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK);
2481         if (fd < 0) {
2482                 /* not fatal; allow uaccess based control on activation */
2483                 log_debug("grdrm: %s/%s: cannot open node %s: %m",
2484                           basecard->session->name, basecard->name, cu->devnode);
2485         } else {
2486                 /* We might get DRM-Master implicitly on open(); drop it immediately
2487                  * so we acquire it only once we're actually enabled. */
2488                 ioctl(fd, DRM_IOCTL_DROP_MASTER, 0);
2489
2490                 r = grdrm_card_open(&cu->card, fd);
2491                 if (r < 0)
2492                         log_debug("grdrm: %s/%s: cannot open: %s",
2493                                   basecard->session->name, basecard->name, strerror(-r));
2494         }
2495
2496         if (out)
2497                 *out = basecard;
2498         basecard = NULL;
2499         return 0;
2500 }
2501
2502 static void unmanaged_card_free(grdev_card *basecard) {
2503         unmanaged_card *cu = unmanaged_card_from_base(basecard);
2504
2505         assert(!basecard->enabled);
2506
2507         grdrm_card_close(&cu->card);
2508         grdrm_card_destroy(&cu->card);
2509         free(cu->devnode);
2510         free(cu);
2511 }
2512
2513 static const grdev_card_vtable unmanaged_card_vtable = {
2514         .free                   = unmanaged_card_free,
2515         .enable                 = unmanaged_card_enable,
2516         .disable                = unmanaged_card_disable,
2517         .commit                 = grdrm_card_commit,
2518         .restore                = grdrm_card_restore,
2519 };
2520
2521 /*
2522  * Managed Cards
2523  * The managed DRM card uses systemd-logind to acquire DRM devices. This
2524  * means, we do not open the device node /dev/dri/cardX directly. Instead,
2525  * logind passes us a file-descriptor whenever our session is activated. Thus,
2526  * we don't need access to the device node directly.
2527  * Furthermore, whenever the session is put asleep, logind revokes the
2528  * file-descriptor so we loose access to the device.
2529  * Managed DRM cards should be preferred over unmanaged DRM cards whenever
2530  * you run inside a user session with exclusive device access.
2531  */
2532
2533 static void managed_card_enable(grdev_card *card) {
2534         managed_card *cm = managed_card_from_base(card);
2535
2536         /* If the device is manually re-enabled, we try to resume our card
2537          * management. Note that we have no control over DRM-Master and the fd,
2538          * so we have to take over the state from the last logind event. */
2539
2540         if (cm->master)
2541                 grdrm_card_enable(&cm->card);
2542 }
2543
2544 static void managed_card_disable(grdev_card *card) {
2545         managed_card *cm = managed_card_from_base(card);
2546
2547         /* If the device is manually disabled, we keep the FD but put our card
2548          * management asleep. This way, we can wake up at any time, but don't
2549          * touch the device while asleep. */
2550
2551         grdrm_card_disable(&cm->card);
2552 }
2553
2554 static int managed_card_pause_device_fn(sd_bus *bus,
2555                                         sd_bus_message *signal,
2556                                         void *userdata,
2557                                         sd_bus_error *ret_error) {
2558         managed_card *cm = userdata;
2559         grdev_session *session = cm->card.base.session;
2560         uint32_t major, minor;
2561         const char *mode;
2562         int r;
2563
2564         /*
2565          * We get PauseDevice() signals from logind whenever a device we
2566          * requested was, or is about to be, paused. Arguments are major/minor
2567          * number of the device and the mode of the operation.
2568          * In case the event is not about our device, we ignore it. Otherwise,
2569          * we treat it as asynchronous DRM-DROP-MASTER. Note that we might have
2570          * already handled an EACCES error from a modeset ioctl, in which case
2571          * we already disabled the device.
2572          *
2573          * @mode can be one of the following:
2574          *   "pause": The device is about to be paused. We must react
2575          *            immediately and respond with PauseDeviceComplete(). Once
2576          *            we replied, logind will pause the device. Note that
2577          *            logind might apply any kind of timeout and force pause
2578          *            the device if we don't respond in a timely manner. In
2579          *            this case, we will receive a second PauseDevice event
2580          *            with @mode set to "force" (or similar).
2581          *   "force": The device was disabled forecfully by logind. DRM-Master
2582          *            was already dropped. This is just an asynchronous
2583          *            notification so we can put the device asleep (in case
2584          *            we didn't already notice the dropped DRM-Master).
2585          *    "gone": This is like "force" but is sent if the device was
2586          *            paused due to a device-removal event.
2587          *
2588          * We always handle PauseDevice signals as "force" as we properly
2589          * support asynchronously dropping DRM-Master, anyway. But in case
2590          * logind sent mode "pause", we also call PauseDeviceComplete() to
2591          * immediately acknowledge the request.
2592          */
2593
2594         r = sd_bus_message_read(signal, "uus", &major, &minor, &mode);
2595         if (r < 0) {
2596                 log_debug("grdrm: %s/%s: erroneous PauseDevice signal",
2597                           session->name, cm->card.base.name);
2598                 return 0;
2599         }
2600
2601         /* not our device? */
2602         if (makedev(major, minor) != cm->devnum)
2603                 return 0;
2604
2605         cm->master = false;
2606         grdrm_card_disable(&cm->card);
2607
2608         if (streq(mode, "pause")) {
2609                 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
2610
2611                 /*
2612                  * Sending PauseDeviceComplete() is racy if logind triggers the
2613                  * timeout. That is, if we take too long and logind pauses the
2614                  * device by sending a forced PauseDevice, our
2615                  * PauseDeviceComplete call will be stray. That's fine, though.
2616                  * logind ignores such stray calls. Only if logind also sent a
2617                  * further PauseDevice() signal, it might match our call
2618                  * incorrectly to the newer PauseDevice(). That's fine, too, as
2619                  * we handle that event asynchronously, anyway. Therefore,
2620                  * whatever happens, we're fine. Yay!
2621                  */
2622
2623                 r = sd_bus_message_new_method_call(session->context->sysbus,
2624                                                    &m,
2625                                                    "org.freedesktop.login1",
2626                                                    session->path,
2627                                                    "org.freedesktop.login1.Session",
2628                                                    "PauseDeviceComplete");
2629                 if (r >= 0) {
2630                         r = sd_bus_message_append(m, "uu", major, minor);
2631                         if (r >= 0)
2632                                 r = sd_bus_send(session->context->sysbus, m, NULL);
2633                 }
2634
2635                 if (r < 0)
2636                         log_debug("grdrm: %s/%s: cannot send PauseDeviceComplete: %s",
2637                                   session->name, cm->card.base.name, strerror(-r));
2638         }
2639
2640         return 0;
2641 }
2642
2643 static int managed_card_resume_device_fn(sd_bus *bus,
2644                                          sd_bus_message *signal,
2645                                          void *userdata,
2646                                          sd_bus_error *ret_error) {
2647         managed_card *cm = userdata;
2648         grdev_session *session = cm->card.base.session;
2649         uint32_t major, minor;
2650         int r, fd;
2651
2652         /*
2653          * We get ResumeDevice signals whenever logind resumed a previously
2654          * paused device. The arguments contain the major/minor number of the
2655          * related device and a new file-descriptor for the freshly opened
2656          * device-node.
2657          * If the signal is not about our device, we simply ignore it.
2658          * Otherwise, we immediately resume the device. Note that we drop the
2659          * new file-descriptor as we already have one from TakeDevice(). logind
2660          * preserves the file-context across pause/resume for DRM but only
2661          * drops/acquires DRM-Master accordingly. This way, our context (like
2662          * DRM-FBs and BOs) is preserved.
2663          */
2664
2665         r = sd_bus_message_read(signal, "uuh", &major, &minor, &fd);
2666         if (r < 0) {
2667                 log_debug("grdrm: %s/%s: erroneous ResumeDevice signal",
2668                           session->name, cm->card.base.name);
2669                 return 0;
2670         }
2671
2672         /* not our device? */
2673         if (makedev(major, minor) != cm->devnum)
2674                 return 0;
2675
2676         if (cm->card.fd < 0) {
2677                 /* This shouldn't happen. We should already own an FD from
2678                  * TakeDevice(). However, lets be safe and use this FD in case
2679                  * we really don't have one. There is no harm in doing this
2680                  * and our code works fine this way. */
2681                 fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
2682                 if (fd < 0) {
2683                         log_debug("grdrm: %s/%s: cannot duplicate fd: %m",
2684                                   session->name, cm->card.base.name);
2685                         return 0;
2686                 }
2687
2688                 r = grdrm_card_open(&cm->card, fd);
2689                 if (r < 0) {
2690                         log_debug("grdrm: %s/%s: cannot open: %s",
2691                                   session->name, cm->card.base.name, strerror(-r));
2692                         return 0;
2693                 }
2694         }
2695
2696         cm->master = true;
2697         if (cm->card.base.enabled)
2698                 grdrm_card_enable(&cm->card);
2699
2700         return 0;
2701 }
2702
2703 static int managed_card_setup_bus(managed_card *cm) {
2704         grdev_session *session = cm->card.base.session;
2705         _cleanup_free_ char *match = NULL;
2706         int r;
2707
2708         match = strjoin("type='signal',"
2709                         "sender='org.freedesktop.login1',"
2710                         "interface='org.freedesktop.login1.Session',"
2711                         "member='PauseDevice',"
2712                         "path='", session->path, "'",
2713                         NULL);
2714         if (!match)
2715                 return -ENOMEM;
2716
2717         r = sd_bus_add_match(session->context->sysbus,
2718                              &cm->slot_pause_device,
2719                              match,
2720                              managed_card_pause_device_fn,
2721                              cm);
2722         if (r < 0)
2723                 return r;
2724
2725         free(match);
2726         match = strjoin("type='signal',"
2727                         "sender='org.freedesktop.login1',"
2728                         "interface='org.freedesktop.login1.Session',"
2729                         "member='ResumeDevice',"
2730                         "path='", session->path, "'",
2731                         NULL);
2732         if (!match)
2733                 return -ENOMEM;
2734
2735         r = sd_bus_add_match(session->context->sysbus,
2736                              &cm->slot_resume_device,
2737                              match,
2738                              managed_card_resume_device_fn,
2739                              cm);
2740         if (r < 0)
2741                 return r;
2742
2743         return 0;
2744 }
2745
2746 static int managed_card_take_device_fn(sd_bus *bus,
2747                                        sd_bus_message *reply,
2748                                        void *userdata,
2749                                        sd_bus_error *ret_error) {
2750         managed_card *cm = userdata;
2751         grdev_session *session = cm->card.base.session;
2752         int r, paused, fd;
2753
2754         cm->slot_take_device = sd_bus_slot_unref(cm->slot_take_device);
2755
2756         if (sd_bus_message_is_method_error(reply, NULL)) {
2757                 const sd_bus_error *error = sd_bus_message_get_error(reply);
2758
2759                 log_debug("grdrm: %s/%s: TakeDevice failed: %s: %s",
2760                           session->name, cm->card.base.name, error->name, error->message);
2761                 return 0;
2762         }
2763
2764         cm->acquired = true;
2765
2766         r = sd_bus_message_read(reply, "hb", &fd, &paused);
2767         if (r < 0) {
2768                 log_debug("grdrm: %s/%s: erroneous TakeDevice reply",
2769                           session->name, cm->card.base.name);
2770                 return 0;
2771         }
2772
2773         fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
2774         if (fd < 0) {
2775                 log_debug("grdrm: %s/%s: cannot duplicate fd: %m",
2776                           session->name, cm->card.base.name);
2777                 return 0;
2778         }
2779
2780         r = grdrm_card_open(&cm->card, fd);
2781         if (r < 0) {
2782                 log_debug("grdrm: %s/%s: cannot open: %s",
2783                           session->name, cm->card.base.name, strerror(-r));
2784                 return 0;
2785         }
2786
2787         if (!paused && cm->card.base.enabled)
2788                 grdrm_card_enable(&cm->card);
2789
2790         return 0;
2791 }
2792
2793 static void managed_card_take_device(managed_card *cm) {
2794         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
2795         grdev_session *session = cm->card.base.session;
2796         int r;
2797
2798         r = sd_bus_message_new_method_call(session->context->sysbus,
2799                                            &m,
2800                                            "org.freedesktop.login1",
2801                                            session->path,
2802                                            "org.freedesktop.login1.Session",
2803                                            "TakeDevice");
2804         if (r < 0)
2805                 goto error;
2806
2807         r = sd_bus_message_append(m, "uu", major(cm->devnum), minor(cm->devnum));
2808         if (r < 0)
2809                 goto error;
2810
2811         r = sd_bus_call_async(session->context->sysbus,
2812                               &cm->slot_take_device,
2813                               m,
2814                               managed_card_take_device_fn,
2815                               cm,
2816                               0);
2817         if (r < 0)
2818                 goto error;
2819
2820         cm->requested = true;
2821         return;
2822
2823 error:
2824         log_debug("grdrm: %s/%s: cannot send TakeDevice request: %s",
2825                   session->name, cm->card.base.name, strerror(-r));
2826 }
2827
2828 static void managed_card_release_device(managed_card *cm) {
2829         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
2830         grdev_session *session = cm->card.base.session;
2831         int r;
2832
2833         /*
2834          * If TakeDevice() is pending or was successful, make sure to
2835          * release the device again. We don't care for return-values,
2836          * so send it without waiting or callbacks.
2837          * If a failed TakeDevice() is pending, but someone else took
2838          * the device on the same bus-connection, we might incorrectly
2839          * release their device. This is an unlikely race, though.
2840          * Furthermore, you really shouldn't have two users of the
2841          * controller-API on the same session, on the same devices, *AND* on
2842          * the same bus-connection. So we don't care for that race..
2843          */
2844
2845         grdrm_card_close(&cm->card);
2846         cm->requested = false;
2847
2848         if (!cm->acquired && !cm->slot_take_device)
2849                 return;
2850
2851         cm->slot_take_device = sd_bus_slot_unref(cm->slot_take_device);
2852         cm->acquired = false;
2853
2854         r = sd_bus_message_new_method_call(session->context->sysbus,
2855                                            &m,
2856                                            "org.freedesktop.login1",
2857                                            session->path,
2858                                            "org.freedesktop.login1.Session",
2859                                            "ReleaseDevice");
2860         if (r >= 0) {
2861                 r = sd_bus_message_append(m, "uu", major(cm->devnum), minor(cm->devnum));
2862                 if (r >= 0)
2863                         r = sd_bus_send(session->context->sysbus, m, NULL);
2864         }
2865
2866         if (r < 0 && r != -ENOTCONN)
2867                 log_debug("grdrm: %s/%s: cannot send ReleaseDevice: %s",
2868                           session->name, cm->card.base.name, strerror(-r));
2869 }
2870
2871 static int managed_card_new(grdev_card **out, grdev_session *session, struct udev_device *ud) {
2872         _cleanup_(grdev_card_freep) grdev_card *basecard = NULL;
2873         char name[GRDRM_CARD_NAME_MAX];
2874         managed_card *cm;
2875         dev_t devnum;
2876         int r;
2877
2878         assert_return(session, -EINVAL);
2879         assert_return(session->managed, -EINVAL);
2880         assert_return(session->context->sysbus, -EINVAL);
2881         assert_return(ud, -EINVAL);
2882
2883         devnum = udev_device_get_devnum(ud);
2884         if (devnum == 0)
2885                 return -ENODEV;
2886
2887         grdrm_name(name, devnum);
2888
2889         cm = new0(managed_card, 1);
2890         if (!cm)
2891                 return -ENOMEM;
2892
2893         basecard = &cm->card.base;
2894         cm->card = GRDRM_CARD_INIT(&managed_card_vtable, session);
2895         cm->devnum = devnum;
2896
2897         r = managed_card_setup_bus(cm);
2898         if (r < 0)
2899                 return r;
2900
2901         r = grdrm_card_add(&cm->card, name);
2902         if (r < 0)
2903                 return r;
2904
2905         managed_card_take_device(cm);
2906
2907         if (out)
2908                 *out = basecard;
2909         basecard = NULL;
2910         return 0;
2911 }
2912
2913 static void managed_card_free(grdev_card *basecard) {
2914         managed_card *cm = managed_card_from_base(basecard);
2915
2916         assert(!basecard->enabled);
2917
2918         managed_card_release_device(cm);
2919         cm->slot_resume_device = sd_bus_slot_unref(cm->slot_resume_device);
2920         cm->slot_pause_device = sd_bus_slot_unref(cm->slot_pause_device);
2921         grdrm_card_destroy(&cm->card);
2922         free(cm);
2923 }
2924
2925 static const grdev_card_vtable managed_card_vtable = {
2926         .free                   = managed_card_free,
2927         .enable                 = managed_card_enable,
2928         .disable                = managed_card_disable,
2929         .commit                 = grdrm_card_commit,
2930         .restore                = grdrm_card_restore,
2931 };
2932
2933 /*
2934  * Generic Constructor
2935  * Instead of relying on the caller to choose between managed and unmanaged
2936  * DRM devices, the grdev_drm_new() constructor does that for you (by
2937  * looking at session->managed).
2938  */
2939
2940 bool grdev_is_drm_card(grdev_card *basecard) {
2941         return basecard && (basecard->vtable == &unmanaged_card_vtable ||
2942                             basecard->vtable == &managed_card_vtable);
2943 }
2944
2945 grdev_card *grdev_find_drm_card(grdev_session *session, dev_t devnum) {
2946         char name[GRDRM_CARD_NAME_MAX];
2947
2948         assert_return(session, NULL);
2949         assert_return(devnum != 0, NULL);
2950
2951         grdrm_name(name, devnum);
2952         return grdev_find_card(session, name);
2953 }
2954
2955 int grdev_drm_card_new(grdev_card **out, grdev_session *session, struct udev_device *ud) {
2956         assert_return(session, -EINVAL);
2957         assert_return(ud, -EINVAL);
2958
2959         return session->managed ? managed_card_new(out, session, ud) : unmanaged_card_new(out, session, ud);
2960 }
2961
2962 void grdev_drm_card_hotplug(grdev_card *basecard, struct udev_device *ud) {
2963         const char *p, *action;
2964         grdrm_card *card;
2965         dev_t devnum;
2966
2967         assert(basecard);
2968         assert(grdev_is_drm_card(basecard));
2969         assert(ud);
2970
2971         card = grdrm_card_from_base(basecard);
2972
2973         action = udev_device_get_action(ud);
2974         if (!action || streq(action, "add") || streq(action, "remove")) {
2975                 /* If we get add/remove events on DRM nodes without devnum, we
2976                  * got hotplugged DRM objects so refresh the device. */
2977                 devnum = udev_device_get_devnum(ud);
2978                 if (devnum == 0)
2979                         grdrm_card_hotplug(card);
2980         } else if (streq_ptr(action, "change")) {
2981                 /* A change event with HOTPLUG=1 is sent whenever a connector
2982                  * changed state. Refresh the device to update our state. */
2983                 p = udev_device_get_property_value(ud, "HOTPLUG");
2984                 if (streq_ptr(p, "1"))
2985                         grdrm_card_hotplug(card);
2986         }
2987 }