[PATCH v2] DDX/fbdevhw: Disable FBIOBLANK ioctl if not supported

Egbert Eich eich at freedesktop.org
Sat Oct 5 04:57:13 PDT 2013


Some ioctls may not be supported by the kernel however their failure
is non-fatal to the driver. Unfortunately we only know once we try
to execute the ioctl however the sematics of the fbdev driver API
doesn't allow upper layers to disable the call.
Instead of changing the fbdevHW driver API just disable the call to
this ioctl on the module level when detecting such a case.

Signed-off-by: Egbert Eich <eich at freedesktop.org>
---
v2: Retry on EINTR and ERESTART. Suggested by Keith Packard <keithp at keithp.com>

 hw/xfree86/fbdevhw/fbdevhw.c | 49 +++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 44 insertions(+), 5 deletions(-)

diff --git a/hw/xfree86/fbdevhw/fbdevhw.c b/hw/xfree86/fbdevhw/fbdevhw.c
index cbb4093..8ddd239 100644
--- a/hw/xfree86/fbdevhw/fbdevhw.c
+++ b/hw/xfree86/fbdevhw/fbdevhw.c
@@ -76,8 +76,14 @@ typedef struct {
     /* buildin video mode */
     DisplayModeRec buildin;
 
+    /* disable non-fatal unsupported ioctls */
+    CARD32 unsupported_ioctls;
 } fbdevHWRec, *fbdevHWPtr;
 
+enum {
+    FBIOBLANK_UNSUPPORTED = 0,
+};
+
 Bool
 fbdevHWGetRec(ScrnInfoPtr pScrn)
 {
@@ -833,6 +839,9 @@ fbdevHWDPMSSet(ScrnInfoPtr pScrn, int mode, int flags)
     if (!pScrn->vtSema)
         return;
 
+    if (fPtr->unsupported_ioctls & (1 << FBIOBLANK_UNSUPPORTED))
+        return;
+
     switch (mode) {
     case DPMSModeOn:
         fbmode = 0;
@@ -850,9 +859,23 @@ fbdevHWDPMSSet(ScrnInfoPtr pScrn, int mode, int flags)
         return;
     }
 
-    if (-1 == ioctl(fPtr->fd, FBIOBLANK, (void *) fbmode))
-        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-                   "FBIOBLANK: %s\n", strerror(errno));
+RETRY:
+    if (-1 == ioctl(fPtr->fd, FBIOBLANK, (void *) fbmode)) {
+        switch (errno) {
+        case EAGAIN:
+            xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                       "FBIOBLANK: %s\n", strerror(errno));
+	    break;
+        case EINTR:
+        case ERESTART:
+            goto RETRY;
+        default:
+            fPtr->unsupported_ioctls |= (1 << FBIOBLANK_UNSUPPORTED);
+            xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                       "FBIOBLANK: %s (Screen blanking not supported "
+                       "by kernel - disabling)\n", strerror(errno));
+        }
+    }
 }
 
 Bool
@@ -865,11 +888,27 @@ fbdevHWSaveScreen(ScreenPtr pScreen, int mode)
     if (!pScrn->vtSema)
         return TRUE;
 
+    if (fPtr->unsupported_ioctls & (1 << FBIOBLANK_UNSUPPORTED))
+        return FALSE;
+
     unblank = xf86IsUnblank(mode);
 
+RETRY:
     if (-1 == ioctl(fPtr->fd, FBIOBLANK, (void *) (1 - unblank))) {
-        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-                   "FBIOBLANK: %s\n", strerror(errno));
+        switch (errno) {
+        case EAGAIN:
+            xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                       "FBIOBLANK: %s\n", strerror(errno));
+            break;
+        case EINTR:
+        case ERESTART:
+            goto RETRY;
+        default:
+            fPtr->unsupported_ioctls |= (1 << FBIOBLANK_UNSUPPORTED);
+            xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                       "FBIOBLANK: %s (Screen blanking not supported "
+                       "by kernel - disabling)\n", strerror(errno));
+        }
         return FALSE;
     }
 
-- 
1.8.1.4



More information about the xorg-devel mailing list