From mboxrd@z Thu Jan 1 00:00:00 1970 From: Thomas Zimmermann Date: Mon, 14 Oct 2019 14:04:11 +0000 Subject: [PATCH v2 10/15] drm/fbconv: Reimplement several fbdev interfaces Message-Id: <20191014140416.28517-11-tzimmermann@suse.de> List-Id: References: <20191014140416.28517-1-tzimmermann@suse.de> In-Reply-To: <20191014140416.28517-1-tzimmermann@suse.de> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: airlied@linux.ie, daniel@ffwll.ch, maarten.lankhorst@linux.intel.com, mripard@kernel.org, sean@poorly.run, b.zolnierkie@samsung.com, ajax@redhat.com, ville.syrjala@linux.intel.com, malat@debian.org, michel@daenzer.net Cc: gregkh@linuxfoundation.org, linux-fbdev@vger.kernel.org, Thomas Zimmermann , dri-devel@lists.freedesktop.org, corbet@lwn.net This patch reimplements fb_blank(), fb_pan_display(), fb_set_cmap() and fb_set_var() for fbconv helpers. The goal is to have all calls to driver callback functions located within fbconv and to reduce the amount of contained work to a minimum. Some noteable differences to fbdev include: * Code related to fbcon has been left out. Console support is emulated by DRM and the drivers don't interact directly with it. * No events are sent out. As the fbconv helpers are not part of the fbdev framework, there are no event listeners anyway. * Code related to ioctl and user-space has been left out as well. User-space interfaces are provided by DRM. * Error messages have been added. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/drm_fbconv_helper.c | 240 +++++++++++++++++++++++++--- 1 file changed, 220 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/drm_fbconv_helper.c b/drivers/gpu/drm/drm_fbconv_helper.c index ca8b43c91266..f7f247e30a3d 100644 --- a/drivers/gpu/drm/drm_fbconv_helper.c +++ b/drivers/gpu/drm/drm_fbconv_helper.c @@ -737,6 +737,55 @@ static const struct drm_connector_funcs connector_funcs = { * Colormap updates */ +static int drm_fbconv_set_cmap(struct fb_cmap *cmap, struct fb_info *fb_info) +{ + int i, start, res; + u16 *red, *green, *blue, *transp; + u_int hred, hgreen, hblue, htransp = 0xffff; + + red = cmap->red; + green = cmap->green; + blue = cmap->blue; + transp = cmap->transp; + start = cmap->start; + + if (start < 0 || (!fb_info->fbops->fb_setcolreg && + !fb_info->fbops->fb_setcmap)) { + DRM_ERROR("fbconv: Palette not supported.\n"); + return -EINVAL; + } + + if (fb_info->fbops->fb_setcmap) { + res = fb_info->fbops->fb_setcmap(cmap, fb_info); + if (res) { + DRM_ERROR("fbconv: fbops->fb_setcmap() failed: %d\n", + res); + return res; + } + } else { + for (i = 0; i < cmap->len; i++) { + hred = *red++; + hgreen = *green++; + hblue = *blue++; + if (transp) + htransp = *transp++; + res = fb_info->fbops->fb_setcolreg(start++, + hred, hgreen, hblue, + htransp, fb_info); + if (res) { + DRM_ERROR("fbconv: fbops->fb_setcolreg() failed: %d\n", + res); + /* cmap handling is a mess; don't err here */ + break; + } + } + } + + fb_copy_cmap(cmap, &fb_info->cmap); + + return 0; +} + /* provides a default colormap for palette modes */ static int create_palette_cmap(struct fb_cmap *cmap, const struct fb_var_screeninfo *fb_var) @@ -856,11 +905,9 @@ static int set_cmap(struct fb_info *fb_info) if (ret) return ret; - ret = fb_set_cmap(&cmap, fb_info); - if (ret) { - DRM_ERROR("fbconv: fb_set_cmap() failed: %d\n", ret); + ret = drm_fbconv_set_cmap(&cmap, fb_info); + if (ret) goto err_fb_dealloc_cmap; - } fb_dealloc_cmap(&cmap); return 0; @@ -891,7 +938,7 @@ static int drm_fbconv_update_fb_var_screeninfo_from_framebuffer( /* Our virtual screen covers all the graphics memory (sans some * trailing bytes). This allows for setting the scanout buffer's - * address with fb_pan_display(). + * address with drm_fbconv_pan_display(). */ width = fb->pitches[0]; @@ -937,6 +984,165 @@ static int drm_fbconv_update_fb_var_screeninfo_from_simple_display_pipe( return 0; } +static int drm_fbconv_blank(struct fb_info *fb_info, int blank) +{ + int ret = -EINVAL; + + if (fb_info->fbops->fb_blank) { + ret = fb_info->fbops->fb_blank(blank, fb_info); + if (ret) { + DRM_ERROR("fbconv: fbops->fb_blank() failed: %d\n", + ret); + } + } + return ret; +} + +static int drm_fbconv_pan_display(struct fb_info *fb_info, + struct fb_var_screeninfo *var) +{ + struct fb_fix_screeninfo *fix = &fb_info->fix; + unsigned int yres = fb_info->var.yres; + int err; + + if (var->yoffset > 0) { + if (var->vmode & FB_VMODE_YWRAP) { + if (!fix->ywrapstep || + (var->yoffset % fix->ywrapstep)) { + DRM_ERROR("fbconv: Invalid fix->ywrapstep: %d\n", + fix->ywrapstep); + return -EINVAL; + } + yres = 0; + } else if (!fix->ypanstep || (var->yoffset % fix->ypanstep)) { + DRM_ERROR("fbconv: Invalid fix->ypanstep: %d\n", + fix->ypanstep); + return -EINVAL; + } + } + + if (var->xoffset > 0) { + if (!fix->xpanstep || (var->xoffset % fix->xpanstep)) { + DRM_ERROR("fbconv: Invalid fix->xpanstep: %d\n", + fix->xpanstep); + return -EINVAL; + } + } + + if (!fb_info->fbops->fb_pan_display || + var->yoffset > fb_info->var.yres_virtual - yres || + var->xoffset > fb_info->var.xres_virtual - fb_info->var.xres) { + DRM_ERROR("fbconv: Display panning unsupported\n"); + return -EINVAL; + } + + err = fb_info->fbops->fb_pan_display(var, fb_info); + if (err) { + DRM_ERROR("fbconv: fbops->pan_display() failed: %d", err); + return err; + } + + fb_info->var.xoffset = var->xoffset; + fb_info->var.yoffset = var->yoffset; + + if (var->vmode & FB_VMODE_YWRAP) + fb_info->var.vmode |= FB_VMODE_YWRAP; + else + fb_info->var.vmode &= ~FB_VMODE_YWRAP; + + return 0; +} + +static int drm_fbconv_set_var(struct fb_info *fb_info, + struct fb_var_screeninfo *var) +{ + int ret = 0; + u32 activate; + struct fb_var_screeninfo old_var; + struct fb_videomode mode; + + if (var->activate & FB_ACTIVATE_INV_MODE) { + struct fb_videomode mode1, mode2; + + fb_var_to_videomode(&mode1, var); + fb_var_to_videomode(&mode2, &fb_info->var); + /* make sure we don't delete the videomode of current var */ + ret = fb_mode_is_equal(&mode1, &mode2); + if (ret) { + DRM_ERROR("fbconv: fb_mode_is_equal() failed: %d\n", + ret); + return -EINVAL; + } + + fb_delete_videomode(&mode1, &fb_info->modelist); + + return 0; + } + + if (!(var->activate & FB_ACTIVATE_FORCE) && + !memcmp(&fb_info->var, var, sizeof(*var))) + return 0; + + activate = var->activate; + + /* When using FOURCC mode, make sure the red, green, blue and + * transp fields are set to 0. + */ + if ((fb_info->fix.capabilities & FB_CAP_FOURCC) && var->grayscale > 1) { + if (var->red.offset || var->green.offset || + var->blue.offset || var->transp.offset || + var->red.length || var->green.length || + var->blue.length || var->transp.length || + var->red.msb_right || var->green.msb_right || + var->blue.msb_right || var->transp.msb_right) { + DRM_ERROR("fbconv: Invalid color offsets in FOURCC mode\n"); + return -EINVAL; + } + } + + if (!fb_info->fbops->fb_check_var) { + *var = fb_info->var; + return 0; + } + + ret = fb_info->fbops->fb_check_var(var, fb_info); + if (ret) { + DRM_ERROR("fbconv: fbops->fb_check_var() failed: %d\n", ret); + return ret; + } + + if ((var->activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NOW) + return 0; + + old_var = fb_info->var; + fb_info->var = *var; + + if (fb_info->fbops->fb_set_par) { + ret = fb_info->fbops->fb_set_par(fb_info); + if (ret) { + fb_info->var = old_var; + DRM_ERROR("fbconv: fbops->fb_set_par() failed: %d\n", + ret); + return ret; + } + } + + drm_fbconv_pan_display(fb_info, &fb_info->var); + drm_fbconv_set_cmap(&fb_info->cmap, fb_info); + fb_var_to_videomode(&mode, &fb_info->var); + + if (fb_info->modelist.prev && fb_info->modelist.next && + !list_empty(&fb_info->modelist)) + ret = fb_add_videomode(&mode, &fb_info->modelist); + + if (ret) { + DRM_ERROR("fbconv: fb_add_videomode() failed: %d\n", ret); + return ret; + } + + return 0; +} + /** * drm_fbconv_simple_display_pipe_mode_valid - default implementation for * struct drm_simple_display_pipe_funcs.mode_valid @@ -1105,13 +1311,11 @@ drm_fbconv_simple_display_pipe_enable(struct drm_simple_display_pipe *pipe, fb_var.activate = FB_ACTIVATE_NOW; - ret = fb_set_var(modeset->fb_info, &fb_var); - if (ret) { - DRM_ERROR("fbconv: fb_set_var() failed: %d\n", ret); + ret = drm_fbconv_set_var(modeset->fb_info, &fb_var); + if (ret) return; - } - fb_blank(modeset->fb_info, FB_BLANK_UNBLANK); + drm_fbconv_blank(modeset->fb_info, FB_BLANK_UNBLANK); drm_fbconv_blit_fullscreen(modeset->blit.screen_base, modeset->blit.vmap, @@ -1129,7 +1333,7 @@ drm_fbconv_simple_display_pipe_disable(struct drm_simple_display_pipe *pipe) { struct drm_fbconv_modeset *modeset = drm_fbconv_modeset_of_pipe(pipe); - fb_blank(modeset->fb_info, FB_BLANK_POWERDOWN); + drm_fbconv_blank(modeset->fb_info, FB_BLANK_POWERDOWN); } EXPORT_SYMBOL(drm_fbconv_simple_display_pipe_disable); @@ -1295,7 +1499,7 @@ drm_fbconv_simple_display_pipe_update(struct drm_simple_display_pipe *pipe, if (!pipe->plane.state->fb) { /* No framebuffer installed; blank display. */ - fb_blank(modeset->fb_info, FB_BLANK_NORMAL); + drm_fbconv_blank(modeset->fb_info, FB_BLANK_NORMAL); return; } @@ -1315,11 +1519,9 @@ drm_fbconv_simple_display_pipe_update(struct drm_simple_display_pipe *pipe, fb_var.activate = FB_ACTIVATE_NOW; - ret = fb_set_var(modeset->fb_info, &fb_var); - if (ret) { - DRM_ERROR("fbconv: fb_set_var() failed: %d\n", ret); + ret = drm_fbconv_set_var(modeset->fb_info, &fb_var); + if (ret) return; - } } if (!old_plane_state->fb || /* first-time update */ @@ -1344,11 +1546,9 @@ drm_fbconv_simple_display_pipe_update(struct drm_simple_display_pipe *pipe, fb_var.xoffset = 0; fb_var.yoffset = 0; - ret = fb_pan_display(modeset->fb_info, &fb_var); - if (ret) { - DRM_ERROR("fbconv: fb_pan_display() failed: %d\n", ret); + ret = drm_fbconv_pan_display(modeset->fb_info, &fb_var); + if (ret) return; - } do_blit = drm_atomic_helper_damage_merged(old_plane_state, pipe->plane.state, -- 2.23.0 From mboxrd@z Thu Jan 1 00:00:00 1970 From: Thomas Zimmermann Subject: [PATCH v2 10/15] drm/fbconv: Reimplement several fbdev interfaces Date: Mon, 14 Oct 2019 16:04:11 +0200 Message-ID: <20191014140416.28517-11-tzimmermann@suse.de> References: <20191014140416.28517-1-tzimmermann@suse.de> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Received: from mx1.suse.de (mx2.suse.de [195.135.220.15]) by gabe.freedesktop.org (Postfix) with ESMTPS id 57C866E2E8 for ; Mon, 14 Oct 2019 14:04:25 +0000 (UTC) In-Reply-To: <20191014140416.28517-1-tzimmermann@suse.de> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: airlied@linux.ie, daniel@ffwll.ch, maarten.lankhorst@linux.intel.com, mripard@kernel.org, sean@poorly.run, b.zolnierkie@samsung.com, ajax@redhat.com, ville.syrjala@linux.intel.com, malat@debian.org, michel@daenzer.net Cc: gregkh@linuxfoundation.org, linux-fbdev@vger.kernel.org, Thomas Zimmermann , dri-devel@lists.freedesktop.org, corbet@lwn.net List-Id: dri-devel@lists.freedesktop.org VGhpcyBwYXRjaCByZWltcGxlbWVudHMgZmJfYmxhbmsoKSwgZmJfcGFuX2Rpc3BsYXkoKSwgZmJf c2V0X2NtYXAoKSBhbmQKZmJfc2V0X3ZhcigpIGZvciBmYmNvbnYgaGVscGVycy4gVGhlIGdvYWwg aXMgdG8gaGF2ZSBhbGwgY2FsbHMgdG8gZHJpdmVyCmNhbGxiYWNrIGZ1bmN0aW9ucyBsb2NhdGVk IHdpdGhpbiBmYmNvbnYgYW5kIHRvIHJlZHVjZSB0aGUgYW1vdW50IG9mCmNvbnRhaW5lZCB3b3Jr IHRvIGEgbWluaW11bS4KClNvbWUgbm90ZWFibGUgZGlmZmVyZW5jZXMgdG8gZmJkZXYgaW5jbHVk ZToKCiAgKiBDb2RlIHJlbGF0ZWQgdG8gZmJjb24gaGFzIGJlZW4gbGVmdCBvdXQuIENvbnNvbGUg c3VwcG9ydCBpcwogICAgZW11bGF0ZWQgYnkgRFJNIGFuZCB0aGUgZHJpdmVycyBkb24ndCBpbnRl cmFjdCBkaXJlY3RseSB3aXRoCiAgICBpdC4KCiAgKiBObyBldmVudHMgYXJlIHNlbnQgb3V0LiBB cyB0aGUgZmJjb252IGhlbHBlcnMgYXJlIG5vdCBwYXJ0IG9mCiAgICB0aGUgZmJkZXYgZnJhbWV3 b3JrLCB0aGVyZSBhcmUgbm8gZXZlbnQgbGlzdGVuZXJzIGFueXdheS4KCiAgKiBDb2RlIHJlbGF0 ZWQgdG8gaW9jdGwgYW5kIHVzZXItc3BhY2UgaGFzIGJlZW4gbGVmdCBvdXQgYXMKICAgIHdlbGwu IFVzZXItc3BhY2UgaW50ZXJmYWNlcyBhcmUgcHJvdmlkZWQgYnkgRFJNLgoKICAqIEVycm9yIG1l c3NhZ2VzIGhhdmUgYmVlbiBhZGRlZC4KClNpZ25lZC1vZmYtYnk6IFRob21hcyBaaW1tZXJtYW5u IDx0emltbWVybWFubkBzdXNlLmRlPgotLS0KIGRyaXZlcnMvZ3B1L2RybS9kcm1fZmJjb252X2hl bHBlci5jIHwgMjQwICsrKysrKysrKysrKysrKysrKysrKysrKystLS0KIDEgZmlsZSBjaGFuZ2Vk LCAyMjAgaW5zZXJ0aW9ucygrKSwgMjAgZGVsZXRpb25zKC0pCgpkaWZmIC0tZ2l0IGEvZHJpdmVy cy9ncHUvZHJtL2RybV9mYmNvbnZfaGVscGVyLmMgYi9kcml2ZXJzL2dwdS9kcm0vZHJtX2ZiY29u dl9oZWxwZXIuYwppbmRleCBjYThiNDNjOTEyNjYuLmY3ZjI0N2UzMGEzZCAxMDA2NDQKLS0tIGEv ZHJpdmVycy9ncHUvZHJtL2RybV9mYmNvbnZfaGVscGVyLmMKKysrIGIvZHJpdmVycy9ncHUvZHJt L2RybV9mYmNvbnZfaGVscGVyLmMKQEAgLTczNyw2ICs3MzcsNTUgQEAgc3RhdGljIGNvbnN0IHN0 cnVjdCBkcm1fY29ubmVjdG9yX2Z1bmNzIGNvbm5lY3Rvcl9mdW5jcyA9IHsKICAqIENvbG9ybWFw IHVwZGF0ZXMKICAqLwogCitzdGF0aWMgaW50IGRybV9mYmNvbnZfc2V0X2NtYXAoc3RydWN0IGZi X2NtYXAgKmNtYXAsIHN0cnVjdCBmYl9pbmZvICpmYl9pbmZvKQoreworCWludCBpLCBzdGFydCwg cmVzOworCXUxNiAqcmVkLCAqZ3JlZW4sICpibHVlLCAqdHJhbnNwOworCXVfaW50IGhyZWQsIGhn cmVlbiwgaGJsdWUsIGh0cmFuc3AgPSAweGZmZmY7CisKKwlyZWQgPSBjbWFwLT5yZWQ7CisJZ3Jl ZW4gPSBjbWFwLT5ncmVlbjsKKwlibHVlID0gY21hcC0+Ymx1ZTsKKwl0cmFuc3AgPSBjbWFwLT50 cmFuc3A7CisJc3RhcnQgPSBjbWFwLT5zdGFydDsKKworCWlmIChzdGFydCA8IDAgfHwgKCFmYl9p bmZvLT5mYm9wcy0+ZmJfc2V0Y29scmVnICYmCisJCQkgICFmYl9pbmZvLT5mYm9wcy0+ZmJfc2V0 Y21hcCkpIHsKKwkJRFJNX0VSUk9SKCJmYmNvbnY6IFBhbGV0dGUgbm90IHN1cHBvcnRlZC5cbiIp OworCQlyZXR1cm4gLUVJTlZBTDsKKwl9CisKKwlpZiAoZmJfaW5mby0+ZmJvcHMtPmZiX3NldGNt YXApIHsKKwkJcmVzID0gZmJfaW5mby0+ZmJvcHMtPmZiX3NldGNtYXAoY21hcCwgZmJfaW5mbyk7 CisJCWlmIChyZXMpIHsKKwkJCURSTV9FUlJPUigiZmJjb252OiBmYm9wcy0+ZmJfc2V0Y21hcCgp IGZhaWxlZDogJWRcbiIsCisJCQkJICByZXMpOworCQkJcmV0dXJuIHJlczsKKwkJfQorCX0gZWxz ZSB7CisJCWZvciAoaSA9IDA7IGkgPCBjbWFwLT5sZW47IGkrKykgeworCQkJaHJlZCA9ICpyZWQr KzsKKwkJCWhncmVlbiA9ICpncmVlbisrOworCQkJaGJsdWUgPSAqYmx1ZSsrOworCQkJaWYgKHRy YW5zcCkKKwkJCQlodHJhbnNwID0gKnRyYW5zcCsrOworCQkJcmVzID0gZmJfaW5mby0+ZmJvcHMt PmZiX3NldGNvbHJlZyhzdGFydCsrLAorCQkJCQkJCSAgIGhyZWQsIGhncmVlbiwgaGJsdWUsCisJ CQkJCQkJICAgaHRyYW5zcCwgZmJfaW5mbyk7CisJCQlpZiAocmVzKSB7CisJCQkJRFJNX0VSUk9S KCJmYmNvbnY6IGZib3BzLT5mYl9zZXRjb2xyZWcoKSBmYWlsZWQ6ICVkXG4iLAorCQkJCQkgIHJl cyk7CisJCQkJLyogY21hcCBoYW5kbGluZyBpcyBhIG1lc3M7IGRvbid0IGVyciBoZXJlICovCisJ CQkJYnJlYWs7CisJCQl9CisJCX0KKwl9CisKKwlmYl9jb3B5X2NtYXAoY21hcCwgJmZiX2luZm8t PmNtYXApOworCisJcmV0dXJuIDA7Cit9CisKIC8qIHByb3ZpZGVzIGEgZGVmYXVsdCBjb2xvcm1h cCBmb3IgcGFsZXR0ZSBtb2RlcyAqLwogc3RhdGljIGludCBjcmVhdGVfcGFsZXR0ZV9jbWFwKHN0 cnVjdCBmYl9jbWFwICpjbWFwLAogCQkJICAgICAgIGNvbnN0IHN0cnVjdCBmYl92YXJfc2NyZWVu aW5mbyAqZmJfdmFyKQpAQCAtODU2LDExICs5MDUsOSBAQCBzdGF0aWMgaW50IHNldF9jbWFwKHN0 cnVjdCBmYl9pbmZvICpmYl9pbmZvKQogCWlmIChyZXQpCiAJCXJldHVybiByZXQ7CiAKLQlyZXQg PSBmYl9zZXRfY21hcCgmY21hcCwgZmJfaW5mbyk7Ci0JaWYgKHJldCkgewotCQlEUk1fRVJST1Io ImZiY29udjogZmJfc2V0X2NtYXAoKSBmYWlsZWQ6ICVkXG4iLCByZXQpOworCXJldCA9IGRybV9m YmNvbnZfc2V0X2NtYXAoJmNtYXAsIGZiX2luZm8pOworCWlmIChyZXQpCiAJCWdvdG8gZXJyX2Zi X2RlYWxsb2NfY21hcDsKLQl9CiAJZmJfZGVhbGxvY19jbWFwKCZjbWFwKTsKIAogCXJldHVybiAw OwpAQCAtODkxLDcgKzkzOCw3IEBAIHN0YXRpYyBpbnQgZHJtX2ZiY29udl91cGRhdGVfZmJfdmFy X3NjcmVlbmluZm9fZnJvbV9mcmFtZWJ1ZmZlcigKIAogCS8qIE91ciB2aXJ0dWFsIHNjcmVlbiBj b3ZlcnMgYWxsIHRoZSBncmFwaGljcyBtZW1vcnkgKHNhbnMgc29tZQogCSAqIHRyYWlsaW5nIGJ5 dGVzKS4gVGhpcyBhbGxvd3MgZm9yIHNldHRpbmcgdGhlIHNjYW5vdXQgYnVmZmVyJ3MKLQkgKiBh ZGRyZXNzIHdpdGggZmJfcGFuX2Rpc3BsYXkoKS4KKwkgKiBhZGRyZXNzIHdpdGggZHJtX2ZiY29u dl9wYW5fZGlzcGxheSgpLgogCSAqLwogCiAJd2lkdGggPSBmYi0+cGl0Y2hlc1swXTsKQEAgLTkz Nyw2ICs5ODQsMTY1IEBAIHN0YXRpYyBpbnQgZHJtX2ZiY29udl91cGRhdGVfZmJfdmFyX3NjcmVl bmluZm9fZnJvbV9zaW1wbGVfZGlzcGxheV9waXBlKAogCXJldHVybiAwOwogfQogCitzdGF0aWMg aW50IGRybV9mYmNvbnZfYmxhbmsoc3RydWN0IGZiX2luZm8gKmZiX2luZm8sIGludCBibGFuaykK K3sKKwlpbnQgcmV0ID0gLUVJTlZBTDsKKworCWlmIChmYl9pbmZvLT5mYm9wcy0+ZmJfYmxhbmsp IHsKKwkJcmV0ID0gZmJfaW5mby0+ZmJvcHMtPmZiX2JsYW5rKGJsYW5rLCBmYl9pbmZvKTsKKwkJ aWYgKHJldCkgeworCQkJRFJNX0VSUk9SKCJmYmNvbnY6IGZib3BzLT5mYl9ibGFuaygpIGZhaWxl ZDogJWRcbiIsCisJCQkJICByZXQpOworCQl9CisJfQorCXJldHVybiByZXQ7Cit9CisKK3N0YXRp YyBpbnQgZHJtX2ZiY29udl9wYW5fZGlzcGxheShzdHJ1Y3QgZmJfaW5mbyAqZmJfaW5mbywKKwkJ CQkgIHN0cnVjdCBmYl92YXJfc2NyZWVuaW5mbyAqdmFyKQoreworCXN0cnVjdCBmYl9maXhfc2Ny ZWVuaW5mbyAqZml4ID0gJmZiX2luZm8tPmZpeDsKKwl1bnNpZ25lZCBpbnQgeXJlcyA9IGZiX2lu Zm8tPnZhci55cmVzOworCWludCBlcnI7CisKKwlpZiAodmFyLT55b2Zmc2V0ID4gMCkgeworCQlp ZiAodmFyLT52bW9kZSAmIEZCX1ZNT0RFX1lXUkFQKSB7CisJCQlpZiAoIWZpeC0+eXdyYXBzdGVw IHx8CisJCQkgICAgKHZhci0+eW9mZnNldCAlIGZpeC0+eXdyYXBzdGVwKSkgeworCQkJCURSTV9F UlJPUigiZmJjb252OiBJbnZhbGlkIGZpeC0+eXdyYXBzdGVwOiAlZFxuIiwKKwkJCQkJICBmaXgt Pnl3cmFwc3RlcCk7CisJCQkJcmV0dXJuIC1FSU5WQUw7CisJCQl9CisJCQl5cmVzID0gMDsKKwkJ fSBlbHNlIGlmICghZml4LT55cGFuc3RlcCB8fCAodmFyLT55b2Zmc2V0ICUgZml4LT55cGFuc3Rl cCkpIHsKKwkJCURSTV9FUlJPUigiZmJjb252OiBJbnZhbGlkIGZpeC0+eXBhbnN0ZXA6ICVkXG4i LAorCQkJCSAgZml4LT55cGFuc3RlcCk7CisJCQlyZXR1cm4gLUVJTlZBTDsKKwkJfQorCX0KKwor CWlmICh2YXItPnhvZmZzZXQgPiAwKSB7CisJCWlmICghZml4LT54cGFuc3RlcCB8fCAodmFyLT54 b2Zmc2V0ICUgZml4LT54cGFuc3RlcCkpIHsKKwkJCURSTV9FUlJPUigiZmJjb252OiBJbnZhbGlk IGZpeC0+eHBhbnN0ZXA6ICVkXG4iLAorCQkJCSAgZml4LT54cGFuc3RlcCk7CisJCQlyZXR1cm4g LUVJTlZBTDsKKwkJfQorCX0KKworCWlmICghZmJfaW5mby0+ZmJvcHMtPmZiX3Bhbl9kaXNwbGF5 IHx8CisJICAgIHZhci0+eW9mZnNldCA+IGZiX2luZm8tPnZhci55cmVzX3ZpcnR1YWwgLSB5cmVz IHx8CisJICAgIHZhci0+eG9mZnNldCA+IGZiX2luZm8tPnZhci54cmVzX3ZpcnR1YWwgLSBmYl9p bmZvLT52YXIueHJlcykgeworCQlEUk1fRVJST1IoImZiY29udjogRGlzcGxheSBwYW5uaW5nIHVu c3VwcG9ydGVkXG4iKTsKKwkJcmV0dXJuIC1FSU5WQUw7CisJfQorCisJZXJyID0gZmJfaW5mby0+ ZmJvcHMtPmZiX3Bhbl9kaXNwbGF5KHZhciwgZmJfaW5mbyk7CisJaWYgKGVycikgeworCQlEUk1f RVJST1IoImZiY29udjogZmJvcHMtPnBhbl9kaXNwbGF5KCkgZmFpbGVkOiAlZCIsIGVycik7CisJ CXJldHVybiBlcnI7CisJfQorCisJZmJfaW5mby0+dmFyLnhvZmZzZXQgPSB2YXItPnhvZmZzZXQ7 CisJZmJfaW5mby0+dmFyLnlvZmZzZXQgPSB2YXItPnlvZmZzZXQ7CisKKwlpZiAodmFyLT52bW9k ZSAmIEZCX1ZNT0RFX1lXUkFQKQorCQlmYl9pbmZvLT52YXIudm1vZGUgfD0gRkJfVk1PREVfWVdS QVA7CisJZWxzZQorCQlmYl9pbmZvLT52YXIudm1vZGUgJj0gfkZCX1ZNT0RFX1lXUkFQOworCisJ cmV0dXJuIDA7Cit9CisKK3N0YXRpYyBpbnQgZHJtX2ZiY29udl9zZXRfdmFyKHN0cnVjdCBmYl9p bmZvICpmYl9pbmZvLAorCQkJICAgICAgc3RydWN0IGZiX3Zhcl9zY3JlZW5pbmZvICp2YXIpCit7 CisJaW50IHJldCA9IDA7CisJdTMyIGFjdGl2YXRlOworCXN0cnVjdCBmYl92YXJfc2NyZWVuaW5m byBvbGRfdmFyOworCXN0cnVjdCBmYl92aWRlb21vZGUgbW9kZTsKKworCWlmICh2YXItPmFjdGl2 YXRlICYgRkJfQUNUSVZBVEVfSU5WX01PREUpIHsKKwkJc3RydWN0IGZiX3ZpZGVvbW9kZSBtb2Rl MSwgbW9kZTI7CisKKwkJZmJfdmFyX3RvX3ZpZGVvbW9kZSgmbW9kZTEsIHZhcik7CisJCWZiX3Zh cl90b192aWRlb21vZGUoJm1vZGUyLCAmZmJfaW5mby0+dmFyKTsKKwkJLyogbWFrZSBzdXJlIHdl IGRvbid0IGRlbGV0ZSB0aGUgdmlkZW9tb2RlIG9mIGN1cnJlbnQgdmFyICovCisJCXJldCA9IGZi X21vZGVfaXNfZXF1YWwoJm1vZGUxLCAmbW9kZTIpOworCQlpZiAocmV0KSB7CisJCQlEUk1fRVJS T1IoImZiY29udjogZmJfbW9kZV9pc19lcXVhbCgpIGZhaWxlZDogJWRcbiIsCisJCQkJICByZXQp OworCQkJcmV0dXJuIC1FSU5WQUw7CisJCX0KKworCQlmYl9kZWxldGVfdmlkZW9tb2RlKCZtb2Rl MSwgJmZiX2luZm8tPm1vZGVsaXN0KTsKKworCQlyZXR1cm4gMDsKKwl9CisKKwlpZiAoISh2YXIt PmFjdGl2YXRlICYgRkJfQUNUSVZBVEVfRk9SQ0UpICYmCisJICAgICFtZW1jbXAoJmZiX2luZm8t PnZhciwgdmFyLCBzaXplb2YoKnZhcikpKQorCQlyZXR1cm4gMDsKKworCWFjdGl2YXRlID0gdmFy LT5hY3RpdmF0ZTsKKworCS8qIFdoZW4gdXNpbmcgRk9VUkNDIG1vZGUsIG1ha2Ugc3VyZSB0aGUg cmVkLCBncmVlbiwgYmx1ZSBhbmQKKwkgKiB0cmFuc3AgZmllbGRzIGFyZSBzZXQgdG8gMC4KKwkg Ki8KKwlpZiAoKGZiX2luZm8tPmZpeC5jYXBhYmlsaXRpZXMgJiBGQl9DQVBfRk9VUkNDKSAmJiB2 YXItPmdyYXlzY2FsZSA+IDEpIHsKKwkJaWYgKHZhci0+cmVkLm9mZnNldCAgICAgfHwgdmFyLT5n cmVlbi5vZmZzZXQgICAgfHwKKwkJICAgIHZhci0+Ymx1ZS5vZmZzZXQgICAgfHwgdmFyLT50cmFu c3Aub2Zmc2V0ICAgfHwKKwkJICAgIHZhci0+cmVkLmxlbmd0aCAgICAgfHwgdmFyLT5ncmVlbi5s ZW5ndGggICAgfHwKKwkJICAgIHZhci0+Ymx1ZS5sZW5ndGggICAgfHwgdmFyLT50cmFuc3AubGVu Z3RoICAgfHwKKwkJICAgIHZhci0+cmVkLm1zYl9yaWdodCAgfHwgdmFyLT5ncmVlbi5tc2Jfcmln aHQgfHwKKwkJICAgIHZhci0+Ymx1ZS5tc2JfcmlnaHQgfHwgdmFyLT50cmFuc3AubXNiX3JpZ2h0 KSB7CisJCQlEUk1fRVJST1IoImZiY29udjogSW52YWxpZCBjb2xvciBvZmZzZXRzIGluIEZPVVJD QyBtb2RlXG4iKTsKKwkJCXJldHVybiAtRUlOVkFMOworCQl9CisJfQorCisJaWYgKCFmYl9pbmZv LT5mYm9wcy0+ZmJfY2hlY2tfdmFyKSB7CisJCSp2YXIgPSBmYl9pbmZvLT52YXI7CisJCXJldHVy biAwOworCX0KKworCXJldCA9IGZiX2luZm8tPmZib3BzLT5mYl9jaGVja192YXIodmFyLCBmYl9p bmZvKTsKKwlpZiAocmV0KSB7CisJCURSTV9FUlJPUigiZmJjb252OiBmYm9wcy0+ZmJfY2hlY2tf dmFyKCkgZmFpbGVkOiAlZFxuIiwgcmV0KTsKKwkJcmV0dXJuIHJldDsKKwl9CisKKwlpZiAoKHZh ci0+YWN0aXZhdGUgJiBGQl9BQ1RJVkFURV9NQVNLKSAhPSBGQl9BQ1RJVkFURV9OT1cpCisJCXJl dHVybiAwOworCisJb2xkX3ZhciA9IGZiX2luZm8tPnZhcjsKKwlmYl9pbmZvLT52YXIgPSAqdmFy OworCisJaWYgKGZiX2luZm8tPmZib3BzLT5mYl9zZXRfcGFyKSB7CisJCXJldCA9IGZiX2luZm8t PmZib3BzLT5mYl9zZXRfcGFyKGZiX2luZm8pOworCQlpZiAocmV0KSB7CisJCQlmYl9pbmZvLT52 YXIgPSBvbGRfdmFyOworCQkJRFJNX0VSUk9SKCJmYmNvbnY6IGZib3BzLT5mYl9zZXRfcGFyKCkg ZmFpbGVkOiAlZFxuIiwKKwkJCQkgIHJldCk7CisJCQlyZXR1cm4gcmV0OworCQl9CisJfQorCisJ ZHJtX2ZiY29udl9wYW5fZGlzcGxheShmYl9pbmZvLCAmZmJfaW5mby0+dmFyKTsKKwlkcm1fZmJj b252X3NldF9jbWFwKCZmYl9pbmZvLT5jbWFwLCBmYl9pbmZvKTsKKwlmYl92YXJfdG9fdmlkZW9t b2RlKCZtb2RlLCAmZmJfaW5mby0+dmFyKTsKKworCWlmIChmYl9pbmZvLT5tb2RlbGlzdC5wcmV2 ICYmIGZiX2luZm8tPm1vZGVsaXN0Lm5leHQgJiYKKwkgICAgIWxpc3RfZW1wdHkoJmZiX2luZm8t Pm1vZGVsaXN0KSkKKwkJcmV0ID0gZmJfYWRkX3ZpZGVvbW9kZSgmbW9kZSwgJmZiX2luZm8tPm1v ZGVsaXN0KTsKKworCWlmIChyZXQpIHsKKwkJRFJNX0VSUk9SKCJmYmNvbnY6IGZiX2FkZF92aWRl b21vZGUoKSBmYWlsZWQ6ICVkXG4iLCByZXQpOworCQlyZXR1cm4gcmV0OworCX0KKworCXJldHVy biAwOworfQorCiAvKioKICAqIGRybV9mYmNvbnZfc2ltcGxlX2Rpc3BsYXlfcGlwZV9tb2RlX3Zh bGlkIC0gZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBmb3IKICAqCXN0cnVjdCBkcm1fc2ltcGxlX2Rp c3BsYXlfcGlwZV9mdW5jcy5tb2RlX3ZhbGlkCkBAIC0xMTA1LDEzICsxMzExLDExIEBAIGRybV9m YmNvbnZfc2ltcGxlX2Rpc3BsYXlfcGlwZV9lbmFibGUoc3RydWN0IGRybV9zaW1wbGVfZGlzcGxh eV9waXBlICpwaXBlLAogCiAJZmJfdmFyLmFjdGl2YXRlID0gRkJfQUNUSVZBVEVfTk9XOwogCi0J cmV0ID0gZmJfc2V0X3Zhcihtb2Rlc2V0LT5mYl9pbmZvLCAmZmJfdmFyKTsKLQlpZiAocmV0KSB7 Ci0JCURSTV9FUlJPUigiZmJjb252OiBmYl9zZXRfdmFyKCkgZmFpbGVkOiAlZFxuIiwgcmV0KTsK KwlyZXQgPSBkcm1fZmJjb252X3NldF92YXIobW9kZXNldC0+ZmJfaW5mbywgJmZiX3Zhcik7CisJ aWYgKHJldCkKIAkJcmV0dXJuOwotCX0KIAotCWZiX2JsYW5rKG1vZGVzZXQtPmZiX2luZm8sIEZC X0JMQU5LX1VOQkxBTkspOworCWRybV9mYmNvbnZfYmxhbmsobW9kZXNldC0+ZmJfaW5mbywgRkJf QkxBTktfVU5CTEFOSyk7CiAKIAlkcm1fZmJjb252X2JsaXRfZnVsbHNjcmVlbihtb2Rlc2V0LT5i bGl0LnNjcmVlbl9iYXNlLAogCQkJCSAgIG1vZGVzZXQtPmJsaXQudm1hcCwKQEAgLTExMjksNyAr MTMzMyw3IEBAIGRybV9mYmNvbnZfc2ltcGxlX2Rpc3BsYXlfcGlwZV9kaXNhYmxlKHN0cnVjdCBk cm1fc2ltcGxlX2Rpc3BsYXlfcGlwZSAqcGlwZSkKIHsKIAlzdHJ1Y3QgZHJtX2ZiY29udl9tb2Rl c2V0ICptb2Rlc2V0ID0gZHJtX2ZiY29udl9tb2Rlc2V0X29mX3BpcGUocGlwZSk7CiAKLQlmYl9i bGFuayhtb2Rlc2V0LT5mYl9pbmZvLCBGQl9CTEFOS19QT1dFUkRPV04pOworCWRybV9mYmNvbnZf YmxhbmsobW9kZXNldC0+ZmJfaW5mbywgRkJfQkxBTktfUE9XRVJET1dOKTsKIH0KIEVYUE9SVF9T WU1CT0woZHJtX2ZiY29udl9zaW1wbGVfZGlzcGxheV9waXBlX2Rpc2FibGUpOwogCkBAIC0xMjk1 LDcgKzE0OTksNyBAQCBkcm1fZmJjb252X3NpbXBsZV9kaXNwbGF5X3BpcGVfdXBkYXRlKHN0cnVj dCBkcm1fc2ltcGxlX2Rpc3BsYXlfcGlwZSAqcGlwZSwKIAogCWlmICghcGlwZS0+cGxhbmUuc3Rh dGUtPmZiKSB7CiAJCS8qIE5vIGZyYW1lYnVmZmVyIGluc3RhbGxlZDsgYmxhbmsgZGlzcGxheS4g Ki8KLQkJZmJfYmxhbmsobW9kZXNldC0+ZmJfaW5mbywgRkJfQkxBTktfTk9STUFMKTsKKwkJZHJt X2ZiY29udl9ibGFuayhtb2Rlc2V0LT5mYl9pbmZvLCBGQl9CTEFOS19OT1JNQUwpOwogCQlyZXR1 cm47CiAJfQogCkBAIC0xMzE1LDExICsxNTE5LDkgQEAgZHJtX2ZiY29udl9zaW1wbGVfZGlzcGxh eV9waXBlX3VwZGF0ZShzdHJ1Y3QgZHJtX3NpbXBsZV9kaXNwbGF5X3BpcGUgKnBpcGUsCiAKIAkJ ZmJfdmFyLmFjdGl2YXRlID0gRkJfQUNUSVZBVEVfTk9XOwogCi0JCXJldCA9IGZiX3NldF92YXIo bW9kZXNldC0+ZmJfaW5mbywgJmZiX3Zhcik7Ci0JCWlmIChyZXQpIHsKLQkJCURSTV9FUlJPUigi ZmJjb252OiBmYl9zZXRfdmFyKCkgZmFpbGVkOiAlZFxuIiwgcmV0KTsKKwkJcmV0ID0gZHJtX2Zi Y29udl9zZXRfdmFyKG1vZGVzZXQtPmZiX2luZm8sICZmYl92YXIpOworCQlpZiAocmV0KQogCQkJ cmV0dXJuOwotCQl9CiAJfQogCiAJaWYgKCFvbGRfcGxhbmVfc3RhdGUtPmZiIHx8IC8qIGZpcnN0 LXRpbWUgdXBkYXRlICovCkBAIC0xMzQ0LDExICsxNTQ2LDkgQEAgZHJtX2ZiY29udl9zaW1wbGVf ZGlzcGxheV9waXBlX3VwZGF0ZShzdHJ1Y3QgZHJtX3NpbXBsZV9kaXNwbGF5X3BpcGUgKnBpcGUs CiAJZmJfdmFyLnhvZmZzZXQgPSAwOwogCWZiX3Zhci55b2Zmc2V0ID0gMDsKIAotCXJldCA9IGZi X3Bhbl9kaXNwbGF5KG1vZGVzZXQtPmZiX2luZm8sICZmYl92YXIpOwotCWlmIChyZXQpIHsKLQkJ RFJNX0VSUk9SKCJmYmNvbnY6IGZiX3Bhbl9kaXNwbGF5KCkgZmFpbGVkOiAlZFxuIiwgcmV0KTsK KwlyZXQgPSBkcm1fZmJjb252X3Bhbl9kaXNwbGF5KG1vZGVzZXQtPmZiX2luZm8sICZmYl92YXIp OworCWlmIChyZXQpCiAJCXJldHVybjsKLQl9CiAKIAlkb19ibGl0ID0gZHJtX2F0b21pY19oZWxw ZXJfZGFtYWdlX21lcmdlZChvbGRfcGxhbmVfc3RhdGUsCiAJCQkJCQkgIHBpcGUtPnBsYW5lLnN0 YXRlLAotLSAKMi4yMy4wCgpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fXwpkcmktZGV2ZWwgbWFpbGluZyBsaXN0CmRyaS1kZXZlbEBsaXN0cy5mcmVlZGVza3Rv cC5vcmcKaHR0cHM6Ly9saXN0cy5mcmVlZGVza3RvcC5vcmcvbWFpbG1hbi9saXN0aW5mby9kcmkt ZGV2ZWw=