Skip to content

Commit d0f2eb3

Browse files
Mikulas Patockagregkh
authored andcommitted
fb: fix lost console when the user unplugs a USB adapter
commit 8c5b044 upstream. I have a USB display adapter using the udlfb driver and I use it on an ARM board that doesn't have any graphics card. When I plug the adapter in, the console is properly displayed, however when I unplug and re-plug the adapter, the console is not displayed and I can't access it until I reboot the board. The reason is this: When the adapter is unplugged, dlfb_usb_disconnect calls unlink_framebuffer, then it waits until the reference count drops to zero and then it deallocates the framebuffer. However, the console that is attached to the framebuffer device keeps the reference count non-zero, so the framebuffer device is never destroyed. When the USB adapter is plugged again, it creates a new device /dev/fb1 and the console is not attached to it. This patch fixes the bug by unbinding the console from unlink_framebuffer. The code to unbind the console is moved from do_unregister_framebuffer to a function unbind_console. When the console is unbound, the reference count drops to zero and the udlfb driver frees the framebuffer. When the adapter is plugged back, a new framebuffer is created and the console is attached to it. Signed-off-by: Mikulas Patocka <[email protected]> Cc: Dave Airlie <[email protected]> Cc: Bernie Thompson <[email protected]> Cc: Ladislav Michl <[email protected]> Cc: [email protected] [b.zolnierkie: preserve old behavior for do_unregister_framebuffer()] Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 9b0dd65 commit d0f2eb3

File tree

1 file changed

+32
-6
lines changed

1 file changed

+32
-6
lines changed

drivers/video/fbdev/core/fbmem.c

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1716,12 +1716,12 @@ static int do_register_framebuffer(struct fb_info *fb_info)
17161716
return 0;
17171717
}
17181718

1719-
static int do_unregister_framebuffer(struct fb_info *fb_info)
1719+
static int unbind_console(struct fb_info *fb_info)
17201720
{
17211721
struct fb_event event;
1722-
int i, ret = 0;
1722+
int ret;
1723+
int i = fb_info->node;
17231724

1724-
i = fb_info->node;
17251725
if (i < 0 || i >= FB_MAX || registered_fb[i] != fb_info)
17261726
return -EINVAL;
17271727

@@ -1736,17 +1736,29 @@ static int do_unregister_framebuffer(struct fb_info *fb_info)
17361736
unlock_fb_info(fb_info);
17371737
console_unlock();
17381738

1739+
return ret;
1740+
}
1741+
1742+
static int __unlink_framebuffer(struct fb_info *fb_info);
1743+
1744+
static int do_unregister_framebuffer(struct fb_info *fb_info)
1745+
{
1746+
struct fb_event event;
1747+
int ret;
1748+
1749+
ret = unbind_console(fb_info);
1750+
17391751
if (ret)
17401752
return -EINVAL;
17411753

17421754
pm_vt_switch_unregister(fb_info->dev);
17431755

1744-
unlink_framebuffer(fb_info);
1756+
__unlink_framebuffer(fb_info);
17451757
if (fb_info->pixmap.addr &&
17461758
(fb_info->pixmap.flags & FB_PIXMAP_DEFAULT))
17471759
kfree(fb_info->pixmap.addr);
17481760
fb_destroy_modelist(&fb_info->modelist);
1749-
registered_fb[i] = NULL;
1761+
registered_fb[fb_info->node] = NULL;
17501762
num_registered_fb--;
17511763
fb_cleanup_device(fb_info);
17521764
event.info = fb_info;
@@ -1759,7 +1771,7 @@ static int do_unregister_framebuffer(struct fb_info *fb_info)
17591771
return 0;
17601772
}
17611773

1762-
int unlink_framebuffer(struct fb_info *fb_info)
1774+
static int __unlink_framebuffer(struct fb_info *fb_info)
17631775
{
17641776
int i;
17651777

@@ -1771,6 +1783,20 @@ int unlink_framebuffer(struct fb_info *fb_info)
17711783
device_destroy(fb_class, MKDEV(FB_MAJOR, i));
17721784
fb_info->dev = NULL;
17731785
}
1786+
1787+
return 0;
1788+
}
1789+
1790+
int unlink_framebuffer(struct fb_info *fb_info)
1791+
{
1792+
int ret;
1793+
1794+
ret = __unlink_framebuffer(fb_info);
1795+
if (ret)
1796+
return ret;
1797+
1798+
unbind_console(fb_info);
1799+
17741800
return 0;
17751801
}
17761802
EXPORT_SYMBOL(unlink_framebuffer);

0 commit comments

Comments
 (0)