X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flibsystemd-terminal%2Fgrdev-drm.c;h=6b130116d7c4011204d6cc527484818a27bc8222;hb=6a15ce2b3eb852023d77787f96c6a4a72eb4d60d;hp=2e55ad326b15ff3484b52179949673a2497267e0;hpb=0fbd4d113e0d2123e896e8005d1b7fe407c28c05;p=elogind.git diff --git a/src/libsystemd-terminal/grdev-drm.c b/src/libsystemd-terminal/grdev-drm.c index 2e55ad326..6b130116d 100644 --- a/src/libsystemd-terminal/grdev-drm.c +++ b/src/libsystemd-terminal/grdev-drm.c @@ -1362,10 +1362,9 @@ static void grdrm_crtc_flip_complete(grdrm_crtc *crtc, uint32_t counter, struct fb = fb_from_base(pipe->base.fbs[i]); if (counter != 0 && counter == pipe->counter && fb->flipid == counter) { pipe->base.front = &fb->base; + fb->flipid = 0; flipped = true; - } - - if (counter - fb->flipid < UINT16_MAX) { + } else if (counter - fb->flipid < UINT16_MAX) { fb->flipid = 0; back = fb; } else if (fb->flipid == 0) { @@ -1373,7 +1372,7 @@ static void grdrm_crtc_flip_complete(grdrm_crtc *crtc, uint32_t counter, struct } } - if (!pipe->base.back) + if (!pipe->base.back && back) pipe->base.back = &back->base; if (flipped) { @@ -1474,14 +1473,19 @@ static int grdrm_fb_new(grdrm_fb **out, grdrm_card *card, const struct drm_mode_ grdrm_fb *grdrm_fb_free(grdrm_fb *fb) { unsigned int i; + int r; if (!fb) return NULL; assert(fb->card); - if (fb->id > 0 && fb->card->fd >= 0) - ioctl(fb->card->fd, DRM_IOCTL_MODE_RMFB, fb->id); + if (fb->id > 0 && fb->card->fd >= 0) { + r = ioctl(fb->card->fd, DRM_IOCTL_MODE_RMFB, fb->id); + if (r < 0) + log_debug("grdrm: %s: cannot delete framebuffer %" PRIu32 ": %m", + fb->card->base.name, fb->id); + } for (i = 0; i < ELEMENTSOF(fb->handles); ++i) { struct drm_mode_destroy_dumb destroy_dumb = { }; @@ -1491,7 +1495,10 @@ grdrm_fb *grdrm_fb_free(grdrm_fb *fb) { if (fb->handles[i] > 0 && fb->card->fd >= 0) { destroy_dumb.handle = fb->handles[i]; - ioctl(fb->card->fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_dumb); + r = ioctl(fb->card->fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_dumb); + if (r < 0) + log_debug("grdrm: %s: cannot destroy dumb-buffer %" PRIu32 ": %m", + fb->card->base.name, fb->handles[i]); } } @@ -2188,7 +2195,8 @@ static int grdrm_card_io_fn(sd_event_source *s, int fd, uint32_t revents, void * uint32_t id, counter; grdrm_object *object; char buf[4096]; - ssize_t l, i; + size_t len; + ssize_t l; if (revents & (EPOLLHUP | EPOLLERR)) { /* Immediately close device on HUP; no need to flush pending @@ -2207,15 +2215,12 @@ static int grdrm_card_io_fn(sd_event_source *s, int fd, uint32_t revents, void * log_debug("grdrm: %s/%s: read error: %m", card->base.session->name, card->base.name); grdrm_card_close(card); return 0; - } else if ((size_t)l < sizeof(*event)) { - log_debug("grdrm: %s/%s: short read of %zd bytes", card->base.session->name, card->base.name, l); - return 0; } - for (i = 0; i < l; i += event->length) { - event = (void*)&buf[i]; + for (len = l; len > 0; len -= event->length) { + event = (void*)buf; - if (i + event->length > l) { + if (len < sizeof(*event) || len < event->length) { log_debug("grdrm: %s/%s: truncated event", card->base.session->name, card->base.name); break; } @@ -2549,8 +2554,13 @@ static int unmanaged_card_new(grdev_card **out, grdev_session *session, struct u basecard->session->name, basecard->name, cu->devnode); } else { /* We might get DRM-Master implicitly on open(); drop it immediately - * so we acquire it only once we're actually enabled. */ - ioctl(fd, DRM_IOCTL_DROP_MASTER, 0); + * so we acquire it only once we're actually enabled. We don't + * really care whether this call fails or not, but lets log any + * weird errors, anyway. */ + r = ioctl(fd, DRM_IOCTL_DROP_MASTER, 0); + if (r < 0 && errno != EACCES && errno != EINVAL) + log_debug("grdrm: %s/%s: cannot drop DRM-Master: %m", + basecard->session->name, basecard->name); r = grdrm_card_open(&cu->card, fd); if (r < 0)