From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752053AbcDTTEs (ORCPT ); Wed, 20 Apr 2016 15:04:48 -0400 Received: from smtp.domeneshop.no ([194.63.252.55]:56864 "EHLO smtp.domeneshop.no" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751302AbcDTTEq (ORCPT ); Wed, 20 Apr 2016 15:04:46 -0400 Subject: Re: [PATCH 7/8] drm/qxl: Use drm_fb_helper deferred_io support To: dri-devel@lists.freedesktop.org, linux-fbdev@vger.kernel.org, laurent.pinchart@ideasonboard.com, tomi.valkeinen@ti.com, linux-kernel@vger.kernel.org References: <1461165929-11344-1-git-send-email-noralf@tronnes.org> <1461165929-11344-8-git-send-email-noralf@tronnes.org> <20160420174710.GR2510@phenom.ffwll.local> From: =?UTF-8?Q?Noralf_Tr=c3=b8nnes?= Message-ID: <5717D2C6.7060806@tronnes.org> Date: Wed, 20 Apr 2016 21:04:38 +0200 User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:38.0) Gecko/20100101 Thunderbird/38.7.1 MIME-Version: 1.0 In-Reply-To: <20160420174710.GR2510@phenom.ffwll.local> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Den 20.04.2016 19:47, skrev Daniel Vetter: > On Wed, Apr 20, 2016 at 05:25:28PM +0200, Noralf Trønnes wrote: >> Use the fbdev deferred io support in drm_fb_helper. >> The (struct fb_ops *)->fb_{fillrect,copyarea,imageblit} functions will >> now be deferred in the same way that mmap damage is, instead of being >> flushed directly. >> This patch has only been compile tested. >> >> Signed-off-by: Noralf Trønnes >> --- >> drivers/gpu/drm/qxl/qxl_display.c | 9 +- >> drivers/gpu/drm/qxl/qxl_drv.h | 7 +- >> drivers/gpu/drm/qxl/qxl_fb.c | 220 ++++++++++---------------------------- >> drivers/gpu/drm/qxl/qxl_kms.c | 4 - >> 4 files changed, 62 insertions(+), 178 deletions(-) >> >> diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c >> index 030409a..9a03524 100644 >> --- a/drivers/gpu/drm/qxl/qxl_display.c >> +++ b/drivers/gpu/drm/qxl/qxl_display.c >> @@ -465,7 +465,7 @@ static const struct drm_crtc_funcs qxl_crtc_funcs = { >> .page_flip = qxl_crtc_page_flip, >> }; >> >> -static void qxl_user_framebuffer_destroy(struct drm_framebuffer *fb) >> +void qxl_user_framebuffer_destroy(struct drm_framebuffer *fb) >> { >> struct qxl_framebuffer *qxl_fb = to_qxl_framebuffer(fb); >> >> @@ -527,12 +527,13 @@ int >> qxl_framebuffer_init(struct drm_device *dev, >> struct qxl_framebuffer *qfb, >> const struct drm_mode_fb_cmd2 *mode_cmd, >> - struct drm_gem_object *obj) >> + struct drm_gem_object *obj, >> + const struct drm_framebuffer_funcs *funcs) > There should be no need at all to have a separate fb funcs table for the > fbdev fb. Both /should/ be able to use the exact same (already existing) > ->dirty() callback. We need this only in CMA because CMA is a midlayer > used by multiple drivers. I don't see how I can avoid it. fbdev framebuffer flushing: static void qxl_fb_dirty_flush(struct fb_info *info) { qxl_fb_image_init(&qxl_fb_image, qdev, info, NULL); qxl_draw_opaque_fb(&qxl_fb_image, stride); } drm framebuffer flushing: static int qxl_framebuffer_surface_dirty(...) { qxl_draw_dirty_fb(...); } qxl_draw_opaque_fb() and qxl_draw_dirty_fb() differ so much that it's way over my head to see if they can be combined. Here's an online diff of the two functions: https://www.diffchecker.com/jqbbalux > > With that change you should be able to condense this patch down to pretty > much just removing lines. Which is Good (tm). > > Cheers, Daniel > >> { >> int ret; >> >> qfb->obj = obj; >> - ret = drm_framebuffer_init(dev, &qfb->base, &qxl_fb_funcs); >> + ret = drm_framebuffer_init(dev, &qfb->base, funcs); >> if (ret) { >> qfb->obj = NULL; >> return ret; >> @@ -999,7 +1000,7 @@ qxl_user_framebuffer_create(struct drm_device *dev, >> if (qxl_fb == NULL) >> return NULL; >> >> - ret = qxl_framebuffer_init(dev, qxl_fb, mode_cmd, obj); >> + ret = qxl_framebuffer_init(dev, qxl_fb, mode_cmd, obj, &qxl_fb_funcs); >> if (ret) { >> kfree(qxl_fb); >> drm_gem_object_unreference_unlocked(obj); >> diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h >> index 3f3897e..3ad6604 100644 >> --- a/drivers/gpu/drm/qxl/qxl_drv.h >> +++ b/drivers/gpu/drm/qxl/qxl_drv.h >> @@ -324,8 +324,6 @@ struct qxl_device { >> struct workqueue_struct *gc_queue; >> struct work_struct gc_work; >> >> - struct work_struct fb_work; >> - >> struct drm_property *hotplug_mode_update_property; >> int monitors_config_width; >> int monitors_config_height; >> @@ -389,11 +387,13 @@ int qxl_get_handle_for_primary_fb(struct qxl_device *qdev, >> void qxl_fbdev_set_suspend(struct qxl_device *qdev, int state); >> >> /* qxl_display.c */ >> +void qxl_user_framebuffer_destroy(struct drm_framebuffer *fb); >> int >> qxl_framebuffer_init(struct drm_device *dev, >> struct qxl_framebuffer *rfb, >> const struct drm_mode_fb_cmd2 *mode_cmd, >> - struct drm_gem_object *obj); >> + struct drm_gem_object *obj, >> + const struct drm_framebuffer_funcs *funcs); >> void qxl_display_read_client_monitors_config(struct qxl_device *qdev); >> void qxl_send_monitors_config(struct qxl_device *qdev); >> int qxl_create_monitors_object(struct qxl_device *qdev); >> @@ -553,7 +553,6 @@ int qxl_irq_init(struct qxl_device *qdev); >> irqreturn_t qxl_irq_handler(int irq, void *arg); >> >> /* qxl_fb.c */ >> -int qxl_fb_init(struct qxl_device *qdev); >> bool qxl_fbdev_qobj_is_fb(struct qxl_device *qdev, struct qxl_bo *qobj); >> >> int qxl_debugfs_add_files(struct qxl_device *qdev, >> diff --git a/drivers/gpu/drm/qxl/qxl_fb.c b/drivers/gpu/drm/qxl/qxl_fb.c >> index 06f032d..090dcee 100644 >> --- a/drivers/gpu/drm/qxl/qxl_fb.c >> +++ b/drivers/gpu/drm/qxl/qxl_fb.c >> @@ -30,6 +30,7 @@ >> #include "drm/drm.h" >> #include "drm/drm_crtc.h" >> #include "drm/drm_crtc_helper.h" >> +#include "drm/drm_rect.h" >> #include "qxl_drv.h" >> >> #include "qxl_object.h" >> @@ -46,15 +47,6 @@ struct qxl_fbdev { >> struct list_head delayed_ops; >> void *shadow; >> int size; >> - >> - /* dirty memory logging */ >> - struct { >> - spinlock_t lock; >> - unsigned x1; >> - unsigned y1; >> - unsigned x2; >> - unsigned y2; >> - } dirty; >> }; >> >> static void qxl_fb_image_init(struct qxl_fb_image *qxl_fb_image, >> @@ -82,169 +74,18 @@ static void qxl_fb_image_init(struct qxl_fb_image *qxl_fb_image, >> } >> } >> >> -static void qxl_fb_dirty_flush(struct fb_info *info) >> -{ >> - struct qxl_fbdev *qfbdev = info->par; >> - struct qxl_device *qdev = qfbdev->qdev; >> - struct qxl_fb_image qxl_fb_image; >> - struct fb_image *image = &qxl_fb_image.fb_image; >> - unsigned long flags; >> - u32 x1, x2, y1, y2; >> - >> - /* TODO: hard coding 32 bpp */ >> - int stride = qfbdev->qfb.base.pitches[0]; >> - >> - spin_lock_irqsave(&qfbdev->dirty.lock, flags); >> - >> - x1 = qfbdev->dirty.x1; >> - x2 = qfbdev->dirty.x2; >> - y1 = qfbdev->dirty.y1; >> - y2 = qfbdev->dirty.y2; >> - qfbdev->dirty.x1 = 0; >> - qfbdev->dirty.x2 = 0; >> - qfbdev->dirty.y1 = 0; >> - qfbdev->dirty.y2 = 0; >> - >> - spin_unlock_irqrestore(&qfbdev->dirty.lock, flags); >> - >> - /* >> - * we are using a shadow draw buffer, at qdev->surface0_shadow >> - */ >> - qxl_io_log(qdev, "dirty x[%d, %d], y[%d, %d]", x1, x2, y1, y2); >> - image->dx = x1; >> - image->dy = y1; >> - image->width = x2 - x1 + 1; >> - image->height = y2 - y1 + 1; >> - image->fg_color = 0xffffffff; /* unused, just to avoid uninitialized >> - warnings */ >> - image->bg_color = 0; >> - image->depth = 32; /* TODO: take from somewhere? */ >> - image->cmap.start = 0; >> - image->cmap.len = 0; >> - image->cmap.red = NULL; >> - image->cmap.green = NULL; >> - image->cmap.blue = NULL; >> - image->cmap.transp = NULL; >> - image->data = qfbdev->shadow + (x1 * 4) + (stride * y1); >> - >> - qxl_fb_image_init(&qxl_fb_image, qdev, info, NULL); >> - qxl_draw_opaque_fb(&qxl_fb_image, stride); >> -} >> - >> -static void qxl_dirty_update(struct qxl_fbdev *qfbdev, >> - int x, int y, int width, int height) >> -{ >> - struct qxl_device *qdev = qfbdev->qdev; >> - unsigned long flags; >> - int x2, y2; >> - >> - x2 = x + width - 1; >> - y2 = y + height - 1; >> - >> - spin_lock_irqsave(&qfbdev->dirty.lock, flags); >> - >> - if ((qfbdev->dirty.y2 - qfbdev->dirty.y1) && >> - (qfbdev->dirty.x2 - qfbdev->dirty.x1)) { >> - if (qfbdev->dirty.y1 < y) >> - y = qfbdev->dirty.y1; >> - if (qfbdev->dirty.y2 > y2) >> - y2 = qfbdev->dirty.y2; >> - if (qfbdev->dirty.x1 < x) >> - x = qfbdev->dirty.x1; >> - if (qfbdev->dirty.x2 > x2) >> - x2 = qfbdev->dirty.x2; >> - } >> - >> - qfbdev->dirty.x1 = x; >> - qfbdev->dirty.x2 = x2; >> - qfbdev->dirty.y1 = y; >> - qfbdev->dirty.y2 = y2; >> - >> - spin_unlock_irqrestore(&qfbdev->dirty.lock, flags); >> - >> - schedule_work(&qdev->fb_work); >> -} >> - >> -static void qxl_deferred_io(struct fb_info *info, >> - struct list_head *pagelist) >> -{ >> - struct qxl_fbdev *qfbdev = info->par; >> - unsigned long start, end, min, max; >> - struct page *page; >> - int y1, y2; >> - >> - min = ULONG_MAX; >> - max = 0; >> - list_for_each_entry(page, pagelist, lru) { >> - start = page->index << PAGE_SHIFT; >> - end = start + PAGE_SIZE - 1; >> - min = min(min, start); >> - max = max(max, end); >> - } >> - >> - if (min < max) { >> - y1 = min / info->fix.line_length; >> - y2 = (max / info->fix.line_length) + 1; >> - qxl_dirty_update(qfbdev, 0, y1, info->var.xres, y2 - y1); >> - } >> -}; >> - >> static struct fb_deferred_io qxl_defio = { >> .delay = QXL_DIRTY_DELAY, >> - .deferred_io = qxl_deferred_io, >> + .deferred_io = drm_fb_helper_deferred_io, >> }; >> >> -static void qxl_fb_fillrect(struct fb_info *info, >> - const struct fb_fillrect *rect) >> -{ >> - struct qxl_fbdev *qfbdev = info->par; >> - >> - sys_fillrect(info, rect); >> - qxl_dirty_update(qfbdev, rect->dx, rect->dy, rect->width, >> - rect->height); >> -} >> - >> -static void qxl_fb_copyarea(struct fb_info *info, >> - const struct fb_copyarea *area) >> -{ >> - struct qxl_fbdev *qfbdev = info->par; >> - >> - sys_copyarea(info, area); >> - qxl_dirty_update(qfbdev, area->dx, area->dy, area->width, >> - area->height); >> -} >> - >> -static void qxl_fb_imageblit(struct fb_info *info, >> - const struct fb_image *image) >> -{ >> - struct qxl_fbdev *qfbdev = info->par; >> - >> - sys_imageblit(info, image); >> - qxl_dirty_update(qfbdev, image->dx, image->dy, image->width, >> - image->height); >> -} >> - >> -static void qxl_fb_work(struct work_struct *work) >> -{ >> - struct qxl_device *qdev = container_of(work, struct qxl_device, fb_work); >> - struct qxl_fbdev *qfbdev = qdev->mode_info.qfbdev; >> - >> - qxl_fb_dirty_flush(qfbdev->helper.fbdev); >> -} >> - >> -int qxl_fb_init(struct qxl_device *qdev) >> -{ >> - INIT_WORK(&qdev->fb_work, qxl_fb_work); >> - return 0; >> -} >> - >> static struct fb_ops qxlfb_ops = { >> .owner = THIS_MODULE, >> .fb_check_var = drm_fb_helper_check_var, >> .fb_set_par = drm_fb_helper_set_par, /* TODO: copy vmwgfx */ >> - .fb_fillrect = qxl_fb_fillrect, >> - .fb_copyarea = qxl_fb_copyarea, >> - .fb_imageblit = qxl_fb_imageblit, >> + .fb_fillrect = drm_fb_helper_sys_fillrect, >> + .fb_copyarea = drm_fb_helper_sys_copyarea, >> + .fb_imageblit = drm_fb_helper_sys_imageblit, >> .fb_pan_display = drm_fb_helper_pan_display, >> .fb_blank = drm_fb_helper_blank, >> .fb_setcmap = drm_fb_helper_setcmap, >> @@ -338,6 +179,53 @@ out_unref: >> return ret; >> } >> >> +static int qxlfb_framebuffer_dirty(struct drm_framebuffer *fb, >> + struct drm_file *file_priv, >> + unsigned flags, unsigned color, >> + struct drm_clip_rect *clips, >> + unsigned num_clips) >> +{ >> + struct qxl_device *qdev = fb->dev->dev_private; >> + struct fb_info *info = qdev->fbdev_info; >> + struct qxl_fbdev *qfbdev = info->par; >> + struct qxl_fb_image qxl_fb_image; >> + struct fb_image *image = &qxl_fb_image.fb_image; >> + >> + /* TODO: hard coding 32 bpp */ >> + int stride = qfbdev->qfb.base.pitches[0]; >> + >> + /* >> + * we are using a shadow draw buffer, at qdev->surface0_shadow >> + */ >> + qxl_io_log(qdev, "dirty x[%d, %d], y[%d, %d]", clips->x1, clips->x2, >> + clips->y1, clips->y2); >> + image->dx = clips->x1; >> + image->dy = clips->y1; >> + image->width = drm_clip_rect_width(clips); >> + image->height = drm_clip_rect_height(clips); >> + image->fg_color = 0xffffffff; /* unused, just to avoid uninitialized >> + warnings */ >> + image->bg_color = 0; >> + image->depth = 32; /* TODO: take from somewhere? */ >> + image->cmap.start = 0; >> + image->cmap.len = 0; >> + image->cmap.red = NULL; >> + image->cmap.green = NULL; >> + image->cmap.blue = NULL; >> + image->cmap.transp = NULL; >> + image->data = qfbdev->shadow + (clips->x1 * 4) + (stride * clips->y1); >> + >> + qxl_fb_image_init(&qxl_fb_image, qdev, info, NULL); >> + qxl_draw_opaque_fb(&qxl_fb_image, stride); >> + >> + return 0; >> +} >> + >> +static const struct drm_framebuffer_funcs qxlfb_fb_funcs = { >> + .destroy = qxl_user_framebuffer_destroy, >> + .dirty = qxlfb_framebuffer_dirty, >> +}; >> + >> static int qxlfb_create(struct qxl_fbdev *qfbdev, >> struct drm_fb_helper_surface_size *sizes) >> { >> @@ -383,7 +271,8 @@ static int qxlfb_create(struct qxl_fbdev *qfbdev, >> >> info->par = qfbdev; >> >> - qxl_framebuffer_init(qdev->ddev, &qfbdev->qfb, &mode_cmd, gobj); >> + qxl_framebuffer_init(qdev->ddev, &qfbdev->qfb, &mode_cmd, gobj, >> + &qxlfb_fb_funcs); >> >> fb = &qfbdev->qfb.base; >> >> @@ -504,7 +393,6 @@ int qxl_fbdev_init(struct qxl_device *qdev) >> qfbdev->qdev = qdev; >> qdev->mode_info.qfbdev = qfbdev; >> spin_lock_init(&qfbdev->delayed_ops_lock); >> - spin_lock_init(&qfbdev->dirty.lock); >> INIT_LIST_HEAD(&qfbdev->delayed_ops); >> >> drm_fb_helper_prepare(qdev->ddev, &qfbdev->helper, >> diff --git a/drivers/gpu/drm/qxl/qxl_kms.c b/drivers/gpu/drm/qxl/qxl_kms.c >> index b2977a1..2319800 100644 >> --- a/drivers/gpu/drm/qxl/qxl_kms.c >> +++ b/drivers/gpu/drm/qxl/qxl_kms.c >> @@ -261,10 +261,6 @@ static int qxl_device_init(struct qxl_device *qdev, >> qdev->gc_queue = create_singlethread_workqueue("qxl_gc"); >> INIT_WORK(&qdev->gc_work, qxl_gc_work); >> >> - r = qxl_fb_init(qdev); >> - if (r) >> - return r; >> - >> return 0; >> } >> >> -- >> 2.2.2 >> From mboxrd@z Thu Jan 1 00:00:00 1970 From: =?UTF-8?Q?Noralf_Tr=c3=b8nnes?= Date: Wed, 20 Apr 2016 19:04:38 +0000 Subject: Re: [PATCH 7/8] drm/qxl: Use drm_fb_helper deferred_io support Message-Id: <5717D2C6.7060806@tronnes.org> List-Id: References: <1461165929-11344-1-git-send-email-noralf@tronnes.org> <1461165929-11344-8-git-send-email-noralf@tronnes.org> <20160420174710.GR2510@phenom.ffwll.local> In-Reply-To: <20160420174710.GR2510@phenom.ffwll.local> MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable To: dri-devel@lists.freedesktop.org, linux-fbdev@vger.kernel.org, laurent.pinchart@ideasonboard.com, tomi.valkeinen@ti.com, linux-kernel@vger.kernel.org Den 20.04.2016 19:47, skrev Daniel Vetter: > On Wed, Apr 20, 2016 at 05:25:28PM +0200, Noralf Tr=F8nnes wrote: >> Use the fbdev deferred io support in drm_fb_helper. >> The (struct fb_ops *)->fb_{fillrect,copyarea,imageblit} functions will >> now be deferred in the same way that mmap damage is, instead of being >> flushed directly. >> This patch has only been compile tested. >> >> Signed-off-by: Noralf Tr=F8nnes >> --- >> drivers/gpu/drm/qxl/qxl_display.c | 9 +- >> drivers/gpu/drm/qxl/qxl_drv.h | 7 +- >> drivers/gpu/drm/qxl/qxl_fb.c | 220 ++++++++++--------------------= -------- >> drivers/gpu/drm/qxl/qxl_kms.c | 4 - >> 4 files changed, 62 insertions(+), 178 deletions(-) >> >> diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl= _display.c >> index 030409a..9a03524 100644 >> --- a/drivers/gpu/drm/qxl/qxl_display.c >> +++ b/drivers/gpu/drm/qxl/qxl_display.c >> @@ -465,7 +465,7 @@ static const struct drm_crtc_funcs qxl_crtc_funcs = =3D { >> .page_flip =3D qxl_crtc_page_flip, >> }; >> =20 >> -static void qxl_user_framebuffer_destroy(struct drm_framebuffer *fb) >> +void qxl_user_framebuffer_destroy(struct drm_framebuffer *fb) >> { >> struct qxl_framebuffer *qxl_fb =3D to_qxl_framebuffer(fb); >> =20 >> @@ -527,12 +527,13 @@ int >> qxl_framebuffer_init(struct drm_device *dev, >> struct qxl_framebuffer *qfb, >> const struct drm_mode_fb_cmd2 *mode_cmd, >> - struct drm_gem_object *obj) >> + struct drm_gem_object *obj, >> + const struct drm_framebuffer_funcs *funcs) > There should be no need at all to have a separate fb funcs table for the > fbdev fb. Both /should/ be able to use the exact same (already existing) > ->dirty() callback. We need this only in CMA because CMA is a midlayer > used by multiple drivers. I don't see how I can avoid it. fbdev framebuffer flushing: static void qxl_fb_dirty_flush(struct fb_info *info) { qxl_fb_image_init(&qxl_fb_image, qdev, info, NULL); qxl_draw_opaque_fb(&qxl_fb_image, stride); } drm framebuffer flushing: static int qxl_framebuffer_surface_dirty(...) { qxl_draw_dirty_fb(...); } qxl_draw_opaque_fb() and qxl_draw_dirty_fb() differ so much that it's way over my head to see if they can be combined. Here's an online diff of the two functions: https://www.diffchecker.com/jqbbalux > > With that change you should be able to condense this patch down to pretty > much just removing lines. Which is Good (tm). > > Cheers, Daniel > >> { >> int ret; >> =20 >> qfb->obj =3D obj; >> - ret =3D drm_framebuffer_init(dev, &qfb->base, &qxl_fb_funcs); >> + ret =3D drm_framebuffer_init(dev, &qfb->base, funcs); >> if (ret) { >> qfb->obj =3D NULL; >> return ret; >> @@ -999,7 +1000,7 @@ qxl_user_framebuffer_create(struct drm_device *dev, >> if (qxl_fb =3D NULL) >> return NULL; >> =20 >> - ret =3D qxl_framebuffer_init(dev, qxl_fb, mode_cmd, obj); >> + ret =3D qxl_framebuffer_init(dev, qxl_fb, mode_cmd, obj, &qxl_fb_funcs= ); >> if (ret) { >> kfree(qxl_fb); >> drm_gem_object_unreference_unlocked(obj); >> diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv= .h >> index 3f3897e..3ad6604 100644 >> --- a/drivers/gpu/drm/qxl/qxl_drv.h >> +++ b/drivers/gpu/drm/qxl/qxl_drv.h >> @@ -324,8 +324,6 @@ struct qxl_device { >> struct workqueue_struct *gc_queue; >> struct work_struct gc_work; >> =20 >> - struct work_struct fb_work; >> - >> struct drm_property *hotplug_mode_update_property; >> int monitors_config_width; >> int monitors_config_height; >> @@ -389,11 +387,13 @@ int qxl_get_handle_for_primary_fb(struct qxl_devic= e *qdev, >> void qxl_fbdev_set_suspend(struct qxl_device *qdev, int state); >> =20 >> /* qxl_display.c */ >> +void qxl_user_framebuffer_destroy(struct drm_framebuffer *fb); >> int >> qxl_framebuffer_init(struct drm_device *dev, >> struct qxl_framebuffer *rfb, >> const struct drm_mode_fb_cmd2 *mode_cmd, >> - struct drm_gem_object *obj); >> + struct drm_gem_object *obj, >> + const struct drm_framebuffer_funcs *funcs); >> void qxl_display_read_client_monitors_config(struct qxl_device *qdev); >> void qxl_send_monitors_config(struct qxl_device *qdev); >> int qxl_create_monitors_object(struct qxl_device *qdev); >> @@ -553,7 +553,6 @@ int qxl_irq_init(struct qxl_device *qdev); >> irqreturn_t qxl_irq_handler(int irq, void *arg); >> =20 >> /* qxl_fb.c */ >> -int qxl_fb_init(struct qxl_device *qdev); >> bool qxl_fbdev_qobj_is_fb(struct qxl_device *qdev, struct qxl_bo *qobj= ); >> =20 >> int qxl_debugfs_add_files(struct qxl_device *qdev, >> diff --git a/drivers/gpu/drm/qxl/qxl_fb.c b/drivers/gpu/drm/qxl/qxl_fb.c >> index 06f032d..090dcee 100644 >> --- a/drivers/gpu/drm/qxl/qxl_fb.c >> +++ b/drivers/gpu/drm/qxl/qxl_fb.c >> @@ -30,6 +30,7 @@ >> #include "drm/drm.h" >> #include "drm/drm_crtc.h" >> #include "drm/drm_crtc_helper.h" >> +#include "drm/drm_rect.h" >> #include "qxl_drv.h" >> =20 >> #include "qxl_object.h" >> @@ -46,15 +47,6 @@ struct qxl_fbdev { >> struct list_head delayed_ops; >> void *shadow; >> int size; >> - >> - /* dirty memory logging */ >> - struct { >> - spinlock_t lock; >> - unsigned x1; >> - unsigned y1; >> - unsigned x2; >> - unsigned y2; >> - } dirty; >> }; >> =20 >> static void qxl_fb_image_init(struct qxl_fb_image *qxl_fb_image, >> @@ -82,169 +74,18 @@ static void qxl_fb_image_init(struct qxl_fb_image *= qxl_fb_image, >> } >> } >> =20 >> -static void qxl_fb_dirty_flush(struct fb_info *info) >> -{ >> - struct qxl_fbdev *qfbdev =3D info->par; >> - struct qxl_device *qdev =3D qfbdev->qdev; >> - struct qxl_fb_image qxl_fb_image; >> - struct fb_image *image =3D &qxl_fb_image.fb_image; >> - unsigned long flags; >> - u32 x1, x2, y1, y2; >> - >> - /* TODO: hard coding 32 bpp */ >> - int stride =3D qfbdev->qfb.base.pitches[0]; >> - >> - spin_lock_irqsave(&qfbdev->dirty.lock, flags); >> - >> - x1 =3D qfbdev->dirty.x1; >> - x2 =3D qfbdev->dirty.x2; >> - y1 =3D qfbdev->dirty.y1; >> - y2 =3D qfbdev->dirty.y2; >> - qfbdev->dirty.x1 =3D 0; >> - qfbdev->dirty.x2 =3D 0; >> - qfbdev->dirty.y1 =3D 0; >> - qfbdev->dirty.y2 =3D 0; >> - >> - spin_unlock_irqrestore(&qfbdev->dirty.lock, flags); >> - >> - /* >> - * we are using a shadow draw buffer, at qdev->surface0_shadow >> - */ >> - qxl_io_log(qdev, "dirty x[%d, %d], y[%d, %d]", x1, x2, y1, y2); >> - image->dx =3D x1; >> - image->dy =3D y1; >> - image->width =3D x2 - x1 + 1; >> - image->height =3D y2 - y1 + 1; >> - image->fg_color =3D 0xffffffff; /* unused, just to avoid uninitialized >> - warnings */ >> - image->bg_color =3D 0; >> - image->depth =3D 32; /* TODO: take from somewhere? */ >> - image->cmap.start =3D 0; >> - image->cmap.len =3D 0; >> - image->cmap.red =3D NULL; >> - image->cmap.green =3D NULL; >> - image->cmap.blue =3D NULL; >> - image->cmap.transp =3D NULL; >> - image->data =3D qfbdev->shadow + (x1 * 4) + (stride * y1); >> - >> - qxl_fb_image_init(&qxl_fb_image, qdev, info, NULL); >> - qxl_draw_opaque_fb(&qxl_fb_image, stride); >> -} >> - >> -static void qxl_dirty_update(struct qxl_fbdev *qfbdev, >> - int x, int y, int width, int height) >> -{ >> - struct qxl_device *qdev =3D qfbdev->qdev; >> - unsigned long flags; >> - int x2, y2; >> - >> - x2 =3D x + width - 1; >> - y2 =3D y + height - 1; >> - >> - spin_lock_irqsave(&qfbdev->dirty.lock, flags); >> - >> - if ((qfbdev->dirty.y2 - qfbdev->dirty.y1) && >> - (qfbdev->dirty.x2 - qfbdev->dirty.x1)) { >> - if (qfbdev->dirty.y1 < y) >> - y =3D qfbdev->dirty.y1; >> - if (qfbdev->dirty.y2 > y2) >> - y2 =3D qfbdev->dirty.y2; >> - if (qfbdev->dirty.x1 < x) >> - x =3D qfbdev->dirty.x1; >> - if (qfbdev->dirty.x2 > x2) >> - x2 =3D qfbdev->dirty.x2; >> - } >> - >> - qfbdev->dirty.x1 =3D x; >> - qfbdev->dirty.x2 =3D x2; >> - qfbdev->dirty.y1 =3D y; >> - qfbdev->dirty.y2 =3D y2; >> - >> - spin_unlock_irqrestore(&qfbdev->dirty.lock, flags); >> - >> - schedule_work(&qdev->fb_work); >> -} >> - >> -static void qxl_deferred_io(struct fb_info *info, >> - struct list_head *pagelist) >> -{ >> - struct qxl_fbdev *qfbdev =3D info->par; >> - unsigned long start, end, min, max; >> - struct page *page; >> - int y1, y2; >> - >> - min =3D ULONG_MAX; >> - max =3D 0; >> - list_for_each_entry(page, pagelist, lru) { >> - start =3D page->index << PAGE_SHIFT; >> - end =3D start + PAGE_SIZE - 1; >> - min =3D min(min, start); >> - max =3D max(max, end); >> - } >> - >> - if (min < max) { >> - y1 =3D min / info->fix.line_length; >> - y2 =3D (max / info->fix.line_length) + 1; >> - qxl_dirty_update(qfbdev, 0, y1, info->var.xres, y2 - y1); >> - } >> -}; >> - >> static struct fb_deferred_io qxl_defio =3D { >> .delay =3D QXL_DIRTY_DELAY, >> - .deferred_io =3D qxl_deferred_io, >> + .deferred_io =3D drm_fb_helper_deferred_io, >> }; >> =20 >> -static void qxl_fb_fillrect(struct fb_info *info, >> - const struct fb_fillrect *rect) >> -{ >> - struct qxl_fbdev *qfbdev =3D info->par; >> - >> - sys_fillrect(info, rect); >> - qxl_dirty_update(qfbdev, rect->dx, rect->dy, rect->width, >> - rect->height); >> -} >> - >> -static void qxl_fb_copyarea(struct fb_info *info, >> - const struct fb_copyarea *area) >> -{ >> - struct qxl_fbdev *qfbdev =3D info->par; >> - >> - sys_copyarea(info, area); >> - qxl_dirty_update(qfbdev, area->dx, area->dy, area->width, >> - area->height); >> -} >> - >> -static void qxl_fb_imageblit(struct fb_info *info, >> - const struct fb_image *image) >> -{ >> - struct qxl_fbdev *qfbdev =3D info->par; >> - >> - sys_imageblit(info, image); >> - qxl_dirty_update(qfbdev, image->dx, image->dy, image->width, >> - image->height); >> -} >> - >> -static void qxl_fb_work(struct work_struct *work) >> -{ >> - struct qxl_device *qdev =3D container_of(work, struct qxl_device, fb_w= ork); >> - struct qxl_fbdev *qfbdev =3D qdev->mode_info.qfbdev; >> - >> - qxl_fb_dirty_flush(qfbdev->helper.fbdev); >> -} >> - >> -int qxl_fb_init(struct qxl_device *qdev) >> -{ >> - INIT_WORK(&qdev->fb_work, qxl_fb_work); >> - return 0; >> -} >> - >> static struct fb_ops qxlfb_ops =3D { >> .owner =3D THIS_MODULE, >> .fb_check_var =3D drm_fb_helper_check_var, >> .fb_set_par =3D drm_fb_helper_set_par, /* TODO: copy vmwgfx */ >> - .fb_fillrect =3D qxl_fb_fillrect, >> - .fb_copyarea =3D qxl_fb_copyarea, >> - .fb_imageblit =3D qxl_fb_imageblit, >> + .fb_fillrect =3D drm_fb_helper_sys_fillrect, >> + .fb_copyarea =3D drm_fb_helper_sys_copyarea, >> + .fb_imageblit =3D drm_fb_helper_sys_imageblit, >> .fb_pan_display =3D drm_fb_helper_pan_display, >> .fb_blank =3D drm_fb_helper_blank, >> .fb_setcmap =3D drm_fb_helper_setcmap, >> @@ -338,6 +179,53 @@ out_unref: >> return ret; >> } >> =20 >> +static int qxlfb_framebuffer_dirty(struct drm_framebuffer *fb, >> + struct drm_file *file_priv, >> + unsigned flags, unsigned color, >> + struct drm_clip_rect *clips, >> + unsigned num_clips) >> +{ >> + struct qxl_device *qdev =3D fb->dev->dev_private; >> + struct fb_info *info =3D qdev->fbdev_info; >> + struct qxl_fbdev *qfbdev =3D info->par; >> + struct qxl_fb_image qxl_fb_image; >> + struct fb_image *image =3D &qxl_fb_image.fb_image; >> + >> + /* TODO: hard coding 32 bpp */ >> + int stride =3D qfbdev->qfb.base.pitches[0]; >> + >> + /* >> + * we are using a shadow draw buffer, at qdev->surface0_shadow >> + */ >> + qxl_io_log(qdev, "dirty x[%d, %d], y[%d, %d]", clips->x1, clips->x2, >> + clips->y1, clips->y2); >> + image->dx =3D clips->x1; >> + image->dy =3D clips->y1; >> + image->width =3D drm_clip_rect_width(clips); >> + image->height =3D drm_clip_rect_height(clips); >> + image->fg_color =3D 0xffffffff; /* unused, just to avoid uninitialized >> + warnings */ >> + image->bg_color =3D 0; >> + image->depth =3D 32; /* TODO: take from somewhere? */ >> + image->cmap.start =3D 0; >> + image->cmap.len =3D 0; >> + image->cmap.red =3D NULL; >> + image->cmap.green =3D NULL; >> + image->cmap.blue =3D NULL; >> + image->cmap.transp =3D NULL; >> + image->data =3D qfbdev->shadow + (clips->x1 * 4) + (stride * clips->y1= ); >> + >> + qxl_fb_image_init(&qxl_fb_image, qdev, info, NULL); >> + qxl_draw_opaque_fb(&qxl_fb_image, stride); >> + >> + return 0; >> +} >> + >> +static const struct drm_framebuffer_funcs qxlfb_fb_funcs =3D { >> + .destroy =3D qxl_user_framebuffer_destroy, >> + .dirty =3D qxlfb_framebuffer_dirty, >> +}; >> + >> static int qxlfb_create(struct qxl_fbdev *qfbdev, >> struct drm_fb_helper_surface_size *sizes) >> { >> @@ -383,7 +271,8 @@ static int qxlfb_create(struct qxl_fbdev *qfbdev, >> =20 >> info->par =3D qfbdev; >> =20 >> - qxl_framebuffer_init(qdev->ddev, &qfbdev->qfb, &mode_cmd, gobj); >> + qxl_framebuffer_init(qdev->ddev, &qfbdev->qfb, &mode_cmd, gobj, >> + &qxlfb_fb_funcs); >> =20 >> fb =3D &qfbdev->qfb.base; >> =20 >> @@ -504,7 +393,6 @@ int qxl_fbdev_init(struct qxl_device *qdev) >> qfbdev->qdev =3D qdev; >> qdev->mode_info.qfbdev =3D qfbdev; >> spin_lock_init(&qfbdev->delayed_ops_lock); >> - spin_lock_init(&qfbdev->dirty.lock); >> INIT_LIST_HEAD(&qfbdev->delayed_ops); >> =20 >> drm_fb_helper_prepare(qdev->ddev, &qfbdev->helper, >> diff --git a/drivers/gpu/drm/qxl/qxl_kms.c b/drivers/gpu/drm/qxl/qxl_kms= .c >> index b2977a1..2319800 100644 >> --- a/drivers/gpu/drm/qxl/qxl_kms.c >> +++ b/drivers/gpu/drm/qxl/qxl_kms.c >> @@ -261,10 +261,6 @@ static int qxl_device_init(struct qxl_device *qdev, >> qdev->gc_queue =3D create_singlethread_workqueue("qxl_gc"); >> INIT_WORK(&qdev->gc_work, qxl_gc_work); >> =20 >> - r =3D qxl_fb_init(qdev); >> - if (r) >> - return r; >> - >> return 0; >> } >> =20 >> --=20 >> 2.2.2 >> From mboxrd@z Thu Jan 1 00:00:00 1970 From: =?UTF-8?Q?Noralf_Tr=c3=b8nnes?= Subject: Re: [PATCH 7/8] drm/qxl: Use drm_fb_helper deferred_io support Date: Wed, 20 Apr 2016 21:04:38 +0200 Message-ID: <5717D2C6.7060806@tronnes.org> References: <1461165929-11344-1-git-send-email-noralf@tronnes.org> <1461165929-11344-8-git-send-email-noralf@tronnes.org> <20160420174710.GR2510@phenom.ffwll.local> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8"; Format="flowed" Content-Transfer-Encoding: base64 Return-path: Received: from smtp.domeneshop.no (smtp.domeneshop.no [IPv6:2a01:5b40:0:3005::1]) by gabe.freedesktop.org (Postfix) with ESMTPS id 7AD2F6E0C4 for ; Wed, 20 Apr 2016 19:04:45 +0000 (UTC) In-Reply-To: <20160420174710.GR2510@phenom.ffwll.local> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: dri-devel@lists.freedesktop.org, linux-fbdev@vger.kernel.org, laurent.pinchart@ideasonboard.com, tomi.valkeinen@ti.com, linux-kernel@vger.kernel.org List-Id: dri-devel@lists.freedesktop.org CkRlbiAyMC4wNC4yMDE2IDE5OjQ3LCBza3JldiBEYW5pZWwgVmV0dGVyOgo+IE9uIFdlZCwgQXBy IDIwLCAyMDE2IGF0IDA1OjI1OjI4UE0gKzAyMDAsIE5vcmFsZiBUcsO4bm5lcyB3cm90ZToKPj4g VXNlIHRoZSBmYmRldiBkZWZlcnJlZCBpbyBzdXBwb3J0IGluIGRybV9mYl9oZWxwZXIuCj4+IFRo ZSAoc3RydWN0IGZiX29wcyAqKS0+ZmJfe2ZpbGxyZWN0LGNvcHlhcmVhLGltYWdlYmxpdH0gZnVu Y3Rpb25zIHdpbGwKPj4gbm93IGJlIGRlZmVycmVkIGluIHRoZSBzYW1lIHdheSB0aGF0IG1tYXAg ZGFtYWdlIGlzLCBpbnN0ZWFkIG9mIGJlaW5nCj4+IGZsdXNoZWQgZGlyZWN0bHkuCj4+IFRoaXMg cGF0Y2ggaGFzIG9ubHkgYmVlbiBjb21waWxlIHRlc3RlZC4KPj4KPj4gU2lnbmVkLW9mZi1ieTog Tm9yYWxmIFRyw7hubmVzIDxub3JhbGZAdHJvbm5lcy5vcmc+Cj4+IC0tLQo+PiAgIGRyaXZlcnMv Z3B1L2RybS9xeGwvcXhsX2Rpc3BsYXkuYyB8ICAgOSArLQo+PiAgIGRyaXZlcnMvZ3B1L2RybS9x eGwvcXhsX2Rydi5oICAgICB8ICAgNyArLQo+PiAgIGRyaXZlcnMvZ3B1L2RybS9xeGwvcXhsX2Zi LmMgICAgICB8IDIyMCArKysrKysrKysrLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQo+PiAg IGRyaXZlcnMvZ3B1L2RybS9xeGwvcXhsX2ttcy5jICAgICB8ICAgNCAtCj4+ICAgNCBmaWxlcyBj aGFuZ2VkLCA2MiBpbnNlcnRpb25zKCspLCAxNzggZGVsZXRpb25zKC0pCj4+Cj4+IGRpZmYgLS1n aXQgYS9kcml2ZXJzL2dwdS9kcm0vcXhsL3F4bF9kaXNwbGF5LmMgYi9kcml2ZXJzL2dwdS9kcm0v cXhsL3F4bF9kaXNwbGF5LmMKPj4gaW5kZXggMDMwNDA5YS4uOWEwMzUyNCAxMDA2NDQKPj4gLS0t IGEvZHJpdmVycy9ncHUvZHJtL3F4bC9xeGxfZGlzcGxheS5jCj4+ICsrKyBiL2RyaXZlcnMvZ3B1 L2RybS9xeGwvcXhsX2Rpc3BsYXkuYwo+PiBAQCAtNDY1LDcgKzQ2NSw3IEBAIHN0YXRpYyBjb25z dCBzdHJ1Y3QgZHJtX2NydGNfZnVuY3MgcXhsX2NydGNfZnVuY3MgPSB7Cj4+ICAgCS5wYWdlX2Zs aXAgPSBxeGxfY3J0Y19wYWdlX2ZsaXAsCj4+ICAgfTsKPj4gICAKPj4gLXN0YXRpYyB2b2lkIHF4 bF91c2VyX2ZyYW1lYnVmZmVyX2Rlc3Ryb3koc3RydWN0IGRybV9mcmFtZWJ1ZmZlciAqZmIpCj4+ ICt2b2lkIHF4bF91c2VyX2ZyYW1lYnVmZmVyX2Rlc3Ryb3koc3RydWN0IGRybV9mcmFtZWJ1ZmZl ciAqZmIpCj4+ICAgewo+PiAgIAlzdHJ1Y3QgcXhsX2ZyYW1lYnVmZmVyICpxeGxfZmIgPSB0b19x eGxfZnJhbWVidWZmZXIoZmIpOwo+PiAgIAo+PiBAQCAtNTI3LDEyICs1MjcsMTMgQEAgaW50Cj4+ ICAgcXhsX2ZyYW1lYnVmZmVyX2luaXQoc3RydWN0IGRybV9kZXZpY2UgKmRldiwKPj4gICAJCSAg ICAgc3RydWN0IHF4bF9mcmFtZWJ1ZmZlciAqcWZiLAo+PiAgIAkJICAgICBjb25zdCBzdHJ1Y3Qg ZHJtX21vZGVfZmJfY21kMiAqbW9kZV9jbWQsCj4+IC0JCSAgICAgc3RydWN0IGRybV9nZW1fb2Jq ZWN0ICpvYmopCj4+ICsJCSAgICAgc3RydWN0IGRybV9nZW1fb2JqZWN0ICpvYmosCj4+ICsJCSAg ICAgY29uc3Qgc3RydWN0IGRybV9mcmFtZWJ1ZmZlcl9mdW5jcyAqZnVuY3MpCj4gVGhlcmUgc2hv dWxkIGJlIG5vIG5lZWQgYXQgYWxsIHRvIGhhdmUgYSBzZXBhcmF0ZSBmYiBmdW5jcyB0YWJsZSBm b3IgdGhlCj4gZmJkZXYgZmIuIEJvdGggL3Nob3VsZC8gYmUgYWJsZSB0byB1c2UgdGhlIGV4YWN0 IHNhbWUgKGFscmVhZHkgZXhpc3RpbmcpCj4gLT5kaXJ0eSgpIGNhbGxiYWNrLiBXZSBuZWVkIHRo aXMgb25seSBpbiBDTUEgYmVjYXVzZSBDTUEgaXMgYSBtaWRsYXllcgo+IHVzZWQgYnkgbXVsdGlw bGUgZHJpdmVycy4KCkkgZG9uJ3Qgc2VlIGhvdyBJIGNhbiBhdm9pZCBpdC4KCmZiZGV2IGZyYW1l YnVmZmVyIGZsdXNoaW5nOgoKc3RhdGljIHZvaWQgcXhsX2ZiX2RpcnR5X2ZsdXNoKHN0cnVjdCBm Yl9pbmZvICppbmZvKQp7CiAgICAgICAgIHF4bF9mYl9pbWFnZV9pbml0KCZxeGxfZmJfaW1hZ2Us IHFkZXYsIGluZm8sIE5VTEwpOwogICAgICAgICBxeGxfZHJhd19vcGFxdWVfZmIoJnF4bF9mYl9p bWFnZSwgc3RyaWRlKTsKfQoKZHJtIGZyYW1lYnVmZmVyIGZsdXNoaW5nOgoKc3RhdGljIGludCBx eGxfZnJhbWVidWZmZXJfc3VyZmFjZV9kaXJ0eSguLi4pCnsKICAgICAgICAgcXhsX2RyYXdfZGly dHlfZmIoLi4uKTsKfQoKcXhsX2RyYXdfb3BhcXVlX2ZiKCkgYW5kIHF4bF9kcmF3X2RpcnR5X2Zi KCkgZGlmZmVyIHNvIG11Y2ggdGhhdCBpdCdzIHdheQpvdmVyIG15IGhlYWQgdG8gc2VlIGlmIHRo ZXkgY2FuIGJlIGNvbWJpbmVkLgpIZXJlJ3MgYW4gb25saW5lIGRpZmYgb2YgdGhlIHR3byBmdW5j dGlvbnM6Cmh0dHBzOi8vd3d3LmRpZmZjaGVja2VyLmNvbS9qcWJiYWx1eAoKCj4KPiBXaXRoIHRo YXQgY2hhbmdlIHlvdSBzaG91bGQgYmUgYWJsZSB0byBjb25kZW5zZSB0aGlzIHBhdGNoIGRvd24g dG8gcHJldHR5Cj4gbXVjaCBqdXN0IHJlbW92aW5nIGxpbmVzLiBXaGljaCBpcyBHb29kICh0bSku Cj4KPiBDaGVlcnMsIERhbmllbAo+Cj4+ICAgewo+PiAgIAlpbnQgcmV0Owo+PiAgIAo+PiAgIAlx ZmItPm9iaiA9IG9iajsKPj4gLQlyZXQgPSBkcm1fZnJhbWVidWZmZXJfaW5pdChkZXYsICZxZmIt PmJhc2UsICZxeGxfZmJfZnVuY3MpOwo+PiArCXJldCA9IGRybV9mcmFtZWJ1ZmZlcl9pbml0KGRl diwgJnFmYi0+YmFzZSwgZnVuY3MpOwo+PiAgIAlpZiAocmV0KSB7Cj4+ICAgCQlxZmItPm9iaiA9 IE5VTEw7Cj4+ICAgCQlyZXR1cm4gcmV0Owo+PiBAQCAtOTk5LDcgKzEwMDAsNyBAQCBxeGxfdXNl cl9mcmFtZWJ1ZmZlcl9jcmVhdGUoc3RydWN0IGRybV9kZXZpY2UgKmRldiwKPj4gICAJaWYgKHF4 bF9mYiA9PSBOVUxMKQo+PiAgIAkJcmV0dXJuIE5VTEw7Cj4+ICAgCj4+IC0JcmV0ID0gcXhsX2Zy YW1lYnVmZmVyX2luaXQoZGV2LCBxeGxfZmIsIG1vZGVfY21kLCBvYmopOwo+PiArCXJldCA9IHF4 bF9mcmFtZWJ1ZmZlcl9pbml0KGRldiwgcXhsX2ZiLCBtb2RlX2NtZCwgb2JqLCAmcXhsX2ZiX2Z1 bmNzKTsKPj4gICAJaWYgKHJldCkgewo+PiAgIAkJa2ZyZWUocXhsX2ZiKTsKPj4gICAJCWRybV9n ZW1fb2JqZWN0X3VucmVmZXJlbmNlX3VubG9ja2VkKG9iaik7Cj4+IGRpZmYgLS1naXQgYS9kcml2 ZXJzL2dwdS9kcm0vcXhsL3F4bF9kcnYuaCBiL2RyaXZlcnMvZ3B1L2RybS9xeGwvcXhsX2Rydi5o Cj4+IGluZGV4IDNmMzg5N2UuLjNhZDY2MDQgMTAwNjQ0Cj4+IC0tLSBhL2RyaXZlcnMvZ3B1L2Ry bS9xeGwvcXhsX2Rydi5oCj4+ICsrKyBiL2RyaXZlcnMvZ3B1L2RybS9xeGwvcXhsX2Rydi5oCj4+ IEBAIC0zMjQsOCArMzI0LDYgQEAgc3RydWN0IHF4bF9kZXZpY2Ugewo+PiAgIAlzdHJ1Y3Qgd29y a3F1ZXVlX3N0cnVjdCAqZ2NfcXVldWU7Cj4+ICAgCXN0cnVjdCB3b3JrX3N0cnVjdCBnY193b3Jr Owo+PiAgIAo+PiAtCXN0cnVjdCB3b3JrX3N0cnVjdCBmYl93b3JrOwo+PiAtCj4+ICAgCXN0cnVj dCBkcm1fcHJvcGVydHkgKmhvdHBsdWdfbW9kZV91cGRhdGVfcHJvcGVydHk7Cj4+ICAgCWludCBt b25pdG9yc19jb25maWdfd2lkdGg7Cj4+ICAgCWludCBtb25pdG9yc19jb25maWdfaGVpZ2h0Owo+ PiBAQCAtMzg5LDExICszODcsMTMgQEAgaW50IHF4bF9nZXRfaGFuZGxlX2Zvcl9wcmltYXJ5X2Zi KHN0cnVjdCBxeGxfZGV2aWNlICpxZGV2LAo+PiAgIHZvaWQgcXhsX2ZiZGV2X3NldF9zdXNwZW5k KHN0cnVjdCBxeGxfZGV2aWNlICpxZGV2LCBpbnQgc3RhdGUpOwo+PiAgIAo+PiAgIC8qIHF4bF9k aXNwbGF5LmMgKi8KPj4gK3ZvaWQgcXhsX3VzZXJfZnJhbWVidWZmZXJfZGVzdHJveShzdHJ1Y3Qg ZHJtX2ZyYW1lYnVmZmVyICpmYik7Cj4+ICAgaW50Cj4+ICAgcXhsX2ZyYW1lYnVmZmVyX2luaXQo c3RydWN0IGRybV9kZXZpY2UgKmRldiwKPj4gICAJCSAgICAgc3RydWN0IHF4bF9mcmFtZWJ1ZmZl ciAqcmZiLAo+PiAgIAkJICAgICBjb25zdCBzdHJ1Y3QgZHJtX21vZGVfZmJfY21kMiAqbW9kZV9j bWQsCj4+IC0JCSAgICAgc3RydWN0IGRybV9nZW1fb2JqZWN0ICpvYmopOwo+PiArCQkgICAgIHN0 cnVjdCBkcm1fZ2VtX29iamVjdCAqb2JqLAo+PiArCQkgICAgIGNvbnN0IHN0cnVjdCBkcm1fZnJh bWVidWZmZXJfZnVuY3MgKmZ1bmNzKTsKPj4gICB2b2lkIHF4bF9kaXNwbGF5X3JlYWRfY2xpZW50 X21vbml0b3JzX2NvbmZpZyhzdHJ1Y3QgcXhsX2RldmljZSAqcWRldik7Cj4+ICAgdm9pZCBxeGxf c2VuZF9tb25pdG9yc19jb25maWcoc3RydWN0IHF4bF9kZXZpY2UgKnFkZXYpOwo+PiAgIGludCBx eGxfY3JlYXRlX21vbml0b3JzX29iamVjdChzdHJ1Y3QgcXhsX2RldmljZSAqcWRldik7Cj4+IEBA IC01NTMsNyArNTUzLDYgQEAgaW50IHF4bF9pcnFfaW5pdChzdHJ1Y3QgcXhsX2RldmljZSAqcWRl dik7Cj4+ICAgaXJxcmV0dXJuX3QgcXhsX2lycV9oYW5kbGVyKGludCBpcnEsIHZvaWQgKmFyZyk7 Cj4+ICAgCj4+ICAgLyogcXhsX2ZiLmMgKi8KPj4gLWludCBxeGxfZmJfaW5pdChzdHJ1Y3QgcXhs X2RldmljZSAqcWRldik7Cj4+ICAgYm9vbCBxeGxfZmJkZXZfcW9ial9pc19mYihzdHJ1Y3QgcXhs X2RldmljZSAqcWRldiwgc3RydWN0IHF4bF9ibyAqcW9iaik7Cj4+ICAgCj4+ICAgaW50IHF4bF9k ZWJ1Z2ZzX2FkZF9maWxlcyhzdHJ1Y3QgcXhsX2RldmljZSAqcWRldiwKPj4gZGlmZiAtLWdpdCBh L2RyaXZlcnMvZ3B1L2RybS9xeGwvcXhsX2ZiLmMgYi9kcml2ZXJzL2dwdS9kcm0vcXhsL3F4bF9m Yi5jCj4+IGluZGV4IDA2ZjAzMmQuLjA5MGRjZWUgMTAwNjQ0Cj4+IC0tLSBhL2RyaXZlcnMvZ3B1 L2RybS9xeGwvcXhsX2ZiLmMKPj4gKysrIGIvZHJpdmVycy9ncHUvZHJtL3F4bC9xeGxfZmIuYwo+ PiBAQCAtMzAsNiArMzAsNyBAQAo+PiAgICNpbmNsdWRlICJkcm0vZHJtLmgiCj4+ICAgI2luY2x1 ZGUgImRybS9kcm1fY3J0Yy5oIgo+PiAgICNpbmNsdWRlICJkcm0vZHJtX2NydGNfaGVscGVyLmgi Cj4+ICsjaW5jbHVkZSAiZHJtL2RybV9yZWN0LmgiCj4+ICAgI2luY2x1ZGUgInF4bF9kcnYuaCIK Pj4gICAKPj4gICAjaW5jbHVkZSAicXhsX29iamVjdC5oIgo+PiBAQCAtNDYsMTUgKzQ3LDYgQEAg c3RydWN0IHF4bF9mYmRldiB7Cj4+ICAgCXN0cnVjdCBsaXN0X2hlYWQgZGVsYXllZF9vcHM7Cj4+ ICAgCXZvaWQgKnNoYWRvdzsKPj4gICAJaW50IHNpemU7Cj4+IC0KPj4gLQkvKiBkaXJ0eSBtZW1v cnkgbG9nZ2luZyAqLwo+PiAtCXN0cnVjdCB7Cj4+IC0JCXNwaW5sb2NrX3QgbG9jazsKPj4gLQkJ dW5zaWduZWQgeDE7Cj4+IC0JCXVuc2lnbmVkIHkxOwo+PiAtCQl1bnNpZ25lZCB4MjsKPj4gLQkJ dW5zaWduZWQgeTI7Cj4+IC0JfSBkaXJ0eTsKPj4gICB9Owo+PiAgIAo+PiAgIHN0YXRpYyB2b2lk IHF4bF9mYl9pbWFnZV9pbml0KHN0cnVjdCBxeGxfZmJfaW1hZ2UgKnF4bF9mYl9pbWFnZSwKPj4g QEAgLTgyLDE2OSArNzQsMTggQEAgc3RhdGljIHZvaWQgcXhsX2ZiX2ltYWdlX2luaXQoc3RydWN0 IHF4bF9mYl9pbWFnZSAqcXhsX2ZiX2ltYWdlLAo+PiAgIAl9Cj4+ICAgfQo+PiAgIAo+PiAtc3Rh dGljIHZvaWQgcXhsX2ZiX2RpcnR5X2ZsdXNoKHN0cnVjdCBmYl9pbmZvICppbmZvKQo+PiAtewo+ PiAtCXN0cnVjdCBxeGxfZmJkZXYgKnFmYmRldiA9IGluZm8tPnBhcjsKPj4gLQlzdHJ1Y3QgcXhs X2RldmljZSAqcWRldiA9IHFmYmRldi0+cWRldjsKPj4gLQlzdHJ1Y3QgcXhsX2ZiX2ltYWdlIHF4 bF9mYl9pbWFnZTsKPj4gLQlzdHJ1Y3QgZmJfaW1hZ2UgKmltYWdlID0gJnF4bF9mYl9pbWFnZS5m Yl9pbWFnZTsKPj4gLQl1bnNpZ25lZCBsb25nIGZsYWdzOwo+PiAtCXUzMiB4MSwgeDIsIHkxLCB5 MjsKPj4gLQo+PiAtCS8qIFRPRE86IGhhcmQgY29kaW5nIDMyIGJwcCAqLwo+PiAtCWludCBzdHJp ZGUgPSBxZmJkZXYtPnFmYi5iYXNlLnBpdGNoZXNbMF07Cj4+IC0KPj4gLQlzcGluX2xvY2tfaXJx c2F2ZSgmcWZiZGV2LT5kaXJ0eS5sb2NrLCBmbGFncyk7Cj4+IC0KPj4gLQl4MSA9IHFmYmRldi0+ ZGlydHkueDE7Cj4+IC0JeDIgPSBxZmJkZXYtPmRpcnR5LngyOwo+PiAtCXkxID0gcWZiZGV2LT5k aXJ0eS55MTsKPj4gLQl5MiA9IHFmYmRldi0+ZGlydHkueTI7Cj4+IC0JcWZiZGV2LT5kaXJ0eS54 MSA9IDA7Cj4+IC0JcWZiZGV2LT5kaXJ0eS54MiA9IDA7Cj4+IC0JcWZiZGV2LT5kaXJ0eS55MSA9 IDA7Cj4+IC0JcWZiZGV2LT5kaXJ0eS55MiA9IDA7Cj4+IC0KPj4gLQlzcGluX3VubG9ja19pcnFy ZXN0b3JlKCZxZmJkZXYtPmRpcnR5LmxvY2ssIGZsYWdzKTsKPj4gLQo+PiAtCS8qCj4+IC0JICog d2UgYXJlIHVzaW5nIGEgc2hhZG93IGRyYXcgYnVmZmVyLCBhdCBxZGV2LT5zdXJmYWNlMF9zaGFk b3cKPj4gLQkgKi8KPj4gLQlxeGxfaW9fbG9nKHFkZXYsICJkaXJ0eSB4WyVkLCAlZF0sIHlbJWQs ICVkXSIsIHgxLCB4MiwgeTEsIHkyKTsKPj4gLQlpbWFnZS0+ZHggPSB4MTsKPj4gLQlpbWFnZS0+ ZHkgPSB5MTsKPj4gLQlpbWFnZS0+d2lkdGggPSB4MiAtIHgxICsgMTsKPj4gLQlpbWFnZS0+aGVp Z2h0ID0geTIgLSB5MSArIDE7Cj4+IC0JaW1hZ2UtPmZnX2NvbG9yID0gMHhmZmZmZmZmZjsgLyog dW51c2VkLCBqdXN0IHRvIGF2b2lkIHVuaW5pdGlhbGl6ZWQKPj4gLQkJCQkJIHdhcm5pbmdzICov Cj4+IC0JaW1hZ2UtPmJnX2NvbG9yID0gMDsKPj4gLQlpbWFnZS0+ZGVwdGggPSAzMjsJICAgICAv KiBUT0RPOiB0YWtlIGZyb20gc29tZXdoZXJlPyAqLwo+PiAtCWltYWdlLT5jbWFwLnN0YXJ0ID0g MDsKPj4gLQlpbWFnZS0+Y21hcC5sZW4gPSAwOwo+PiAtCWltYWdlLT5jbWFwLnJlZCA9IE5VTEw7 Cj4+IC0JaW1hZ2UtPmNtYXAuZ3JlZW4gPSBOVUxMOwo+PiAtCWltYWdlLT5jbWFwLmJsdWUgPSBO VUxMOwo+PiAtCWltYWdlLT5jbWFwLnRyYW5zcCA9IE5VTEw7Cj4+IC0JaW1hZ2UtPmRhdGEgPSBx ZmJkZXYtPnNoYWRvdyArICh4MSAqIDQpICsgKHN0cmlkZSAqIHkxKTsKPj4gLQo+PiAtCXF4bF9m Yl9pbWFnZV9pbml0KCZxeGxfZmJfaW1hZ2UsIHFkZXYsIGluZm8sIE5VTEwpOwo+PiAtCXF4bF9k cmF3X29wYXF1ZV9mYigmcXhsX2ZiX2ltYWdlLCBzdHJpZGUpOwo+PiAtfQo+PiAtCj4+IC1zdGF0 aWMgdm9pZCBxeGxfZGlydHlfdXBkYXRlKHN0cnVjdCBxeGxfZmJkZXYgKnFmYmRldiwKPj4gLQkJ CSAgICAgaW50IHgsIGludCB5LCBpbnQgd2lkdGgsIGludCBoZWlnaHQpCj4+IC17Cj4+IC0Jc3Ry dWN0IHF4bF9kZXZpY2UgKnFkZXYgPSBxZmJkZXYtPnFkZXY7Cj4+IC0JdW5zaWduZWQgbG9uZyBm bGFnczsKPj4gLQlpbnQgeDIsIHkyOwo+PiAtCj4+IC0JeDIgPSB4ICsgd2lkdGggLSAxOwo+PiAt CXkyID0geSArIGhlaWdodCAtIDE7Cj4+IC0KPj4gLQlzcGluX2xvY2tfaXJxc2F2ZSgmcWZiZGV2 LT5kaXJ0eS5sb2NrLCBmbGFncyk7Cj4+IC0KPj4gLQlpZiAoKHFmYmRldi0+ZGlydHkueTIgLSBx ZmJkZXYtPmRpcnR5LnkxKSAmJgo+PiAtCSAgICAocWZiZGV2LT5kaXJ0eS54MiAtIHFmYmRldi0+ ZGlydHkueDEpKSB7Cj4+IC0JCWlmIChxZmJkZXYtPmRpcnR5LnkxIDwgeSkKPj4gLQkJCXkgPSBx ZmJkZXYtPmRpcnR5LnkxOwo+PiAtCQlpZiAocWZiZGV2LT5kaXJ0eS55MiA+IHkyKQo+PiAtCQkJ eTIgPSBxZmJkZXYtPmRpcnR5LnkyOwo+PiAtCQlpZiAocWZiZGV2LT5kaXJ0eS54MSA8IHgpCj4+ IC0JCQl4ID0gcWZiZGV2LT5kaXJ0eS54MTsKPj4gLQkJaWYgKHFmYmRldi0+ZGlydHkueDIgPiB4 MikKPj4gLQkJCXgyID0gcWZiZGV2LT5kaXJ0eS54MjsKPj4gLQl9Cj4+IC0KPj4gLQlxZmJkZXYt PmRpcnR5LngxID0geDsKPj4gLQlxZmJkZXYtPmRpcnR5LngyID0geDI7Cj4+IC0JcWZiZGV2LT5k aXJ0eS55MSA9IHk7Cj4+IC0JcWZiZGV2LT5kaXJ0eS55MiA9IHkyOwo+PiAtCj4+IC0Jc3Bpbl91 bmxvY2tfaXJxcmVzdG9yZSgmcWZiZGV2LT5kaXJ0eS5sb2NrLCBmbGFncyk7Cj4+IC0KPj4gLQlz Y2hlZHVsZV93b3JrKCZxZGV2LT5mYl93b3JrKTsKPj4gLX0KPj4gLQo+PiAtc3RhdGljIHZvaWQg cXhsX2RlZmVycmVkX2lvKHN0cnVjdCBmYl9pbmZvICppbmZvLAo+PiAtCQkJICAgIHN0cnVjdCBs aXN0X2hlYWQgKnBhZ2VsaXN0KQo+PiAtewo+PiAtCXN0cnVjdCBxeGxfZmJkZXYgKnFmYmRldiA9 IGluZm8tPnBhcjsKPj4gLQl1bnNpZ25lZCBsb25nIHN0YXJ0LCBlbmQsIG1pbiwgbWF4Owo+PiAt CXN0cnVjdCBwYWdlICpwYWdlOwo+PiAtCWludCB5MSwgeTI7Cj4+IC0KPj4gLQltaW4gPSBVTE9O R19NQVg7Cj4+IC0JbWF4ID0gMDsKPj4gLQlsaXN0X2Zvcl9lYWNoX2VudHJ5KHBhZ2UsIHBhZ2Vs aXN0LCBscnUpIHsKPj4gLQkJc3RhcnQgPSBwYWdlLT5pbmRleCA8PCBQQUdFX1NISUZUOwo+PiAt CQllbmQgPSBzdGFydCArIFBBR0VfU0laRSAtIDE7Cj4+IC0JCW1pbiA9IG1pbihtaW4sIHN0YXJ0 KTsKPj4gLQkJbWF4ID0gbWF4KG1heCwgZW5kKTsKPj4gLQl9Cj4+IC0KPj4gLQlpZiAobWluIDwg bWF4KSB7Cj4+IC0JCXkxID0gbWluIC8gaW5mby0+Zml4LmxpbmVfbGVuZ3RoOwo+PiAtCQl5MiA9 IChtYXggLyBpbmZvLT5maXgubGluZV9sZW5ndGgpICsgMTsKPj4gLQkJcXhsX2RpcnR5X3VwZGF0 ZShxZmJkZXYsIDAsIHkxLCBpbmZvLT52YXIueHJlcywgeTIgLSB5MSk7Cj4+IC0JfQo+PiAtfTsK Pj4gLQo+PiAgIHN0YXRpYyBzdHJ1Y3QgZmJfZGVmZXJyZWRfaW8gcXhsX2RlZmlvID0gewo+PiAg IAkuZGVsYXkJCT0gUVhMX0RJUlRZX0RFTEFZLAo+PiAtCS5kZWZlcnJlZF9pbwk9IHF4bF9kZWZl cnJlZF9pbywKPj4gKwkuZGVmZXJyZWRfaW8JPSBkcm1fZmJfaGVscGVyX2RlZmVycmVkX2lvLAo+ PiAgIH07Cj4+ICAgCj4+IC1zdGF0aWMgdm9pZCBxeGxfZmJfZmlsbHJlY3Qoc3RydWN0IGZiX2lu Zm8gKmluZm8sCj4+IC0JCQkgICAgY29uc3Qgc3RydWN0IGZiX2ZpbGxyZWN0ICpyZWN0KQo+PiAt ewo+PiAtCXN0cnVjdCBxeGxfZmJkZXYgKnFmYmRldiA9IGluZm8tPnBhcjsKPj4gLQo+PiAtCXN5 c19maWxscmVjdChpbmZvLCByZWN0KTsKPj4gLQlxeGxfZGlydHlfdXBkYXRlKHFmYmRldiwgcmVj dC0+ZHgsIHJlY3QtPmR5LCByZWN0LT53aWR0aCwKPj4gLQkJCSByZWN0LT5oZWlnaHQpOwo+PiAt fQo+PiAtCj4+IC1zdGF0aWMgdm9pZCBxeGxfZmJfY29weWFyZWEoc3RydWN0IGZiX2luZm8gKmlu Zm8sCj4+IC0JCQkgICAgY29uc3Qgc3RydWN0IGZiX2NvcHlhcmVhICphcmVhKQo+PiAtewo+PiAt CXN0cnVjdCBxeGxfZmJkZXYgKnFmYmRldiA9IGluZm8tPnBhcjsKPj4gLQo+PiAtCXN5c19jb3B5 YXJlYShpbmZvLCBhcmVhKTsKPj4gLQlxeGxfZGlydHlfdXBkYXRlKHFmYmRldiwgYXJlYS0+ZHgs IGFyZWEtPmR5LCBhcmVhLT53aWR0aCwKPj4gLQkJCSBhcmVhLT5oZWlnaHQpOwo+PiAtfQo+PiAt Cj4+IC1zdGF0aWMgdm9pZCBxeGxfZmJfaW1hZ2VibGl0KHN0cnVjdCBmYl9pbmZvICppbmZvLAo+ PiAtCQkJICAgICBjb25zdCBzdHJ1Y3QgZmJfaW1hZ2UgKmltYWdlKQo+PiAtewo+PiAtCXN0cnVj dCBxeGxfZmJkZXYgKnFmYmRldiA9IGluZm8tPnBhcjsKPj4gLQo+PiAtCXN5c19pbWFnZWJsaXQo aW5mbywgaW1hZ2UpOwo+PiAtCXF4bF9kaXJ0eV91cGRhdGUocWZiZGV2LCBpbWFnZS0+ZHgsIGlt YWdlLT5keSwgaW1hZ2UtPndpZHRoLAo+PiAtCQkJIGltYWdlLT5oZWlnaHQpOwo+PiAtfQo+PiAt Cj4+IC1zdGF0aWMgdm9pZCBxeGxfZmJfd29yayhzdHJ1Y3Qgd29ya19zdHJ1Y3QgKndvcmspCj4+ IC17Cj4+IC0Jc3RydWN0IHF4bF9kZXZpY2UgKnFkZXYgPSBjb250YWluZXJfb2Yod29yaywgc3Ry dWN0IHF4bF9kZXZpY2UsIGZiX3dvcmspOwo+PiAtCXN0cnVjdCBxeGxfZmJkZXYgKnFmYmRldiA9 IHFkZXYtPm1vZGVfaW5mby5xZmJkZXY7Cj4+IC0KPj4gLQlxeGxfZmJfZGlydHlfZmx1c2gocWZi ZGV2LT5oZWxwZXIuZmJkZXYpOwo+PiAtfQo+PiAtCj4+IC1pbnQgcXhsX2ZiX2luaXQoc3RydWN0 IHF4bF9kZXZpY2UgKnFkZXYpCj4+IC17Cj4+IC0JSU5JVF9XT1JLKCZxZGV2LT5mYl93b3JrLCBx eGxfZmJfd29yayk7Cj4+IC0JcmV0dXJuIDA7Cj4+IC19Cj4+IC0KPj4gICBzdGF0aWMgc3RydWN0 IGZiX29wcyBxeGxmYl9vcHMgPSB7Cj4+ICAgCS5vd25lciA9IFRISVNfTU9EVUxFLAo+PiAgIAku ZmJfY2hlY2tfdmFyID0gZHJtX2ZiX2hlbHBlcl9jaGVja192YXIsCj4+ICAgCS5mYl9zZXRfcGFy ID0gZHJtX2ZiX2hlbHBlcl9zZXRfcGFyLCAvKiBUT0RPOiBjb3B5IHZtd2dmeCAqLwo+PiAtCS5m Yl9maWxscmVjdCA9IHF4bF9mYl9maWxscmVjdCwKPj4gLQkuZmJfY29weWFyZWEgPSBxeGxfZmJf Y29weWFyZWEsCj4+IC0JLmZiX2ltYWdlYmxpdCA9IHF4bF9mYl9pbWFnZWJsaXQsCj4+ICsJLmZi X2ZpbGxyZWN0ID0gZHJtX2ZiX2hlbHBlcl9zeXNfZmlsbHJlY3QsCj4+ICsJLmZiX2NvcHlhcmVh ID0gZHJtX2ZiX2hlbHBlcl9zeXNfY29weWFyZWEsCj4+ICsJLmZiX2ltYWdlYmxpdCA9IGRybV9m Yl9oZWxwZXJfc3lzX2ltYWdlYmxpdCwKPj4gICAJLmZiX3Bhbl9kaXNwbGF5ID0gZHJtX2ZiX2hl bHBlcl9wYW5fZGlzcGxheSwKPj4gICAJLmZiX2JsYW5rID0gZHJtX2ZiX2hlbHBlcl9ibGFuaywK Pj4gICAJLmZiX3NldGNtYXAgPSBkcm1fZmJfaGVscGVyX3NldGNtYXAsCj4+IEBAIC0zMzgsNiAr MTc5LDUzIEBAIG91dF91bnJlZjoKPj4gICAJcmV0dXJuIHJldDsKPj4gICB9Cj4+ICAgCj4+ICtz dGF0aWMgaW50IHF4bGZiX2ZyYW1lYnVmZmVyX2RpcnR5KHN0cnVjdCBkcm1fZnJhbWVidWZmZXIg KmZiLAo+PiArCQkJCSAgIHN0cnVjdCBkcm1fZmlsZSAqZmlsZV9wcml2LAo+PiArCQkJCSAgIHVu c2lnbmVkIGZsYWdzLCB1bnNpZ25lZCBjb2xvciwKPj4gKwkJCQkgICBzdHJ1Y3QgZHJtX2NsaXBf cmVjdCAqY2xpcHMsCj4+ICsJCQkJICAgdW5zaWduZWQgbnVtX2NsaXBzKQo+PiArewo+PiArCXN0 cnVjdCBxeGxfZGV2aWNlICpxZGV2ID0gZmItPmRldi0+ZGV2X3ByaXZhdGU7Cj4+ICsJc3RydWN0 IGZiX2luZm8gKmluZm8gPSBxZGV2LT5mYmRldl9pbmZvOwo+PiArCXN0cnVjdCBxeGxfZmJkZXYg KnFmYmRldiA9IGluZm8tPnBhcjsKPj4gKwlzdHJ1Y3QgcXhsX2ZiX2ltYWdlIHF4bF9mYl9pbWFn ZTsKPj4gKwlzdHJ1Y3QgZmJfaW1hZ2UgKmltYWdlID0gJnF4bF9mYl9pbWFnZS5mYl9pbWFnZTsK Pj4gKwo+PiArCS8qIFRPRE86IGhhcmQgY29kaW5nIDMyIGJwcCAqLwo+PiArCWludCBzdHJpZGUg PSBxZmJkZXYtPnFmYi5iYXNlLnBpdGNoZXNbMF07Cj4+ICsKPj4gKwkvKgo+PiArCSAqIHdlIGFy ZSB1c2luZyBhIHNoYWRvdyBkcmF3IGJ1ZmZlciwgYXQgcWRldi0+c3VyZmFjZTBfc2hhZG93Cj4+ ICsJICovCj4+ICsJcXhsX2lvX2xvZyhxZGV2LCAiZGlydHkgeFslZCwgJWRdLCB5WyVkLCAlZF0i LCBjbGlwcy0+eDEsIGNsaXBzLT54MiwKPj4gKwkJICAgY2xpcHMtPnkxLCBjbGlwcy0+eTIpOwo+ PiArCWltYWdlLT5keCA9IGNsaXBzLT54MTsKPj4gKwlpbWFnZS0+ZHkgPSBjbGlwcy0+eTE7Cj4+ ICsJaW1hZ2UtPndpZHRoID0gZHJtX2NsaXBfcmVjdF93aWR0aChjbGlwcyk7Cj4+ICsJaW1hZ2Ut PmhlaWdodCA9IGRybV9jbGlwX3JlY3RfaGVpZ2h0KGNsaXBzKTsKPj4gKwlpbWFnZS0+ZmdfY29s b3IgPSAweGZmZmZmZmZmOyAvKiB1bnVzZWQsIGp1c3QgdG8gYXZvaWQgdW5pbml0aWFsaXplZAo+ PiArCQkJCQkgd2FybmluZ3MgKi8KPj4gKwlpbWFnZS0+YmdfY29sb3IgPSAwOwo+PiArCWltYWdl LT5kZXB0aCA9IDMyOwkgICAgIC8qIFRPRE86IHRha2UgZnJvbSBzb21ld2hlcmU/ICovCj4+ICsJ aW1hZ2UtPmNtYXAuc3RhcnQgPSAwOwo+PiArCWltYWdlLT5jbWFwLmxlbiA9IDA7Cj4+ICsJaW1h Z2UtPmNtYXAucmVkID0gTlVMTDsKPj4gKwlpbWFnZS0+Y21hcC5ncmVlbiA9IE5VTEw7Cj4+ICsJ aW1hZ2UtPmNtYXAuYmx1ZSA9IE5VTEw7Cj4+ICsJaW1hZ2UtPmNtYXAudHJhbnNwID0gTlVMTDsK Pj4gKwlpbWFnZS0+ZGF0YSA9IHFmYmRldi0+c2hhZG93ICsgKGNsaXBzLT54MSAqIDQpICsgKHN0 cmlkZSAqIGNsaXBzLT55MSk7Cj4+ICsKPj4gKwlxeGxfZmJfaW1hZ2VfaW5pdCgmcXhsX2ZiX2lt YWdlLCBxZGV2LCBpbmZvLCBOVUxMKTsKPj4gKwlxeGxfZHJhd19vcGFxdWVfZmIoJnF4bF9mYl9p bWFnZSwgc3RyaWRlKTsKPj4gKwo+PiArCXJldHVybiAwOwo+PiArfQo+PiArCj4+ICtzdGF0aWMg Y29uc3Qgc3RydWN0IGRybV9mcmFtZWJ1ZmZlcl9mdW5jcyBxeGxmYl9mYl9mdW5jcyA9IHsKPj4g KwkuZGVzdHJveSA9IHF4bF91c2VyX2ZyYW1lYnVmZmVyX2Rlc3Ryb3ksCj4+ICsJLmRpcnR5ID0g cXhsZmJfZnJhbWVidWZmZXJfZGlydHksCj4+ICt9Owo+PiArCj4+ICAgc3RhdGljIGludCBxeGxm Yl9jcmVhdGUoc3RydWN0IHF4bF9mYmRldiAqcWZiZGV2LAo+PiAgIAkJCXN0cnVjdCBkcm1fZmJf aGVscGVyX3N1cmZhY2Vfc2l6ZSAqc2l6ZXMpCj4+ICAgewo+PiBAQCAtMzgzLDcgKzI3MSw4IEBA IHN0YXRpYyBpbnQgcXhsZmJfY3JlYXRlKHN0cnVjdCBxeGxfZmJkZXYgKnFmYmRldiwKPj4gICAK Pj4gICAJaW5mby0+cGFyID0gcWZiZGV2Owo+PiAgIAo+PiAtCXF4bF9mcmFtZWJ1ZmZlcl9pbml0 KHFkZXYtPmRkZXYsICZxZmJkZXYtPnFmYiwgJm1vZGVfY21kLCBnb2JqKTsKPj4gKwlxeGxfZnJh bWVidWZmZXJfaW5pdChxZGV2LT5kZGV2LCAmcWZiZGV2LT5xZmIsICZtb2RlX2NtZCwgZ29iaiwK Pj4gKwkJCSAgICAgJnF4bGZiX2ZiX2Z1bmNzKTsKPj4gICAKPj4gICAJZmIgPSAmcWZiZGV2LT5x ZmIuYmFzZTsKPj4gICAKPj4gQEAgLTUwNCw3ICszOTMsNiBAQCBpbnQgcXhsX2ZiZGV2X2luaXQo c3RydWN0IHF4bF9kZXZpY2UgKnFkZXYpCj4+ICAgCXFmYmRldi0+cWRldiA9IHFkZXY7Cj4+ICAg CXFkZXYtPm1vZGVfaW5mby5xZmJkZXYgPSBxZmJkZXY7Cj4+ICAgCXNwaW5fbG9ja19pbml0KCZx ZmJkZXYtPmRlbGF5ZWRfb3BzX2xvY2spOwo+PiAtCXNwaW5fbG9ja19pbml0KCZxZmJkZXYtPmRp cnR5LmxvY2spOwo+PiAgIAlJTklUX0xJU1RfSEVBRCgmcWZiZGV2LT5kZWxheWVkX29wcyk7Cj4+ ICAgCj4+ICAgCWRybV9mYl9oZWxwZXJfcHJlcGFyZShxZGV2LT5kZGV2LCAmcWZiZGV2LT5oZWxw ZXIsCj4+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vcXhsL3F4bF9rbXMuYyBiL2RyaXZl cnMvZ3B1L2RybS9xeGwvcXhsX2ttcy5jCj4+IGluZGV4IGIyOTc3YTEuLjIzMTk4MDAgMTAwNjQ0 Cj4+IC0tLSBhL2RyaXZlcnMvZ3B1L2RybS9xeGwvcXhsX2ttcy5jCj4+ICsrKyBiL2RyaXZlcnMv Z3B1L2RybS9xeGwvcXhsX2ttcy5jCj4+IEBAIC0yNjEsMTAgKzI2MSw2IEBAIHN0YXRpYyBpbnQg cXhsX2RldmljZV9pbml0KHN0cnVjdCBxeGxfZGV2aWNlICpxZGV2LAo+PiAgIAlxZGV2LT5nY19x dWV1ZSA9IGNyZWF0ZV9zaW5nbGV0aHJlYWRfd29ya3F1ZXVlKCJxeGxfZ2MiKTsKPj4gICAJSU5J VF9XT1JLKCZxZGV2LT5nY193b3JrLCBxeGxfZ2Nfd29yayk7Cj4+ICAgCj4+IC0JciA9IHF4bF9m Yl9pbml0KHFkZXYpOwo+PiAtCWlmIChyKQo+PiAtCQlyZXR1cm4gcjsKPj4gLQo+PiAgIAlyZXR1 cm4gMDsKPj4gICB9Cj4+ICAgCj4+IC0tIAo+PiAyLjIuMgo+PgoKX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX18KZHJpLWRldmVsIG1haWxpbmcgbGlzdApkcmkt ZGV2ZWxAbGlzdHMuZnJlZWRlc2t0b3Aub3JnCmh0dHBzOi8vbGlzdHMuZnJlZWRlc2t0b3Aub3Jn L21haWxtYW4vbGlzdGluZm8vZHJpLWRldmVsCg==