summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSiarhei Siamashka <siarhei.siamashka@gmail.com>2014-09-21 01:25:42 +0400
committerSiarhei Siamashka <siarhei.siamashka@gmail.com>2014-09-21 01:25:42 +0400
commit046a7714cdf1f3f8eb39a8167ef2e5109cf7a4f9 (patch)
tree0195f2261f1efcd439985417c578d133f7d7811e
parent4c7313c6db9ee770f39740c735268c88fcd136cf (diff)
downloadxf86-video-fbturbo-046a7714cdf1f3f8eb39a8167ef2e5109cf7a4f9.tar.xz
Check if the kernel framebuffer driver returns errors on bad ioctlsfbioctl
When probing for the copyarea ioctl, we want to be sure that the kernel just does not return 0 (success) for any unsupported ioctls. The rockchip vendor kernels have been reported to have this issue. In the case if the support for the Raspberry Pi specific copyarea ioctl was detected by mistake, moving windows or scrolling was broken. Signed-off-by: Siarhei Siamashka <siarhei.siamashka@gmail.com>
-rw-r--r--src/fb_copyarea.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/src/fb_copyarea.c b/src/fb_copyarea.c
index 3c827c1..63f12f6 100644
--- a/src/fb_copyarea.c
+++ b/src/fb_copyarea.c
@@ -38,6 +38,11 @@
* defined in "linux/fb.h" header
*/
#define FBIOCOPYAREA _IOW('z', 0x21, struct fb_copyarea)
+/*
+ * HACK: another non-standard ioctl, which is used to check whether the
+ * fbdev kernel driver actually returns errors on unsupported ioctls.
+ */
+#define FBUNSUPPORTED _IOW('z', 0x22, struct fb_copyarea)
/* Fallback to CPU when handling less than COPYAREA_BLT_SIZE_THRESHOLD pixels */
#define COPYAREA_BLT_SIZE_THRESHOLD 90
@@ -65,6 +70,16 @@ fb_copyarea_t *fb_copyarea_init(const char *device, void *xserver_fbmem)
}
/*
+ * Check if the unsupported dummy ioctl fails. If it does not, then the
+ * kernel framebuffer driver is buggy and does not handle errors correctly.
+ */
+ if (ioctl(ctx->fd, FBUNSUPPORTED, &copyarea) == 0) {
+ close(ctx->fd);
+ free(ctx);
+ return NULL;
+ }
+
+ /*
* Check whether the FBIOCOPYAREA ioctl is supported by requesting to do
* a copy of 1x1 rectangle in the top left corner to itself
*/